// ========================================== // SUPABASE CREDENTIALS // ========================================== // ⚠️ DO NOT FORGET TO PASTE YOUR REAL KEYS HERE ⚠️ const SUPABASE_URL = 'https://byagcwxnzmmtluaqxvoz.supabase.co'; const SUPABASE_ANON_KEY = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6ImJ5YWdjd3huem1tdGx1YXF4dm96Iiwicm9sZSI6ImFub24iLCJpYXQiOjE3NzMzMzAyOTAsImV4cCI6MjA4ODkwNjI5MH0.RSVRkOzUqDUCPdUPfnd9_-Q9c39q0TFM7z0Rimh0VxU'; const supabaseClient = supabase.createClient(SUPABASE_URL, SUPABASE_ANON_KEY); // Helper function for Tooltips const tip = (text) => `${text}`; // ========================================== // DASHBOARD INITIALIZATION // ========================================== const nifty100 = [ "ABB", "ADANIENSOL", "ADANIENT", "ADANIGREEN", "ADANIPORTS", "AMBUJACEM", "APOLLOHOSP", "ASIANPAINT", "AWL", "AXISBANK", "BAJAJ-AUTO", "BAJAJFINSV", "BAJAJHLDNG", "BAJFINANCE", "BANKBARODA", "BEL", "BERGEPAINT", "BHEL", "BHARTIARTL", "BOSCHLTD", "BPCL", "BRITANNIA", "CANBK", "CHOLAFIN", "CIPLA", "COALINDIA", "COLPAL", "DIVISLAB", "DLF", "DRREDDY", "EICHERMOT", "GAIL", "GODREJCP", "GRASIM", "HAL", "HAVELLS", "HCLTECH", "HDFCBANK", "HDFCLIFE", "HEROMOTOCO", "HINDALCO", "HINDUNILVR", "ICICIBANK", "ICICIGI", "ICICIPRULI", "INDUSINDBK", "INFY", "IOC", "IRCTC", "IRFC", "ITC", "JINDALSTEL", "JIOFIN", "JSWSTEEL", "KOTAKBANK", "LICI", "LODHA", "LT", "LTIM", "M&M", "MANKIND", "MARICO", "MARUTI", "MAXHEALTH", "MUTHOOTFIN", "NESTLEIND", "NHPC", "NTPC", "ONGC", "PFC", "PIDILITIND", "PIIND", "PNB", "POWERGRID", "RECLTD", "RELIANCE", "SBILIFE", "SBIN", "SHREECEM", "SHRIRAMFIN", "SIEMENS", "SRF", "SUNPHARMA", "TATACOMM", "TATACONSUM", "TATAELXSI", "TATAMOTORS", "TATAPOWER", "TATASTEEL", "TCS", "TECHM", "TITAN", "TRENT", "TVSMOTOR", "ULTRACEMCO", "UNITDSPR", "VBL", "VEDL", "WIPRO", "ZOMATO" ]; window.onload = function() { const dropdown = document.getElementById("stock-cb"); nifty100.forEach(stock => { let option = document.createElement("option"); option.value = stock; option.text = stock; if (stock === "RELIANCE") option.selected = true; dropdown.appendChild(option); }); loadDashboardData(); }; // ========================================== // DATA FETCHING & UI POPULATION // ========================================== async function loadDashboardData() { const today = new Date().toISOString().split('T')[0]; // ------------------------------------------ // 1. ELITE & BTST PICKS // ------------------------------------------ try { const { data: intradayPicks, error: picksErr } = await supabaseClient .from('stock_performance_log').select('*').order('timestamp', { ascending: false }).limit(3); if (picksErr) throw picksErr; renderPicks(intradayPicks, 'intraday-picks-container', false); const { data: btstPicks, error: btstErr } = await supabaseClient .from('btst_performance_log').select('*').order('date', { ascending: false }).limit(3); if (btstErr) throw btstErr; renderPicks(btstPicks, 'btst-picks-container', true); } catch (err) { console.error("Picks DB Error:", err); } // ------------------------------------------ // 2. GAP PREDICTION // ------------------------------------------ try { const { data: gap, error: gapErr } = await supabaseClient .from('gap_performance_log').select('*').order('id', { ascending: false }).limit(1); if (gapErr) throw gapErr; const macroContainer = document.getElementById('macro-container'); if (gap && gap.length > 0 && macroContainer) { const g = gap[0]; let dateStr = 'Today'; if (g.date) { try { const parts = g.date.split('T')[0].split('-'); const d = parseInt(parts[2], 10); const months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]; const suffix = (d % 10 === 1 && d !== 11) ? 'st' : (d % 10 === 2 && d !== 12) ? 'nd' : (d % 10 === 3 && d !== 13) ? 'rd' : 'th'; dateStr = `${d}${suffix} ${months[parseInt(parts[1], 10) - 1]}'${parts[0].substring(2)}`; } catch(e) { dateStr = g.date; } } let typeColor = '#fff'; let predType = g.prediction_type ? g.prediction_type.toUpperCase() : 'NEUTRAL'; if(predType.includes('UP')) typeColor = 'var(--neon-green)'; if(predType.includes('DOWN')) typeColor = 'var(--neon-red)'; if(predType.includes('FLAT')) typeColor = 'var(--neon-amber)'; macroContainer.innerHTML = ` GAP PREDICTION FOR NIFTY 50 for ${dateStr} ${predType} of ${g.predicted_points || 0} points. `; } else if (macroContainer) { macroContainer.innerHTML = `NO GAP DATA FOUND`; } } catch (err) {} // ------------------------------------------ // 3. EDGE PROBABILITY CHART // ------------------------------------------ try { const { data: history, error: histErr } = await supabaseClient .from('stock_performance_log').select('actual_outcome').in('actual_outcome', ['TARGET', 'STOPLOSS']).limit(30); if (histErr) throw histErr; const chartCanvas = document.getElementById('performanceChart'); if (history && history.length > 0 && chartCanvas) { let targetsHit = history.filter(d => d.actual_outcome === 'TARGET').length; let stopsHit = history.filter(d => d.actual_outcome === 'STOPLOSS').length; const ctx = chartCanvas.getContext('2d'); new Chart(ctx, { type: 'doughnut', plugins: [ChartDataLabels], data: { labels: ['Wins', 'Losses'], datasets: [{ data: [targetsHit, stopsHit], backgroundColor: ['rgba(0,255,65,0.2)', 'rgba(255,0,60,0.2)'], borderColor: ['#00ff41', '#ff003c'], borderWidth: 1 }] }, options: { responsive: true, maintainAspectRatio: false, cutout: '75%', plugins: { legend: { display: false }, datalabels: { color: '#fff', font: { family: "'JetBrains Mono', monospace", size: 13, weight: 'bold' }, formatter: (value, ctx) => { let sum = 0; ctx.chart.data.datasets[0].data.map(data => { sum += data; }); return sum === 0 ? '' : (value * 100 / sum).toFixed(0) + "%"; } } } } }); } } catch (err) {} } // ========================================== // RENDER HTML FOR PICKS // ========================================== function renderPicks(picks, containerId, isBTST = false) { const container = document.getElementById(containerId); if (!container) return; if (!picks || picks.length === 0) { container.innerHTML = '[ NO DATA FOUND ]'; return; } let html = ''; picks.forEach(pick => { const labelColor = isBTST ? 'var(--neon-green)' : 'var(--neon-blue)'; const confidence = pick.mc_prob ? pick.mc_prob.toFixed(1) + '%' : 'N/A'; html += ` ${pick.ticker} ₹${pick.entry_price} ₹${pick.target_price} ₹${pick.stoploss_price} ${confidence} `; }); container.innerHTML = html; } // ========================================== // MODAL 1: STOCK HISTORY VIEWER // ========================================== async function openHistoryModal() { const modal = document.getElementById('historyModal'); const tbody = document.getElementById('history-tbody'); if(!modal || !tbody) return; tbody.innerHTML = 'FETCHING_DATABASE...'; modal.style.display = 'flex'; try { const { data: history } = await supabaseClient.from('stock_performance_log').select('*').in('actual_outcome', ['TARGET', 'STOPLOSS']).order('timestamp', { ascending: false }).limit(50); if (history && history.length > 0) { let html = ''; history.forEach(row => { let outColor = row.actual_outcome === 'TARGET' ? 'var(--neon-green)' : 'var(--neon-red)'; let dateStr = 'N/A'; if (row.timestamp) { const parts = row.timestamp.split('T')[0].split('-'); dateStr = `${parts[2]}-${parts[1]}-${parts[0]}`; } html += ` ${dateStr}${row.ticker} ₹${row.entry_price}₹${row.target_price}₹${row.stoploss_price} ${row.actual_outcome} ${row.fusion_score ? row.fusion_score.toFixed(1) : '-'} ${row.mc_prob ? row.mc_prob.toFixed(1) : '-'} `; }); tbody.innerHTML = html; } else { tbody.innerHTML = 'NO_CLOSED_TRADES_FOUND'; } } catch (err) { tbody.innerHTML = 'ERR_FETCH_FAILED'; } } // ========================================== // MODAL 2: GAP HISTORY VIEWER // ========================================== async function openGapHistoryModal() { const modal = document.getElementById('gapHistoryModal'); const tbody = document.getElementById('gap-history-tbody'); if(!modal || !tbody) return; tbody.innerHTML = 'FETCHING_DATABASE...'; modal.style.display = 'flex'; try { const { data: history, error } = await supabaseClient.from('gap_performance_log').select('*').neq('status', 'PENDING').order('id', { ascending: false }).limit(50); if (error) throw error; const validHistory = history ? history.filter(row => !row.status || row.status.toUpperCase() !== 'PENDING') : []; if (validHistory && validHistory.length > 0) { let html = ''; validHistory.forEach(row => { let typeColor = '#fff', accColor = '#fff', statusColor = '#fff'; if (row.prediction_type && row.prediction_type.includes('UP')) typeColor = 'var(--neon-green)'; if (row.prediction_type && row.prediction_type.includes('DOWN')) typeColor = 'var(--neon-red)'; if (row.prediction_type === 'NEUTRAL' || row.prediction_type === 'FLAT') typeColor = 'var(--neon-amber)'; if (row.accuracy_percent) { if (row.accuracy_percent >= 70) accColor = 'var(--neon-green)'; else if (row.accuracy_percent >= 50) accColor = 'var(--neon-amber)'; else accColor = 'var(--neon-red)'; } let rowStatus = row.status ? row.status.toUpperCase() : '-'; if (rowStatus === 'HIT') statusColor = 'var(--neon-green)'; if (rowStatus === 'MISS') statusColor = 'var(--neon-red)'; let dateStr = 'N/A'; if (row.date) { const parts = row.date.split('T')[0].split('-'); dateStr = `${parts[2]}-${parts[1]}-${parts[0]}`; } html += ` ${dateStr}${row.prediction_type || '-'} ${row.predicted_points !== null ? row.predicted_points : '-'} ${row.actual_points !== null ? row.actual_points : '-'} ${row.accuracy_percent !== null ? row.accuracy_percent + '%' : '-'} ${rowStatus} `; }); tbody.innerHTML = html; } else { tbody.innerHTML = 'NO_CLOSED_GAP_DATA_FOUND'; } } catch (err) { tbody.innerHTML = 'ERR_FETCH_FAILED'; } } // ========================================== // MODAL 3: INDIVIDUAL STOCK DIAGNOSTICS // ========================================== async function showStockInfo(ticker, clickTime) { const modal = document.getElementById('stockInfoModal'); const title = document.getElementById('stockInfoTitle'); const body = document.getElementById('stockInfoBody'); if(!modal || !body) return; modal.style.display = 'flex'; title.innerText = `[ ${ticker} ] DIAGNOSTICS`; body.innerHTML = '

Fetching Database History...
'; try { const tickerBase = ticker.replace('.NS', ''); const { data: engine1Hist } = await supabaseClient.from('stock_performance_log').select('*').eq('ticker', tickerBase).in('actual_outcome', ['TARGET', 'STOPLOSS']); const { data: engine2Hist } = await supabaseClient.from('trade_signals').select('*').eq('symbol', tickerBase).order('created_at', { ascending: false }).limit(1); let html = ''; let winRate = 0, totalTrades = 0; if (engine1Hist && engine1Hist.length > 0) { totalTrades = engine1Hist.length; const wins = engine1Hist.filter(t => t.actual_outcome === 'TARGET').length; winRate = ((wins / totalTrades) * 100).toFixed(1); } html += `

1. HISTORICAL ACCURACY (1st Engine)

TOTAL TRADES
${totalTrades}
WIN RATE
${totalTrades > 0 ? winRate + '%' : 'N/A'}
`; if (engine2Hist && engine2Hist.length > 0) { const latest = engine2Hist[0]; const statColor = latest.status === 'OPEN' ? 'var(--neon-blue)' : 'var(--text-muted)'; html += `

2. 9PM HYBRID ORACLE (Latest Scan)

LATEST SIGNAL
${latest.status} (${latest.trade_type})
AI CONVICTION${tip("Mathematical probability (0-100%) of this signal hitting its target, derived from historical AI win rates.")}
${latest.conviction_probability ? latest.conviction_probability + '%' : 'N/A'}
ENTRY PRICE
₹${latest.entry_price || '-'}
TARGET PRICE
₹${latest.target_price || '-'}
`; } else { html += `

2. 9PM HYBRID ORACLE

No signals generated for this stock by the 2nd engine yet.

`; } html += `

3. LIVE NEURAL NETWORK STATE ● RUNNING

[ AWAITING CLOUD UPLINK... ]
_
`; body.innerHTML = html; pollLiveData(tickerBase, clickTime); } catch (err) { body.innerHTML = '
ERR_FETCH_FAILED
'; } } async function pollLiveData(tickerBase, clickTime) { const container = document.getElementById('live-ai-container'); const modal = document.getElementById('stockInfoModal'); let attempts = 0; const maxAttempts = 25; const pollInterval = setInterval(async () => { attempts++; if(!container || modal.style.display === 'none') { clearInterval(pollInterval); return; } try { const { data } = await supabaseClient.from('live_stress_tests').select('*').eq('ticker', tickerBase).gte('created_at', clickTime).order('created_at', { ascending: false }).limit(1); if (data && data.length > 0) { clearInterval(pollInterval); const state = data[0]; const regime = state.regime || 'UNKNOWN'; const fusion = state.fusion_score ? state.fusion_score.toFixed(1) : 'N/A'; const mc = state.mc_prob ? state.mc_prob.toFixed(1) + '%' : 'N/A'; const regimeColor = regime === 'TRENDING' ? 'var(--neon-green)' : 'var(--neon-amber)'; const { data: weights, error: weightsErr } = await supabaseClient.from('indicator_weights').select('indicator, weight').eq('ticker', tickerBase).eq('regime', regime).order('weight', { ascending: false }).limit(4); let topIndicatorsHtml = ''; if (!weightsErr && weights && weights.length > 0) { topIndicatorsHtml = weights.map(w => `
${w.indicator} ${w.weight.toFixed(3)}
`).join(''); } else { topIndicatorsHtml = `
[ AI PENDING TRAINING ]
Default Baseline: 0.100
`; } container.innerHTML = `

3. LIVE NEURAL NETWORK STATE ● SYNCED

MKT REGIME${tip("Classifies stock behavior as TRENDING or SIDEWAYS using ADX (Average Directional Index) to apply the correct strategy.")}
${regime}
FUSION SCORE${tip("Combined weighted score of 17 Technicals + Fundamentals. >65 is a BUY, <35 is a SELL.")}
${fusion}
MONTE CARLO${tip("Win probability calculated by simulating 1,000 randomized future price paths based on historical volatility.")}
${mc}
Top Trusted Indicators (${regime})${tip("Indicators dynamically weighted by the AI. Weights automatically increase when they predict correctly in this specific regime.")}: ${topIndicatorsHtml}
`; container.style.borderColor = 'rgba(255,255,255,0.1)'; container.style.boxShadow = 'none'; } else if (attempts >= maxAttempts) { clearInterval(pollInterval); container.innerHTML = `
[ TIMEOUT: SATELLITE LINK FAILED ]
Make sure Python scripts executed successfully.
`; container.style.borderColor = 'var(--neon-red)'; } } catch (err) { } }, 3000); } // ========================================== // CLOUDFLARE WORKER TRIGGER // ========================================== const workerUrl = 'https://stock-oracle-trigger.sinha-k-manish.workers.dev'; const statusBox = document.getElementById('status-box'); async function triggerEngine(taskType) { const allButtons = document.querySelectorAll('button'); allButtons.forEach(btn => btn.disabled = true); if(statusBox) statusBox.innerHTML = `[ SYS.STATUS: EXECUTING ${taskType}_ ]`; const tickerCb = document.getElementById('stock-cb'); const ticker = tickerCb ? tickerCb.value : 'RELIANCE'; if (taskType === 'SINGLE') { const clickTime = new Date().toISOString(); showStockInfo(ticker, clickTime); } try { const response = await fetch(workerUrl, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ task: taskType, ticker: ticker + ".NS" }) }); if (response.ok) { if(statusBox) statusBox.innerHTML = `[ SYS.STATUS: TASK_COMPLETE_ ]`; } else { if(statusBox) statusBox.innerHTML = `[ SYS.STATUS: ERR_FETCH_FAILED_ ]`; } } catch (err) { if(statusBox) statusBox.innerHTML = `[ SYS.STATUS: ERR_NETWORK_DISCONNECT_ ]`; } finally { allButtons.forEach(btn => btn.disabled = false); setTimeout(() => { if(statusBox) statusBox.innerHTML = `[ SYS.STATUS: ONLINE_ ]`; }, 4000); } }