Skip to content

aether_quant.experience

Observation metrics and the simulated portfolio (queues stay in experience/).

Observation metrics and the simulated portfolio (queues stay in experience/).

SimulatedPortfolioState

Tracks fake cash/holdings/equity for a single algorithm run.

cash instance-attribute

cash = float(initial_cash)

cumulative_turnover instance-attribute

cumulative_turnover = 0.0

equity_curve instance-attribute

equity_curve: list[dict] = []

holdings instance-attribute

holdings: dict[str, dict[str, float]] = {}

initial_cash instance-attribute

initial_cash = float(initial_cash)

peak_equity instance-attribute

peak_equity = float(initial_cash)

trade_log instance-attribute

trade_log: list[dict] = []

enter_long

enter_long(symbol_key: str, close_price: float, target_weight: float, bar_index: int, slippage_bps: float = 0.0) -> None

exit

exit(symbol_key: str, close_price: float, bar_index: int) -> None

exit_using_last_known_price

exit_using_last_known_price(symbol_key: str, bar_index: int) -> None

Sibling of exit() (needs an explicit close_price, unavailable to main.py's per-bar asset-class-disablement sweep - it runs before Pass 1 builds this bar's close prices) and liquidate_all() (which already solves this exact problem for the whole portfolio via self._last_prices' per-symbol fallback, for the total-drawdown- breach path). This is liquidate_all()'s SELECTIVE sibling, exiting only symbol_key instead of every holding - delegates to exit() so there is exactly one place the realized-pnl/cash/trade_log math lives. No-op if symbol_key isn't currently held.

liquidate_all

liquidate_all(bar_index: int) -> None

mark_to_market

mark_to_market(prices_by_symbol: dict[str, float], bar_index: int | None = None) -> None

position_value

position_value(symbol_key: str) -> float

Current mark-to-market notional value of a held symbol, 0.0 if flat.

snapshot

snapshot(consume_realized_pnl: bool = True) -> dict[str, Any]

Portfolio snapshot compatible with build_experience_event(portfolio=...).

By default this consumes (clears) the pending realized-PnL value so it is attributed to exactly one experience event rather than bleeding into later, unrelated snapshots.

action_distribution

action_distribution(events: list[dict]) -> dict[str, int]

How many observation-mode events took each action.

compute_observation_summary

compute_observation_summary(events: list[dict]) -> dict[str, Any]

The observation-mode summary the readiness checks read: counts, distributions, rejections and the simulated record.

count_observations

count_observations(events: list[dict]) -> int

The number of observation-mode events.

rejected_by_reason

rejected_by_reason(events: list[dict]) -> dict[str, int]

How many observation-mode decisions were rejected for each reason.

signal_distribution

signal_distribution(events: list[dict]) -> dict[str, int]

How many observation-mode events carried each signal.

simulated_max_drawdown

simulated_max_drawdown(events: list[dict]) -> float

The largest peak-to-trough fall of the simulated equity in observation mode, as a negative fraction.

simulated_sharpe

simulated_sharpe(events: list[dict], periods_per_year: int = 252) -> float

The annualised Sharpe of the simulated equity in observation mode; 0.0 with fewer than two points.

simulated_win_loss

simulated_win_loss(events: list[dict]) -> dict[str, Any]

Wins, losses and win rate of the simulated round trips in observation mode.