diff --git a/ARCHITECT_HANDOVER.md b/ARCHITECT_HANDOVER.md index 417b013..ff33fe1 100644 --- a/ARCHITECT_HANDOVER.md +++ b/ARCHITECT_HANDOVER.md @@ -136,3 +136,33 @@ Indicators in the cockpit cards use HSL-tailored status lights (Emerald-Green, A } } ``` + +### PEAD Drift Radar API Response Schema (`/api/scanner`) +```json +{ + "results": [ + { + "ticker": "NVDA", + "name": "NVIDIA Corporation", + "peadSector": "Technology", + "announcementDate": "2026-05-20", + "daysElapsed": 25, + "epsActual": 6.12, + "epsConsensus": 5.58, + "surprisePercent": 9.68, + "driftStatus": "Active Drift", + "isLiveApi": true + } + ], + "isShieldActive": false +} +``` + +--- + +## 4. Fallback Protection & Operational Transparency Levels +The workstation enforces zero silent caching or historical data ingestion: +* **PEAD Drift Radar**: Uses a dynamic state flag `isLivePeadApi` to toggle status rendering. + * *Green Badge (`🟢 LIVE EPS FEED`)*: FMP API endpoint responded with real-world quarterly reports (`isLiveApi: true`). + * *Amber Badge (`⚠️ ARCHIV-DATEN (API OFFLINE)`)*: Live API timeout, failure, or developer shield fallback active (`isLiveApi: false`). + diff --git a/DEV_LOG.md b/DEV_LOG.md index 899bd41..13d0f9b 100644 --- a/DEV_LOG.md +++ b/DEV_LOG.md @@ -288,6 +288,18 @@ 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] - PEAD Fallback Transparency Warning Graphic (#ISSUE-023-WARN) + +### Added +* **Transparency Flag Ingestion**: Refactored `fetchFmpEarningsSurprise` and `getSimulatedPEAD` in [/api/scanner/route.ts](file:///c:/Users/jannr/.gemini/antigravity/scratch/investment-sandbox/app/api/scanner/route.ts) to return `isLiveApi: true` upon successful live API queries and `isLiveApi: false` on failure or simulated fallbacks. +* **Dynamic Warning Badges**: Declared a state hook `isLivePeadApi` in [ScannerDemo.tsx](file:///c:/Users/jannr/.gemini/antigravity/scratch/investment-sandbox/components/modules/scanner/ScannerDemo.tsx) and bound it to scan responses in `handleMarketScan`. Renders green `"🟢 LIVE EPS FEED"` and amber `"⚠️ ARCHIV-DATEN (API OFFLINE)"` status badges adjacent to the PEAD Drift Radar header title depending on the scan api status. + +### 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 7ccf102..c2058b9 100644 --- a/QUANT_ROADMAP.md +++ b/QUANT_ROADMAP.md @@ -38,6 +38,9 @@ This document serves as the permanent, centralized system architecture design an * **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)**. +* **Phase 8.0: Isolated PEAD Screener & Fallback Warning Graphic** + * *Features*: Integrated zero-coupling Post-Earnings Announcement Drift (PEAD) Screener parsing reported vs. consensus EPS surprise vectors. Implemented an `isLiveApi` flag to detect and handle offline API or rate-limit simulated fallbacks. Mounted glassmorphic warning status badges (`🟢 LIVE EPS FEED` vs `⚠️ ARCHIV-DATEN (API OFFLINE)`) in the frontend header to prevent trading on historical cached data without operational awareness. + * *Status*: **Fully Operational (Production Lock)**. --- diff --git a/app/api/scanner/route.ts b/app/api/scanner/route.ts index fec6951..36c190d 100644 --- a/app/api/scanner/route.ts +++ b/app/api/scanner/route.ts @@ -27,6 +27,7 @@ interface TickerDetails { epsConsensus?: number; surprisePercent?: number; driftStatus?: string; + isLiveApi?: boolean; } // 14-day Welles Wilder RSI solver @@ -412,6 +413,7 @@ function getSimulatedPEAD(ticker: string): { epsConsensus: number; surprisePercent: number; driftStatus: 'Active Drift' | 'Consolidating'; + isLiveApi: boolean; } { const getSector = (t: string) => { const tech = ['AAPL', 'MSFT', 'NVDA', 'AMD', 'SMCI', 'ADBE', 'CRM', 'AVGO', 'QCOM', 'TXN', 'INTC', 'MU', 'AMAT', 'LRCX', 'PLTR']; @@ -438,7 +440,8 @@ function getSimulatedPEAD(ticker: string): { epsActual: 0, epsConsensus: 0, surprisePercent: 0, - driftStatus: 'Consolidating' + driftStatus: 'Consolidating', + isLiveApi: false }; } @@ -464,7 +467,8 @@ function getSimulatedPEAD(ticker: string): { epsActual, epsConsensus, surprisePercent, - driftStatus + driftStatus, + isLiveApi: false }; } @@ -476,6 +480,7 @@ async function fetchFmpEarningsSurprise(ticker: string, apiKey: string): Promise epsConsensus: number; surprisePercent: number; driftStatus: 'Active Drift' | 'Consolidating'; + isLiveApi: boolean; }> { const getSector = (t: string) => { const tech = ['AAPL', 'MSFT', 'NVDA', 'AMD', 'SMCI', 'ADBE', 'CRM', 'AVGO', 'QCOM', 'TXN', 'INTC', 'MU', 'AMAT', 'LRCX', 'PLTR']; @@ -502,7 +507,8 @@ async function fetchFmpEarningsSurprise(ticker: string, apiKey: string): Promise epsActual: 0, epsConsensus: 0, surprisePercent: 0, - driftStatus: 'Consolidating' + driftStatus: 'Consolidating', + isLiveApi: false }; } @@ -536,7 +542,8 @@ async function fetchFmpEarningsSurprise(ticker: string, apiKey: string): Promise epsActual, epsConsensus, surprisePercent, - driftStatus + driftStatus, + isLiveApi: true }; } } @@ -545,7 +552,10 @@ async function fetchFmpEarningsSurprise(ticker: string, apiKey: string): Promise } // Fallback to deterministic simulation - return getSimulatedPEAD(ticker); + return { + ...getSimulatedPEAD(ticker), + isLiveApi: false + }; } export async function GET(request: Request) { diff --git a/components/modules/scanner/ScannerDemo.tsx b/components/modules/scanner/ScannerDemo.tsx index b65c727..a414394 100644 --- a/components/modules/scanner/ScannerDemo.tsx +++ b/components/modules/scanner/ScannerDemo.tsx @@ -40,6 +40,7 @@ interface PEADData { epsConsensus: number; surprisePercent: number; driftStatus: 'Active Drift' | 'Consolidating'; + isLiveApi?: boolean; } export default function ScannerDemo() { @@ -71,6 +72,7 @@ export default function ScannerDemo() { { ticker: 'TSLA', name: 'Tesla Inc.', peadSector: 'Consumer Goods', announcementDate: '2026-04-23', daysElapsed: 52, epsActual: 0.45, epsConsensus: 0.51, surprisePercent: -11.76, driftStatus: 'Consolidating' }, { ticker: 'JPM', name: 'JPMorgan Chase & Co.', peadSector: 'Financial Services', announcementDate: '2026-04-12', daysElapsed: 63, epsActual: 4.44, epsConsensus: 4.15, surprisePercent: 6.99, driftStatus: 'Consolidating' } ]); + const [isLivePeadApi, setIsLivePeadApi] = useState(false); // Cache for metadata and prices retrieved dynamically const [alertsMetadata, setAlertsMetadata] = useState>({}); @@ -193,12 +195,16 @@ export default function ScannerDemo() { epsActual: r.epsActual || 0, epsConsensus: r.epsConsensus || 0, surprisePercent: r.surprisePercent || 0, - driftStatus: r.driftStatus || 'Consolidating' + driftStatus: r.driftStatus || 'Consolidating', + isLiveApi: r.isLiveApi }); }); peadList.sort((a, b) => Math.abs(b.surprisePercent) - Math.abs(a.surprisePercent)); setPeadData(peadList); + const hasLivePead = peadList.some(item => item.isLiveApi === true); + setIsLivePeadApi(hasLivePead); + // Update global store alerts for Sandbox module use updateScannerAlerts(newAlerts); @@ -766,12 +772,27 @@ export default function ScannerDemo() { > 3-Tier Screener Capacity Grid - +
+ + {leftPanelTab === 'pead' && ( + isLivePeadApi ? ( + + + 🟢 LIVE EPS FEED + + ) : ( + + + ⚠️ ARCHIV-DATEN (API OFFLINE) + + ) + )} +
Modus: {scanMode.toUpperCase()} | Region: {marketRegion.toUpperCase()}