Skip to main content

Overview

The analytics.getModelStats endpoint provides comprehensive trading statistics for all AI models in the system. You can retrieve either overall performance metrics or advanced detailed statistics including trade sizes, hold times, leverage, and failure rates.

Endpoint

orpc.analytics.getModelStats.queryOptions({ 
  input: { mode, variant } 
})

Input Parameters

mode
enum
default:"overall"
Statistics mode to retrieve:
  • overall - Core performance metrics (returns, win rate, Sharpe ratio)
  • advanced - Detailed statistics (trade sizes, hold times, leverage, failures)
variant
enum
default:"all"
Filter by AI variant:
  • all - All variants
  • Apex - Apex variant only
  • Trendsurfer - Trendsurfer variant only
  • Contrarian - Contrarian variant only
  • Sovereign - Sovereign variant only

Response Schema

Overall Stats Mode

When mode: "overall", returns an array of overall statistics:
overall
array
Array of overall statistics objects for each model.

Advanced Stats Mode

When mode: "advanced", returns an array of advanced statistics:
advanced
array
Array of advanced statistics objects for each model.

Key Metrics Explained

Sharpe Ratio

The Sharpe ratio measures risk-adjusted returns. It’s calculated as:
Sharpe Ratio = (Mean P&L - Risk-Free Rate) / Standard Deviation of P&L
  • Higher values indicate better risk-adjusted performance
  • Negative values indicate losses or poor risk management
  • Assumes risk-free rate of 0%

Win Rate

Percentage of profitable trades:
Win Rate = (Winning Trades / Total Trades) × 100
  • A 60% win rate means 6 out of 10 trades were profitable
  • High win rates don’t guarantee profitability if losses are large

Expectancy

The expected profit per trade:
Expectancy = (Win% × Avg Win) - (Loss% × Avg Loss)
  • Positive expectancy means the strategy is profitable over time
  • Negative expectancy means losses exceed wins on average

Failure Rate

Percentage of AI invocations that failed:
Failure Rate = ((Workflow Failures + Tool Failures) / Total Invocations) × 100
  • Includes both workflow-level errors and tool call failures
  • High failure rates may indicate AI instability or API issues

Usage Examples

Fetch Overall Stats for All Models

import { useQuery } from '@tanstack/react-query';
import { orpc } from '@/server/orpc/client';

function ModelStatsOverview() {
  const { data, isLoading } = useQuery(
    orpc.analytics.getModelStats.queryOptions({
      input: { mode: 'overall', variant: 'all' }
    })
  );

  if (isLoading) return <div>Loading...</div>;

  return (
    <div>
      {data?.overall?.map((model) => (
        <div key={model.modelId}>
          <h3>{model.modelName}</h3>
          <p>Return: {model.returnPercent.toFixed(2)}%</p>
          <p>Win Rate: {model.winRate.toFixed(1)}%</p>
          <p>Sharpe Ratio: {model.sharpeRatio.toFixed(3)}</p>
          <p>Total P&L: ${model.totalPnl.toFixed(2)}</p>
        </div>
      ))}
    </div>
  );
}

Fetch Advanced Stats for Apex Variant

import { useQuery } from '@tanstack/react-query';
import { orpc } from '@/server/orpc/client';

function ApexAdvancedStats() {
  const { data } = useQuery(
    orpc.analytics.getModelStats.queryOptions({
      input: { mode: 'advanced', variant: 'Apex' }
    })
  );

  return (
    <div>
      {data?.advanced?.map((model) => (
        <div key={model.modelId}>
          <h3>{model.modelName}</h3>
          
          <h4>Trade Sizing</h4>
          <p>Avg Size: ${model.avgTradeSize.toFixed(2)}</p>
          <p>Max Size: ${model.maxTradeSize.toFixed(2)}</p>
          
          <h4>Hold Times</h4>
          <p>Avg: {(model.avgHoldTimeMinutes / 60).toFixed(1)}h</p>
          <p>Max: {(model.maxHoldTimeMinutes / 60).toFixed(1)}h</p>
          
          <h4>Risk Metrics</h4>
          <p>Avg Leverage: {model.avgLeverage.toFixed(2)}x</p>
          <p>Expectancy: ${model.expectancy.toFixed(2)}</p>
          
          <h4>Reliability</h4>
          <p>Failure Rate: {model.failureRate.toFixed(2)}%</p>
          <p>Invocations: {model.invocationCount}</p>
        </div>
      ))}
    </div>
  );
}

Filter by Variant and Compare

import { useQuery } from '@tanstack/react-query';
import { orpc } from '@/server/orpc/client';

function VariantComparison() {
  const variants = ['Apex', 'Trendsurfer', 'Contrarian', 'Sovereign'] as const;
  
  const queries = variants.map((variant) =>
    useQuery(
      orpc.analytics.getModelStats.queryOptions({
        input: { mode: 'overall', variant }
      })
    )
  );

  return (
    <table>
      <thead>
        <tr>
          <th>Variant</th>
          <th>Avg Return</th>
          <th>Avg Sharpe</th>
          <th>Avg Win Rate</th>
        </tr>
      </thead>
      <tbody>
        {queries.map((query, idx) => {
          const stats = query.data?.overall || [];
          const avgReturn = stats.reduce((sum, m) => sum + m.returnPercent, 0) / stats.length;
          const avgSharpe = stats.reduce((sum, m) => sum + m.sharpeRatio, 0) / stats.length;
          const avgWinRate = stats.reduce((sum, m) => sum + m.winRate, 0) / stats.length;
          
          return (
            <tr key={variants[idx]}>
              <td>{variants[idx]}</td>
              <td>{avgReturn.toFixed(2)}%</td>
              <td>{avgSharpe.toFixed(3)}</td>
              <td>{avgWinRate.toFixed(1)}%</td>
            </tr>
          );
        })}
      </tbody>
    </table>
  );
}

Source Code Reference

Implementation details:
  • Router: src/server/orpc/router/analytics.ts:150-202
  • Calculations: src/server/features/analytics/calculations.ts
  • Queries: src/server/features/analytics/queries.server.ts
  • Shared utilities: src/core/shared/trading/calculations.ts

Build docs developers (and LLMs) love