Skip to main content

Overview

Both bot.py and consensus.py record all trades to CSV files for analysis. This guide explains the CSV format and how to analyze your trading performance.

CSV Output Files

The bot creates CSV files in the data/ directory:
FileSourceDescription
data/mock_trades.csvbot.pyPaper trading results from all strategies
data/consensus_trades.csvconsensus.pyReal trading results from CONSENSUS strategy

CSV Format: Paper Trading (bot.py)

Columns

ColumnTypeDescription
timeISO timestampWhen the trade was placed
strategystringStrategy name (PREVIOUS, MOMENTUM, CONSENSUS, etc.)
previous_tickerstringPrevious market ticker (for context)
previous_resultstringPrevious market result or signal description
buy_tickerstringMarket ticker that was traded
buy_sidestringyes or no
stake_usdfloatAmount staked in USD
price_usdfloatPrice per contract (0.00-1.00)
contractsfloatNumber of contracts purchased
fee_usdfloatTrading fees (for CONSENSUS strategies)
gross_profit_usdfloatProfit before fees
outcomestringWIN, LOSS, or empty (pending)
payout_usdfloatPayout received (contracts if won, 0 if lost)
profit_usdfloatNet profit/loss after fees

Example Data

time,strategy,previous_ticker,previous_result,buy_ticker,buy_side,stake_usd,price_usd,contracts,fee_usd,gross_profit_usd,outcome,payout_usd,profit_usd
2025-03-05T14:23:58.123456+00:00,PREVIOUS,KXBTC15M-25MAR05-T1015,yes,KXBTC15M-25MAR05-T1030,yes,5.0,0.52,9.6154,,,WIN,9.6154,4.6154
2025-03-05T14:24:03.234567+00:00,MOMENTUM,KXBTC15M-25MAR05-T1015,BTC +0.234%,KXBTC15M-25MAR05-T1030,yes,5.0,0.52,9.6154,,,WIN,9.6154,4.6154
2025-03-05T14:24:08.345678+00:00,CONSENSUS,,PREV=yes MOM=yes,KXBTC15M-25MAR05-T1030,yes,4.8,0.48,10.0,0.048,5.2,WIN,10.0,5.152

CSV Format: Real Trading (consensus.py)

Columns

ColumnTypeDescription
timeISO timestampWhen the trade was placed
buy_tickerstringMarket ticker that was traded
buy_sidestringyes or no
stake_usdfloatAmount staked in USD
price_usdfloatPrice per contract (0.00-1.00)
contractsintNumber of contracts purchased
order_idstringKalshi order ID
prev_signalstringPREVIOUS strategy signal (yes or no)
mom_signalstringMOMENTUM strategy signal (yes or no)
outcomestringWIN, LOSS, or empty (pending)
payout_usdfloatPayout received
profit_usdfloatNet profit/loss

Example Data

time,buy_ticker,buy_side,stake_usd,price_usd,contracts,order_id,prev_signal,mom_signal,outcome,payout_usd,profit_usd
2025-03-05T14:30:45.123456+00:00,KXBTC15M-25MAR05-T1045,yes,4.8,0.48,10,DRY-RUN-f8e9a7b6,yes,yes,WIN,10.0,5.2
2025-03-05T14:45:32.234567+00:00,KXBTC15M-25MAR05-T1100,no,5.2,0.52,10,DRY-RUN-a1b2c3d4,no,no,LOSS,0.0,-5.2

Using the Analysis Script

The project includes analyze.py for automated performance analysis.

Running the Analysis

python analyze.py

Example Output

Loaded 150 trades from data/mock_trades.csv
Note: 12 trades are pending (no outcome yet)

======================================================================
STRATEGY PERFORMANCE ANALYSIS
======================================================================

Strategy         Wins  Losses  Total   Win Rate      Profit        ROI
----------------------------------------------------------------------
CONSENSUS_2        24       7     31      77.4%     $+84.20      168.4%
CONSENSUS          22       8     30      73.3%     $+68.50      137.0%
ARBITRAGE          28       6     34      82.4%     $+21.50       31.6%
PREVIOUS_2         16      11     27      59.3%     $+31.00       62.0%
MOMENTUM           18      14     32      56.3%     $+42.00       84.0%
MOMENTUM_15        14      12     26      53.8%     $+15.00       30.0%
PREVIOUS           12      15     27      44.4%     $-23.50      -47.0%
----------------------------------------------------------------------

TOTALS             134     73    207      64.7%    $+239.70       79.9%

Best Strategy by Win Rate: ARBITRAGE (82.4%)
Best Strategy by Profit: CONSENSUS_2 ($84.20)
Best Strategy by ROI: CONSENSUS_2 (168.4%)

======================================================================

DETAILED BREAKDOWN
----------------------------------------------------------------------

ARBITRAGE:
  Total Trades: 34
  Wins: 28, Losses: 6
  Win Rate: 82.35%
  Total Staked: $68.00
  Total Profit: $21.50
  ROI: 31.62%
  Avg Profit/Trade: $0.63

CONSENSUS:
  Total Trades: 30
  Wins: 22, Losses: 8
  Win Rate: 73.33%
  Total Staked: $50.00
  Total Profit: $68.50
  ROI: 137.00%
  Avg Profit/Trade: $2.28

CONSENSUS_2:
  Total Trades: 31
  Wins: 24, Losses: 7
  Win Rate: 77.42%
  Total Staked: $50.00
  Total Profit: $84.20
  ROI: 168.40%
  Avg Profit/Trade: $2.72

[... additional strategies ...]

Understanding the Metrics

Win Rate
percentage
Percentage of trades that were profitable.Formula: (Wins / Total Trades) × 100
Total Profit
USD
Net profit/loss across all trades for the strategy.Formula: Sum of all profit_usd values
ROI (Return on Investment)
percentage
Total profit as a percentage of total capital staked.Formula: (Total Profit / Total Staked) × 100
Avg Profit/Trade
USD
Average profit per trade.Formula: Total Profit / Total Trades

Manual Analysis with Python

For custom analysis, load the CSV with pandas:
import pandas as pd

# Load trades
df = pd.read_csv('data/mock_trades.csv')

# Filter to settled trades only
settled = df[df['outcome'].notna() & (df['outcome'] != '')]

# Calculate win rate by strategy
win_rates = settled.groupby('strategy')['outcome'].apply(
    lambda x: (x == 'WIN').sum() / len(x) * 100
)
print(win_rates)

# Calculate cumulative P&L over time
settled['cumulative_pnl'] = settled['profit_usd'].astype(float).cumsum()

# Plot performance
import matplotlib.pyplot as plt
settled.plot(x='time', y='cumulative_pnl', figsize=(12, 6))
plt.title('Cumulative P&L Over Time')
plt.ylabel('Profit/Loss (USD)')
plt.show()

Key Performance Indicators

Strategy Comparison

Compare strategies on these dimensions:

Win Rate

Higher is better, but consider sample size. 70%+ is excellent.

ROI

Return on capital. Positive ROI means profitable strategy.

Total Profit

Absolute gains. Strategies with higher volume may have higher total profit.

Risk-Adjusted Returns

Consider volatility and drawdowns, not just returns.

Red Flags

Watch for these warning signs:
  • Win rate < 50% - Strategy may not have an edge
  • Negative ROI - Losing money over time
  • High variance - Large swings in profit/loss
  • Small sample size - Need more trades for statistical significance

Advanced Analytics

Calculate Sharpe Ratio

Measure risk-adjusted returns:
import numpy as np

# Calculate returns per trade
df['return'] = df['profit_usd'] / df['stake_usd']

# Sharpe ratio (assuming risk-free rate = 0)
sharpe = df['return'].mean() / df['return'].std() * np.sqrt(len(df))
print(f"Sharpe Ratio: {sharpe:.2f}")

Maximum Drawdown

Find worst peak-to-trough decline:
# Calculate cumulative P&L
df['cumulative'] = df['profit_usd'].cumsum()

# Calculate running maximum
running_max = df['cumulative'].cummax()

# Calculate drawdown
drawdown = df['cumulative'] - running_max
max_drawdown = drawdown.min()

print(f"Maximum Drawdown: ${max_drawdown:.2f}")

Win/Loss Streaks

Identify longest winning and losing streaks:
# Create win/loss indicator
df['is_win'] = (df['outcome'] == 'WIN').astype(int)

# Calculate streaks
streaks = df['is_win'].groupby(
    (df['is_win'] != df['is_win'].shift()).cumsum()
).agg(['sum', 'count'])

max_win_streak = streaks[streaks['sum'] > 0]['count'].max()
max_loss_streak = streaks[streaks['sum'] == 0]['count'].max()

print(f"Longest win streak: {max_win_streak}")
print(f"Longest loss streak: {max_loss_streak}")

Exporting Results

To Excel

import pandas as pd

df = pd.read_csv('data/mock_trades.csv')

# Create Excel writer
with pd.ExcelWriter('analysis.xlsx') as writer:
    # All trades
    df.to_excel(writer, sheet_name='All Trades', index=False)
    
    # Summary by strategy
    summary = df.groupby('strategy').agg({
        'profit_usd': ['sum', 'mean', 'count'],
        'outcome': lambda x: (x == 'WIN').sum() / len(x) * 100
    })
    summary.to_excel(writer, sheet_name='Summary')

To JSON

import pandas as pd
import json

df = pd.read_csv('data/mock_trades.csv')

# Convert to JSON
result = df.to_json(orient='records', date_format='iso')

with open('trades.json', 'w') as f:
    f.write(result)

Monitoring Live Performance

Real-time Metrics

While the bot is running, monitor these in real-time:
1

Watch cumulative P&L

Track the running profit/loss for each strategy in the status output.
2

Check win/loss ratio

Look for strategies consistently showing more wins than losses.
3

Monitor CONSENSUS bankroll

The CB value shows current bankroll after realized P&L.
4

Track pending trades

Note how many trades are waiting for settlement.

Setting Alerts

Create alerts for important events:
import pandas as pd
import time

WARNING_LOSS_THRESHOLD = -50.0  # Alert if loss exceeds this

while True:
    df = pd.read_csv('data/mock_trades.csv')
    total_pnl = df['profit_usd'].sum()
    
    if total_pnl < WARNING_LOSS_THRESHOLD:
        print(f"⚠️  WARNING: Total P&L is ${total_pnl:.2f}")
        # Send email, SMS, etc.
    
    time.sleep(60)  # Check every minute

Best Practices

Regular AnalysisRun analysis daily to:
  • Identify underperforming strategies
  • Detect changing market conditions
  • Adjust risk parameters as needed
Keep Historical DataArchive CSV files periodically:
cp data/mock_trades.csv backups/mock_trades_$(date +%Y%m%d).csv
Version ControlTrack configuration changes alongside performance data to understand what works.

Next Steps

Configuration

Optimize your configuration based on analysis

Running the Bot

Run the bot with updated settings

Build docs developers (and LLMs) love