aether_quant.sizing¶
Position sizing, grouped by the job (V6.6.5): Kelly, volatility targeting, the live path's bounded sizing and the per-name cap. Each name is the object the system itself uses.
Position sizing, grouped by the job (V6.6.5): Kelly, volatility targeting, the live path's bounded sizing and the per-name cap. Each name is the object the system itself uses.
PositionSizingDecision
dataclass
¶
One position's sizing: the base and final weight and every multiplier between them (volatility, topology, rank, RL, cost).
cost_sizing_reason
class-attribute
instance-attribute
¶
cost_sizing_reason: str = 'cost_sizing_disabled_or_absent'
rank_sizing_reason
class-attribute
instance-attribute
¶
rank_sizing_reason: str = 'rank_sizing_disabled_or_absent'
rl_sizing_reason
class-attribute
instance-attribute
¶
rl_sizing_reason: str = 'rl_sizing_disabled_or_absent'
build_dynamic_position_sizing ¶
build_dynamic_position_sizing(base_target_weight: float, confidence: float, rolling_volatility: float, max_position_weight: float, target_daily_volatility: float = 0.015, min_position_weight: float = 0.0, low_volatility_threshold: float = 0.01, high_volatility_threshold: float = 0.03, min_volatility_multiplier: float = 0.35, max_volatility_multiplier: float = 1.25, max_leverage: float = 1.0, topology_source: str | None = None, topology_confidence: float | None = None, topology_disagreement: float | None = None, min_topology_multiplier: float = 0.5, max_topology_multiplier: float = 1.0, predicted_volatility: float | None = None, use_predicted_volatility: bool = False, predicted_rank_20d: float | None = None, rank_sizing_enabled: bool = False, min_rank_multiplier: float = 0.75, max_rank_multiplier: float = 1.25, rl_model: dict[str, Any] | None = None, rl_state: dict[str, Any] | None = None, rl_sizing_enabled: bool = False, min_rl_multiplier: float = 0.6, max_rl_multiplier: float = 1.0) -> PositionSizingDecision
Size one position: the base weight scaled by confidence, volatility, topology, rank, RL and cost multipliers, never past the cap and never flipped.
cap_target_weight ¶
cap_target_weight(target_weight: float, current_exposure: float, exposure_cap: float) -> tuple[float, bool]
(weight, blocked): the target clipped to the exposure left under the cap, sign preserved. A non-finite target is
blocked (V6.4.3: nan >= 0.0 is False, so a NaN target came out as a full short of the remaining capacity).
kelly_fraction ¶
kelly_fraction(mean: float, variance: float, *, fraction: float = 0.5, cap: float = 1.0) -> float
fraction * mean / variance, clipped to [-cap, cap]. Zero for a non-positive or non-finite variance or input.
kelly_weights ¶
kelly_weights(mu: ndarray, cov: ndarray, *, fraction: float = 0.5, gross_cap: float = 1.0, ridge: float = 1e-08) -> np.ndarray
fraction * solve(cov + ridge*I, mu), scaled down (never up) so that sum(|w|) <= gross_cap. Zeros when an input
is non-finite, the shapes disagree, or the system is singular.
realized_vol ¶
realized_vol(returns: Series, *, window: int = 20, annualization: int = 252) -> pd.Series
Rolling sample standard deviation of returns times sqrt(annualization); NaN until window finite values.
volatility_target_weights ¶
volatility_target_weights(weights: Mapping[str, float], cov: DataFrame, *, target_annual_vol: float, max_leverage: float = 1.0, annualization: int = 252) -> dict[str, float]
Scale weights so that sqrt(w' cov w * annualization) equals target_annual_vol (cov is of per-period returns),
then cap gross exposure at max_leverage. A name missing from cov is dropped; a non-finite or zero risk returns the
weights capped but unscaled. A target of zero is a flat book; a negative target or leverage raises ValueError
(V6.6.7, #376, formal/AetherFormal/VolTarget.lean: before, a zero target returned the weights unscaled and a negative
leverage was silently read as positive).