Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/DeweyMarco/simple-kalshi-bot/llms.txt

Use this file to discover all available pages before exploring further.

Overview

The monitor.py module provides logging setup and progress monitoring functions for the genetic algorithm evolution loop. It handles dual logging (file + console), periodic progress reports, and generation summaries with leaderboards.

Functions

setup_logging() → logging.Logger

Configure dual logging with file and console handlers.
logger
logging.Logger
Configured logger instance named “evolution”
Behavior:
  • Creates STATE_DIR/evolution.log for full debug logs
  • Outputs INFO+ messages to console with timestamps
  • Automatically creates state directory if missing
  • Prevents duplicate handlers on re-initialization
from genetic.monitor import setup_logging

logger = setup_logging()
logger.info("Evolution started")
logger.debug("Detailed debug info (file only)")
Log Formats:
  • File: 2023-12-31 10:30:45 [INFO] message
  • Console: [10:30:45] message

log_tick_progress()

Log periodic progress during a generation’s trading period.
logger
logging.Logger
required
Logger instance from setup_logging()
gen_num
int
required
Current generation number
tick_count
int
required
Number of ticks elapsed in this generation
bots
list[GeneticBot]
required
List of all bots in this generation
feed
MarketDataFeed | None
Optional market data feed for unrealized ROI calculation
Output Example:
[Gen 5 | 2.5h] Active: 45/50 | Open: 120 | Trades: 458 | Settled: 203 | 
Est ROI: +15.2%/+8.1% | Realized: +12.3%/+6.5%
from genetic.monitor import log_tick_progress

for tick in range(generation_ticks):
    # ... trading logic ...
    
    if tick % PROGRESS_LOG_INTERVAL_TICKS == 0:
        log_tick_progress(logger, gen_num, tick, bots, feed)
Metrics Reported:
  • Elapsed time in hours
  • Active bots (with at least one trade)
  • Total open positions across all bots
  • Total trades and settled positions
  • Best and median ROI (both estimated and realized)

log_generation_summary()

Log a complete generation summary with leaderboard after trading completes.
logger
logging.Logger
required
Logger instance from setup_logging()
gen_num
int
required
Generation number being summarized
bots
list[GeneticBot]
required
List of all bots in this generation
fitness
list[float]
required
Fitness scores (ROI percentages) for each bot
Output Example:
======================================================================
GENERATION 5 RESULTS
======================================================================
Rank  Bot ID         ROI%    Trades Settled  WinRate          Signal
----------------------------------------------------------------------
1     a1b2c3d4       18.5%      127      89    65.2%     momentum
2     e5f6g7h8       15.2%       98      67    58.2%  price_level
3     i9j0k1l2       12.8%      115      78    61.5%         value
...

Signal distribution: {'momentum': 15, 'price_level': 12, 'value': 10, ...}
Top-10 category prefs: {'politics': 8, 'economics': 6, 'crypto': 4, ...}
from genetic.monitor import log_generation_summary
from genetic.evolution import evaluate_fitness

# After generation completes
fitness = [evaluate_fitness(bot) for bot in bots]
log_generation_summary(logger, gen_num, bots, fitness)
Information Displayed:
  • Top 20 bots ranked by fitness (ROI)
  • Bot ID, ROI%, total trades, settled trades, win rate, signal type
  • Distribution of signal types across population
  • Category preferences of top 10 performers

compute_generation_stats(bots: list[GeneticBot]) → dict

Compute summary statistics for a completed generation.
bots
list[GeneticBot]
required
List of all bots in the generation
stats
dict
Dictionary containing:
  • best_roi: Highest fitness (ROI%) in generation
  • median_roi: Median fitness across all bots
  • worst_roi: Lowest fitness in generation
  • mean_roi: Average fitness across all bots
  • mean_trades: Average number of trades per bot
  • max_trades: Maximum trades by any single bot
  • mean_win_rate: Average win rate percentage
  • total_settled: Total settled positions across all bots
  • active_bots: Number of bots that made at least one trade
from genetic.monitor import compute_generation_stats

stats = compute_generation_stats(bots)
print(f"Best ROI: {stats['best_roi']:.2f}%")
print(f"Median ROI: {stats['median_roi']:.2f}%")
print(f"Mean trades: {stats['mean_trades']:.1f}")
print(f"Active bots: {stats['active_bots']}/{len(bots)}")

Usage Example

Complete monitoring setup for an evolution loop:
from genetic.monitor import (
    setup_logging,
    log_tick_progress,
    log_generation_summary,
    compute_generation_stats
)
from genetic.config import PROGRESS_LOG_INTERVAL_TICKS

# Initialize
logger = setup_logging()
logger.info("Starting evolution...")

# During generation
for tick in range(total_ticks):
    # Trading logic here
    for bot in bots:
        bot.tick()
    
    # Periodic progress
    if tick % PROGRESS_LOG_INTERVAL_TICKS == 0:
        log_tick_progress(logger, gen_num, tick, bots, feed)

# After generation
fitness = [evaluate_fitness(bot) for bot in bots]
log_generation_summary(logger, gen_num, bots, fitness)

stats = compute_generation_stats(bots)
logger.info(f"Best: {stats['best_roi']:.2f}%, Active: {stats['active_bots']}")

Configuration

Uses these constants from genetic.config:
  • STATE_DIR: Directory for log file storage
  • TICK_INTERVAL_SECONDS: Used to calculate elapsed hours

Build docs developers (and LLMs) love