cfquant 0.2.39__tar.gz → 0.2.40__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.
- {cfquant-0.2.39 → cfquant-0.2.40}/PKG-INFO +1 -1
- {cfquant-0.2.39 → cfquant-0.2.40}/cfquant/qmt_bridge.py +18 -13
- cfquant-0.2.40/cfquant/tests/test_order_time_callback.py +71 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/cfquant/tx_trade_bridge.py +17 -12
- {cfquant-0.2.39 → cfquant-0.2.40}/cfquant/version.py +2 -2
- {cfquant-0.2.39 → cfquant-0.2.40}/cfquant/xttype.py +43 -4
- {cfquant-0.2.39 → cfquant-0.2.40}/cfquant.egg-info/PKG-INFO +1 -1
- {cfquant-0.2.39 → cfquant-0.2.40}/cfquant.egg-info/SOURCES.txt +1 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/pyproject.toml +1 -1
- {cfquant-0.2.39 → cfquant-0.2.40}/qmt_scripts/CFQUANT_LITE.py +27 -3
- {cfquant-0.2.39 → cfquant-0.2.40}/qmt_scripts//345/220/214/350/264/246/345/217/267/347/213/254/347/253/213/345/270/202/345/234/272/CFQUANT_LITE_SH.py +27 -3
- {cfquant-0.2.39 → cfquant-0.2.40}/qmt_scripts//345/220/214/350/264/246/345/217/267/347/213/254/347/253/213/345/270/202/345/234/272/CFQUANT_LITE_SZ.py +27 -3
- {cfquant-0.2.39 → cfquant-0.2.40}/web_dashboard/app.js +4 -1
- {cfquant-0.2.39 → cfquant-0.2.40}/web_dashboard/index.html +2 -2
- {cfquant-0.2.39 → cfquant-0.2.40}/LICENSE +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/LTtx/__init__.py +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/LTtx/tx/Config.txt +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/LTtx/tx/LTtx_server.py +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/LTtx/tx/__init__.py +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/LTtx/tx/tx.py +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/MANIFEST.in +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/README.md +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/cfquant/__init__.py +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/cfquant/_editable_install.py +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/cfquant/account_routing.py +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/cfquant/batch_orders.py +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/cfquant/build_info.py +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/cfquant/callback_dispatcher.py +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/cfquant/cftrader.py +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/cfquant/channels.py +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/cfquant/cli.py +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/cfquant/client.py +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/cfquant/config.py +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/cfquant/hub.py +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/cfquant/level2.py +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/cfquant/log_management.py +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/cfquant/logging_i18n.py +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/cfquant/normal_bridge.py +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/cfquant/order_meta.py +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/cfquant/pipe_bridge.py +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/cfquant/pipe_client.py +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/cfquant/pipe_hub.py +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/cfquant/pipe_transport.py +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/cfquant/protocol.py +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/cfquant/qmt_strategy_deploy.py +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/cfquant/qmt_strategy_package.py +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/cfquant/qmt_strategy_runtime.py +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/cfquant/runtime_report.py +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/cfquant/tests/10_/345/221/275/344/273/244/350/241/214/346/216/245/345/217/243/346/265/213/350/257/225.py" +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/cfquant/tests/11_/346/231/256/351/200/232/346/241/245/346/216/245/346/264/276/345/217/221/346/265/213/350/257/225.py" +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/cfquant/tests/12_/350/256/242/345/215/225/345/244/207/346/263/250/346/265/213/350/257/225.py" +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/cfquant/tests/13_/347/256/241/351/201/223/344/270/255/345/277/203/350/277/236/346/216/245/346/265/213/350/257/225.py" +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/cfquant/tests/14_/350/277/220/350/241/214/346/227/266/346/212/245/345/221/212/346/265/213/350/257/225.py" +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/cfquant/tests/15_/347/275/221/351/241/265/347/212/266/346/200/201/347/274/223/345/255/230/346/265/213/350/257/225.py" +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/cfquant/tests/16_/345/220/257/345/212/250/345/256/211/350/243/205/346/265/213/350/257/225.py" +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/cfquant/tests/17_/345/244/247QMT/346/216/245/345/217/243/351/200/202/351/205/215/346/265/213/350/257/225.py" +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/cfquant/tests/18_/351/253/230/347/272/247/346/250/241/345/274/217/345/256/236/346/234/272/350/201/224/350/260/203.py" +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/cfquant/tests/19_/345/256/236/346/234/272/350/201/224/350/260/203/345/210/244/345/256/232/346/265/213/350/257/225.py" +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/cfquant/tests/1_/350/241/214/346/203/205/346/216/245/346/224/266/346/265/213/350/257/225.py" +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/cfquant/tests/20_/350/201/224/350/260/203/351/227/256/351/242/230/344/277/256/345/244/215/346/265/213/350/257/225.py" +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/cfquant/tests/21_/345/215/225/350/202/241/350/241/214/346/203/205/350/256/242/351/230/205/346/265/213/350/257/225.py" +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/cfquant/tests/22_/350/277/236/346/216/245/350/257/212/346/226/255/346/265/213/350/257/225.py" +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/cfquant/tests/23_/347/244/272/344/276/213/351/205/215/347/275/256/346/265/213/350/257/225.py" +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/cfquant/tests/24_/350/264/246/346/210/267/347/274/223/345/255/230/346/214/211/351/234/200/345/210/267/346/226/260/346/265/213/350/257/225.py" +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/cfquant/tests/25_/350/264/246/346/210/267/347/274/223/345/255/230/351/241/265/351/235/242/346/265/213/350/257/225.py" +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/cfquant/tests/26_/345/205/250/346/216/250/350/256/242/351/230/205/346/265/213/350/257/225.py" +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/cfquant/tests/27_/345/205/250/346/216/250/350/256/242/351/230/205/351/241/265/351/235/242/346/265/213/350/257/225.py" +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/cfquant/tests/28_Level2/346/216/245/345/217/243/351/200/202/351/205/215/346/265/213/350/257/225.py" +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/cfquant/tests/29_Level2/350/241/214/346/203/205/346/265/213/350/257/225.py" +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/cfquant/tests/2_/346/225/260/346/215/256/350/216/267/345/217/226/346/265/213/350/257/225.py" +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/cfquant/tests/30_cftrader/346/211/271/351/207/217/344/270/213/345/215/225/346/200/247/350/203/275/345/237/272/345/207/206.py" +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/cfquant/tests/31_cftrader/346/250/241/346/213/237/350/264/246/345/217/267/346/211/271/351/207/217/344/270/213/345/215/225/346/265/213/350/257/225.py" +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/cfquant/tests/32_/345/274/202/346/255/245/344/270/213/345/215/225/346/265/213/350/257/225.py" +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/cfquant/tests/33_/345/220/214/346/255/245/344/270/213/345/215/225/345/233/236/350/260/203/346/265/213/350/257/225.py" +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/cfquant/tests/3_/346/225/260/346/215/256/344/270/213/350/275/275/346/265/213/350/257/225.py" +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/cfquant/tests/4_/344/272/244/346/230/223/345/247/224/346/211/230/346/237/245/350/257/242/346/265/213/350/257/225.py" +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/cfquant/tests/5_/347/234/237/345/256/236/344/270/213/345/215/225/346/265/213/350/257/225.py" +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/cfquant/tests/6_/345/233/236/350/260/203/346/265/213/350/257/225.py" +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/cfquant/tests/7_/345/220/214/346/255/245/345/274/202/346/255/245/344/270/213/345/215/225/346/265/213/350/257/225.py" +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/cfquant/tests/8_/346/210/220/344/272/244/350/256/242/345/215/225/345/222/214/345/247/224/346/211/230/350/256/242/345/215/225/346/237/245/350/257/242/346/265/213/350/257/225.py" +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/cfquant/tests/9_/345/217/257/346/222/244/350/256/242/345/215/225/346/265/213/350/257/225.py" +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/cfquant/tests/_helpers.py +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/cfquant/tests/log/cftrader/346/250/241/346/213/237/350/264/246/345/217/267/346/211/271/351/207/217/344/270/213/345/215/225/346/265/213/350/257/225_20260911_024617.md" +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/cfquant/tests/log/cftrader/346/250/241/346/213/237/350/264/246/345/217/267/346/211/271/351/207/217/344/270/213/345/215/225/346/265/213/350/257/225_20260921_175732.md" +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/cfquant/tests/readme.md +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/cfquant/tests/test_api_tester_browser.py +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/cfquant/tests/test_api_tester_web.py +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/cfquant/tests/test_binding_delete_confirmation.py +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/cfquant/tests/test_callback_requests.py +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/cfquant/tests/test_cftrader.py +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/cfquant/tests/test_cftrader_tutorial.py +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/cfquant/tests/test_cftrader_web.py +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/cfquant/tests/test_credit_compat.py +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/cfquant/tests/test_json_serialization.py +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/cfquant/tests/test_log_management.py +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/cfquant/tests/test_management_batch.py +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/cfquant/tests/test_project_updater.py +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/cfquant/tests/test_python_api_reference.py +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/cfquant/tests/test_qmt_strategy_browser.py +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/cfquant/tests/test_qmt_strategy_deploy.py +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/cfquant/tests/test_qmt_strategy_web.py +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/cfquant/tests/test_tutorial_reader.py +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/cfquant/tests/test_tx_auto_import.py +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/cfquant/tx.py +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/cfquant/xtconstant.py +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/cfquant/xtdata.py +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/cfquant/xttrader.py +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/cfquant.egg-info/dependency_links.txt +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/cfquant.egg-info/entry_points.txt +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/cfquant.egg-info/requires.txt +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/cfquant.egg-info/top_level.txt +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/cfquant_pipe_hub.py +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/cfquant_web_server.py +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/qmt_scripts/CFQUANT.py +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/qmt_scripts/CFQUANT_CTYPE_ALL_LOWLAT.py +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/qmt_scripts/CFQUANT_TRADE_LOWLAT.py +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/qmt_scripts/__init__.py +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/qmt_scripts//345/220/214/350/264/246/345/217/267/347/213/254/347/253/213/345/270/202/345/234/272/CFQUANT_CTYPE_ALL_LOWLAT_SH.py" +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/qmt_scripts//345/220/214/350/264/246/345/217/267/347/213/254/347/253/213/345/270/202/345/234/272/CFQUANT_CTYPE_ALL_LOWLAT_SZ.py" +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/qmt_scripts//345/220/214/350/264/246/345/217/267/347/213/254/347/253/213/345/270/202/345/234/272/CFQUANT_TRADE_LOWLAT_SH.py" +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/qmt_scripts//345/220/214/350/264/246/345/217/267/347/213/254/347/253/213/345/270/202/345/234/272/CFQUANT_TRADE_LOWLAT_SZ.py" +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/qmt_scripts//345/220/214/350/264/246/345/217/267/347/213/254/347/253/213/345/270/202/345/234/272/readme.md" +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/requirements.txt +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/setup.cfg +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/web_dashboard/__init__.py +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/web_dashboard/api-tester.js +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/web_dashboard/avatars/amber-pulse.svg +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/web_dashboard/avatars/copper-grid.svg +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/web_dashboard/avatars/market-blue.svg +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/web_dashboard/avatars/rose-circuit.svg +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/web_dashboard/avatars/signal-green.svg +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/web_dashboard/avatars/slate-wave.svg +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/web_dashboard/avatars/teal-orbit.svg +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/web_dashboard/avatars/violet-node.svg +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/web_dashboard/cftrader-api-data.js +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/web_dashboard/favicon.svg +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/web_dashboard/image/qmt_deploy/image-10.png +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/web_dashboard/image/qmt_deploy/image-11.png +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/web_dashboard/image/qmt_deploy/image-12.png +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/web_dashboard/image/qmt_deploy/image-13.png +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/web_dashboard/image/qmt_deploy/image-14.png +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/web_dashboard/image/qmt_deploy/image-15.png +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/web_dashboard/image/qmt_deploy/image-16.png +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/web_dashboard/image/qmt_deploy/image-17.png +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/web_dashboard/image/qmt_deploy/image-18.png +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/web_dashboard/image/qmt_deploy/image-19.png +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/web_dashboard/image/qmt_deploy/image-20.png +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/web_dashboard/image/qmt_deploy/image-21.png +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/web_dashboard/image/qmt_deploy/image-4.png +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/web_dashboard/image/qmt_deploy/image-5.png +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/web_dashboard/image/qmt_deploy/image-6.png +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/web_dashboard/image/qmt_deploy/image-7.png +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/web_dashboard/image/qmt_deploy/image-8.png +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/web_dashboard/image/qmt_deploy/image-9.png +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/web_dashboard/python-api-data.js +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/web_dashboard/python-api.js +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/web_dashboard/styles.css +0 -0
- {cfquant-0.2.39 → cfquant-0.2.40}/web_dashboard/vendor/mermaid.min.js +0 -0
|
@@ -18,7 +18,7 @@ from .level2 import (
|
|
|
18
18
|
require_l2_callable,
|
|
19
19
|
thousand_price,
|
|
20
20
|
)
|
|
21
|
-
from .xttype import filter_cancelable_orders
|
|
21
|
+
from .xttype import _is_zero_time_value, filter_cancelable_orders
|
|
22
22
|
|
|
23
23
|
|
|
24
24
|
class CfquantQmtBridge(object):
|
|
@@ -1111,23 +1111,26 @@ class CfquantQmtBridge(object):
|
|
|
1111
1111
|
"order_time": self._first_value(obj, (
|
|
1112
1112
|
"time",
|
|
1113
1113
|
"order_time",
|
|
1114
|
-
"entrust_time",
|
|
1114
|
+
"entrust_time",
|
|
1115
1115
|
"insert_time",
|
|
1116
1116
|
"m_strOrderTime",
|
|
1117
1117
|
"m_strEntrustTime",
|
|
1118
1118
|
"m_strInsertTime",
|
|
1119
|
-
"m_nOrderTime",
|
|
1120
|
-
"m_nEntrustTime",
|
|
1121
|
-
"m_nInsertTime",
|
|
1122
|
-
)),
|
|
1119
|
+
"m_nOrderTime",
|
|
1120
|
+
"m_nEntrustTime",
|
|
1121
|
+
"m_nInsertTime",
|
|
1122
|
+
), skip_zero=True),
|
|
1123
1123
|
"order_date": self._first_value(obj, (
|
|
1124
1124
|
"order_date",
|
|
1125
1125
|
"entrust_date",
|
|
1126
|
+
"insert_date",
|
|
1126
1127
|
"m_strOrderDate",
|
|
1127
1128
|
"m_strEntrustDate",
|
|
1129
|
+
"m_strInsertDate",
|
|
1128
1130
|
"m_strTradingDay",
|
|
1129
1131
|
"m_nOrderDate",
|
|
1130
1132
|
"m_nEntrustDate",
|
|
1133
|
+
"m_nInsertDate",
|
|
1131
1134
|
)),
|
|
1132
1135
|
"direction": self._get_value(obj, "m_nDirection"),
|
|
1133
1136
|
"offset_flag": self._get_value(obj, "m_nOffsetFlag"),
|
|
@@ -1205,7 +1208,7 @@ class CfquantQmtBridge(object):
|
|
|
1205
1208
|
"m_strDealTime",
|
|
1206
1209
|
"m_nTradeTime",
|
|
1207
1210
|
"m_nDealTime",
|
|
1208
|
-
)),
|
|
1211
|
+
), skip_zero=True),
|
|
1209
1212
|
"trade_date": self._first_value(obj, (
|
|
1210
1213
|
"trade_date",
|
|
1211
1214
|
"deal_date",
|
|
@@ -1377,12 +1380,14 @@ class CfquantQmtBridge(object):
|
|
|
1377
1380
|
text = " ".join(str(value or "") for value in values).strip().lower()
|
|
1378
1381
|
return "cfquant" if "cfquant" in text else "other"
|
|
1379
1382
|
|
|
1380
|
-
def _first_value(self, obj, names):
|
|
1381
|
-
for name in names:
|
|
1382
|
-
value = self._get_value(obj, name)
|
|
1383
|
-
if value is not None and value != "":
|
|
1384
|
-
|
|
1385
|
-
|
|
1383
|
+
def _first_value(self, obj, names, skip_zero=False):
|
|
1384
|
+
for name in names:
|
|
1385
|
+
value = self._get_value(obj, name)
|
|
1386
|
+
if value is not None and value != "":
|
|
1387
|
+
if skip_zero and _is_zero_time_value(value):
|
|
1388
|
+
continue
|
|
1389
|
+
return value
|
|
1390
|
+
return None
|
|
1386
1391
|
|
|
1387
1392
|
def _object_to_dict(self, obj):
|
|
1388
1393
|
if hasattr(obj, "items"):
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import datetime
|
|
2
|
+
import json
|
|
3
|
+
|
|
4
|
+
from cfquant.normal_bridge import NormalQmtBridge
|
|
5
|
+
from cfquant.xttype import XtOrder
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class RecordingTx(object):
|
|
9
|
+
def __init__(self):
|
|
10
|
+
self.pushes = []
|
|
11
|
+
|
|
12
|
+
def push(self, kind, payload, key):
|
|
13
|
+
self.pushes.append((kind, payload, key))
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def _expected_timestamp(hour=21, minute=24, second=23):
|
|
17
|
+
timezone = datetime.timezone(datetime.timedelta(hours=8))
|
|
18
|
+
value = datetime.datetime(2026, 9, 24, hour, minute, second, tzinfo=timezone)
|
|
19
|
+
return int(value.timestamp())
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def test_order_callback_skips_zero_placeholder_time():
|
|
23
|
+
raw = {
|
|
24
|
+
"time": 0,
|
|
25
|
+
"order_time": 0,
|
|
26
|
+
"m_strOrderTime": "212423",
|
|
27
|
+
"m_strOrderDate": "20260924",
|
|
28
|
+
"m_strAccountID": "A123",
|
|
29
|
+
"m_strInstrumentID": "000001",
|
|
30
|
+
"m_strExchangeID": "SZ",
|
|
31
|
+
}
|
|
32
|
+
bridge = NormalQmtBridge(None, show=False, schedule_timer=False, order_meta_enabled=False)
|
|
33
|
+
tx = RecordingTx()
|
|
34
|
+
bridge.tx = tx
|
|
35
|
+
try:
|
|
36
|
+
bridge.publish_callback_event("trader:on_stock_order", raw)
|
|
37
|
+
payload = json.loads(tx.pushes[-1][1])
|
|
38
|
+
assert payload["data"]["order_time"] == "212423"
|
|
39
|
+
assert XtOrder.from_any(payload["data"]).order_time == _expected_timestamp()
|
|
40
|
+
finally:
|
|
41
|
+
bridge.close()
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def test_order_time_conversion_skips_zero_before_valid_qmt_time():
|
|
45
|
+
raw = {
|
|
46
|
+
"time": 0,
|
|
47
|
+
"m_strOrderTime": "212423",
|
|
48
|
+
"order_date": 0,
|
|
49
|
+
"m_strOrderDate": "20260924",
|
|
50
|
+
}
|
|
51
|
+
assert XtOrder.from_any(raw).order_time == _expected_timestamp()
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def test_order_callback_uses_insert_time_and_insert_date():
|
|
55
|
+
raw = {
|
|
56
|
+
"time": 0,
|
|
57
|
+
"m_strOrderTime": None,
|
|
58
|
+
"m_strInsertTime": "112021",
|
|
59
|
+
"m_strInsertDate": "20260924",
|
|
60
|
+
"m_strAccountID": "A123",
|
|
61
|
+
"m_strInstrumentID": "688051",
|
|
62
|
+
"m_strExchangeID": "SH",
|
|
63
|
+
}
|
|
64
|
+
bridge = NormalQmtBridge(None, show=False, schedule_timer=False, order_meta_enabled=False)
|
|
65
|
+
try:
|
|
66
|
+
row = bridge._format_trade_detail(raw, "order")
|
|
67
|
+
assert row["order_time"] == "112021"
|
|
68
|
+
assert row["order_date"] == "20260924"
|
|
69
|
+
assert XtOrder.from_any(row).order_time == _expected_timestamp(11, 20, 21)
|
|
70
|
+
finally:
|
|
71
|
+
bridge.close()
|
|
@@ -30,7 +30,7 @@ from .runtime_report import build_qmt_runtime_report, module_source_state, sourc
|
|
|
30
30
|
from .xttype import (
|
|
31
31
|
CreditAssure, CreditSloCode, CreditSubjects, StkCompacts, XtCreditDetail, XtPositionStatistics,
|
|
32
32
|
XtAccountInfo, XtAccountStatus, XtSmtAppointmentResponse,
|
|
33
|
-
filter_cancelable_orders, normalize_order_price_type, _with_qmt_compact_aliases,
|
|
33
|
+
filter_cancelable_orders, normalize_order_price_type, _is_zero_time_value, _with_qmt_compact_aliases,
|
|
34
34
|
)
|
|
35
35
|
|
|
36
36
|
|
|
@@ -3069,23 +3069,26 @@ class TxTradeBridge(object):
|
|
|
3069
3069
|
"order_time": self._first_value(obj, (
|
|
3070
3070
|
"time",
|
|
3071
3071
|
"order_time",
|
|
3072
|
-
"entrust_time",
|
|
3072
|
+
"entrust_time",
|
|
3073
3073
|
"insert_time",
|
|
3074
3074
|
"m_strOrderTime",
|
|
3075
3075
|
"m_strEntrustTime",
|
|
3076
3076
|
"m_strInsertTime",
|
|
3077
|
-
"m_nOrderTime",
|
|
3078
|
-
"m_nEntrustTime",
|
|
3079
|
-
"m_nInsertTime",
|
|
3080
|
-
)),
|
|
3077
|
+
"m_nOrderTime",
|
|
3078
|
+
"m_nEntrustTime",
|
|
3079
|
+
"m_nInsertTime",
|
|
3080
|
+
), skip_zero=True),
|
|
3081
3081
|
"order_date": self._first_value(obj, (
|
|
3082
3082
|
"order_date",
|
|
3083
3083
|
"entrust_date",
|
|
3084
|
+
"insert_date",
|
|
3084
3085
|
"m_strOrderDate",
|
|
3085
3086
|
"m_strEntrustDate",
|
|
3087
|
+
"m_strInsertDate",
|
|
3086
3088
|
"m_strTradingDay",
|
|
3087
3089
|
"m_nOrderDate",
|
|
3088
3090
|
"m_nEntrustDate",
|
|
3091
|
+
"m_nInsertDate",
|
|
3089
3092
|
)),
|
|
3090
3093
|
"direction": self._get_value(obj, "m_nDirection"),
|
|
3091
3094
|
"offset_flag": self._get_value(obj, "m_nOffsetFlag"),
|
|
@@ -3166,12 +3169,12 @@ class TxTradeBridge(object):
|
|
|
3166
3169
|
"trade_time": self._first_value(obj, (
|
|
3167
3170
|
"time",
|
|
3168
3171
|
"trade_time",
|
|
3169
|
-
"deal_time",
|
|
3172
|
+
"deal_time",
|
|
3170
3173
|
"m_strTradeTime",
|
|
3171
3174
|
"m_strDealTime",
|
|
3172
|
-
"m_nTradeTime",
|
|
3173
|
-
"m_nDealTime",
|
|
3174
|
-
)),
|
|
3175
|
+
"m_nTradeTime",
|
|
3176
|
+
"m_nDealTime",
|
|
3177
|
+
), skip_zero=True),
|
|
3175
3178
|
"trade_date": self._first_value(obj, (
|
|
3176
3179
|
"trade_date",
|
|
3177
3180
|
"deal_date",
|
|
@@ -3286,11 +3289,13 @@ class TxTradeBridge(object):
|
|
|
3286
3289
|
return value
|
|
3287
3290
|
return None
|
|
3288
3291
|
|
|
3289
|
-
def _first_value(self, obj, names):
|
|
3292
|
+
def _first_value(self, obj, names, skip_zero=False):
|
|
3290
3293
|
for name in names:
|
|
3291
3294
|
value = self._get_value(obj, name)
|
|
3292
3295
|
if value is not None and value != "":
|
|
3293
|
-
|
|
3296
|
+
if skip_zero and _is_zero_time_value(value):
|
|
3297
|
+
continue
|
|
3298
|
+
return value
|
|
3294
3299
|
return None
|
|
3295
3300
|
|
|
3296
3301
|
def _stock_order_type(self, obj):
|
|
@@ -249,10 +249,49 @@ def _coerce_timestamp(value, date_value=None, default=0):
|
|
|
249
249
|
return default
|
|
250
250
|
|
|
251
251
|
|
|
252
|
+
def _is_zero_time_value(value):
|
|
253
|
+
"""Return whether a time field contains the provider's empty value."""
|
|
254
|
+
if value is None or isinstance(value, bool):
|
|
255
|
+
return True
|
|
256
|
+
if isinstance(value, (int, float)):
|
|
257
|
+
return value == 0
|
|
258
|
+
text = str(value).strip()
|
|
259
|
+
if not text:
|
|
260
|
+
return True
|
|
261
|
+
# QMT uses both numeric zero and display forms such as 00:00:00 for an
|
|
262
|
+
# unavailable order/trade time. Do not discard values such as 000001.
|
|
263
|
+
if re.fullmatch(r"[+-]?\d+(?:\.\d+)?", text):
|
|
264
|
+
try:
|
|
265
|
+
return float(text) == 0
|
|
266
|
+
except (TypeError, ValueError):
|
|
267
|
+
return False
|
|
268
|
+
digits = re.sub(r"\D", "", text)
|
|
269
|
+
return bool(digits) and not set(digits) - {"0"}
|
|
270
|
+
|
|
271
|
+
|
|
252
272
|
def _time_field_timestamp(data, time_names, date_names):
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
273
|
+
date_value = None
|
|
274
|
+
for name in _with_qmt_compact_aliases(*date_names):
|
|
275
|
+
if name not in data:
|
|
276
|
+
continue
|
|
277
|
+
candidate = data.get(name)
|
|
278
|
+
if _is_empty(candidate) or _is_zero_time_value(candidate):
|
|
279
|
+
continue
|
|
280
|
+
date_value = candidate
|
|
281
|
+
break
|
|
282
|
+
# A callback can expose a generic ``time``/canonical field as 0 while a
|
|
283
|
+
# later QMT field (for example m_strOrderTime) contains the real value.
|
|
284
|
+
# Try every candidate instead of letting the zero placeholder win.
|
|
285
|
+
for name in _with_qmt_compact_aliases(*time_names):
|
|
286
|
+
if name not in data:
|
|
287
|
+
continue
|
|
288
|
+
value = data.get(name)
|
|
289
|
+
if _is_empty(value) or _is_zero_time_value(value):
|
|
290
|
+
continue
|
|
291
|
+
timestamp = _coerce_timestamp(value, date_value)
|
|
292
|
+
if timestamp:
|
|
293
|
+
return timestamp
|
|
294
|
+
return 0
|
|
256
295
|
|
|
257
296
|
|
|
258
297
|
def normalize_order_price_type(value, market=""):
|
|
@@ -636,7 +675,7 @@ class XtOrder(DictObject):
|
|
|
636
675
|
data["order_time"] = _time_field_timestamp(
|
|
637
676
|
data,
|
|
638
677
|
("order_time", "time", "entrust_time", "insert_time", "m_strOrderTime", "m_strEntrustTime", "m_strInsertTime", "m_nOrderTime", "m_nEntrustTime", "m_nInsertTime"),
|
|
639
|
-
("order_date", "entrust_date", "m_strOrderDate", "m_strEntrustDate", "m_strTradingDay", "m_nOrderDate", "m_nEntrustDate"),
|
|
678
|
+
("order_date", "entrust_date", "insert_date", "m_strOrderDate", "m_strEntrustDate", "m_strInsertDate", "m_strTradingDay", "m_nOrderDate", "m_nEntrustDate", "m_nInsertDate"),
|
|
640
679
|
)
|
|
641
680
|
for name in ("order_type", "order_volume", "price_type", "traded_volume", "order_status", "direction", "offset_flag"):
|
|
642
681
|
data[name] = _coerce_int(data.get(name))
|
|
@@ -96,6 +96,7 @@ cfquant/tests/test_credit_compat.py
|
|
|
96
96
|
cfquant/tests/test_json_serialization.py
|
|
97
97
|
cfquant/tests/test_log_management.py
|
|
98
98
|
cfquant/tests/test_management_batch.py
|
|
99
|
+
cfquant/tests/test_order_time_callback.py
|
|
99
100
|
cfquant/tests/test_project_updater.py
|
|
100
101
|
cfquant/tests/test_python_api_reference.py
|
|
101
102
|
cfquant/tests/test_qmt_strategy_browser.py
|
|
@@ -1529,6 +1529,23 @@ def l2_query(func, period, params):
|
|
|
1529
1529
|
return {"columns": columns, "records": rows}
|
|
1530
1530
|
|
|
1531
1531
|
|
|
1532
|
+
def _is_zero_time_value(value):
|
|
1533
|
+
if value is None or isinstance(value, bool):
|
|
1534
|
+
return True
|
|
1535
|
+
if isinstance(value, (int, float)):
|
|
1536
|
+
return value == 0
|
|
1537
|
+
text = str(value).strip()
|
|
1538
|
+
if not text:
|
|
1539
|
+
return True
|
|
1540
|
+
if re.fullmatch(r"[+-]?\d+(?:\.\d+)?", text):
|
|
1541
|
+
try:
|
|
1542
|
+
return float(text) == 0
|
|
1543
|
+
except (TypeError, ValueError):
|
|
1544
|
+
return False
|
|
1545
|
+
digits = re.sub(r"\D", "", text)
|
|
1546
|
+
return bool(digits) and not set(digits) - {"0"}
|
|
1547
|
+
|
|
1548
|
+
|
|
1532
1549
|
class TxTradeBridge(object):
|
|
1533
1550
|
def __init__(
|
|
1534
1551
|
self,
|
|
@@ -3617,6 +3634,7 @@ class TxTradeBridge(object):
|
|
|
3617
3634
|
"order_sysid": self._get_value(obj, "m_strOrderSysID"),
|
|
3618
3635
|
"order_type": self._stock_order_type(obj),
|
|
3619
3636
|
"order_time": self._first_value(obj, (
|
|
3637
|
+
"time",
|
|
3620
3638
|
"order_time",
|
|
3621
3639
|
"entrust_time",
|
|
3622
3640
|
"insert_time",
|
|
@@ -3626,15 +3644,18 @@ class TxTradeBridge(object):
|
|
|
3626
3644
|
"m_nOrderTime",
|
|
3627
3645
|
"m_nEntrustTime",
|
|
3628
3646
|
"m_nInsertTime",
|
|
3629
|
-
)),
|
|
3647
|
+
), skip_zero=True),
|
|
3630
3648
|
"order_date": self._first_value(obj, (
|
|
3631
3649
|
"order_date",
|
|
3632
3650
|
"entrust_date",
|
|
3651
|
+
"insert_date",
|
|
3633
3652
|
"m_strOrderDate",
|
|
3634
3653
|
"m_strEntrustDate",
|
|
3654
|
+
"m_strInsertDate",
|
|
3635
3655
|
"m_strTradingDay",
|
|
3636
3656
|
"m_nOrderDate",
|
|
3637
3657
|
"m_nEntrustDate",
|
|
3658
|
+
"m_nInsertDate",
|
|
3638
3659
|
)),
|
|
3639
3660
|
"direction": self._get_value(obj, "m_nDirection"),
|
|
3640
3661
|
"offset_flag": self._get_value(obj, "m_nOffsetFlag"),
|
|
@@ -3707,13 +3728,14 @@ class TxTradeBridge(object):
|
|
|
3707
3728
|
"strategy_name": self._get_value(obj, "m_strStrategyName"),
|
|
3708
3729
|
"order_remark": self._first_value(obj, ("m_strRemark", "m_strOrderRemark")),
|
|
3709
3730
|
"trade_time": self._first_value(obj, (
|
|
3731
|
+
"time",
|
|
3710
3732
|
"trade_time",
|
|
3711
3733
|
"deal_time",
|
|
3712
3734
|
"m_strTradeTime",
|
|
3713
3735
|
"m_strDealTime",
|
|
3714
3736
|
"m_nTradeTime",
|
|
3715
3737
|
"m_nDealTime",
|
|
3716
|
-
)),
|
|
3738
|
+
), skip_zero=True),
|
|
3717
3739
|
"trade_date": self._first_value(obj, (
|
|
3718
3740
|
"trade_date",
|
|
3719
3741
|
"deal_date",
|
|
@@ -3850,10 +3872,12 @@ class TxTradeBridge(object):
|
|
|
3850
3872
|
continue
|
|
3851
3873
|
return value
|
|
3852
3874
|
return None
|
|
3853
|
-
def _first_value(self, obj, names):
|
|
3875
|
+
def _first_value(self, obj, names, skip_zero=False):
|
|
3854
3876
|
for name in names:
|
|
3855
3877
|
value = self._get_value(obj, name)
|
|
3856
3878
|
if value is not None and value != "":
|
|
3879
|
+
if skip_zero and _is_zero_time_value(value):
|
|
3880
|
+
continue
|
|
3857
3881
|
return value
|
|
3858
3882
|
return None
|
|
3859
3883
|
|
|
@@ -1583,6 +1583,23 @@ def l2_query(func, period, params):
|
|
|
1583
1583
|
return {"columns": columns, "records": rows}
|
|
1584
1584
|
|
|
1585
1585
|
|
|
1586
|
+
def _is_zero_time_value(value):
|
|
1587
|
+
if value is None or isinstance(value, bool):
|
|
1588
|
+
return True
|
|
1589
|
+
if isinstance(value, (int, float)):
|
|
1590
|
+
return value == 0
|
|
1591
|
+
text = str(value).strip()
|
|
1592
|
+
if not text:
|
|
1593
|
+
return True
|
|
1594
|
+
if re.fullmatch(r"[+-]?\d+(?:\.\d+)?", text):
|
|
1595
|
+
try:
|
|
1596
|
+
return float(text) == 0
|
|
1597
|
+
except (TypeError, ValueError):
|
|
1598
|
+
return False
|
|
1599
|
+
digits = re.sub(r"\D", "", text)
|
|
1600
|
+
return bool(digits) and not set(digits) - {"0"}
|
|
1601
|
+
|
|
1602
|
+
|
|
1586
1603
|
class TxTradeBridge(object):
|
|
1587
1604
|
def __init__(
|
|
1588
1605
|
self,
|
|
@@ -3709,6 +3726,7 @@ class TxTradeBridge(object):
|
|
|
3709
3726
|
"order_sysid": self._get_value(obj, "m_strOrderSysID"),
|
|
3710
3727
|
"order_type": self._stock_order_type(obj),
|
|
3711
3728
|
"order_time": self._first_value(obj, (
|
|
3729
|
+
"time",
|
|
3712
3730
|
"order_time",
|
|
3713
3731
|
"entrust_time",
|
|
3714
3732
|
"insert_time",
|
|
@@ -3718,15 +3736,18 @@ class TxTradeBridge(object):
|
|
|
3718
3736
|
"m_nOrderTime",
|
|
3719
3737
|
"m_nEntrustTime",
|
|
3720
3738
|
"m_nInsertTime",
|
|
3721
|
-
)),
|
|
3739
|
+
), skip_zero=True),
|
|
3722
3740
|
"order_date": self._first_value(obj, (
|
|
3723
3741
|
"order_date",
|
|
3724
3742
|
"entrust_date",
|
|
3743
|
+
"insert_date",
|
|
3725
3744
|
"m_strOrderDate",
|
|
3726
3745
|
"m_strEntrustDate",
|
|
3746
|
+
"m_strInsertDate",
|
|
3727
3747
|
"m_strTradingDay",
|
|
3728
3748
|
"m_nOrderDate",
|
|
3729
3749
|
"m_nEntrustDate",
|
|
3750
|
+
"m_nInsertDate",
|
|
3730
3751
|
)),
|
|
3731
3752
|
"direction": self._get_value(obj, "m_nDirection"),
|
|
3732
3753
|
"offset_flag": self._get_value(obj, "m_nOffsetFlag"),
|
|
@@ -3799,13 +3820,14 @@ class TxTradeBridge(object):
|
|
|
3799
3820
|
"strategy_name": self._get_value(obj, "m_strStrategyName"),
|
|
3800
3821
|
"order_remark": self._first_value(obj, ("m_strRemark", "m_strOrderRemark")),
|
|
3801
3822
|
"trade_time": self._first_value(obj, (
|
|
3823
|
+
"time",
|
|
3802
3824
|
"trade_time",
|
|
3803
3825
|
"deal_time",
|
|
3804
3826
|
"m_strTradeTime",
|
|
3805
3827
|
"m_strDealTime",
|
|
3806
3828
|
"m_nTradeTime",
|
|
3807
3829
|
"m_nDealTime",
|
|
3808
|
-
)),
|
|
3830
|
+
), skip_zero=True),
|
|
3809
3831
|
"trade_date": self._first_value(obj, (
|
|
3810
3832
|
"trade_date",
|
|
3811
3833
|
"deal_date",
|
|
@@ -3942,10 +3964,12 @@ class TxTradeBridge(object):
|
|
|
3942
3964
|
continue
|
|
3943
3965
|
return value
|
|
3944
3966
|
return None
|
|
3945
|
-
def _first_value(self, obj, names):
|
|
3967
|
+
def _first_value(self, obj, names, skip_zero=False):
|
|
3946
3968
|
for name in names:
|
|
3947
3969
|
value = self._get_value(obj, name)
|
|
3948
3970
|
if value is not None and value != "":
|
|
3971
|
+
if skip_zero and _is_zero_time_value(value):
|
|
3972
|
+
continue
|
|
3949
3973
|
return value
|
|
3950
3974
|
return None
|
|
3951
3975
|
|
|
@@ -1583,6 +1583,23 @@ def l2_query(func, period, params):
|
|
|
1583
1583
|
return {"columns": columns, "records": rows}
|
|
1584
1584
|
|
|
1585
1585
|
|
|
1586
|
+
def _is_zero_time_value(value):
|
|
1587
|
+
if value is None or isinstance(value, bool):
|
|
1588
|
+
return True
|
|
1589
|
+
if isinstance(value, (int, float)):
|
|
1590
|
+
return value == 0
|
|
1591
|
+
text = str(value).strip()
|
|
1592
|
+
if not text:
|
|
1593
|
+
return True
|
|
1594
|
+
if re.fullmatch(r"[+-]?\d+(?:\.\d+)?", text):
|
|
1595
|
+
try:
|
|
1596
|
+
return float(text) == 0
|
|
1597
|
+
except (TypeError, ValueError):
|
|
1598
|
+
return False
|
|
1599
|
+
digits = re.sub(r"\D", "", text)
|
|
1600
|
+
return bool(digits) and not set(digits) - {"0"}
|
|
1601
|
+
|
|
1602
|
+
|
|
1586
1603
|
class TxTradeBridge(object):
|
|
1587
1604
|
def __init__(
|
|
1588
1605
|
self,
|
|
@@ -3709,6 +3726,7 @@ class TxTradeBridge(object):
|
|
|
3709
3726
|
"order_sysid": self._get_value(obj, "m_strOrderSysID"),
|
|
3710
3727
|
"order_type": self._stock_order_type(obj),
|
|
3711
3728
|
"order_time": self._first_value(obj, (
|
|
3729
|
+
"time",
|
|
3712
3730
|
"order_time",
|
|
3713
3731
|
"entrust_time",
|
|
3714
3732
|
"insert_time",
|
|
@@ -3718,15 +3736,18 @@ class TxTradeBridge(object):
|
|
|
3718
3736
|
"m_nOrderTime",
|
|
3719
3737
|
"m_nEntrustTime",
|
|
3720
3738
|
"m_nInsertTime",
|
|
3721
|
-
)),
|
|
3739
|
+
), skip_zero=True),
|
|
3722
3740
|
"order_date": self._first_value(obj, (
|
|
3723
3741
|
"order_date",
|
|
3724
3742
|
"entrust_date",
|
|
3743
|
+
"insert_date",
|
|
3725
3744
|
"m_strOrderDate",
|
|
3726
3745
|
"m_strEntrustDate",
|
|
3746
|
+
"m_strInsertDate",
|
|
3727
3747
|
"m_strTradingDay",
|
|
3728
3748
|
"m_nOrderDate",
|
|
3729
3749
|
"m_nEntrustDate",
|
|
3750
|
+
"m_nInsertDate",
|
|
3730
3751
|
)),
|
|
3731
3752
|
"direction": self._get_value(obj, "m_nDirection"),
|
|
3732
3753
|
"offset_flag": self._get_value(obj, "m_nOffsetFlag"),
|
|
@@ -3799,13 +3820,14 @@ class TxTradeBridge(object):
|
|
|
3799
3820
|
"strategy_name": self._get_value(obj, "m_strStrategyName"),
|
|
3800
3821
|
"order_remark": self._first_value(obj, ("m_strRemark", "m_strOrderRemark")),
|
|
3801
3822
|
"trade_time": self._first_value(obj, (
|
|
3823
|
+
"time",
|
|
3802
3824
|
"trade_time",
|
|
3803
3825
|
"deal_time",
|
|
3804
3826
|
"m_strTradeTime",
|
|
3805
3827
|
"m_strDealTime",
|
|
3806
3828
|
"m_nTradeTime",
|
|
3807
3829
|
"m_nDealTime",
|
|
3808
|
-
)),
|
|
3830
|
+
), skip_zero=True),
|
|
3809
3831
|
"trade_date": self._first_value(obj, (
|
|
3810
3832
|
"trade_date",
|
|
3811
3833
|
"deal_date",
|
|
@@ -3942,10 +3964,12 @@ class TxTradeBridge(object):
|
|
|
3942
3964
|
continue
|
|
3943
3965
|
return value
|
|
3944
3966
|
return None
|
|
3945
|
-
def _first_value(self, obj, names):
|
|
3967
|
+
def _first_value(self, obj, names, skip_zero=False):
|
|
3946
3968
|
for name in names:
|
|
3947
3969
|
value = self._get_value(obj, name)
|
|
3948
3970
|
if value is not None and value != "":
|
|
3971
|
+
if skip_zero and _is_zero_time_value(value):
|
|
3972
|
+
continue
|
|
3949
3973
|
return value
|
|
3950
3974
|
return None
|
|
3951
3975
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const FRONTEND_VERSION = '
|
|
1
|
+
const FRONTEND_VERSION = 'web_20260924_01';
|
|
2
2
|
|
|
3
3
|
const state = {
|
|
4
4
|
accountId: '',
|
|
@@ -11029,11 +11029,14 @@ const ORDER_TIME_FIELDS = [
|
|
|
11029
11029
|
const ORDER_DATE_FIELDS = [
|
|
11030
11030
|
'order_date',
|
|
11031
11031
|
'entrust_date',
|
|
11032
|
+
'insert_date',
|
|
11032
11033
|
'm_strOrderDate',
|
|
11033
11034
|
'm_strEntrustDate',
|
|
11035
|
+
'm_strInsertDate',
|
|
11034
11036
|
'm_strTradingDay',
|
|
11035
11037
|
'm_nOrderDate',
|
|
11036
11038
|
'm_nEntrustDate',
|
|
11039
|
+
'm_nInsertDate',
|
|
11037
11040
|
];
|
|
11038
11041
|
|
|
11039
11042
|
const TRADE_TIME_FIELDS = [
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
6
6
|
<title>cfquant 控制台</title>
|
|
7
7
|
<link rel="icon" type="image/svg+xml" href="/favicon.svg">
|
|
8
|
-
<link rel="stylesheet" href="/styles.css?v=
|
|
8
|
+
<link rel="stylesheet" href="/styles.css?v=web_20260924_01">
|
|
9
9
|
</head>
|
|
10
10
|
<body>
|
|
11
11
|
<div id="webAuthOverlay" class="auth-overlay hidden" aria-live="polite">
|
|
@@ -3211,6 +3211,6 @@ else:
|
|
|
3211
3211
|
<script src="/cftrader-api-data.js?v=20260911_02"></script>
|
|
3212
3212
|
<script src="/api-tester.js?v=20260916_apikey_01"></script>
|
|
3213
3213
|
<script src="/python-api.js?v=20260911_api_test_01"></script>
|
|
3214
|
-
<script src="/app.js?v=
|
|
3214
|
+
<script src="/app.js?v=web_20260924_01"></script>
|
|
3215
3215
|
</body>
|
|
3216
3216
|
</html>
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|