@ -347,7 +347,7 @@ def compute_return_max_long_score_v10(row: dict[str, Any]) -> float:
use_signal_strength_proxy = True ,
weights = _RETURN_MAX_LONG_V2_WEIGHTS ,
allow_generic_material_events = True ,
use_macro_regime_bonus= True ,
macro_regime_weight= 0.12 ,
)
@ -377,7 +377,40 @@ def compute_return_max_long_score_v9(row: dict[str, Any]) -> float:
use_signal_strength_proxy = True ,
weights = _RETURN_MAX_LONG_V2_WEIGHTS ,
allow_generic_material_events = True ,
use_prior_drift_momentum = True ,
prior_drift_weight = 0.10 ,
)
def compute_return_max_long_score_v11 ( row : dict [ str , Any ] ) - > float :
""" V11 = V5 + positive-only micro bonuses from macro regime and prior drift.
This keeps V5 eligibility intact and only nudges ordering for already - strong
candidates . Unlike v9 / v10 , adverse macro or negative prior drift do not
penalize the score .
"""
return _compute_return_max_long_score (
row ,
earnings_reaction_fallback = True ,
use_signal_strength_proxy = True ,
weights = _RETURN_MAX_LONG_V2_WEIGHTS ,
allow_generic_material_events = True ,
prior_drift_weight = 0.02 ,
macro_regime_weight = 0.03 ,
positive_only_aux_bonus = True ,
)
def compute_return_max_long_score_v11g ( row : dict [ str , Any ] ) - > float :
""" V11G = gentler V11, intended as a near-tiebreak perturbation. """
return _compute_return_max_long_score (
row ,
earnings_reaction_fallback = True ,
use_signal_strength_proxy = True ,
weights = _RETURN_MAX_LONG_V2_WEIGHTS ,
allow_generic_material_events = True ,
prior_drift_weight = 0.01 ,
macro_regime_weight = 0.02 ,
positive_only_aux_bonus = True ,
)
@ -391,8 +424,10 @@ def _compute_return_max_long_score(
use_zone_scoring : bool = False ,
use_market_confirmed_gate : bool = False ,
use_financial_bonus : bool = False ,
use_prior_drift_momentum : bool = False ,
use_macro_regime_bonus : bool = False ,
prior_drift_weight : float = 0.0 ,
macro_regime_weight : float = 0.0 ,
positive_only_aux_bonus : bool = False ,
use_earnings_surprise_bonus : bool = False ,
) - > float :
""" Long-biased score for return-max event strategies.
@ -486,11 +521,20 @@ def _compute_return_max_long_score(
if use_financial_bonus :
raw + = _financial_bonus_score ( row ) * 0.07
if use_prior_drift_momentum :
raw + = _prior_drift_momentum_score ( row ) * 0.10
if prior_drift_weight > 0.0 :
prior_signal = _prior_drift_momentum_score ( row )
if positive_only_aux_bonus :
prior_signal = max ( 0.0 , prior_signal )
raw + = prior_signal * prior_drift_weight
if use_macro_regime_bonus :
raw + = _macro_regime_score ( row ) * 0.12
if macro_regime_weight > 0.0 :
macro_signal = _macro_regime_score ( row )
if positive_only_aux_bonus :
macro_signal = max ( 0.0 , macro_signal )
raw + = macro_signal * macro_regime_weight
if use_earnings_surprise_bonus :
raw + = _earnings_surprise_bonus ( row ) * 0.10
return _clamp ( raw )
@ -764,6 +808,32 @@ def _financial_bonus_score(row: dict[str, Any]) -> float:
return min ( 1.0 , bonus )
def _earnings_surprise_bonus ( row : dict [ str , Any ] ) - > float :
""" Bonus from earnings surprise (actual vs estimated EPS).
Empirical finding : small beats ( 0 - 3 % ) have 82.4 % WR vs 54.8 % for big beats .
Moderate surprise creates strongest PEAD ( gradual repricing ) .
"""
event_type = str ( row . get ( " event_type " , " " ) ) . lower ( )
if event_type != " earnings_release " :
return 0.0
surprise = _safe_float ( row . get ( " earnings_surprise_pct " ) )
if surprise is None :
return 0.0
if 0 < surprise < = 3 :
return 1.0 # sweet spot: moderate beat
elif 3 < surprise < = 8 :
return 0.5 # decent beat but partially priced in
elif surprise > 8 :
return 0.0 # big beat = already priced in
elif surprise < = 0 :
return - 0.5 # miss = penalty
return 0.0
def _overheat_penalty ( row : dict [ str , Any ] ) - > float :
penalties : list [ float ] = [ ]
@ -1195,3 +1265,20 @@ def _text_sentiment_score(row: dict[str, Any]) -> float:
if n > - 0.005 :
return 0.35
return 0.2
def compute_return_max_long_score_v11 ( row : dict [ str , Any ] ) - > float :
""" V11 = V5 + earnings surprise bonus.
Uses actual vs estimated EPS surprise from Oracle earnings / surprise API .
Empirical finding : small beats ( 0 - 3 % ) have 82.4 % WR vs 54.8 % for big beats .
Moderate surprise = strongest PEAD drift ( gradual repricing ) .
"""
return _compute_return_max_long_score (
row ,
earnings_reaction_fallback = True ,
use_signal_strength_proxy = True ,
weights = _RETURN_MAX_LONG_V2_WEIGHTS ,
allow_generic_material_events = True ,
use_earnings_surprise_bonus = True ,
)