akquant 0.2.51__tar.gz → 0.3.2__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 (584) hide show
  1. akquant-0.3.2/.gitignore +49 -0
  2. {akquant-0.2.51 → akquant-0.3.2}/CHANGELOG.md +1 -0
  3. {akquant-0.2.51 → akquant-0.3.2}/Cargo.lock +3 -3
  4. {akquant-0.2.51 → akquant-0.3.2}/Cargo.toml +1 -1
  5. {akquant-0.2.51 → akquant-0.3.2}/PKG-INFO +4 -4
  6. {akquant-0.2.51 → akquant-0.3.2}/README.md +3 -3
  7. {akquant-0.2.51 → akquant-0.3.2}/docs/en/advanced/live_functional_quickstart.md +6 -4
  8. {akquant-0.2.51 → akquant-0.3.2}/docs/en/advanced/llm.md +2 -2
  9. {akquant-0.2.51 → akquant-0.3.2}/docs/en/advanced/warm_start.md +2 -2
  10. {akquant-0.2.51 → akquant-0.3.2}/docs/en/guide/examples.md +1 -1
  11. {akquant-0.2.51 → akquant-0.3.2}/docs/en/guide/strategy.md +7 -7
  12. {akquant-0.2.51 → akquant-0.3.2}/docs/en/reference/api.md +12 -11
  13. {akquant-0.2.51 → akquant-0.3.2}/docs/en/start/quickstart.md +2 -2
  14. {akquant-0.2.51 → akquant-0.3.2}/docs/en/textbook/07_futures.md +2 -2
  15. akquant-0.3.2/docs/zh/advanced/adding_a_broker.md +245 -0
  16. {akquant-0.2.51 → akquant-0.3.2}/docs/zh/advanced/live_functional_quickstart.md +5 -4
  17. {akquant-0.2.51 → akquant-0.3.2}/docs/zh/advanced/llm.md +2 -2
  18. {akquant-0.2.51 → akquant-0.3.2}/docs/zh/advanced/multi_timeframe_feed_api.md +49 -0
  19. {akquant-0.2.51 → akquant-0.3.2}/docs/zh/advanced/warm_start.md +2 -2
  20. {akquant-0.2.51 → akquant-0.3.2}/docs/zh/guide/examples.md +5 -5
  21. {akquant-0.2.51 → akquant-0.3.2}/docs/zh/guide/strategy.md +63 -12
  22. {akquant-0.2.51 → akquant-0.3.2}/docs/zh/reference/api.md +8 -8
  23. {akquant-0.2.51 → akquant-0.3.2}/docs/zh/start/quickstart.md +2 -2
  24. {akquant-0.2.51 → akquant-0.3.2}/docs/zh/textbook/00_glossary.md +1 -1
  25. {akquant-0.2.51 → akquant-0.3.2}/docs/zh/textbook/05_strategy.md +3 -3
  26. {akquant-0.2.51 → akquant-0.3.2}/docs/zh/textbook/07_futures.md +2 -2
  27. {akquant-0.2.51 → akquant-0.3.2}/examples/06_complex_orders.py +1 -1
  28. {akquant-0.2.51 → akquant-0.3.2}/examples/21_warm_start_demo.py +2 -2
  29. {akquant-0.2.51 → akquant-0.3.2}/examples/36_trailing_orders.py +6 -2
  30. {akquant-0.2.51 → akquant-0.3.2}/examples/39_live_broker_submit_order_demo.py +12 -2
  31. {akquant-0.2.51 → akquant-0.3.2}/examples/42_live_broker_event_audit_demo.py +1 -1
  32. {akquant-0.2.51 → akquant-0.3.2}/examples/43_target_weights_rebalance.py +1 -1
  33. {akquant-0.2.51 → akquant-0.3.2}/examples/59_akshare_etf_rotation.py +2 -2
  34. akquant-0.3.2/examples/65_bar_generator.py +126 -0
  35. {akquant-0.2.51 → akquant-0.3.2}/examples/README.md +4 -4
  36. {akquant-0.2.51 → akquant-0.3.2}/examples/strategies/08_target_positions_long_short.py +4 -4
  37. {akquant-0.2.51 → akquant-0.3.2}/examples/strategies/README.md +2 -2
  38. {akquant-0.2.51 → akquant-0.3.2}/examples/textbook/ch09_portfolio.py +1 -1
  39. {akquant-0.2.51 → akquant-0.3.2}/pyproject.toml +2 -1
  40. {akquant-0.2.51 → akquant-0.3.2}/python/akquant/__init__.py +8 -0
  41. {akquant-0.2.51 → akquant-0.3.2}/python/akquant/akquant.pyi +1 -1
  42. {akquant-0.2.51 → akquant-0.3.2}/python/akquant/backtest/engine.py +20 -21
  43. akquant-0.3.2/python/akquant/bar_generator.py +134 -0
  44. akquant-0.3.2/python/akquant/execution/__init__.py +1 -0
  45. akquant-0.3.2/python/akquant/execution/base.py +49 -0
  46. akquant-0.3.2/python/akquant/execution/sim.py +69 -0
  47. {akquant-0.2.51 → akquant-0.3.2}/python/akquant/gateway/__init__.py +8 -0
  48. akquant-0.3.2/python/akquant/gateway/broker_event_adapter.py +260 -0
  49. {akquant-0.2.51 → akquant-0.3.2}/python/akquant/gateway/broker_event_bridge.py +54 -2
  50. akquant-0.3.2/python/akquant/gateway/broker_execution.py +273 -0
  51. {akquant-0.2.51 → akquant-0.3.2}/python/akquant/gateway/broker_models.py +46 -0
  52. {akquant-0.2.51 → akquant-0.3.2}/python/akquant/gateway/broker_recovery.py +4 -1
  53. {akquant-0.2.51 → akquant-0.3.2}/python/akquant/gateway/broker_runtime.py +41 -0
  54. akquant-0.3.2/python/akquant/gateway/broker_state_cache.py +112 -0
  55. akquant-0.3.2/python/akquant/gateway/broker_strategy_api.py +124 -0
  56. akquant-0.3.2/python/akquant/gateway/brokers/builtins.py +85 -0
  57. akquant-0.3.2/python/akquant/gateway/brokers/plugins.py +30 -0
  58. akquant-0.3.2/python/akquant/gateway/factory.py +27 -0
  59. akquant-0.3.2/python/akquant/gateway/local_stop_book.py +153 -0
  60. akquant-0.3.2/python/akquant/gateway/order_receipt.py +60 -0
  61. {akquant-0.2.51 → akquant-0.3.2}/python/akquant/gateway/order_submitter.py +178 -39
  62. {akquant-0.2.51 → akquant-0.3.2}/python/akquant/gateway/protocols.py +1 -1
  63. akquant-0.3.2/python/akquant/gateway/trader_base.py +90 -0
  64. {akquant-0.2.51 → akquant-0.3.2}/python/akquant/live.py +240 -17
  65. {akquant-0.2.51 → akquant-0.3.2}/python/akquant/strategy.py +317 -204
  66. {akquant-0.2.51 → akquant-0.3.2}/python/akquant/strategy_events.py +16 -0
  67. {akquant-0.2.51 → akquant-0.3.2}/python/akquant/strategy_framework_hooks.py +78 -3
  68. {akquant-0.2.51 → akquant-0.3.2}/python/akquant/strategy_trading_api.py +491 -453
  69. {akquant-0.2.51 → akquant-0.3.2}/src/pipeline/stages/shared.rs +18 -12
  70. {akquant-0.2.51 → akquant-0.3.2}/tests/gateway_contract/test_event_bridge_contract.py +5 -0
  71. {akquant-0.2.51 → akquant-0.3.2}/tests/gateway_contract/test_submitter_contract.py +12 -15
  72. {akquant-0.2.51 → akquant-0.3.2}/tests/golden/current/futures_margin/equity_curve.parquet +0 -0
  73. {akquant-0.2.51 → akquant-0.3.2}/tests/golden/current/futures_margin/metrics.json +1 -1
  74. {akquant-0.2.51 → akquant-0.3.2}/tests/golden/current/futures_margin/orders.parquet +0 -0
  75. {akquant-0.2.51 → akquant-0.3.2}/tests/golden/current/option_basic/equity_curve.parquet +0 -0
  76. {akquant-0.2.51 → akquant-0.3.2}/tests/golden/current/option_basic/metrics.json +1 -1
  77. {akquant-0.2.51 → akquant-0.3.2}/tests/golden/current/option_basic/orders.parquet +0 -0
  78. {akquant-0.2.51 → akquant-0.3.2}/tests/golden/current/stock_t1/equity_curve.parquet +0 -0
  79. {akquant-0.2.51 → akquant-0.3.2}/tests/golden/current/stock_t1/metrics.json +1 -1
  80. {akquant-0.2.51 → akquant-0.3.2}/tests/golden/current/stock_t1/orders.parquet +0 -0
  81. {akquant-0.2.51 → akquant-0.3.2}/tests/golden/current/stock_t1/trades.parquet +0 -0
  82. {akquant-0.2.51 → akquant-0.3.2}/tests/test_account_risk_rules.py +1 -1
  83. akquant-0.3.2/tests/test_api_rename_cash.py +9 -0
  84. akquant-0.3.2/tests/test_api_rename_composites.py +13 -0
  85. akquant-0.3.2/tests/test_api_rename_equity.py +9 -0
  86. akquant-0.3.2/tests/test_api_rename_holding_bars.py +9 -0
  87. akquant-0.3.2/tests/test_api_rename_positions.py +15 -0
  88. akquant-0.3.2/tests/test_api_rename_rebalance.py +11 -0
  89. akquant-0.3.2/tests/test_bar_generator.py +296 -0
  90. akquant-0.3.2/tests/test_broker_bridge_adapts_events.py +140 -0
  91. akquant-0.3.2/tests/test_broker_bridge_drives_order_groups.py +72 -0
  92. akquant-0.3.2/tests/test_broker_event_adapter.py +186 -0
  93. akquant-0.3.2/tests/test_broker_event_adapter_local_id.py +46 -0
  94. akquant-0.3.2/tests/test_broker_execution_local_stops.py +168 -0
  95. akquant-0.3.2/tests/test_broker_execution_read_path_parity.py +173 -0
  96. akquant-0.3.2/tests/test_broker_execution_stop_requeue.py +103 -0
  97. akquant-0.3.2/tests/test_broker_plugins.py +87 -0
  98. akquant-0.3.2/tests/test_broker_position_sync.py +115 -0
  99. akquant-0.3.2/tests/test_broker_seed_baseline.py +168 -0
  100. akquant-0.3.2/tests/test_broker_trade_redelivery_dedup.py +122 -0
  101. akquant-0.3.2/tests/test_close_position_delegate.py +86 -0
  102. akquant-0.3.2/tests/test_composed_ctx_not_ready.py +158 -0
  103. akquant-0.3.2/tests/test_cost_config_consolidation.py +110 -0
  104. {akquant-0.2.51 → akquant-0.3.2}/tests/test_engine.py +2 -2
  105. akquant-0.3.2/tests/test_event_model_parity.py +73 -0
  106. akquant-0.3.2/tests/test_execution_binding.py +18 -0
  107. akquant-0.3.2/tests/test_execution_broker.py +146 -0
  108. akquant-0.3.2/tests/test_execution_broker_reads_routed.py +144 -0
  109. akquant-0.3.2/tests/test_execution_composed_parity.py +45 -0
  110. akquant-0.3.2/tests/test_execution_read_delegation.py +26 -0
  111. akquant-0.3.2/tests/test_execution_sim.py +53 -0
  112. akquant-0.3.2/tests/test_execution_write_delegation.py +40 -0
  113. akquant-0.3.2/tests/test_gateway_broker_live_cancel.py +146 -0
  114. akquant-0.3.2/tests/test_gateway_broker_live_reads.py +82 -0
  115. akquant-0.3.2/tests/test_gateway_broker_models_ext.py +90 -0
  116. akquant-0.3.2/tests/test_gateway_broker_state_cache.py +59 -0
  117. akquant-0.3.2/tests/test_gateway_broker_state_invalidation.py +130 -0
  118. akquant-0.3.2/tests/test_gateway_broker_submitter_readiness.py +62 -0
  119. akquant-0.3.2/tests/test_gateway_broker_submitter_signature.py +152 -0
  120. akquant-0.3.2/tests/test_gateway_builtins_registry.py +23 -0
  121. akquant-0.3.2/tests/test_gateway_optional_market.py +15 -0
  122. akquant-0.3.2/tests/test_gateway_order_submitter_extra.py +216 -0
  123. akquant-0.3.2/tests/test_gateway_sim_submit_guard.py +68 -0
  124. akquant-0.3.2/tests/test_gateway_tif_mapping.py +25 -0
  125. akquant-0.3.2/tests/test_gateway_trader_base.py +63 -0
  126. {akquant-0.2.51 → akquant-0.3.2}/tests/test_live_runner_broker_bridge.py +199 -26
  127. akquant-0.3.2/tests/test_live_runner_broker_readiness.py +109 -0
  128. {akquant-0.2.51 → akquant-0.3.2}/tests/test_live_runner_broker_recovery.py +3 -1
  129. {akquant-0.2.51 → akquant-0.3.2}/tests/test_live_runner_broker_submitter.py +23 -20
  130. akquant-0.3.2/tests/test_live_runner_order_request_cache.py +89 -0
  131. akquant-0.3.2/tests/test_live_runner_stop_remap.py +44 -0
  132. akquant-0.3.2/tests/test_local_stop_book.py +122 -0
  133. akquant-0.3.2/tests/test_local_stop_book_threadsafe.py +53 -0
  134. akquant-0.3.2/tests/test_local_stop_scenario.py +78 -0
  135. {akquant-0.2.51 → akquant-0.3.2}/tests/test_multisymbol_cross_section_consistency.py +22 -22
  136. akquant-0.3.2/tests/test_oco_bracket_broker_live_scenario.py +103 -0
  137. akquant-0.3.2/tests/test_on_execution_report_noop.py +10 -0
  138. akquant-0.3.2/tests/test_order_receipt.py +66 -0
  139. akquant-0.3.2/tests/test_order_receipt_backtest.py +39 -0
  140. akquant-0.3.2/tests/test_removed_wrappers.py +9 -0
  141. akquant-0.3.2/tests/test_review_minors_cleanup.py +78 -0
  142. akquant-0.3.2/tests/test_stop_id_remap_scenario.py +78 -0
  143. akquant-0.3.2/tests/test_strategy_events_stop_hook.py +38 -0
  144. {akquant-0.2.51 → akquant-0.3.2}/tests/test_strategy_extras.py +93 -65
  145. akquant-0.3.2/tests/test_strategy_order_group_lock.py +55 -0
  146. akquant-0.3.2/tests/test_strategy_sizing_broker_live_guard.py +159 -0
  147. akquant-0.3.2/tests/test_target_orders_core.py +65 -0
  148. akquant-0.2.51/.gitignore +0 -35
  149. akquant-0.2.51/python/akquant/gateway/factory.py +0 -105
  150. {akquant-0.2.51 → akquant-0.3.2}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
  151. {akquant-0.2.51 → akquant-0.3.2}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  152. {akquant-0.2.51 → akquant-0.3.2}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
  153. {akquant-0.2.51 → akquant-0.3.2}/.github/workflows/deploy-docs.yml +0 -0
  154. {akquant-0.2.51 → akquant-0.3.2}/.github/workflows/docs-quality.yml +0 -0
  155. {akquant-0.2.51 → akquant-0.3.2}/.github/workflows/release.yml +0 -0
  156. {akquant-0.2.51 → akquant-0.3.2}/.pre-commit-config.yaml +0 -0
  157. {akquant-0.2.51 → akquant-0.3.2}/CODE_OF_CONDUCT.md +0 -0
  158. {akquant-0.2.51 → akquant-0.3.2}/CONTRIBUTING.md +0 -0
  159. {akquant-0.2.51 → akquant-0.3.2}/LICENSE +0 -0
  160. {akquant-0.2.51 → akquant-0.3.2}/assets/dashboard_preview.png +0 -0
  161. {akquant-0.2.51 → akquant-0.3.2}/assets/logo.svg +0 -0
  162. {akquant-0.2.51 → akquant-0.3.2}/assets/social_preview.png +0 -0
  163. {akquant-0.2.51 → akquant-0.3.2}/docs/CNAME +0 -0
  164. {akquant-0.2.51 → akquant-0.3.2}/docs/assets/akquant-icon.svg +0 -0
  165. {akquant-0.2.51 → akquant-0.3.2}/docs/assets/akquant-logo.svg +0 -0
  166. {akquant-0.2.51 → akquant-0.3.2}/docs/assets/reports/akquant_report.html +0 -0
  167. {akquant-0.2.51 → akquant-0.3.2}/docs/en/advanced/analyzer_plugin_spec.md +0 -0
  168. {akquant-0.2.51 → akquant-0.3.2}/docs/en/advanced/broker_capability_matrix.md +0 -0
  169. {akquant-0.2.51 → akquant-0.3.2}/docs/en/advanced/custom_broker_production_checklist.md +0 -0
  170. {akquant-0.2.51 → akquant-0.3.2}/docs/en/advanced/custom_broker_registry.md +0 -0
  171. {akquant-0.2.51 → akquant-0.3.2}/docs/en/advanced/data_feed_adapter_spec.md +0 -0
  172. {akquant-0.2.51 → akquant-0.3.2}/docs/en/advanced/ml.md +0 -0
  173. {akquant-0.2.51 → akquant-0.3.2}/docs/en/advanced/multi_strategy_guide.md +0 -0
  174. {akquant-0.2.51 → akquant-0.3.2}/docs/en/advanced/multi_timeframe_feed_api.md +0 -0
  175. {akquant-0.2.51 → akquant-0.3.2}/docs/en/advanced/runtime_config.md +0 -0
  176. {akquant-0.2.51 → akquant-0.3.2}/docs/en/advanced/strategy_style_decision.md +0 -0
  177. {akquant-0.2.51 → akquant-0.3.2}/docs/en/advanced/timezone.md +0 -0
  178. {akquant-0.2.51 → akquant-0.3.2}/docs/en/guide/analysis.md +0 -0
  179. {akquant-0.2.51 → akquant-0.3.2}/docs/en/guide/cross_section_checklist.md +0 -0
  180. {akquant-0.2.51 → akquant-0.3.2}/docs/en/guide/custom_indicator.md +0 -0
  181. {akquant-0.2.51 → akquant-0.3.2}/docs/en/guide/data.md +0 -0
  182. {akquant-0.2.51 → akquant-0.3.2}/docs/en/guide/factor.md +0 -0
  183. {akquant-0.2.51 → akquant-0.3.2}/docs/en/guide/indicator_scenario_quickref.md +0 -0
  184. {akquant-0.2.51 → akquant-0.3.2}/docs/en/guide/optimization.md +0 -0
  185. {akquant-0.2.51 → akquant-0.3.2}/docs/en/guide/python_basics.md +0 -0
  186. {akquant-0.2.51 → akquant-0.3.2}/docs/en/guide/quant_basics.md +0 -0
  187. {akquant-0.2.51 → akquant-0.3.2}/docs/en/guide/rust_indicator_reference.md +0 -0
  188. {akquant-0.2.51 → akquant-0.3.2}/docs/en/guide/talib_indicator_playbook.md +0 -0
  189. {akquant-0.2.51 → akquant-0.3.2}/docs/en/guide/testing.md +0 -0
  190. {akquant-0.2.51 → akquant-0.3.2}/docs/en/guide/visualization.md +0 -0
  191. {akquant-0.2.51 → akquant-0.3.2}/docs/en/index.md +0 -0
  192. {akquant-0.2.51 → akquant-0.3.2}/docs/en/meta/architecture.md +0 -0
  193. {akquant-0.2.51 → akquant-0.3.2}/docs/en/meta/internals.md +0 -0
  194. {akquant-0.2.51 → akquant-0.3.2}/docs/en/start/first_strategy.md +0 -0
  195. {akquant-0.2.51 → akquant-0.3.2}/docs/en/start/installation.md +0 -0
  196. {akquant-0.2.51 → akquant-0.3.2}/docs/en/start/setup_guide.md +0 -0
  197. {akquant-0.2.51 → akquant-0.3.2}/docs/en/textbook/01_foundations.md +0 -0
  198. {akquant-0.2.51 → akquant-0.3.2}/docs/en/textbook/02_programming.md +0 -0
  199. {akquant-0.2.51 → akquant-0.3.2}/docs/en/textbook/03_data.md +0 -0
  200. {akquant-0.2.51 → akquant-0.3.2}/docs/en/textbook/04_backtest_engine.md +0 -0
  201. {akquant-0.2.51 → akquant-0.3.2}/docs/en/textbook/05_strategy.md +0 -0
  202. {akquant-0.2.51 → akquant-0.3.2}/docs/en/textbook/06_stock_a.md +0 -0
  203. {akquant-0.2.51 → akquant-0.3.2}/docs/en/textbook/08_options.md +0 -0
  204. {akquant-0.2.51 → akquant-0.3.2}/docs/en/textbook/09_funds.md +0 -0
  205. {akquant-0.2.51 → akquant-0.3.2}/docs/en/textbook/10_analysis.md +0 -0
  206. {akquant-0.2.51 → akquant-0.3.2}/docs/en/textbook/11_optimization.md +0 -0
  207. {akquant-0.2.51 → akquant-0.3.2}/docs/en/textbook/12_ml.md +0 -0
  208. {akquant-0.2.51 → akquant-0.3.2}/docs/en/textbook/13_visualization.md +0 -0
  209. {akquant-0.2.51 → akquant-0.3.2}/docs/en/textbook/14_factor.md +0 -0
  210. {akquant-0.2.51 → akquant-0.3.2}/docs/en/textbook/15_live_trading.md +0 -0
  211. {akquant-0.2.51 → akquant-0.3.2}/docs/en/textbook/16_rust_indicators.md +0 -0
  212. {akquant-0.2.51 → akquant-0.3.2}/docs/en/textbook/index.md +0 -0
  213. {akquant-0.2.51 → akquant-0.3.2}/docs/javascripts/mathjax.js +0 -0
  214. {akquant-0.2.51 → akquant-0.3.2}/docs/javascripts/search-lang-filter.js +0 -0
  215. {akquant-0.2.51 → akquant-0.3.2}/docs/robots.txt +0 -0
  216. {akquant-0.2.51 → akquant-0.3.2}/docs/zh/advanced/analyzer_plugin_spec.md +0 -0
  217. {akquant-0.2.51 → akquant-0.3.2}/docs/zh/advanced/broker_capability_matrix.md +0 -0
  218. {akquant-0.2.51 → akquant-0.3.2}/docs/zh/advanced/custom_broker_production_checklist.md +0 -0
  219. {akquant-0.2.51 → akquant-0.3.2}/docs/zh/advanced/custom_broker_registry.md +0 -0
  220. {akquant-0.2.51 → akquant-0.3.2}/docs/zh/advanced/data_feed_adapter_spec.md +0 -0
  221. {akquant-0.2.51 → akquant-0.3.2}/docs/zh/advanced/ml.md +0 -0
  222. {akquant-0.2.51 → akquant-0.3.2}/docs/zh/advanced/multi_strategy_guide.md +0 -0
  223. {akquant-0.2.51 → akquant-0.3.2}/docs/zh/advanced/runtime_config.md +0 -0
  224. {akquant-0.2.51 → akquant-0.3.2}/docs/zh/advanced/strategy_style_decision.md +0 -0
  225. {akquant-0.2.51 → akquant-0.3.2}/docs/zh/advanced/timezone.md +0 -0
  226. {akquant-0.2.51 → akquant-0.3.2}/docs/zh/guide/analysis.md +0 -0
  227. {akquant-0.2.51 → akquant-0.3.2}/docs/zh/guide/cross_section_checklist.md +0 -0
  228. {akquant-0.2.51 → akquant-0.3.2}/docs/zh/guide/custom_indicator.md +0 -0
  229. {akquant-0.2.51 → akquant-0.3.2}/docs/zh/guide/data.md +0 -0
  230. {akquant-0.2.51 → akquant-0.3.2}/docs/zh/guide/factor.md +0 -0
  231. {akquant-0.2.51 → akquant-0.3.2}/docs/zh/guide/indicator_scenario_quickref.md +0 -0
  232. {akquant-0.2.51 → akquant-0.3.2}/docs/zh/guide/optimization.md +0 -0
  233. {akquant-0.2.51 → akquant-0.3.2}/docs/zh/guide/python_basics.md +0 -0
  234. {akquant-0.2.51 → akquant-0.3.2}/docs/zh/guide/quant_basics.md +0 -0
  235. {akquant-0.2.51 → akquant-0.3.2}/docs/zh/guide/rust_indicator_reference.md +0 -0
  236. {akquant-0.2.51 → akquant-0.3.2}/docs/zh/guide/talib_indicator_playbook.md +0 -0
  237. {akquant-0.2.51 → akquant-0.3.2}/docs/zh/guide/testing.md +0 -0
  238. {akquant-0.2.51 → akquant-0.3.2}/docs/zh/guide/visualization.md +0 -0
  239. {akquant-0.2.51 → akquant-0.3.2}/docs/zh/index.md +0 -0
  240. {akquant-0.2.51 → akquant-0.3.2}/docs/zh/meta/architecture.md +0 -0
  241. {akquant-0.2.51 → akquant-0.3.2}/docs/zh/meta/internals.md +0 -0
  242. {akquant-0.2.51 → akquant-0.3.2}/docs/zh/start/first_strategy.md +0 -0
  243. {akquant-0.2.51 → akquant-0.3.2}/docs/zh/start/installation.md +0 -0
  244. {akquant-0.2.51 → akquant-0.3.2}/docs/zh/start/setup_guide.md +0 -0
  245. {akquant-0.2.51 → akquant-0.3.2}/docs/zh/textbook/01_foundations.md +0 -0
  246. {akquant-0.2.51 → akquant-0.3.2}/docs/zh/textbook/02_programming.md +0 -0
  247. {akquant-0.2.51 → akquant-0.3.2}/docs/zh/textbook/03_data.md +0 -0
  248. {akquant-0.2.51 → akquant-0.3.2}/docs/zh/textbook/04_backtest_engine.md +0 -0
  249. {akquant-0.2.51 → akquant-0.3.2}/docs/zh/textbook/06_stock_a.md +0 -0
  250. {akquant-0.2.51 → akquant-0.3.2}/docs/zh/textbook/08_options.md +0 -0
  251. {akquant-0.2.51 → akquant-0.3.2}/docs/zh/textbook/09_funds.md +0 -0
  252. {akquant-0.2.51 → akquant-0.3.2}/docs/zh/textbook/10_analysis.md +0 -0
  253. {akquant-0.2.51 → akquant-0.3.2}/docs/zh/textbook/11_optimization.md +0 -0
  254. {akquant-0.2.51 → akquant-0.3.2}/docs/zh/textbook/12_ml.md +0 -0
  255. {akquant-0.2.51 → akquant-0.3.2}/docs/zh/textbook/13_visualization.md +0 -0
  256. {akquant-0.2.51 → akquant-0.3.2}/docs/zh/textbook/14_factor.md +0 -0
  257. {akquant-0.2.51 → akquant-0.3.2}/docs/zh/textbook/15_live_trading.md +0 -0
  258. {akquant-0.2.51 → akquant-0.3.2}/docs/zh/textbook/16_rust_indicators.md +0 -0
  259. {akquant-0.2.51 → akquant-0.3.2}/docs/zh/textbook/ROADMAP.md +0 -0
  260. {akquant-0.2.51 → akquant-0.3.2}/docs/zh/textbook/appendix_cite.md +0 -0
  261. {akquant-0.2.51 → akquant-0.3.2}/docs/zh/textbook/appendix_pitfalls.md +0 -0
  262. {akquant-0.2.51 → akquant-0.3.2}/docs/zh/textbook/appendix_setup.md +0 -0
  263. {akquant-0.2.51 → akquant-0.3.2}/docs/zh/textbook/capstone.md +0 -0
  264. {akquant-0.2.51 → akquant-0.3.2}/docs/zh/textbook/index.md +0 -0
  265. {akquant-0.2.51 → akquant-0.3.2}/examples/01_quickstart.py +0 -0
  266. {akquant-0.2.51 → akquant-0.3.2}/examples/02_parameter_optimization.py +0 -0
  267. {akquant-0.2.51 → akquant-0.3.2}/examples/03_parameter_optimization_advanced.py +0 -0
  268. {akquant-0.2.51 → akquant-0.3.2}/examples/04_mixed_assets.py +0 -0
  269. {akquant-0.2.51 → akquant-0.3.2}/examples/05_live_trading_ctp.py +0 -0
  270. {akquant-0.2.51 → akquant-0.3.2}/examples/07_option_test.py +0 -0
  271. {akquant-0.2.51 → akquant-0.3.2}/examples/08_event_callbacks.py +0 -0
  272. {akquant-0.2.51 → akquant-0.3.2}/examples/09_ml_framework.py +0 -0
  273. {akquant-0.2.51 → akquant-0.3.2}/examples/10_ml_walk_forward.py +0 -0
  274. {akquant-0.2.51 → akquant-0.3.2}/examples/11_plot_visualization.py +0 -0
  275. {akquant-0.2.51 → akquant-0.3.2}/examples/12_wfo_integrated.py +0 -0
  276. {akquant-0.2.51 → akquant-0.3.2}/examples/13_quantstats_report.py +0 -0
  277. {akquant-0.2.51 → akquant-0.3.2}/examples/14_multi_frequency.py +0 -0
  278. {akquant-0.2.51 → akquant-0.3.2}/examples/15_plot_intraday.py +0 -0
  279. {akquant-0.2.51 → akquant-0.3.2}/examples/16_adj_returns_signal.py +0 -0
  280. {akquant-0.2.51 → akquant-0.3.2}/examples/17_readme_demo.py +0 -0
  281. {akquant-0.2.51 → akquant-0.3.2}/examples/18_benchmark_multisymbol.py +0 -0
  282. {akquant-0.2.51 → akquant-0.3.2}/examples/19_factor_expression.py +0 -0
  283. {akquant-0.2.51 → akquant-0.3.2}/examples/20_risk_management_demo.py +0 -0
  284. {akquant-0.2.51 → akquant-0.3.2}/examples/22_strategy_runtime_config_demo.py +0 -0
  285. {akquant-0.2.51 → akquant-0.3.2}/examples/23_functional_callbacks_demo.py +0 -0
  286. {akquant-0.2.51 → akquant-0.3.2}/examples/24_functional_tick_simulation_demo.py +0 -0
  287. {akquant-0.2.51 → akquant-0.3.2}/examples/25_streaming_backtest_demo.py +0 -0
  288. {akquant-0.2.51 → akquant-0.3.2}/examples/26_streaming_quickstart.py +0 -0
  289. {akquant-0.2.51 → akquant-0.3.2}/examples/27_streaming_monitoring_console.py +0 -0
  290. {akquant-0.2.51 → akquant-0.3.2}/examples/28_streaming_alerts_and_persist.py +0 -0
  291. {akquant-0.2.51 → akquant-0.3.2}/examples/29_streaming_event_report.py +0 -0
  292. {akquant-0.2.51 → akquant-0.3.2}/examples/30_streaming_report_oneclick.py +0 -0
  293. {akquant-0.2.51 → akquant-0.3.2}/examples/31_streaming_live_console.py +0 -0
  294. {akquant-0.2.51 → akquant-0.3.2}/examples/32_streaming_live_web.py +0 -0
  295. {akquant-0.2.51 → akquant-0.3.2}/examples/33_report_and_analysis_outputs.py +0 -0
  296. {akquant-0.2.51 → akquant-0.3.2}/examples/34_multi_strategy_demo.py +0 -0
  297. {akquant-0.2.51 → akquant-0.3.2}/examples/35_custom_broker_registry_demo.py +0 -0
  298. {akquant-0.2.51 → akquant-0.3.2}/examples/37_feed_replay_alignment_demo.py +0 -0
  299. {akquant-0.2.51 → akquant-0.3.2}/examples/38_live_functional_strategy_demo.py +0 -0
  300. {akquant-0.2.51 → akquant-0.3.2}/examples/40_functional_multi_slot_risk_demo.py +0 -0
  301. {akquant-0.2.51 → akquant-0.3.2}/examples/41_live_multi_slot_orchestration_demo.py +0 -0
  302. {akquant-0.2.51 → akquant-0.3.2}/examples/44_strategy_source_loader_demo.py +0 -0
  303. {akquant-0.2.51 → akquant-0.3.2}/examples/45_talib_indicator_playbook_demo.py +0 -0
  304. {akquant-0.2.51 → akquant-0.3.2}/examples/46_broker_profile_demo.py +0 -0
  305. {akquant-0.2.51 → akquant-0.3.2}/examples/47_margin_liquidation_audit_demo.py +0 -0
  306. {akquant-0.2.51 → akquant-0.3.2}/examples/48_margin_liquidation_priority_compare.py +0 -0
  307. {akquant-0.2.51 → akquant-0.3.2}/examples/49_on_expiry_demo.py +0 -0
  308. {akquant-0.2.51 → akquant-0.3.2}/examples/50_framework_hooks_demo.py +0 -0
  309. {akquant-0.2.51 → akquant-0.3.2}/examples/51_class_tick_callbacks_demo.py +0 -0
  310. {akquant-0.2.51 → akquant-0.3.2}/examples/52_pre_open_demo.py +0 -0
  311. {akquant-0.2.51 → akquant-0.3.2}/examples/53_timer_to_pre_open_demo.py +0 -0
  312. {akquant-0.2.51 → akquant-0.3.2}/examples/54_functional_pre_open_demo.py +0 -0
  313. {akquant-0.2.51 → akquant-0.3.2}/examples/55_functional_ml_walk_forward.py +0 -0
  314. {akquant-0.2.51 → akquant-0.3.2}/examples/56_functional_warm_start_demo.py +0 -0
  315. {akquant-0.2.51 → akquant-0.3.2}/examples/57_functional_multi_slot_warm_start_demo.py +0 -0
  316. {akquant-0.2.51 → akquant-0.3.2}/examples/58_incremental_bootstrap_demo.py +0 -0
  317. {akquant-0.2.51 → akquant-0.3.2}/examples/60_custom_indicator_demo.py +0 -0
  318. {akquant-0.2.51 → akquant-0.3.2}/examples/61_indicator_visualization_export_demo.py +0 -0
  319. {akquant-0.2.51 → akquant-0.3.2}/examples/62_indicator_streaming_demo.py +0 -0
  320. {akquant-0.2.51 → akquant-0.3.2}/examples/63_indicator_ws_bridge_demo.py +0 -0
  321. {akquant-0.2.51 → akquant-0.3.2}/examples/64_indicator_live_web.py +0 -0
  322. {akquant-0.2.51 → akquant-0.3.2}/examples/benchmark_utils.py +0 -0
  323. {akquant-0.2.51 → akquant-0.3.2}/examples/pb_mock.py +0 -0
  324. {akquant-0.2.51 → akquant-0.3.2}/examples/strategies/01_stock_dual_moving_average.py +0 -0
  325. {akquant-0.2.51 → akquant-0.3.2}/examples/strategies/02_stock_grid_trading.py +0 -0
  326. {akquant-0.2.51 → akquant-0.3.2}/examples/strategies/03_stock_atr_breakout.py +0 -0
  327. {akquant-0.2.51 → akquant-0.3.2}/examples/strategies/04_stock_momentum_rotation.py +0 -0
  328. {akquant-0.2.51 → akquant-0.3.2}/examples/strategies/05_stock_momentum_rotation_timer.py +0 -0
  329. {akquant-0.2.51 → akquant-0.3.2}/examples/strategies/06_stock_momentum_rotation_bucket.py +0 -0
  330. {akquant-0.2.51 → akquant-0.3.2}/examples/strategies/07_stock_momentum_rotation_on_timer.py +0 -0
  331. {akquant-0.2.51 → akquant-0.3.2}/examples/strategies/09_stock_momentum_rotation_after_bar.py +0 -0
  332. {akquant-0.2.51 → akquant-0.3.2}/examples/textbook/ch01_quickstart.py +0 -0
  333. {akquant-0.2.51 → akquant-0.3.2}/examples/textbook/ch02_programming.py +0 -0
  334. {akquant-0.2.51 → akquant-0.3.2}/examples/textbook/ch03_data.py +0 -0
  335. {akquant-0.2.51 → akquant-0.3.2}/examples/textbook/ch04_comparison.py +0 -0
  336. {akquant-0.2.51 → akquant-0.3.2}/examples/textbook/ch05_strategy.py +0 -0
  337. {akquant-0.2.51 → akquant-0.3.2}/examples/textbook/ch06_stock_a.py +0 -0
  338. {akquant-0.2.51 → akquant-0.3.2}/examples/textbook/ch07_futures.py +0 -0
  339. {akquant-0.2.51 → akquant-0.3.2}/examples/textbook/ch08_options.py +0 -0
  340. {akquant-0.2.51 → akquant-0.3.2}/examples/textbook/ch09_funds.py +0 -0
  341. {akquant-0.2.51 → akquant-0.3.2}/examples/textbook/ch10_analysis.py +0 -0
  342. {akquant-0.2.51 → akquant-0.3.2}/examples/textbook/ch11_optimization.py +0 -0
  343. {akquant-0.2.51 → akquant-0.3.2}/examples/textbook/ch12_ml.py +0 -0
  344. {akquant-0.2.51 → akquant-0.3.2}/examples/textbook/ch13_visualization.py +0 -0
  345. {akquant-0.2.51 → akquant-0.3.2}/examples/textbook/ch14_factor.py +0 -0
  346. {akquant-0.2.51 → akquant-0.3.2}/examples/textbook/ch15_live_trading.py +0 -0
  347. {akquant-0.2.51 → akquant-0.3.2}/examples/textbook/ch15_strategy_loader.py +0 -0
  348. {akquant-0.2.51 → akquant-0.3.2}/examples/textbook/ch16_indicators.py +0 -0
  349. {akquant-0.2.51 → akquant-0.3.2}/mkdocs.yml +0 -0
  350. {akquant-0.2.51 → akquant-0.3.2}/python/akquant/analysis/__init__.py +0 -0
  351. {akquant-0.2.51 → akquant-0.3.2}/python/akquant/analysis/benchmark.py +0 -0
  352. {akquant-0.2.51 → akquant-0.3.2}/python/akquant/analyzer_plugin.py +0 -0
  353. {akquant-0.2.51 → akquant-0.3.2}/python/akquant/backtest/__init__.py +0 -0
  354. {akquant-0.2.51 → akquant-0.3.2}/python/akquant/backtest/__init__.pyi +0 -0
  355. {akquant-0.2.51 → akquant-0.3.2}/python/akquant/backtest/result.py +0 -0
  356. {akquant-0.2.51 → akquant-0.3.2}/python/akquant/checkpoint.py +0 -0
  357. {akquant-0.2.51 → akquant-0.3.2}/python/akquant/config.py +0 -0
  358. {akquant-0.2.51 → akquant-0.3.2}/python/akquant/data.py +0 -0
  359. {akquant-0.2.51 → akquant-0.3.2}/python/akquant/factor/__init__.py +0 -0
  360. {akquant-0.2.51 → akquant-0.3.2}/python/akquant/factor/engine.py +0 -0
  361. {akquant-0.2.51 → akquant-0.3.2}/python/akquant/factor/ops.py +0 -0
  362. {akquant-0.2.51 → akquant-0.3.2}/python/akquant/factor/parser.py +0 -0
  363. {akquant-0.2.51 → akquant-0.3.2}/python/akquant/feed_adapter.py +0 -0
  364. {akquant-0.2.51 → akquant-0.3.2}/python/akquant/fund/__init__.py +0 -0
  365. {akquant-0.2.51 → akquant-0.3.2}/python/akquant/futures/__init__.py +0 -0
  366. {akquant-0.2.51 → akquant-0.3.2}/python/akquant/gateway/base.py +0 -0
  367. {akquant-0.2.51 → akquant-0.3.2}/python/akquant/gateway/broker_event_mapper.py +0 -0
  368. {akquant-0.2.51 → akquant-0.3.2}/python/akquant/gateway/brokers/__init__.py +0 -0
  369. {akquant-0.2.51 → akquant-0.3.2}/python/akquant/gateway/brokers/ctp/__init__.py +0 -0
  370. {akquant-0.2.51 → akquant-0.3.2}/python/akquant/gateway/brokers/ctp/adapter.py +0 -0
  371. {akquant-0.2.51 → akquant-0.3.2}/python/akquant/gateway/brokers/ctp/native.py +0 -0
  372. {akquant-0.2.51 → akquant-0.3.2}/python/akquant/gateway/brokers/miniqmt/__init__.py +0 -0
  373. {akquant-0.2.51 → akquant-0.3.2}/python/akquant/gateway/brokers/miniqmt/stub.py +0 -0
  374. {akquant-0.2.51 → akquant-0.3.2}/python/akquant/gateway/brokers/ptrade/__init__.py +0 -0
  375. {akquant-0.2.51 → akquant-0.3.2}/python/akquant/gateway/brokers/ptrade/stub.py +0 -0
  376. {akquant-0.2.51 → akquant-0.3.2}/python/akquant/gateway/ctp_adapter.py +0 -0
  377. {akquant-0.2.51 → akquant-0.3.2}/python/akquant/gateway/ctp_native.py +0 -0
  378. {akquant-0.2.51 → akquant-0.3.2}/python/akquant/gateway/mapper.py +0 -0
  379. {akquant-0.2.51 → akquant-0.3.2}/python/akquant/gateway/miniqmt.py +0 -0
  380. {akquant-0.2.51 → akquant-0.3.2}/python/akquant/gateway/models.py +0 -0
  381. {akquant-0.2.51 → akquant-0.3.2}/python/akquant/gateway/ptrade.py +0 -0
  382. {akquant-0.2.51 → akquant-0.3.2}/python/akquant/gateway/registry.py +0 -0
  383. {akquant-0.2.51 → akquant-0.3.2}/python/akquant/indicator.py +0 -0
  384. {akquant-0.2.51 → akquant-0.3.2}/python/akquant/indicator_recording.py +0 -0
  385. {akquant-0.2.51 → akquant-0.3.2}/python/akquant/indicator_stream.py +0 -0
  386. {akquant-0.2.51 → akquant-0.3.2}/python/akquant/log.py +0 -0
  387. {akquant-0.2.51 → akquant-0.3.2}/python/akquant/ml/__init__.py +0 -0
  388. {akquant-0.2.51 → akquant-0.3.2}/python/akquant/ml/model.py +0 -0
  389. {akquant-0.2.51 → akquant-0.3.2}/python/akquant/optimize.py +0 -0
  390. {akquant-0.2.51 → akquant-0.3.2}/python/akquant/option/__init__.py +0 -0
  391. {akquant-0.2.51 → akquant-0.3.2}/python/akquant/params.py +0 -0
  392. {akquant-0.2.51 → akquant-0.3.2}/python/akquant/params_adapter.py +0 -0
  393. {akquant-0.2.51 → akquant-0.3.2}/python/akquant/plot/__init__.py +0 -0
  394. {akquant-0.2.51 → akquant-0.3.2}/python/akquant/plot/analysis.py +0 -0
  395. {akquant-0.2.51 → akquant-0.3.2}/python/akquant/plot/dashboard.py +0 -0
  396. {akquant-0.2.51 → akquant-0.3.2}/python/akquant/plot/indicator.py +0 -0
  397. {akquant-0.2.51 → akquant-0.3.2}/python/akquant/plot/report.py +0 -0
  398. {akquant-0.2.51 → akquant-0.3.2}/python/akquant/plot/strategy.py +0 -0
  399. {akquant-0.2.51 → akquant-0.3.2}/python/akquant/plot/utils.py +0 -0
  400. {akquant-0.2.51 → akquant-0.3.2}/python/akquant/py.typed +0 -0
  401. {akquant-0.2.51 → akquant-0.3.2}/python/akquant/risk.py +0 -0
  402. {akquant-0.2.51 → akquant-0.3.2}/python/akquant/sizer.py +0 -0
  403. {akquant-0.2.51 → akquant-0.3.2}/python/akquant/stock/__init__.py +0 -0
  404. {akquant-0.2.51 → akquant-0.3.2}/python/akquant/strategy_history.py +0 -0
  405. {akquant-0.2.51 → akquant-0.3.2}/python/akquant/strategy_loader.py +0 -0
  406. {akquant-0.2.51 → akquant-0.3.2}/python/akquant/strategy_logging.py +0 -0
  407. {akquant-0.2.51 → akquant-0.3.2}/python/akquant/strategy_ml.py +0 -0
  408. {akquant-0.2.51 → akquant-0.3.2}/python/akquant/strategy_order_events.py +0 -0
  409. {akquant-0.2.51 → akquant-0.3.2}/python/akquant/strategy_position.py +0 -0
  410. {akquant-0.2.51 → akquant-0.3.2}/python/akquant/strategy_scheduler.py +0 -0
  411. {akquant-0.2.51 → akquant-0.3.2}/python/akquant/strategy_time.py +0 -0
  412. {akquant-0.2.51 → akquant-0.3.2}/python/akquant/talib/__init__.py +0 -0
  413. {akquant-0.2.51 → akquant-0.3.2}/python/akquant/talib/backend.py +0 -0
  414. {akquant-0.2.51 → akquant-0.3.2}/python/akquant/talib/core.py +0 -0
  415. {akquant-0.2.51 → akquant-0.3.2}/python/akquant/talib/funcs.py +0 -0
  416. {akquant-0.2.51 → akquant-0.3.2}/python/akquant/utils/__init__.py +0 -0
  417. {akquant-0.2.51 → akquant-0.3.2}/python/akquant/utils/inspector.py +0 -0
  418. {akquant-0.2.51 → akquant-0.3.2}/requirements-dev.txt +0 -0
  419. {akquant-0.2.51 → akquant-0.3.2}/scripts/cargo-test.sh +0 -0
  420. {akquant-0.2.51 → akquant-0.3.2}/scripts/check_docs_api_examples.py +0 -0
  421. {akquant-0.2.51 → akquant-0.3.2}/scripts/check_docs_links.py +0 -0
  422. {akquant-0.2.51 → akquant-0.3.2}/scripts/dev-check.sh +0 -0
  423. {akquant-0.2.51 → akquant-0.3.2}/scripts/find_legacy_execution_policy_calls.py +0 -0
  424. {akquant-0.2.51 → akquant-0.3.2}/scripts/golden_baseline_report.py +0 -0
  425. {akquant-0.2.51 → akquant-0.3.2}/src/account.rs +0 -0
  426. {akquant-0.2.51 → akquant-0.3.2}/src/analysis/mod.rs +0 -0
  427. {akquant-0.2.51 → akquant-0.3.2}/src/analysis/python.rs +0 -0
  428. {akquant-0.2.51 → akquant-0.3.2}/src/analysis/result.rs +0 -0
  429. {akquant-0.2.51 → akquant-0.3.2}/src/analysis/tests.rs +0 -0
  430. {akquant-0.2.51 → akquant-0.3.2}/src/analysis/tracker.rs +0 -0
  431. {akquant-0.2.51 → akquant-0.3.2}/src/analysis/types.rs +0 -0
  432. {akquant-0.2.51 → akquant-0.3.2}/src/bin/stub_gen.rs +0 -0
  433. {akquant-0.2.51 → akquant-0.3.2}/src/clock.rs +0 -0
  434. {akquant-0.2.51 → akquant-0.3.2}/src/context.rs +0 -0
  435. {akquant-0.2.51 → akquant-0.3.2}/src/data/aggregator.rs +0 -0
  436. {akquant-0.2.51 → akquant-0.3.2}/src/data/batch.rs +0 -0
  437. {akquant-0.2.51 → akquant-0.3.2}/src/data/client.rs +0 -0
  438. {akquant-0.2.51 → akquant-0.3.2}/src/data/feed.rs +0 -0
  439. {akquant-0.2.51 → akquant-0.3.2}/src/data/mod.rs +0 -0
  440. {akquant-0.2.51 → akquant-0.3.2}/src/engine/core.rs +0 -0
  441. {akquant-0.2.51 → akquant-0.3.2}/src/engine/mod.rs +0 -0
  442. {akquant-0.2.51 → akquant-0.3.2}/src/engine/python.rs +0 -0
  443. {akquant-0.2.51 → akquant-0.3.2}/src/engine/state.rs +0 -0
  444. {akquant-0.2.51 → akquant-0.3.2}/src/error.rs +0 -0
  445. {akquant-0.2.51 → akquant-0.3.2}/src/event.rs +0 -0
  446. {akquant-0.2.51 → akquant-0.3.2}/src/event_manager.rs +0 -0
  447. {akquant-0.2.51 → akquant-0.3.2}/src/execution/common.rs +0 -0
  448. {akquant-0.2.51 → akquant-0.3.2}/src/execution/crypto.rs +0 -0
  449. {akquant-0.2.51 → akquant-0.3.2}/src/execution/forex.rs +0 -0
  450. {akquant-0.2.51 → akquant-0.3.2}/src/execution/futures.rs +0 -0
  451. {akquant-0.2.51 → akquant-0.3.2}/src/execution/matcher.rs +0 -0
  452. {akquant-0.2.51 → akquant-0.3.2}/src/execution/mod.rs +0 -0
  453. {akquant-0.2.51 → akquant-0.3.2}/src/execution/option.rs +0 -0
  454. {akquant-0.2.51 → akquant-0.3.2}/src/execution/python.rs +0 -0
  455. {akquant-0.2.51 → akquant-0.3.2}/src/execution/realtime.rs +0 -0
  456. {akquant-0.2.51 → akquant-0.3.2}/src/execution/simulated.rs +0 -0
  457. {akquant-0.2.51 → akquant-0.3.2}/src/execution/slippage.rs +0 -0
  458. {akquant-0.2.51 → akquant-0.3.2}/src/execution/stock.rs +0 -0
  459. {akquant-0.2.51 → akquant-0.3.2}/src/history.rs +0 -0
  460. {akquant-0.2.51 → akquant-0.3.2}/src/indicators/momentum.rs +0 -0
  461. {akquant-0.2.51 → akquant-0.3.2}/src/indicators/momentum_oscillators.rs +0 -0
  462. {akquant-0.2.51 → akquant-0.3.2}/src/indicators/momentum_rates.rs +0 -0
  463. {akquant-0.2.51 → akquant-0.3.2}/src/indicators/moving_average.rs +0 -0
  464. {akquant-0.2.51 → akquant-0.3.2}/src/indicators/moving_average_compound.rs +0 -0
  465. {akquant-0.2.51 → akquant-0.3.2}/src/indicators/moving_average_core.rs +0 -0
  466. {akquant-0.2.51 → akquant-0.3.2}/src/indicators/moving_average_transforms.rs +0 -0
  467. {akquant-0.2.51 → akquant-0.3.2}/src/indicators/moving_average_windowed.rs +0 -0
  468. {akquant-0.2.51 → akquant-0.3.2}/src/indicators/trend.rs +0 -0
  469. {akquant-0.2.51 → akquant-0.3.2}/src/indicators/trend_directional.rs +0 -0
  470. {akquant-0.2.51 → akquant-0.3.2}/src/indicators/trend_oscillators.rs +0 -0
  471. {akquant-0.2.51 → akquant-0.3.2}/src/indicators/trend_regression.rs +0 -0
  472. {akquant-0.2.51 → akquant-0.3.2}/src/indicators/volatility.rs +0 -0
  473. {akquant-0.2.51 → akquant-0.3.2}/src/indicators/volatility_price.rs +0 -0
  474. {akquant-0.2.51 → akquant-0.3.2}/src/indicators/volatility_stats.rs +0 -0
  475. {akquant-0.2.51 → akquant-0.3.2}/src/indicators/volume.rs +0 -0
  476. {akquant-0.2.51 → akquant-0.3.2}/src/indicators.rs +0 -0
  477. {akquant-0.2.51 → akquant-0.3.2}/src/lib.rs +0 -0
  478. {akquant-0.2.51 → akquant-0.3.2}/src/log_context.rs +0 -0
  479. {akquant-0.2.51 → akquant-0.3.2}/src/margin/calculator.rs +0 -0
  480. {akquant-0.2.51 → akquant-0.3.2}/src/margin/engine.rs +0 -0
  481. {akquant-0.2.51 → akquant-0.3.2}/src/margin/mod.rs +0 -0
  482. {akquant-0.2.51 → akquant-0.3.2}/src/market/china.rs +0 -0
  483. {akquant-0.2.51 → akquant-0.3.2}/src/market/core.rs +0 -0
  484. {akquant-0.2.51 → akquant-0.3.2}/src/market/corporate_action.rs +0 -0
  485. {akquant-0.2.51 → akquant-0.3.2}/src/market/fund.rs +0 -0
  486. {akquant-0.2.51 → akquant-0.3.2}/src/market/futures.rs +0 -0
  487. {akquant-0.2.51 → akquant-0.3.2}/src/market/manager.rs +0 -0
  488. {akquant-0.2.51 → akquant-0.3.2}/src/market/mod.rs +0 -0
  489. {akquant-0.2.51 → akquant-0.3.2}/src/market/option.rs +0 -0
  490. {akquant-0.2.51 → akquant-0.3.2}/src/market/simple.rs +0 -0
  491. {akquant-0.2.51 → akquant-0.3.2}/src/market/stock.rs +0 -0
  492. {akquant-0.2.51 → akquant-0.3.2}/src/model/corporate_action.rs +0 -0
  493. {akquant-0.2.51 → akquant-0.3.2}/src/model/instrument.rs +0 -0
  494. {akquant-0.2.51 → akquant-0.3.2}/src/model/market_data.rs +0 -0
  495. {akquant-0.2.51 → akquant-0.3.2}/src/model/mod.rs +0 -0
  496. {akquant-0.2.51 → akquant-0.3.2}/src/model/order.rs +0 -0
  497. {akquant-0.2.51 → akquant-0.3.2}/src/model/timer.rs +0 -0
  498. {akquant-0.2.51 → akquant-0.3.2}/src/model/types.rs +0 -0
  499. {akquant-0.2.51 → akquant-0.3.2}/src/order_manager.rs +0 -0
  500. {akquant-0.2.51 → akquant-0.3.2}/src/pipeline/mod.rs +0 -0
  501. {akquant-0.2.51 → akquant-0.3.2}/src/pipeline/processor.rs +0 -0
  502. {akquant-0.2.51 → akquant-0.3.2}/src/pipeline/runner.rs +0 -0
  503. {akquant-0.2.51 → akquant-0.3.2}/src/pipeline/stages/channel.rs +0 -0
  504. {akquant-0.2.51 → akquant-0.3.2}/src/pipeline/stages/cleanup.rs +0 -0
  505. {akquant-0.2.51 → akquant-0.3.2}/src/pipeline/stages/data.rs +0 -0
  506. {akquant-0.2.51 → akquant-0.3.2}/src/pipeline/stages/execution.rs +0 -0
  507. {akquant-0.2.51 → akquant-0.3.2}/src/pipeline/stages/mod.rs +0 -0
  508. {akquant-0.2.51 → akquant-0.3.2}/src/pipeline/stages/statistics.rs +0 -0
  509. {akquant-0.2.51 → akquant-0.3.2}/src/pipeline/stages/strategy.rs +0 -0
  510. {akquant-0.2.51 → akquant-0.3.2}/src/portfolio.rs +0 -0
  511. {akquant-0.2.51 → akquant-0.3.2}/src/risk/common.rs +0 -0
  512. {akquant-0.2.51 → akquant-0.3.2}/src/risk/config.rs +0 -0
  513. {akquant-0.2.51 → akquant-0.3.2}/src/risk/futures.rs +0 -0
  514. {akquant-0.2.51 → akquant-0.3.2}/src/risk/manager.rs +0 -0
  515. {akquant-0.2.51 → akquant-0.3.2}/src/risk/mod.rs +0 -0
  516. {akquant-0.2.51 → akquant-0.3.2}/src/risk/option.rs +0 -0
  517. {akquant-0.2.51 → akquant-0.3.2}/src/risk/portfolio.rs +0 -0
  518. {akquant-0.2.51 → akquant-0.3.2}/src/risk/rule.rs +0 -0
  519. {akquant-0.2.51 → akquant-0.3.2}/src/risk/stock.rs +0 -0
  520. {akquant-0.2.51 → akquant-0.3.2}/src/settlement/expiry.rs +0 -0
  521. {akquant-0.2.51 → akquant-0.3.2}/src/settlement/handler.rs +0 -0
  522. {akquant-0.2.51 → akquant-0.3.2}/src/settlement/manager.rs +0 -0
  523. {akquant-0.2.51 → akquant-0.3.2}/src/settlement/mod.rs +0 -0
  524. {akquant-0.2.51 → akquant-0.3.2}/src/settlement/option.rs +0 -0
  525. {akquant-0.2.51 → akquant-0.3.2}/src/statistics/mod.rs +0 -0
  526. {akquant-0.2.51 → akquant-0.3.2}/tests/gateway_contract/test_recovery_contract.py +0 -0
  527. {akquant-0.2.51 → akquant-0.3.2}/tests/golden/BASELINE_REPORT.md +0 -0
  528. {akquant-0.2.51 → akquant-0.3.2}/tests/golden/LEGACY_EXECUTION_CALLS.md +0 -0
  529. {akquant-0.2.51 → akquant-0.3.2}/tests/golden/baselines/futures_margin/equity_curve.parquet +0 -0
  530. {akquant-0.2.51 → akquant-0.3.2}/tests/golden/baselines/futures_margin/metrics.json +0 -0
  531. {akquant-0.2.51 → akquant-0.3.2}/tests/golden/baselines/futures_margin/orders.parquet +0 -0
  532. {akquant-0.2.51 → akquant-0.3.2}/tests/golden/baselines/option_basic/equity_curve.parquet +0 -0
  533. {akquant-0.2.51 → akquant-0.3.2}/tests/golden/baselines/option_basic/metrics.json +0 -0
  534. {akquant-0.2.51 → akquant-0.3.2}/tests/golden/baselines/option_basic/orders.parquet +0 -0
  535. {akquant-0.2.51 → akquant-0.3.2}/tests/golden/baselines/stock_t1/equity_curve.parquet +0 -0
  536. {akquant-0.2.51 → akquant-0.3.2}/tests/golden/baselines/stock_t1/metrics.json +0 -0
  537. {akquant-0.2.51 → akquant-0.3.2}/tests/golden/baselines/stock_t1/orders.parquet +0 -0
  538. {akquant-0.2.51 → akquant-0.3.2}/tests/golden/baselines/stock_t1/trades.parquet +0 -0
  539. {akquant-0.2.51 → akquant-0.3.2}/tests/golden/data/future_margin.parquet +0 -0
  540. {akquant-0.2.51 → akquant-0.3.2}/tests/golden/data/future_margin.parquet.sha256 +0 -0
  541. {akquant-0.2.51 → akquant-0.3.2}/tests/golden/data/option_basic.parquet +0 -0
  542. {akquant-0.2.51 → akquant-0.3.2}/tests/golden/data/option_basic.parquet.sha256 +0 -0
  543. {akquant-0.2.51 → akquant-0.3.2}/tests/golden/data/stock_t1.parquet +0 -0
  544. {akquant-0.2.51 → akquant-0.3.2}/tests/golden/data/stock_t1.parquet.sha256 +0 -0
  545. {akquant-0.2.51 → akquant-0.3.2}/tests/golden/gen_data.py +0 -0
  546. {akquant-0.2.51 → akquant-0.3.2}/tests/golden/runner.py +0 -0
  547. {akquant-0.2.51 → akquant-0.3.2}/tests/golden/strategies/futures_margin.py +0 -0
  548. {akquant-0.2.51 → akquant-0.3.2}/tests/golden/strategies/option_basic.py +0 -0
  549. {akquant-0.2.51 → akquant-0.3.2}/tests/golden/strategies/stock_t1.py +0 -0
  550. {akquant-0.2.51 → akquant-0.3.2}/tests/golden/test_golden.py +0 -0
  551. {akquant-0.2.51 → akquant-0.3.2}/tests/test_custom_matcher.py +0 -0
  552. {akquant-0.2.51 → akquant-0.3.2}/tests/test_data_catalog.py +0 -0
  553. {akquant-0.2.51 → akquant-0.3.2}/tests/test_docs_api_examples.py +0 -0
  554. {akquant-0.2.51 → akquant-0.3.2}/tests/test_docs_links.py +0 -0
  555. {akquant-0.2.51 → akquant-0.3.2}/tests/test_examples_regression.py +0 -0
  556. {akquant-0.2.51 → akquant-0.3.2}/tests/test_factor_engine.py +0 -0
  557. {akquant-0.2.51 → akquant-0.3.2}/tests/test_factor_ops.py +0 -0
  558. {akquant-0.2.51 → akquant-0.3.2}/tests/test_feed_adapter.py +0 -0
  559. {akquant-0.2.51 → akquant-0.3.2}/tests/test_gateway_brokers_paths.py +0 -0
  560. {akquant-0.2.51 → akquant-0.3.2}/tests/test_gateway_callbacks.py +0 -0
  561. {akquant-0.2.51 → akquant-0.3.2}/tests/test_gateway_ctp_adapter.py +0 -0
  562. {akquant-0.2.51 → akquant-0.3.2}/tests/test_gateway_ctp_native.py +0 -0
  563. {akquant-0.2.51 → akquant-0.3.2}/tests/test_gateway_factory.py +0 -0
  564. {akquant-0.2.51 → akquant-0.3.2}/tests/test_gateway_mapper.py +0 -0
  565. {akquant-0.2.51 → akquant-0.3.2}/tests/test_gateway_registry.py +0 -0
  566. {akquant-0.2.51 → akquant-0.3.2}/tests/test_indicator_live_web_example.py +0 -0
  567. {akquant-0.2.51 → akquant-0.3.2}/tests/test_indicator_recording.py +0 -0
  568. {akquant-0.2.51 → akquant-0.3.2}/tests/test_inspector.py +0 -0
  569. {akquant-0.2.51 → akquant-0.3.2}/tests/test_live_runner.py +0 -0
  570. {akquant-0.2.51 → akquant-0.3.2}/tests/test_orders_df.py +0 -0
  571. {akquant-0.2.51 → akquant-0.3.2}/tests/test_params_adapter.py +0 -0
  572. {akquant-0.2.51 → akquant-0.3.2}/tests/test_partial_filled_status.py +0 -0
  573. {akquant-0.2.51 → akquant-0.3.2}/tests/test_portfolio.py +0 -0
  574. {akquant-0.2.51 → akquant-0.3.2}/tests/test_quickstart_stream_consistency.py +0 -0
  575. {akquant-0.2.51 → akquant-0.3.2}/tests/test_report_helpers.py +0 -0
  576. {akquant-0.2.51 → akquant-0.3.2}/tests/test_report_plot_extensions.py +0 -0
  577. {akquant-0.2.51 → akquant-0.3.2}/tests/test_result_analysis_extensions.py +0 -0
  578. {akquant-0.2.51 → akquant-0.3.2}/tests/test_stop_orders.py +0 -0
  579. {akquant-0.2.51 → akquant-0.3.2}/tests/test_strategy_timers_indicators.py +0 -0
  580. {akquant-0.2.51 → akquant-0.3.2}/tests/test_t_plus_one.py +0 -0
  581. {akquant-0.2.51 → akquant-0.3.2}/tests/test_talib_backend.py +0 -0
  582. {akquant-0.2.51 → akquant-0.3.2}/tests/test_talib_compat.py +0 -0
  583. {akquant-0.2.51 → akquant-0.3.2}/tests/test_trades_df.py +0 -0
  584. {akquant-0.2.51 → akquant-0.3.2}/tests/test_version.py +0 -0
@@ -0,0 +1,49 @@
1
+ # ── 构建产物 ──
2
+ target/
3
+ build/
4
+ dist/
5
+ site/
6
+ refs/
7
+ *.egg-info/
8
+
9
+ # ── Python ──
10
+ __pycache__/
11
+ *.so
12
+ *.dylib
13
+ *.dSYM/
14
+ *.pyd
15
+ *.pdb
16
+
17
+ # ── 环境 / 依赖 ──
18
+ .env
19
+ .venv
20
+ venv/
21
+ uv.lock
22
+
23
+ # ── IDE / 编辑器 ──
24
+ .idea/
25
+ .vscode/
26
+ .trae/
27
+ *.swp
28
+
29
+ # ── 操作系统 ──
30
+ .DS_Store
31
+
32
+ # ── 日志 ──
33
+ *.log
34
+ *.err
35
+
36
+ # ── 本地配置 ──
37
+ .cargo/config.toml
38
+ CLAUDE.md
39
+
40
+ # ── 本地数据 ──
41
+ /data_catalog/
42
+
43
+ # ── AI 工作流文档(内部,不公开)──
44
+ docs/superpowers
45
+
46
+ # ── 私有 broker 已拆分为独立包(akquant-qmf / akquant-middleware,独立私有仓)──
47
+
48
+ # ── 外部前置机/回测服务子项目(vendored,独立仓库,不纳入本仓版本管理)──
49
+ /vendor/
@@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
12
12
  - `BacktestConfig` 新增 `days_per_year`(年化天数因子,默认 252;数字货币 24/7 市场可设 365)与 `risk_free_rate`(年化无风险利率,默认 0.0)两个字段,用于参数化 Sharpe/Sortino/波动率等风险指标的年化口径。`risk_free_rate` 默认 0 不改变任何现有数值。
13
13
 
14
14
  ### Changed
15
+ - **`buy`/`sell`/`submit_order` 返回类型变更(破坏性)**:三者现统一返回 `OrderReceipt`(原为 `str` 订单号),回测与实盘(`broker_live`)两种模式返回类型一致;实盘 `submit_order` 此前会将多腿委托(如反手拆分的平仓+开仓、开平分离)收窄为单一 id 字符串,现已修复为返回携带全部腿 id 的完整 `OrderReceipt`。取单个订单 id 用 `receipt.primary`(首腿 broker_order_id,兼容旧用法),取全部腿 id 用 `receipt.order_ids`;`str(receipt)` 取 `group_id`(逻辑委托的客户端订单号),关联成交请用 `trade.group_id` 而非逐个 order_id 比对;新增 `cancel_group(group_id)` 用于一次性撤销一个逻辑委托的全部腿。
15
16
  - **回测指标口径变更(破坏性)**:Sharpe / Sortino 比率的分子改为「日收益算术均值 × `days_per_year`」做年化,替代原先的 CAGR(复合年化),与 pyfolio/empyrical/quantstats 等主流实现一致,并与分母 `√days_per_year` 的年化口径匹配。升级后历史报告的 Sharpe/Sortino 数值会变化,不可直接与旧版逐值对比;UPI 与 Calmar 仍沿用 CAGR 口径。
16
17
  - 策略交易日边界回调已硬切改名:`before_trading(trading_date, timestamp)` 更名为 `on_before_trading(trading_date, timestamp)`,`after_trading(trading_date, timestamp)` 更名为 `on_after_trading(trading_date, timestamp)`。
17
18
  - 旧回调名不再保留兼容别名;升级到当前版本后,若策略仍实现 `before_trading` / `after_trading`,将不会再被框架触发,请同步迁移到新名称。
@@ -30,7 +30,7 @@ dependencies = [
30
30
 
31
31
  [[package]]
32
32
  name = "akquant"
33
- version = "0.2.51"
33
+ version = "0.3.2"
34
34
  dependencies = [
35
35
  "anyhow",
36
36
  "chrono",
@@ -692,9 +692,9 @@ dependencies = [
692
692
 
693
693
  [[package]]
694
694
  name = "ethnum"
695
- version = "1.5.2"
695
+ version = "1.5.3"
696
696
  source = "registry+https://github.com/rust-lang/crates.io-index"
697
- checksum = "ca81e6b4777c89fd810c25a4be2b1bd93ea034fbe58e6a75216a34c6b82c539b"
697
+ checksum = "40404c3f5f511ec4da6fe866ddf6a717c309fdbb69fbbad7b0f3edab8f2e835f"
698
698
 
699
699
  [[package]]
700
700
  name = "event-listener"
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "akquant"
3
- version = "0.2.51"
3
+ version = "0.3.2"
4
4
  edition = "2024"
5
5
  description = "High-performance quantitative trading framework based on Rust and Python"
6
6
  license = "MIT"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: akquant
3
- Version: 0.2.51
3
+ Version: 0.3.2
4
4
  Classifier: Programming Language :: Rust
5
5
  Classifier: Programming Language :: Python :: Implementation :: CPython
6
6
  Classifier: Programming Language :: Python :: Implementation :: PyPy
@@ -222,8 +222,8 @@ min_margin_level 68.587671
222
222
 
223
223
  AKQuant 提供了两组复杂订单助手,减少手写订单联动逻辑:
224
224
 
225
- * `create_oco_order_group(first_order_id, second_order_id, group_id=None)`:将两个订单绑定为 OCO,任一成交后自动撤销另一单。
226
- * `place_bracket_order(symbol, quantity, entry_price=None, stop_trigger_price=None, take_profit_price=None, ...)`:一次性提交 Bracket 结构;进场成交后自动挂出止损/止盈,并在双退出单场景下自动绑定 OCO。
225
+ * `place_oco(first_order_id, second_order_id, group_id=None)`:将两个订单绑定为 OCO,任一成交后自动撤销另一单。
226
+ * `place_bracket(symbol, quantity, entry_price=None, stop_trigger_price=None, take_profit_price=None, ...)`:一次性提交 Bracket 结构;进场成交后自动挂出止损/止盈,并在双退出单场景下自动绑定 OCO。
227
227
 
228
228
  ```python
229
229
  from akquant import OrderStatus, Strategy
@@ -236,7 +236,7 @@ class BracketHelperStrategy(Strategy):
236
236
  if self.get_position(bar.symbol) > 0 or self.entry_order_id:
237
237
  return
238
238
 
239
- self.entry_order_id = self.place_bracket_order(
239
+ self.entry_order_id = self.place_bracket(
240
240
  symbol=bar.symbol,
241
241
  quantity=100,
242
242
  stop_trigger_price=bar.close * 0.98,
@@ -167,8 +167,8 @@ min_margin_level 68.587671
167
167
 
168
168
  AKQuant 提供了两组复杂订单助手,减少手写订单联动逻辑:
169
169
 
170
- * `create_oco_order_group(first_order_id, second_order_id, group_id=None)`:将两个订单绑定为 OCO,任一成交后自动撤销另一单。
171
- * `place_bracket_order(symbol, quantity, entry_price=None, stop_trigger_price=None, take_profit_price=None, ...)`:一次性提交 Bracket 结构;进场成交后自动挂出止损/止盈,并在双退出单场景下自动绑定 OCO。
170
+ * `place_oco(first_order_id, second_order_id, group_id=None)`:将两个订单绑定为 OCO,任一成交后自动撤销另一单。
171
+ * `place_bracket(symbol, quantity, entry_price=None, stop_trigger_price=None, take_profit_price=None, ...)`:一次性提交 Bracket 结构;进场成交后自动挂出止损/止盈,并在双退出单场景下自动绑定 OCO。
172
172
 
173
173
  ```python
174
174
  from akquant import OrderStatus, Strategy
@@ -181,7 +181,7 @@ class BracketHelperStrategy(Strategy):
181
181
  if self.get_position(bar.symbol) > 0 or self.entry_order_id:
182
182
  return
183
183
 
184
- self.entry_order_id = self.place_bracket_order(
184
+ self.entry_order_id = self.place_bracket(
185
185
  symbol=bar.symbol,
186
186
  quantity=100,
187
187
  stop_trigger_price=bar.close * 0.98,
@@ -45,7 +45,7 @@ def initialize(ctx):
45
45
  ctx.sent = False
46
46
 
47
47
  def on_bar(ctx, bar):
48
- if not ctx.sent and hasattr(ctx, "submit_order"):
48
+ if not ctx.sent and getattr(ctx, "broker_ready", False):
49
49
  ctx.submit_order(
50
50
  symbol=bar.symbol,
51
51
  side="Buy",
@@ -72,9 +72,11 @@ runner.run(duration="30s", show_progress=False)
72
72
 
73
73
  ## 4. Common troubleshooting
74
74
 
75
- - `submit_order not injected yet`
76
- - Cause: trader gateway binding is not ready.
77
- - Fix: guard with `hasattr(ctx, "submit_order")` before placing.
75
+ - `submit_order` not ready yet
76
+ - Cause: the trader gateway has not finished connecting/logging in.
77
+ - Fix: guard with `if getattr(ctx, "broker_ready", False):` before placing
78
+ (readiness is decided by LiveRunner's heartbeat poll; submitting before
79
+ ready raises a clear error).
78
80
  - `duplicate active client_order_id`
79
81
  - Cause: reused active client id.
80
82
  - Fix: generate a fresh `client_order_id` for each new order.
@@ -36,11 +36,11 @@ Your task is to write trading strategies or backtest scripts based on user requi
36
36
  * `self.order_target_percent(target, symbol)`: Adjust position to target percentage.
37
37
  * `self.order_target_value(target, symbol)`: Adjust position to target value.
38
38
  * **Position**: `self.get_position(symbol)` returns current holding (float). `self.position.entry_price` or `self.ctx.get_position_entry_price(symbol)` returns runtime average entry price.
39
- * **Account**: `self.ctx.cash`, `self.get_portfolio_value()`, `self.get_account()`.
39
+ * **Account**: `self.ctx.cash`, `self.equity`, `self.get_account()`.
40
40
 
41
41
  4. **Indicators**:
42
42
  * Prefer using `akquant.indicators` (e.g., `SMA`, `RSI`).
43
- * Register in `__init__` or `on_start`: `self.sma = SMA(20); self.register_indicator("sma", self.sma)`.
43
+ * Register in `__init__` or `on_start`: `self.sma = SMA(20); self.register_precomputed_indicator("sma", self.sma)`.
44
44
  * Access value via `self.sma.value`.
45
45
 
46
46
  5. **Backtest Execution**:
@@ -94,7 +94,7 @@ def on_start(self):
94
94
  else:
95
95
  self.log("Resumed from snapshot. Indicators retained.")
96
96
 
97
- self.register_indicator("sma", self.sma)
97
+ self.register_precomputed_indicator("sma", self.sma)
98
98
  self.subscribe(self.symbol)
99
99
  ```
100
100
 
@@ -122,7 +122,7 @@ class MyStrategy(Strategy):
122
122
  def on_start(self):
123
123
  if not self.is_restored:
124
124
  self.sma = SMA(10)
125
- self.register_indicator("sma", self.sma)
125
+ self.register_precomputed_indicator("sma", self.sma)
126
126
 
127
127
  # ... run phase 1 ...
128
128
  save_snapshot(engine, strategy, "checkpoint.pkl")
@@ -479,7 +479,7 @@ The `examples/` directory contains more scripts demonstrating AKShare integratio
479
479
  * Prints `bundle.metadata` to confirm the custom broker is resolved by factory.
480
480
 
481
481
  * **[43_target_weights_rebalance.py](https://github.com/akfamily/akquant/blob/main/examples/43_target_weights_rebalance.py)**:
482
- * Demonstrates TopN dynamic weights: rank symbols by momentum, select winners, then rebalance with `order_target_weights`.
482
+ * Demonstrates TopN dynamic weights: rank symbols by momentum, select winners, then rebalance with `rebalance_weights`.
483
483
  * Shows practical usage of `liquidate_unmentioned` and `rebalance_tolerance`, then prints `selected_history` / `final_positions` / `final_equity`.
484
484
 
485
485
  * **[46_broker_profile_demo.py](https://github.com/akfamily/akquant/blob/main/examples/46_broker_profile_demo.py)**:
@@ -81,7 +81,7 @@ Notes:
81
81
  * `on_reject` is emitted once per order id when the order first becomes `Rejected`.
82
82
  * `on_pre_open` is emitted once per trading day before the first regular bar/tick callback of that day.
83
83
  * `on_before_trading` is emitted once per local trading date when the regular trading session starts; on the default backtest path this session is usually exposed as `Continuous`.
84
- * `on_before_trading` / `on_daily_rebalance` always use a "previous trading day / previous snapshot only" visibility model; inside these callbacks, `get_history()`, `get_account()`, and `get_portfolio_value()` must not expose the current day's new bar or the current day's updated account view.
84
+ * `on_before_trading` / `on_daily_rebalance` always use a "previous trading day / previous snapshot only" visibility model; inside these callbacks, `get_history()`, `get_account()`, and `equity` must not expose the current day's new bar or the current day's updated account view.
85
85
  * `on_daily_rebalance_after_bar` runs after the framework has seen the first complete cross-symbol slice for the trading day; inside this callback, current-day history and the current account snapshot are visible.
86
86
  * `on_after_trading` is emitted once per local trading date when leaving the regular trading session, or on the next event if day rollover occurs first.
87
87
  * Inside `on_pre_open`, plain `buy/sell/order_target_*` calls automatically resolve to `price_basis=open, bar_offset=1, temporal=same_cycle` unless an explicit `fill_policy` is provided.
@@ -531,7 +531,7 @@ In AKQuant, order status transitions are as follows:
531
531
  Converts to a market order when the market price touches the trigger price (`trigger_price`).
532
532
  ```python
533
533
  # Stop Sell (Market) when price drops below 140
534
- self.stop_sell(symbol="AAPL", quantity=100, trigger_price=140.0)
534
+ self.sell(symbol="AAPL", quantity=100, trigger_price=140.0)
535
535
  ```
536
536
  * **Target Orders**:
537
537
  Automatically calculates buy/sell quantities to adjust the position to a target value.
@@ -544,7 +544,7 @@ In AKQuant, order status transitions are as follows:
544
544
  ```
545
545
  Rebalance multiple symbols with a single target-weight call:
546
546
  ```python
547
- self.order_target_weights(
547
+ self.rebalance_weights(
548
548
  target_weights={"AAPL": 0.4, "MSFT": 0.3, "GOOGL": 0.2},
549
549
  liquidate_unmentioned=True,
550
550
  rebalance_tolerance=0.01,
@@ -769,7 +769,7 @@ Notes:
769
769
 
770
770
  - Opening a futures position does not deduct full notional from cash the way a spot buy does.
771
771
  - For futures, use `equity` for net account value, `used_margin` for margin usage, and `notional_value` for leverage exposure.
772
- - If you only need one "current total equity" number, prefer `get_portfolio_value()`, which is aligned with `get_account()["equity"]`.
772
+ - If you only need one "current total equity" number, prefer `equity`, which is aligned with `get_account()["equity"]`.
773
773
 
774
774
  ## 6. Using High-Performance Indicators {: #indicatorset }
775
775
 
@@ -914,10 +914,10 @@ class IntradayStrategy(Strategy):
914
914
 
915
915
  AKQuant provides helper APIs for linked order management:
916
916
 
917
- * `self.create_oco_order_group(first_order_id, second_order_id, group_id=None)`
917
+ * `self.place_oco(first_order_id, second_order_id, group_id=None)`
918
918
  * Binds two orders as OCO (One-Cancels-the-Other).
919
919
  * Once either order is filled, the peer order is canceled automatically.
920
- * `self.place_bracket_order(symbol, quantity, entry_price=None, stop_trigger_price=None, take_profit_price=None, ...)`
920
+ * `self.place_bracket(symbol, quantity, entry_price=None, stop_trigger_price=None, take_profit_price=None, ...)`
921
921
  * Submits a bracket structure in one call.
922
922
  * After entry fill, stop-loss and take-profit exits are submitted automatically; when both exits exist, they are linked as OCO.
923
923
 
@@ -932,7 +932,7 @@ class BracketHelperStrategy(Strategy):
932
932
  if self.get_position(bar.symbol) > 0 or self.entry_order_id:
933
933
  return
934
934
 
935
- self.entry_order_id = self.place_bracket_order(
935
+ self.entry_order_id = self.place_bracket(
936
936
  symbol=bar.symbol,
937
937
  quantity=100,
938
938
  stop_trigger_price=bar.close * 0.98,
@@ -832,19 +832,20 @@ Note: if you do not pass an explicit `fill_policy` here, the framework defaults
832
832
  * `self.position`: Position object for current symbol, with `size` and `available` properties.
833
833
  * `self.now`: Current backtest time (`pd.Timestamp`).
834
834
  * `self.runtime_config`: Runtime behavior config object (`StrategyRuntimeConfig`).
835
- * `self.enable_precise_day_boundary_hooks`: Enable boundary timer based precise day hooks (default `False`). This switch changes trigger precision only; it does not change the visibility window of `get_history()`, `get_account()`, or `get_portfolio_value()` inside `on_before_trading` / `on_daily_rebalance`.
835
+ * `self.enable_precise_day_boundary_hooks`: Enable boundary timer based precise day hooks (default `False`). This switch changes trigger precision only; it does not change the visibility window of `get_history()`, `get_account()`, or `equity` inside `on_before_trading` / `on_daily_rebalance`.
836
836
  * `self.portfolio_update_eps`: Snapshot threshold; changes below it skip `on_portfolio_update` (default `0.0`).
837
837
  * `self.error_mode`: Error handling mode, `"raise"` or `"continue"` (default `"raise"`).
838
838
  * `self.re_raise_on_error`: Whether to re-raise user callback exception after `on_error` (default `True`).
839
839
 
840
840
  **Trading Methods:**
841
841
 
842
- * `buy(symbol, quantity, price=None, ...)`: Buy. Market order if `price` is not specified.
843
- * `sell(symbol, quantity, price=None, ...)`: Sell.
842
+ * `buy(symbol, quantity, price=None, trigger_price=None, ...)`: Buy (open long / close short).
843
+ * Market order if `price` is not specified.
844
+ * Limit order if `price` is specified.
845
+ * Stop order (Stop Market) if `trigger_price` is specified.
846
+ * `sell(symbol, quantity, price=None, trigger_price=None, ...)`: Sell (close long / open short). Same parameters as above.
844
847
  * `short(symbol, quantity, price=None, ...)`: Short sell.
845
848
  * `cover(symbol, quantity, price=None, ...)`: Buy to cover.
846
- * `stop_buy(symbol, trigger_price, quantity, ...)`: Stop buy (Stop Market). Triggers a market buy order when price breaks above `trigger_price`.
847
- * `stop_sell(symbol, trigger_price, quantity, ...)`: Stop sell (Stop Market). Triggers a market sell order when price drops below `trigger_price`.
848
849
  * `submit_order(..., order_type="StopTrail", trail_offset=..., trail_reference_price=None)`: Submit a trailing stop order. `trail_offset` must be greater than 0.
849
850
  * `submit_order(..., order_type="StopTrailLimit", price=..., trail_offset=..., trail_reference_price=None)`: Submit a trailing stop-limit order. `price` and `trail_offset` are required.
850
851
  * `submit_order(..., broker_options={...})`: Optional broker extension fields passthrough (backtest currently records them on `order.broker_options` for debugging/audit).
@@ -852,7 +853,7 @@ Note: if you do not pass an explicit `fill_policy` here, the framework defaults
852
853
  * `place_trailing_stop_limit(symbol, quantity, price, trail_offset, side="Sell", trail_reference_price=None, ...) -> str`: Helper for trailing stop-limit orders, promoted to limit order when triggered.
853
854
  * `order_target_value(target_value, symbol, price=None)`: Adjust position to target value.
854
855
  * `order_target_percent(target_percent, symbol, price=None)`: Adjust position to target account percentage.
855
- * `order_target_weights(target_weights, price_map=None, liquidate_unmentioned=False, allow_leverage=False, rebalance_tolerance=0.0, ...)`: Rebalance a multi-asset portfolio by target weights.
856
+ * `rebalance_weights(target_weights, price_map=None, liquidate_unmentioned=False, allow_leverage=False, rebalance_tolerance=0.0, ...)`: Rebalance a multi-asset portfolio by target weights.
856
857
  * `target_weights` is `{symbol: weight}` and by default requires total weight `<= 1.0`.
857
858
  * `liquidate_unmentioned=True` sets all existing non-mentioned positions to target `0`.
858
859
  * Orders are submitted in sell-first then buy-second order to reduce cash-lock conflicts.
@@ -860,8 +861,8 @@ Note: if you do not pass an explicit `fill_policy` here, the framework defaults
860
861
  * `close_position(symbol)`: Close position for a specific instrument.
861
862
  * `cancel_order(order_id: str)`: Cancel a specific order.
862
863
  * `cancel_all_orders(symbol)`: Cancel all pending orders for a specific instrument. If `symbol` is omitted, cancels all orders.
863
- * `create_oco_order_group(first_order_id, second_order_id, group_id=None) -> str`: Create an OCO order group. Once one order is filled, the peer order is canceled automatically.
864
- * `place_bracket_order(symbol, quantity, entry_price=None, stop_trigger_price=None, take_profit_price=None, ...) -> str`: Create a bracket order. The entry order is submitted first, then stop-loss/take-profit exits are submitted after entry fill; if both exits exist, they are linked as OCO automatically.
864
+ * `place_oco(first_order_id, second_order_id, group_id=None) -> str`: Create an OCO order group. Once one order is filled, the peer order is canceled automatically.
865
+ * `place_bracket(symbol, quantity, entry_price=None, stop_trigger_price=None, take_profit_price=None, ...) -> str`: Create a bracket order. The entry order is submitted first, then stop-loss/take-profit exits are submitted after entry fill; if both exits exist, they are linked as OCO automatically.
865
866
 
866
867
  **Data & Utilities:**
867
868
 
@@ -869,17 +870,17 @@ Note: if you do not pass an explicit `fill_policy` here, the framework defaults
869
870
  * `get_history_df(count, symbol) -> pd.DataFrame`: Get history data DataFrame (OHLCV).
870
871
  * `get_position(symbol) -> float`: Get current position size. This still returns a numeric quantity, not an object.
871
872
  * `get_available_position(symbol) -> float`: Get available position size.
872
- * `get_positions() -> Dict[str, float]`: Get all positions by symbol.
873
+ * `positions -> Dict[str, float]`: Get all positions by symbol (read-only property).
873
874
  * `self.position.entry_price -> float`: Get the current symbol's average entry price via the `Position` helper.
874
875
  * `self.position.avg_price -> float`: Alias of `entry_price`.
875
876
  * `ctx.get_position_entry_price(symbol) -> float`: Get the current average entry price for one symbol.
876
877
  * `ctx.get_position_entry_prices() -> Dict[str, float]`: Get current average entry prices for all symbols.
877
- * `get_cash() -> float`: Get current available cash.
878
+ * `cash -> float`: Get current available cash (read-only property).
878
879
  * `get_account() -> Dict[str, float]`: Get an account snapshot. Common fields include `cash`, `equity`, `market_value`, `notional_value`, `frozen_cash`, `margin`, `used_margin`, `free_margin`, `unrealized_pnl`, `borrowed_cash`, `short_market_value`, `maintenance_ratio`, `account_mode`, `accrued_interest`, and `daily_interest`.
879
880
  * In cash / spot-style accounts, `market_value` usually represents marked position value.
880
881
  * In futures margin accounts, `equity` is account equity, `used_margin` is margin in use, `notional_value` is futures notional exposure, and `unrealized_pnl` is marked floating PnL. Futures trades do not deduct full notional from `cash` the way spot buys do, and notional exposure is not mirrored into `market_value` as if it were spot inventory.
881
882
  * `cash` is the cash balance; `free_margin` (= `equity - used_margin`) is the amount actually available to open new positions and matches the `Available` value shown in the rejection log when an order is rejected. In futures margin accounts, opening a position does not deduct margin from `cash`, so `cash` is usually larger than `free_margin`; in stock cash accounts the two are equal.
882
- * Inside strategy callbacks, prefer `get_portfolio_value()` when you only need current total equity; it is aligned with `get_account()["equity"]`.
883
+ * Inside strategy callbacks, prefer `equity` when you only need current total equity; it is aligned with `get_account()["equity"]`.
883
884
  * `get_order(order_id) -> Order`: Get details of a specific order.
884
885
  * `get_open_orders(symbol) -> List[Order]`: Get list of open orders.
885
886
  * `subscribe(instrument_id: str)`: Subscribe to market data. Must be called explicitly for multi-asset backtesting or live trading to receive `on_tick`/`on_bar` callbacks.
@@ -367,7 +367,7 @@ result = run_backtest(data=df, strategy=MetaQuickStrategy, config=config)
367
367
 
368
368
  ## Complex Orders in 30 Seconds
369
369
 
370
- If you need an entry + stop-loss + take-profit flow with automatic OCO linkage, use `place_bracket_order` directly:
370
+ If you need an entry + stop-loss + take-profit flow with automatic OCO linkage, use `place_bracket` directly:
371
371
 
372
372
  ```python
373
373
  from akquant import OrderStatus, Strategy
@@ -379,7 +379,7 @@ class BracketQuickStrategy(Strategy):
379
379
  def on_bar(self, bar):
380
380
  if self.get_position(bar.symbol) > 0 or self.entry_order_id:
381
381
  return
382
- self.entry_order_id = self.place_bracket_order(
382
+ self.entry_order_id = self.place_bracket(
383
383
  symbol=bar.symbol,
384
384
  quantity=100,
385
385
  stop_trigger_price=bar.close * 0.98,
@@ -51,11 +51,11 @@ Low-level Engine API naming:
51
51
  ## Futures Margin Account Snapshot Semantics
52
52
 
53
53
  Under AKQuant's futures margin-account semantics, read `get_account()` and
54
- `get_portfolio_value()` like this:
54
+ `equity` like this:
55
55
 
56
56
  - `cash`: cash balance. Opening a futures position does not deduct full notional
57
57
  the way a spot buy does; cash mainly reflects fees and realized cash flows.
58
- - `equity`: account equity. `get_portfolio_value()` is aligned with this field.
58
+ - `equity`: account equity. This is the `equity` property.
59
59
  - `used_margin` / `margin`: margin currently in use.
60
60
  - `free_margin`: available margin (`equity - used_margin`), i.e. the amount
61
61
  actually usable to open new positions. When an order is rejected for
@@ -0,0 +1,245 @@
1
+ # 如何新增一个 Broker
2
+
3
+ 本页说明 akquant broker 网关层的插件契约:新增一个 broker 需要实现哪些接口、
4
+ 声明哪些能力、以及如何把下单请求路由到具体柜台。目标是让接入者不修改
5
+ `akquant.gateway` 核心代码即可插入一个新的交易通道。
6
+
7
+ 如果只是想在不改内置工厂分支的前提下注册一个 broker,先看
8
+ [自定义 Broker 注册](custom_broker_registry.md);本页补充的是"网关本身怎么写"。
9
+
10
+ ## 总览:五步契约
11
+
12
+ 1. 写 **builder** 函数,通过 `register_broker(name, builder)` 注册(或者内置
13
+ broker 直接放进 `python/akquant/gateway/brokers/builtins.py`,由
14
+ `register_builtin_brokers()` 统一注册)。
15
+ 2. 声明 **`BrokerCapability`**:`broker_extra_fields` 列出本 broker 允许的
16
+ 订单专属字段,`features` 声明任意能力标志。
17
+ 3. 继承 **`TraderGatewayBase`** 实现必需方法。
18
+ 4. 在 `place_order` 里按 `req.asset_type` 路由品种、从 `req.extra` 取专属
19
+ 字段,并维护 broker 订单号与 `client_order_id` 的映射。
20
+ 5. 纯交易 broker(不接行情)令 `GatewayBundle(market_gateway=None, ...)`,
21
+ 行情继续走 akquant 现有 `DataFeed`。
22
+
23
+ ## 1. Builder:注册入口
24
+
25
+ Builder 是一个可调用对象,签名固定为:
26
+
27
+ ```python
28
+ def builder(
29
+ feed: DataFeed,
30
+ symbols: Sequence[str],
31
+ use_aggregator: bool,
32
+ **kwargs: Any,
33
+ ) -> GatewayBundle:
34
+ ...
35
+ ```
36
+
37
+ - 第三方/内部 broker:调用 `register_broker(name, builder)`(来自
38
+ `akquant.gateway`),注册后 `create_gateway_bundle(broker=name, ...)` 会
39
+ 优先解析到它。
40
+ - 想合并进内置分支的 broker:把 builder 函数加进
41
+ `python/akquant/gateway/brokers/builtins.py`,并在
42
+ `register_builtin_brokers()` 里追加一行 `register_broker("xxx", _build_xxx)`。
43
+
44
+ Builder 内部通常做三件事:校验必填 `kwargs`、构造 `TraderGateway`(以及可选的
45
+ `MarketGateway`)、把 `trader_gateway.get_capabilities()` 的结果写入
46
+ `GatewayBundle.trader_capabilities`,供上层校验 `extra` 字段用。
47
+
48
+ ## 2. 声明 `BrokerCapability`
49
+
50
+ `BrokerCapability`(`from akquant.gateway.broker_models import BrokerCapability`)
51
+ 是一个 frozen dataclass,描述这个 broker 的执行语义边界:
52
+
53
+ - `broker_extra_fields: tuple[str, ...]`:策略下单时通过
54
+ `submit_order(..., extra={...})` 传入的柜台专属字段,必须在这里声明;
55
+ 未声明的 key 会在校验时被拒绝(`validate_broker_extra` 会抛
56
+ `RuntimeError`,列出未声明字段与已声明集合)。
57
+ - `features: frozenset[str]`:任意能力标志的开放集合,用于策略侧按需探测
58
+ "这个 broker 支不支持某个特性",不做强类型约束。
59
+ - 其余字段(`position_effect`、`reduce_only`、`supports_short_sell`、
60
+ `supported_position_effects` 等)描述开平仓/做空等语义是否可用,按 broker
61
+ 实际能力如实填写即可,不确定的保持默认值(保守)。
62
+
63
+ `TraderGateway` 协议要求实现 `get_capabilities() -> BrokerCapability`,
64
+ 通常返回一个模块级的 `default_capability()` 单例:
65
+
66
+ ```python
67
+ def default_capability() -> BrokerCapability:
68
+ return BrokerCapability(
69
+ broker_name="mybroker",
70
+ broker_extra_fields=("account_id", "order_style"),
71
+ features=frozenset({"supports_stop_limit"}),
72
+ )
73
+ ```
74
+
75
+ ## 3. 继承 `TraderGatewayBase`
76
+
77
+ `from akquant.gateway.trader_base import TraderGatewayBase` 提供了所有
78
+ broker 共享的管件:回调注册、id 反查表、以及默认的
79
+ `heartbeat`/`sync_open_orders`/`sync_today_trades` 实现。子类只需要实现
80
+ `TraderGateway` 协议中还缺的部分:
81
+
82
+ 必须实现:
83
+
84
+ - `connect()` / `disconnect()` / `start()` —— 生命周期
85
+ - `place_order(req) -> str` / `cancel_order(broker_order_id)`
86
+ - `query_order(broker_order_id)` / `query_trades(since=None)`
87
+ - `query_account()` / `query_positions()`
88
+ - `get_capabilities() -> BrokerCapability`
89
+
90
+ 基类已提供、通常不需要重写:
91
+
92
+ - 回调注册:`on_order` / `on_trade` / `on_execution_report`
93
+ - id 反查:`record_broker_order(broker_order_id, client_order_id)` /
94
+ `client_order_id_for(broker_order_id)`
95
+ - 分发:`_emit_order` / `_emit_trade` / `_emit_exec_from_order`
96
+ - 默认实现:`heartbeat()`(恒真)、`sync_open_orders()` /
97
+ `sync_today_trades()`(空列表)—— 如果 broker 支持断线补齐,覆盖这两个
98
+ 方法即可。
99
+
100
+ ## 4. `place_order` 里的路由与 id 映射
101
+
102
+ `UnifiedOrderRequest` 里的 `asset_type` 用来在 `place_order` 内部路由到不同
103
+ 品种的下单通道(例如证券 vs 期货);`extra: dict[str, Any]` 携带的是
104
+ `BrokerCapability.broker_extra_fields` 里声明过的柜台专属字段,直接从
105
+ `req.extra` 取值即可(上层已按声明集合校验过,未声明的 key 不会出现)。
106
+
107
+ 下单成功后,用 `self.record_broker_order(broker_order_id, req.client_order_id)`
108
+ 记录柜台委托号到策略 `client_order_id` 的映射;收到委托/成交回报时,用
109
+ `self.client_order_id_for(broker_order_id)` 反查回 `client_order_id`,再拼成
110
+ 统一模型对象经 `self._emit_order(...)` / `self._emit_trade(...)` /
111
+ `self._emit_exec_from_order(...)` 分发给策略层回调。
112
+
113
+ ## 5. 纯交易 broker:行情走现有 feed
114
+
115
+ 如果新 broker 只做交易、不提供行情(多数国内前置机/柜台都是这种情况),
116
+ builder 返回的 `GatewayBundle` 里 `market_gateway=None` 即可,行情继续由
117
+ akquant 现有的 `DataFeed` 提供:
118
+
119
+ ```python
120
+ return GatewayBundle(
121
+ market_gateway=None,
122
+ trader_gateway=trader_gateway,
123
+ trader_capabilities=trader_gateway.get_capabilities(),
124
+ metadata={"broker": "mybroker"},
125
+ )
126
+ ```
127
+
128
+ ## 最小骨架
129
+
130
+ ```python
131
+ from __future__ import annotations
132
+
133
+ from typing import Any, Sequence
134
+
135
+ from akquant import DataFeed
136
+ from akquant.gateway import register_broker
137
+ from akquant.gateway.broker_models import (
138
+ BrokerCapability,
139
+ UnifiedAccount,
140
+ UnifiedOrderRequest,
141
+ UnifiedOrderSnapshot,
142
+ UnifiedPosition,
143
+ UnifiedTrade,
144
+ )
145
+ from akquant.gateway.protocols import GatewayBundle
146
+ from akquant.gateway.trader_base import TraderGatewayBase
147
+
148
+
149
+ def default_capability() -> BrokerCapability:
150
+ return BrokerCapability(
151
+ broker_name="mybroker",
152
+ broker_extra_fields=("account_id",),
153
+ features=frozenset(),
154
+ )
155
+
156
+
157
+ class MyTraderGateway(TraderGatewayBase):
158
+ """最小可运行的 TraderGateway 骨架。"""
159
+
160
+ def __init__(self, capability: BrokerCapability | None = None) -> None:
161
+ super().__init__()
162
+ self._capability = capability or default_capability()
163
+
164
+ def connect(self) -> None:
165
+ ... # 登录/建立会话
166
+
167
+ def disconnect(self) -> None:
168
+ ... # 释放连接
169
+
170
+ def start(self) -> None:
171
+ ... # 建立推送长连、开始分发回报
172
+
173
+ def get_capabilities(self) -> BrokerCapability:
174
+ return self._capability
175
+
176
+ def place_order(self, req: UnifiedOrderRequest) -> str:
177
+ # 按 req.asset_type 路由品种;req.extra 取柜台专属字段。
178
+ account_id = req.extra.get("account_id")
179
+ broker_order_id = self._send_order_to_broker(req, account_id)
180
+ if broker_order_id:
181
+ self.record_broker_order(broker_order_id, req.client_order_id)
182
+ return broker_order_id
183
+
184
+ def cancel_order(self, broker_order_id: str) -> None:
185
+ ... # 调用柜台撤单接口
186
+
187
+ def query_order(self, broker_order_id: str) -> UnifiedOrderSnapshot | None:
188
+ ... # 查询单笔委托并转换为 UnifiedOrderSnapshot
189
+
190
+ def query_trades(self, since: int | None = None) -> list[UnifiedTrade]:
191
+ ... # 查询成交并转换为 UnifiedTrade 列表
192
+
193
+ def query_account(self) -> UnifiedAccount | None:
194
+ ... # 查询资金账户
195
+
196
+ def query_positions(self) -> list[UnifiedPosition]:
197
+ ... # 查询持仓
198
+
199
+ def _on_broker_push(self, event: str, data: dict[str, Any]) -> None:
200
+ # 收到推送后:反查 client_order_id,再分发给策略层回调。
201
+ broker_order_id = str(data.get("order_id", ""))
202
+ client_order_id = self.client_order_id_for(broker_order_id)
203
+ if event == "order_update":
204
+ snapshot = self._parse_order(data, client_order_id)
205
+ self._emit_order(snapshot)
206
+ self._emit_exec_from_order(snapshot)
207
+ elif event == "trade_update":
208
+ self._emit_trade(self._parse_trade(data, client_order_id))
209
+
210
+ def _send_order_to_broker(
211
+ self, req: UnifiedOrderRequest, account_id: Any
212
+ ) -> str:
213
+ raise NotImplementedError
214
+
215
+ def _parse_order(
216
+ self, data: dict[str, Any], client_order_id: str
217
+ ) -> UnifiedOrderSnapshot:
218
+ raise NotImplementedError
219
+
220
+ def _parse_trade(self, data: dict[str, Any], client_order_id: str) -> UnifiedTrade:
221
+ raise NotImplementedError
222
+
223
+
224
+ def build_mybroker(
225
+ feed: DataFeed, symbols: Sequence[str], use_aggregator: bool, **kwargs: Any
226
+ ) -> GatewayBundle:
227
+ _ = (feed, symbols, use_aggregator)
228
+ trader_gateway = MyTraderGateway()
229
+ return GatewayBundle(
230
+ market_gateway=None, # 纯交易 broker:行情走 akquant 现有 feed
231
+ trader_gateway=trader_gateway,
232
+ trader_capabilities=trader_gateway.get_capabilities(),
233
+ metadata={"broker": "mybroker"},
234
+ )
235
+
236
+
237
+ register_broker("mybroker", build_mybroker)
238
+ ```
239
+
240
+ ## 参考实现与相关文档
241
+
242
+ - [自定义 Broker 注册](custom_broker_registry.md) —— `register_broker` /
243
+ `create_gateway_bundle` 等注册 API 的详细说明。
244
+ - [Broker Capability Matrix](broker_capability_matrix.md) —— 各内置 broker
245
+ 的能力矩阵与统一错误规范,声明 `BrokerCapability` 前建议先对照。
@@ -45,7 +45,7 @@ def initialize(ctx):
45
45
  ctx.sent = False
46
46
 
47
47
  def on_bar(ctx, bar):
48
- if not ctx.sent and hasattr(ctx, "submit_order"):
48
+ if not ctx.sent and getattr(ctx, "broker_ready", False):
49
49
  ctx.submit_order(
50
50
  symbol=bar.symbol,
51
51
  side="Buy",
@@ -72,9 +72,10 @@ runner.run(duration="30s", show_progress=False)
72
72
 
73
73
  ## 4. 常见排查
74
74
 
75
- - `submit_order 尚未注入`
76
- - 原因:网关尚未完成交易侧绑定。
77
- - 处理:在 `on_bar` `hasattr(ctx, "submit_order")` 判定后再下单。
75
+ - `submit_order` 尚未就绪
76
+ - 原因:交易网关尚未完成连接/登录。
77
+ - 处理:在 `on_bar` 中用 `if getattr(ctx, "broker_ready", False):` 门首单
78
+ (broker 就绪由 LiveRunner 的 heartbeat 轮询裁定;就绪前调用会抛清晰错误)。
78
79
  - `duplicate active client_order_id`
79
80
  - 原因:重复提交活跃 client id。
80
81
  - 处理:每次下单生成新的 `client_order_id`。