aether-quant 0.6.0__tar.gz → 0.8.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 (322) hide show
  1. {aether_quant-0.6.0 → aether_quant-0.8.0}/Dockerfile.retraining_worker +4 -0
  2. {aether_quant-0.6.0 → aether_quant-0.8.0}/PKG-INFO +1 -1
  3. {aether_quant-0.6.0 → aether_quant-0.8.0}/README.md +310 -72
  4. {aether_quant-0.6.0 → aether_quant-0.8.0}/aether_quant.egg-info/PKG-INFO +1 -1
  5. {aether_quant-0.6.0 → aether_quant-0.8.0}/aether_quant.egg-info/SOURCES.txt +57 -0
  6. {aether_quant-0.6.0 → aether_quant-0.8.0}/aether_quant.egg-info/scm_file_list.json +57 -0
  7. aether_quant-0.8.0/aether_quant.egg-info/scm_version.json +8 -0
  8. {aether_quant-0.6.0 → aether_quant-0.8.0}/analyzer/README.md +35 -0
  9. {aether_quant-0.6.0 → aether_quant-0.8.0}/analyzer/market_analyzer.py +33 -6
  10. {aether_quant-0.6.0 → aether_quant-0.8.0}/aq_cli.py +95 -0
  11. {aether_quant-0.6.0 → aether_quant-0.8.0}/config.json +287 -12
  12. {aether_quant-0.6.0 → aether_quant-0.8.0}/data_pipeline/README.md +35 -0
  13. {aether_quant-0.6.0 → aether_quant-0.8.0}/data_pipeline/yfinance_backfill.py +9 -1
  14. {aether_quant-0.6.0 → aether_quant-0.8.0}/development/Changelog.md +1304 -1
  15. {aether_quant-0.6.0 → aether_quant-0.8.0}/development/Problems.md +301 -0
  16. aether_quant-0.8.0/development/backtest_equity_chart.png +0 -0
  17. {aether_quant-0.6.0 → aether_quant-0.8.0}/development/infrastructure.md +24 -1
  18. {aether_quant-0.6.0 → aether_quant-0.8.0}/development/v2_architecture.md +304 -23
  19. {aether_quant-0.6.0 → aether_quant-0.8.0}/docker-compose.yml +26 -0
  20. {aether_quant-0.6.0 → aether_quant-0.8.0}/execution/README.md +51 -0
  21. aether_quant-0.8.0/execution/paper_readiness_scheduler.py +137 -0
  22. {aether_quant-0.6.0 → aether_quant-0.8.0}/experience/redis_queue.py +25 -0
  23. aether_quant-0.8.0/features/__init__.py +35 -0
  24. aether_quant-0.8.0/features/macro_features.py +79 -0
  25. aether_quant-0.8.0/features/technical_indicators.py +185 -0
  26. aether_quant-0.8.0/inference/README.md +129 -0
  27. aether_quant-0.8.0/inference/__init__.py +13 -0
  28. aether_quant-0.8.0/inference/exported_model.py +321 -0
  29. {aether_quant-0.6.0 → aether_quant-0.8.0}/lean.json +1 -1
  30. {aether_quant-0.6.0 → aether_quant-0.8.0}/liquidity/README.md +34 -0
  31. aether_quant-0.8.0/liquidity/__init__.py +8 -0
  32. {aether_quant-0.6.0 → aether_quant-0.8.0}/main.py +809 -125
  33. aether_quant-0.8.0/ml/gating_model.json +570 -0
  34. aether_quant-0.8.0/ml/gating_training_metrics.json +130 -0
  35. aether_quant-0.8.0/ml/multitask_feature_schema.json +76 -0
  36. aether_quant-0.8.0/ml/multitask_model.json +7703 -0
  37. aether_quant-0.8.0/ml/multitask_training_metrics.json +6320 -0
  38. aether_quant-0.8.0/ml/sequence_feature_schema.json +64 -0
  39. aether_quant-0.8.0/ml/sequence_model.json +15233 -0
  40. aether_quant-0.8.0/ml/sequence_training_metrics.json +506 -0
  41. aether_quant-0.8.0/ml/versions/gating-only-05c572c8-9566-4152-805c-fa57142a3f8c/gating_model.json +570 -0
  42. aether_quant-0.8.0/ml/versions/gating-only-05c572c8-9566-4152-805c-fa57142a3f8c/gating_training_metrics.json +130 -0
  43. aether_quant-0.8.0/ml/versions/gating-only-26218402-34d9-4a0a-add8-ee5d50dd0459/gating_feature_schema.json +30 -0
  44. aether_quant-0.8.0/ml/versions/multitask-only-f5708084-512b-4484-a47b-0720f9c1460c/multitask_feature_schema.json +76 -0
  45. aether_quant-0.8.0/ml/versions/multitask-only-f5708084-512b-4484-a47b-0720f9c1460c/multitask_model.json +7703 -0
  46. aether_quant-0.8.0/ml/versions/multitask-only-f5708084-512b-4484-a47b-0720f9c1460c/multitask_training_metrics.json +6320 -0
  47. aether_quant-0.8.0/ml/versions/stage123-1783709428/gating_feature_schema.json +30 -0
  48. aether_quant-0.8.0/ml/versions/stage123-1783709428/gating_model.json +570 -0
  49. aether_quant-0.8.0/ml/versions/stage123-1783709428/gating_training_metrics.json +190 -0
  50. aether_quant-0.8.0/ml/versions/stage123-1783709428/multitask_feature_schema.json +52 -0
  51. aether_quant-0.8.0/ml/versions/stage123-1783709428/multitask_model.json +5888 -0
  52. aether_quant-0.8.0/ml/versions/stage123-1783709428/multitask_training_metrics.json +248 -0
  53. aether_quant-0.8.0/ml/versions/stage4-1783711025/gating_feature_schema.json +30 -0
  54. aether_quant-0.8.0/ml/versions/stage4-1783711025/gating_model.json +570 -0
  55. aether_quant-0.8.0/ml/versions/stage4-1783711025/gating_training_metrics.json +190 -0
  56. aether_quant-0.8.0/ml/versions/stage4-1783711025/multitask_feature_schema.json +52 -0
  57. aether_quant-0.8.0/ml/versions/stage4-1783711025/multitask_model.json +5888 -0
  58. aether_quant-0.8.0/ml/versions/stage4-1783711025/multitask_training_metrics.json +248 -0
  59. aether_quant-0.8.0/ml/versions/stage5-1783715333/sequence_feature_schema.json +53 -0
  60. aether_quant-0.8.0/ml/versions/stage5-1783715333/sequence_model.json +13258 -0
  61. aether_quant-0.8.0/ml/versions/stage5-1783715333/sequence_training_metrics.json +209 -0
  62. aether_quant-0.8.0/ml/versions/v1/multitask_feature_schema.json +52 -0
  63. aether_quant-0.8.0/ml/versions/v1/multitask_model.json +5888 -0
  64. aether_quant-0.8.0/ml/versions/v1/multitask_training_metrics.json +284 -0
  65. aether_quant-0.8.0/ml/versions/v1/sequence_feature_schema.json +53 -0
  66. aether_quant-0.8.0/ml/versions/v1/sequence_model.json +13258 -0
  67. aether_quant-0.8.0/ml/versions/v1/sequence_training_metrics.json +248 -0
  68. aether_quant-0.8.0/moe/README.md +166 -0
  69. {aether_quant-0.6.0 → aether_quant-0.8.0}/moe/gating.py +108 -1
  70. aether_quant-0.8.0/monitoring/neural_network_state.py +444 -0
  71. {aether_quant-0.6.0 → aether_quant-0.8.0}/performance/README.md +20 -2
  72. aether_quant-0.8.0/performance/rank_ic_monitor.py +122 -0
  73. {aether_quant-0.6.0 → aether_quant-0.8.0}/performance/trigger_worker.py +16 -1
  74. {aether_quant-0.6.0 → aether_quant-0.8.0}/performance/triggers.py +78 -1
  75. aether_quant-0.8.0/portfolio/README.md +154 -0
  76. aether_quant-0.8.0/portfolio/__init__.py +8 -0
  77. aether_quant-0.8.0/portfolio/book_construction.py +137 -0
  78. aether_quant-0.8.0/regime/README.md +57 -0
  79. {aether_quant-0.6.0 → aether_quant-0.8.0}/retraining/README.md +34 -4
  80. {aether_quant-0.6.0 → aether_quant-0.8.0}/retraining/__init__.py +8 -0
  81. {aether_quant-0.6.0 → aether_quant-0.8.0}/retraining/artifacts.py +40 -5
  82. {aether_quant-0.6.0 → aether_quant-0.8.0}/retraining/orchestrator.py +108 -0
  83. {aether_quant-0.6.0 → aether_quant-0.8.0}/retraining/planning.py +8 -0
  84. {aether_quant-0.6.0 → aether_quant-0.8.0}/retraining/worker.py +14 -0
  85. aether_quant-0.8.0/risk/README.md +139 -0
  86. {aether_quant-0.6.0 → aether_quant-0.8.0}/risk/position_sizing.py +79 -2
  87. {aether_quant-0.6.0 → aether_quant-0.8.0}/tests/README.md +2 -2
  88. {aether_quant-0.6.0 → aether_quant-0.8.0}/tests/test_aq_cli.py +126 -0
  89. {aether_quant-0.6.0 → aether_quant-0.8.0}/tests/test_experience_queue.py +36 -2
  90. aether_quant-0.8.0/tests/test_exported_model.py +483 -0
  91. aether_quant-0.8.0/tests/test_gating_network.py +476 -0
  92. {aether_quant-0.6.0 → aether_quant-0.8.0}/tests/test_lean_backtest_ml_coverage.py +55 -3
  93. aether_quant-0.8.0/tests/test_macro_features.py +49 -0
  94. {aether_quant-0.6.0 → aether_quant-0.8.0}/tests/test_market_analyzer.py +46 -0
  95. {aether_quant-0.6.0 → aether_quant-0.8.0}/tests/test_market_topology.py +103 -1
  96. aether_quant-0.8.0/tests/test_neural_network_state.py +427 -0
  97. aether_quant-0.8.0/tests/test_paper_readiness_scheduler.py +104 -0
  98. aether_quant-0.8.0/tests/test_portfolio_book_construction.py +150 -0
  99. {aether_quant-0.6.0 → aether_quant-0.8.0}/tests/test_position_sizing.py +87 -0
  100. aether_quant-0.8.0/tests/test_rank_ic_monitor.py +137 -0
  101. {aether_quant-0.6.0 → aether_quant-0.8.0}/tests/test_retraining_artifacts.py +136 -1
  102. {aether_quant-0.6.0 → aether_quant-0.8.0}/tests/test_retraining_orchestrator.py +149 -0
  103. {aether_quant-0.6.0 → aether_quant-0.8.0}/tests/test_retraining_planning.py +17 -0
  104. {aether_quant-0.6.0 → aether_quant-0.8.0}/tests/test_retraining_worker.py +16 -2
  105. {aether_quant-0.6.0 → aether_quant-0.8.0}/tests/test_simulated_portfolio.py +29 -0
  106. aether_quant-0.8.0/tests/test_technical_indicators.py +261 -0
  107. aether_quant-0.8.0/tests/test_train_cross_sectional_features.py +535 -0
  108. aether_quant-0.8.0/tests/test_train_indicators.py +187 -0
  109. aether_quant-0.8.0/tests/test_train_macro_features.py +157 -0
  110. aether_quant-0.8.0/tests/test_train_multitask.py +278 -0
  111. aether_quant-0.8.0/tests/test_train_multitask_architecture.py +189 -0
  112. aether_quant-0.8.0/tests/test_train_pipeline.py +931 -0
  113. aether_quant-0.8.0/tests/test_train_ranking_validation.py +385 -0
  114. aether_quant-0.8.0/tests/test_train_sequence.py +193 -0
  115. aether_quant-0.8.0/tests/test_train_sequence_architecture.py +250 -0
  116. aether_quant-0.8.0/tests/test_train_walk_forward_windows.py +131 -0
  117. {aether_quant-0.6.0 → aether_quant-0.8.0}/tests/test_trigger_worker.py +29 -0
  118. {aether_quant-0.6.0 → aether_quant-0.8.0}/tests/test_triggers.py +95 -0
  119. {aether_quant-0.6.0 → aether_quant-0.8.0}/topology/README.md +34 -0
  120. {aether_quant-0.6.0 → aether_quant-0.8.0}/topology/market_topology.py +36 -0
  121. aether_quant-0.8.0/train.py +4912 -0
  122. aether_quant-0.8.0/train_multitask.py +506 -0
  123. aether_quant-0.8.0/train_sequence.py +514 -0
  124. {aether_quant-0.6.0 → aether_quant-0.8.0}/webui/src/components/neuralnet/NeuralNetworkScene3D.tsx +60 -7
  125. {aether_quant-0.6.0 → aether_quant-0.8.0}/webui/src/components/neuralnet/NeuralNetworkStatsPanel.tsx +65 -0
  126. {aether_quant-0.6.0 → aether_quant-0.8.0}/webui/src/components/risk/AssetSizingTable.tsx +8 -0
  127. {aether_quant-0.6.0 → aether_quant-0.8.0}/webui/src/components/signals/Badge.tsx +5 -0
  128. {aether_quant-0.6.0 → aether_quant-0.8.0}/webui/src/types/state.ts +62 -1
  129. aether_quant-0.6.0/aether_quant.egg-info/scm_version.json +0 -8
  130. aether_quant-0.6.0/development/backtest_equity_chart.png +0 -0
  131. aether_quant-0.6.0/inference/README.md +0 -35
  132. aether_quant-0.6.0/inference/__init__.py +0 -3
  133. aether_quant-0.6.0/inference/exported_model.py +0 -68
  134. aether_quant-0.6.0/liquidity/__init__.py +0 -3
  135. aether_quant-0.6.0/ml/versions/gating-only-26218402-34d9-4a0a-add8-ee5d50dd0459/gating_model.json +0 -570
  136. aether_quant-0.6.0/ml/versions/gating-only-26218402-34d9-4a0a-add8-ee5d50dd0459/gating_training_metrics.json +0 -190
  137. aether_quant-0.6.0/moe/README.md +0 -61
  138. aether_quant-0.6.0/monitoring/neural_network_state.py +0 -238
  139. aether_quant-0.6.0/regime/README.md +0 -18
  140. aether_quant-0.6.0/risk/README.md +0 -50
  141. aether_quant-0.6.0/tests/test_exported_model.py +0 -106
  142. aether_quant-0.6.0/tests/test_gating_network.py +0 -235
  143. aether_quant-0.6.0/tests/test_neural_network_state.py +0 -148
  144. aether_quant-0.6.0/tests/test_train_pipeline.py +0 -285
  145. aether_quant-0.6.0/train.py +0 -2378
  146. {aether_quant-0.6.0 → aether_quant-0.8.0}/.dockerignore +0 -0
  147. {aether_quant-0.6.0 → aether_quant-0.8.0}/.env.compose.example +0 -0
  148. {aether_quant-0.6.0 → aether_quant-0.8.0}/.env.live.example +0 -0
  149. {aether_quant-0.6.0 → aether_quant-0.8.0}/.gitattributes +0 -0
  150. {aether_quant-0.6.0 → aether_quant-0.8.0}/.github/workflows/ci.yml +0 -0
  151. {aether_quant-0.6.0 → aether_quant-0.8.0}/.github/workflows/release.yml +0 -0
  152. {aether_quant-0.6.0 → aether_quant-0.8.0}/.gitignore +0 -0
  153. {aether_quant-0.6.0 → aether_quant-0.8.0}/Dockerfile +0 -0
  154. {aether_quant-0.6.0 → aether_quant-0.8.0}/Dockerfile.workers +0 -0
  155. {aether_quant-0.6.0 → aether_quant-0.8.0}/aether_quant.egg-info/dependency_links.txt +0 -0
  156. {aether_quant-0.6.0 → aether_quant-0.8.0}/aether_quant.egg-info/entry_points.txt +0 -0
  157. {aether_quant-0.6.0 → aether_quant-0.8.0}/aether_quant.egg-info/top_level.txt +0 -0
  158. {aether_quant-0.6.0 → aether_quant-0.8.0}/analyzer/__init__.py +0 -0
  159. {aether_quant-0.6.0 → aether_quant-0.8.0}/backtests/.gitkeep +0 -0
  160. {aether_quant-0.6.0 → aether_quant-0.8.0}/data/alternative/estimize/consensus/aapl/.keep +0 -0
  161. {aether_quant-0.6.0 → aether_quant-0.8.0}/data/alternative/estimize/estimate/.keep +0 -0
  162. {aether_quant-0.6.0 → aether_quant-0.8.0}/data/alternative/estimize/release/.keep +0 -0
  163. {aether_quant-0.6.0 → aether_quant-0.8.0}/data/alternative/sec/aapl/.keep +0 -0
  164. {aether_quant-0.6.0 → aether_quant-0.8.0}/data/alternative/trading-economics/.keep +0 -0
  165. {aether_quant-0.6.0 → aether_quant-0.8.0}/data/alternative/trading-economics/calendar/.keep +0 -0
  166. {aether_quant-0.6.0 → aether_quant-0.8.0}/data/alternative/trading-economics/earnings/.keep +0 -0
  167. {aether_quant-0.6.0 → aether_quant-0.8.0}/data/alternative/trading-economics/indicator/.keep +0 -0
  168. {aether_quant-0.6.0 → aether_quant-0.8.0}/data_pipeline/__init__.py +0 -0
  169. {aether_quant-0.6.0 → aether_quant-0.8.0}/data_pipeline/fetch.py +0 -0
  170. {aether_quant-0.6.0 → aether_quant-0.8.0}/data_pipeline/v2_manifest.py +0 -0
  171. {aether_quant-0.6.0 → aether_quant-0.8.0}/development/README.md +0 -0
  172. {aether_quant-0.6.0 → aether_quant-0.8.0}/development/logo.png +0 -0
  173. {aether_quant-0.6.0 → aether_quant-0.8.0}/execution/__init__.py +0 -0
  174. {aether_quant-0.6.0 → aether_quant-0.8.0}/execution/config_cache.py +0 -0
  175. {aether_quant-0.6.0 → aether_quant-0.8.0}/execution/live_credentials.py +0 -0
  176. {aether_quant-0.6.0 → aether_quant-0.8.0}/execution/live_credentials_io.py +0 -0
  177. {aether_quant-0.6.0 → aether_quant-0.8.0}/execution/order_gate.py +0 -0
  178. {aether_quant-0.6.0 → aether_quant-0.8.0}/execution/paper_readiness.py +0 -0
  179. {aether_quant-0.6.0 → aether_quant-0.8.0}/execution/paper_readiness_io.py +0 -0
  180. {aether_quant-0.6.0 → aether_quant-0.8.0}/execution/paper_readiness_report.py +0 -0
  181. {aether_quant-0.6.0 → aether_quant-0.8.0}/execution/runtime_config_io.py +0 -0
  182. {aether_quant-0.6.0 → aether_quant-0.8.0}/experience/README.md +0 -0
  183. {aether_quant-0.6.0 → aether_quant-0.8.0}/experience/__init__.py +0 -0
  184. {aether_quant-0.6.0 → aether_quant-0.8.0}/experience/observation_metrics.py +0 -0
  185. {aether_quant-0.6.0 → aether_quant-0.8.0}/experience/postgres_worker.py +0 -0
  186. {aether_quant-0.6.0 → aether_quant-0.8.0}/experience/simulated_portfolio.py +0 -0
  187. {aether_quant-0.6.0 → aether_quant-0.8.0}/experts/README.md +0 -0
  188. {aether_quant-0.6.0 → aether_quant-0.8.0}/experts/__init__.py +0 -0
  189. {aether_quant-0.6.0 → aether_quant-0.8.0}/experts/expert_datasets.py +0 -0
  190. {aether_quant-0.6.0 → aether_quant-0.8.0}/generate_backtest_report.py +0 -0
  191. {aether_quant-0.6.0 → aether_quant-0.8.0}/liquidity/market_liquidity.py +0 -0
  192. {aether_quant-0.6.0 → aether_quant-0.8.0}/ml/README.md +0 -0
  193. {aether_quant-0.6.0 → aether_quant-0.8.0}/ml/gating_feature_schema.json +0 -0
  194. {aether_quant-0.6.0/ml/versions/gating-only-26218402-34d9-4a0a-add8-ee5d50dd0459 → aether_quant-0.8.0/ml/versions/gating-only-05c572c8-9566-4152-805c-fa57142a3f8c}/gating_feature_schema.json +0 -0
  195. {aether_quant-0.6.0/ml → aether_quant-0.8.0/ml/versions/gating-only-26218402-34d9-4a0a-add8-ee5d50dd0459}/gating_model.json +0 -0
  196. {aether_quant-0.6.0/ml → aether_quant-0.8.0/ml/versions/gating-only-26218402-34d9-4a0a-add8-ee5d50dd0459}/gating_training_metrics.json +0 -0
  197. {aether_quant-0.6.0 → aether_quant-0.8.0}/moe/__init__.py +0 -0
  198. {aether_quant-0.6.0 → aether_quant-0.8.0}/monitoring/README.md +0 -0
  199. {aether_quant-0.6.0 → aether_quant-0.8.0}/monitoring/__init__.py +0 -0
  200. {aether_quant-0.6.0 → aether_quant-0.8.0}/monitoring/api_server.py +0 -0
  201. {aether_quant-0.6.0 → aether_quant-0.8.0}/notifications/README.md +0 -0
  202. {aether_quant-0.6.0 → aether_quant-0.8.0}/notifications/__init__.py +0 -0
  203. {aether_quant-0.6.0 → aether_quant-0.8.0}/notifications/postgres_telegram.py +0 -0
  204. {aether_quant-0.6.0 → aether_quant-0.8.0}/notifications/telegram_alerts.py +0 -0
  205. {aether_quant-0.6.0 → aether_quant-0.8.0}/notifications/telegram_client.py +0 -0
  206. {aether_quant-0.6.0 → aether_quant-0.8.0}/notifications/telegram_worker.py +0 -0
  207. {aether_quant-0.6.0 → aether_quant-0.8.0}/performance/__init__.py +0 -0
  208. {aether_quant-0.6.0 → aether_quant-0.8.0}/performance/postgres_triggers.py +0 -0
  209. {aether_quant-0.6.0 → aether_quant-0.8.0}/pyproject.toml +0 -0
  210. {aether_quant-0.6.0 → aether_quant-0.8.0}/regime/__init__.py +0 -0
  211. {aether_quant-0.6.0 → aether_quant-0.8.0}/regime/market_regime.py +0 -0
  212. {aether_quant-0.6.0 → aether_quant-0.8.0}/requirements/README.md +0 -0
  213. {aether_quant-0.6.0 → aether_quant-0.8.0}/requirements/requirements-dev.txt +0 -0
  214. {aether_quant-0.6.0 → aether_quant-0.8.0}/requirements/requirements-retraining-worker.txt +0 -0
  215. {aether_quant-0.6.0 → aether_quant-0.8.0}/requirements/requirements-runtime.txt +0 -0
  216. {aether_quant-0.6.0 → aether_quant-0.8.0}/requirements/requirements-workers.txt +0 -0
  217. {aether_quant-0.6.0 → aether_quant-0.8.0}/requirements/requirements.txt +0 -0
  218. {aether_quant-0.6.0 → aether_quant-0.8.0}/retraining/backtest_gate.py +0 -0
  219. {aether_quant-0.6.0 → aether_quant-0.8.0}/retraining/lean_backtest.py +0 -0
  220. {aether_quant-0.6.0 → aether_quant-0.8.0}/retraining/postgres_registry.py +0 -0
  221. {aether_quant-0.6.0 → aether_quant-0.8.0}/retraining/status_export.py +0 -0
  222. {aether_quant-0.6.0 → aether_quant-0.8.0}/retraining/validation_gate.py +0 -0
  223. {aether_quant-0.6.0 → aether_quant-0.8.0}/retraining/vault_client.py +0 -0
  224. {aether_quant-0.6.0 → aether_quant-0.8.0}/retraining/vault_commands.py +0 -0
  225. {aether_quant-0.6.0 → aether_quant-0.8.0}/risk/__init__.py +0 -0
  226. {aether_quant-0.6.0 → aether_quant-0.8.0}/risk/manual_override.py +0 -0
  227. {aether_quant-0.6.0 → aether_quant-0.8.0}/risk_controls.py +0 -0
  228. {aether_quant-0.6.0 → aether_quant-0.8.0}/setup.cfg +0 -0
  229. {aether_quant-0.6.0 → aether_quant-0.8.0}/tests/test_backtest_gate.py +0 -0
  230. {aether_quant-0.6.0 → aether_quant-0.8.0}/tests/test_config_cache.py +0 -0
  231. {aether_quant-0.6.0 → aether_quant-0.8.0}/tests/test_expert_datasets.py +0 -0
  232. {aether_quant-0.6.0 → aether_quant-0.8.0}/tests/test_expert_models.py +0 -0
  233. {aether_quant-0.6.0 → aether_quant-0.8.0}/tests/test_fetch.py +0 -0
  234. {aether_quant-0.6.0 → aether_quant-0.8.0}/tests/test_generate_backtest_report.py +0 -0
  235. {aether_quant-0.6.0 → aether_quant-0.8.0}/tests/test_lean_backtest.py +0 -0
  236. {aether_quant-0.6.0 → aether_quant-0.8.0}/tests/test_learned_topology.py +0 -0
  237. {aether_quant-0.6.0 → aether_quant-0.8.0}/tests/test_live_credentials.py +0 -0
  238. {aether_quant-0.6.0 → aether_quant-0.8.0}/tests/test_live_credentials_io.py +0 -0
  239. {aether_quant-0.6.0 → aether_quant-0.8.0}/tests/test_manual_override.py +0 -0
  240. {aether_quant-0.6.0 → aether_quant-0.8.0}/tests/test_market_liquidity.py +0 -0
  241. {aether_quant-0.6.0 → aether_quant-0.8.0}/tests/test_market_regime.py +0 -0
  242. {aether_quant-0.6.0 → aether_quant-0.8.0}/tests/test_observation_metrics.py +0 -0
  243. {aether_quant-0.6.0 → aether_quant-0.8.0}/tests/test_order_gate.py +0 -0
  244. {aether_quant-0.6.0 → aether_quant-0.8.0}/tests/test_paper_readiness.py +0 -0
  245. {aether_quant-0.6.0 → aether_quant-0.8.0}/tests/test_paper_readiness_io.py +0 -0
  246. {aether_quant-0.6.0 → aether_quant-0.8.0}/tests/test_paper_readiness_report.py +0 -0
  247. {aether_quant-0.6.0 → aether_quant-0.8.0}/tests/test_postgres_telegram.py +0 -0
  248. {aether_quant-0.6.0 → aether_quant-0.8.0}/tests/test_postgres_triggers.py +0 -0
  249. {aether_quant-0.6.0 → aether_quant-0.8.0}/tests/test_postgres_worker.py +0 -0
  250. {aether_quant-0.6.0 → aether_quant-0.8.0}/tests/test_retraining_postgres_registry.py +0 -0
  251. {aether_quant-0.6.0 → aether_quant-0.8.0}/tests/test_risk_controls.py +0 -0
  252. {aether_quant-0.6.0 → aether_quant-0.8.0}/tests/test_runtime_config_io.py +0 -0
  253. {aether_quant-0.6.0 → aether_quant-0.8.0}/tests/test_status_export.py +0 -0
  254. {aether_quant-0.6.0 → aether_quant-0.8.0}/tests/test_telegram_alerts.py +0 -0
  255. {aether_quant-0.6.0 → aether_quant-0.8.0}/tests/test_telegram_client.py +0 -0
  256. {aether_quant-0.6.0 → aether_quant-0.8.0}/tests/test_telegram_worker.py +0 -0
  257. {aether_quant-0.6.0 → aether_quant-0.8.0}/tests/test_train_gating.py +0 -0
  258. {aether_quant-0.6.0 → aether_quant-0.8.0}/tests/test_train_topology.py +0 -0
  259. {aether_quant-0.6.0 → aether_quant-0.8.0}/tests/test_v2_pipeline_manifest.py +0 -0
  260. {aether_quant-0.6.0 → aether_quant-0.8.0}/tests/test_validation_gate.py +0 -0
  261. {aether_quant-0.6.0 → aether_quant-0.8.0}/tests/test_vault_client.py +0 -0
  262. {aether_quant-0.6.0 → aether_quant-0.8.0}/tests/test_vault_commands.py +0 -0
  263. {aether_quant-0.6.0 → aether_quant-0.8.0}/tests/test_yfinance_backfill.py +0 -0
  264. {aether_quant-0.6.0 → aether_quant-0.8.0}/topology/__init__.py +0 -0
  265. {aether_quant-0.6.0 → aether_quant-0.8.0}/topology/learned_topology.py +0 -0
  266. {aether_quant-0.6.0 → aether_quant-0.8.0}/train_gating.py +0 -0
  267. {aether_quant-0.6.0 → aether_quant-0.8.0}/train_topology.py +0 -0
  268. {aether_quant-0.6.0 → aether_quant-0.8.0}/visualization/README.md +0 -0
  269. {aether_quant-0.6.0 → aether_quant-0.8.0}/webui/.gitignore +0 -0
  270. {aether_quant-0.6.0 → aether_quant-0.8.0}/webui/.oxlintrc.json +0 -0
  271. {aether_quant-0.6.0 → aether_quant-0.8.0}/webui/README.md +0 -0
  272. {aether_quant-0.6.0 → aether_quant-0.8.0}/webui/index.html +0 -0
  273. {aether_quant-0.6.0 → aether_quant-0.8.0}/webui/overview_v2_12.png +0 -0
  274. {aether_quant-0.6.0 → aether_quant-0.8.0}/webui/package-lock.json +0 -0
  275. {aether_quant-0.6.0 → aether_quant-0.8.0}/webui/package.json +0 -0
  276. {aether_quant-0.6.0 → aether_quant-0.8.0}/webui/public/favicon.svg +0 -0
  277. {aether_quant-0.6.0 → aether_quant-0.8.0}/webui/public/icons.svg +0 -0
  278. {aether_quant-0.6.0 → aether_quant-0.8.0}/webui/risk_v2_12.png +0 -0
  279. {aether_quant-0.6.0 → aether_quant-0.8.0}/webui/src/App.tsx +0 -0
  280. {aether_quant-0.6.0 → aether_quant-0.8.0}/webui/src/api/client.ts +0 -0
  281. {aether_quant-0.6.0 → aether_quant-0.8.0}/webui/src/api/hooks.ts +0 -0
  282. {aether_quant-0.6.0 → aether_quant-0.8.0}/webui/src/components/heatmap/AssetHeatmap.tsx +0 -0
  283. {aether_quant-0.6.0 → aether_quant-0.8.0}/webui/src/components/layout/AppShell.tsx +0 -0
  284. {aether_quant-0.6.0 → aether_quant-0.8.0}/webui/src/components/layout/Panel.tsx +0 -0
  285. {aether_quant-0.6.0 → aether_quant-0.8.0}/webui/src/components/monitoring/CountTable.tsx +0 -0
  286. {aether_quant-0.6.0 → aether_quant-0.8.0}/webui/src/components/monitoring/MonitoringFeeds.tsx +0 -0
  287. {aether_quant-0.6.0 → aether_quant-0.8.0}/webui/src/components/monitoring/ObservationPanel.tsx +0 -0
  288. {aether_quant-0.6.0 → aether_quant-0.8.0}/webui/src/components/monitoring/PaperReadinessPanel.tsx +0 -0
  289. {aether_quant-0.6.0 → aether_quant-0.8.0}/webui/src/components/monitoring/PerformanceTriggersPanel.tsx +0 -0
  290. {aether_quant-0.6.0 → aether_quant-0.8.0}/webui/src/components/monitoring/RawStateViewer.tsx +0 -0
  291. {aether_quant-0.6.0 → aether_quant-0.8.0}/webui/src/components/monitoring/RetrainingStatusPanel.tsx +0 -0
  292. {aether_quant-0.6.0 → aether_quant-0.8.0}/webui/src/components/risk/LiquidityTable.tsx +0 -0
  293. {aether_quant-0.6.0 → aether_quant-0.8.0}/webui/src/components/risk/RiskBar.tsx +0 -0
  294. {aether_quant-0.6.0 → aether_quant-0.8.0}/webui/src/components/risk/RiskCore.tsx +0 -0
  295. {aether_quant-0.6.0 → aether_quant-0.8.0}/webui/src/components/risk/StrategyRiskCards.tsx +0 -0
  296. {aether_quant-0.6.0 → aether_quant-0.8.0}/webui/src/components/scene3d/Scene3D.tsx +0 -0
  297. {aether_quant-0.6.0 → aether_quant-0.8.0}/webui/src/components/scorecards/Scorecards.tsx +0 -0
  298. {aether_quant-0.6.0 → aether_quant-0.8.0}/webui/src/components/signals/PositionsList.tsx +0 -0
  299. {aether_quant-0.6.0 → aether_quant-0.8.0}/webui/src/components/signals/SignalBoard.tsx +0 -0
  300. {aether_quant-0.6.0 → aether_quant-0.8.0}/webui/src/components/topology/ClusterList.tsx +0 -0
  301. {aether_quant-0.6.0 → aether_quant-0.8.0}/webui/src/components/topology/TopologyLearningPanel.tsx +0 -0
  302. {aether_quant-0.6.0 → aether_quant-0.8.0}/webui/src/components/topology/TopologyScene3D.tsx +0 -0
  303. {aether_quant-0.6.0 → aether_quant-0.8.0}/webui/src/components/tracing/AssetPerformancePanel.tsx +0 -0
  304. {aether_quant-0.6.0 → aether_quant-0.8.0}/webui/src/components/tracing/BacktestEquityPanel.tsx +0 -0
  305. {aether_quant-0.6.0 → aether_quant-0.8.0}/webui/src/components/tracing/DivergingBarChart.tsx +0 -0
  306. {aether_quant-0.6.0 → aether_quant-0.8.0}/webui/src/components/tracing/LineChart.tsx +0 -0
  307. {aether_quant-0.6.0 → aether_quant-0.8.0}/webui/src/components/tracing/MetricsSnapshotPanel.tsx +0 -0
  308. {aether_quant-0.6.0 → aether_quant-0.8.0}/webui/src/components/tracing/ObservationEquityPanel.tsx +0 -0
  309. {aether_quant-0.6.0 → aether_quant-0.8.0}/webui/src/index.css +0 -0
  310. {aether_quant-0.6.0 → aether_quant-0.8.0}/webui/src/lib/downsample.ts +0 -0
  311. {aether_quant-0.6.0 → aether_quant-0.8.0}/webui/src/lib/format.ts +0 -0
  312. {aether_quant-0.6.0 → aether_quant-0.8.0}/webui/src/main.tsx +0 -0
  313. {aether_quant-0.6.0 → aether_quant-0.8.0}/webui/src/pages/NeuralNetworkPage.tsx +0 -0
  314. {aether_quant-0.6.0 → aether_quant-0.8.0}/webui/src/pages/Overview.tsx +0 -0
  315. {aether_quant-0.6.0 → aether_quant-0.8.0}/webui/src/pages/RiskPage.tsx +0 -0
  316. {aether_quant-0.6.0 → aether_quant-0.8.0}/webui/src/pages/TopologyPage.tsx +0 -0
  317. {aether_quant-0.6.0 → aether_quant-0.8.0}/webui/src/pages/TracingPage.tsx +0 -0
  318. {aether_quant-0.6.0 → aether_quant-0.8.0}/webui/src/types/tracing.ts +0 -0
  319. {aether_quant-0.6.0 → aether_quant-0.8.0}/webui/tsconfig.app.json +0 -0
  320. {aether_quant-0.6.0 → aether_quant-0.8.0}/webui/tsconfig.json +0 -0
  321. {aether_quant-0.6.0 → aether_quant-0.8.0}/webui/tsconfig.node.json +0 -0
  322. {aether_quant-0.6.0 → aether_quant-0.8.0}/webui/vite.config.ts +0 -0
@@ -7,11 +7,15 @@ COPY experience/ ./experience/
7
7
  COPY performance/ ./performance/
8
8
  COPY regime/ ./regime/
9
9
  COPY experts/ ./experts/
10
+ COPY features/ ./features/
10
11
  COPY topology/ ./topology/
11
12
  COPY moe/ ./moe/
12
13
  COPY inference/ ./inference/
14
+ COPY risk/ ./risk/
13
15
  COPY retraining/ ./retraining/
14
16
  COPY train.py .
15
17
  COPY train_topology.py .
16
18
  COPY train_gating.py .
19
+ COPY train_multitask.py .
20
+ COPY train_sequence.py .
17
21
  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.8.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-934%2F945%20passing-red?style=flat-square&labelColor=1A1A1A" alt="934 of 945 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>
@@ -32,14 +32,16 @@ Mixture-of-Experts ensemble (bullish/bearish/sideways/volatility specialists)
32
32
  routed by a learned gating network, a market-regime detector, a 3D market
33
33
  topology layer that combines a deterministic correlation embedding with a
34
34
  learned probabilistic overlay, a liquidity/market-impact engine that adjusts
35
- position sizing to real trading conditions, and a controlled retraining loop
36
- that lets the model itself evolve as markets do — all wired together and
37
- validated end-to-end inside QuantConnect's Lean engine. The thesis this
38
- project exists to test is simple to state and hard to prove: **markets are
39
- non-stationary, so a trading model should be too.** Every subsystem here
40
- exists to make the model adapt — to regime shifts, to changing correlation
41
- structure, to liquidity conditions — rather than to fit one historical
42
- window and hope it generalizes.
35
+ position sizing to real trading conditions, a cross-sectional ranking signal
36
+ that sizes each position by its predicted relative strength against the rest
37
+ of the trading universe, and a controlled retraining loop that lets the
38
+ model itself evolve as markets do — all wired together and validated
39
+ end-to-end inside QuantConnect's Lean engine. The thesis this project exists
40
+ to test is simple to state and hard to prove: **markets are non-stationary,
41
+ so a trading model should be too.** Every subsystem here exists to make the
42
+ model adapt — to regime shifts, to changing correlation structure, to
43
+ liquidity conditions — rather than to fit one historical window and hope it
44
+ generalizes.
43
45
 
44
46
  ## Table of Contents
45
47
 
@@ -158,11 +160,14 @@ that a controlled retraining loop reads from to evolve the model over time.
158
160
 
159
161
  ```mermaid
160
162
  flowchart LR
161
- A["Lean data folder<br/>stocks, ETFs, crypto"] --> B["Feature pipeline<br/>train.py"]
163
+ A["Lean data folder<br/>stocks, ETFs, bonds, crypto"] --> B["Feature pipeline<br/>train.py<br/>62-dim: price/volume + indicators +<br/>regime + liquidity + topology + peer returns + macro"]
162
164
  B --> C["Regime detection<br/>trend, volatility, drawdown, correlation"]
163
165
  B --> D["3D topology modeling<br/>market structure and clusters"]
164
- C --> E["Gating network<br/>the manager"]
166
+ B -.-> U["Sequence encoder (Phase 2)<br/>causal-TCN, 30-bar window<br/>informational only"]
167
+ B --> V["Multitask heads<br/>baseline + 4 experts<br/>direction + magnitude + volatility"]
168
+ C --> E["Gating network<br/>the manager<br/>blends probability + magnitude/volatility"]
165
169
  D --> E
170
+ V --> E
166
171
  E --> F["Expert modules"]
167
172
  F --> G["Bullish expert"]
168
173
  F --> H["Bearish expert"]
@@ -180,6 +185,7 @@ flowchart LR
180
185
  M --> O["Observation / simulation record"]
181
186
  N --> P["Redis event stream<br/>temporary low-latency buffer"]
182
187
  O --> P
188
+ U -.-> P
183
189
  P --> Q["Experience worker<br/>async batch persistence"]
184
190
  Q --> R["PostgreSQL experience database<br/>single source of truth"]
185
191
  R --> S["Performance triggers<br/>100 observations, drawdown, Sharpe, regime shift"]
@@ -187,6 +193,11 @@ flowchart LR
187
193
  T --> E
188
194
  ```
189
195
 
196
+ Dashed edges mark the Phase 2 sequence encoder's **informational-only**
197
+ path — it's computed every bar and reaches the experience log, but never
198
+ the gating network, market analyzer, or position sizing (see
199
+ `inference/README.md`'s Phase 2 section).
200
+
190
201
  #### Tech Stack
191
202
 
192
203
  ```mermaid
@@ -203,6 +214,7 @@ flowchart TB
203
214
  D --> D2["scikit-learn"]
204
215
  D --> D3["NumPy / Pandas"]
205
216
  D --> D4["MoE experts and gating network"]
217
+ D --> D5["Multitask heads (direction/magnitude/<br/>volatility) + causal-TCN sequence encoder"]
206
218
  E["Monitoring and UI"] --> E1["React/Vite webui — Tracing dashboard (port 3002 dev / 8001 Docker)"]
207
219
  E --> E2["FastAPI JSON API (port 8000)"]
208
220
  E --> E3["Telegram alerts (V2-19)<br/>notifications/telegram_worker.py"]
@@ -215,12 +227,111 @@ and more), the module map, and an honest analysis of what would need to
215
227
  change for this to become a genuinely low-latency/HFT system — see
216
228
  **[`development/v2_architecture.md`](development/v2_architecture.md)**.
217
229
 
230
+ **The baseline model can now predict more than direction.** An optional
231
+ multi-task model (`train.py::AetherNetMultiTask`, trained by
232
+ `train_multitask.py`) predicts next-day direction, return magnitude and
233
+ volatility jointly from one shared trunk — the direction-only baseline and
234
+ experts are unchanged and still ship independently. All 4 experts also
235
+ have their own optional multitask heads (`train.py::_train_expert_multitask()`),
236
+ so `moe/gating.py` blends per-expert magnitude/volatility with a
237
+ baseline-scale anchor the same weighted-average way it already blends
238
+ direction. `main.py` threads the resulting `predicted_return_magnitude`/
239
+ `predicted_volatility` through the market analyzer (informational only,
240
+ never changes routing) and, opt-in via
241
+ `phase_v2.dynamic_risk.use_predicted_volatility`, into position sizing —
242
+ replacing the backward-looking `rolling_volatility_20d` average with an
243
+ actual forward-looking forecast for that one calculation.
244
+
245
+ **Regime, liquidity and topology are now genuine model input features,
246
+ not just downstream consumers of its output.** Model input dimensionality
247
+ grew from 30 to 48: regime one-hot/confidence/trend/risk score, an
248
+ asset-intrinsic liquidity spread/dollar-volume estimate, and cross-asset
249
+ topology correlation/risk state are all computed offline
250
+ (`train.py::add_regime_features()`/`add_liquidity_features()`/
251
+ `build_topology_features_by_date()`) and at runtime
252
+ (`main.py::_build_model_input()`, reordered so regime is computed
253
+ *before* the model runs) with verified train/runtime parity.
254
+
255
+ **Multi-horizon direction, cross-sectional ranking, correlated-peer
256
+ returns and technical indicators (model input 48 → 59).** A root-cause
257
+ investigation found every model — baseline, all 4 experts, the multitask
258
+ heads, the sequence encoder — sitting at backtest MCC 0.02-0.07 (noise) on
259
+ next-day binary direction, and traced (and fixed) real data bugs
260
+ confounding those numbers: an unadjusted-split bug in `train.py`'s own
261
+ Lean-zip reader (Lean's live/backtest engine was never affected — see
262
+ `development/Problems.md` #24) and a data-feed volume-unit discontinuity
263
+ that blew up the sequence model's RMSE 31x (#23). Beyond the fixes,
264
+ `AetherNetMultiTaskHorizons`/`AetherNetSequenceMultiTaskHorizons` (new
265
+ sibling classes to the originals — experts/baseline/gating stay
266
+ 1d-direction-only by design) add 4 heads: `direction_5d`/`direction_20d`
267
+ (longer-horizon direction) and `rank_5d`/`rank_20d` (per-date
268
+ cross-sectional percentile rank of forward return — the most learnable
269
+ target this investigation found, maps directly onto a long/short
270
+ portfolio, evaluated via rank-IC, `train.py::compute_rank_ic()`, not MCC).
271
+ 11 new scaled input features: 4 correlated-peer lagged-return features
272
+ (`topology/market_topology.py`'s `top_peers`/`top_peer_returns`, a genuine
273
+ new information channel from correlation data the model previously only
274
+ saw as a compressed scalar) and 7 technical indicators (`features/`
275
+ package — RSI, ATR%, Bollinger %B, volume z-score, MACD histogram,
276
+ distance-from-52-week-high, cross-sectional momentum rank), all computed
277
+ identically offline and at runtime by construction (shared pure
278
+ functions, not hand-matched duplicated formulas). All new signals are
279
+ visible on `/neural-network` and in `*_training_metrics.json`; see
280
+ `development/Changelog.md`'s "Frontier-model edge investigation" entry
281
+ for the full build and the real rank-IC results.
282
+
283
+ **`rank_20d` now sizes positions (opt-in).** A follow-up pass wired the
284
+ one Phase-4 signal with a statistically significant full-series result —
285
+ `rank_20d`, sequence model mean IC `0.073`/t-stat `4.40` — into an actual
286
+ trading decision: `risk/position_sizing.py::rank_sizing_multiplier()`
287
+ adds a fourth, bounded, direction-preserving factor to the sizing chain,
288
+ scaling an already-approved trade UP toward `max_rank_multiplier` (default
289
+ `1.25`) when the model predicts this asset near the top of the universe's
290
+ 20-day forward-return ranking, and DOWN toward `min_rank_multiplier`
291
+ (default `0.75`) near the bottom — never flipping direction, same
292
+ convention as the existing `topology_sizing_multiplier()`. **Off by
293
+ default** (`phase_v2.dynamic_risk.rank_sizing_enabled: false`): the
294
+ signal's non-overlapping-date subsample (28 independent 20-day windows)
295
+ was not yet independently significant on its own (t-stat `1.20`), so it
296
+ ships wired end-to-end but not promoted to on-by-default until validated
297
+ on more out-of-sample data. `direction_5d`/`direction_20d`/`rank_5d`
298
+ remain informational-only. See `risk/README.md`'s "Cross-sectional
299
+ rank_20d → position sizing" section.
300
+
301
+ **A causal-TCN sequence encoder (Phase 2) now exists alongside the
302
+ flat-MLP trunk**, replacing the "zero temporal structure" limitation the
303
+ original root-cause investigation flagged — `train.py::AetherNetSequenceMultiTask`,
304
+ trained by `train_sequence.py`, over a rolling 30-bar window of
305
+ already-computed model inputs. Informational only this pass
306
+ (`main.py::_run_sequence_model()` — not yet wired into any trading
307
+ decision); see `inference/README.md`'s Phase 2 section for the new
308
+ `_conv1d_causal`/`_multihead_attention`/`_softmax`/`_layernorm_axis`
309
+ interpreter primitives (each independently verified against real PyTorch
310
+ modules).
311
+
312
+ See `inference/README.md`, `moe/README.md`, `risk/README.md`,
313
+ `regime/README.md`, `liquidity/README.md` and `topology/README.md` for
314
+ the full contracts, and `development/Changelog.md`'s "Multi-task
315
+ prediction" and "Phase 1 remainder + Phase 2" entries for the complete
316
+ writeup.
317
+
218
318
  ## Universe Size
219
319
 
220
- The trading universe currently spans **20 assets** — 15 equities and 5
221
- crypto pairs — defined in `config.json`'s `phase1.universe.assets` and
222
- shared across training, validation, and backtesting
223
- (`phase1.universe.common_window`: `2014-12-01` to `2021-03-31`).
320
+ The trading universe currently spans **30 assets** — 15 stocks/broad-market
321
+ ETFs, 10 fixed-income (bond) ETFs, and 5 crypto pairs — defined in
322
+ `config.json`'s `phase1.universe.assets` and shared across training,
323
+ validation, and backtesting (`phase1.universe.common_window`: `2014-12-01`
324
+ to `2021-03-31`). The bond ETF sleeve (Phase 1 of the 5/10 -> 9/10 roadmap,
325
+ see [`development/Changelog.md`](development/Changelog.md)) was added
326
+ specifically as a new, genuinely different information channel — not more
327
+ of the same equity cross-section — and deliberately spans the duration
328
+ curve (short/intermediate/long/aggregate) and credit spectrum
329
+ (Treasury/investment-grade/high-yield/municipal/emerging-market) so the
330
+ yield-curve-slope and credit-spread macro proxies computed from it
331
+ (`features/macro_features.py`) are meaningful. Bond ETFs are registered
332
+ with `security_type: "equity"` (they trade through Lean's ordinary equity
333
+ subscription path, like every other ETF already in the universe, e.g.
334
+ SPY/QQQ/IWM/EEM — not a new Lean security type).
224
335
 
225
336
  | Ticker | Type | Role |
226
337
  |---|---|---|
@@ -239,6 +350,16 @@ shared across training, validation, and backtesting
239
350
  | USO | Equity | Trading |
240
351
  | WM | Equity | Trading |
241
352
  | AAA | Equity | Observation-only (thin history) |
353
+ | SHY | Equity (Fixed Income ETF) | Trading — short-duration Treasury (1-3y) |
354
+ | IEF | Equity (Fixed Income ETF) | Trading — intermediate-duration Treasury (7-10y) |
355
+ | TLT | Equity (Fixed Income ETF) | Trading — long-duration Treasury (20y+) |
356
+ | AGG | Equity (Fixed Income ETF) | Trading — broad aggregate bond benchmark |
357
+ | LQD | Equity (Fixed Income ETF) | Trading — investment-grade corporate |
358
+ | HYG | Equity (Fixed Income ETF) | Trading — high-yield corporate |
359
+ | TIP | Equity (Fixed Income ETF) | Trading — inflation-protected (TIPS) |
360
+ | MBB | Equity (Fixed Income ETF) | Trading — mortgage-backed |
361
+ | EMB | Equity (Fixed Income ETF) | Trading — emerging-market sovereign debt |
362
+ | MUB | Equity (Fixed Income ETF) | Trading — municipal |
242
363
  | BTCUSD | Crypto | Trading |
243
364
  | ETHUSD | Crypto | Observation-only (thin history) |
244
365
  | LTCUSD | Crypto | Trading |
@@ -276,6 +397,19 @@ flowchart TD
276
397
  AAA["AAA"]
277
398
  end
278
399
 
400
+ subgraph FixedIncome["Fixed Income ETFs (10)"]
401
+ SHY["SHY"]
402
+ IEF["IEF"]
403
+ TLT["TLT"]
404
+ AGG["AGG"]
405
+ LQD["LQD"]
406
+ HYG["HYG"]
407
+ TIP["TIP"]
408
+ MBB["MBB"]
409
+ EMB["EMB"]
410
+ MUB["MUB"]
411
+ end
412
+
279
413
  subgraph Crypto["Crypto (5)"]
280
414
  BTCUSD["BTCUSD"]
281
415
  ETHUSD["ETHUSD"]
@@ -299,6 +433,16 @@ flowchart TD
299
433
  USO --- DNN
300
434
  WM --- DNN
301
435
  AAA --- DNN
436
+ SHY --- DNN
437
+ IEF --- DNN
438
+ TLT --- DNN
439
+ AGG --- DNN
440
+ LQD --- DNN
441
+ HYG --- DNN
442
+ TIP --- DNN
443
+ MBB --- DNN
444
+ EMB --- DNN
445
+ MUB --- DNN
302
446
  BTCUSD --- DNN
303
447
  ETHUSD --- DNN
304
448
  LTCUSD --- DNN
@@ -310,7 +454,7 @@ flowchart TD
310
454
  classDef observation fill:#3A3A3A,stroke:#FF8C00,color:#FF8C00,stroke-width:1px,stroke-dasharray: 4 2;
311
455
 
312
456
  class DNN hub;
313
- class AAPL,SPY,QQQ,IWM,EEM,BAC,IBM,AIG,BNO,FB,GOOG,GOOGL,USO,WM,BTCUSD,LTCUSD trading;
457
+ class AAPL,SPY,QQQ,IWM,EEM,BAC,IBM,AIG,BNO,FB,GOOG,GOOGL,USO,WM,SHY,IEF,TLT,AGG,LQD,HYG,TIP,MBB,EMB,MUB,BTCUSD,LTCUSD trading;
314
458
  class AAA,ETHUSD,XRPUSD,ADAUSD observation;
315
459
  ```
316
460
 
@@ -341,12 +485,15 @@ aether-quant/
341
485
  ├── ml/ # Model weights, datasets, versioned retraining candidates
342
486
  ├── storage/ # Reserved for future persistent artifact storage
343
487
  ├── requirements/ # All requirements*.txt variants
344
- ├── tests/ # Full pytest suite (507 tests)
488
+ ├── tests/ # Full pytest suite (828 tests)
345
489
  ├── backtests/ # Lean backtest run outputs (gitignored)
346
490
  ├── Aether-quant-Obsidian-Vault/ # Auto-generated code-graph / architecture vault
347
491
  ├── main.py # Lean algorithm: inference, signal engine, risk controls
348
492
  ├── train.py # Training pipeline: dataset build, model training, validation
349
493
  ├── train_topology.py # Offline trainer for the learned topology overlay
494
+ ├── train_gating.py # Offline trainer for the learned gating blend
495
+ ├── train_multitask.py # Offline trainer for the joint direction+magnitude+volatility model
496
+ ├── train_sequence.py # Offline trainer for the Phase 2 causal-TCN sequence encoder
350
497
  ├── generate_backtest_report.py # Regenerates this README's Backtest Results section
351
498
  ├── aq_cli.py # `aq` convenience CLI
352
499
  ├── config.json # Runtime configuration (phase1 / phase_v2 blocks)
@@ -380,7 +527,7 @@ and how it's wired in — this table is the index.
380
527
  | `retraining/` | Controlled retraining — plan/train/validate/backtest/commit/promote/rollback | [README](retraining/README.md) |
381
528
  | `risk/` | Dynamic position sizing, leverage caps, drawdown-aware sizing | [README](risk/README.md) |
382
529
  | `storage/` | Reserved placeholder for future persistent artifact storage | [README](storage/README.md) |
383
- | `tests/` | Pytest suite conventions (507 tests) | [README](tests/README.md) |
530
+ | `tests/` | Pytest suite conventions (828 tests) | [README](tests/README.md) |
384
531
  | `topology/` | 3D market topology — deterministic SMACOF embedding + learned overlay | [README](topology/README.md) |
385
532
  | `visualization/` | Shared runtime-state JSON/CSV exports | [README](visualization/README.md) |
386
533
  | `webui/` | React/Vite dashboard (Overview, Risk, Topology, Neural Network, Tracing) | [README](webui/README.md) |
@@ -404,13 +551,13 @@ and how it's wired in — this table is the index.
404
551
  | Metric | Value |
405
552
  |---|---|
406
553
  | 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`) |
554
+ | Sharpe Ratio | -0.758 |
555
+ | Net Profit | -4.847% |
556
+ | Compounding Annual Return | -1.640% |
557
+ | Drawdown | 12.300% |
558
+ | Total Orders | 36 |
559
+ | Win Rate | 25% |
560
+ | Last updated | 2026-07-08 13:10 UTC (auto-generated by `aq backtest`) |
414
561
  <!-- AQ:BACKTEST_END -->
415
562
 
416
563
  <details>
@@ -419,33 +566,33 @@ and how it's wired in — this table is the index.
419
566
  <!-- AQ:BACKTEST_FULL_STATS_START -->
420
567
  | Metric | Value |
421
568
  |---|---|
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 |
569
+ | Total Orders | 36 |
570
+ | Average Win | 0.38% |
571
+ | Average Loss | -0.67% |
572
+ | Compounding Annual Return | -1.640% |
573
+ | Drawdown | 12.300% |
574
+ | Expectancy | -0.609 |
428
575
  | 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 |
576
+ | End Equity | 95153.40 |
577
+ | Net Profit | -4.847% |
578
+ | Sharpe Ratio | -0.758 |
579
+ | Sortino Ratio | -0.363 |
580
+ | Probabilistic Sharpe Ratio | 0.006% |
581
+ | Loss Rate | 75% |
582
+ | Win Rate | 25% |
583
+ | Profit-Loss Ratio | 0.56 |
584
+ | Alpha | -0.034 |
585
+ | Beta | 0.047 |
586
+ | Annual Standard Deviation | 0.038 |
587
+ | Annual Variance | 0.001 |
588
+ | Information Ratio | -0.786 |
589
+ | Tracking Error | 0.182 |
590
+ | Treynor Ratio | -0.603 |
591
+ | Total Fees | $25.59 |
592
+ | Estimated Strategy Capacity | $2300000.00 |
593
+ | Lowest Capacity Asset | BNO UN3IMQ2JU1YD |
594
+ | Portfolio Turnover | 0.14% |
595
+ | Drawdown Recovery | 32 |
449
596
  <!-- AQ:BACKTEST_FULL_STATS_END -->
450
597
 
451
598
  </details>
@@ -488,7 +635,7 @@ genuinely halted trading exactly as designed.
488
635
 
489
636
  ## Test Suite
490
637
 
491
- 507 tests, one file per source module, run via:
638
+ 828 tests, one file per source module, run via:
492
639
 
493
640
  ```powershell
494
641
  aq test
@@ -515,42 +662,133 @@ instead, without waiting on a PyPI release:
515
662
  pip install -e .
516
663
  ```
517
664
 
518
- Either way, `aq --help` gives the full command list:
665
+ Either way, `aq --help` gives the full command list. Every command except
666
+ `aq trade-lock` and `aq fetch` is a thin `subprocess` wrapper around a
667
+ command already documented elsewhere in this README:
519
668
 
669
+ #### `aq train`
670
+ ```text
671
+ aq train [--dataset-only|--init-only|--experts-only|--gating-only|--multitask-only|--sequence-only|--walk-forward] [--step-days N] [--mode rolling|expanding]
672
+ ```
673
+ Runs `train.py`: builds the dataset and trains the baseline + expert
674
+ models. `--gating-only` trains just the learned gating blend
675
+ (`train_gating.py`) and installs it straight into active `ml/`,
676
+ mirroring what `--experts-only` already does for the expert models — see
677
+ `moe/README.md`. `--multitask-only` does the same for the joint
678
+ direction+magnitude+volatility model (`train_multitask.py`) — see
679
+ `inference/README.md`/`risk/README.md`. `--sequence-only` does the same
680
+ for the Phase 2 causal-TCN sequence encoder (`train_sequence.py`) — see
681
+ `inference/README.md`. `--walk-forward` (Phase 4 of the 5/10 -> 9/10
682
+ roadmap) wraps `python train.py --walk-forward`, running the dataset-build
683
+ + training pipeline once per rolling/expanding window instead of once on
684
+ the fixed `phase1.windows` — diagnostic only, never touches active `ml/`
685
+ (each window writes to `ml/versions/<run-id>/window_<i>/`, same as
686
+ `--candidate`); `--step-days`/`--mode` override
687
+ `phase_v2.retraining.walk_forward`'s `step_days`/`mode` defaults — see
688
+ `retraining/README.md`'s "Walk-forward retraining is a separate, scheduled
689
+ mechanism" section.
690
+
691
+ #### `aq test`
520
692
  ```text
521
- aq train [--dataset-only|--init-only|--experts-only|--gating-only]
522
693
  aq test
694
+ ```
695
+ Runs the pytest suite and refreshes this README's test badge.
696
+
697
+ #### `aq backtest`
698
+ ```text
523
699
  aq backtest
700
+ ```
701
+ Runs `lean backtest .` and refreshes this README's [Backtest Results](#backtest-results) section.
702
+
703
+ #### `aq report`
704
+ ```text
524
705
  aq report <backtest-folder> <result-id>
706
+ ```
707
+ Generates Lean's own HTML backtest report (trade blotter, standard Lean
708
+ charts) at `backtests/<backtest-folder>/report.html`.
709
+
710
+ #### `aq api`
711
+ ```text
525
712
  aq api
713
+ ```
714
+ Starts the FastAPI monitoring server on `:8001`.
715
+
716
+ #### `aq webui`
717
+ ```text
526
718
  aq webui
719
+ ```
720
+ Starts the webui dev server (`npm run dev`).
721
+
722
+ #### `aq docker`
723
+ ```text
527
724
  aq docker up [--lean|--all]
528
725
  aq docker build
726
+ ```
727
+ `up` starts local infrastructure (default: Redis + PostgreSQL only).
728
+ `build` rebuilds the `aether-quant` app image.
729
+
730
+ #### `aq config`
731
+ ```text
529
732
  aq config [get <dotted.key>|set <dotted.key> <value>|keys [<dotted.prefix>]]
733
+ ```
734
+ Reads or edits `config.json` directly, no manual file editing needed.
735
+ Bare `aq config` pretty-prints the whole file; `aq config keys
736
+ [<dotted.prefix>]` lists every leaf key path (handy for finding the right
737
+ key in a deeply nested file); `aq config get <dotted.key>` prints one
738
+ value (scalar, or a whole nested section as JSON); `aq config set
739
+ <dotted.key> <value>` writes it — the value is parsed as JSON first (so
740
+ `true`/`123`/`0.5`/`["a","b"]` become their real types automatically),
741
+ falling back to a plain string otherwise. Every `set` backs up the
742
+ previous file to `config.json.bak` first and prints old → new so a
743
+ mistake is immediately visible; changing a value's type (e.g. bool →
744
+ string) prints a warning but still writes it, since this command
745
+ intentionally gives full access to every key, not just a safe subset.
746
+
747
+ #### `aq lean`
748
+ ```text
530
749
  aq lean [get <dotted.key>|set <dotted.key> <value>|keys [<dotted.prefix>]]
750
+ ```
751
+ The exact same `get`/`set`/`keys` tool as `aq config`, just pointed at
752
+ `lean.json` (the QuantConnect Lean CLI's own config file — broker
753
+ credentials, environments, data providers) instead. `aq lean set
754
+ ib-trading-mode live`, `aq lean keys environments.live-paper`, etc.
755
+
756
+ #### `aq retrain`
757
+ ```text
531
758
  aq retrain <plan|train|validate|backtest|commit|promote|rollback|status> [...]
759
+ ```
760
+ Dispatches to `python -m retraining.orchestrator <stage> ...` for a
761
+ single manual pipeline stage.
762
+
763
+ #### `aq trade-lock`
764
+ ```text
532
765
  aq trade-lock --on|--off|--auto|--status
766
+ ```
767
+ Manually overrides `main.py`'s sticky total-drawdown trade lock (see
768
+ `development/v2_architecture.md`'s Manual Trade-Lock Override Contract).
769
+ `--off` deliberately clears an otherwise-permanent lock; `--auto` returns
770
+ to fully automatic behavior.
771
+
772
+ #### `aq fetch`
773
+ ```text
533
774
  aq fetch <crypto|stock> --ticker <TICKER> --start <YYYY-MM-DD> --end <YYYY-MM-DD> [--apply]
775
+ ```
776
+ Fetches historical OHLCV from Yahoo Finance for a ticker that isn't in
777
+ `config.json` yet, formats it into Lean's zip/CSV convention, and writes
778
+ it to the right spot under `data/` (`data/crypto/coinbase/daily/<ticker>_trade.zip`
779
+ or `data/equity/usa/daily/<ticker>.zip`). On `--apply`, it also appends a
780
+ new asset block to `config.json`'s `phase1.universe.assets[]` — no manual
781
+ editing needed. Dry run by default (no `--apply`): reports what would
782
+ happen, writes nothing. Never runs `train.py` itself — once applied, run
783
+ `python train.py --dataset-only` (then `python train.py` when ready)
784
+ yourself to actually train on the new ticker. `crypto`/`stock` today; a
785
+ `derivative` asset class is planned for V3.
786
+
787
+ #### `aq status`
788
+ ```text
534
789
  aq status
535
790
  ```
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`.
791
+ Shows `git status`.
554
792
 
555
793
  ## Release Process
556
794
 
@@ -1,5 +1,5 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: aether-quant
3
- Version: 0.6.0
3
+ Version: 0.8.0
4
4
  Summary: Aether Quant convenience CLI
5
5
  Requires-Python: >=3.10