cfquant 0.2.37__tar.gz → 0.2.38__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.37 → cfquant-0.2.38}/PKG-INFO +1 -1
- {cfquant-0.2.37 → cfquant-0.2.38}/cfquant/qmt_bridge.py +3 -1
- {cfquant-0.2.37 → cfquant-0.2.38}/cfquant/tx_trade_bridge.py +4 -2
- {cfquant-0.2.37 → cfquant-0.2.38}/cfquant/version.py +2 -2
- {cfquant-0.2.37 → cfquant-0.2.38}/cfquant/xttype.py +60 -18
- {cfquant-0.2.37 → cfquant-0.2.38}/cfquant.egg-info/PKG-INFO +1 -1
- {cfquant-0.2.37 → cfquant-0.2.38}/pyproject.toml +1 -1
- {cfquant-0.2.37 → cfquant-0.2.38}/web_dashboard/app.js +45 -7
- {cfquant-0.2.37 → cfquant-0.2.38}/web_dashboard/index.html +2 -3
- {cfquant-0.2.37 → cfquant-0.2.38}/LICENSE +0 -0
- {cfquant-0.2.37 → cfquant-0.2.38}/LTtx/__init__.py +0 -0
- {cfquant-0.2.37 → cfquant-0.2.38}/LTtx/tx/Config.txt +0 -0
- {cfquant-0.2.37 → cfquant-0.2.38}/LTtx/tx/LTtx_server.py +0 -0
- {cfquant-0.2.37 → cfquant-0.2.38}/LTtx/tx/__init__.py +0 -0
- {cfquant-0.2.37 → cfquant-0.2.38}/LTtx/tx/tx.py +0 -0
- {cfquant-0.2.37 → cfquant-0.2.38}/MANIFEST.in +0 -0
- {cfquant-0.2.37 → cfquant-0.2.38}/README.md +0 -0
- {cfquant-0.2.37 → cfquant-0.2.38}/cfquant/__init__.py +0 -0
- {cfquant-0.2.37 → cfquant-0.2.38}/cfquant/_editable_install.py +0 -0
- {cfquant-0.2.37 → cfquant-0.2.38}/cfquant/account_routing.py +0 -0
- {cfquant-0.2.37 → cfquant-0.2.38}/cfquant/batch_orders.py +0 -0
- {cfquant-0.2.37 → cfquant-0.2.38}/cfquant/cftrader.py +0 -0
- {cfquant-0.2.37 → cfquant-0.2.38}/cfquant/channels.py +0 -0
- {cfquant-0.2.37 → cfquant-0.2.38}/cfquant/cli.py +0 -0
- {cfquant-0.2.37 → cfquant-0.2.38}/cfquant/client.py +0 -0
- {cfquant-0.2.37 → cfquant-0.2.38}/cfquant/config.py +0 -0
- {cfquant-0.2.37 → cfquant-0.2.38}/cfquant/hub.py +0 -0
- {cfquant-0.2.37 → cfquant-0.2.38}/cfquant/level2.py +0 -0
- {cfquant-0.2.37 → cfquant-0.2.38}/cfquant/log_management.py +0 -0
- {cfquant-0.2.37 → cfquant-0.2.38}/cfquant/logging_i18n.py +0 -0
- {cfquant-0.2.37 → cfquant-0.2.38}/cfquant/normal_bridge.py +0 -0
- {cfquant-0.2.37 → cfquant-0.2.38}/cfquant/order_meta.py +0 -0
- {cfquant-0.2.37 → cfquant-0.2.38}/cfquant/pipe_bridge.py +0 -0
- {cfquant-0.2.37 → cfquant-0.2.38}/cfquant/pipe_client.py +0 -0
- {cfquant-0.2.37 → cfquant-0.2.38}/cfquant/pipe_hub.py +0 -0
- {cfquant-0.2.37 → cfquant-0.2.38}/cfquant/pipe_transport.py +0 -0
- {cfquant-0.2.37 → cfquant-0.2.38}/cfquant/protocol.py +0 -0
- {cfquant-0.2.37 → cfquant-0.2.38}/cfquant/qmt_strategy_deploy.py +0 -0
- {cfquant-0.2.37 → cfquant-0.2.38}/cfquant/qmt_strategy_package.py +0 -0
- {cfquant-0.2.37 → cfquant-0.2.38}/cfquant/qmt_strategy_runtime.py +0 -0
- {cfquant-0.2.37 → cfquant-0.2.38}/cfquant/runtime_report.py +0 -0
- {cfquant-0.2.37 → cfquant-0.2.38}/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.37 → cfquant-0.2.38}/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.37 → cfquant-0.2.38}/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.37 → cfquant-0.2.38}/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.37 → cfquant-0.2.38}/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.37 → cfquant-0.2.38}/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.37 → cfquant-0.2.38}/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.37 → cfquant-0.2.38}/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.37 → cfquant-0.2.38}/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.37 → cfquant-0.2.38}/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.37 → cfquant-0.2.38}/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.37 → cfquant-0.2.38}/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.37 → cfquant-0.2.38}/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.37 → cfquant-0.2.38}/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.37 → cfquant-0.2.38}/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.37 → cfquant-0.2.38}/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.37 → cfquant-0.2.38}/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.37 → cfquant-0.2.38}/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.37 → cfquant-0.2.38}/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.37 → cfquant-0.2.38}/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.37 → cfquant-0.2.38}/cfquant/tests/29_Level2/350/241/214/346/203/205/346/265/213/350/257/225.py" +0 -0
- {cfquant-0.2.37 → cfquant-0.2.38}/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.37 → cfquant-0.2.38}/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.37 → cfquant-0.2.38}/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.37 → cfquant-0.2.38}/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.37 → cfquant-0.2.38}/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.37 → cfquant-0.2.38}/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.37 → cfquant-0.2.38}/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.37 → cfquant-0.2.38}/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.37 → cfquant-0.2.38}/cfquant/tests/6_/345/233/236/350/260/203/346/265/213/350/257/225.py" +0 -0
- {cfquant-0.2.37 → cfquant-0.2.38}/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.37 → cfquant-0.2.38}/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.37 → cfquant-0.2.38}/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.37 → cfquant-0.2.38}/cfquant/tests/_helpers.py +0 -0
- {cfquant-0.2.37 → cfquant-0.2.38}/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.37 → cfquant-0.2.38}/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.37 → cfquant-0.2.38}/cfquant/tests/readme.md +0 -0
- {cfquant-0.2.37 → cfquant-0.2.38}/cfquant/tests/test_api_tester_browser.py +0 -0
- {cfquant-0.2.37 → cfquant-0.2.38}/cfquant/tests/test_api_tester_web.py +0 -0
- {cfquant-0.2.37 → cfquant-0.2.38}/cfquant/tests/test_binding_delete_confirmation.py +0 -0
- {cfquant-0.2.37 → cfquant-0.2.38}/cfquant/tests/test_cftrader.py +0 -0
- {cfquant-0.2.37 → cfquant-0.2.38}/cfquant/tests/test_cftrader_tutorial.py +0 -0
- {cfquant-0.2.37 → cfquant-0.2.38}/cfquant/tests/test_cftrader_web.py +0 -0
- {cfquant-0.2.37 → cfquant-0.2.38}/cfquant/tests/test_credit_compat.py +0 -0
- {cfquant-0.2.37 → cfquant-0.2.38}/cfquant/tests/test_json_serialization.py +0 -0
- {cfquant-0.2.37 → cfquant-0.2.38}/cfquant/tests/test_log_management.py +0 -0
- {cfquant-0.2.37 → cfquant-0.2.38}/cfquant/tests/test_management_batch.py +0 -0
- {cfquant-0.2.37 → cfquant-0.2.38}/cfquant/tests/test_project_updater.py +0 -0
- {cfquant-0.2.37 → cfquant-0.2.38}/cfquant/tests/test_python_api_reference.py +0 -0
- {cfquant-0.2.37 → cfquant-0.2.38}/cfquant/tests/test_qmt_strategy_browser.py +0 -0
- {cfquant-0.2.37 → cfquant-0.2.38}/cfquant/tests/test_qmt_strategy_deploy.py +0 -0
- {cfquant-0.2.37 → cfquant-0.2.38}/cfquant/tests/test_qmt_strategy_web.py +0 -0
- {cfquant-0.2.37 → cfquant-0.2.38}/cfquant/tests/test_tutorial_reader.py +0 -0
- {cfquant-0.2.37 → cfquant-0.2.38}/cfquant/tests/test_tx_auto_import.py +0 -0
- {cfquant-0.2.37 → cfquant-0.2.38}/cfquant/tx.py +0 -0
- {cfquant-0.2.37 → cfquant-0.2.38}/cfquant/xtconstant.py +0 -0
- {cfquant-0.2.37 → cfquant-0.2.38}/cfquant/xtdata.py +0 -0
- {cfquant-0.2.37 → cfquant-0.2.38}/cfquant/xttrader.py +0 -0
- {cfquant-0.2.37 → cfquant-0.2.38}/cfquant.egg-info/SOURCES.txt +0 -0
- {cfquant-0.2.37 → cfquant-0.2.38}/cfquant.egg-info/dependency_links.txt +0 -0
- {cfquant-0.2.37 → cfquant-0.2.38}/cfquant.egg-info/entry_points.txt +0 -0
- {cfquant-0.2.37 → cfquant-0.2.38}/cfquant.egg-info/requires.txt +0 -0
- {cfquant-0.2.37 → cfquant-0.2.38}/cfquant.egg-info/top_level.txt +0 -0
- {cfquant-0.2.37 → cfquant-0.2.38}/cfquant_pipe_hub.py +0 -0
- {cfquant-0.2.37 → cfquant-0.2.38}/cfquant_web_server.py +0 -0
- {cfquant-0.2.37 → cfquant-0.2.38}/qmt_scripts/CFQUANT.py +0 -0
- {cfquant-0.2.37 → cfquant-0.2.38}/qmt_scripts/CFQUANT_CTYPE_ALL_LOWLAT.py +0 -0
- {cfquant-0.2.37 → cfquant-0.2.38}/qmt_scripts/CFQUANT_LITE.py +0 -0
- {cfquant-0.2.37 → cfquant-0.2.38}/qmt_scripts/CFQUANT_TRADE_LOWLAT.py +0 -0
- {cfquant-0.2.37 → cfquant-0.2.38}/qmt_scripts/__init__.py +0 -0
- {cfquant-0.2.37 → cfquant-0.2.38}/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.37 → cfquant-0.2.38}/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.37 → cfquant-0.2.38}/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" +0 -0
- {cfquant-0.2.37 → cfquant-0.2.38}/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" +0 -0
- {cfquant-0.2.37 → cfquant-0.2.38}/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.37 → cfquant-0.2.38}/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.37 → cfquant-0.2.38}/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.37 → cfquant-0.2.38}/requirements.txt +0 -0
- {cfquant-0.2.37 → cfquant-0.2.38}/setup.cfg +0 -0
- {cfquant-0.2.37 → cfquant-0.2.38}/web_dashboard/__init__.py +0 -0
- {cfquant-0.2.37 → cfquant-0.2.38}/web_dashboard/api-tester.js +0 -0
- {cfquant-0.2.37 → cfquant-0.2.38}/web_dashboard/avatars/amber-pulse.svg +0 -0
- {cfquant-0.2.37 → cfquant-0.2.38}/web_dashboard/avatars/copper-grid.svg +0 -0
- {cfquant-0.2.37 → cfquant-0.2.38}/web_dashboard/avatars/market-blue.svg +0 -0
- {cfquant-0.2.37 → cfquant-0.2.38}/web_dashboard/avatars/rose-circuit.svg +0 -0
- {cfquant-0.2.37 → cfquant-0.2.38}/web_dashboard/avatars/signal-green.svg +0 -0
- {cfquant-0.2.37 → cfquant-0.2.38}/web_dashboard/avatars/slate-wave.svg +0 -0
- {cfquant-0.2.37 → cfquant-0.2.38}/web_dashboard/avatars/teal-orbit.svg +0 -0
- {cfquant-0.2.37 → cfquant-0.2.38}/web_dashboard/avatars/violet-node.svg +0 -0
- {cfquant-0.2.37 → cfquant-0.2.38}/web_dashboard/cftrader-api-data.js +0 -0
- {cfquant-0.2.37 → cfquant-0.2.38}/web_dashboard/favicon.svg +0 -0
- {cfquant-0.2.37 → cfquant-0.2.38}/web_dashboard/image/qmt_deploy/image-10.png +0 -0
- {cfquant-0.2.37 → cfquant-0.2.38}/web_dashboard/image/qmt_deploy/image-11.png +0 -0
- {cfquant-0.2.37 → cfquant-0.2.38}/web_dashboard/image/qmt_deploy/image-12.png +0 -0
- {cfquant-0.2.37 → cfquant-0.2.38}/web_dashboard/image/qmt_deploy/image-13.png +0 -0
- {cfquant-0.2.37 → cfquant-0.2.38}/web_dashboard/image/qmt_deploy/image-14.png +0 -0
- {cfquant-0.2.37 → cfquant-0.2.38}/web_dashboard/image/qmt_deploy/image-15.png +0 -0
- {cfquant-0.2.37 → cfquant-0.2.38}/web_dashboard/image/qmt_deploy/image-16.png +0 -0
- {cfquant-0.2.37 → cfquant-0.2.38}/web_dashboard/image/qmt_deploy/image-17.png +0 -0
- {cfquant-0.2.37 → cfquant-0.2.38}/web_dashboard/image/qmt_deploy/image-18.png +0 -0
- {cfquant-0.2.37 → cfquant-0.2.38}/web_dashboard/image/qmt_deploy/image-19.png +0 -0
- {cfquant-0.2.37 → cfquant-0.2.38}/web_dashboard/image/qmt_deploy/image-20.png +0 -0
- {cfquant-0.2.37 → cfquant-0.2.38}/web_dashboard/image/qmt_deploy/image-21.png +0 -0
- {cfquant-0.2.37 → cfquant-0.2.38}/web_dashboard/image/qmt_deploy/image-4.png +0 -0
- {cfquant-0.2.37 → cfquant-0.2.38}/web_dashboard/image/qmt_deploy/image-5.png +0 -0
- {cfquant-0.2.37 → cfquant-0.2.38}/web_dashboard/image/qmt_deploy/image-6.png +0 -0
- {cfquant-0.2.37 → cfquant-0.2.38}/web_dashboard/image/qmt_deploy/image-7.png +0 -0
- {cfquant-0.2.37 → cfquant-0.2.38}/web_dashboard/image/qmt_deploy/image-8.png +0 -0
- {cfquant-0.2.37 → cfquant-0.2.38}/web_dashboard/image/qmt_deploy/image-9.png +0 -0
- {cfquant-0.2.37 → cfquant-0.2.38}/web_dashboard/python-api-data.js +0 -0
- {cfquant-0.2.37 → cfquant-0.2.38}/web_dashboard/python-api.js +0 -0
- {cfquant-0.2.37 → cfquant-0.2.38}/web_dashboard/styles.css +0 -0
- {cfquant-0.2.37 → cfquant-0.2.38}/web_dashboard/vendor/mermaid.min.js +0 -0
|
@@ -1109,7 +1109,8 @@ class CfquantQmtBridge(object):
|
|
|
1109
1109
|
"order_sysid": self._get_value(obj, "m_strOrderSysID"),
|
|
1110
1110
|
"order_type": self._stock_order_type(obj),
|
|
1111
1111
|
"order_time": self._first_value(obj, (
|
|
1112
|
-
"
|
|
1112
|
+
"time",
|
|
1113
|
+
"order_time",
|
|
1113
1114
|
"entrust_time",
|
|
1114
1115
|
"insert_time",
|
|
1115
1116
|
"m_strOrderTime",
|
|
@@ -1197,6 +1198,7 @@ class CfquantQmtBridge(object):
|
|
|
1197
1198
|
"order_sysid": self._get_value(obj, "m_strOrderSysID"),
|
|
1198
1199
|
"traded_id": self._first_value(obj, ("m_strTradeID", "m_strDealID", "m_nTradeID", "m_nDealID")),
|
|
1199
1200
|
"trade_time": self._first_value(obj, (
|
|
1201
|
+
"time",
|
|
1200
1202
|
"trade_time",
|
|
1201
1203
|
"deal_time",
|
|
1202
1204
|
"m_strTradeTime",
|
|
@@ -3067,7 +3067,8 @@ class TxTradeBridge(object):
|
|
|
3067
3067
|
"order_sysid": self._get_value(obj, "m_strOrderSysID"),
|
|
3068
3068
|
"order_type": self._stock_order_type(obj),
|
|
3069
3069
|
"order_time": self._first_value(obj, (
|
|
3070
|
-
"
|
|
3070
|
+
"time",
|
|
3071
|
+
"order_time",
|
|
3071
3072
|
"entrust_time",
|
|
3072
3073
|
"insert_time",
|
|
3073
3074
|
"m_strOrderTime",
|
|
@@ -3163,7 +3164,8 @@ class TxTradeBridge(object):
|
|
|
3163
3164
|
"contract_no": self._first_value(obj, ("contract_no", "m_strCompactNo", "m_strContractNo", "m_strCompactID")),
|
|
3164
3165
|
"stock_code1": self._first_value(obj, ("stock_code1", "m_stockCode", "m_strStockCode1", "m_strUnderCode")),
|
|
3165
3166
|
"trade_time": self._first_value(obj, (
|
|
3166
|
-
"
|
|
3167
|
+
"time",
|
|
3168
|
+
"trade_time",
|
|
3167
3169
|
"deal_time",
|
|
3168
3170
|
"m_strTradeTime",
|
|
3169
3171
|
"m_strDealTime",
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
|
+
import datetime
|
|
2
3
|
import re
|
|
3
4
|
|
|
4
5
|
from . import xtconstant
|
|
@@ -198,31 +199,62 @@ def _coerce_bool(value, default=False):
|
|
|
198
199
|
return default
|
|
199
200
|
|
|
200
201
|
|
|
201
|
-
def
|
|
202
|
-
"""Convert QMT's
|
|
202
|
+
def _coerce_timestamp(value, date_value=None, default=0):
|
|
203
|
+
"""Convert QMT's display time to MiniQMT's Unix timestamp in seconds."""
|
|
203
204
|
if value is None or isinstance(value, bool):
|
|
204
205
|
return default
|
|
205
206
|
if isinstance(value, int):
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
207
|
+
if value >= 100000000000:
|
|
208
|
+
return value // 1000
|
|
209
|
+
if value >= 100000000:
|
|
210
|
+
return value
|
|
211
|
+
text = str(value)
|
|
212
|
+
elif isinstance(value, float):
|
|
213
|
+
if value >= 100000000000:
|
|
214
|
+
return int(value / 1000)
|
|
215
|
+
if value >= 100000000:
|
|
216
|
+
return int(value)
|
|
217
|
+
text = str(int(value)) if value.is_integer() else str(value)
|
|
218
|
+
else:
|
|
219
|
+
text = str(value).strip()
|
|
210
220
|
if not text:
|
|
211
221
|
return default
|
|
212
|
-
if re.fullmatch(r"[+-]?\d
|
|
222
|
+
if re.fullmatch(r"[+-]?\d{9,}", text):
|
|
213
223
|
try:
|
|
214
|
-
|
|
224
|
+
number = int(text)
|
|
225
|
+
return number // 1000 if number >= 100000000000 else number
|
|
215
226
|
except ValueError:
|
|
216
227
|
return default
|
|
217
228
|
digits = re.sub(r"\D", "", text)
|
|
218
229
|
if not digits:
|
|
219
230
|
return default
|
|
231
|
+
# HHMMSS / HHMMSSmmm values need the trading date before they can
|
|
232
|
+
# represent the same Unix timestamp exposed by native xtquant.
|
|
233
|
+
if len(digits) not in (5, 6, 8, 9):
|
|
234
|
+
return default
|
|
235
|
+
if len(digits) == 5:
|
|
236
|
+
digits = "0" + digits
|
|
237
|
+
hour, minute, second = int(digits[:2]), int(digits[2:4]), int(digits[4:6])
|
|
238
|
+
microsecond = int((digits[6:] + "000000")[:6]) if len(digits) > 6 else 0
|
|
239
|
+
date_text = re.sub(r"\D", "", str(date_value or ""))
|
|
240
|
+
if len(date_text) != 8:
|
|
241
|
+
return default
|
|
220
242
|
try:
|
|
221
|
-
|
|
222
|
-
|
|
243
|
+
dt = datetime.datetime.strptime(date_text, "%Y%m%d").replace(
|
|
244
|
+
hour=hour, minute=minute, second=second, microsecond=microsecond,
|
|
245
|
+
tzinfo=datetime.timezone(datetime.timedelta(hours=8)),
|
|
246
|
+
)
|
|
247
|
+
return int(dt.timestamp())
|
|
248
|
+
except (TypeError, ValueError, OverflowError):
|
|
223
249
|
return default
|
|
224
250
|
|
|
225
251
|
|
|
252
|
+
def _time_field_timestamp(data, time_names, date_names):
|
|
253
|
+
value = _first_value(data, time_names, default=None)
|
|
254
|
+
date_value = _first_value(data, date_names, default=None)
|
|
255
|
+
return _coerce_timestamp(value, date_value)
|
|
256
|
+
|
|
257
|
+
|
|
226
258
|
def normalize_order_price_type(value, market=""):
|
|
227
259
|
"""Translate documented QMT broker price enums, preserving unknown values."""
|
|
228
260
|
try:
|
|
@@ -525,8 +557,9 @@ class XtOrder(DictObject):
|
|
|
525
557
|
"sysid",
|
|
526
558
|
"m_strOrderID",
|
|
527
559
|
), default="")
|
|
528
|
-
_set_first(data, "order_time", (
|
|
529
|
-
"
|
|
560
|
+
_set_first(data, "order_time", (
|
|
561
|
+
"time",
|
|
562
|
+
"entrust_time",
|
|
530
563
|
"insert_time",
|
|
531
564
|
"m_strOrderTime",
|
|
532
565
|
"m_strEntrustTime",
|
|
@@ -600,7 +633,11 @@ class XtOrder(DictObject):
|
|
|
600
633
|
data["stock_code"] = _coerce_text(data.get("stock_code"))
|
|
601
634
|
data["order_id"] = _coerce_int(data.get("order_id"), -1)
|
|
602
635
|
data["order_sysid"] = _coerce_text(data.get("order_sysid"))
|
|
603
|
-
data["order_time"] =
|
|
636
|
+
data["order_time"] = _time_field_timestamp(
|
|
637
|
+
data,
|
|
638
|
+
("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"),
|
|
640
|
+
)
|
|
604
641
|
for name in ("order_type", "order_volume", "price_type", "traded_volume", "order_status", "direction", "offset_flag"):
|
|
605
642
|
data[name] = _coerce_int(data.get(name))
|
|
606
643
|
for name in ("price", "traded_price"):
|
|
@@ -636,7 +673,7 @@ class XtCreditOrder(XtOrder):
|
|
|
636
673
|
account_id=_coerce_text(data.get("account_id")),
|
|
637
674
|
stock_code=_coerce_text(data.get("stock_code")),
|
|
638
675
|
order_id=_coerce_int(data.get("order_id"), -1),
|
|
639
|
-
order_time=
|
|
676
|
+
order_time=data.get("order_time", 0),
|
|
640
677
|
order_type=_coerce_int(data.get("order_type")),
|
|
641
678
|
order_volume=_coerce_int(data.get("order_volume")),
|
|
642
679
|
price_type=_coerce_int(data.get("price_type")),
|
|
@@ -698,8 +735,9 @@ class XtTrade(DictObject):
|
|
|
698
735
|
"m_nTradeID",
|
|
699
736
|
"m_nDealID",
|
|
700
737
|
), default="")
|
|
701
|
-
_set_first(data, "traded_time", (
|
|
702
|
-
"
|
|
738
|
+
_set_first(data, "traded_time", (
|
|
739
|
+
"time",
|
|
740
|
+
"trade_time",
|
|
703
741
|
"deal_time",
|
|
704
742
|
"m_strTradeTime",
|
|
705
743
|
"m_strDealTime",
|
|
@@ -763,7 +801,11 @@ class XtTrade(DictObject):
|
|
|
763
801
|
data["stock_code"] = _coerce_text(data.get("stock_code"))
|
|
764
802
|
data["order_type"] = _coerce_int(data.get("order_type"))
|
|
765
803
|
data["traded_id"] = _coerce_text(data.get("traded_id"))
|
|
766
|
-
data["traded_time"] =
|
|
804
|
+
data["traded_time"] = _time_field_timestamp(
|
|
805
|
+
data,
|
|
806
|
+
("traded_time", "time", "trade_time", "deal_time", "m_strTradeTime", "m_strDealTime", "m_nTradeTime", "m_nDealTime"),
|
|
807
|
+
("trade_date", "deal_date", "m_strTradeDate", "m_strDealDate", "m_strTradingDay", "m_nTradeDate", "m_nDealDate"),
|
|
808
|
+
)
|
|
767
809
|
for name in ("traded_volume",):
|
|
768
810
|
data[name] = _coerce_int(data.get(name))
|
|
769
811
|
for name in ("traded_price", "traded_amount", "commission"):
|
|
@@ -803,7 +845,7 @@ class XtCreditDeal(DictObject):
|
|
|
803
845
|
account_id=_coerce_text(data.get("account_id")),
|
|
804
846
|
stock_code=_coerce_text(data.get("stock_code")),
|
|
805
847
|
traded_id=_coerce_text(data.get("traded_id")),
|
|
806
|
-
traded_time=
|
|
848
|
+
traded_time=data.get("traded_time", 0),
|
|
807
849
|
traded_price=_coerce_float(data.get("traded_price")),
|
|
808
850
|
traded_volume=_coerce_int(data.get("traded_volume")),
|
|
809
851
|
order_id=_coerce_int(data.get("order_id"), -1),
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const FRONTEND_VERSION = '
|
|
1
|
+
const FRONTEND_VERSION = 'web_20260923_02';
|
|
2
2
|
|
|
3
3
|
const state = {
|
|
4
4
|
accountId: '',
|
|
@@ -2500,9 +2500,42 @@ function normalizeApiBaseUrl(value) {
|
|
|
2500
2500
|
}
|
|
2501
2501
|
}
|
|
2502
2502
|
|
|
2503
|
+
function isPrivateApiHost(host) {
|
|
2504
|
+
host = String(host || '').trim().toLowerCase();
|
|
2505
|
+
if (!host || host === 'localhost' || host === '::1' || host === '[::1]') return true;
|
|
2506
|
+
if (/^127\./.test(host)) return true;
|
|
2507
|
+
const parts = host.split('.').map((item) => Number(item));
|
|
2508
|
+
if (parts.length !== 4 || parts.some((item) => !Number.isInteger(item) || item < 0 || item > 255)) return false;
|
|
2509
|
+
return parts[0] === 10
|
|
2510
|
+
|| parts[0] === 192 && parts[1] === 168
|
|
2511
|
+
|| parts[0] === 172 && parts[1] >= 16 && parts[1] <= 31
|
|
2512
|
+
|| parts[0] === 169 && parts[1] === 254;
|
|
2513
|
+
}
|
|
2514
|
+
|
|
2515
|
+
function apiBaseUrlForPage(value) {
|
|
2516
|
+
const configured = normalizeApiBaseUrl(value);
|
|
2517
|
+
const page = normalizeApiBaseUrl(window.location.origin);
|
|
2518
|
+
try {
|
|
2519
|
+
const configuredUrl = new URL(configured);
|
|
2520
|
+
const pageUrl = new URL(page);
|
|
2521
|
+
// A saved LAN address belongs to the machine that last ran Web. When the
|
|
2522
|
+
// page is opened from another private/loopback address, follow the current
|
|
2523
|
+
// page so changing the host IP does not leave the tester pointing at the
|
|
2524
|
+
// old machine. Public/explicit remote URLs remain user-configurable.
|
|
2525
|
+
if (isPrivateApiHost(configuredUrl.hostname)
|
|
2526
|
+
&& isPrivateApiHost(pageUrl.hostname)
|
|
2527
|
+
&& configuredUrl.hostname !== pageUrl.hostname) {
|
|
2528
|
+
return page;
|
|
2529
|
+
}
|
|
2530
|
+
} catch (error) {
|
|
2531
|
+
return page;
|
|
2532
|
+
}
|
|
2533
|
+
return configured;
|
|
2534
|
+
}
|
|
2535
|
+
|
|
2503
2536
|
function currentApiBaseUrl() {
|
|
2504
2537
|
const input = $('apiBaseUrlInput');
|
|
2505
|
-
if (input && input.value.trim()) return
|
|
2538
|
+
if (input && input.value.trim()) return apiBaseUrlForPage(input.value);
|
|
2506
2539
|
return normalizeApiBaseUrl(window.location.origin);
|
|
2507
2540
|
}
|
|
2508
2541
|
|
|
@@ -4616,7 +4649,10 @@ function renderServerAccessLegacy(info) {
|
|
|
4616
4649
|
|
|
4617
4650
|
const baseInput = $('apiBaseUrlInput');
|
|
4618
4651
|
if (baseInput && !baseInput.value.trim()) {
|
|
4619
|
-
baseInput.value =
|
|
4652
|
+
baseInput.value = apiBaseUrlForPage(state.serverAccess.api_base_url || window.location.origin);
|
|
4653
|
+
} else if (baseInput && baseInput.value.trim()) {
|
|
4654
|
+
const effectiveBaseUrl = apiBaseUrlForPage(baseInput.value);
|
|
4655
|
+
if (effectiveBaseUrl !== normalizeApiBaseUrl(baseInput.value)) baseInput.value = effectiveBaseUrl;
|
|
4620
4656
|
}
|
|
4621
4657
|
updateApiRequestPreview();
|
|
4622
4658
|
}
|
|
@@ -4732,7 +4768,10 @@ function renderServerAccess(info) {
|
|
|
4732
4768
|
const baseInput = $('apiBaseUrlInput');
|
|
4733
4769
|
if (baseInput && !baseInput.value.trim()) {
|
|
4734
4770
|
const currentUrl = state.serverAccess.api_base_url || state.serverAccess.local_url || window.location.origin;
|
|
4735
|
-
baseInput.value =
|
|
4771
|
+
baseInput.value = apiBaseUrlForPage(currentUrl);
|
|
4772
|
+
} else if (baseInput && baseInput.value.trim()) {
|
|
4773
|
+
const effectiveBaseUrl = apiBaseUrlForPage(baseInput.value);
|
|
4774
|
+
if (effectiveBaseUrl !== normalizeApiBaseUrl(baseInput.value)) baseInput.value = effectiveBaseUrl;
|
|
4736
4775
|
}
|
|
4737
4776
|
if (!authEnabled) {
|
|
4738
4777
|
clearWebAuthToken();
|
|
@@ -10369,7 +10408,7 @@ async function loadConfigLegacy() {
|
|
|
10369
10408
|
const savedBaseUrl = data.server_access && data.server_access.api_base_url
|
|
10370
10409
|
? data.server_access.api_base_url
|
|
10371
10410
|
: window.location.origin;
|
|
10372
|
-
apiBaseInput.value =
|
|
10411
|
+
apiBaseInput.value = apiBaseUrlForPage(savedBaseUrl);
|
|
10373
10412
|
}
|
|
10374
10413
|
renderServerAccess(data.server_access);
|
|
10375
10414
|
renderUserProfile(data.user_profile);
|
|
@@ -10430,7 +10469,7 @@ async function loadConfig() {
|
|
|
10430
10469
|
const savedBaseUrl = data.server_access && data.server_access.api_base_url
|
|
10431
10470
|
? data.server_access.api_base_url
|
|
10432
10471
|
: window.location.origin;
|
|
10433
|
-
apiBaseInput.value =
|
|
10472
|
+
apiBaseInput.value = apiBaseUrlForPage(savedBaseUrl);
|
|
10434
10473
|
}
|
|
10435
10474
|
renderServerAccess(data.server_access);
|
|
10436
10475
|
renderUserProfile(data.user_profile);
|
|
@@ -14027,4 +14066,3 @@ async function boot() {
|
|
|
14027
14066
|
}
|
|
14028
14067
|
|
|
14029
14068
|
boot().catch((error) => log('启动失败', { error: error.message }));
|
|
14030
|
-
|
|
@@ -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_20260923_02">
|
|
9
9
|
</head>
|
|
10
10
|
<body>
|
|
11
11
|
<div id="webAuthOverlay" class="auth-overlay hidden" aria-live="polite">
|
|
@@ -3202,7 +3202,6 @@ else:
|
|
|
3202
3202
|
<script src="/cftrader-api-data.js?v=20260911_02"></script>
|
|
3203
3203
|
<script src="/api-tester.js?v=20260916_apikey_01"></script>
|
|
3204
3204
|
<script src="/python-api.js?v=20260911_api_test_01"></script>
|
|
3205
|
-
<script src="/app.js?v=
|
|
3205
|
+
<script src="/app.js?v=web_20260923_02"></script>
|
|
3206
3206
|
</body>
|
|
3207
3207
|
</html>
|
|
3208
|
-
|
|
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
|
|
File without changes
|