122 lines
No EOL
3.8 KiB
TypeScript
Executable file
122 lines
No EOL
3.8 KiB
TypeScript
Executable file
#!/usr/bin/env bun
|
|
|
|
/**
|
|
* Test order flow through the full backtest system
|
|
*/
|
|
|
|
import { BacktestEngine } from './src/backtest/BacktestEngine';
|
|
import { StrategyManager } from './src/strategies/StrategyManager';
|
|
import { StorageService } from './src/services/StorageService';
|
|
import { getLogger } from '@stock-bot/logger';
|
|
import { SimpleMovingAverageCrossover } from './src/strategies/examples/SimpleMovingAverageCrossover';
|
|
|
|
async function testOrderFlow() {
|
|
console.log('Testing order flow in backtest...\n');
|
|
|
|
// Create minimal container
|
|
const logger = getLogger('test');
|
|
const container = {
|
|
logger,
|
|
custom: {}
|
|
};
|
|
|
|
// Create services
|
|
const storageService = new StorageService(container as any);
|
|
const strategyManager = new StrategyManager(container as any);
|
|
|
|
// First test the strategy directly
|
|
console.log('=== Testing Strategy Directly ===');
|
|
const testStrategy = new SimpleMovingAverageCrossover({
|
|
id: 'test-direct',
|
|
name: 'Direct Test',
|
|
enabled: true,
|
|
symbols: ['AAPL'],
|
|
allocation: 1.0
|
|
}, null, null);
|
|
|
|
let directSignals = 0;
|
|
let directOrders = 0;
|
|
|
|
testStrategy.on('signal', (signal) => {
|
|
directSignals++;
|
|
console.log(`Direct signal #${directSignals}:`, signal);
|
|
});
|
|
|
|
testStrategy.on('order', (order) => {
|
|
directOrders++;
|
|
console.log(`Direct order #${directOrders}:`, order);
|
|
});
|
|
|
|
await testStrategy.start();
|
|
|
|
// Generate test data with clear crossover
|
|
for (let i = 0; i < 30; i++) {
|
|
const basePrice = 100;
|
|
const price = i < 15 ? basePrice - i * 0.5 : basePrice + (i - 15) * 0.5;
|
|
|
|
await testStrategy.onMarketData({
|
|
type: 'bar',
|
|
data: {
|
|
symbol: 'AAPL',
|
|
open: price,
|
|
high: price + 1,
|
|
low: price - 1,
|
|
close: price,
|
|
volume: 1000000,
|
|
timestamp: Date.now() + i * 86400000
|
|
}
|
|
});
|
|
}
|
|
|
|
await testStrategy.stop();
|
|
console.log(`\nDirect test: ${directSignals} signals, ${directOrders} orders\n`);
|
|
|
|
// Now test through backtest engine
|
|
console.log('=== Testing Through Backtest Engine ===');
|
|
|
|
// Create backtest engine (it will initialize strategies)
|
|
const backtestEngine = new BacktestEngine(container as any, storageService, strategyManager);
|
|
|
|
// Hook into backtest engine to see what's happening
|
|
const origProcessMarketData = (backtestEngine as any).processMarketData;
|
|
(backtestEngine as any).processMarketData = async function(data: any) {
|
|
console.log(`Processing market data: ${data.data.symbol} @ ${data.data.close}`);
|
|
return origProcessMarketData.call(this, data);
|
|
};
|
|
|
|
const origCheckAndFillOrders = (backtestEngine as any).checkAndFillOrders;
|
|
(backtestEngine as any).checkAndFillOrders = async function(data: any) {
|
|
const pendingCount = this.pendingOrders.size;
|
|
if (pendingCount > 0) {
|
|
console.log(`Checking ${pendingCount} pending orders...`);
|
|
}
|
|
return origCheckAndFillOrders.call(this, data);
|
|
};
|
|
|
|
const config = {
|
|
mode: 'backtest',
|
|
name: 'Order Flow Test',
|
|
strategy: 'sma-crossover',
|
|
symbols: ['AAPL'],
|
|
startDate: '2023-01-01T00:00:00Z',
|
|
endDate: '2023-02-01T00:00:00Z', // Just 1 month
|
|
initialCapital: 100000,
|
|
dataFrequency: '1d',
|
|
commission: 0.001,
|
|
slippage: 0.0001
|
|
};
|
|
|
|
try {
|
|
const result = await backtestEngine.runBacktest(config);
|
|
|
|
console.log('\nBacktest Results:');
|
|
console.log(`Total Return: ${result.metrics.totalReturn.toFixed(2)}%`);
|
|
console.log(`Total Trades: ${result.metrics.totalTrades}`);
|
|
console.log(`Trades in history: ${result.trades.length}`);
|
|
|
|
} catch (error) {
|
|
console.error('Backtest failed:', error);
|
|
}
|
|
}
|
|
|
|
testOrderFlow().catch(console.error); |