aether-quant 0.0.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (99) hide show
  1. aether_quant-0.0.1.dist-info/METADATA +7 -0
  2. aether_quant-0.0.1.dist-info/RECORD +99 -0
  3. aether_quant-0.0.1.dist-info/WHEEL +5 -0
  4. aether_quant-0.0.1.dist-info/entry_points.txt +2 -0
  5. aether_quant-0.0.1.dist-info/licenses/LICENSE +133 -0
  6. aether_quant-0.0.1.dist-info/top_level.txt +13 -0
  7. analyzer/README.md +69 -0
  8. analyzer/__init__.py +17 -0
  9. analyzer/market_analyzer.py +521 -0
  10. aq_cli.py +3633 -0
  11. audit/README.md +47 -0
  12. audit/__init__.py +38 -0
  13. audit/hash_chain.py +52 -0
  14. audit/postgres_audit.py +61 -0
  15. audit/postgres_worker.py +402 -0
  16. audit/redis_queue.py +124 -0
  17. audit/status_export.py +62 -0
  18. data_pipeline/README.md +257 -0
  19. data_pipeline/__init__.py +6 -0
  20. data_pipeline/bar_synthesis.py +97 -0
  21. data_pipeline/dividend_backfill.py +243 -0
  22. data_pipeline/factor_file_backfill.py +276 -0
  23. data_pipeline/fetch.py +206 -0
  24. data_pipeline/fred_backfill.py +435 -0
  25. data_pipeline/ib_backfill.py +287 -0
  26. data_pipeline/v2_manifest.py +75 -0
  27. data_pipeline/yfinance_backfill.py +501 -0
  28. evaluation/README.md +152 -0
  29. evaluation/__init__.py +73 -0
  30. evaluation/ablation.py +310 -0
  31. evaluation/benchmark_comparison.py +195 -0
  32. evaluation/confidence_threshold_calibration.py +157 -0
  33. evaluation/factor_neutralization_check.py +94 -0
  34. evaluation/feature_parity.py +321 -0
  35. evaluation/feature_reconciliation.py +286 -0
  36. evaluation/impact_model.py +77 -0
  37. evaluation/kill_switch_replay.py +186 -0
  38. evaluation/limit_fill_simulator.py +152 -0
  39. evaluation/model_predictions.py +192 -0
  40. evaluation/monte_carlo.py +161 -0
  41. evaluation/public_benchmarks.py +117 -0
  42. evaluation/rank_book_simulator.py +494 -0
  43. evaluation/rank_ic_core.py +204 -0
  44. evaluation/rank_signal_calibration.py +690 -0
  45. evaluation/rolling_ic_gate_calibration.py +190 -0
  46. evaluation/rolling_ic_gate_replay.py +138 -0
  47. execution/README.md +281 -0
  48. execution/__init__.py +80 -0
  49. execution/config_cache.py +48 -0
  50. execution/cost_model.py +213 -0
  51. execution/lean_config_render.py +131 -0
  52. execution/live_credentials.py +38 -0
  53. execution/live_credentials_io.py +52 -0
  54. execution/order_gate.py +388 -0
  55. execution/paper_readiness.py +181 -0
  56. execution/paper_readiness_io.py +54 -0
  57. execution/paper_readiness_report.py +103 -0
  58. execution/paper_readiness_scheduler.py +137 -0
  59. execution/reconciliation.py +160 -0
  60. execution/runtime_config_io.py +38 -0
  61. execution/secret_scan.py +73 -0
  62. features/README.md +77 -0
  63. features/__init__.py +137 -0
  64. features/alt_data_features.py +154 -0
  65. features/bond_features.py +275 -0
  66. features/cross_asset_sensitivity.py +79 -0
  67. features/derivatives_macro_features.py +72 -0
  68. features/macro_features.py +79 -0
  69. features/options_greeks.py +329 -0
  70. features/sector_map.py +53 -0
  71. features/technical_indicators.py +185 -0
  72. generate_backtest_report.py +311 -0
  73. generate_evaluation_report.py +712 -0
  74. inference/README.md +105 -0
  75. inference/__init__.py +36 -0
  76. inference/exported_model.py +929 -0
  77. inference/parallel_inference.py +160 -0
  78. inference/strategy_selector_inference.py +75 -0
  79. json_safety.py +130 -0
  80. portfolio/README.md +447 -0
  81. portfolio/__init__.py +41 -0
  82. portfolio/book_construction.py +786 -0
  83. portfolio/book_neutrality.py +178 -0
  84. portfolio/hrp_allocation.py +159 -0
  85. portfolio/options_arbitrage_detector.py +232 -0
  86. portfolio/options_assignment_risk.py +119 -0
  87. portfolio/options_margin_sizing.py +333 -0
  88. portfolio/options_strategy.py +1999 -0
  89. portfolio/rank_signal.py +219 -0
  90. portfolio/rolling_ic_gate.py +183 -0
  91. risk/README.md +275 -0
  92. risk/__init__.py +38 -0
  93. risk/asset_class_router.py +584 -0
  94. risk/forex_risk.py +158 -0
  95. risk/futures_risk.py +202 -0
  96. risk/kill_switch.py +261 -0
  97. risk/manual_override.py +118 -0
  98. risk/position_sizing.py +303 -0
  99. risk/rl_sizing.py +189 -0
risk/README.md ADDED
@@ -0,0 +1,275 @@
1
+ # risk
2
+
3
+ Dynamic, per-asset-class risk control: volatility-adjusted position sizing,
4
+ leverage caps, drawdown-aware sizing, liquidity checks, market-impact/slippage
5
+ controls, and asset-class dispatch (equity/crypto/bond, futures, options,
6
+ forex). Equity/crypto/bond flow through the shared volatility-scaled sizer;
7
+ futures/options/forex get dedicated sizers behind one dispatch point
8
+ (`asset_class_router.py`) so downstream consumers stay asset-class-agnostic.
9
+
10
+ ## Base sizing — `position_sizing.py`
11
+
12
+ `build_dynamic_position_sizing(...)` → `PositionSizingDecision`.
13
+ `classify_volatility_regime()` buckets `rolling_volatility_20d` into
14
+ low/normal/high, driving `volatility_multiplier` (shrinks in high-vol,
15
+ expands in low-vol toward a target daily volatility). Full chain:
16
+
17
+ `volatility_multiplier × confidence_multiplier(0.5+0.5*confidence) ×
18
+ topology_multiplier × rank_multiplier × rl_multiplier`, then
19
+ `cost_sizing_multiplier()` on top. Every optional multiplier below is a
20
+ strict `1.0` no-op unless its own config flag is on and its model output is
21
+ present.
22
+
23
+ | Multiplier | Function | Config flag (default) | Bounds / shape |
24
+ |---|---|---|---|
25
+ | Volatility source swap | `_resolve_effective_volatility()` | `phase_v2.dynamic_risk.use_predicted_volatility` (`false`) | swaps `rolling_volatility_20d` → predicted |
26
+ | Topology | `topology_sizing_multiplier()` | `phase_v2.dynamic_risk.topology_sizing_enabled` (`true`) | `[min,1.0]`, shrink-only |
27
+ | Rank | `rank_sizing_multiplier()` | `phase_v2.dynamic_risk.rank_sizing_enabled` (`false`) | `[0.75,1.25]`, can amplify |
28
+ | RL overlay | `rl_sizing.py::rl_sizing_multiplier()` | `phase_v2.dynamic_risk.rl_sizing_enabled` (`false`) | `[0.6,1.0]`, shrink-only |
29
+ | Cost | `cost_sizing_multiplier()` | `phase_v2.costs.cost_sizing_enabled` (`false`) | `<=1.0`, shrink-only |
30
+
31
+ ### Predicted volatility
32
+
33
+ `build_dynamic_position_sizing(..., predicted_volatility=None,
34
+ use_predicted_volatility=False)` swaps the number driving
35
+ `volatility_regime`/`annualized_volatility`/`volatility_multiplier` from
36
+ trailing `rolling_volatility_20d` to the forward-looking `volatility` head of
37
+ the multi-task model (`train_multitask.py`/`AetherNetMultiTask`).
38
+ `_resolve_effective_volatility()` falls back to rolling whenever the flag is
39
+ off or the prediction is `None`. `PositionSizingDecision.volatility_source`
40
+ (`"rolling"`/`"predicted"`) records which was used. Fed from
41
+ `gating_payload["final_volatility"]` (`moe/gating.py::_weighted_blend()`,
42
+ also includes the sequence encoder when `phase_v2.gating_network.sequence_weight`
43
+ is on — see `moe/README.md`), not the raw multitask output directly. Wired
44
+ via `main.py::_build_dynamic_sizing_payload(..., predicted_volatility=...)`.
45
+ Sizing only, never routing — `analyzer/market_analyzer.py` never reads it.
46
+
47
+ ### Topology multiplier (shrink-only)
48
+
49
+ `topology_sizing_multiplier(topology_source, topology_confidence,
50
+ topology_disagreement, min_topology_multiplier=0.5,
51
+ max_topology_multiplier=1.0)`. No-op unless `topology_source == "learned"`
52
+ (the `topology/learned_topology.py` overlay's own confidence-gated label);
53
+ otherwise `multiplier = min + (max-min) * confidence * (1-disagreement)`,
54
+ always `<= max`. Config: `phase_v2.dynamic_risk.topology_sizing_enabled`
55
+ (`true`), `min_topology_multiplier`/`max_topology_multiplier` (`0.5`/`1.0`)
56
+ — independent of `phase_v2.topology_learning.enabled` (gates the unrelated
57
+ dashboard/retrain consumers). Wired via
58
+ `main.py::_build_dynamic_sizing_payload(..., topology=...)`. Not wired into
59
+ `analyzer/market_analyzer.py`'s trade decision — changes size only.
60
+
61
+ ### Rank multiplier (bounded, direction-preserving)
62
+
63
+ `rank_sizing_multiplier(rank_prediction, rank_sizing_enabled,
64
+ min_rank_multiplier=0.75, max_rank_multiplier=1.25)`. Source: `rank_20d`
65
+ head (predicted cross-sectional percentile rank, [0,1], `train.py::compute_rank_ic()`).
66
+ `multiplier = min + (max-min) * rank_prediction` — rank near `1.0` scales up,
67
+ near `0.0` scales down, `0.5` is a no-op; can amplify (unlike topology). No-op
68
+ if disabled or prediction is `None` (model unloaded, inference failed, or
69
+ universe below `train.py`'s `min_universe_size`). Config:
70
+ `phase_v2.dynamic_risk.rank_sizing_enabled` — **default `false`**: full-series
71
+ backtest is significant (sequence model, mean rank-IC 0.073, t-stat 4.40) but
72
+ the 28-window non-overlapping subsample isn't yet independently significant
73
+ (t-stat 1.20). `PositionSizingDecision.rank_multiplier`/`.rank_sizing_reason`.
74
+ Wired via `main.py::_build_dynamic_sizing_payload(..., predicted_rank_20d=...)`
75
+ — sequence model's head preferred, multitask model's as fallback.
76
+
77
+ ### RL sizing overlay (Phase 4.12 — ships disabled)
78
+
79
+ `rl_sizing.py::rl_sizing_multiplier(model, state, rl_sizing_enabled,
80
+ min_rl_multiplier=0.6, max_rl_multiplier=1.0)` — an offline **contextual
81
+ bandit**, not online/off-policy RL (no exploration data exists;
82
+ `train_rl_sizing.py` docstring). `build_rl_sizing_state()` assembles
83
+ `RL_SIZING_STATE_KEYS` (rank confidence, predicted volatility, regime,
84
+ topology risk, liquidity) from `base_features`/`confidence`; returns `None`
85
+ (no-op) if any key is missing or the flag is off. `_softmax_argmax_index()`
86
+ is deterministic — argmax over the trained policy, never samples at runtime.
87
+ Trained by `train_rl_sizing.py`: softmax policy-gradient over
88
+ `ml/datasets/validation_dataset.csv`, reward = realized PnL net of fees
89
+ (asymmetrically weighted so oversizing is punished more than undersizing —
90
+ the V5.4.1 fix for an earlier reward that made the policy look honestly
91
+ negative). `aq train --rl-sizing-only` wires it like `_train_topology_only()`.
92
+ **Ships
93
+ disabled** pending a retrain demonstrating positive expected reward over
94
+ the constant-`1.0` baseline (see `development/Problems.md` #71 and the
95
+ V5.4.1 changelog entry).
96
+ `PositionSizingDecision.rl_multiplier`/`.rl_sizing_reason`. All chain
97
+ multipliers render in the webui's `AssetSizingTable.tsx` as a `label×value`
98
+ chip, muted at `1.0`.
99
+
100
+ ### Cost-scaled sizing
101
+
102
+ `cost_sizing_multiplier()` shrinks (never grows) sized weight when expected
103
+ edge doesn't clear expected round-trip cost (`execution/cost_model.py`) —
104
+ same shrink-only contract as topology. Config:
105
+ `phase_v2.costs.cost_sizing_enabled` (default off).
106
+
107
+ ## Multi-asset-class dispatch — `asset_class_router.py`
108
+
109
+ `route_position_sizing()` is the single dispatch point. Equity/crypto/bond →
110
+ `build_dynamic_position_sizing()` unchanged (bonds get better features via
111
+ `features/bond_features.py`, not a new sizing formula). `future`/`option` →
112
+ dedicated modules below, adapted onto the same `PositionSizingDecision` shape
113
+ so `portfolio/book_construction.py`, liquidity, analyzer, and
114
+ `main.py::_apply_signal()` stay asset-class-agnostic.
115
+
116
+ ### Futures — `futures_risk.py`
117
+
118
+ `build_futures_position_sizing()` — margin-utilization-targeted, not
119
+ volatility-of-notional. Max contracts at `max_margin_utilization` (hard
120
+ ceiling), scales toward `target_margin_utilization` by confidence, floors to
121
+ integer `contract_count`. Specs via `load_futures_contract_specs()` from
122
+ `data/reference/futures_contract_specs.json` (static fallback, always
123
+ available). **Live margin source (opt-in, Problems.md #67)**:
124
+ `phase_v2.futures_risk.margin_source` (`"static"` default / `"live"`,
125
+ `resolve_futures_margin_source()`) attaches Lean's IB-calibrated
126
+ `BuyingPowerModel` per-security (`main.py::_add_asset()`, never a global
127
+ `SetBrokerageModel()`), queried via `main.py::_resolve_futures_contract_spec()`/
128
+ `build_live_contract_spec()`. "Live" = Lean's local calc, no network
129
+ round-trip; falls back to static file on any failure. Code-complete,
130
+ Lean-API-unverified. `rollover_due()` is a diagnostic date check only —
131
+ rollover itself is Lean's native `add_future()` + `SetFilter()`. Config:
132
+ `phase_v2.futures_risk.{enabled,target_margin_utilization,
133
+ max_margin_utilization,margin_source}`, off by default.
134
+
135
+ ### Options — `portfolio/options_strategy.py` (lives in `portfolio/`, needs the option chain)
136
+
137
+ Sizing for options is chain-aware, so the modules live in `portfolio/` —
138
+ see `portfolio/README.md` for the full options design (the 43-strategy
139
+ registry, held-position sizing, combo limit orders, assignment risk).
140
+ The sizing-relevant summary:
141
+
142
+ - **3 sizing paradigms**, dispatched by strategy shape: vega budget
143
+ (`build_options_position_sizing()` single-leg / `build_multi_leg_position_sizing()`
144
+ for bounded-risk multi-leg shapes, sized by `abs(net_vega)`); margin
145
+ (`portfolio/options_margin_sizing.py` — naked/uncovered-leg/
146
+ bounded-max-loss margin, hard-gated to `runtime_mode == "backtest"`);
147
+ equity-ratio (`build_covered_protective_position_sizing()` — option
148
+ legs sized off the held equity quantity).
149
+ - **Volatility-view gating**: `classify_volatility_view()` classifies
150
+ `predicted_volatility` against chain ATM IV into
151
+ long_vol/short_vol/neutral — gates straddle/strangle/iron-condor/
152
+ butterfly selection only.
153
+ - **Strategy selection**: `phase_v2.options_risk.enabled_strategy_names`
154
+ is an ordered priority list (first match that sizes wins) +
155
+ `risk_tier_preference` (defined-risk-first by default) + optional
156
+ per-asset override. A trained strategy-selector model can rerank the
157
+ list (`route_multi_leg_option_sizing(..., strategy_selector_scores=...)`,
158
+ dormant by default).
159
+ - Config: `phase_v2.options_risk.{enabled,target_delta_at_full_confidence,
160
+ max_vega_budget_pct_of_equity,risk_free_rate,spread_strategy,
161
+ multi_leg_strategies_enabled,max_positions_per_underlying,
162
+ rotation_cooldown_bars,arbitrage_detector}`, off by default.
163
+ - **Verification status**: every combo-order path is code-complete but
164
+ Lean-API-unverified — no real Lean backtest has placed a combo option
165
+ order.
166
+
167
+ ### Forex — `forex_risk.py`
168
+
169
+ `build_forex_position_sizing()` mirrors `futures_risk.py`'s soft-target/
170
+ hard-ceiling shape, leverage-utilization-targeted (margin = `lot_size * price
171
+ * margin_pct`). Specs via `load_forex_pair_specs()` from
172
+ `data/reference/forex_pair_specs.json` (15 pairs — EURUSD, GBPUSD, USDJPY,
173
+ AUDUSD, USDCAD, USDCHF, NZDUSD, EURGBP, EURJPY, GBPJPY, EURCHF, EURAUD,
174
+ AUDJPY, CADJPY, GBPCAD — via `aq fetch forex`, `data_pipeline/fetch.py`, in
175
+ `config.json`'s universe; see `development/asset_universe.md`).
176
+ `asset_class_router.py::_forex_decision_to_position_sizing()` adapts the
177
+ result; `resolve_asset_class_enabled()` takes `forex_risk_enabled`.
178
+ Quote-bar (bid/ask, not trade-bar) data: additive fallback in
179
+ `main.py::on_data()` consulting `slice.quote_bars` only for
180
+ `security_type == "forex"` with no `TradeBar` that bar. Config:
181
+ `phase_v2.forex_risk.enabled`, default `false` — nothing technically blocks
182
+ enabling (`aq config set phase_v2.forex_risk.enabled true`). Code-complete,
183
+ IB-unverified for live.
184
+
185
+ Individual-bond trading is infeasible under this Lean version (no
186
+ `SecurityType.Bond`) — reframed as bond-ETF duration/convexity in
187
+ `features/bond_features.py` (`portfolio/README.md`).
188
+
189
+ ## Adding to / rotating an existing position
190
+
191
+ `risk_controls.py` (repo root) governs whether an already-open position may
192
+ be scaled toward a fresh target, instead of either fully blocking
193
+ (equity/crypto/bond) or restacking an absolute target as an incremental
194
+ order every bar (futures/options):
195
+
196
+ - `should_scale_position(current_weight, target_weight,
197
+ rebalance_threshold_weight=0.03)` — equity/crypto/bond churn guard: resubmit
198
+ `SetHoldings()` only when target moved ≥ threshold from current weight.
199
+ - `compute_incremental_order_quantity(target_quantity, current_quantity)` —
200
+ signed delta a `MarketOrder`/`self.Buy` submits to converge a
201
+ discrete-contract instrument (futures/options/spreads) toward its fresh
202
+ absolute target (churn guard is "integer delta rounds to nonzero").
203
+
204
+ Gated by `phase_v2.functionality.position_scaling.{enabled,rotate_on_drift}`,
205
+ both off by default (`enabled` = may top up an open matching position;
206
+ `rotate_on_drift` = a drifted option contract/spread is rotated
207
+ `Liquidate()` → fresh entry same bar — independent of `enabled` because a
208
+ same-bar reenter carries real transient margin/vega exposure). Scale-down:
209
+ single-leg negative delta sells via `MarketOrder(contract_symbol, delta)`;
210
+ multi-leg via `self.Sell(strategy, abs(delta))`.
211
+
212
+ ## Liquidating positions when an asset class is disabled
213
+
214
+ Flipping `phase_v2.futures_risk.enabled`/`phase_v2.options_risk.enabled` to
215
+ `False` mid-run zeroes new *sizing* but previously left an already-open
216
+ position untouched (equity/crypto/bond have no enable/disable flag — this
217
+ only applies to futures/options).
218
+
219
+ - `asset_class_router.py::resolve_asset_class_enabled(asset_class,
220
+ futures_risk_enabled, options_risk_enabled, forex_risk_enabled=True)` —
221
+ pure lookup: `True` for equity/crypto/bond/unrecognized always;
222
+ future/option/forex follow their flags.
223
+ - `asset_class_router.py::should_liquidate_disabled_asset_class_position(
224
+ asset_class_enabled, is_invested)` — pure predicate:
225
+ `(not asset_class_enabled) and is_invested`.
226
+ - `main.py::_liquidate_positions_for_disabled_asset_classes()` — per-bar
227
+ sweep called right after `_refresh_risk_state()`. Liquidates via real
228
+ `_liquidate_position()` or simulated
229
+ `experience/simulated_portfolio.py::SimulatedPortfolioState.exit_using_last_known_price()`;
230
+ logs via `self.Debug()` only.
231
+
232
+ ## Kill switch and manual overrides
233
+
234
+ `kill_switch.py::evaluate_kill_switch(runtime_metrics, config)` →
235
+ `KillSwitchDecision` — automated production circuit breaker. Pure per-bar
236
+ function over tracked runtime state (rolling return history, drawdown
237
+ velocity, live rank-IC, consecutive losing sessions, slippage divergence,
238
+ model age, a reconciliation-breach flag); trips `main.py`'s existing sticky
239
+ trade lock (never a second one) if any of 7 independently config-gated
240
+ conditions fires. Every threshold defaults to a value it can never cross —
241
+ strict no-op until configured.
242
+
243
+ `manual_override.py`: `read_manual_trade_lock_override()`/
244
+ `write_manual_trade_lock_override()` (pre-existing trade-lock override);
245
+ `read_kill_switch_manual_override()`/`write_kill_switch_manual_override()`
246
+ (matching `kill_switch_manual_override` key, same read/write/cache shape).
247
+ Both driven by `aq kill-switch --arm|--disarm|--auto|--status|--history`.
248
+
249
+ See `development/architecture.md`'s Kill-Switch, Reconciliation, and
250
+ Auto-Rollback Contract, including `execution/reconciliation.py` and
251
+ `retraining/auto_rollback.py`.
252
+
253
+ ## Backtest safety-gate bypass flags (`risk_controls.py`)
254
+
255
+ Three flags, all backtest-only (`runtime_mode == "backtest"`, else always
256
+ `False`) and off by default. The legacy flag still works standalone; the
257
+ two split flags both OR the legacy flag in for backward compatibility:
258
+
259
+ - `is_backtest_safety_bypass_active(runtime_mode, bypass_flag)` —
260
+ **legacy/combined**, `phase_v2.backtest.bypass_safety_gates` (covers both
261
+ behaviors below at once; kept for backward compatibility).
262
+ - `is_sticky_trade_lock_bypass_active(...)` — backtesting with
263
+ `phase_v2.backtest.bypass_sticky_trade_lock` OR the legacy flag. Controls
264
+ **only** `main.py`'s session-rollover clear of a
265
+ `total_drawdown_limit_breached`/`kill_switch_*` sticky lock — never the
266
+ regime drawdown branch. (Rationale: `kill_switch_*` locks are exempt from
267
+ the normal daily auto-clear — correct for live/paper where a human
268
+ decides — but an unattended backtest has no human to clear it.)
269
+ - `is_regime_drawdown_bypass_active(...)` — backtesting with
270
+ `phase_v2.backtest.bypass_regime_drawdown_gate` OR the legacy flag.
271
+ Controls **only** `main.py::_build_regime_payload()`'s
272
+ `risk_off_drawdown_threshold` override (set to infinity when active) —
273
+ never the sticky trade-lock clear. The two flags are deliberately
274
+ independent: unsticking a stuck kill-switch lock shouldn't force
275
+ disabling the unrelated regime-drawdown protection too.
risk/__init__.py ADDED
@@ -0,0 +1,38 @@
1
+ """Dynamic risk, leverage and liquidity controls for Aether Quant V2."""
2
+
3
+ from .asset_class_router import route_position_sizing
4
+ from .futures_risk import (
5
+ FuturesSizingDecision,
6
+ build_futures_position_sizing,
7
+ load_futures_contract_specs,
8
+ rollover_due,
9
+ )
10
+ from .manual_override import read_manual_trade_lock_override, write_manual_trade_lock_override
11
+ from .position_sizing import (
12
+ PositionSizingDecision,
13
+ build_dynamic_position_sizing,
14
+ classify_volatility_regime,
15
+ )
16
+ from .rl_sizing import (
17
+ RL_SIZING_STATE_KEYS,
18
+ build_rl_sizing_state,
19
+ load_rl_sizing_model,
20
+ rl_sizing_multiplier,
21
+ )
22
+
23
+ __all__ = [
24
+ "FuturesSizingDecision",
25
+ "PositionSizingDecision",
26
+ "RL_SIZING_STATE_KEYS",
27
+ "build_dynamic_position_sizing",
28
+ "build_futures_position_sizing",
29
+ "build_rl_sizing_state",
30
+ "classify_volatility_regime",
31
+ "load_futures_contract_specs",
32
+ "load_rl_sizing_model",
33
+ "read_manual_trade_lock_override",
34
+ "rl_sizing_multiplier",
35
+ "rollover_due",
36
+ "route_position_sizing",
37
+ "write_manual_trade_lock_override",
38
+ ]