Actually use long-term vol in adaptive calculation.
This commit is contained in:
@@ -163,6 +163,9 @@ def calculate_adaptive_volatility(
|
|||||||
"""
|
"""
|
||||||
Calculate volatility with adaptive window sizes based on market conditions.
|
Calculate volatility with adaptive window sizes based on market conditions.
|
||||||
Returns a single volatility value for the most recent period.
|
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 = df.copy()
|
||||||
df["Log_Return"] = np.log(df["Close"]).diff()
|
df["Log_Return"] = np.log(df["Close"]).diff()
|
||||||
@@ -190,10 +193,17 @@ def calculate_adaptive_volatility(
|
|||||||
|
|
||||||
# Calculate regime indicators for recent period
|
# Calculate regime indicators for recent period
|
||||||
medium_vol_mean = medium_vol.rolling(min(90, len(recent_df))).mean()
|
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:
|
if medium_vol_mean.iloc[-1] == 0:
|
||||||
vol_regime = pd.Series([1.0] * len(recent_df))
|
vol_regime = pd.Series([1.0] * len(recent_df))
|
||||||
else:
|
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)
|
vol_regime = vol_regime.clip(vol_clip_min, vol_clip_max)
|
||||||
|
|
||||||
@@ -219,24 +229,26 @@ def calculate_adaptive_volatility(
|
|||||||
]:
|
]:
|
||||||
return df["Log_Return"].std()
|
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)
|
high_vol_weight = (latest_regime - vol_clip_min) / (vol_clip_max - vol_clip_min)
|
||||||
base_weights = np.array([0.2, 0.5, 0.3])
|
base_weights = np.array([0.2, 0.5, 0.3]) # Short, medium, long weights
|
||||||
stress_weights = np.array([0.4, 0.4, 0.2])
|
stress_weights = np.array(
|
||||||
|
[0.4, 0.4, 0.2]
|
||||||
|
) # More weight on short-term during stress
|
||||||
|
|
||||||
# Interpolate between base and stress weights
|
# Interpolate between base and stress weights
|
||||||
weights = (
|
weights = (
|
||||||
base_weights * (1 - high_vol_weight) + stress_weights * high_vol_weight
|
base_weights * (1 - high_vol_weight) + stress_weights * high_vol_weight
|
||||||
)
|
)
|
||||||
|
|
||||||
# Calculate final volatility
|
# Calculate final volatility using all three timeframes
|
||||||
final_vol = (
|
final_vol = (
|
||||||
final_short * weights[0]
|
final_short * weights[0]
|
||||||
+ final_medium * weights[1]
|
+ final_medium * weights[1]
|
||||||
+ final_long * weights[2]
|
+ final_long * weights[2]
|
||||||
)
|
)
|
||||||
|
|
||||||
# Add uncertainty adjustment
|
# Add uncertainty adjustment based on regime changes
|
||||||
regime_change = abs(vol_regime.diff()).fillna(0)
|
regime_change = abs(vol_regime.diff()).fillna(0)
|
||||||
regime_change_mean = regime_change.rolling(5, min_periods=1).mean().iloc[-1]
|
regime_change_mean = regime_change.rolling(5, min_periods=1).mean().iloc[-1]
|
||||||
if regime_change_mean == 0:
|
if regime_change_mean == 0:
|
||||||
|
|||||||
Reference in New Issue
Block a user