import { useState } from "react"; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; import { Slider } from "@/components/ui/slider"; import { Badge } from "@/components/ui/badge"; import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"; import { Play, RotateCcw, Download, Save, AlertCircle } from "lucide-react"; import { XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer, Area, AreaChart } from "recharts"; import { useToast } from "@/hooks/use-toast"; import { supabase } from "@/integrations/supabase/client"; import { z } from "zod"; // Input validation schema const backtestConfigSchema = z.object({ symbol: z.string().min(1, "Symbol is required").max(20, "Symbol too long"), startDate: z.string().refine((date) => !isNaN(Date.parse(date)), "Invalid start date"), endDate: z.string().refine((date) => !isNaN(Date.parse(date)), "Invalid end date"), initialCapital: z.number().min(10, "Minimum capital is $10").max(1000000000, "Capital too large"), tradeSize: z.number().min(0.01, "Minimum 0.01").max(1, "Maximum 1 (100%)"), stopLoss: z.number().min(0.1, "Minimum 0.1%").max(50, "Maximum 50%"), takeProfit: z.number().min(0.1, "Minimum 0.1%").max(100, "Maximum 100%"), coherenceThreshold: z.number().min(0.1, "Minimum 0.1").max(1, "Maximum 1"), kellySafety: z.number().min(0.1, "Minimum 0.1").max(1, "Maximum 1"), lighthouseConfidence: z.number().min(0.1, "Minimum 0.1").max(1, "Maximum 1"), minPrismLevel: z.number().int().min(1, "Minimum 1").max(5, "Maximum 5"), requireLHE: z.boolean(), }); type BacktestConfig = z.infer; interface BacktestResults { totalTrades: number; winRate: number; totalReturn: number; sharpeRatio: number; maxDrawdown: number; profitFactor: number; avgWin: number; avgLoss: number; equityCurve: Array<{ date: string; equity: number }>; trades: Array; } export function BacktestingInterface() { const { toast } = useToast(); const [isRunning, setIsRunning] = useState(false); const [results, setResults] = useState(null); const [errors, setErrors] = useState>({}); // Configuration state const [config, setConfig] = useState({ symbol: "BTCUSDT", startDate: "2024-01-01", endDate: "2024-11-01", initialCapital: 10000, tradeSize: 0.98, stopLoss: 2.0, takeProfit: 5.0, coherenceThreshold: 0.945, kellySafety: 0.5, lighthouseConfidence: 0.7, minPrismLevel: 3, requireLHE: true, }); const validateConfig = (): boolean => { try { backtestConfigSchema.parse(config); // Additional validation: end date must be after start date if (new Date(config.endDate) <= new Date(config.startDate)) { setErrors({ endDate: "End date must be after start date" }); return false; } setErrors({}); return true; } catch (error) { if (error instanceof z.ZodError) { const newErrors: Record = {}; error.errors.forEach((err) => { if (err.path.length > 0) { newErrors[err.path[0].toString()] = err.message; } }); setErrors(newErrors); } return false; } }; const runBacktest = async () => { if (!validateConfig()) { toast({ title: "Invalid Configuration", description: "Please check your input parameters", variant: "destructive", }); return; } setIsRunning(true); setResults(null); try { // Call edge function to run backtest const { data, error } = await supabase.functions.invoke('run-backtest', { body: { config: { symbol: config.symbol.trim(), startDate: config.startDate, endDate: config.endDate, initialCapital: config.initialCapital, tradeSize: config.tradeSize, stopLoss: config.stopLoss, takeProfit: config.takeProfit, coherenceThreshold: config.coherenceThreshold, kellySafety: config.kellySafety, lighthouseConfidence: config.lighthouseConfidence, minPrismLevel: config.minPrismLevel, requireLHE: config.requireLHE, } } }); if (error) throw error; // LIVE DATA ONLY - Use real results from edge function if (!data || !data.results) { throw new Error('LIVE_DATA_REQUIRED: Backtest edge function did not return results. No simulation allowed.'); } const realResults: BacktestResults = { totalTrades: data.results.totalTrades || 0, winRate: data.results.winRate || 0, totalReturn: data.results.totalReturn || 0, sharpeRatio: data.results.sharpeRatio || 0, maxDrawdown: data.results.maxDrawdown || 0, profitFactor: data.results.profitFactor || 0, avgWin: data.results.avgWin || 0, avgLoss: data.results.avgLoss || 0, equityCurve: data.results.equityCurve || [], trades: data.results.trades || [], }; setResults(realResults); toast({ title: "Backtest Complete", description: `Analyzed ${realResults.totalTrades} trades with ${realResults.winRate.toFixed(1)}% win rate`, }); } catch (error) { console.error('Backtest error:', error); toast({ title: "Backtest Failed", description: "An error occurred during backtesting", variant: "destructive", }); } finally { setIsRunning(false); } }; const saveResults = async () => { if (!results) return; try { const { error } = await supabase.from('backtest_results').insert({ symbol: config.symbol.trim(), start_date: config.startDate, end_date: config.endDate, initial_capital: config.initialCapital, final_capital: results.equityCurve[results.equityCurve.length - 1].equity, total_trades: results.totalTrades, winning_trades: Math.round(results.totalTrades * results.winRate / 100), losing_trades: results.totalTrades - Math.round(results.totalTrades * results.winRate / 100), win_rate: results.winRate, total_return: results.totalReturn, max_drawdown: results.maxDrawdown, sharpe_ratio: results.sharpeRatio, profit_factor: results.profitFactor, config: config, trades: results.trades, equity_curve: results.equityCurve, status: 'completed', }); if (error) throw error; toast({ title: "Results Saved", description: "Backtest results saved to database", }); } catch (error) { console.error('Save error:', error); toast({ title: "Save Failed", description: "Could not save results", variant: "destructive", }); } }; const resetConfig = () => { setConfig({ symbol: "BTCUSDT", startDate: "2024-01-01", endDate: "2024-11-01", initialCapital: 10000, tradeSize: 0.98, stopLoss: 2.0, takeProfit: 5.0, coherenceThreshold: 0.945, kellySafety: 0.5, lighthouseConfidence: 0.7, minPrismLevel: 3, requireLHE: true, }); setResults(null); setErrors({}); }; const formatCurrency = (value: number) => { return new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD', minimumFractionDigits: 0, maximumFractionDigits: 0, }).format(value); }; return (
Backtesting Interface Test strategies on historical data with custom parameters
AUREON Engine
Configuration Results {/* Basic Settings */}
{errors.symbol &&

{errors.symbol}

}
setConfig({ ...config, initialCapital: Number(e.target.value) })} min={10} max={1000000000} className="font-mono" /> {errors.initialCapital &&

{errors.initialCapital}

}
setConfig({ ...config, startDate: e.target.value })} /> {errors.startDate &&

{errors.startDate}

}
setConfig({ ...config, endDate: e.target.value })} /> {errors.endDate &&

{errors.endDate}

}
{/* Risk Parameters */}

Risk Parameters

{formatCurrency(config.initialCapital * config.tradeSize)}
setConfig({ ...config, tradeSize: value })} min={0.01} max={1} step={0.01} />
setConfig({ ...config, stopLoss: value })} min={0.1} max={50} step={0.1} />
setConfig({ ...config, takeProfit: value })} min={0.1} max={100} step={0.1} />
{/* AUREON Parameters */}

AUREON Field Parameters

{config.coherenceThreshold.toFixed(3)}
setConfig({ ...config, coherenceThreshold: value })} min={0.1} max={1} step={0.001} />
{config.kellySafety.toFixed(2)}
setConfig({ ...config, kellySafety: value })} min={0.1} max={1} step={0.05} />
{config.lighthouseConfidence.toFixed(2)}
setConfig({ ...config, lighthouseConfidence: value })} min={0.1} max={1} step={0.05} />
{config.minPrismLevel}
setConfig({ ...config, minPrismLevel: Math.round(value) })} min={1} max={5} step={1} />
setConfig({ ...config, requireLHE: e.target.checked })} className="h-4 w-4 accent-primary" />
{/* Action Buttons */}
{Object.keys(errors).length > 0 && (

Configuration Errors

Please correct the errors above

)}
{results && ( <> {/* Performance Metrics */}

Total Trades

{results.totalTrades}

Win Rate

{results.winRate.toFixed(1)}%

Total Return

{results.totalReturn.toFixed(1)}%

Sharpe Ratio

{results.sharpeRatio.toFixed(2)}

{/* Equity Curve */}

Equity Curve

`$${(value / 1000).toFixed(0)}K`} /> [`${formatCurrency(value)}`, 'Equity']} />
{/* Additional Metrics */}

Max Drawdown

-{results.maxDrawdown.toFixed(1)}%

Profit Factor

{results.profitFactor.toFixed(2)}

Avg Win

+{results.avgWin.toFixed(2)}%

Avg Loss

-{results.avgLoss.toFixed(2)}%

{/* Actions */}
)}
); }