fix: Correct SQL column names and add navigation links
- Fixed tp1Hit/tp2Hit -> tp1Filled/tp2Filled in Runner Performance query - Fixed atr -> atrAtEntry in ATR vs MFE Correlation and Data Collection queries - Added Analytics card to homepage with link to /analytics/optimization - Added Home button to optimization page header - All 7 analyses now working without SQL errors
This commit is contained in:
@@ -39,10 +39,20 @@ export default function OptimizationPage() {
|
||||
<div className="max-w-7xl mx-auto">
|
||||
{/* Header */}
|
||||
<div className="mb-8">
|
||||
<h1 className="text-4xl font-bold mb-2">🔬 Optimization Analytics Dashboard</h1>
|
||||
<p className="text-slate-400">
|
||||
Data-driven analysis for trading system improvements based on roadmaps and SQL queries
|
||||
</p>
|
||||
<div className="flex items-center justify-between">
|
||||
<div>
|
||||
<h1 className="text-4xl font-bold mb-2">🔬 Optimization Analytics Dashboard</h1>
|
||||
<p className="text-slate-400">
|
||||
Data-driven analysis for trading system improvements based on roadmaps and SQL queries
|
||||
</p>
|
||||
</div>
|
||||
<a
|
||||
href="/"
|
||||
className="px-4 py-2 bg-slate-700 hover:bg-slate-600 rounded-lg transition-colors flex items-center gap-2"
|
||||
>
|
||||
← Home
|
||||
</a>
|
||||
</div>
|
||||
{lastRefresh && (
|
||||
<p className="text-sm text-slate-500 mt-2">
|
||||
Last refresh: {lastRefresh.toLocaleTimeString()}
|
||||
|
||||
@@ -190,10 +190,10 @@ export async function GET() {
|
||||
const runnerPerformance = await prisma.$queryRaw<any[]>`
|
||||
SELECT
|
||||
COUNT(*) as total_trades,
|
||||
SUM(CASE WHEN "tp1Hit" = true THEN 1 ELSE 0 END) as tp1_hits,
|
||||
SUM(CASE WHEN "tp2Hit" = true THEN 1 ELSE 0 END) as tp2_hits,
|
||||
ROUND(100.0 * SUM(CASE WHEN "tp1Hit" = true THEN 1 ELSE 0 END) / COUNT(*)::numeric, 1) as tp1_rate,
|
||||
ROUND(100.0 * SUM(CASE WHEN "tp2Hit" = true THEN 1 ELSE 0 END) / COUNT(*)::numeric, 1) as tp2_rate,
|
||||
SUM(CASE WHEN "tp1Filled" = true THEN 1 ELSE 0 END) as tp1_hits,
|
||||
SUM(CASE WHEN "tp2Filled" = true THEN 1 ELSE 0 END) as tp2_hits,
|
||||
ROUND(100.0 * SUM(CASE WHEN "tp1Filled" = true THEN 1 ELSE 0 END) / COUNT(*)::numeric, 1) as tp1_rate,
|
||||
ROUND(100.0 * SUM(CASE WHEN "tp2Filled" = true THEN 1 ELSE 0 END) / COUNT(*)::numeric, 1) as tp2_rate,
|
||||
ROUND(AVG("maxFavorableExcursion")::numeric, 2) as avg_mfe,
|
||||
ROUND(AVG("maxAdverseExcursion")::numeric, 2) as avg_mae
|
||||
FROM "Trade"
|
||||
@@ -244,9 +244,9 @@ export async function GET() {
|
||||
const atrCorrelation = await prisma.$queryRaw<any[]>`
|
||||
SELECT
|
||||
CASE
|
||||
WHEN atr < 0.3 THEN '<0.3 (Low Vol)'
|
||||
WHEN atr < 0.5 THEN '0.3-0.5 (Med Vol)'
|
||||
WHEN atr < 0.7 THEN '0.5-0.7 (High Vol)'
|
||||
WHEN "atrAtEntry" < 0.3 THEN '<0.3 (Low Vol)'
|
||||
WHEN "atrAtEntry" < 0.5 THEN '0.3-0.5 (Med Vol)'
|
||||
WHEN "atrAtEntry" < 0.7 THEN '0.5-0.7 (High Vol)'
|
||||
ELSE '0.7+ (Very High Vol)'
|
||||
END as atr_range,
|
||||
COUNT(*) as trades,
|
||||
@@ -255,9 +255,9 @@ export async function GET() {
|
||||
ROUND(100.0 * SUM(CASE WHEN "realizedPnL" > 0 THEN 1 ELSE 0 END) / COUNT(*)::numeric, 1) as win_rate
|
||||
FROM "Trade"
|
||||
WHERE "exitReason" IS NOT NULL
|
||||
AND atr IS NOT NULL
|
||||
AND "atrAtEntry" IS NOT NULL
|
||||
GROUP BY atr_range
|
||||
ORDER BY MIN(atr)
|
||||
ORDER BY MIN("atrAtEntry")
|
||||
`
|
||||
|
||||
const formattedData = atrCorrelation.map(row => ({
|
||||
@@ -356,7 +356,7 @@ export async function GET() {
|
||||
SELECT
|
||||
COUNT(*) FILTER (WHERE "exitReason" IS NOT NULL) as completed_trades,
|
||||
COUNT(*) FILTER (WHERE "signalQualityScore" IS NOT NULL) as with_quality,
|
||||
COUNT(*) FILTER (WHERE atr IS NOT NULL) as with_atr,
|
||||
COUNT(*) FILTER (WHERE "atrAtEntry" IS NOT NULL) as with_atr,
|
||||
COUNT(*) FILTER (WHERE "maxFavorableExcursion" IS NOT NULL) as with_mfe,
|
||||
COUNT(*) FILTER (WHERE "indicatorVersion" = 'v8') as v8_trades,
|
||||
(SELECT COUNT(*) FROM "BlockedSignal" WHERE "blockReason" = 'QUALITY_SCORE_TOO_LOW') as blocked_quality
|
||||
|
||||
27
app/page.tsx
27
app/page.tsx
@@ -124,6 +124,33 @@ export default function HomePage() {
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
{/* Analytics Card */}
|
||||
<a
|
||||
href="/analytics/optimization"
|
||||
className="group relative bg-gradient-to-br from-gray-800/50 to-gray-900/50 backdrop-blur-sm rounded-2xl p-8 border border-gray-700/50 hover:border-gray-600 transition-all duration-300 hover:scale-105"
|
||||
>
|
||||
<div className="absolute inset-0 bg-gradient-to-br from-blue-500/10 to-purple-700/10 rounded-2xl opacity-0 group-hover:opacity-100 transition-opacity"></div>
|
||||
|
||||
<div className="relative">
|
||||
<div className="w-16 h-16 bg-gradient-to-br from-blue-600 to-purple-800 rounded-xl flex items-center justify-center mb-6 group-hover:scale-110 transition-transform">
|
||||
<span className="text-4xl">🔬</span>
|
||||
</div>
|
||||
|
||||
<h3 className="text-2xl font-bold text-white mb-3">Analytics</h3>
|
||||
|
||||
<p className="text-gray-300 mb-6">
|
||||
Data-driven optimization analysis with automated SQL insights
|
||||
</p>
|
||||
|
||||
<div className="flex items-center text-gray-400 group-hover:text-gray-300">
|
||||
<span className="font-medium">View Analytics</span>
|
||||
<svg className="w-5 h-5 ml-2 group-hover:translate-x-1 transition-transform" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 5l7 7-7 7" />
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
{/* Quick Stats */}
|
||||
|
||||
Reference in New Issue
Block a user