'use client'; import React, { useState, useMemo, useEffect } from 'react'; import { useSandboxStore } from '@/lib/store'; import { predictCryptoTrend, calculateBetaPosterior } from '@/lib/math/statistics'; import 'katex/dist/katex.min.css'; import { BlockMath, InlineMath } from 'react-katex'; import CryptoMathModal from './CryptoMathModal'; import CryptoBlueprintModal from './CryptoBlueprintModal'; import { Cpu, Search, RefreshCw, BarChart2, TrendingUp, AlertCircle, Info, ChevronDown, ChevronUp, ArrowUpRight, ArrowDownRight, Compass, ShieldAlert, Sparkles, BookOpen, Check } from 'lucide-react'; interface TrackerState { alpha: number; beta: number; } type TrackersMap = Record; const ESTIMATORS = [ { id: 'rf', name: 'Random Forest' }, { id: 'gb', name: 'XGBoost / GB' }, { id: 'lr', name: 'Logistic Regression' }, { id: 'svm', name: 'Support Vector Machine' }, { id: 'mlp', name: 'Multi-Layer Perceptron' } ] as const; const HORIZONS = [ { id: 'T1', name: 'T+1 Day', days: 1 }, { id: 'T5', name: 'T+5 Days', days: 5 }, { id: 'T10', name: 'T+10 Days', days: 10 } ] as const; interface CoinData { ticker: string; name: string; price: string; change24h: number; fundingRate: number; // in % openInterestChange: number; // in % longShortRatio: number; whaleInflow: number; // net flows exchangeReserves: number; // in % liqLong: string; liqShort: string; } const defaultCoins: Record = { 'BTC': { ticker: 'BTC', name: 'Bitcoin', price: '$69,450', change24h: 2.4, fundingRate: -0.015, openInterestChange: 8.2, longShortRatio: 0.92, whaleInflow: 480, exchangeReserves: -1.4, liqLong: '$68,200', liqShort: '$70,500' }, 'ETH': { ticker: 'ETH', name: 'Ethereum', price: '$3,820', change24h: -1.2, fundingRate: 0.045, openInterestChange: -3.5, longShortRatio: 1.34, whaleInflow: -120, exchangeReserves: 0.8, liqLong: '$3,710', liqShort: '$3,920' }, 'SOL': { ticker: 'SOL', name: 'Solana', price: '$184.20', change24h: 5.8, fundingRate: 0.082, openInterestChange: 14.5, longShortRatio: 1.62, whaleInflow: 1250, exchangeReserves: -2.8, liqLong: '$176.00', liqShort: '$192.50' } }; interface Forecast { id: string; ticker: string; entryPrice: number; resolved: boolean; timestamp: number; predictions: Record>; targetTimes: Record; results?: Record; } export default function CryptoDemo() { const { addModelTrial } = useSandboxStore(); // Local state for alphaSuccess and betaFailure to satisfy SSR hydration safeguarding const [alphaSuccess, setAlphaSuccess] = useState(394); const [betaFailure, setBetaFailure] = useState(118); const [forecasts, setForecasts] = useState([]); const [learningLoopLog, setLearningLoopLog] = useState(''); const [activeTicker, setActiveTicker] = useState('BTC'); const [searchQuery, setSearchQuery] = useState(''); const [customCoins, setCustomCoins] = useState>({}); const [searchError, setSearchError] = useState(false); const [showMathAccordion, setShowMathAccordion] = useState(false); const [isMathModalOpen, setIsMathModalOpen] = useState(false); const [isBlueprintModalOpen, setIsBlueprintModalOpen] = useState(false); const [simulatedTrialLogged, setSimulatedTrialLogged] = useState(false); const [lastTrialSuccess, setLastTrialSuccess] = useState(false); // 15 independent Beta-Posterior trackers const [trackers, setTrackers] = useState({}); const [ensemblePredictions, setEnsemblePredictions] = useState(null); const [loadingEnsemble, setLoadingEnsemble] = useState(false); const [isShieldActive, setIsShieldActive] = useState(true); const [coins, setCoins] = useState>(defaultCoins); const [feedbackFilterAsset, setFeedbackFilterAsset] = useState<'BTC' | 'ETH' | 'SOL'>('BTC'); // Safely load counters and forecasts from localStorage on client mount useEffect(() => { const savedAlpha = localStorage.getItem('crypto_bayes_alpha'); const savedBeta = localStorage.getItem('crypto_bayes_beta'); const savedForecasts = localStorage.getItem('crypto_bayes_forecasts'); let loadedAlpha = 394; let loadedBeta = 118; if (savedAlpha !== null) { loadedAlpha = parseInt(savedAlpha, 10); setAlphaSuccess(loadedAlpha); } else { localStorage.setItem('crypto_bayes_alpha', '394'); } if (savedBeta !== null) { loadedBeta = parseInt(savedBeta, 10); setBetaFailure(loadedBeta); } else { localStorage.setItem('crypto_bayes_beta', '118'); } // Load trackers const defaultPriors: Record = { 'rf_T1': { alpha: 38, beta: 12 }, 'rf_T5': { alpha: 35, beta: 15 }, 'rf_T10': { alpha: 32, beta: 18 }, 'gb_T1': { alpha: 40, beta: 10 }, 'gb_T5': { alpha: 36, beta: 14 }, 'gb_T10': { alpha: 30, beta: 20 }, 'lr_T1': { alpha: 35, beta: 15 }, 'lr_T5': { alpha: 33, beta: 17 }, 'lr_T10': { alpha: 31, beta: 19 }, 'svm_T1': { alpha: 36, beta: 14 }, 'svm_T5': { alpha: 34, beta: 16 }, 'svm_T10': { alpha: 32, beta: 18 }, 'mlp_T1': { alpha: 39, beta: 11 }, 'mlp_T5': { alpha: 35, beta: 15 }, 'mlp_T10': { alpha: 31, beta: 19 } }; const map: TrackersMap = {}; Object.keys(defaultPriors).forEach((key) => { const a = localStorage.getItem(`crypto_bayes_tracker_${key}_alpha`); const b = localStorage.getItem(`crypto_bayes_tracker_${key}_beta`); const alphaVal = a !== null ? parseInt(a, 10) : defaultPriors[key].alpha; const betaVal = b !== null ? parseInt(b, 10) : defaultPriors[key].beta; map[key] = { alpha: alphaVal, beta: betaVal }; if (a === null) { localStorage.setItem(`crypto_bayes_tracker_${key}_alpha`, String(alphaVal)); localStorage.setItem(`crypto_bayes_tracker_${key}_beta`, String(betaVal)); } }); setTrackers(map); // Fetch ensemble predictions const fetchEnsemble = async () => { setLoadingEnsemble(true); try { const res = await fetch('/api/crypto/ensemble'); if (res.ok) { const data = await res.json(); setEnsemblePredictions(data.predictions || null); setIsShieldActive(data.isShieldActive !== undefined ? data.isShieldActive : true); } } catch (err) { console.error("Failed to load ensemble predictions:", err); } finally { setLoadingEnsemble(false); } }; fetchEnsemble(); if (savedForecasts !== null) { try { const parsed = JSON.parse(savedForecasts); // Clean legacy formats if necessary if (parsed.length > 0 && parsed[0].predictions === undefined) { throw new Error("Legacy forecast format"); } setForecasts(parsed); } catch (err) { console.log("Resetting legacy forecasts to multi-model format..."); const now = Date.now(); const mockForecasts: Forecast[] = [ { id: 'mock-1', ticker: 'BTC', entryPrice: 65000, resolved: true, timestamp: now - 86400 * 1000 * 3, predictions: { rf: { T1: 0.62, T5: 0.58, T10: 0.54 }, gb: { T1: 0.65, T5: 0.61, T10: 0.51 }, lr: { T1: 0.58, T5: 0.57, T10: 0.55 }, svm: { T1: 0.60, T5: 0.59, T10: 0.56 }, mlp: { T1: 0.64, T5: 0.60, T10: 0.53 } }, targetTimes: { T1: now - 86400 * 1000 * 2, T5: now - 86400 * 1000 * 2, T10: now - 86400 * 1000 * 2 }, results: { rf_T1: 'SUCCESS', rf_T5: 'SUCCESS', rf_T10: 'SUCCESS', gb_T1: 'SUCCESS', gb_T5: 'SUCCESS', gb_T10: 'SUCCESS', lr_T1: 'SUCCESS', lr_T5: 'SUCCESS', lr_T10: 'SUCCESS', svm_T1: 'SUCCESS', svm_T5: 'SUCCESS', svm_T10: 'SUCCESS', mlp_T1: 'SUCCESS', mlp_T5: 'SUCCESS', mlp_T10: 'SUCCESS' } } ]; setForecasts(mockForecasts); localStorage.setItem('crypto_bayes_forecasts', JSON.stringify(mockForecasts)); } } else { const now = Date.now(); const mockForecasts: Forecast[] = [ { id: 'mock-1', ticker: 'BTC', entryPrice: 65000, resolved: true, timestamp: now - 86400 * 1000 * 3, predictions: { rf: { T1: 0.62, T5: 0.58, T10: 0.54 }, gb: { T1: 0.65, T5: 0.61, T10: 0.51 }, lr: { T1: 0.58, T5: 0.57, T10: 0.55 }, svm: { T1: 0.60, T5: 0.59, T10: 0.56 }, mlp: { T1: 0.64, T5: 0.60, T10: 0.53 } }, targetTimes: { T1: now - 86400 * 1000 * 2, T5: now - 86400 * 1000 * 2, T10: now - 86400 * 1000 * 2 }, results: { rf_T1: 'SUCCESS', rf_T5: 'SUCCESS', rf_T10: 'SUCCESS', gb_T1: 'SUCCESS', gb_T5: 'SUCCESS', gb_T10: 'SUCCESS', lr_T1: 'SUCCESS', lr_T5: 'SUCCESS', lr_T10: 'SUCCESS', svm_T1: 'SUCCESS', svm_T5: 'SUCCESS', svm_T10: 'SUCCESS', mlp_T1: 'SUCCESS', mlp_T5: 'SUCCESS', mlp_T10: 'SUCCESS' } } ]; setForecasts(mockForecasts); localStorage.setItem('crypto_bayes_forecasts', JSON.stringify(mockForecasts)); } }, []); // Poll live price, 24h change, and indicators from the backend API useEffect(() => { const fetchCryptoPrices = async () => { try { const res = await fetch('/api/finance?region=crypto'); if (!res.ok) return; const data = await res.json(); const results = data.results || []; setCoins(prevCoins => { const updatedCoins = { ...prevCoins }; results.forEach((r: any) => { const cleanTicker = r.ticker.replace('-USD', ''); if (cleanTicker === 'BTC' || cleanTicker === 'ETH' || cleanTicker === 'SOL') { const currentPrice = r.currentPrice; const dayChangePercent = r.dayChange * 100; // Bind API indicators directly const fundingRate = r.fundingRate !== undefined ? r.fundingRate : (cleanTicker === 'BTC' ? -0.015 : cleanTicker === 'ETH' ? 0.045 : 0.082); const openInterestChange = r.openInterestChange !== undefined ? r.openInterestChange : (cleanTicker === 'BTC' ? 8.2 : cleanTicker === 'ETH' ? -3.5 : 14.5); const longShortRatio = r.longShortRatio !== undefined ? r.longShortRatio : (cleanTicker === 'BTC' ? 0.92 : cleanTicker === 'ETH' ? 1.34 : 1.62); const whaleInflow = r.whaleInflow !== undefined ? r.whaleInflow : (cleanTicker === 'BTC' ? 480 : cleanTicker === 'ETH' ? -120 : 1250); const exchangeReserves = r.exchangeReserves !== undefined ? r.exchangeReserves : (cleanTicker === 'BTC' ? -1.4 : cleanTicker === 'ETH' ? 0.8 : -2.8); // Scale liquidations dynamically relative to the current real price const liqLongVal = currentPrice * (cleanTicker === 'BTC' ? 0.982 : cleanTicker === 'ETH' ? 0.971 : 0.955); const liqShortVal = currentPrice * (cleanTicker === 'BTC' ? 1.015 : cleanTicker === 'ETH' ? 1.026 : 1.045); updatedCoins[cleanTicker] = { ticker: cleanTicker, name: cleanTicker === 'BTC' ? 'Bitcoin' : cleanTicker === 'ETH' ? 'Ethereum' : 'Solana', price: `$${currentPrice.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}`, change24h: parseFloat(dayChangePercent.toFixed(2)), fundingRate, openInterestChange, longShortRatio, whaleInflow, exchangeReserves, liqLong: `$${liqLongVal.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}`, liqShort: `$${liqShortVal.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}` }; } }); return updatedCoins; }); } catch (err) { console.error("Failed to fetch crypto prices:", err); } }; fetchCryptoPrices(); const interval = setInterval(fetchCryptoPrices, 15000); // Poll every 15s return () => clearInterval(interval); }, []); // Client-side background learning loop evaluating forecasts against actual live returns useEffect(() => { const runLearningLoop = async () => { if (Object.keys(trackers).length === 0) return; try { const res = await fetch('/api/finance?region=crypto'); if (!res.ok) return; const data = await res.json(); const results = data.results || []; const pricesMap: Record = {}; results.forEach((r: any) => { pricesMap[r.ticker] = r.currentPrice; const cleanTicker = r.ticker.replace('-USD', ''); pricesMap[cleanTicker] = r.currentPrice; }); let updatedAny = false; const nextTrackers = { ...trackers }; const updatedForecasts = forecasts.map((f) => { if (f.resolved) return f; const currentPrice = pricesMap[f.ticker] || pricesMap[`${f.ticker}-USD`]; if (!currentPrice) return f; const now = Date.now(); const resultsMap = { ...(f.results || {}) }; let modified = false; HORIZONS.forEach((h) => { const hKey = h.id; const targetTime = f.targetTimes[hKey]; ESTIMATORS.forEach((est) => { const trackerKey = `${est.id}_${hKey}`; if (now >= targetTime && !resultsMap[trackerKey]) { const priceWentUp = currentPrice > f.entryPrice; const predProb = f.predictions[est.id]?.[hKey] ?? 0.5; const predDir = predProb > 0.5 ? 'UP' : 'DOWN'; const success = (predDir === 'UP' && priceWentUp) || (predDir === 'DOWN' && !priceWentUp); resultsMap[trackerKey] = success ? 'SUCCESS' : 'FAILURE'; if (success) { nextTrackers[trackerKey].alpha += 1; localStorage.setItem(`crypto_bayes_tracker_${trackerKey}_alpha`, String(nextTrackers[trackerKey].alpha)); } else { nextTrackers[trackerKey].beta += 1; localStorage.setItem(`crypto_bayes_tracker_${trackerKey}_beta`, String(nextTrackers[trackerKey].beta)); } addModelTrial(success); updatedAny = true; modified = true; } }); }); if (modified) { const allResolved = ESTIMATORS.every(est => HORIZONS.every(h => resultsMap[`${est.id}_${h.id}`] !== undefined) ); return { ...f, results: resultsMap, resolved: allResolved }; } return f; }); if (updatedAny) { setTrackers(nextTrackers); setForecasts(updatedForecasts); localStorage.setItem('crypto_bayes_forecasts', JSON.stringify(updatedForecasts)); setLearningLoopLog(`Processed active ensemble forecasts. Trackers calibration updated.`); setTimeout(() => setLearningLoopLog(''), 6000); } } catch (err) { console.error("Learning loop evaluation error:", err); } }; if (forecasts.length > 0) { runLearningLoop(); } const interval = setInterval(runLearningLoop, 30000); return () => clearInterval(interval); }, [forecasts, trackers, addModelTrial]); // Active Coin data retrieval const activeCoin = useMemo(() => { return customCoins[activeTicker] || coins[activeTicker] || coins['BTC']; }, [activeTicker, customCoins, coins]); const filteredForecasts = useMemo(() => { return forecasts.filter((f) => f.ticker === feedbackFilterAsset); }, [forecasts, feedbackFilterAsset]); // Helper to fetch/load prediction probabilities const getPredictionProb = (ticker: string, estimator: string, horizon: string): number => { const cleanTicker = ticker.replace('-USD', ''); if (ensemblePredictions && ensemblePredictions[cleanTicker] && ensemblePredictions[cleanTicker][estimator]) { return ensemblePredictions[cleanTicker][estimator][horizon] ?? 0.5; } // Fallback static predictions const defaultMapping: Record>> = { BTC: { rf: { T1: 0.528, T5: 0.539, T10: 0.59 }, gb: { T1: 0.54, T5: 0.513, T10: 0.733 }, lr: { T1: 0.542, T5: 0.595, T10: 0.641 }, svm: { T1: 0.487, T5: 0.477, T10: 0.528 }, mlp: { T1: 0.36, T5: 1.0, T10: 0.998 } }, ETH: { rf: { T1: 0.508, T5: 0.549, T10: 0.59 }, gb: { T1: 0.55, T5: 0.513, T10: 0.703 }, lr: { T1: 0.542, T5: 0.575, T10: 0.651 }, svm: { T1: 0.477, T5: 0.477, T10: 0.528 }, mlp: { T1: 0.36, T5: 0.99, T10: 1.018 } }, SOL: { rf: { T1: 0.558, T5: 0.539, T10: 0.57 }, gb: { T1: 0.52, T5: 0.533, T10: 0.733 }, lr: { T1: 0.552, T5: 0.595, T10: 0.631 }, svm: { T1: 0.487, T5: 0.507, T10: 0.528 }, mlp: { T1: 0.38, T5: 1.0, T10: 0.978 } } }; const assetKey = defaultMapping[cleanTicker] ? cleanTicker : 'BTC'; return defaultMapping[assetKey][estimator]?.[horizon] ?? 0.5; }; // Compute live Random Forest baseline predictions (for legacy/visual compatibility) const mlPredictions = useMemo(() => { const inputs = { fundingRate: activeCoin.fundingRate, openInterestChange: activeCoin.openInterestChange, longShortRatio: activeCoin.longShortRatio, whaleInflow: activeCoin.whaleInflow }; return predictCryptoTrend(inputs); }, [activeCoin]); // Apply Bayesian online learning error-correction posterior update (legacy/visual) const correctedPredictions = useMemo(() => { const shortTermCorrected = calculateBetaPosterior( alphaSuccess, betaFailure, mlPredictions.shortTermProb, 12 // confidence scale ); const mediumTermCorrected = calculateBetaPosterior( alphaSuccess, betaFailure, mlPredictions.mediumTermProb, 12 ); return { shortTerm: shortTermCorrected, mediumTerm: mediumTermCorrected }; }, [mlPredictions, alphaSuccess, betaFailure]); // Search/add new altcoin const handleAltcoinSearch = (e: React.FormEvent) => { e.preventDefault(); setSearchError(false); const query = searchQuery.trim().toUpperCase(); if (!query) return; if (coins[query]) { setActiveTicker(query); setSearchQuery(''); return; } if (customCoins[query]) { setActiveTicker(query); setSearchQuery(''); return; } const isBull = Math.random() > 0.45; const simulatedChange = isBull ? 3 + Math.random() * 8 : -2 - Math.random() * 6; const simulatedPrice = isBull ? 2 + Math.random() * 10 : 0.2 + Math.random() * 3; const newCoin: CoinData = { ticker: query, name: `${query} Token`, price: `$${simulatedPrice.toFixed(4)}`, change24h: parseFloat(simulatedChange.toFixed(2)), fundingRate: parseFloat((Math.random() * 0.12 - 0.04).toFixed(3)), openInterestChange: parseFloat((Math.random() * 30 - 10).toFixed(1)), longShortRatio: parseFloat((0.8 + Math.random() * 1.1).toFixed(2)), whaleInflow: Math.floor(Math.random() * 1500 - 400), exchangeReserves: parseFloat((Math.random() * 4 - 2).toFixed(1)), liqLong: `$${(simulatedPrice * 0.9).toFixed(4)}`, liqShort: `$${(simulatedPrice * 1.1).toFixed(4)}` }; setCustomCoins(prev => ({ ...prev, [query]: newCoin })); setActiveTicker(query); setSearchQuery(''); }; // Manual logging of active forecast for all 15 models & horizons const handleLogManualForecast = () => { const entryPrice = parseFloat(activeCoin.price.replace(/[^0-9.]/g, '')); // Save snapshot of all predictions const predictionsMap: Record> = {}; ESTIMATORS.forEach((est) => { predictionsMap[est.id] = { T1: getPredictionProb(activeCoin.ticker, est.id, 'T1'), T5: getPredictionProb(activeCoin.ticker, est.id, 'T5'), T10: getPredictionProb(activeCoin.ticker, est.id, 'T10') }; }); const now = Date.now(); const newForecast: Forecast = { id: 'fc-' + now, ticker: activeCoin.ticker, entryPrice, resolved: false, timestamp: now, predictions: predictionsMap, targetTimes: { T1: now + 24 * 60 * 60 * 1000, // resolves in 24 hours T5: now + 5 * 24 * 60 * 60 * 1000, // resolves in 5 days T10: now + 10 * 24 * 60 * 60 * 1000 // resolves in 10 days } }; const nextForecasts = [newForecast, ...forecasts]; setForecasts(nextForecasts); localStorage.setItem('crypto_bayes_forecasts', JSON.stringify(nextForecasts)); setLearningLoopLog(`Registered active multi-model forecast for ${activeCoin.ticker} at $${entryPrice}. Evaluating T+1 (24h), T+5 (5d), and T+10 (10d).`); setTimeout(() => setLearningLoopLog(''), 8000); }; // Simulator for ensemble calibration (simulates trials across all 15 trackers) const handleSimulateEnsembleTrial = (success: boolean) => { if (Object.keys(trackers).length === 0) return; const nextTrackers = { ...trackers }; ESTIMATORS.forEach((est) => { HORIZONS.forEach((h) => { const trackerKey = `${est.id}_${h.id}`; if (!nextTrackers[trackerKey]) { nextTrackers[trackerKey] = { alpha: 1, beta: 1 }; } if (success) { nextTrackers[trackerKey].alpha += 1; localStorage.setItem(`crypto_bayes_tracker_${trackerKey}_alpha`, String(nextTrackers[trackerKey].alpha)); } else { nextTrackers[trackerKey].beta += 1; localStorage.setItem(`crypto_bayes_tracker_${trackerKey}_beta`, String(nextTrackers[trackerKey].beta)); } }); }); setTrackers(nextTrackers); setLastTrialSuccess(success); setSimulatedTrialLogged(true); setTimeout(() => setSimulatedTrialLogged(false), 2000); }; const totalTrials = alphaSuccess + betaFailure; const priorAccuracy = (alphaSuccess / (totalTrials || 1)) * 100; return (
{/* Header */}
Level 4

Predictive Crypto Models & Bayes Self-Correction

{isShieldActive ? ( SYSTEM-AUTARK (OFFLINE-CORE) ) : ( LIVE-API ENDPUNKT )}

Prior Accuracy

{priorAccuracy.toFixed(1)}% (n={totalTrials})

{/* SECTION 1: Top 3 Cards & Search Mask */}
{/* Status Cards BTC, ETH, SOL */} {['BTC', 'ETH', 'SOL'].map((tick) => { const coin = coins[tick] || defaultCoins[tick]; const isActive = activeTicker === tick; const isUp = coin.change24h >= 0; return (
setActiveTicker(tick)} className={`p-4 rounded-xl border cursor-pointer transition-all hover:bg-slate-850 flex items-center justify-between relative overflow-hidden ${isActive ? 'border-cyan-500/40 bg-cyan-500/5 shadow-md shadow-cyan-500/5' : 'border-slate-850 bg-slate-950/20'}`} >
{coin.name}
{coin.price}
{isUp ? : } {isUp ? '+' : ''}{coin.change24h}%
{tick}
); })} {/* Custom Search bar */}
setSearchQuery(e.target.value)} />
{Object.keys(customCoins).length > 0 && (
{Object.keys(customCoins).map(tick => ( ))}
)}
{/* SECTION 2: Derivatives & On-Chain Metrics Ledger */}
{/* Left Column: Metrics Widgets */}

On-Chain & Derivative Indicators ({activeCoin.ticker})

{/* Funding & Open Interest Widget */}

Funding Rates & Open Interest

Daily Funding Rate: {activeCoin.fundingRate > 0 ? '+' : ''}{activeCoin.fundingRate.toFixed(3)}%
Open Interest (24h Δ): = 0 ? 'text-emerald-400' : 'text-rose-400'}`}> {activeCoin.openInterestChange > 0 ? '+' : ''}{activeCoin.openInterestChange.toFixed(1)}%
{/* Long/Short & Liquidation Widget */}

Positioning & Liquidations

Long / Short Ratio: {activeCoin.longShortRatio}
Liq Cluster: Long: {activeCoin.liqLong} | Short: {activeCoin.liqShort}
{/* Whale Flows Widget */}

Whale Flows (Net Inflow)

Net Inflow (Wallets): = 0 ? 'text-emerald-400' : 'text-rose-400'}`}> {activeCoin.whaleInflow > 0 ? '+' : ''}{activeCoin.whaleInflow} {activeCoin.ticker}
Positive values signal that large investors are withdrawing assets from exchanges to private wallets (accumulation).
{/* Exchange Reserves Widget */}

Exchange Reserves (Spot)

Reserve Change (7d): {activeCoin.exchangeReserves > 0 ? '+' : ''}{activeCoin.exchangeReserves}%
Falling reserves at spot exchanges reduce available selling pressure and favor squeezes.
{/* Right Column: Multi-Model Ensemble & Walk-Forward Radar Table */}

Walk-Forward Ensemble Radar

{loadingEnsemble && ( )}
Displays predictions and live calibration metrics () across 15 independent trackers.
{ESTIMATORS.map((est) => ( {HORIZONS.map((h) => { const trackerKey = `${est.id}_${h.id}`; const tracker = trackers[trackerKey] || { alpha: 1, beta: 1 }; const prob = getPredictionProb(activeTicker, est.id, h.id); const direction = prob > 0.5 ? 'UP' : 'DOWN'; const expValue = tracker.alpha / (tracker.alpha + tracker.beta); return ( ); })} ))}
Estimator T+1 T+5 T+10
{est.name}
{direction === 'UP' ? '▲' : '▼'} {(prob * 100).toFixed(0)}% {tracker.alpha}/{tracker.beta} E: {(expValue * 100).toFixed(1)}%
{/* Model Calibration Log & Simulation */}

Beta-Posterior Calibration

Simulate Walk-Forward

Simulate model drift across all 15 independent trackers to calibrate Beta posterior expectations.

{simulatedTrialLogged && (
Logged trial outcomes across all 15 estimators & horizons!
)}
{/* SECTION 3: Active Forecasts (Feedback Loop) */}

Active Learning Feedback Loop

{learningLoopLog && (
{learningLoopLog}
)} {/* Sleek Dynamic Asset-Selector Tab-Bar */}
{(['BTC', 'ETH', 'SOL'] as const).map((asset) => ( ))}
{filteredForecasts.length === 0 ? ( ) : ( filteredForecasts.map((fc) => { const now = Date.now(); const getHorizonStatus = (hKey: 'T1' | 'T5' | 'T10') => { const targetTime = fc.targetTimes[hKey]; const isPast = now >= targetTime; let successes = 0; let total = 0; ESTIMATORS.forEach((est) => { const rKey = `${est.id}_${hKey}`; if (fc.results && fc.results[rKey]) { total++; if (fc.results[rKey] === 'SUCCESS') successes++; } }); if (total === 5) { return ( {successes}/5 OK ); } if (isPast) { return Resolving...; } const secondsLeft = Math.max(0, Math.ceil((targetTime - now) / 1000)); return {secondsLeft}s; }; const renderHorizonCell = (hKey: 'T1' | 'T5' | 'T10') => { let avgProb = 0.5; const modelProbs: string[] = []; if (fc.predictions) { let sum = 0; let count = 0; ESTIMATORS.forEach((est) => { const prob = fc.predictions[est.id]?.[hKey]; if (prob !== undefined) { sum += prob; count++; modelProbs.push(`${est.id.toUpperCase()}:${(prob * 100).toFixed(0)}%`); } }); if (count > 0) avgProb = sum / count; } const avgDir = avgProb > 0.5 ? 'UP' : 'DOWN'; return ( ); }; let resolvedCount = 0; let successCount = 0; if (fc.results) { Object.values(fc.results).forEach((r) => { resolvedCount++; if (r === 'SUCCESS') successCount++; }); } let statusText = 'PENDING'; if (resolvedCount === 15) { statusText = 'RESOLVED'; } else if (resolvedCount > 0) { statusText = `PARTIAL (${resolvedCount}/15)`; } return ( {renderHorizonCell('T1')} {renderHorizonCell('T5')} {renderHorizonCell('T10')} ); }) )}
Ticker Entry Price T+1 Forecast & Res T+5 Forecast & Res T+10 Forecast & Res Status Accuracy
No forecasts registered for {feedbackFilterAsset} yet.
{avgDir} {(avgProb * 100).toFixed(0)}%
{getHorizonStatus(hKey)}
{modelProbs.join(' | ')}
{fc.ticker} ${fc.entryPrice.toLocaleString()}{statusText} {resolvedCount > 0 ? ( = 0.5 ? 'text-emerald-400' : 'text-rose-400'}> {((successCount / resolvedCount) * 100).toFixed(0)}% ({successCount}/{resolvedCount}) ) : ( - )}
{/* Informational overlay */}

Econometric Feedback Loop Spec

The learning loop automatically evaluates active forecast parameters in the background against actual price histories returned by /api/finance?region=crypto.

When a logged forecast passes its evaluation target timestamp, it resolves against live market data, updating the Bayesian online calibration metrics and .

{/* SECTION 4: Mathematical LaTeX Accordion */}
{showMathAccordion && (

1. Bayesian Beta-Conjugate Error Correction

We model the error rate confidence interval of the model using a Beta distribution. The prior error state is represented by the parameters (Successes) and (False Alarms):

With a new ML signal , we perform a conjugate Bayes update with a confidence weight :

If the model is historically highly unstable (high ), the Bayesian term corrects an overconfident ML signal downwards, safeguarding the robustness of the system.

2. Random Forest Non-Linear Signal Mapping

The Random Forest simulates an ensemble of 10 weak decision trees. Each tree splits the data based on threshold criteria (e.g., 'Funding Rate < -0.04%' and 'Open Interest > 10%'):

where is the predicted output value of the -th decision tree for the feature vector .

)}
setIsMathModalOpen(false)} /> setIsBlueprintModalOpen(false)} />
); }