Actually use long-term vol in adaptive calculation.

This commit is contained in:
sam
2024-11-16 21:56:39 -08:00
parent 50f3f76830
commit 3158d7479d
+18 -6
View File
@@ -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: