import sys import os import pytest import numpy as np import pandas as pd _this_dir = os.path.dirname(os.path.abspath(__file__)) sys.path.insert(0, _this_dir) from regime_detection import detect_volatility_regime, dynamic_risk_aversion from config import DEFAULT_CONFIG def test_detect_volatility_regime_sorting(): rng = np.random.default_rng(42) # Generate 3 distinct regimes to ensure sorting logic works # Low vol (bull), Med vol (normal), High vol (crash) rets_low = rng.normal(0.001, 0.005, 100) rets_med = rng.normal(0.000, 0.015, 100) rets_high = rng.normal(-0.002, 0.040, 100) # Combine into a single series all_rets = np.concatenate([rets_low, rets_med, rets_high]) series = pd.Series(all_rets) res = detect_volatility_regime(series, cfg=DEFAULT_CONFIG, silent=True) # Verify the HMM detected the high vol regime at the end assert bool(res["is_high_vol"]) is True assert res["current_regime"] == "Crash / High Volatility" assert res["severity_score"] > 1.0 # Verify the state sorting worked (variances should be strictly increasing) regime_vols = res["details"]["regime_vols"] assert regime_vols[0] < regime_vols[1] < regime_vols[2] def test_dynamic_risk_aversion_vix_crisis(): """Base inputs (Aggressive profile < 6)""" base_input = 4 base_factor = 2.0 # Crisis VIX vix = 40.0 adj_input, adj_factor = dynamic_risk_aversion(vix, base_input, base_factor, silent=True) # Should clamp aggressive risk profile to conservative assert adj_input == 7 assert adj_factor >= 7.5 def test_dynamic_risk_aversion_vix_complacent(): """Aggressive inputs""" base_input = 8 base_factor = 2.0 # Complacent VIX vix = 10.0 adj_input, adj_factor = dynamic_risk_aversion(vix, base_input, base_factor, silent=True) assert adj_input == base_input assert adj_factor < base_factor def test_detect_volatility_regime_zeros_boundary(): """HMM should gracefully handle a completely flat/zero return series without crashing.""" series = pd.Series(np.zeros(200)) res = detect_volatility_regime(series, cfg=DEFAULT_CONFIG, silent=True) # Should fallback to baseline or calm regime assert res["severity_score"] == 1.0 assert not res["is_high_vol"]