diff --git a/app/analytics/optimization/page.tsx b/app/analytics/optimization/page.tsx new file mode 100644 index 0000000..312b591 --- /dev/null +++ b/app/analytics/optimization/page.tsx @@ -0,0 +1,417 @@ +'use client' + +import { useEffect, useState } from 'react' +import Link from 'next/link' + +interface TPSLAnalysis { + success: boolean + analysis?: { + totalTrades: number + winningTrades: number + losingTrades: number + winRate: number + avgWin: number + avgLoss: number + profitFactor: number + + maeAnalysis: { + avgMAE: number + medianMAE: number + percentile25MAE: number + percentile75MAE: number + worstMAE: number + } + + mfeAnalysis: { + avgMFE: number + medianMFE: number + percentile25MFE: number + percentile75MFE: number + bestMFE: number + } + + currentLevels: { + tp1Percent: number + tp2Percent: number + slPercent: number + tp1HitRate: number + tp2HitRate: number + slHitRate: number + moneyLeftOnTable: number + } + + recommendations: { + optimalTP1: number + optimalTP2: number + optimalSL: number + + reasoning: { + tp1: string + tp2: string + sl: string + } + + projectedImpact: { + expectedWinRateChange: number + expectedProfitFactorChange: number + estimatedProfitImprovement: number + } + } + + tradesByOutcome: { + tp1Exits: number + tp2Exits: number + slExits: number + manualExits: number + } + } + error?: string +} + +export default function OptimizationPage() { + const [analysis, setAnalysis] = useState(null) + const [loading, setLoading] = useState(true) + const [error, setError] = useState(null) + + useEffect(() => { + fetchAnalysis() + }, []) + + const fetchAnalysis = async () => { + try { + setLoading(true) + setError(null) + + const response = await fetch('/api/analytics/tp-sl-optimization') + const data = await response.json() + + setAnalysis(data) + + if (!data.success) { + setError(data.error || 'Failed to load analysis') + } + } catch (err) { + setError('Failed to fetch analytics: ' + (err as Error).message) + } finally { + setLoading(false) + } + } + + if (loading) { + return ( +
+
+
+
+
+
+

Loading optimization analysis...

+
+
+
+
+ ) + } + + if (error || !analysis?.success) { + return ( +
+
+
+
+

⚠️ Insufficient Data

+

{error || analysis?.error}

+

+ Need at least 10 closed trades with MAE/MFE tracking data. + The next trades you take will automatically track this data. +

+ +
+
+
+ ) + } + + const data = analysis.analysis! + + return ( +
+
+ +
+ {/* Header with Refresh */} +
+
+

💡 TP/SL Optimization

+

Based on {data.totalTrades} trades with MAE/MFE data

+
+ +
+ + {/* Overview Stats */} +
+ + + + +
+ + {/* MAE/MFE Analysis */} +
+
+

+ 📈 Maximum Favorable Excursion (MFE) +

+
+ + + + +
+ +
+
+
+ +
+

+ 📉 Maximum Adverse Excursion (MAE) +

+
+ + + + +
+ +
+
+
+
+ + {/* Current Configuration Performance */} +
+

🎯 Current Configuration Performance

+ +
+ + + +
+
+ + {/* Recommendations */} +
+

💡 Optimization Recommendations

+ +
+ + + +
+ + {/* Reasoning */} +
+ + + +
+ + {/* Projected Impact */} +
+

📊 Projected Impact

+
+ = 0} + /> + = 0} + /> + = 0} + /> +
+
+
+ + {/* Action Button */} +
+

+ Ready to apply these optimized levels? Update your configuration in Settings. +

+ + ⚙️ Go to Settings + +
+
+
+ ) +} + +// Component helpers +function Header() { + return ( +
+
+
+ + + + + +
+

🎯 TP/SL Optimization

+

Data-driven recommendations for optimal exit levels

+
+
+
+
+ ) +} + +function StatCard({ title, value, valueColor = 'text-white' }: { title: string, value: string, valueColor?: string }) { + return ( +
+
{title}
+
{value}
+
+ ) +} + +function MetricRow({ label, value, valueColor = 'text-white' }: { label: string, value: string, valueColor?: string }) { + return ( +
+ {label}: + {value} +
+ ) +} + +function HitRateBar({ label, hitRate, exits, color }: { label: string, hitRate: number, exits: number, color: string }) { + return ( +
+
{label}
+
+
+
+
+
Hit Rate: {hitRate.toFixed(1)}%
+
{exits} exits
+
+
+ ) +} + +function RecommendationCard({ label, value, current, color }: { label: string, value: string, current: string, color: string }) { + return ( +
+
{label}
+
{value}
+
Current: {current}
+
+ ) +} + +function ReasoningCard({ label, text, color }: { label: string, text: string, color: string }) { + return ( +
+
{label}
+
{text}
+
+ ) +} + +function ImpactMetric({ label, value, positive }: { label: string, value: string, positive: boolean }) { + return ( +
+
{label}
+
+ {positive ? '+' : ''}{value} +
+
+ ) +} diff --git a/app/analytics/page.tsx b/app/analytics/page.tsx index 22a6d17..ce88e37 100644 --- a/app/analytics/page.tsx +++ b/app/analytics/page.tsx @@ -106,18 +106,27 @@ export default function AnalyticsPage() {
{/* Time Period Selector */} -
- Period: - + 🎯 TP/SL Optimization + + +
+ Period: + +