Skip to main content

Strategy Execution & Performance Metrics Implementation

Overview

This implementation adds comprehensive strategy execution tracking and performance metrics to the Predicta strategy automation system. Users can now:
  • Track all strategy executions with detailed logs (when triggered, market, outcome, price, P&L)
  • Monitor performance metrics including win rate, ROI, total P&L
  • Analyze execution history with a detailed table viewer
  • Cache metrics for fast retrieval without recalculation

Architecture

Type Definitions (src/types/portfolio.ts)

StrategyExecutionLog

Tracks individual strategy execution events:
type StrategyExecutionLog = {
  id: string;
  strategyId: string;
  userId: string;
  executedAt: number;
  triggerReason: 'manual' | 'threshold' | 'price_target' | 'scheduled' | 'ai_signal';
  
  // Execution details
  marketId: string;
  marketName: string;
  outcome: 'Yes' | 'No';
  orderType: 'buy' | 'sell';
  shares: number;
  executionPrice: number;
  totalValue: number;
  
  // P&L tracking (populated on close)
  status: 'pending' | 'executed' | 'closed';
  pnl?: number;
  roi?: number;
  closedAt?: number;
  
  notes?: string;
  txHash?: string;
};

StrategyPerformanceMetrics

Aggregated performance statistics:
type StrategyPerformanceMetrics = {
  strategyId: string;
  totalExecutions: number;
  profitableExecutions: number;
  lossExecutions: number;
  winRate: number; // 0-100
  
  totalPnL: number;
  averagePnL: number;
  bestTrade: number;
  worstTrade: number;
  
  totalROI: number;
  averageROI: number;
  
  firstExecutionAt: number;
  lastExecutionAt: number;
  
  totalCapitalDeployed: number;
  averageTradeSize: number;
};

Services

strategyMetricsService (src/services/strategyMetricsService.ts)

Core Methods:
  • logExecution(userId, strategyId, executionData) - Record a new strategy execution
  • closeExecution(userId, strategyId, executionId, pnl, roi) - Mark execution as closed with P&L
  • getExecutionLogs(userId, strategyId, limit) - Retrieve execution history
  • calculateMetrics(userId, strategyId) - Calculate metrics from logs (real-time)
  • cacheMetrics(userId, strategyId) - Store metrics in strategy document for fast reads
  • getCachedMetrics(userId, strategyId) - Read pre-computed metrics (no recalculation)
  • formatMetrics(metrics) - Format metrics for display (win rate %, currency format, etc.)
Firestore Structure:
users/
  {userId}/
    strategies/
      {strategyId}/
        executionLogs/
          {executionId}
            - id, strategyId, userId
            - executedAt, triggerReason
            - marketId, marketName, outcome
            - orderType, shares, executionPrice, totalValue
            - status (pending|executed|closed)
            - pnl, roi, closedAt (populated on close)
        
        (strategy document contains)
        - metrics: StrategyPerformanceMetrics
        - metricsUpdatedAt: number

Components

StrategyMetricsCard (src/components/automate/StrategyMetricsCard.tsx)

Displays key performance metrics for a strategy:
┌─ Performance ─────────────────────┐
│ Total Executions: 5              │
├──────────────────────────────────┤
│ Total P&L          +$1,234.56    │
│ Avg ROI            +5.2%         │
├──────────────────────────────────┤
│ ★ Win Rate         80%           │
│ ■■■■■■■□□ (4W / 1L)             │
├──────────────────────────────────┤
│ Avg Trade          $245.67       │
│ Best Trade         +$456.78      │
├──────────────────────────────────┤
│ Average P&L        +$246.91      │
│ Max Loss           -$123.45      │
└──────────────────────────────────┘
Features:
  • Loading skeleton while fetching metrics
  • “No execution data yet” state
  • Color coding (green for profit, red for loss)
  • Icons for trending up/down
  • Progress bar for win rate visualization

ExecutionLogsViewer (src/components/automate/ExecutionLogsViewer.tsx)

Detailed execution history in a sheet modal with table:
Execution History | [All triggered executions with P&L tracking]

Date         | Trigger | Market    | Order    | Price  | Shares | Value   | Status    | P&L      | ROI
2026-01-31   | 🤖      | Crypto X  | BUY YES  | 0.456  | 50     | $22.80  | CLOSED    | +$1.23   | +5.4%
2026-01-30   | ⏰      | Politics  | BUY NO   | 0.234  | 100    | $23.40  | EXECUTED  | -        | -
2026-01-29   | 📊      | Sports    | SELL YES | 0.789  | 30     | $23.67  | CLOSED    | -$0.78   | -3.3%

Summary:
├ Total Executions: 3
├ Closed Trades: 2
├ Total Capital: $69.87
└ Avg P&L: +$0.23
Features:
  • Click “Execution Logs” button to open sheet
  • Sortable columns (date, trigger type, market, order type, etc.)
  • Emoji badges for trigger reason (🤖 AI, ⏰ Scheduled, 📊 Threshold, 🎯 Target, 👤 Manual)
  • Status badges (PENDING, EXECUTED, CLOSED)
  • Color-coded P&L (green profit, red loss)
  • Summary statistics at bottom
  • Responsive table for mobile

Integration in StrategyList

Each strategy card now includes:
  • StrategyMetricsCard embedded below strategy details
  • ExecutionLogsViewer button in footer (alongside Delete)

Usage Flows

Flow 1: Log a Strategy Execution

When a strategy triggers and executes a trade:
import { logStrategyExecution } from '@/services/strategyService';

const result = await logStrategyExecution(userId, strategyId, {
  executedAt: Date.now(),
  triggerReason: 'ai_signal',
  marketId: 'market-123',
  marketName: 'Will Bitcoin hit $100k?',
  outcome: 'Yes',
  orderType: 'buy',
  shares: 50,
  executionPrice: 0.45,
  totalValue: 22.50,
  status: 'executed',
  txHash: '0x...',
});

if (result.success) {
  console.log('Execution logged:', result.executionId);
}

Flow 2: Close an Execution and Record P&L

When the position is eventually closed/sold:
import { closeStrategyExecution } from '@/services/strategyService';

const pnl = 25.00 - 22.50; // $2.50 profit
const roi = (pnl / 22.50) * 100; // 11.1% ROI

const result = await closeStrategyExecution(
  userId,
  strategyId,
  executionId,
  pnl,      // $2.50
  roi       // 11.1
);

Flow 3: Display Metrics

Metrics automatically display in the UI:
// In StrategyList component (already integrated)
<StrategyMetricsCard 
  strategyId={strategy.id}
  userId={userId}
/>

// View detailed logs
<ExecutionLogsViewer
  strategyId={strategy.id}
  userId={userId}
/>

Flow 4: Calculate Fresh Metrics (Manual)

For real-time calculation without cache:
import { strategyMetricsService } from '@/services/strategyMetricsService';

const metrics = await strategyMetricsService.calculateMetrics(userId, strategyId);

if (metrics) {
  console.log(`Win Rate: ${metrics.winRate}%`);
  console.log(`Total P&L: $${metrics.totalPnL}`);
  console.log(`Average ROI: ${metrics.averageROI}%`);
}

Flow 5: Cache Metrics (Background Job)

Periodically cache metrics for faster reads:
// Could be run from Cloud Function or scheduled cron
import { strategyMetricsService } from '@/services/strategyMetricsService';

// Recalculate and cache all user's strategies
for (const strategy of userStrategies) {
  await strategyMetricsService.cacheMetrics(userId, strategy.id);
}

Flow 6: Use Cached Metrics (Fast Read)

For performance-critical UI updates:
const cachedMetrics = await strategyMetricsService.getCachedMetrics(userId, strategyId);

if (cachedMetrics) {
  // Metrics already computed, use immediately
  displayMetrics(cachedMetrics);
} else {
  // No cache yet, fall back to real-time calculation
  const metrics = await strategyMetricsService.calculateMetrics(userId, strategyId);
  displayMetrics(metrics);
}

Metrics Calculations

Win Rate

winRate = (profitableExecutions / closedTrades) * 100

Total P&L

totalPnL = sum of all pnl values from closed executions

Average P&L

averagePnL = totalPnL / closedTrades.length

ROI Metrics

totalROI = sum of all roi percentages
averageROI = totalROI / closedTrades.length

Best/Worst Trades

bestTrade = max(pnl values)
worstTrade = min(pnl values)

Capital Metrics

totalCapitalDeployed = sum of all totalValue
averageTradeSize = totalCapitalDeployed / totalExecutions

State Management

No Redux/Zustand needed - data flows directly from Firestore:
  1. StrategyMetricsCard reads from Firestore via getCachedMetrics()
  2. Loading state shows skeleton while fetching
  3. Empty state shown if no data
  4. Auto-updates when component remounts

Performance Considerations

Optimization Strategies

  1. Caching: Pre-computed metrics cached in strategy doc
  2. Pagination: ExecutionLogsViewer loads max 100 logs, limit configurable
  3. Lazy Loading: Only recalculate on explicit action
  4. Cloud Functions: Cache metrics every 5 minutes with scheduler
// functions/src/strategies/cache-metrics.ts
export const cacheStrategyMetrics = onSchedule(
  { schedule: 'every 5 minutes' },
  async (context) => {
    // For each strategy with executions this period
    // Call strategyMetricsService.cacheMetrics(userId, strategyId)
  }
);

Error Handling

All service methods include try-catch and emit errors via errorEmitter:
errorEmitter.emit('error', {
  code: 'STRATEGY_LOG_EXECUTION_ERROR',
  message: 'Failed to log execution'
});
Error codes:
  • STRATEGY_LOG_EXECUTION_ERROR - Failed to create execution log
  • STRATEGY_CLOSE_EXECUTION_ERROR - Failed to close/update execution
  • STRATEGY_FETCH_LOGS_ERROR - Failed to retrieve logs
  • STRATEGY_CALCULATE_METRICS_ERROR - Failed to calculate metrics
  • STRATEGY_CACHE_METRICS_ERROR - Failed to cache metrics
  • STRATEGY_GET_CACHED_METRICS_ERROR - Failed to read cached metrics

Future Enhancements

  1. Advanced Charting: Chart P&L over time using Recharts
  2. Strategy Comparison: Compare metrics across multiple strategies
  3. Benchmark Comparison: Compare against market baseline
  4. Export Metrics: Download execution history as CSV
  5. Webhook Integration: Send metrics to external analytics
  6. Notifications: Alert on milestone metrics (e.g., 90% win rate)
  7. A/B Testing: Compare performance of strategy variations
  8. Time Range Filtering: View metrics for specific date ranges

Files Changed

  • src/types/portfolio.ts - Added StrategyExecutionLog, StrategyPerformanceMetrics types
  • src/services/strategyMetricsService.ts - New metrics service (300+ lines)
  • src/services/strategyService.ts - Added execution logging hooks
  • src/components/automate/StrategyMetricsCard.tsx - Metrics display (150 lines)
  • src/components/automate/ExecutionLogsViewer.tsx - Execution history viewer (230 lines)
  • src/components/automate/StrategyList.tsx - Integrated metrics & logs into cards

Testing Checklist

  • Create a test strategy (market-specific or portfolio-level)
  • Manually log an execution with logStrategyExecution()
  • Verify execution appears in ExecutionLogsViewer table
  • Close the execution with closeStrategyExecution() and add P&L
  • Verify metrics appear in StrategyMetricsCard
  • Check win rate calculation (should show 100% for 1 profitable trade)
  • Check P&L and ROI display correctness
  • Test with multiple executions to verify aggregation
  • Test error handling (try invalid strategyId, etc.)
  • Mobile responsiveness of ExecutionLogsViewer sheet

Integration Points

To fully activate this system, you’ll need to:
  1. In the execution engine (when strategy triggers):
    await logStrategyExecution(userId, strategyId, executionData);
    
  2. In the settlement/close flow (when position is closed):
    const pnl = exitPrice - entryPrice;
    const roi = (pnl / entryPrice) * 100;
    await closeStrategyExecution(userId, strategyId, executionId, pnl, roi);
    
  3. Optional: Cache metrics periodically (Cloud Function):
    // Run every 5 minutes to keep UI fast
    await strategyMetricsService.cacheMetrics(userId, strategyId);
    
This ensures real-time tracking while maintaining performant reads from cache.