stock-bot/apps/stock/orchestrator/test-equity-curve-spike.ts
2025-07-03 18:49:48 -04:00

95 lines
No EOL
3.3 KiB
TypeScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { createContainer } from './src/simple-container';
import { BacktestEngine } from './src/backtest/BacktestEngine';
import { StrategyManager } from './src/strategies/StrategyManager';
import { StorageService } from './src/services/StorageService';
async function testEquityCurveSpikeFixture() {
console.log('Testing equity curve spike fix...\n');
// Create minimal container
const container = await createContainer({
database: {
mongodb: { enabled: false, uri: '' },
postgres: { enabled: false, uri: '' },
questdb: { enabled: false, host: '', port: 0 }
}
});
// Create services
const storageService = new StorageService(container);
const strategyManager = new StrategyManager(container);
// Create backtest engine
const backtestEngine = new BacktestEngine(container, storageService, strategyManager);
// Run a quick backtest
const config = {
mode: 'backtest',
name: 'Equity Curve Spike Test',
strategy: 'sma-crossover',
symbols: ['AAPL'],
startDate: '2023-01-01T00:00:00Z',
endDate: '2023-01-31T00:00:00Z', // Just one month
initialCapital: 100000,
commission: 0.001,
slippage: 0.0001,
dataFrequency: '1d',
speed: 'max'
};
console.log('Running backtest...');
const result = await backtestEngine.runBacktest(config);
// Check the equity curve
console.log('\n=== Equity Curve Analysis ===');
console.log(`Initial Capital: $${config.initialCapital}`);
console.log(`Total equity points: ${result.equity.length}`);
if (result.equity.length > 0) {
// Check first few points
console.log('\nFirst 5 equity curve points:');
result.equity.slice(0, 5).forEach((point, index) => {
console.log(`${index + 1}. ${point.date}: $${point.value.toFixed(2)}`);
});
// Check for spike
const firstValue = result.equity[0].value;
const secondValue = result.equity.length > 1 ? result.equity[1].value : firstValue;
console.log(`\nFirst equity value: $${firstValue.toFixed(2)}`);
console.log(`Second equity value: $${secondValue.toFixed(2)}`);
// Check if there's a spike from 0 to initial capital
if (firstValue === 0 || firstValue < config.initialCapital * 0.5) {
console.log('\n❌ SPIKE DETECTED: First equity value is too low!');
} else if (Math.abs(firstValue - config.initialCapital) < 1) {
console.log('\n✅ NO SPIKE: First equity value correctly starts at initial capital!');
} else {
console.log(`\n⚠ First equity value differs from initial capital by $${Math.abs(firstValue - config.initialCapital).toFixed(2)}`);
}
// Check for duplicate timestamps
const timestamps = new Set();
let duplicates = 0;
result.equity.forEach(point => {
if (timestamps.has(point.date)) {
duplicates++;
}
timestamps.add(point.date);
});
if (duplicates > 0) {
console.log(`\n⚠ Found ${duplicates} duplicate timestamps in equity curve`);
} else {
console.log('\n✅ No duplicate timestamps found');
}
}
console.log('\n=== Test Complete ===');
process.exit(0);
}
testEquityCurveSpikeFixture().catch(error => {
console.error('Test failed:', error);
process.exit(1);
});