rqalpha 5.3.6__tar.gz → 5.3.8__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.
- {rqalpha-5.3.6/rqalpha.egg-info → rqalpha-5.3.8}/PKG-INFO +1 -1
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/_version.py +3 -3
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/data/base_data_source/data_source.py +5 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/data/base_data_source/storages.py +8 -7
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/data/bundle.py +102 -3
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/data/data_proxy.py +5 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/data/trading_dates_mixin.py +9 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/environment.py +2 -1
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/interface.py +14 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/main.py +3 -2
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/mod/rqalpha_mod_sys_accounts/position_model.py +12 -2
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/mod/rqalpha_mod_sys_simulation/matcher.py +1 -1
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/utils/testing/fixtures.py +1 -1
- {rqalpha-5.3.6 → rqalpha-5.3.8/rqalpha.egg-info}/PKG-INFO +1 -1
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha.egg-info/SOURCES.txt +4 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/setup.cfg +1 -1
- {rqalpha-5.3.6 → rqalpha-5.3.8}/tests/api_tests/mod/sys_simulation/test_simulation_broker.py +3 -0
- rqalpha-5.3.8/tests/test_f_delivery.py +42 -0
- rqalpha-5.3.8/tests/test_f_tick_size.py +67 -0
- rqalpha-5.3.8/tests/unittest/test_data/test_auto_update_bundle/__init__.py +7 -0
- rqalpha-5.3.8/tests/unittest/test_data/test_auto_update_bundle/test_auto_update_bundle_mixin.py +75 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/CHANGELOG.rst +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/LICENSE +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/MANIFEST.in +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/README.rst +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/__init__.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/__main__.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/api.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/apis/__init__.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/apis/api_abstract.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/apis/api_base.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/apis/api_rqdatac.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/apis/names.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/cmds/__init__.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/cmds/bundle.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/cmds/entry.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/cmds/misc.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/cmds/mod.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/cmds/run.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/config.yml +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/const.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/core/__init__.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/core/events.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/core/execution_context.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/core/executor.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/core/global_var.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/core/strategy.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/core/strategy_context.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/core/strategy_loader.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/core/strategy_universe.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/data/__init__.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/data/bar_dict_price_board.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/data/base_data_source/__init__.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/data/base_data_source/adjust.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/data/base_data_source/storage_interface.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/examples/IF1706_20161108.csv +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/examples/IF_macd.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/examples/buy_and_hold.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/examples/data_source/get_csv_module.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/examples/data_source/import_get_csv_module.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/examples/data_source/read_csv_as_df.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/examples/extend_api/rqalpha_mod_extend_api_demo.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/examples/extend_api/test_extend_api.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/examples/golden_cross.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/examples/macd.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/examples/pair_trading.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/examples/rsi.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/examples/run_code_demo.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/examples/run_file_demo.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/examples/run_func_demo.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/examples/subscribe_event.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/examples/test_pt.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/examples/turtle.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/mod/__init__.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/mod/rqalpha_mod_sys_accounts/__init__.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/mod/rqalpha_mod_sys_accounts/api/__init__.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/mod/rqalpha_mod_sys_accounts/api/api_future.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/mod/rqalpha_mod_sys_accounts/api/api_stock.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/mod/rqalpha_mod_sys_accounts/component_validator.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/mod/rqalpha_mod_sys_accounts/mod.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/mod/rqalpha_mod_sys_accounts/position_validator.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/mod/rqalpha_mod_sys_accounts/validator.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/mod/rqalpha_mod_sys_analyser/__init__.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/mod/rqalpha_mod_sys_analyser/mod.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/mod/rqalpha_mod_sys_analyser/plot/__init__.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/mod/rqalpha_mod_sys_analyser/plot/consts.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/mod/rqalpha_mod_sys_analyser/plot/plot.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/mod/rqalpha_mod_sys_analyser/plot/utils.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/mod/rqalpha_mod_sys_analyser/plot_store.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/mod/rqalpha_mod_sys_analyser/report/__init__.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/mod/rqalpha_mod_sys_analyser/report/excel_template.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/mod/rqalpha_mod_sys_analyser/report/report.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/mod/rqalpha_mod_sys_analyser/report/templates/summary.xlsx +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/mod/rqalpha_mod_sys_progress/__init__.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/mod/rqalpha_mod_sys_progress/mod.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/mod/rqalpha_mod_sys_risk/__init__.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/mod/rqalpha_mod_sys_risk/mod.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/mod/rqalpha_mod_sys_risk/validators/__init__.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/mod/rqalpha_mod_sys_risk/validators/cash_validator.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/mod/rqalpha_mod_sys_risk/validators/is_trading_validator.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/mod/rqalpha_mod_sys_risk/validators/price_validator.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/mod/rqalpha_mod_sys_risk/validators/self_trade_validator.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/mod/rqalpha_mod_sys_scheduler/__init__.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/mod/rqalpha_mod_sys_scheduler/mod.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/mod/rqalpha_mod_sys_scheduler/scheduler.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/mod/rqalpha_mod_sys_simulation/__init__.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/mod/rqalpha_mod_sys_simulation/mod.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/mod/rqalpha_mod_sys_simulation/signal_broker.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/mod/rqalpha_mod_sys_simulation/simulation_broker.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/mod/rqalpha_mod_sys_simulation/simulation_event_source.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/mod/rqalpha_mod_sys_simulation/slippage.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/mod/rqalpha_mod_sys_simulation/testing.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/mod/rqalpha_mod_sys_simulation/validator.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/mod/rqalpha_mod_sys_transaction_cost/__init__.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/mod/rqalpha_mod_sys_transaction_cost/deciders.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/mod/rqalpha_mod_sys_transaction_cost/mod.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/mod/utils.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/mod_config.yml +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/model/__init__.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/model/bar.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/model/instrument.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/model/order.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/model/tick.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/model/trade.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/portfolio/__init__.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/portfolio/account.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/portfolio/position.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/resource/ricequant-logo.png +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/user_module.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/utils/__init__.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/utils/arg_checker.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/utils/class_helper.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/utils/click_helper.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/utils/concurrent.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/utils/config.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/utils/datetime_func.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/utils/dict_func.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/utils/exception.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/utils/functools.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/utils/i18n.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/utils/log_capture.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/utils/logger.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/utils/package_helper.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/utils/persisit_helper.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/utils/repr.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/utils/risk_free_helper.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/utils/rq_json.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/utils/strategy_loader_help.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/utils/testing/__init__.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/utils/testing/mocking.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/utils/translations/__init__.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/utils/translations/zh_Hans_CN/LC_MESSAGES/__init__.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/utils/translations/zh_Hans_CN/LC_MESSAGES/messages.mo +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/utils/translations/zh_Hans_CN/LC_MESSAGES/messages.po +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/utils/translations/zh_Hans_CN/__init__.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha/utils/typing.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha.egg-info/dependency_links.txt +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha.egg-info/entry_points.txt +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha.egg-info/not-zip-safe +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha.egg-info/requires.txt +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/rqalpha.egg-info/top_level.txt +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/setup.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/tests/__init__.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/tests/api_tests/__init__.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/tests/api_tests/mod/__init__.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/tests/api_tests/mod/sys_accounts/__init__.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/tests/api_tests/mod/sys_accounts/test_account_model.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/tests/api_tests/mod/sys_accounts/test_futures_settlement_price_type.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/tests/api_tests/mod/sys_accounts/test_margin_stocks.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/tests/api_tests/mod/sys_accounts/test_position_models.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/tests/api_tests/mod/sys_scheduler/__init__.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/tests/api_tests/mod/sys_scheduler/test_physical_time.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/tests/api_tests/mod/sys_scheduler/test_scheduler.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/tests/api_tests/mod/sys_simulation/__init__.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/tests/api_tests/mod/sys_simulation/test_management_fee.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/tests/api_tests/mod/sys_simulation/test_match.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/tests/api_tests/mod/sys_simulation/test_signal_broker.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/tests/api_tests/mod/sys_simulation/test_simulation_event_source.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/tests/api_tests/mod/sys_transaction_cost/__init__.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/tests/api_tests/mod/sys_transaction_cost/test_commission_multiplier.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/tests/api_tests/test_api_base.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/tests/api_tests/test_api_future.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/tests/api_tests/test_api_stock.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/tests/api_tests/test_config.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/tests/api_tests/utils.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/tests/test_f_buy_and_hold.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/tests/test_f_macd.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/tests/test_f_macd_signal.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/tests/test_f_mean_reverting.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/tests/test_s_buy_and_hold.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/tests/test_s_dual_thrust.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/tests/test_s_pit_tax.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/tests/test_s_scheduler.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/tests/test_s_tick_size.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/tests/test_s_turtle.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/tests/test_s_turtle_signal.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/tests/test_sf_buy_and_hold.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/tests/unittest/__init__.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/tests/unittest/test_data/__init__.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/tests/unittest/test_data/test_instrument_mixin.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/tests/unittest/test_data/test_trading_dates_mixin.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/tests/unittest/test_mod/__init__.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/tests/unittest/test_mod/test_sys_simulation/__init__.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/tests/unittest/test_mod/test_sys_simulation/test_simulation_event_source.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/tests/utils.py +0 -0
- {rqalpha-5.3.6 → rqalpha-5.3.8}/versioneer.py +0 -0
|
@@ -8,11 +8,11 @@ import json
|
|
|
8
8
|
|
|
9
9
|
version_json = '''
|
|
10
10
|
{
|
|
11
|
-
"date": "2024-
|
|
11
|
+
"date": "2024-03-27T18:19:51+0800",
|
|
12
12
|
"dirty": false,
|
|
13
13
|
"error": null,
|
|
14
|
-
"full-revisionid": "
|
|
15
|
-
"version": "5.3.
|
|
14
|
+
"full-revisionid": "7322d2b4d1da97bcde04288d0bd114624dc4c6d2",
|
|
15
|
+
"version": "5.3.8"
|
|
16
16
|
}
|
|
17
17
|
''' # END VERSION_JSON
|
|
18
18
|
|
|
@@ -400,3 +400,8 @@ class BaseDataSource(AbstractDataSource):
|
|
|
400
400
|
|
|
401
401
|
def get_algo_bar(self, id_or_ins, start_min, end_min, dt):
|
|
402
402
|
raise NotImplementedError("open source rqalpha not support algo order")
|
|
403
|
+
|
|
404
|
+
def get_open_auction_volume(self, instrument, dt):
|
|
405
|
+
# type: (Instrument, datetime.datetime) -> float
|
|
406
|
+
volume = self.get_open_auction_bar(instrument, dt)['volume']
|
|
407
|
+
return volume
|
|
@@ -100,14 +100,15 @@ class FutureInfoStore(object):
|
|
|
100
100
|
|
|
101
101
|
def _to_namedtuple(self, info):
|
|
102
102
|
# type: (dict) -> FuturesTradingParameters
|
|
103
|
-
|
|
104
|
-
|
|
103
|
+
futures_info = copy(info)
|
|
104
|
+
futures_info['long_margin_ratio'], futures_info['short_margin_ratio'] = futures_info['margin_rate'], futures_info['margin_rate']
|
|
105
|
+
del futures_info['margin_rate'], futures_info['tick_size']
|
|
105
106
|
try:
|
|
106
|
-
del
|
|
107
|
+
del futures_info['order_book_id']
|
|
107
108
|
except KeyError:
|
|
108
|
-
del
|
|
109
|
-
|
|
110
|
-
return
|
|
109
|
+
del futures_info['underlying_symbol']
|
|
110
|
+
futures_info = FuturesTradingParameters(**futures_info)
|
|
111
|
+
return futures_info
|
|
111
112
|
|
|
112
113
|
@lru_cache(8)
|
|
113
114
|
def get_tick_size(self, instrument):
|
|
@@ -115,7 +116,7 @@ class FutureInfoStore(object):
|
|
|
115
116
|
order_book_id = instrument.order_book_id
|
|
116
117
|
underlying_symbol = instrument.underlying_symbol
|
|
117
118
|
custom_info = self._custom_data.get(order_book_id) or self._custom_data.get(underlying_symbol)
|
|
118
|
-
info = self._default_data.get(order_book_id) or self.
|
|
119
|
+
info = self._default_data.get(order_book_id) or self._default_data.get(underlying_symbol)
|
|
119
120
|
if custom_info:
|
|
120
121
|
info = copy(info) or {}
|
|
121
122
|
info.update(custom_info)
|
|
@@ -18,17 +18,23 @@ import os
|
|
|
18
18
|
import pickle
|
|
19
19
|
import re
|
|
20
20
|
from itertools import chain
|
|
21
|
+
from typing import Callable, Optional, List
|
|
21
22
|
|
|
22
23
|
import h5py
|
|
23
24
|
import numpy as np
|
|
25
|
+
import pandas as pd
|
|
24
26
|
from rqalpha.apis.api_rqdatac import rqdatac
|
|
25
27
|
from rqalpha.utils.concurrent import (ProgressedProcessPoolExecutor,
|
|
26
28
|
ProgressedTask)
|
|
27
29
|
from rqalpha.utils.datetime_func import (convert_date_to_date_int,
|
|
28
|
-
convert_date_to_int)
|
|
30
|
+
convert_date_to_int,)
|
|
29
31
|
from rqalpha.utils.exception import RQDatacVersionTooLow
|
|
30
32
|
from rqalpha.utils.i18n import gettext as _
|
|
31
|
-
from rqalpha.utils.logger import system_log
|
|
33
|
+
from rqalpha.utils.logger import system_log
|
|
34
|
+
from rqalpha.const import TRADING_CALENDAR_TYPE
|
|
35
|
+
from rqalpha.utils.functools import lru_cache
|
|
36
|
+
from rqalpha.environment import Environment
|
|
37
|
+
from rqalpha.model.instrument import Instrument
|
|
32
38
|
|
|
33
39
|
START_DATE = 20050104
|
|
34
40
|
END_DATE = 29991231
|
|
@@ -519,10 +525,10 @@ class FuturesTradingParametersTask(object):
|
|
|
519
525
|
if recreate_futures_list:
|
|
520
526
|
self.generate_futures_trading_parameters(path, fields, last_date, recreate_futures_list=recreate_futures_list)
|
|
521
527
|
if end_date > last_date:
|
|
522
|
-
system_log.info(_("Futures historical trading parameters data is being updated, please wait......"))
|
|
523
528
|
if rqdatac.get_previous_trading_date(end_date) == last_date:
|
|
524
529
|
return
|
|
525
530
|
else:
|
|
531
|
+
system_log.info(_("Futures historical trading parameters data is being updated, please wait......"))
|
|
526
532
|
start_date = rqdatac.get_next_trading_date(last_date)
|
|
527
533
|
df = rqdatac.futures.get_trading_parameters(self._order_book_ids, start_date, end_date, fields)
|
|
528
534
|
if not(df is None or df.empty):
|
|
@@ -624,3 +630,96 @@ def update_futures_trading_parameters(path, end_date):
|
|
|
624
630
|
FUTURES_TRADING_PARAMETERS_FIELDS,
|
|
625
631
|
end_date
|
|
626
632
|
)
|
|
633
|
+
|
|
634
|
+
|
|
635
|
+
class AutomaticUpdateBundle(object):
|
|
636
|
+
def __init__(self, path: str, filename: str, api: Callable, fields: List[str], end_date: datetime.date) -> None:
|
|
637
|
+
if not os.path.exists(path):
|
|
638
|
+
os.makedirs(path)
|
|
639
|
+
self._file = os.path.join(path, filename)
|
|
640
|
+
self._trading_dates = None
|
|
641
|
+
self._filename = filename
|
|
642
|
+
self._api = api
|
|
643
|
+
self._fields = fields
|
|
644
|
+
self._end_date = end_date
|
|
645
|
+
self.updated = []
|
|
646
|
+
self._env = Environment.get_instance()
|
|
647
|
+
|
|
648
|
+
def get_data(self, instrument: Instrument, dt: datetime.date) -> Optional[np.ndarray]:
|
|
649
|
+
dt = convert_date_to_date_int(dt)
|
|
650
|
+
data = self._get_data_all_time(instrument)
|
|
651
|
+
if data is None:
|
|
652
|
+
return data
|
|
653
|
+
else:
|
|
654
|
+
try:
|
|
655
|
+
data = data[np.searchsorted(data['trading_dt'], dt)]
|
|
656
|
+
except IndexError:
|
|
657
|
+
data = None
|
|
658
|
+
return data
|
|
659
|
+
|
|
660
|
+
@lru_cache(128)
|
|
661
|
+
def _get_data_all_time(self, instrument: Instrument) -> Optional[np.ndarray]:
|
|
662
|
+
if instrument.order_book_id not in self.updated:
|
|
663
|
+
self._auto_update_task(instrument)
|
|
664
|
+
self.updated.append(instrument.order_book_id)
|
|
665
|
+
with h5py.File(self._file, "r") as h5:
|
|
666
|
+
data = h5[instrument.order_book_id][:]
|
|
667
|
+
if len(data) == 0:
|
|
668
|
+
return None
|
|
669
|
+
return data
|
|
670
|
+
|
|
671
|
+
def _auto_update_task(self, instrument: Instrument) -> None:
|
|
672
|
+
"""
|
|
673
|
+
在 rqalpha 策略运行过程中自动更新所需的日线数据
|
|
674
|
+
|
|
675
|
+
:param instrument: 合约对象
|
|
676
|
+
:type instrument: `Instrument`
|
|
677
|
+
"""
|
|
678
|
+
order_book_id = instrument.order_book_id
|
|
679
|
+
start_date = START_DATE
|
|
680
|
+
try:
|
|
681
|
+
h5 = h5py.File(self._file, "a")
|
|
682
|
+
if order_book_id in h5:
|
|
683
|
+
if len(h5[order_book_id][:]) != 0:
|
|
684
|
+
last_date = datetime.datetime.strptime(str(h5[order_book_id][-1]['trading_dt']), "%Y%m%d").date()
|
|
685
|
+
if last_date >= self._end_date:
|
|
686
|
+
return
|
|
687
|
+
start_date = self._env.data_proxy._data_source.get_next_trading_date(last_date).date()
|
|
688
|
+
if start_date > self._end_date:
|
|
689
|
+
return
|
|
690
|
+
arr = self._get_array(instrument, start_date)
|
|
691
|
+
if arr is None:
|
|
692
|
+
if order_book_id not in h5:
|
|
693
|
+
arr = np.array([])
|
|
694
|
+
h5.create_dataset(order_book_id, data=arr)
|
|
695
|
+
else:
|
|
696
|
+
if order_book_id in h5:
|
|
697
|
+
data = np.array(
|
|
698
|
+
[tuple(i) for i in chain(h5[order_book_id][:], arr)],
|
|
699
|
+
dtype=h5[order_book_id].dtype)
|
|
700
|
+
del h5[order_book_id]
|
|
701
|
+
h5.create_dataset(order_book_id, data=data)
|
|
702
|
+
else:
|
|
703
|
+
h5.create_dataset(order_book_id, data=arr)
|
|
704
|
+
except OSError as e:
|
|
705
|
+
raise OSError(_("File {} update failed, if it is using, please update later, "
|
|
706
|
+
"or you can delete then update again".format(self._file))) from e
|
|
707
|
+
finally:
|
|
708
|
+
h5.close()
|
|
709
|
+
|
|
710
|
+
def _get_array(self, instrument: Instrument, start_date: datetime.date) -> Optional[np.ndarray]:
|
|
711
|
+
df = self._api(instrument.order_book_id, start_date, self._end_date, self._fields)
|
|
712
|
+
if not (df is None or df.empty):
|
|
713
|
+
df = df[self._fields].loc[instrument.order_book_id] # rqdatac.get_open_auction_info get Futures's data will auto add 'open_interest' and 'prev_settlement'
|
|
714
|
+
record = df.iloc[0: 1].to_records()
|
|
715
|
+
dtype = [('trading_dt', 'int')]
|
|
716
|
+
for field in self._fields:
|
|
717
|
+
dtype.append((field, record.dtype[field]))
|
|
718
|
+
trading_dt = self._env.data_proxy._data_source.batch_get_trading_date(df.index)
|
|
719
|
+
trading_dt = convert_date_to_date_int(trading_dt)
|
|
720
|
+
arr = np.ones((trading_dt.shape[0], ), dtype=dtype)
|
|
721
|
+
arr['trading_dt'] = trading_dt
|
|
722
|
+
for field in self._fields:
|
|
723
|
+
arr[field] = df[field].values
|
|
724
|
+
return arr
|
|
725
|
+
return None
|
|
@@ -185,6 +185,11 @@ class DataProxy(TradingDatesMixin):
|
|
|
185
185
|
"datetime", "open", "limit_up", "limit_down", "volume", "total_turnover"
|
|
186
186
|
]}
|
|
187
187
|
return PartialBarObject(instrument, bar)
|
|
188
|
+
|
|
189
|
+
def get_open_auction_volume(self, order_book_id, dt):
|
|
190
|
+
instrument = self.instruments(order_book_id)
|
|
191
|
+
volume = self._data_source.get_open_auction_volume(instrument, dt)
|
|
192
|
+
return volume
|
|
188
193
|
|
|
189
194
|
def history(self, order_book_id, bar_count, frequency, field, dt):
|
|
190
195
|
data = self.history_bars(order_book_id, bar_count, frequency,
|
|
@@ -19,6 +19,7 @@ import datetime
|
|
|
19
19
|
from typing import Dict, Optional, Union
|
|
20
20
|
|
|
21
21
|
import pandas as pd
|
|
22
|
+
import numpy as np
|
|
22
23
|
|
|
23
24
|
from rqalpha.utils.functools import lru_cache
|
|
24
25
|
from rqalpha.const import TRADING_CALENDAR_TYPE
|
|
@@ -114,3 +115,11 @@ class TradingDatesMixin(object):
|
|
|
114
115
|
return trading_dates[pos + 1]
|
|
115
116
|
|
|
116
117
|
return td
|
|
118
|
+
|
|
119
|
+
def batch_get_trading_date(self, dt_index: pd.DatetimeIndex):
|
|
120
|
+
# 获取 numpy.array 中所有时间所在的交易日
|
|
121
|
+
# 认为晚八点后为第二个交易日,认为晚八点至次日凌晨四点为夜盘
|
|
122
|
+
dt = dt_index - datetime.timedelta(hours=4)
|
|
123
|
+
trading_dates = self.get_trading_calendar(TRADING_CALENDAR_TYPE.EXCHANGE)
|
|
124
|
+
pos = trading_dates.searchsorted(dt.date) + np.where(dt.hour >= 16, 1, 0)
|
|
125
|
+
return trading_dates[pos]
|
|
@@ -30,7 +30,7 @@ from rqalpha.utils.i18n import gettext as _
|
|
|
30
30
|
class Environment(object):
|
|
31
31
|
_env = None # type: Environment
|
|
32
32
|
|
|
33
|
-
def __init__(self, config):
|
|
33
|
+
def __init__(self, config, rqdatac_init):
|
|
34
34
|
Environment._env = self
|
|
35
35
|
self.config = config
|
|
36
36
|
self.data_proxy = None # type: Optional[rqalpha.data.data_proxy.DataProxy]
|
|
@@ -55,6 +55,7 @@ class Environment(object):
|
|
|
55
55
|
self._frontend_validators = {} # type: Dict[str, List]
|
|
56
56
|
self._default_frontend_validators = []
|
|
57
57
|
self._transaction_cost_decider_dict = {}
|
|
58
|
+
self.rqdatac_init = rqdatac_init # type: Boolean
|
|
58
59
|
|
|
59
60
|
# Environment.event_bus used in StrategyUniverse()
|
|
60
61
|
from rqalpha.core.strategy_universe import StrategyUniverse
|
|
@@ -347,6 +347,20 @@ class AbstractDataSource(object):
|
|
|
347
347
|
datetime, open, limit_up, limit_down, volume, total_turnover
|
|
348
348
|
"""
|
|
349
349
|
raise NotImplementedError
|
|
350
|
+
|
|
351
|
+
def get_open_auction_volume(self, instrument, dt):
|
|
352
|
+
"""
|
|
353
|
+
获取指定资产当日的集合竞价成交量
|
|
354
|
+
|
|
355
|
+
:param instrument: 合约对象
|
|
356
|
+
:type instrument: class:`~Instrument`
|
|
357
|
+
|
|
358
|
+
:param dt: 集合竞价时间
|
|
359
|
+
:type dt: datetime.datetime
|
|
360
|
+
|
|
361
|
+
:return: `float`
|
|
362
|
+
"""
|
|
363
|
+
raise NotImplementedError
|
|
350
364
|
|
|
351
365
|
def get_settle_price(self, instrument, date):
|
|
352
366
|
"""
|
|
@@ -122,12 +122,14 @@ def init_rqdatac(rqdatac_uri):
|
|
|
122
122
|
init_rqdatac_env(rqdatac_uri)
|
|
123
123
|
try:
|
|
124
124
|
rqdatac.init()
|
|
125
|
+
return True
|
|
125
126
|
except Exception as e:
|
|
126
127
|
system_log.warn(_('rqdatac init failed, some apis will not function properly: {}').format(str(e)))
|
|
128
|
+
return
|
|
127
129
|
|
|
128
130
|
|
|
129
131
|
def run(config, source_code=None, user_funcs=None):
|
|
130
|
-
env = Environment(config)
|
|
132
|
+
env = Environment(config, init_rqdatac(getattr(config.base, 'rqdatac_uri', None)))
|
|
131
133
|
persist_helper = None
|
|
132
134
|
init_succeed = False
|
|
133
135
|
mod_handler = ModHandler()
|
|
@@ -136,7 +138,6 @@ def run(config, source_code=None, user_funcs=None):
|
|
|
136
138
|
# avoid register handlers everytime
|
|
137
139
|
# when running in ipython
|
|
138
140
|
set_loggers(config)
|
|
139
|
-
init_rqdatac(getattr(config.base, 'rqdatac_uri', None))
|
|
140
141
|
system_log.debug("\n" + pformat(config.convert_to_dict()))
|
|
141
142
|
|
|
142
143
|
env.set_strategy_loader(init_strategy_loader(env, source_code, user_funcs, config))
|
|
@@ -191,9 +191,13 @@ class StockPosition(Position):
|
|
|
191
191
|
round_lot = self._instrument.round_lot
|
|
192
192
|
amount = int(Decimal(amount) / Decimal(round_lot)) * round_lot
|
|
193
193
|
if amount > 0:
|
|
194
|
-
self.
|
|
194
|
+
account = self._env.get_account(self._order_book_id)
|
|
195
|
+
trade = Trade.__from_create__(
|
|
195
196
|
None, last_price, amount, SIDE.BUY, POSITION_EFFECT.OPEN, self._order_book_id
|
|
196
|
-
)
|
|
197
|
+
)
|
|
198
|
+
trade._commission = self._env.get_trade_commission(trade)
|
|
199
|
+
trade._tax = self._env.get_trade_tax(trade)
|
|
200
|
+
self._env.event_bus.publish_event(Event(EVENT.TRADE, account=account, trade=trade, order=None))
|
|
197
201
|
return dividend_value - amount * last_price
|
|
198
202
|
else:
|
|
199
203
|
return dividend_value
|
|
@@ -314,6 +318,12 @@ class FuturePosition(Position):
|
|
|
314
318
|
user_system_log.warn(_(u"{order_book_id} is expired, close all positions by system").format(
|
|
315
319
|
order_book_id=self._order_book_id
|
|
316
320
|
))
|
|
321
|
+
account = self._env.get_account(self._order_book_id)
|
|
322
|
+
side = SIDE.SELL if self.direction == POSITION_DIRECTION.LONG else SIDE.BUY
|
|
323
|
+
trade = Trade.__from_create__(
|
|
324
|
+
None, self.last_price, self._quantity, side, POSITION_EFFECT.CLOSE, self._order_book_id
|
|
325
|
+
)
|
|
326
|
+
self._env.event_bus.publish_event(Event(EVENT.TRADE, account=account, trade=trade, order=None))
|
|
317
327
|
self._quantity = self._old_quantity = 0
|
|
318
328
|
return delta_cash
|
|
319
329
|
|
|
@@ -85,7 +85,7 @@ class DefaultBarMatcher(AbstractMatcher):
|
|
|
85
85
|
|
|
86
86
|
def _get_bar_volume(self, order, open_auction=False):
|
|
87
87
|
if open_auction:
|
|
88
|
-
volume = self._env.data_proxy.
|
|
88
|
+
volume = self._env.data_proxy.get_open_auction_volume(order.order_book_id, self._env.trading_dt)
|
|
89
89
|
else:
|
|
90
90
|
if isinstance(order.style, ALGO_ORDER_STYLES):
|
|
91
91
|
_, volume = self._env.data_proxy.get_algo_bar(order.order_book_id, order.style, self._env.calendar_dt)
|
|
@@ -26,7 +26,7 @@ class EnvironmentFixture(RQAlphaFixture):
|
|
|
26
26
|
from rqalpha.environment import Environment
|
|
27
27
|
|
|
28
28
|
super(EnvironmentFixture, self).init_fixture()
|
|
29
|
-
self.env = Environment(RqAttrDict(self.env_config))
|
|
29
|
+
self.env = Environment(RqAttrDict(self.env_config), False)
|
|
30
30
|
|
|
31
31
|
@contextmanager
|
|
32
32
|
def mock_env_method(self, name, mock_method):
|
|
@@ -157,9 +157,11 @@ rqalpha/utils/translations/zh_Hans_CN/LC_MESSAGES/messages.mo
|
|
|
157
157
|
rqalpha/utils/translations/zh_Hans_CN/LC_MESSAGES/messages.po
|
|
158
158
|
tests/__init__.py
|
|
159
159
|
tests/test_f_buy_and_hold.py
|
|
160
|
+
tests/test_f_delivery.py
|
|
160
161
|
tests/test_f_macd.py
|
|
161
162
|
tests/test_f_macd_signal.py
|
|
162
163
|
tests/test_f_mean_reverting.py
|
|
164
|
+
tests/test_f_tick_size.py
|
|
163
165
|
tests/test_s_buy_and_hold.py
|
|
164
166
|
tests/test_s_dual_thrust.py
|
|
165
167
|
tests/test_s_pit_tax.py
|
|
@@ -196,6 +198,8 @@ tests/unittest/__init__.py
|
|
|
196
198
|
tests/unittest/test_data/__init__.py
|
|
197
199
|
tests/unittest/test_data/test_instrument_mixin.py
|
|
198
200
|
tests/unittest/test_data/test_trading_dates_mixin.py
|
|
201
|
+
tests/unittest/test_data/test_auto_update_bundle/__init__.py
|
|
202
|
+
tests/unittest/test_data/test_auto_update_bundle/test_auto_update_bundle_mixin.py
|
|
199
203
|
tests/unittest/test_mod/__init__.py
|
|
200
204
|
tests/unittest/test_mod/test_sys_simulation/__init__.py
|
|
201
205
|
tests/unittest/test_mod/test_sys_simulation/test_simulation_event_source.py
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import datetime
|
|
2
|
+
|
|
3
|
+
def init(context):
|
|
4
|
+
context.f1 = "IH2402"
|
|
5
|
+
context.f2 = "IC2402"
|
|
6
|
+
context.fired = False
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def handle_bar(context, bar_dict):
|
|
10
|
+
if not context.fired:
|
|
11
|
+
buy_open(context.f1, 3)
|
|
12
|
+
sell_open(context.f2, 3)
|
|
13
|
+
context.fired = True
|
|
14
|
+
if bar_dict._dt.date() == datetime.date(2024, 2, 19):
|
|
15
|
+
context.cash_before_delivery = context.portfolio.cash
|
|
16
|
+
context.daily_pnl = context.portfolio.daily_pnl
|
|
17
|
+
if bar_dict._dt.date() == datetime.date(2024, 2, 20):
|
|
18
|
+
assert get_position(context.f1).quantity == 0
|
|
19
|
+
assert get_position(context.f2).quantity == 0
|
|
20
|
+
assert abs(context.portfolio.cash - (((2363 * 300) + (5105.6 * 200)) * 0.12 * 3 + context.cash_before_delivery + context.daily_pnl)) < 0.0000001
|
|
21
|
+
assert context.portfolio.total_value == context.portfolio.cash
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
__config__ = {
|
|
25
|
+
"base": {
|
|
26
|
+
"start_date": "2024-02-05",
|
|
27
|
+
"end_date": "2024-02-20",
|
|
28
|
+
"frequency": "1d",
|
|
29
|
+
"accounts": {
|
|
30
|
+
"future": 10000000,
|
|
31
|
+
},
|
|
32
|
+
},
|
|
33
|
+
"extra": {
|
|
34
|
+
"log_level": "error",
|
|
35
|
+
},
|
|
36
|
+
"mod": {
|
|
37
|
+
"sys_progress": {
|
|
38
|
+
"enabled":True,
|
|
39
|
+
"show": True,
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
from rqalpha.environment import Environment
|
|
2
|
+
|
|
3
|
+
SLIPPAGE = 10
|
|
4
|
+
price = 0
|
|
5
|
+
futures_1 = "AG1702" # future_info.json 中存有该合约的数据
|
|
6
|
+
futures_2 = "AG1612" # future_info.json 中不存在该合约的数据,需要通过 underlying_symbol 获取
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def init(context):
|
|
10
|
+
context.count = 0
|
|
11
|
+
|
|
12
|
+
subscribe_event(EVENT.TRADE, on_trade)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def on_trade(context, event):
|
|
16
|
+
|
|
17
|
+
global price
|
|
18
|
+
trade = event.trade
|
|
19
|
+
order_book_id = trade.order_book_id
|
|
20
|
+
tick_size = Environment.get_instance().get_instrument(order_book_id).tick_size()
|
|
21
|
+
assert tick_size == 1.0
|
|
22
|
+
assert trade.last_price == price + tick_size * SLIPPAGE
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def before_trading(context):
|
|
26
|
+
pass
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def handle_bar(context, bar_dict):
|
|
30
|
+
global price
|
|
31
|
+
context.count += 1
|
|
32
|
+
if context.count == 1:
|
|
33
|
+
price = bar_dict[futures_1].close
|
|
34
|
+
buy_open(futures_1, 10)
|
|
35
|
+
elif context.count == 2:
|
|
36
|
+
price = bar_dict[futures_2].close
|
|
37
|
+
buy_open(futures_2, 10)
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def after_trading(context):
|
|
41
|
+
pass
|
|
42
|
+
|
|
43
|
+
__config__ = {
|
|
44
|
+
"base": {
|
|
45
|
+
"start_date": "2016-09-01",
|
|
46
|
+
"end_date": "2016-09-30",
|
|
47
|
+
"frequency": "1d",
|
|
48
|
+
"matching_type": "current_bar",
|
|
49
|
+
"accounts": {
|
|
50
|
+
"future": 1000000
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
"extra": {
|
|
54
|
+
"log_level": "error",
|
|
55
|
+
},
|
|
56
|
+
"mod": {
|
|
57
|
+
"sys_progress": {
|
|
58
|
+
"enabled": True,
|
|
59
|
+
"show": True,
|
|
60
|
+
},
|
|
61
|
+
"sys_simulation": {
|
|
62
|
+
"signal": True,
|
|
63
|
+
"slippage_model": "TickSizeSlippage",
|
|
64
|
+
"slippage": SLIPPAGE,
|
|
65
|
+
}
|
|
66
|
+
},
|
|
67
|
+
}
|
rqalpha-5.3.8/tests/unittest/test_data/test_auto_update_bundle/test_auto_update_bundle_mixin.py
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
# 版权所有 2019 深圳米筐科技有限公司(下称“米筐科技”)
|
|
3
|
+
#
|
|
4
|
+
# 除非遵守当前许可,否则不得使用本软件。
|
|
5
|
+
#
|
|
6
|
+
# * 非商业用途(非商业用途指个人出于非商业目的使用本软件,或者高校、研究所等非营利机构出于教育、科研等目的使用本软件):
|
|
7
|
+
# 遵守 Apache License 2.0(下称“Apache 2.0 许可”),您可以在以下位置获得 Apache 2.0 许可的副本:http://www.apache.org/licenses/LICENSE-2.0。
|
|
8
|
+
# 除非法律有要求或以书面形式达成协议,否则本软件分发时需保持当前许可“原样”不变,且不得附加任何条件。
|
|
9
|
+
#
|
|
10
|
+
# * 商业用途(商业用途指个人出于任何商业目的使用本软件,或者法人或其他组织出于任何目的使用本软件):
|
|
11
|
+
# 未经米筐科技授权,任何个人不得出于任何商业目的使用本软件(包括但不限于向第三方提供、销售、出租、出借、转让本软件、本软件的衍生产品、引用或借鉴了本软件功能或源代码的产品或服务),任何法人或其他组织不得出于任何目的使用本软件,否则米筐科技有权追究相应的知识产权侵权责任。
|
|
12
|
+
# 在此前提下,对本软件的使用同样需要遵守 Apache 2.0 许可,Apache 2.0 许可与本许可冲突之处,以本许可为准。
|
|
13
|
+
# 详细的授权流程,请联系 public@ricequant.com 获取。
|
|
14
|
+
|
|
15
|
+
import os
|
|
16
|
+
import datetime
|
|
17
|
+
import pickle
|
|
18
|
+
import tempfile
|
|
19
|
+
|
|
20
|
+
from rqalpha.utils.testing import DataProxyFixture, RQAlphaTestCase
|
|
21
|
+
from rqalpha.data.bundle import AutomaticUpdateBundle
|
|
22
|
+
from rqalpha.data.trading_dates_mixin import TradingDatesMixin
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class AutomaticUpdateBundleTestCase(DataProxyFixture, RQAlphaTestCase):
|
|
26
|
+
def __init__(self, *args, **kwargs):
|
|
27
|
+
super(AutomaticUpdateBundleTestCase, self).__init__(*args, **kwargs)
|
|
28
|
+
self._path = tempfile.TemporaryDirectory().name
|
|
29
|
+
|
|
30
|
+
def init_fixture(self):
|
|
31
|
+
super(AutomaticUpdateBundleTestCase, self).init_fixture()
|
|
32
|
+
self._auto_update_bundle_module = AutomaticUpdateBundle(
|
|
33
|
+
path=self._path,
|
|
34
|
+
filename="open_auction_volume.h5",
|
|
35
|
+
api=self._mock_get_open_auction_info,
|
|
36
|
+
fields=['volume'],
|
|
37
|
+
end_date=datetime.date(2024, 2, 28),
|
|
38
|
+
)
|
|
39
|
+
trading_dates_mixin = TradingDatesMixin(self.base_data_source.get_trading_calendars())
|
|
40
|
+
self.base_data_source.batch_get_trading_date = trading_dates_mixin.batch_get_trading_date
|
|
41
|
+
self.base_data_source.get_next_trading_date = trading_dates_mixin.get_next_trading_date
|
|
42
|
+
|
|
43
|
+
def _mock_get_open_auction_info(self, order_book_id, *args, **kwargs):
|
|
44
|
+
df = pickle.loads(open(
|
|
45
|
+
os.path.join(os.path.dirname(__file__), "mock_data/mock_open_auction_info.pkl"), "rb"
|
|
46
|
+
).read())
|
|
47
|
+
df = df.loc[order_book_id].reset_index()
|
|
48
|
+
df['order_book_id'] = order_book_id
|
|
49
|
+
df = df.set_index(["order_book_id", "datetime"])
|
|
50
|
+
return df
|
|
51
|
+
|
|
52
|
+
def _mock_get_open_auction_volume(self, instrument, dt):
|
|
53
|
+
# type: (Instrument, datetime.date) -> float
|
|
54
|
+
data = self._auto_update_bundle_module.get_data(instrument, dt)
|
|
55
|
+
if data is None:
|
|
56
|
+
volume = 0
|
|
57
|
+
else:
|
|
58
|
+
volume = 0 if len(data) == 0 else data['volume']
|
|
59
|
+
return volume
|
|
60
|
+
|
|
61
|
+
def test_auto_update_bundle(self):
|
|
62
|
+
s_volume = self._mock_get_open_auction_volume(self.env.get_instrument("000001.XSHE"), datetime.date(2023, 12, 28))
|
|
63
|
+
f_volume = self._mock_get_open_auction_volume(self.env.get_instrument("A2401"), datetime.date(2023, 12, 28))
|
|
64
|
+
assert os.path.exists(os.path.join(self._path, "open_auction_volume.h5")) == True
|
|
65
|
+
|
|
66
|
+
pickle_data = pickle.loads(open(
|
|
67
|
+
os.path.join(os.path.dirname(__file__), "mock_data/mock_open_auction_info.pkl"), "rb"
|
|
68
|
+
).read())
|
|
69
|
+
|
|
70
|
+
s_df = pickle_data.loc["000001.XSHE"]
|
|
71
|
+
assert s_volume == s_df[s_df.index.date == datetime.date(2023, 12, 28)].volume[0]
|
|
72
|
+
f_df = pickle_data.loc['A2401']
|
|
73
|
+
# 期货由于有夜盘,open_auction_info 的时间为前一个交易日的晚上,即从 pickle 文件中获取时,date 应该提前一个交易日
|
|
74
|
+
assert f_volume == f_df[f_df.index.date == datetime.date(2023, 12, 27)].volume[0]
|
|
75
|
+
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|