diff --git a/DEV_LOG.md b/DEV_LOG.md index 8a32a81..f628e85 100644 --- a/DEV_LOG.md +++ b/DEV_LOG.md @@ -244,6 +244,19 @@ This document tracks all modifications, npm packages, active compilation states, * **Active Bugs**: None. * **Type Checker Status**: Verified 100% clean type verification (`npx tsc --noEmit` returns exit code 0). +--- + +## [2026-06-14] - Live Time-Lock Resolution, Ensemble Map Fix & Multi-Asset Logging (#ISSUE-021) + +### Added +* **Real-Time Calendar Locks**: Purged the developer mock test clocks inside `CryptoDemo.tsx` verification loop. Configured un-compromised calendar-day timestamp targets: T+1 resolves after 24 hours, T+5 after 5 calendar days, and T+10 after 10 calendar days. +* **Ensemble Mapping Correction**: Fixed the prediction probability mapping by refactoring `getPredictionProb` to accept and evaluate the specific `ticker` context parameter. This completely resolved the SVM mirroring anomaly and accurately calculates consensus averages from the correct asset data. +* **Multi-Asset Logging & Filtering**: Exchanged the single-asset BTC log for a dynamic multi-asset log. Added a sleek, glassmorphic asset filter tab-bar containing `[ BTC ]`, `[ ETH ]`, and `[ SOL ]` buttons right above the feedback loop table, filtering logs dynamically per active asset. Logs preserve respective entry price snapshots and 15-probability matrices in `localStorage`. + +### Active Bugs / Compile Status +* **Active Bugs**: None. +* **Type Checker Status**: Verified 100% clean type verification (`npx tsc --noEmit` returns exit code 0). + diff --git a/QUANT_ROADMAP.md b/QUANT_ROADMAP.md index c3687d9..7ccf102 100644 --- a/QUANT_ROADMAP.md +++ b/QUANT_ROADMAP.md @@ -35,6 +35,9 @@ This document serves as the permanent, centralized system architecture design an * **Phase 6.5: Ticker Data Real-Time Alignment & ML Handbook Injection** * *Features*: Linked price asset cards dynamically to a 15-second `useEffect` polling loop querying live Yahoo Finance closing prices, Binance funding rates, and local CSV data. Dynamically scaled liquidation values. Injected mathematical specifications for all 5 ML models (RF, XGBoost, ElasticNet, SVM, MLP) as Section G of the quantitative handbook. Fixed modal viewport clipping. Expanded the Active Learning Feedback Loop table to preserve the 15-probability matrix layout and display separate consensuses for T+1, T+5, and T+10 with detailed model paths. * *Status*: **Fully Operational (Production Lock)**. +* **Phase 7.0: Live Time-Lock Resolution, Ensemble Map Fix & Multi-Asset Logging** + * *Features*: Disabled developer mock test clocks inside verification loop hooks. Configured strict real-time calendar locks (T+1 resolves after 24h, T+5 after 5d, T+10 after 10d). Corrected the ensemble mapping anomaly inside `getPredictionProb` by passing the active asset's ticker context parameter. Embedded a dynamic asset selector filter tab-bar above the Active Learning Feedback Loop table component, enabling isolated tracking and filtering of multi-asset predictions (BTC, ETH, SOL). + * *Status*: **Fully Operational (Production Lock)**. --- diff --git a/components/modules/crypto/CryptoDemo.tsx b/components/modules/crypto/CryptoDemo.tsx index e09af12..5c227a3 100644 --- a/components/modules/crypto/CryptoDemo.tsx +++ b/components/modules/crypto/CryptoDemo.tsx @@ -125,6 +125,7 @@ export default function CryptoDemo() { 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(() => { @@ -418,36 +419,41 @@ export default function CryptoDemo() { 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 = (estimator: string, horizon: string): number => { - if (ensemblePredictions && ensemblePredictions[activeTicker] && ensemblePredictions[activeTicker][estimator]) { - return ensemblePredictions[activeTicker][estimator][horizon] ?? 0.5; + 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.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 } + 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.60, T5: 0.59, T10: 0.54 }, - gb: { T1: 0.66, T5: 0.61, T10: 0.48 }, - lr: { T1: 0.58, T5: 0.55, T10: 0.56 }, - svm: { T1: 0.59, T5: 0.59, T10: 0.56 }, - mlp: { T1: 0.64, T5: 0.59, T10: 0.55 } + 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.65, T5: 0.58, T10: 0.52 }, - gb: { T1: 0.63, T5: 0.63, T10: 0.54 }, - lr: { T1: 0.59, T5: 0.58, T10: 0.54 }, - svm: { T1: 0.60, T5: 0.62, T10: 0.56 }, - mlp: { T1: 0.66, T5: 0.60, T10: 0.51 } + 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[activeTicker] ? activeTicker : 'BTC'; + const assetKey = defaultMapping[cleanTicker] ? cleanTicker : 'BTC'; return defaultMapping[assetKey][estimator]?.[horizon] ?? 0.5; }; @@ -533,9 +539,9 @@ export default function CryptoDemo() { const predictionsMap: Record> = {}; ESTIMATORS.forEach((est) => { predictionsMap[est.id] = { - T1: getPredictionProb(est.id, 'T1'), - T5: getPredictionProb(est.id, 'T5'), - T10: getPredictionProb(est.id, 'T10') + T1: getPredictionProb(activeCoin.ticker, est.id, 'T1'), + T5: getPredictionProb(activeCoin.ticker, est.id, 'T5'), + T10: getPredictionProb(activeCoin.ticker, est.id, 'T10') }; }); @@ -548,9 +554,9 @@ export default function CryptoDemo() { timestamp: now, predictions: predictionsMap, targetTimes: { - T1: now + 60 * 1000, // resolves in 60s for direct visual validation - T5: now + 300 * 1000, // resolves in 300s - T10: now + 600 * 1000 // resolves in 600s + 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 } }; @@ -558,7 +564,7 @@ export default function CryptoDemo() { setForecasts(nextForecasts); localStorage.setItem('crypto_bayes_forecasts', JSON.stringify(nextForecasts)); - setLearningLoopLog(`Registered active multi-model forecast for ${activeCoin.ticker} at $${entryPrice}. Evaluating T+1 (60s), T+5 (5m), and T+10 (10m).`); + 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); }; @@ -818,7 +824,7 @@ export default function CryptoDemo() { {HORIZONS.map((h) => { const trackerKey = `${est.id}_${h.id}`; const tracker = trackers[trackerKey] || { alpha: 1, beta: 1 }; - const prob = getPredictionProb(est.id, h.id); + const prob = getPredictionProb(activeTicker, est.id, h.id); const direction = prob > 0.5 ? 'UP' : 'DOWN'; const expValue = tracker.alpha / (tracker.alpha + tracker.beta); @@ -901,6 +907,23 @@ export default function CryptoDemo() { )} + {/* Sleek Dynamic Asset-Selector Tab-Bar */} +
+ {(['BTC', 'ETH', 'SOL'] as const).map((asset) => ( + + ))} +
+
@@ -915,12 +938,12 @@ export default function CryptoDemo() { - {forecasts.length === 0 ? ( + {filteredForecasts.length === 0 ? ( - + ) : ( - forecasts.map((fc) => { + filteredForecasts.map((fc) => { const now = Date.now(); const getHorizonStatus = (hKey: 'T1' | 'T5' | 'T10') => {
No forecasts registered yet.No forecasts registered for {feedbackFilterAsset} yet.