feat: replace regime monitor with v2 methodology
This commit is contained in:
+81
-53
@@ -439,106 +439,134 @@ export type RegimeBand = 'stable' | 'watch' | 'elevated' | 'breaking';
|
||||
export interface RegimeSignal {
|
||||
id: string;
|
||||
label: string;
|
||||
sub_score: number | null;
|
||||
weight: number;
|
||||
score: number | null;
|
||||
available: boolean;
|
||||
contribution: number;
|
||||
details?: Record<string, unknown>;
|
||||
}
|
||||
|
||||
export interface RegimeSubScore {
|
||||
export interface RegimePillar {
|
||||
id: string;
|
||||
label: string;
|
||||
score: number | null;
|
||||
weight: number;
|
||||
contribution: number;
|
||||
available: boolean;
|
||||
sensors: RegimeSignal[];
|
||||
}
|
||||
|
||||
export interface RegimeReading {
|
||||
score: number | null;
|
||||
band: RegimeBand | null;
|
||||
delta_7?: number | null;
|
||||
delta_30?: number | null;
|
||||
coverage: number;
|
||||
minimum_coverage: number;
|
||||
available_pillars: string[];
|
||||
pillars: RegimePillar[];
|
||||
trend?: { delta_7: number | null; delta_30: number | null };
|
||||
}
|
||||
|
||||
export interface RegimeHistoryPoint {
|
||||
date: string;
|
||||
index: number;
|
||||
early_warning: number | null;
|
||||
combined: number | null;
|
||||
state: number | null;
|
||||
warning: number | null;
|
||||
state_coverage: number | null;
|
||||
warning_coverage: number | null;
|
||||
basket_hash: string | null;
|
||||
}
|
||||
|
||||
export interface RegimeMonitor {
|
||||
available: boolean;
|
||||
reason?: string;
|
||||
methodology?: string;
|
||||
date?: string;
|
||||
total_score?: number;
|
||||
band?: RegimeBand;
|
||||
alert_threshold?: number;
|
||||
breakdown?: RegimeSignal[];
|
||||
state?: RegimeReading;
|
||||
warning?: RegimeReading;
|
||||
inputs?: {
|
||||
vix: number | null;
|
||||
vix_date: string | null;
|
||||
hy_oas: number | null;
|
||||
hy_oas_date: string | null;
|
||||
breadth_pct_above_200: number | null;
|
||||
breadth_date: string | null;
|
||||
fundamentals_fetched_at: string | null;
|
||||
fundamentals_effective_date: string | null;
|
||||
fundamentals_age_days: number | null;
|
||||
};
|
||||
trend?: { delta_7: number | null; delta_30: number | null };
|
||||
// Separate, observational early-warning score (breadth divergence) + a small
|
||||
// combined blend. Decoupled from the index above.
|
||||
early_warning?: RegimeSubScore;
|
||||
combined?: RegimeSubScore;
|
||||
basket?: {
|
||||
symbols: string[];
|
||||
hash: string;
|
||||
basket_asof: string;
|
||||
members_available: number | null;
|
||||
members_expected: number;
|
||||
history_kind: 'forward' | 'retrospective';
|
||||
};
|
||||
data_quality?: {
|
||||
minimum_coverage: number;
|
||||
oldest_market_input_age_days: number | null;
|
||||
stale_inputs: string[];
|
||||
inputs_fresh: boolean;
|
||||
snapshot_age_days?: number;
|
||||
is_fresh?: boolean;
|
||||
};
|
||||
quadrant_config?: { state_divider: number; warning_divider: number; margin: number };
|
||||
}
|
||||
|
||||
export interface RegimeFundamentals {
|
||||
f1_score: number;
|
||||
f3_score: number;
|
||||
f1_score: number | null;
|
||||
f3_score: number | null;
|
||||
locked: boolean;
|
||||
reasoning: string | null;
|
||||
fetched_at: string | null;
|
||||
effective_date: 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;
|
||||
breadth_basket: string[];
|
||||
basket_asof: string;
|
||||
fundamental_staleness_days: number;
|
||||
}
|
||||
|
||||
// Event study — measured lead time of early-warning indicators vs. drawdowns
|
||||
export interface EventStudyLeadStats {
|
||||
median_lead_days: number | null;
|
||||
events_with_signal: number;
|
||||
events_total: number;
|
||||
warn_threshold: number;
|
||||
mean_path: { rel_day: number; value: number }[];
|
||||
signal: {
|
||||
base_rate: number;
|
||||
horizon_days: number;
|
||||
rows: { threshold: number; precision: number | null; recall: number | null; alarms: number }[];
|
||||
};
|
||||
}
|
||||
|
||||
export interface EventStudyPerEvent {
|
||||
date: string;
|
||||
depth_pct: number;
|
||||
breadth_lead: number | null;
|
||||
coincident_lead: number | null;
|
||||
}
|
||||
|
||||
export interface EventStudyReport {
|
||||
available: boolean;
|
||||
reason?: string;
|
||||
methodology?: string;
|
||||
generated_at?: string;
|
||||
evaluation?: 'exploratory' | 'holdout';
|
||||
summary?: string;
|
||||
params?: {
|
||||
benchmark: string;
|
||||
outcome: string;
|
||||
event_threshold_pct: number;
|
||||
cooldown_days: number;
|
||||
event_cooldown_days: number;
|
||||
horizon_days: number;
|
||||
train_fraction: number;
|
||||
warn_percentile: number;
|
||||
warn_threshold: number;
|
||||
basket_hash: string;
|
||||
basket_asof: string;
|
||||
};
|
||||
events?: { date: string; index: number; depth_pct: number }[];
|
||||
indicators?: {
|
||||
breadth_divergence: EventStudyLeadStats;
|
||||
coincident_price: EventStudyLeadStats;
|
||||
sample?: {
|
||||
start: string;
|
||||
end: string;
|
||||
train_end: string;
|
||||
test_start: string;
|
||||
sessions: number;
|
||||
holdout_sessions: number;
|
||||
};
|
||||
per_event?: EventStudyPerEvent[];
|
||||
lead_delta_days?: number | null;
|
||||
recent_breadth?: { date: string; breadth: number; divergence: number | null }[];
|
||||
metrics?: {
|
||||
events: number;
|
||||
events_warned: number;
|
||||
events_missed: number;
|
||||
alarm_episodes: number;
|
||||
false_alarms: number;
|
||||
false_alarms_per_year: number;
|
||||
median_lead_days: number | null;
|
||||
};
|
||||
events?: { date: string; warned: boolean; lead_days: number | null }[];
|
||||
recent_breadth?: { date: string; breadth: number; warning: number | null }[];
|
||||
}
|
||||
|
||||
export interface AlertConfig {
|
||||
|
||||
Reference in New Issue
Block a user