aether-quant 0.6.0__tar.gz → 0.7.0__tar.gz

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 (292) hide show
  1. {aether_quant-0.6.0 → aether_quant-0.7.0}/Dockerfile.retraining_worker +3 -0
  2. {aether_quant-0.6.0 → aether_quant-0.7.0}/PKG-INFO +1 -1
  3. {aether_quant-0.6.0 → aether_quant-0.7.0}/README.md +194 -56
  4. {aether_quant-0.6.0 → aether_quant-0.7.0}/aether_quant.egg-info/PKG-INFO +1 -1
  5. {aether_quant-0.6.0 → aether_quant-0.7.0}/aether_quant.egg-info/SOURCES.txt +33 -0
  6. {aether_quant-0.6.0 → aether_quant-0.7.0}/aether_quant.egg-info/scm_file_list.json +33 -0
  7. aether_quant-0.7.0/aether_quant.egg-info/scm_version.json +8 -0
  8. {aether_quant-0.6.0 → aether_quant-0.7.0}/analyzer/README.md +15 -0
  9. {aether_quant-0.6.0 → aether_quant-0.7.0}/analyzer/market_analyzer.py +20 -0
  10. {aether_quant-0.6.0 → aether_quant-0.7.0}/aq_cli.py +70 -0
  11. {aether_quant-0.6.0 → aether_quant-0.7.0}/config.json +78 -4
  12. {aether_quant-0.6.0 → aether_quant-0.7.0}/development/Changelog.md +534 -1
  13. {aether_quant-0.6.0 → aether_quant-0.7.0}/development/Problems.md +72 -0
  14. aether_quant-0.7.0/development/backtest_equity_chart.png +0 -0
  15. {aether_quant-0.6.0 → aether_quant-0.7.0}/development/infrastructure.md +24 -1
  16. {aether_quant-0.6.0 → aether_quant-0.7.0}/development/v2_architecture.md +144 -23
  17. {aether_quant-0.6.0 → aether_quant-0.7.0}/experience/redis_queue.py +9 -0
  18. aether_quant-0.7.0/inference/README.md +125 -0
  19. aether_quant-0.7.0/inference/__init__.py +11 -0
  20. aether_quant-0.7.0/inference/exported_model.py +306 -0
  21. {aether_quant-0.6.0 → aether_quant-0.7.0}/lean.json +1 -1
  22. {aether_quant-0.6.0 → aether_quant-0.7.0}/liquidity/README.md +34 -0
  23. aether_quant-0.7.0/liquidity/__init__.py +8 -0
  24. {aether_quant-0.6.0 → aether_quant-0.7.0}/main.py +299 -19
  25. aether_quant-0.7.0/ml/gating_model.json +570 -0
  26. aether_quant-0.7.0/ml/gating_training_metrics.json +190 -0
  27. aether_quant-0.7.0/ml/multitask_feature_schema.json +52 -0
  28. aether_quant-0.7.0/ml/multitask_model.json +5888 -0
  29. aether_quant-0.7.0/ml/multitask_training_metrics.json +248 -0
  30. aether_quant-0.7.0/ml/sequence_feature_schema.json +53 -0
  31. aether_quant-0.7.0/ml/sequence_model.json +13258 -0
  32. aether_quant-0.7.0/ml/sequence_training_metrics.json +209 -0
  33. aether_quant-0.7.0/ml/versions/stage123-1783709428/gating_feature_schema.json +30 -0
  34. aether_quant-0.7.0/ml/versions/stage123-1783709428/gating_model.json +570 -0
  35. aether_quant-0.7.0/ml/versions/stage123-1783709428/gating_training_metrics.json +190 -0
  36. aether_quant-0.7.0/ml/versions/stage123-1783709428/multitask_feature_schema.json +52 -0
  37. aether_quant-0.7.0/ml/versions/stage123-1783709428/multitask_model.json +5888 -0
  38. aether_quant-0.7.0/ml/versions/stage123-1783709428/multitask_training_metrics.json +248 -0
  39. aether_quant-0.7.0/ml/versions/stage4-1783711025/gating_feature_schema.json +30 -0
  40. aether_quant-0.7.0/ml/versions/stage4-1783711025/gating_model.json +570 -0
  41. aether_quant-0.7.0/ml/versions/stage4-1783711025/gating_training_metrics.json +190 -0
  42. aether_quant-0.7.0/ml/versions/stage4-1783711025/multitask_feature_schema.json +52 -0
  43. aether_quant-0.7.0/ml/versions/stage4-1783711025/multitask_model.json +5888 -0
  44. aether_quant-0.7.0/ml/versions/stage4-1783711025/multitask_training_metrics.json +248 -0
  45. aether_quant-0.7.0/ml/versions/stage5-1783715333/sequence_feature_schema.json +53 -0
  46. aether_quant-0.7.0/ml/versions/stage5-1783715333/sequence_model.json +13258 -0
  47. aether_quant-0.7.0/ml/versions/stage5-1783715333/sequence_training_metrics.json +209 -0
  48. aether_quant-0.7.0/ml/versions/v1/multitask_feature_schema.json +52 -0
  49. aether_quant-0.7.0/ml/versions/v1/multitask_model.json +5888 -0
  50. aether_quant-0.7.0/ml/versions/v1/multitask_training_metrics.json +248 -0
  51. aether_quant-0.7.0/ml/versions/v1/sequence_feature_schema.json +53 -0
  52. aether_quant-0.7.0/ml/versions/v1/sequence_model.json +13258 -0
  53. aether_quant-0.7.0/ml/versions/v1/sequence_training_metrics.json +209 -0
  54. {aether_quant-0.6.0 → aether_quant-0.7.0}/moe/README.md +43 -0
  55. {aether_quant-0.6.0 → aether_quant-0.7.0}/moe/gating.py +64 -1
  56. {aether_quant-0.6.0 → aether_quant-0.7.0}/monitoring/neural_network_state.py +149 -13
  57. aether_quant-0.7.0/regime/README.md +57 -0
  58. {aether_quant-0.6.0 → aether_quant-0.7.0}/retraining/README.md +15 -4
  59. {aether_quant-0.6.0 → aether_quant-0.7.0}/retraining/__init__.py +8 -0
  60. {aether_quant-0.6.0 → aether_quant-0.7.0}/retraining/artifacts.py +40 -5
  61. {aether_quant-0.6.0 → aether_quant-0.7.0}/retraining/orchestrator.py +108 -0
  62. {aether_quant-0.6.0 → aether_quant-0.7.0}/retraining/worker.py +14 -0
  63. {aether_quant-0.6.0 → aether_quant-0.7.0}/risk/README.md +32 -0
  64. {aether_quant-0.6.0 → aether_quant-0.7.0}/risk/position_sizing.py +25 -1
  65. {aether_quant-0.6.0 → aether_quant-0.7.0}/tests/test_aq_cli.py +95 -0
  66. {aether_quant-0.6.0 → aether_quant-0.7.0}/tests/test_experience_queue.py +19 -2
  67. aether_quant-0.7.0/tests/test_exported_model.py +464 -0
  68. {aether_quant-0.6.0 → aether_quant-0.7.0}/tests/test_gating_network.py +127 -0
  69. {aether_quant-0.6.0 → aether_quant-0.7.0}/tests/test_lean_backtest_ml_coverage.py +46 -0
  70. aether_quant-0.7.0/tests/test_neural_network_state.py +311 -0
  71. {aether_quant-0.6.0 → aether_quant-0.7.0}/tests/test_retraining_artifacts.py +136 -1
  72. {aether_quant-0.6.0 → aether_quant-0.7.0}/tests/test_retraining_orchestrator.py +149 -0
  73. aether_quant-0.7.0/tests/test_train_cross_sectional_features.py +243 -0
  74. aether_quant-0.7.0/tests/test_train_multitask.py +113 -0
  75. aether_quant-0.7.0/tests/test_train_multitask_architecture.py +189 -0
  76. aether_quant-0.7.0/tests/test_train_sequence_architecture.py +196 -0
  77. {aether_quant-0.6.0 → aether_quant-0.7.0}/topology/README.md +34 -0
  78. {aether_quant-0.6.0 → aether_quant-0.7.0}/train.py +840 -17
  79. aether_quant-0.7.0/train_multitask.py +403 -0
  80. aether_quant-0.7.0/train_sequence.py +403 -0
  81. {aether_quant-0.6.0 → aether_quant-0.7.0}/webui/src/components/neuralnet/NeuralNetworkScene3D.tsx +60 -7
  82. {aether_quant-0.6.0 → aether_quant-0.7.0}/webui/src/types/state.ts +9 -1
  83. aether_quant-0.6.0/aether_quant.egg-info/scm_version.json +0 -8
  84. aether_quant-0.6.0/development/backtest_equity_chart.png +0 -0
  85. aether_quant-0.6.0/inference/README.md +0 -35
  86. aether_quant-0.6.0/inference/__init__.py +0 -3
  87. aether_quant-0.6.0/inference/exported_model.py +0 -68
  88. aether_quant-0.6.0/liquidity/__init__.py +0 -3
  89. aether_quant-0.6.0/ml/versions/gating-only-26218402-34d9-4a0a-add8-ee5d50dd0459/gating_model.json +0 -570
  90. aether_quant-0.6.0/ml/versions/gating-only-26218402-34d9-4a0a-add8-ee5d50dd0459/gating_training_metrics.json +0 -190
  91. aether_quant-0.6.0/regime/README.md +0 -18
  92. aether_quant-0.6.0/tests/test_exported_model.py +0 -106
  93. aether_quant-0.6.0/tests/test_neural_network_state.py +0 -148
  94. {aether_quant-0.6.0 → aether_quant-0.7.0}/.dockerignore +0 -0
  95. {aether_quant-0.6.0 → aether_quant-0.7.0}/.env.compose.example +0 -0
  96. {aether_quant-0.6.0 → aether_quant-0.7.0}/.env.live.example +0 -0
  97. {aether_quant-0.6.0 → aether_quant-0.7.0}/.gitattributes +0 -0
  98. {aether_quant-0.6.0 → aether_quant-0.7.0}/.github/workflows/ci.yml +0 -0
  99. {aether_quant-0.6.0 → aether_quant-0.7.0}/.github/workflows/release.yml +0 -0
  100. {aether_quant-0.6.0 → aether_quant-0.7.0}/.gitignore +0 -0
  101. {aether_quant-0.6.0 → aether_quant-0.7.0}/Dockerfile +0 -0
  102. {aether_quant-0.6.0 → aether_quant-0.7.0}/Dockerfile.workers +0 -0
  103. {aether_quant-0.6.0 → aether_quant-0.7.0}/aether_quant.egg-info/dependency_links.txt +0 -0
  104. {aether_quant-0.6.0 → aether_quant-0.7.0}/aether_quant.egg-info/entry_points.txt +0 -0
  105. {aether_quant-0.6.0 → aether_quant-0.7.0}/aether_quant.egg-info/top_level.txt +0 -0
  106. {aether_quant-0.6.0 → aether_quant-0.7.0}/analyzer/__init__.py +0 -0
  107. {aether_quant-0.6.0 → aether_quant-0.7.0}/backtests/.gitkeep +0 -0
  108. {aether_quant-0.6.0 → aether_quant-0.7.0}/data/alternative/estimize/consensus/aapl/.keep +0 -0
  109. {aether_quant-0.6.0 → aether_quant-0.7.0}/data/alternative/estimize/estimate/.keep +0 -0
  110. {aether_quant-0.6.0 → aether_quant-0.7.0}/data/alternative/estimize/release/.keep +0 -0
  111. {aether_quant-0.6.0 → aether_quant-0.7.0}/data/alternative/sec/aapl/.keep +0 -0
  112. {aether_quant-0.6.0 → aether_quant-0.7.0}/data/alternative/trading-economics/.keep +0 -0
  113. {aether_quant-0.6.0 → aether_quant-0.7.0}/data/alternative/trading-economics/calendar/.keep +0 -0
  114. {aether_quant-0.6.0 → aether_quant-0.7.0}/data/alternative/trading-economics/earnings/.keep +0 -0
  115. {aether_quant-0.6.0 → aether_quant-0.7.0}/data/alternative/trading-economics/indicator/.keep +0 -0
  116. {aether_quant-0.6.0 → aether_quant-0.7.0}/data_pipeline/README.md +0 -0
  117. {aether_quant-0.6.0 → aether_quant-0.7.0}/data_pipeline/__init__.py +0 -0
  118. {aether_quant-0.6.0 → aether_quant-0.7.0}/data_pipeline/fetch.py +0 -0
  119. {aether_quant-0.6.0 → aether_quant-0.7.0}/data_pipeline/v2_manifest.py +0 -0
  120. {aether_quant-0.6.0 → aether_quant-0.7.0}/data_pipeline/yfinance_backfill.py +0 -0
  121. {aether_quant-0.6.0 → aether_quant-0.7.0}/development/README.md +0 -0
  122. {aether_quant-0.6.0 → aether_quant-0.7.0}/development/logo.png +0 -0
  123. {aether_quant-0.6.0 → aether_quant-0.7.0}/docker-compose.yml +0 -0
  124. {aether_quant-0.6.0 → aether_quant-0.7.0}/execution/README.md +0 -0
  125. {aether_quant-0.6.0 → aether_quant-0.7.0}/execution/__init__.py +0 -0
  126. {aether_quant-0.6.0 → aether_quant-0.7.0}/execution/config_cache.py +0 -0
  127. {aether_quant-0.6.0 → aether_quant-0.7.0}/execution/live_credentials.py +0 -0
  128. {aether_quant-0.6.0 → aether_quant-0.7.0}/execution/live_credentials_io.py +0 -0
  129. {aether_quant-0.6.0 → aether_quant-0.7.0}/execution/order_gate.py +0 -0
  130. {aether_quant-0.6.0 → aether_quant-0.7.0}/execution/paper_readiness.py +0 -0
  131. {aether_quant-0.6.0 → aether_quant-0.7.0}/execution/paper_readiness_io.py +0 -0
  132. {aether_quant-0.6.0 → aether_quant-0.7.0}/execution/paper_readiness_report.py +0 -0
  133. {aether_quant-0.6.0 → aether_quant-0.7.0}/execution/runtime_config_io.py +0 -0
  134. {aether_quant-0.6.0 → aether_quant-0.7.0}/experience/README.md +0 -0
  135. {aether_quant-0.6.0 → aether_quant-0.7.0}/experience/__init__.py +0 -0
  136. {aether_quant-0.6.0 → aether_quant-0.7.0}/experience/observation_metrics.py +0 -0
  137. {aether_quant-0.6.0 → aether_quant-0.7.0}/experience/postgres_worker.py +0 -0
  138. {aether_quant-0.6.0 → aether_quant-0.7.0}/experience/simulated_portfolio.py +0 -0
  139. {aether_quant-0.6.0 → aether_quant-0.7.0}/experts/README.md +0 -0
  140. {aether_quant-0.6.0 → aether_quant-0.7.0}/experts/__init__.py +0 -0
  141. {aether_quant-0.6.0 → aether_quant-0.7.0}/experts/expert_datasets.py +0 -0
  142. {aether_quant-0.6.0 → aether_quant-0.7.0}/generate_backtest_report.py +0 -0
  143. {aether_quant-0.6.0 → aether_quant-0.7.0}/liquidity/market_liquidity.py +0 -0
  144. {aether_quant-0.6.0 → aether_quant-0.7.0}/ml/README.md +0 -0
  145. {aether_quant-0.6.0 → aether_quant-0.7.0}/ml/gating_feature_schema.json +0 -0
  146. {aether_quant-0.6.0 → aether_quant-0.7.0}/ml/versions/gating-only-26218402-34d9-4a0a-add8-ee5d50dd0459/gating_feature_schema.json +0 -0
  147. {aether_quant-0.6.0/ml → aether_quant-0.7.0/ml/versions/gating-only-26218402-34d9-4a0a-add8-ee5d50dd0459}/gating_model.json +0 -0
  148. {aether_quant-0.6.0/ml → aether_quant-0.7.0/ml/versions/gating-only-26218402-34d9-4a0a-add8-ee5d50dd0459}/gating_training_metrics.json +0 -0
  149. {aether_quant-0.6.0 → aether_quant-0.7.0}/moe/__init__.py +0 -0
  150. {aether_quant-0.6.0 → aether_quant-0.7.0}/monitoring/README.md +0 -0
  151. {aether_quant-0.6.0 → aether_quant-0.7.0}/monitoring/__init__.py +0 -0
  152. {aether_quant-0.6.0 → aether_quant-0.7.0}/monitoring/api_server.py +0 -0
  153. {aether_quant-0.6.0 → aether_quant-0.7.0}/notifications/README.md +0 -0
  154. {aether_quant-0.6.0 → aether_quant-0.7.0}/notifications/__init__.py +0 -0
  155. {aether_quant-0.6.0 → aether_quant-0.7.0}/notifications/postgres_telegram.py +0 -0
  156. {aether_quant-0.6.0 → aether_quant-0.7.0}/notifications/telegram_alerts.py +0 -0
  157. {aether_quant-0.6.0 → aether_quant-0.7.0}/notifications/telegram_client.py +0 -0
  158. {aether_quant-0.6.0 → aether_quant-0.7.0}/notifications/telegram_worker.py +0 -0
  159. {aether_quant-0.6.0 → aether_quant-0.7.0}/performance/README.md +0 -0
  160. {aether_quant-0.6.0 → aether_quant-0.7.0}/performance/__init__.py +0 -0
  161. {aether_quant-0.6.0 → aether_quant-0.7.0}/performance/postgres_triggers.py +0 -0
  162. {aether_quant-0.6.0 → aether_quant-0.7.0}/performance/trigger_worker.py +0 -0
  163. {aether_quant-0.6.0 → aether_quant-0.7.0}/performance/triggers.py +0 -0
  164. {aether_quant-0.6.0 → aether_quant-0.7.0}/pyproject.toml +0 -0
  165. {aether_quant-0.6.0 → aether_quant-0.7.0}/regime/__init__.py +0 -0
  166. {aether_quant-0.6.0 → aether_quant-0.7.0}/regime/market_regime.py +0 -0
  167. {aether_quant-0.6.0 → aether_quant-0.7.0}/requirements/README.md +0 -0
  168. {aether_quant-0.6.0 → aether_quant-0.7.0}/requirements/requirements-dev.txt +0 -0
  169. {aether_quant-0.6.0 → aether_quant-0.7.0}/requirements/requirements-retraining-worker.txt +0 -0
  170. {aether_quant-0.6.0 → aether_quant-0.7.0}/requirements/requirements-runtime.txt +0 -0
  171. {aether_quant-0.6.0 → aether_quant-0.7.0}/requirements/requirements-workers.txt +0 -0
  172. {aether_quant-0.6.0 → aether_quant-0.7.0}/requirements/requirements.txt +0 -0
  173. {aether_quant-0.6.0 → aether_quant-0.7.0}/retraining/backtest_gate.py +0 -0
  174. {aether_quant-0.6.0 → aether_quant-0.7.0}/retraining/lean_backtest.py +0 -0
  175. {aether_quant-0.6.0 → aether_quant-0.7.0}/retraining/planning.py +0 -0
  176. {aether_quant-0.6.0 → aether_quant-0.7.0}/retraining/postgres_registry.py +0 -0
  177. {aether_quant-0.6.0 → aether_quant-0.7.0}/retraining/status_export.py +0 -0
  178. {aether_quant-0.6.0 → aether_quant-0.7.0}/retraining/validation_gate.py +0 -0
  179. {aether_quant-0.6.0 → aether_quant-0.7.0}/retraining/vault_client.py +0 -0
  180. {aether_quant-0.6.0 → aether_quant-0.7.0}/retraining/vault_commands.py +0 -0
  181. {aether_quant-0.6.0 → aether_quant-0.7.0}/risk/__init__.py +0 -0
  182. {aether_quant-0.6.0 → aether_quant-0.7.0}/risk/manual_override.py +0 -0
  183. {aether_quant-0.6.0 → aether_quant-0.7.0}/risk_controls.py +0 -0
  184. {aether_quant-0.6.0 → aether_quant-0.7.0}/setup.cfg +0 -0
  185. {aether_quant-0.6.0 → aether_quant-0.7.0}/tests/README.md +0 -0
  186. {aether_quant-0.6.0 → aether_quant-0.7.0}/tests/test_backtest_gate.py +0 -0
  187. {aether_quant-0.6.0 → aether_quant-0.7.0}/tests/test_config_cache.py +0 -0
  188. {aether_quant-0.6.0 → aether_quant-0.7.0}/tests/test_expert_datasets.py +0 -0
  189. {aether_quant-0.6.0 → aether_quant-0.7.0}/tests/test_expert_models.py +0 -0
  190. {aether_quant-0.6.0 → aether_quant-0.7.0}/tests/test_fetch.py +0 -0
  191. {aether_quant-0.6.0 → aether_quant-0.7.0}/tests/test_generate_backtest_report.py +0 -0
  192. {aether_quant-0.6.0 → aether_quant-0.7.0}/tests/test_lean_backtest.py +0 -0
  193. {aether_quant-0.6.0 → aether_quant-0.7.0}/tests/test_learned_topology.py +0 -0
  194. {aether_quant-0.6.0 → aether_quant-0.7.0}/tests/test_live_credentials.py +0 -0
  195. {aether_quant-0.6.0 → aether_quant-0.7.0}/tests/test_live_credentials_io.py +0 -0
  196. {aether_quant-0.6.0 → aether_quant-0.7.0}/tests/test_manual_override.py +0 -0
  197. {aether_quant-0.6.0 → aether_quant-0.7.0}/tests/test_market_analyzer.py +0 -0
  198. {aether_quant-0.6.0 → aether_quant-0.7.0}/tests/test_market_liquidity.py +0 -0
  199. {aether_quant-0.6.0 → aether_quant-0.7.0}/tests/test_market_regime.py +0 -0
  200. {aether_quant-0.6.0 → aether_quant-0.7.0}/tests/test_market_topology.py +0 -0
  201. {aether_quant-0.6.0 → aether_quant-0.7.0}/tests/test_observation_metrics.py +0 -0
  202. {aether_quant-0.6.0 → aether_quant-0.7.0}/tests/test_order_gate.py +0 -0
  203. {aether_quant-0.6.0 → aether_quant-0.7.0}/tests/test_paper_readiness.py +0 -0
  204. {aether_quant-0.6.0 → aether_quant-0.7.0}/tests/test_paper_readiness_io.py +0 -0
  205. {aether_quant-0.6.0 → aether_quant-0.7.0}/tests/test_paper_readiness_report.py +0 -0
  206. {aether_quant-0.6.0 → aether_quant-0.7.0}/tests/test_position_sizing.py +0 -0
  207. {aether_quant-0.6.0 → aether_quant-0.7.0}/tests/test_postgres_telegram.py +0 -0
  208. {aether_quant-0.6.0 → aether_quant-0.7.0}/tests/test_postgres_triggers.py +0 -0
  209. {aether_quant-0.6.0 → aether_quant-0.7.0}/tests/test_postgres_worker.py +0 -0
  210. {aether_quant-0.6.0 → aether_quant-0.7.0}/tests/test_retraining_planning.py +0 -0
  211. {aether_quant-0.6.0 → aether_quant-0.7.0}/tests/test_retraining_postgres_registry.py +0 -0
  212. {aether_quant-0.6.0 → aether_quant-0.7.0}/tests/test_retraining_worker.py +0 -0
  213. {aether_quant-0.6.0 → aether_quant-0.7.0}/tests/test_risk_controls.py +0 -0
  214. {aether_quant-0.6.0 → aether_quant-0.7.0}/tests/test_runtime_config_io.py +0 -0
  215. {aether_quant-0.6.0 → aether_quant-0.7.0}/tests/test_simulated_portfolio.py +0 -0
  216. {aether_quant-0.6.0 → aether_quant-0.7.0}/tests/test_status_export.py +0 -0
  217. {aether_quant-0.6.0 → aether_quant-0.7.0}/tests/test_telegram_alerts.py +0 -0
  218. {aether_quant-0.6.0 → aether_quant-0.7.0}/tests/test_telegram_client.py +0 -0
  219. {aether_quant-0.6.0 → aether_quant-0.7.0}/tests/test_telegram_worker.py +0 -0
  220. {aether_quant-0.6.0 → aether_quant-0.7.0}/tests/test_train_gating.py +0 -0
  221. {aether_quant-0.6.0 → aether_quant-0.7.0}/tests/test_train_pipeline.py +0 -0
  222. {aether_quant-0.6.0 → aether_quant-0.7.0}/tests/test_train_topology.py +0 -0
  223. {aether_quant-0.6.0 → aether_quant-0.7.0}/tests/test_trigger_worker.py +0 -0
  224. {aether_quant-0.6.0 → aether_quant-0.7.0}/tests/test_triggers.py +0 -0
  225. {aether_quant-0.6.0 → aether_quant-0.7.0}/tests/test_v2_pipeline_manifest.py +0 -0
  226. {aether_quant-0.6.0 → aether_quant-0.7.0}/tests/test_validation_gate.py +0 -0
  227. {aether_quant-0.6.0 → aether_quant-0.7.0}/tests/test_vault_client.py +0 -0
  228. {aether_quant-0.6.0 → aether_quant-0.7.0}/tests/test_vault_commands.py +0 -0
  229. {aether_quant-0.6.0 → aether_quant-0.7.0}/tests/test_yfinance_backfill.py +0 -0
  230. {aether_quant-0.6.0 → aether_quant-0.7.0}/topology/__init__.py +0 -0
  231. {aether_quant-0.6.0 → aether_quant-0.7.0}/topology/learned_topology.py +0 -0
  232. {aether_quant-0.6.0 → aether_quant-0.7.0}/topology/market_topology.py +0 -0
  233. {aether_quant-0.6.0 → aether_quant-0.7.0}/train_gating.py +0 -0
  234. {aether_quant-0.6.0 → aether_quant-0.7.0}/train_topology.py +0 -0
  235. {aether_quant-0.6.0 → aether_quant-0.7.0}/visualization/README.md +0 -0
  236. {aether_quant-0.6.0 → aether_quant-0.7.0}/webui/.gitignore +0 -0
  237. {aether_quant-0.6.0 → aether_quant-0.7.0}/webui/.oxlintrc.json +0 -0
  238. {aether_quant-0.6.0 → aether_quant-0.7.0}/webui/README.md +0 -0
  239. {aether_quant-0.6.0 → aether_quant-0.7.0}/webui/index.html +0 -0
  240. {aether_quant-0.6.0 → aether_quant-0.7.0}/webui/overview_v2_12.png +0 -0
  241. {aether_quant-0.6.0 → aether_quant-0.7.0}/webui/package-lock.json +0 -0
  242. {aether_quant-0.6.0 → aether_quant-0.7.0}/webui/package.json +0 -0
  243. {aether_quant-0.6.0 → aether_quant-0.7.0}/webui/public/favicon.svg +0 -0
  244. {aether_quant-0.6.0 → aether_quant-0.7.0}/webui/public/icons.svg +0 -0
  245. {aether_quant-0.6.0 → aether_quant-0.7.0}/webui/risk_v2_12.png +0 -0
  246. {aether_quant-0.6.0 → aether_quant-0.7.0}/webui/src/App.tsx +0 -0
  247. {aether_quant-0.6.0 → aether_quant-0.7.0}/webui/src/api/client.ts +0 -0
  248. {aether_quant-0.6.0 → aether_quant-0.7.0}/webui/src/api/hooks.ts +0 -0
  249. {aether_quant-0.6.0 → aether_quant-0.7.0}/webui/src/components/heatmap/AssetHeatmap.tsx +0 -0
  250. {aether_quant-0.6.0 → aether_quant-0.7.0}/webui/src/components/layout/AppShell.tsx +0 -0
  251. {aether_quant-0.6.0 → aether_quant-0.7.0}/webui/src/components/layout/Panel.tsx +0 -0
  252. {aether_quant-0.6.0 → aether_quant-0.7.0}/webui/src/components/monitoring/CountTable.tsx +0 -0
  253. {aether_quant-0.6.0 → aether_quant-0.7.0}/webui/src/components/monitoring/MonitoringFeeds.tsx +0 -0
  254. {aether_quant-0.6.0 → aether_quant-0.7.0}/webui/src/components/monitoring/ObservationPanel.tsx +0 -0
  255. {aether_quant-0.6.0 → aether_quant-0.7.0}/webui/src/components/monitoring/PaperReadinessPanel.tsx +0 -0
  256. {aether_quant-0.6.0 → aether_quant-0.7.0}/webui/src/components/monitoring/PerformanceTriggersPanel.tsx +0 -0
  257. {aether_quant-0.6.0 → aether_quant-0.7.0}/webui/src/components/monitoring/RawStateViewer.tsx +0 -0
  258. {aether_quant-0.6.0 → aether_quant-0.7.0}/webui/src/components/monitoring/RetrainingStatusPanel.tsx +0 -0
  259. {aether_quant-0.6.0 → aether_quant-0.7.0}/webui/src/components/neuralnet/NeuralNetworkStatsPanel.tsx +0 -0
  260. {aether_quant-0.6.0 → aether_quant-0.7.0}/webui/src/components/risk/AssetSizingTable.tsx +0 -0
  261. {aether_quant-0.6.0 → aether_quant-0.7.0}/webui/src/components/risk/LiquidityTable.tsx +0 -0
  262. {aether_quant-0.6.0 → aether_quant-0.7.0}/webui/src/components/risk/RiskBar.tsx +0 -0
  263. {aether_quant-0.6.0 → aether_quant-0.7.0}/webui/src/components/risk/RiskCore.tsx +0 -0
  264. {aether_quant-0.6.0 → aether_quant-0.7.0}/webui/src/components/risk/StrategyRiskCards.tsx +0 -0
  265. {aether_quant-0.6.0 → aether_quant-0.7.0}/webui/src/components/scene3d/Scene3D.tsx +0 -0
  266. {aether_quant-0.6.0 → aether_quant-0.7.0}/webui/src/components/scorecards/Scorecards.tsx +0 -0
  267. {aether_quant-0.6.0 → aether_quant-0.7.0}/webui/src/components/signals/Badge.tsx +0 -0
  268. {aether_quant-0.6.0 → aether_quant-0.7.0}/webui/src/components/signals/PositionsList.tsx +0 -0
  269. {aether_quant-0.6.0 → aether_quant-0.7.0}/webui/src/components/signals/SignalBoard.tsx +0 -0
  270. {aether_quant-0.6.0 → aether_quant-0.7.0}/webui/src/components/topology/ClusterList.tsx +0 -0
  271. {aether_quant-0.6.0 → aether_quant-0.7.0}/webui/src/components/topology/TopologyLearningPanel.tsx +0 -0
  272. {aether_quant-0.6.0 → aether_quant-0.7.0}/webui/src/components/topology/TopologyScene3D.tsx +0 -0
  273. {aether_quant-0.6.0 → aether_quant-0.7.0}/webui/src/components/tracing/AssetPerformancePanel.tsx +0 -0
  274. {aether_quant-0.6.0 → aether_quant-0.7.0}/webui/src/components/tracing/BacktestEquityPanel.tsx +0 -0
  275. {aether_quant-0.6.0 → aether_quant-0.7.0}/webui/src/components/tracing/DivergingBarChart.tsx +0 -0
  276. {aether_quant-0.6.0 → aether_quant-0.7.0}/webui/src/components/tracing/LineChart.tsx +0 -0
  277. {aether_quant-0.6.0 → aether_quant-0.7.0}/webui/src/components/tracing/MetricsSnapshotPanel.tsx +0 -0
  278. {aether_quant-0.6.0 → aether_quant-0.7.0}/webui/src/components/tracing/ObservationEquityPanel.tsx +0 -0
  279. {aether_quant-0.6.0 → aether_quant-0.7.0}/webui/src/index.css +0 -0
  280. {aether_quant-0.6.0 → aether_quant-0.7.0}/webui/src/lib/downsample.ts +0 -0
  281. {aether_quant-0.6.0 → aether_quant-0.7.0}/webui/src/lib/format.ts +0 -0
  282. {aether_quant-0.6.0 → aether_quant-0.7.0}/webui/src/main.tsx +0 -0
  283. {aether_quant-0.6.0 → aether_quant-0.7.0}/webui/src/pages/NeuralNetworkPage.tsx +0 -0
  284. {aether_quant-0.6.0 → aether_quant-0.7.0}/webui/src/pages/Overview.tsx +0 -0
  285. {aether_quant-0.6.0 → aether_quant-0.7.0}/webui/src/pages/RiskPage.tsx +0 -0
  286. {aether_quant-0.6.0 → aether_quant-0.7.0}/webui/src/pages/TopologyPage.tsx +0 -0
  287. {aether_quant-0.6.0 → aether_quant-0.7.0}/webui/src/pages/TracingPage.tsx +0 -0
  288. {aether_quant-0.6.0 → aether_quant-0.7.0}/webui/src/types/tracing.ts +0 -0
  289. {aether_quant-0.6.0 → aether_quant-0.7.0}/webui/tsconfig.app.json +0 -0
  290. {aether_quant-0.6.0 → aether_quant-0.7.0}/webui/tsconfig.json +0 -0
  291. {aether_quant-0.6.0 → aether_quant-0.7.0}/webui/tsconfig.node.json +0 -0
  292. {aether_quant-0.6.0 → aether_quant-0.7.0}/webui/vite.config.ts +0 -0
@@ -10,8 +10,11 @@ COPY experts/ ./experts/
10
10
  COPY topology/ ./topology/
11
11
  COPY moe/ ./moe/
12
12
  COPY inference/ ./inference/
13
+ COPY risk/ ./risk/
13
14
  COPY retraining/ ./retraining/
14
15
  COPY train.py .
15
16
  COPY train_topology.py .
16
17
  COPY train_gating.py .
18
+ COPY train_multitask.py .
19
+ COPY train_sequence.py .
17
20
  CMD ["python", "-m", "retraining.worker"]
@@ -1,5 +1,5 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: aether-quant
3
- Version: 0.6.0
3
+ Version: 0.7.0
4
4
  Summary: Aether Quant convenience CLI
5
5
  Requires-Python: >=3.10
@@ -10,7 +10,7 @@
10
10
 
11
11
  <p align="center">
12
12
  <img src="https://img.shields.io/badge/python-3.10%2B-FF8C00?style=flat-square&labelColor=1A1A1A&logo=python&logoColor=white" alt="Python 3.10+">
13
- <!-- AQ:TEST_BADGE_START --><img src="https://img.shields.io/badge/tests-611%2F611%20passing-brightgreen?style=flat-square&labelColor=1A1A1A" alt="611 of 611 tests passing"><!-- AQ:TEST_BADGE_END -->
13
+ <!-- AQ:TEST_BADGE_START --><img src="https://img.shields.io/badge/tests-642%2F642%20passing-brightgreen?style=flat-square&labelColor=1A1A1A" alt="642 of 642 tests passing"><!-- AQ:TEST_BADGE_END -->
14
14
  <img src="https://img.shields.io/pypi/v/aether-quant?style=flat-square&labelColor=1A1A1A&color=FF8C00" alt="PyPI version">
15
15
  <img src="https://img.shields.io/badge/docker-ghcr.io%2Faether--quant-2496ED?style=flat-square&labelColor=1A1A1A&logo=docker&logoColor=white" alt="Docker image on GHCR">
16
16
  </p>
@@ -158,11 +158,14 @@ that a controlled retraining loop reads from to evolve the model over time.
158
158
 
159
159
  ```mermaid
160
160
  flowchart LR
161
- A["Lean data folder<br/>stocks, ETFs, crypto"] --> B["Feature pipeline<br/>train.py"]
161
+ A["Lean data folder<br/>stocks, ETFs, crypto"] --> B["Feature pipeline<br/>train.py<br/>48-dim: price/volume +<br/>regime + liquidity + topology"]
162
162
  B --> C["Regime detection<br/>trend, volatility, drawdown, correlation"]
163
163
  B --> D["3D topology modeling<br/>market structure and clusters"]
164
- C --> E["Gating network<br/>the manager"]
164
+ B -.-> U["Sequence encoder (Phase 2)<br/>causal-TCN, 30-bar window<br/>informational only"]
165
+ B --> V["Multitask heads<br/>baseline + 4 experts<br/>direction + magnitude + volatility"]
166
+ C --> E["Gating network<br/>the manager<br/>blends probability + magnitude/volatility"]
165
167
  D --> E
168
+ V --> E
166
169
  E --> F["Expert modules"]
167
170
  F --> G["Bullish expert"]
168
171
  F --> H["Bearish expert"]
@@ -180,6 +183,7 @@ flowchart LR
180
183
  M --> O["Observation / simulation record"]
181
184
  N --> P["Redis event stream<br/>temporary low-latency buffer"]
182
185
  O --> P
186
+ U -.-> P
183
187
  P --> Q["Experience worker<br/>async batch persistence"]
184
188
  Q --> R["PostgreSQL experience database<br/>single source of truth"]
185
189
  R --> S["Performance triggers<br/>100 observations, drawdown, Sharpe, regime shift"]
@@ -187,6 +191,11 @@ flowchart LR
187
191
  T --> E
188
192
  ```
189
193
 
194
+ Dashed edges mark the Phase 2 sequence encoder's **informational-only**
195
+ path — it's computed every bar and reaches the experience log, but never
196
+ the gating network, market analyzer, or position sizing (see
197
+ `inference/README.md`'s Phase 2 section).
198
+
190
199
  #### Tech Stack
191
200
 
192
201
  ```mermaid
@@ -203,6 +212,7 @@ flowchart TB
203
212
  D --> D2["scikit-learn"]
204
213
  D --> D3["NumPy / Pandas"]
205
214
  D --> D4["MoE experts and gating network"]
215
+ D --> D5["Multitask heads (direction/magnitude/<br/>volatility) + causal-TCN sequence encoder"]
206
216
  E["Monitoring and UI"] --> E1["React/Vite webui — Tracing dashboard (port 3002 dev / 8001 Docker)"]
207
217
  E --> E2["FastAPI JSON API (port 8000)"]
208
218
  E --> E3["Telegram alerts (V2-19)<br/>notifications/telegram_worker.py"]
@@ -215,6 +225,48 @@ and more), the module map, and an honest analysis of what would need to
215
225
  change for this to become a genuinely low-latency/HFT system — see
216
226
  **[`development/v2_architecture.md`](development/v2_architecture.md)**.
217
227
 
228
+ **The baseline model can now predict more than direction.** An optional
229
+ multi-task model (`train.py::AetherNetMultiTask`, trained by
230
+ `train_multitask.py`) predicts next-day direction, return magnitude and
231
+ volatility jointly from one shared trunk — the direction-only baseline and
232
+ experts are unchanged and still ship independently. All 4 experts also
233
+ have their own optional multitask heads (`train.py::_train_expert_multitask()`),
234
+ so `moe/gating.py` blends per-expert magnitude/volatility with a
235
+ baseline-scale anchor the same weighted-average way it already blends
236
+ direction. `main.py` threads the resulting `predicted_return_magnitude`/
237
+ `predicted_volatility` through the market analyzer (informational only,
238
+ never changes routing) and, opt-in via
239
+ `phase_v2.dynamic_risk.use_predicted_volatility`, into position sizing —
240
+ replacing the backward-looking `rolling_volatility_20d` average with an
241
+ actual forward-looking forecast for that one calculation.
242
+
243
+ **Regime, liquidity and topology are now genuine model input features,
244
+ not just downstream consumers of its output.** Model input dimensionality
245
+ grew from 30 to 48: regime one-hot/confidence/trend/risk score, an
246
+ asset-intrinsic liquidity spread/dollar-volume estimate, and cross-asset
247
+ topology correlation/risk state are all computed offline
248
+ (`train.py::add_regime_features()`/`add_liquidity_features()`/
249
+ `build_topology_features_by_date()`) and at runtime
250
+ (`main.py::_build_model_input()`, reordered so regime is computed
251
+ *before* the model runs) with verified train/runtime parity.
252
+
253
+ **A causal-TCN sequence encoder (Phase 2) now exists alongside the
254
+ flat-MLP trunk**, replacing the "zero temporal structure" limitation the
255
+ original root-cause investigation flagged — `train.py::AetherNetSequenceMultiTask`,
256
+ trained by `train_sequence.py`, over a rolling 30-bar window of
257
+ already-computed model inputs. Informational only this pass
258
+ (`main.py::_run_sequence_model()` — not yet wired into any trading
259
+ decision); see `inference/README.md`'s Phase 2 section for the new
260
+ `_conv1d_causal`/`_multihead_attention`/`_softmax`/`_layernorm_axis`
261
+ interpreter primitives (each independently verified against real PyTorch
262
+ modules).
263
+
264
+ See `inference/README.md`, `moe/README.md`, `risk/README.md`,
265
+ `regime/README.md`, `liquidity/README.md` and `topology/README.md` for
266
+ the full contracts, and `development/Changelog.md`'s "Multi-task
267
+ prediction" and "Phase 1 remainder + Phase 2" entries for the complete
268
+ writeup.
269
+
218
270
  ## Universe Size
219
271
 
220
272
  The trading universe currently spans **20 assets** — 15 equities and 5
@@ -347,6 +399,9 @@ aether-quant/
347
399
  ├── main.py # Lean algorithm: inference, signal engine, risk controls
348
400
  ├── train.py # Training pipeline: dataset build, model training, validation
349
401
  ├── train_topology.py # Offline trainer for the learned topology overlay
402
+ ├── train_gating.py # Offline trainer for the learned gating blend
403
+ ├── train_multitask.py # Offline trainer for the joint direction+magnitude+volatility model
404
+ ├── train_sequence.py # Offline trainer for the Phase 2 causal-TCN sequence encoder
350
405
  ├── generate_backtest_report.py # Regenerates this README's Backtest Results section
351
406
  ├── aq_cli.py # `aq` convenience CLI
352
407
  ├── config.json # Runtime configuration (phase1 / phase_v2 blocks)
@@ -404,13 +459,13 @@ and how it's wired in — this table is the index.
404
459
  | Metric | Value |
405
460
  |---|---|
406
461
  | Backtest window | 2018-04-01 to 2021-04-02 |
407
- | Sharpe Ratio | -0.71 |
408
- | Net Profit | -8.069% |
409
- | Compounding Annual Return | -2.761% |
410
- | Drawdown | 12.500% |
411
- | Total Orders | 27 |
412
- | Win Rate | 17% |
413
- | Last updated | 2026-07-06 17:20 UTC (auto-generated by `aq backtest`) |
462
+ | Sharpe Ratio | -0.758 |
463
+ | Net Profit | -4.847% |
464
+ | Compounding Annual Return | -1.640% |
465
+ | Drawdown | 12.300% |
466
+ | Total Orders | 36 |
467
+ | Win Rate | 25% |
468
+ | Last updated | 2026-07-08 13:10 UTC (auto-generated by `aq backtest`) |
414
469
  <!-- AQ:BACKTEST_END -->
415
470
 
416
471
  <details>
@@ -419,33 +474,33 @@ and how it's wired in — this table is the index.
419
474
  <!-- AQ:BACKTEST_FULL_STATS_START -->
420
475
  | Metric | Value |
421
476
  |---|---|
422
- | Total Orders | 27 |
423
- | Average Win | 0.18% |
424
- | Average Loss | -1.70% |
425
- | Compounding Annual Return | -2.761% |
426
- | Drawdown | 12.500% |
427
- | Expectancy | -0.816 |
477
+ | Total Orders | 36 |
478
+ | Average Win | 0.38% |
479
+ | Average Loss | -0.67% |
480
+ | Compounding Annual Return | -1.640% |
481
+ | Drawdown | 12.300% |
482
+ | Expectancy | -0.609 |
428
483
  | Start Equity | 100000.00 |
429
- | End Equity | 91930.60 |
430
- | Net Profit | -8.069% |
431
- | Sharpe Ratio | -0.71 |
432
- | Sortino Ratio | -0.471 |
433
- | Probabilistic Sharpe Ratio | 0.171% |
434
- | Loss Rate | 83% |
435
- | Win Rate | 17% |
436
- | Profit-Loss Ratio | 0.11 |
437
- | Alpha | -0.058 |
438
- | Beta | 0.195 |
439
- | Annual Standard Deviation | 0.051 |
440
- | Annual Variance | 0.003 |
441
- | Information Ratio | -0.972 |
442
- | Tracking Error | 0.155 |
443
- | Treynor Ratio | -0.184 |
444
- | Total Fees | $12.00 |
445
- | Estimated Strategy Capacity | $210000000.00 |
446
- | Lowest Capacity Asset | IBM R735QTJ8XC9X |
447
- | Portfolio Turnover | 0.07% |
448
- | Drawdown Recovery | 503 |
484
+ | End Equity | 95153.40 |
485
+ | Net Profit | -4.847% |
486
+ | Sharpe Ratio | -0.758 |
487
+ | Sortino Ratio | -0.363 |
488
+ | Probabilistic Sharpe Ratio | 0.006% |
489
+ | Loss Rate | 75% |
490
+ | Win Rate | 25% |
491
+ | Profit-Loss Ratio | 0.56 |
492
+ | Alpha | -0.034 |
493
+ | Beta | 0.047 |
494
+ | Annual Standard Deviation | 0.038 |
495
+ | Annual Variance | 0.001 |
496
+ | Information Ratio | -0.786 |
497
+ | Tracking Error | 0.182 |
498
+ | Treynor Ratio | -0.603 |
499
+ | Total Fees | $25.59 |
500
+ | Estimated Strategy Capacity | $2300000.00 |
501
+ | Lowest Capacity Asset | BNO UN3IMQ2JU1YD |
502
+ | Portfolio Turnover | 0.14% |
503
+ | Drawdown Recovery | 32 |
449
504
  <!-- AQ:BACKTEST_FULL_STATS_END -->
450
505
 
451
506
  </details>
@@ -515,42 +570,125 @@ instead, without waiting on a PyPI release:
515
570
  pip install -e .
516
571
  ```
517
572
 
518
- Either way, `aq --help` gives the full command list:
573
+ Either way, `aq --help` gives the full command list. Every command except
574
+ `aq trade-lock` and `aq fetch` is a thin `subprocess` wrapper around a
575
+ command already documented elsewhere in this README:
519
576
 
577
+ #### `aq train`
578
+ ```text
579
+ aq train [--dataset-only|--init-only|--experts-only|--gating-only|--multitask-only|--sequence-only]
580
+ ```
581
+ Runs `train.py`: builds the dataset and trains the baseline + expert
582
+ models. `--gating-only` trains just the learned gating blend
583
+ (`train_gating.py`) and installs it straight into active `ml/`,
584
+ mirroring what `--experts-only` already does for the expert models — see
585
+ `moe/README.md`. `--multitask-only` does the same for the joint
586
+ direction+magnitude+volatility model (`train_multitask.py`) — see
587
+ `inference/README.md`/`risk/README.md`. `--sequence-only` does the same
588
+ for the Phase 2 causal-TCN sequence encoder (`train_sequence.py`) — see
589
+ `inference/README.md`.
590
+
591
+ #### `aq test`
520
592
  ```text
521
- aq train [--dataset-only|--init-only|--experts-only|--gating-only]
522
593
  aq test
594
+ ```
595
+ Runs the pytest suite and refreshes this README's test badge.
596
+
597
+ #### `aq backtest`
598
+ ```text
523
599
  aq backtest
600
+ ```
601
+ Runs `lean backtest .` and refreshes this README's [Backtest Results](#backtest-results) section.
602
+
603
+ #### `aq report`
604
+ ```text
524
605
  aq report <backtest-folder> <result-id>
606
+ ```
607
+ Generates Lean's own HTML backtest report (trade blotter, standard Lean
608
+ charts) at `backtests/<backtest-folder>/report.html`.
609
+
610
+ #### `aq api`
611
+ ```text
525
612
  aq api
613
+ ```
614
+ Starts the FastAPI monitoring server on `:8001`.
615
+
616
+ #### `aq webui`
617
+ ```text
526
618
  aq webui
619
+ ```
620
+ Starts the webui dev server (`npm run dev`).
621
+
622
+ #### `aq docker`
623
+ ```text
527
624
  aq docker up [--lean|--all]
528
625
  aq docker build
626
+ ```
627
+ `up` starts local infrastructure (default: Redis + PostgreSQL only).
628
+ `build` rebuilds the `aether-quant` app image.
629
+
630
+ #### `aq config`
631
+ ```text
529
632
  aq config [get <dotted.key>|set <dotted.key> <value>|keys [<dotted.prefix>]]
633
+ ```
634
+ Reads or edits `config.json` directly, no manual file editing needed.
635
+ Bare `aq config` pretty-prints the whole file; `aq config keys
636
+ [<dotted.prefix>]` lists every leaf key path (handy for finding the right
637
+ key in a deeply nested file); `aq config get <dotted.key>` prints one
638
+ value (scalar, or a whole nested section as JSON); `aq config set
639
+ <dotted.key> <value>` writes it — the value is parsed as JSON first (so
640
+ `true`/`123`/`0.5`/`["a","b"]` become their real types automatically),
641
+ falling back to a plain string otherwise. Every `set` backs up the
642
+ previous file to `config.json.bak` first and prints old → new so a
643
+ mistake is immediately visible; changing a value's type (e.g. bool →
644
+ string) prints a warning but still writes it, since this command
645
+ intentionally gives full access to every key, not just a safe subset.
646
+
647
+ #### `aq lean`
648
+ ```text
530
649
  aq lean [get <dotted.key>|set <dotted.key> <value>|keys [<dotted.prefix>]]
650
+ ```
651
+ The exact same `get`/`set`/`keys` tool as `aq config`, just pointed at
652
+ `lean.json` (the QuantConnect Lean CLI's own config file — broker
653
+ credentials, environments, data providers) instead. `aq lean set
654
+ ib-trading-mode live`, `aq lean keys environments.live-paper`, etc.
655
+
656
+ #### `aq retrain`
657
+ ```text
531
658
  aq retrain <plan|train|validate|backtest|commit|promote|rollback|status> [...]
659
+ ```
660
+ Dispatches to `python -m retraining.orchestrator <stage> ...` for a
661
+ single manual pipeline stage.
662
+
663
+ #### `aq trade-lock`
664
+ ```text
532
665
  aq trade-lock --on|--off|--auto|--status
666
+ ```
667
+ Manually overrides `main.py`'s sticky total-drawdown trade lock (see
668
+ `development/v2_architecture.md`'s Manual Trade-Lock Override Contract).
669
+ `--off` deliberately clears an otherwise-permanent lock; `--auto` returns
670
+ to fully automatic behavior.
671
+
672
+ #### `aq fetch`
673
+ ```text
533
674
  aq fetch <crypto|stock> --ticker <TICKER> --start <YYYY-MM-DD> --end <YYYY-MM-DD> [--apply]
675
+ ```
676
+ Fetches historical OHLCV from Yahoo Finance for a ticker that isn't in
677
+ `config.json` yet, formats it into Lean's zip/CSV convention, and writes
678
+ it to the right spot under `data/` (`data/crypto/coinbase/daily/<ticker>_trade.zip`
679
+ or `data/equity/usa/daily/<ticker>.zip`). On `--apply`, it also appends a
680
+ new asset block to `config.json`'s `phase1.universe.assets[]` — no manual
681
+ editing needed. Dry run by default (no `--apply`): reports what would
682
+ happen, writes nothing. Never runs `train.py` itself — once applied, run
683
+ `python train.py --dataset-only` (then `python train.py` when ready)
684
+ yourself to actually train on the new ticker. `crypto`/`stock` today; a
685
+ `derivative` asset class is planned for V3.
686
+
687
+ #### `aq status`
688
+ ```text
534
689
  aq status
535
690
  ```
536
-
537
- Every command except `aq trade-lock` and `aq fetch` is a thin `subprocess`
538
- wrapper around a command already documented elsewhere in this README:
539
-
540
- - **`aq train`** — runs `train.py`: builds the dataset and trains the baseline + expert models. `--gating-only` trains just the learned gating blend (`train_gating.py`) and installs it straight into active `ml/`, mirroring what `--experts-only` already does for the expert models — see `moe/README.md`.
541
- - **`aq test`** — runs the pytest suite and refreshes this README's test badge.
542
- - **`aq backtest`** — runs `lean backtest .` and refreshes this README's [Backtest Results](#backtest-results) section.
543
- - **`aq report <backtest-folder> <result-id>`** — generates Lean's own HTML backtest report (trade blotter, standard Lean charts) at `backtests/<backtest-folder>/report.html`.
544
- - **`aq api`** — starts the FastAPI monitoring server on `:8001`.
545
- - **`aq webui`** — starts the webui dev server (`npm run dev`).
546
- - **`aq docker up [--lean|--all]`** — starts local infrastructure (default: Redis + PostgreSQL only).
547
- - **`aq docker build`** — rebuilds the `aether-quant` app image.
548
- - **`aq config`** — reads or edits `config.json` directly, no manual file editing needed. Bare `aq config` pretty-prints the whole file; `aq config keys [<dotted.prefix>]` lists every leaf key path (handy for finding the right key in a deeply nested file); `aq config get <dotted.key>` prints one value (scalar, or a whole nested section as JSON); `aq config set <dotted.key> <value>` writes it — the value is parsed as JSON first (so `true`/`123`/`0.5`/`["a","b"]` become their real types automatically), falling back to a plain string otherwise. Every `set` backs up the previous file to `config.json.bak` first and prints old → new so a mistake is immediately visible; changing a value's type (e.g. bool → string) prints a warning but still writes it, since this command intentionally gives full access to every key, not just a safe subset.
549
- - **`aq lean`** — the exact same `get`/`set`/`keys` tool as `aq config`, just pointed at `lean.json` (the QuantConnect Lean CLI's own config file — broker credentials, environments, data providers) instead. `aq lean set ib-trading-mode live`, `aq lean keys environments.live-paper`, etc.
550
- - **`aq retrain <stage>`** — dispatches to `python -m retraining.orchestrator <stage> ...` for a single manual pipeline stage.
551
- - **`aq trade-lock --on|--off|--auto|--status`** — manually overrides `main.py`'s sticky total-drawdown trade lock (see `development/v2_architecture.md`'s Manual Trade-Lock Override Contract). `--off` deliberately clears an otherwise-permanent lock; `--auto` returns to fully automatic behavior.
552
- - **`aq fetch <crypto|stock> --ticker <TICKER> --start <YYYY-MM-DD> --end <YYYY-MM-DD> [--apply]`** — fetches historical OHLCV from Yahoo Finance for a ticker that isn't in `config.json` yet, formats it into Lean's zip/CSV convention, and writes it to the right spot under `data/` (`data/crypto/coinbase/daily/<ticker>_trade.zip` or `data/equity/usa/daily/<ticker>.zip`). On `--apply`, it also appends a new asset block to `config.json`'s `phase1.universe.assets[]` — no manual editing needed. Dry run by default (no `--apply`): reports what would happen, writes nothing. Never runs `train.py` itself — once applied, run `python train.py --dataset-only` (then `python train.py` when ready) yourself to actually train on the new ticker. `crypto`/`stock` today; a `derivative` asset class is planned for V3.
553
- - **`aq status`** — shows `git status`.
691
+ Shows `git status`.
554
692
 
555
693
  ## Release Process
556
694
 
@@ -1,5 +1,5 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: aether-quant
3
- Version: 0.6.0
3
+ Version: 0.7.0
4
4
  Summary: Aether Quant convenience CLI
5
5
  Requires-Python: >=3.10
@@ -17,6 +17,8 @@ pyproject.toml
17
17
  risk_controls.py
18
18
  train.py
19
19
  train_gating.py
20
+ train_multitask.py
21
+ train_sequence.py
20
22
  train_topology.py
21
23
  .github/workflows/ci.yml
22
24
  .github/workflows/release.yml
@@ -80,9 +82,36 @@ ml/README.md
80
82
  ml/gating_feature_schema.json
81
83
  ml/gating_model.json
82
84
  ml/gating_training_metrics.json
85
+ ml/multitask_feature_schema.json
86
+ ml/multitask_model.json
87
+ ml/multitask_training_metrics.json
88
+ ml/sequence_feature_schema.json
89
+ ml/sequence_model.json
90
+ ml/sequence_training_metrics.json
83
91
  ml/versions/gating-only-26218402-34d9-4a0a-add8-ee5d50dd0459/gating_feature_schema.json
84
92
  ml/versions/gating-only-26218402-34d9-4a0a-add8-ee5d50dd0459/gating_model.json
85
93
  ml/versions/gating-only-26218402-34d9-4a0a-add8-ee5d50dd0459/gating_training_metrics.json
94
+ ml/versions/stage123-1783709428/gating_feature_schema.json
95
+ ml/versions/stage123-1783709428/gating_model.json
96
+ ml/versions/stage123-1783709428/gating_training_metrics.json
97
+ ml/versions/stage123-1783709428/multitask_feature_schema.json
98
+ ml/versions/stage123-1783709428/multitask_model.json
99
+ ml/versions/stage123-1783709428/multitask_training_metrics.json
100
+ ml/versions/stage4-1783711025/gating_feature_schema.json
101
+ ml/versions/stage4-1783711025/gating_model.json
102
+ ml/versions/stage4-1783711025/gating_training_metrics.json
103
+ ml/versions/stage4-1783711025/multitask_feature_schema.json
104
+ ml/versions/stage4-1783711025/multitask_model.json
105
+ ml/versions/stage4-1783711025/multitask_training_metrics.json
106
+ ml/versions/stage5-1783715333/sequence_feature_schema.json
107
+ ml/versions/stage5-1783715333/sequence_model.json
108
+ ml/versions/stage5-1783715333/sequence_training_metrics.json
109
+ ml/versions/v1/multitask_feature_schema.json
110
+ ml/versions/v1/multitask_model.json
111
+ ml/versions/v1/multitask_training_metrics.json
112
+ ml/versions/v1/sequence_feature_schema.json
113
+ ml/versions/v1/sequence_model.json
114
+ ml/versions/v1/sequence_training_metrics.json
86
115
  moe/README.md
87
116
  moe/__init__.py
88
117
  moe/gating.py
@@ -170,8 +199,12 @@ tests/test_status_export.py
170
199
  tests/test_telegram_alerts.py
171
200
  tests/test_telegram_client.py
172
201
  tests/test_telegram_worker.py
202
+ tests/test_train_cross_sectional_features.py
173
203
  tests/test_train_gating.py
204
+ tests/test_train_multitask.py
205
+ tests/test_train_multitask_architecture.py
174
206
  tests/test_train_pipeline.py
207
+ tests/test_train_sequence_architecture.py
175
208
  tests/test_train_topology.py
176
209
  tests/test_trigger_worker.py
177
210
  tests/test_triggers.py
@@ -1,11 +1,13 @@
1
1
  {
2
2
  "files": [
3
3
  "README.md",
4
+ "train_multitask.py",
4
5
  "train_gating.py",
5
6
  "Dockerfile.workers",
6
7
  "aq_cli.py",
7
8
  "Dockerfile",
8
9
  "pyproject.toml",
10
+ "train_sequence.py",
9
11
  ".env.compose.example",
10
12
  "Dockerfile.retraining_worker",
11
13
  "train_topology.py",
@@ -165,6 +167,7 @@
165
167
  "development/infrastructure.md",
166
168
  "tests/test_order_gate.py",
167
169
  "tests/test_config_cache.py",
170
+ "tests/test_train_sequence_architecture.py",
168
171
  "tests/test_telegram_alerts.py",
169
172
  "tests/test_trigger_worker.py",
170
173
  "tests/test_v2_pipeline_manifest.py",
@@ -187,12 +190,14 @@
187
190
  "tests/test_market_regime.py",
188
191
  "tests/test_vault_client.py",
189
192
  "tests/test_validation_gate.py",
193
+ "tests/test_train_multitask.py",
190
194
  "tests/test_observation_metrics.py",
191
195
  "tests/test_paper_readiness_io.py",
192
196
  "tests/test_exported_model.py",
193
197
  "tests/test_train_topology.py",
194
198
  "tests/test_telegram_worker.py",
195
199
  "tests/test_paper_readiness.py",
200
+ "tests/test_train_multitask_architecture.py",
196
201
  "tests/test_triggers.py",
197
202
  "tests/test_simulated_portfolio.py",
198
203
  "tests/test_position_sizing.py",
@@ -201,6 +206,7 @@
201
206
  "tests/test_live_credentials_io.py",
202
207
  "tests/test_market_analyzer.py",
203
208
  "tests/test_generate_backtest_report.py",
209
+ "tests/test_train_cross_sectional_features.py",
204
210
  "tests/test_lean_backtest.py",
205
211
  "tests/test_retraining_planning.py",
206
212
  "tests/test_market_topology.py",
@@ -230,13 +236,40 @@
230
236
  "requirements/requirements-dev.txt",
231
237
  "requirements/requirements-workers.txt",
232
238
  "requirements/requirements-retraining-worker.txt",
239
+ "ml/sequence_feature_schema.json",
233
240
  "ml/README.md",
234
241
  "ml/gating_model.json",
242
+ "ml/multitask_feature_schema.json",
243
+ "ml/multitask_model.json",
244
+ "ml/multitask_training_metrics.json",
235
245
  "ml/gating_feature_schema.json",
236
246
  "ml/gating_training_metrics.json",
247
+ "ml/sequence_model.json",
248
+ "ml/sequence_training_metrics.json",
249
+ "ml/versions/stage5-1783715333/sequence_feature_schema.json",
250
+ "ml/versions/stage5-1783715333/sequence_model.json",
251
+ "ml/versions/stage5-1783715333/sequence_training_metrics.json",
252
+ "ml/versions/v1/sequence_feature_schema.json",
253
+ "ml/versions/v1/multitask_feature_schema.json",
254
+ "ml/versions/v1/multitask_model.json",
255
+ "ml/versions/v1/multitask_training_metrics.json",
256
+ "ml/versions/v1/sequence_model.json",
257
+ "ml/versions/v1/sequence_training_metrics.json",
258
+ "ml/versions/stage4-1783711025/gating_model.json",
259
+ "ml/versions/stage4-1783711025/multitask_feature_schema.json",
260
+ "ml/versions/stage4-1783711025/multitask_model.json",
261
+ "ml/versions/stage4-1783711025/multitask_training_metrics.json",
262
+ "ml/versions/stage4-1783711025/gating_feature_schema.json",
263
+ "ml/versions/stage4-1783711025/gating_training_metrics.json",
237
264
  "ml/versions/gating-only-26218402-34d9-4a0a-add8-ee5d50dd0459/gating_model.json",
238
265
  "ml/versions/gating-only-26218402-34d9-4a0a-add8-ee5d50dd0459/gating_feature_schema.json",
239
266
  "ml/versions/gating-only-26218402-34d9-4a0a-add8-ee5d50dd0459/gating_training_metrics.json",
267
+ "ml/versions/stage123-1783709428/gating_model.json",
268
+ "ml/versions/stage123-1783709428/multitask_feature_schema.json",
269
+ "ml/versions/stage123-1783709428/multitask_model.json",
270
+ "ml/versions/stage123-1783709428/multitask_training_metrics.json",
271
+ "ml/versions/stage123-1783709428/gating_feature_schema.json",
272
+ "ml/versions/stage123-1783709428/gating_training_metrics.json",
240
273
  ".github/workflows/release.yml",
241
274
  ".github/workflows/ci.yml"
242
275
  ]
@@ -0,0 +1,8 @@
1
+ {
2
+ "tag": "0.7.0",
3
+ "distance": 0,
4
+ "node": "gd20060c9112a861a4ff09903fa8bcdb2d01cfb93",
5
+ "dirty": false,
6
+ "branch": "HEAD",
7
+ "node_date": "2026-07-10"
8
+ }
@@ -79,3 +79,18 @@ risk engine, and before action categorization / Lean order placement.
79
79
  reasoning as the topology-elevated/isolated rules above. Default `false`
80
80
  means output is byte-identical to pre-this-change behavior everywhere
81
81
  the flag isn't explicitly turned on.
82
+ - **Multi-task prediction fields (additive, never change routing).**
83
+ `MarketAnalysisDecision` gains `predicted_return_magnitude`/
84
+ `predicted_volatility` (both `float | None`, default `None`), threaded
85
+ straight through from `main.py`'s optional multi-task model call
86
+ (`train_multitask.py`/`AetherNetMultiTask`, see `inference/README.md`)
87
+ into every one of this module's 8 return statements via two new
88
+ `build_market_analysis_decision(..., predicted_return_magnitude=None,
89
+ predicted_volatility=None)` parameters. Purely informational here — this
90
+ module's `trade`/`simulate`/`observe`/`reduce_risk` categorization does
91
+ not read either field; `predicted_volatility` only ever changes anything
92
+ downstream in `risk/position_sizing.py` (see `risk/README.md`), and only
93
+ when `phase_v2.dynamic_risk.use_predicted_volatility` is explicitly
94
+ enabled. Always `None` when no multitask model is loaded (or the model
95
+ call failed), matching every other optional-model fallback contract in
96
+ this codebase.
@@ -23,6 +23,8 @@ class MarketAnalysisDecision:
23
23
  reasons: list[str]
24
24
  signal_quality_score: float = 0.0
25
25
  signal_quality_breakdown: dict = field(default_factory=dict)
26
+ predicted_return_magnitude: float | None = None
27
+ predicted_volatility: float | None = None
26
28
 
27
29
  def to_dict(self) -> dict:
28
30
  return asdict(self)
@@ -88,6 +90,8 @@ def build_market_analysis_decision(
88
90
  retrain_min_regime_confidence: float = 0.20,
89
91
  low_regime_confidence_threshold: float = 0.35,
90
92
  use_composite_signal_score: bool = False,
93
+ predicted_return_magnitude: float | None = None,
94
+ predicted_volatility: float | None = None,
91
95
  ) -> MarketAnalysisDecision:
92
96
  reasons: list[str] = []
93
97
  decision_source = str(gating.get("decision_source", "unknown"))
@@ -130,6 +134,8 @@ def build_market_analysis_decision(
130
134
  reasons=reasons,
131
135
  signal_quality_score=signal_quality_score,
132
136
  signal_quality_breakdown=signal_quality_breakdown,
137
+ predicted_return_magnitude=predicted_return_magnitude,
138
+ predicted_volatility=predicted_volatility,
133
139
  )
134
140
 
135
141
  # Priority 2: reduce_risk - asset-level risk regime override even
@@ -148,6 +154,8 @@ def build_market_analysis_decision(
148
154
  reasons=reasons,
149
155
  signal_quality_score=signal_quality_score,
150
156
  signal_quality_breakdown=signal_quality_breakdown,
157
+ predicted_return_magnitude=predicted_return_magnitude,
158
+ predicted_volatility=predicted_volatility,
151
159
  )
152
160
 
153
161
  # Priority 3: reduce_risk - elevated cross-sectional volatility pressure
@@ -170,6 +178,8 @@ def build_market_analysis_decision(
170
178
  reasons=reasons,
171
179
  signal_quality_score=signal_quality_score,
172
180
  signal_quality_breakdown=signal_quality_breakdown,
181
+ predicted_return_magnitude=predicted_return_magnitude,
182
+ predicted_volatility=predicted_volatility,
173
183
  )
174
184
 
175
185
  # Priority 4: retrain_candidate - zero experts contributing AND the
@@ -191,6 +201,8 @@ def build_market_analysis_decision(
191
201
  reasons=reasons,
192
202
  signal_quality_score=signal_quality_score,
193
203
  signal_quality_breakdown=signal_quality_breakdown,
204
+ predicted_return_magnitude=predicted_return_magnitude,
205
+ predicted_volatility=predicted_volatility,
194
206
  )
195
207
 
196
208
  # Priority 5: simulate - liquidity blocked (zero volume or DDV below
@@ -210,6 +222,8 @@ def build_market_analysis_decision(
210
222
  reasons=reasons,
211
223
  signal_quality_score=signal_quality_score,
212
224
  signal_quality_breakdown=signal_quality_breakdown,
225
+ predicted_return_magnitude=predicted_return_magnitude,
226
+ predicted_volatility=predicted_volatility,
213
227
  )
214
228
 
215
229
  # Priority 6: simulate - thin market; participation rate would be
@@ -228,6 +242,8 @@ def build_market_analysis_decision(
228
242
  reasons=reasons,
229
243
  signal_quality_score=signal_quality_score,
230
244
  signal_quality_breakdown=signal_quality_breakdown,
245
+ predicted_return_magnitude=predicted_return_magnitude,
246
+ predicted_volatility=predicted_volatility,
231
247
  )
232
248
 
233
249
  # Priority 7: trade - only for trading-eligible assets with an actionable
@@ -256,6 +272,8 @@ def build_market_analysis_decision(
256
272
  reasons=reasons,
257
273
  signal_quality_score=signal_quality_score,
258
274
  signal_quality_breakdown=signal_quality_breakdown,
275
+ predicted_return_magnitude=predicted_return_magnitude,
276
+ predicted_volatility=predicted_volatility,
259
277
  )
260
278
 
261
279
  # Priority 8: simulate vs observe.
@@ -278,6 +296,8 @@ def build_market_analysis_decision(
278
296
  reasons=reasons,
279
297
  signal_quality_score=signal_quality_score,
280
298
  signal_quality_breakdown=signal_quality_breakdown,
299
+ predicted_return_magnitude=predicted_return_magnitude,
300
+ predicted_volatility=predicted_volatility,
281
301
  )
282
302
 
283
303
  reasons.append("no_actionable_edge")