188 lines
No EOL
6.5 KiB
TypeScript
188 lines
No EOL
6.5 KiB
TypeScript
import { BacktestEngine } from '../src/backtest/BacktestEngine';
|
|
import { StrategyManager } from '../src/strategies/StrategyManager';
|
|
import { StorageService } from '../src/services/StorageService';
|
|
import { ModeManager } from '../src/core/ModeManager';
|
|
import { MarketDataService } from '../src/services/MarketDataService';
|
|
import { ExecutionService } from '../src/services/ExecutionService';
|
|
import { IServiceContainer } from '@stock-bot/di';
|
|
|
|
async function traceShortPositions() {
|
|
let orderCount = 0;
|
|
let fillCount = 0;
|
|
const orderTracker: any[] = [];
|
|
const fillTracker: any[] = [];
|
|
|
|
// Create service container with detailed logging
|
|
const container: IServiceContainer = {
|
|
logger: {
|
|
info: (msg: string, ...args: any[]) => {
|
|
// Log all order and fill events
|
|
if (msg.includes('order') || msg.includes('Order') ||
|
|
msg.includes('fill') || msg.includes('Fill') ||
|
|
msg.includes('position') || msg.includes('Position')) {
|
|
console.log('[INFO]', msg, ...args);
|
|
}
|
|
|
|
// Track order submissions
|
|
if (msg.includes('Submitting order')) {
|
|
orderCount++;
|
|
const orderData = args[0];
|
|
orderTracker.push({
|
|
count: orderCount,
|
|
symbol: orderData.symbol,
|
|
side: orderData.side,
|
|
quantity: orderData.quantity,
|
|
type: orderData.type
|
|
});
|
|
console.log(`\n🔵 ORDER #${orderCount}:`, orderData.side.toUpperCase(), orderData.symbol);
|
|
}
|
|
|
|
// Track fills
|
|
if (msg.includes('Order filled')) {
|
|
fillCount++;
|
|
const fillData = args[0];
|
|
fillTracker.push({
|
|
count: fillCount,
|
|
orderId: fillData.orderId,
|
|
symbol: fillData.symbol,
|
|
side: fillData.side,
|
|
price: fillData.price,
|
|
quantity: fillData.quantity
|
|
});
|
|
console.log(`\n🟢 FILL #${fillCount}:`, fillData.side.toUpperCase(), fillData.symbol, '@', fillData.price);
|
|
}
|
|
},
|
|
error: console.error,
|
|
warn: () => {},
|
|
debug: () => {},
|
|
} as any,
|
|
custom: {}
|
|
};
|
|
|
|
// Initialize services
|
|
const storageService = new StorageService();
|
|
const marketDataService = new MarketDataService(container);
|
|
const executionService = new ExecutionService(container);
|
|
const modeManager = new ModeManager(container, marketDataService, executionService, storageService);
|
|
const strategyManager = new StrategyManager(container);
|
|
|
|
container.custom = {
|
|
MarketDataService: marketDataService,
|
|
ExecutionService: executionService,
|
|
ModeManager: modeManager,
|
|
StorageService: storageService
|
|
};
|
|
|
|
// Listen to strategy events
|
|
strategyManager.on('signal', (signal: any) => {
|
|
console.log('\n🎯 STRATEGY SIGNAL:', signal);
|
|
});
|
|
|
|
// Initialize backtest mode
|
|
await modeManager.initializeMode({
|
|
mode: 'backtest',
|
|
startDate: '2023-06-01T00:00:00Z',
|
|
endDate: '2023-09-01T00:00:00Z', // 3 months
|
|
speed: 'max',
|
|
symbols: ['AAPL'],
|
|
initialCapital: 100000,
|
|
dataFrequency: '1d',
|
|
strategy: 'sma-crossover'
|
|
});
|
|
|
|
// Create backtest engine
|
|
const backtestEngine = new BacktestEngine(container, storageService, strategyManager);
|
|
|
|
// Configure backtest
|
|
const config = {
|
|
mode: 'backtest' as const,
|
|
name: 'Short Position Trace',
|
|
strategy: 'sma-crossover',
|
|
symbols: ['AAPL'],
|
|
startDate: '2023-06-01T00:00:00Z',
|
|
endDate: '2023-09-01T00:00:00Z',
|
|
initialCapital: 100000,
|
|
commission: 0.001,
|
|
slippage: 0.0001,
|
|
dataFrequency: '1d' as const,
|
|
speed: 'max' as const
|
|
};
|
|
|
|
console.log('=== TRACING SHORT POSITION FLOW ===\n');
|
|
|
|
try {
|
|
const result = await backtestEngine.runBacktest(config);
|
|
|
|
console.log('\n=== ORDER/FILL TRACKING SUMMARY ===');
|
|
console.log(`Total orders submitted: ${orderCount}`);
|
|
console.log(`Total fills executed: ${fillCount}`);
|
|
|
|
// Analyze order flow
|
|
let buyOrders = 0;
|
|
let sellOrders = 0;
|
|
orderTracker.forEach(order => {
|
|
if (order.side === 'buy') buyOrders++;
|
|
else sellOrders++;
|
|
});
|
|
|
|
console.log(`\nOrder breakdown:`);
|
|
console.log(`- BUY orders: ${buyOrders}`);
|
|
console.log(`- SELL orders: ${sellOrders}`);
|
|
|
|
// Check for short positions
|
|
console.log('\n=== LOOKING FOR SHORT PATTERNS ===');
|
|
console.log('(A short position starts with a SELL and closes with a BUY)\n');
|
|
|
|
let potentialShorts = 0;
|
|
for (let i = 0; i < orderTracker.length - 1; i++) {
|
|
if (orderTracker[i].side === 'sell') {
|
|
// Look for subsequent buy to close
|
|
for (let j = i + 1; j < orderTracker.length; j++) {
|
|
if (orderTracker[j].side === 'buy' && orderTracker[j].symbol === orderTracker[i].symbol) {
|
|
potentialShorts++;
|
|
console.log(`Potential short trade found:`);
|
|
console.log(` Open: Order #${orderTracker[i].count} (SELL)`);
|
|
console.log(` Close: Order #${orderTracker[j].count} (BUY)`);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
console.log(`\nPotential short trades identified: ${potentialShorts}`);
|
|
|
|
// Final results
|
|
console.log('\n=== BACKTEST RESULTS ===');
|
|
console.log(`Total closed trades: ${result.metrics.totalTrades}`);
|
|
|
|
let longTrades = 0;
|
|
let shortTrades = 0;
|
|
|
|
result.trades.forEach((trade, i) => {
|
|
const tradeType = trade.side === 'buy' ? 'LONG' : 'SHORT';
|
|
if (trade.side === 'buy') longTrades++;
|
|
else shortTrades++;
|
|
|
|
console.log(`\nTrade ${i + 1} (${tradeType}):`);
|
|
console.log(` Entry: ${trade.entryDate} @ $${trade.entryPrice.toFixed(2)}`);
|
|
console.log(` Exit: ${trade.exitDate} @ $${trade.exitPrice.toFixed(2)}`);
|
|
console.log(` P&L: $${trade.pnl.toFixed(2)}`);
|
|
});
|
|
|
|
console.log('\n=== FINAL SUMMARY ===');
|
|
console.log(`Long trades recorded: ${longTrades}`);
|
|
console.log(`Short trades recorded: ${shortTrades}`);
|
|
console.log(`Expected short trades (from order flow): ${potentialShorts}`);
|
|
|
|
if (shortTrades < potentialShorts) {
|
|
console.log('\n❌ ISSUE: Not all short trades were recorded in closed trades!');
|
|
console.log('This suggests the Rust core trade matching logic may have an issue.');
|
|
}
|
|
|
|
} catch (error) {
|
|
console.error('Trace failed:', error);
|
|
}
|
|
}
|
|
|
|
// Run the trace
|
|
traceShortPositions().catch(console.error); |