Bot Version Reports and Balance Tracking Implementation
Date: May 4, 2026
Project: Quantago
Feature: Version Reports with Performance Statistics and Balance Progression
Overview
Implemented a comprehensive reporting system for Quantago bots that tracks performance metrics and balances across version changes. When a bot version is created (via strategy changes, parameter updates, etc.), the system automatically:
- Closes the previous version's report with performance statistics calculated from trades during its active period
- Propagates the balance from the previous version's ending balance to the new version's starting balance
- Creates a new version report starting with the inherited balance
- Records version transitions for audit trail and analysis
Architecture
Database Layer (0026_bot_version_reports.sql)
Created two new tables:
bot_version_reports
- Stores performance snapshot for each bot version
- Tracks: version number, active period (started_at, ended_at), starting/ending balance
- Calculates metrics: trades, win rate, profit, profit factor, pips, drawdown
- Includes strategy snapshot and notes for context
Key columns:
bot_id UUID -- Foreign key to bots
user_id TEXT -- Owner
version INTEGER -- Version number
started_at TIMESTAMP -- When this version became active
ended_at TIMESTAMP -- When this version was superseded (NULL if active)
starting_balance DECIMAL -- Balance inherited from previous version
ending_balance DECIMAL -- Final balance when version closed
total_trades, winning_trades, losing_trades
win_rate, total_profit, profit_factor, avg_pips, total_pips
strategy_name, strategy_snapshot -- Strategy info at version creation
bot_version_transitions
- Audit trail for version changes
- Records: from/to versions, reason (parameter_change, strategy_change, schedule_change, manual), changes delta
- Enables tracing the evolution of bot configuration
Key columns:
bot_id UUID
from_version INTEGER
to_version INTEGER
reason TEXT
changes JSONB -- Diff of what changed
transitioned_at TIMESTAMP
transitioned_by_user_id TEXT
Also added current_balance DECIMAL column to bots table for real-time tracking.
Backend Service Layer (src/db/reports-service.ts)
Core Functions
-
calculateReportMetrics()- Queries
bot_tradesfor a version's active period - Aggregates: trade count, win/loss rates, profit metrics, pips
- Uses PostgreSQL CTEs for efficient calculation
- Queries
-
upsertVersionReport()- Creates or updates a version report
- Automatically calculates metrics from trades
- Supports
ON CONFLICTfor idempotent updates
-
handleVersionTransitionWithBalance()⭐ Core Balance Logic- Closes previous version: Sets
ended_at = NOW()andending_balance = currentBalance - Creates new version: Sets
started_at = NOW()andstarting_balance = currentBalance(inherited) - Updates bot: Sets
bot.current_balanceand incrementsbot.version - Records transition: Logs what changed and why
- Ensures balance chain continuity:
Version 1 ending_balance→Version 2 starting_balance
- Closes previous version: Sets
-
getVersionReport(),listVersionReports(),getVersionTransitionHistory()- Fetch reports by version or bot
- Support ordering by version/date
API Endpoints (src/routes/bots/bots-reports-handlers.ts)
All endpoints mounted under /api/bots/:id/reports:
GET /api/bots/:id/reports -- List all version reports
GET /api/bots/:id/reports/:version -- Get specific version report
POST /api/bots/:id/reports -- Create/update version report (admin)
GET /api/bots/:id/reports/transitions/history -- Get version transition timeline
POST /api/bots/:id/reports/transition -- Record a transition (admin)
Example response:
{
"id": "uuid",
"botId": "uuid",
"version": 2,
"startedAt": "2026-05-01T10:30:00Z",
"endedAt": "2026-05-03T15:45:00Z",
"startingBalance": 10000,
"endingBalance": 12500,
"totalTrades": 15,
"winningTrades": 10,
"losingTrades": 5,
"winRate": 66.67,
"totalProfit": 2500,
"profitFactor": 1.85,
"avgPips": 28.5,
"totalPips": 427.5
}
Frontend Layer
Report Card Component (ReportCard.tsx)
- Displays version snapshot in grid/card format
- Shows: version #, active status, balance, profit, metrics, ROI
- Clickable to open detail modal
- Responsive grid layout (1-3 columns)
Reports Page (BotReportsPage.tsx)
- Full-page view of bot's version history
- Grid of Report Cards: Browse all versions at once
- Detail Modal: Click card to view full metrics, balance chain, strategy config
- Timeline: Visual sequence of version transitions with reason annotations
- Empty State: Guidance when no reports exist
API Hooks (bots-reports-hooks.ts)
- React Query integration for data fetching
useListBotReports()— Fetch all reportsuseGetBotVersionReport()— Fetch specific versionuseVersionTransitionHistory()— Fetch timelineuseCreateBotReport()— Mutate reportuseRecordVersionTransition()— Mutate transition
Type Definitions (types/reports.ts)
export interface VersionReport {
id: string;
botId: string;
version: number;
startedAt: Date;
endedAt: Date | null;
startingBalance: number;
endingBalance: number | null;
totalTrades: number;
winRate: number;
totalProfit: number;
profitFactor: number | null;
// ... more fields
}
Balance Progression Example
Version 1: Jan 1 – Feb 1
Starting: $10,000
Ending: $12,500 (profit: $2,500, ROI: 25%)
↓ (balance carries forward)
Version 2: Feb 1 – Mar 1
Starting: $12,500 (inherited from V1)
Ending: $11,800 (loss: -$700, ROI: -5.6%)
↓
Version 3: Mar 1 – present
Starting: $11,800 (inherited from V2)
Ending: NULL (active, current_balance tracks live)
Current: $13,200 (in-progress)
Key Features
✅ Automatic Metric Calculation
- Win rate, profit factor, pips aggregated from trades
- Accurate period filtering (started_at to ended_at)
✅ Balance Chain Integrity
- Previous ending_balance = Next starting_balance
- Single source of truth:
bots.current_balance - Supports ROI calculation across version boundaries
✅ Audit Trail
- Every version transition logged with reason
- Changes delta recorded (parameter, strategy, schedule changes)
- Timestamp + user tracking
✅ UI/UX
- Card-based grid for quick overview
- Modal deep-dive for full metrics
- Timeline visualization
- ROI calculation and color-coded indicators (green profit, red loss)
Integration Points
When to Call handleVersionTransitionWithBalance()
This should be called whenever a bot's version increments:
- Strategy changes (
POST /api/bots/:id/strategy) - Parameter updates (if version bump is triggered)
- Manual version creation (future UI for setting version markers)
Example usage in bots-handlers:
const result = await handleVersionTransitionWithBalance(
c.env,
botId,
userId,
newVersion,
currentBalance, // from bot_trades or portfolio tracking
'strategy_change',
{ strategy: 'old_strategy', newStrategy: 'momentum_strategy' },
'Momentum Strategy',
strategySnapshot
);
Testing Considerations
- Balance Progression: Verify starting_balance of V2 = ending_balance of V1
- Metric Accuracy: Spot-check trade aggregation against bot_trades manually
- Active Version: Ensure ended_at IS NULL for current version
- Historical Queries: Test listing reports, filtering by date range
- UI Rendering: Test with 1, 10, 100+ versions to check grid responsiveness
Files Created/Modified
Backend
src/db/migrations/0026_bot_version_reports.sql(NEW)src/db/reports-service.ts(NEW)src/routes/bots/bots-reports-handlers.ts(NEW)src/routes/bots/bots-router.ts(MODIFIED - added report endpoints)src/index.ts(no changes needed, reports-handlers imported)
Frontend
src/routes/bots/ReportCard.tsx(NEW)src/routes/bots/BotReportsPage.tsx(NEW)src/routes/bots/bots-reports-hooks.ts(NEW)src/types/reports.ts(NEW)
Future Enhancements
- Drawdown Tracking: Calculate max_drawdown, recovery time
- Performance Charts: Equity curve, P&L timeline
- Version Comparison: Side-by-side metrics between versions
- Export Reports: PDF/CSV export for compliance/analysis
- Alerts: Notify when version transition crosses thresholds (loss limit, win rate drop)
- Backtest Integration: Link backtests to version reports for validation
Validation Checklist
- Migration creates tables with correct schema
- Reports service calculates metrics from trades
- Balance progression logic implemented
- API endpoints functional and secured
- Frontend components display data correctly
- React Query hooks cache/invalidate appropriately
- Types match backend responses
- Error handling for missing bots/versions
Notes
- Reports are created on-demand (not pre-calculated), allowing flexibility in period definition
- Current version's
ending_balanceis NULL; usebots.current_balancefor live equity - All balance values stored as DECIMAL(19,8) for precision with crypto/forex
- Strategy snapshot captured at version creation for reproducibility