import { describe, expect, it } from 'vitest' import { aggregateStatus } from './aggregate' const SINGLE = { equity: 100, total_pnl: 5, strategies: [] } function strategy(overrides = {}) { return { strategy_key: 'sma_cross', symbol: 'BTC/USDT', timeframe: '5m', allocation: 0.5, cash: 1000, equity: 1000, realized_pnl: 0, unrealized_pnl: 0, total_pnl: 0, open_positions: 0, halted: false, halt_reason: null, trades_today: 0, day_pnl: 0, drawdown_pct: 0, ...overrides, } } describe('aggregateStatus', () => { it('returns the plain status when there is at most one strategy', () => { expect(aggregateStatus(SINGLE, { strategies: [] })).toBe(SINGLE) expect(aggregateStatus(SINGLE, { strategies: [strategy()] })).toBe(SINGLE) }) it('sums the per-strategy numbers', () => { const multi = { running: true, equity: 2100, starting_balance: 2000, total_pnl: 100, price: 123, strategies: [ strategy({ cash: 1000, equity: 1100, realized_pnl: 100, unrealized_pnl: 0, total_pnl: 100, trades_today: 2, open_positions: 1, day_pnl: 40 }), strategy({ cash: 1000, equity: 1000, realized_pnl: 0, unrealized_pnl: 0, total_pnl: 0, trades_today: 0, open_positions: 0, day_pnl: -10 }), ], } const result = aggregateStatus(SINGLE, multi) expect(result.cash).toBe(2000) expect(result.equity).toBe(2100) expect(result.realized_pnl).toBe(100) expect(result.total_pnl).toBe(100) expect(result.day_pnl).toBe(30) expect(result.trades_today).toBe(2) expect(result.open_positions).toBe(1) expect(result.price).toBe(123) expect(result.running).toBe(true) }) it('reports the worst drawdown and any halt', () => { const multi = { running: true, equity: 2000, starting_balance: 2000, total_pnl: 0, price: null, strategies: [ strategy({ drawdown_pct: 3, halted: false }), strategy({ drawdown_pct: 7.5, halted: true, halt_reason: 'daily loss limit hit' }), ], } const result = aggregateStatus(SINGLE, multi) expect(result.drawdown_pct).toBe(7.5) expect(result.halted).toBe(true) expect(result.halt_reason).toBe('daily loss limit hit') }) it('falls back to the plain price when multi has none', () => { const multi = { running: false, equity: 2000, starting_balance: 2000, total_pnl: 0, price: null, strategies: [strategy(), strategy()], } const result = aggregateStatus({ ...SINGLE, price: 99 }, multi) expect(result.price).toBe(99) }) })