'use client'; import React, { useState, useMemo } 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 { Cpu, Search, RefreshCw, BarChart2, TrendingUp, AlertCircle, Info, ChevronDown, ChevronUp, ArrowUpRight, ArrowDownRight, Compass, ShieldAlert, Sparkles, BookOpen, Check } from 'lucide-react'; 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; predictedDirection: 'UP' | 'DOWN'; predictedProb: number; entryPrice: number; resolved: boolean; result?: 'SUCCESS' | 'FAILURE'; timestamp: number; targetTime: number; } 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 [simulatedTrialLogged, setSimulatedTrialLogged] = useState(false); const [lastTrialSuccess, setLastTrialSuccess] = useState(false); // Safely load counters and forecasts from localStorage on client mount React.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'); } if (savedForecasts !== null) { setForecasts(JSON.parse(savedForecasts)); } else { const now = Date.now(); const mockForecasts: Forecast[] = [ { id: 'mock-1', ticker: 'BTC', predictedDirection: 'UP', predictedProb: 0.68, entryPrice: 65000, resolved: true, result: 'SUCCESS', timestamp: now - 86400 * 1000 * 3, targetTime: now - 86400 * 1000 * 2, }, { id: 'mock-2', ticker: 'ETH', predictedDirection: 'DOWN', predictedProb: 0.35, entryPrice: 3950, resolved: true, result: 'SUCCESS', timestamp: now - 86400 * 1000 * 3, targetTime: now - 86400 * 1000 * 2, }, { id: 'mock-3', ticker: 'SOL', predictedDirection: 'UP', predictedProb: 0.72, entryPrice: 170, resolved: true, result: 'SUCCESS', timestamp: now - 86400 * 1000 * 2, targetTime: now - 86400 * 1000 * 1, }, { id: 'mock-4', ticker: 'BTC', predictedDirection: 'UP', predictedProb: 0.62, entryPrice: 71000, resolved: true, result: 'FAILURE', timestamp: now - 86400 * 1000 * 2, targetTime: now - 86400 * 1000 * 1, }, { id: 'mock-5', ticker: 'ETH', predictedDirection: 'UP', predictedProb: 0.58, entryPrice: 3900, resolved: true, result: 'FAILURE', timestamp: now - 86400 * 1000 * 2, targetTime: now - 86400 * 1000 * 1, } ]; setForecasts(mockForecasts); localStorage.setItem('crypto_bayes_forecasts', JSON.stringify(mockForecasts)); } }, []); // Client-side background learning loop evaluating forecasts against actual live returns React.useEffect(() => { const runLearningLoop = async () => { try { const res = await fetch('/api/finance?region=crypto'); if (!res.ok) return; const data = await res.ok ? await res.json() : { results: [] }; 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; let newAlpha = alphaSuccess; let newBeta = betaFailure; 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(); if (now >= f.targetTime) { const priceWentUp = currentPrice > f.entryPrice; const success = (f.predictedDirection === 'UP' && priceWentUp) || (f.predictedDirection === 'DOWN' && !priceWentUp); updatedAny = true; if (success) { newAlpha += 1; } else { newBeta += 1; } addModelTrial(success); return { ...f, resolved: true, result: success ? ('SUCCESS' as const) : ('FAILURE' as const) }; } return f; }); if (updatedAny) { setAlphaSuccess(newAlpha); setBetaFailure(newBeta); setForecasts(updatedForecasts); localStorage.setItem('crypto_bayes_alpha', String(newAlpha)); localStorage.setItem('crypto_bayes_beta', String(newBeta)); localStorage.setItem('crypto_bayes_forecasts', JSON.stringify(updatedForecasts)); setLearningLoopLog(`Processed active forecasts. New successes: ${newAlpha}, New failures: ${newBeta}`); 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, alphaSuccess, betaFailure, addModelTrial]); // Active Coin data retrieval const activeCoin = useMemo(() => { return customCoins[activeTicker] || defaultCoins[activeTicker] || defaultCoins['BTC']; }, [activeTicker, customCoins]); // Compute live Random Forest baseline predictions 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 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 (defaultCoins[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 const handleLogManualForecast = () => { const entryPrice = parseFloat(activeCoin.price.replace(/[^0-9.]/g, '')); const predictedDirection = correctedPredictions.shortTerm > 0.5 ? 'UP' : 'DOWN'; const predictedProb = correctedPredictions.shortTerm; const newForecast: Forecast = { id: 'fc-' + Date.now(), ticker: activeCoin.ticker, predictedDirection, predictedProb, entryPrice, resolved: false, timestamp: Date.now(), targetTime: Date.now() + 60 * 1000 // resolves in 60s for direct visual validation }; const nextForecasts = [newForecast, ...forecasts]; setForecasts(nextForecasts); localStorage.setItem('crypto_bayes_forecasts', JSON.stringify(nextForecasts)); setLearningLoopLog(`Registered active forecast for ${activeCoin.ticker} at $${entryPrice}. Evaluating returns in 60 seconds.`); setTimeout(() => setLearningLoopLog(''), 6000); }; // Simulator for calibration const handleSimulateTrial = (success: boolean) => { addModelTrial(success); setAlphaSuccess(prev => { const next = success ? prev + 1 : prev; localStorage.setItem('crypto_bayes_alpha', String(next)); return next; }); setBetaFailure(prev => { const next = !success ? prev + 1 : prev; localStorage.setItem('crypto_bayes_beta', String(next)); return next; }); setLastTrialSuccess(success); setSimulatedTrialLogged(true); setTimeout(() => setSimulatedTrialLogged(false), 2500); }; const totalTrials = alphaSuccess + betaFailure; const priorAccuracy = (alphaSuccess / (totalTrials || 1)) * 100; return (
{/* Header */}
Level 4

Predictive Crypto Models & Bayes Self-Correction

SYSTEM-AUTARK (OFFLINE-CORE)

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 = 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: Predictive Gauges & Correction Calibration */}

Prediction Probabilities

{/* Gauges / Progress Bars */}
{/* 24h Gauge */}
24h Volatility Squeeze (Short-Term) {(correctedPredictions.shortTerm * 100).toFixed(0)}%
ML Signal: {(mlPredictions.shortTermProb * 100).toFixed(0)}% Bayes Corrected: {(correctedPredictions.shortTerm * 100).toFixed(0)}%
{/* 14d Gauge */}
14d Structural Bullish Trend (Medium-Term) {(correctedPredictions.mediumTerm * 100).toFixed(0)}%
ML Signal: {(mlPredictions.mediumTermProb * 100).toFixed(0)}% Bayes Corrected: {(correctedPredictions.mediumTerm * 100).toFixed(0)}%
{/* Model Calibration Log & Simulation */}

Bayes Model Calibration

n = {totalTrials} Trials
Successes (α):
{alphaSuccess}
False Alarms (β):
{betaFailure}
{/* Trial simulator */}

Simulate model drift: Add correct/false outcomes to calibrate the Beta distribution.

{simulatedTrialLogged && (
Trial logged! Bayes prior updated to {lastTrialSuccess ? 'Success' : 'False Alarm'}.
)}
{/* SECTION 3: Active Forecasts (Feedback Loop) */}

Active Learning Feedback Loop

{learningLoopLog && (
{learningLoopLog}
)}
{forecasts.length === 0 ? ( ) : ( forecasts.map((fc) => ( )) )}
Ticker Direction Probability Entry Price Status Result
No forecasts registered yet.
{fc.ticker} {fc.predictedDirection} {(fc.predictedProb * 100).toFixed(0)}% ${fc.entryPrice.toLocaleString()} {fc.resolved ? 'RESOLVED' : 'PENDING'} {fc.result || '-'}
{/* 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)} />
); }