rqalpha 5.3.11__tar.gz → 5.4.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {rqalpha-5.3.11/rqalpha.egg-info → rqalpha-5.4.0}/PKG-INFO +1 -1
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/_version.py +3 -3
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/config.yml +5 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/data/base_data_source/data_source.py +9 -33
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/data/base_data_source/storages.py +1 -67
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/data/bundle.py +38 -222
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/main.py +3 -1
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/mod/rqalpha_mod_sys_accounts/api/api_stock.py +7 -6
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/model/instrument.py +5 -10
- rqalpha-5.4.0/rqalpha/utils/translations/zh_Hans_CN/LC_MESSAGES/messages.mo +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/utils/translations/zh_Hans_CN/LC_MESSAGES/messages.po +51 -50
- {rqalpha-5.3.11 → rqalpha-5.4.0/rqalpha.egg-info}/PKG-INFO +1 -1
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha.egg-info/requires.txt +1 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/setup.cfg +1 -1
- {rqalpha-5.3.11 → rqalpha-5.4.0}/setup.py +2 -1
- rqalpha-5.3.11/rqalpha/utils/translations/zh_Hans_CN/LC_MESSAGES/messages.mo +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/CHANGELOG.rst +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/LICENSE +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/MANIFEST.in +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/README.rst +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/__init__.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/__main__.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/api.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/apis/__init__.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/apis/api_abstract.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/apis/api_base.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/apis/api_rqdatac.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/apis/names.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/cmds/__init__.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/cmds/bundle.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/cmds/entry.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/cmds/misc.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/cmds/mod.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/cmds/run.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/const.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/core/__init__.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/core/events.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/core/execution_context.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/core/executor.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/core/global_var.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/core/strategy.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/core/strategy_context.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/core/strategy_loader.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/core/strategy_universe.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/data/__init__.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/data/bar_dict_price_board.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/data/base_data_source/__init__.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/data/base_data_source/adjust.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/data/base_data_source/storage_interface.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/data/data_proxy.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/data/trading_dates_mixin.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/environment.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/examples/IF1706_20161108.csv +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/examples/IF_macd.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/examples/buy_and_hold.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/examples/data_source/get_csv_module.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/examples/data_source/import_get_csv_module.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/examples/data_source/read_csv_as_df.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/examples/extend_api/rqalpha_mod_extend_api_demo.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/examples/extend_api/test_extend_api.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/examples/golden_cross.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/examples/macd.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/examples/pair_trading.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/examples/rsi.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/examples/run_code_demo.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/examples/run_file_demo.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/examples/run_func_demo.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/examples/subscribe_event.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/examples/test_pt.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/examples/turtle.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/interface.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/mod/__init__.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/mod/rqalpha_mod_sys_accounts/__init__.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/mod/rqalpha_mod_sys_accounts/api/__init__.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/mod/rqalpha_mod_sys_accounts/api/api_future.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/mod/rqalpha_mod_sys_accounts/component_validator.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/mod/rqalpha_mod_sys_accounts/mod.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/mod/rqalpha_mod_sys_accounts/position_model.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/mod/rqalpha_mod_sys_accounts/position_validator.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/mod/rqalpha_mod_sys_accounts/validator.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/mod/rqalpha_mod_sys_analyser/__init__.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/mod/rqalpha_mod_sys_analyser/mod.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/mod/rqalpha_mod_sys_analyser/plot/__init__.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/mod/rqalpha_mod_sys_analyser/plot/consts.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/mod/rqalpha_mod_sys_analyser/plot/plot.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/mod/rqalpha_mod_sys_analyser/plot/utils.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/mod/rqalpha_mod_sys_analyser/plot_store.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/mod/rqalpha_mod_sys_analyser/report/__init__.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/mod/rqalpha_mod_sys_analyser/report/excel_template.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/mod/rqalpha_mod_sys_analyser/report/report.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/mod/rqalpha_mod_sys_analyser/report/templates/summary.xlsx +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/mod/rqalpha_mod_sys_progress/__init__.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/mod/rqalpha_mod_sys_progress/mod.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/mod/rqalpha_mod_sys_risk/__init__.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/mod/rqalpha_mod_sys_risk/mod.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/mod/rqalpha_mod_sys_risk/validators/__init__.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/mod/rqalpha_mod_sys_risk/validators/cash_validator.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/mod/rqalpha_mod_sys_risk/validators/is_trading_validator.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/mod/rqalpha_mod_sys_risk/validators/price_validator.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/mod/rqalpha_mod_sys_risk/validators/self_trade_validator.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/mod/rqalpha_mod_sys_scheduler/__init__.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/mod/rqalpha_mod_sys_scheduler/mod.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/mod/rqalpha_mod_sys_scheduler/scheduler.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/mod/rqalpha_mod_sys_simulation/__init__.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/mod/rqalpha_mod_sys_simulation/matcher.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/mod/rqalpha_mod_sys_simulation/mod.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/mod/rqalpha_mod_sys_simulation/signal_broker.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/mod/rqalpha_mod_sys_simulation/simulation_broker.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/mod/rqalpha_mod_sys_simulation/simulation_event_source.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/mod/rqalpha_mod_sys_simulation/slippage.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/mod/rqalpha_mod_sys_simulation/testing.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/mod/rqalpha_mod_sys_simulation/validator.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/mod/rqalpha_mod_sys_transaction_cost/__init__.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/mod/rqalpha_mod_sys_transaction_cost/deciders.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/mod/rqalpha_mod_sys_transaction_cost/mod.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/mod/utils.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/mod_config.yml +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/model/__init__.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/model/bar.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/model/order.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/model/tick.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/model/trade.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/portfolio/__init__.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/portfolio/account.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/portfolio/position.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/resource/ricequant-logo.png +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/user_module.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/utils/__init__.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/utils/arg_checker.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/utils/class_helper.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/utils/click_helper.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/utils/concurrent.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/utils/config.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/utils/datetime_func.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/utils/dict_func.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/utils/exception.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/utils/functools.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/utils/i18n.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/utils/log_capture.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/utils/logger.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/utils/package_helper.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/utils/persisit_helper.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/utils/repr.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/utils/risk_free_helper.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/utils/rq_json.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/utils/strategy_loader_help.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/utils/testing/__init__.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/utils/testing/fixtures.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/utils/testing/mocking.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/utils/translations/__init__.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/utils/translations/zh_Hans_CN/LC_MESSAGES/__init__.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/utils/translations/zh_Hans_CN/__init__.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha/utils/typing.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha.egg-info/SOURCES.txt +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha.egg-info/dependency_links.txt +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha.egg-info/entry_points.txt +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha.egg-info/not-zip-safe +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/rqalpha.egg-info/top_level.txt +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/tests/__init__.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/tests/api_tests/__init__.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/tests/api_tests/mod/__init__.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/tests/api_tests/mod/sys_accounts/__init__.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/tests/api_tests/mod/sys_accounts/test_account_model.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/tests/api_tests/mod/sys_accounts/test_futures_settlement_price_type.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/tests/api_tests/mod/sys_accounts/test_margin_stocks.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/tests/api_tests/mod/sys_accounts/test_position_models.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/tests/api_tests/mod/sys_scheduler/__init__.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/tests/api_tests/mod/sys_scheduler/test_physical_time.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/tests/api_tests/mod/sys_scheduler/test_scheduler.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/tests/api_tests/mod/sys_simulation/__init__.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/tests/api_tests/mod/sys_simulation/test_management_fee.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/tests/api_tests/mod/sys_simulation/test_match.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/tests/api_tests/mod/sys_simulation/test_signal_broker.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/tests/api_tests/mod/sys_simulation/test_simulation_broker.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/tests/api_tests/mod/sys_simulation/test_simulation_event_source.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/tests/api_tests/mod/sys_transaction_cost/__init__.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/tests/api_tests/mod/sys_transaction_cost/test_commission_multiplier.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/tests/api_tests/test_api_base.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/tests/api_tests/test_api_future.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/tests/api_tests/test_api_stock.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/tests/api_tests/test_config.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/tests/api_tests/utils.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/tests/test_f_buy_and_hold.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/tests/test_f_delivery.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/tests/test_f_macd.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/tests/test_f_macd_signal.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/tests/test_f_mean_reverting.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/tests/test_f_tick_size.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/tests/test_s_buy_and_hold.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/tests/test_s_dual_thrust.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/tests/test_s_pit_tax.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/tests/test_s_scheduler.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/tests/test_s_tick_size.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/tests/test_s_turtle.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/tests/test_s_turtle_signal.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/tests/test_sf_buy_and_hold.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/tests/unittest/__init__.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/tests/unittest/test_data/__init__.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/tests/unittest/test_data/test_auto_update_bundle/__init__.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/tests/unittest/test_data/test_auto_update_bundle/test_auto_update_bundle_mixin.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/tests/unittest/test_data/test_instrument_mixin.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/tests/unittest/test_data/test_trading_dates_mixin.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/tests/unittest/test_mod/__init__.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/tests/unittest/test_mod/test_sys_simulation/__init__.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/tests/unittest/test_mod/test_sys_simulation/test_simulation_event_source.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/tests/utils.py +0 -0
- {rqalpha-5.3.11 → rqalpha-5.4.0}/versioneer.py +0 -0
|
@@ -8,11 +8,11 @@ import json
|
|
|
8
8
|
|
|
9
9
|
version_json = '''
|
|
10
10
|
{
|
|
11
|
-
"date": "2024-05-
|
|
11
|
+
"date": "2024-05-17T11:01:34+0800",
|
|
12
12
|
"dirty": false,
|
|
13
13
|
"error": null,
|
|
14
|
-
"full-revisionid": "
|
|
15
|
-
"version": "5.
|
|
14
|
+
"full-revisionid": "5821e6ab2d97cf7d47746284bd3619ded72842f8",
|
|
15
|
+
"version": "5.4.0"
|
|
16
16
|
}
|
|
17
17
|
''' # END VERSION_JSON
|
|
18
18
|
|
|
@@ -41,6 +41,11 @@ base:
|
|
|
41
41
|
forced_liquidation: true
|
|
42
42
|
# 是否开启期货历史交易参数进行回测,默认为 False
|
|
43
43
|
futures_time_series_trading_parameters: false
|
|
44
|
+
# 是否开启在回测过程中自动下载所需的 bundle 数据
|
|
45
|
+
# 当前支持数据:1. 盘前集合竞价成交量;2. 期货历史交易参数
|
|
46
|
+
auto_update_bundle: false
|
|
47
|
+
# 自动下载的 bundle 文件支持单独设置存储路径,若不设置则使用 data_bundle_path 路径
|
|
48
|
+
auto_update_bundle_path: ~
|
|
44
49
|
|
|
45
50
|
|
|
46
51
|
extra:
|
|
@@ -24,23 +24,21 @@ import numpy as np
|
|
|
24
24
|
import pandas as pd
|
|
25
25
|
import six
|
|
26
26
|
from rqalpha.utils.i18n import gettext as _
|
|
27
|
-
from rqalpha.const import INSTRUMENT_TYPE, TRADING_CALENDAR_TYPE
|
|
27
|
+
from rqalpha.const import INSTRUMENT_TYPE, TRADING_CALENDAR_TYPE
|
|
28
28
|
from rqalpha.interface import AbstractDataSource
|
|
29
29
|
from rqalpha.model.instrument import Instrument
|
|
30
30
|
from rqalpha.utils.datetime_func import (convert_date_to_int, convert_int_to_date, convert_int_to_datetime)
|
|
31
|
-
from rqalpha.utils.exception import RQInvalidArgument
|
|
31
|
+
from rqalpha.utils.exception import RQInvalidArgument
|
|
32
32
|
from rqalpha.utils.functools import lru_cache
|
|
33
33
|
from rqalpha.utils.typing import DateLike
|
|
34
34
|
from rqalpha.environment import Environment
|
|
35
|
-
from rqalpha.data.bundle import update_futures_trading_parameters
|
|
36
|
-
from rqalpha.utils.logger import user_system_log
|
|
37
35
|
from rqalpha.data.base_data_source.adjust import FIELDS_REQUIRE_ADJUSTMENT, adjust_bars
|
|
38
36
|
from rqalpha.data.base_data_source.storage_interface import (AbstractCalendarStore, AbstractDateSet,
|
|
39
37
|
AbstractDayBarStore, AbstractDividendStore,
|
|
40
38
|
AbstractInstrumentStore)
|
|
41
39
|
from rqalpha.data.base_data_source.storages import (DateSet, DayBarStore, DividendStore,
|
|
42
40
|
ExchangeTradingCalendarStore, FutureDayBarStore,
|
|
43
|
-
FutureInfoStore,
|
|
41
|
+
FutureInfoStore,InstrumentStore,
|
|
44
42
|
ShareTransformationStore, SimpleFactorStore,
|
|
45
43
|
YieldCurveStore, FuturesTradingParameters)
|
|
46
44
|
|
|
@@ -72,8 +70,7 @@ class BaseDataSource(AbstractDataSource):
|
|
|
72
70
|
INSTRUMENT_TYPE.PUBLIC_FUND,
|
|
73
71
|
)
|
|
74
72
|
|
|
75
|
-
def __init__(self, path, custom_future_info,
|
|
76
|
-
# type: (str, dict, bool, date) -> None
|
|
73
|
+
def __init__(self, path: str, custom_future_info: dict, *args, **kwargs) -> None:
|
|
77
74
|
if not os.path.exists(path):
|
|
78
75
|
raise RuntimeError('bundle path {} not exist'.format(os.path.abspath(path)))
|
|
79
76
|
|
|
@@ -89,13 +86,13 @@ class BaseDataSource(AbstractDataSource):
|
|
|
89
86
|
INSTRUMENT_TYPE.LOF: funds_day_bar_store
|
|
90
87
|
} # type: Dict[INSTRUMENT_TYPE, AbstractDayBarStore]
|
|
91
88
|
|
|
92
|
-
self._futures_trading_parameters_store = None
|
|
93
89
|
self._future_info_store = FutureInfoStore(_p("future_info.json"), custom_future_info)
|
|
94
90
|
|
|
95
91
|
self._instruments_stores = {} # type: Dict[INSTRUMENT_TYPE, AbstractInstrumentStore]
|
|
96
92
|
self._ins_id_or_sym_type_map = {} # type: Dict[str, INSTRUMENT_TYPE]
|
|
97
93
|
instruments = []
|
|
98
94
|
|
|
95
|
+
env = Environment.get_instance()
|
|
99
96
|
with open(_p('instruments.pk'), 'rb') as f:
|
|
100
97
|
for i in pickle.load(f):
|
|
101
98
|
if i["type"] == "Future" and Instrument.is_future_continuous_contract(i["order_book_id"]):
|
|
@@ -103,8 +100,8 @@ class BaseDataSource(AbstractDataSource):
|
|
|
103
100
|
instruments.append(Instrument(
|
|
104
101
|
i,
|
|
105
102
|
lambda i: self._future_info_store.get_tick_size(i),
|
|
106
|
-
lambda i, dt:
|
|
107
|
-
lambda i, dt:
|
|
103
|
+
# lambda i, dt: env.data_proxy.get_futures_trading_parameters(i, dt).long_margin_ratio,
|
|
104
|
+
# lambda i, dt: env.data_proxy.get_futures_trading_parameters(i, dt).short_margin_ratio
|
|
108
105
|
))
|
|
109
106
|
for ins_type in self.DEFAULT_INS_TYPES:
|
|
110
107
|
self.register_instruments_store(InstrumentStore(instruments, ins_type))
|
|
@@ -133,20 +130,6 @@ class BaseDataSource(AbstractDataSource):
|
|
|
133
130
|
self._suspend_days = [DateSet(_p('suspended_days.h5'))] # type: List[AbstractDateSet]
|
|
134
131
|
self._st_stock_days = DateSet(_p('st_stock_days.h5'))
|
|
135
132
|
|
|
136
|
-
if futures_time_series_trading_parameters:
|
|
137
|
-
try:
|
|
138
|
-
import rqdatac
|
|
139
|
-
except ImportError:
|
|
140
|
-
user_system_log.warn(_("RQDatac is not installed, \"config.base.futures_time_series_trading_parameters\" will be disabled."))
|
|
141
|
-
else:
|
|
142
|
-
try:
|
|
143
|
-
update_futures_trading_parameters(path, end_date)
|
|
144
|
-
except (rqdatac.share.errors.PermissionDenied, RQDatacVersionTooLow):
|
|
145
|
-
user_system_log.warn(_("RQDatac does not have permission to obtain futures histrical trading parameters, \"config.base.futures_time_series_trading_parameters\" will be disabled."))
|
|
146
|
-
else:
|
|
147
|
-
file = os.path.join(path, "futures_trading_parameters.h5")
|
|
148
|
-
self._futures_trading_parameters_store = FuturesTradingParametersStore(file, custom_future_info)
|
|
149
|
-
|
|
150
133
|
def register_day_bar_store(self, instrument_type, store):
|
|
151
134
|
# type: (INSTRUMENT_TYPE, AbstractDayBarStore) -> None
|
|
152
135
|
self._day_bars[instrument_type] = store
|
|
@@ -382,15 +365,8 @@ class BaseDataSource(AbstractDataSource):
|
|
|
382
365
|
return self._yield_curve.get_yield_curve(start_date, end_date, tenor=tenor)
|
|
383
366
|
|
|
384
367
|
@lru_cache(1024)
|
|
385
|
-
def get_futures_trading_parameters(self, instrument, dt):
|
|
386
|
-
|
|
387
|
-
if self._futures_trading_parameters_store:
|
|
388
|
-
trading_parameters = self._futures_trading_parameters_store.get_futures_trading_parameters(instrument, dt)
|
|
389
|
-
if trading_parameters is None:
|
|
390
|
-
return self._future_info_store.get_future_info(instrument.order_book_id, instrument.underlying_symbol)
|
|
391
|
-
return trading_parameters
|
|
392
|
-
else:
|
|
393
|
-
return self._future_info_store.get_future_info(instrument.order_book_id, instrument.underlying_symbol)
|
|
368
|
+
def get_futures_trading_parameters(self, instrument: Instrument, dt: datetime.date) -> FuturesTradingParameters:
|
|
369
|
+
return self._future_info_store.get_future_info(instrument.order_book_id, instrument.underlying_symbol)
|
|
394
370
|
|
|
395
371
|
def get_merge_ticks(self, order_book_id_list, trading_date, last_dt=None):
|
|
396
372
|
raise NotImplementedError
|
|
@@ -78,7 +78,7 @@ class FutureInfoStore(object):
|
|
|
78
78
|
}
|
|
79
79
|
self._custom_data = custom_future_info
|
|
80
80
|
if "margin_rate" not in self._default_data[next(iter(self._default_data))]:
|
|
81
|
-
raise RuntimeError(_("
|
|
81
|
+
raise RuntimeError(_("The bundle data you are using is too old, please update it to lastest before using"))
|
|
82
82
|
|
|
83
83
|
@classmethod
|
|
84
84
|
def _process_future_info_item(cls, item):
|
|
@@ -247,72 +247,6 @@ class FutureDayBarStore(DayBarStore):
|
|
|
247
247
|
DEFAULT_DTYPE = np.dtype(DayBarStore.DEFAULT_DTYPE.descr + [("open_interest", '<f8')])
|
|
248
248
|
|
|
249
249
|
|
|
250
|
-
class FuturesTradingParametersStore(object):
|
|
251
|
-
COMMISSION_TYPE_MAP = {
|
|
252
|
-
0: COMMISSION_TYPE.BY_MONEY,
|
|
253
|
-
1: COMMISSION_TYPE.BY_VOLUME
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
# 历史期货交易参数的数据在2010年4月之后才有
|
|
257
|
-
FUTURES_TRADING_PARAMETERS_START_DATE = 20100401
|
|
258
|
-
|
|
259
|
-
def __init__(self, path, custom_future_info):
|
|
260
|
-
self._path = path
|
|
261
|
-
self._custom_data = custom_future_info
|
|
262
|
-
|
|
263
|
-
def get_futures_trading_parameters(self, instrument, dt):
|
|
264
|
-
# type: (Instrument, datetime.date) -> FuturesTradingParameters or None
|
|
265
|
-
dt = convert_date_to_date_int(dt)
|
|
266
|
-
if dt < self.FUTURES_TRADING_PARAMETERS_START_DATE:
|
|
267
|
-
return None
|
|
268
|
-
order_book_id = instrument.order_book_id
|
|
269
|
-
underlying_symbol = instrument.underlying_symbol
|
|
270
|
-
data = self.get_futures_trading_parameters_all_time(order_book_id)
|
|
271
|
-
if data is None:
|
|
272
|
-
return None
|
|
273
|
-
else:
|
|
274
|
-
arr = data[data['datetime'] == dt]
|
|
275
|
-
if len(arr) == 0:
|
|
276
|
-
if dt >= convert_date_to_date_int(instrument.listed_date) and dt <= convert_date_to_date_int(instrument.de_listed_date):
|
|
277
|
-
user_system_log.info("Historical futures trading parameters are abnormal, the lastst parameters will be used for calculations.\nPlease contract RiceQuant to repair: 0755-26569969")
|
|
278
|
-
return None
|
|
279
|
-
custom_info = self._custom_data.get(order_book_id) or self._custom_data.get(underlying_symbol)
|
|
280
|
-
if custom_info:
|
|
281
|
-
arr[0] = self.set_custom_info(arr[0], custom_info)
|
|
282
|
-
futures_trading_parameters = self._to_namedtuple(arr[0])
|
|
283
|
-
return futures_trading_parameters
|
|
284
|
-
|
|
285
|
-
@lru_cache(1024)
|
|
286
|
-
def get_futures_trading_parameters_all_time(self, order_book_id):
|
|
287
|
-
# type: (str) -> numpy.ndarray or None
|
|
288
|
-
with h5_file(self._path) as h5:
|
|
289
|
-
try:
|
|
290
|
-
data = h5[order_book_id][:]
|
|
291
|
-
except KeyError:
|
|
292
|
-
return None
|
|
293
|
-
return data
|
|
294
|
-
|
|
295
|
-
def set_custom_info(self, arr, custom_info):
|
|
296
|
-
for field in custom_info:
|
|
297
|
-
if field == "commission_type":
|
|
298
|
-
if custom_info[field] == COMMISSION_TYPE.BY_MONEY:
|
|
299
|
-
value = 0
|
|
300
|
-
elif custom_info[field] == COMMISSION_TYPE.BY_VOLUME:
|
|
301
|
-
value = 1
|
|
302
|
-
else:
|
|
303
|
-
value = custom_info[field]
|
|
304
|
-
arr[field] = value
|
|
305
|
-
return arr
|
|
306
|
-
|
|
307
|
-
def _to_namedtuple(self, arr):
|
|
308
|
-
# type: (numpy.void) -> FuturesTradingParameters
|
|
309
|
-
dic = dict(zip(arr.dtype.names, arr))
|
|
310
|
-
del dic['datetime']
|
|
311
|
-
dic["commission_type"] = self.COMMISSION_TYPE_MAP[dic['commission_type']]
|
|
312
|
-
futures_trading_parameters = FuturesTradingParameters(**dic)
|
|
313
|
-
return futures_trading_parameters
|
|
314
|
-
|
|
315
|
-
|
|
316
250
|
class DividendStore(AbstractDividendStore):
|
|
317
251
|
def __init__(self, path):
|
|
318
252
|
self._path = path
|
|
@@ -18,20 +18,15 @@ import os
|
|
|
18
18
|
import pickle
|
|
19
19
|
import re
|
|
20
20
|
from itertools import chain
|
|
21
|
-
from typing import Callable, Optional, List
|
|
21
|
+
from typing import Callable, Optional, Union, List
|
|
22
|
+
from filelock import FileLock, Timeout
|
|
22
23
|
|
|
23
24
|
import h5py
|
|
24
25
|
import numpy as np
|
|
25
|
-
import pandas as pd
|
|
26
26
|
from rqalpha.apis.api_rqdatac import rqdatac
|
|
27
|
-
from rqalpha.utils.concurrent import
|
|
28
|
-
|
|
29
|
-
from rqalpha.utils.datetime_func import (convert_date_to_date_int,
|
|
30
|
-
convert_date_to_int,)
|
|
31
|
-
from rqalpha.utils.exception import RQDatacVersionTooLow
|
|
27
|
+
from rqalpha.utils.concurrent import ProgressedProcessPoolExecutor, ProgressedTask
|
|
28
|
+
from rqalpha.utils.datetime_func import convert_date_to_date_int, convert_date_to_int
|
|
32
29
|
from rqalpha.utils.i18n import gettext as _
|
|
33
|
-
from rqalpha.utils.logger import system_log
|
|
34
|
-
from rqalpha.const import TRADING_CALENDAR_TYPE
|
|
35
30
|
from rqalpha.utils.functools import lru_cache
|
|
36
31
|
from rqalpha.environment import Environment
|
|
37
32
|
from rqalpha.model.instrument import Instrument
|
|
@@ -445,195 +440,8 @@ def update_bundle(path, create, enable_compression=False, concurrency=1):
|
|
|
445
440
|
executor.submit(_DayBarTask(order_book_id), os.path.join(path, file), field, **kwargs)
|
|
446
441
|
|
|
447
442
|
|
|
448
|
-
FUTURES_TRADING_PARAMETERS_FIELDS = ["long_margin_ratio", "short_margin_ratio", "commission_type", "open_commission", "close_commission", "close_commission_today"]
|
|
449
|
-
TRADING_PARAMETERS_START_DATE = 20100401
|
|
450
|
-
FUTURES_TRADING_PARAMETERS_FILE = "futures_trading_parameters.h5"
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
class FuturesTradingParametersTask(object):
|
|
454
|
-
def __init__(self, order_book_ids, underlying_symbols):
|
|
455
|
-
self._order_book_ids = order_book_ids
|
|
456
|
-
self._underlying_symbols = underlying_symbols
|
|
457
|
-
|
|
458
|
-
def __call__(self, path, fields, end_date):
|
|
459
|
-
if rqdatac.__version__ < '2.11.12':
|
|
460
|
-
raise RQDatacVersionTooLow(_("RQAlpha already supports backtesting using futures historical margins and rates, please upgrade RQDatac to version 2.11.12 and above to use it"))
|
|
461
|
-
|
|
462
|
-
if not os.path.exists(path):
|
|
463
|
-
self.generate_futures_trading_parameters(path, fields, end_date)
|
|
464
|
-
else:
|
|
465
|
-
self.update_futures_trading_parameters(path, fields, end_date)
|
|
466
|
-
|
|
467
|
-
def generate_futures_trading_parameters(self, path, fields, end_date, recreate_futures_list=None):
|
|
468
|
-
# type: (str, list, datetime.date, list) -> None
|
|
469
|
-
if not recreate_futures_list:
|
|
470
|
-
system_log.info(_("Futures historical trading parameters data is being updated, please wait......"))
|
|
471
|
-
order_book_ids = self._order_book_ids
|
|
472
|
-
if recreate_futures_list:
|
|
473
|
-
order_book_ids = recreate_futures_list
|
|
474
|
-
df = rqdatac.futures.get_trading_parameters(order_book_ids, TRADING_PARAMETERS_START_DATE, end_date, fields)
|
|
475
|
-
if not (df is None or df.empty):
|
|
476
|
-
df.dropna(axis=0, how="all")
|
|
477
|
-
df.reset_index(inplace=True)
|
|
478
|
-
df['datetime'] = df['trading_date'].map(convert_date_to_date_int)
|
|
479
|
-
del df["trading_date"]
|
|
480
|
-
df['commission_type'] = df['commission_type'].map(self.set_commission_type)
|
|
481
|
-
df.rename(columns={
|
|
482
|
-
'close_commission': "close_commission_ratio",
|
|
483
|
-
'close_commission_today': "close_commission_today_ratio",
|
|
484
|
-
'open_commission': 'open_commission_ratio'
|
|
485
|
-
}, inplace=True)
|
|
486
|
-
df.set_index(["order_book_id", "datetime"], inplace=True)
|
|
487
|
-
df.sort_index(inplace=True)
|
|
488
|
-
with h5py.File(path, "w") as h5:
|
|
489
|
-
for order_book_id in df.index.levels[0]:
|
|
490
|
-
h5.create_dataset(order_book_id, data=df.loc[order_book_id].to_records())
|
|
491
|
-
# 更新期货连续合约的历史交易参数数据(当函数执行目的为补充上次未正常更新的数据时,不需要执行此段逻辑)
|
|
492
|
-
if recreate_futures_list is None:
|
|
493
|
-
with h5py.File(path, "a") as h5:
|
|
494
|
-
df = rqdatac.all_instruments("Future")
|
|
495
|
-
for underlying_symbol in self._underlying_symbols:
|
|
496
|
-
futures_continuous_contract = df[(df['underlying_symbol'] == underlying_symbol) & (df["listed_date"] == '0000-00-00')].order_book_id.tolist()
|
|
497
|
-
s = rqdatac.futures.get_dominant(underlying_symbol, TRADING_PARAMETERS_START_DATE, end_date)
|
|
498
|
-
if (s is None or s.empty):
|
|
499
|
-
continue
|
|
500
|
-
s = s.to_frame().reset_index()
|
|
501
|
-
s['date'] = s['date'].map(convert_date_to_date_int)
|
|
502
|
-
s.set_index(['date'], inplace=True)
|
|
503
|
-
trading_parameters_list = []
|
|
504
|
-
for date in s.index:
|
|
505
|
-
try:
|
|
506
|
-
data = h5[s['dominant'][date]][:]
|
|
507
|
-
except KeyError:
|
|
508
|
-
continue
|
|
509
|
-
trading_parameters = data[data['datetime'] == date]
|
|
510
|
-
if len(trading_parameters) != 0:
|
|
511
|
-
trading_parameters_list.append(trading_parameters[0])
|
|
512
|
-
data = np.array(trading_parameters_list)
|
|
513
|
-
for order_book_id in futures_continuous_contract:
|
|
514
|
-
h5.create_dataset(order_book_id, data=data)
|
|
515
|
-
|
|
516
|
-
def update_futures_trading_parameters(self, path, fields, end_date):
|
|
517
|
-
# type: (str, list, datetime.date) -> None
|
|
518
|
-
try:
|
|
519
|
-
h5 = h5py.File(path, "a")
|
|
520
|
-
h5.close()
|
|
521
|
-
except OSError as e:
|
|
522
|
-
raise OSError(_("File {} update failed, if it is using, please update later, or you can delete then update again".format(path))) from e
|
|
523
|
-
last_date = self.get_h5_last_date(path)
|
|
524
|
-
recreate_futures_list = self.get_recreate_futures_list(path, last_date)
|
|
525
|
-
if recreate_futures_list:
|
|
526
|
-
self.generate_futures_trading_parameters(path, fields, last_date, recreate_futures_list=recreate_futures_list)
|
|
527
|
-
if end_date > last_date:
|
|
528
|
-
if rqdatac.get_previous_trading_date(end_date) == last_date:
|
|
529
|
-
return
|
|
530
|
-
else:
|
|
531
|
-
system_log.info(_("Futures historical trading parameters data is being updated, please wait......"))
|
|
532
|
-
start_date = rqdatac.get_next_trading_date(last_date)
|
|
533
|
-
df = rqdatac.futures.get_trading_parameters(self._order_book_ids, start_date, end_date, fields)
|
|
534
|
-
if not(df is None or df.empty):
|
|
535
|
-
df = df.dropna(axis=0, how="all")
|
|
536
|
-
df.reset_index(inplace=True)
|
|
537
|
-
df['datetime'] = df['trading_date'].map(convert_date_to_date_int)
|
|
538
|
-
del [df['trading_date']]
|
|
539
|
-
df['commission_type'] = df['commission_type'].map(self.set_commission_type)
|
|
540
|
-
df.rename(columns={
|
|
541
|
-
'close_commission': "close_commission_ratio",
|
|
542
|
-
'close_commission_today': "close_commission_today_ratio",
|
|
543
|
-
'open_commission': 'open_commission_ratio'
|
|
544
|
-
}, inplace=True)
|
|
545
|
-
df.set_index(['order_book_id', 'datetime'], inplace=True)
|
|
546
|
-
with h5py.File(path, "a") as h5:
|
|
547
|
-
for order_book_id in df.index.levels[0]:
|
|
548
|
-
if order_book_id in h5:
|
|
549
|
-
data = np.array(
|
|
550
|
-
[tuple(i) for i in chain(h5[order_book_id][:], df.loc[order_book_id].to_records())],
|
|
551
|
-
dtype=h5[order_book_id].dtype
|
|
552
|
-
)
|
|
553
|
-
del h5[order_book_id]
|
|
554
|
-
h5.create_dataset(order_book_id, data=data)
|
|
555
|
-
else:
|
|
556
|
-
h5.create_dataset(order_book_id, data=df.loc[order_book_id].to_records())
|
|
557
|
-
# 更新期货连续合约历史交易参数
|
|
558
|
-
with h5py.File(path, "a") as h5:
|
|
559
|
-
df = rqdatac.all_instruments("Future")
|
|
560
|
-
for underlying_symbol in self._underlying_symbols:
|
|
561
|
-
futures_continuous_contract = df[(df['underlying_symbol'] == underlying_symbol) & (df["listed_date"] == '0000-00-00')].order_book_id.tolist()
|
|
562
|
-
s = rqdatac.futures.get_dominant(underlying_symbol, start_date, end_date)
|
|
563
|
-
if (s is None or s.empty):
|
|
564
|
-
continue
|
|
565
|
-
s = s.to_frame().reset_index()
|
|
566
|
-
s['date'] = s['date'].map(convert_date_to_date_int)
|
|
567
|
-
s.set_index(['date'], inplace=True)
|
|
568
|
-
trading_parameters_list = []
|
|
569
|
-
for date in s.index:
|
|
570
|
-
try:
|
|
571
|
-
data = h5[s['dominant'][date]][:]
|
|
572
|
-
except KeyError:
|
|
573
|
-
continue
|
|
574
|
-
trading_parameters = data[data['datetime'] == date]
|
|
575
|
-
if len(trading_parameters) != 0:
|
|
576
|
-
trading_parameters_list.append(trading_parameters[0])
|
|
577
|
-
for order_book_id in futures_continuous_contract:
|
|
578
|
-
if order_book_id in h5:
|
|
579
|
-
data = np.array(
|
|
580
|
-
[tuple(i) for i in chain(h5[order_book_id][:], trading_parameters_list)],
|
|
581
|
-
dtype=h5[order_book_id].dtype
|
|
582
|
-
)
|
|
583
|
-
del h5[order_book_id]
|
|
584
|
-
h5.create_dataset(order_book_id, data=data)
|
|
585
|
-
else:
|
|
586
|
-
h5.create_dataset(order_book_id, data=np.array(trading_parameters))
|
|
587
|
-
|
|
588
|
-
def set_commission_type(self, commission_type):
|
|
589
|
-
if commission_type == "by_money":
|
|
590
|
-
commission_type = 0
|
|
591
|
-
elif commission_type == "by_volume":
|
|
592
|
-
commission_type = 1
|
|
593
|
-
return commission_type
|
|
594
|
-
|
|
595
|
-
def get_h5_last_date(self, path):
|
|
596
|
-
last_date = TRADING_PARAMETERS_START_DATE
|
|
597
|
-
with h5py.File(path, "r") as h5:
|
|
598
|
-
for key in h5.keys():
|
|
599
|
-
if int(h5[key]['datetime'][-1]) > last_date:
|
|
600
|
-
last_date = h5[key]['datetime'][-1]
|
|
601
|
-
last_date = datetime.datetime.strptime(str(last_date), "%Y%m%d").date()
|
|
602
|
-
return last_date
|
|
603
|
-
|
|
604
|
-
def get_recreate_futures_list(self, path, h5_last_date):
|
|
605
|
-
# type: (str, datetime.date) -> list
|
|
606
|
-
"""
|
|
607
|
-
用户在运行策略的过程中可能中断进程,进而可能导致在创建 h5 文件时,部分合约没有成功 download
|
|
608
|
-
通过该函数,获取在上一次更新中因为异常而没有更新的合约
|
|
609
|
-
"""
|
|
610
|
-
recreate_futures_list = []
|
|
611
|
-
df = rqdatac.all_instruments("Future")
|
|
612
|
-
last_update_futures_list = df[(df['de_listed_date'] >= str(TRADING_PARAMETERS_START_DATE)) & (df['listed_date'] <= h5_last_date.strftime("%Y%m%d"))].order_book_id.to_list()
|
|
613
|
-
with h5py.File(path, "r") as h5:
|
|
614
|
-
h5_order_book_ids = h5.keys()
|
|
615
|
-
for order_book_id in last_update_futures_list:
|
|
616
|
-
if order_book_id in h5_order_book_ids:
|
|
617
|
-
continue
|
|
618
|
-
else:
|
|
619
|
-
recreate_futures_list.append(order_book_id)
|
|
620
|
-
return recreate_futures_list
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
def update_futures_trading_parameters(path, end_date):
|
|
624
|
-
# type: (str, datetime.date) -> None
|
|
625
|
-
df = rqdatac.all_instruments("Future")
|
|
626
|
-
order_book_ids = (df[df['de_listed_date'] >= str(TRADING_PARAMETERS_START_DATE)]).order_book_id.tolist()
|
|
627
|
-
underlying_symbols = list(set((df[df['de_listed_date'] >= str(TRADING_PARAMETERS_START_DATE)]).underlying_symbol.tolist()))
|
|
628
|
-
FuturesTradingParametersTask(order_book_ids, underlying_symbols)(
|
|
629
|
-
os.path.join(path, FUTURES_TRADING_PARAMETERS_FILE),
|
|
630
|
-
FUTURES_TRADING_PARAMETERS_FIELDS,
|
|
631
|
-
end_date
|
|
632
|
-
)
|
|
633
|
-
|
|
634
|
-
|
|
635
443
|
class AutomaticUpdateBundle(object):
|
|
636
|
-
def __init__(self, path: str, filename: str, api: Callable, fields: List[str], end_date: datetime.date) -> None:
|
|
444
|
+
def __init__(self, path: str, filename: str, api: Callable, fields: List[str], end_date: datetime.date, start_date: Union[int, datetime.date] = START_DATE) -> None:
|
|
637
445
|
if not os.path.exists(path):
|
|
638
446
|
os.makedirs(path)
|
|
639
447
|
self._file = os.path.join(path, filename)
|
|
@@ -641,9 +449,11 @@ class AutomaticUpdateBundle(object):
|
|
|
641
449
|
self._filename = filename
|
|
642
450
|
self._api = api
|
|
643
451
|
self._fields = fields
|
|
452
|
+
self._start_date = start_date
|
|
644
453
|
self._end_date = end_date
|
|
645
454
|
self.updated = []
|
|
646
455
|
self._env = Environment.get_instance()
|
|
456
|
+
self._file_lock = FileLock(self._file + ".lock")
|
|
647
457
|
|
|
648
458
|
def get_data(self, instrument: Instrument, dt: datetime.date) -> Optional[np.ndarray]:
|
|
649
459
|
dt = convert_date_to_date_int(dt)
|
|
@@ -676,34 +486,40 @@ class AutomaticUpdateBundle(object):
|
|
|
676
486
|
:type instrument: `Instrument`
|
|
677
487
|
"""
|
|
678
488
|
order_book_id = instrument.order_book_id
|
|
679
|
-
start_date =
|
|
489
|
+
start_date = self._start_date
|
|
680
490
|
try:
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
if
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
h5.create_dataset(order_book_id, data=data)
|
|
491
|
+
with self._file_lock.acquire():
|
|
492
|
+
h5 = h5py.File(self._file, "a")
|
|
493
|
+
if order_book_id in h5 and h5[order_book_id].dtype.names:
|
|
494
|
+
if 'trading_dt' in h5[order_book_id].dtype.names:
|
|
495
|
+
# 需要兼容此前的旧版数据,对字段名进行更新
|
|
496
|
+
if len(h5[order_book_id][:]) != 0:
|
|
497
|
+
last_date = datetime.datetime.strptime(str(h5[order_book_id][-1]['trading_dt']), "%Y%m%d").date()
|
|
498
|
+
if last_date >= self._end_date:
|
|
499
|
+
return
|
|
500
|
+
start_date = self._env.data_proxy._data_source.get_next_trading_date(last_date).date()
|
|
501
|
+
if start_date > self._end_date:
|
|
502
|
+
return
|
|
503
|
+
else:
|
|
504
|
+
del h5[order_book_id]
|
|
505
|
+
|
|
506
|
+
arr = self._get_array(instrument, start_date)
|
|
507
|
+
if arr is None:
|
|
508
|
+
if order_book_id not in h5:
|
|
509
|
+
arr = np.array([])
|
|
510
|
+
h5.create_dataset(order_book_id, data=arr)
|
|
702
511
|
else:
|
|
703
|
-
|
|
704
|
-
|
|
512
|
+
if order_book_id in h5:
|
|
513
|
+
data = np.array(
|
|
514
|
+
[tuple(i) for i in chain(h5[order_book_id][:], arr)],
|
|
515
|
+
dtype=h5[order_book_id].dtype)
|
|
516
|
+
del h5[order_book_id]
|
|
517
|
+
h5.create_dataset(order_book_id, data=data)
|
|
518
|
+
else:
|
|
519
|
+
h5.create_dataset(order_book_id, data=arr)
|
|
520
|
+
except (OSError, Timeout) as e:
|
|
705
521
|
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
|
|
522
|
+
"or you can delete then update again".format(self._file))) from e
|
|
707
523
|
finally:
|
|
708
524
|
h5.close()
|
|
709
525
|
|
|
@@ -118,7 +118,9 @@ def init_rqdatac(rqdatac_uri):
|
|
|
118
118
|
except ImportError:
|
|
119
119
|
return
|
|
120
120
|
|
|
121
|
-
if
|
|
121
|
+
if rqdatac.initialized():
|
|
122
|
+
return True
|
|
123
|
+
else:
|
|
122
124
|
init_rqdatac_env(rqdatac_uri)
|
|
123
125
|
try:
|
|
124
126
|
rqdatac.init()
|
|
@@ -94,7 +94,7 @@ def _get_order_style_price(order_book_id, style):
|
|
|
94
94
|
raise RuntimeError(f"no support {style} order style")
|
|
95
95
|
|
|
96
96
|
|
|
97
|
-
def _submit_order(ins, amount, side, position_effect, style, current_quantity, auto_switch_order_value):
|
|
97
|
+
def _submit_order(ins, amount, side, position_effect, style, current_quantity, auto_switch_order_value, zero_amount_as_exception=True):
|
|
98
98
|
env = Environment.get_instance()
|
|
99
99
|
if isinstance(style, LimitOrder) and np.isnan(style.get_limit_price()):
|
|
100
100
|
raise RQInvalidArgument(_(u"Limit order price should not be nan."))
|
|
@@ -109,8 +109,9 @@ def _submit_order(ins, amount, side, position_effect, style, current_quantity, a
|
|
|
109
109
|
amount = _round_order_quantity(ins, amount)
|
|
110
110
|
|
|
111
111
|
if amount == 0:
|
|
112
|
-
|
|
113
|
-
|
|
112
|
+
if zero_amount_as_exception:
|
|
113
|
+
reason = _(u"Order Creation Failed: 0 order quantity, order_book_id={order_book_id}").format(order_book_id=ins.order_book_id)
|
|
114
|
+
env.order_creation_failed(order_book_id=ins.order_book_id, reason=reason)
|
|
114
115
|
return
|
|
115
116
|
order = Order.__from_create__(ins.order_book_id, abs(amount), side, style, position_effect)
|
|
116
117
|
if side == SIDE.BUY and auto_switch_order_value:
|
|
@@ -123,9 +124,9 @@ def _submit_order(ins, amount, side, position_effect, style, current_quantity, a
|
|
|
123
124
|
return env.submit_order(order)
|
|
124
125
|
|
|
125
126
|
|
|
126
|
-
def _order_shares(ins, amount, style, quantity, auto_switch_order_value):
|
|
127
|
+
def _order_shares(ins, amount, style, quantity, auto_switch_order_value, zero_amount_as_exception=True):
|
|
127
128
|
side, position_effect = (SIDE.BUY, POSITION_EFFECT.OPEN) if amount > 0 else (SIDE.SELL, POSITION_EFFECT.CLOSE)
|
|
128
|
-
return _submit_order(ins, amount, side, position_effect, style, quantity, auto_switch_order_value)
|
|
129
|
+
return _submit_order(ins, amount, side, position_effect, style, quantity, auto_switch_order_value, zero_amount_as_exception)
|
|
129
130
|
|
|
130
131
|
|
|
131
132
|
def _order_value(account, position, ins, cash_amount, style, zero_amount_as_exception=True):
|
|
@@ -161,7 +162,7 @@ def _order_value(account, position, ins, cash_amount, style, zero_amount_as_exce
|
|
|
161
162
|
if amount < 0:
|
|
162
163
|
amount = max(amount, -position.closable)
|
|
163
164
|
|
|
164
|
-
return _order_shares(ins, amount, style, position.quantity, auto_switch_order_value=False)
|
|
165
|
+
return _order_shares(ins, amount, style, position.quantity, auto_switch_order_value=False, zero_amount_as_exception=zero_amount_as_exception)
|
|
165
166
|
|
|
166
167
|
|
|
167
168
|
@order_shares.register(INST_TYPE_IN_STOCK_ACCOUNT)
|
|
@@ -48,12 +48,9 @@ class Instrument(metaclass=PropertyReprMeta):
|
|
|
48
48
|
|
|
49
49
|
__repr__ = property_repr
|
|
50
50
|
|
|
51
|
-
def __init__(self, dic, futures_tick_size_getter=None,
|
|
52
|
-
# type: (Dict, Optional[Callable[[Instrument], float]], Optional[Callable[[Instrument], float]], Optional[Callable[[Instrument], float]]) -> None
|
|
51
|
+
def __init__(self, dic: Dict, futures_tick_size_getter: Optional[Callable] = None, *args, **kwrags) -> None:
|
|
53
52
|
self.__dict__ = copy.copy(dic)
|
|
54
53
|
self._futures_tick_size_getter = futures_tick_size_getter
|
|
55
|
-
self._futures_long_margin_ratio_getter = futures_long_margin_ratio_getter
|
|
56
|
-
self._futures_short_margin_ratio_getter = futures_short_margin_ratio_getter
|
|
57
54
|
|
|
58
55
|
if "listed_date" in dic:
|
|
59
56
|
self.__dict__["listed_date"] = self._fix_date(dic["listed_date"])
|
|
@@ -446,20 +443,18 @@ class Instrument(metaclass=PropertyReprMeta):
|
|
|
446
443
|
raise NotImplementedError
|
|
447
444
|
|
|
448
445
|
@lru_cache(8)
|
|
449
|
-
def get_long_margin_ratio(self, dt):
|
|
450
|
-
# type: (datetime.date) -> float
|
|
446
|
+
def get_long_margin_ratio(self, dt: datetime.date) -> float:
|
|
451
447
|
"""
|
|
452
448
|
获取多头保证金率(期货专用)
|
|
453
449
|
"""
|
|
454
|
-
return
|
|
450
|
+
return Environment.get_instance().data_proxy.get_futures_trading_parameters(self.order_book_id, dt).long_margin_ratio
|
|
455
451
|
|
|
456
452
|
@lru_cache(8)
|
|
457
|
-
def get_short_margin_ratio(self, dt):
|
|
458
|
-
# type: (datetime.date) -> float
|
|
453
|
+
def get_short_margin_ratio(self, dt: datetime.date) -> float:
|
|
459
454
|
"""
|
|
460
455
|
获取空头保证金率(期货专用)
|
|
461
456
|
"""
|
|
462
|
-
return
|
|
457
|
+
return Environment.get_instance().data_proxy.get_futures_trading_parameters(self.order_book_id, dt).short_margin_ratio
|
|
463
458
|
|
|
464
459
|
def calc_cash_occupation(self, price, quantity, direction, dt):
|
|
465
460
|
# type: (float, int, POSITION_DIRECTION, datetime.date) -> float
|