Overview
Deriverse provides a comprehensive set of calculation utilities for analyzing trading performance. These functions are distributed across multiple files:
- tradeFilters.ts: Date filtering, win rate, PnL calculations
- mockData.ts: Session performance, fee breakdowns, leverage analytics
- drawdownCalculations.ts: Drawdown analysis and risk metrics
For detailed calculation logic and interpretation guidelines, see Calculation Logic Reference.
Date & Filtering Utilities
filterTradesByDate
Filter trades by predefined date ranges.
function filterTradesByDate(
trades: Trade[],
filter: FilterType
): Trade[]
Array of trades to filter
Time period: 'All', 'Today', 'Yesterday', 'This Week' (last 7 days), 'This Month' (last 30 days), or 'This Year' (last 365 days)
Returns: Filtered array of trades within the specified date range.
Usage:
import { filterTradesByDate } from './tradeFilters';
const weekTrades = filterTradesByDate(allTrades, 'This Week');
const todayTrades = filterTradesByDate(allTrades, 'Today');
getPreviousPeriodTrades
Get trades from the previous period for comparison.
function getPreviousPeriodTrades(
trades: Trade[],
filter: FilterType
): Trade[]
Returns: Trades from the equivalent previous period (e.g., if filter is 'This Week', returns trades from 7-14 days ago).
calculateWinRate
Calculate win rate statistics.
function calculateWinRate(trades: Trade[]): {
winRate: string;
wins: number;
losses: number;
}
Array of trades to analyze
Returns:
winRate: Percentage as string with 1 decimal (e.g., "65.5")
wins: Count of winning trades
losses: Count of losing trades
Interpretation: Higher win rate (>50%) indicates consistency. Low win rate with high avg win can still be profitable. See Calculation Logic for behavioral signals.
Usage:
const { winRate, wins, losses } = calculateWinRate(trades);
console.log(`Win Rate: ${winRate}% (${wins}W / ${losses}L)`);
calculateAvgWin
Calculate average profit per winning trade.
function calculateAvgWin(trades: Trade[]): number
Returns: Average PnL of winning trades, or 0 if no wins.
Usage:
const avgWin = calculateAvgWin(trades);
console.log(`Average Win: $${avgWin.toFixed(2)}`);
calculateAvgLoss
Calculate average loss per losing trade.
function calculateAvgLoss(trades: Trade[]): number
Returns: Average PnL of losing trades (negative number), or 0 if no losses.
Interpretation: Compare with calculateAvgWin to assess risk/reward balance. Large average loss vs. average win suggests poor risk control.
calculateTotalPnL
Sum total profit and loss across all trades.
function calculateTotalPnL(trades: Trade[]): number
Returns: Net PnL (positive for profit, negative for loss).
calculateAvgPnL
Calculate average PnL per trade.
function calculateAvgPnL(trades: Trade[]): number
Returns: Mean PnL across all trades, or 0 if no trades.
calculatePercentChange
Calculate percentage change between two values.
function calculatePercentChange(
current: number,
previous: number
): string
Returns: Formatted percentage with sign (e.g., "+15.3%", "-8.7%"). Returns "+100.0%" or "-100.0%" when previous is 0.
Usage:
const currentPnL = calculateTotalPnL(currentTrades);
const previousPnL = calculateTotalPnL(previousTrades);
const change = calculatePercentChange(currentPnL, previousPnL);
Volume & Trading Metrics
calculateTradingVolume
Calculate total trading volume (sum of notional values).
function calculateTradingVolume(trades: Trade[]): number
Returns: Total notional value traded.
Interpretation: Measures capital throughput. Spikes may indicate overtrading. See Calculation Logic.
Format large numbers with K/M abbreviations for display.
function formatCompactNumber(value: number): string
Returns: Formatted string (e.g., "$1.23K", "$1.23M", "$123.45").
Usage:
const volume = calculateTradingVolume(trades);
console.log(`Volume: ${formatCompactNumber(volume)}`);
// Output: "Volume: $1.23M"
Directional Analysis
calculateLongShortRatio
Calculate long/short ratio from perpetual trades.
function calculateLongShortRatio(trades: Trade[]): {
longPercent: number;
shortPercent: number;
longCount: number;
shortCount: number;
}
Array of trades (only perpetual trades with side: 'long' | 'short' are counted)
Returns:
longPercent: Percentage of long positions (0-100)
shortPercent: Percentage of short positions (0-100)
longCount: Number of long trades
shortCount: Number of short trades
Interpretation: Heavy bias (>70% one direction) indicates directional risk concentration. See Scoring Signals.
Journaling & Streaks
calculateJournalStreak
Calculate 21-day journaling streak.
function calculateJournalStreak(
trades: Trade[],
annotations: Record<string, any>
): boolean[]
annotations
Record<string, any>
required
Map of trade IDs to annotation objects
Returns: Array of 21 booleans, where true means that day had at least one annotated trade. Index 0 is today, index 20 is 20 days ago.
Interpretation: Measures journaling consistency. Sparse streaks indicate inconsistent review habits.
Usage:
const streak = calculateJournalStreak(trades, annotationsMap);
const currentStreak = streak.findIndex(day => !day); // Days until first gap
Session & Time Analysis
calculateDailyPnL
Aggregate trades into daily PnL buckets.
function calculateDailyPnL(trades: Trade[]): DailyPnL[]
Returns: Array of DailyPnL objects sorted by date.
Analyze performance by session (morning, afternoon, evening, night).
function calculateSessionPerformance(trades: Trade[]): SessionBucket[]
Returns: Array of 4 SessionBucket objects:
- Morning: 6:00 AM - 12:00 PM
- Afternoon: 12:00 PM - 6:00 PM
- Evening: 6:00 PM - 10:00 PM
- Night: 10:00 PM - 6:00 AM
Usage:
const sessions = calculateSessionPerformance(trades);
const bestSession = sessions.reduce((best, curr) =>
curr.pnl > best.pnl ? curr : best
);
console.log(`Best session: ${bestSession.session}`);
Analyze hourly trading performance.
function calculateTimeOfDayPerformance(trades: Trade[]): TimeOfDayBucket[]
Returns: Array of 24 TimeOfDayBucket objects (one per hour, 0-23).
Fee Analytics
calculateFeeBreakdown
Calculate fee composition by type.
function calculateFeeBreakdown(trades: Trade[]): FeeComposition[]
Returns: Array of FeeComposition objects showing protocol maker fees, protocol taker fees, and network fees.
Interpretation: High taker/network share indicates costly execution. Track to reduce slippage and fees.
Leverage Analysis
calculateAverageLeverage
Calculate average leverage used across perpetual trades.
function calculateAverageLeverage(trades: Trade[]): number
Array of trades (only those with leverage field are counted)
Returns: Average leverage, or 1 if no leveraged trades.
Interpretation: Higher average leverage signals elevated risk appetite.
calculateLeverageVsWinRate
Analyze win rate by leverage bucket.
function calculateLeverageVsWinRate(trades: Trade[]): Array<{
leverage: number;
winRate: number;
trades: number;
}>
Returns: Array of leverage buckets with their respective win rates and trade counts, sorted by leverage.
Interpretation: Detects whether performance degrades at higher leverage. If >80% of trades use ≥10x leverage, flag as “greed-prone” risk concentration.
Usage:
const leverageAnalysis = calculateLeverageVsWinRate(trades);
leverageAnalysis.forEach(bucket => {
console.log(
`${bucket.leverage}x: ${(bucket.winRate * 100).toFixed(1)}% win rate ` +
`(${bucket.trades} trades)`
);
});
Drawdown Calculations
calculateDrawdownSeries
Calculate drawdown metrics from daily PnL data.
function calculateDrawdownSeries(dailyPnL: {date: string, pnl: number}[]): {
drawdowns: DrawdownPoint[];
maxDrawdown: number;
peakToTroughPoints: Array<{
peak: {date: string, value: number};
trough: {date: string, value: number};
}>;
}
dailyPnL
{date: string, pnl: number}[]
required
Array of daily PnL data points
Returns:
drawdowns: Array of drawdown data points with equity peaks and troughs
maxDrawdown: Maximum drawdown amount (absolute value)
peakToTroughPoints: Array of peak-to-trough drawdown periods
Usage:
import { calculateDailyPnL } from './mockData';
import { calculateDrawdownSeries } from './drawdownCalculations';
const dailyPnL = calculateDailyPnL(trades);
const { maxDrawdown, peakToTroughPoints } = calculateDrawdownSeries(dailyPnL);
console.log(`Max Drawdown: $${maxDrawdown.toFixed(2)}`);
calculateDrawdownStats
Calculate comprehensive drawdown statistics.
function calculateDrawdownStats(trades: Trade[]): DrawdownStats
Returns: DrawdownStats object containing:
maxDrawdown: Maximum drawdown amount
maxDrawdownPercentage: Maximum drawdown as percentage of peak equity
avgRecoveryDays: Average days to recover from drawdowns
pnlToDrawdownRatio: Ratio of total PnL to max drawdown (higher is better)
recoveryPeriods: Array of drawdown recovery periods with start/end dates and duration
Usage:
const stats = calculateDrawdownStats(trades);
console.log(`Max Drawdown: ${stats.maxDrawdownPercentage.toFixed(1)}%`);
console.log(`Avg Recovery: ${stats.avgRecoveryDays.toFixed(1)} days`);
console.log(`PnL/Drawdown Ratio: ${stats.pnlToDrawdownRatio.toFixed(2)}`);
calculateProfitToDrawdownRatio
Calculate profit-to-drawdown ratio.
function calculateProfitToDrawdownRatio(
totalPnL: number,
maxDrawdown: number
): number
Returns: Ratio of profit to drawdown. Higher values indicate better risk-adjusted returns. Returns 0 if maxDrawdown is 0.
Mock Data Generation
generateMockTrades
Generate realistic mock trading data for development and demos.
function generateMockTrades(): Trade[]
Returns: Array of 250 mock trades with deterministic seeded generation, spanning 180 days of history with guaranteed recent trades for streak functionality.
Features:
- Realistic price ranges per token
- 60% win rate
- Mix of spot and perpetual trades
- Fee breakdowns (maker/taker)
- Leverage distribution (1x-10x)
- Proper liquidation prices for perpetuals
Complete Example
import { Trade } from './types';
import {
filterTradesByDate,
calculateWinRate,
calculateAvgWin,
calculateAvgLoss,
calculateTradingVolume,
calculateLongShortRatio,
formatCompactNumber
} from './tradeFilters';
import { calculateDrawdownStats } from './drawdownCalculations';
// Filter trades for this month
const monthTrades = filterTradesByDate(allTrades, 'This Month');
// Calculate performance metrics
const { winRate, wins, losses } = calculateWinRate(monthTrades);
const avgWin = calculateAvgWin(monthTrades);
const avgLoss = calculateAvgLoss(monthTrades);
const volume = calculateTradingVolume(monthTrades);
const { longPercent, shortPercent } = calculateLongShortRatio(monthTrades);
// Risk metrics
const drawdownStats = calculateDrawdownStats(monthTrades);
// Display summary
console.log(`
📊 Monthly Performance Summary
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Win Rate: ${winRate}% (${wins}W / ${losses}L)
Avg Win: $${avgWin.toFixed(2)}
Avg Loss: $${avgLoss.toFixed(2)}
Volume: ${formatCompactNumber(volume)}
Direction: ${longPercent}% Long / ${shortPercent}% Short
⚠️ Risk Metrics
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Max Drawdown: ${drawdownStats.maxDrawdownPercentage.toFixed(1)}%
Avg Recovery: ${drawdownStats.avgRecoveryDays.toFixed(1)} days
PnL/DD Ratio: ${drawdownStats.pnlToDrawdownRatio.toFixed(2)}
`);