akquant 0.2.32__tar.gz → 0.2.34__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 (467) hide show
  1. {akquant-0.2.32 → akquant-0.2.34}/.gitignore +1 -0
  2. {akquant-0.2.32 → akquant-0.2.34}/Cargo.lock +1 -1
  3. {akquant-0.2.32 → akquant-0.2.34}/Cargo.toml +1 -1
  4. {akquant-0.2.32 → akquant-0.2.34}/PKG-INFO +1 -1
  5. {akquant-0.2.32 → akquant-0.2.34}/docs/en/guide/custom_indicator.md +222 -0
  6. {akquant-0.2.32 → akquant-0.2.34}/docs/zh/guide/custom_indicator.md +220 -0
  7. akquant-0.2.34/examples/61_indicator_visualization_export_demo.py +91 -0
  8. akquant-0.2.34/examples/62_indicator_streaming_demo.py +153 -0
  9. akquant-0.2.34/examples/63_indicator_ws_bridge_demo.py +103 -0
  10. akquant-0.2.34/examples/64_indicator_live_web.py +472 -0
  11. {akquant-0.2.32 → akquant-0.2.34}/pyproject.toml +1 -1
  12. {akquant-0.2.32 → akquant-0.2.34}/python/akquant/__init__.py +14 -1
  13. {akquant-0.2.32 → akquant-0.2.34}/python/akquant/akquant.pyi +68 -0
  14. {akquant-0.2.32 → akquant-0.2.34}/python/akquant/backtest/engine.py +135 -9
  15. {akquant-0.2.32 → akquant-0.2.34}/python/akquant/backtest/result.py +198 -0
  16. akquant-0.2.34/python/akquant/indicator_recording.py +225 -0
  17. akquant-0.2.34/python/akquant/indicator_stream.py +148 -0
  18. {akquant-0.2.32 → akquant-0.2.34}/python/akquant/plot/__init__.py +2 -0
  19. akquant-0.2.34/python/akquant/plot/indicator.py +193 -0
  20. {akquant-0.2.32 → akquant-0.2.34}/python/akquant/plot/report.py +118 -0
  21. {akquant-0.2.32 → akquant-0.2.34}/python/akquant/strategy.py +66 -0
  22. {akquant-0.2.32 → akquant-0.2.34}/python/akquant/strategy_events.py +14 -0
  23. {akquant-0.2.32 → akquant-0.2.34}/src/engine/core.rs +15 -0
  24. {akquant-0.2.32 → akquant-0.2.34}/src/engine/python.rs +23 -3
  25. {akquant-0.2.32 → akquant-0.2.34}/src/order_manager.rs +3 -1
  26. {akquant-0.2.32 → akquant-0.2.34}/src/pipeline/stages.rs +14 -0
  27. {akquant-0.2.32 → akquant-0.2.34}/src/settlement/manager.rs +211 -87
  28. {akquant-0.2.32 → akquant-0.2.34}/tests/test_account_risk_rules.py +209 -0
  29. akquant-0.2.34/tests/test_indicator_live_web_example.py +92 -0
  30. akquant-0.2.34/tests/test_indicator_recording.py +415 -0
  31. {akquant-0.2.32 → akquant-0.2.34}/tests/test_report_plot_extensions.py +138 -0
  32. {akquant-0.2.32 → akquant-0.2.34}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
  33. {akquant-0.2.32 → akquant-0.2.34}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  34. {akquant-0.2.32 → akquant-0.2.34}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
  35. {akquant-0.2.32 → akquant-0.2.34}/.github/workflows/deploy-docs.yml +0 -0
  36. {akquant-0.2.32 → akquant-0.2.34}/.github/workflows/docs-quality.yml +0 -0
  37. {akquant-0.2.32 → akquant-0.2.34}/.github/workflows/release.yml +0 -0
  38. {akquant-0.2.32 → akquant-0.2.34}/.pre-commit-config.yaml +0 -0
  39. {akquant-0.2.32 → akquant-0.2.34}/CHANGELOG.md +0 -0
  40. {akquant-0.2.32 → akquant-0.2.34}/CODE_OF_CONDUCT.md +0 -0
  41. {akquant-0.2.32 → akquant-0.2.34}/CONTRIBUTING.md +0 -0
  42. {akquant-0.2.32 → akquant-0.2.34}/LICENSE +0 -0
  43. {akquant-0.2.32 → akquant-0.2.34}/README.md +0 -0
  44. {akquant-0.2.32 → akquant-0.2.34}/assets/dashboard_preview.png +0 -0
  45. {akquant-0.2.32 → akquant-0.2.34}/assets/logo.svg +0 -0
  46. {akquant-0.2.32 → akquant-0.2.34}/assets/social_preview.png +0 -0
  47. {akquant-0.2.32 → akquant-0.2.34}/docs/CNAME +0 -0
  48. {akquant-0.2.32 → akquant-0.2.34}/docs/assets/akquant-icon.svg +0 -0
  49. {akquant-0.2.32 → akquant-0.2.34}/docs/assets/akquant-logo.svg +0 -0
  50. {akquant-0.2.32 → akquant-0.2.34}/docs/assets/reports/akquant_report.html +0 -0
  51. {akquant-0.2.32 → akquant-0.2.34}/docs/en/advanced/analyzer_plugin_spec.md +0 -0
  52. {akquant-0.2.32 → akquant-0.2.34}/docs/en/advanced/broker_capability_matrix.md +0 -0
  53. {akquant-0.2.32 → akquant-0.2.34}/docs/en/advanced/custom_broker_production_checklist.md +0 -0
  54. {akquant-0.2.32 → akquant-0.2.34}/docs/en/advanced/custom_broker_registry.md +0 -0
  55. {akquant-0.2.32 → akquant-0.2.34}/docs/en/advanced/data_feed_adapter_spec.md +0 -0
  56. {akquant-0.2.32 → akquant-0.2.34}/docs/en/advanced/live_functional_quickstart.md +0 -0
  57. {akquant-0.2.32 → akquant-0.2.34}/docs/en/advanced/llm.md +0 -0
  58. {akquant-0.2.32 → akquant-0.2.34}/docs/en/advanced/ml.md +0 -0
  59. {akquant-0.2.32 → akquant-0.2.34}/docs/en/advanced/multi_strategy_guide.md +0 -0
  60. {akquant-0.2.32 → akquant-0.2.34}/docs/en/advanced/multi_timeframe_feed_api.md +0 -0
  61. {akquant-0.2.32 → akquant-0.2.34}/docs/en/advanced/runtime_config.md +0 -0
  62. {akquant-0.2.32 → akquant-0.2.34}/docs/en/advanced/strategy_style_decision.md +0 -0
  63. {akquant-0.2.32 → akquant-0.2.34}/docs/en/advanced/timezone.md +0 -0
  64. {akquant-0.2.32 → akquant-0.2.34}/docs/en/advanced/warm_start.md +0 -0
  65. {akquant-0.2.32 → akquant-0.2.34}/docs/en/guide/analysis.md +0 -0
  66. {akquant-0.2.32 → akquant-0.2.34}/docs/en/guide/cross_section_checklist.md +0 -0
  67. {akquant-0.2.32 → akquant-0.2.34}/docs/en/guide/data.md +0 -0
  68. {akquant-0.2.32 → akquant-0.2.34}/docs/en/guide/examples.md +0 -0
  69. {akquant-0.2.32 → akquant-0.2.34}/docs/en/guide/factor.md +0 -0
  70. {akquant-0.2.32 → akquant-0.2.34}/docs/en/guide/indicator_scenario_quickref.md +0 -0
  71. {akquant-0.2.32 → akquant-0.2.34}/docs/en/guide/optimization.md +0 -0
  72. {akquant-0.2.32 → akquant-0.2.34}/docs/en/guide/python_basics.md +0 -0
  73. {akquant-0.2.32 → akquant-0.2.34}/docs/en/guide/quant_basics.md +0 -0
  74. {akquant-0.2.32 → akquant-0.2.34}/docs/en/guide/rust_indicator_reference.md +0 -0
  75. {akquant-0.2.32 → akquant-0.2.34}/docs/en/guide/strategy.md +0 -0
  76. {akquant-0.2.32 → akquant-0.2.34}/docs/en/guide/talib_indicator_playbook.md +0 -0
  77. {akquant-0.2.32 → akquant-0.2.34}/docs/en/guide/testing.md +0 -0
  78. {akquant-0.2.32 → akquant-0.2.34}/docs/en/guide/visualization.md +0 -0
  79. {akquant-0.2.32 → akquant-0.2.34}/docs/en/index.md +0 -0
  80. {akquant-0.2.32 → akquant-0.2.34}/docs/en/meta/architecture.md +0 -0
  81. {akquant-0.2.32 → akquant-0.2.34}/docs/en/meta/internals.md +0 -0
  82. {akquant-0.2.32 → akquant-0.2.34}/docs/en/reference/api.md +0 -0
  83. {akquant-0.2.32 → akquant-0.2.34}/docs/en/start/first_strategy.md +0 -0
  84. {akquant-0.2.32 → akquant-0.2.34}/docs/en/start/installation.md +0 -0
  85. {akquant-0.2.32 → akquant-0.2.34}/docs/en/start/quickstart.md +0 -0
  86. {akquant-0.2.32 → akquant-0.2.34}/docs/en/start/setup_guide.md +0 -0
  87. {akquant-0.2.32 → akquant-0.2.34}/docs/en/textbook/01_foundations.md +0 -0
  88. {akquant-0.2.32 → akquant-0.2.34}/docs/en/textbook/02_programming.md +0 -0
  89. {akquant-0.2.32 → akquant-0.2.34}/docs/en/textbook/03_data.md +0 -0
  90. {akquant-0.2.32 → akquant-0.2.34}/docs/en/textbook/04_backtest_engine.md +0 -0
  91. {akquant-0.2.32 → akquant-0.2.34}/docs/en/textbook/05_strategy.md +0 -0
  92. {akquant-0.2.32 → akquant-0.2.34}/docs/en/textbook/06_stock_a.md +0 -0
  93. {akquant-0.2.32 → akquant-0.2.34}/docs/en/textbook/07_futures.md +0 -0
  94. {akquant-0.2.32 → akquant-0.2.34}/docs/en/textbook/08_options.md +0 -0
  95. {akquant-0.2.32 → akquant-0.2.34}/docs/en/textbook/09_funds.md +0 -0
  96. {akquant-0.2.32 → akquant-0.2.34}/docs/en/textbook/10_analysis.md +0 -0
  97. {akquant-0.2.32 → akquant-0.2.34}/docs/en/textbook/11_optimization.md +0 -0
  98. {akquant-0.2.32 → akquant-0.2.34}/docs/en/textbook/12_ml.md +0 -0
  99. {akquant-0.2.32 → akquant-0.2.34}/docs/en/textbook/13_visualization.md +0 -0
  100. {akquant-0.2.32 → akquant-0.2.34}/docs/en/textbook/14_factor.md +0 -0
  101. {akquant-0.2.32 → akquant-0.2.34}/docs/en/textbook/15_live_trading.md +0 -0
  102. {akquant-0.2.32 → akquant-0.2.34}/docs/en/textbook/16_rust_indicators.md +0 -0
  103. {akquant-0.2.32 → akquant-0.2.34}/docs/en/textbook/index.md +0 -0
  104. {akquant-0.2.32 → akquant-0.2.34}/docs/javascripts/mathjax.js +0 -0
  105. {akquant-0.2.32 → akquant-0.2.34}/docs/javascripts/search-lang-filter.js +0 -0
  106. {akquant-0.2.32 → akquant-0.2.34}/docs/robots.txt +0 -0
  107. {akquant-0.2.32 → akquant-0.2.34}/docs/zh/advanced/analyzer_plugin_spec.md +0 -0
  108. {akquant-0.2.32 → akquant-0.2.34}/docs/zh/advanced/broker_capability_matrix.md +0 -0
  109. {akquant-0.2.32 → akquant-0.2.34}/docs/zh/advanced/custom_broker_production_checklist.md +0 -0
  110. {akquant-0.2.32 → akquant-0.2.34}/docs/zh/advanced/custom_broker_registry.md +0 -0
  111. {akquant-0.2.32 → akquant-0.2.34}/docs/zh/advanced/data_feed_adapter_spec.md +0 -0
  112. {akquant-0.2.32 → akquant-0.2.34}/docs/zh/advanced/live_functional_quickstart.md +0 -0
  113. {akquant-0.2.32 → akquant-0.2.34}/docs/zh/advanced/llm.md +0 -0
  114. {akquant-0.2.32 → akquant-0.2.34}/docs/zh/advanced/ml.md +0 -0
  115. {akquant-0.2.32 → akquant-0.2.34}/docs/zh/advanced/multi_strategy_guide.md +0 -0
  116. {akquant-0.2.32 → akquant-0.2.34}/docs/zh/advanced/multi_timeframe_feed_api.md +0 -0
  117. {akquant-0.2.32 → akquant-0.2.34}/docs/zh/advanced/runtime_config.md +0 -0
  118. {akquant-0.2.32 → akquant-0.2.34}/docs/zh/advanced/strategy_style_decision.md +0 -0
  119. {akquant-0.2.32 → akquant-0.2.34}/docs/zh/advanced/timezone.md +0 -0
  120. {akquant-0.2.32 → akquant-0.2.34}/docs/zh/advanced/warm_start.md +0 -0
  121. {akquant-0.2.32 → akquant-0.2.34}/docs/zh/guide/analysis.md +0 -0
  122. {akquant-0.2.32 → akquant-0.2.34}/docs/zh/guide/cross_section_checklist.md +0 -0
  123. {akquant-0.2.32 → akquant-0.2.34}/docs/zh/guide/data.md +0 -0
  124. {akquant-0.2.32 → akquant-0.2.34}/docs/zh/guide/examples.md +0 -0
  125. {akquant-0.2.32 → akquant-0.2.34}/docs/zh/guide/factor.md +0 -0
  126. {akquant-0.2.32 → akquant-0.2.34}/docs/zh/guide/indicator_scenario_quickref.md +0 -0
  127. {akquant-0.2.32 → akquant-0.2.34}/docs/zh/guide/optimization.md +0 -0
  128. {akquant-0.2.32 → akquant-0.2.34}/docs/zh/guide/python_basics.md +0 -0
  129. {akquant-0.2.32 → akquant-0.2.34}/docs/zh/guide/quant_basics.md +0 -0
  130. {akquant-0.2.32 → akquant-0.2.34}/docs/zh/guide/rust_indicator_reference.md +0 -0
  131. {akquant-0.2.32 → akquant-0.2.34}/docs/zh/guide/strategy.md +0 -0
  132. {akquant-0.2.32 → akquant-0.2.34}/docs/zh/guide/talib_indicator_playbook.md +0 -0
  133. {akquant-0.2.32 → akquant-0.2.34}/docs/zh/guide/testing.md +0 -0
  134. {akquant-0.2.32 → akquant-0.2.34}/docs/zh/guide/visualization.md +0 -0
  135. {akquant-0.2.32 → akquant-0.2.34}/docs/zh/index.md +0 -0
  136. {akquant-0.2.32 → akquant-0.2.34}/docs/zh/meta/architecture.md +0 -0
  137. {akquant-0.2.32 → akquant-0.2.34}/docs/zh/meta/internals.md +0 -0
  138. {akquant-0.2.32 → akquant-0.2.34}/docs/zh/reference/api.md +0 -0
  139. {akquant-0.2.32 → akquant-0.2.34}/docs/zh/start/first_strategy.md +0 -0
  140. {akquant-0.2.32 → akquant-0.2.34}/docs/zh/start/installation.md +0 -0
  141. {akquant-0.2.32 → akquant-0.2.34}/docs/zh/start/quickstart.md +0 -0
  142. {akquant-0.2.32 → akquant-0.2.34}/docs/zh/start/setup_guide.md +0 -0
  143. {akquant-0.2.32 → akquant-0.2.34}/docs/zh/textbook/01_foundations.md +0 -0
  144. {akquant-0.2.32 → akquant-0.2.34}/docs/zh/textbook/02_programming.md +0 -0
  145. {akquant-0.2.32 → akquant-0.2.34}/docs/zh/textbook/03_data.md +0 -0
  146. {akquant-0.2.32 → akquant-0.2.34}/docs/zh/textbook/04_backtest_engine.md +0 -0
  147. {akquant-0.2.32 → akquant-0.2.34}/docs/zh/textbook/05_strategy.md +0 -0
  148. {akquant-0.2.32 → akquant-0.2.34}/docs/zh/textbook/06_stock_a.md +0 -0
  149. {akquant-0.2.32 → akquant-0.2.34}/docs/zh/textbook/07_futures.md +0 -0
  150. {akquant-0.2.32 → akquant-0.2.34}/docs/zh/textbook/08_options.md +0 -0
  151. {akquant-0.2.32 → akquant-0.2.34}/docs/zh/textbook/09_funds.md +0 -0
  152. {akquant-0.2.32 → akquant-0.2.34}/docs/zh/textbook/10_analysis.md +0 -0
  153. {akquant-0.2.32 → akquant-0.2.34}/docs/zh/textbook/11_optimization.md +0 -0
  154. {akquant-0.2.32 → akquant-0.2.34}/docs/zh/textbook/12_ml.md +0 -0
  155. {akquant-0.2.32 → akquant-0.2.34}/docs/zh/textbook/13_visualization.md +0 -0
  156. {akquant-0.2.32 → akquant-0.2.34}/docs/zh/textbook/14_factor.md +0 -0
  157. {akquant-0.2.32 → akquant-0.2.34}/docs/zh/textbook/15_live_trading.md +0 -0
  158. {akquant-0.2.32 → akquant-0.2.34}/docs/zh/textbook/16_rust_indicators.md +0 -0
  159. {akquant-0.2.32 → akquant-0.2.34}/docs/zh/textbook/index.md +0 -0
  160. {akquant-0.2.32 → akquant-0.2.34}/examples/01_quickstart.py +0 -0
  161. {akquant-0.2.32 → akquant-0.2.34}/examples/02_parameter_optimization.py +0 -0
  162. {akquant-0.2.32 → akquant-0.2.34}/examples/03_parameter_optimization_advanced.py +0 -0
  163. {akquant-0.2.32 → akquant-0.2.34}/examples/04_mixed_assets.py +0 -0
  164. {akquant-0.2.32 → akquant-0.2.34}/examples/05_live_trading_ctp.py +0 -0
  165. {akquant-0.2.32 → akquant-0.2.34}/examples/06_complex_orders.py +0 -0
  166. {akquant-0.2.32 → akquant-0.2.34}/examples/07_option_test.py +0 -0
  167. {akquant-0.2.32 → akquant-0.2.34}/examples/08_event_callbacks.py +0 -0
  168. {akquant-0.2.32 → akquant-0.2.34}/examples/09_ml_framework.py +0 -0
  169. {akquant-0.2.32 → akquant-0.2.34}/examples/10_ml_walk_forward.py +0 -0
  170. {akquant-0.2.32 → akquant-0.2.34}/examples/11_plot_visualization.py +0 -0
  171. {akquant-0.2.32 → akquant-0.2.34}/examples/12_wfo_integrated.py +0 -0
  172. {akquant-0.2.32 → akquant-0.2.34}/examples/13_quantstats_report.py +0 -0
  173. {akquant-0.2.32 → akquant-0.2.34}/examples/14_multi_frequency.py +0 -0
  174. {akquant-0.2.32 → akquant-0.2.34}/examples/15_plot_intraday.py +0 -0
  175. {akquant-0.2.32 → akquant-0.2.34}/examples/16_adj_returns_signal.py +0 -0
  176. {akquant-0.2.32 → akquant-0.2.34}/examples/17_readme_demo.py +0 -0
  177. {akquant-0.2.32 → akquant-0.2.34}/examples/18_benchmark_multisymbol.py +0 -0
  178. {akquant-0.2.32 → akquant-0.2.34}/examples/19_factor_expression.py +0 -0
  179. {akquant-0.2.32 → akquant-0.2.34}/examples/20_risk_management_demo.py +0 -0
  180. {akquant-0.2.32 → akquant-0.2.34}/examples/21_warm_start_demo.py +0 -0
  181. {akquant-0.2.32 → akquant-0.2.34}/examples/22_strategy_runtime_config_demo.py +0 -0
  182. {akquant-0.2.32 → akquant-0.2.34}/examples/23_functional_callbacks_demo.py +0 -0
  183. {akquant-0.2.32 → akquant-0.2.34}/examples/24_functional_tick_simulation_demo.py +0 -0
  184. {akquant-0.2.32 → akquant-0.2.34}/examples/25_streaming_backtest_demo.py +0 -0
  185. {akquant-0.2.32 → akquant-0.2.34}/examples/26_streaming_quickstart.py +0 -0
  186. {akquant-0.2.32 → akquant-0.2.34}/examples/27_streaming_monitoring_console.py +0 -0
  187. {akquant-0.2.32 → akquant-0.2.34}/examples/28_streaming_alerts_and_persist.py +0 -0
  188. {akquant-0.2.32 → akquant-0.2.34}/examples/29_streaming_event_report.py +0 -0
  189. {akquant-0.2.32 → akquant-0.2.34}/examples/30_streaming_report_oneclick.py +0 -0
  190. {akquant-0.2.32 → akquant-0.2.34}/examples/31_streaming_live_console.py +0 -0
  191. {akquant-0.2.32 → akquant-0.2.34}/examples/32_streaming_live_web.py +0 -0
  192. {akquant-0.2.32 → akquant-0.2.34}/examples/33_report_and_analysis_outputs.py +0 -0
  193. {akquant-0.2.32 → akquant-0.2.34}/examples/34_multi_strategy_demo.py +0 -0
  194. {akquant-0.2.32 → akquant-0.2.34}/examples/35_custom_broker_registry_demo.py +0 -0
  195. {akquant-0.2.32 → akquant-0.2.34}/examples/36_trailing_orders.py +0 -0
  196. {akquant-0.2.32 → akquant-0.2.34}/examples/37_feed_replay_alignment_demo.py +0 -0
  197. {akquant-0.2.32 → akquant-0.2.34}/examples/38_live_functional_strategy_demo.py +0 -0
  198. {akquant-0.2.32 → akquant-0.2.34}/examples/39_live_broker_submit_order_demo.py +0 -0
  199. {akquant-0.2.32 → akquant-0.2.34}/examples/40_functional_multi_slot_risk_demo.py +0 -0
  200. {akquant-0.2.32 → akquant-0.2.34}/examples/41_live_multi_slot_orchestration_demo.py +0 -0
  201. {akquant-0.2.32 → akquant-0.2.34}/examples/42_live_broker_event_audit_demo.py +0 -0
  202. {akquant-0.2.32 → akquant-0.2.34}/examples/43_target_weights_rebalance.py +0 -0
  203. {akquant-0.2.32 → akquant-0.2.34}/examples/44_strategy_source_loader_demo.py +0 -0
  204. {akquant-0.2.32 → akquant-0.2.34}/examples/45_talib_indicator_playbook_demo.py +0 -0
  205. {akquant-0.2.32 → akquant-0.2.34}/examples/46_broker_profile_demo.py +0 -0
  206. {akquant-0.2.32 → akquant-0.2.34}/examples/47_margin_liquidation_audit_demo.py +0 -0
  207. {akquant-0.2.32 → akquant-0.2.34}/examples/48_margin_liquidation_priority_compare.py +0 -0
  208. {akquant-0.2.32 → akquant-0.2.34}/examples/49_on_expiry_demo.py +0 -0
  209. {akquant-0.2.32 → akquant-0.2.34}/examples/50_framework_hooks_demo.py +0 -0
  210. {akquant-0.2.32 → akquant-0.2.34}/examples/51_class_tick_callbacks_demo.py +0 -0
  211. {akquant-0.2.32 → akquant-0.2.34}/examples/52_pre_open_demo.py +0 -0
  212. {akquant-0.2.32 → akquant-0.2.34}/examples/53_timer_to_pre_open_demo.py +0 -0
  213. {akquant-0.2.32 → akquant-0.2.34}/examples/54_functional_pre_open_demo.py +0 -0
  214. {akquant-0.2.32 → akquant-0.2.34}/examples/55_functional_ml_walk_forward.py +0 -0
  215. {akquant-0.2.32 → akquant-0.2.34}/examples/56_functional_warm_start_demo.py +0 -0
  216. {akquant-0.2.32 → akquant-0.2.34}/examples/57_functional_multi_slot_warm_start_demo.py +0 -0
  217. {akquant-0.2.32 → akquant-0.2.34}/examples/58_incremental_bootstrap_demo.py +0 -0
  218. {akquant-0.2.32 → akquant-0.2.34}/examples/59_akshare_etf_rotation.py +0 -0
  219. {akquant-0.2.32 → akquant-0.2.34}/examples/60_custom_indicator_demo.py +0 -0
  220. {akquant-0.2.32 → akquant-0.2.34}/examples/README.md +0 -0
  221. {akquant-0.2.32 → akquant-0.2.34}/examples/benchmark_utils.py +0 -0
  222. {akquant-0.2.32 → akquant-0.2.34}/examples/pb_mock.py +0 -0
  223. {akquant-0.2.32 → akquant-0.2.34}/examples/strategies/01_stock_dual_moving_average.py +0 -0
  224. {akquant-0.2.32 → akquant-0.2.34}/examples/strategies/02_stock_grid_trading.py +0 -0
  225. {akquant-0.2.32 → akquant-0.2.34}/examples/strategies/03_stock_atr_breakout.py +0 -0
  226. {akquant-0.2.32 → akquant-0.2.34}/examples/strategies/04_stock_momentum_rotation.py +0 -0
  227. {akquant-0.2.32 → akquant-0.2.34}/examples/strategies/05_stock_momentum_rotation_timer.py +0 -0
  228. {akquant-0.2.32 → akquant-0.2.34}/examples/strategies/06_stock_momentum_rotation_bucket.py +0 -0
  229. {akquant-0.2.32 → akquant-0.2.34}/examples/strategies/07_stock_momentum_rotation_on_timer.py +0 -0
  230. {akquant-0.2.32 → akquant-0.2.34}/examples/strategies/08_target_positions_long_short.py +0 -0
  231. {akquant-0.2.32 → akquant-0.2.34}/examples/strategies/README.md +0 -0
  232. {akquant-0.2.32 → akquant-0.2.34}/examples/textbook/ch01_quickstart.py +0 -0
  233. {akquant-0.2.32 → akquant-0.2.34}/examples/textbook/ch02_programming.py +0 -0
  234. {akquant-0.2.32 → akquant-0.2.34}/examples/textbook/ch03_data.py +0 -0
  235. {akquant-0.2.32 → akquant-0.2.34}/examples/textbook/ch04_comparison.py +0 -0
  236. {akquant-0.2.32 → akquant-0.2.34}/examples/textbook/ch05_strategy.py +0 -0
  237. {akquant-0.2.32 → akquant-0.2.34}/examples/textbook/ch06_stock_a.py +0 -0
  238. {akquant-0.2.32 → akquant-0.2.34}/examples/textbook/ch07_futures.py +0 -0
  239. {akquant-0.2.32 → akquant-0.2.34}/examples/textbook/ch08_options.py +0 -0
  240. {akquant-0.2.32 → akquant-0.2.34}/examples/textbook/ch09_funds.py +0 -0
  241. {akquant-0.2.32 → akquant-0.2.34}/examples/textbook/ch09_portfolio.py +0 -0
  242. {akquant-0.2.32 → akquant-0.2.34}/examples/textbook/ch10_analysis.py +0 -0
  243. {akquant-0.2.32 → akquant-0.2.34}/examples/textbook/ch11_optimization.py +0 -0
  244. {akquant-0.2.32 → akquant-0.2.34}/examples/textbook/ch12_ml.py +0 -0
  245. {akquant-0.2.32 → akquant-0.2.34}/examples/textbook/ch13_visualization.py +0 -0
  246. {akquant-0.2.32 → akquant-0.2.34}/examples/textbook/ch14_factor.py +0 -0
  247. {akquant-0.2.32 → akquant-0.2.34}/examples/textbook/ch15_live_trading.py +0 -0
  248. {akquant-0.2.32 → akquant-0.2.34}/examples/textbook/ch15_strategy_loader.py +0 -0
  249. {akquant-0.2.32 → akquant-0.2.34}/mkdocs.yml +0 -0
  250. {akquant-0.2.32 → akquant-0.2.34}/python/akquant/analyzer_plugin.py +0 -0
  251. {akquant-0.2.32 → akquant-0.2.34}/python/akquant/backtest/__init__.py +0 -0
  252. {akquant-0.2.32 → akquant-0.2.34}/python/akquant/backtest/__init__.pyi +0 -0
  253. {akquant-0.2.32 → akquant-0.2.34}/python/akquant/checkpoint.py +0 -0
  254. {akquant-0.2.32 → akquant-0.2.34}/python/akquant/config.py +0 -0
  255. {akquant-0.2.32 → akquant-0.2.34}/python/akquant/data.py +0 -0
  256. {akquant-0.2.32 → akquant-0.2.34}/python/akquant/factor/__init__.py +0 -0
  257. {akquant-0.2.32 → akquant-0.2.34}/python/akquant/factor/engine.py +0 -0
  258. {akquant-0.2.32 → akquant-0.2.34}/python/akquant/factor/ops.py +0 -0
  259. {akquant-0.2.32 → akquant-0.2.34}/python/akquant/factor/parser.py +0 -0
  260. {akquant-0.2.32 → akquant-0.2.34}/python/akquant/feed_adapter.py +0 -0
  261. {akquant-0.2.32 → akquant-0.2.34}/python/akquant/fund/__init__.py +0 -0
  262. {akquant-0.2.32 → akquant-0.2.34}/python/akquant/futures/__init__.py +0 -0
  263. {akquant-0.2.32 → akquant-0.2.34}/python/akquant/gateway/__init__.py +0 -0
  264. {akquant-0.2.32 → akquant-0.2.34}/python/akquant/gateway/base.py +0 -0
  265. {akquant-0.2.32 → akquant-0.2.34}/python/akquant/gateway/ctp_adapter.py +0 -0
  266. {akquant-0.2.32 → akquant-0.2.34}/python/akquant/gateway/ctp_native.py +0 -0
  267. {akquant-0.2.32 → akquant-0.2.34}/python/akquant/gateway/factory.py +0 -0
  268. {akquant-0.2.32 → akquant-0.2.34}/python/akquant/gateway/mapper.py +0 -0
  269. {akquant-0.2.32 → akquant-0.2.34}/python/akquant/gateway/miniqmt.py +0 -0
  270. {akquant-0.2.32 → akquant-0.2.34}/python/akquant/gateway/models.py +0 -0
  271. {akquant-0.2.32 → akquant-0.2.34}/python/akquant/gateway/ptrade.py +0 -0
  272. {akquant-0.2.32 → akquant-0.2.34}/python/akquant/gateway/registry.py +0 -0
  273. {akquant-0.2.32 → akquant-0.2.34}/python/akquant/indicator.py +0 -0
  274. {akquant-0.2.32 → akquant-0.2.34}/python/akquant/live.py +0 -0
  275. {akquant-0.2.32 → akquant-0.2.34}/python/akquant/log.py +0 -0
  276. {akquant-0.2.32 → akquant-0.2.34}/python/akquant/ml/__init__.py +0 -0
  277. {akquant-0.2.32 → akquant-0.2.34}/python/akquant/ml/model.py +0 -0
  278. {akquant-0.2.32 → akquant-0.2.34}/python/akquant/optimize.py +0 -0
  279. {akquant-0.2.32 → akquant-0.2.34}/python/akquant/option/__init__.py +0 -0
  280. {akquant-0.2.32 → akquant-0.2.34}/python/akquant/params.py +0 -0
  281. {akquant-0.2.32 → akquant-0.2.34}/python/akquant/params_adapter.py +0 -0
  282. {akquant-0.2.32 → akquant-0.2.34}/python/akquant/plot/analysis.py +0 -0
  283. {akquant-0.2.32 → akquant-0.2.34}/python/akquant/plot/dashboard.py +0 -0
  284. {akquant-0.2.32 → akquant-0.2.34}/python/akquant/plot/strategy.py +0 -0
  285. {akquant-0.2.32 → akquant-0.2.34}/python/akquant/plot/utils.py +0 -0
  286. {akquant-0.2.32 → akquant-0.2.34}/python/akquant/py.typed +0 -0
  287. {akquant-0.2.32 → akquant-0.2.34}/python/akquant/risk.py +0 -0
  288. {akquant-0.2.32 → akquant-0.2.34}/python/akquant/sizer.py +0 -0
  289. {akquant-0.2.32 → akquant-0.2.34}/python/akquant/stock/__init__.py +0 -0
  290. {akquant-0.2.32 → akquant-0.2.34}/python/akquant/strategy_framework_hooks.py +0 -0
  291. {akquant-0.2.32 → akquant-0.2.34}/python/akquant/strategy_history.py +0 -0
  292. {akquant-0.2.32 → akquant-0.2.34}/python/akquant/strategy_loader.py +0 -0
  293. {akquant-0.2.32 → akquant-0.2.34}/python/akquant/strategy_logging.py +0 -0
  294. {akquant-0.2.32 → akquant-0.2.34}/python/akquant/strategy_ml.py +0 -0
  295. {akquant-0.2.32 → akquant-0.2.34}/python/akquant/strategy_order_events.py +0 -0
  296. {akquant-0.2.32 → akquant-0.2.34}/python/akquant/strategy_position.py +0 -0
  297. {akquant-0.2.32 → akquant-0.2.34}/python/akquant/strategy_scheduler.py +0 -0
  298. {akquant-0.2.32 → akquant-0.2.34}/python/akquant/strategy_time.py +0 -0
  299. {akquant-0.2.32 → akquant-0.2.34}/python/akquant/strategy_trading_api.py +0 -0
  300. {akquant-0.2.32 → akquant-0.2.34}/python/akquant/talib/__init__.py +0 -0
  301. {akquant-0.2.32 → akquant-0.2.34}/python/akquant/talib/backend.py +0 -0
  302. {akquant-0.2.32 → akquant-0.2.34}/python/akquant/talib/core.py +0 -0
  303. {akquant-0.2.32 → akquant-0.2.34}/python/akquant/talib/funcs.py +0 -0
  304. {akquant-0.2.32 → akquant-0.2.34}/python/akquant/utils/__init__.py +0 -0
  305. {akquant-0.2.32 → akquant-0.2.34}/python/akquant/utils/inspector.py +0 -0
  306. {akquant-0.2.32 → akquant-0.2.34}/requirements-dev.txt +0 -0
  307. {akquant-0.2.32 → akquant-0.2.34}/scripts/cargo-test.sh +0 -0
  308. {akquant-0.2.32 → akquant-0.2.34}/scripts/check_docs_api_examples.py +0 -0
  309. {akquant-0.2.32 → akquant-0.2.34}/scripts/check_docs_links.py +0 -0
  310. {akquant-0.2.32 → akquant-0.2.34}/scripts/dev-check.sh +0 -0
  311. {akquant-0.2.32 → akquant-0.2.34}/scripts/find_legacy_execution_policy_calls.py +0 -0
  312. {akquant-0.2.32 → akquant-0.2.34}/scripts/golden_baseline_report.py +0 -0
  313. {akquant-0.2.32 → akquant-0.2.34}/src/account.rs +0 -0
  314. {akquant-0.2.32 → akquant-0.2.34}/src/analysis/mod.rs +0 -0
  315. {akquant-0.2.32 → akquant-0.2.34}/src/analysis/python.rs +0 -0
  316. {akquant-0.2.32 → akquant-0.2.34}/src/analysis/result.rs +0 -0
  317. {akquant-0.2.32 → akquant-0.2.34}/src/analysis/tests.rs +0 -0
  318. {akquant-0.2.32 → akquant-0.2.34}/src/analysis/tracker.rs +0 -0
  319. {akquant-0.2.32 → akquant-0.2.34}/src/analysis/types.rs +0 -0
  320. {akquant-0.2.32 → akquant-0.2.34}/src/bin/stub_gen.rs +0 -0
  321. {akquant-0.2.32 → akquant-0.2.34}/src/clock.rs +0 -0
  322. {akquant-0.2.32 → akquant-0.2.34}/src/context.rs +0 -0
  323. {akquant-0.2.32 → akquant-0.2.34}/src/data/aggregator.rs +0 -0
  324. {akquant-0.2.32 → akquant-0.2.34}/src/data/batch.rs +0 -0
  325. {akquant-0.2.32 → akquant-0.2.34}/src/data/client.rs +0 -0
  326. {akquant-0.2.32 → akquant-0.2.34}/src/data/feed.rs +0 -0
  327. {akquant-0.2.32 → akquant-0.2.34}/src/data/mod.rs +0 -0
  328. {akquant-0.2.32 → akquant-0.2.34}/src/engine/mod.rs +0 -0
  329. {akquant-0.2.32 → akquant-0.2.34}/src/engine/state.rs +0 -0
  330. {akquant-0.2.32 → akquant-0.2.34}/src/error.rs +0 -0
  331. {akquant-0.2.32 → akquant-0.2.34}/src/event.rs +0 -0
  332. {akquant-0.2.32 → akquant-0.2.34}/src/event_manager.rs +0 -0
  333. {akquant-0.2.32 → akquant-0.2.34}/src/execution/common.rs +0 -0
  334. {akquant-0.2.32 → akquant-0.2.34}/src/execution/crypto.rs +0 -0
  335. {akquant-0.2.32 → akquant-0.2.34}/src/execution/forex.rs +0 -0
  336. {akquant-0.2.32 → akquant-0.2.34}/src/execution/futures.rs +0 -0
  337. {akquant-0.2.32 → akquant-0.2.34}/src/execution/matcher.rs +0 -0
  338. {akquant-0.2.32 → akquant-0.2.34}/src/execution/mod.rs +0 -0
  339. {akquant-0.2.32 → akquant-0.2.34}/src/execution/option.rs +0 -0
  340. {akquant-0.2.32 → akquant-0.2.34}/src/execution/python.rs +0 -0
  341. {akquant-0.2.32 → akquant-0.2.34}/src/execution/realtime.rs +0 -0
  342. {akquant-0.2.32 → akquant-0.2.34}/src/execution/simulated.rs +0 -0
  343. {akquant-0.2.32 → akquant-0.2.34}/src/execution/slippage.rs +0 -0
  344. {akquant-0.2.32 → akquant-0.2.34}/src/execution/stock.rs +0 -0
  345. {akquant-0.2.32 → akquant-0.2.34}/src/history.rs +0 -0
  346. {akquant-0.2.32 → akquant-0.2.34}/src/indicators/momentum.rs +0 -0
  347. {akquant-0.2.32 → akquant-0.2.34}/src/indicators/momentum_oscillators.rs +0 -0
  348. {akquant-0.2.32 → akquant-0.2.34}/src/indicators/momentum_rates.rs +0 -0
  349. {akquant-0.2.32 → akquant-0.2.34}/src/indicators/moving_average.rs +0 -0
  350. {akquant-0.2.32 → akquant-0.2.34}/src/indicators/moving_average_compound.rs +0 -0
  351. {akquant-0.2.32 → akquant-0.2.34}/src/indicators/moving_average_core.rs +0 -0
  352. {akquant-0.2.32 → akquant-0.2.34}/src/indicators/moving_average_transforms.rs +0 -0
  353. {akquant-0.2.32 → akquant-0.2.34}/src/indicators/moving_average_windowed.rs +0 -0
  354. {akquant-0.2.32 → akquant-0.2.34}/src/indicators/trend.rs +0 -0
  355. {akquant-0.2.32 → akquant-0.2.34}/src/indicators/trend_directional.rs +0 -0
  356. {akquant-0.2.32 → akquant-0.2.34}/src/indicators/trend_oscillators.rs +0 -0
  357. {akquant-0.2.32 → akquant-0.2.34}/src/indicators/trend_regression.rs +0 -0
  358. {akquant-0.2.32 → akquant-0.2.34}/src/indicators/volatility.rs +0 -0
  359. {akquant-0.2.32 → akquant-0.2.34}/src/indicators/volatility_price.rs +0 -0
  360. {akquant-0.2.32 → akquant-0.2.34}/src/indicators/volatility_stats.rs +0 -0
  361. {akquant-0.2.32 → akquant-0.2.34}/src/indicators/volume.rs +0 -0
  362. {akquant-0.2.32 → akquant-0.2.34}/src/indicators.rs +0 -0
  363. {akquant-0.2.32 → akquant-0.2.34}/src/lib.rs +0 -0
  364. {akquant-0.2.32 → akquant-0.2.34}/src/margin/calculator.rs +0 -0
  365. {akquant-0.2.32 → akquant-0.2.34}/src/margin/engine.rs +0 -0
  366. {akquant-0.2.32 → akquant-0.2.34}/src/margin/mod.rs +0 -0
  367. {akquant-0.2.32 → akquant-0.2.34}/src/market/china.rs +0 -0
  368. {akquant-0.2.32 → akquant-0.2.34}/src/market/core.rs +0 -0
  369. {akquant-0.2.32 → akquant-0.2.34}/src/market/corporate_action.rs +0 -0
  370. {akquant-0.2.32 → akquant-0.2.34}/src/market/fund.rs +0 -0
  371. {akquant-0.2.32 → akquant-0.2.34}/src/market/futures.rs +0 -0
  372. {akquant-0.2.32 → akquant-0.2.34}/src/market/manager.rs +0 -0
  373. {akquant-0.2.32 → akquant-0.2.34}/src/market/mod.rs +0 -0
  374. {akquant-0.2.32 → akquant-0.2.34}/src/market/option.rs +0 -0
  375. {akquant-0.2.32 → akquant-0.2.34}/src/market/simple.rs +0 -0
  376. {akquant-0.2.32 → akquant-0.2.34}/src/market/stock.rs +0 -0
  377. {akquant-0.2.32 → akquant-0.2.34}/src/model/corporate_action.rs +0 -0
  378. {akquant-0.2.32 → akquant-0.2.34}/src/model/instrument.rs +0 -0
  379. {akquant-0.2.32 → akquant-0.2.34}/src/model/market_data.rs +0 -0
  380. {akquant-0.2.32 → akquant-0.2.34}/src/model/mod.rs +0 -0
  381. {akquant-0.2.32 → akquant-0.2.34}/src/model/order.rs +0 -0
  382. {akquant-0.2.32 → akquant-0.2.34}/src/model/timer.rs +0 -0
  383. {akquant-0.2.32 → akquant-0.2.34}/src/model/types.rs +0 -0
  384. {akquant-0.2.32 → akquant-0.2.34}/src/pipeline/mod.rs +0 -0
  385. {akquant-0.2.32 → akquant-0.2.34}/src/pipeline/processor.rs +0 -0
  386. {akquant-0.2.32 → akquant-0.2.34}/src/pipeline/runner.rs +0 -0
  387. {akquant-0.2.32 → akquant-0.2.34}/src/portfolio.rs +0 -0
  388. {akquant-0.2.32 → akquant-0.2.34}/src/risk/common.rs +0 -0
  389. {akquant-0.2.32 → akquant-0.2.34}/src/risk/config.rs +0 -0
  390. {akquant-0.2.32 → akquant-0.2.34}/src/risk/futures.rs +0 -0
  391. {akquant-0.2.32 → akquant-0.2.34}/src/risk/manager.rs +0 -0
  392. {akquant-0.2.32 → akquant-0.2.34}/src/risk/mod.rs +0 -0
  393. {akquant-0.2.32 → akquant-0.2.34}/src/risk/option.rs +0 -0
  394. {akquant-0.2.32 → akquant-0.2.34}/src/risk/portfolio.rs +0 -0
  395. {akquant-0.2.32 → akquant-0.2.34}/src/risk/rule.rs +0 -0
  396. {akquant-0.2.32 → akquant-0.2.34}/src/risk/stock.rs +0 -0
  397. {akquant-0.2.32 → akquant-0.2.34}/src/settlement/expiry.rs +0 -0
  398. {akquant-0.2.32 → akquant-0.2.34}/src/settlement/handler.rs +0 -0
  399. {akquant-0.2.32 → akquant-0.2.34}/src/settlement/mod.rs +0 -0
  400. {akquant-0.2.32 → akquant-0.2.34}/src/settlement/option.rs +0 -0
  401. {akquant-0.2.32 → akquant-0.2.34}/src/statistics/mod.rs +0 -0
  402. {akquant-0.2.32 → akquant-0.2.34}/tests/golden/BASELINE_REPORT.md +0 -0
  403. {akquant-0.2.32 → akquant-0.2.34}/tests/golden/LEGACY_EXECUTION_CALLS.md +0 -0
  404. {akquant-0.2.32 → akquant-0.2.34}/tests/golden/baselines/futures_margin/equity_curve.parquet +0 -0
  405. {akquant-0.2.32 → akquant-0.2.34}/tests/golden/baselines/futures_margin/metrics.json +0 -0
  406. {akquant-0.2.32 → akquant-0.2.34}/tests/golden/baselines/futures_margin/orders.parquet +0 -0
  407. {akquant-0.2.32 → akquant-0.2.34}/tests/golden/baselines/option_basic/equity_curve.parquet +0 -0
  408. {akquant-0.2.32 → akquant-0.2.34}/tests/golden/baselines/option_basic/metrics.json +0 -0
  409. {akquant-0.2.32 → akquant-0.2.34}/tests/golden/baselines/option_basic/orders.parquet +0 -0
  410. {akquant-0.2.32 → akquant-0.2.34}/tests/golden/baselines/stock_t1/equity_curve.parquet +0 -0
  411. {akquant-0.2.32 → akquant-0.2.34}/tests/golden/baselines/stock_t1/metrics.json +0 -0
  412. {akquant-0.2.32 → akquant-0.2.34}/tests/golden/baselines/stock_t1/orders.parquet +0 -0
  413. {akquant-0.2.32 → akquant-0.2.34}/tests/golden/baselines/stock_t1/trades.parquet +0 -0
  414. {akquant-0.2.32 → akquant-0.2.34}/tests/golden/current/futures_margin/equity_curve.parquet +0 -0
  415. {akquant-0.2.32 → akquant-0.2.34}/tests/golden/current/futures_margin/metrics.json +0 -0
  416. {akquant-0.2.32 → akquant-0.2.34}/tests/golden/current/futures_margin/orders.parquet +0 -0
  417. {akquant-0.2.32 → akquant-0.2.34}/tests/golden/current/option_basic/equity_curve.parquet +0 -0
  418. {akquant-0.2.32 → akquant-0.2.34}/tests/golden/current/option_basic/metrics.json +0 -0
  419. {akquant-0.2.32 → akquant-0.2.34}/tests/golden/current/option_basic/orders.parquet +0 -0
  420. {akquant-0.2.32 → akquant-0.2.34}/tests/golden/current/stock_t1/equity_curve.parquet +0 -0
  421. {akquant-0.2.32 → akquant-0.2.34}/tests/golden/current/stock_t1/metrics.json +0 -0
  422. {akquant-0.2.32 → akquant-0.2.34}/tests/golden/current/stock_t1/orders.parquet +0 -0
  423. {akquant-0.2.32 → akquant-0.2.34}/tests/golden/current/stock_t1/trades.parquet +0 -0
  424. {akquant-0.2.32 → akquant-0.2.34}/tests/golden/data/future_margin.parquet +0 -0
  425. {akquant-0.2.32 → akquant-0.2.34}/tests/golden/data/future_margin.parquet.sha256 +0 -0
  426. {akquant-0.2.32 → akquant-0.2.34}/tests/golden/data/option_basic.parquet +0 -0
  427. {akquant-0.2.32 → akquant-0.2.34}/tests/golden/data/option_basic.parquet.sha256 +0 -0
  428. {akquant-0.2.32 → akquant-0.2.34}/tests/golden/data/stock_t1.parquet +0 -0
  429. {akquant-0.2.32 → akquant-0.2.34}/tests/golden/data/stock_t1.parquet.sha256 +0 -0
  430. {akquant-0.2.32 → akquant-0.2.34}/tests/golden/gen_data.py +0 -0
  431. {akquant-0.2.32 → akquant-0.2.34}/tests/golden/runner.py +0 -0
  432. {akquant-0.2.32 → akquant-0.2.34}/tests/golden/strategies/futures_margin.py +0 -0
  433. {akquant-0.2.32 → akquant-0.2.34}/tests/golden/strategies/option_basic.py +0 -0
  434. {akquant-0.2.32 → akquant-0.2.34}/tests/golden/strategies/stock_t1.py +0 -0
  435. {akquant-0.2.32 → akquant-0.2.34}/tests/golden/test_golden.py +0 -0
  436. {akquant-0.2.32 → akquant-0.2.34}/tests/test_custom_matcher.py +0 -0
  437. {akquant-0.2.32 → akquant-0.2.34}/tests/test_docs_api_examples.py +0 -0
  438. {akquant-0.2.32 → akquant-0.2.34}/tests/test_docs_links.py +0 -0
  439. {akquant-0.2.32 → akquant-0.2.34}/tests/test_engine.py +0 -0
  440. {akquant-0.2.32 → akquant-0.2.34}/tests/test_examples_regression.py +0 -0
  441. {akquant-0.2.32 → akquant-0.2.34}/tests/test_factor_engine.py +0 -0
  442. {akquant-0.2.32 → akquant-0.2.34}/tests/test_factor_ops.py +0 -0
  443. {akquant-0.2.32 → akquant-0.2.34}/tests/test_feed_adapter.py +0 -0
  444. {akquant-0.2.32 → akquant-0.2.34}/tests/test_gateway_callbacks.py +0 -0
  445. {akquant-0.2.32 → akquant-0.2.34}/tests/test_gateway_ctp_adapter.py +0 -0
  446. {akquant-0.2.32 → akquant-0.2.34}/tests/test_gateway_ctp_native.py +0 -0
  447. {akquant-0.2.32 → akquant-0.2.34}/tests/test_gateway_factory.py +0 -0
  448. {akquant-0.2.32 → akquant-0.2.34}/tests/test_gateway_mapper.py +0 -0
  449. {akquant-0.2.32 → akquant-0.2.34}/tests/test_gateway_registry.py +0 -0
  450. {akquant-0.2.32 → akquant-0.2.34}/tests/test_inspector.py +0 -0
  451. {akquant-0.2.32 → akquant-0.2.34}/tests/test_live_runner_broker_bridge.py +0 -0
  452. {akquant-0.2.32 → akquant-0.2.34}/tests/test_multisymbol_cross_section_consistency.py +0 -0
  453. {akquant-0.2.32 → akquant-0.2.34}/tests/test_orders_df.py +0 -0
  454. {akquant-0.2.32 → akquant-0.2.34}/tests/test_params_adapter.py +0 -0
  455. {akquant-0.2.32 → akquant-0.2.34}/tests/test_partial_filled_status.py +0 -0
  456. {akquant-0.2.32 → akquant-0.2.34}/tests/test_portfolio.py +0 -0
  457. {akquant-0.2.32 → akquant-0.2.34}/tests/test_quickstart_stream_consistency.py +0 -0
  458. {akquant-0.2.32 → akquant-0.2.34}/tests/test_report_helpers.py +0 -0
  459. {akquant-0.2.32 → akquant-0.2.34}/tests/test_result_analysis_extensions.py +0 -0
  460. {akquant-0.2.32 → akquant-0.2.34}/tests/test_stop_orders.py +0 -0
  461. {akquant-0.2.32 → akquant-0.2.34}/tests/test_strategy_extras.py +0 -0
  462. {akquant-0.2.32 → akquant-0.2.34}/tests/test_strategy_timers_indicators.py +0 -0
  463. {akquant-0.2.32 → akquant-0.2.34}/tests/test_t_plus_one.py +0 -0
  464. {akquant-0.2.32 → akquant-0.2.34}/tests/test_talib_backend.py +0 -0
  465. {akquant-0.2.32 → akquant-0.2.34}/tests/test_talib_compat.py +0 -0
  466. {akquant-0.2.32 → akquant-0.2.34}/tests/test_trades_df.py +0 -0
  467. {akquant-0.2.32 → akquant-0.2.34}/tests/test_version.py +0 -0
@@ -31,3 +31,4 @@ build/
31
31
  # Local cargo config
32
32
  .cargo/config.toml
33
33
  /data_catalog/
34
+ plans/
@@ -30,7 +30,7 @@ dependencies = [
30
30
 
31
31
  [[package]]
32
32
  name = "akquant"
33
- version = "0.2.32"
33
+ version = "0.2.34"
34
34
  dependencies = [
35
35
  "anyhow",
36
36
  "chrono",
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "akquant"
3
- version = "0.2.32"
3
+ version = "0.2.34"
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.32
3
+ Version: 0.2.34
4
4
  Classifier: Programming Language :: Rust
5
5
  Classifier: Programming Language :: Python :: Implementation :: CPython
6
6
  Classifier: Programming Language :: Python :: Implementation :: PyPy
@@ -199,6 +199,228 @@ Many users mix up "custom strategy indicators" and "extending `akquant.talib`".
199
199
 
200
200
  If you only need a private signal inside one strategy, prefer a custom strategy indicator instead of extending `akquant.talib`.
201
201
 
202
+ ## Export Indicators For Frontend Use
203
+
204
+ If your goal is not only to use a custom indicator inside the strategy, but also to send the indicator output to a web frontend, treat indicator calculation and indicator output as separate concerns:
205
+
206
+ - keep indicator calculation inside `Strategy` / `Indicator`;
207
+ - use `Strategy.record_indicator(...)` to record normalized indicator points;
208
+ - after the run, use `BacktestResult.indicator_df(...)` or `export_indicators(...)` for downstream systems.
209
+
210
+ ### Minimal example
211
+
212
+ ```python
213
+ from akquant import Bar, Strategy
214
+
215
+
216
+ class IndicatorExportStrategy(Strategy):
217
+ def on_bar(self, bar: Bar) -> None:
218
+ spread = bar.high - bar.low
219
+ self.record_indicator(
220
+ name="intrabar_spread",
221
+ value=spread,
222
+ display_name="Intra Bar Spread",
223
+ pane="sub",
224
+ render_type="line",
225
+ precision=4,
226
+ meta={"source": ["high", "low"]},
227
+ )
228
+ ```
229
+
230
+ After the run:
231
+
232
+ ```python
233
+ result = ...
234
+
235
+ # 1) Read inside Python
236
+ indicator_df = result.indicator_df(name="intrabar_spread", symbol="AAPL")
237
+
238
+ # 2) Generate a lightweight local preview
239
+ fig = result.plot_indicators(
240
+ name="intrabar_spread",
241
+ symbol="AAPL",
242
+ show=False,
243
+ filename="indicator_preview.html",
244
+ )
245
+
246
+ # 3) Export for frontend or external services
247
+ result.export_indicators("indicator_outputs.json", format="json")
248
+ result.export_indicators("indicator_outputs", format="parquet")
249
+ ```
250
+
251
+ When available, the JSON export also includes a top-level `run_id` so downstream services can correlate offline exports with the streaming event flow.
252
+
253
+ ### Built-in Minimal Visualization
254
+
255
+ If you only want a quick history preview before wiring a full frontend, use:
256
+
257
+ - `result.plot_indicators(...)`
258
+ - `from akquant.plot import plot_indicators`
259
+
260
+ This built-in path is intentionally lightweight:
261
+
262
+ - it keeps `result.plot()` focused on the existing account dashboard;
263
+ - it splits subplots by `pane`;
264
+ - it reuses `render_type`, with day-one support for common `line` and `bar`;
265
+ - it supports filtering by `name`, `symbol`, and `include_warmup`;
266
+ - it can write a local HTML file for quick inspection alongside exported JSON.
267
+
268
+ Example:
269
+
270
+ ```python
271
+ fig = result.plot_indicators(
272
+ name="intrabar_spread",
273
+ symbol="AAPL",
274
+ include_warmup=False,
275
+ show=False,
276
+ filename="indicator_preview.html",
277
+ title="Indicator Preview",
278
+ )
279
+ ```
280
+
281
+ If you need enterprise-grade multi-panel UX, persistence, permissions, or realtime subscriptions, keep those concerns in external systems and let AKQuant stay responsible for the preview plus normalized data production.
282
+
283
+ ### Optional Indicator Section In Reports
284
+
285
+ If you want the indicator preview embedded into the built-in HTML report instead of a separate figure, enable it explicitly:
286
+
287
+ ```python
288
+ result.report(
289
+ filename="akquant_report.html",
290
+ show=False,
291
+ include_indicators=True,
292
+ indicator_name="intrabar_spread",
293
+ indicator_symbol="AAPL",
294
+ indicator_include_warmup=False,
295
+ )
296
+ ```
297
+
298
+ This path is intentionally constrained:
299
+
300
+ - it is off by default, so existing `report()` output does not change;
301
+ - it is meant for a lightweight indicator section inside the strategy report;
302
+ - if no indicator data exists, the report shows an empty-state notice;
303
+ - if you need richer interaction or layout control, keep that in external frontend systems.
304
+
305
+ ### Bridging Stream Events To Frontend Messages
306
+
307
+ If your external service is a WebSocket or SSE gateway, keep the raw payload parsing out of your business code and use:
308
+
309
+ - `akquant.is_indicator_stream_event(event)`
310
+ - `akquant.to_indicator_message(event)`
311
+ - `akquant.to_indicator_messages(events)`
312
+
313
+ Example:
314
+
315
+ ```python
316
+ def on_event(event):
317
+ if not aq.is_indicator_stream_event(event):
318
+ return
319
+ message = aq.to_indicator_message(event)
320
+ if message is not None:
321
+ websocket.broadcast_json(message)
322
+ ```
323
+
324
+ These helpers are meant to:
325
+
326
+ - bridge only `indicator_point` and `indicator_snapshot`
327
+ - coerce numeric fields into frontend-friendly values
328
+ - unpack `meta_json` and `items_json`
329
+ - preserve the outer stream semantics such as `run_id`, `seq`, and `ts`
330
+
331
+ The bridged `snapshot` payload now also includes a few shortcut fields so frontend
332
+ code does not have to rescan `items` on every update:
333
+
334
+ - `indicator_keys`
335
+ - `panes`
336
+ - `render_types`
337
+ - `value_by_key`
338
+ - `items_by_key`
339
+ - `warmup_count`
340
+ - `has_warmup`
341
+
342
+ The bridge helper also normalizes `_unknown` or empty `symbol` values into `None`,
343
+ and accepts already-decoded `dict/list` values for `meta_json` and `items_json`,
344
+ which makes gateway-side wrapping easier.
345
+
346
+ This is not a new transport layer. It is just a normalization layer that turns AKQuant stream events into steadier frontend message objects.
347
+
348
+ ### Zero-Dependency Browser Live Preview
349
+
350
+ If you want a browser-based demo that product or frontend teammates can open
351
+ immediately, but you do not want to introduce `fastapi`, `uvicorn`, or
352
+ `websockets` yet, use `examples/64_indicator_live_web.py`.
353
+
354
+ This example does three things:
355
+
356
+ - consumes stream events with `run_backtest(..., on_event=...)`
357
+ - normalizes them with `aq.to_indicator_message(event)`
358
+ - serves a tiny `/state` JSON endpoint via built-in `http.server`, then lets the browser poll and draw the `close_echo` line
359
+
360
+ It now supports two polling modes:
361
+
362
+ - request `/state` for the recent full snapshot window
363
+ - request `/state?since_seq=123` for incremental messages with `seq > 123`, while still returning total counts and the latest cursor
364
+
365
+ The payload shape now separates common metadata from message bodies:
366
+
367
+ - shared fields live under `cursor`, `counts`, and `latest_indicator_values`
368
+ - full snapshot mode returns message windows under `window.point_messages` and `window.snapshot_messages`
369
+ - incremental mode returns only new messages under `delta.point_messages` and `delta.snapshot_messages`
370
+
371
+ Run it with:
372
+
373
+ ```bash
374
+ UV_INDEX_URL=https://pypi.org/simple uv run python examples/64_indicator_live_web.py --open
375
+ ```
376
+
377
+ For a quick smoke check, keep the server alive for a shorter window:
378
+
379
+ ```bash
380
+ UV_INDEX_URL=https://pypi.org/simple uv run python examples/64_indicator_live_web.py --keep-seconds 1
381
+ ```
382
+
383
+ The goal is not to become a full frontend product. The goal is to help you:
384
+
385
+ - verify that indicator stream data is leaving the backtest correctly
386
+ - give frontend code a stable `/state` JSON shape to consume first
387
+ - demonstrate live indicator rendering without adding new dependencies
388
+
389
+ ### Current output shape
390
+
391
+ The first implementation exposes three structured layers:
392
+
393
+ - indicator definitions, such as `display_name`, `pane`, and `render_type`
394
+ - indicator instances grouped by `strategy/symbol/indicator/meta`
395
+ - indicator points as the actual time series values
396
+
397
+ This keeps AKQuant focused on producing stable indicator data instead of coupling the framework to a specific charting library.
398
+
399
+ ### Recommended boundary
400
+
401
+ Suggested split of responsibilities:
402
+
403
+ - `AKQuant` owns:
404
+ - indicator calculation
405
+ - indicator recording
406
+ - indicator query
407
+ - indicator export
408
+ - external systems own:
409
+ - persistence
410
+ - APIs
411
+ - websocket delivery
412
+ - frontend applications
413
+
414
+ In short, AKQuant should act as the indicator producer, not the full enterprise frontend platform.
415
+
416
+ ### Recommended examples
417
+
418
+ - [60_custom_indicator_demo.py](https://github.com/akfamily/akquant/blob/main/examples/60_custom_indicator_demo.py)
419
+ - [61_indicator_visualization_export_demo.py](https://github.com/akfamily/akquant/blob/main/examples/61_indicator_visualization_export_demo.py)
420
+ - [62_indicator_streaming_demo.py](https://github.com/akfamily/akquant/blob/main/examples/62_indicator_streaming_demo.py)
421
+ - [63_indicator_ws_bridge_demo.py](https://github.com/akfamily/akquant/blob/main/examples/63_indicator_ws_bridge_demo.py)
422
+ - [64_indicator_live_web.py](https://github.com/akfamily/akquant/blob/main/examples/64_indicator_live_web.py)
423
+
202
424
  ## Common Pitfalls
203
425
 
204
426
  - Pitfall 1: every custom indicator must inherit from `Indicator`
@@ -201,6 +201,226 @@ def __setstate__(self, state):
201
201
 
202
202
  如果你只是要一个策略内的私有信号,优先写自定义指标,而不是去扩展 `akquant.talib`。
203
203
 
204
+ ## 导出指标给前端
205
+
206
+ 如果你的目标不只是“在策略里使用指标”,而是要把指标结果进一步交给 Web 前端展示,建议把“计算指标”和“输出指标”分开处理:
207
+
208
+ - 指标计算仍然放在 `Strategy` / `Indicator` 里;
209
+ - 指标输出使用 `Strategy.record_indicator(...)` 记录标准化点位;
210
+ - 回测结束后,通过 `BacktestResult.indicator_df(...)` 或 `export_indicators(...)` 交给外部服务或前端。
211
+
212
+ ### 最小示例
213
+
214
+ ```python
215
+ from akquant import Bar, Strategy
216
+
217
+
218
+ class IndicatorExportStrategy(Strategy):
219
+ def on_bar(self, bar: Bar) -> None:
220
+ spread = bar.high - bar.low
221
+ self.record_indicator(
222
+ name="intrabar_spread",
223
+ value=spread,
224
+ display_name="Intra Bar Spread",
225
+ pane="sub",
226
+ render_type="line",
227
+ precision=4,
228
+ meta={"source": ["high", "low"]},
229
+ )
230
+ ```
231
+
232
+ 运行结束后:
233
+
234
+ ```python
235
+ result = ...
236
+
237
+ # 1) 在 Python 里直接读取
238
+ indicator_df = result.indicator_df(name="intrabar_spread", symbol="AAPL")
239
+
240
+ # 2) 在本地做一个轻量预览
241
+ fig = result.plot_indicators(
242
+ name="intrabar_spread",
243
+ symbol="AAPL",
244
+ show=False,
245
+ filename="indicator_preview.html",
246
+ )
247
+
248
+ # 3) 导出给前端或外部服务
249
+ result.export_indicators("indicator_outputs.json", format="json")
250
+ result.export_indicators("indicator_outputs", format="parquet")
251
+ ```
252
+
253
+ 其中 JSON 导出在可用时会额外带上顶层 `run_id`,方便外部服务把离线导出与流式事件链路关联起来。
254
+
255
+ ### 内置最小可视化
256
+
257
+ 如果你只是想快速确认指标历史形态,而不是立刻接入完整前端,可以直接使用:
258
+
259
+ - `result.plot_indicators(...)`
260
+ - `from akquant.plot import plot_indicators`
261
+
262
+ 这条内置路径的定位是“轻量 history preview”,特点是:
263
+
264
+ - 保持现有 `result.plot()` 继续只做账户 dashboard;
265
+ - 按 `pane` 自动拆分子图;
266
+ - 复用 `render_type`,第一版支持常见的 `line` / `bar`;
267
+ - 支持 `name`、`symbol`、`include_warmup` 过滤;
268
+ - 可直接输出为本地 HTML,方便和导出的 JSON 一起联调。
269
+
270
+ 例如:
271
+
272
+ ```python
273
+ fig = result.plot_indicators(
274
+ name="intrabar_spread",
275
+ symbol="AAPL",
276
+ include_warmup=False,
277
+ show=False,
278
+ filename="indicator_preview.html",
279
+ title="Indicator Preview",
280
+ )
281
+ ```
282
+
283
+ 如果你需要的是企业级多图联动、权限、持久化和实时订阅,这些仍建议放在外部平台实现;AKQuant 内部只提供最小预览和标准化数据输出。
284
+
285
+ ### 报告中的可选指标区块
286
+
287
+ 如果你希望把指标预览放进内置 HTML 报告,而不是单独输出一个图,也可以显式开启:
288
+
289
+ ```python
290
+ result.report(
291
+ filename="akquant_report.html",
292
+ show=False,
293
+ include_indicators=True,
294
+ indicator_name="intrabar_spread",
295
+ indicator_symbol="AAPL",
296
+ indicator_include_warmup=False,
297
+ )
298
+ ```
299
+
300
+ 这条路径有几个约束:
301
+
302
+ - 默认关闭,不会改变现有 `report()` 的输出;
303
+ - 适合把“一个轻量指标区块”嵌进策略报告;
304
+ - 如果没有指标数据,会在报告里显示空状态提示;
305
+ - 如果你需要复杂交互布局,仍建议交给外部前端实现。
306
+
307
+ ### 流式桥接到前端消息
308
+
309
+ 如果你的外部服务是 WebSocket / SSE 网关,推荐不要把原始 `payload` 解析逻辑散落在业务代码里,可以直接使用:
310
+
311
+ - `akquant.is_indicator_stream_event(event)`
312
+ - `akquant.to_indicator_message(event)`
313
+ - `akquant.to_indicator_messages(events)`
314
+
315
+ 例如:
316
+
317
+ ```python
318
+ def on_event(event):
319
+ if not aq.is_indicator_stream_event(event):
320
+ return
321
+ message = aq.to_indicator_message(event)
322
+ if message is not None:
323
+ websocket.broadcast_json(message)
324
+ ```
325
+
326
+ 这条 helper 的目标是:
327
+
328
+ - 只桥接 `indicator_point` / `indicator_snapshot`
329
+ - 把数值字段转成更适合前端消费的类型
330
+ - 自动解开 `meta_json` / `items_json`
331
+ - 保留 `run_id`、`seq`、`ts` 等外层流式语义
332
+
333
+ 当前 `snapshot` 桥接结果除了 `items` 之外,还会补充几组快捷字段,方便前端减少二次遍历:
334
+
335
+ - `indicator_keys`
336
+ - `panes`
337
+ - `render_types`
338
+ - `value_by_key`
339
+ - `items_by_key`
340
+ - `warmup_count`
341
+ - `has_warmup`
342
+
343
+ 另外,bridge helper 也会把 `_unknown` / 空 `symbol` 规整为 `None`,并兼容已经预先解码成
344
+ `dict/list` 的 `meta_json` / `items_json` 值,便于网关层做二次封装。
345
+
346
+ 它不是新的传输层,只是把 AKQuant 的事件结构整理成更稳定的“前端消息对象”。
347
+
348
+ ### 零依赖浏览器实时预览
349
+
350
+ 如果你想先给业务方或前端同事一个“打开浏览器就能看到”的最小接入样板,而暂时不引入
351
+ `fastapi`、`uvicorn` 或 `websockets` 等依赖,可以直接参考
352
+ `examples/64_indicator_live_web.py`。
353
+
354
+ 这个示例做了三件事:
355
+
356
+ - 用 `run_backtest(..., on_event=...)` 接收流式事件;
357
+ - 用 `aq.to_indicator_message(event)` 规整成前端友好消息;
358
+ - 用内置 `http.server` 暴露 `/state` JSON,并由浏览器轮询绘制 `close_echo` 折线。
359
+
360
+ 现在这个示例同时支持两种轮询方式:
361
+
362
+ - 直接请求 `/state`,拿最近窗口内的完整快照;
363
+ - 请求 `/state?since_seq=123`,只拿 `seq > 123` 的增量消息,同时保留总量统计和最新游标。
364
+
365
+ 当前返回结构也做了区分,便于前端减少分支歧义:
366
+
367
+ - 公共字段放在 `cursor`、`counts`、`latest_indicator_values`
368
+ - 全量模式把消息窗口放在 `window.point_messages` / `window.snapshot_messages`
369
+ - 增量模式把新增消息放在 `delta.point_messages` / `delta.snapshot_messages`
370
+
371
+ 运行方式:
372
+
373
+ ```bash
374
+ UV_INDEX_URL=https://pypi.org/simple uv run python examples/64_indicator_live_web.py --open
375
+ ```
376
+
377
+ 如果你只是想快速验证链路,也可以缩短保活时间:
378
+
379
+ ```bash
380
+ UV_INDEX_URL=https://pypi.org/simple uv run python examples/64_indicator_live_web.py --keep-seconds 1
381
+ ```
382
+
383
+ 这个样板的定位不是完整前端产品,而是帮助你更快完成以下工作:
384
+
385
+ - 验证指标流是否已经成功出站;
386
+ - 让前端先对接稳定的消息结构和 `/state` JSON;
387
+ - 在不新增依赖栈的前提下演示实时指标预览效果。
388
+
389
+ ### 当前输出结构
390
+
391
+ 第一版实现会输出三类结构化结果:
392
+
393
+ - 指标定义:如 `display_name`、`pane`、`render_type`
394
+ - 指标实例:按 `strategy/symbol/indicator/meta` 归并后的实例信息
395
+ - 指标点位:按时间记录的数值序列
396
+
397
+ 这三层结构的目的,是让 AKQuant 负责“生产标准化指标数据”,而不是直接耦合某个具体前端图表库。
398
+
399
+ ### 推荐边界
400
+
401
+ 建议把职责切开:
402
+
403
+ - `AKQuant` 内部负责:
404
+ - 指标计算
405
+ - 指标记录
406
+ - 指标查询
407
+ - 指标导出
408
+ - 外部平台负责:
409
+ - 存储服务
410
+ - API 查询
411
+ - WebSocket 推送
412
+ - 前端图表页面
413
+
414
+ 也就是说,AKQuant 更适合作为“指标生产者”,而不是企业前端平台本身。
415
+
416
+ ### 推荐示例
417
+
418
+ - [60_custom_indicator_demo.py](https://github.com/akfamily/akquant/blob/main/examples/60_custom_indicator_demo.py)
419
+ - [61_indicator_visualization_export_demo.py](https://github.com/akfamily/akquant/blob/main/examples/61_indicator_visualization_export_demo.py)
420
+ - [62_indicator_streaming_demo.py](https://github.com/akfamily/akquant/blob/main/examples/62_indicator_streaming_demo.py)
421
+ - [63_indicator_ws_bridge_demo.py](https://github.com/akfamily/akquant/blob/main/examples/63_indicator_ws_bridge_demo.py)
422
+ - [64_indicator_live_web.py](https://github.com/akfamily/akquant/blob/main/examples/64_indicator_live_web.py)
423
+
204
424
  ## 常见误区
205
425
 
206
426
  - 误区 1:所有自定义指标都必须继承 `Indicator`
@@ -0,0 +1,91 @@
1
+ #!/usr/bin/env python
2
+ # -*- coding: utf-8 -*-
3
+ """
4
+ AKQuant indicator visualization export demo.
5
+
6
+ This example shows the minimal workflow for frontend-facing indicator output:
7
+ 1. Run a strategy that records custom indicator points.
8
+ 2. Read indicator series from `BacktestResult.indicator_df(...)`.
9
+ 3. Render a lightweight local preview with `plot_indicators(...)`.
10
+ 4. Export normalized indicator outputs to JSON.
11
+ """
12
+
13
+ from pathlib import Path
14
+
15
+ import akquant as aq
16
+ import pandas as pd
17
+ from akquant import Bar, Strategy
18
+
19
+
20
+ def make_demo_bars() -> list[Bar]:
21
+ """Build deterministic data for indicator export demo."""
22
+ closes = [10.0, 10.4, 10.9, 10.7, 11.2]
23
+ bars: list[Bar] = []
24
+ for i, close in enumerate(closes):
25
+ bars.append(
26
+ Bar(
27
+ timestamp=pd.Timestamp(f"2024-02-0{i + 1} 10:00:00").value,
28
+ open=close - 0.1,
29
+ high=close + 0.2,
30
+ low=close - 0.3,
31
+ close=close,
32
+ volume=1000.0 + float(i) * 50.0,
33
+ symbol="VIS",
34
+ )
35
+ )
36
+ return bars
37
+
38
+
39
+ class IndicatorVisualizationStrategy(Strategy):
40
+ """Record one custom visualization-oriented indicator on every bar."""
41
+
42
+ def on_bar(self, bar: Bar) -> None:
43
+ """Record one spread-style indicator for export and preview."""
44
+ intrabar_spread = bar.high - bar.low
45
+ self.record_indicator(
46
+ name="intrabar_spread",
47
+ value=intrabar_spread,
48
+ display_name="Intra Bar Spread",
49
+ pane="sub",
50
+ render_type="line",
51
+ precision=4,
52
+ meta={"source": ["high", "low"]},
53
+ )
54
+
55
+
56
+ def main() -> None:
57
+ """Run backtest, preview indicator history, and export indicator data."""
58
+ result = aq.run_backtest(
59
+ data=make_demo_bars(),
60
+ strategy=IndicatorVisualizationStrategy,
61
+ symbols="VIS",
62
+ initial_cash=100000.0,
63
+ commission_rate=0.0,
64
+ stamp_tax_rate=0.0,
65
+ transfer_fee_rate=0.0,
66
+ min_commission=0.0,
67
+ lot_size=1,
68
+ show_progress=False,
69
+ )
70
+
71
+ indicator_df = result.indicator_df(name="intrabar_spread", symbol="VIS")
72
+ html_path = Path(__file__).with_name("indicator_visualization_preview.html")
73
+ export_path = Path(__file__).with_name("indicator_visualization_outputs.json")
74
+ result.plot_indicators(
75
+ name="intrabar_spread",
76
+ symbol="VIS",
77
+ show=False,
78
+ filename=str(html_path),
79
+ title="AKQuant Indicator Preview",
80
+ )
81
+ result.export_indicators(str(export_path), format="json")
82
+
83
+ print(indicator_df[["datetime", "indicator_key", "symbol", "value"]])
84
+ print(f"indicator_rows={len(indicator_df)}")
85
+ print(f"indicator_plot_html={html_path.resolve()}")
86
+ print(f"indicator_export_json={export_path.resolve()}")
87
+ print("done_indicator_visualization_export_demo")
88
+
89
+
90
+ if __name__ == "__main__":
91
+ main()