akquant 0.2.35__tar.gz → 0.2.36__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.
- {akquant-0.2.35 → akquant-0.2.36}/Cargo.lock +23 -1
- {akquant-0.2.35 → akquant-0.2.36}/Cargo.toml +3 -1
- {akquant-0.2.35 → akquant-0.2.36}/PKG-INFO +1 -1
- {akquant-0.2.35 → akquant-0.2.36}/docs/en/guide/data.md +32 -0
- {akquant-0.2.35 → akquant-0.2.36}/docs/en/guide/optimization.md +26 -0
- {akquant-0.2.35 → akquant-0.2.36}/docs/en/guide/strategy.md +46 -0
- {akquant-0.2.35 → akquant-0.2.36}/docs/en/reference/api.md +119 -0
- {akquant-0.2.35 → akquant-0.2.36}/docs/zh/guide/data.md +32 -0
- {akquant-0.2.35 → akquant-0.2.36}/docs/zh/guide/optimization.md +26 -0
- {akquant-0.2.35 → akquant-0.2.36}/docs/zh/guide/strategy.md +46 -0
- {akquant-0.2.35 → akquant-0.2.36}/docs/zh/reference/api.md +119 -0
- {akquant-0.2.35 → akquant-0.2.36}/pyproject.toml +1 -1
- {akquant-0.2.35 → akquant-0.2.36}/python/akquant/__init__.py +20 -1
- {akquant-0.2.35 → akquant-0.2.36}/python/akquant/akquant.pyi +55 -0
- {akquant-0.2.35 → akquant-0.2.36}/python/akquant/backtest/engine.py +148 -25
- {akquant-0.2.35 → akquant-0.2.36}/python/akquant/data.py +1 -1
- {akquant-0.2.35 → akquant-0.2.36}/python/akquant/factor/engine.py +1 -1
- {akquant-0.2.35 → akquant-0.2.36}/python/akquant/live.py +58 -6
- akquant-0.2.36/python/akquant/log.py +614 -0
- {akquant-0.2.35 → akquant-0.2.36}/python/akquant/optimize.py +58 -40
- {akquant-0.2.35 → akquant-0.2.36}/python/akquant/risk.py +26 -8
- {akquant-0.2.35 → akquant-0.2.36}/python/akquant/strategy.py +17 -1
- {akquant-0.2.35 → akquant-0.2.36}/python/akquant/strategy_framework_hooks.py +12 -0
- akquant-0.2.36/python/akquant/strategy_logging.py +89 -0
- {akquant-0.2.35 → akquant-0.2.36}/python/akquant/strategy_time.py +8 -3
- {akquant-0.2.35 → akquant-0.2.36}/src/data/batch.rs +19 -5
- {akquant-0.2.35 → akquant-0.2.36}/src/data/client.rs +46 -6
- {akquant-0.2.35 → akquant-0.2.36}/src/data/feed.rs +45 -2
- {akquant-0.2.35 → akquant-0.2.36}/src/execution/simulated.rs +232 -8
- {akquant-0.2.35 → akquant-0.2.36}/src/lib.rs +2 -0
- akquant-0.2.36/src/log_context.rs +84 -0
- {akquant-0.2.35 → akquant-0.2.36}/src/market/corporate_action.rs +13 -3
- {akquant-0.2.35 → akquant-0.2.36}/tests/test_account_risk_rules.py +24 -0
- {akquant-0.2.35 → akquant-0.2.36}/tests/test_engine.py +704 -39
- {akquant-0.2.35 → akquant-0.2.36}/tests/test_live_runner_broker_bridge.py +77 -16
- {akquant-0.2.35 → akquant-0.2.36}/tests/test_strategy_extras.py +223 -3
- akquant-0.2.35/python/akquant/log.py +0 -149
- akquant-0.2.35/python/akquant/strategy_logging.py +0 -20
- {akquant-0.2.35 → akquant-0.2.36}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/.github/workflows/deploy-docs.yml +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/.github/workflows/docs-quality.yml +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/.github/workflows/release.yml +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/.gitignore +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/.pre-commit-config.yaml +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/CHANGELOG.md +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/CODE_OF_CONDUCT.md +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/CONTRIBUTING.md +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/LICENSE +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/README.md +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/assets/dashboard_preview.png +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/assets/logo.svg +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/assets/social_preview.png +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/docs/CNAME +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/docs/assets/akquant-icon.svg +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/docs/assets/akquant-logo.svg +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/docs/assets/reports/akquant_report.html +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/docs/en/advanced/analyzer_plugin_spec.md +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/docs/en/advanced/broker_capability_matrix.md +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/docs/en/advanced/custom_broker_production_checklist.md +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/docs/en/advanced/custom_broker_registry.md +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/docs/en/advanced/data_feed_adapter_spec.md +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/docs/en/advanced/live_functional_quickstart.md +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/docs/en/advanced/llm.md +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/docs/en/advanced/ml.md +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/docs/en/advanced/multi_strategy_guide.md +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/docs/en/advanced/multi_timeframe_feed_api.md +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/docs/en/advanced/runtime_config.md +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/docs/en/advanced/strategy_style_decision.md +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/docs/en/advanced/timezone.md +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/docs/en/advanced/warm_start.md +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/docs/en/guide/analysis.md +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/docs/en/guide/cross_section_checklist.md +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/docs/en/guide/custom_indicator.md +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/docs/en/guide/examples.md +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/docs/en/guide/factor.md +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/docs/en/guide/indicator_scenario_quickref.md +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/docs/en/guide/python_basics.md +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/docs/en/guide/quant_basics.md +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/docs/en/guide/rust_indicator_reference.md +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/docs/en/guide/talib_indicator_playbook.md +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/docs/en/guide/testing.md +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/docs/en/guide/visualization.md +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/docs/en/index.md +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/docs/en/meta/architecture.md +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/docs/en/meta/internals.md +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/docs/en/start/first_strategy.md +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/docs/en/start/installation.md +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/docs/en/start/quickstart.md +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/docs/en/start/setup_guide.md +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/docs/en/textbook/01_foundations.md +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/docs/en/textbook/02_programming.md +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/docs/en/textbook/03_data.md +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/docs/en/textbook/04_backtest_engine.md +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/docs/en/textbook/05_strategy.md +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/docs/en/textbook/06_stock_a.md +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/docs/en/textbook/07_futures.md +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/docs/en/textbook/08_options.md +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/docs/en/textbook/09_funds.md +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/docs/en/textbook/10_analysis.md +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/docs/en/textbook/11_optimization.md +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/docs/en/textbook/12_ml.md +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/docs/en/textbook/13_visualization.md +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/docs/en/textbook/14_factor.md +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/docs/en/textbook/15_live_trading.md +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/docs/en/textbook/16_rust_indicators.md +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/docs/en/textbook/index.md +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/docs/javascripts/mathjax.js +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/docs/javascripts/search-lang-filter.js +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/docs/robots.txt +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/docs/zh/advanced/analyzer_plugin_spec.md +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/docs/zh/advanced/broker_capability_matrix.md +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/docs/zh/advanced/custom_broker_production_checklist.md +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/docs/zh/advanced/custom_broker_registry.md +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/docs/zh/advanced/data_feed_adapter_spec.md +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/docs/zh/advanced/live_functional_quickstart.md +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/docs/zh/advanced/llm.md +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/docs/zh/advanced/ml.md +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/docs/zh/advanced/multi_strategy_guide.md +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/docs/zh/advanced/multi_timeframe_feed_api.md +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/docs/zh/advanced/runtime_config.md +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/docs/zh/advanced/strategy_style_decision.md +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/docs/zh/advanced/timezone.md +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/docs/zh/advanced/warm_start.md +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/docs/zh/guide/analysis.md +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/docs/zh/guide/cross_section_checklist.md +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/docs/zh/guide/custom_indicator.md +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/docs/zh/guide/examples.md +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/docs/zh/guide/factor.md +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/docs/zh/guide/indicator_scenario_quickref.md +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/docs/zh/guide/python_basics.md +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/docs/zh/guide/quant_basics.md +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/docs/zh/guide/rust_indicator_reference.md +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/docs/zh/guide/talib_indicator_playbook.md +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/docs/zh/guide/testing.md +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/docs/zh/guide/visualization.md +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/docs/zh/index.md +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/docs/zh/meta/architecture.md +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/docs/zh/meta/internals.md +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/docs/zh/start/first_strategy.md +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/docs/zh/start/installation.md +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/docs/zh/start/quickstart.md +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/docs/zh/start/setup_guide.md +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/docs/zh/textbook/01_foundations.md +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/docs/zh/textbook/02_programming.md +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/docs/zh/textbook/03_data.md +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/docs/zh/textbook/04_backtest_engine.md +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/docs/zh/textbook/05_strategy.md +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/docs/zh/textbook/06_stock_a.md +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/docs/zh/textbook/07_futures.md +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/docs/zh/textbook/08_options.md +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/docs/zh/textbook/09_funds.md +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/docs/zh/textbook/10_analysis.md +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/docs/zh/textbook/11_optimization.md +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/docs/zh/textbook/12_ml.md +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/docs/zh/textbook/13_visualization.md +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/docs/zh/textbook/14_factor.md +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/docs/zh/textbook/15_live_trading.md +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/docs/zh/textbook/16_rust_indicators.md +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/docs/zh/textbook/index.md +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/examples/01_quickstart.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/examples/02_parameter_optimization.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/examples/03_parameter_optimization_advanced.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/examples/04_mixed_assets.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/examples/05_live_trading_ctp.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/examples/06_complex_orders.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/examples/07_option_test.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/examples/08_event_callbacks.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/examples/09_ml_framework.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/examples/10_ml_walk_forward.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/examples/11_plot_visualization.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/examples/12_wfo_integrated.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/examples/13_quantstats_report.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/examples/14_multi_frequency.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/examples/15_plot_intraday.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/examples/16_adj_returns_signal.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/examples/17_readme_demo.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/examples/18_benchmark_multisymbol.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/examples/19_factor_expression.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/examples/20_risk_management_demo.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/examples/21_warm_start_demo.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/examples/22_strategy_runtime_config_demo.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/examples/23_functional_callbacks_demo.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/examples/24_functional_tick_simulation_demo.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/examples/25_streaming_backtest_demo.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/examples/26_streaming_quickstart.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/examples/27_streaming_monitoring_console.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/examples/28_streaming_alerts_and_persist.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/examples/29_streaming_event_report.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/examples/30_streaming_report_oneclick.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/examples/31_streaming_live_console.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/examples/32_streaming_live_web.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/examples/33_report_and_analysis_outputs.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/examples/34_multi_strategy_demo.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/examples/35_custom_broker_registry_demo.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/examples/36_trailing_orders.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/examples/37_feed_replay_alignment_demo.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/examples/38_live_functional_strategy_demo.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/examples/39_live_broker_submit_order_demo.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/examples/40_functional_multi_slot_risk_demo.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/examples/41_live_multi_slot_orchestration_demo.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/examples/42_live_broker_event_audit_demo.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/examples/43_target_weights_rebalance.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/examples/44_strategy_source_loader_demo.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/examples/45_talib_indicator_playbook_demo.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/examples/46_broker_profile_demo.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/examples/47_margin_liquidation_audit_demo.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/examples/48_margin_liquidation_priority_compare.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/examples/49_on_expiry_demo.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/examples/50_framework_hooks_demo.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/examples/51_class_tick_callbacks_demo.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/examples/52_pre_open_demo.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/examples/53_timer_to_pre_open_demo.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/examples/54_functional_pre_open_demo.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/examples/55_functional_ml_walk_forward.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/examples/56_functional_warm_start_demo.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/examples/57_functional_multi_slot_warm_start_demo.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/examples/58_incremental_bootstrap_demo.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/examples/59_akshare_etf_rotation.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/examples/60_custom_indicator_demo.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/examples/61_indicator_visualization_export_demo.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/examples/62_indicator_streaming_demo.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/examples/63_indicator_ws_bridge_demo.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/examples/64_indicator_live_web.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/examples/README.md +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/examples/benchmark_utils.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/examples/pb_mock.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/examples/strategies/01_stock_dual_moving_average.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/examples/strategies/02_stock_grid_trading.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/examples/strategies/03_stock_atr_breakout.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/examples/strategies/04_stock_momentum_rotation.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/examples/strategies/05_stock_momentum_rotation_timer.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/examples/strategies/06_stock_momentum_rotation_bucket.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/examples/strategies/07_stock_momentum_rotation_on_timer.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/examples/strategies/08_target_positions_long_short.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/examples/strategies/README.md +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/examples/textbook/ch01_quickstart.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/examples/textbook/ch02_programming.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/examples/textbook/ch03_data.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/examples/textbook/ch04_comparison.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/examples/textbook/ch05_strategy.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/examples/textbook/ch06_stock_a.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/examples/textbook/ch07_futures.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/examples/textbook/ch08_options.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/examples/textbook/ch09_funds.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/examples/textbook/ch09_portfolio.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/examples/textbook/ch10_analysis.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/examples/textbook/ch11_optimization.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/examples/textbook/ch12_ml.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/examples/textbook/ch13_visualization.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/examples/textbook/ch14_factor.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/examples/textbook/ch15_live_trading.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/examples/textbook/ch15_strategy_loader.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/mkdocs.yml +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/python/akquant/analyzer_plugin.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/python/akquant/backtest/__init__.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/python/akquant/backtest/__init__.pyi +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/python/akquant/backtest/result.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/python/akquant/checkpoint.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/python/akquant/config.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/python/akquant/factor/__init__.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/python/akquant/factor/ops.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/python/akquant/factor/parser.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/python/akquant/feed_adapter.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/python/akquant/fund/__init__.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/python/akquant/futures/__init__.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/python/akquant/gateway/__init__.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/python/akquant/gateway/base.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/python/akquant/gateway/ctp_adapter.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/python/akquant/gateway/ctp_native.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/python/akquant/gateway/factory.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/python/akquant/gateway/mapper.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/python/akquant/gateway/miniqmt.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/python/akquant/gateway/models.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/python/akquant/gateway/ptrade.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/python/akquant/gateway/registry.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/python/akquant/indicator.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/python/akquant/indicator_recording.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/python/akquant/indicator_stream.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/python/akquant/ml/__init__.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/python/akquant/ml/model.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/python/akquant/option/__init__.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/python/akquant/params.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/python/akquant/params_adapter.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/python/akquant/plot/__init__.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/python/akquant/plot/analysis.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/python/akquant/plot/dashboard.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/python/akquant/plot/indicator.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/python/akquant/plot/report.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/python/akquant/plot/strategy.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/python/akquant/plot/utils.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/python/akquant/py.typed +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/python/akquant/sizer.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/python/akquant/stock/__init__.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/python/akquant/strategy_events.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/python/akquant/strategy_history.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/python/akquant/strategy_loader.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/python/akquant/strategy_ml.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/python/akquant/strategy_order_events.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/python/akquant/strategy_position.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/python/akquant/strategy_scheduler.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/python/akquant/strategy_trading_api.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/python/akquant/talib/__init__.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/python/akquant/talib/backend.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/python/akquant/talib/core.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/python/akquant/talib/funcs.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/python/akquant/utils/__init__.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/python/akquant/utils/inspector.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/requirements-dev.txt +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/scripts/cargo-test.sh +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/scripts/check_docs_api_examples.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/scripts/check_docs_links.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/scripts/dev-check.sh +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/scripts/find_legacy_execution_policy_calls.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/scripts/golden_baseline_report.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/src/account.rs +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/src/analysis/mod.rs +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/src/analysis/python.rs +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/src/analysis/result.rs +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/src/analysis/tests.rs +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/src/analysis/tracker.rs +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/src/analysis/types.rs +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/src/bin/stub_gen.rs +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/src/clock.rs +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/src/context.rs +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/src/data/aggregator.rs +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/src/data/mod.rs +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/src/engine/core.rs +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/src/engine/mod.rs +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/src/engine/python.rs +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/src/engine/state.rs +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/src/error.rs +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/src/event.rs +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/src/event_manager.rs +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/src/execution/common.rs +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/src/execution/crypto.rs +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/src/execution/forex.rs +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/src/execution/futures.rs +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/src/execution/matcher.rs +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/src/execution/mod.rs +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/src/execution/option.rs +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/src/execution/python.rs +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/src/execution/realtime.rs +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/src/execution/slippage.rs +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/src/execution/stock.rs +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/src/history.rs +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/src/indicators/momentum.rs +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/src/indicators/momentum_oscillators.rs +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/src/indicators/momentum_rates.rs +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/src/indicators/moving_average.rs +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/src/indicators/moving_average_compound.rs +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/src/indicators/moving_average_core.rs +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/src/indicators/moving_average_transforms.rs +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/src/indicators/moving_average_windowed.rs +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/src/indicators/trend.rs +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/src/indicators/trend_directional.rs +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/src/indicators/trend_oscillators.rs +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/src/indicators/trend_regression.rs +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/src/indicators/volatility.rs +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/src/indicators/volatility_price.rs +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/src/indicators/volatility_stats.rs +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/src/indicators/volume.rs +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/src/indicators.rs +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/src/margin/calculator.rs +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/src/margin/engine.rs +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/src/margin/mod.rs +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/src/market/china.rs +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/src/market/core.rs +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/src/market/fund.rs +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/src/market/futures.rs +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/src/market/manager.rs +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/src/market/mod.rs +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/src/market/option.rs +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/src/market/simple.rs +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/src/market/stock.rs +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/src/model/corporate_action.rs +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/src/model/instrument.rs +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/src/model/market_data.rs +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/src/model/mod.rs +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/src/model/order.rs +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/src/model/timer.rs +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/src/model/types.rs +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/src/order_manager.rs +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/src/pipeline/mod.rs +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/src/pipeline/processor.rs +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/src/pipeline/runner.rs +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/src/pipeline/stages.rs +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/src/portfolio.rs +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/src/risk/common.rs +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/src/risk/config.rs +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/src/risk/futures.rs +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/src/risk/manager.rs +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/src/risk/mod.rs +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/src/risk/option.rs +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/src/risk/portfolio.rs +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/src/risk/rule.rs +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/src/risk/stock.rs +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/src/settlement/expiry.rs +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/src/settlement/handler.rs +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/src/settlement/manager.rs +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/src/settlement/mod.rs +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/src/settlement/option.rs +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/src/statistics/mod.rs +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/tests/golden/BASELINE_REPORT.md +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/tests/golden/LEGACY_EXECUTION_CALLS.md +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/tests/golden/baselines/futures_margin/equity_curve.parquet +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/tests/golden/baselines/futures_margin/metrics.json +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/tests/golden/baselines/futures_margin/orders.parquet +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/tests/golden/baselines/option_basic/equity_curve.parquet +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/tests/golden/baselines/option_basic/metrics.json +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/tests/golden/baselines/option_basic/orders.parquet +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/tests/golden/baselines/stock_t1/equity_curve.parquet +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/tests/golden/baselines/stock_t1/metrics.json +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/tests/golden/baselines/stock_t1/orders.parquet +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/tests/golden/baselines/stock_t1/trades.parquet +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/tests/golden/current/futures_margin/equity_curve.parquet +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/tests/golden/current/futures_margin/metrics.json +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/tests/golden/current/futures_margin/orders.parquet +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/tests/golden/current/option_basic/equity_curve.parquet +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/tests/golden/current/option_basic/metrics.json +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/tests/golden/current/option_basic/orders.parquet +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/tests/golden/current/stock_t1/equity_curve.parquet +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/tests/golden/current/stock_t1/metrics.json +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/tests/golden/current/stock_t1/orders.parquet +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/tests/golden/current/stock_t1/trades.parquet +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/tests/golden/data/future_margin.parquet +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/tests/golden/data/future_margin.parquet.sha256 +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/tests/golden/data/option_basic.parquet +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/tests/golden/data/option_basic.parquet.sha256 +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/tests/golden/data/stock_t1.parquet +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/tests/golden/data/stock_t1.parquet.sha256 +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/tests/golden/gen_data.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/tests/golden/runner.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/tests/golden/strategies/futures_margin.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/tests/golden/strategies/option_basic.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/tests/golden/strategies/stock_t1.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/tests/golden/test_golden.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/tests/test_custom_matcher.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/tests/test_docs_api_examples.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/tests/test_docs_links.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/tests/test_examples_regression.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/tests/test_factor_engine.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/tests/test_factor_ops.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/tests/test_feed_adapter.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/tests/test_gateway_callbacks.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/tests/test_gateway_ctp_adapter.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/tests/test_gateway_ctp_native.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/tests/test_gateway_factory.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/tests/test_gateway_mapper.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/tests/test_gateway_registry.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/tests/test_indicator_live_web_example.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/tests/test_indicator_recording.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/tests/test_inspector.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/tests/test_multisymbol_cross_section_consistency.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/tests/test_orders_df.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/tests/test_params_adapter.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/tests/test_partial_filled_status.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/tests/test_portfolio.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/tests/test_quickstart_stream_consistency.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/tests/test_report_helpers.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/tests/test_report_plot_extensions.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/tests/test_result_analysis_extensions.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/tests/test_stop_orders.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/tests/test_strategy_timers_indicators.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/tests/test_t_plus_one.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/tests/test_talib_backend.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/tests/test_talib_compat.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/tests/test_trades_df.py +0 -0
- {akquant-0.2.35 → akquant-0.2.36}/tests/test_version.py +0 -0
|
@@ -30,7 +30,7 @@ dependencies = [
|
|
|
30
30
|
|
|
31
31
|
[[package]]
|
|
32
32
|
name = "akquant"
|
|
33
|
-
version = "0.2.
|
|
33
|
+
version = "0.2.36"
|
|
34
34
|
dependencies = [
|
|
35
35
|
"anyhow",
|
|
36
36
|
"chrono",
|
|
@@ -41,12 +41,14 @@ dependencies = [
|
|
|
41
41
|
"numpy",
|
|
42
42
|
"polars",
|
|
43
43
|
"pyo3",
|
|
44
|
+
"pyo3-log",
|
|
44
45
|
"pyo3-stub-gen",
|
|
45
46
|
"rayon",
|
|
46
47
|
"rmp-serde",
|
|
47
48
|
"rust_decimal",
|
|
48
49
|
"rust_decimal_macros",
|
|
49
50
|
"serde",
|
|
51
|
+
"serde_json",
|
|
50
52
|
"thiserror",
|
|
51
53
|
"uuid",
|
|
52
54
|
]
|
|
@@ -96,6 +98,15 @@ dependencies = [
|
|
|
96
98
|
"object",
|
|
97
99
|
]
|
|
98
100
|
|
|
101
|
+
[[package]]
|
|
102
|
+
name = "arc-swap"
|
|
103
|
+
version = "1.9.1"
|
|
104
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
105
|
+
checksum = "6a3a1fd6f75306b68087b831f025c712524bcb19aad54e557b1129cfa0a2b207"
|
|
106
|
+
dependencies = [
|
|
107
|
+
"rustversion",
|
|
108
|
+
]
|
|
109
|
+
|
|
99
110
|
[[package]]
|
|
100
111
|
name = "argminmax"
|
|
101
112
|
version = "0.6.3"
|
|
@@ -2255,6 +2266,17 @@ dependencies = [
|
|
|
2255
2266
|
"pyo3-build-config",
|
|
2256
2267
|
]
|
|
2257
2268
|
|
|
2269
|
+
[[package]]
|
|
2270
|
+
name = "pyo3-log"
|
|
2271
|
+
version = "0.13.3"
|
|
2272
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
2273
|
+
checksum = "26c2ec80932c5c3b2d4fbc578c9b56b2d4502098587edb8bef5b6bfcad43682e"
|
|
2274
|
+
dependencies = [
|
|
2275
|
+
"arc-swap",
|
|
2276
|
+
"log",
|
|
2277
|
+
"pyo3",
|
|
2278
|
+
]
|
|
2279
|
+
|
|
2258
2280
|
[[package]]
|
|
2259
2281
|
name = "pyo3-macros"
|
|
2260
2282
|
version = "0.28.2"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[package]
|
|
2
2
|
name = "akquant"
|
|
3
|
-
version = "0.2.
|
|
3
|
+
version = "0.2.36"
|
|
4
4
|
edition = "2024"
|
|
5
5
|
description = "High-performance quantitative trading framework based on Rust and Python"
|
|
6
6
|
license = "MIT"
|
|
@@ -30,8 +30,10 @@ csv = "1.3"
|
|
|
30
30
|
thiserror = "2.0.18"
|
|
31
31
|
rust_decimal_macros = "1.40"
|
|
32
32
|
log = "0.4"
|
|
33
|
+
pyo3-log = "0.13.1"
|
|
33
34
|
crossbeam-channel = "0.5"
|
|
34
35
|
rmp-serde = "1.3.1"
|
|
36
|
+
serde_json = "1.0"
|
|
35
37
|
|
|
36
38
|
[features]
|
|
37
39
|
default = []
|
|
@@ -144,6 +144,38 @@ Parameter semantics:
|
|
|
144
144
|
* `align="day"`: Partition by day without `session_windows`; `day_mode` supports `trading/calendar`.
|
|
145
145
|
* `align="global"`: Aggregate on the full timeline without day partitioning.
|
|
146
146
|
|
|
147
|
+
### 2.5 Using `DataFeed` Directly
|
|
148
|
+
|
|
149
|
+
If you want explicit control over how data enters the engine, you can work with `DataFeed` directly instead of normalizing everything into a `DataFrame` first:
|
|
150
|
+
|
|
151
|
+
```python
|
|
152
|
+
import akquant as aq
|
|
153
|
+
|
|
154
|
+
feed = aq.DataFeed.from_csv("/data/000001.csv", "000001.SZ")
|
|
155
|
+
|
|
156
|
+
result = aq.run_backtest(
|
|
157
|
+
data=feed,
|
|
158
|
+
strategy=MyStrategy,
|
|
159
|
+
symbols="000001.SZ",
|
|
160
|
+
show_progress=False,
|
|
161
|
+
)
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
For live scenarios, create a writable live feed:
|
|
165
|
+
|
|
166
|
+
```python
|
|
167
|
+
import akquant as aq
|
|
168
|
+
|
|
169
|
+
feed = aq.DataFeed.create_live()
|
|
170
|
+
feed.add_tick(aq.Tick(...))
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
Notes:
|
|
174
|
+
|
|
175
|
+
* `DataFeed.from_csv(...)` is a good fit when you want AKQuant to read a CSV-backed event stream directly.
|
|
176
|
+
* `add_bar(...)`, `add_bars(...)`, and `add_arrays(...)` fit cases where you already have normalized market objects or arrays on the Python side.
|
|
177
|
+
* If CSV or array inputs contain invalid floating-point values, Rust emits warnings that are forwarded into AKQuant's Python `logging` pipeline instead of failing silently.
|
|
178
|
+
|
|
147
179
|
---
|
|
148
180
|
|
|
149
181
|
## 3. Multi-Symbol Data
|
|
@@ -201,6 +201,32 @@ When `max_workers > 1`, warning behavior is tied to `forward_worker_logs`:
|
|
|
201
201
|
* `forward_worker_logs=True` with active main-process logger handlers: log forwarding is enabled and visibility warning is suppressed.
|
|
202
202
|
* `forward_worker_logs=True` without active main-process handlers: warns that forwarding was requested but no handler is available.
|
|
203
203
|
|
|
204
|
+
It is recommended to configure logging explicitly before launching optimization, especially when you want aggregated worker logs in the main process:
|
|
205
|
+
|
|
206
|
+
```python
|
|
207
|
+
import akquant
|
|
208
|
+
|
|
209
|
+
akquant.configure_logging(
|
|
210
|
+
akquant.LogConfig(
|
|
211
|
+
profile="optimize",
|
|
212
|
+
level="INFO",
|
|
213
|
+
console=True,
|
|
214
|
+
filename="logs/optimize.log",
|
|
215
|
+
file_level="DEBUG",
|
|
216
|
+
file_json=True,
|
|
217
|
+
file_max_bytes=50_000_000,
|
|
218
|
+
file_backup_count=3,
|
|
219
|
+
)
|
|
220
|
+
)
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
Notes:
|
|
224
|
+
|
|
225
|
+
* `profile="optimize"` includes process identity in the default format, which helps distinguish worker output.
|
|
226
|
+
* `forward_worker_logs=True` only forwards worker logs back to the main process; it does not create handlers automatically.
|
|
227
|
+
* If you only want quick console logging, `akquant.register_logger(level="INFO")` remains valid.
|
|
228
|
+
* If you want file logs to be easier for external log pipelines to consume, enable `file_json=True`.
|
|
229
|
+
|
|
204
230
|
### Persistence & Resume
|
|
205
231
|
|
|
206
232
|
For scenarios with extremely large parameter sets (e.g., > 10,000 combinations), running on a single machine might take days. AKQuant supports real-time result persistence to SQLite, enabling breakpoint resume.
|
|
@@ -212,6 +212,52 @@ def on_bar(self, bar):
|
|
|
212
212
|
self.log("Insufficient funds", level=logging.WARNING)
|
|
213
213
|
```
|
|
214
214
|
|
|
215
|
+
When log handlers are configured through `akquant.configure_logging(...)` or `akquant.register_logger(...)`, `self.log()` also carries structured context that is useful in `live` profile output and file logs:
|
|
216
|
+
|
|
217
|
+
* `phase`: current stage such as `strategy`, `order`, or `trade`
|
|
218
|
+
* `strategy_id` / `slot`: strategy identity in multi-strategy runs
|
|
219
|
+
* `symbol`: current instrument
|
|
220
|
+
* `event_time`: strategy event time
|
|
221
|
+
* `order_id` / `client_order_id`: auto-filled inside `on_order` / `on_trade` / `on_reject`
|
|
222
|
+
|
|
223
|
+
The simplest option remains the compatibility helper:
|
|
224
|
+
|
|
225
|
+
```python
|
|
226
|
+
import akquant
|
|
227
|
+
|
|
228
|
+
akquant.register_logger(level="INFO")
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
For clearer research / optimize / live separation, prefer the structured config API:
|
|
232
|
+
|
|
233
|
+
```python
|
|
234
|
+
import akquant
|
|
235
|
+
|
|
236
|
+
akquant.configure_logging(
|
|
237
|
+
akquant.LogConfig(
|
|
238
|
+
profile="live",
|
|
239
|
+
level="INFO",
|
|
240
|
+
console=True,
|
|
241
|
+
filename="logs/strategy.log",
|
|
242
|
+
file_level="DEBUG",
|
|
243
|
+
file_json=True,
|
|
244
|
+
file_max_bytes=10_000_000,
|
|
245
|
+
file_backup_count=5,
|
|
246
|
+
)
|
|
247
|
+
)
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
If you want to ship logs into a log pipeline or collector, you can enable JSON output per handler:
|
|
251
|
+
|
|
252
|
+
* `console_json=True`: console emits JSON lines
|
|
253
|
+
* `file_json=True`: file emits JSON lines
|
|
254
|
+
|
|
255
|
+
Practical guidance:
|
|
256
|
+
|
|
257
|
+
* Use `self.log()` for human-readable strategy debugging
|
|
258
|
+
* Use `run_backtest(..., on_event=...)` when you need a machine-consumable `order/trade/progress/risk` event stream
|
|
259
|
+
* Inside `on_order`, `on_trade`, and `on_reject`, you usually do not need to manually concatenate order ids into the message
|
|
260
|
+
|
|
215
261
|
### 3.2 Data Access (Syntactic Sugar)
|
|
216
262
|
|
|
217
263
|
The `Strategy` class provides properties for quick access to current Bar/Tick data:
|
|
@@ -639,6 +639,101 @@ result = run_backtest(
|
|
|
639
639
|
* **UI-Driven Parameter Input**: Declare `PARAM_MODEL` in strategy classes (`akquant.ParamModel`) and use `get_strategy_param_schema` / `validate_strategy_params` for frontend-backend parameter consistency.
|
|
640
640
|
* **Parameter Tuning**: When using `run_grid_search`, modify the Config object or pass override parameters as needed.
|
|
641
641
|
|
|
642
|
+
### Logging API
|
|
643
|
+
|
|
644
|
+
AKQuant stays quiet by default when imported as a library; until explicitly configured, the `akquant` root logger only carries a `NullHandler`.
|
|
645
|
+
|
|
646
|
+
#### `akquant.LogConfig`
|
|
647
|
+
|
|
648
|
+
Advanced logging config object used by `configure_logging(...)`.
|
|
649
|
+
|
|
650
|
+
Core fields:
|
|
651
|
+
|
|
652
|
+
* `level`: global fallback level.
|
|
653
|
+
* `console`: whether to enable the console handler.
|
|
654
|
+
* `console_level` / `file_level`: per-handler level overrides.
|
|
655
|
+
* `console_format` / `file_format`: text formatter overrides.
|
|
656
|
+
* `console_show_context` / `file_show_context`: whether human-readable output should append structured context.
|
|
657
|
+
* `console_json` / `file_json`: whether the corresponding handler should emit JSON lines.
|
|
658
|
+
* `filename`: target log file path.
|
|
659
|
+
* `file_mode`: file open mode, default `a`.
|
|
660
|
+
* `file_max_bytes` / `file_backup_count`: size-based rotation threshold and retention count.
|
|
661
|
+
* `profile`: preset profile, one of `research`, `optimize`, or `live`.
|
|
662
|
+
* `reset_handlers`: whether to reset AKQuant-managed handlers.
|
|
663
|
+
* `propagate`: whether records should propagate to parent loggers.
|
|
664
|
+
|
|
665
|
+
#### `akquant.configure_logging`
|
|
666
|
+
|
|
667
|
+
```python
|
|
668
|
+
def configure_logging(config: LogConfig) -> logging.Logger
|
|
669
|
+
```
|
|
670
|
+
|
|
671
|
+
Initializes or reconfigures the `akquant` logging system through a structured config.
|
|
672
|
+
|
|
673
|
+
Recommended example:
|
|
674
|
+
|
|
675
|
+
```python
|
|
676
|
+
import akquant
|
|
677
|
+
|
|
678
|
+
akquant.configure_logging(
|
|
679
|
+
akquant.LogConfig(
|
|
680
|
+
profile="live",
|
|
681
|
+
level="INFO",
|
|
682
|
+
console=True,
|
|
683
|
+
console_json=False,
|
|
684
|
+
filename="logs/live.log",
|
|
685
|
+
file_level="DEBUG",
|
|
686
|
+
file_json=True,
|
|
687
|
+
file_max_bytes=10_000_000,
|
|
688
|
+
file_backup_count=5,
|
|
689
|
+
)
|
|
690
|
+
)
|
|
691
|
+
```
|
|
692
|
+
|
|
693
|
+
Behavior notes:
|
|
694
|
+
|
|
695
|
+
* `profile` only fills unspecified fields; explicit config values always win.
|
|
696
|
+
* `profile="optimize"` uses a process-aware default text format so worker output is easier to distinguish.
|
|
697
|
+
* `profile="live"` is the natural place to enable structured context and/or JSON output.
|
|
698
|
+
|
|
699
|
+
#### `akquant.register_logger`
|
|
700
|
+
|
|
701
|
+
```python
|
|
702
|
+
def register_logger(
|
|
703
|
+
filename: Optional[str] = None,
|
|
704
|
+
console: bool = True,
|
|
705
|
+
level: str = "INFO",
|
|
706
|
+
) -> None
|
|
707
|
+
```
|
|
708
|
+
|
|
709
|
+
Compatibility helper for quickly enabling logging without exposing advanced fields. Internally this maps to `configure_logging(LogConfig(...))`.
|
|
710
|
+
|
|
711
|
+
#### `akquant.get_logger`
|
|
712
|
+
|
|
713
|
+
```python
|
|
714
|
+
def get_logger(name: Optional[str] = None) -> logging.Logger
|
|
715
|
+
```
|
|
716
|
+
|
|
717
|
+
Fetches a logger under the `akquant` namespace:
|
|
718
|
+
|
|
719
|
+
* `get_logger()` -> `akquant`
|
|
720
|
+
* `get_logger("strategy")` -> `akquant.strategy`
|
|
721
|
+
* `get_logger("gateway.live")` -> `akquant.gateway.live`
|
|
722
|
+
|
|
723
|
+
#### `akquant.set_log_level`
|
|
724
|
+
|
|
725
|
+
```python
|
|
726
|
+
def set_log_level(level: Union[str, int]) -> None
|
|
727
|
+
```
|
|
728
|
+
|
|
729
|
+
Updates the current `akquant` root logger level.
|
|
730
|
+
|
|
731
|
+
#### Boundary Guidance
|
|
732
|
+
|
|
733
|
+
* `self.log(...)` is the primary human-readable strategy logging path.
|
|
734
|
+
* `run_backtest(..., on_event=...)` is the machine-consumable event stream and is better suited for realtime UI, alerting, and audit sinks.
|
|
735
|
+
* Inside `on_order` / `on_trade` / `on_reject`, `self.log(...)` automatically carries structured fields such as `order_id` and `client_order_id`.
|
|
736
|
+
|
|
642
737
|
### `akquant.RiskConfig`
|
|
643
738
|
|
|
644
739
|
Configuration for risk management.
|
|
@@ -835,6 +930,30 @@ The main entry point for the backtesting engine (usually used implicitly via `ru
|
|
|
835
930
|
* `use_china_market()`: Enable China market.
|
|
836
931
|
* `set_stock_fee_rules(commission, stamp_tax, transfer_fee, min_commission)`: Set fee rules.
|
|
837
932
|
|
|
933
|
+
### `akquant.DataFeed`
|
|
934
|
+
|
|
935
|
+
`DataFeed` is the engine-facing event source abstraction. Use it when you want explicit control over how data enters the engine.
|
|
936
|
+
|
|
937
|
+
**Constructors & factories:**
|
|
938
|
+
|
|
939
|
+
* `DataFeed()`: Create an empty historical feed.
|
|
940
|
+
* `DataFeed.from_csv(path, symbol)`: Create a feed directly from a CSV file; useful when you want Rust-side row iteration to drive the event stream.
|
|
941
|
+
* `DataFeed.create_live()`: Create a live feed suitable for gateway / market data push scenarios.
|
|
942
|
+
|
|
943
|
+
**Input methods:**
|
|
944
|
+
|
|
945
|
+
* `add_bar(bar)`: Append one `Bar` to the feed.
|
|
946
|
+
* `add_bars(bars)`: Append a batch of `Bar` objects.
|
|
947
|
+
* `add_tick(tick)`: Append one `Tick` to a live feed.
|
|
948
|
+
* `add_arrays(timestamps, opens, highs, lows, closes, volumes, symbol)`: Build bars from arrays and inject them into the feed efficiently.
|
|
949
|
+
* `sort()`: Sort the current historical feed by event time.
|
|
950
|
+
|
|
951
|
+
**When to use it:**
|
|
952
|
+
|
|
953
|
+
* For normal backtests, prefer `run_backtest(data=...)` with a `DataFrame`, `List[Bar]`, or `DataFeedAdapter`.
|
|
954
|
+
* Use `DataFeed` when you want to reuse the same feed object, switch explicitly between historical and live modes, or wire data into `Engine.add_data(feed)` yourself.
|
|
955
|
+
* If `from_csv(...)` or `add_arrays(...)` encounters invalid floating-point values, Rust emits warnings that flow into AKQuant's Python `logging` pipeline, such as `akquant.data.client` and `akquant.data.batch`.
|
|
956
|
+
|
|
838
957
|
### `akquant.gateway` Custom Broker Registry
|
|
839
958
|
|
|
840
959
|
You can plug in a custom broker by name through the registry without editing built-in factory branches.
|
|
@@ -144,6 +144,38 @@ result = aq.run_backtest(
|
|
|
144
144
|
* `align="day"`:按日分区,不接收 `session_windows`;`day_mode` 支持 `trading/calendar`。
|
|
145
145
|
* `align="global"`:按全局时间轴聚合,不按交易日切段。
|
|
146
146
|
|
|
147
|
+
### 2.5 直接使用 `DataFeed`
|
|
148
|
+
|
|
149
|
+
如果你希望显式控制“数据如何进入引擎”,可以直接使用 `DataFeed`,而不必先转成 `DataFrame`:
|
|
150
|
+
|
|
151
|
+
```python
|
|
152
|
+
import akquant as aq
|
|
153
|
+
|
|
154
|
+
feed = aq.DataFeed.from_csv("/data/000001.csv", "000001.SZ")
|
|
155
|
+
|
|
156
|
+
result = aq.run_backtest(
|
|
157
|
+
data=feed,
|
|
158
|
+
strategy=MyStrategy,
|
|
159
|
+
symbols="000001.SZ",
|
|
160
|
+
show_progress=False,
|
|
161
|
+
)
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
实时场景则可以创建可写入的 live feed:
|
|
165
|
+
|
|
166
|
+
```python
|
|
167
|
+
import akquant as aq
|
|
168
|
+
|
|
169
|
+
feed = aq.DataFeed.create_live()
|
|
170
|
+
feed.add_tick(aq.Tick(...))
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
补充说明:
|
|
174
|
+
|
|
175
|
+
* `DataFeed.from_csv(...)` 适合让 AKQuant 直接从 CSV 事件流读取数据。
|
|
176
|
+
* `add_bar(...)` / `add_bars(...)` / `add_arrays(...)` 适合你已经在 Python 侧拿到标准化行情对象或数组。
|
|
177
|
+
* 如果 CSV 或数组里出现非法浮点值,Rust 侧会发出 warning,并通过 AKQuant 的 Python `logging` 输出,而不是静默吞掉。
|
|
178
|
+
|
|
147
179
|
---
|
|
148
180
|
|
|
149
181
|
## 3. 多标的数据 (Multi-Symbol Data)
|
|
@@ -201,6 +201,32 @@ if __name__ == "__main__":
|
|
|
201
201
|
* `forward_worker_logs=True` 且主进程存在有效 logger handler:启用日志回传,不再显示“不可见”提示。
|
|
202
202
|
* `forward_worker_logs=True` 但主进程无有效 logger handler:会提示“请求了日志回传但主进程无可用 handler”。
|
|
203
203
|
|
|
204
|
+
推荐在运行优化前显式配置一次日志,尤其是你希望查看主进程聚合后的 worker 日志时:
|
|
205
|
+
|
|
206
|
+
```python
|
|
207
|
+
import akquant
|
|
208
|
+
|
|
209
|
+
akquant.configure_logging(
|
|
210
|
+
akquant.LogConfig(
|
|
211
|
+
profile="optimize",
|
|
212
|
+
level="INFO",
|
|
213
|
+
console=True,
|
|
214
|
+
filename="logs/optimize.log",
|
|
215
|
+
file_level="DEBUG",
|
|
216
|
+
file_json=True,
|
|
217
|
+
file_max_bytes=50_000_000,
|
|
218
|
+
file_backup_count=3,
|
|
219
|
+
)
|
|
220
|
+
)
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
说明:
|
|
224
|
+
|
|
225
|
+
* `profile="optimize"` 会在默认格式中带上进程名,便于区分不同 worker。
|
|
226
|
+
* `forward_worker_logs=True` 只负责“把子进程日志送回主进程”,不负责自动创建 handler。
|
|
227
|
+
* 如果你只想快速打开控制台日志,也可以继续使用 `akquant.register_logger(level="INFO")`。
|
|
228
|
+
* 如果你希望文件日志更方便被日志平台消费,可额外打开 `file_json=True`。
|
|
229
|
+
|
|
204
230
|
### 持久化与断点续传 (Persistence & Resume)
|
|
205
231
|
|
|
206
232
|
对于参数组合极多(如 > 10,000 组)的场景,单机运行可能需要数小时甚至数天。如果中途断电或程序崩溃,重新运行将非常耗时。AKQuant 支持将优化结果实时写入 SQLite 数据库,并支持断点续传。
|
|
@@ -348,6 +348,52 @@ def on_bar(self, bar):
|
|
|
348
348
|
self.log("资金不足", level=logging.WARNING)
|
|
349
349
|
```
|
|
350
350
|
|
|
351
|
+
如果你已经通过 `akquant.configure_logging(...)` 或 `akquant.register_logger(...)` 配置了日志处理器,`self.log()` 还会自动附带结构化上下文,便于在 `live` profile 或文件日志中排障:
|
|
352
|
+
|
|
353
|
+
* `phase`: 当前日志阶段,例如 `strategy`、`order`、`trade`
|
|
354
|
+
* `strategy_id` / `slot`: 多策略场景下的策略身份
|
|
355
|
+
* `symbol`: 当前标的
|
|
356
|
+
* `event_time`: 策略事件时间
|
|
357
|
+
* `order_id` / `client_order_id`: 在 `on_order` / `on_trade` / `on_reject` 内会自动补齐
|
|
358
|
+
|
|
359
|
+
最简单的方式仍然是兼容接口:
|
|
360
|
+
|
|
361
|
+
```python
|
|
362
|
+
import akquant
|
|
363
|
+
|
|
364
|
+
akquant.register_logger(level="INFO")
|
|
365
|
+
```
|
|
366
|
+
|
|
367
|
+
如果你想区分 research / optimize / live 场景,推荐使用结构化配置接口:
|
|
368
|
+
|
|
369
|
+
```python
|
|
370
|
+
import akquant
|
|
371
|
+
|
|
372
|
+
akquant.configure_logging(
|
|
373
|
+
akquant.LogConfig(
|
|
374
|
+
profile="live",
|
|
375
|
+
level="INFO",
|
|
376
|
+
console=True,
|
|
377
|
+
filename="logs/strategy.log",
|
|
378
|
+
file_level="DEBUG",
|
|
379
|
+
file_json=True,
|
|
380
|
+
file_max_bytes=10_000_000,
|
|
381
|
+
file_backup_count=5,
|
|
382
|
+
)
|
|
383
|
+
)
|
|
384
|
+
```
|
|
385
|
+
|
|
386
|
+
如果你要把日志送到日志平台或采集系统,也可以为控制台或文件单独开启 JSON 输出:
|
|
387
|
+
|
|
388
|
+
* `console_json=True`: 控制台输出 JSON line
|
|
389
|
+
* `file_json=True`: 文件输出 JSON line
|
|
390
|
+
|
|
391
|
+
实践建议:
|
|
392
|
+
|
|
393
|
+
* 人类阅读的调试信息优先用 `self.log()`
|
|
394
|
+
* 需要统一消费 `order/trade/progress/risk` 事件流时,优先用 `run_backtest(..., on_event=...)`
|
|
395
|
+
* 如果你在 `on_order`、`on_trade`、`on_reject` 里写 `self.log()`,通常不需要再手动拼接订单 id
|
|
396
|
+
|
|
351
397
|
### 3.2 便捷数据访问 (Data Access)
|
|
352
398
|
|
|
353
399
|
为了减少代码冗余,`Strategy` 类提供了当前 Bar/Tick 数据的快捷访问属性:
|
|
@@ -694,6 +694,101 @@ result = run_backtest(
|
|
|
694
694
|
* **页面化参数输入**: 在策略类中声明 `PARAM_MODEL`(`akquant.ParamModel`),并使用 `get_strategy_param_schema` / `validate_strategy_params` 完成前后端参数联动与校验。
|
|
695
695
|
* **参数调优**: 使用 `run_grid_search` 时,通常通过修改 Config 对象或传入 override 参数来实现。
|
|
696
696
|
|
|
697
|
+
### 日志配置 API (Logging)
|
|
698
|
+
|
|
699
|
+
AKQuant 作为库使用时默认保持静默;未显式配置前,`akquant` 根 logger 仅挂载 `NullHandler`。
|
|
700
|
+
|
|
701
|
+
#### `akquant.LogConfig`
|
|
702
|
+
|
|
703
|
+
高级日志配置对象,供 `configure_logging(...)` 使用。
|
|
704
|
+
|
|
705
|
+
核心字段:
|
|
706
|
+
|
|
707
|
+
* `level`: 全局回退等级。
|
|
708
|
+
* `console`: 是否启用控制台 handler。
|
|
709
|
+
* `console_level` / `file_level`: handler 级别覆盖。
|
|
710
|
+
* `console_format` / `file_format`: 文本 formatter 覆盖。
|
|
711
|
+
* `console_show_context` / `file_show_context`: 文本模式下是否附带结构化上下文。
|
|
712
|
+
* `console_json` / `file_json`: 是否对对应 handler 启用 JSON line 输出。
|
|
713
|
+
* `filename`: 文件日志路径。
|
|
714
|
+
* `file_mode`: 文件模式,默认 `a`。
|
|
715
|
+
* `file_max_bytes` / `file_backup_count`: 启用按大小轮转时的阈值与保留份数。
|
|
716
|
+
* `profile`: 预设 profile,支持 `research`、`optimize`、`live`。
|
|
717
|
+
* `reset_handlers`: 是否重置 AKQuant 自己管理的 handler。
|
|
718
|
+
* `propagate`: 是否向上游 logger 传播。
|
|
719
|
+
|
|
720
|
+
#### `akquant.configure_logging`
|
|
721
|
+
|
|
722
|
+
```python
|
|
723
|
+
def configure_logging(config: LogConfig) -> logging.Logger
|
|
724
|
+
```
|
|
725
|
+
|
|
726
|
+
使用结构化配置初始化或重配 `akquant` 日志系统。
|
|
727
|
+
|
|
728
|
+
推荐示例:
|
|
729
|
+
|
|
730
|
+
```python
|
|
731
|
+
import akquant
|
|
732
|
+
|
|
733
|
+
akquant.configure_logging(
|
|
734
|
+
akquant.LogConfig(
|
|
735
|
+
profile="live",
|
|
736
|
+
level="INFO",
|
|
737
|
+
console=True,
|
|
738
|
+
console_json=False,
|
|
739
|
+
filename="logs/live.log",
|
|
740
|
+
file_level="DEBUG",
|
|
741
|
+
file_json=True,
|
|
742
|
+
file_max_bytes=10_000_000,
|
|
743
|
+
file_backup_count=5,
|
|
744
|
+
)
|
|
745
|
+
)
|
|
746
|
+
```
|
|
747
|
+
|
|
748
|
+
行为说明:
|
|
749
|
+
|
|
750
|
+
* `profile` 只填充未显式指定的字段,显式参数优先级更高。
|
|
751
|
+
* `profile="optimize"` 默认文本格式会带 `processName`,便于区分 worker。
|
|
752
|
+
* `profile="live"` 适合打开结构化上下文或 JSON 输出。
|
|
753
|
+
|
|
754
|
+
#### `akquant.register_logger`
|
|
755
|
+
|
|
756
|
+
```python
|
|
757
|
+
def register_logger(
|
|
758
|
+
filename: Optional[str] = None,
|
|
759
|
+
console: bool = True,
|
|
760
|
+
level: str = "INFO",
|
|
761
|
+
) -> None
|
|
762
|
+
```
|
|
763
|
+
|
|
764
|
+
兼容快捷接口,适合快速打开日志,不暴露高级字段。内部会转成 `configure_logging(LogConfig(...))`。
|
|
765
|
+
|
|
766
|
+
#### `akquant.get_logger`
|
|
767
|
+
|
|
768
|
+
```python
|
|
769
|
+
def get_logger(name: Optional[str] = None) -> logging.Logger
|
|
770
|
+
```
|
|
771
|
+
|
|
772
|
+
获取 `akquant` 命名空间下的 logger:
|
|
773
|
+
|
|
774
|
+
* `get_logger()` -> `akquant`
|
|
775
|
+
* `get_logger("strategy")` -> `akquant.strategy`
|
|
776
|
+
* `get_logger("gateway.live")` -> `akquant.gateway.live`
|
|
777
|
+
|
|
778
|
+
#### `akquant.set_log_level`
|
|
779
|
+
|
|
780
|
+
```python
|
|
781
|
+
def set_log_level(level: Union[str, int]) -> None
|
|
782
|
+
```
|
|
783
|
+
|
|
784
|
+
修改当前 `akquant` 根 logger 的 level。
|
|
785
|
+
|
|
786
|
+
#### 使用边界
|
|
787
|
+
|
|
788
|
+
* `self.log(...)` 面向人类阅读的策略调试日志。
|
|
789
|
+
* `run_backtest(..., on_event=...)` 面向机器消费的统一事件流,更适合实时 UI、告警、审计落盘。
|
|
790
|
+
* 在 `on_order` / `on_trade` / `on_reject` 中使用 `self.log(...)` 时,日志会自动携带 `order_id` / `client_order_id` 等结构化字段。
|
|
791
|
+
|
|
697
792
|
## 2. 策略开发 (Strategy)
|
|
698
793
|
|
|
699
794
|
### `akquant.Strategy`
|
|
@@ -890,6 +985,30 @@ runner = LiveRunner(
|
|
|
890
985
|
* 期货费率接口统一使用复数命名 `set_futures_fee_rules*`。
|
|
891
986
|
* 旧单数命名 `set_future_fee_rules*` 已移除,不再对外暴露。
|
|
892
987
|
|
|
988
|
+
### `akquant.DataFeed`
|
|
989
|
+
|
|
990
|
+
`DataFeed` 是引擎内部的事件数据源封装,适合在你希望显式控制“数据如何进入引擎”时直接使用。
|
|
991
|
+
|
|
992
|
+
**构造与工厂方法:**
|
|
993
|
+
|
|
994
|
+
* `DataFeed()`: 创建一个空的历史数据源。
|
|
995
|
+
* `DataFeed.from_csv(path, symbol)`: 直接从 CSV 文件创建数据源;适合由 Rust 侧按行读取并驱动事件流。
|
|
996
|
+
* `DataFeed.create_live()`: 创建实时数据源,适合供 gateway / 行情推送场景写入事件。
|
|
997
|
+
|
|
998
|
+
**写入方法:**
|
|
999
|
+
|
|
1000
|
+
* `add_bar(bar)`: 向数据源追加单个 `Bar`。
|
|
1001
|
+
* `add_bars(bars)`: 向数据源批量追加 `Bar` 列表。
|
|
1002
|
+
* `add_tick(tick)`: 向实时数据源追加单个 `Tick`。
|
|
1003
|
+
* `add_arrays(timestamps, opens, highs, lows, closes, volumes, symbol)`: 通过数组快速批量构建 `Bar` 并注入数据源。
|
|
1004
|
+
* `sort()`: 对当前历史数据源按事件时间排序。
|
|
1005
|
+
|
|
1006
|
+
**使用边界:**
|
|
1007
|
+
|
|
1008
|
+
* 若你只是做普通回测,优先使用 `run_backtest(data=...)`,直接传 `DataFrame`、`List[Bar]` 或 `DataFeedAdapter` 即可。
|
|
1009
|
+
* 若你需要复用同一数据源对象、显式切换历史/实时模式,或直接接入 `Engine.add_data(feed)`,则使用 `DataFeed` 更合适。
|
|
1010
|
+
* `from_csv(...)` / `add_arrays(...)` 中如果遇到非法浮点值,Rust 侧会记录 warning,并通过 AKQuant 的 Python `logging` 体系输出,例如 `akquant.data.client`、`akquant.data.batch`。
|
|
1011
|
+
|
|
893
1012
|
### `akquant.gateway` 自定义 Broker 注册
|
|
894
1013
|
|
|
895
1014
|
可通过注册表机制按名称接入自定义 broker,而无需修改内置工厂分支。
|
|
@@ -11,6 +11,7 @@ except metadata.PackageNotFoundError:
|
|
|
11
11
|
__engine_rule_version__ = "1.0.0" # Increment on behavior-changing updates
|
|
12
12
|
|
|
13
13
|
from . import akquant as _akquant
|
|
14
|
+
from . import log as _log
|
|
14
15
|
from . import talib
|
|
15
16
|
from .akquant import * # noqa: F403
|
|
16
17
|
from .akquant import ATR, EMA, MACD, RSI, SMA, BollingerBands
|
|
@@ -56,7 +57,6 @@ from .indicator_stream import (
|
|
|
56
57
|
to_indicator_message,
|
|
57
58
|
to_indicator_messages,
|
|
58
59
|
)
|
|
59
|
-
from .log import get_logger, register_logger
|
|
60
60
|
from .optimize import OptimizationResult, run_grid_search, run_walk_forward
|
|
61
61
|
from .params import (
|
|
62
62
|
BoolParam,
|
|
@@ -85,6 +85,19 @@ from .utils import (
|
|
|
85
85
|
prepare_dataframe,
|
|
86
86
|
)
|
|
87
87
|
|
|
88
|
+
if typing.TYPE_CHECKING:
|
|
89
|
+
from .log import LogConfig as LogConfig # type: ignore[assignment]
|
|
90
|
+
from .log import configure_logging as configure_logging # type: ignore[assignment]
|
|
91
|
+
from .log import get_logger as get_logger
|
|
92
|
+
from .log import register_logger as register_logger
|
|
93
|
+
from .log import set_log_level as set_log_level
|
|
94
|
+
else:
|
|
95
|
+
globals()["LogConfig"] = _log.LogConfig
|
|
96
|
+
globals()["configure_logging"] = _log.configure_logging
|
|
97
|
+
globals()["get_logger"] = _log.get_logger
|
|
98
|
+
globals()["register_logger"] = _log.register_logger
|
|
99
|
+
globals()["set_log_level"] = _log.set_log_level
|
|
100
|
+
|
|
88
101
|
__doc__ = _akquant.__doc__
|
|
89
102
|
if hasattr(_akquant, "__all__"): # noqa: F405
|
|
90
103
|
__all__ = [name for name in _akquant.__all__ if name != "ExecutionMode"] + [ # noqa: F405
|
|
@@ -108,8 +121,11 @@ if hasattr(_akquant, "__all__"): # noqa: F405
|
|
|
108
121
|
"ParquetFeedAdapter",
|
|
109
122
|
"ResampledFeedAdapter",
|
|
110
123
|
"ReplayFeedAdapter",
|
|
124
|
+
"LogConfig",
|
|
125
|
+
"configure_logging",
|
|
111
126
|
"get_logger",
|
|
112
127
|
"register_logger",
|
|
128
|
+
"set_log_level",
|
|
113
129
|
"strategy_config",
|
|
114
130
|
"ChinaFuturesConfig",
|
|
115
131
|
"ChinaFuturesFeeConfig",
|
|
@@ -187,8 +203,11 @@ else:
|
|
|
187
203
|
"ParquetFeedAdapter",
|
|
188
204
|
"ResampledFeedAdapter",
|
|
189
205
|
"ReplayFeedAdapter",
|
|
206
|
+
"LogConfig",
|
|
207
|
+
"configure_logging",
|
|
190
208
|
"get_logger",
|
|
191
209
|
"register_logger",
|
|
210
|
+
"set_log_level",
|
|
192
211
|
"strategy_config",
|
|
193
212
|
"ChinaOptionsConfig",
|
|
194
213
|
"ChinaOptionsFeeConfig",
|