diff --git a/model.py b/model.py index 91a6f88..b090e6d 100644 --- a/model.py +++ b/model.py @@ -163,6 +163,9 @@ def calculate_adaptive_volatility( """ Calculate volatility with adaptive window sizes based on market conditions. Returns a single volatility value for the most recent period. + + Incorporates long-term volatility as a stability baseline and additional + reference point for regime detection. """ df = df.copy() df["Log_Return"] = np.log(df["Close"]).diff() @@ -190,10 +193,17 @@ def calculate_adaptive_volatility( # Calculate regime indicators for recent period medium_vol_mean = medium_vol.rolling(min(90, len(recent_df))).mean() + long_vol_mean = long_vol.rolling(min(180, len(recent_df))).mean() + if medium_vol_mean.iloc[-1] == 0: vol_regime = pd.Series([1.0] * len(recent_df)) else: - vol_regime = short_vol / medium_vol_mean + # Compare short-term to both medium and long-term volatility + medium_regime = short_vol / medium_vol_mean + long_regime = short_vol / long_vol_mean + + # Use the more conservative (higher) regime indicator + vol_regime = pd.concat([medium_regime, long_regime], axis=1).max(axis=1) vol_regime = vol_regime.clip(vol_clip_min, vol_clip_max) @@ -219,24 +229,26 @@ def calculate_adaptive_volatility( ]: return df["Log_Return"].std() - # Calculate regime-based weights + # Calculate regime-based weights, now incorporating long-term volatility high_vol_weight = (latest_regime - vol_clip_min) / (vol_clip_max - vol_clip_min) - base_weights = np.array([0.2, 0.5, 0.3]) - stress_weights = np.array([0.4, 0.4, 0.2]) + base_weights = np.array([0.2, 0.5, 0.3]) # Short, medium, long weights + stress_weights = np.array( + [0.4, 0.4, 0.2] + ) # More weight on short-term during stress # Interpolate between base and stress weights weights = ( base_weights * (1 - high_vol_weight) + stress_weights * high_vol_weight ) - # Calculate final volatility + # Calculate final volatility using all three timeframes final_vol = ( final_short * weights[0] + final_medium * weights[1] + final_long * weights[2] ) - # Add uncertainty adjustment + # Add uncertainty adjustment based on regime changes regime_change = abs(vol_regime.diff()).fillna(0) regime_change_mean = regime_change.rolling(5, min_periods=1).mean().iloc[-1] if regime_change_mean == 0: