#!/usr/bin/env bun import { BacktestEngine } from './apps/stock/core/index.js'; // Test configuration const config = { name: 'Native Rust Strategies Test', symbols: ['AA', 'AAS'], startDate: '2024-01-01T00:00:00Z', endDate: '2024-01-31T00:00:00Z', initialCapital: 100000, commission: 0.001, slippage: 0.0001, dataFrequency: '1d', }; // Create the Rust engine const engine = new BacktestEngine(config); // Test different native Rust strategies console.log('Testing native Rust strategies...\n'); // 1. Test Mean Reversion Strategy console.log('1. Mean Reversion Strategy'); engine.addNativeStrategy( 'mean_reversion', 'Mean Reversion AA/AAS', 'mean-rev-1', { lookbackPeriod: 20, entryThreshold: 2.0, positionSize: 1000, } ); // Generate synthetic market data with mean-reverting characteristics const testData = []; const startDate = new Date('2024-01-01'); for (let i = 0; i < 30; i++) { const date = new Date(startDate); date.setDate(date.getDate() + i); // AA: Mean-reverting around 100 const aaMean = 100; const aaPrice = aaMean + Math.sin(i / 5) * 10 + (Math.random() - 0.5) * 5; // AAS: Mean-reverting around 50 const aasMean = 50; const aasPrice = aasMean + Math.sin(i / 5) * 5 + (Math.random() - 0.5) * 2.5; testData.push({ symbol: 'AA', timestamp: date.getTime(), type: 'bar', open: aaPrice - 0.5, high: aaPrice + 0.5, low: aaPrice - 1, close: aaPrice, volume: 1000000, vwap: aaPrice, }); testData.push({ symbol: 'AAS', timestamp: date.getTime(), type: 'bar', open: aasPrice - 0.25, high: aasPrice + 0.25, low: aasPrice - 0.5, close: aasPrice, volume: 500000, vwap: aasPrice, }); } console.log(`Loading ${testData.length} market data points...`); engine.loadMarketData(testData); // Run the backtest console.log('Running mean reversion backtest...'); try { const resultJson = engine.run(); const result = JSON.parse(resultJson); console.log('\nResults:'); console.log('Total trades:', result.trades?.length || 0); console.log('Win rate:', result.metrics.win_rate?.toFixed(2) + '%'); console.log('Profit factor:', result.metrics.profit_factor?.toFixed(2)); console.log('Total PnL:', '$' + result.metrics.total_pnl?.toFixed(2)); console.log('Final equity:', '$' + result.equity_curve[result.equity_curve.length - 1]?.[1].toFixed(2)); // Show some trades if (result.trades && result.trades.length > 0) { console.log('\nFirst few trades:'); result.trades.slice(0, 5).forEach((trade, i) => { console.log(` ${i + 1}. ${trade.symbol} ${trade.side} @ $${trade.price.toFixed(2)}`); }); } } catch (error) { console.error('Backtest failed:', error); } console.log('\n' + '='.repeat(50) + '\n'); // 2. Test Momentum Strategy console.log('2. Momentum Strategy'); // Create a new engine for momentum strategy const engine2 = new BacktestEngine(config); engine2.addNativeStrategy( 'momentum', 'Momentum Trading', 'momentum-1', { lookbackPeriod: 10, momentumThreshold: 5.0, positionSize: 1000, } ); // Generate trending market data const trendData = []; for (let i = 0; i < 30; i++) { const date = new Date(startDate); date.setDate(date.getDate() + i); // AA: Uptrend const aaPrice = 100 + i * 2 + (Math.random() - 0.5) * 2; // AAS: Downtrend then uptrend const aasPrice = i < 15 ? 50 - i * 1 + (Math.random() - 0.5) * 1 : 35 + (i - 15) * 1.5 + (Math.random() - 0.5) * 1; trendData.push({ symbol: 'AA', timestamp: date.getTime(), type: 'bar', open: aaPrice - 0.5, high: aaPrice + 0.5, low: aaPrice - 1, close: aaPrice, volume: 1000000, vwap: aaPrice, }); trendData.push({ symbol: 'AAS', timestamp: date.getTime(), type: 'bar', open: aasPrice - 0.25, high: aasPrice + 0.25, low: aasPrice - 0.5, close: aasPrice, volume: 500000, vwap: aasPrice, }); } engine2.loadMarketData(trendData); console.log('Running momentum backtest...'); try { const resultJson = engine2.run(); const result = JSON.parse(resultJson); console.log('\nResults:'); console.log('Total trades:', result.trades?.length || 0); console.log('Win rate:', result.metrics.win_rate?.toFixed(2) + '%'); console.log('Profit factor:', result.metrics.profit_factor?.toFixed(2)); console.log('Total PnL:', '$' + result.metrics.total_pnl?.toFixed(2)); console.log('Final equity:', '$' + result.equity_curve[result.equity_curve.length - 1]?.[1].toFixed(2)); } catch (error) { console.error('Backtest failed:', error); } console.log('\n' + '='.repeat(50) + '\n'); // 3. Test Pairs Trading Strategy console.log('3. Pairs Trading Strategy'); const engine3 = new BacktestEngine(config); engine3.addNativeStrategy( 'pairs_trading', 'Pairs Trading AA/AAS', 'pairs-1', { pairA: 'AA', pairB: 'AAS', lookbackPeriod: 20, entryThreshold: 2.0, positionSize: 1000, } ); // Generate correlated market data with spread deviations const pairsData = []; for (let i = 0; i < 30; i++) { const date = new Date(startDate); date.setDate(date.getDate() + i); // Base prices const basePrice = 100 + Math.sin(i / 10) * 5; // Spread oscillates around 50 const spread = 50 + Math.sin(i / 3) * 10 + (Math.random() - 0.5) * 2; const aaPrice = basePrice; const aasPrice = basePrice - spread; pairsData.push({ symbol: 'AA', timestamp: date.getTime(), type: 'bar', open: aaPrice - 0.5, high: aaPrice + 0.5, low: aaPrice - 1, close: aaPrice, volume: 1000000, vwap: aaPrice, }); pairsData.push({ symbol: 'AAS', timestamp: date.getTime(), type: 'bar', open: aasPrice - 0.25, high: aasPrice + 0.25, low: aasPrice - 0.5, close: aasPrice, volume: 500000, vwap: aasPrice, }); } engine3.loadMarketData(pairsData); console.log('Running pairs trading backtest...'); try { const resultJson = engine3.run(); const result = JSON.parse(resultJson); console.log('\nResults:'); console.log('Total trades:', result.trades?.length || 0); console.log('Win rate:', result.metrics.win_rate?.toFixed(2) + '%'); console.log('Profit factor:', result.metrics.profit_factor?.toFixed(2)); console.log('Total PnL:', '$' + result.metrics.total_pnl?.toFixed(2)); console.log('Final equity:', '$' + result.equity_curve[result.equity_curve.length - 1]?.[1].toFixed(2)); // Show paired trades if (result.trades && result.trades.length > 0) { console.log('\nPairs trades (showing pairs):'); for (let i = 0; i < result.trades.length && i < 6; i += 2) { const trade1 = result.trades[i]; const trade2 = result.trades[i + 1]; if (trade2) { console.log(` Pair ${Math.floor(i/2) + 1}: ${trade1.symbol} ${trade1.side} @ $${trade1.price.toFixed(2)}, ${trade2.symbol} ${trade2.side} @ $${trade2.price.toFixed(2)}`); } } } } catch (error) { console.error('Backtest failed:', error); } console.log('\n' + '='.repeat(50)); console.log('\nNative Rust strategies test complete!'); console.log('\nThese strategies run at microsecond speeds in Rust,'); console.log('perfect for high-frequency trading and production use.');