Skip to content

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).

annualized_volatility instance-attribute

annualized_volatility: float

base_target_weight instance-attribute

base_target_weight: float

confidence_multiplier instance-attribute

confidence_multiplier: float

cost_multiplier class-attribute instance-attribute

cost_multiplier: float = 1.0

cost_sizing_reason class-attribute instance-attribute

cost_sizing_reason: str = 'cost_sizing_disabled_or_absent'

leverage_factor instance-attribute

leverage_factor: float

max_leverage instance-attribute

max_leverage: float

rank_multiplier class-attribute instance-attribute

rank_multiplier: float = 1.0

rank_sizing_reason class-attribute instance-attribute

rank_sizing_reason: str = 'rank_sizing_disabled_or_absent'

rl_multiplier class-attribute instance-attribute

rl_multiplier: float = 1.0

rl_sizing_reason class-attribute instance-attribute

rl_sizing_reason: str = 'rl_sizing_disabled_or_absent'

rolling_volatility instance-attribute

rolling_volatility: float

sizing_reason instance-attribute

sizing_reason: str

target_weight instance-attribute

target_weight: float

topology_multiplier instance-attribute

topology_multiplier: float

topology_sizing_reason instance-attribute

topology_sizing_reason: str

volatility_multiplier instance-attribute

volatility_multiplier: float

volatility_regime instance-attribute

volatility_regime: str

volatility_source class-attribute instance-attribute

volatility_source: str = 'rolling'

to_dict

to_dict() -> dict[str, Any]

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).