feat: add standalone AI/Tech regime-change monitor tab
A new /regime tab scoring how far the AI/Tech bull regime has deteriorated toward a re-rating as a single 0-100 index with per-signal breakdown and a 7/30-day trend. Intentionally decoupled: nothing reads its output to gate or score trades — the daily-pipeline membership is scheduling only. - regime_monitor_service: price sub-scores (P1-P6 via Alpaca, like market_regime), VIX + HY credit spreads via a small FRED helper, weighted aggregation over available signals (missing source -> n/a, dropped from the denominator), one snapshot row/day, and a ~90-day history backfill by replaying the already-fetched series as-of each past day. - F1/F3 fundamentals proposed by the configured grounded LLM (reuses sentiment_provider_service config resolution), with a manual override + lock. - regime_snapshots table (migration 011); endpoints on the existing market router; admin-editable weights/threshold; standalone /regime page. Data needs: prices via Alpaca, VIX/credit via FRED (optional key — signals show n/a without it). No LLM needed for history. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -263,6 +263,54 @@ export interface MarketRegime {
|
||||
computed_at?: string;
|
||||
}
|
||||
|
||||
// AI/Tech Regime-Change Monitor (standalone, observational)
|
||||
export type RegimeBand = 'stable' | 'watch' | 'elevated' | 'breaking';
|
||||
|
||||
export interface RegimeSignal {
|
||||
id: string;
|
||||
label: string;
|
||||
sub_score: number | null;
|
||||
weight: number;
|
||||
available: boolean;
|
||||
contribution: number;
|
||||
}
|
||||
|
||||
export interface RegimeMonitor {
|
||||
available: boolean;
|
||||
reason?: string;
|
||||
date?: string;
|
||||
total_score?: number;
|
||||
band?: RegimeBand;
|
||||
alert_threshold?: number;
|
||||
breakdown?: RegimeSignal[];
|
||||
inputs?: {
|
||||
vix: number | null;
|
||||
hy_oas: number | null;
|
||||
fundamentals_fetched_at: string | null;
|
||||
};
|
||||
trend?: { delta_7: number | null; delta_30: number | null };
|
||||
}
|
||||
|
||||
export interface RegimeFundamentals {
|
||||
f1_score: number;
|
||||
f3_score: number;
|
||||
locked: boolean;
|
||||
reasoning: string | null;
|
||||
fetched_at: string | null;
|
||||
source: string;
|
||||
capex?: Record<string, string>;
|
||||
good_news_stock_down?: string | null;
|
||||
}
|
||||
|
||||
export interface RegimeConfig {
|
||||
weights: Record<string, number>;
|
||||
alert_threshold: number;
|
||||
tickers: Record<string, unknown>;
|
||||
leader_weight: number;
|
||||
rs_lookback: number;
|
||||
fundamental_staleness_days: number;
|
||||
}
|
||||
|
||||
export interface AlertConfig {
|
||||
enabled: boolean;
|
||||
telegram_chat_id: string;
|
||||
|
||||
Reference in New Issue
Block a user