#!/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.');