Skip to content

aether_quant.topology

The market topology overlay and its learned model's inputs.

The market topology overlay and its learned model's inputs.

MarketTopology dataclass

The market's correlation topology on one bar: nodes, links, clusters and the reasons for its state.

clusters instance-attribute

clusters: list[TopologyCluster]

correlation_change_history class-attribute instance-attribute

correlation_change_history: list[float] = field(default_factory=list)

correlations instance-attribute

correlations: dict[tuple[str, str], float]

dimensions instance-attribute

dimensions: dict
links: list[TopologyLink]

nodes instance-attribute

nodes: list[TopologyNode]

reasons instance-attribute

reasons: list[str]

state instance-attribute

state: str

to_dict

to_dict() -> dict[str, Any]

TopologyCluster dataclass

One cluster of correlated names, with its average correlation.

average_correlation instance-attribute

average_correlation: float

cluster_id instance-attribute

cluster_id: str

dominant_regime_label instance-attribute

dominant_regime_label: str

members instance-attribute

members: list[str]

to_dict

to_dict() -> dict[str, Any]

A correlation link between two names.

correlation instance-attribute

correlation: float

distance instance-attribute

distance: float

source instance-attribute

source: str

target instance-attribute

target: str

to_dict

to_dict() -> dict[str, Any]

TopologyNode dataclass

One name's place in the topology: its cluster, 3D position, distance from the market and risk label.

cluster_id instance-attribute

cluster_id: str

correlation_strength instance-attribute

correlation_strength: float

market_distance instance-attribute

market_distance: float

regime_label instance-attribute

regime_label: str

symbol instance-attribute

symbol: str

top_peer_returns instance-attribute

top_peer_returns: list[float]

top_peers instance-attribute

top_peers: list[str]

topology_risk instance-attribute

topology_risk: str

volatility_pressure instance-attribute

volatility_pressure: float

x instance-attribute

x: float

y instance-attribute

y: float

z instance-attribute

z: float

to_dict

to_dict() -> dict[str, Any]

apply_learned_topology

apply_learned_topology(deterministic_topology: dict[str, Any], symbol_features: dict[str, dict] | None = None, previous_neighbors_by_symbol: dict[str, list[str]] | None = None, model: dict[str, Any] | None = None, feature_schema: dict[str, Any] | None = None, *, temperature: float = DEFAULT_TEMPERATURE, top_n_neighbors: int = DEFAULT_TOP_N_NEIGHBORS, min_confidence_for_learned: float = DEFAULT_MIN_CONFIDENCE_FOR_LEARNED, max_offset_xy: float = DEFAULT_MAX_OFFSET_XY, max_offset_z: float = DEFAULT_MAX_OFFSET_Z) -> dict[str, Any]

Overlay learned cluster probabilities/uncertainty/offsets on top of a deterministic MarketTopology.to_dict()-shaped payload.

Never raises. Falls back to the deterministic node unchanged (position untouched, diagnostic fields zeroed) whenever the model is missing, a symbol has no current-bar features, or the model's confidence for that symbol is below min_confidence_for_learned.

build_market_topology

build_market_topology(returns_by_symbol: dict[str, list[float]], regime_labels_by_symbol: dict[str, str] | None = None, correlation_threshold: float = 0.6, link_threshold: float = 0.5, min_observations: int = 5, embedding_iterations: int = 100, previous_positions: dict[str, tuple[float, ...]] | None = None, convergence_tolerance: float | None = None, top_peers_n: int = 3, previous_correlations: dict[tuple[str, str], float] | None = None, correlation_stability_tolerance: float | None = None, embedding_dimensions: int = 2, correlation_stability_tolerance_percentile: float | None = None, correlation_change_history: list[float] | None = None, correlation_change_history_max_len: int = 50, elevated_volatility_threshold: float = ELEVATED_VOLATILITY_THRESHOLD, elevated_volatility_threshold_by_symbol: dict[str, float] | None = None) -> MarketTopology

embedding_dimensions (V4-W3, phase_v2.topology.embedding_dimensions, default 2) selects how many axes SMACOF embeds. At 2 - the default - every coordinate, reason string and dimension is byte-identical to the pre-V4 behavior, and z stays the volatility encoding. At 3, z becomes a real correlation-distance axis on the same 0..100 scale as x/y, and volatility is carried by node radius in the webui instead.

correlation_stability_tolerance_percentile (V4.9 Priority 1, default None) is a self-relative alternative to the fixed correlation_stability_tolerance above - development/Problems.md#36 found the fixed default poorly calibrated (the skip "essentially never fires" against synthetic data, and this environment can't run a real backtest to calibrate a better fixed number). When set, the effective tolerance each bar is the given percentile of correlation_change_history (a rolling window of RECENT PRIOR bars' own max-pairwise-correlation-change values, NOT including this bar's - avoids the circularity of a bar judging itself), making the skip rate a mathematically-guaranteed function of the chosen percentile regardless of the real correlation-noise distribution. Takes priority over correlation_stability_tolerance when set; None (the default) reproduces the fixed-tolerance behavior byte-identically. The caller (main.py) is expected to thread correlation_change_history through bar-to-bar exactly like previous_positions/previous_correlations - read this call's returned MarketTopology.correlation_change_history and pass it back in as next bar's correlation_change_history.

elevated_volatility_threshold (V5.2.6, development/Problems.md, default matches the module's own ELEVATED_VOLATILITY_THRESHOLD constant exactly - a no-op unless a caller passes a different value) is the volatility_pressure cutoff for a node's topology_risk becoming "elevated" - which analyzer/market_analyzer.py::build_market_analysis_decision()'s Priority 3 uses to unconditionally override any directional signal. Threaded through (not just a bare module constant) so main.py can raise it to a value derived from this backtest universe's own real historical volatility_pressure distribution, narrowing the override to genuinely extreme readings instead of a fixed, ungrounded 0.45.

elevated_volatility_threshold_by_symbol (V5.5.0, Problems.md #129, default None = every symbol uses the single threshold above) lets a symbol carry its own cutoff - see resolve_elevated_volatility_thresholds(). Crypto's annualized volatility sits structurally above 0.45, so under one global cutoff every crypto node was permanently "elevated" and the analyzer's Priority 3 cancelled every BTC/LTC directional signal (13 of its 26 book selections in the 2026-08-27 backtest).

learned_sizing_inputs

learned_sizing_inputs(vector: dict[str, Any], model: dict[str, Any] | None, feature_schema: dict[str, Any] | None, *, cluster_regime_label: str | None = None, peer_distance: float = 0.5, temperature: float = DEFAULT_TEMPERATURE, min_confidence_for_learned: float = DEFAULT_MIN_CONFIDENCE_FOR_LEARNED) -> dict[str, Any]

The three numbers risk.position_sizing.topology_sizing_multiplier reads, for ONE node from its feature vector alone: the same prototype distances, softmax confidence and regime-mismatch term _score_node computes. The peer term (_jaccard_distance of the learned neighbours vs the deterministic cluster peers) needs the whole bar's topology, so offline callers pass it as peer_distance (a bracket, 0.0..1.0). cluster_regime_label is the deterministic cluster's dominant regime; None means "no mismatch information" (term 0). Never raises: a missing or malformed model gives the fallback no-op.

liquidity_score_from_decision

liquidity_score_from_decision(liquidity: dict[str, Any]) -> float

Maps a liquidity.market_liquidity.LiquidityDecision-shaped dict (or any dict carrying participation_rate/estimated_slippage) into a single 0..1 liquidity_score feature - higher is more liquid. Shared by train_topology.py (offline training) and main.py (runtime) so both sides compute this feature identically.

rank_correlated_peers

rank_correlated_peers(symbol: str, eligible_symbols: list[str], correlation_fn: Callable[[str, str], float], top_n: int) -> list[str]

Ranks every OTHER eligible symbol by descending correlation to symbol across the WHOLE eligible universe (not just symbol's own cluster - a correlation_threshold-defined cluster can be much smaller than top_n), returning up to top_n symbols. Ties broken alphabetically for determinism (matches this module's existing tie-breaking convention, e.g. sorted_roots/nodes.sort() below).

rank_correlated_peers_from_row

rank_correlated_peers_from_row(row_index: int, symbols: list[str], correlation_row: ArrayLike, top_n: int, alphabetical_positions: ArrayLike | None = None) -> list[str]

rank_correlated_peers() on one row of the full correlation matrix (V5.8.0): the same ordering - descending correlation, ties by symbol name - via one stable lexsort instead of a Python sort with a lookup per pair. symbols must be in the matrix's row order; alphabetical_positions (rank of each symbol's name) defaults to the row order, which equals alphabetical order for build_market_topology()'s sorted eligible symbols.

resolve_elevated_volatility_thresholds

resolve_elevated_volatility_thresholds(raw_threshold: float | dict[str, Any] | None, asset_class_by_symbol: dict[str, str | None]) -> tuple[float, dict[str, float]]

V5.5.0 (Problems.md #129) - normalize phase_v2.topology.elevated_volatility_threshold.

Accepts the legacy bare float (one cutoff for everyone - unchanged behavior) or a dict like {"default": 0.45, "crypto": 1.2} keyed by asset class. Returns (default_threshold, {symbol: threshold}) where the per-symbol map only holds symbols whose class has its own entry. Malformed/non-finite/non-positive entries are ignored, never raised on.