diff --git a/README.md b/README.md index 68cc7517..bfce8338 100644 --- a/README.md +++ b/README.md @@ -384,6 +384,20 @@ export BLOSC_DIR=/opt/homebrew/opt/c-blosc 同上 + + + 期货 + + + + + + 同上 + + diff --git a/auto_monitor.py b/backend/auto_monitor.py similarity index 99% rename from auto_monitor.py rename to backend/auto_monitor.py index fd9dc114..bc66e2fd 100644 --- a/auto_monitor.py +++ b/backend/auto_monitor.py @@ -59,7 +59,7 @@ def show_notification_2(title, text): 使用mac系统定时任务crontab设置告警通知的执行时间。 crontab设置过程 1. 输入 crontab -e进入设置文本。 - 2. 填写 */3 9-12,13-15 * * 1-5 /usr/local/anaconda3/bin/python /Users/charmve/Qbot/auto_monitor.py , + 2. 填写 */3 9-12,13-15 * * 1-5 /usr/local/anaconda3/bin/python backend/auto_monitor.py , 即周一到周五,上午9点到12点,下午1点到3点,每三分钟执行阀值告警。 """ diff --git a/main.py b/main.py index fc5fbbeb..9ff22dfc 100644 --- a/main.py +++ b/main.py @@ -1,8 +1,6 @@ #!/usr/bin/python # -*- coding: UTF-8 -*- -import os - import wx from qbot.gui.mainframe import MainFrame @@ -12,8 +10,4 @@ frame = MainFrame(None, title="AI智能量化投研平台") frame.Show() - os.popen( - "python /usr/local/anaconda3/bin/python /Users/charmve/Qbot/auto_monitor.py" - ) - app.MainLoop() diff --git a/pyfunds/funds b/pyfunds/funds new file mode 160000 index 00000000..947bb3e7 --- /dev/null +++ b/pyfunds/funds @@ -0,0 +1 @@ +Subproject commit 947bb3e7c26ae06e68fdb779ad8c005c8a958e59 diff --git a/qbot/asserts/statics/icons/btc_logo/binance_logo.png b/qbot/asserts/statics/icons/btc_logo/binance_logo.png new file mode 100644 index 00000000..63077e3f Binary files /dev/null and b/qbot/asserts/statics/icons/btc_logo/binance_logo.png differ diff --git a/qbot/asserts/statics/icons/btc_logo/bitget_logo.png b/qbot/asserts/statics/icons/btc_logo/bitget_logo.png new file mode 100644 index 00000000..2853e812 Binary files /dev/null and b/qbot/asserts/statics/icons/btc_logo/bitget_logo.png differ diff --git a/qbot/asserts/statics/icons/btc_logo/bybit_logo.jpg b/qbot/asserts/statics/icons/btc_logo/bybit_logo.jpg new file mode 100644 index 00000000..3581619d Binary files /dev/null and b/qbot/asserts/statics/icons/btc_logo/bybit_logo.jpg differ diff --git a/qbot/asserts/statics/icons/btc_logo/bybit_logo.png b/qbot/asserts/statics/icons/btc_logo/bybit_logo.png new file mode 100644 index 00000000..6618cd77 Binary files /dev/null and b/qbot/asserts/statics/icons/btc_logo/bybit_logo.png differ diff --git a/qbot/asserts/statics/icons/btc_logo/coinbase.png b/qbot/asserts/statics/icons/btc_logo/coinbase.png new file mode 100644 index 00000000..71c9c738 Binary files /dev/null and b/qbot/asserts/statics/icons/btc_logo/coinbase.png differ diff --git a/qbot/asserts/statics/icons/btc_logo/coinbase_logo.png b/qbot/asserts/statics/icons/btc_logo/coinbase_logo.png new file mode 100644 index 00000000..fb099d24 Binary files /dev/null and b/qbot/asserts/statics/icons/btc_logo/coinbase_logo.png differ diff --git a/qbot/asserts/statics/icons/btc_logo/huobi_logo.png b/qbot/asserts/statics/icons/btc_logo/huobi_logo.png new file mode 100644 index 00000000..5f538df0 Binary files /dev/null and b/qbot/asserts/statics/icons/btc_logo/huobi_logo.png differ diff --git a/qbot/asserts/statics/icons/btc_logo/okx_logo.png b/qbot/asserts/statics/icons/btc_logo/okx_logo.png new file mode 100644 index 00000000..42e41889 Binary files /dev/null and b/qbot/asserts/statics/icons/btc_logo/okx_logo.png differ diff --git a/qbot/asserts/statics/icons/logo-with-font.png b/qbot/asserts/statics/icons/logo-with-font.png new file mode 100644 index 00000000..e722b65c Binary files /dev/null and b/qbot/asserts/statics/icons/logo-with-font.png differ diff --git a/qbot/asserts/statics/icons/qbot.ico b/qbot/asserts/statics/icons/qbot.ico new file mode 100644 index 00000000..007abf99 Binary files /dev/null and b/qbot/asserts/statics/icons/qbot.ico differ diff --git a/qbot/asserts/statics/icons/stocks_logo/caitong_logo.png b/qbot/asserts/statics/icons/stocks_logo/caitong_logo.png new file mode 100644 index 00000000..8f1bb956 Binary files /dev/null and b/qbot/asserts/statics/icons/stocks_logo/caitong_logo.png differ diff --git a/qbot/asserts/statics/icons/stocks_logo/debang_logo.jpg b/qbot/asserts/statics/icons/stocks_logo/debang_logo.jpg new file mode 100644 index 00000000..9649112e Binary files /dev/null and b/qbot/asserts/statics/icons/stocks_logo/debang_logo.jpg differ diff --git a/qbot/asserts/statics/icons/stocks_logo/dongfang_logo.jpeg b/qbot/asserts/statics/icons/stocks_logo/dongfang_logo.jpeg new file mode 100644 index 00000000..cff6529a Binary files /dev/null and b/qbot/asserts/statics/icons/stocks_logo/dongfang_logo.jpeg differ diff --git a/qbot/asserts/statics/icons/stocks_logo/eastmoney_logo.jpg b/qbot/asserts/statics/icons/stocks_logo/eastmoney_logo.jpg new file mode 100644 index 00000000..f8e0bec8 Binary files /dev/null and b/qbot/asserts/statics/icons/stocks_logo/eastmoney_logo.jpg differ diff --git a/qbot/asserts/statics/icons/stocks_logo/guangfa_logo.jpg b/qbot/asserts/statics/icons/stocks_logo/guangfa_logo.jpg new file mode 100644 index 00000000..2ebd6c48 Binary files /dev/null and b/qbot/asserts/statics/icons/stocks_logo/guangfa_logo.jpg differ diff --git a/qbot/asserts/statics/icons/stocks_logo/guojin_logo.jpg b/qbot/asserts/statics/icons/stocks_logo/guojin_logo.jpg new file mode 100644 index 00000000..a1af9f7f Binary files /dev/null and b/qbot/asserts/statics/icons/stocks_logo/guojin_logo.jpg differ diff --git a/qbot/asserts/statics/icons/stocks_logo/guolian_logo.png b/qbot/asserts/statics/icons/stocks_logo/guolian_logo.png new file mode 100644 index 00000000..a5a2422c Binary files /dev/null and b/qbot/asserts/statics/icons/stocks_logo/guolian_logo.png differ diff --git a/qbot/asserts/statics/icons/stocks_logo/guotou_logo.jpg b/qbot/asserts/statics/icons/stocks_logo/guotou_logo.jpg new file mode 100644 index 00000000..fc273e51 Binary files /dev/null and b/qbot/asserts/statics/icons/stocks_logo/guotou_logo.jpg differ diff --git a/qbot/asserts/statics/icons/stocks_logo/guoxin_logo.png b/qbot/asserts/statics/icons/stocks_logo/guoxin_logo.png new file mode 100644 index 00000000..6b003703 Binary files /dev/null and b/qbot/asserts/statics/icons/stocks_logo/guoxin_logo.png differ diff --git a/qbot/asserts/statics/icons/stocks_logo/haitong_logo.png b/qbot/asserts/statics/icons/stocks_logo/haitong_logo.png new file mode 100644 index 00000000..4881751e Binary files /dev/null and b/qbot/asserts/statics/icons/stocks_logo/haitong_logo.png differ diff --git a/qbot/asserts/statics/icons/stocks_logo/hongyuan_logo.png b/qbot/asserts/statics/icons/stocks_logo/hongyuan_logo.png new file mode 100644 index 00000000..14ff09e2 Binary files /dev/null and b/qbot/asserts/statics/icons/stocks_logo/hongyuan_logo.png differ diff --git a/qbot/asserts/statics/icons/stocks_logo/huatai_logo.png b/qbot/asserts/statics/icons/stocks_logo/huatai_logo.png new file mode 100644 index 00000000..10ff6053 Binary files /dev/null and b/qbot/asserts/statics/icons/stocks_logo/huatai_logo.png differ diff --git a/qbot/asserts/statics/icons/stocks_logo/huaxin_logo.jpeg b/qbot/asserts/statics/icons/stocks_logo/huaxin_logo.jpeg new file mode 100644 index 00000000..576a62e6 Binary files /dev/null and b/qbot/asserts/statics/icons/stocks_logo/huaxin_logo.jpeg differ diff --git a/qbot/asserts/statics/icons/stocks_logo/huaying_logo.jpeg b/qbot/asserts/statics/icons/stocks_logo/huaying_logo.jpeg new file mode 100644 index 00000000..ae243d05 Binary files /dev/null and b/qbot/asserts/statics/icons/stocks_logo/huaying_logo.jpeg differ diff --git a/qbot/asserts/statics/icons/stocks_logo/tonghuashun_logo.png b/qbot/asserts/statics/icons/stocks_logo/tonghuashun_logo.png new file mode 100644 index 00000000..68df3f44 Binary files /dev/null and b/qbot/asserts/statics/icons/stocks_logo/tonghuashun_logo.png differ diff --git a/qbot/asserts/statics/icons/stocks_logo/xindatong_logo.png b/qbot/asserts/statics/icons/stocks_logo/xindatong_logo.png new file mode 100644 index 00000000..0766a5b8 Binary files /dev/null and b/qbot/asserts/statics/icons/stocks_logo/xindatong_logo.png differ diff --git a/qbot/asserts/statics/icons/stocks_logo/xingye_logo.jpg b/qbot/asserts/statics/icons/stocks_logo/xingye_logo.jpg new file mode 100644 index 00000000..324a52ac Binary files /dev/null and b/qbot/asserts/statics/icons/stocks_logo/xingye_logo.jpg differ diff --git a/qbot/asserts/statics/icons/stocks_logo/yinhe_logo.png b/qbot/asserts/statics/icons/stocks_logo/yinhe_logo.png new file mode 100644 index 00000000..e9af9d54 Binary files /dev/null and b/qbot/asserts/statics/icons/stocks_logo/yinhe_logo.png differ diff --git a/qbot/asserts/statics/icons/vnpy.ico b/qbot/asserts/statics/icons/vnpy.ico new file mode 100644 index 00000000..f5146d56 Binary files /dev/null and b/qbot/asserts/statics/icons/vnpy.ico differ diff --git a/qbot/common/configs/back_para.json b/qbot/common/configs/back_para.json new file mode 100644 index 00000000..467087e8 --- /dev/null +++ b/qbot/common/configs/back_para.json @@ -0,0 +1,62 @@ +{ + "layout_dict": { + "figsize": null, + "nrows": 3, + "ncols": 1, + "left": 0.08, + "bottom": 0.15, + "right": 0.92, + "top": 0.96, + "wspace": null, + "hspace": 0, + "height_ratios": [ + 1.5, + 1, + 1 + ], + "subplots": [ + "kgraph", + "cashgraph", + "cmppfgraph" + ] + }, + "subplots_dict": { + "graph_fst": { + "graph_name": "kgraph", + "graph_type": { + "trade": null, + "close_retrace": null + }, + "title": "sz.000875-回测分析", + "ylabel": "价格", + "xticks": 15, + "legend": "best" + }, + "graph_sec": { + "graph_name": "cashgraph", + "graph_type": { + "cash_profit": { + "cash_hold": "100000", + "slippage": "0.01", + "c_rate": "0.0005", + "t_rate": "0.001", + "stake_size": "all" + } + }, + "ylabel": "资金收益和回撤", + "xticks": 15, + "legend": "best" + }, + "graph_fth": { + "graph_name": "cmppfgraph", + "graph_type": { + "cmp_profit": null + }, + "ylabel": "策略收益VS基准收益", + "xlabel": "日期", + "xticks": 15, + "legend": "best", + "xticklabels": "%Y-%m-%d %H:%M" + } + } +} \ No newline at end of file diff --git a/qbot/common/configs/btc_trade_plat_para.json b/qbot/common/configs/btc_trade_plat_para.json new file mode 100644 index 00000000..6a340a0c --- /dev/null +++ b/qbot/common/configs/btc_trade_plat_para.json @@ -0,0 +1,169 @@ +{ + "__version__": "V1.3.8", + "__author__": "Charmve", + "欧易OKX": { + "license": "xxxxxxx", + "icon": "qbot/asserts/statics/icons/btc_logo/okx_logo.png", + "ads": [ + "''", + "''" + ], + "labels": [ + "", + "" + ], + "api_key": { + "real_trade": { + "uid": "", + "apikey": "", + "secretkey": "", + "passphrase": "" + }, + "sim_trade": { + "uid": "", + "apikey": "", + "secretkey": "", + "passphrase": "" + } + }, + "operate_sys": [ + "macos", + "windows" + ], + "vip_channel": "https://www.cnouyi.social/join/57246734" + }, + "币安Binance": { + "license": "xxxxxxx", + "icon": "qbot/asserts/statics/icons/btc_logo/binance_logo.png", + "ads": [ + "''", + "''" + ], + "labels": [ + "", + "" + ], + "api_key": { + "real_trade": { + "uid": "", + "apikey": "", + "secretkey": "" + }, + "sim_trade": { + "uid": "", + "apikey": "", + "secretkey": "" + } + }, + "operate_sys": [ + "macos", + "windows" + ] + }, + "火币Huobi": { + "license": "xxxxxxx", + "icon": "qbot/asserts/statics/icons/btc_logo/huobi_logo.png", + "ads": [ + "''", + "''" + ], + "labels": [ + "", + "" + ], + "api_key": { + "real_trade": { + "uid": "443400068", + "apikey": "", + "secretkey": "" + }, + "sim_trade": { + "uid": "", + "apikey": "", + "secretkey": "" + } + }, + "operate_sys": [ + "macos", + "windows" + ] + }, + "CoinBase": { + "license": "xxxxxxx", + "icon": "qbot/asserts/statics/icons/btc_logo/coinbase_logo.png", + "ads": [ + "'开户享惊喜佣金'", + "''" + ], + "api_key": { + "real_trade": { + "uid": "", + "apikey": "", + "secretkey": "" + }, + "sim_trade": { + "uid": "", + "apikey": "", + "secretkey": "" + } + }, + "labels": [ + "国企券商", + "安全可靠" + ] + }, + "BitGet": { + "license": "xxxxxxx", + "icon": "qbot/asserts/statics/icons/btc_logo/bitget_logo.png", + "ads": [ + "'专门极低佣金'", + "'新客专属理财'" + ], + "labels": [ + "国企券商", + "安全可靠" + ], + "api_key": { + "real_trade": { + "uid": "", + "apikey": "", + "secretkey": "" + }, + "sim_trade": { + "uid": "", + "apikey": "", + "secretkey": "" + } + }, + "operate_sys": [ + "windows" + ] + }, + "Bybit": { + "license": "xxxxxxx", + "icon": "qbot/asserts/statics/icons/btc_logo/bybit_logo.jpg", + "ads": [ + "'开户享惊喜佣金'", + "'千万Cryper选择'" + ], + "api_key": { + "real_trade": { + "uid": "", + "apikey": "", + "secretkey": "" + }, + "sim_trade": { + "uid": "", + "apikey": "", + "secretkey": "" + } + }, + "labels": [ + "国企券商", + "安全可靠" + ], + "operate_sys": [ + "linux_x86" + ] + } +} \ No newline at end of file diff --git a/qbot/common/configs/firm_para.json b/qbot/common/configs/firm_para.json new file mode 100644 index 00000000..e9fccfba --- /dev/null +++ b/qbot/common/configs/firm_para.json @@ -0,0 +1,70 @@ +{ + "layout_dict": { + "figsize": null, + "nrows": 4, + "ncols": 1, + "left": 0.05, + "bottom": 0.15, + "right": 0.99, + "top": 0.96, + "wspace": null, + "hspace": 0, + "height_ratios": [ + 3.5, + 1, + 1, + 1 + ], + "subplots": [ + "kgraph", + "volgraph", + "kdjgraph", + "macdgraph" + ] + }, + "subplots_dict": { + "graph_fst": { + "graph_name": "kgraph", + "graph_type": { + "ochl": null, + "sma": [ + 20, + 30, + 60 + ] + }, + "title": "000651 格力电器-日K线", + "ylabel": "价格", + "xticks": 15, + "legend": "best" + }, + "graph_sec": { + "graph_name": "volgraph", + "graph_type": { + "vol": null + }, + "ylabel": "成交量", + "xticks": 15 + }, + "graph_thd": { + "graph_name": "kdjgraph", + "graph_type": { + "kdj": null + }, + "ylabel": "KDJ", + "xticks": 15, + "legend": "best" + }, + "graph_fth": { + "graph_name": "macdgraph", + "graph_type": { + "macd": null + }, + "ylabel": "MACD", + "xlabel": "日期", + "xticks": 15, + "legend": "best", + "xticklabels": "%Y-%m-%d %H:%M" + } + } +} \ No newline at end of file diff --git a/qbot/common/configs/sys_para.json b/qbot/common/configs/sys_para.json new file mode 100644 index 00000000..4c61a9fd --- /dev/null +++ b/qbot/common/configs/sys_para.json @@ -0,0 +1,28 @@ +{ + "__version__": "V1.3.8", + "__author__": "Charmve", + "operate_sys": "macos", + "multi-panels": { + "mpl_fig_x": 5, + "mpl_fig_y": 4, + "web_size_x": 600, + "web_size_y": 300, + "mpl_fig_left": 0.1, + "mpl_fig_right": 0.95, + "mpl_fig_top": 0.9, + "mpl_fig_bottom": 0.15 + }, + "mailbox": { + "license": "new_license_value", + "to_address": [ + "new_email@gmail.com" + ], + "from_address": "new_from@qq.com", + "server_address": "smtp.qq.com" + }, + "license_reminder_box": { + "latest_pop_date": "20240831", + "release_date": "20230829", + "license_created": false + } +} \ No newline at end of file diff --git a/qbot/common/configs/trade_plat_para.json b/qbot/common/configs/trade_plat_para.json new file mode 100644 index 00000000..4271464b --- /dev/null +++ b/qbot/common/configs/trade_plat_para.json @@ -0,0 +1,201 @@ +{ + "__version__": "V1.3.8", + "__author__": "Charmve", + "国信证券": { + "license": "xxxxxxx", + "user": "国信证券用户名", + "password": "国信证券明文密码", + "icon": "qbot/asserts/statics/icons/stocks_logo/guoxin_logo.png", + "ads": [ + "'开户享惊喜佣金'", + "'千万股民选择'" + ], + "labels": [ + "国企券商", + "安全可靠" + ], + "operate_sys": [ + "macos", + "windows" + ] + }, + "兴业证券": { + "license": "xxxxxxx", + "user": "兴业证券用户名", + "password": "兴业证券明文密码", + "icon": "qbot/asserts/statics/icons/stocks_logo/xingye_logo.jpg", + "ads": [ + "'专属优惠佣金'", + "'新客专属理财'" + ], + "labels": [ + "金牌投顾", + "行业前列" + ] + }, + "国投证券(原安信)": { + "license": "xxxxxxx", + "user": "国投证券用户名", + "password": "国投证券明文密码", + "icon": "qbot/asserts/statics/icons/stocks_logo/guotou_logo.jpg", + "ads": [ + "'专属优惠佣金'", + "'6.88%专属理财'" + ], + "labels": [ + "央企背景", + "安全可靠" + ], + "operate_sys": [ + "macos", + "windows" + ] + }, + "财通证券": { + "license": "xxxxxxx", + "user": "财通证券用户名", + "password": "财通证券明文密码", + "icon": "qbot/asserts/statics/icons/stocks_logo/xingye_logo.jpg", + "ads": [ + "'开户享惊喜佣金'", + "'上市券商 省属企业'" + ], + "labels": [ + "国企券商", + "安全可靠" + ] + }, + "国金证券": { + "license": "xxxxxxx", + "user": "国金用户名", + "password": "国金明文密码", + "icon": "qbot/asserts/statics/icons/stocks_logo/guojin_logo.jpg", + "ads": [ + "'专门极低佣金'", + "'新客专属理财'" + ], + "labels": [ + "国企券商", + "安全可靠" + ], + "operate_sys": [ + "windows" + ] + }, + "华泰证券": { + "license": "xxxxxxx", + "user": "华泰证券用户名", + "password": "华泰证券明文密码", + "icon": "qbot/asserts/statics/icons/stocks_logo/huatai_logo.png", + "ads": [ + "'开户享惊喜佣金'", + "'千万股民选择'" + ], + "labels": [ + "国企券商", + "安全可靠" + ] + }, + "银河证券": { + "license": "xxxxxxx", + "user": "银河用户名", + "password": "银河明文密码", + "icon": "qbot/asserts/statics/icons/stocks_logo/yinhe_logo.png", + "ads": [ + "'开户享惊喜佣金'", + "'千万股民选择'" + ], + "labels": [ + "国企券商", + "安全可靠" + ] + }, + "通达信": { + "license": "xxxxxxx", + "user": "通达信用户名", + "password": "通达信明文密码", + "icon": "qbot/asserts/statics/icons/stocks_logo/xindatong_logo.png", + "ads": [ + "'开户享惊喜佣金'", + "'千万股民选择'" + ], + "labels": [ + "国企券商", + "安全可靠" + ] + }, + "国联证券": { + "license": "xxxxxxx", + "user": "国联证券用户名", + "password": "国联证券明文密码", + "icon": "qbot/asserts/statics/icons/stocks_logo/guolian_logo.png", + "ads": [ + "'财富管理领先的'", + "'区域精品券商'" + ], + "labels": [ + "财富管理", + "稳步提升" + ] + }, + "海通证券": { + "license": "xxxxxxx", + "user": "海通用户名", + "password": "海通明文密码", + "icon": "qbot/asserts/statics/icons/stocks_logo/haitong_logo.png", + "ads": [ + "'财富管理领先的'", + "'区域精品券商'" + ], + "labels": [ + "财富管理", + "稳步提升" + ] + }, + "申万宏源证券": { + "license": "xxxxxxx", + "icon": "qbot/asserts/statics/icons/stocks_logo/hongyuan_logo.png", + "ads": [ + "'开户VIP超低佣金'", + "" + ], + "labels": [ + "贴心精准", + "稳定便捷" + ] + }, + "东方财富": { + "license": "xxxxxxx", + "user": "东方财富用户名", + "password": "东方财富明文密码", + "icon": "qbot/asserts/statics/icons/stocks_logo/eastmoney_logo.jpg", + "ads": [ + "'悦享财富,'", + "'尽在东方财富'" + ], + "labels": [ + "互联网优势‌", + "发行可转债" + ], + "operate_sys": [ + "windows" + ] + }, + "同花顺": { + "license": "xxxxxxx", + "user": "同花顺用户名", + "password": "同花顺明文密码", + "icon": "qbot/asserts/statics/icons/stocks_logo/tonghuashun_logo.png", + "ads": [ + "'四大券商'", + "'长期稳定'" + ], + "labels": [ + "四梅策略", + "东方证券" + ], + "operate_sys": [ + "windows" + ] + } +} \ No newline at end of file diff --git "a/qbot/common/configs/\345\217\214\345\272\225\345\275\242\346\200\201\350\257\206\345\210\253\346\250\241\345\236\213\345\233\276.png" "b/qbot/common/configs/\345\217\214\345\272\225\345\275\242\346\200\201\350\257\206\345\210\253\346\250\241\345\236\213\345\233\276.png" new file mode 100644 index 00000000..b05cb696 Binary files /dev/null and "b/qbot/common/configs/\345\217\214\345\272\225\345\275\242\346\200\201\350\257\206\345\210\253\346\250\241\345\236\213\345\233\276.png" differ diff --git a/qbot/common/file_utils.py b/qbot/common/file_utils.py index 34122f75..72cda84f 100644 --- a/qbot/common/file_utils.py +++ b/qbot/common/file_utils.py @@ -1,6 +1,7 @@ import json -import re import os +import re + def extract_content(text): pattern = r"\((.*?)\)" # 匹配()之间的内容 @@ -15,10 +16,12 @@ def save_strings_as_json(str_data, file_path): with open(file_path, "w") as file: file.write(json_str) + def file2dict(path): with open(path, encoding="utf-8") as f: return json.load(f) + def list_files_in_directory(path, file_suffix=[".csv"]): files_list = [] for root, dirs, files in os.walk(path): @@ -27,6 +30,7 @@ def list_files_in_directory(path, file_suffix=[".csv"]): files_list.append(file.strip(file_suf)) return files_list + # data_str=""" # { # 'universe': ['000300.SH', '000905.SH', '399006.SZ', 'SPX'], diff --git a/qbot/common/logging/utils.py b/qbot/common/logging/utils.py index d152dde0..c67f9e2b 100644 --- a/qbot/common/logging/utils.py +++ b/qbot/common/logging/utils.py @@ -35,4 +35,4 @@ def cri(self, message): self.logger.critical(message) -log = logger("log.txt") +log = logger("qbot-log.txt") diff --git a/qbot/common/utils.py b/qbot/common/utils.py index d9a2c9bf..377463fe 100644 --- a/qbot/common/utils.py +++ b/qbot/common/utils.py @@ -5,13 +5,15 @@ class logger: def __init__(self, path, clevel=logging.INFO, Flevel=logging.INFO): self.logger = logging.getLogger(path) self.logger.setLevel(logging.DEBUG) - fmt = logging.Formatter('[%(asctime)s] [%(levelname)s] %(message)s', '%Y-%m-%d %H:%M:%S') + fmt = logging.Formatter( + "[%(asctime)s] [%(levelname)s] %(message)s", "%Y-%m-%d %H:%M:%S" + ) # 设置CMD日志 sh = logging.StreamHandler() sh.setFormatter(fmt) sh.setLevel(clevel) # 设置文件日志 - fh = logging.FileHandler(path, encoding='utf-8') + fh = logging.FileHandler(path, encoding="utf-8") fh.setFormatter(fmt) fh.setLevel(Flevel) self.logger.addHandler(sh) @@ -33,11 +35,13 @@ def cri(self, message): self.logger.critical(message) -log = logger("log.txt") +log = logger("qbot-log.txt") import socket -def check_port_in_use(port, host='127.0.0.1'): + + +def check_port_in_use(port, host="127.0.0.1"): s = None try: s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) @@ -49,4 +53,3 @@ def check_port_in_use(port, host='127.0.0.1'): finally: if s: s.close() - diff --git a/scripts/check_dump_bin.py b/qbot/data/check_dump_bin.py similarity index 100% rename from scripts/check_dump_bin.py rename to qbot/data/check_dump_bin.py diff --git a/scripts/dump_bin.py b/qbot/data/dump_bin.py similarity index 100% rename from scripts/dump_bin.py rename to qbot/data/dump_bin.py diff --git a/scripts/dump_pit.py b/qbot/data/dump_pit.py similarity index 100% rename from scripts/dump_pit.py rename to qbot/data/dump_pit.py diff --git a/qbot/engine/backtest/backtest_base.py b/qbot/engine/backtest/backtest_base.py new file mode 100644 index 00000000..04d6d0b0 --- /dev/null +++ b/qbot/engine/backtest/backtest_base.py @@ -0,0 +1,54 @@ +# coding:utf-8 +import matplotlib.pyplot as plt +from pandas import DataFrame + + +# 策略 尾盘根据K线数据买卖 +class BacktestStrategyTemplate: + name = "BacktestStrategyTemplate" + + def __init__(self, stock_code, bars: DataFrame, days=250): + self.stock_code = stock_code + self.days = days + # 截止到当天的全部K线 + self.bars = bars + self.signals = [] + + def output_earning_rate(self): + df = self.bars[-self.days :] + df["signals"] = self.signals + df["strategy"] = (1 + df.close.pct_change(1).fillna(0) * self.signals).cumprod() + df["base"] = df["close"] / df["close"][0] + print(df["strategy"].values[-1:]) + return df + + def show_plt(self): + df = self.output_earning_rate() + fig, axes = plt.subplots(2, 1, sharex=True, figsize=(18, 12)) + df[["strategy", "base", "signals"]].plot( + ax=axes[0], grid=True, title="收益", figsize=(20, 10) + ) + self.show_score(df, axes[1]) + plt.show() + + def show_score(self, df, ax): + df["score"] = self.get_scores(df) + df.score.plot(ax=ax, grid=True, title="score", figsize=(20, 10)) + + def process(self): + position = 0 + for i in range(self.days): + # 当前的持仓,是上一天的信号 + singal = self.get_singal(self.bars[: -self.days + i - 1]) + if singal == -1: + # 保持不变 + self.signals.append(position) + else: + position = singal + self.signals.append(singal) + + def get_singal(self, bars: DataFrame): + return 0 + + def get_scores(self, df: DataFrame): + return 0 diff --git a/qbot/engine/backtest/backtest_main.py b/qbot/engine/backtest/backtest_main.py new file mode 100644 index 00000000..ed5a6162 --- /dev/null +++ b/qbot/engine/backtest/backtest_main.py @@ -0,0 +1,25 @@ +from easyquant.quotation import use_quotation +from RSI import RSIStrategy + +print("backtest 回测 测试 ") + +quotation = use_quotation("jqdata") + + +trade_days = quotation.get_all_trade_days() + +end_date = "2021-12-24" + +stock_code = "002230" +size = 500 + +bars = quotation.get_bars(stock_code, size, end_dt=end_date) + +# strategy = CCIStrategy(stock_code, bars, days=size) +# strategy = BOLLStrategy(stock_code, bars, days=size) + +# strategy = MACDStrategy(stock_code, bars, days=size) + +strategy = RSIStrategy(stock_code, bars, days=size) +strategy.process() +strategy.show_plt() diff --git a/qbot/engine/backtest/bitcoin_bt_example.py b/qbot/engine/backtest/bitcoin_bt_example.py new file mode 100644 index 00000000..21db0660 --- /dev/null +++ b/qbot/engine/backtest/bitcoin_bt_example.py @@ -0,0 +1,199 @@ +# ====================================================================================================================== +# 导入必要的库 +# ====================================================================================================================== + +import io +from datetime import datetime + +import backtrader as bt +import pandas as pd +import requests +from dateutil.relativedelta import relativedelta + +# ====================================================================================================================== +# 配置数据 +# ====================================================================================================================== + +# 设置Amberdata的API_KEY,以便从Amberdata下载行情数据 +Amberdata_API_KEY = "YOUR_API_KEY" + +# 初始资金 +icap = 100000 + +# 每次交易投入的仓位百分比 +PercSize = 100 + +# 追踪停损百分比 +PercTrail = 0.40 + +# 回测时段 +start_date = "2015-01-20" +end_date = "2020-05-09" + + +# ====================================================================================================================== +# 帮助类和函数 - 数据源 +# ====================================================================================================================== +# 定义一个新的pandas data feed,加入线 stf +class CustomPandas(bt.feeds.PandasData): + # Add a 'stf' line to the inherited ones from the base class + lines = ("stf",) + # sft默认在dataframe的第8列 + params = (("stf", 8),) + + +# 调用 Amberdata 的 在线API +def amberdata(url, queryString, apiKey): + try: + headers = {"x-api-key": apiKey} + response = requests.request("GET", url, headers=headers, params=queryString) + return response.text + except Exception as e: + raise e + + +# 从 Amberdata获取日线行情数据 +def amberdata_ohlcv(exchange, symbol, startDate, endDate): + format = "%Y-%m-%dT%H:%M:%S" + startTimestamp = datetime.strptime(startDate, "%Y-%m-%d") + endTimestamp = datetime.strptime(endDate, "%Y-%m-%d") + + current = startTimestamp + next = current + fields = "timestamp,open,high,low,close,volume" + payload = fields + while current < endTimestamp: + next += relativedelta(years=1) + if next > endTimestamp: + next = endTimestamp + print("Retrieving OHLCV between", current, " and ", next) + result = amberdata( + "https://web3api.io/api/v2/market/ohlcv/" + symbol + "/historical", + { + "exchange": exchange, + "timeInterval": "days", + "timeFormat": "iso", + "format": "raw_csv", + "fields": fields, + "startDate": current.strftime(format), + "endDate": next.strftime(format), + }, + Amberdata_API_KEY, + ) + payload += "\n" + result + current = next + + return payload + + +# 获取stf指标数据 +def amberdata_stf(symbol, startDate, endDate): + print("Retrieving STF between", startDate, " and ", endDate) + return amberdata( + "https://web3api.io/api/v2/market/metrics/" + + symbol + + "/historical/stock-to-flow", + { + "format": "csv", + "timeFrame": "day", + "startDate": startDate, + "endDate": endDate, + }, + Amberdata_API_KEY, + ) + + +def to_pandas(csv): + return pd.read_csv(io.StringIO(csv), index_col="timestamp", parse_dates=True) + + +# ====================================================================================================================== +# 策略 +# ====================================================================================================================== + + +class Strategy(bt.Strategy): + params = ( + ("macd1", 12), + ("macd2", 26), + ("macdsig", 9), + ("trailpercent", PercTrail), + ("smaperiod", 30), + ("dirperiod", 10), + ) + + def notify_order(self, order): + if order.status == order.Completed: + pass + + if not order.alive(): + self.order = None # No pending orders + + def __init__(self): + self.macd = bt.indicators.MACD( + self.data, + period_me1=self.p.macd1, + period_me2=self.p.macd2, + period_signal=self.p.macdsig, + ) + + # Cross of macd.macd and macd.signal + self.mcross = bt.indicators.CrossOver(self.macd.macd, self.macd.signal) + + # 移动均线。 + self.sma = bt.indicators.SMA(self.data, period=self.p.smaperiod) + # 当日移动均线与dirperiod期前移动均线的差值,若小于0,说明市场处于跌势 + self.smadir = self.sma - self.sma(-self.p.dirperiod) + + def start(self): + self.order = None + + def next(self): + if self.order: + return + + if not self.position: # 无仓位 + # 如果macd金叉,并且当日移动均值比dirperiod前的低,并且收盘价低于stf,则买入 + # 基本思想是当市场处于跌势、且价格低估时,若出现macd金叉,则买入 + if ( + self.mcross[0] > 0.0 + and self.smadir < 0.0 + and self.data.close < self.data.stf + ): + self.order = self.buy() + + # 若有仓位 + elif self.order is None: + # 发出停损跟踪单,保护自己 + self.order = self.sell( + exectype=bt.Order.StopTrail, trailpercent=self.p.trailpercent + ) + + +# ====================================================================================================================== +# 主程序开始 +# ====================================================================================================================== + + +cerebro = bt.Cerebro(stdstats=False) +cerebro.broker.setcash(icap) + +# addsizer设置下单量管理者 +cerebro.addsizer(bt.sizers.PercentSizer, percents=PercSize) + +# Add our strategy +cerebro.addstrategy(Strategy) + +# 通过amberdata api获取gdax交易所的比特币行情数据,放到dataframe +btc = to_pandas(amberdata_ohlcv("gdax", "btc_usd", start_date, end_date)) +btc.to_csv("btc_new.csv") +# 获取stf指标 +btc_stf = to_pandas(amberdata_stf("btc", start_date, end_date)) +# 将stf指标合并到行情数据帧 +btc["stf"] = btc_stf["price"] + +# 注入数据 +cerebro.adddata(CustomPandas(dataname=btc, openinterest=None, stf="stf")) + +# 运行回测 +backtest = cerebro.run() diff --git a/qbot/engine/backtest/live_trade_binance.py b/qbot/engine/backtest/live_trade_binance.py new file mode 100644 index 00000000..44c48f4e --- /dev/null +++ b/qbot/engine/backtest/live_trade_binance.py @@ -0,0 +1,56 @@ +import datetime as dt + +import backtrader as bt +from backtrader_binance import BinanceStore + +from qbot.engine.tokens import binance_api + +# https://github.com/lindomar-oliveira/backtrader-binance + + +class RSIStrategy(bt.Strategy): + def __init__(self): + self.rsi = bt.indicators.RSI(period=14) # RSI indicator + + def next(self): + print( + "Open: {}, High: {}, Low: {}, Close: {}".format( + self.data.open[0], + self.data.high[0], + self.data.low[0], + self.data.close[0], + ) + ) + print("RSI: {}".format(self.rsi[0])) + + if not self.position: + if self.rsi < 30: # Enter long + self.buy() + else: + if self.rsi > 70: + self.sell() # Close long position + + def notify_order(self, order): + print(order) + + +if __name__ == "__main__": + cerebro = bt.Cerebro(quicknotify=True) + + store = BinanceStore( + api_key=binance_api["apikey"], + api_secret=binance_api["secretkey"], + coin_refer="BTC", + coin_target="USDT", + testnet=True, + ) + + broker = store.getbroker() + cerebro.setbroker(broker) + + from_date = dt.datetime.utcnow() - dt.timedelta(minutes=5 * 16) + data = store.getdata(timeframe_in_minutes=5, start_date=from_date) + + cerebro.addstrategy(RSIStrategy) + cerebro.adddata(data) + cerebro.run() diff --git a/qbot/engine/backtest/macd_bt.py b/qbot/engine/backtest/macd_bt.py new file mode 100644 index 00000000..8f2d0777 --- /dev/null +++ b/qbot/engine/backtest/macd_bt.py @@ -0,0 +1,73 @@ +import backtrader as bt +import pandas as pd +import tushare as ts + + +class MyStrategy(bt.Strategy): + params = ( + ("fast", 5), # 快速移动平均线的周期 + ("slow", 20), # 慢速移动平均线的周期 + ) + + def __init__(self): + self.fast_moving_average = bt.indicators.SMA( + self.data.close, + period=self.params.fast, + plotname="5 day moving average", # 计算快速移动平均线 + ) + self.slow_moving_average = bt.indicators.SMA( + self.data.close, + period=self.params.slow, + plotname="20 day moving average", # 计算慢速移动平均线 + ) + self.crossover = bt.indicators.CrossOver( + self.fast_moving_average, self.slow_moving_average + ) # 计算交叉点 + + def next(self): + if not self.position: + if self.crossover > 0: # 如果快速移动平均线上穿慢速移动平均线 + amount_to_invest = 0.95 * self.broker.cash # 计算可投资金额 + self.size = int( + amount_to_invest / self.data.close + ) # 计算可购买股票数量 + print( + "Buy {} shares of {} at {}".format( + self.size, "600519", self.data.close[0] + ) + ) # 输出购买信息 + self.buy(size=self.size) # 买入股票 + else: + if self.crossover < 0: # 如果快速移动平均线下穿慢速移动平均线 + print( + "Sell {} shares of {} at {}".format( + self.size, "600519", self.data.close[0] + ) + ) # 输出卖出信息 + self.close() # 卖出股票 + + +if __name__ == "__main__": + cerebro = bt.Cerebro() # 创建Cerebro引擎 + cerebro.addstrategy(MyStrategy) # 添加策略 + symbol = "600519" # 股票代码 + df = ts.get_k_data(symbol, start="2018-01-01", end="2023-03-20") # 获取股票数据 + df["date"] = pd.to_datetime(df["date"]) # 将日期转换为datetime格式 + df = df.set_index("date", drop=True) # 将日期设置为索引 + data = bt.feeds.PandasData( + dataname=df, + datetime=None, + open=0, + high=1, + low=2, + close=3, + volume=4, + openinterest=-1, + ) # 创建数据源 + cerebro.adddata(data) # 添加数据源 + cerebro.broker.setcash(1000000.0) # 设置初始资金 + cerebro.broker.setcommission(commission=0.001) # 设置佣金 + print("Starting Portfolio Value: %.2f" % cerebro.broker.getvalue()) # 输出初始资金 + cerebro.run() # 运行策略 + print("Final Portfolio Value: %.2f" % cerebro.broker.getvalue()) # 输出最终资金 + cerebro.plot() # 绘制图表 diff --git a/qbot/engine/backtest/rsrs.py b/qbot/engine/backtest/rsrs.py new file mode 100644 index 00000000..188ad9fe --- /dev/null +++ b/qbot/engine/backtest/rsrs.py @@ -0,0 +1,232 @@ +import matplotlib.pyplot as plt +import numpy as np +from easyquant.quotation import use_quotation + +# error: +# plt.rcParams["font.sans-serif"] = ["SimHei"] # 用来正常显示中文标签 + +# 指定字体 +plt.rcParams["font.sans-serif"] = ["SimHei"] +plt.rcParams["axes.unicode_minus"] = False # 用来正常显示负号 + +import datetime + +import jqdatasdk as jq +import pandas as pd +from easytrader.utils.misc import file2dict + +config = file2dict("jqdata.json") +print(config["user"], config["password"]) +jq.auth(config["user"], config["password"]) +quotation = use_quotation("jqdata") + + +class ETFQuant: + # 初始化函数 + def __init__(self, stkList): + self.edate = datetime.date.today() + self.date = pd.to_datetime(self.edate) + if self.date.dayofweek + 1 in [6, 7]: # 剔除周末的日期,避免混淆 + self.date = self.date - datetime.timedelta(self.date.dayofweek - 4) + # print('today:',self.edate) + self.stock_pool = stkList + self.mom = 20 + self.ref = "000300.XSHG" + self.N, self.M = 17, 400 + self.RSRS_threshold = 0.7 + + # 20日收益率动量拟合取斜率最大的 + def get_rank(self): + self.slope_series = self.initial_slope_series()[:-1] + rank = [] + for stock in self.stock_pool: + data = jq.get_price(stock, end_date=self.date, count=self.mom) + score = np.polyfit(np.arange(len(data)), data.close / data.close[0], 1)[0] + rank.append([stock, 100 * score]) + rank.sort(key=lambda x: x[-1], reverse=True) + return rank[0] + + def get_ols(self, x, y): + try: + slope, intercept = np.polyfit(x, y, 1) + r2 = 1 - ( + sum((y - (slope * x + intercept)) ** 2) + / ((len(y) - 1) * np.var(y, ddof=1)) + ) + return (intercept, slope, r2) + except Exception as e: + print(e) + + def initial_slope_series(self): + data = jq.get_price( + self.ref, end_date=self.date, count=self.M + self.N, fields=["high", "low"] + ) + return [ + self.get_ols(data.low[i : i + self.N], data.high[i : i + self.N])[1] + for i in range(self.M) + ] + + # 因子标准化 + def get_zscore(self, slope_series): + mean = np.mean(slope_series) + std = np.std(slope_series) + return (slope_series[-1] - mean) / std + + def get_rsrs_score( + self, + stock_code, + days=60, + slop_days=18, + M=400, + MA=10, + buy_sail=0.7, + sail_score=-1.4, + ): + self.M = M + # m + n + days + data = quotation.get_bars( + stock_code, + self.M + slop_days + days, + fields=["close", "high", "low"], + end_dt=self.date, + ) + data["ma"] = data.close.rolling(MA).mean() + # M+days + ols_data = [ + self.get_ols(data.low[i : i + slop_days], data.high[i : i + slop_days]) + for i in range(self.M + days) + ] + slope_series = [ols_data[i][1] for i in range(self.M + days)] + r2 = [ols_data[i][2] for i in range(self.M + days)] + result = [] + signal = [] + position = 1 # 是否持仓,持仓:1,不持仓:0 + last_rsrs_score = 0 + last_ma = data.ma[self.M - 1] + # > -1.2 持仓 + # 最近的N天 + for i in range(days): + current_ma = data.ma[self.M + i] + close = data.close[self.M + i] + rsrs_score = self.get_zscore(slope_series[i : self.M + i]) * r2[self.M + i] + # M 天序列 + result.append(rsrs_score) + signal.append(position) + if rsrs_score < sail_score: + position = 0 + # 10日线拐头 + elif rsrs_score > buy_sail and current_ma > last_ma: + position = 1 + last_rsrs_score = rsrs_score + last_ma = current_ma + + return result, slope_series[-days:], signal, data.close[-days:].values + + def get_timing_signal(self, stock_code): + high_low_data = jq.get_price( + stock_code, end_date=self.date, count=self.N, fields=["high", "low"] + ) + intercept, slope, r2 = self.get_ols(high_low_data.low, high_low_data.high) + self.slope_series.append(slope) + rsrs_score = self.get_zscore(self.slope_series[-self.M :]) * r2 + global RSRS + RSRS.append(rsrs_score) + # print("rsrs factor:\t\t{:.3f}".format(rsrs_score)) + if rsrs_score > self.RSRS_threshold: + return "BUY" + elif rsrs_score < -self.RSRS_threshold: + return "SELL" + else: + return "KEEP" + + def run(self, date=datetime.date.today()): + self.date = pd.to_datetime(date) + if self.date.dayofweek + 1 in [6, 7]: # 剔除周末的日期,避免混淆 + self.date = date - datetime.timedelta(self.date.dayofweek - 4) + check_out_list = self.get_rank() + timing_signal = self.get_timing_signal(stock_code) + return [self.date.strftime("%Y-%m-%d"), check_out_list, timing_signal] + + +fig, axes = plt.subplots(3, 1, sharex=True, figsize=(18, 12)) + +# , '000300.XSHG'['159949.XSHE' +stkList = ["002230"] +eq = ETFQuant(stkList) +days = 240 +# trading_dates = get_trade_da0ys(end_date=eq.date, count=eq.N) +trading_dates = jq.get_trade_days(end_date=eq.date, count=days) +RSRS = pd.DataFrame([0 for i in range(days)], index=trading_dates, columns=["0"]) +stock_price = pd.DataFrame([1 for i in range(days)], index=trading_dates, columns=["1"]) +slope = pd.DataFrame([1 for i in range(days)], index=trading_dates, columns=["1"]) + + +def get_payments( + stock_code, days, slop_days=18, M=400, MA=10, buy_sail=0.7, sail_score=-1.4 +): + data = eq.get_rsrs_score(stock_code, days, slop_days, M, MA, buy_sail, sail_score) + RSRS[stock_code + "ma18"] = data[0] + slope[stock_code + "ma18"] = data[1] + + # data = eq.get_rsrs_score(stock_code, days, 5) + # RSRS[stock_code+"ma5"] = data[0] + # slope[stock_code+"ma5"] = data[1] + + # data = eq.get_rsrs_score(stock_code, days, 10) + # RSRS[stock_code + "ma10"] = data[0] + # slope[stock_code + "ma10"] = data[1] + + stock_price[stock_code] = data[3] + stock_price[stock_code + "策略"] = ( + 1 + stock_price[stock_code].pct_change(1).fillna(0) * data[2] + ).cumprod() + # stock_price[stock_code] = stock_price[stock_code].pct_change(1) + stock_price[stock_code] = stock_price[stock_code] / stock_price[stock_code][0] + stock_price[stock_code + "signal"] = data[2] + + print( + "days=%s, slop_days=%s, M=%s, MA=%s,buy_sail = %s, sail_score = %s 基准收益率: %s 收益率: %s" + % ( + days, + slop_days, + M, + MA, + buy_sail, + sail_score, + stock_price[stock_code][-1], + stock_price[stock_code + "策略"][-1], + ) + ) + + +# get_payments('002230', days, slop_days=10, M=200, MA=1, buy_sail = 0.8, sail_score = -0.9 ) +get_payments("002230", days, slop_days=18, M=600, MA=10, buy_sail=0.8, sail_score=-1.4) +# get_max_args('002230', days, slop_days=18, M=600, MA=10, buy_sail = 0.6, sail_score = -1.4 ) +# get_max_args('002230', days, slop_days=18, M=600, MA=10, buy_sail = 0.5, sail_score = -1.4 ) +# get_max_args('002230', days, slop_days=18, M=600, MA=10, buy_sail = 0.4, sail_score = -1.4 ) +# get_max_args('002230', days, slop_days=18, M=600, MA=10, buy_sail = 0.8, sail_score = -1.4 ) +# get_max_args('002230', days, slop_days=18, M=400, MA=10, buy_sail = 0.7, sail_score = -1.4 ) +# get_max_args('002230', days, slop_days=18, M=400, MA=10, buy_sail = 0.6, sail_score = -1.4 ) +# get_max_args('002230', days, slop_days=18, M=400, MA=10, buy_sail = 0.5, sail_score = -1.4 ) +# get_max_args('002230', days, slop_days=18, M=400, MA=10, buy_sail = 0.4, sail_score = -1.4 ) +# get_max_args('002230', days, slop_days=18, M=400, MA=10, buy_sail = 0.8, sail_score = -1.5 ) +# get_max_args('002230', days, slop_days=18, M=400, MA=10, buy_sail = 0.7, sail_score = -1.5 ) +# get_max_args('002230', days, slop_days=18, M=400, MA=10, buy_sail = 0.6, sail_score = -1.5 ) +# get_max_args('002230', days, slop_days=18, M=400, MA=10, buy_sail = 0.5, sail_score = -1.5 ) +# get_max_args('002230', days, slop_days=18, M=400, MA=10, buy_sail = 0.4, sail_score = -1.5 ) +# get_max_args('002230', days, slop_days=18, M=400, MA=10, buy_sail = 0.8, sail_score = -1.3 ) +# get_max_args('002230', days, slop_days=18, M=400, MA=10, buy_sail = 0.7, sail_score = -1.3 ) +# get_max_args('002230', days, slop_days=18, M=400, MA=10, buy_sail = 0.6, sail_score = -1.3 ) +# get_max_args('002230', days, slop_days=18, M=400, MA=10, buy_sail = 0.5, sail_score = -1.3 ) +# get_max_args('002230', days, slop_days=18, M=400, MA=10, buy_sail = 0.4, sail_score = -1.3 ) +# print("now:", datetime.datetime.now()) +# for date in trading_dates: print('target and signal:\t', eq.run(date)) + +RSRS["买"] = 0.8 +RSRS["卖"] = -0.9 +RSRS.plot(ax=axes[1], title="score", grid=True) +slope.plot(ax=axes[2], title="斜率", grid=True) +stock_price.plot(ax=axes[0], title="价格", grid=True) + +plt.show() +# get_price('159949.XSHE', end_date=datetime.date.today(), count=3) diff --git a/qbot/engine/trade/easytrader/LICENSE b/qbot/engine/trade/easytrader/LICENSE new file mode 100644 index 00000000..6d2dafda --- /dev/null +++ b/qbot/engine/trade/easytrader/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2018 shidenggui + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/qbot/engine/trade/easytrader/MANIFEST.in b/qbot/engine/trade/easytrader/MANIFEST.in new file mode 100644 index 00000000..bb3ec5f0 --- /dev/null +++ b/qbot/engine/trade/easytrader/MANIFEST.in @@ -0,0 +1 @@ +include README.md diff --git a/qbot/engine/trade/easytrader/Makefile b/qbot/engine/trade/easytrader/Makefile new file mode 100644 index 00000000..bde70097 --- /dev/null +++ b/qbot/engine/trade/easytrader/Makefile @@ -0,0 +1,2 @@ +test: + pytest -vx --cov=easytrader tests diff --git a/qbot/engine/trade/easytrader/Pipfile b/qbot/engine/trade/easytrader/Pipfile new file mode 100644 index 00000000..9670212d --- /dev/null +++ b/qbot/engine/trade/easytrader/Pipfile @@ -0,0 +1,40 @@ +[[source]] +url = "http://mirrors.aliyun.com/pypi/simple/" +verify_ssl = false +name = "pypi" + +[packages] +pywinauto = "*" +"bs4" = "*" +requests = "*" +dill = "*" +click = "*" +six = "*" +flask = "*" +pillow = "*" +pytesseract = "*" +pandas = "*" +pyperclip = "*" +easyutils = "*" + +[dev-packages] +pytest-cov = "*" +pre-commit = "*" +pytest = "*" +pylint = "*" +mypy = "*" +isort = "*" +black = "==18.6b4" +ipython = "*" +better-exceptions = "*" + +[requires] +python_version = "3.6" + +[scripts] +sort_imports = "bash -c 'isort \"$@\"; git add -u' --" +format = "bash -c 'black -l 79 \"$@\"; git add -u' --" +lint = "pylint" +type_check = "mypy" +test = "bash -c 'pytest -vx --cov=easytrader tests'" +lock = "bash -c 'pipenv lock -r > requirements.txt'" diff --git a/qbot/engine/trade/easytrader/README.md b/qbot/engine/trade/easytrader/README.md new file mode 100644 index 00000000..9321155d --- /dev/null +++ b/qbot/engine/trade/easytrader/README.md @@ -0,0 +1,57 @@ +# easytrader + +[![Package](https://img.shields.io/pypi/v/easytrader.svg)](https://pypi.python.org/pypi/easytrader) +[![Travis](https://img.shields.io/travis/shidenggui/easytrader.svg)](https://travis-ci.org/shidenggui/easytrader) +[![License](https://img.shields.io/github/license/shidenggui/easytrader.svg)](https://github.com/shidenggui/easytrader/blob/master/LICENSE) + +* 进行自动的程序化股票交易 +* 支持跟踪 `joinquant`, `ricequant` 的模拟交易 +* 支持跟踪 雪球组合 调仓 +* 支持通用的同花顺客户端模拟操作 +* 实现自动登录 +* 支持通过 webserver 远程操作客户端 +* 支持命令行调用,方便其他语言适配 +* 基于 Python3.6, Win。注: Linux 仅支持雪球 + + +### 微信群以及公众号 + +欢迎大家扫码关注公众号「食灯鬼」,一起交流。进群可通过菜单加我好友,备注量化。 + +![公众号二维码](https://gitee.com/shidenggui/assets/raw/master/uPic/mp-qr.png) + +若二维码因 Github 网络无法打开,请点击[公众号二维码](https://gitee.com/shidenggui/assets/raw/master/uPic/mp-qr.png)直接打开图片。 + +### Author + +**easytrader** © [shidenggui](https://github.com/shidenggui), Released under the [MIT](./LICENSE) License.
+ +> Blog [@shidenggui](https://shidenggui.com) · Weibo [@食灯鬼](https://www.weibo.com/u/1651274491) · Twitter [@shidenggui](https://twitter.com/shidenggui) + +### 相关 + +[获取新浪免费实时行情的类库: easyquotation](https://github.com/shidenggui/easyquotation) + +[简单的股票量化交易框架 使用 easytrader 和 easyquotation](https://github.com/shidenggui/easyquant) + + +### 支持券商 + +* 海通客户端(海通网上交易系统独立委托) +* 华泰客户端(网上交易系统(专业版Ⅱ)) +* 国金客户端(全能行证券交易终端PC版) +* 其他券商通用同花顺客户端(需要手动登陆) + + +### 模拟交易 + +* 雪球组合 by @[haogefeifei](https://github.com/haogefeifei)([说明](doc/xueqiu.md)) + +### 使用文档 + +[中文文档](http://easytrader.readthedocs.io/zh/master/) + + +### 作者其他作品 +* [大数据网络小说推荐系统 - 推书君](https://www.tuishujun.com) +* [中文独立个人博客导航 - bloghub.fun](https://bloghub.fun) diff --git a/qbot/engine/trade/easytrader/docs/help.md b/qbot/engine/trade/easytrader/docs/help.md new file mode 100644 index 00000000..d8bbcb1a --- /dev/null +++ b/qbot/engine/trade/easytrader/docs/help.md @@ -0,0 +1,62 @@ +# 某些同花顺客户端不允许拷贝 `Grid` 数据 + +现在默认获取 `Grid` 数据的策略是通过剪切板拷贝,有些券商不允许这种方式,导致无法获取持仓等数据。为解决此问题,额外实现了一种通过将 `Grid` 数据存为文件再读取的策略, +使用方式如下: + +```python +from easytrader import grid_strategies + +user.grid_strategy = grid_strategies.Xls +``` + +# 通过工具栏刷新按钮刷新数据 + +当前的刷新数据方式是通过切换菜单栏实现,通用但是比较缓慢,可以选择通过点击工具栏的刷新按钮来刷新 + +```python +from easytrader import refresh_strategies + +# refresh_btn_index 指的是刷新按钮在工具栏的排序,默认为第四个,根据客户端实际情况调整 +user.refresh_strategy = refresh_strategies.Toolbar(refresh_btn_index=4) +``` + +# 无法保存对应的 xls 文件 + +有些系统默认的临时文件目录过长,使用 xls 策略时无法正常保存,可通过如下方式修改为自定义目录 + +``` +user.grid_strategy_instance.tmp_folder = 'C:\\custom_folder' +``` + +# 某些券商客户端无法输入文本 + +有些客户端无法通过 set_edit_text 方法输入内容,可以通过使用 type_keys 方法绕过,开启方式 + +``` +user.enable_type_keys_for_editor() +``` + +# 如何关闭 debug 日志的输出 + +```python +user = easytrader.use('yh', debug=False) + +``` + + +# 编辑配置文件,运行后出现 `json` 解码报错 + + +出现如下错误 + +```python +raise JSONDecodeError("Expecting value", s, err.value) from None + +JSONDecodeError: Expecting value +``` + +请勿使用 `记事本` 编辑账户的 `json` 配置文件,推荐使用 [notepad++](https://notepad-plus-plus.org/zh/) 或者 [sublime text](http://www.sublimetext.com/) + +### 其他 + +[软件实现原理](http://www.jisilu.cn/question/42707) diff --git a/qbot/engine/trade/easytrader/docs/index.md b/qbot/engine/trade/easytrader/docs/index.md new file mode 100644 index 00000000..0f1fd337 --- /dev/null +++ b/qbot/engine/trade/easytrader/docs/index.md @@ -0,0 +1,44 @@ +# 简介 + +* 进行自动的程序化股票交易 +* 支持跟踪 `joinquant`, `ricequant` 的模拟交易 +* 支持跟踪 雪球组合 调仓, 实盘雪球组合 +* 支持通用的同花顺客户端模拟操作 +* 支持命令行调用,方便其他语言适配 +* 支持远程操作客户端 +* 支持 Python3 , Linux / Win / Mac + +### 加微信群以及公众号 + +欢迎大家扫码关注公众号"食灯鬼",通过菜单加我好友,备注量化进群 + +![JDRUhz](https://gitee.com/shidenggui/assets/raw/master/uPic/JDRUhz.jpg) + + +### 支持券商 + + +* 海通客户端(海通网上交易系统独立委托) +* 华泰客户端(网上交易系统(专业版Ⅱ)) +* 国金客户端(全能行证券交易终端PC版) +* 通用同花顺客户端(同花顺免费版) +* 其他券商专用同花顺客户端(需要手动登陆) + + +### 模拟交易 + +* 雪球组合 by @[haogefeifei](https://github.com/haogefeifei)([说明](other/xueqiu.md)) + + +### 相关 + +[获取新浪免费实时行情的类库: easyquotation](https://github.com/shidenggui/easyquotation) + +[简单的股票量化交易框架 使用 easytrader 和 easyquotation](https://github.com/shidenggui/easyquant) + + +### 作者其他作品 + +* [大数据网络小说推荐系统 - 推书君](https://www.tuishujun.com) +* [中文独立个人博客导航 - bloghub.fun](https://bloghub.fun) + diff --git a/qbot/engine/trade/easytrader/docs/install.md b/qbot/engine/trade/easytrader/docs/install.md new file mode 100644 index 00000000..5d71030a --- /dev/null +++ b/qbot/engine/trade/easytrader/docs/install.md @@ -0,0 +1,37 @@ +### requirements + +### 客户端设置 + +需要对客户端按以下设置,不然会导致下单时价格出错以及客户端超时锁定 + +* 系统设置 > 界面设置: 界面不操作超时时间设为 0 +* 系统设置 > 交易设置: 默认买入价格/买入数量/卖出价格/卖出数量 都设置为 空 + +同时客户端不能最小化也不能处于精简模式 + +### 云端部署建议 + +在云服务上部署时,使用自带的远程桌面会有问题,推荐使用 TightVNC + +### 登陆时的验证码识别 + +券商如果登陆需要识别验证码的话需要安装 tesseract: + +* `tesseract` : 非 `pytesseract`, 需要单独安装, [地址](https://github.com/tesseract-ocr/tesseract/wiki),保证在命令行下 `tesseract` 可用 + +或者你也可以手动登陆后在通过 `easytrader` 调用,此时 `easytrader` 在登陆过程中会直接识别到已登陆的窗口。 + +### 安装 + +```shell +pip install easytrader +``` + +注: `Windows` 用户 `pip` 安装时会提示 `No module named xxx`, 请使用 `pip install xxx` 安装对应缺失的 `module`, 然后再重新 `pip install easytrader`, 可以参考此文档 [INSTALL4Windows.md](other/INSTALL4Windows.md) + +### 升级 + +```shell +pip install easytrader -U +``` + diff --git a/qbot/engine/trade/easytrader/docs/other/xueqiu.md b/qbot/engine/trade/easytrader/docs/other/xueqiu.md new file mode 100644 index 00000000..8d5c06a9 --- /dev/null +++ b/qbot/engine/trade/easytrader/docs/other/xueqiu.md @@ -0,0 +1,16 @@ +# 雪球组合模拟交易 + +因为雪球组合是按比例调仓的,所以模拟成券商实盘接口会有一些要注意的问题 + +* 接口基本与其他券商接口调用参数返回一致 +* 委托单不支持挂高挂低(开盘时间都是直接市价成交的) +* 初始资金是按组合净值 1:1000000 换算来的, 可以通过 `easytrader.use('xq', initial_assets=初始资金值)` 来调整 +* 委托单的委托价格和委托数量目前换算回来都是按1手拆的(雪球是按比例调仓的) +* 持仓价格和持仓数量问题同上, 但持股市值是对的. +* 一些不合理的操作会直接抛TradeError,注意看错误信息 + +---------------- +20160909 新增函数adjust_weight,用于雪球组合比例调仓 + +adjust_weight函数包含两个参数,stock_code 指定调仓股票代码,weight 指定调仓比例 + diff --git a/qbot/engine/trade/easytrader/docs/usage.md b/qbot/engine/trade/easytrader/docs/usage.md new file mode 100644 index 00000000..ae1affcb --- /dev/null +++ b/qbot/engine/trade/easytrader/docs/usage.md @@ -0,0 +1,479 @@ +## 一、引入 + +```python +import easytrader +``` + +## 二、设置交易客户端类型 + +**海通客户端** + +```python +user = easytrader.use('htzq_client') +``` + +**华泰客户端** + +```python +user = easytrader.use('ht_client') +``` + +**国金客户端** + +```python +user = easytrader.use('gj_client') +``` + +**通用同花顺客户端** + +```python +user = easytrader.use('universal_client') +``` + +注: 通用同花顺客户端是指同花顺官网提供的客户端软件内的下单程序,内含对多个券商的交易支持,适用于券商不直接提供同花顺客户端时的后备方案。 + +**其他券商专用同花顺客户端** + +```python +user = easytrader.use('ths') +``` + +注: 其他券商专用同花顺客户端是指对应券商官网提供的基于同花顺修改的软件版本,类似银河的双子星(同花顺版本),国金证券网上交易独立下单程序(核新PC版)等。 + + + +**雪球** + +```python +user = easytrader.use('xq') +``` + + +## 三、启动并连接客户端 + +### (一)其他券商专用同花顺客户端 + +其他券商专用同花顺客户端不支持自动登录,需要先手动登录。 + +请手动打开并登录客户端后,运用connect函数连接客户端。 + +```python +user.connect(r'客户端xiadan.exe路径') # 类似 r'C:\htzqzyb2\xiadan.exe' +``` + +### (二)通用同花顺客户端 + +需要先手动登录一次:添加券商,填入账户号、密码、验证码,勾选“保存密码” + +第一次登录后,上述信息被缓存,可以调用prepare函数自动登录(仅需账户号、客户端路径,密码随意输入)。 + +### (三)其它 + +非同花顺的客户端,可以调用prepare函数自动登录。 + +调用prepare时所需的参数,可以通过`函数参数` 或 `配置文件` 赋予。 + +**1. 函数参数(推荐)** + +``` +user.prepare(user='用户名', password='雪球、银河客户端为明文密码', comm_password='华泰通讯密码,其他券商不用') +``` + +注: 雪球比较特殊,见下列配置文件格式 + +**2. 配置文件** + +```python +user.prepare('/path/to/your/yh_client.json') # 配置文件路径 +``` + +注: 配置文件需自己用编辑器编辑生成, **请勿使用记事本**, 推荐使用 [notepad++](https://notepad-plus-plus.org/zh/) 或者 [sublime text](http://www.sublimetext.com/) 。 + +**配置文件格式如下:** + +银河/国金客户端 + +``` +{ + "user": "用户名", + "password": "明文密码" +} + +``` + +华泰客户端 + +``` +{ +  "user": "华泰用户名", +  "password": "华泰明文密码", +  "comm_password": "华泰通讯密码" +} + +``` + +雪球 + +``` +{ + "cookies": "雪球 cookies,登陆后获取,获取方式见 https://smalltool.github.io/2016/08/02/cookie/", + "portfolio_code": "组合代码(例:ZH818559)", + "portfolio_market": "交易市场(例:us 或者 cn 或者 hk)" +} +``` + +## 四、交易相关 + +### 1. 获取资金状况 + +```python +user.balance +``` + +**return** +```python +[{'参考市值': 21642.0, + '可用资金': 28494.21, + '币种': '0', + '总资产': 50136.21, + '股份参考盈亏': -90.21, + '资金余额': 28494.21, + '资金帐号': 'xxx'}] +``` + +### 2. 获取持仓 + +```python +user.position +``` + +**return** +```python +[{'买入冻结': 0, + '交易市场': '沪A', + '卖出冻结': '0', + '参考市价': 4.71, + '参考市值': 10362.0, + '参考成本价': 4.672, + '参考盈亏': 82.79, + '当前持仓': 2200, + '盈亏比例(%)': '0.81%', + '股东代码': 'xxx', + '股份余额': 2200, + '股份可用': 2200, + '证券代码': '601398', + '证券名称': '工商银行'}] +``` + +### 3. 买入 + +```python +user.buy('162411', price=0.55, amount=100) +``` + +**return** + +```python +{'entrust_no': 'xxxxxxxx'} +``` + +注: 系统可以配置是否返回成交回报。如果没配的话默认返回 `{"message": "success"}` + +### 4. 卖出 + +```python +user.sell('162411', price=0.55, amount=100) +``` + +**return** + +```python +{'entrust_no': 'xxxxxxxx'} +``` + +### 5. 一键打新 + +```python +user.auto_ipo() +``` + +### 6. 撤单 + +```python +user.cancel_entrust('buy/sell 获取的 entrust_no') +``` + +**return** + +``` +{'message': '撤单申报成功'} +``` + + +### 7. 查询当日成交 + +```python +user.today_trades +``` + +**return** + +``` +[{'买卖标志': '买入', + '交易市场': '深A', + '委托序号': '12345', + '成交价格': 0.626, + '成交数量': 100, + '成交日期': '20170313', + '成交时间': '09:50:30', + '成交金额': 62.60, + '股东代码': 'xxx', + '证券代码': '162411', + '证券名称': '华宝油气'}] +``` + +### 8. 查询当日委托 + +```python +user.today_entrusts +``` + +**return** + +``` +[{'买卖标志': '买入', + '交易市场': '深A', + '委托价格': 0.627, + '委托序号': '111111', + '委托数量': 100, + '委托日期': '20170313', + '委托时间': '09:50:30', + '成交数量': 100, + '撤单数量': 0, + '状态说明': '已成', + '股东代码': 'xxxxx', + '证券代码': '162411', + '证券名称': '华宝油气'}, + {'买卖标志': '买入', + '交易市场': '深A', + '委托价格': 0.6, + '委托序号': '1111', + '委托数量': 100, + '委托日期': '20170313', + '委托时间': '09:40:30', + '成交数量': 0, + '撤单数量': 100, + '状态说明': '已撤', + '股东代码': 'xxx', + '证券代码': '162411', + '证券名称': '华宝油气'}] +``` + + +### 9. 查询今日可申购新股 + +```python +from easytrader.utils.stock import get_today_ipo_data +ipo_data = get_today_ipo_data() +print(ipo_data) +``` + +**return** + +```python +[{'stock_code': '股票代码', + 'stock_name': '股票名称', + 'price': 发行价, + 'apply_code': '申购代码'}] +``` + +### 10. 刷新数据 + +``` +user.refresh() +``` + +### 11. 雪球组合比例调仓 ### + +```python +user.adjust_weight('股票代码', 目标比例) +``` + +例如,`user.adjust_weight('000001', 10)`是将平安银行在组合中的持仓比例调整到10%。 + +## 五、退出客户端软件 + +```python +user.exit() +``` + +## 六、远端服务器模式 + +远端服务器模式是交易服务端和量化策略端分离的模式。 + +**交易服务端**通常是有固定`IP`地址的云服务器,该服务器上运行着`easytrader`交易服务。而**量化策略端**可能是`JoinQuant、RiceQuant、Vn.Py`,物理上与交易服务端不在同一台电脑上。交易服务端被动或主动获取交易信号,并驱动**交易软件**(交易软件包括运行在同一服务器上的下单软件,比如同花顺`xiadan.exe`,或者运行在另一台服务器上的雪球`xq`)。 + +远端模式下,`easytrader`交易服务通过以下两种方式获得交易信号并驱动交易软件: + +### (一) 被动接收远端量化策略发送的交易相关指令 + +#### 交易服务端——启动服务 + +```python +from easytrader import server + +server.run(port=1430) # 默认端口为 1430 +``` + +#### 量化策略端——调用服务 + +```python +from easytrader import remoteclient + +user = remoteclient.use('使用客户端类型,可选 yh_client, ht_client, ths, xq等', host='服务器ip', port='服务器端口,默认为1430') + +user.buy(......) + +user.sell(......) + +# 交易函数用法同上,见“四、交易相关” +``` + +### (二) 主动监控远端量化策略的成交记录或仓位变化 + + +#### 1. 跟踪 `joinquant` / `ricequant` 的模拟交易 + +##### 1) 初始化跟踪的 trader + +这里以雪球为例, 也可以使用银河之类 `easytrader` 支持的券商 + +``` +xq_user = easytrader.use('xq') +xq_user.prepare('xueqiu.json') +``` + +##### 2) 初始化跟踪 `joinquant` / `ricequant` 的 follower + +``` +target = 'jq' # joinquant +target = 'rq' # ricequant +follower = easytrader.follower(target) +follower.login(user='rq/jq用户名', password='rq/jq密码') +``` + +##### 3) 连接 follower 和 trader + +##### joinquant +``` +follower.follow(xq_user, 'jq的模拟交易url') +``` + +注: jq的模拟交易url指的是对应模拟交易对应的可以查看持仓, 交易记录的页面, 类似 `https://www.joinquant.com/algorithm/live/index?backtestId=xxx` + +正常会输出 + +![enjoy it](https://raw.githubusercontent.com/shidenggui/assets/master/easytrader/joinquant.jpg) + +注: 启动后发现跟踪策略无输出,那是因为今天模拟交易没有调仓或者接收到的调仓信号过期了,默认只处理120s内的信号,想要测试的可以用下面的命令: + +```python +jq_follower.follow(user, '模拟交易url', + trade_cmd_expire_seconds=100000000000, cmd_cache=False) +``` + +- trade_cmd_expire_seconds 默认处理多少秒内的信号 + +- cmd_cache 是否读取已经执行过的命令缓存,以防止重复执行 + +目录下产生的 cmd_cache.pk,是用来存储历史执行过的交易指令,防止在重启程序时重复执行交易过的指令,可以通过 `follower.follow(xxx, cmd_cache=False)` 来关闭。 + +##### ricequant + +``` +follower.follow(xq_user, run_id) +``` +注:ricequant的run_id即PT列表中的ID。 + + +#### 2. 跟踪雪球的组合 + +##### 1) 初始化跟踪的 trader + +同上 + +##### 2) 初始化跟踪 雪球组合 的 follower + +``` +xq_follower = easytrader.follower('xq') +xq_follower.login(cookies='雪球 cookies,登陆后获取,获取方式见 https://smalltool.github.io/2016/08/02/cookie/') +``` + +##### 3) 连接 follower 和 trader + +``` +xq_follower.follow(xq_user, 'xq组合ID,类似ZH123456', total_assets=100000) +``` + + +注: 雪球组合是以百分比调仓的, 所以需要额外设置组合对应的资金额度 + +* 这里可以设置 total_assets, 为当前组合的净值对应的总资金额度, 具体可以参考参数说明 +* 或者设置 initial_assets, 这时候总资金额度为 initial_assets * 组合净值 + +* 雪球额外支持 adjust_sell 参数,决定是否根据用户的实际持仓数调整卖出股票数量,解决雪球根据百分比调仓时计算出的股数有偏差的问题。当卖出股票数大于实际持仓数时,调整为实际持仓数。目前仅在银河客户端测试通过。 当 users 为多个时,根据第一个 user 的持仓数决定 + + +#### 3. 多用户跟踪多策略 + +``` +follower.follow(users=[xq_user, yh_user], strategies=['组合1', '组合2'], total_assets=[10000, 10000]) +``` + +#### 4. 其它与跟踪有关的问题 + +使用市价单跟踪模式,目前仅支持银河 + +``` +follower.follow(***, entrust_prop='market') +``` + +调整下单间隔, 默认为0s。调大可防止卖出买入时卖出单没有及时成交导致的买入金额不足 + +``` +follower.follow(***, send_interval=30) # 设置下单间隔为 30 s +``` +设置买卖时的滑点 + +``` +follower.follow(***, slippage=0.05) # 设置滑点为 5% +``` + +## 七、命令行模式 + +#### 登录 + +``` + python cli.py --use yh --prepare gf.json +``` + +注: 此时会生成 `account.session` 文件保存生成的 `user` 对象 + +#### 获取余额 / 持仓 / 以及其他变量 + +``` + python cli.py --get balance +``` + +#### 买卖 / 撤单 + +``` + python cli.py --do buy 162411 0.450 100 +``` +#### 查看帮助 + +``` + python cli.py --help +``` + + diff --git a/qbot/engine/trade/easytrader/easytrader/__init__.py b/qbot/engine/trade/easytrader/easytrader/__init__.py new file mode 100644 index 00000000..ecff7756 --- /dev/null +++ b/qbot/engine/trade/easytrader/easytrader/__init__.py @@ -0,0 +1,11 @@ +# -*- coding: utf-8 -*- +import urllib3 + +from easytrader import exceptions +from easytrader.api import use, follower +from easytrader.log import logger + +urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) + +__version__ = "0.23.0" +__author__ = "shidenggui" diff --git a/qbot/engine/trade/easytrader/easytrader/api.py b/qbot/engine/trade/easytrader/easytrader/api.py new file mode 100644 index 00000000..96d51ffb --- /dev/null +++ b/qbot/engine/trade/easytrader/easytrader/api.py @@ -0,0 +1,101 @@ +# -*- coding: utf-8 -*- +import logging +import sys + +from easytrader.joinquant_follower import JoinQuantFollower +from easytrader.log import logger +from easytrader.ricequant_follower import RiceQuantFollower +from easytrader.xq_follower import XueQiuFollower +from easytrader.xqtrader import XueQiuTrader + +if sys.version_info <= (3, 5): + raise TypeError("不支持 Python3.5 及以下版本,请升级") + + +def use(broker, debug=False, **kwargs): + """用于生成特定的券商对象 + :param broker:券商名支持 ['yh_client', '银河客户端'] ['ht_client', '华泰客户端'] + :param debug: 控制 debug 日志的显示, 默认为 True + :param initial_assets: [雪球参数] 控制雪球初始资金,默认为一百万 + :return the class of trader + + Usage:: + + >>> import easytrader + >>> user = easytrader.use('xq') + >>> user.prepare('xueqiu.json') + """ + if debug: + logger.setLevel(logging.DEBUG) + + if broker.lower() in ["xq", "雪球"]: + return XueQiuTrader(**kwargs) + + if broker.lower() in ["yh_client", "银河客户端"]: + from .yh_clienttrader import YHClientTrader + + return YHClientTrader() + + if broker.lower() in ["ht_client", "华泰客户端"]: + from .ht_clienttrader import HTClientTrader + + return HTClientTrader() + + if broker.lower() in ["wk_client", "五矿客户端"]: + from easytrader.wk_clienttrader import WKClientTrader + + return WKClientTrader() + + if broker.lower() in ["htzq_client", "海通证券客户端"]: + from easytrader.htzq_clienttrader import HTZQClientTrader + + return HTZQClientTrader() + + if broker.lower() in ["gj_client", "国金客户端"]: + from .gj_clienttrader import GJClientTrader + + return GJClientTrader() + + if broker.lower() in ["gf_client", "广发客户端"]: + from .gf_clienttrader import GFClientTrader + + return GFClientTrader() + + if broker.lower() in ["universal_client", "通用同花顺客户端"]: + from easytrader.universal_clienttrader import UniversalClientTrader + + return UniversalClientTrader() + + if broker.lower() in ["ths", "同花顺客户端"]: + from .clienttrader import ClientTrader + + return ClientTrader() + + raise NotImplementedError + + +def follower(platform, **kwargs): + """用于生成特定的券商对象 + :param platform:平台支持 ['jq', 'joinquant', '聚宽’] + :param initial_assets: [雪球参数] 控制雪球初始资金,默认为一万, + 总资金由 initial_assets * 组合当前净值 得出 + :param total_assets: [雪球参数] 控制雪球总资金,无默认值, + 若设置则覆盖 initial_assets + :return the class of follower + + Usage:: + + >>> import easytrader + >>> user = easytrader.use('xq') + >>> user.prepare('xueqiu.json') + >>> jq = easytrader.follower('jq') + >>> jq.login(user='username', password='password') + >>> jq.follow(users=user, strategies=['strategies_link']) + """ + if platform.lower() in ["rq", "ricequant", "米筐"]: + return RiceQuantFollower() + if platform.lower() in ["jq", "joinquant", "聚宽"]: + return JoinQuantFollower() + if platform.lower() in ["xq", "xueqiu", "雪球"]: + return XueQiuFollower(**kwargs) + raise NotImplementedError diff --git a/qbot/engine/trade/easytrader/easytrader/clienttrader.py b/qbot/engine/trade/easytrader/easytrader/clienttrader.py new file mode 100644 index 00000000..b0a4b648 --- /dev/null +++ b/qbot/engine/trade/easytrader/easytrader/clienttrader.py @@ -0,0 +1,617 @@ +# -*- coding: utf-8 -*- +import abc +import functools +import logging +import os +import re +import sys +import time +from typing import Type, Union + +import hashlib, binascii + +import easyutils +from pywinauto import findwindows, timings + +from easytrader import grid_strategies, pop_dialog_handler, refresh_strategies +from easytrader.config import client +from easytrader.grid_strategies import IGridStrategy +from easytrader.log import logger +from easytrader.refresh_strategies import IRefreshStrategy +from easytrader.utils.misc import file2dict +from easytrader.utils.perf import perf_clock + +if not sys.platform.startswith("darwin"): + import pywinauto + import pywinauto.clipboard + +class IClientTrader(abc.ABC): + @property + @abc.abstractmethod + def app(self): + """Return current app instance""" + pass + + @property + @abc.abstractmethod + def main(self): + """Return current main window instance""" + pass + + @property + @abc.abstractmethod + def config(self): + """Return current config instance""" + pass + + @abc.abstractmethod + def wait(self, seconds: float): + """Wait for operation return""" + pass + + @abc.abstractmethod + def refresh(self): + """Refresh data""" + pass + + @abc.abstractmethod + def is_exist_pop_dialog(self): + pass + + +class ClientTrader(IClientTrader): + _editor_need_type_keys = False + # The strategy to use for getting grid data + grid_strategy: Union[IGridStrategy, Type[IGridStrategy]] = grid_strategies.Copy + _grid_strategy_instance: IGridStrategy = None + refresh_strategy: IRefreshStrategy = refresh_strategies.Switch() + + def enable_type_keys_for_editor(self): + """ + 有些客户端无法通过 set_edit_text 方法输入内容,可以通过使用 type_keys 方法绕过 + """ + self._editor_need_type_keys = True + + @property + def grid_strategy_instance(self): + if self._grid_strategy_instance is None: + self._grid_strategy_instance = ( + self.grid_strategy + if isinstance(self.grid_strategy, IGridStrategy) + else self.grid_strategy() + ) + self._grid_strategy_instance.set_trader(self) + return self._grid_strategy_instance + + def __init__(self): + self._config = client.create(self.broker_type) + self._app = None + self._main = None + self._toolbar = None + + @property + def app(self): + return self._app + + @property + def main(self): + return self._main + + @property + def config(self): + return self._config + + def connect(self, exe_path=None, **kwargs): + """ + 直接连接登陆后的客户端 + :param exe_path: 客户端路径类似 r'C:\\htzqzyb2\\xiadan.exe', 默认 r'C:\\htzqzyb2\\xiadan.exe' + :return: + """ + connect_path = exe_path or self._config.DEFAULT_EXE_PATH + if connect_path is None: + raise ValueError( + "参数 exe_path 未设置,请设置客户端对应的 exe 地址,类似 C:\\客户端安装目录\\xiadan.exe" + ) + + self._app = pywinauto.Application().connect(path=connect_path, timeout=10) + self._close_prompt_windows() + self._main = self._app.top_window() + self._init_toolbar() + + @property + def broker_type(self): + return "ths" + + @property + def balance(self): + self._switch_left_menus(["查询[F4]", "资金股票"]) + + return self._get_balance_from_statics() + + def _init_toolbar(self): + self._toolbar = self._main.child_window(class_name="ToolbarWindow32") + + def _get_balance_from_statics(self): + result = {} + for key, control_id in self._config.BALANCE_CONTROL_ID_GROUP.items(): + result[key] = float( + self._main.child_window( + control_id=control_id, class_name="Static" + ).window_text() + ) + return result + + @property + def position(self): + self._switch_left_menus(["查询[F4]", "资金股票"]) + + return self._get_grid_data(self._config.COMMON_GRID_CONTROL_ID) + + @property + def today_entrusts(self): + self._switch_left_menus(["查询[F4]", "当日委托"]) + + return self._get_grid_data(self._config.COMMON_GRID_CONTROL_ID) + + @property + def today_trades(self): + self._switch_left_menus(["查询[F4]", "当日成交"]) + + return self._get_grid_data(self._config.COMMON_GRID_CONTROL_ID) + + @property + def cancel_entrusts(self): + self.refresh() + self._switch_left_menus(["撤单[F3]"]) + + return self._get_grid_data(self._config.COMMON_GRID_CONTROL_ID) + + @perf_clock + def cancel_entrust(self, entrust_no): + self.refresh() + for i, entrust in enumerate(self.cancel_entrusts): + if entrust[self._config.CANCEL_ENTRUST_ENTRUST_FIELD] == entrust_no: + self._cancel_entrust_by_double_click(i) + return self._handle_pop_dialogs() + return {"message": "委托单状态错误不能撤单, 该委托单可能已经成交或者已撤"} + + def cancel_all_entrusts(self): + self.refresh() + self._switch_left_menus(["撤单[F3]"]) + + # 点击全部撤销控件 + self._app.top_window().child_window( + control_id=self._config.TRADE_CANCEL_ALL_ENTRUST_CONTROL_ID, class_name="Button", title_re="""全撤.*""" + ).click() + self.wait(0.2) + + # 等待出现 确认兑换框 + if self.is_exist_pop_dialog(): + # 点击是 按钮 + w = self._app.top_window() + if w is not None: + btn = w["是(Y)"] + if btn is not None: + btn.click() + self.wait(0.2) + + # 如果出现了确认窗口 + self.close_pop_dialog() + + @perf_clock + def repo(self, security, price, amount, **kwargs): + self._switch_left_menus(["债券回购", "融资回购(正回购)"]) + + return self.trade(security, price, amount) + + @perf_clock + def reverse_repo(self, security, price, amount, **kwargs): + self._switch_left_menus(["债券回购", "融劵回购(逆回购)"]) + + return self.trade(security, price, amount) + + @perf_clock + def buy(self, security, price, amount, **kwargs): + self._switch_left_menus(["买入[F1]"]) + + return self.trade(security, price, amount) + + @perf_clock + def sell(self, security, price, amount, **kwargs): + self._switch_left_menus(["卖出[F2]"]) + + return self.trade(security, price, amount) + + @perf_clock + def market_buy(self, security, amount, ttype=None, limit_price=None, **kwargs): + """ + 市价买入 + :param security: 六位证券代码 + :param amount: 交易数量 + :param ttype: 市价委托类型,默认客户端默认选择, + 深市可选 ['对手方最优价格', '本方最优价格', '即时成交剩余撤销', '最优五档即时成交剩余 '全额成交或撤销'] + 沪市可选 ['最优五档成交剩余撤销', '最优五档成交剩余转限价'] + :param limit_price: 科创板 限价 + + :return: {'entrust_no': '委托单号'} + """ + self._switch_left_menus(["市价委托", "买入"]) + + return self.market_trade(security, amount, ttype, limit_price=limit_price) + + @perf_clock + def market_sell(self, security, amount, ttype=None, limit_price=None, **kwargs): + """ + 市价卖出 + :param security: 六位证券代码 + :param amount: 交易数量 + :param ttype: 市价委托类型,默认客户端默认选择, + 深市可选 ['对手方最优价格', '本方最优价格', '即时成交剩余撤销', '最优五档即时成交剩余 '全额成交或撤销'] + 沪市可选 ['最优五档成交剩余撤销', '最优五档成交剩余转限价'] + :param limit_price: 科创板 限价 + :return: {'entrust_no': '委托单号'} + """ + self._switch_left_menus(["市价委托", "卖出"]) + + return self.market_trade(security, amount, ttype, limit_price=limit_price) + + def market_trade(self, security, amount, ttype=None, limit_price=None, **kwargs): + """ + 市价交易 + :param security: 六位证券代码 + :param amount: 交易数量 + :param ttype: 市价委托类型,默认客户端默认选择, + 深市可选 ['对手方最优价格', '本方最优价格', '即时成交剩余撤销', '最优五档即时成交剩余 '全额成交或撤销'] + 沪市可选 ['最优五档成交剩余撤销', '最优五档成交剩余转限价'] + + :return: {'entrust_no': '委托单号'} + """ + code = security[-6:] + self._type_edit_control_keys(self._config.TRADE_SECURITY_CONTROL_ID, code) + if ttype is not None: + retry = 0 + retry_max = 10 + while retry < retry_max: + try: + self._set_market_trade_type(ttype) + break + except: + retry += 1 + self.wait(0.1) + self._set_market_trade_params(security, amount, limit_price=limit_price) + self._submit_trade() + + return self._handle_pop_dialogs( + handler_class=pop_dialog_handler.TradePopDialogHandler + ) + + def _set_market_trade_type(self, ttype): + """根据选择的市价交易类型选择对应的下拉选项""" + selects = self._main.child_window( + control_id=self._config.TRADE_MARKET_TYPE_CONTROL_ID, class_name="ComboBox" + ) + for i, text in enumerate(selects.texts()): + # skip 0 index, because 0 index is current select index + if i == 0: + if re.search(ttype, text): # 当前已经选中 + return + else: + continue + if re.search(ttype, text): + selects.select(i - 1) + return + raise TypeError("不支持对应的市价类型: {}".format(ttype)) + + def _set_stock_exchange_type(self, ttype): + """根据选择的市价交易类型选择对应的下拉选项""" + selects = self._main.child_window( + control_id=self._config.TRADE_STOCK_EXCHANGE_CONTROL_ID, class_name="ComboBox" + ) + + for i, text in enumerate(selects.texts()): + # skip 0 index, because 0 index is current select index + if i == 0: + if ttype.strip() == text.strip(): # 当前已经选中 + return + else: + continue + if ttype.strip() == text.strip(): + selects.select(i - 1) + return + raise TypeError("不支持对应的市场类型: {}".format(ttype)) + + def auto_ipo(self): + self._switch_left_menus(self._config.AUTO_IPO_MENU_PATH) + + stock_list = self._get_grid_data(self._config.COMMON_GRID_CONTROL_ID) + + if len(stock_list) == 0: + return {"message": "今日无新股"} + invalid_list_idx = [ + i for i, v in enumerate(stock_list) if v[self.config.AUTO_IPO_NUMBER] <= 0 + ] + + if len(stock_list) == len(invalid_list_idx): + return {"message": "没有发现可以申购的新股"} + + self._click(self._config.AUTO_IPO_SELECT_ALL_BUTTON_CONTROL_ID) + self.wait(0.1) + + for row in invalid_list_idx: + self._click_grid_by_row(row) + self.wait(0.1) + + self._click(self._config.AUTO_IPO_BUTTON_CONTROL_ID) + self.wait(0.1) + + return self._handle_pop_dialogs() + + def _click_grid_by_row(self, row): + x = self._config.COMMON_GRID_LEFT_MARGIN + y = ( + self._config.COMMON_GRID_FIRST_ROW_HEIGHT + + self._config.COMMON_GRID_ROW_HEIGHT * row + ) + self._app.top_window().child_window( + control_id=self._config.COMMON_GRID_CONTROL_ID, + class_name="CVirtualGridCtrl", + ).click(coords=(x, y)) + + @perf_clock + def is_exist_pop_dialog(self): + self.wait(0.5) # wait dialog display + try: + return ( + self._main.wrapper_object() != self._app.top_window().wrapper_object() + ) + except ( + findwindows.ElementNotFoundError, + timings.TimeoutError, + RuntimeError, + ) as ex: + logger.exception("check pop dialog timeout") + return False + + @perf_clock + def close_pop_dialog(self): + try: + if self._main.wrapper_object() != self._app.top_window().wrapper_object(): + w = self._app.top_window() + if w is not None: + w.close() + self.wait(0.2) + except ( + findwindows.ElementNotFoundError, + timings.TimeoutError, + RuntimeError, + ) as ex: + pass + + def _run_exe_path(self, exe_path): + return os.path.join(os.path.dirname(exe_path), "xiadan.exe") + + def wait(self, seconds): + time.sleep(seconds) + + def exit(self): + self._app.kill() + + def _close_prompt_windows(self): + self.wait(1) + for window in self._app.windows(class_name="#32770", visible_only=True): + title = window.window_text() + if title != self._config.TITLE: + logging.info("close " + title) + window.close() + self.wait(0.2) + self.wait(1) + + def close_pormpt_window_no_wait(self): + for window in self._app.windows(class_name="#32770"): + if window.window_text() != self._config.TITLE: + window.close() + + def trade(self, security, price, amount): + self._set_trade_params(security, price, amount) + + self._submit_trade() + + return self._handle_pop_dialogs( + handler_class=pop_dialog_handler.TradePopDialogHandler + ) + + def _click(self, control_id): + self._app.top_window().child_window( + control_id=control_id, class_name="Button" + ).click() + + @perf_clock + def _submit_trade(self): + time.sleep(0.2) + self._main.child_window( + control_id=self._config.TRADE_SUBMIT_CONTROL_ID, class_name="Button" + ).click() + + @perf_clock + def __get_top_window_pop_dialog(self): + return self._app.top_window().window( + control_id=self._config.POP_DIALOD_TITLE_CONTROL_ID + ) + + @perf_clock + def _get_pop_dialog_title(self): + return ( + self._app.top_window() + .child_window(control_id=self._config.POP_DIALOD_TITLE_CONTROL_ID) + .window_text() + ) + + def _set_trade_params(self, security, price, amount): + code = security[-6:] + + self._type_edit_control_keys(self._config.TRADE_SECURITY_CONTROL_ID, code) + + # wait security input finish + self.wait(0.1) + + # 设置交易所 + if security.lower().startswith("sz"): + self._set_stock_exchange_type("深圳A股") + if security.lower().startswith("sh"): + self._set_stock_exchange_type("上海A股") + + self.wait(0.1) + + self._type_edit_control_keys( + self._config.TRADE_PRICE_CONTROL_ID, + easyutils.round_price_by_code(price, code), + ) + self._type_edit_control_keys( + self._config.TRADE_AMOUNT_CONTROL_ID, str(int(amount)) + ) + + def _set_market_trade_params(self, security, amount, limit_price=None): + self._type_edit_control_keys( + self._config.TRADE_AMOUNT_CONTROL_ID, str(int(amount)) + ) + self.wait(0.1) + price_control = None + if str(security).startswith("68"): # 科创板存在限价 + try: + price_control = self._main.child_window( + control_id=self._config.TRADE_PRICE_CONTROL_ID, class_name="Edit" + ) + except: + pass + if price_control is not None: + price_control.set_edit_text(limit_price) + + def _get_grid_data(self, control_id): + return self.grid_strategy_instance.get(control_id) + + def _type_keys(self, control_id, text): + self._main.child_window(control_id=control_id, class_name="Edit").set_edit_text( + text + ) + + def _type_edit_control_keys(self, control_id, text): + if not self._editor_need_type_keys: + self._main.child_window( + control_id=control_id, class_name="Edit" + ).set_edit_text(text) + else: + editor = self._main.child_window(control_id=control_id, class_name="Edit") + editor.select() + editor.type_keys(text) + + def type_edit_control_keys(self, editor, text): + if not self._editor_need_type_keys: + editor.set_edit_text(text) + else: + editor.select() + editor.type_keys(text) + + def _collapse_left_menus(self): + items = self._get_left_menus_handle().roots() + for item in items: + item.collapse() + + @perf_clock + def _switch_left_menus(self, path, sleep=0.2): + self.close_pop_dialog() + self._get_left_menus_handle().get_item(path).select() + self._app.top_window().type_keys('{F5}') + self.wait(sleep) + + def _switch_left_menus_by_shortcut(self, shortcut, sleep=0.5): + self.close_pop_dialog() + self._app.top_window().type_keys(shortcut) + self.wait(sleep) + + @functools.lru_cache() + def _get_left_menus_handle(self): + count = 2 + while True: + try: + handle = self._main.child_window( + control_id=129, class_name="SysTreeView32" + ) + if count <= 0: + return handle + # sometime can't find handle ready, must retry + handle.wait("ready", 2) + return handle + # pylint: disable=broad-except + except Exception as ex: + logger.exception("error occurred when trying to get left menus") + count = count - 1 + + def _cancel_entrust_by_double_click(self, row): + x = self._config.CANCEL_ENTRUST_GRID_LEFT_MARGIN + y = ( + self._config.CANCEL_ENTRUST_GRID_FIRST_ROW_HEIGHT + + self._config.CANCEL_ENTRUST_GRID_ROW_HEIGHT * row + ) + self._app.top_window().child_window( + control_id=self._config.COMMON_GRID_CONTROL_ID, + class_name="CVirtualGridCtrl", + ).double_click(coords=(x, y)) + + def refresh(self): + self.refresh_strategy.set_trader(self) + self.refresh_strategy.refresh() + + @perf_clock + def _handle_pop_dialogs(self, handler_class=pop_dialog_handler.PopDialogHandler): + handler = handler_class(self._app) + + while self.is_exist_pop_dialog(): + try: + title = self._get_pop_dialog_title() + except pywinauto.findwindows.ElementNotFoundError: + return {"message": "success"} + + result = handler.handle(title) + if result: + return result + return {"message": "success"} + + +class BaseLoginClientTrader(ClientTrader): + @abc.abstractmethod + def login(self, user, password, exe_path, comm_password=None, **kwargs): + """Login Client Trader""" + pass + + def prepare( + self, + config_path=None, + user=None, + password=None, + exe_path=None, + comm_password=None, + **kwargs + ): + """ + 登陆客户端 + :param config_path: 登陆配置文件,跟参数登陆方式二选一 + :param user: 账号 + :param password: 明文密码 + :param exe_path: 客户端路径类似 r'C:\\htzqzyb2\\xiadan.exe', 默认 r'C:\\htzqzyb2\\xiadan.exe' + :param comm_password: 通讯密码 + :return: + """ + if config_path is not None: + account = file2dict(config_path) + user = account["user"] + password = account["password"] + comm_password = account.get("comm_password") + exe_path = account.get("exe_path") + self.login( + user, + password, + exe_path or self._config.DEFAULT_EXE_PATH, + comm_password, + **kwargs + ) + self._init_toolbar() diff --git a/qbot/engine/trade/easytrader/easytrader/config/__init__.py b/qbot/engine/trade/easytrader/easytrader/config/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/qbot/engine/trade/easytrader/easytrader/config/client.py b/qbot/engine/trade/easytrader/easytrader/config/client.py new file mode 100644 index 00000000..a028ecef --- /dev/null +++ b/qbot/engine/trade/easytrader/easytrader/config/client.py @@ -0,0 +1,193 @@ +# -*- coding: utf-8 -*- +def create(broker): + if broker == "yh": + return YH + if broker == "ht": + return HT + if broker == "gj": + return GJ + if broker == "gf": + return GF + if broker == "ths": + return CommonConfig + if broker == "wk": + return WK + if broker == "htzq": + return HTZQ + if broker == "universal": + return UNIVERSAL + raise NotImplementedError + + +class CommonConfig: + DEFAULT_EXE_PATH: str = "" + TITLE = "网上股票交易系统5.0" + + # 交易所类型。 深圳A股、上海A股 + TRADE_STOCK_EXCHANGE_CONTROL_ID = 1003 + + # 撤销界面上, 全部撤销按钮 + TRADE_CANCEL_ALL_ENTRUST_CONTROL_ID = 30001 + + TRADE_SECURITY_CONTROL_ID = 1032 + TRADE_PRICE_CONTROL_ID = 1033 + TRADE_AMOUNT_CONTROL_ID = 1034 + + TRADE_SUBMIT_CONTROL_ID = 1006 + + TRADE_MARKET_TYPE_CONTROL_ID = 1541 + + COMMON_GRID_CONTROL_ID = 1047 + + COMMON_GRID_LEFT_MARGIN = 10 + COMMON_GRID_FIRST_ROW_HEIGHT = 30 + COMMON_GRID_ROW_HEIGHT = 16 + + BALANCE_MENU_PATH = ["查询[F4]", "资金股票"] + POSITION_MENU_PATH = ["查询[F4]", "资金股票"] + TODAY_ENTRUSTS_MENU_PATH = ["查询[F4]", "当日委托"] + TODAY_TRADES_MENU_PATH = ["查询[F4]", "当日成交"] + + BALANCE_CONTROL_ID_GROUP = { + "资金余额": 1012, + "可用金额": 1016, + "可取金额": 1017, + "股票市值": 1014, + "总资产": 1015, + } + + POP_DIALOD_TITLE_CONTROL_ID = 1365 + + GRID_DTYPE = { + "操作日期": str, + "委托编号": str, + "申请编号": str, + "合同编号": str, + "证券代码": str, + "股东代码": str, + "资金帐号": str, + "资金帐户": str, + "发生日期": str, + } + + CANCEL_ENTRUST_ENTRUST_FIELD = "合同编号" + CANCEL_ENTRUST_GRID_LEFT_MARGIN = 50 + CANCEL_ENTRUST_GRID_FIRST_ROW_HEIGHT = 30 + CANCEL_ENTRUST_GRID_ROW_HEIGHT = 16 + + AUTO_IPO_SELECT_ALL_BUTTON_CONTROL_ID = 1098 + AUTO_IPO_BUTTON_CONTROL_ID = 1006 + AUTO_IPO_MENU_PATH = ["新股申购", "批量新股申购"] + AUTO_IPO_NUMBER = '申购数量' + + +class YH(CommonConfig): + DEFAULT_EXE_PATH = r"C:\双子星-中国银河证券\Binarystar.exe" + + BALANCE_GRID_CONTROL_ID = 1308 + + GRID_DTYPE = { + "操作日期": str, + "委托编号": str, + "申请编号": str, + "合同编号": str, + "证券代码": str, + "股东代码": str, + "资金帐号": str, + "资金帐户": str, + "发生日期": str, + } + + AUTO_IPO_MENU_PATH = ["新股申购", "一键打新"] + + +class HT(CommonConfig): + DEFAULT_EXE_PATH = r"C:\htzqzyb2\xiadan.exe" + + BALANCE_CONTROL_ID_GROUP = { + "资金余额": 1012, + "冻结资金": 1013, + "可用金额": 1016, + "可取金额": 1017, + "股票市值": 1014, + "总资产": 1015, + } + + GRID_DTYPE = { + "操作日期": str, + "委托编号": str, + "申请编号": str, + "合同编号": str, + "证券代码": str, + "股东代码": str, + "资金帐号": str, + "资金帐户": str, + "发生日期": str, + } + + AUTO_IPO_MENU_PATH = ["新股申购", "批量新股申购"] + + +class GJ(CommonConfig): + DEFAULT_EXE_PATH = "C:\\全能行证券交易终端\\xiadan.exe" + + GRID_DTYPE = { + "操作日期": str, + "委托编号": str, + "申请编号": str, + "合同编号": str, + "证券代码": str, + "股东代码": str, + "资金帐号": str, + "资金帐户": str, + "发生日期": str, + } + + AUTO_IPO_MENU_PATH = ["新股申购", "新股批量申购"] + +class GF(CommonConfig): + DEFAULT_EXE_PATH = "C:\\gfzqrzrq\\xiadan.exe" + TITLE = "核新网上交易系统" + + GRID_DTYPE = { + "操作日期": str, + "委托编号": str, + "申请编号": str, + "合同编号": str, + "证券代码": str, + "股东代码": str, + "资金帐号": str, + "资金帐户": str, + "发生日期": str, + } + + AUTO_IPO_MENU_PATH = ["新股申购", "批量新股申购"] + +class WK(HT): + pass + + +class HTZQ(CommonConfig): + DEFAULT_EXE_PATH = r"c:\\海通证券委托\\xiadan.exe" + + BALANCE_CONTROL_ID_GROUP = { + "资金余额": 1012, + "可用金额": 1016, + "可取金额": 1017, + "总资产": 1015, + } + + AUTO_IPO_NUMBER = '可申购数量' + + +class UNIVERSAL(CommonConfig): + DEFAULT_EXE_PATH = r"c:\\ths\\xiadan.exe" + + BALANCE_CONTROL_ID_GROUP = { + "资金余额": 1012, + "可用金额": 1016, + "可取金额": 1017, + "总资产": 1015, + } + + AUTO_IPO_NUMBER = '可申购数量' diff --git a/qbot/engine/trade/easytrader/easytrader/config/global.json b/qbot/engine/trade/easytrader/easytrader/config/global.json new file mode 100644 index 00000000..388c4d96 --- /dev/null +++ b/qbot/engine/trade/easytrader/easytrader/config/global.json @@ -0,0 +1,52 @@ +{ + "response_format": { + "int": [ + "current_amount", + "enable_amount", + "entrust_amount", + "business_amount", + "成交数量", + "撤单数量", + "委托数量", + "股份可用", + "买入冻结", + "卖出冻结", + "当前持仓", + "股份余额" + ], + "float": [ + "current_balance", + "enable_balance", + "fetch_balance", + "market_value", + "asset_balance", + "av_buy_price", + "cost_price", + "income_balance", + "market_value", + "entrust_price", + "business_price", + "business_balance", + "fare1", + "occur_balance", + "farex", + "fare0", + "occur_amount", + "post_balance", + "fare2", + "fare3", + "资金余额", + "可用资金", + "参考市值", + "总资产", + "股份参考盈亏", + "委托价格", + "成交价格", + "成交金额", + "参考盈亏", + "参考成本价", + "参考市价", + "参考市值" + ] + } +} diff --git a/qbot/engine/trade/easytrader/easytrader/config/xueqiu.json b/qbot/engine/trade/easytrader/easytrader/config/xueqiu.json new file mode 100644 index 00000000..f0c53116 --- /dev/null +++ b/qbot/engine/trade/easytrader/easytrader/config/xueqiu.json @@ -0,0 +1,9 @@ +{ + "login_api": "https://xueqiu.com/user/login", + "prefix": "https://xueqiu.com/user/login", + "portfolio_url": "https://xueqiu.com/p/", + "search_stock_url": "https://xueqiu.com/stock/p/search.json", + "rebalance_url": "https://xueqiu.com/cubes/rebalancing/create.json", + "history_url": "https://xueqiu.com/cubes/rebalancing/history.json", + "referer": "https://xueqiu.com/p/update?action=holdings&symbol=%s" +} diff --git a/qbot/engine/trade/easytrader/easytrader/exceptions.py b/qbot/engine/trade/easytrader/easytrader/exceptions.py new file mode 100644 index 00000000..adbaa82a --- /dev/null +++ b/qbot/engine/trade/easytrader/easytrader/exceptions.py @@ -0,0 +1,11 @@ +# -*- coding: utf-8 -*- + + +class TradeError(IOError): + pass + + +class NotLoginError(Exception): + def __init__(self, result=None): + super(NotLoginError, self).__init__() + self.result = result diff --git a/qbot/engine/trade/easytrader/easytrader/follower.py b/qbot/engine/trade/easytrader/easytrader/follower.py new file mode 100644 index 00000000..dd3b7642 --- /dev/null +++ b/qbot/engine/trade/easytrader/easytrader/follower.py @@ -0,0 +1,408 @@ +# -*- coding: utf-8 -*- +import abc +import datetime +import os +import pickle +import queue +import re +import threading +import time +from typing import List + +import requests + +from easytrader import exceptions +from easytrader.log import logger + + +class BaseFollower(metaclass=abc.ABCMeta): + """ + slippage: 滑点,取值范围为 [0, 1] + """ + + LOGIN_PAGE = "" + LOGIN_API = "" + TRANSACTION_API = "" + CMD_CACHE_FILE = "cmd_cache.pk" + WEB_REFERER = "" + WEB_ORIGIN = "" + + def __init__(self): + self.trade_queue = queue.Queue() + self.expired_cmds = set() + + self.s = requests.Session() + self.s.verify = False + + self.slippage: float = 0.0 + + def login(self, user=None, password=None, **kwargs): + """ + 登陆接口 + :param user: 用户名 + :param password: 密码 + :param kwargs: 其他参数 + :return: + """ + headers = self._generate_headers() + self.s.headers.update(headers) + + # init cookie + self.s.get(self.LOGIN_PAGE) + + # post for login + params = self.create_login_params(user, password, **kwargs) + rep = self.s.post(self.LOGIN_API, data=params) + + self.check_login_success(rep) + logger.info("登录成功") + + def _generate_headers(self): + headers = { + "Accept": "application/json, text/javascript, */*; q=0.01", + "Accept-Encoding": "gzip, deflate, br", + "Accept-Language": "en-US,en;q=0.8", + "User-Agent": "Mozilla/5.0 (X11; Linux x86_64) " + "AppleWebKit/537.36 (KHTML, like Gecko) " + "Chrome/54.0.2840.100 Safari/537.36", + "Referer": self.WEB_REFERER, + "X-Requested-With": "XMLHttpRequest", + "Origin": self.WEB_ORIGIN, + "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8", + } + return headers + + def check_login_success(self, rep): + """检查登录状态是否成功 + :param rep: post login 接口返回的 response 对象 + :raise 如果登录失败应该抛出 NotLoginError """ + pass + + def create_login_params(self, user, password, **kwargs) -> dict: + """生成 post 登录接口的参数 + :param user: 用户名 + :param password: 密码 + :return dict 登录参数的字典 + """ + return {} + + def follow( + self, + users, + strategies, + track_interval=1, + trade_cmd_expire_seconds=120, + cmd_cache=True, + slippage: float = 0.0, + **kwargs + ): + """跟踪平台对应的模拟交易,支持多用户多策略 + + :param users: 支持easytrader的用户对象,支持使用 [] 指定多个用户 + :param strategies: 雪球组合名, 类似 ZH123450 + :param total_assets: 雪球组合对应的总资产, 格式 [ 组合1对应资金, 组合2对应资金 ] + 若 strategies=['ZH000001', 'ZH000002'] 设置 total_assets=[10000, 10000], 则表明每个组合对应的资产为 1w 元, + 假设组合 ZH000001 加仓 价格为 p 股票 A 10%, 则对应的交易指令为 买入 股票 A 价格 P 股数 1w * 10% / p 并按 100 取整 + :param initial_assets:雪球组合对应的初始资产, 格式 [ 组合1对应资金, 组合2对应资金 ] + 总资产由 初始资产 × 组合净值 算得, total_assets 会覆盖此参数 + :param track_interval: 轮询模拟交易时间,单位为秒 + :param trade_cmd_expire_seconds: 交易指令过期时间, 单位为秒 + :param cmd_cache: 是否读取存储历史执行过的指令,防止重启时重复执行已经交易过的指令 + :param slippage: 滑点,0.0 表示无滑点, 0.05 表示滑点为 5% + """ + self.slippage = slippage + + def _calculate_price_by_slippage(self, action: str, price: float) -> float: + """ + 计算考虑滑点之后的价格 + :param action: 交易动作, 支持 ['buy', 'sell'] + :param price: 原始交易价格 + :return: 考虑滑点后的交易价格 + """ + if action == "buy": + return price * (1 + self.slippage) + if action == "sell": + return price * (1 - self.slippage) + return price + + def load_expired_cmd_cache(self): + if os.path.exists(self.CMD_CACHE_FILE): + with open(self.CMD_CACHE_FILE, "rb") as f: + self.expired_cmds = pickle.load(f) + + def start_trader_thread( + self, + users, + trade_cmd_expire_seconds, + entrust_prop="limit", + send_interval=0, + ): + trader = threading.Thread( + target=self.trade_worker, + args=[users], + kwargs={ + "expire_seconds": trade_cmd_expire_seconds, + "entrust_prop": entrust_prop, + "send_interval": send_interval, + }, + ) + trader.setDaemon(True) + trader.start() + + @staticmethod + def warp_list(value): + if not isinstance(value, list): + value = [value] + return value + + @staticmethod + def extract_strategy_id(strategy_url): + """ + 抽取 策略 id,一般用于获取策略相关信息 + :param strategy_url: 策略 url + :return: str 策略 id + """ + pass + + def extract_strategy_name(self, strategy_url): + """ + 抽取 策略名,主要用于日志打印,便于识别 + :param strategy_url: + :return: str 策略名 + """ + pass + + def track_strategy_worker(self, strategy, name, interval=10, **kwargs): + """跟踪下单worker + :param strategy: 策略id + :param name: 策略名字 + :param interval: 轮询策略的时间间隔,单位为秒""" + while True: + try: + transactions = self.query_strategy_transaction( + strategy, **kwargs + ) + # pylint: disable=broad-except + except Exception as e: + logger.exception("无法获取策略 %s 调仓信息, 错误: %s, 跳过此次调仓查询", name, e) + time.sleep(3) + continue + for transaction in transactions: + trade_cmd = { + "strategy": strategy, + "strategy_name": name, + "action": transaction["action"], + "stock_code": transaction["stock_code"], + "amount": transaction["amount"], + "price": transaction["price"], + "datetime": transaction["datetime"], + } + if self.is_cmd_expired(trade_cmd): + continue + logger.info( + "策略 [%s] 发送指令到交易队列, 股票: %s 动作: %s 数量: %s 价格: %s 信号产生时间: %s", + name, + trade_cmd["stock_code"], + trade_cmd["action"], + trade_cmd["amount"], + trade_cmd["price"], + trade_cmd["datetime"], + ) + self.trade_queue.put(trade_cmd) + self.add_cmd_to_expired_cmds(trade_cmd) + try: + for _ in range(interval): + time.sleep(1) + except KeyboardInterrupt: + logger.info("程序退出") + break + + @staticmethod + def generate_expired_cmd_key(cmd): + return "{}_{}_{}_{}_{}_{}".format( + cmd["strategy_name"], + cmd["stock_code"], + cmd["action"], + cmd["amount"], + cmd["price"], + cmd["datetime"], + ) + + def is_cmd_expired(self, cmd): + key = self.generate_expired_cmd_key(cmd) + return key in self.expired_cmds + + def add_cmd_to_expired_cmds(self, cmd): + key = self.generate_expired_cmd_key(cmd) + self.expired_cmds.add(key) + + with open(self.CMD_CACHE_FILE, "wb") as f: + pickle.dump(self.expired_cmds, f) + + @staticmethod + def _is_number(s): + try: + float(s) + return True + except ValueError: + return False + + def _execute_trade_cmd( + self, trade_cmd, users, expire_seconds, entrust_prop, send_interval + ): + """分发交易指令到对应的 user 并执行 + :param trade_cmd: + :param users: + :param expire_seconds: + :param entrust_prop: + :param send_interval: + :return: + """ + for user in users: + # check expire + now = datetime.datetime.now() + expire = (now - trade_cmd["datetime"]).total_seconds() + if expire > expire_seconds: + logger.warning( + "策略 [%s] 指令(股票: %s 动作: %s 数量: %s 价格: %s)超时,指令产生时间: %s 当前时间: %s, 超过设置的最大过期时间 %s 秒, 被丢弃", + trade_cmd["strategy_name"], + trade_cmd["stock_code"], + trade_cmd["action"], + trade_cmd["amount"], + trade_cmd["price"], + trade_cmd["datetime"], + now, + expire_seconds, + ) + break + + # check price + price = trade_cmd["price"] + if not self._is_number(price) or price <= 0: + logger.warning( + "策略 [%s] 指令(股票: %s 动作: %s 数量: %s 价格: %s)超时,指令产生时间: %s 当前时间: %s, 价格无效 , 被丢弃", + trade_cmd["strategy_name"], + trade_cmd["stock_code"], + trade_cmd["action"], + trade_cmd["amount"], + trade_cmd["price"], + trade_cmd["datetime"], + now, + ) + break + + # check amount + if trade_cmd["amount"] <= 0: + logger.warning( + "策略 [%s] 指令(股票: %s 动作: %s 数量: %s 价格: %s)超时,指令产生时间: %s 当前时间: %s, 买入股数无效 , 被丢弃", + trade_cmd["strategy_name"], + trade_cmd["stock_code"], + trade_cmd["action"], + trade_cmd["amount"], + trade_cmd["price"], + trade_cmd["datetime"], + now, + ) + break + + actual_price = self._calculate_price_by_slippage( + trade_cmd["action"], trade_cmd["price"] + ) + args = { + "security": trade_cmd["stock_code"], + "price": actual_price, + "amount": trade_cmd["amount"], + "entrust_prop": entrust_prop, + } + try: + response = getattr(user, trade_cmd["action"])(**args) + except exceptions.TradeError as e: + trader_name = type(user).__name__ + err_msg = "{}: {}".format(type(e).__name__, e.args) + logger.error( + "%s 执行 策略 [%s] 指令(股票: %s 动作: %s 数量: %s 价格(考虑滑点): %s 指令产生时间: %s) 失败, 错误信息: %s", + trader_name, + trade_cmd["strategy_name"], + trade_cmd["stock_code"], + trade_cmd["action"], + trade_cmd["amount"], + actual_price, + trade_cmd["datetime"], + err_msg, + ) + else: + logger.info( + "策略 [%s] 指令(股票: %s 动作: %s 数量: %s 价格(考虑滑点): %s 指令产生时间: %s) 执行成功, 返回: %s", + trade_cmd["strategy_name"], + trade_cmd["stock_code"], + trade_cmd["action"], + trade_cmd["amount"], + actual_price, + trade_cmd["datetime"], + response, + ) + + def trade_worker( + self, users, expire_seconds=120, entrust_prop="limit", send_interval=0 + ): + """ + :param send_interval: 交易发送间隔, 默认为0s。调大可防止卖出买入时买出单没有及时成交导致的买入金额不足 + """ + while True: + trade_cmd = self.trade_queue.get() + self._execute_trade_cmd( + trade_cmd, users, expire_seconds, entrust_prop, send_interval + ) + time.sleep(send_interval) + + def query_strategy_transaction(self, strategy, **kwargs): + params = self.create_query_transaction_params(strategy) + + rep = self.s.get(self.TRANSACTION_API, params=params) + history = rep.json() + + transactions = self.extract_transactions(history) + self.project_transactions(transactions, **kwargs) + return self.order_transactions_sell_first(transactions) + + def extract_transactions(self, history) -> List[str]: + """ + 抽取接口返回中的调仓记录列表 + :param history: 调仓接口返回信息的字典对象 + :return: [] 调参历史记录的列表 + """ + return [] + + def create_query_transaction_params(self, strategy) -> dict: + """ + 生成用于查询调参记录的参数 + :param strategy: 策略 id + :return: dict 调参记录参数 + """ + return {} + + @staticmethod + def re_find(pattern, string, dtype=str): + return dtype(re.search(pattern, string).group()) + + @staticmethod + def re_search(pattern, string, dtype=str): + return dtype(re.search(pattern,string).group(1)) + + def project_transactions(self, transactions, **kwargs): + """ + 修证调仓记录为内部使用的统一格式 + :param transactions: [] 调仓记录的列表 + :return: [] 修整后的调仓记录 + """ + pass + + def order_transactions_sell_first(self, transactions): + # 调整调仓记录的顺序为先卖再买 + sell_first_transactions = [] + for transaction in transactions: + if transaction["action"] == "sell": + sell_first_transactions.insert(0, transaction) + else: + sell_first_transactions.append(transaction) + return sell_first_transactions diff --git a/qbot/engine/trade/easytrader/easytrader/gf_clienttrader.py b/qbot/engine/trade/easytrader/easytrader/gf_clienttrader.py new file mode 100644 index 00000000..ab5e6e8d --- /dev/null +++ b/qbot/engine/trade/easytrader/easytrader/gf_clienttrader.py @@ -0,0 +1,84 @@ +# -*- coding: utf-8 -*- +import re +import tempfile +import time +import os + +import pywinauto +import pywinauto.clipboard + +from easytrader import clienttrader +from easytrader.utils.captcha import recognize_verify_code + + +class GFClientTrader(clienttrader.BaseLoginClientTrader): + @property + def broker_type(self): + return "gf" + + def login(self, user, password, exe_path, comm_password=None, **kwargs): + """ + 登陆客户端 + + :param user: 账号 + :param password: 明文密码 + :param exe_path: 客户端路径类似 'C:\\中国银河证券双子星3.2\\Binarystar.exe', + 默认 'C:\\中国银河证券双子星3.2\\Binarystar.exe' + :param comm_password: 通讯密码, 华泰需要,可不设 + :return: + """ + try: + self._app = pywinauto.Application().connect( + path=self._run_exe_path(exe_path), timeout=1 + ) + # pylint: disable=broad-except + except Exception: + self._app = pywinauto.Application().start(exe_path) + + # wait login window ready + while True: + try: + self._app.top_window().Edit1.wait("ready") + break + except RuntimeError: + pass + + self.type_edit_control_keys(self._app.top_window().Edit1, user) + self.type_edit_control_keys(self._app.top_window().Edit2, password) + edit3 = self._app.top_window().window(control_id=0x3eb) + while True: + try: + code = self._handle_verify_code() + self.type_edit_control_keys(edit3, code) + time.sleep(1) + self._app.top_window()["登录(Y)"].click() + # detect login is success or not + try: + self._app.top_window().wait_not("exists", 5) + break + + # pylint: disable=broad-except + except Exception: + self._app.top_window()["确定"].click() + + # pylint: disable=broad-except + except Exception: + pass + + self._app = pywinauto.Application().connect( + path=self._run_exe_path(exe_path), timeout=10 + ) + self._main = self._app.window(title_re="""{title}.*""".format(title=self._config.TITLE)) + self.close_pop_dialog() + + def _handle_verify_code(self): + control = self._app.top_window().window(control_id=0x5db) + control.click() + time.sleep(0.2) + file_path = tempfile.mktemp() + ".jpg" + control.capture_as_image().save(file_path) + time.sleep(0.2) + vcode = recognize_verify_code(file_path, "gf_client") + if os.path.exists(file_path): + os.remove(file_path) + return "".join(re.findall("[a-zA-Z0-9]+", vcode)) diff --git a/qbot/engine/trade/easytrader/easytrader/gj_clienttrader.py b/qbot/engine/trade/easytrader/easytrader/gj_clienttrader.py new file mode 100644 index 00000000..00d865d9 --- /dev/null +++ b/qbot/engine/trade/easytrader/easytrader/gj_clienttrader.py @@ -0,0 +1,80 @@ +# -*- coding: utf-8 -*- +import re +import tempfile +import time + +import pywinauto +import pywinauto.clipboard + +from easytrader import clienttrader +from easytrader.utils.captcha import recognize_verify_code + + +class GJClientTrader(clienttrader.BaseLoginClientTrader): + @property + def broker_type(self): + return "gj" + + def login(self, user, password, exe_path, comm_password=None, **kwargs): + """ + 登陆客户端 + + :param user: 账号 + :param password: 明文密码 + :param exe_path: 客户端路径类似 'C:\\中国银河证券双子星3.2\\Binarystar.exe', + 默认 'C:\\中国银河证券双子星3.2\\Binarystar.exe' + :param comm_password: 通讯密码, 华泰需要,可不设 + :return: + """ + try: + self._app = pywinauto.Application().connect( + path=self._run_exe_path(exe_path), timeout=1 + ) + # pylint: disable=broad-except + except Exception: + self._app = pywinauto.Application().start(exe_path) + + # wait login window ready + while True: + try: + self._app.top_window().Edit1.wait("ready") + break + except RuntimeError: + pass + + self._app.top_window().Edit1.type_keys(user) + self._app.top_window().Edit2.type_keys(password) + edit3 = self._app.top_window().window(control_id=0x3eb) + while True: + try: + code = self._handle_verify_code() + edit3.type_keys(code) + time.sleep(1) + self._app.top_window()["确定(Y)"].click() + # detect login is success or not + try: + self._app.top_window().wait_not("exists", 5) + break + + # pylint: disable=broad-except + except Exception: + self._app.top_window()["确定"].click() + + # pylint: disable=broad-except + except Exception: + pass + + self._app = pywinauto.Application().connect( + path=self._run_exe_path(exe_path), timeout=10 + ) + self._main = self._app.window(title="网上股票交易系统5.0") + + def _handle_verify_code(self): + control = self._app.top_window().window(control_id=0x5db) + control.click() + time.sleep(0.2) + file_path = tempfile.mktemp() + ".jpg" + control.capture_as_image().save(file_path) + time.sleep(0.2) + vcode = recognize_verify_code(file_path, "gj_client") + return "".join(re.findall("[a-zA-Z0-9]+", vcode)) diff --git a/qbot/engine/trade/easytrader/easytrader/grid_strategies.py b/qbot/engine/trade/easytrader/easytrader/grid_strategies.py new file mode 100644 index 00000000..b294b967 --- /dev/null +++ b/qbot/engine/trade/easytrader/easytrader/grid_strategies.py @@ -0,0 +1,216 @@ +# -*- coding: utf-8 -*- +import abc +import io +import tempfile +from io import StringIO +from typing import TYPE_CHECKING, Dict, List, Optional + +import pandas as pd +import pywinauto.keyboard +import pywinauto +import pywinauto.clipboard + +from easytrader.log import logger +from easytrader.utils.captcha import captcha_recognize +from easytrader.utils.win_gui import SetForegroundWindow, ShowWindow, win32defines + +if TYPE_CHECKING: + # pylint: disable=unused-import + from easytrader import clienttrader + + +class IGridStrategy(abc.ABC): + @abc.abstractmethod + def get(self, control_id: int) -> List[Dict]: + """ + 获取 gird 数据并格式化返回 + + :param control_id: grid 的 control id + :return: grid 数据 + """ + pass + + @abc.abstractmethod + def set_trader(self, trader: "clienttrader.IClientTrader"): + pass + + +class BaseStrategy(IGridStrategy): + def __init__(self): + self._trader = None + + def set_trader(self, trader: "clienttrader.IClientTrader"): + self._trader = trader + + @abc.abstractmethod + def get(self, control_id: int) -> List[Dict]: + """ + :param control_id: grid 的 control id + :return: grid 数据 + """ + pass + + def _get_grid(self, control_id: int): + grid = self._trader.main.child_window( + control_id=control_id, class_name="CVirtualGridCtrl" + ) + return grid + + def _set_foreground(self, grid=None): + try: + if grid is None: + grid = self._trader.main + if grid.has_style(win32defines.WS_MINIMIZE): # if minimized + ShowWindow(grid.wrapper_object(), 9) # restore window state + else: + SetForegroundWindow(grid.wrapper_object()) # bring to front + except: + pass + + +class Copy(BaseStrategy): + """ + 通过复制 grid 内容到剪切板再读取来获取 grid 内容 + """ + + _need_captcha_reg = True + + def get(self, control_id: int) -> List[Dict]: + grid = self._get_grid(control_id) + self._set_foreground(grid) + grid.type_keys("^A^C", set_foreground=False) + content = self._get_clipboard_data() + return self._format_grid_data(content) + + def _format_grid_data(self, data: str) -> List[Dict]: + try: + df = pd.read_csv( + io.StringIO(data), + delimiter="\t", + dtype=self._trader.config.GRID_DTYPE, + na_filter=False, + ) + return df.to_dict("records") + except: + Copy._need_captcha_reg = True + + def _get_clipboard_data(self) -> str: + if Copy._need_captcha_reg: + if ( + self._trader.app.top_window().window(class_name="Static", title_re="验证码").exists(timeout=1) + ): + file_path = "tmp.png" + count = 5 + found = False + while count > 0: + self._trader.app.top_window().window( + control_id=0x965, class_name="Static" + ).capture_as_image().save( + file_path + ) # 保存验证码 + + captcha_num = captcha_recognize(file_path).strip() # 识别验证码 + captcha_num = "".join(captcha_num.split()) + logger.info("captcha result-->" + captcha_num) + if len(captcha_num) == 4: + self._trader.app.top_window().window( + control_id=0x964, class_name="Edit" + ).set_text( + captcha_num + ) # 模拟输入验证码 + + self._trader.app.top_window().set_focus() + pywinauto.keyboard.SendKeys("{ENTER}") # 模拟发送enter,点击确定 + try: + logger.info( + self._trader.app.top_window() + .window(control_id=0x966, class_name="Static") + .window_text() + ) + except Exception as ex: # 窗体消失 + logger.exception(ex) + found = True + break + count -= 1 + self._trader.wait(0.1) + self._trader.app.top_window().window( + control_id=0x965, class_name="Static" + ).click() + if not found: + self._trader.app.top_window().Button2.click() # 点击取消 + else: + Copy._need_captcha_reg = False + count = 5 + while count > 0: + try: + return pywinauto.clipboard.GetData() + # pylint: disable=broad-except + except Exception as e: + count -= 1 + logger.exception("%s, retry ......", e) + + +class WMCopy(Copy): + """ + 通过复制 grid 内容到剪切板再读取来获取 grid 内容 + """ + + def get(self, control_id: int) -> List[Dict]: + grid = self._get_grid(control_id) + grid.post_message(win32defines.WM_COMMAND, 0xE122, 0) + self._trader.wait(0.1) + content = self._get_clipboard_data() + return self._format_grid_data(content) + + +class Xls(BaseStrategy): + """ + 通过将 Grid 另存为 xls 文件再读取的方式获取 grid 内容 + """ + + def __init__(self, tmp_folder: Optional[str] = None): + """ + :param tmp_folder: 用于保持临时文件的文件夹 + """ + super().__init__() + self.tmp_folder = tmp_folder + + def get(self, control_id: int) -> List[Dict]: + grid = self._get_grid(control_id) + + # ctrl+s 保存 grid 内容为 xls 文件 + self._set_foreground(grid) # setFocus buggy, instead of SetForegroundWindow + grid.type_keys("^s", set_foreground=False) + count = 10 + while count > 0: + if self._trader.is_exist_pop_dialog(): + break + self._trader.wait(0.2) + count -= 1 + + temp_path = tempfile.mktemp(suffix=".xls", dir=self.tmp_folder) + self._set_foreground(self._trader.app.top_window()) + + # alt+s保存,alt+y替换已存在的文件 + self._trader.app.top_window().Edit1.set_edit_text(temp_path) + self._trader.wait(0.1) + self._trader.app.top_window().type_keys("%{s}%{y}", set_foreground=False) + # Wait until file save complete otherwise pandas can not find file + self._trader.wait(0.2) + if self._trader.is_exist_pop_dialog(): + self._trader.app.top_window().Button2.click() + self._trader.wait(0.2) + + return self._format_grid_data(temp_path) + + def _format_grid_data(self, data: str) -> List[Dict]: + with open(data, encoding="gbk", errors="replace") as f: + content = f.read() + + df = pd.read_csv( + StringIO(content), + delimiter="\t", + dtype=self._trader.config.GRID_DTYPE, + na_filter=False, + ) + return df.to_dict("records") diff --git a/qbot/engine/trade/easytrader/easytrader/ht_clienttrader.py b/qbot/engine/trade/easytrader/easytrader/ht_clienttrader.py new file mode 100644 index 00000000..b1b0e869 --- /dev/null +++ b/qbot/engine/trade/easytrader/easytrader/ht_clienttrader.py @@ -0,0 +1,76 @@ +# -*- coding: utf-8 -*- + +import pywinauto +import pywinauto.clipboard + +from easytrader import grid_strategies +from . import clienttrader + + +class HTClientTrader(clienttrader.BaseLoginClientTrader): + grid_strategy = grid_strategies.Xls + + @property + def broker_type(self): + return "ht" + + def login(self, user, password, exe_path, comm_password=None, **kwargs): + """ + :param user: 用户名 + :param password: 密码 + :param exe_path: 客户端路径, 类似 + :param comm_password: + :param kwargs: + :return: + """ + self._editor_need_type_keys = False + if comm_password is None: + raise ValueError("华泰必须设置通讯密码") + + try: + self._app = pywinauto.Application().connect( + path=self._run_exe_path(exe_path), timeout=1 + ) + # pylint: disable=broad-except + except Exception: + self._app = pywinauto.Application().start(exe_path) + + # wait login window ready + while True: + try: + self._app.top_window().Edit1.wait("ready") + break + except RuntimeError: + pass + self._app.top_window().Edit1.set_focus() + self._app.top_window().Edit1.type_keys(user) + self._app.top_window().Edit2.type_keys(password) + + self._app.top_window().Edit3.set_edit_text(comm_password) + + self._app.top_window().button0.click() + + self._app = pywinauto.Application().connect( + path=self._run_exe_path(exe_path), timeout=10 + ) + self._main = self._app.window(title="网上股票交易系统5.0") + self._main.wait ( "exists enabled visible ready" , timeout=100 ) + self._close_prompt_windows ( ) + + @property + def balance(self): + self._switch_left_menus(self._config.BALANCE_MENU_PATH) + + return self._get_balance_from_statics() + + def _get_balance_from_statics(self): + result = {} + for key, control_id in self._config.BALANCE_CONTROL_ID_GROUP.items(): + result[key] = float( + self._main.child_window( + control_id=control_id, class_name="Static" + ).window_text() + ) + return result + + diff --git a/qbot/engine/trade/easytrader/easytrader/htzq_clienttrader.py b/qbot/engine/trade/easytrader/easytrader/htzq_clienttrader.py new file mode 100644 index 00000000..4ffa4538 --- /dev/null +++ b/qbot/engine/trade/easytrader/easytrader/htzq_clienttrader.py @@ -0,0 +1,61 @@ +# -*- coding: utf-8 -*- + +import pywinauto +import pywinauto.clipboard + +from easytrader import grid_strategies +from . import clienttrader + + +class HTZQClientTrader(clienttrader.BaseLoginClientTrader): + grid_strategy = grid_strategies.Xls + + @property + def broker_type(self): + return "htzq" + + def login(self, user, password, exe_path, comm_password=None, **kwargs): + """ + :param user: 用户名 + :param password: 密码 + :param exe_path: 客户端路径, 类似 + :param comm_password: + :param kwargs: + :return: + """ + self._editor_need_type_keys = False + if comm_password is None: + raise ValueError("必须设置通讯密码") + + try: + self._app = pywinauto.Application().connect( + path=self._run_exe_path(exe_path), timeout=1 + ) + # pylint: disable=broad-except + except Exception: + self._app = pywinauto.Application().start(exe_path) + + # wait login window ready + while True: + try: + self._app.top_window().Edit1.wait("ready") + break + except RuntimeError: + pass + self._app.top_window().Edit1.set_focus() + self._app.top_window().Edit1.type_keys(user) + self._app.top_window().Edit2.type_keys(password) + + self._app.top_window().Edit3.type_keys(comm_password) + + self._app.top_window().button0.click() + + # detect login is success or not + self._app.top_window().wait_not("exists", 100) + + self._app = pywinauto.Application().connect( + path=self._run_exe_path(exe_path), timeout=10 + ) + self._close_prompt_windows() + self._main = self._app.window(title="网上股票交易系统5.0") + diff --git a/qbot/engine/trade/easytrader/easytrader/joinquant_follower.py b/qbot/engine/trade/easytrader/easytrader/joinquant_follower.py new file mode 100644 index 00000000..d1d55b58 --- /dev/null +++ b/qbot/engine/trade/easytrader/easytrader/joinquant_follower.py @@ -0,0 +1,137 @@ +# -*- coding: utf-8 -*- +from datetime import datetime +from threading import Thread + +from easytrader import exceptions +from easytrader.follower import BaseFollower +from easytrader.log import logger + + +class JoinQuantFollower(BaseFollower): + LOGIN_PAGE = "https://www.joinquant.com" + LOGIN_API = "https://www.joinquant.com/user/login/doLogin?ajax=1" + TRANSACTION_API = ( + "https://www.joinquant.com/algorithm/live/transactionDetail" + ) + WEB_REFERER = "https://www.joinquant.com/user/login/index" + WEB_ORIGIN = "https://www.joinquant.com" + + def create_login_params(self, user, password, **kwargs): + params = { + "CyLoginForm[username]": user, + "CyLoginForm[pwd]": password, + "ajax": 1, + } + return params + + def check_login_success(self, rep): + set_cookie = rep.headers["set-cookie"] + if len(set_cookie) < 50: + raise exceptions.NotLoginError("登录失败,请检查用户名和密码") + self.s.headers.update({"cookie": set_cookie}) + + def follow( + self, + users, + strategies, + track_interval=1, + trade_cmd_expire_seconds=120, + cmd_cache=True, + entrust_prop="limit", + send_interval=0, + ): + """跟踪joinquant对应的模拟交易,支持多用户多策略 + :param users: 支持easytrader的用户对象,支持使用 [] 指定多个用户 + :param strategies: joinquant 的模拟交易地址,支持使用 [] 指定多个模拟交易, + 地址类似 https://www.joinquant.com/algorithm/live/index?backtestId=xxx + :param track_interval: 轮训模拟交易时间,单位为秒 + :param trade_cmd_expire_seconds: 交易指令过期时间, 单位为秒 + :param cmd_cache: 是否读取存储历史执行过的指令,防止重启时重复执行已经交易过的指令 + :param entrust_prop: 委托方式, 'limit' 为限价,'market' 为市价, 仅在银河实现 + :param send_interval: 交易发送间隔, 默认为0s。调大可防止卖出买入时卖出单没有及时成交导致的买入金额不足 + """ + users = self.warp_list(users) + strategies = self.warp_list(strategies) + + if cmd_cache: + self.load_expired_cmd_cache() + + self.start_trader_thread( + users, trade_cmd_expire_seconds, entrust_prop, send_interval + ) + + workers = [] + for strategy_url in strategies: + try: + strategy_id = self.extract_strategy_id(strategy_url) + strategy_name = self.extract_strategy_name(strategy_url) + except: + logger.error("抽取交易id和策略名失败, 无效的模拟交易url: %s", strategy_url) + raise + strategy_worker = Thread( + target=self.track_strategy_worker, + args=[strategy_id, strategy_name], + kwargs={"interval": track_interval}, + ) + strategy_worker.start() + workers.append(strategy_worker) + logger.info("开始跟踪策略: %s", strategy_name) + for worker in workers: + worker.join() + + # @staticmethod + # def extract_strategy_id(strategy_url): + # return re.search(r"(?<=backtestId=)\w+", strategy_url).group() + # + # def extract_strategy_name(self, strategy_url): + # rep = self.s.get(strategy_url) + # return self.re_find( + # r'(?<=title="点击修改策略名称"\>).*(?=\', rep.content.decode("utf8")) + + def extract_strategy_name(self, strategy_url): + rep = self.s.get(strategy_url) + return self.re_search(r'class="backtest_name".+?>(.*?)', rep.content.decode("utf8")) + + def create_query_transaction_params(self, strategy): + today_str = datetime.today().strftime("%Y-%m-%d") + params = {"backtestId": strategy, "date": today_str, "ajax": 1} + return params + + def extract_transactions(self, history): + transactions = history["data"]["transaction"] + return transactions + + @staticmethod + def stock_shuffle_to_prefix(stock): + assert ( + len(stock) == 11 + ), "stock {} must like 123456.XSHG or 123456.XSHE".format(stock) + code = stock[:6] + if stock.find("XSHG") != -1: + return "sh" + code + + if stock.find("XSHE") != -1: + return "sz" + code + raise TypeError("not valid stock code: {}".format(code)) + + def project_transactions(self, transactions, **kwargs): + for transaction in transactions: + transaction["amount"] = self.re_find( + r"\d+", transaction["amount"], dtype=int + ) + + time_str = "{} {}".format(transaction["date"], transaction["time"]) + transaction["datetime"] = datetime.strptime( + time_str, "%Y-%m-%d %H:%M:%S" + ) + + stock = self.re_find(r"\d{6}\.\w{4}", transaction["stock"]) + transaction["stock_code"] = self.stock_shuffle_to_prefix(stock) + + transaction["action"] = ( + "buy" if transaction["transaction"] == "买" else "sell" + ) diff --git a/qbot/engine/trade/easytrader/easytrader/log.py b/qbot/engine/trade/easytrader/easytrader/log.py new file mode 100644 index 00000000..27f8dc8b --- /dev/null +++ b/qbot/engine/trade/easytrader/easytrader/log.py @@ -0,0 +1,14 @@ +# -*- coding: utf-8 -*- +import logging + +logger = logging.getLogger("easytrader") +logger.setLevel(logging.INFO) +logger.propagate = False + +fmt = logging.Formatter( + "%(asctime)s [%(levelname)s] %(filename)s %(lineno)s: %(message)s" +) +ch = logging.StreamHandler() + +ch.setFormatter(fmt) +logger.handlers.append(ch) diff --git a/qbot/engine/trade/easytrader/easytrader/pop_dialog_handler.py b/qbot/engine/trade/easytrader/easytrader/pop_dialog_handler.py new file mode 100644 index 00000000..bc4ad3fd --- /dev/null +++ b/qbot/engine/trade/easytrader/easytrader/pop_dialog_handler.py @@ -0,0 +1,98 @@ +# coding:utf-8 +import re +import time +from typing import Optional + +from easytrader import exceptions +from easytrader.utils.perf import perf_clock +from easytrader.utils.win_gui import SetForegroundWindow, ShowWindow, win32defines + + +class PopDialogHandler: + def __init__(self, app): + self._app = app + + @staticmethod + def _set_foreground(window): + if window.has_style(win32defines.WS_MINIMIZE): # if minimized + ShowWindow(window.wrapper_object(), 9) # restore window state + else: + SetForegroundWindow(window.wrapper_object()) # bring to front + + @perf_clock + def handle(self, title): + if any(s in title for s in {"提示信息", "委托确认", "网上交易用户协议", "撤单确认"}): + self._submit_by_shortcut() + return None + + if "提示" in title: + content = self._extract_content() + self._submit_by_click() + return {"message": content} + + content = self._extract_content() + self._close() + return {"message": "unknown message: {}".format(content)} + + def _extract_content(self): + return self._app.top_window().Static.window_text() + + @staticmethod + def _extract_entrust_id(content): + return re.search(r"[\da-zA-Z]+", content).group() + + def _submit_by_click(self): + try: + self._app.top_window()["确定"].click() + except Exception as ex: + self._app.Window_(best_match="Dialog", top_level_only=True).ChildWindow( + best_match="确定" + ).click() + + def _submit_by_shortcut(self): + self._set_foreground(self._app.top_window()) + self._app.top_window().type_keys("%Y", set_foreground=False) + + def _close(self): + self._app.top_window().close() + + +class TradePopDialogHandler(PopDialogHandler): + @perf_clock + def handle(self, title) -> Optional[dict]: + if title == "委托确认": + self._submit_by_shortcut() + return None + + if title == "提示信息": + content = self._extract_content() + if "超出涨跌停" in content: + self._submit_by_shortcut() + return None + + if "委托价格的小数价格应为" in content: + self._submit_by_shortcut() + return None + + if "逆回购" in content: + self._submit_by_shortcut() + return None + + if "正回购" in content: + self._submit_by_shortcut() + return None + + return None + + if title == "提示": + content = self._extract_content() + if "成功" in content: + entrust_no = self._extract_entrust_id(content) + self._submit_by_click() + return {"entrust_no": entrust_no} + + self._submit_by_click() + time.sleep(0.05) + raise exceptions.TradeError(content) + self._close() + return None diff --git a/qbot/engine/trade/easytrader/easytrader/refresh_strategies.py b/qbot/engine/trade/easytrader/easytrader/refresh_strategies.py new file mode 100644 index 00000000..e638c359 --- /dev/null +++ b/qbot/engine/trade/easytrader/easytrader/refresh_strategies.py @@ -0,0 +1,59 @@ +# -*- coding: utf-8 -*- +import abc +import io +import tempfile +from io import StringIO +from typing import TYPE_CHECKING, Dict, List, Optional + +import pandas as pd +import pywinauto.keyboard +import pywinauto +import pywinauto.clipboard + +from easytrader.log import logger +from easytrader.utils.captcha import captcha_recognize +from easytrader.utils.win_gui import SetForegroundWindow, ShowWindow, win32defines + +if TYPE_CHECKING: + # pylint: disable=unused-import + from easytrader import clienttrader + + +class IRefreshStrategy(abc.ABC): + _trader: "clienttrader.ClientTrader" + + @abc.abstractmethod + def refresh(self): + """ + 刷新数据 + """ + pass + + def set_trader(self, trader: "clienttrader.ClientTrader"): + self._trader = trader + + +# noinspection PyProtectedMember +class Switch(IRefreshStrategy): + """通过切换菜单栏刷新""" + + def __init__(self, sleep: float = 0.1): + self.sleep = sleep + + def refresh(self): + self._trader._switch_left_menus_by_shortcut("{F5}", sleep=self.sleep) + + +# noinspection PyProtectedMember +class Toolbar(IRefreshStrategy): + """通过点击工具栏刷新按钮刷新""" + + def __init__(self, refresh_btn_index: int = 4): + """ + :param refresh_btn_index: + 交易客户端工具栏中“刷新”排序,默认为第4个,请根据自己实际调整 + """ + self.refresh_btn_index = refresh_btn_index + + def refresh(self): + self._trader._toolbar.button(self.refresh_btn_index - 1).click() diff --git a/qbot/engine/trade/easytrader/easytrader/remoteclient.py b/qbot/engine/trade/easytrader/easytrader/remoteclient.py new file mode 100644 index 00000000..626ab319 --- /dev/null +++ b/qbot/engine/trade/easytrader/easytrader/remoteclient.py @@ -0,0 +1,107 @@ +# -*- coding: utf-8 -*- +import requests +from easytrader.utils.misc import file2dict + + +def use(broker, host, port=1430, **kwargs): + return RemoteClient(broker, host, port) + + +class RemoteClient: + def __init__(self, broker, host, port=1430, **kwargs): + self._s = requests.session() + self._api = "http://{}:{}".format(host, port) + self._broker = broker + + def prepare( + self, + config_path=None, + user=None, + password=None, + exe_path=None, + comm_password=None, + **kwargs + ): + """ + 登陆客户端 + :param config_path: 登陆配置文件,跟参数登陆方式二选一 + :param user: 账号 + :param password: 明文密码 + :param exe_path: 客户端路径类似 r'C:\\htzqzyb2\\xiadan.exe', + 默认 r'C:\\htzqzyb2\\xiadan.exe' + :param comm_password: 通讯密码 + :return: + """ + params = locals().copy() + params.pop("self") + + if config_path is not None: + account = file2dict(config_path) + params["user"] = account["user"] + params["password"] = account["password"] + + params["broker"] = self._broker + + response = self._s.post(self._api + "/prepare", json=params) + if response.status_code >= 300: + raise Exception(response.json()["error"]) + return response.json() + + @property + def balance(self): + return self.common_get("balance") + + @property + def position(self): + return self.common_get("position") + + @property + def today_entrusts(self): + return self.common_get("today_entrusts") + + @property + def today_trades(self): + return self.common_get("today_trades") + + @property + def cancel_entrusts(self): + return self.common_get("cancel_entrusts") + + def auto_ipo(self): + return self.common_get("auto_ipo") + + def exit(self): + return self.common_get("exit") + + def common_get(self, endpoint): + response = self._s.get(self._api + "/" + endpoint) + if response.status_code >= 300: + raise Exception(response.json()["error"]) + return response.json() + + def buy(self, security, price, amount, **kwargs): + params = locals().copy() + params.pop("self") + + response = self._s.post(self._api + "/buy", json=params) + if response.status_code >= 300: + raise Exception(response.json()["error"]) + return response.json() + + def sell(self, security, price, amount, **kwargs): + params = locals().copy() + params.pop("self") + + response = self._s.post(self._api + "/sell", json=params) + if response.status_code >= 300: + raise Exception(response.json()["error"]) + return response.json() + + def cancel_entrust(self, entrust_no): + params = locals().copy() + params.pop("self") + + response = self._s.post(self._api + "/cancel_entrust", json=params) + if response.status_code >= 300: + raise Exception(response.json()["error"]) + return response.json() diff --git a/qbot/engine/trade/easytrader/easytrader/ricequant_follower.py b/qbot/engine/trade/easytrader/easytrader/ricequant_follower.py new file mode 100644 index 00000000..4c93e6f5 --- /dev/null +++ b/qbot/engine/trade/easytrader/easytrader/ricequant_follower.py @@ -0,0 +1,119 @@ +# -*- coding: utf-8 -*- + +from datetime import datetime +from threading import Thread + +from easytrader.follower import BaseFollower +from easytrader.log import logger + + +class RiceQuantFollower(BaseFollower): + def __init__(self): + super().__init__() + self.client = None + + def login(self, user=None, password=None, **kwargs): + from rqopen_client import RQOpenClient + + self.client = RQOpenClient(user, password, logger=logger) + + def follow( + self, + users, + run_id, + track_interval=1, + trade_cmd_expire_seconds=120, + cmd_cache=True, + entrust_prop="limit", + send_interval=0, + ): + """跟踪ricequant对应的模拟交易,支持多用户多策略 + :param users: 支持easytrader的用户对象,支持使用 [] 指定多个用户 + :param run_id: ricequant 的模拟交易ID,支持使用 [] 指定多个模拟交易 + :param track_interval: 轮训模拟交易时间,单位为秒 + :param trade_cmd_expire_seconds: 交易指令过期时间, 单位为秒 + :param cmd_cache: 是否读取存储历史执行过的指令,防止重启时重复执行已经交易过的指令 + :param entrust_prop: 委托方式, 'limit' 为限价,'market' 为市价, 仅在银河实现 + :param send_interval: 交易发送间隔, 默认为0s。调大可防止卖出买入时卖出单没有及时成交导致的买入金额不足 + """ + users = self.warp_list(users) + run_ids = self.warp_list(run_id) + + if cmd_cache: + self.load_expired_cmd_cache() + + self.start_trader_thread( + users, trade_cmd_expire_seconds, entrust_prop, send_interval + ) + + workers = [] + for id_ in run_ids: + strategy_name = self.extract_strategy_name(id_) + strategy_worker = Thread( + target=self.track_strategy_worker, + args=[id_, strategy_name], + kwargs={"interval": track_interval}, + ) + strategy_worker.start() + workers.append(strategy_worker) + logger.info("开始跟踪策略: %s", strategy_name) + for worker in workers: + worker.join() + + def extract_strategy_name(self, run_id): + ret_json = self.client.get_positions(run_id) + if ret_json["code"] != 200: + logger.error( + "fetch data from run_id %s fail, msg %s", + run_id, + ret_json["msg"], + ) + raise RuntimeError(ret_json["msg"]) + return ret_json["resp"]["name"] + + def extract_day_trades(self, run_id): + ret_json = self.client.get_day_trades(run_id) + if ret_json["code"] != 200: + logger.error( + "fetch day trades from run_id %s fail, msg %s", + run_id, + ret_json["msg"], + ) + raise RuntimeError(ret_json["msg"]) + return ret_json["resp"]["trades"] + + def query_strategy_transaction(self, strategy, **kwargs): + transactions = self.extract_day_trades(strategy) + transactions = self.project_transactions(transactions, **kwargs) + return self.order_transactions_sell_first(transactions) + + @staticmethod + def stock_shuffle_to_prefix(stock): + assert ( + len(stock) == 11 + ), "stock {} must like 123456.XSHG or 123456.XSHE".format(stock) + code = stock[:6] + if stock.find("XSHG") != -1: + return "sh" + code + if stock.find("XSHE") != -1: + return "sz" + code + raise TypeError("not valid stock code: {}".format(code)) + + def project_transactions(self, transactions, **kwargs): + new_transactions = [] + for transaction in transactions: + new_transaction = {} + new_transaction["price"] = transaction["price"] + new_transaction["amount"] = int(abs(transaction["quantity"])) + new_transaction["datetime"] = datetime.strptime( + transaction["time"], "%Y-%m-%d %H:%M:%S" + ) + new_transaction["stock_code"] = self.stock_shuffle_to_prefix( + transaction["order_book_id"] + ) + new_transaction["action"] = ( + "buy" if transaction["quantity"] > 0 else "sell" + ) + new_transactions.append(new_transaction) + + return new_transactions diff --git a/qbot/engine/trade/easytrader/easytrader/server.py b/qbot/engine/trade/easytrader/easytrader/server.py new file mode 100644 index 00000000..02ce98d6 --- /dev/null +++ b/qbot/engine/trade/easytrader/easytrader/server.py @@ -0,0 +1,135 @@ +import functools + +from flask import Flask, jsonify, request + +from . import api +from .log import logger + +app = Flask(__name__) + +global_store = {} + + +def error_handle(func): + @functools.wraps(func) + def wrapper(*args, **kwargs): + try: + return func(*args, **kwargs) + # pylint: disable=broad-except + except Exception as e: + logger.exception("server error") + message = "{}: {}".format(e.__class__, e) + return jsonify({"error": message}), 400 + + return wrapper + + +@app.route("/prepare", methods=["POST"]) +@error_handle +def post_prepare(): + json_data = request.get_json(force=True) + + user = api.use(json_data.pop("broker")) + user.prepare(**json_data) + + global_store["user"] = user + return jsonify({"msg": "login success"}), 201 + + +@app.route("/balance", methods=["GET"]) +@error_handle +def get_balance(): + user = global_store["user"] + balance = user.balance + + return jsonify(balance), 200 + + +@app.route("/position", methods=["GET"]) +@error_handle +def get_position(): + user = global_store["user"] + position = user.position + + return jsonify(position), 200 + + +@app.route("/auto_ipo", methods=["GET"]) +@error_handle +def get_auto_ipo(): + user = global_store["user"] + res = user.auto_ipo() + + return jsonify(res), 200 + + +@app.route("/today_entrusts", methods=["GET"]) +@error_handle +def get_today_entrusts(): + user = global_store["user"] + today_entrusts = user.today_entrusts + + return jsonify(today_entrusts), 200 + + +@app.route("/today_trades", methods=["GET"]) +@error_handle +def get_today_trades(): + user = global_store["user"] + today_trades = user.today_trades + + return jsonify(today_trades), 200 + + +@app.route("/cancel_entrusts", methods=["GET"]) +@error_handle +def get_cancel_entrusts(): + user = global_store["user"] + cancel_entrusts = user.cancel_entrusts + + return jsonify(cancel_entrusts), 200 + + +@app.route("/buy", methods=["POST"]) +@error_handle +def post_buy(): + json_data = request.get_json(force=True) + user = global_store["user"] + res = user.buy(**json_data) + + return jsonify(res), 201 + + +@app.route("/sell", methods=["POST"]) +@error_handle +def post_sell(): + json_data = request.get_json(force=True) + + user = global_store["user"] + res = user.sell(**json_data) + + return jsonify(res), 201 + + +@app.route("/cancel_entrust", methods=["POST"]) +@error_handle +def post_cancel_entrust(): + json_data = request.get_json(force=True) + + user = global_store["user"] + res = user.cancel_entrust(**json_data) + + return jsonify(res), 201 + + +@app.route("/exit", methods=["GET"]) +@error_handle +def get_exit(): + user = global_store["user"] + user.exit() + + return jsonify({"msg": "exit success"}), 200 + + +def run(port=1430): + app.run(host="0.0.0.0", port=port) diff --git a/qbot/engine/trade/easytrader/easytrader/universal_clienttrader.py b/qbot/engine/trade/easytrader/easytrader/universal_clienttrader.py new file mode 100644 index 00000000..afec1eae --- /dev/null +++ b/qbot/engine/trade/easytrader/easytrader/universal_clienttrader.py @@ -0,0 +1,60 @@ +# -*- coding: utf-8 -*- + +import pywinauto +import pywinauto.clipboard + +from easytrader import grid_strategies +from . import clienttrader + + +class UniversalClientTrader(clienttrader.BaseLoginClientTrader): + grid_strategy = grid_strategies.Xls + + @property + def broker_type(self): + return "universal" + + def login(self, user, password, exe_path, comm_password=None, **kwargs): + """ + :param user: 用户名 + :param password: 密码 + :param exe_path: 客户端路径, 类似 + :param comm_password: + :param kwargs: + :return: + """ + self._editor_need_type_keys = False + + try: + self._app = pywinauto.Application().connect( + path=self._run_exe_path(exe_path), timeout=1 + ) + # pylint: disable=broad-except + except Exception: + self._app = pywinauto.Application().start(exe_path) + + # wait login window ready + while True: + try: + login_window = pywinauto.findwindows.find_window(class_name='#32770', found_index=1) + break + except: + self.wait(1) + + self.wait(1) + self._app.window(handle=login_window).Edit1.set_focus() + self._app.window(handle=login_window).Edit1.type_keys(user) + + self._app.window(handle=login_window).button7.click() + + # detect login is success or not + # self._app.top_window().wait_not("exists", 100) + self.wait(5) + + self._app = pywinauto.Application().connect( + path=self._run_exe_path(exe_path), timeout=10 + ) + + self._close_prompt_windows() + self._main = self._app.window(title="网上股票交易系统5.0") + diff --git a/qbot/engine/trade/easytrader/easytrader/utils/__init__.py b/qbot/engine/trade/easytrader/easytrader/utils/__init__.py new file mode 100644 index 00000000..d3f5a12f --- /dev/null +++ b/qbot/engine/trade/easytrader/easytrader/utils/__init__.py @@ -0,0 +1 @@ + diff --git a/qbot/engine/trade/easytrader/easytrader/utils/captcha.py b/qbot/engine/trade/easytrader/easytrader/utils/captcha.py new file mode 100644 index 00000000..cfbfc009 --- /dev/null +++ b/qbot/engine/trade/easytrader/easytrader/utils/captcha.py @@ -0,0 +1,103 @@ +import re + +import requests +from PIL import Image + +from easytrader import exceptions + + +def captcha_recognize(img_path): + import pytesseract + + im = Image.open(img_path).convert("L") + # 1. threshold the image + threshold = 200 + table = [] + for i in range(256): + if i < threshold: + table.append(0) + else: + table.append(1) + + out = im.point(table, "1") + # 2. recognize with tesseract + num = pytesseract.image_to_string(out) + return num + + +def recognize_verify_code(image_path, broker="ht"): + """识别验证码,返回识别后的字符串,使用 tesseract 实现 + :param image_path: 图片路径 + :param broker: 券商 ['ht', 'yjb', 'gf', 'yh'] + :return recognized: verify code string""" + + if broker == "gf": + return detect_gf_result(image_path) + if broker in ["yh_client", "gj_client"]: + return detect_yh_client_result(image_path) + # 调用 tesseract 识别 + return default_verify_code_detect(image_path) + + +def detect_yh_client_result(image_path): + """封装了tesseract的识别,部署在阿里云上, + 服务端源码地址为: https://github.com/shidenggui/yh_verify_code_docker""" + api = "http://yh.ez.shidenggui.com:5000/yh_client" + with open(image_path, "rb") as f: + rep = requests.post(api, files={"image": f}) + if rep.status_code != 201: + error = rep.json()["message"] + raise exceptions.TradeError("request {} error: {}".format(api, error)) + return rep.json()["result"] + + +def input_verify_code_manual(image_path): + from PIL import Image + + image = Image.open(image_path) + image.show() + code = input( + "image path: {}, input verify code answer:".format(image_path) + ) + return code + + +def default_verify_code_detect(image_path): + from PIL import Image + + img = Image.open(image_path) + return invoke_tesseract_to_recognize(img) + + +def detect_gf_result(image_path): + from PIL import ImageFilter, Image + + img = Image.open(image_path) + if hasattr(img, "width"): + width, height = img.width, img.height + else: + width, height = img.size + for x in range(width): + for y in range(height): + if img.getpixel((x, y)) < (100, 100, 100): + img.putpixel((x, y), (256, 256, 256)) + gray = img.convert("L") + two = gray.point(lambda p: 0 if 68 < p < 90 else 256) + min_res = two.filter(ImageFilter.MinFilter) + med_res = min_res.filter(ImageFilter.MedianFilter) + for _ in range(2): + med_res = med_res.filter(ImageFilter.MedianFilter) + return invoke_tesseract_to_recognize(med_res) + + +def invoke_tesseract_to_recognize(img): + import pytesseract + + try: + res = pytesseract.image_to_string(img) + except FileNotFoundError: + raise Exception( + "tesseract 未安装,请至 https://github.com/tesseract-ocr/tesseract/wiki 查看安装教程" + ) + valid_chars = re.findall("[0-9a-z]", res, re.IGNORECASE) + return "".join(valid_chars) diff --git a/qbot/engine/trade/easytrader/easytrader/utils/misc.py b/qbot/engine/trade/easytrader/easytrader/utils/misc.py new file mode 100644 index 00000000..a47592b5 --- /dev/null +++ b/qbot/engine/trade/easytrader/easytrader/utils/misc.py @@ -0,0 +1,31 @@ +# coding:utf-8 +import json + + +def parse_cookies_str(cookies): + """ + parse cookies str to dict + :param cookies: cookies str + :type cookies: str + :return: cookie dict + :rtype: dict + """ + cookie_dict = {} + for record in cookies.split(";"): + key, value = record.strip().split("=", 1) + cookie_dict[key] = value + return cookie_dict + + +def file2dict(path): + with open(path, encoding="utf-8") as f: + return json.load(f) + + +def grep_comma(num_str): + return num_str.replace(",", "") + + +def str2num(num_str, convert_type="float"): + num = float(grep_comma(num_str)) + return num if convert_type == "float" else int(num) diff --git a/qbot/engine/trade/easytrader/easytrader/utils/perf.py b/qbot/engine/trade/easytrader/easytrader/utils/perf.py new file mode 100644 index 00000000..b48a5e7b --- /dev/null +++ b/qbot/engine/trade/easytrader/easytrader/utils/perf.py @@ -0,0 +1,46 @@ +# coding:utf-8 +import functools +import logging +import timeit + +from easytrader import logger + +try: + from time import process_time +except Exception: + from time import clock as process_time + + +def perf_clock(f): + @functools.wraps(f) + def wrapper(*args, **kwargs): + if not logger.isEnabledFor(logging.DEBUG): + return f(*args, **kwargs) + + ts = timeit.default_timer() + cs = process_time() + ex = None + result = None + + try: + result = f(*args, **kwargs) + except Exception as ex1: + ex = ex1 + + te = timeit.default_timer() + ce = process_time() + logger.debug( + "%r consume %2.4f sec, cpu %2.4f sec. args %s, extra args %s" + % ( + f.__name__, + te - ts, + ce - cs, + args[1:], + kwargs, + ) + ) + if ex is not None: + raise ex + return result + + return wrapper diff --git a/qbot/engine/trade/easytrader/easytrader/utils/stock.py b/qbot/engine/trade/easytrader/easytrader/utils/stock.py new file mode 100644 index 00000000..21acea23 --- /dev/null +++ b/qbot/engine/trade/easytrader/easytrader/utils/stock.py @@ -0,0 +1,91 @@ +# coding:utf-8 +import datetime +import json +import random + +import requests + + +def get_stock_type(stock_code): + """判断股票ID对应的证券市场 + 匹配规则 + ['50', '51', '60', '90', '110'] 为 sh + ['00', '13', '18', '15', '16', '18', '20', '30', '39', '115'] 为 sz + ['5', '6', '9'] 开头的为 sh, 其余为 sz + :param stock_code:股票ID, 若以 'sz', 'sh' 开头直接返回对应类型,否则使用内置规则判断 + :return 'sh' or 'sz'""" + stock_code = str(stock_code) + if stock_code.startswith(("sh", "sz")): + return stock_code[:2] + if stock_code.startswith( + ("50", "51", "60", "73", "90", "110", "113", "132", "204", "78") + ): + return "sh" + if stock_code.startswith( + ("00", "13", "18", "15", "16", "18", "20", "30", "39", "115", "1318") + ): + return "sz" + if stock_code.startswith(("5", "6", "9")): + return "sh" + return "sz" + + +def get_30_date(): + """ + 获得用于查询的默认日期, 今天的日期, 以及30天前的日期 + 用于查询的日期格式通常为 20160211 + :return: + """ + now = datetime.datetime.now() + end_date = now.date() + start_date = end_date - datetime.timedelta(days=30) + return start_date.strftime("%Y%m%d"), end_date.strftime("%Y%m%d") + + +def get_today_ipo_data(): + """ + 查询今天可以申购的新股信息 + :return: 今日可申购新股列表 apply_code申购代码 price发行价格 + """ + + agent = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:43.0) Gecko/20100101 Firefox/43.0" + send_headers = { + "Host": "xueqiu.com", + "User-Agent": agent, + "Accept": "application/json, text/javascript, */*; q=0.01", + "Accept-Language": "zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3", + "Accept-Encoding": "deflate", + "Cache-Control": "no-cache", + "X-Requested-With": "XMLHttpRequest", + "Referer": "https://xueqiu.com/hq", + "Connection": "keep-alive", + } + + timestamp = random.randint(1000000000000, 9999999999999) + home_page_url = "https://xueqiu.com" + ipo_data_url = ( + "https://xueqiu.com/proipo/query.json?column=symbol,name,onl_subcode,onl_subbegdate,actissqty,onl" + "_actissqty,onl_submaxqty,iss_price,onl_lotwiner_stpub_date,onl_lotwinrt,onl_lotwin_amount,stock_" + "income&orderBy=onl_subbegdate&order=desc&stockType=&page=1&size=30&_=%s" + % (str(timestamp)) + ) + + session = requests.session() + session.get(home_page_url, headers=send_headers) # 产生cookies + ipo_response = session.post(ipo_data_url, headers=send_headers) + + json_data = json.loads(ipo_response.text) + today_ipo = [] + + for line in json_data["data"]: + if datetime.datetime.now().strftime("%a %b %d") == line[3][:10]: + today_ipo.append( + { + "stock_code": line[0], + "stock_name": line[1], + "apply_code": line[2], + "price": line[7], + } + ) + + return today_ipo diff --git a/qbot/engine/trade/easytrader/easytrader/utils/win_gui.py b/qbot/engine/trade/easytrader/easytrader/utils/win_gui.py new file mode 100644 index 00000000..903c5f91 --- /dev/null +++ b/qbot/engine/trade/easytrader/easytrader/utils/win_gui.py @@ -0,0 +1,3 @@ +# coding:utf-8 +from pywinauto import win32defines +from pywinauto.win32functions import SetForegroundWindow, ShowWindow diff --git a/qbot/engine/trade/easytrader/easytrader/webtrader.py b/qbot/engine/trade/easytrader/easytrader/webtrader.py new file mode 100644 index 00000000..f591db3e --- /dev/null +++ b/qbot/engine/trade/easytrader/easytrader/webtrader.py @@ -0,0 +1,245 @@ +# -*- coding: utf-8 -*- +import abc +import logging +import os +import re +import time +from threading import Thread + +import requests +import requests.exceptions + +from easytrader import exceptions +from easytrader.log import logger +from easytrader.utils.misc import file2dict, str2num +from easytrader.utils.stock import get_30_date + + +# noinspection PyIncorrectDocstring +class WebTrader(metaclass=abc.ABCMeta): + global_config_path = os.path.dirname(__file__) + "/config/global.json" + config_path = "" + + def __init__(self, debug=True): + self.__read_config() + self.trade_prefix = self.config["prefix"] + self.account_config = "" + self.heart_active = True + self.heart_thread = Thread(target=self.send_heartbeat) + self.heart_thread.setDaemon(True) + + self.log_level = logging.DEBUG if debug else logging.INFO + + def read_config(self, path): + try: + self.account_config = file2dict(path) + except ValueError: + logger.error("配置文件格式有误,请勿使用记事本编辑,推荐 sublime text") + for value in self.account_config: + if isinstance(value, int): + logger.warning("配置文件的值最好使用双引号包裹,使用字符串,否则可能导致不可知问题") + + def prepare(self, config_file=None, user=None, password=None, **kwargs): + """登录的统一接口 + :param config_file 登录数据文件,若无则选择参数登录模式 + :param user: 各家券商的账号 + :param password: 密码, 券商为加密后的密码 + :param cookies: [雪球登录需要]雪球登录需要设置对应的 cookies + :param portfolio_code: [雪球登录需要]组合代码 + :param portfolio_market: [雪球登录需要]交易市场, + 可选['cn', 'us', 'hk'] 默认 'cn' + """ + if config_file is not None: + self.read_config(config_file) + else: + self._prepare_account(user, password, **kwargs) + self.autologin() + + def _prepare_account(self, user, password, **kwargs): + """映射用户名密码到对应的字段""" + raise Exception("支持参数登录需要实现此方法") + + def autologin(self, limit=10): + """实现自动登录 + :param limit: 登录次数限制 + """ + for _ in range(limit): + if self.login(): + break + else: + raise exceptions.NotLoginError( + "登录失败次数过多, 请检查密码是否正确 / 券商服务器是否处于维护中 / 网络连接是否正常" + ) + self.keepalive() + + def login(self): + pass + + def keepalive(self): + """启动保持在线的进程 """ + if self.heart_thread.is_alive(): + self.heart_active = True + else: + self.heart_thread.start() + + def send_heartbeat(self): + """每隔10秒查询指定接口保持 token 的有效性""" + while True: + if self.heart_active: + self.check_login() + else: + time.sleep(1) + + def check_login(self, sleepy=30): + logger.setLevel(logging.ERROR) + try: + response = self.heartbeat() + self.check_account_live(response) + except requests.exceptions.ConnectionError: + pass + except requests.exceptions.RequestException as e: + logger.setLevel(self.log_level) + logger.error("心跳线程发现账户出现错误: %s %s, 尝试重新登陆", e.__class__, e) + self.autologin() + finally: + logger.setLevel(self.log_level) + time.sleep(sleepy) + + def heartbeat(self): + return self.balance + + def check_account_live(self, response): + pass + + def exit(self): + """结束保持 token 在线的进程""" + self.heart_active = False + + def __read_config(self): + """读取 config""" + self.config = file2dict(self.config_path) + self.global_config = file2dict(self.global_config_path) + self.config.update(self.global_config) + + @property + def balance(self): + return self.get_balance() + + def get_balance(self): + """获取账户资金状况""" + return self.do(self.config["balance"]) + + @property + def position(self): + return self.get_position() + + def get_position(self): + """获取持仓""" + return self.do(self.config["position"]) + + @property + def entrust(self): + return self.get_entrust() + + def get_entrust(self): + """获取当日委托列表""" + return self.do(self.config["entrust"]) + + @property + def current_deal(self): + return self.get_current_deal() + + def get_current_deal(self): + """获取当日委托列表""" + # return self.do(self.config['current_deal']) + logger.warning("目前仅在 佣金宝/银河子类 中实现, 其余券商需要补充") + + @property + def exchangebill(self): + """ + 默认提供最近30天的交割单, 通常只能返回查询日期内最新的 90 天数据。 + :return: + """ + # TODO 目前仅在 华泰子类 中实现 + start_date, end_date = get_30_date() + return self.get_exchangebill(start_date, end_date) + + def get_exchangebill(self, start_date, end_date): + """ + 查询指定日期内的交割单 + :param start_date: 20160211 + :param end_date: 20160211 + :return: + """ + logger.warning("目前仅在 华泰子类 中实现, 其余券商需要补充") + + def get_ipo_limit(self, stock_code): + """ + 查询新股申购额度申购上限 + :param stock_code: 申购代码 ID + :return: + """ + logger.warning("目前仅在 佣金宝子类 中实现, 其余券商需要补充") + + def do(self, params): + """发起对 api 的请求并过滤返回结果 + :param params: 交易所需的动态参数""" + request_params = self.create_basic_params() + request_params.update(params) + response_data = self.request(request_params) + try: + format_json_data = self.format_response_data(response_data) + # pylint: disable=broad-except + except Exception: + # Caused by server force logged out + return None + return_data = self.fix_error_data(format_json_data) + try: + self.check_login_status(return_data) + except exceptions.NotLoginError: + self.autologin() + return return_data + + def create_basic_params(self) -> dict: + """生成基本的参数""" + return {} + + def request(self, params) -> dict: + """请求并获取 JSON 数据 + :param params: Get 参数""" + return {} + + def format_response_data(self, data): + """格式化返回的 json 数据 + :param data: 请求返回的数据 """ + return data + + def fix_error_data(self, data): + """若是返回错误移除外层的列表 + :param data: 需要判断是否包含错误信息的数据""" + return data + + def format_response_data_type(self, response_data): + """格式化返回的值为正确的类型 + :param response_data: 返回的数据 + """ + if isinstance(response_data, list) and not isinstance( + response_data, str + ): + return response_data + + int_match_str = "|".join(self.config["response_format"]["int"]) + float_match_str = "|".join(self.config["response_format"]["float"]) + for item in response_data: + for key in item: + try: + if re.search(int_match_str, key) is not None: + item[key] = str2num(item[key], "int") + elif re.search(float_match_str, key) is not None: + item[key] = str2num(item[key], "float") + except ValueError: + continue + return response_data + + def check_login_status(self, return_data): + pass diff --git a/qbot/engine/trade/easytrader/easytrader/wk_clienttrader.py b/qbot/engine/trade/easytrader/easytrader/wk_clienttrader.py new file mode 100644 index 00000000..8906d8ce --- /dev/null +++ b/qbot/engine/trade/easytrader/easytrader/wk_clienttrader.py @@ -0,0 +1,56 @@ +# -*- coding: utf-8 -*- +import pywinauto + +from easytrader.ht_clienttrader import HTClientTrader + + +class WKClientTrader(HTClientTrader): + @property + def broker_type(self): + return "wk" + + def login(self, user, password, exe_path, comm_password=None, **kwargs): + """ + :param user: 用户名 + :param password: 密码 + :param exe_path: 客户端路径, 类似 + :param comm_password: + :param kwargs: + :return: + """ + self._editor_need_type_keys = False + if comm_password is None: + raise ValueError("五矿必须设置通讯密码") + + try: + self._app = pywinauto.Application().connect( + path=self._run_exe_path(exe_path), timeout=1 + ) + # pylint: disable=broad-except + except Exception: + self._app = pywinauto.Application().start(exe_path) + + # wait login window ready + while True: + try: + self._app.top_window().Edit1.wait("ready") + break + except RuntimeError: + pass + + self._app.top_window().Edit1.set_focus() + self._app.top_window().Edit1.set_edit_text(user) + self._app.top_window().Edit2.set_edit_text(password) + + self._app.top_window().Edit3.set_edit_text(comm_password) + + self._app.top_window().Button1.click() + + # detect login is success or not + self._app.top_window().wait_not("exists", 100) + + self._app = pywinauto.Application().connect( + path=self._run_exe_path(exe_path), timeout=10 + ) + self._close_prompt_windows() + self._main = self._app.window(title="网上股票交易系统5.0") \ No newline at end of file diff --git a/qbot/engine/trade/easytrader/easytrader/xq_follower.py b/qbot/engine/trade/easytrader/easytrader/xq_follower.py new file mode 100644 index 00000000..d76085d2 --- /dev/null +++ b/qbot/engine/trade/easytrader/easytrader/xq_follower.py @@ -0,0 +1,260 @@ +# -*- coding: utf-8 -*- +from __future__ import division, print_function, unicode_literals + +import json +import re +from datetime import datetime +from numbers import Number +from threading import Thread + +from easytrader.follower import BaseFollower +from easytrader.log import logger +from easytrader.utils.misc import parse_cookies_str + + +class XueQiuFollower(BaseFollower): + LOGIN_PAGE = "https://www.xueqiu.com" + LOGIN_API = "https://xueqiu.com/snowman/login" + TRANSACTION_API = "https://xueqiu.com/cubes/rebalancing/history.json" + PORTFOLIO_URL = "https://xueqiu.com/p/" + WEB_REFERER = "https://www.xueqiu.com" + + def __init__(self): + super().__init__() + self._adjust_sell = None + self._users = None + + def login(self, user=None, password=None, **kwargs): + """ + 雪球登陆, 需要设置 cookies + :param cookies: 雪球登陆需要设置 cookies, 具体见 + https://smalltool.github.io/2016/08/02/cookie/ + :return: + """ + cookies = kwargs.get("cookies") + if cookies is None: + raise TypeError( + "雪球登陆需要设置 cookies, 具体见" + "https://smalltool.github.io/2016/08/02/cookie/" + ) + headers = self._generate_headers() + self.s.headers.update(headers) + + self.s.get(self.LOGIN_PAGE) + + cookie_dict = parse_cookies_str(cookies) + self.s.cookies.update(cookie_dict) + + logger.info("登录成功") + + def follow( # type: ignore + self, + users, + strategies, + total_assets=10000, + initial_assets=None, + adjust_sell=False, + track_interval=10, + trade_cmd_expire_seconds=120, + cmd_cache=True, + slippage: float = 0.0, + ): + """跟踪 joinquant 对应的模拟交易,支持多用户多策略 + :param users: 支持 easytrader 的用户对象,支持使用 [] 指定多个用户 + :param strategies: 雪球组合名, 类似 ZH123450 + :param total_assets: 雪球组合对应的总资产, 格式 [组合1对应资金, 组合2对应资金] + 若 strategies=['ZH000001', 'ZH000002'], + 设置 total_assets=[10000, 10000], 则表明每个组合对应的资产为 1w 元 + 假设组合 ZH000001 加仓 价格为 p 股票 A 10%, + 则对应的交易指令为 买入 股票 A 价格 P 股数 1w * 10% / p 并按 100 取整 + :param adjust_sell: 是否根据用户的实际持仓数调整卖出股票数量, + 当卖出股票数大于实际持仓数时,调整为实际持仓数。目前仅在银河客户端测试通过。 + 当 users 为多个时,根据第一个 user 的持仓数决定 + :type adjust_sell: bool + :param initial_assets: 雪球组合对应的初始资产, + 格式 [ 组合1对应资金, 组合2对应资金 ] + 总资产由 初始资产 × 组合净值 算得, total_assets 会覆盖此参数 + :param track_interval: 轮训模拟交易时间,单位为秒 + :param trade_cmd_expire_seconds: 交易指令过期时间, 单位为秒 + :param cmd_cache: 是否读取存储历史执行过的指令,防止重启时重复执行已经交易过的指令 + :param slippage: 滑点,0.0 表示无滑点, 0.05 表示滑点为 5% + """ + super().follow( + users=users, + strategies=strategies, + track_interval=track_interval, + trade_cmd_expire_seconds=trade_cmd_expire_seconds, + cmd_cache=cmd_cache, + slippage=slippage, + ) + + self._adjust_sell = adjust_sell + + self._users = self.warp_list(users) + + strategies = self.warp_list(strategies) + total_assets = self.warp_list(total_assets) + initial_assets = self.warp_list(initial_assets) + + if cmd_cache: + self.load_expired_cmd_cache() + + self.start_trader_thread(self._users, trade_cmd_expire_seconds) + + for strategy_url, strategy_total_assets, strategy_initial_assets in zip( + strategies, total_assets, initial_assets + ): + assets = self.calculate_assets( + strategy_url, strategy_total_assets, strategy_initial_assets + ) + try: + strategy_id = self.extract_strategy_id(strategy_url) + strategy_name = self.extract_strategy_name(strategy_url) + except Exception: + logger.error( + "抽取交易id和策略名失败, 无效模拟交易url: %s", strategy_url + ) + raise + strategy_worker = Thread( + target=self.track_strategy_worker, + args=[strategy_id, strategy_name], + kwargs={"interval": track_interval, "assets": assets}, + ) + strategy_worker.start() + logger.info("开始跟踪策略: %s", strategy_name) + + def calculate_assets(self, strategy_url, total_assets=None, initial_assets=None): + # 都设置时优先选择 total_assets + if total_assets is None and initial_assets is not None: + net_value = self._get_portfolio_net_value(strategy_url) + total_assets = initial_assets * net_value + if not isinstance(total_assets, Number): + raise TypeError("input assets type must be number(int, float)") + if total_assets < 1e3: + raise ValueError( + "雪球总资产不能小于1000元,当前预设值 {}".format(total_assets) + ) + return total_assets + + @staticmethod + def extract_strategy_id(strategy_url): + return strategy_url + + def extract_strategy_name(self, strategy_url): + base_url = "https://xueqiu.com/cubes/nav_daily/all.json?cube_symbol={}" + url = base_url.format(strategy_url) + rep = self.s.get(url) + info_index = 0 + return rep.json()[info_index]["name"] + + def extract_transactions(self, history): + if history["count"] <= 0: + return [] + rebalancing_index = 0 + raw_transactions = history["list"][rebalancing_index]["rebalancing_histories"] + transactions = [] + for transaction in raw_transactions: + if transaction["price"] is None: + logger.info( + "该笔交易无法获取价格,疑似未成交,跳过。交易详情: %s", transaction + ) + continue + transactions.append(transaction) + + return transactions + + def create_query_transaction_params(self, strategy): + params = {"cube_symbol": strategy, "page": 1, "count": 1} + return params + + # noinspection PyMethodOverriding + def none_to_zero(self, data): + if data is None: + return 0 + return data + + # noinspection PyMethodOverriding + def project_transactions(self, transactions, assets): + for transaction in transactions: + weight_diff = self.none_to_zero(transaction["weight"]) - self.none_to_zero( + transaction["prev_weight"] + ) + + initial_amount = abs(weight_diff) / 100 * assets / transaction["price"] + + transaction["datetime"] = datetime.fromtimestamp( + transaction["created_at"] // 1000 + ) + + transaction["stock_code"] = transaction["stock_symbol"].lower() + + transaction["action"] = "buy" if weight_diff > 0 else "sell" + + transaction["amount"] = int(round(initial_amount, -2)) + if transaction["action"] == "sell" and self._adjust_sell: + transaction["amount"] = self._adjust_sell_amount( + transaction["stock_code"], transaction["amount"] + ) + + def _adjust_sell_amount(self, stock_code, amount): + """ + 根据实际持仓值计算雪球卖出股数 + 因为雪球的交易指令是基于持仓百分比,在取近似值的情况下可能出现不精确的问题。 + 导致如下情况的产生,计算出的指令为买入 1049 股,取近似值买入 1000 股。 + 而卖出的指令计算出为卖出 1051 股,取近似值卖出 1100 股,超过 1000 股的买入量, + 导致卖出失败 + :param stock_code: 证券代码 + :type stock_code: str + :param amount: 卖出股份数 + :type amount: int + :return: 考虑实际持仓之后的卖出股份数 + :rtype: int + """ + stock_code = stock_code[-6:] + user = self._users[0] + position = user.position + try: + stock = next(s for s in position if s["证券代码"] == stock_code) + except StopIteration: + logger.info( + "根据持仓调整 %s 卖出额,发现未持有股票 %s, 不做任何调整", + stock_code, + stock_code, + ) + return amount + + available_amount = stock["可用余额"] + if available_amount >= amount: + return amount + + adjust_amount = available_amount // 100 * 100 + logger.info( + "股票 %s 实际可用余额 %s, 指令卖出股数为 %s, 调整为 %s", + stock_code, + available_amount, + amount, + adjust_amount, + ) + return adjust_amount + + def _get_portfolio_info(self, portfolio_code): + """ + 获取组合信息 + """ + url = self.PORTFOLIO_URL + portfolio_code + portfolio_page = self.s.get(url) + match_info = re.search(r"(?<=SNB.cubeInfo = ).*(?=;\n)", portfolio_page.text) + if match_info is None: + raise Exception("cant get portfolio info, portfolio url : {}".format(url)) + try: + portfolio_info = json.loads(match_info.group()) + except Exception as e: + raise Exception("get portfolio info error: {}".format(e)) + return portfolio_info + + def _get_portfolio_net_value(self, portfolio_code): + """ + 获取组合信息 + """ + portfolio_info = self._get_portfolio_info(portfolio_code) + return portfolio_info["net_value"] diff --git a/qbot/engine/trade/easytrader/easytrader/xqtrader.py b/qbot/engine/trade/easytrader/easytrader/xqtrader.py new file mode 100644 index 00000000..6daecc29 --- /dev/null +++ b/qbot/engine/trade/easytrader/easytrader/xqtrader.py @@ -0,0 +1,539 @@ +# -*- coding: utf-8 -*- +import json +import numbers +import os +import re +import time + +import requests +from easytrader import exceptions, webtrader +from easytrader.log import logger +from easytrader.utils.misc import parse_cookies_str + + +class XueQiuTrader(webtrader.WebTrader): + config_path = os.path.dirname(__file__) + "/config/xueqiu.json" + + _HEADERS = { + "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) " + "AppleWebKit/537.36 (KHTML, like Gecko) " + "Chrome/64.0.3282.167 Safari/537.36", + "Host": "xueqiu.com", + "Pragma": "no-cache", + "Connection": "keep-alive", + "Accept": "*/*", + "Accept-Encoding": "gzip, deflate, br", + "Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8", + "Cache-Control": "no-cache", + "Referer": "https://xueqiu.com/P/ZH004612", + "X-Requested-With": "XMLHttpRequest", + } + + def __init__(self, **kwargs): + super(XueQiuTrader, self).__init__() + + # 资金换算倍数 + self.multiple = ( + kwargs["initial_assets"] if "initial_assets" in kwargs else 1000000 + ) + if not isinstance(self.multiple, numbers.Number): + raise TypeError("initial assets must be number(int, float)") + if self.multiple < 1e3: + raise ValueError( + "雪球初始资产不能小于1000元,当前预设值 {}".format(self.multiple) + ) + + self.s = requests.Session() + self.s.verify = False + self.s.headers.update(self._HEADERS) + self.account_config = None + + def autologin(self, **kwargs): + """ + 使用 cookies 之后不需要自动登陆 + :return: + """ + self._set_cookies(self.account_config["cookies"]) + + def _set_cookies(self, cookies): + """设置雪球 cookies,代码来自于 + https://github.com/shidenggui/easytrader/issues/269 + :param cookies: 雪球 cookies + :type cookies: str + """ + cookie_dict = parse_cookies_str(cookies) + self.s.cookies.update(cookie_dict) + + def _prepare_account(self, user="", password="", **kwargs): + """ + 转换参数到登录所需的字典格式 + :param cookies: 雪球登陆需要设置 cookies, 具体见 + https://smalltool.github.io/2016/08/02/cookie/ + :param portfolio_code: 组合代码 + :param portfolio_market: 交易市场, 可选['cn', 'us', 'hk'] 默认 'cn' + :return: + """ + if "portfolio_code" not in kwargs: + raise TypeError("雪球登录需要设置 portfolio_code(组合代码) 参数") + if "portfolio_market" not in kwargs: + kwargs["portfolio_market"] = "cn" + if "cookies" not in kwargs: + raise TypeError( + "雪球登陆需要设置 cookies, 具体见" + "https://smalltool.github.io/2016/08/02/cookie/" + ) + self.account_config = { + "cookies": kwargs["cookies"], + "portfolio_code": kwargs["portfolio_code"], + "portfolio_market": kwargs["portfolio_market"], + } + + def _virtual_to_balance(self, virtual): + """ + 虚拟净值转化为资金 + :param virtual: 雪球组合净值 + :return: 换算的资金 + """ + return virtual * self.multiple + + def _get_html(self, url): + return self.s.get(url).text + + def _search_stock_info(self, code): + """ + 通过雪球的接口获取股票详细信息 + :param code: 股票代码 000001 + :return: 查询到的股票 {u'stock_id': 1000279, u'code': u'SH600325', + u'name': u'华发股份', u'ind_color': u'#d9633b', u'chg': -1.09, + u'ind_id': 100014, u'percent': -9.31, u'current': 10.62, + u'hasexist': None, u'flag': 1, u'ind_name': u'房地产', u'type': None, + u'enName': None} + ** flag : 未上市(0)、正常(1)、停牌(2)、涨跌停(3)、退市(4) + """ + data = { + "code": str(code), + "size": "300", + "key": "47bce5c74f", + "market": self.account_config["portfolio_market"], + } + r = self.s.get(self.config["search_stock_url"], params=data) + stocks = json.loads(r.text) + stocks = stocks["stocks"] + stock = None + if len(stocks) > 0: + stock = stocks[0] + return stock + + def _get_portfolio_info(self, portfolio_code): + """ + 获取组合信息 + :return: 字典 + """ + url = self.config["portfolio_url"] + portfolio_code + html = self._get_html(url) + match_info = re.search(r"(?<=SNB.cubeInfo = ).*(?=;\n)", html) + if match_info is None: + raise Exception("cant get portfolio info, portfolio html : {}".format(html)) + try: + portfolio_info = json.loads(match_info.group()) + except Exception as e: + raise Exception("get portfolio info error: {}".format(e)) + return portfolio_info + + def get_balance(self): + """ + 获取账户资金状况 + :return: + """ + portfolio_code = self.account_config.get("portfolio_code", "ch") + portfolio_info = self._get_portfolio_info(portfolio_code) + asset_balance = self._virtual_to_balance( + float(portfolio_info["net_value"]) + ) # 总资产 + position = portfolio_info["view_rebalancing"] # 仓位结构 + cash = asset_balance * float(position["cash"]) / 100 + market = asset_balance - cash + return [ + { + "asset_balance": asset_balance, + "current_balance": cash, + "enable_balance": cash, + "market_value": market, + "money_type": "人民币", + "pre_interest": 0.25, + } + ] + + def _get_position(self): + """ + 获取雪球持仓 + :return: + """ + portfolio_code = self.account_config["portfolio_code"] + portfolio_info = self._get_portfolio_info(portfolio_code) + position = portfolio_info["view_rebalancing"] # 仓位结构 + stocks = position["holdings"] # 持仓股票 + return stocks + + @staticmethod + def _time_strftime(time_stamp): + try: + local_time = time.localtime(time_stamp / 1000) + return time.strftime("%Y-%m-%d %H:%M:%S", local_time) + # pylint: disable=broad-except + except Exception: + return time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()) + + def get_position(self): + """ + 获取持仓 + :return: + """ + xq_positions = self._get_position() + balance = self.get_balance()[0] + position_list = [] + for pos in xq_positions: + volume = pos["weight"] * balance["asset_balance"] / 100 + position_list.append( + { + "cost_price": volume / 100, + "current_amount": 100, + "enable_amount": 100, + "income_balance": 0, + "keep_cost_price": volume / 100, + "last_price": volume / 100, + "market_value": volume, + "position_str": "random", + "stock_code": pos["stock_symbol"], + "stock_name": pos["stock_name"], + } + ) + return position_list + + def _get_xq_history(self): + """ + 获取雪球调仓历史 + :param instance: + :param owner: + :return: + """ + data = { + "cube_symbol": str(self.account_config["portfolio_code"]), + "count": 20, + "page": 1, + } + resp = self.s.get(self.config["history_url"], params=data) + res = json.loads(resp.text) + return res["list"] + + @property + def history(self): + return self._get_xq_history() + + def get_entrust(self): + """ + 获取委托单(目前返回20次调仓的结果) + 操作数量都按1手模拟换算的 + :return: + """ + xq_entrust_list = self._get_xq_history() + entrust_list = [] + replace_none = lambda s: s or 0 # noqa: E731 + for xq_entrusts in xq_entrust_list: + status = xq_entrusts["status"] # 调仓状态 + if status == "pending": + status = "已报" + elif status in ["canceled", "failed"]: + status = "废单" + else: + status = "已成" + for entrust in xq_entrusts["rebalancing_histories"]: + price = entrust["price"] + entrust_list.append( + { + "entrust_no": entrust["id"], + "entrust_bs": ( + "买入" + if entrust["target_weight"] + > replace_none(entrust["prev_weight"]) + else "卖出" + ), + "report_time": self._time_strftime(entrust["updated_at"]), + "entrust_status": status, + "stock_code": entrust["stock_symbol"], + "stock_name": entrust["stock_name"], + "business_amount": 100, + "business_price": price, + "entrust_amount": 100, + "entrust_price": price, + } + ) + return entrust_list + + def cancel_entrust(self, entrust_no): + """ + 对未成交的调仓进行伪撤单 + :param entrust_no: + :return: + """ + xq_entrust_list = self._get_xq_history() + is_have = False + for xq_entrusts in xq_entrust_list: + status = xq_entrusts["status"] # 调仓状态 + for entrust in xq_entrusts["rebalancing_histories"]: + if entrust["id"] == entrust_no and status == "pending": + is_have = True + buy_or_sell = ( + "buy" + if entrust["target_weight"] < entrust["weight"] + else "sell" + ) + if entrust["target_weight"] == 0 and entrust["weight"] == 0: + raise exceptions.TradeError( + "移除的股票操作无法撤销,建议重新买入" + ) + balance = self.get_balance()[0] + volume = ( + abs(entrust["target_weight"] - entrust["weight"]) + * balance["asset_balance"] + / 100 + ) + r = self._trade( + security=entrust["stock_symbol"], + volume=volume, + entrust_bs=buy_or_sell, + ) + if len(r) > 0 and "error_info" in r[0]: + raise exceptions.TradeError( + "撤销失败!%s" % ("error_info" in r[0]) + ) + if not is_have: + raise exceptions.TradeError("撤销对象已失效") + return True + + def adjust_weight(self, stock_code, weight): + """ + 雪球组合调仓, weight 为调整后的仓位比例 + :param stock_code: str 股票代码 + :param weight: float 调整之后的持仓百分比, 0 - 100 之间的浮点数 + """ + + stock = self._search_stock_info(stock_code) + if stock is None: + raise exceptions.TradeError("没有查询要操作的股票信息") + if stock["flag"] != 1: + raise exceptions.TradeError("未上市、停牌、涨跌停、退市的股票无法操作。") + + # 仓位比例向下取两位数 + weight = round(weight, 2) + # 获取原有仓位信息 + position_list = self._get_position() + + # 调整后的持仓 + for position in position_list: + if position["stock_id"] == stock["stock_id"]: + position["proactive"] = True + position["weight"] = weight + + if weight != 0 and stock["stock_id"] not in [ + k["stock_id"] for k in position_list + ]: + position_list.append( + { + "code": stock["code"], + "name": stock["name"], + "enName": stock["enName"], + "hasexist": stock["hasexist"], + "flag": stock["flag"], + "type": stock["type"], + "current": stock["current"], + "chg": stock["chg"], + "percent": str(stock["percent"]), + "stock_id": stock["stock_id"], + "ind_id": stock["ind_id"], + "ind_name": stock["ind_name"], + "ind_color": stock["ind_color"], + "textname": stock["name"], + "segment_name": stock["ind_name"], + "weight": weight, + "url": "/S/" + stock["code"], + "proactive": True, + "price": str(stock["current"]), + } + ) + + remain_weight = 100 - sum(i.get("weight") for i in position_list) + cash = round(remain_weight, 2) + logger.info("调仓比例:%f, 剩余持仓 :%f", weight, remain_weight) + data = { + "cash": cash, + "holdings": str(json.dumps(position_list)), + "cube_symbol": str(self.account_config["portfolio_code"]), + "segment": "true", + "comment": "", + } + + try: + resp = self.s.post(self.config["rebalance_url"], data=data) + # pylint: disable=broad-except + except Exception as e: + logger.warning("调仓失败: %s ", e) + return None + logger.info("调仓 %s: 持仓比例%d", stock["name"], weight) + resp_json = json.loads(resp.text) + if "error_description" in resp_json and resp.status_code != 200: + logger.error("调仓错误: %s", resp_json["error_description"]) + return [ + { + "error_no": resp_json["error_code"], + "error_info": resp_json["error_description"], + } + ] + logger.info("调仓成功 %s: 持仓比例%d", stock["name"], weight) + return None + + def _trade(self, security, price=0, amount=0, volume=0, entrust_bs="buy"): + """ + 调仓 + :param security: + :param price: + :param amount: + :param volume: + :param entrust_bs: + :return: + """ + stock = self._search_stock_info(security) + balance = self.get_balance()[0] + if stock is None: + raise exceptions.TradeError("没有查询要操作的股票信息") + if not volume: + volume = int(float(price) * amount) # 可能要取整数 + if balance["current_balance"] < volume and entrust_bs == "buy": + raise exceptions.TradeError("没有足够的现金进行操作") + if stock["flag"] != 1: + raise exceptions.TradeError("未上市、停牌、涨跌停、退市的股票无法操作。") + if volume == 0: + raise exceptions.TradeError("操作金额不能为零") + + # 计算调仓调仓份额 + weight = volume / balance["asset_balance"] * 100 + weight = round(weight, 2) + + # 获取原有仓位信息 + position_list = self._get_position() + + # 调整后的持仓 + is_have = False + for position in position_list: + if position["stock_id"] == stock["stock_id"]: + is_have = True + position["proactive"] = True + old_weight = position["weight"] + if entrust_bs == "buy": + position["weight"] = weight + old_weight + else: + if weight > old_weight: + raise exceptions.TradeError("操作数量大于实际可卖出数量") + else: + position["weight"] = old_weight - weight + position["weight"] = round(position["weight"], 2) + if not is_have: + if entrust_bs == "buy": + position_list.append( + { + "code": stock["code"], + "name": stock["name"], + "enName": stock["enName"], + "hasexist": stock["hasexist"], + "flag": stock["flag"], + "type": stock["type"], + "current": stock["current"], + "chg": stock["chg"], + "percent": str(stock["percent"]), + "stock_id": stock["stock_id"], + "ind_id": stock["ind_id"], + "ind_name": stock["ind_name"], + "ind_color": stock["ind_color"], + "textname": stock["name"], + "segment_name": stock["ind_name"], + "weight": round(weight, 2), + "url": "/S/" + stock["code"], + "proactive": True, + "price": str(stock["current"]), + } + ) + else: + raise exceptions.TradeError("没有持有要卖出的股票") + + if entrust_bs == "buy": + cash = ( + (balance["current_balance"] - volume) / balance["asset_balance"] * 100 + ) + else: + cash = ( + (balance["current_balance"] + volume) / balance["asset_balance"] * 100 + ) + cash = round(cash, 2) + logger.info("weight:%f, cash:%f", weight, cash) + + data = { + "cash": cash, + "holdings": str(json.dumps(position_list)), + "cube_symbol": str(self.account_config["portfolio_code"]), + "segment": 1, + "comment": "", + } + + try: + resp = self.s.post(self.config["rebalance_url"], data=data) + # pylint: disable=broad-except + except Exception as e: + logger.warning("调仓失败: %s ", e) + return None + else: + logger.info("调仓 %s%s: %d", entrust_bs, stock["name"], resp.status_code) + resp_json = json.loads(resp.text) + if "error_description" in resp_json and resp.status_code != 200: + logger.error("调仓错误: %s", resp_json["error_description"]) + return [ + { + "error_no": resp_json["error_code"], + "error_info": resp_json["error_description"], + } + ] + return [ + { + "entrust_no": resp_json["id"], + "init_date": self._time_strftime(resp_json["created_at"]), + "batch_no": "委托批号", + "report_no": "申报号", + "seat_no": "席位编号", + "entrust_time": self._time_strftime(resp_json["updated_at"]), + "entrust_price": price, + "entrust_amount": amount, + "stock_code": security, + "entrust_bs": "买入", + "entrust_type": "雪球虚拟委托", + "entrust_status": "-", + } + ] + + def buy(self, security, price=0, amount=0, volume=0, entrust_prop=0): + """买入卖出股票 + :param security: 股票代码 + :param price: 买入价格 + :param amount: 买入股数 + :param volume: 买入总金额 由 volume / price 取整, 若指定 price 则此参数无效 + :param entrust_prop: + """ + return self._trade(security, price, amount, volume, "buy") + + def sell(self, security, price=0, amount=0, volume=0, entrust_prop=0): + """卖出股票 + :param security: 股票代码 + :param price: 卖出价格 + :param amount: 卖出股数 + :param volume: 卖出总金额 由 volume / price 取整, 若指定 price 则此参数无效 + :param entrust_prop: + """ + return self._trade(security, price, amount, volume, "sell") diff --git a/qbot/engine/trade/easytrader/easytrader/yh_clienttrader.py b/qbot/engine/trade/easytrader/easytrader/yh_clienttrader.py new file mode 100644 index 00000000..29343134 --- /dev/null +++ b/qbot/engine/trade/easytrader/easytrader/yh_clienttrader.py @@ -0,0 +1,129 @@ +# -*- coding: utf-8 -*- +import re +import tempfile + +import pywinauto + +from easytrader import clienttrader, grid_strategies +from easytrader.utils.captcha import recognize_verify_code + + +class YHClientTrader(clienttrader.BaseLoginClientTrader): + """ + Changelog: + + 2018.07.01: + 银河客户端 2018.5.11 更新后不再支持通过剪切板复制获取 Grid 内容, + 改为使用保存为 Xls 再读取的方式获取 + """ + + grid_strategy = grid_strategies.Xls + + @property + def broker_type(self): + return "yh" + + def login(self, user, password, exe_path, comm_password=None, **kwargs): + """ + 登陆客户端 + :param user: 账号 + :param password: 明文密码 + :param exe_path: 客户端路径类似 'C:\\中国银河证券双子星3.2\\Binarystar.exe', + 默认 'C:\\中国银河证券双子星3.2\\Binarystar.exe' + :param comm_password: 通讯密码, 华泰需要,可不设 + :return: + """ + try: + self._app = pywinauto.Application().connect( + path=self._run_exe_path(exe_path), timeout=1 + ) + # pylint: disable=broad-except + except Exception: + self._app = pywinauto.Application().start(exe_path) + is_xiadan = True if "xiadan.exe" in exe_path else False + # wait login window ready + while True: + try: + self._app.top_window().Edit1.wait("ready") + break + except RuntimeError: + pass + + self._app.top_window().Edit1.type_keys(user) + self._app.top_window().Edit2.type_keys(password) + while True: + self._app.top_window().Edit3.type_keys( + self._handle_verify_code(is_xiadan) + ) + if is_xiadan: + self._app.top_window().child_window(control_id=1006, class_name="Button").click() + else: + self._app.top_window()["登录"].click() + + # detect login is success or not + try: + self._app.top_window().wait_not("exists visible", 10) + break + # pylint: disable=broad-except + except Exception: + if is_xiadan: + self._app.top_window()["确定"].click() + + self._app = pywinauto.Application().connect( + path=self._run_exe_path(exe_path), timeout=10 + ) + self._close_prompt_windows() + self._main = self._app.window(title="网上股票交易系统5.0") + try: + self._main.child_window( + control_id=129, class_name="SysTreeView32" + ).wait("ready", 2) + # pylint: disable=broad-except + except Exception: + self.wait(2) + self._switch_window_to_normal_mode() + + def _switch_window_to_normal_mode(self): + self._app.top_window().child_window( + control_id=32812, class_name="Button" + ).click() + + def _handle_verify_code(self, is_xiadan): + control = self._app.top_window().child_window( + control_id=1499 if is_xiadan else 22202 + ) + control.click() + + file_path = tempfile.mktemp() + if is_xiadan: + rect = control.element_info.rectangle + rect.right = round( + rect.right + (rect.right - rect.left) * 0.3 + ) # 扩展验证码控件截图范围为4个字符 + control.capture_as_image(rect).save(file_path, "jpeg") + else: + control.capture_as_image().save(file_path, "jpeg") + verify_code = recognize_verify_code(file_path, "yh_client") + return "".join(re.findall(r"\d+", verify_code)) + + @property + def balance(self): + self._switch_left_menus(self._config.BALANCE_MENU_PATH) + return self._get_grid_data(self._config.BALANCE_GRID_CONTROL_ID) + + def auto_ipo(self): + self._switch_left_menus(self._config.AUTO_IPO_MENU_PATH) + stock_list = self._get_grid_data(self._config.COMMON_GRID_CONTROL_ID) + if len(stock_list) == 0: + return {"message": "今日无新股"} + invalid_list_idx = [ + i for i, v in enumerate(stock_list) if v["申购数量"] <= 0 + ] + if len(stock_list) == len(invalid_list_idx): + return {"message": "没有发现可以申购的新股"} + self.wait(0.1) + # for row in invalid_list_idx: + # self._click_grid_by_row(row) + self._click(self._config.AUTO_IPO_BUTTON_CONTROL_ID) + self.wait(0.1) + return self._handle_pop_dialogs() diff --git a/qbot/engine/trade/easytrader/gj_client.json b/qbot/engine/trade/easytrader/gj_client.json new file mode 100644 index 00000000..e20ebf09 --- /dev/null +++ b/qbot/engine/trade/easytrader/gj_client.json @@ -0,0 +1,4 @@ +{ + "user": "国金用户名", + "password": "国金明文密码" +} \ No newline at end of file diff --git a/qbot/engine/trade/easytrader/mkdocs.yml b/qbot/engine/trade/easytrader/mkdocs.yml new file mode 100644 index 00000000..d1810457 --- /dev/null +++ b/qbot/engine/trade/easytrader/mkdocs.yml @@ -0,0 +1,8 @@ +site_name: easytrader +pages: + - Home: index.md + - 安装: install.md + - 使用: usage.md + - 常见问题: help.md + - 其他: 'other/xueqiu.md' +theme: readthedocs diff --git a/qbot/engine/trade/easytrader/mypy.ini b/qbot/engine/trade/easytrader/mypy.ini new file mode 100644 index 00000000..976ba029 --- /dev/null +++ b/qbot/engine/trade/easytrader/mypy.ini @@ -0,0 +1,2 @@ +[mypy] +ignore_missing_imports = True diff --git a/qbot/engine/trade/easytrader/readthedocs-requirements.txt b/qbot/engine/trade/easytrader/readthedocs-requirements.txt new file mode 100644 index 00000000..e69de29b diff --git a/qbot/engine/trade/easytrader/requirements.txt b/qbot/engine/trade/easytrader/requirements.txt new file mode 100644 index 00000000..a101ca4f --- /dev/null +++ b/qbot/engine/trade/easytrader/requirements.txt @@ -0,0 +1,31 @@ +-i http://mirrors.aliyun.com/pypi/simple/ +--trusted-host mirrors.aliyun.com +beautifulsoup4==4.6.0 +bs4==0.0.1 +certifi==2018.4.16 +chardet==3.0.4 +click==6.7 +cssselect==1.0.3; python_version != '3.3.*' +dill==0.2.8.2 +easyutils==0.1.7 +flask==1.0.2 +idna==2.7 +itsdangerous==0.24 +jinja2==2.10 +lxml==4.2.3 +markupsafe==1.0 +numpy==1.15.0; python_version >= '2.7' +pandas==0.23.3 +pillow==5.2.0 +pyperclip==1.6.4 +pyquery==1.4.0; python_version != '3.0.*' +pytesseract==0.2.4 +python-dateutil==2.7.3 +python-xlib==0.23 +pytz==2018.5 +pywinauto==0.6.6 +requests==2.19.1 +six==1.11.0 +urllib3==1.23; python_version != '3.1.*' +werkzeug==0.14.1 + diff --git a/qbot/engine/trade/easytrader/setup.py b/qbot/engine/trade/easytrader/setup.py new file mode 100644 index 00000000..61a540c2 --- /dev/null +++ b/qbot/engine/trade/easytrader/setup.py @@ -0,0 +1,113 @@ +# coding:utf8 +from setuptools import setup + +long_desc = """ +easytrader +=============== + +* easy to use to trade in China Stock + +Installation +-------------- + +pip install easytrader + +Upgrade +--------------- + + pip install easytrader --upgrade + +Quick Start +-------------- + +:: + + import easytrader + + user = easytrader.use('ht') + + user.prepare('account.json') + + user.balance + +return:: + + [{ 'asset_balance': '资产总值', + 'current_balance': '当前余额', + 'enable_balance': '可用金额', + 'market_value': '证券市值', + 'money_type': '币种', + 'pre_interest': '预计利息' ]} + + user.position + +return:: + + [{'cost_price': '摊薄成本价', + 'current_amount': '当前数量', + 'enable_amount': '可卖数量', + 'income_balance': '摊薄浮动盈亏', + 'keep_cost_price': '保本价', + 'last_price': '最新价', + 'market_value': '证券市值', + 'position_str': '定位串', + 'stock_code': '证券代码', + 'stock_name': '证券名称'}] + + user.entrust + +return:: + + [{'business_amount': '成交数量', + 'business_price': '成交价格', + 'entrust_amount': '委托数量', + 'entrust_bs': '买卖方向', + 'entrust_no': '委托编号', + 'entrust_price': '委托价格', + 'entrust_status': '委托状态', # 废单 / 已报 + 'report_time': '申报时间', + 'stock_code': '证券代码', + 'stock_name': '证券名称'}] + + user.buy('162411', price=5.55) + + user.sell('16411', price=5.65) + +""" + +setup( + name="easytrader", + version="0.23.0", + description="A utility for China Stock Trade", + long_description=long_desc, + author="shidenggui", + author_email="longlyshidenggui@gmail.com", + license="BSD", + url="https://github.com/shidenggui/easytrader", + keywords="China stock trade", + install_requires=[ + "requests", + "six", + "easyutils", + "flask", + "pywinauto==0.6.6", + "pillow", + "pandas", + ], + classifiers=[ + "Development Status :: 4 - Beta", + "Programming Language :: Python :: 2.6", + "Programming Language :: Python :: 2.7", + "Programming Language :: Python :: 3.2", + "Programming Language :: Python :: 3.3", + "Programming Language :: Python :: 3.4", + "Programming Language :: Python :: 3.5", + "License :: OSI Approved :: BSD License", + ], + packages=["easytrader", "easytrader.config", "easytrader.utils"], + package_data={ + "": ["*.jar", "*.json"], + "config": ["config/*.json"], + "thirdlibrary": ["thirdlibrary/*.jar"], + }, +) diff --git a/qbot/engine/trade/easytrader/test-requirements.txt b/qbot/engine/trade/easytrader/test-requirements.txt new file mode 100644 index 00000000..edfca411 --- /dev/null +++ b/qbot/engine/trade/easytrader/test-requirements.txt @@ -0,0 +1,5 @@ +-r requirements.txt + +pytest +pytest-cov + diff --git a/qbot/engine/trade/easytrader/tests/__init__.py b/qbot/engine/trade/easytrader/tests/__init__.py new file mode 100644 index 00000000..8288f42b --- /dev/null +++ b/qbot/engine/trade/easytrader/tests/__init__.py @@ -0,0 +1 @@ +# coding:utf8 diff --git a/qbot/engine/trade/easytrader/tests/test_easytrader.py b/qbot/engine/trade/easytrader/tests/test_easytrader.py new file mode 100644 index 00000000..dd2f4599 --- /dev/null +++ b/qbot/engine/trade/easytrader/tests/test_easytrader.py @@ -0,0 +1,182 @@ +# coding: utf-8 +import os +import sys +import time +import unittest + +sys.path.append(".") + +TEST_CLIENTS = set(os.environ.get("EZ_TEST_CLIENTS", "").split(",")) + +IS_WIN_PLATFORM = sys.platform != "darwin" + + +@unittest.skipUnless("yh" in TEST_CLIENTS and IS_WIN_PLATFORM, "skip yh test") +class TestYhClientTrader(unittest.TestCase): + @classmethod + def setUpClass(cls): + import easytrader + + if "yh" not in TEST_CLIENTS: + return + + # input your test account and password + cls._ACCOUNT = os.environ.get("EZ_TEST_YH_ACCOUNT") or "your account" + cls._PASSWORD = os.environ.get("EZ_TEST_YH_PASSWORD") or "your password" + + cls._user = easytrader.use("yh_client") + cls._user.prepare(user=cls._ACCOUNT, password=cls._PASSWORD) + + def test_balance(self): + time.sleep(3) + result = self._user.balance + + def test_today_entrusts(self): + result = self._user.today_entrusts + + def test_today_trades(self): + result = self._user.today_trades + + def test_cancel_entrusts(self): + result = self._user.cancel_entrusts + + def test_cancel_entrust(self): + result = self._user.cancel_entrust("123456789") + + def test_invalid_buy(self): + import easytrader + + with self.assertRaises(easytrader.exceptions.TradeError): + result = self._user.buy("511990", 1, 1e10) + + def test_invalid_sell(self): + import easytrader + + with self.assertRaises(easytrader.exceptions.TradeError): + result = self._user.sell("162411", 200, 1e10) + + def test_auto_ipo(self): + self._user.auto_ipo() + + +@unittest.skipUnless("ht" in TEST_CLIENTS and IS_WIN_PLATFORM, "skip ht test") +class TestHTClientTrader(unittest.TestCase): + @classmethod + def setUpClass(cls): + import easytrader + + if "ht" not in TEST_CLIENTS: + return + + # input your test account and password + cls._ACCOUNT = os.environ.get("EZ_TEST_HT_ACCOUNT") or "your account" + cls._PASSWORD = os.environ.get("EZ_TEST_HT_PASSWORD") or "your password" + cls._COMM_PASSWORD = ( + os.environ.get("EZ_TEST_HT_COMM_PASSWORD") or "your comm password" + ) + + cls._user = easytrader.use("ht_client") + cls._user.prepare( + user=cls._ACCOUNT, password=cls._PASSWORD, comm_password=cls._COMM_PASSWORD + ) + + def test_balance(self): + time.sleep(3) + result = self._user.balance + + def test_today_entrusts(self): + result = self._user.today_entrusts + + def test_today_trades(self): + result = self._user.today_trades + + def test_cancel_entrusts(self): + result = self._user.cancel_entrusts + + def test_cancel_entrust(self): + result = self._user.cancel_entrust("123456789") + + def test_invalid_buy(self): + import easytrader + + with self.assertRaises(easytrader.exceptions.TradeError): + result = self._user.buy("511990", 1, 1e10) + + def test_invalid_sell(self): + import easytrader + + with self.assertRaises(easytrader.exceptions.TradeError): + result = self._user.sell("162411", 200, 1e10) + + def test_auto_ipo(self): + self._user.auto_ipo() + + def test_invalid_repo(self): + import easytrader + + with self.assertRaises(easytrader.exceptions.TradeError): + result = self._user.repo("204001", 100, 1) + + def test_invalid_reverse_repo(self): + import easytrader + + with self.assertRaises(easytrader.exceptions.TradeError): + result = self._user.reverse_repo("204001", 1, 100) + + +@unittest.skipUnless("htzq" in TEST_CLIENTS and IS_WIN_PLATFORM, "skip htzq test") +class TestHTZQClientTrader(unittest.TestCase): + @classmethod + def setUpClass(cls): + import easytrader + + if "htzq" not in TEST_CLIENTS: + return + + # input your test account and password + cls._ACCOUNT = os.environ.get("EZ_TEST_HTZQ_ACCOUNT") or "your account" + cls._PASSWORD = os.environ.get("EZ_TEST_HTZQ_PASSWORD") or "your password" + cls._COMM_PASSWORD = ( + os.environ.get("EZ_TEST_HTZQ_COMM_PASSWORD") or "your comm password" + ) + + cls._user = easytrader.use("htzq_client") + + cls._user.prepare( + user=cls._ACCOUNT, password=cls._PASSWORD, comm_password=cls._COMM_PASSWORD + ) + + def test_balance(self): + time.sleep(3) + result = self._user.balance + + def test_today_entrusts(self): + result = self._user.today_entrusts + + def test_today_trades(self): + result = self._user.today_trades + + def test_cancel_entrusts(self): + result = self._user.cancel_entrusts + + def test_cancel_entrust(self): + result = self._user.cancel_entrust("123456789") + + def test_invalid_buy(self): + import easytrader + + with self.assertRaises(easytrader.exceptions.TradeError): + result = self._user.buy("511990", 1, 1e10) + + def test_invalid_sell(self): + import easytrader + + with self.assertRaises(easytrader.exceptions.TradeError): + result = self._user.sell("162411", 200, 1e10) + + def test_auto_ipo(self): + self._user.auto_ipo() + + +if __name__ == "__main__": + unittest.main(verbosity=2) diff --git a/qbot/engine/trade/easytrader/tests/test_xq_follower.py b/qbot/engine/trade/easytrader/tests/test_xq_follower.py new file mode 100644 index 00000000..dec9a690 --- /dev/null +++ b/qbot/engine/trade/easytrader/tests/test_xq_follower.py @@ -0,0 +1,240 @@ +# coding:utf-8 +import datetime +import os +import time +import unittest +from unittest import mock + +from easytrader.xq_follower import XueQiuFollower + + +class TestXueQiuTrader(unittest.TestCase): + def test_adjust_sell_amount_without_enable(self): + follower = XueQiuFollower() + + mock_user = mock.MagicMock() + follower._users = [mock_user] + + follower._adjust_sell = False + amount = follower._adjust_sell_amount("169101", 1000) + self.assertEqual(amount, amount) + + def test_adjust_sell_should_only_work_when_sell(self): + follower = XueQiuFollower() + follower._adjust_sell = True + test_transaction = { + "weight": 10, + "prev_weight": 0, + "price": 10, + "stock_symbol": "162411", + "created_at": int(time.time() * 1000), + } + test_assets = 1000 + + mock_adjust_sell_amount = mock.MagicMock() + follower._adjust_sell_amount = mock_adjust_sell_amount + + follower.project_transactions( + transactions=[test_transaction], assets=test_assets + ) + mock_adjust_sell_amount.assert_not_called() + + mock_adjust_sell_amount.reset_mock() + test_transaction["prev_weight"] = test_transaction["weight"] + 1 + follower.project_transactions( + transactions=[test_transaction], assets=test_assets + ) + mock_adjust_sell_amount.assert_called() + + def test_adjust_sell_amount(self): + follower = XueQiuFollower() + + mock_user = mock.MagicMock() + follower._users = [mock_user] + mock_user.position = TEST_POSITION + + follower._adjust_sell = True + test_cases = [ + ("169101", 600, 600), + ("169101", 700, 600), + ("000000", 100, 100), + ("sh169101", 700, 600), + ] + for stock_code, sell_amount, excepted_amount in test_cases: + amount = follower._adjust_sell_amount(stock_code, sell_amount) + self.assertEqual(amount, excepted_amount) + + def test_slippage_with_default(self): + follower = XueQiuFollower() + mock_user = mock.MagicMock() + + # test default no slippage + test_price = 1.0 + test_trade_cmd = { + "strategy": "test_strategy", + "strategy_name": "test_strategy", + "action": "buy", + "stock_code": "162411", + "amount": 100, + "price": 1.0, + "datetime": datetime.datetime.now(), + } + follower._execute_trade_cmd( + trade_cmd=test_trade_cmd, + users=[mock_user], + expire_seconds=10, + entrust_prop="limit", + send_interval=10, + ) + _, kwargs = getattr(mock_user, test_trade_cmd["action"]).call_args + self.assertAlmostEqual(kwargs["price"], test_price) + + def test_slippage(self): + follower = XueQiuFollower() + mock_user = mock.MagicMock() + + test_price = 1.0 + follower.slippage = 0.05 + + # test buy + test_trade_cmd = { + "strategy": "test_strategy", + "strategy_name": "test_strategy", + "action": "buy", + "stock_code": "162411", + "amount": 100, + "price": 1.0, + "datetime": datetime.datetime.now(), + } + follower._execute_trade_cmd( + trade_cmd=test_trade_cmd, + users=[mock_user], + expire_seconds=10, + entrust_prop="limit", + send_interval=10, + ) + excepted_price = test_price * (1 + follower.slippage) + _, kwargs = getattr(mock_user, test_trade_cmd["action"]).call_args + self.assertAlmostEqual(kwargs["price"], excepted_price) + + # test sell + test_trade_cmd["action"] = "sell" + follower._execute_trade_cmd( + trade_cmd=test_trade_cmd, + users=[mock_user], + expire_seconds=10, + entrust_prop="limit", + send_interval=10, + ) + excepted_price = test_price * (1 - follower.slippage) + _, kwargs = getattr(mock_user, test_trade_cmd["action"]).call_args + self.assertAlmostEqual(kwargs["price"], excepted_price) + + +class TestXqFollower(unittest.TestCase): + def setUp(self): + self.follower = XueQiuFollower() + cookies = os.getenv("EZ_TEST_XQ_COOKIES") + if not cookies: + return + self.follower.login(cookies=cookies) + + def test_extract_transactions(self): + result = self.follower.extract_transactions(TEST_XQ_PORTOFOLIO_HISTORY) + self.assertTrue(len(result) == 1) + + +TEST_POSITION = [ + { + "Unnamed: 14": "", + "买入冻结": 0, + "交易市场": "深A", + "卖出冻结": 0, + "参考市价": 1.464, + "参考市值": 919.39, + "参考成本价": 1.534, + "参考盈亏": -43.77, + "可用余额": 628, + "当前持仓": 628, + "盈亏比例(%)": -4.544, + "股东代码": "0000000000", + "股份余额": 628, + "证券代码": "169101", + } +] + +TEST_XQ_PORTOFOLIO_HISTORY = { + "count": 1, + "page": 1, + "totalCount": 17, + "list": [ + { + "id": 1, + "status": "pending", + "cube_id": 1, + "prev_bebalancing_id": 1, + "category": "user_rebalancing", + "exe_strategy": "intraday_all", + "created_at": 1, + "updated_at": 1, + "cash_value": 0.1, + "cash": 100.0, + "error_code": "1", + "error_message": None, + "error_status": None, + "holdings": None, + "rebalancing_histories": [ + { + "id": 1, + "rebalancing_id": 1, + "stock_id": 1023662, + "stock_name": "华宝油气", + "stock_symbol": "SZ162411", + "volume": 0.0, + "price": None, + "net_value": 0.0, + "weight": 0.0, + "target_weight": 0.1, + "prev_weight": None, + "prev_target_weight": None, + "prev_weight_adjusted": None, + "prev_volume": None, + "prev_price": None, + "prev_net_value": None, + "proactive": True, + "created_at": 1554339333333, + "updated_at": 1554339233333, + "target_volume": 0.00068325, + "prev_target_volume": None, + }, + { + "id": 2, + "rebalancing_id": 1, + "stock_id": 1023662, + "stock_name": "华宝油气", + "stock_symbol": "SZ162411", + "volume": 0.0, + "price": 0.55, + "net_value": 0.0, + "weight": 0.0, + "target_weight": 0.1, + "prev_weight": None, + "prev_target_weight": None, + "prev_weight_adjusted": None, + "prev_volume": None, + "prev_price": None, + "prev_net_value": None, + "proactive": True, + "created_at": 1554339333333, + "updated_at": 1554339233333, + "target_volume": 0.00068325, + "prev_target_volume": None, + }, + ], + "comment": "", + "diff": 0.0, + "new_buy_count": 0, + } + ], + "maxPage": 17, +} diff --git a/qbot/engine/trade/easytrader/tests/test_xqtrader.py b/qbot/engine/trade/easytrader/tests/test_xqtrader.py new file mode 100644 index 00000000..22abf274 --- /dev/null +++ b/qbot/engine/trade/easytrader/tests/test_xqtrader.py @@ -0,0 +1,18 @@ +# coding: utf-8 +import unittest + +from easytrader.xqtrader import XueQiuTrader + + +class TestXueQiuTrader(unittest.TestCase): + def test_prepare_account(self): + user = XueQiuTrader() + params_without_cookies = dict( + portfolio_code="ZH123456", portfolio_market="cn" + ) + with self.assertRaises(TypeError): + user._prepare_account(**params_without_cookies) + + params_without_cookies.update(cookies="123") + user._prepare_account(**params_without_cookies) + self.assertEqual(params_without_cookies, user.account_config) diff --git a/qbot/engine/trade/easytrader/xueqiu.json b/qbot/engine/trade/easytrader/xueqiu.json new file mode 100644 index 00000000..9690b683 --- /dev/null +++ b/qbot/engine/trade/easytrader/xueqiu.json @@ -0,0 +1,5 @@ +{ + "cookies": "雪球 cookies,登陆后获取,获取方式见 https://smalltool.github.io/2016/08/02/cookie/", + "portfolio_code": "组合代码(例:ZH818559)", + "portfolio_market": "交易市场(例:us 或者 cn 或者 hk)" +} diff --git a/qbot/engine/trade/easytrader/yh_client.json b/qbot/engine/trade/easytrader/yh_client.json new file mode 100644 index 00000000..eb862fd9 --- /dev/null +++ b/qbot/engine/trade/easytrader/yh_client.json @@ -0,0 +1,4 @@ +{ + "user": "银河用户名", + "password": "银河明文密码" +} \ No newline at end of file diff --git a/qbot/engine/trade/engine_apis/.gitignore b/qbot/engine/trade/engine_apis/.gitignore new file mode 100644 index 00000000..b952da9b --- /dev/null +++ b/qbot/engine/trade/engine_apis/.gitignore @@ -0,0 +1 @@ +**/*.json \ No newline at end of file diff --git a/qbot/engine/trade/engine_apis/btc/account.json.example b/qbot/engine/trade/engine_apis/btc/account.json.example new file mode 100644 index 00000000..b7c87caa --- /dev/null +++ b/qbot/engine/trade/engine_apis/btc/account.json.example @@ -0,0 +1,29 @@ +{ + "okx": { + "uid": "", + "apikey": "", + "secretkey": "", + "IP": "", + "备注名": "qbot", + "权限": "读取/交易", + "vip_channel": "https://www.cnouyi.social/join/57246734" + }, + "binance": { + "uid": "", + "apikey": "", + "secretkey": "", + "IP": "", + "备注名": "qbot", + "权限": "读取/交易", + "vip_channel": "https://accounts.binance.com/register?ref=130173909" + }, + "huobi": { + "uid": "", + "apikey": "", + "secretkey": "", + "IP": "", + "备注名": "qbot", + "权限": "读取/交易", + "vip_channel": "https://www.htx.com/invite/zh-cn/1f?invite_code=wr938223" + } +} \ No newline at end of file diff --git a/qbot/engine/trade/engine_apis/btc/btc_engine.py b/qbot/engine/trade/engine_apis/btc/btc_engine.py new file mode 100644 index 00000000..cf5c8027 --- /dev/null +++ b/qbot/engine/trade/engine_apis/btc/btc_engine.py @@ -0,0 +1,107 @@ +from qbot.engine.trade.engine_apis.btc.btc_trade_engine import ( + BinanceTradeEngine, + CcxtTradeEngine, + # HuobiTradeEngine, + OkxTradeEngine, +) + + +class BtcTradeEngine: + def __init__(self, account, trade_opts: dict, syslog_obj=None): + self.account = account + self.strategy = trade_opts["strategy"] + self.syslog = syslog_obj + self.trade_engine = None + + if trade_opts["platform"] == "欧易OKX": + self.trade_engine = OkxTradeEngine(self.account, trade_opts, syslog_obj) + elif trade_opts["platform"] == "币安Binance": + self.trade_engine = BinanceTradeEngine(self.account, trade_opts, syslog_obj) + else: + self.trade_engine = CcxtTradeEngine(self.account, trade_opts, syslog_obj) + + if not self.trade_engine: + logger.error("trade engine is null") + return + + def login(self): + uid = self.account["uid"] + apikey = self.account["apikey"] + secretkey = self.account["secretkey"] + + print(uid, apikey, secretkey) + + def start_trade(self): + self.syslog.re_print("BtcTradeEngine start trade ...\n") + pass + + def get_balance(self): + pass + + def get_positions(self): + # 获取登录账户的持仓,如登录多个账户需要指定账户ID + poses = self.trade_engine.get_positions() + print(f"get_positions poes={poses}") + + def get_all_tickers(self): + pass + + def get_order_book(self, symbol="BTCUSDT"): + pass + + def get_account(self): + pass + + def get_asset_balance(self): + pass + + def order_market_buy(self, symbol, quantity): + pass + + +if __name__ == "__main__": + trade_opts = { + "class": "虚拟盘", + "platform": "欧易OKX", + "trade_type": "BTC", + "trade_code": "ETHUSDT", + "strategy": "单因子-相对强弱指数RSI", + } + + from qbot.common.file_utils import file2dict + from qbot.engine.config import BTC_REAL_ACCOUNT, BTC_SIM_ACCOUNT + + # 实盘交易 + real_accounts = file2dict(BTC_SIM_ACCOUNT) + print(real_accounts[trade_opts["platform"]]) + + trade_engine = BtcTradeEngine( + account=real_accounts[trade_opts["platform"]], + trade_opts=trade_opts, + syslog_obj=None, + ) + trade_engine.login() + trade_engine.get_balance() + trade_engine.get_positions() + trade_engine.start_trade() + if trade_opts["platform"] not in real_accounts: + logger.error("当前还不支持该平台, 请联系微信 Yida_Zhang2") + + run_sim_test = False + if run_sim_test: + # 虚拟交易 + trade_opts["class"] = "实盘" + trade_opts["platform"] = "BTCUSDT" + sim_accounts = file2dict(BTC_REAL_ACCOUNT) + + trade_engine = BtcTradeEngine( + account=sim_accounts[trade_opts["platform"]], + trade_opts=trade_opts, + syslog_obj=None, + ) + trade_engine.login() + trade_engine.get_balance() + trade_engine.get_position() + trade_engine.start_trade() + if trade_opts["platform"] not in sim_accounts: + logger.error("当前还不支持该平台, 请联系微信 Yida_Zhang2") diff --git a/qbot/engine/trade/engine_apis/btc/btc_trade_engine.py b/qbot/engine/trade/engine_apis/btc/btc_trade_engine.py new file mode 100644 index 00000000..af2d42c9 --- /dev/null +++ b/qbot/engine/trade/engine_apis/btc/btc_trade_engine.py @@ -0,0 +1,495 @@ +from qbot.common.logging.logger import LOGGER as logger + +# ref: https://mp.weixin.qq.com/s/tQCmrQ3iWxND0VPABYWW2g + + +class BinanceTradeEngine: + def __init__(self, account, trade_opts: dict, syslog_obj=None): + self.account = account + self.trade_opts = trade_opts + self.strategy = trade_opts["strategy"] + self.syslog = syslog_obj + + from binance.client import Client + + api_key = self.account["apikey"] + api_secret = self.account["secretkey"] + + logger.info(f"api_key: {api_key}") + logger.info(f"api_secret: {api_secret}") + + self.client = Client(api_key, api_secret) + + # 获取市场价格 + def get_all_tickers(self): + + prices = self.client.get_all_tickers() + logger.info(prices) + return prices + + # 获取订单簿深度 + def get_order_book(self, symbol="BTCUSDT"): + + depth = self.client.get_order_book(symbol) + logger.info(depth) + return depth + + # 获取账户信息 + def get_account(self): + + account = self.client.get_account() + logger.info(account) + return account + + # 获取账户余额 + def get_balance(self, asset="BTC"): + + balances = self.client.get_asset_balance(asset) + logger.info(balances) + return balances + + # 获取账户持仓 + def get_positions(self, asset="BTC"): + + balances = self.client.get_positions(asset) + logger.info(balances) + return balances + + # 市价买入 + def order_market_buy(self, symbol="BTCUSDT", quantity=0.001): + from binance.exceptions import BinanceAPIException, BinanceOrderException + + try: + order = self.client.order_market_buy(symbol, quantity) + logger.info(order) + except BinanceAPIException as err: + # 捕获API错误 + logger.error(err) + return err + except BinanceOrderException as err: + # 捕获订单错误 + logger.error(err) + return err + return True + + # 限价卖出 + def order_limit_sell(self, symbol="BTCUSDT", quantity=0.001, price="50000"): + from binance.exceptions import BinanceAPIException, BinanceOrderException + + try: + order = self.client.order_limit_sell(symbol, quantity, price) + logger.info(order) + except BinanceAPIException as err: + # 捕获API错误 + logger.error(err) + return err + except BinanceOrderException as err: + # 捕获订单错误 + logger.error(err) + return err + return True + + +import base64 +# import hashlib +import hmac +import json +import time + +import requests + + +class OkxTradeEngine: + def __init__(self, account, trade_opts: dict, syslog_obj=None): + self.account = account + self.trade_opts = trade_opts + self.strategy = trade_opts["strategy"] + self.syslog = syslog_obj + + # 替换为你的API密钥、秘密密钥和Passphrase + api_key = self.account["apikey"] + api_secret = self.account["secretkey"] + passphrase = self.account["passphrase"] + + # OKX API基础URL + self.base_url = "https://www.okx.com" + + def sign(self, message, secret): + mac = hmac.new( + bytes(secret, encoding="utf8"), + bytes(message, encoding="utf-8"), + digestmod="sha256", + ) + return base64.b64encode(mac.digest()).decode() + + def get_timestamp(self): + return str(int(time.time())) + + def get_headers(self, method, endpoint, api_key="", api_secret="", passphrase=""): + timestamp = self.get_timestamp() + message = timestamp + method + endpoint + signature = self.sign(message, self.api_secret) + + headers = { + "OK-ACCESS-KEY": self.api_key, + "OK-ACCESS-SIGN": signature, + "OK-ACCESS-TIMESTAMP": timestamp, + "OK-ACCESS-PASSPHRASE": self.passphrase, + "Content-Type": "application/json", + } + return headers + + # 获取BTC/USDT市场价格 + def get_ticker(self, symbol): + endpoint = f"/api/v5/market/ticker?instId={symbol}" + url = self.base_url + endpoint + response = requests.get(url) + return response.json() + + # 获取市场价格 + def get_all_tickers(self): + + pass + + # 获取账户持仓 + def get_positions(self): + + pass + + # 获取订单簿深度 + def get_order_book(self, symbol="BTCUSDT"): + + pass + + # 获取账户信息 + def get_account(self): + + account = self.client.get_account() + logger.info(account) + return account + + # 获取账户余额 + def get_balance(self, asset="BTC"): + + def get_account_balance(): + endpoint = "/api/v5/account/balance" + url = self.base_url + endpoint + headers = self.get_headers("GET", endpoint) + response = requests.get(url, headers=headers) + return response.json() + + try: + balance = get_account_balance() + print(json.dumps(balance, indent=4)) + return balance + except requests.exceptions.RequestException as err: + logger.error(err) + except Exception as err: + logger.error(err) + + def order_market_buy(self, symbol="BTCUSDT", quantity=0.001, side="buy"): + return self.place_order(symbol, quantity, side) + + def order_limit_sell_2( + self, symbol="BTCUSDT", quantity=0.001, side="sell", price="50000" + ): + return self.place_order(symbol, quantity, side, price) + + # 市价买入 + def place_order(self, symbol="BTCUSDT", quantity=0.001, side="buy"): + endpoint = "/api/v5/trade/order" + url = base_url + endpoint + + order_data = { + "instId": symbol, + "tdMode": "cash", # "cash" for spot trading + "side": side, + "ordType": "limit" if price else "market", + "sz": quantity, + } + if price: + order_data["px"] = price + + body = json.dumps(order_data) + headers = self.get_headers("POST", endpoint) + response = requests.post(url, headers=headers, data=body) + return response.json() + + # 限价卖出 + def order_limit_sell(self, symbol="BTCUSDT", quantity=0.001, price="50000"): + from binance.exceptions import BinanceAPIException, BinanceOrderException + + try: + order = self.client.order_limit_sell(symbol, quantity, price) + logger.info(order) + except BinanceAPIException as err: + # 捕获API错误 + logger.error(err) + return err + except BinanceOrderException as err: + # 捕获订单错误 + logger.error(err) + return err + return True + + +class HuobiTradeEngine: + def __init__(self, account, trade_opts: dict, syslog_obj=None): + self.account = account + self.trade_opts = trade_opts + self.syslog = syslog_obj + + from binance.client import Client + + api_key = self.account["apikey"] + api_secret = self.account["secretkey"] + + self.client = Client(api_key, api_secret) + + # 获取市场价格 + def get_all_tickers(self): + + prices = self.client.get_all_tickers() + logger.info(prices) + return prices + + # 获取订单簿深度 + def get_order_book(self, symbol="BTCUSDT"): + + depth = self.client.get_order_book(symbol) + logger.info(depth) + return depth + + # 获取账户信息 + def get_account(self): + + account = self.client.get_account() + logger.info(account) + return account + + # 获取账户余额 + def get_balance(self, asset="BTC"): + + balances = self.client.get_asset_balance(asset) + logger.info(balances) + return balances + + # 市价买入 + def order_market_buy(self, symbol="BTCUSDT", quantity=0.001): + from binance.exceptions import BinanceAPIException, BinanceOrderException + + try: + order = self.client.order_market_buy(symbol, quantity) + logger.info(order) + except BinanceAPIException as err: + # 捕获API错误 + logger.error(err) + return err + except BinanceOrderException as err: + # 捕获订单错误 + logger.error(err) + return err + return True + + # 限价卖出 + def order_market_sell(self, symbol="BTCUSDT", quantity=0.001, price="50000"): + from binance.exceptions import BinanceAPIException, BinanceOrderException + + try: + order = self.client.order_limit_sell(symbol, quantity, price) + logger.info(order) + except BinanceAPIException as err: + # 捕获API错误 + logger.error(err) + return err + except BinanceOrderException as err: + # 捕获订单错误 + logger.error(err) + return err + return True + + +class CcxtTradeEngine: + def __init__(self, account, trade_opts: dict, syslog_obj): + self.account = account + self.trade_opts = trade_opts + self.syslog = syslog_obj + + import ccxt + + self.exchange = None + if self.trade_opts["platform"] == "币安Binance": + # 初始化 Binance 交易所实例 + self.exchange = ccxt.binance( + { + "apiKey": self.account["apikey"], # 替换为你的 API Key + "secret": self.account["secretkey"], # 替换为你的 Secret Key + } + ) + + if self.trade_opts["platform"] == "欧易OKX": + # 初始化 Binance 交易所实例 + self.exchange = ccxt.okx( + { + "apiKey": self.account["apikey"], # 替换为你的 API Key + "secret": self.account["secretkey"], # 替换为你的 Secret Key + } + ) + + elif self.trade_opts["platform"] == "Bitget": + # 初始化 Bitget 交易所实例 + self.exchange = ccxt.bitget( + { + "apiKey": self.account["apikey"], # 替换为你的 API Key + "secret": self.account["secretkey"], # 替换为你的 Secret Key + } + ) + + elif self.trade_opts["platform"] == "coinex": + # 初始化 coinex 交易所实例 + self.exchange = ccxt.coinex( + { + "apiKey": self.account["apikey"], # 替换为你的 API Key + "secret": self.account["secretkey"], # 替换为你的 Secret Key + } + ) + + elif self.trade_opts["platform"] == "kucoin": + # 初始化 kucoin 交易所实例 + self.exchange = ccxt.kucoin( + { + "apiKey": self.account["apikey"], # 替换为你的 API Key + "secret": self.account["secretkey"], # 替换为你的 Secret Key + } + ) + + elif self.trade_opts["platform"] == "coinbase": + # 初始化 coinbase 交易所实例 + self.exchange = ccxt.coinbase( + { + "apiKey": self.account["apikey"], # 替换为你的 API Key + "secret": self.account["secretkey"], # 替换为你的 Secret Key + } + ) + + elif self.trade_opts["platform"] == "Bitmart": + # 初始化 Bitmart 交易所实例 + self.exchange = ccxt.bitmart( + { + "apiKey": self.account["apikey"], # 替换为你的 API Key + "secret": self.account["secretkey"], # 替换为你的 Secret Key + } + ) + elif self.trade_opts["platform"] == "bitmex": + # 初始化 bitmex 交易所实例 + self.exchange = ccxt.bitmex( + { + "apiKey": self.account["apikey"], # 替换为你的 API Key + "secret": self.account["secretkey"], # 替换为你的 Secret Key + } + ) + elif self.trade_opts["platform"] == "bingx": + # 初始化 bingx 交易所实例 + self.exchange = ccxt.bingx( + { + "apiKey": self.account["apikey"], # 替换为你的 API Key + "secret": self.account["secretkey"], # 替换为你的 Secret Key + } + ) + elif self.trade_opts["platform"] == "bitget": + # 初始化 bitget 交易所实例 + self.exchange = ccxt.bitget( + { + "apiKey": self.account["apikey"], # 替换为你的 API Key + "secret": self.account["secretkey"], # 替换为你的 Secret Key + } + ) + elif self.trade_opts["platform"] == "okcoin": + # 初始化 okcoin 交易所实例 + self.exchange = ccxt.okcoin( + { + "apiKey": self.account["apikey"], # 替换为你的 API Key + "secret": self.account["secretkey"], # 替换为你的 Secret Key + } + ) + elif self.trade_opts["platform"] == "火币Huobi": + # 初始化 火币Huobi 交易所实例 + self.exchange = ccxt.huobi( + { + "apiKey": self.account["apikey"], # 替换为你的 API Key + "secret": self.account["secretkey"], # 替换为你的 Secret Key + } + ) + elif self.trade_opts["platform"] == "htx": + # 初始化 htx 交易所实例 + self.exchange = ccxt.htx( + { + "apiKey": self.account["apikey"], # 替换为你的 API Key + "secret": self.account["secretkey"], # 替换为你的 Secret Key + } + ) + else: + logger.warning(f"{trade_opts['platform']} 还未支持,可联系微信 Yida_Zhang2") + + # 检查交易信号 + def check_trade_signals(self, df): + last_row = df.iloc[-1] + previous_row = df.iloc[-2] + + # 买入条件:MACD 越过零线 + if previous_row["macd"] < 0 and last_row["macd"] > 0: + return "buy" + + # 卖出条件:MACD 低于零线 + if previous_row["macd"] > 0 and last_row["macd"] < 0: + return "sell" + + return "hold" + + # 获取当前持仓方向和数量 + def get_positions(self, symbol): + balance = self.exchange.fetch_balance() + if symbol in balance["total"]: + return balance["total"][symbol] + return 0 + + # 计算持仓盈亏比例 + def calculate_profit_loss(self, entry_price, current_price): + return (current_price - entry_price) / entry_price + + # 执行交易 + def execute_trade(self, signal, symbol="BTC/USDT", amount=0.001, entry_price=None): + base_currency = symbol.split("/")[0] + position = self.get_positions(symbol) + + if signal == "buy": + if position <= 0: + order = self.exchange.create_market_buy_order(symbol, amount) + logger.info(f"Buy order executed: {order}") + entry_price = order["price"] + else: + logger.info("Already holding a buy position. No action taken.") + elif signal == "sell": + if position > 0: + order = self.exchange.create_market_sell_order(symbol, amount) + logger.info(f"Sell order executed: {order}") + entry_price = None + else: + logger.error("No buy position to sell. No action taken.") + + # 止盈止损逻辑 + if entry_price: + ticker = exchange.fetch_ticker(symbol) + current_price = ticker["last"] + profit_loss_ratio = self.calculate_profit_loss(entry_price, current_price) + + if profit_loss_ratio >= 0.05: # 止盈条件 + if position > 0: + order = self.exchange.create_market_sell_order(symbol, amount) + logger.info(f"Take profit order executed: {order}") + entry_price = None + elif profit_loss_ratio <= -0.03: # 止损条件 + if position > 0: + order = self.exchange.create_market_sell_order(symbol, amount) + logger.info(f"Stop loss order executed: {order}") + entry_price = None diff --git a/qbot/engine/trade/engine_apis/btc/btc_trade_engine_test.py b/qbot/engine/trade/engine_apis/btc/btc_trade_engine_test.py new file mode 100644 index 00000000..dbe668f5 --- /dev/null +++ b/qbot/engine/trade/engine_apis/btc/btc_trade_engine_test.py @@ -0,0 +1,113 @@ +from qbot.common.logging.logger import LOGGER as logger +from qbot.engine.trade.engine_apis.btc.btc_trade_engine import ( + CcxtTradeEngine, + OkxTradeEngine, +) + + +# 获取 5 分钟的 K 线数据 +def fetch_ohlcv(exchange, symbol, timeframe="5m", limit=100): + ohlcv = exchange.fetch_ohlcv(symbol, timeframe, limit=limit) + df = pd.DataFrame( + ohlcv, columns=["timestamp", "open", "high", "low", "close", "volume"] + ) + df["timestamp"] = pd.to_datetime(df["timestamp"], unit="ms") + df.set_index("timestamp", inplace=True) + return df + + +# 计算 MACD 指标 +def calculate_macd(df): + import talib as ta + + macd = ta.trend.MACD(df["close"]) + df["macd"] = macd.macd() + df["macd_signal"] = macd.macd_signal() + df["macd_diff"] = macd.macd_diff() + + +# 检查交易信号 +def check_trade_signals(df): + last_row = df.iloc[-1] + previous_row = df.iloc[-2] + + # 买入条件:MACD 越过零线 + if previous_row["macd"] < 0 and last_row["macd"] > 0: + return "buy" + + # 卖出条件:MACD 低于零线 + if previous_row["macd"] > 0 and last_row["macd"] < 0: + return "sell" + + return "hold" + + +# ref: https://mp.weixin.qq.com/s?__biz=MzIzMjE3NTAxNw==&mid=2649269697&idx=1&sn=f562d5de13bd125237b888ff89f25112&chksm=f084e107c7f36811d64e7e51c523ea8a54085937c28949ddc930f4d0e6506d6ccf5f5e1dc59a&cur_album_id=3563545010618269709&scene=189#wechat_redirect +def cctx_main(account, trade_opts, symbol="BTC/USDT"): + if "/" not in symbol: + symbol = symbol[:3] + "/" + symbol[-4:] + + ccxt_engine = CcxtTradeEngine(account, trade_opts, syslog_obj=None) + + print(ccxt_engine.exchange) + + entry_price = None + while True: + df = fetch_ohlcv(ccxt_engine.exchange, symbol) + calculate_macd(df) + calculate_ema(df) + calculate_kdj(df) + signal = check_trade_signals(df) + ccxt_engine.execute_trade(signal, symbol, entry_price=entry_price) + time.sleep(300) # 每5分钟运行一次 + + +def okx_main(account, trade_opts, symbol="BTC/USDT"): + trade_engine = OkxTradeEngine(account, trade_opts) + + trade_engine.get_ticker(symbol) + trade_engine.get_balance() + # trade_engine.get_positions() + # trade_engine.start_trade() + + +def main(): + from qbot.common.file_utils import file2dict + from qbot.engine.config import BTC_REAL_ACCOUNT, BTC_SIM_ACCOUNT + + trade_opts = { + "class": "虚拟盘", + "platform": "欧易OKX", + "trade_type": "BTC", + "trade_code": "ETHUSDT", + "strategy": "单因子-相对强弱指数RSI", + } + + # 虚拟盘交易 + sim_accounts = file2dict(BTC_SIM_ACCOUNT) + + # cctx_main(account=sim_accounts[trade_opts["platform"]], trade_opts=trade_opts, symbol='BTC/USDT') + + # trade_opts["class"] = "虚拟盘" + # trade_opts["platform"] = "币安Binance" + logger.info(sim_accounts[trade_opts["platform"]]) + okx_main( + account=sim_accounts[trade_opts["platform"]], + trade_opts=trade_opts, + symbol="BTC/USDT", + ) + + # 实盘交易 + real_accounts = file2dict(BTC_REAL_ACCOUNT) + trade_opts["class"] = "实盘" + trade_opts["platform"] = "币安Binance" + logger.info(real_accounts[trade_opts["platform"]]) + okx_main( + account=real_accounts[trade_opts["platform"]], + trade_opts=trade_opts, + symbol="BTC/USDT", + ) + + +if __name__ == "__main__": + main() diff --git a/qbot/engine/trade/engine_apis/funds/account.json.example b/qbot/engine/trade/engine_apis/funds/account.json.example new file mode 100644 index 00000000..c7f061bf --- /dev/null +++ b/qbot/engine/trade/engine_apis/funds/account.json.example @@ -0,0 +1,12 @@ +{ + "东方财富": { + "/des": " account info", + "user": "", + "password": "" + }, + "华泰证券": { + "/des": " account info", + "user": "", + "password": "" + } +} \ No newline at end of file diff --git a/qbot/engine/trade/engine_apis/futures/CTPtest/CTPtest.sln b/qbot/engine/trade/engine_apis/futures/CTPtest/CTPtest.sln new file mode 100644 index 00000000..92f9678e --- /dev/null +++ b/qbot/engine/trade/engine_apis/futures/CTPtest/CTPtest.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2013 +VisualStudioVersion = 12.0.21005.1 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CTPtest", "CTPtest\CTPtest.vcxproj", "{B6E4CF70-7540-45BB-9DBF-C49EAA6E32E8}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {B6E4CF70-7540-45BB-9DBF-C49EAA6E32E8}.Debug|Win32.ActiveCfg = Debug|Win32 + {B6E4CF70-7540-45BB-9DBF-C49EAA6E32E8}.Debug|Win32.Build.0 = Debug|Win32 + {B6E4CF70-7540-45BB-9DBF-C49EAA6E32E8}.Release|Win32.ActiveCfg = Release|Win32 + {B6E4CF70-7540-45BB-9DBF-C49EAA6E32E8}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/qbot/engine/trade/engine_apis/futures/CTPtest/CTPtest/CF705_market_data.csv b/qbot/engine/trade/engine_apis/futures/CTPtest/CTPtest/CF705_market_data.csv new file mode 100644 index 00000000..9487b0a7 --- /dev/null +++ b/qbot/engine/trade/engine_apis/futures/CTPtest/CTPtest/CF705_market_data.csv @@ -0,0 +1,2 @@ +Լ,ʱ,¼,ɽ,һ,һ,һ,һ,ֲ, +CF705,11:29:59.0,14985,94376,14980,14,14985,7,195516,1.418e+009 diff --git a/qbot/engine/trade/engine_apis/futures/CTPtest/CTPtest/CTPtest.vcxproj b/qbot/engine/trade/engine_apis/futures/CTPtest/CTPtest/CTPtest.vcxproj new file mode 100644 index 00000000..0a7cfbbb --- /dev/null +++ b/qbot/engine/trade/engine_apis/futures/CTPtest/CTPtest/CTPtest.vcxproj @@ -0,0 +1,86 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + + + + + + + + + + + + + + {B6E4CF70-7540-45BB-9DBF-C49EAA6E32E8} + CTPtest + + + + Application + true + v120 + MultiByte + + + Application + false + v140 + true + MultiByte + + + + + + + + + + + + + ..\src\CTP_API;$(IncludePath) + ..\src\CTP_API;$(LibraryPath) + + + + Level3 + Disabled + true + _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + + + true + + + + + Level3 + MaxSpeed + true + true + true + + + true + true + true + + + + + + \ No newline at end of file diff --git a/qbot/engine/trade/engine_apis/futures/CTPtest/CTPtest/CTPtest.vcxproj.filters b/qbot/engine/trade/engine_apis/futures/CTPtest/CTPtest/CTPtest.vcxproj.filters new file mode 100644 index 00000000..cbebb316 --- /dev/null +++ b/qbot/engine/trade/engine_apis/futures/CTPtest/CTPtest/CTPtest.vcxproj.filters @@ -0,0 +1,48 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + 源文件 + + + 源文件 + + + 源文件 + + + 源文件 + + + 源文件 + + + + + 头文件 + + + 头文件 + + + 头文件 + + + 头文件 + + + \ No newline at end of file diff --git a/qbot/engine/trade/engine_apis/futures/CTPtest/CTPtest/K_line_data.csv b/qbot/engine/trade/engine_apis/futures/CTPtest/CTPtest/K_line_data.csv new file mode 100644 index 00000000..3ff2a443 --- /dev/null +++ b/qbot/engine/trade/engine_apis/futures/CTPtest/CTPtest/K_line_data.csv @@ -0,0 +1,10 @@ +̼,߼,ͼ,̼,ɽ +99.31,99.31,99.28,99.28,138 +99.28,99.285,99.265,99.265,100 +99.265,99.265,99.24,99.25,81 +99.25,99.25,99.215,99.25,102 +99.25,99.27,99.245,99.27,29 +99.27,99.275,99.24,99.24,75 +99.24,99.24,99.21,99.23,74 +99.225,99.25,99.225,99.245,54 +99.245,99.25,99.23,99.23,58 diff --git a/qbot/engine/trade/engine_apis/futures/CTPtest/CTPtest/TF1706_market_data.csv b/qbot/engine/trade/engine_apis/futures/CTPtest/CTPtest/TF1706_market_data.csv new file mode 100644 index 00000000..2ee6ff2c --- /dev/null +++ b/qbot/engine/trade/engine_apis/futures/CTPtest/CTPtest/TF1706_market_data.csv @@ -0,0 +1,2 @@ +Լ,ʱ,¼,ɽ,һ,һ,һ,һ,ֲ, +TF1706,11:29:59.500,99.155,3719,99.15,14,99.16,12,17166,3.68645e+009 diff --git a/qbot/engine/trade/engine_apis/futures/CTPtest/CTPtest/al1712_market_data.csv b/qbot/engine/trade/engine_apis/futures/CTPtest/CTPtest/al1712_market_data.csv new file mode 100644 index 00000000..f1bb00e0 --- /dev/null +++ b/qbot/engine/trade/engine_apis/futures/CTPtest/CTPtest/al1712_market_data.csv @@ -0,0 +1,25 @@ +Լ,ʱ,¼,ɽ,һ,һ,һ,һ,ֲ, +al1712,11:22:34.0,14065,8,14095,1,14125,1,1690,561100 +al1712,11:28:09.0,14065,8,14080,5,14125,1,1690,561100 +al1712,11:28:09.500,14065,8,14085,1,14125,1,1690,561100 +al1712,11:28:10.0,14065,8,14085,1,14125,1,1690,561100 +al1712,11:28:24.500,14065,8,14085,1,14120,1,1690,561100 +al1712,11:28:25.0,14065,8,14085,1,14120,1,1690,561100 +al1712,11:28:25.500,14065,8,14085,1,14120,2,1690,561100 +al1712,11:28:28.500,14120,10,14085,1,14120,1,1692,702300 +al1712,11:28:36.500,14120,10,14090,1,14120,1,1692,702300 +al1712,11:28:37.0,14120,10,14090,1,14120,1,1692,702300 +al1712,11:28:37.500,14120,10,14090,2,14120,1,1692,702300 +al1712,11:28:46.0,14120,10,14090,1,14120,1,1692,702300 +al1712,11:28:47.0,14120,10,14095,1,14120,1,1692,702300 +al1712,11:28:55.500,14120,10,14095,1,14115,1,1692,702300 +al1712,11:28:57.500,14115,12,14095,1,14120,1,1694,843450 +al1712,11:29:13.0,14115,12,14095,2,14120,1,1694,843450 +al1712,11:29:24.0,14115,12,14095,1,14130,1,1694,843450 +al1712,11:29:24.500,14115,12,14095,1,14125,1,1694,843450 +al1712,11:29:35.0,14095,14,14090,1,14130,1,1692,984400 +al1712,11:29:38.0,14090,16,14080,5,14130,1,1690,1.1253e+006 +al1712,11:29:41.0,14090,16,14080,5,14130,1,1690,1.1253e+006 +al1712,11:29:45.500,14090,16,14080,5,14130,1,1690,1.1253e+006 +al1712,11:29:54.0,14090,16,14060,1,14130,1,1690,1.1253e+006 +al1712,11:30:01.0,14090,16,14060,1,14130,1,1690,1.1253e+006 diff --git a/qbot/engine/trade/engine_apis/futures/CTPtest/CTPtest/cs1801_market_data.csv b/qbot/engine/trade/engine_apis/futures/CTPtest/CTPtest/cs1801_market_data.csv new file mode 100644 index 00000000..b2a5e79c --- /dev/null +++ b/qbot/engine/trade/engine_apis/futures/CTPtest/CTPtest/cs1801_market_data.csv @@ -0,0 +1,2 @@ +Լ,ʱ,¼,ɽ,һ,һ,һ,һ,ֲ, +cs1801,11:29:58.0,2065,19920,2065,43,2066,20,76166,4.11766e+008 diff --git a/qbot/engine/trade/engine_apis/futures/CTPtest/CTPtest/market_data.csv b/qbot/engine/trade/engine_apis/futures/CTPtest/CTPtest/market_data.csv new file mode 100644 index 00000000..c449236c --- /dev/null +++ b/qbot/engine/trade/engine_apis/futures/CTPtest/CTPtest/market_data.csv @@ -0,0 +1,1175 @@ +Լ,ʱ,¼,ɽ,һ,һ,һ,һ,ֲ, +TF1706,40:48.5,99.31,3580,99.295,4,99.31,38,15823,3.55E+09 +TF1706,40:49.0,99.31,3585,99.3,3,99.31,33,15823,3.56E+09 +TF1706,40:49.5,99.3,3586,99.295,3,99.31,33,15822,3.56E+09 +TF1706,40:50.0,99.3,3587,99.295,3,99.305,1,15823,3.56E+09 +TF1706,40:50.5,99.305,3588,99.295,4,99.305,1,15823,3.56E+09 +TF1706,40:51.0,99.305,3589,99.3,1,99.31,33,15822,3.56E+09 +TF1706,40:54.5,99.305,3589,99.3,2,99.31,33,15822,3.56E+09 +TF1706,40:55.0,99.305,3589,99.3,2,99.31,33,15822,3.56E+09 +TF1706,40:57.5,99.305,3589,99.3,2,99.31,33,15822,3.56E+09 +TF1706,41:01.5,99.305,3589,99.3,3,99.31,33,15822,3.56E+09 +TF1706,41:02.0,99.305,3589,99.3,3,99.31,33,15822,3.56E+09 +TF1706,41:05.5,99.305,3589,99.3,3,99.31,33,15822,3.56E+09 +TF1706,41:07.5,99.305,3589,99.3,11,99.31,33,15822,3.56E+09 +TF1706,41:11.0,99.31,3594,99.305,1,99.31,28,15822,3.57E+09 +TF1706,41:11.5,99.305,3595,99.3,3,99.305,1,15822,3.57E+09 +TF1706,41:12.0,99.305,3595,99.305,1,99.31,28,15822,3.57E+09 +TF1706,41:12.5,99.305,3596,99.3,3,99.31,28,15822,3.57E+09 +TF1706,41:17.5,99.3,3599,99.295,4,99.3,22,15821,3.57E+09 +TF1706,41:18.0,99.3,3604,99.295,4,99.3,17,15817,3.58E+09 +TF1706,41:18.5,99.3,3604,99.295,3,99.3,17,15817,3.58E+09 +TF1706,41:21.5,99.3,3607,99.295,3,99.3,14,15814,3.58E+09 +TF1706,41:28.0,99.3,3607,99.295,13,99.3,14,15814,3.58E+09 +TF1706,41:31.0,99.3,3607,99.295,13,99.3,14,15814,3.58E+09 +TF1706,41:32.5,99.3,3607,99.295,13,99.3,14,15814,3.58E+09 +TF1706,41:34.5,99.3,3607,99.295,13,99.3,14,15814,3.58E+09 +TF1706,41:36.0,99.3,3607,99.295,13,99.3,14,15814,3.58E+09 +TF1706,41:39.5,99.3,3607,99.295,13,99.3,14,15814,3.58E+09 +TF1706,41:42.5,99.295,3614,99.295,6,99.3,14,15821,3.59E+09 +TF1706,41:43.0,99.295,3620,99.29,10,99.295,12,15822,3.59E+09 +TF1706,41:43.5,99.295,3620,99.29,10,99.295,2,15822,3.59E+09 +TF1706,41:44.0,99.295,3620,99.29,10,99.295,1,15822,3.59E+09 +TF1706,41:45.0,99.295,3620,99.29,9,99.295,1,15822,3.59E+09 +TF1706,41:45.5,99.295,3620,99.295,1,99.3,14,15822,3.59E+09 +TF1706,41:46.0,99.295,3621,99.295,1,99.3,14,15821,3.60E+09 +TF1706,41:48.0,99.295,3622,99.29,2,99.3,14,15820,3.60E+09 +TF1706,41:49.5,99.295,3622,99.295,6,99.3,14,15820,3.60E+09 +TF1706,41:50.0,99.295,3623,99.295,5,99.3,14,15820,3.60E+09 +TF1706,41:51.5,99.295,3623,99.295,5,99.3,15,15820,3.60E+09 +TF1706,41:54.5,99.295,3623,99.29,2,99.3,15,15820,3.60E+09 +TF1706,41:58.0,99.295,3623,99.29,2,99.3,43,15820,3.60E+09 +TF1706,41:58.5,99.295,3623,99.295,5,99.3,43,15820,3.60E+09 +TF1706,42:03.0,99.295,3623,99.295,5,99.3,43,15820,3.60E+09 +TF1706,42:03.5,99.295,3623,99.29,2,99.3,43,15820,3.60E+09 +TF1706,42:07.5,99.295,3623,99.295,5,99.3,43,15820,3.60E+09 +TF1706,42:09.0,99.295,3623,99.295,5,99.3,43,15820,3.60E+09 +TF1706,42:12.5,99.295,3623,99.29,3,99.3,43,15820,3.60E+09 +TF1706,42:16.5,99.3,3628,99.29,3,99.3,38,15815,3.60E+09 +TF1706,42:31.0,99.3,3628,99.295,40,99.3,38,15815,3.60E+09 +TF1706,42:37.0,99.295,3631,99.295,37,99.3,38,15817,3.61E+09 +TF1706,42:43.0,99.295,3631,99.295,37,99.3,39,15817,3.61E+09 +TF1706,42:43.5,99.295,3633,99.295,36,99.3,38,15817,3.61E+09 +TF1706,42:47.0,99.295,3635,99.295,34,99.3,46,15818,3.61E+09 +TF1706,42:47.5,99.295,3640,99.295,29,99.3,46,15820,3.61E+09 +TF1706,42:48.0,99.295,3644,99.295,25,99.3,46,15820,3.62E+09 +TF1706,42:48.5,99.295,3646,99.295,23,99.3,46,15822,3.62E+09 +TF1706,42:49.0,99.295,3650,99.295,19,99.3,55,15823,3.62E+09 +TF1706,42:50.0,99.295,3650,99.295,19,99.3,57,15823,3.62E+09 +TF1706,42:51.5,99.295,3651,99.295,18,99.3,57,15824,3.63E+09 +TF1706,42:52.0,99.295,3654,99.295,15,99.3,57,15827,3.63E+09 +TF1706,42:54.5,99.295,3654,99.295,15,99.3,56,15827,3.63E+09 +TF1706,43:00.5,99.295,3654,99.295,15,99.3,57,15827,3.63E+09 +TF1706,43:02.0,99.295,3654,99.295,15,99.3,55,15827,3.63E+09 +TF1706,43:02.5,99.295,3666,99.295,3,99.3,63,15829,3.64E+09 +TF1706,43:03.0,99.295,3669,99.29,3,99.295,1,15831,3.64E+09 +TF1706,43:03.5,99.29,3670,99.29,2,99.295,3,15832,3.64E+09 +TF1706,43:04.0,99.29,3672,99.285,3,99.295,11,15832,3.65E+09 +TF1706,43:04.5,99.29,3672,99.285,3,99.295,11,15832,3.65E+09 +TF1706,43:05.0,99.29,3672,99.285,3,99.295,12,15832,3.65E+09 +TF1706,43:05.5,99.29,3672,99.285,3,99.295,13,15832,3.65E+09 +TF1706,43:06.0,99.295,3673,99.285,3,99.295,7,15832,3.65E+09 +TF1706,43:07.5,99.295,3673,99.285,3,99.295,7,15832,3.65E+09 +TF1706,43:12.0,99.285,3674,99.285,2,99.295,7,15832,3.65E+09 +TF1706,43:12.5,99.295,3675,99.285,2,99.295,8,15832,3.65E+09 +TF1706,43:13.0,99.295,3675,99.285,2,99.295,9,15832,3.65E+09 +TF1706,43:15.0,99.295,3675,99.285,2,99.295,9,15832,3.65E+09 +TF1706,43:19.0,99.295,3675,99.285,2,99.295,9,15832,3.65E+09 +TF1706,43:20.5,99.295,3678,99.285,2,99.295,5,15831,3.65E+09 +TF1706,43:21.0,99.295,3678,99.285,3,99.295,7,15831,3.65E+09 +TF1706,43:21.5,99.295,3678,99.285,3,99.295,6,15831,3.65E+09 +TF1706,43:25.5,99.295,3678,99.285,3,99.295,6,15831,3.65E+09 +TF1706,43:27.0,99.285,3681,99.28,3,99.285,7,15832,3.66E+09 +TF1706,43:27.5,99.285,3691,99.285,12,99.295,4,15834,3.67E+09 +TF1706,43:28.0,99.285,3691,99.285,3,99.295,4,15834,3.67E+09 +TF1706,43:29.0,99.285,3691,99.285,3,99.295,5,15834,3.67E+09 +TF1706,43:31.0,99.285,3691,99.285,3,99.295,5,15834,3.67E+09 +TF1706,43:33.0,99.285,3694,99.28,3,99.285,7,15836,3.67E+09 +TF1706,43:33.5,99.285,3699,99.28,3,99.285,2,15838,3.67E+09 +TF1706,43:34.0,99.285,3701,99.28,2,99.295,5,15840,3.68E+09 +TF1706,43:34.5,99.285,3701,99.285,10,99.295,6,15840,3.68E+09 +TF1706,43:35.0,99.285,3701,99.285,10,99.295,6,15840,3.68E+09 +TF1706,43:35.5,99.285,3701,99.29,1,99.295,6,15840,3.68E+09 +TF1706,43:36.0,99.285,3701,99.29,2,99.295,6,15840,3.68E+09 +TF1706,43:37.0,99.29,3703,99.285,10,99.295,7,15840,3.68E+09 +TF1706,43:37.5,99.285,3707,99.285,6,99.295,7,15842,3.68E+09 +TF1706,43:41.0,99.285,3708,99.285,5,99.295,10,15842,3.68E+09 +TF1706,43:41.5,99.285,3711,99.285,2,99.29,2,15842,3.69E+09 +TF1706,43:42.0,99.285,3713,99.28,3,99.29,15,15842,3.69E+09 +TF1706,43:42.5,99.285,3713,99.28,3,99.29,15,15842,3.69E+09 +TF1706,43:43.0,99.285,3713,99.28,2,99.29,15,15842,3.69E+09 +TF1706,43:43.5,99.285,3713,99.28,2,99.29,15,15842,3.69E+09 +TF1706,43:44.5,99.285,3713,99.28,2,99.29,15,15842,3.69E+09 +TF1706,43:45.0,99.285,3713,99.28,2,99.285,2,15842,3.69E+09 +TF1706,43:45.5,99.285,3713,99.28,2,99.285,16,15842,3.69E+09 +TF1706,43:46.0,99.285,3713,99.28,1,99.285,16,15842,3.69E+09 +TF1706,43:46.5,99.28,3714,99.275,2,99.285,16,15842,3.69E+09 +TF1706,43:47.0,99.28,3714,99.275,2,99.285,16,15842,3.69E+09 +TF1706,43:47.5,99.28,3714,99.275,2,99.285,17,15842,3.69E+09 +TF1706,43:50.0,99.28,3714,99.275,2,99.285,15,15842,3.69E+09 +TF1706,43:50.5,99.285,3717,99.275,2,99.285,12,15839,3.69E+09 +TF1706,43:51.0,99.285,3717,99.275,2,99.285,13,15839,3.69E+09 +TF1706,43:51.5,99.285,3717,99.275,2,99.285,13,15839,3.69E+09 +TF1706,43:52.5,99.285,3717,99.275,3,99.285,13,15839,3.69E+09 +TF1706,43:54.5,99.285,3717,99.275,4,99.285,13,15839,3.69E+09 +TF1706,43:56.0,99.285,3717,99.275,5,99.285,13,15839,3.69E+09 +TF1706,43:57.0,99.285,3717,99.275,5,99.28,1,15839,3.69E+09 +TF1706,43:57.5,99.28,3718,99.28,2,99.285,12,15838,3.69E+09 +TF1706,43:58.0,99.28,3718,99.28,1,99.285,3,15838,3.69E+09 +TF1706,43:59.0,99.28,3718,99.28,1,99.285,5,15838,3.69E+09 +TF1706,43:59.5,99.28,3718,99.28,1,99.285,4,15838,3.69E+09 +TF1706,44:00.0,99.28,3718,99.275,5,99.285,4,15838,3.69E+09 +TF1706,44:01.0,99.28,3718,99.275,5,99.285,6,15838,3.69E+09 +TF1706,44:03.0,99.28,3718,99.275,5,99.285,6,15838,3.69E+09 +TF1706,44:03.5,99.28,3718,99.275,5,99.285,6,15838,3.69E+09 +TF1706,44:08.5,99.28,3718,99.275,5,99.285,6,15838,3.69E+09 +TF1706,44:10.0,99.28,3718,99.275,6,99.285,6,15838,3.69E+09 +TF1706,44:14.0,99.28,3718,99.275,6,99.285,6,15838,3.69E+09 +TF1706,44:18.0,99.28,3718,99.275,6,99.285,6,15838,3.69E+09 +TF1706,44:18.5,99.28,3718,99.275,5,99.285,6,15838,3.69E+09 +TF1706,44:19.0,99.28,3718,99.275,5,99.285,5,15838,3.69E+09 +TF1706,44:19.5,99.28,3718,99.275,5,99.285,6,15838,3.69E+09 +TF1706,44:24.5,99.28,3718,99.275,5,99.285,6,15838,3.69E+09 +TF1706,44:30.0,99.28,3718,99.275,5,99.285,5,15838,3.69E+09 +TF1706,44:30.5,99.28,3718,99.28,1,99.285,5,15838,3.69E+09 +TF1706,44:32.5,99.28,3718,99.275,5,99.285,5,15838,3.69E+09 +TF1706,44:33.0,99.28,3718,99.28,1,99.285,5,15838,3.69E+09 +TF1706,44:43.0,99.28,3718,99.275,4,99.285,6,15838,3.69E+09 +TF1706,44:47.5,99.275,3719,99.275,3,99.285,17,15837,3.69E+09 +TF1706,44:48.0,99.275,3719,99.275,3,99.28,2,15837,3.69E+09 +TF1706,44:48.5,99.275,3719,99.275,2,99.28,4,15837,3.69E+09 +TF1706,44:49.0,99.28,3724,99.275,1,99.285,17,15839,3.70E+09 +TF1706,44:54.5,99.28,3724,99.275,2,99.285,20,15839,3.70E+09 +TF1706,44:57.0,99.28,3724,99.275,3,99.285,20,15839,3.70E+09 +TF1706,44:57.5,99.275,3726,99.275,1,99.285,25,15838,3.70E+09 +TF1706,44:58.0,99.275,3727,99.27,2,99.28,2,15839,3.70E+09 +TF1706,44:58.5,99.275,3727,99.27,2,99.28,4,15839,3.70E+09 +TF1706,45:03.0,99.275,3727,99.27,2,99.28,4,15839,3.70E+09 +TF1706,45:04.5,99.275,3727,99.27,12,99.28,4,15839,3.70E+09 +TF1706,45:07.0,99.275,3727,99.27,12,99.28,4,15839,3.70E+09 +TF1706,45:07.5,99.27,3728,99.27,11,99.28,4,15839,3.70E+09 +TF1706,45:08.0,99.27,3728,99.27,11,99.28,4,15839,3.70E+09 +TF1706,45:08.5,99.27,3728,99.27,11,99.28,5,15839,3.70E+09 +TF1706,45:13.5,99.27,3728,99.27,12,99.28,5,15839,3.70E+09 +TF1706,45:19.5,99.28,3733,99.28,1,99.285,21,15839,3.71E+09 +TF1706,45:20.0,99.285,3735,99.275,1,99.285,8,15839,3.71E+09 +TF1706,45:20.5,99.285,3735,99.275,2,99.285,15,15839,3.71E+09 +TF1706,45:21.0,99.285,3735,99.275,2,99.285,20,15839,3.71E+09 +TF1706,45:22.0,99.285,3735,99.275,2,99.285,20,15839,3.71E+09 +TF1706,45:22.5,99.285,3735,99.275,2,99.285,20,15839,3.71E+09 +TF1706,45:25.5,99.285,3735,99.275,2,99.285,17,15839,3.71E+09 +TF1706,45:26.0,99.285,3735,99.28,10,99.285,17,15839,3.71E+09 +TF1706,45:28.0,99.285,3735,99.28,10,99.285,20,15839,3.71E+09 +TF1706,45:28.5,99.285,3735,99.28,10,99.285,17,15839,3.71E+09 +TF1706,45:29.0,99.28,3736,99.28,9,99.285,15,15839,3.71E+09 +TF1706,45:29.5,99.28,3740,99.28,5,99.285,21,15843,3.71E+09 +TF1706,45:30.0,99.28,3740,99.28,5,99.285,18,15843,3.71E+09 +TF1706,45:33.0,99.28,3740,99.28,5,99.285,15,15843,3.71E+09 +TF1706,45:34.5,99.28,3740,99.28,5,99.285,15,15843,3.71E+09 +TF1706,45:35.0,99.285,3744,99.28,5,99.285,7,15840,3.72E+09 +TF1706,45:35.5,99.285,3744,99.28,6,99.285,4,15840,3.72E+09 +TF1706,45:36.5,99.285,3744,99.28,6,99.285,4,15840,3.72E+09 +TF1706,45:41.5,99.285,3744,99.28,16,99.285,4,15840,3.72E+09 +TF1706,45:42.0,99.285,3749,99.28,16,99.29,13,15843,3.72E+09 +TF1706,45:42.5,99.285,3749,99.28,16,99.29,13,15843,3.72E+09 +TF1706,45:43.0,99.285,3749,99.285,1,99.29,13,15843,3.72E+09 +TF1706,45:43.5,99.285,3749,99.285,2,99.29,13,15843,3.72E+09 +TF1706,45:44.0,99.285,3749,99.285,3,99.29,13,15843,3.72E+09 +TF1706,45:49.5,99.285,3749,99.285,3,99.29,13,15843,3.72E+09 +TF1706,45:51.0,99.285,3749,99.285,3,99.29,16,15843,3.72E+09 +TF1706,45:51.5,99.285,3749,99.285,1,99.29,16,15843,3.72E+09 +TF1706,45:53.0,99.285,3750,99.28,16,99.29,16,15842,3.72E+09 +TF1706,45:53.5,99.285,3750,99.28,16,99.285,2,15842,3.72E+09 +TF1706,45:54.0,99.285,3750,99.28,15,99.285,13,15842,3.72E+09 +TF1706,45:54.5,99.285,3750,99.28,15,99.285,11,15842,3.72E+09 +TF1706,46:00.0,99.285,3750,99.28,15,99.285,7,15842,3.72E+09 +TF1706,46:00.5,99.285,3751,99.28,15,99.285,6,15842,3.72E+09 +TF1706,46:01.0,99.285,3751,99.28,15,99.285,6,15842,3.72E+09 +TF1706,46:04.0,99.285,3751,99.28,15,99.285,6,15842,3.72E+09 +TF1706,46:04.5,99.285,3751,99.28,15,99.285,6,15842,3.72E+09 +TF1706,46:16.5,99.285,3751,99.28,15,99.285,10,15842,3.72E+09 +TF1706,46:27.5,99.285,3751,99.28,15,99.285,17,15842,3.72E+09 +TF1706,46:28.0,99.28,3753,99.28,13,99.285,17,15842,3.73E+09 +TF1706,46:29.0,99.285,3772,99.28,13,99.29,9,15861,3.75E+09 +TF1706,46:29.5,99.285,3772,99.28,13,99.29,7,15861,3.75E+09 +TF1706,46:30.0,99.285,3772,99.28,13,99.29,9,15861,3.75E+09 +TF1706,46:31.5,99.285,3772,99.28,13,99.29,9,15861,3.75E+09 +TF1706,46:35.5,99.285,3772,99.28,13,99.29,4,15861,3.75E+09 +TF1706,46:36.0,99.285,3772,99.285,1,99.29,9,15861,3.75E+09 +TF1706,46:36.5,99.285,3772,99.285,3,99.29,4,15861,3.75E+09 +TF1706,46:37.0,99.285,3772,99.285,3,99.29,9,15861,3.75E+09 +TF1706,46:46.0,99.285,3772,99.285,3,99.29,4,15861,3.75E+09 +TF1706,46:46.5,99.285,3772,99.285,3,99.29,3,15861,3.75E+09 +TF1706,46:52.5,99.285,3775,99.28,14,99.285,7,15862,3.75E+09 +TF1706,47:04.5,99.285,3775,99.28,14,99.285,9,15862,3.75E+09 +TF1706,47:05.0,99.28,3776,99.28,13,99.285,9,15863,3.75E+09 +TF1706,47:06.0,99.28,3786,99.28,3,99.285,14,15873,3.76E+09 +TF1706,47:06.5,99.28,3788,99.275,2,99.28,1,15873,3.76E+09 +TF1706,47:07.0,99.28,3788,99.275,2,99.28,2,15873,3.76E+09 +TF1706,47:11.0,99.275,3790,99.27,2,99.28,2,15873,3.76E+09 +TF1706,47:11.5,99.275,3790,99.27,2,99.28,3,15873,3.76E+09 +TF1706,47:12.0,99.275,3790,99.27,2,99.275,1,15873,3.76E+09 +TF1706,47:12.5,99.275,3790,99.27,2,99.275,1,15873,3.76E+09 +TF1706,47:13.5,99.275,3790,99.27,2,99.275,3,15873,3.76E+09 +TF1706,47:14.0,99.27,3791,99.27,1,99.275,3,15873,3.76E+09 +TF1706,47:14.5,99.27,3792,99.265,1,99.27,1,15873,3.77E+09 +TF1706,47:15.0,99.27,3792,99.265,2,99.27,5,15873,3.77E+09 +TF1706,47:17.5,99.27,3792,99.265,2,99.27,6,15873,3.77E+09 +TF1706,47:19.0,99.27,3792,99.265,2,99.27,7,15873,3.77E+09 +TF1706,47:19.5,99.27,3792,99.265,1,99.27,7,15873,3.77E+09 +TF1706,47:20.0,99.265,3793,99.26,5,99.265,9,15873,3.77E+09 +TF1706,47:20.5,99.265,3793,99.26,5,99.265,10,15873,3.77E+09 +TF1706,47:21.0,99.265,3793,99.26,5,99.265,10,15873,3.77E+09 +TF1706,47:22.5,99.265,3793,99.26,5,99.265,10,15873,3.77E+09 +TF1706,47:24.0,99.265,3793,99.26,6,99.265,10,15873,3.77E+09 +TF1706,47:24.5,99.265,3793,99.26,5,99.265,10,15873,3.77E+09 +TF1706,47:25.0,99.265,3803,99.26,6,99.27,4,15882,3.78E+09 +TF1706,47:25.5,99.27,3805,99.265,6,99.27,1,15882,3.78E+09 +TF1706,47:26.0,99.27,3806,99.27,8,99.275,4,15882,3.78E+09 +TF1706,47:26.5,99.27,3806,99.27,6,99.275,3,15882,3.78E+09 +TF1706,47:27.0,99.275,3809,99.275,4,99.28,2,15882,3.78E+09 +TF1706,47:27.5,99.275,3813,99.27,1,99.275,4,15880,3.79E+09 +TF1706,47:28.0,99.275,3813,99.265,5,99.275,1,15880,3.79E+09 +TF1706,47:28.5,99.275,3813,99.265,5,99.275,1,15880,3.79E+09 +TF1706,47:29.0,99.275,3813,99.265,5,99.275,1,15880,3.79E+09 +TF1706,47:30.5,99.275,3813,99.265,6,99.275,1,15880,3.79E+09 +TF1706,47:31.0,99.275,3813,99.265,6,99.275,1,15880,3.79E+09 +TF1706,47:35.5,99.275,3813,99.265,4,99.275,1,15880,3.79E+09 +TF1706,47:39.5,99.265,3814,99.265,3,99.275,1,15879,3.79E+09 +TF1706,47:40.0,99.265,3814,99.265,3,99.27,4,15879,3.79E+09 +TF1706,47:40.5,99.265,3817,99.26,6,99.265,1,15881,3.79E+09 +TF1706,47:41.0,99.265,3818,99.265,2,99.275,2,15881,3.79E+09 +TF1706,47:41.5,99.265,3819,99.26,6,99.265,9,15881,3.79E+09 +TF1706,47:42.0,99.265,3821,99.26,6,99.265,7,15882,3.79E+09 +TF1706,47:44.5,99.265,3821,99.26,6,99.265,7,15882,3.79E+09 +TF1706,47:47.5,99.265,3821,99.26,6,99.265,7,15882,3.79E+09 +TF1706,47:48.0,99.265,3821,99.26,6,99.265,8,15882,3.79E+09 +TF1706,47:48.5,99.26,3822,99.26,4,99.265,8,15882,3.80E+09 +TF1706,47:49.0,99.26,3826,99.255,1,99.26,2,15882,3.80E+09 +TF1706,47:49.5,99.26,3826,99.26,1,99.265,8,15882,3.80E+09 +TF1706,47:50.0,99.26,3826,99.26,2,99.265,8,15882,3.80E+09 +TF1706,47:50.5,99.26,3826,99.26,2,99.265,8,15882,3.80E+09 +TF1706,47:53.5,99.26,3826,99.26,2,99.265,7,15882,3.80E+09 +TF1706,47:54.0,99.26,3826,99.255,3,99.265,7,15882,3.80E+09 +TF1706,47:54.5,99.26,3826,99.26,1,99.265,7,15882,3.80E+09 +TF1706,47:55.0,99.26,3826,99.26,1,99.265,7,15882,3.80E+09 +TF1706,47:56.0,99.25,3835,99.25,9,99.265,7,15883,3.81E+09 +TF1706,47:56.5,99.25,3835,99.25,9,99.255,4,15883,3.81E+09 +TF1706,47:57.0,99.25,3835,99.25,9,99.26,1,15883,3.81E+09 +TF1706,47:57.5,99.255,3836,99.25,9,99.26,1,15883,3.81E+09 +TF1706,47:58.0,99.255,3837,99.25,9,99.26,2,15882,3.81E+09 +TF1706,47:59.0,99.255,3837,99.25,9,99.26,2,15882,3.81E+09 +TF1706,47:59.5,99.255,3837,99.255,1,99.26,2,15882,3.81E+09 +TF1706,48:00.0,99.255,3837,99.255,2,99.26,2,15882,3.81E+09 +TF1706,48:00.5,99.255,3837,99.255,1,99.26,2,15882,3.81E+09 +TF1706,48:01.0,99.26,3839,99.255,2,99.265,8,15882,3.81E+09 +TF1706,48:01.5,99.26,3839,99.255,2,99.265,8,15882,3.81E+09 +TF1706,48:02.0,99.26,3839,99.255,2,99.265,9,15882,3.81E+09 +TF1706,48:03.0,99.26,3839,99.255,2,99.265,2,15882,3.81E+09 +TF1706,48:03.5,99.26,3839,99.255,2,99.26,1,15882,3.81E+09 +TF1706,48:04.0,99.26,3840,99.26,1,99.265,2,15882,3.81E+09 +TF1706,48:04.5,99.26,3840,99.26,2,99.265,2,15882,3.81E+09 +TF1706,48:05.0,99.26,3841,99.26,2,99.265,1,15881,3.81E+09 +TF1706,48:06.0,99.26,3841,99.26,2,99.265,1,15881,3.81E+09 +TF1706,48:06.5,99.26,3842,99.255,2,99.265,1,15880,3.82E+09 +TF1706,48:07.5,99.26,3842,99.255,2,99.265,1,15880,3.82E+09 +TF1706,48:10.0,99.26,3842,99.255,2,99.265,1,15880,3.82E+09 +TF1706,48:11.5,99.26,3842,99.255,2,99.265,1,15880,3.82E+09 +TF1706,48:12.0,99.26,3842,99.255,2,99.265,1,15880,3.82E+09 +TF1706,48:12.5,99.255,3844,99.25,10,99.255,8,15880,3.82E+09 +TF1706,48:13.0,99.255,3852,99.255,5,99.265,1,15882,3.83E+09 +TF1706,48:13.5,99.255,3852,99.255,2,99.265,1,15882,3.83E+09 +TF1706,48:14.0,99.255,3852,99.255,2,99.265,2,15882,3.83E+09 +TF1706,48:16.0,99.255,3852,99.255,2,99.265,3,15882,3.83E+09 +TF1706,48:17.0,99.255,3852,99.255,2,99.265,3,15882,3.83E+09 +TF1706,48:18.0,99.255,3852,99.255,11,99.265,3,15882,3.83E+09 +TF1706,48:19.0,99.255,3852,99.255,11,99.265,10,15882,3.83E+09 +TF1706,48:22.0,99.255,3852,99.255,13,99.265,10,15882,3.83E+09 +TF1706,48:22.5,99.255,3852,99.255,16,99.265,10,15882,3.83E+09 +TF1706,48:34.5,99.255,3852,99.255,17,99.265,10,15882,3.83E+09 +TF1706,48:38.0,99.255,3852,99.255,17,99.265,10,15882,3.83E+09 +TF1706,48:45.0,99.255,3852,99.255,17,99.265,10,15882,3.83E+09 +TF1706,48:45.5,99.255,3852,99.255,16,99.265,10,15882,3.83E+09 +TF1706,48:46.5,99.255,3852,99.255,16,99.265,10,15882,3.83E+09 +TF1706,48:47.0,99.255,3852,99.255,16,99.265,10,15882,3.83E+09 +TF1706,48:49.0,99.255,3852,99.255,16,99.265,10,15882,3.83E+09 +TF1706,48:49.5,99.255,3852,99.255,16,99.26,1,15882,3.83E+09 +TF1706,48:50.0,99.255,3852,99.255,16,99.26,1,15882,3.83E+09 +TF1706,48:50.5,99.255,3852,99.26,5,99.265,12,15882,3.83E+09 +TF1706,48:51.0,99.255,3852,99.26,4,99.265,12,15882,3.83E+09 +TF1706,48:52.5,99.255,3852,99.26,4,99.265,12,15882,3.83E+09 +TF1706,48:53.0,99.255,3852,99.26,4,99.265,12,15882,3.83E+09 +TF1706,48:53.5,99.26,3856,99.255,13,99.26,3,15885,3.83E+09 +TF1706,48:56.0,99.26,3856,99.255,13,99.26,3,15885,3.83E+09 +TF1706,48:57.0,99.26,3856,99.255,13,99.26,3,15885,3.83E+09 +TF1706,49:00.0,99.26,3856,99.255,12,99.26,3,15885,3.83E+09 +TF1706,49:01.5,99.26,3856,99.255,12,99.26,4,15885,3.83E+09 +TF1706,49:02.5,99.255,3859,99.255,9,99.26,4,15885,3.83E+09 +TF1706,49:03.0,99.255,3863,99.255,5,99.26,4,15888,3.84E+09 +TF1706,49:03.5,99.255,3868,99.25,10,99.255,9,15885,3.84E+09 +TF1706,49:04.0,99.25,3878,99.245,1,99.25,2,15881,3.85E+09 +TF1706,49:04.5,99.25,3878,99.245,1,99.255,11,15881,3.85E+09 +TF1706,49:05.0,99.25,3878,99.245,1,99.25,3,15881,3.85E+09 +TF1706,49:05.5,99.25,3878,99.245,2,99.25,1,15881,3.85E+09 +TF1706,49:06.0,99.25,3879,99.245,2,99.255,2,15881,3.85E+09 +TF1706,49:06.5,99.25,3879,99.245,2,99.255,2,15881,3.85E+09 +TF1706,49:07.5,99.245,3881,99.24,1,99.255,3,15881,3.85E+09 +TF1706,49:08.0,99.245,3881,99.24,1,99.25,1,15881,3.85E+09 +TF1706,49:08.5,99.245,3881,99.24,2,99.25,2,15881,3.85E+09 +TF1706,49:09.0,99.245,3881,99.24,2,99.25,2,15881,3.85E+09 +TF1706,49:10.0,99.245,3881,99.24,2,99.25,4,15881,3.85E+09 +TF1706,49:10.5,99.245,3881,99.24,2,99.25,3,15881,3.85E+09 +TF1706,49:11.0,99.245,3881,99.24,3,99.25,3,15881,3.85E+09 +TF1706,49:12.0,99.245,3881,99.24,3,99.25,4,15881,3.85E+09 +TF1706,49:12.5,99.24,3882,99.245,1,99.25,10,15880,3.85E+09 +TF1706,49:13.0,99.245,3883,99.24,2,99.245,4,15880,3.86E+09 +TF1706,49:13.5,99.245,3883,99.24,2,99.245,2,15880,3.86E+09 +TF1706,49:14.5,99.245,3883,99.24,2,99.245,3,15880,3.86E+09 +TF1706,49:15.0,99.245,3883,99.24,2,99.245,3,15880,3.86E+09 +TF1706,49:15.5,99.245,3884,99.24,2,99.245,2,15880,3.86E+09 +TF1706,49:18.5,99.245,3884,99.24,2,99.245,3,15880,3.86E+09 +TF1706,49:19.5,99.245,3884,99.24,12,99.245,3,15880,3.86E+09 +TF1706,49:20.0,99.245,3886,99.24,12,99.25,10,15882,3.86E+09 +TF1706,49:22.5,99.245,3886,99.24,12,99.25,10,15882,3.86E+09 +TF1706,49:23.0,99.245,3886,99.24,13,99.25,10,15882,3.86E+09 +TF1706,49:26.0,99.245,3886,99.24,13,99.25,26,15882,3.86E+09 +TF1706,49:26.5,99.245,3886,99.24,13,99.245,2,15882,3.86E+09 +TF1706,49:27.0,99.245,3886,99.24,13,99.25,26,15882,3.86E+09 +TF1706,49:30.5,99.245,3886,99.24,13,99.245,4,15882,3.86E+09 +TF1706,49:31.0,99.245,3886,99.24,13,99.245,4,15882,3.86E+09 +TF1706,49:32.0,99.245,3886,99.24,13,99.245,4,15882,3.86E+09 +TF1706,49:33.0,99.245,3887,99.24,13,99.25,27,15881,3.86E+09 +TF1706,49:33.5,99.245,3887,99.24,13,99.25,26,15881,3.86E+09 +TF1706,49:34.5,99.245,3887,99.24,13,99.245,4,15881,3.86E+09 +TF1706,49:35.0,99.245,3887,99.24,13,99.245,4,15881,3.86E+09 +TF1706,49:36.0,99.245,3890,99.24,13,99.245,1,15881,3.86E+09 +TF1706,49:36.5,99.245,3890,99.24,13,99.245,4,15881,3.86E+09 +TF1706,49:37.0,99.245,3890,99.24,13,99.245,5,15881,3.86E+09 +TF1706,49:38.0,99.245,3891,99.24,13,99.245,5,15880,3.86E+09 +TF1706,49:40.5,99.245,3891,99.245,1,99.25,27,15880,3.86E+09 +TF1706,49:46.0,99.245,3891,99.245,1,99.25,27,15880,3.86E+09 +TF1706,49:46.5,99.245,3893,99.24,13,99.245,1,15880,3.87E+09 +TF1706,49:47.5,99.24,3895,99.24,12,99.245,1,15880,3.87E+09 +TF1706,49:50.5,99.245,3896,99.24,12,99.25,27,15880,3.87E+09 +TF1706,49:51.0,99.245,3896,99.24,12,99.25,8,15880,3.87E+09 +TF1706,49:53.5,99.245,3896,99.245,1,99.25,8,15880,3.87E+09 +TF1706,49:54.0,99.245,3896,99.245,3,99.25,8,15880,3.87E+09 +TF1706,49:54.5,99.245,3896,99.245,3,99.25,2,15880,3.87E+09 +TF1706,49:55.0,99.25,3898,99.25,2,99.255,7,15880,3.87E+09 +TF1706,49:55.5,99.25,3900,99.245,3,99.255,8,15879,3.87E+09 +TF1706,49:56.0,99.25,3900,99.245,3,99.255,7,15879,3.87E+09 +TF1706,49:56.5,99.25,3900,99.245,3,99.255,15,15879,3.87E+09 +TF1706,49:57.0,99.25,3900,99.245,3,99.25,6,15879,3.87E+09 +TF1706,49:57.5,99.25,3900,99.245,3,99.25,4,15879,3.87E+09 +TF1706,50:01.5,99.245,3903,99.24,13,99.25,5,15877,3.88E+09 +TF1706,50:02.0,99.245,3903,99.24,13,99.25,5,15877,3.88E+09 +TF1706,50:02.5,99.245,3903,99.24,13,99.25,16,15877,3.88E+09 +TF1706,50:03.0,99.24,3905,99.24,11,99.245,3,15879,3.88E+09 +TF1706,50:03.5,99.24,3907,99.24,9,99.245,21,15881,3.88E+09 +TF1706,50:04.0,99.24,3908,99.24,8,99.245,21,15882,3.88E+09 +TF1706,50:04.5,99.24,3910,99.24,6,99.245,21,15882,3.88E+09 +TF1706,50:05.0,99.24,3910,99.24,6,99.245,21,15882,3.88E+09 +TF1706,50:05.5,99.24,3912,99.24,4,99.245,21,15883,3.88E+09 +TF1706,50:06.0,99.24,3916,99.235,4,99.24,5,15883,3.89E+09 +TF1706,50:06.5,99.24,3916,99.235,4,99.24,24,15883,3.89E+09 +TF1706,50:07.0,99.24,3916,99.235,3,99.24,28,15883,3.89E+09 +TF1706,50:08.5,99.235,3917,99.235,2,99.24,26,15883,3.89E+09 +TF1706,50:09.0,99.23,3920,99.23,9,99.24,26,15885,3.89E+09 +TF1706,50:09.5,99.23,3920,99.23,9,99.235,2,15885,3.89E+09 +TF1706,50:10.0,99.23,3920,99.23,9,99.235,7,15885,3.89E+09 +TF1706,50:10.5,99.23,3929,99.225,1,99.23,3,15884,3.90E+09 +TF1706,50:11.0,99.225,3930,99.215,1,99.225,2,15884,3.90E+09 +TF1706,50:11.5,99.225,3932,99.225,6,99.23,11,15883,3.90E+09 +TF1706,50:12.0,99.225,3933,99.22,4,99.23,2,15883,3.91E+09 +TF1706,50:12.5,99.23,3935,99.225,6,99.235,11,15883,3.91E+09 +TF1706,50:13.0,99.23,3935,99.22,4,99.235,11,15883,3.91E+09 +TF1706,50:13.5,99.23,3935,99.22,4,99.235,11,15883,3.91E+09 +TF1706,50:14.0,99.23,3935,99.22,5,99.23,1,15883,3.91E+09 +TF1706,50:14.5,99.23,3935,99.22,3,99.23,14,15883,3.91E+09 +TF1706,50:15.0,99.22,3937,99.215,2,99.225,4,15884,3.91E+09 +TF1706,50:15.5,99.215,3938,99.215,1,99.225,17,15884,3.91E+09 +TF1706,50:16.0,99.215,3939,99.205,2,99.215,1,15885,3.91E+09 +TF1706,50:16.5,99.215,3940,99.215,6,99.22,2,15885,3.91E+09 +TF1706,50:17.0,99.22,3941,99.21,5,99.22,2,15884,3.91E+09 +TF1706,50:17.5,99.22,3942,99.215,9,99.22,1,15884,3.91E+09 +TF1706,50:18.0,99.22,3943,99.22,7,99.225,9,15884,3.92E+09 +TF1706,50:18.5,99.22,3943,99.22,3,99.225,13,15884,3.92E+09 +TF1706,50:19.0,99.22,3946,99.215,3,99.225,15,15884,3.92E+09 +TF1706,50:19.5,99.22,3946,99.215,3,99.225,13,15884,3.92E+09 +TF1706,50:20.0,99.22,3946,99.215,3,99.225,1,15884,3.92E+09 +TF1706,50:20.5,99.22,3946,99.22,5,99.225,1,15884,3.92E+09 +TF1706,50:21.0,99.22,3946,99.22,3,99.225,1,15884,3.92E+09 +TF1706,50:21.5,99.22,3946,99.22,1,99.225,1,15884,3.92E+09 +TF1706,50:22.0,99.22,3946,99.22,1,99.225,2,15884,3.92E+09 +TF1706,50:23.0,99.22,3947,99.215,3,99.225,11,15883,3.92E+09 +TF1706,50:23.5,99.22,3947,99.22,3,99.225,6,15883,3.92E+09 +TF1706,50:24.0,99.22,3947,99.22,3,99.225,2,15883,3.92E+09 +TF1706,50:24.5,99.22,3947,99.22,2,99.225,2,15883,3.92E+09 +TF1706,50:26.0,99.22,3947,99.22,2,99.225,2,15883,3.92E+09 +TF1706,50:26.5,99.225,3949,99.225,3,99.23,12,15882,3.92E+09 +TF1706,50:27.0,99.225,3949,99.225,4,99.23,3,15882,3.92E+09 +TF1706,50:27.5,99.225,3949,99.225,4,99.23,2,15882,3.92E+09 +TF1706,50:29.0,99.235,3957,99.225,4,99.235,5,15889,3.93E+09 +TF1706,50:29.5,99.235,3958,99.23,3,99.24,7,15889,3.93E+09 +TF1706,50:30.0,99.235,3958,99.23,4,99.24,1,15889,3.93E+09 +TF1706,50:30.5,99.235,3958,99.235,3,99.245,3,15889,3.93E+09 +TF1706,50:31.0,99.235,3958,99.235,6,99.245,3,15889,3.93E+09 +TF1706,50:31.5,99.235,3964,99.23,2,99.245,10,15886,3.94E+09 +TF1706,50:32.0,99.235,3964,99.23,2,99.245,10,15886,3.94E+09 +TF1706,50:32.5,99.235,3964,99.23,2,99.24,5,15886,3.94E+09 +TF1706,50:33.0,99.235,3964,99.23,2,99.24,3,15886,3.94E+09 +TF1706,50:33.5,99.235,3964,99.23,3,99.24,3,15886,3.94E+09 +TF1706,50:34.0,99.235,3964,99.23,3,99.24,3,15886,3.94E+09 +TF1706,50:36.0,99.24,3965,99.235,2,99.24,2,15885,3.94E+09 +TF1706,50:36.5,99.24,3967,99.235,3,99.245,4,15887,3.94E+09 +TF1706,50:37.5,99.24,3967,99.235,1,99.245,4,15887,3.94E+09 +TF1706,50:38.0,99.24,3967,99.235,1,99.245,4,15887,3.94E+09 +TF1706,50:38.5,99.24,3967,99.235,1,99.245,4,15887,3.94E+09 +TF1706,50:40.0,99.24,3967,99.235,1,99.245,4,15887,3.94E+09 +TF1706,50:41.0,99.24,3967,99.235,1,99.245,4,15887,3.94E+09 +TF1706,50:41.5,99.24,3967,99.235,1,99.245,7,15887,3.94E+09 +TF1706,50:42.0,99.24,3967,99.235,1,99.245,3,15887,3.94E+09 +TF1706,50:42.5,99.235,3968,99.23,3,99.24,2,15886,3.94E+09 +TF1706,50:43.0,99.235,3968,99.23,3,99.245,7,15886,3.94E+09 +TF1706,50:44.5,99.235,3968,99.23,3,99.245,13,15886,3.94E+09 +TF1706,50:45.0,99.235,3968,99.235,10,99.24,2,15886,3.94E+09 +TF1706,50:45.5,99.24,3970,99.24,10,99.245,3,15884,3.94E+09 +TF1706,50:46.0,99.24,3970,99.24,2,99.245,3,15884,3.94E+09 +TF1706,50:46.5,99.24,3970,99.24,3,99.245,3,15884,3.94E+09 +TF1706,50:47.0,99.24,3970,99.24,2,99.245,3,15884,3.94E+09 +TF1706,50:47.5,99.24,3970,99.24,2,99.245,3,15884,3.94E+09 +TF1706,50:48.0,99.24,3970,99.24,2,99.245,3,15884,3.94E+09 +TF1706,50:50.0,99.24,3970,99.24,2,99.245,3,15884,3.94E+09 +TF1706,50:50.5,99.24,3970,99.24,2,99.245,7,15884,3.94E+09 +TF1706,50:51.5,99.24,3971,99.24,1,99.245,7,15884,3.94E+09 +TF1706,50:52.0,99.24,3972,99.235,10,99.24,3,15884,3.94E+09 +TF1706,50:52.5,99.24,3972,99.235,10,99.24,3,15884,3.94E+09 +TF1706,50:53.0,99.24,3972,99.235,10,99.24,3,15884,3.94E+09 +TF1706,50:55.5,99.24,3972,99.235,10,99.24,9,15884,3.94E+09 +TF1706,50:56.0,99.24,3972,99.235,10,99.24,2,15884,3.94E+09 +TF1706,50:56.5,99.24,3972,99.235,11,99.24,2,15884,3.94E+09 +TF1706,50:57.0,99.24,3972,99.235,11,99.24,8,15884,3.94E+09 +TF1706,50:57.5,99.24,3972,99.235,11,99.24,6,15884,3.94E+09 +TF1706,50:58.5,99.24,3972,99.235,11,99.24,2,15884,3.94E+09 +TF1706,50:59.5,99.24,3972,99.235,11,99.24,12,15884,3.94E+09 +TF1706,51:00.0,99.24,3973,99.235,11,99.24,11,15883,3.95E+09 +TF1706,51:01.0,99.24,3973,99.235,11,99.24,1,15883,3.95E+09 +TF1706,51:01.5,99.235,3974,99.235,10,99.24,8,15883,3.95E+09 +TF1706,51:02.0,99.24,3976,99.235,10,99.24,10,15885,3.95E+09 +TF1706,51:02.5,99.24,3976,99.235,10,99.24,4,15885,3.95E+09 +TF1706,51:03.5,99.24,3976,99.235,10,99.245,9,15885,3.95E+09 +TF1706,51:04.0,99.24,3976,99.235,10,99.245,13,15885,3.95E+09 +TF1706,51:06.0,99.24,3976,99.235,10,99.245,7,15885,3.95E+09 +TF1706,51:06.5,99.235,3977,99.235,9,99.24,3,15885,3.95E+09 +TF1706,51:07.0,99.235,3980,99.235,5,99.245,15,15885,3.95E+09 +TF1706,51:07.5,99.235,3980,99.235,5,99.24,5,15885,3.95E+09 +TF1706,51:11.0,99.245,3988,99.235,6,99.24,4,15886,3.96E+09 +TF1706,51:11.5,99.24,3992,99.24,15,99.25,1,15883,3.96E+09 +TF1706,51:12.0,99.245,3996,99.24,10,99.25,1,15883,3.97E+09 +TF1706,51:12.5,99.245,3996,99.24,6,99.245,4,15883,3.97E+09 +TF1706,51:13.0,99.245,3996,99.24,7,99.245,4,15883,3.97E+09 +TF1706,51:13.5,99.245,4000,99.245,4,99.25,1,15879,3.97E+09 +TF1706,51:14.0,99.25,4001,99.25,3,99.255,7,15880,3.97E+09 +TF1706,51:14.5,99.25,4001,99.245,1,99.255,7,15880,3.97E+09 +TF1706,51:15.0,99.25,4001,99.245,1,99.255,7,15880,3.97E+09 +TF1706,51:16.5,99.25,4001,99.245,1,99.25,3,15880,3.97E+09 +TF1706,51:17.0,99.25,4001,99.245,1,99.255,7,15880,3.97E+09 +TF1706,51:17.5,99.25,4001,99.245,1,99.25,3,15880,3.97E+09 +TF1706,51:18.0,99.25,4001,99.245,1,99.25,2,15880,3.97E+09 +TF1706,51:18.5,99.25,4001,99.25,1,99.255,7,15880,3.97E+09 +TF1706,51:19.0,99.25,4002,99.245,1,99.25,1,15879,3.97E+09 +TF1706,51:19.5,99.25,4002,99.245,1,99.25,1,15879,3.97E+09 +TF1706,51:21.0,99.25,4002,99.245,1,99.25,1,15879,3.97E+09 +TF1706,51:25.5,99.245,4003,99.24,2,99.25,1,15878,3.97E+09 +TF1706,51:26.0,99.245,4003,99.24,2,99.25,1,15878,3.97E+09 +TF1706,51:28.0,99.245,4003,99.24,3,99.25,1,15878,3.97E+09 +TF1706,51:30.0,99.245,4003,99.24,3,99.25,1,15878,3.97E+09 +TF1706,51:33.0,99.245,4003,99.24,3,99.25,1,15878,3.97E+09 +TF1706,51:33.5,99.245,4003,99.245,5,99.25,1,15878,3.97E+09 +TF1706,51:34.0,99.245,4003,99.245,6,99.25,1,15878,3.97E+09 +TF1706,51:34.5,99.245,4003,99.245,6,99.25,1,15878,3.97E+09 +TF1706,51:37.0,99.25,4004,99.245,6,99.255,7,15877,3.98E+09 +TF1706,51:38.0,99.25,4004,99.245,7,99.255,1,15877,3.98E+09 +TF1706,51:38.5,99.25,4004,99.25,1,99.255,1,15877,3.98E+09 +TF1706,51:39.0,99.25,4004,99.25,2,99.255,1,15877,3.98E+09 +TF1706,51:42.5,99.255,4005,99.25,2,99.26,7,15877,3.98E+09 +TF1706,51:43.0,99.255,4005,99.25,2,99.255,3,15877,3.98E+09 +TF1706,51:43.5,99.25,4007,99.25,1,99.255,9,15877,3.98E+09 +TF1706,51:44.0,99.25,4009,99.245,7,99.255,9,15875,3.98E+09 +TF1706,51:45.0,99.25,4009,99.245,8,99.255,3,15875,3.98E+09 +TF1706,51:48.5,99.25,4009,99.245,8,99.255,3,15875,3.98E+09 +TF1706,51:49.0,99.25,4013,99.25,9,99.26,1,15874,3.98E+09 +TF1706,51:49.5,99.25,4014,99.25,4,99.26,1,15875,3.99E+09 +TF1706,51:50.5,99.25,4014,99.25,4,99.255,1,15875,3.99E+09 +TF1706,51:51.0,99.25,4014,99.25,4,99.26,7,15875,3.99E+09 +TF1706,51:51.5,99.25,4014,99.25,4,99.26,7,15875,3.99E+09 +TF1706,51:53.5,99.25,4014,99.25,4,99.26,7,15875,3.99E+09 +TF1706,51:55.0,99.25,4014,99.25,4,99.26,7,15875,3.99E+09 +TF1706,51:55.5,99.25,4014,99.25,4,99.26,7,15875,3.99E+09 +TF1706,51:58.5,99.25,4014,99.25,2,99.26,7,15875,3.99E+09 +TF1706,51:59.0,99.25,4014,99.25,2,99.26,1,15875,3.99E+09 +TF1706,52:00.5,99.25,4014,99.25,2,99.26,1,15875,3.99E+09 +TF1706,52:03.5,99.26,4015,99.25,2,99.265,2,15876,3.99E+09 +TF1706,52:04.0,99.26,4015,99.25,2,99.265,8,15876,3.99E+09 +TF1706,52:04.5,99.26,4015,99.25,2,99.26,1,15876,3.99E+09 +TF1706,52:05.0,99.26,4015,99.25,2,99.26,1,15876,3.99E+09 +TF1706,52:06.0,99.26,4015,99.25,2,99.26,1,15876,3.99E+09 +TF1706,52:09.0,99.26,4015,99.25,2,99.26,1,15876,3.99E+09 +TF1706,52:15.0,99.26,4015,99.255,1,99.26,1,15876,3.99E+09 +TF1706,52:15.5,99.26,4016,99.255,2,99.265,2,15876,3.99E+09 +TF1706,52:16.0,99.26,4016,99.255,2,99.265,2,15876,3.99E+09 +TF1706,52:16.5,99.26,4016,99.255,2,99.26,1,15876,3.99E+09 +TF1706,52:17.0,99.26,4017,99.26,2,99.265,2,15876,3.99E+09 +TF1706,52:17.5,99.26,4017,99.26,1,99.265,2,15876,3.99E+09 +TF1706,52:18.0,99.26,4017,99.26,1,99.265,1,15876,3.99E+09 +TF1706,52:23.0,99.26,4017,99.26,1,99.265,1,15876,3.99E+09 +TF1706,52:27.5,99.265,4018,99.265,1,99.27,4,15877,3.99E+09 +TF1706,52:28.0,99.265,4019,99.26,1,99.27,4,15877,3.99E+09 +TF1706,52:29.0,99.265,4019,99.26,1,99.265,4,15877,3.99E+09 +TF1706,52:33.0,99.265,4020,99.26,1,99.27,8,15877,3.99E+09 +TF1706,52:33.5,99.265,4020,99.26,1,99.27,8,15877,3.99E+09 +TF1706,52:34.0,99.265,4020,99.26,1,99.27,8,15877,3.99E+09 +TF1706,52:34.5,99.265,4020,99.26,1,99.27,8,15877,3.99E+09 +TF1706,52:36.0,99.265,4020,99.26,1,99.265,1,15877,3.99E+09 +TF1706,52:40.0,99.265,4020,99.26,1,99.265,1,15877,3.99E+09 +TF1706,52:41.5,99.265,4020,99.26,2,99.265,1,15877,3.99E+09 +TF1706,52:42.0,99.265,4020,99.26,2,99.265,1,15877,3.99E+09 +TF1706,52:42.5,99.265,4020,99.26,2,99.265,1,15877,3.99E+09 +TF1706,52:45.0,99.26,4022,99.255,3,99.265,1,15876,3.99E+09 +TF1706,52:45.5,99.26,4022,99.255,3,99.265,1,15876,3.99E+09 +TF1706,52:46.0,99.26,4022,99.255,3,99.265,2,15876,3.99E+09 +TF1706,52:48.0,99.26,4022,99.255,3,99.265,2,15876,3.99E+09 +TF1706,52:48.5,99.26,4022,99.255,3,99.265,7,15876,3.99E+09 +TF1706,52:52.5,99.26,4022,99.26,1,99.265,7,15876,3.99E+09 +TF1706,52:53.0,99.26,4023,99.255,3,99.26,6,15875,3.99E+09 +TF1706,52:53.5,99.26,4023,99.255,3,99.26,2,15875,3.99E+09 +TF1706,52:55.0,99.26,4025,99.26,3,99.265,7,15876,4.00E+09 +TF1706,52:55.5,99.26,4025,99.26,3,99.265,7,15876,4.00E+09 +TF1706,52:57.0,99.26,4025,99.26,3,99.265,3,15876,4.00E+09 +TF1706,52:57.5,99.26,4025,99.26,4,99.265,3,15876,4.00E+09 +TF1706,52:58.0,99.26,4025,99.26,5,99.265,3,15876,4.00E+09 +TF1706,52:58.5,99.26,4025,99.26,5,99.265,3,15876,4.00E+09 +TF1706,52:59.0,99.26,4025,99.26,5,99.265,2,15876,4.00E+09 +TF1706,53:01.0,99.26,4025,99.26,5,99.265,2,15876,4.00E+09 +TF1706,53:04.5,99.26,4025,99.26,5,99.265,2,15876,4.00E+09 +TF1706,53:08.0,99.26,4025,99.26,5,99.265,2,15876,4.00E+09 +TF1706,53:09.5,99.26,4025,99.26,4,99.265,2,15876,4.00E+09 +TF1706,53:10.5,99.26,4025,99.26,4,99.265,2,15876,4.00E+09 +TF1706,53:11.0,99.26,4025,99.26,4,99.265,6,15876,4.00E+09 +TF1706,53:11.5,99.26,4025,99.26,4,99.265,2,15876,4.00E+09 +TF1706,53:16.5,99.26,4025,99.26,4,99.265,2,15876,4.00E+09 +TF1706,53:21.5,99.26,4025,99.26,4,99.265,2,15876,4.00E+09 +TF1706,53:25.0,99.26,4025,99.26,5,99.265,2,15876,4.00E+09 +TF1706,53:25.5,99.26,4025,99.26,5,99.265,2,15876,4.00E+09 +TF1706,53:30.0,99.265,4027,99.26,5,99.27,8,15875,4.00E+09 +TF1706,53:30.5,99.265,4027,99.26,5,99.27,8,15875,4.00E+09 +TF1706,53:35.5,99.265,4027,99.26,5,99.27,8,15875,4.00E+09 +TF1706,53:40.0,99.265,4027,99.26,5,99.27,8,15875,4.00E+09 +TF1706,53:44.5,99.265,4027,99.26,5,99.27,8,15875,4.00E+09 +TF1706,53:47.5,99.265,4027,99.26,5,99.27,8,15875,4.00E+09 +TF1706,53:59.5,99.265,4027,99.26,5,99.27,8,15875,4.00E+09 +TF1706,54:24.5,99.265,4027,99.26,6,99.27,8,15875,4.00E+09 +TF1706,54:25.5,99.265,4027,99.26,6,99.27,4,15875,4.00E+09 +TF1706,54:26.0,99.265,4027,99.26,6,99.265,4,15875,4.00E+09 +TF1706,54:27.5,99.265,4027,99.26,5,99.265,4,15875,4.00E+09 +TF1706,54:35.5,99.265,4027,99.26,6,99.265,4,15875,4.00E+09 +TF1706,54:36.0,99.265,4027,99.26,5,99.27,8,15875,4.00E+09 +TF1706,54:36.5,99.265,4027,99.26,5,99.27,4,15875,4.00E+09 +TF1706,54:37.0,99.265,4027,99.26,6,99.265,4,15875,4.00E+09 +TF1706,54:37.5,99.265,4028,99.26,6,99.27,8,15874,4.00E+09 +TF1706,54:38.0,99.265,4028,99.26,6,99.27,4,15874,4.00E+09 +TF1706,54:38.5,99.265,4028,99.26,6,99.265,4,15874,4.00E+09 +TF1706,54:40.5,99.265,4028,99.26,6,99.27,8,15874,4.00E+09 +TF1706,54:41.0,99.265,4028,99.26,6,99.27,4,15874,4.00E+09 +TF1706,54:41.5,99.265,4028,99.26,6,99.265,4,15874,4.00E+09 +TF1706,54:42.0,99.265,4028,99.26,6,99.27,8,15874,4.00E+09 +TF1706,54:43.5,99.265,4028,99.26,6,99.27,4,15874,4.00E+09 +TF1706,54:44.0,99.265,4028,99.26,6,99.27,8,15874,4.00E+09 +TF1706,54:46.5,99.265,4028,99.26,6,99.27,8,15874,4.00E+09 +TF1706,54:51.0,99.265,4028,99.26,6,99.27,4,15874,4.00E+09 +TF1706,54:51.5,99.265,4028,99.26,6,99.27,8,15874,4.00E+09 +TF1706,54:57.0,99.265,4028,99.26,6,99.27,8,15874,4.00E+09 +TF1706,55:01.5,99.265,4028,99.26,6,99.27,9,15874,4.00E+09 +TF1706,55:02.0,99.265,4028,99.26,6,99.27,5,15874,4.00E+09 +TF1706,55:03.0,99.265,4028,99.26,6,99.265,4,15874,4.00E+09 +TF1706,55:04.5,99.265,4028,99.26,6,99.27,9,15874,4.00E+09 +TF1706,55:07.0,99.265,4028,99.26,6,99.27,9,15874,4.00E+09 +TF1706,55:09.0,99.265,4028,99.26,6,99.27,5,15874,4.00E+09 +TF1706,55:09.5,99.265,4028,99.26,6,99.265,4,15874,4.00E+09 +TF1706,55:10.0,99.265,4028,99.26,6,99.27,9,15874,4.00E+09 +TF1706,55:23.5,99.265,4028,99.26,3,99.27,9,15874,4.00E+09 +TF1706,55:24.0,99.27,4031,99.26,3,99.27,6,15875,4.00E+09 +TF1706,55:30.5,99.27,4031,99.26,4,99.27,6,15875,4.00E+09 +TF1706,55:38.0,99.27,4031,99.26,14,99.27,6,15875,4.00E+09 +TF1706,55:45.0,99.27,4031,99.265,1,99.27,6,15875,4.00E+09 +TF1706,55:45.5,99.27,4031,99.265,3,99.27,6,15875,4.00E+09 +TF1706,55:46.0,99.27,4031,99.265,4,99.27,6,15875,4.00E+09 +TF1706,55:46.5,99.27,4031,99.265,4,99.27,6,15875,4.00E+09 +TF1706,55:49.0,99.27,4031,99.265,4,99.27,6,15875,4.00E+09 +TF1706,55:49.5,99.27,4031,99.265,4,99.27,6,15875,4.00E+09 +TF1706,55:51.5,99.27,4031,99.265,4,99.27,5,15875,4.00E+09 +TF1706,55:52.0,99.27,4031,99.265,4,99.27,5,15875,4.00E+09 +TF1706,55:54.0,99.27,4031,99.265,4,99.27,5,15875,4.00E+09 +TF1706,55:56.5,99.27,4031,99.265,14,99.27,5,15875,4.00E+09 +TF1706,55:59.5,99.27,4033,99.265,15,99.275,3,15874,4.00E+09 +TF1706,56:00.0,99.27,4033,99.265,15,99.275,3,15874,4.00E+09 +TF1706,56:00.5,99.27,4033,99.27,2,99.275,7,15874,4.00E+09 +TF1706,56:01.0,99.27,4033,99.27,5,99.275,7,15874,4.00E+09 +TF1706,56:01.5,99.27,4033,99.27,4,99.275,7,15874,4.00E+09 +TF1706,56:04.0,99.275,4040,99.275,3,99.28,2,15876,4.01E+09 +TF1706,56:04.5,99.275,4044,99.27,3,99.275,14,15875,4.02E+09 +TF1706,56:05.0,99.275,4044,99.27,3,99.275,7,15875,4.02E+09 +TF1706,56:06.0,99.27,4046,99.27,1,99.275,5,15874,4.02E+09 +TF1706,56:08.5,99.265,4050,99.26,4,99.27,1,15871,4.02E+09 +TF1706,56:09.0,99.265,4050,99.265,1,99.27,1,15871,4.02E+09 +TF1706,56:09.5,99.265,4050,99.265,1,99.27,5,15871,4.02E+09 +TF1706,56:10.0,99.265,4050,99.265,1,99.27,6,15871,4.02E+09 +TF1706,56:14.0,99.265,4051,99.26,4,99.265,2,15871,4.02E+09 +TF1706,56:15.0,99.265,4051,99.26,4,99.265,2,15871,4.02E+09 +TF1706,56:16.5,99.265,4051,99.26,4,99.265,2,15871,4.02E+09 +TF1706,56:19.5,99.265,4051,99.26,4,99.265,2,15871,4.02E+09 +TF1706,56:25.5,99.26,4055,99.255,3,99.26,1,15871,4.03E+09 +TF1706,56:26.0,99.26,4056,99.26,7,99.265,1,15871,4.03E+09 +TF1706,56:26.5,99.26,4056,99.26,2,99.265,2,15871,4.03E+09 +TF1706,56:27.0,99.26,4056,99.26,2,99.265,2,15871,4.03E+09 +TF1706,56:27.5,99.26,4056,99.26,1,99.265,3,15871,4.03E+09 +TF1706,56:29.0,99.26,4056,99.26,1,99.265,3,15871,4.03E+09 +TF1706,56:29.5,99.26,4057,99.255,3,99.265,7,15872,4.03E+09 +TF1706,56:32.0,99.26,4057,99.255,3,99.265,3,15872,4.03E+09 +TF1706,56:32.5,99.26,4057,99.255,3,99.265,3,15872,4.03E+09 +TF1706,56:33.0,99.26,4057,99.255,3,99.265,7,15872,4.03E+09 +TF1706,56:34.5,99.245,4062,99.245,1,99.26,1,15872,4.03E+09 +TF1706,56:35.0,99.245,4062,99.24,2,99.25,6,15872,4.03E+09 +TF1706,56:35.5,99.245,4062,99.25,1,99.255,5,15872,4.03E+09 +TF1706,56:36.0,99.25,4063,99.245,2,99.25,9,15871,4.03E+09 +TF1706,56:36.5,99.25,4064,99.245,1,99.25,1,15870,4.04E+09 +TF1706,56:37.0,99.25,4064,99.245,1,99.25,2,15870,4.04E+09 +TF1706,56:38.5,99.25,4064,99.245,1,99.25,3,15870,4.04E+09 +TF1706,56:39.0,99.25,4064,99.245,1,99.25,3,15870,4.04E+09 +TF1706,56:40.0,99.25,4067,99.25,1,99.255,2,15869,4.04E+09 +TF1706,56:40.5,99.25,4067,99.25,1,99.255,1,15869,4.04E+09 +TF1706,56:41.0,99.25,4067,99.24,2,99.255,1,15869,4.04E+09 +TF1706,56:41.5,99.25,4067,99.25,1,99.255,1,15869,4.04E+09 +TF1706,56:42.0,99.25,4067,99.25,1,99.255,1,15869,4.04E+09 +TF1706,56:43.0,99.25,4067,99.245,4,99.255,2,15869,4.04E+09 +TF1706,56:43.5,99.25,4067,99.25,1,99.255,2,15869,4.04E+09 +TF1706,56:44.0,99.25,4067,99.245,4,99.255,2,15869,4.04E+09 +TF1706,56:46.0,99.245,4068,99.245,3,99.255,2,15869,4.04E+09 +TF1706,56:46.5,99.245,4068,99.25,1,99.255,2,15869,4.04E+09 +TF1706,56:47.0,99.245,4068,99.25,1,99.255,2,15869,4.04E+09 +TF1706,56:48.5,99.245,4068,99.245,3,99.255,2,15869,4.04E+09 +TF1706,56:53.5,99.245,4068,99.25,1,99.255,2,15869,4.04E+09 +TF1706,56:54.0,99.245,4068,99.25,4,99.255,1,15869,4.04E+09 +TF1706,56:54.5,99.255,4069,99.255,3,99.26,1,15870,4.04E+09 +TF1706,56:55.0,99.255,4069,99.255,3,99.26,2,15870,4.04E+09 +TF1706,56:55.5,99.255,4070,99.25,1,99.26,2,15871,4.04E+09 +TF1706,56:56.0,99.255,4070,99.25,1,99.26,2,15871,4.04E+09 +TF1706,56:59.5,99.255,4070,99.245,2,99.26,2,15871,4.04E+09 +TF1706,57:00.0,99.255,4070,99.245,2,99.25,6,15871,4.04E+09 +TF1706,57:00.5,99.255,4070,99.245,2,99.25,1,15871,4.04E+09 +TF1706,57:01.0,99.245,4072,99.24,2,99.245,2,15869,4.04E+09 +TF1706,57:01.5,99.245,4072,99.245,2,99.25,1,15869,4.04E+09 +TF1706,57:02.0,99.245,4072,99.245,2,99.25,1,15869,4.04E+09 +TF1706,57:02.5,99.245,4072,99.245,2,99.25,1,15869,4.04E+09 +TF1706,57:03.0,99.245,4072,99.245,2,99.25,1,15869,4.04E+09 +TF1706,57:04.0,99.245,4072,99.245,2,99.25,1,15869,4.04E+09 +TF1706,57:07.5,99.245,4072,99.245,2,99.25,1,15869,4.04E+09 +TF1706,57:08.0,99.245,4072,99.245,2,99.25,1,15869,4.04E+09 +TF1706,57:08.5,99.245,4074,99.24,3,99.245,2,15867,4.05E+09 +TF1706,57:09.0,99.245,4074,99.24,3,99.25,1,15867,4.05E+09 +TF1706,57:10.0,99.245,4074,99.245,2,99.25,1,15867,4.05E+09 +TF1706,57:10.5,99.245,4074,99.24,3,99.25,1,15867,4.05E+09 +TF1706,57:11.0,99.245,4074,99.24,3,99.25,1,15867,4.05E+09 +TF1706,57:13.5,99.245,4074,99.24,3,99.25,1,15867,4.05E+09 +TF1706,57:14.0,99.245,4074,99.245,2,99.25,1,15867,4.05E+09 +TF1706,57:15.5,99.245,4074,99.24,3,99.25,1,15867,4.05E+09 +TF1706,57:16.0,99.245,4074,99.245,3,99.25,1,15867,4.05E+09 +TF1706,57:18.5,99.245,4074,99.245,3,99.25,1,15867,4.05E+09 +TF1706,57:21.0,99.245,4074,99.24,4,99.25,1,15867,4.05E+09 +TF1706,57:21.5,99.245,4074,99.24,4,99.245,10,15867,4.05E+09 +TF1706,57:22.5,99.245,4081,99.24,4,99.245,3,15870,4.05E+09 +TF1706,57:23.0,99.245,4081,99.24,4,99.245,3,15870,4.05E+09 +TF1706,57:24.0,99.245,4081,99.24,6,99.245,3,15870,4.05E+09 +TF1706,57:24.5,99.245,4084,99.245,4,99.25,1,15870,4.06E+09 +TF1706,57:25.0,99.245,4084,99.245,3,99.25,1,15870,4.06E+09 +TF1706,57:26.5,99.245,4084,99.245,1,99.25,1,15870,4.06E+09 +TF1706,57:27.0,99.245,4084,99.24,5,99.25,2,15870,4.06E+09 +TF1706,57:27.5,99.245,4084,99.24,6,99.25,2,15870,4.06E+09 +TF1706,57:28.0,99.245,4084,99.24,6,99.25,2,15870,4.06E+09 +TF1706,57:29.5,99.245,4084,99.24,6,99.25,2,15870,4.06E+09 +TF1706,57:34.0,99.245,4084,99.24,6,99.25,2,15870,4.06E+09 +TF1706,57:39.5,99.24,4090,99.235,4,99.24,4,15873,4.06E+09 +TF1706,57:40.0,99.24,4094,99.24,6,99.25,2,15873,4.07E+09 +TF1706,57:40.5,99.24,4094,99.24,5,99.245,1,15873,4.07E+09 +TF1706,57:41.0,99.24,4094,99.24,5,99.25,2,15873,4.07E+09 +TF1706,57:42.0,99.24,4094,99.245,2,99.25,2,15873,4.07E+09 +TF1706,57:42.5,99.24,4094,99.24,3,99.25,2,15873,4.07E+09 +TF1706,57:43.0,99.24,4094,99.24,3,99.25,2,15873,4.07E+09 +TF1706,57:44.5,99.24,4094,99.24,3,99.25,2,15873,4.07E+09 +TF1706,57:45.5,99.24,4097,99.235,4,99.24,7,15873,4.07E+09 +TF1706,57:46.0,99.24,4100,99.235,4,99.24,4,15874,4.07E+09 +TF1706,57:47.5,99.24,4104,99.24,2,99.25,2,15875,4.08E+09 +TF1706,57:48.0,99.24,4104,99.24,2,99.245,1,15875,4.08E+09 +TF1706,57:48.5,99.24,4104,99.24,2,99.245,1,15875,4.08E+09 +TF1706,57:49.0,99.24,4104,99.24,2,99.245,1,15875,4.08E+09 +TF1706,57:52.0,99.24,4104,99.24,2,99.245,1,15875,4.08E+09 +TF1706,57:52.5,99.24,4106,99.235,4,99.245,1,15877,4.08E+09 +TF1706,57:53.0,99.24,4106,99.235,4,99.245,1,15877,4.08E+09 +TF1706,57:54.5,99.24,4106,99.235,4,99.245,1,15877,4.08E+09 +TF1706,57:58.5,99.24,4106,99.235,4,99.245,1,15877,4.08E+09 +TF1706,58:01.0,99.24,4106,99.235,4,99.245,1,15877,4.08E+09 +TF1706,58:01.5,99.24,4106,99.235,4,99.245,2,15877,4.08E+09 +TF1706,58:02.0,99.24,4106,99.235,4,99.245,3,15877,4.08E+09 +TF1706,58:12.5,99.24,4107,99.235,4,99.24,1,15876,4.08E+09 +TF1706,58:13.0,99.24,4107,99.235,4,99.24,2,15876,4.08E+09 +TF1706,58:18.5,99.24,4107,99.235,4,99.24,2,15876,4.08E+09 +TF1706,58:19.5,99.24,4107,99.235,4,99.24,2,15876,4.08E+09 +TF1706,58:20.0,99.24,4108,99.24,2,99.245,3,15876,4.08E+09 +TF1706,58:20.5,99.24,4109,99.24,1,99.245,3,15875,4.08E+09 +TF1706,58:21.0,99.24,4110,99.235,4,99.245,3,15874,4.08E+09 +TF1706,58:23.5,99.24,4110,99.235,4,99.245,3,15874,4.08E+09 +TF1706,58:26.0,99.24,4110,99.235,5,99.245,3,15874,4.08E+09 +TF1706,58:27.0,99.24,4110,99.235,6,99.245,3,15874,4.08E+09 +TF1706,58:33.0,99.24,4110,99.235,6,99.245,3,15874,4.08E+09 +TF1706,58:33.5,99.24,4110,99.235,6,99.24,1,15874,4.08E+09 +TF1706,58:34.0,99.24,4110,99.235,7,99.24,1,15874,4.08E+09 +TF1706,58:34.5,99.24,4111,99.24,2,99.245,3,15875,4.08E+09 +TF1706,58:35.0,99.24,4111,99.24,2,99.245,3,15875,4.08E+09 +TF1706,58:36.5,99.24,4111,99.24,2,99.245,3,15875,4.08E+09 +TF1706,58:40.5,99.24,4113,99.235,7,99.24,8,15877,4.08E+09 +TF1706,58:41.5,99.24,4113,99.235,7,99.245,3,15877,4.08E+09 +TF1706,58:42.0,99.24,4113,99.24,1,99.245,3,15877,4.08E+09 +TF1706,58:43.5,99.24,4113,99.24,1,99.245,2,15877,4.08E+09 +TF1706,58:46.5,99.24,4113,99.24,1,99.245,2,15877,4.08E+09 +TF1706,58:50.0,99.24,4113,99.24,1,99.245,2,15877,4.08E+09 +TF1706,58:51.0,99.24,4114,99.235,7,99.24,9,15877,4.09E+09 +TF1706,58:52.5,99.24,4114,99.235,7,99.245,2,15877,4.09E+09 +TF1706,59:00.5,99.24,4114,99.235,7,99.245,3,15877,4.09E+09 +TF1706,59:01.0,99.24,4114,99.235,7,99.245,3,15877,4.09E+09 +TF1706,59:12.5,99.24,4114,99.235,7,99.245,3,15877,4.09E+09 +TF1706,59:13.0,99.24,4114,99.235,6,99.245,3,15877,4.09E+09 +TF1706,59:15.0,99.235,4119,99.235,1,99.245,3,15879,4.09E+09 +TF1706,59:15.5,99.235,4120,99.23,1,99.24,3,15879,4.09E+09 +TF1706,59:16.0,99.235,4120,99.23,1,99.235,1,15879,4.09E+09 +TF1706,59:16.5,99.235,4120,99.23,1,99.235,1,15879,4.09E+09 +TF1706,59:17.0,99.235,4120,99.23,1,99.235,2,15879,4.09E+09 +TF1706,59:19.0,99.23,4121,99.225,1,99.235,2,15879,4.09E+09 +TF1706,59:19.5,99.23,4121,99.225,1,99.23,1,15879,4.09E+09 +TF1706,59:20.0,99.225,4122,99.22,1,99.225,1,15879,4.09E+09 +TF1706,59:20.5,99.225,4123,99.22,1,99.23,2,15878,4.09E+09 +TF1706,59:21.0,99.225,4123,99.22,3,99.225,1,15878,4.09E+09 +TF1706,59:22.0,99.225,4123,99.22,3,99.225,1,15878,4.09E+09 +TF1706,59:22.5,99.225,4123,99.22,1,99.225,1,15878,4.09E+09 +TF1706,59:23.0,99.225,4124,99.22,1,99.225,1,15878,4.09E+09 +TF1706,59:23.5,99.225,4124,99.22,1,99.225,1,15878,4.09E+09 +TF1706,59:24.5,99.225,4124,99.22,1,99.225,1,15878,4.09E+09 +TF1706,59:27.0,99.22,4125,99.215,1,99.225,2,15878,4.10E+09 +TF1706,59:27.5,99.22,4125,99.215,1,99.225,2,15878,4.10E+09 +TF1706,59:28.0,99.22,4125,99.215,1,99.225,2,15878,4.10E+09 +TF1706,59:30.0,99.225,4127,99.22,2,99.23,3,15878,4.10E+09 +TF1706,59:31.5,99.225,4127,99.215,5,99.23,3,15878,4.10E+09 +TF1706,59:32.0,99.225,4127,99.22,1,99.23,3,15878,4.10E+09 +TF1706,59:33.0,99.225,4127,99.22,1,99.23,3,15878,4.10E+09 +TF1706,59:33.5,99.22,4128,99.215,3,99.225,9,15877,4.10E+09 +TF1706,59:34.0,99.215,4129,99.215,2,99.22,1,15877,4.10E+09 +TF1706,59:34.5,99.22,4131,99.22,1,99.225,6,15878,4.10E+09 +TF1706,59:35.0,99.22,4132,99.215,1,99.22,1,15878,4.10E+09 +TF1706,59:35.5,99.22,4132,99.215,1,99.22,2,15878,4.10E+09 +TF1706,59:36.0,99.22,4132,99.215,1,99.22,2,15878,4.10E+09 +TF1706,59:37.0,99.22,4132,99.215,1,99.22,2,15878,4.10E+09 +TF1706,59:37.5,99.215,4133,99.21,1,99.22,2,15879,4.10E+09 +TF1706,59:38.0,99.215,4133,99.21,3,99.215,1,15879,4.10E+09 +TF1706,59:38.5,99.215,4137,99.205,2,99.215,2,15878,4.11E+09 +TF1706,59:39.0,99.215,4137,99.21,4,99.215,1,15878,4.11E+09 +TF1706,59:39.5,99.215,4137,99.205,2,99.21,2,15878,4.11E+09 +TF1706,59:40.0,99.215,4140,99.21,9,99.22,7,15879,4.11E+09 +TF1706,59:40.5,99.215,4140,99.21,5,99.22,3,15879,4.11E+09 +TF1706,59:41.0,99.215,4140,99.21,5,99.22,4,15879,4.11E+09 +TF1706,59:41.5,99.22,4142,99.21,3,99.22,1,15881,4.11E+09 +TF1706,59:42.0,99.22,4142,99.21,1,99.22,1,15881,4.11E+09 +TF1706,59:42.5,99.22,4142,99.21,1,99.22,2,15881,4.11E+09 +TF1706,59:43.0,99.22,4143,99.21,1,99.22,1,15880,4.11E+09 +TF1706,59:43.5,99.22,4143,99.21,1,99.215,1,15880,4.11E+09 +TF1706,59:44.0,99.215,4144,99.215,1,99.22,5,15881,4.11E+09 +TF1706,59:44.5,99.215,4144,99.21,1,99.215,1,15881,4.11E+09 +TF1706,59:45.0,99.215,4145,99.21,2,99.22,6,15881,4.12E+09 +TF1706,59:45.5,99.215,4145,99.21,1,99.22,2,15881,4.12E+09 +TF1706,59:46.0,99.215,4145,99.21,2,99.22,2,15881,4.12E+09 +TF1706,59:46.5,99.21,4147,99.205,2,99.22,2,15880,4.12E+09 +TF1706,59:47.0,99.21,4147,99.21,1,99.215,4,15880,4.12E+09 +TF1706,59:48.0,99.21,4147,99.21,1,99.215,4,15880,4.12E+09 +TF1706,59:48.5,99.22,4153,99.215,9,99.22,1,15882,4.12E+09 +TF1706,59:49.0,99.225,4155,99.22,16,99.23,3,15882,4.13E+09 +TF1706,59:49.5,99.225,4155,99.22,11,99.23,3,15882,4.13E+09 +TF1706,59:50.0,99.225,4155,99.225,1,99.23,3,15882,4.13E+09 +TF1706,59:50.5,99.23,4157,99.225,1,99.23,1,15883,4.13E+09 +TF1706,59:51.0,99.225,4158,99.225,1,99.23,1,15882,4.13E+09 +TF1706,59:51.5,99.225,4159,99.22,1,99.23,1,15882,4.13E+09 +TF1706,59:53.0,99.225,4159,99.22,1,99.23,1,15882,4.13E+09 +TF1706,59:53.5,99.225,4159,99.22,2,99.23,1,15882,4.13E+09 +TF1706,59:54.5,99.225,4159,99.22,2,99.23,1,15882,4.13E+09 +TF1706,59:55.0,99.225,4159,99.22,2,99.23,1,15882,4.13E+09 +TF1706,59:55.5,99.225,4159,99.22,2,99.23,1,15882,4.13E+09 +TF1706,59:56.5,99.22,4160,99.22,1,99.23,1,15883,4.13E+09 +TF1706,59:57.0,99.21,4166,99.21,1,99.23,2,15880,4.14E+09 +TF1706,59:57.5,99.21,4166,99.215,1,99.225,1,15880,4.14E+09 +TF1706,59:58.0,99.21,4166,99.22,3,99.225,1,15880,4.14E+09 +TF1706,59:58.5,99.21,4166,99.22,3,99.23,2,15880,4.14E+09 +TF1706,59:59.0,99.22,4167,99.22,2,99.23,2,15880,4.14E+09 +TF1706,00:02.0,99.22,4167,99.22,2,99.23,3,15880,4.14E+09 +TF1706,00:02.5,99.22,4170,99.22,13,99.225,2,15879,4.14E+09 +TF1706,00:03.0,99.22,4173,99.22,10,99.225,3,15881,4.14E+09 +TF1706,00:03.5,99.22,4173,99.22,10,99.225,7,15881,4.14E+09 +TF1706,00:04.0,99.22,4173,99.22,10,99.225,2,15881,4.14E+09 +TF1706,00:04.5,99.22,4173,99.22,10,99.225,2,15881,4.14E+09 +TF1706,00:05.5,99.22,4174,99.22,9,99.225,2,15881,4.14E+09 +TF1706,00:07.0,99.23,4177,99.22,9,99.23,2,15883,4.15E+09 +TF1706,00:08.0,99.23,4177,99.22,9,99.23,6,15883,4.15E+09 +TF1706,00:08.5,99.23,4177,99.22,9,99.23,2,15883,4.15E+09 +TF1706,00:11.5,99.23,4177,99.22,9,99.23,2,15883,4.15E+09 +TF1706,00:12.0,99.23,4177,99.22,9,99.23,3,15883,4.15E+09 +TF1706,00:12.5,99.23,4177,99.22,9,99.23,3,15883,4.15E+09 +TF1706,00:13.0,99.23,4177,99.225,1,99.23,4,15883,4.15E+09 +TF1706,00:13.5,99.23,4178,99.225,7,99.23,3,15884,4.15E+09 +TF1706,00:14.0,99.23,4178,99.225,7,99.23,3,15884,4.15E+09 +TF1706,00:14.5,99.225,4179,99.225,8,99.23,3,15885,4.15E+09 +TF1706,00:15.0,99.225,4179,99.225,8,99.23,3,15885,4.15E+09 +TF1706,00:15.5,99.225,4179,99.225,10,99.23,7,15885,4.15E+09 +TF1706,00:17.0,99.225,4179,99.225,10,99.23,7,15885,4.15E+09 +TF1706,00:17.5,99.225,4179,99.225,10,99.23,3,15885,4.15E+09 +TF1706,00:18.0,99.23,4180,99.225,10,99.23,2,15884,4.15E+09 +TF1706,00:18.5,99.23,4180,99.225,10,99.23,5,15884,4.15E+09 +TF1706,00:22.5,99.225,4182,99.225,8,99.23,1,15885,4.15E+09 +TF1706,00:23.0,99.225,4182,99.225,8,99.23,1,15885,4.15E+09 +TF1706,00:23.5,99.225,4182,99.225,8,99.23,1,15885,4.15E+09 +TF1706,00:24.0,99.225,4182,99.225,9,99.23,1,15885,4.15E+09 +TF1706,00:25.0,99.225,4182,99.225,9,99.23,1,15885,4.15E+09 +TF1706,00:28.0,99.225,4182,99.225,9,99.23,2,15885,4.15E+09 +TF1706,00:28.5,99.23,4183,99.225,9,99.23,1,15885,4.15E+09 +TF1706,00:29.0,99.23,4183,99.225,9,99.23,1,15885,4.15E+09 +TF1706,00:30.0,99.23,4184,99.23,1,99.235,5,15885,4.15E+09 +TF1706,00:30.5,99.23,4184,99.23,5,99.235,5,15885,4.15E+09 +TF1706,00:31.5,99.23,4184,99.23,7,99.235,5,15885,4.15E+09 +TF1706,00:32.0,99.23,4189,99.23,2,99.235,5,15885,4.16E+09 +TF1706,00:32.5,99.23,4191,99.23,2,99.235,5,15887,4.16E+09 +TF1706,00:33.5,99.23,4191,99.23,3,99.235,5,15887,4.16E+09 +TF1706,00:34.5,99.23,4191,99.23,3,99.235,1,15887,4.16E+09 +TF1706,00:35.0,99.235,4192,99.235,1,99.24,4,15887,4.16E+09 +TF1706,00:35.5,99.235,4192,99.235,3,99.24,8,15887,4.16E+09 +TF1706,00:38.5,99.235,4192,99.235,3,99.24,8,15887,4.16E+09 +TF1706,00:39.0,99.235,4192,99.235,3,99.24,8,15887,4.16E+09 +TF1706,00:42.5,99.235,4192,99.235,3,99.24,8,15887,4.16E+09 +TF1706,00:43.0,99.235,4192,99.235,2,99.24,4,15887,4.16E+09 +TF1706,00:43.5,99.235,4192,99.235,2,99.24,8,15887,4.16E+09 +TF1706,00:44.5,99.235,4192,99.235,2,99.24,8,15887,4.16E+09 +TF1706,00:46.5,99.235,4192,99.235,2,99.24,8,15887,4.16E+09 +TF1706,00:47.0,99.235,4192,99.235,2,99.24,4,15887,4.16E+09 +TF1706,00:48.5,99.24,4193,99.235,2,99.24,3,15888,4.16E+09 +TF1706,00:49.0,99.24,4193,99.235,2,99.24,2,15888,4.16E+09 +TF1706,00:54.0,99.24,4195,99.235,2,99.245,3,15887,4.17E+09 +TF1706,00:54.5,99.24,4195,99.235,2,99.245,3,15887,4.17E+09 +TF1706,00:55.5,99.235,4198,99.23,1,99.24,1,15888,4.17E+09 +TF1706,00:56.0,99.235,4198,99.23,1,99.235,1,15888,4.17E+09 +TF1706,00:56.5,99.235,4198,99.23,1,99.24,1,15888,4.17E+09 +TF1706,00:57.0,99.235,4198,99.23,1,99.24,5,15888,4.17E+09 +TF1706,00:57.5,99.235,4198,99.23,1,99.235,10,15888,4.17E+09 +TF1706,00:58.0,99.235,4198,99.23,1,99.235,3,15888,4.17E+09 +TF1706,00:58.5,99.235,4198,99.23,1,99.235,1,15888,4.17E+09 +TF1706,01:00.0,99.235,4198,99.23,1,99.24,6,15888,4.17E+09 +TF1706,01:00.5,99.235,4198,99.23,1,99.24,6,15888,4.17E+09 +TF1706,01:01.5,99.235,4198,99.23,2,99.235,1,15888,4.17E+09 +TF1706,01:02.0,99.235,4198,99.23,2,99.235,1,15888,4.17E+09 +TF1706,01:02.5,99.235,4198,99.23,3,99.235,1,15888,4.17E+09 +TF1706,01:03.5,99.235,4199,99.23,4,99.24,6,15887,4.17E+09 +TF1706,01:04.0,99.235,4199,99.23,4,99.24,6,15887,4.17E+09 +TF1706,01:04.5,99.235,4199,99.23,4,99.24,2,15887,4.17E+09 +TF1706,01:05.5,99.235,4199,99.23,4,99.24,6,15887,4.17E+09 +TF1706,01:07.0,99.235,4199,99.235,1,99.24,6,15887,4.17E+09 +TF1706,01:09.0,99.235,4199,99.235,1,99.24,6,15887,4.17E+09 +TF1706,01:09.5,99.235,4199,99.235,2,99.24,6,15887,4.17E+09 +TF1706,01:10.0,99.235,4199,99.235,2,99.24,2,15887,4.17E+09 +TF1706,01:14.0,99.235,4199,99.235,2,99.24,6,15887,4.17E+09 +TF1706,01:17.5,99.235,4199,99.235,2,99.24,2,15887,4.17E+09 +TF1706,01:21.0,99.23,4204,99.23,2,99.24,7,15885,4.17E+09 +TF1706,01:21.5,99.24,4206,99.235,5,99.24,5,15884,4.18E+09 +TF1706,01:22.0,99.24,4206,99.23,2,99.24,5,15884,4.18E+09 +TF1706,01:22.5,99.24,4206,99.235,1,99.24,5,15884,4.18E+09 +TF1706,01:23.5,99.24,4206,99.235,1,99.24,5,15884,4.18E+09 +TF1706,01:25.5,99.24,4209,99.235,1,99.24,2,15884,4.18E+09 +TF1706,01:26.0,99.24,4211,99.24,2,99.245,3,15884,4.18E+09 +TF1706,01:26.5,99.24,4212,99.24,4,99.245,7,15885,4.18E+09 +TF1706,01:27.0,99.24,4216,99.235,2,99.245,7,15884,4.19E+09 +TF1706,01:27.5,99.24,4216,99.235,2,99.245,7,15884,4.19E+09 +TF1706,01:31.5,99.24,4216,99.235,2,99.245,7,15884,4.19E+09 +TF1706,01:33.5,99.24,4216,99.235,3,99.245,3,15884,4.19E+09 +TF1706,01:40.0,99.24,4216,99.24,1,99.245,3,15884,4.19E+09 +TF1706,01:40.5,99.245,4219,99.245,8,99.25,7,15887,4.19E+09 +TF1706,01:41.0,99.245,4219,99.245,1,99.25,7,15887,4.19E+09 +TF1706,01:41.5,99.25,4220,99.245,1,99.25,2,15888,4.19E+09 +TF1706,01:42.0,99.245,4221,99.24,1,99.245,1,15887,4.19E+09 +TF1706,01:42.5,99.245,4221,99.24,2,99.245,1,15887,4.19E+09 +TF1706,01:43.0,99.245,4221,99.24,2,99.245,1,15887,4.19E+09 +TF1706,01:43.5,99.235,4224,99.235,1,99.24,1,15884,4.19E+09 +TF1706,01:44.0,99.235,4224,99.235,2,99.24,1,15884,4.19E+09 +TF1706,01:44.5,99.235,4224,99.235,2,99.24,1,15884,4.19E+09 +TF1706,01:45.0,99.24,4225,99.24,3,99.245,2,15884,4.20E+09 +TF1706,01:45.5,99.24,4225,99.235,2,99.245,2,15884,4.20E+09 +TF1706,01:46.0,99.245,4227,99.245,3,99.25,2,15884,4.20E+09 +TF1706,01:46.5,99.245,4230,99.24,3,99.25,2,15881,4.20E+09 +TF1706,01:47.0,99.245,4230,99.24,3,99.245,1,15881,4.20E+09 +TF1706,01:47.5,99.245,4231,99.245,1,99.25,6,15880,4.20E+09 +TF1706,01:48.0,99.245,4231,99.24,3,99.25,6,15880,4.20E+09 +TF1706,01:48.5,99.245,4231,99.24,3,99.25,2,15880,4.20E+09 +TF1706,01:49.0,99.245,4231,99.24,4,99.25,2,15880,4.20E+09 +TF1706,01:49.5,99.245,4231,99.24,4,99.25,6,15880,4.20E+09 +TF1706,01:50.0,99.245,4231,99.24,4,99.25,6,15880,4.20E+09 +TF1706,01:51.5,99.25,4234,99.24,4,99.25,4,15881,4.20E+09 +TF1706,01:53.0,99.25,4234,99.24,4,99.25,5,15881,4.20E+09 +TF1706,01:54.5,99.25,4234,99.24,4,99.25,1,15881,4.20E+09 +TF1706,01:55.0,99.25,4234,99.24,4,99.25,1,15881,4.20E+09 +TF1706,01:55.5,99.25,4234,99.24,2,99.25,1,15881,4.20E+09 +TF1706,01:56.0,99.25,4234,99.24,2,99.25,1,15881,4.20E+09 +TF1706,01:56.5,99.25,4234,99.24,2,99.25,1,15881,4.20E+09 +TF1706,01:57.0,99.25,4234,99.24,2,99.25,1,15881,4.20E+09 +TF1706,02:00.5,99.24,4235,99.24,1,99.25,1,15881,4.21E+09 +TF1706,02:01.0,99.24,4235,99.24,1,99.25,2,15881,4.21E+09 +TF1706,02:03.0,99.24,4235,99.24,1,99.25,2,15881,4.21E+09 +TF1706,02:04.0,99.24,4235,99.24,1,99.25,2,15881,4.21E+09 +TF1706,02:05.0,99.24,4235,99.24,1,99.25,3,15881,4.21E+09 +TF1706,02:06.0,99.24,4235,99.24,1,99.25,3,15881,4.21E+09 +TF1706,02:07.5,99.24,4235,99.24,1,99.25,3,15881,4.21E+09 +TF1706,02:09.0,99.24,4235,99.24,1,99.25,3,15881,4.21E+09 +TF1706,02:09.5,99.24,4235,99.24,1,99.245,5,15881,4.21E+09 +TF1706,02:10.0,99.24,4235,99.24,1,99.245,1,15881,4.21E+09 +TF1706,02:11.5,99.24,4235,99.24,2,99.245,1,15881,4.21E+09 +TF1706,02:12.0,99.245,4236,99.245,2,99.25,3,15882,4.21E+09 +TF1706,02:12.5,99.245,4236,99.245,1,99.25,3,15882,4.21E+09 +TF1706,02:13.0,99.245,4236,99.245,1,99.25,3,15882,4.21E+09 +TF1706,02:17.0,99.245,4236,99.245,1,99.25,3,15882,4.21E+09 +TF1706,02:17.5,99.245,4236,99.24,2,99.25,3,15882,4.21E+09 +TF1706,02:18.5,99.245,4236,99.24,2,99.25,3,15882,4.21E+09 +TF1706,02:19.0,99.245,4236,99.24,2,99.25,3,15882,4.21E+09 +TF1706,02:20.0,99.245,4236,99.24,2,99.25,3,15882,4.21E+09 +TF1706,02:23.0,99.245,4236,99.24,2,99.25,3,15882,4.21E+09 +TF1706,02:27.5,99.245,4236,99.24,6,99.25,3,15882,4.21E+09 +TF1706,02:36.5,99.245,4236,99.24,2,99.25,3,15882,4.21E+09 +TF1706,02:37.5,99.245,4236,99.24,2,99.25,3,15882,4.21E+09 +TF1706,02:38.0,99.245,4236,99.24,2,99.25,3,15882,4.21E+09 +TF1706,02:39.0,99.245,4236,99.24,2,99.25,3,15882,4.21E+09 +TF1706,02:40.0,99.245,4236,99.24,2,99.25,3,15882,4.21E+09 +TF1706,02:40.5,99.245,4236,99.24,2,99.25,7,15882,4.21E+09 +TF1706,02:42.5,99.245,4236,99.24,2,99.25,3,15882,4.21E+09 +TF1706,02:43.0,99.245,4236,99.24,2,99.25,3,15882,4.21E+09 +TF1706,02:50.0,99.245,4236,99.24,2,99.25,3,15882,4.21E+09 +TF1706,02:51.0,99.245,4236,99.24,2,99.25,3,15882,4.21E+09 +TF1706,02:51.5,99.245,4236,99.24,2,99.25,3,15882,4.21E+09 +TF1706,02:52.5,99.245,4236,99.24,2,99.25,3,15882,4.21E+09 +TF1706,02:53.0,99.245,4236,99.24,2,99.25,3,15882,4.21E+09 +TF1706,02:57.0,99.245,4236,99.24,2,99.25,3,15882,4.21E+09 +TF1706,02:59.0,99.245,4236,99.24,3,99.25,3,15882,4.21E+09 +TF1706,03:00.0,99.245,4236,99.245,1,99.25,3,15882,4.21E+09 +TF1706,03:01.0,99.245,4236,99.245,1,99.25,2,15882,4.21E+09 +TF1706,03:01.5,99.245,4236,99.245,2,99.25,4,15882,4.21E+09 +TF1706,03:02.5,99.245,4236,99.245,2,99.25,4,15882,4.21E+09 +TF1706,03:03.0,99.25,4240,99.25,2,99.255,3,15881,4.21E+09 +TF1706,03:03.5,99.25,4241,99.245,2,99.255,4,15880,4.21E+09 +TF1706,03:04.0,99.25,4241,99.245,2,99.255,4,15880,4.21E+09 +TF1706,03:04.5,99.25,4241,99.245,2,99.255,4,15880,4.21E+09 +TF1706,03:08.0,99.25,4241,99.245,1,99.255,4,15880,4.21E+09 +TF1706,03:08.5,99.25,4241,99.245,1,99.25,6,15880,4.21E+09 +TF1706,03:09.0,99.25,4241,99.245,1,99.255,4,15880,4.21E+09 +TF1706,03:11.0,99.25,4241,99.245,1,99.255,8,15880,4.21E+09 +TF1706,03:11.5,99.25,4241,99.245,1,99.255,4,15880,4.21E+09 +TF1706,03:18.0,99.25,4241,99.245,1,99.255,4,15880,4.21E+09 +TF1706,03:18.5,99.25,4241,99.245,1,99.255,4,15880,4.21E+09 +TF1706,03:29.0,99.245,4242,99.24,5,99.255,4,15879,4.21E+09 +TF1706,03:29.5,99.245,4242,99.24,8,99.245,4,15879,4.21E+09 +TF1706,03:30.0,99.24,4247,99.235,3,99.25,1,15882,4.22E+09 +TF1706,03:30.5,99.24,4248,99.235,3,99.24,3,15882,4.22E+09 +TF1706,03:31.5,99.235,4252,99.23,4,99.24,2,15883,4.22E+09 +TF1706,03:32.0,99.24,4254,99.24,1,99.245,2,15882,4.22E+09 +TF1706,03:32.5,99.24,4254,99.24,1,99.245,3,15882,4.22E+09 +TF1706,03:33.0,99.24,4254,99.24,1,99.245,3,15882,4.22E+09 +TF1706,03:35.0,99.24,4254,99.24,1,99.245,3,15882,4.22E+09 +TF1706,03:36.0,99.24,4255,99.235,3,99.245,3,15881,4.22E+09 +TF1706,03:36.5,99.24,4255,99.235,3,99.24,3,15881,4.22E+09 +TF1706,03:37.0,99.24,4256,99.235,3,99.245,3,15881,4.23E+09 +TF1706,03:37.5,99.24,4256,99.235,3,99.24,3,15881,4.23E+09 +TF1706,03:38.0,99.24,4256,99.235,3,99.245,3,15881,4.23E+09 +TF1706,03:41.5,99.24,4256,99.235,1,99.245,3,15881,4.23E+09 +TF1706,03:42.0,99.24,4256,99.235,2,99.24,3,15881,4.23E+09 +TF1706,03:42.5,99.24,4256,99.235,2,99.24,1,15881,4.23E+09 +TF1706,03:43.0,99.24,4256,99.235,2,99.24,1,15881,4.23E+09 +TF1706,03:46.5,99.24,4256,99.235,1,99.24,1,15881,4.23E+09 +TF1706,03:47.5,99.24,4256,99.235,11,99.24,1,15881,4.23E+09 +TF1706,03:48.0,99.24,4256,99.24,9,99.245,3,15881,4.23E+09 +TF1706,03:48.5,99.24,4256,99.24,4,99.245,3,15881,4.23E+09 +TF1706,03:51.0,99.24,4256,99.24,4,99.245,4,15881,4.23E+09 +TF1706,03:58.0,99.24,4256,99.24,2,99.245,4,15881,4.23E+09 +TF1706,03:59.0,99.245,4257,99.235,11,99.245,3,15881,4.23E+09 +TF1706,03:59.5,99.245,4257,99.24,1,99.245,3,15881,4.23E+09 +TF1706,04:03.0,99.245,4257,99.24,1,99.245,2,15881,4.23E+09 +TF1706,04:03.5,99.245,4257,99.24,2,99.245,2,15881,4.23E+09 +TF1706,04:04.0,99.245,4257,99.24,2,99.245,1,15881,4.23E+09 +TF1706,04:13.0,99.245,4257,99.24,2,99.245,2,15881,4.23E+09 +TF1706,04:33.0,99.245,4257,99.24,2,99.245,2,15881,4.23E+09 +TF1706,04:33.5,99.245,4257,99.24,2,99.245,7,15881,4.23E+09 +TF1706,04:34.0,99.245,4257,99.24,1,99.245,7,15881,4.23E+09 +TF1706,04:34.5,99.24,4258,99.235,14,99.24,2,15880,4.23E+09 +TF1706,04:35.0,99.24,4260,99.235,14,99.245,7,15879,4.23E+09 +TF1706,04:36.0,99.24,4260,99.235,11,99.245,7,15879,4.23E+09 +TF1706,04:39.5,99.24,4260,99.235,11,99.245,7,15879,4.23E+09 +TF1706,04:40.0,99.24,4260,99.235,11,99.245,3,15879,4.23E+09 +TF1706,04:40.5,99.24,4260,99.24,1,99.245,3,15879,4.23E+09 +TF1706,04:44.0,99.24,4260,99.24,1,99.245,2,15879,4.23E+09 +TF1706,04:44.5,99.24,4260,99.24,2,99.245,2,15879,4.23E+09 +TF1706,04:45.5,99.24,4260,99.24,2,99.245,2,15879,4.23E+09 +TF1706,04:47.0,99.24,4260,99.24,2,99.245,2,15879,4.23E+09 +TF1706,04:49.5,99.24,4260,99.24,5,99.245,2,15879,4.23E+09 +TF1706,04:54.5,99.24,4260,99.24,2,99.245,2,15879,4.23E+09 +TF1706,04:58.5,99.24,4260,99.24,5,99.245,2,15879,4.23E+09 +TF1706,04:59.5,99.24,4260,99.24,5,99.245,3,15879,4.23E+09 +TF1706,05:00.5,99.24,4260,99.24,5,99.245,7,15879,4.23E+09 +TF1706,05:01.0,99.24,4260,99.24,4,99.245,7,15879,4.23E+09 +TF1706,05:03.5,99.24,4260,99.24,1,99.245,7,15879,4.23E+09 +TF1706,05:07.5,99.24,4260,99.24,4,99.245,7,15879,4.23E+09 +TF1706,05:12.5,99.24,4260,99.24,1,99.245,7,15879,4.23E+09 +TF1706,05:13.0,99.24,4260,99.24,1,99.245,6,15879,4.23E+09 +TF1706,05:14.0,99.24,4260,99.24,1,99.245,6,15879,4.23E+09 +TF1706,05:16.5,99.245,4263,99.24,1,99.245,3,15877,4.23E+09 +TF1706,05:17.0,99.24,4265,99.235,12,99.245,3,15875,4.23E+09 +TF1706,05:26.5,99.24,4265,99.235,12,99.245,3,15875,4.23E+09 +TF1706,05:29.5,99.24,4265,99.235,12,99.245,4,15875,4.23E+09 +TF1706,05:30.0,99.24,4265,99.235,12,99.245,4,15875,4.23E+09 +TF1706,05:30.5,99.24,4265,99.24,1,99.245,4,15875,4.23E+09 +TF1706,05:34.5,99.24,4265,99.24,1,99.245,4,15875,4.23E+09 +TF1706,05:35.0,99.24,4266,99.24,1,99.245,4,15875,4.24E+09 +TF1706,05:35.5,99.24,4267,99.235,15,99.245,4,15875,4.24E+09 +TF1706,05:36.0,99.24,4267,99.235,12,99.245,4,15875,4.24E+09 +TF1706,05:36.5,99.24,4267,99.235,12,99.24,1,15875,4.24E+09 +TF1706,05:37.0,99.24,4267,99.235,12,99.24,2,15875,4.24E+09 +TF1706,05:37.5,99.24,4269,99.235,12,99.24,4,15875,4.24E+09 +TF1706,05:38.0,99.24,4269,99.235,12,99.245,4,15875,4.24E+09 +TF1706,05:38.5,99.24,4269,99.235,12,99.245,6,15875,4.24E+09 +TF1706,05:39.5,99.24,4269,99.235,12,99.245,6,15875,4.24E+09 +TF1706,05:40.5,99.24,4269,99.235,12,99.245,6,15875,4.24E+09 +TF1706,05:45.5,99.24,4269,99.235,12,99.245,6,15875,4.24E+09 +TF1706,05:47.0,99.235,4270,99.235,11,99.245,6,15875,4.24E+09 +TF1706,05:47.5,99.235,4270,99.235,11,99.24,1,15875,4.24E+09 +TF1706,05:48.0,99.235,4271,99.235,10,99.24,1,15876,4.24E+09 +TF1706,05:48.5,99.235,4271,99.235,13,99.24,2,15876,4.24E+09 +TF1706,05:51.5,99.235,4272,99.235,12,99.24,3,15877,4.24E+09 +TF1706,05:54.5,99.235,4272,99.235,9,99.24,4,15877,4.24E+09 +TF1706,05:55.0,99.24,4275,99.235,9,99.24,1,15877,4.24E+09 +TF1706,05:56.0,99.24,4275,99.235,9,99.245,6,15877,4.24E+09 +TF1706,05:58.5,99.24,4275,99.24,3,99.245,6,15877,4.24E+09 +TF1706,05:59.0,99.235,4279,99.235,8,99.24,5,15875,4.25E+09 +TF1706,05:59.5,99.235,4281,99.235,6,99.24,5,15875,4.25E+09 +TF1706,06:00.0,99.235,4281,99.235,6,99.24,9,15875,4.25E+09 +TF1706,06:00.5,99.235,4284,99.235,3,99.24,9,15878,4.25E+09 +TF1706,06:01.0,99.235,4287,99.23,3,99.24,9,15878,4.26E+09 +TF1706,06:01.5,99.235,4287,99.23,3,99.24,9,15878,4.26E+09 +TF1706,06:02.0,99.235,4287,99.23,3,99.235,1,15878,4.26E+09 +TF1706,06:02.5,99.23,4290,99.225,6,99.235,3,15881,4.26E+09 +TF1706,06:03.0,99.23,4290,99.225,6,99.235,3,15881,4.26E+09 +TF1706,06:04.0,99.23,4290,99.225,6,99.235,7,15881,4.26E+09 +TF1706,06:04.5,99.23,4290,99.225,6,99.235,3,15881,4.26E+09 +TF1706,06:05.0,99.23,4290,99.225,6,99.235,3,15881,4.26E+09 +TF1706,06:05.5,99.23,4294,99.23,5,99.24,2,15880,4.26E+09 +TF1706,06:06.0,99.23,4294,99.23,3,99.24,6,15880,4.26E+09 +TF1706,06:06.5,99.23,4294,99.23,4,99.24,6,15880,4.26E+09 +TF1706,06:07.0,99.23,4294,99.23,4,99.24,7,15880,4.26E+09 +TF1706,06:08.0,99.23,4294,99.23,3,99.24,7,15880,4.26E+09 +TF1706,06:08.5,99.23,4294,99.23,4,99.24,7,15880,4.26E+09 +TF1706,06:09.0,99.23,4294,99.23,4,99.24,7,15880,4.26E+09 +TF1706,06:11.0,99.23,4294,99.23,4,99.24,8,15880,4.26E+09 +TF1706,06:11.5,99.23,4294,99.23,4,99.24,8,15880,4.26E+09 +TF1706,06:12.0,99.24,4298,99.23,4,99.24,4,15882,4.27E+09 +TF1706,06:12.5,99.24,4298,99.235,1,99.24,2,15882,4.27E+09 +TF1706,06:13.0,99.24,4298,99.235,2,99.24,2,15882,4.27E+09 +TF1706,06:13.5,99.24,4298,99.235,3,99.24,2,15882,4.27E+09 +TF1706,06:14.0,99.24,4298,99.235,3,99.24,2,15882,4.27E+09 +TF1706,06:16.5,99.24,4300,99.24,2,99.245,2,15882,4.27E+09 +TF1706,06:17.0,99.24,4300,99.24,2,99.245,2,15882,4.27E+09 +TF1706,06:17.5,99.24,4300,99.24,2,99.245,2,15882,4.27E+09 +TF1706,06:19.5,99.24,4300,99.24,2,99.245,2,15882,4.27E+09 +TF1706,06:20.5,99.24,4300,99.24,2,99.245,1,15882,4.27E+09 +TF1706,06:21.0,99.24,4302,99.235,3,99.245,1,15882,4.27E+09 +TF1706,06:21.5,99.24,4302,99.235,3,99.245,5,15882,4.27E+09 +TF1706,06:22.0,99.24,4302,99.235,3,99.245,1,15882,4.27E+09 +TF1706,06:22.5,99.24,4302,99.24,1,99.245,1,15882,4.27E+09 +TF1706,06:23.0,99.24,4302,99.24,2,99.245,5,15882,4.27E+09 +TF1706,06:24.5,99.24,4302,99.24,2,99.245,1,15882,4.27E+09 +TF1706,06:25.0,99.24,4302,99.24,2,99.245,1,15882,4.27E+09 +TF1706,06:25.5,99.24,4302,99.24,2,99.245,1,15882,4.27E+09 +TF1706,06:26.0,99.24,4302,99.24,2,99.245,1,15882,4.27E+09 +TF1706,06:26.5,99.245,4304,99.24,3,99.245,3,15881,4.27E+09 +TF1706,06:27.0,99.245,4304,99.24,2,99.255,4,15881,4.27E+09 +TF1706,06:27.5,99.245,4304,99.24,2,99.25,3,15881,4.27E+09 +TF1706,06:28.0,99.245,4304,99.24,2,99.25,4,15881,4.27E+09 +TF1706,06:34.5,99.245,4304,99.24,2,99.25,4,15881,4.27E+09 +TF1706,06:36.0,99.245,4304,99.24,2,99.25,4,15881,4.27E+09 +TF1706,06:37.0,99.24,4305,99.24,1,99.25,4,15882,4.27E+09 +TF1706,06:38.0,99.24,4305,99.24,1,99.25,4,15882,4.27E+09 +TF1706,06:39.5,99.24,4305,99.24,1,99.25,4,15882,4.27E+09 +TF1706,06:45.0,99.24,4305,99.24,1,99.25,4,15882,4.27E+09 +TF1706,06:47.0,99.24,4305,99.24,2,99.25,4,15882,4.27E+09 +TF1706,06:48.0,99.24,4305,99.245,9,99.25,4,15882,4.27E+09 +TF1706,06:48.5,99.24,4305,99.245,9,99.25,4,15882,4.27E+09 +TF1706,06:49.0,99.24,4305,99.245,9,99.25,3,15882,4.27E+09 +TF1706,06:53.0,99.24,4305,99.245,9,99.25,1,15882,4.27E+09 +TF1706,06:53.5,99.245,4315,99.24,2,99.255,4,15882,4.28E+09 +TF1706,06:54.0,99.245,4315,99.24,2,99.25,1,15882,4.28E+09 +TF1706,06:54.5,99.245,4315,99.24,2,99.25,2,15882,4.28E+09 +TF1706,06:59.5,99.245,4315,99.24,2,99.25,2,15882,4.28E+09 +TF1706,07:03.0,99.24,4317,99.235,25,99.25,5,15881,4.29E+09 +TF1706,07:03.5,99.24,4317,99.24,1,99.245,7,15881,4.29E+09 +TF1706,07:04.0,99.245,4318,99.24,1,99.245,8,15882,4.29E+09 +TF1706,07:04.5,99.245,4318,99.24,1,99.245,8,15882,4.29E+09 +TF1706,07:05.0,99.245,4318,99.24,1,99.245,1,15882,4.29E+09 +TF1706,07:11.0,99.245,4318,99.24,2,99.245,1,15882,4.29E+09 +TF1706,07:16.0,99.245,4318,99.24,3,99.25,3,15882,4.29E+09 +TF1706,07:16.5,99.245,4318,99.24,3,99.25,3,15882,4.29E+09 +TF1706,07:27.0,99.245,4318,99.24,3,99.25,3,15882,4.29E+09 +TF1706,07:28.0,99.245,4318,99.24,3,99.25,3,15882,4.29E+09 +TF1706,07:28.5,99.245,4318,99.24,4,99.25,3,15882,4.29E+09 +TF1706,07:34.5,99.245,4318,99.24,4,99.25,3,15882,4.29E+09 +TF1706,07:35.5,99.245,4318,99.24,4,99.25,3,15882,4.29E+09 +TF1706,07:36.0,99.245,4318,99.24,4,99.25,3,15882,4.29E+09 +TF1706,07:39.0,99.245,4318,99.24,4,99.25,3,15882,4.29E+09 +TF1706,07:44.0,99.245,4318,99.24,4,99.25,3,15882,4.29E+09 +TF1706,07:47.0,99.245,4318,99.245,6,99.25,3,15882,4.29E+09 +TF1706,07:53.0,99.245,4318,99.24,4,99.25,3,15882,4.29E+09 +TF1706,07:55.5,99.245,4318,99.24,57,99.25,3,15882,4.29E+09 +TF1706,07:56.0,99.245,4318,99.245,8,99.25,3,15882,4.29E+09 +TF1706,07:56.5,99.245,4318,99.245,7,99.25,3,15882,4.29E+09 +TF1706,08:02.0,99.245,4318,99.245,4,99.25,3,15882,4.29E+09 +TF1706,08:02.5,99.245,4318,99.245,1,99.25,3,15882,4.29E+09 +TF1706,08:05.0,99.245,4318,99.245,7,99.25,3,15882,4.29E+09 +TF1706,08:05.5,99.245,4319,99.245,7,99.25,2,15881,4.29E+09 +TF1706,08:06.0,99.245,4319,99.245,7,99.25,2,15881,4.29E+09 +TF1706,08:11.0,99.245,4319,99.245,1,99.25,2,15881,4.29E+09 +TF1706,08:13.5,99.245,4320,99.24,57,99.245,2,15882,4.29E+09 +TF1706,08:14.0,99.245,4322,99.245,15,99.25,2,15882,4.29E+09 +TF1706,08:14.5,99.245,4322,99.245,10,99.25,2,15882,4.29E+09 +TF1706,08:15.0,99.245,4322,99.245,10,99.25,1,15882,4.29E+09 +TF1706,08:15.5,99.245,4322,99.245,10,99.25,1,15882,4.29E+09 +TF1706,08:16.0,99.245,4322,99.245,8,99.25,1,15882,4.29E+09 +TF1706,08:17.5,99.245,4330,99.24,57,99.245,2,15883,4.30E+09 +TF1706,08:18.0,99.245,4330,99.24,57,99.245,7,15883,4.30E+09 +TF1706,08:18.5,99.24,4333,99.24,54,99.245,7,15881,4.30E+09 +TF1706,08:19.5,99.24,4333,99.24,54,99.245,2,15881,4.30E+09 +TF1706,08:21.5,99.245,4335,99.24,54,99.25,2,15883,4.30E+09 +TF1706,08:22.0,99.245,4335,99.24,54,99.245,5,15883,4.30E+09 +TF1706,08:22.5,99.245,4335,99.24,54,99.245,5,15883,4.30E+09 +TF1706,08:27.5,99.245,4335,99.24,54,99.245,5,15883,4.30E+09 +TF1706,08:29.0,99.245,4335,99.24,54,99.245,5,15883,4.30E+09 +TF1706,08:32.5,99.245,4335,99.24,54,99.25,3,15883,4.30E+09 +TF1706,08:33.0,99.245,4335,99.24,54,99.25,3,15883,4.30E+09 +TF1706,08:34.5,99.245,4335,99.24,54,99.25,3,15883,4.30E+09 +TF1706,08:36.0,99.245,4335,99.24,54,99.25,3,15883,4.30E+09 +TF1706,08:39.5,99.245,4335,99.24,54,99.25,3,15883,4.30E+09 +TF1706,08:40.0,99.245,4335,99.24,34,99.25,3,15883,4.30E+09 +TF1706,08:41.5,99.245,4335,99.24,34,99.245,5,15883,4.30E+09 +TF1706,08:42.0,99.245,4335,99.24,34,99.25,3,15883,4.30E+09 +TF1706,08:42.5,99.245,4335,99.24,34,99.25,3,15883,4.30E+09 diff --git a/qbot/engine/trade/engine_apis/futures/CTPtest/CTPtest/zn1705_market_data.csv b/qbot/engine/trade/engine_apis/futures/CTPtest/CTPtest/zn1705_market_data.csv new file mode 100644 index 00000000..353d8666 --- /dev/null +++ b/qbot/engine/trade/engine_apis/futures/CTPtest/CTPtest/zn1705_market_data.csv @@ -0,0 +1,2 @@ +Լ,ʱ,¼,ɽ,һ,һ,һ,һ,ֲ, +zn1705,11:30:01.0,23140,653404,23135,47,23140,16,245380,7.48516e+010 diff --git a/qbot/engine/trade/engine_apis/futures/CTPtest/Debug/thostmduserapi.dll b/qbot/engine/trade/engine_apis/futures/CTPtest/Debug/thostmduserapi.dll new file mode 100644 index 00000000..89b7cec4 Binary files /dev/null and b/qbot/engine/trade/engine_apis/futures/CTPtest/Debug/thostmduserapi.dll differ diff --git a/qbot/engine/trade/engine_apis/futures/CTPtest/Debug/thosttraderapi.dll b/qbot/engine/trade/engine_apis/futures/CTPtest/Debug/thosttraderapi.dll new file mode 100644 index 00000000..9e386185 Binary files /dev/null and b/qbot/engine/trade/engine_apis/futures/CTPtest/Debug/thosttraderapi.dll differ diff --git a/qbot/engine/trade/engine_apis/futures/CTPtest/LICENSE b/qbot/engine/trade/engine_apis/futures/CTPtest/LICENSE new file mode 100644 index 00000000..2546ff60 --- /dev/null +++ b/qbot/engine/trade/engine_apis/futures/CTPtest/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2017 Ethan He + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/qbot/engine/trade/engine_apis/futures/CTPtest/README.md b/qbot/engine/trade/engine_apis/futures/CTPtest/README.md new file mode 100644 index 00000000..2be0e581 --- /dev/null +++ b/qbot/engine/trade/engine_apis/futures/CTPtest/README.md @@ -0,0 +1,13 @@ +# CTPtest +用ctp官方接口写的一个简单demo,具备行情、交易、k线数据以及策略功能,可以连接simnow模拟交易~
+编译环境是windows+vs2015,如果要用在linux上,需要用linux版的ctp api + +# 博客地址 +http://blog.csdn.net/u012234115/article/details/70195889 + +# 截图 +![](http://img.blog.csdn.net/20170417215811398?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxMjIzNDExNQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
+![](http://img.blog.csdn.net/20170418214637074?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxMjIzNDExNQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
+![](http://img.blog.csdn.net/20170417215830533?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxMjIzNDExNQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
+![](http://img.blog.csdn.net/20170418214714089?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxMjIzNDExNQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
+![](http://img.blog.csdn.net/20170417215848789?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxMjIzNDExNQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center) diff --git a/qbot/engine/trade/engine_apis/futures/CTPtest/src/CTP_API/ThostFtdcMdApi.h b/qbot/engine/trade/engine_apis/futures/CTPtest/src/CTP_API/ThostFtdcMdApi.h new file mode 100644 index 00000000..b9b19581 --- /dev/null +++ b/qbot/engine/trade/engine_apis/futures/CTPtest/src/CTP_API/ThostFtdcMdApi.h @@ -0,0 +1,186 @@ +///////////////////////////////////////////////////////////////////////// +///@system һϵͳ +///@company ϺڻϢ޹˾ +///@file ThostFtdcMdApi.h +///@brief ˿ͻ˽ӿ +///@history +/// 20060106 Ժ ļ +///////////////////////////////////////////////////////////////////////// + +#if !defined(THOST_FTDCMDAPI_H) +#define THOST_FTDCMDAPI_H + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 + +#include "ThostFtdcUserApiStruct.h" + +#if defined(ISLIB) && defined(WIN32) +#ifdef LIB_MD_API_EXPORT +#define MD_API_EXPORT __declspec(dllexport) +#else +#define MD_API_EXPORT __declspec(dllimport) +#endif +#else +#define MD_API_EXPORT +#endif + +class CThostFtdcMdSpi { +public: + ///ͻ뽻׺̨ͨʱδ¼ǰ÷á + virtual void OnFrontConnected(){}; + + ///ͻ뽻׺̨ͨӶϿʱ÷áAPIԶӣͻ˿ɲ + ///@param nReason ԭ + /// 0x1001 ʧ + /// 0x1002 дʧ + /// 0x2001 ʱ + /// 0x2002 ʧ + /// 0x2003 յ + virtual void OnFrontDisconnected(int nReason){}; + + ///ʱ档ʱδյʱ÷á + ///@param nTimeLapse ϴνձĵʱ + virtual void OnHeartBeatWarning(int nTimeLapse){}; + + ///¼Ӧ + virtual void OnRspUserLogin(CThostFtdcRspUserLoginField *pRspUserLogin, + CThostFtdcRspInfoField *pRspInfo, int nRequestID, + bool bIsLast){}; + + ///dzӦ + virtual void OnRspUserLogout(CThostFtdcUserLogoutField *pUserLogout, + CThostFtdcRspInfoField *pRspInfo, int nRequestID, + bool bIsLast){}; + + ///Ӧ + virtual void OnRspError(CThostFtdcRspInfoField *pRspInfo, int nRequestID, + bool bIsLast){}; + + ///Ӧ + virtual void + OnRspSubMarketData(CThostFtdcSpecificInstrumentField *pSpecificInstrument, + CThostFtdcRspInfoField *pRspInfo, int nRequestID, + bool bIsLast){}; + + ///ȡӦ + virtual void + OnRspUnSubMarketData(CThostFtdcSpecificInstrumentField *pSpecificInstrument, + CThostFtdcRspInfoField *pRspInfo, int nRequestID, + bool bIsLast){}; + + ///ѯӦ + virtual void + OnRspSubForQuoteRsp(CThostFtdcSpecificInstrumentField *pSpecificInstrument, + CThostFtdcRspInfoField *pRspInfo, int nRequestID, + bool bIsLast){}; + + ///ȡѯӦ + virtual void + OnRspUnSubForQuoteRsp(CThostFtdcSpecificInstrumentField *pSpecificInstrument, + CThostFtdcRspInfoField *pRspInfo, int nRequestID, + bool bIsLast){}; + + ///֪ͨ + virtual void + OnRtnDepthMarketData(CThostFtdcDepthMarketDataField *pDepthMarketData){}; + + ///ѯ֪ͨ + virtual void OnRtnForQuoteRsp(CThostFtdcForQuoteRspField *pForQuoteRsp){}; +}; + +class MD_API_EXPORT CThostFtdcMdApi { +public: + ///MdApi + ///@param pszFlowPath ϢļĿ¼ĬΪǰĿ¼ + ///@return UserApi + /// modify for udp marketdata + static CThostFtdcMdApi *CreateFtdcMdApi(const char *pszFlowPath = "", + const bool bIsUsingUdp = false, + const bool bIsMulticast = false); + + ///ȡAPIİ汾Ϣ + ///@retrun ȡİ汾 + static const char *GetApiVersion(); + + ///ɾӿڶ + ///@remark ʹñӿڶʱ,øúɾӿڶ + virtual void Release() = 0; + + ///ʼ + ///@remark ʼл,ֻеú,ӿڲſʼ + virtual void Init() = 0; + + ///ȴӿ߳̽ + ///@return ߳˳ + virtual int Join() = 0; + + ///ȡǰ + ///@retrun ȡĽ + ///@remark ֻе¼ɹ,ܵõȷĽ + virtual const char *GetTradingDay() = 0; + + ///עǰûַ + ///@param pszFrontAddressǰûַ + ///@remark + ///ַĸʽΪprotocol://ipaddress:port磺tcp://127.0.0.1:17001 + ///@remark + ///tcpЭ飬127.0.0.1ַ17001˿ںš + virtual void RegisterFront(char *pszFrontAddress) = 0; + + ///עַַ + ///@param pszNsAddressַַ + ///@remark + ///ַĸʽΪprotocol://ipaddress:port磺tcp://127.0.0.1:12001 + ///@remark + ///tcpЭ飬127.0.0.1ַ12001˿ںš + ///@remark RegisterNameServerRegisterFront + virtual void RegisterNameServer(char *pszNsAddress) = 0; + + ///עַûϢ + ///@param pFensUserInfoûϢ + virtual void + RegisterFensUserInfo(CThostFtdcFensUserInfoField *pFensUserInfo) = 0; + + ///עصӿ + ///@param pSpi Իصӿʵ + virtual void RegisterSpi(CThostFtdcMdSpi *pSpi) = 0; + + ///顣 + ///@param ppInstrumentID ԼID + ///@param nCount Ҫ/˶ĺԼ + ///@remark + virtual int SubscribeMarketData(char *ppInstrumentID[], int nCount) = 0; + + ///˶顣 + ///@param ppInstrumentID ԼID + ///@param nCount Ҫ/˶ĺԼ + ///@remark + virtual int UnSubscribeMarketData(char *ppInstrumentID[], int nCount) = 0; + + ///ѯۡ + ///@param ppInstrumentID ԼID + ///@param nCount Ҫ/˶ĺԼ + ///@remark + virtual int SubscribeForQuoteRsp(char *ppInstrumentID[], int nCount) = 0; + + ///˶ѯۡ + ///@param ppInstrumentID ԼID + ///@param nCount Ҫ/˶ĺԼ + ///@remark + virtual int UnSubscribeForQuoteRsp(char *ppInstrumentID[], int nCount) = 0; + + ///û¼ + virtual int ReqUserLogin(CThostFtdcReqUserLoginField *pReqUserLoginField, + int nRequestID) = 0; + + ///dz + virtual int ReqUserLogout(CThostFtdcUserLogoutField *pUserLogout, + int nRequestID) = 0; + +protected: + ~CThostFtdcMdApi(){}; +}; + +#endif diff --git a/qbot/engine/trade/engine_apis/futures/CTPtest/src/CTP_API/ThostFtdcTraderApi.h b/qbot/engine/trade/engine_apis/futures/CTPtest/src/CTP_API/ThostFtdcTraderApi.h new file mode 100644 index 00000000..f4baa44d --- /dev/null +++ b/qbot/engine/trade/engine_apis/futures/CTPtest/src/CTP_API/ThostFtdcTraderApi.h @@ -0,0 +1,980 @@ +///////////////////////////////////////////////////////////////////////// +///@system һϵͳ +///@company ϺڻϢ޹˾ +///@file ThostFtdcTraderApi.h +///@brief ˿ͻ˽ӿ +///@history +/// 20060106 Ժ ļ +///////////////////////////////////////////////////////////////////////// + +#if !defined(THOST_FTDCTRADERAPI_H) +#define THOST_FTDCTRADERAPI_H + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 + +#include "ThostFtdcUserApiStruct.h" + +#if defined(ISLIB) && defined(WIN32) +#ifdef LIB_TRADER_API_EXPORT +#define TRADER_API_EXPORT __declspec(dllexport) +#else +#define TRADER_API_EXPORT __declspec(dllimport) +#endif +#else +#define TRADER_API_EXPORT +#endif + +class CThostFtdcTraderSpi { +public: + ///ͻ뽻׺̨ͨʱδ¼ǰ÷á + virtual void OnFrontConnected(){}; + + ///ͻ뽻׺̨ͨӶϿʱ÷áAPIԶӣͻ˿ɲ + ///@param nReason ԭ + /// 0x1001 ʧ + /// 0x1002 дʧ + /// 0x2001 ʱ + /// 0x2002 ʧ + /// 0x2003 յ + virtual void OnFrontDisconnected(int nReason){}; + + ///ʱ档ʱδյʱ÷á + ///@param nTimeLapse ϴνձĵʱ + virtual void OnHeartBeatWarning(int nTimeLapse){}; + + ///ͻ֤Ӧ + virtual void + OnRspAuthenticate(CThostFtdcRspAuthenticateField *pRspAuthenticateField, + CThostFtdcRspInfoField *pRspInfo, int nRequestID, + bool bIsLast){}; + + ///¼Ӧ + virtual void OnRspUserLogin(CThostFtdcRspUserLoginField *pRspUserLogin, + CThostFtdcRspInfoField *pRspInfo, int nRequestID, + bool bIsLast){}; + + ///dzӦ + virtual void OnRspUserLogout(CThostFtdcUserLogoutField *pUserLogout, + CThostFtdcRspInfoField *pRspInfo, int nRequestID, + bool bIsLast){}; + + ///ûӦ + virtual void OnRspUserPasswordUpdate( + CThostFtdcUserPasswordUpdateField *pUserPasswordUpdate, + CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast){}; + + ///ʽ˻Ӧ + virtual void + OnRspTradingAccountPasswordUpdate(CThostFtdcTradingAccountPasswordUpdateField + *pTradingAccountPasswordUpdate, + CThostFtdcRspInfoField *pRspInfo, + int nRequestID, bool bIsLast){}; + + ///¼Ӧ + virtual void OnRspOrderInsert(CThostFtdcInputOrderField *pInputOrder, + CThostFtdcRspInfoField *pRspInfo, + int nRequestID, bool bIsLast){}; + + ///Ԥ¼Ӧ + virtual void OnRspParkedOrderInsert(CThostFtdcParkedOrderField *pParkedOrder, + CThostFtdcRspInfoField *pRspInfo, + int nRequestID, bool bIsLast){}; + + ///Ԥ񳷵¼Ӧ + virtual void + OnRspParkedOrderAction(CThostFtdcParkedOrderActionField *pParkedOrderAction, + CThostFtdcRspInfoField *pRspInfo, int nRequestID, + bool bIsLast){}; + + ///Ӧ + virtual void + OnRspOrderAction(CThostFtdcInputOrderActionField *pInputOrderAction, + CThostFtdcRspInfoField *pRspInfo, int nRequestID, + bool bIsLast){}; + + ///ѯ󱨵Ӧ + virtual void OnRspQueryMaxOrderVolume( + CThostFtdcQueryMaxOrderVolumeField *pQueryMaxOrderVolume, + CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast){}; + + ///Ͷ߽ȷӦ + virtual void OnRspSettlementInfoConfirm( + CThostFtdcSettlementInfoConfirmField *pSettlementInfoConfirm, + CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast){}; + + ///ɾԤӦ + virtual void + OnRspRemoveParkedOrder(CThostFtdcRemoveParkedOrderField *pRemoveParkedOrder, + CThostFtdcRspInfoField *pRspInfo, int nRequestID, + bool bIsLast){}; + + ///ɾԤ񳷵Ӧ + virtual void OnRspRemoveParkedOrderAction( + CThostFtdcRemoveParkedOrderActionField *pRemoveParkedOrderAction, + CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast){}; + + ///ִ¼Ӧ + virtual void + OnRspExecOrderInsert(CThostFtdcInputExecOrderField *pInputExecOrder, + CThostFtdcRspInfoField *pRspInfo, int nRequestID, + bool bIsLast){}; + + ///ִӦ + virtual void OnRspExecOrderAction( + CThostFtdcInputExecOrderActionField *pInputExecOrderAction, + CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast){}; + + ///ѯ¼Ӧ + virtual void OnRspForQuoteInsert(CThostFtdcInputForQuoteField *pInputForQuote, + CThostFtdcRspInfoField *pRspInfo, + int nRequestID, bool bIsLast){}; + + ///¼Ӧ + virtual void OnRspQuoteInsert(CThostFtdcInputQuoteField *pInputQuote, + CThostFtdcRspInfoField *pRspInfo, + int nRequestID, bool bIsLast){}; + + ///۲Ӧ + virtual void + OnRspQuoteAction(CThostFtdcInputQuoteActionField *pInputQuoteAction, + CThostFtdcRspInfoField *pRspInfo, int nRequestID, + bool bIsLast){}; + + ///Ӧ + virtual void OnRspBatchOrderAction( + CThostFtdcInputBatchOrderActionField *pInputBatchOrderAction, + CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast){}; + + ///¼Ӧ + virtual void + OnRspCombActionInsert(CThostFtdcInputCombActionField *pInputCombAction, + CThostFtdcRspInfoField *pRspInfo, int nRequestID, + bool bIsLast){}; + + ///ѯӦ + virtual void OnRspQryOrder(CThostFtdcOrderField *pOrder, + CThostFtdcRspInfoField *pRspInfo, int nRequestID, + bool bIsLast){}; + + ///ѯɽӦ + virtual void OnRspQryTrade(CThostFtdcTradeField *pTrade, + CThostFtdcRspInfoField *pRspInfo, int nRequestID, + bool bIsLast){}; + + ///ѯͶֲ߳Ӧ + virtual void + OnRspQryInvestorPosition(CThostFtdcInvestorPositionField *pInvestorPosition, + CThostFtdcRspInfoField *pRspInfo, int nRequestID, + bool bIsLast){}; + + ///ѯʽ˻Ӧ + virtual void + OnRspQryTradingAccount(CThostFtdcTradingAccountField *pTradingAccount, + CThostFtdcRspInfoField *pRspInfo, int nRequestID, + bool bIsLast){}; + + ///ѯͶӦ + virtual void OnRspQryInvestor(CThostFtdcInvestorField *pInvestor, + CThostFtdcRspInfoField *pRspInfo, + int nRequestID, bool bIsLast){}; + + ///ѯױӦ + virtual void OnRspQryTradingCode(CThostFtdcTradingCodeField *pTradingCode, + CThostFtdcRspInfoField *pRspInfo, + int nRequestID, bool bIsLast){}; + + ///ѯԼ֤Ӧ + virtual void OnRspQryInstrumentMarginRate( + CThostFtdcInstrumentMarginRateField *pInstrumentMarginRate, + CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast){}; + + ///ѯԼӦ + virtual void OnRspQryInstrumentCommissionRate( + CThostFtdcInstrumentCommissionRateField *pInstrumentCommissionRate, + CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast){}; + + ///ѯӦ + virtual void OnRspQryExchange(CThostFtdcExchangeField *pExchange, + CThostFtdcRspInfoField *pRspInfo, + int nRequestID, bool bIsLast){}; + + ///ѯƷӦ + virtual void OnRspQryProduct(CThostFtdcProductField *pProduct, + CThostFtdcRspInfoField *pRspInfo, int nRequestID, + bool bIsLast){}; + + ///ѯԼӦ + virtual void OnRspQryInstrument(CThostFtdcInstrumentField *pInstrument, + CThostFtdcRspInfoField *pRspInfo, + int nRequestID, bool bIsLast){}; + + ///ѯӦ + virtual void + OnRspQryDepthMarketData(CThostFtdcDepthMarketDataField *pDepthMarketData, + CThostFtdcRspInfoField *pRspInfo, int nRequestID, + bool bIsLast){}; + + ///ѯͶ߽Ӧ + virtual void + OnRspQrySettlementInfo(CThostFtdcSettlementInfoField *pSettlementInfo, + CThostFtdcRspInfoField *pRspInfo, int nRequestID, + bool bIsLast){}; + + ///ѯתӦ + virtual void OnRspQryTransferBank(CThostFtdcTransferBankField *pTransferBank, + CThostFtdcRspInfoField *pRspInfo, + int nRequestID, bool bIsLast){}; + + ///ѯͶֲ߳ϸӦ + virtual void OnRspQryInvestorPositionDetail( + CThostFtdcInvestorPositionDetailField *pInvestorPositionDetail, + CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast){}; + + ///ѯͻ֪ͨӦ + virtual void OnRspQryNotice(CThostFtdcNoticeField *pNotice, + CThostFtdcRspInfoField *pRspInfo, int nRequestID, + bool bIsLast){}; + + ///ѯϢȷӦ + virtual void OnRspQrySettlementInfoConfirm( + CThostFtdcSettlementInfoConfirmField *pSettlementInfoConfirm, + CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast){}; + + ///ѯͶֲ߳ϸӦ + virtual void OnRspQryInvestorPositionCombineDetail( + CThostFtdcInvestorPositionCombineDetailField + *pInvestorPositionCombineDetail, + CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast){}; + + ///ѯ֤ϵͳ͹˾ʽ˻ԿӦ + virtual void OnRspQryCFMMCTradingAccountKey( + CThostFtdcCFMMCTradingAccountKeyField *pCFMMCTradingAccountKey, + CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast){}; + + ///ѯֵ۵ϢӦ + virtual void + OnRspQryEWarrantOffset(CThostFtdcEWarrantOffsetField *pEWarrantOffset, + CThostFtdcRspInfoField *pRspInfo, int nRequestID, + bool bIsLast){}; + + ///ѯͶƷ/Ʒֱ֤Ӧ + virtual void OnRspQryInvestorProductGroupMargin( + CThostFtdcInvestorProductGroupMarginField *pInvestorProductGroupMargin, + CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast){}; + + ///ѯ֤Ӧ + virtual void OnRspQryExchangeMarginRate( + CThostFtdcExchangeMarginRateField *pExchangeMarginRate, + CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast){}; + + ///ѯ֤Ӧ + virtual void OnRspQryExchangeMarginRateAdjust( + CThostFtdcExchangeMarginRateAdjustField *pExchangeMarginRateAdjust, + CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast){}; + + ///ѯӦ + virtual void OnRspQryExchangeRate(CThostFtdcExchangeRateField *pExchangeRate, + CThostFtdcRspInfoField *pRspInfo, + int nRequestID, bool bIsLast){}; + + ///ѯԱȨӦ + virtual void + OnRspQrySecAgentACIDMap(CThostFtdcSecAgentACIDMapField *pSecAgentACIDMap, + CThostFtdcRspInfoField *pRspInfo, int nRequestID, + bool bIsLast){}; + + ///ѯƷۻ + virtual void + OnRspQryProductExchRate(CThostFtdcProductExchRateField *pProductExchRate, + CThostFtdcRspInfoField *pRspInfo, int nRequestID, + bool bIsLast){}; + + ///ѯƷ + virtual void OnRspQryProductGroup(CThostFtdcProductGroupField *pProductGroup, + CThostFtdcRspInfoField *pRspInfo, + int nRequestID, bool bIsLast){}; + + ///ѯ̺ԼӦ + virtual void OnRspQryMMInstrumentCommissionRate( + CThostFtdcMMInstrumentCommissionRateField *pMMInstrumentCommissionRate, + CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast){}; + + ///ѯȨԼӦ + virtual void OnRspQryMMOptionInstrCommRate( + CThostFtdcMMOptionInstrCommRateField *pMMOptionInstrCommRate, + CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast){}; + + ///ѯӦ + virtual void OnRspQryInstrumentOrderCommRate( + CThostFtdcInstrumentOrderCommRateField *pInstrumentOrderCommRate, + CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast){}; + + ///ѯȨ׳ɱӦ + virtual void OnRspQryOptionInstrTradeCost( + CThostFtdcOptionInstrTradeCostField *pOptionInstrTradeCost, + CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast){}; + + ///ѯȨԼӦ + virtual void OnRspQryOptionInstrCommRate( + CThostFtdcOptionInstrCommRateField *pOptionInstrCommRate, + CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast){}; + + ///ѯִӦ + virtual void OnRspQryExecOrder(CThostFtdcExecOrderField *pExecOrder, + CThostFtdcRspInfoField *pRspInfo, + int nRequestID, bool bIsLast){}; + + ///ѯѯӦ + virtual void OnRspQryForQuote(CThostFtdcForQuoteField *pForQuote, + CThostFtdcRspInfoField *pRspInfo, + int nRequestID, bool bIsLast){}; + + ///ѯӦ + virtual void OnRspQryQuote(CThostFtdcQuoteField *pQuote, + CThostFtdcRspInfoField *pRspInfo, int nRequestID, + bool bIsLast){}; + + ///ѯϺԼȫϵӦ + virtual void OnRspQryCombInstrumentGuard( + CThostFtdcCombInstrumentGuardField *pCombInstrumentGuard, + CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast){}; + + ///ѯӦ + virtual void OnRspQryCombAction(CThostFtdcCombActionField *pCombAction, + CThostFtdcRspInfoField *pRspInfo, + int nRequestID, bool bIsLast){}; + + ///ѯתˮӦ + virtual void + OnRspQryTransferSerial(CThostFtdcTransferSerialField *pTransferSerial, + CThostFtdcRspInfoField *pRspInfo, int nRequestID, + bool bIsLast){}; + + ///ѯǩԼϵӦ + virtual void + OnRspQryAccountregister(CThostFtdcAccountregisterField *pAccountregister, + CThostFtdcRspInfoField *pRspInfo, int nRequestID, + bool bIsLast){}; + + ///Ӧ + virtual void OnRspError(CThostFtdcRspInfoField *pRspInfo, int nRequestID, + bool bIsLast){}; + + ///֪ͨ + virtual void OnRtnOrder(CThostFtdcOrderField *pOrder){}; + + ///ɽ֪ͨ + virtual void OnRtnTrade(CThostFtdcTradeField *pTrade){}; + + ///¼ر + virtual void OnErrRtnOrderInsert(CThostFtdcInputOrderField *pInputOrder, + CThostFtdcRspInfoField *pRspInfo){}; + + ///ر + virtual void OnErrRtnOrderAction(CThostFtdcOrderActionField *pOrderAction, + CThostFtdcRspInfoField *pRspInfo){}; + + ///Լ״̬֪ͨ + virtual void + OnRtnInstrumentStatus(CThostFtdcInstrumentStatusField *pInstrumentStatus){}; + + ///֪ͨ + virtual void OnRtnBulletin(CThostFtdcBulletinField *pBulletin){}; + + ///֪ͨ + virtual void + OnRtnTradingNotice(CThostFtdcTradingNoticeInfoField *pTradingNoticeInfo){}; + + ///ʾУ + virtual void OnRtnErrorConditionalOrder( + CThostFtdcErrorConditionalOrderField *pErrorConditionalOrder){}; + + ///ִ֪ͨ + virtual void OnRtnExecOrder(CThostFtdcExecOrderField *pExecOrder){}; + + ///ִ¼ر + virtual void + OnErrRtnExecOrderInsert(CThostFtdcInputExecOrderField *pInputExecOrder, + CThostFtdcRspInfoField *pRspInfo){}; + + ///ִر + virtual void + OnErrRtnExecOrderAction(CThostFtdcExecOrderActionField *pExecOrderAction, + CThostFtdcRspInfoField *pRspInfo){}; + + ///ѯ¼ر + virtual void + OnErrRtnForQuoteInsert(CThostFtdcInputForQuoteField *pInputForQuote, + CThostFtdcRspInfoField *pRspInfo){}; + + ///֪ͨ + virtual void OnRtnQuote(CThostFtdcQuoteField *pQuote){}; + + ///¼ر + virtual void OnErrRtnQuoteInsert(CThostFtdcInputQuoteField *pInputQuote, + CThostFtdcRspInfoField *pRspInfo){}; + + ///۲ر + virtual void OnErrRtnQuoteAction(CThostFtdcQuoteActionField *pQuoteAction, + CThostFtdcRspInfoField *pRspInfo){}; + + ///ѯ֪ͨ + virtual void OnRtnForQuoteRsp(CThostFtdcForQuoteRspField *pForQuoteRsp){}; + + ///֤û + virtual void OnRtnCFMMCTradingAccountToken( + CThostFtdcCFMMCTradingAccountTokenField *pCFMMCTradingAccountToken){}; + + ///ر + virtual void + OnErrRtnBatchOrderAction(CThostFtdcBatchOrderActionField *pBatchOrderAction, + CThostFtdcRspInfoField *pRspInfo){}; + + ///֪ͨ + virtual void OnRtnCombAction(CThostFtdcCombActionField *pCombAction){}; + + ///¼ر + virtual void + OnErrRtnCombActionInsert(CThostFtdcInputCombActionField *pInputCombAction, + CThostFtdcRspInfoField *pRspInfo){}; + + ///ѯǩԼӦ + virtual void OnRspQryContractBank(CThostFtdcContractBankField *pContractBank, + CThostFtdcRspInfoField *pRspInfo, + int nRequestID, bool bIsLast){}; + + ///ѯԤӦ + virtual void OnRspQryParkedOrder(CThostFtdcParkedOrderField *pParkedOrder, + CThostFtdcRspInfoField *pRspInfo, + int nRequestID, bool bIsLast){}; + + ///ѯԤ񳷵Ӧ + virtual void OnRspQryParkedOrderAction( + CThostFtdcParkedOrderActionField *pParkedOrderAction, + CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast){}; + + ///ѯ֪ͨӦ + virtual void + OnRspQryTradingNotice(CThostFtdcTradingNoticeField *pTradingNotice, + CThostFtdcRspInfoField *pRspInfo, int nRequestID, + bool bIsLast){}; + + ///ѯ͹˾ײӦ + virtual void OnRspQryBrokerTradingParams( + CThostFtdcBrokerTradingParamsField *pBrokerTradingParams, + CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast){}; + + ///ѯ͹˾㷨Ӧ + virtual void OnRspQryBrokerTradingAlgos( + CThostFtdcBrokerTradingAlgosField *pBrokerTradingAlgos, + CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast){}; + + ///ѯû + virtual void OnRspQueryCFMMCTradingAccountToken( + CThostFtdcQueryCFMMCTradingAccountTokenField + *pQueryCFMMCTradingAccountToken, + CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast){}; + + ///зʽתڻ֪ͨ + virtual void + OnRtnFromBankToFutureByBank(CThostFtdcRspTransferField *pRspTransfer){}; + + ///зڻʽת֪ͨ + virtual void + OnRtnFromFutureToBankByBank(CThostFtdcRspTransferField *pRspTransfer){}; + + ///зתڻ֪ͨ + virtual void + OnRtnRepealFromBankToFutureByBank(CThostFtdcRspRepealField *pRspRepeal){}; + + ///зڻת֪ͨ + virtual void + OnRtnRepealFromFutureToBankByBank(CThostFtdcRspRepealField *pRspRepeal){}; + + ///ڻʽתڻ֪ͨ + virtual void + OnRtnFromBankToFutureByFuture(CThostFtdcRspTransferField *pRspTransfer){}; + + ///ڻڻʽת֪ͨ + virtual void + OnRtnFromFutureToBankByFuture(CThostFtdcRspTransferField *pRspTransfer){}; + + ///ϵͳʱڻֹתڻдϺ̷ص֪ͨ + virtual void OnRtnRepealFromBankToFutureByFutureManual( + CThostFtdcRspRepealField *pRspRepeal){}; + + ///ϵͳʱڻֹڻתдϺ̷ص֪ͨ + virtual void OnRtnRepealFromFutureToBankByFutureManual( + CThostFtdcRspRepealField *pRspRepeal){}; + + ///ڻѯ֪ͨ + virtual void OnRtnQueryBankBalanceByFuture( + CThostFtdcNotifyQueryAccountField *pNotifyQueryAccount){}; + + ///ڻʽתڻر + virtual void + OnErrRtnBankToFutureByFuture(CThostFtdcReqTransferField *pReqTransfer, + CThostFtdcRspInfoField *pRspInfo){}; + + ///ڻڻʽתдر + virtual void + OnErrRtnFutureToBankByFuture(CThostFtdcReqTransferField *pReqTransfer, + CThostFtdcRspInfoField *pRspInfo){}; + + ///ϵͳʱڻֹתڻر + virtual void + OnErrRtnRepealBankToFutureByFutureManual(CThostFtdcReqRepealField *pReqRepeal, + CThostFtdcRspInfoField *pRspInfo){}; + + ///ϵͳʱڻֹڻתдر + virtual void + OnErrRtnRepealFutureToBankByFutureManual(CThostFtdcReqRepealField *pReqRepeal, + CThostFtdcRspInfoField *pRspInfo){}; + + ///ڻѯر + virtual void OnErrRtnQueryBankBalanceByFuture( + CThostFtdcReqQueryAccountField *pReqQueryAccount, + CThostFtdcRspInfoField *pRspInfo){}; + + ///ڻתڻдϺ̷ص֪ͨ + virtual void + OnRtnRepealFromBankToFutureByFuture(CThostFtdcRspRepealField *pRspRepeal){}; + + ///ڻڻתдϺ̷ص֪ͨ + virtual void + OnRtnRepealFromFutureToBankByFuture(CThostFtdcRspRepealField *pRspRepeal){}; + + ///ڻʽתڻӦ + virtual void + OnRspFromBankToFutureByFuture(CThostFtdcReqTransferField *pReqTransfer, + CThostFtdcRspInfoField *pRspInfo, + int nRequestID, bool bIsLast){}; + + ///ڻڻʽתӦ + virtual void + OnRspFromFutureToBankByFuture(CThostFtdcReqTransferField *pReqTransfer, + CThostFtdcRspInfoField *pRspInfo, + int nRequestID, bool bIsLast){}; + + ///ڻѯӦ + virtual void OnRspQueryBankAccountMoneyByFuture( + CThostFtdcReqQueryAccountField *pReqQueryAccount, + CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast){}; + + ///зڿ֪ͨ + virtual void + OnRtnOpenAccountByBank(CThostFtdcOpenAccountField *pOpenAccount){}; + + ///з֪ͨ + virtual void + OnRtnCancelAccountByBank(CThostFtdcCancelAccountField *pCancelAccount){}; + + ///з˺֪ͨ + virtual void + OnRtnChangeAccountByBank(CThostFtdcChangeAccountField *pChangeAccount){}; +}; + +class TRADER_API_EXPORT CThostFtdcTraderApi { +public: + ///TraderApi + ///@param pszFlowPath ϢļĿ¼ĬΪǰĿ¼ + ///@return UserApi + static CThostFtdcTraderApi *CreateFtdcTraderApi(const char *pszFlowPath = ""); + + ///ȡAPIİ汾Ϣ + ///@retrun ȡİ汾 + static const char *GetApiVersion(); + + ///ɾӿڶ + ///@remark ʹñӿڶʱ,øúɾӿڶ + virtual void Release() = 0; + + ///ʼ + ///@remark ʼл,ֻеú,ӿڲſʼ + virtual void Init() = 0; + + ///ȴӿ߳̽ + ///@return ߳˳ + virtual int Join() = 0; + + ///ȡǰ + ///@retrun ȡĽ + ///@remark ֻе¼ɹ,ܵõȷĽ + virtual const char *GetTradingDay() = 0; + + ///עǰûַ + ///@param pszFrontAddressǰûַ + ///@remark + ///ַĸʽΪprotocol://ipaddress:port磺tcp://127.0.0.1:17001 + ///@remark + ///tcpЭ飬127.0.0.1ַ17001˿ںš + virtual void RegisterFront(char *pszFrontAddress) = 0; + + ///עַַ + ///@param pszNsAddressַַ + ///@remark + ///ַĸʽΪprotocol://ipaddress:port磺tcp://127.0.0.1:12001 + ///@remark + ///tcpЭ飬127.0.0.1ַ12001˿ںš + ///@remark RegisterNameServerRegisterFront + virtual void RegisterNameServer(char *pszNsAddress) = 0; + + ///עַûϢ + ///@param pFensUserInfoûϢ + virtual void + RegisterFensUserInfo(CThostFtdcFensUserInfoField *pFensUserInfo) = 0; + + ///עصӿ + ///@param pSpi Իصӿʵ + virtual void RegisterSpi(CThostFtdcTraderSpi *pSpi) = 0; + + ///˽ + ///@param nResumeType ˽شʽ + /// THOST_TERT_RESTART:ӱտʼش + /// THOST_TERT_RESUME:ϴյ + /// THOST_TERT_QUICK:ֻ͵¼˽ + ///@remark ÷ҪInitǰá򲻻յ˽ݡ + virtual void SubscribePrivateTopic(THOST_TE_RESUME_TYPE nResumeType) = 0; + + ///Ĺ + ///@param nResumeType شʽ + /// THOST_TERT_RESTART:ӱտʼش + /// THOST_TERT_RESUME:ϴյ + /// THOST_TERT_QUICK:ֻ͵¼󹫹 + ///@remark ÷ҪInitǰá򲻻յݡ + virtual void SubscribePublicTopic(THOST_TE_RESUME_TYPE nResumeType) = 0; + + ///ͻ֤ + virtual int + ReqAuthenticate(CThostFtdcReqAuthenticateField *pReqAuthenticateField, + int nRequestID) = 0; + + ///û¼ + virtual int ReqUserLogin(CThostFtdcReqUserLoginField *pReqUserLoginField, + int nRequestID) = 0; + + ///dz + virtual int ReqUserLogout(CThostFtdcUserLogoutField *pUserLogout, + int nRequestID) = 0; + + ///û + virtual int + ReqUserPasswordUpdate(CThostFtdcUserPasswordUpdateField *pUserPasswordUpdate, + int nRequestID) = 0; + + ///ʽ˻ + virtual int + ReqTradingAccountPasswordUpdate(CThostFtdcTradingAccountPasswordUpdateField + *pTradingAccountPasswordUpdate, + int nRequestID) = 0; + + ///¼ + virtual int ReqOrderInsert(CThostFtdcInputOrderField *pInputOrder, + int nRequestID) = 0; + + ///Ԥ¼ + virtual int ReqParkedOrderInsert(CThostFtdcParkedOrderField *pParkedOrder, + int nRequestID) = 0; + + ///Ԥ񳷵¼ + virtual int + ReqParkedOrderAction(CThostFtdcParkedOrderActionField *pParkedOrderAction, + int nRequestID) = 0; + + /// + virtual int ReqOrderAction(CThostFtdcInputOrderActionField *pInputOrderAction, + int nRequestID) = 0; + + ///ѯ󱨵 + virtual int ReqQueryMaxOrderVolume( + CThostFtdcQueryMaxOrderVolumeField *pQueryMaxOrderVolume, + int nRequestID) = 0; + + ///Ͷ߽ȷ + virtual int ReqSettlementInfoConfirm( + CThostFtdcSettlementInfoConfirmField *pSettlementInfoConfirm, + int nRequestID) = 0; + + ///ɾԤ + virtual int + ReqRemoveParkedOrder(CThostFtdcRemoveParkedOrderField *pRemoveParkedOrder, + int nRequestID) = 0; + + ///ɾԤ񳷵 + virtual int ReqRemoveParkedOrderAction( + CThostFtdcRemoveParkedOrderActionField *pRemoveParkedOrderAction, + int nRequestID) = 0; + + ///ִ¼ + virtual int ReqExecOrderInsert(CThostFtdcInputExecOrderField *pInputExecOrder, + int nRequestID) = 0; + + ///ִ + virtual int + ReqExecOrderAction(CThostFtdcInputExecOrderActionField *pInputExecOrderAction, + int nRequestID) = 0; + + ///ѯ¼ + virtual int ReqForQuoteInsert(CThostFtdcInputForQuoteField *pInputForQuote, + int nRequestID) = 0; + + ///¼ + virtual int ReqQuoteInsert(CThostFtdcInputQuoteField *pInputQuote, + int nRequestID) = 0; + + ///۲ + virtual int ReqQuoteAction(CThostFtdcInputQuoteActionField *pInputQuoteAction, + int nRequestID) = 0; + + /// + virtual int ReqBatchOrderAction( + CThostFtdcInputBatchOrderActionField *pInputBatchOrderAction, + int nRequestID) = 0; + + ///¼ + virtual int + ReqCombActionInsert(CThostFtdcInputCombActionField *pInputCombAction, + int nRequestID) = 0; + + ///ѯ + virtual int ReqQryOrder(CThostFtdcQryOrderField *pQryOrder, + int nRequestID) = 0; + + ///ѯɽ + virtual int ReqQryTrade(CThostFtdcQryTradeField *pQryTrade, + int nRequestID) = 0; + + ///ѯͶֲ߳ + virtual int ReqQryInvestorPosition( + CThostFtdcQryInvestorPositionField *pQryInvestorPosition, + int nRequestID) = 0; + + ///ѯʽ˻ + virtual int + ReqQryTradingAccount(CThostFtdcQryTradingAccountField *pQryTradingAccount, + int nRequestID) = 0; + + ///ѯͶ + virtual int ReqQryInvestor(CThostFtdcQryInvestorField *pQryInvestor, + int nRequestID) = 0; + + ///ѯױ + virtual int ReqQryTradingCode(CThostFtdcQryTradingCodeField *pQryTradingCode, + int nRequestID) = 0; + + ///ѯԼ֤ + virtual int ReqQryInstrumentMarginRate( + CThostFtdcQryInstrumentMarginRateField *pQryInstrumentMarginRate, + int nRequestID) = 0; + + ///ѯԼ + virtual int ReqQryInstrumentCommissionRate( + CThostFtdcQryInstrumentCommissionRateField *pQryInstrumentCommissionRate, + int nRequestID) = 0; + + ///ѯ + virtual int ReqQryExchange(CThostFtdcQryExchangeField *pQryExchange, + int nRequestID) = 0; + + ///ѯƷ + virtual int ReqQryProduct(CThostFtdcQryProductField *pQryProduct, + int nRequestID) = 0; + + ///ѯԼ + virtual int ReqQryInstrument(CThostFtdcQryInstrumentField *pQryInstrument, + int nRequestID) = 0; + + ///ѯ + virtual int + ReqQryDepthMarketData(CThostFtdcQryDepthMarketDataField *pQryDepthMarketData, + int nRequestID) = 0; + + ///ѯͶ߽ + virtual int + ReqQrySettlementInfo(CThostFtdcQrySettlementInfoField *pQrySettlementInfo, + int nRequestID) = 0; + + ///ѯת + virtual int + ReqQryTransferBank(CThostFtdcQryTransferBankField *pQryTransferBank, + int nRequestID) = 0; + + ///ѯͶֲ߳ϸ + virtual int ReqQryInvestorPositionDetail( + CThostFtdcQryInvestorPositionDetailField *pQryInvestorPositionDetail, + int nRequestID) = 0; + + ///ѯͻ֪ͨ + virtual int ReqQryNotice(CThostFtdcQryNoticeField *pQryNotice, + int nRequestID) = 0; + + ///ѯϢȷ + virtual int ReqQrySettlementInfoConfirm( + CThostFtdcQrySettlementInfoConfirmField *pQrySettlementInfoConfirm, + int nRequestID) = 0; + + ///ѯͶֲ߳ϸ + virtual int ReqQryInvestorPositionCombineDetail( + CThostFtdcQryInvestorPositionCombineDetailField + *pQryInvestorPositionCombineDetail, + int nRequestID) = 0; + + ///ѯ֤ϵͳ͹˾ʽ˻Կ + virtual int ReqQryCFMMCTradingAccountKey( + CThostFtdcQryCFMMCTradingAccountKeyField *pQryCFMMCTradingAccountKey, + int nRequestID) = 0; + + ///ѯֵ۵Ϣ + virtual int + ReqQryEWarrantOffset(CThostFtdcQryEWarrantOffsetField *pQryEWarrantOffset, + int nRequestID) = 0; + + ///ѯͶƷ/Ʒֱ֤ + virtual int + ReqQryInvestorProductGroupMargin(CThostFtdcQryInvestorProductGroupMarginField + *pQryInvestorProductGroupMargin, + int nRequestID) = 0; + + ///ѯ֤ + virtual int ReqQryExchangeMarginRate( + CThostFtdcQryExchangeMarginRateField *pQryExchangeMarginRate, + int nRequestID) = 0; + + ///ѯ֤ + virtual int ReqQryExchangeMarginRateAdjust( + CThostFtdcQryExchangeMarginRateAdjustField *pQryExchangeMarginRateAdjust, + int nRequestID) = 0; + + ///ѯ + virtual int + ReqQryExchangeRate(CThostFtdcQryExchangeRateField *pQryExchangeRate, + int nRequestID) = 0; + + ///ѯԱȨ + virtual int + ReqQrySecAgentACIDMap(CThostFtdcQrySecAgentACIDMapField *pQrySecAgentACIDMap, + int nRequestID) = 0; + + ///ѯƷۻ + virtual int + ReqQryProductExchRate(CThostFtdcQryProductExchRateField *pQryProductExchRate, + int nRequestID) = 0; + + ///ѯƷ + virtual int + ReqQryProductGroup(CThostFtdcQryProductGroupField *pQryProductGroup, + int nRequestID) = 0; + + ///ѯ̺Լ + virtual int + ReqQryMMInstrumentCommissionRate(CThostFtdcQryMMInstrumentCommissionRateField + *pQryMMInstrumentCommissionRate, + int nRequestID) = 0; + + ///ѯȨԼ + virtual int ReqQryMMOptionInstrCommRate( + CThostFtdcQryMMOptionInstrCommRateField *pQryMMOptionInstrCommRate, + int nRequestID) = 0; + + ///ѯ + virtual int ReqQryInstrumentOrderCommRate( + CThostFtdcQryInstrumentOrderCommRateField *pQryInstrumentOrderCommRate, + int nRequestID) = 0; + + ///ѯȨ׳ɱ + virtual int ReqQryOptionInstrTradeCost( + CThostFtdcQryOptionInstrTradeCostField *pQryOptionInstrTradeCost, + int nRequestID) = 0; + + ///ѯȨԼ + virtual int ReqQryOptionInstrCommRate( + CThostFtdcQryOptionInstrCommRateField *pQryOptionInstrCommRate, + int nRequestID) = 0; + + ///ѯִ + virtual int ReqQryExecOrder(CThostFtdcQryExecOrderField *pQryExecOrder, + int nRequestID) = 0; + + ///ѯѯ + virtual int ReqQryForQuote(CThostFtdcQryForQuoteField *pQryForQuote, + int nRequestID) = 0; + + ///ѯ + virtual int ReqQryQuote(CThostFtdcQryQuoteField *pQryQuote, + int nRequestID) = 0; + + ///ѯϺԼȫϵ + virtual int ReqQryCombInstrumentGuard( + CThostFtdcQryCombInstrumentGuardField *pQryCombInstrumentGuard, + int nRequestID) = 0; + + ///ѯ + virtual int ReqQryCombAction(CThostFtdcQryCombActionField *pQryCombAction, + int nRequestID) = 0; + + ///ѯתˮ + virtual int + ReqQryTransferSerial(CThostFtdcQryTransferSerialField *pQryTransferSerial, + int nRequestID) = 0; + + ///ѯǩԼϵ + virtual int + ReqQryAccountregister(CThostFtdcQryAccountregisterField *pQryAccountregister, + int nRequestID) = 0; + + ///ѯǩԼ + virtual int + ReqQryContractBank(CThostFtdcQryContractBankField *pQryContractBank, + int nRequestID) = 0; + + ///ѯԤ + virtual int ReqQryParkedOrder(CThostFtdcQryParkedOrderField *pQryParkedOrder, + int nRequestID) = 0; + + ///ѯԤ񳷵 + virtual int ReqQryParkedOrderAction( + CThostFtdcQryParkedOrderActionField *pQryParkedOrderAction, + int nRequestID) = 0; + + ///ѯ֪ͨ + virtual int + ReqQryTradingNotice(CThostFtdcQryTradingNoticeField *pQryTradingNotice, + int nRequestID) = 0; + + ///ѯ͹˾ײ + virtual int ReqQryBrokerTradingParams( + CThostFtdcQryBrokerTradingParamsField *pQryBrokerTradingParams, + int nRequestID) = 0; + + ///ѯ͹˾㷨 + virtual int ReqQryBrokerTradingAlgos( + CThostFtdcQryBrokerTradingAlgosField *pQryBrokerTradingAlgos, + int nRequestID) = 0; + + ///ѯû + virtual int + ReqQueryCFMMCTradingAccountToken(CThostFtdcQueryCFMMCTradingAccountTokenField + *pQueryCFMMCTradingAccountToken, + int nRequestID) = 0; + + ///ڻʽתڻ + virtual int + ReqFromBankToFutureByFuture(CThostFtdcReqTransferField *pReqTransfer, + int nRequestID) = 0; + + ///ڻڻʽת + virtual int + ReqFromFutureToBankByFuture(CThostFtdcReqTransferField *pReqTransfer, + int nRequestID) = 0; + + ///ڻѯ + virtual int ReqQueryBankAccountMoneyByFuture( + CThostFtdcReqQueryAccountField *pReqQueryAccount, int nRequestID) = 0; + +protected: + ~CThostFtdcTraderApi(){}; +}; + +#endif diff --git a/qbot/engine/trade/engine_apis/futures/CTPtest/src/CTP_API/ThostFtdcUserApiDataType.h b/qbot/engine/trade/engine_apis/futures/CTPtest/src/CTP_API/ThostFtdcUserApiDataType.h new file mode 100644 index 00000000..cb20b4a0 --- /dev/null +++ b/qbot/engine/trade/engine_apis/futures/CTPtest/src/CTP_API/ThostFtdcUserApiDataType.h @@ -0,0 +1,6377 @@ +///////////////////////////////////////////////////////////////////////// +///@system һϵͳ +///@company ϺڻϢ޹˾ +///@file ThostFtdcUserApiDataType.h +///@brief ˿ͻ˽ӿʹõҵ +///@history +/// 20060106 Ժ ļ +///////////////////////////////////////////////////////////////////////// + +#ifndef THOST_FTDCDATATYPE_H +#define THOST_FTDCDATATYPE_H + +enum THOST_TE_RESUME_TYPE { + THOST_TERT_RESTART = 0, + THOST_TERT_RESUME, + THOST_TERT_QUICK +}; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcTraderIDTypeһԱ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcTraderIDType[21]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcInvestorIDTypeһͶߴ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcInvestorIDType[13]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcBrokerIDTypeһ͹˾ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcBrokerIDType[11]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcBrokerAbbrTypeһ͹˾ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcBrokerAbbrType[9]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcBrokerNameTypeһ͹˾ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcBrokerNameType[81]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcExchangeInstIDTypeһԼڽĴ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcExchangeInstIDType[31]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcOrderRefTypeһ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcOrderRefType[13]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcParticipantIDTypeһԱ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcParticipantIDType[11]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcUserIDTypeһû +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcUserIDType[16]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcPasswordTypeһ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcPasswordType[41]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcClientIDTypeһױ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcClientIDType[11]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcInstrumentIDTypeһԼ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcInstrumentIDType[31]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcMarketIDTypeһг +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcMarketIDType[31]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcProductNameTypeһƷ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcProductNameType[21]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcExchangeIDTypeһ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcExchangeIDType[9]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcExchangeNameTypeһ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcExchangeNameType[61]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcExchangeAbbrTypeһ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcExchangeAbbrType[9]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcExchangeFlagTypeһ־ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcExchangeFlagType[2]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcMacAddressTypeһMacַ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcMacAddressType[21]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcSystemIDTypeһϵͳ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcSystemIDType[21]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcExchangePropertyTypeһ +///////////////////////////////////////////////////////////////////////// +/// +#define THOST_FTDC_EXP_Normal '0' +///ݳɽɱ +#define THOST_FTDC_EXP_GenOrderByTrade '1' + +typedef char TThostFtdcExchangePropertyType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcDateTypeһ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcDateType[9]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcTimeTypeһʱ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcTimeType[9]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcLongTimeTypeһʱ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcLongTimeType[13]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcInstrumentNameTypeһԼ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcInstrumentNameType[21]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcSettlementGroupIDTypeһ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcSettlementGroupIDType[9]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcOrderSysIDTypeһ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcOrderSysIDType[21]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcTradeIDTypeһɽ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcTradeIDType[21]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcCommandTypeTypeһDB +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcCommandTypeType[65]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcIPAddressTypeһIPַ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcIPAddressType[16]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcIPPortTypeһIP˿ +///////////////////////////////////////////////////////////////////////// +typedef int TThostFtdcIPPortType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcProductInfoTypeһƷϢ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcProductInfoType[11]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcProtocolInfoTypeһЭϢ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcProtocolInfoType[11]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcBusinessUnitTypeһҵԪ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcBusinessUnitType[21]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcDepositSeqNoTypeһˮ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcDepositSeqNoType[15]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcIdentifiedCardNoTypeһ֤ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcIdentifiedCardNoType[51]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcIdCardTypeTypeһ֤ +///////////////////////////////////////////////////////////////////////// +///֯ +#define THOST_FTDC_ICT_EID '0' +///й֤ +#define THOST_FTDC_ICT_IDCard '1' +///֤ +#define THOST_FTDC_ICT_OfficerIDCard '2' +///֤ +#define THOST_FTDC_ICT_PoliceIDCard '3' +///ʿ֤ +#define THOST_FTDC_ICT_SoldierIDCard '4' +///ڲ +#define THOST_FTDC_ICT_HouseholdRegister '5' +/// +#define THOST_FTDC_ICT_Passport '6' +///̨֤ +#define THOST_FTDC_ICT_TaiwanCompatriotIDCard '7' +///֤ +#define THOST_FTDC_ICT_HomeComingCard '8' +///Ӫҵִպ +#define THOST_FTDC_ICT_LicenseNo '9' +///˰ǼǺ/˰ID +#define THOST_FTDC_ICT_TaxNo 'A' +///۰ľڵ֤ͨ +#define THOST_FTDC_ICT_HMMainlandTravelPermit 'B' +///̨½֤ͨ +#define THOST_FTDC_ICT_TwMainlandTravelPermit 'C' +/// +#define THOST_FTDC_ICT_DrivingLicense 'D' +///籣ID +#define THOST_FTDC_ICT_SocialID 'F' +///֤ +#define THOST_FTDC_ICT_LocalID 'G' +///ҵǼ֤ +#define THOST_FTDC_ICT_BusinessRegistration 'H' +///۰Ծ֤ +#define THOST_FTDC_ICT_HKMCIDCard 'I' +///п֤ +#define THOST_FTDC_ICT_AccountsPermits 'J' +///֤ +#define THOST_FTDC_ICT_OtherCard 'x' + +typedef char TThostFtdcIdCardTypeType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcOrderLocalIDTypeһر +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcOrderLocalIDType[13]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcUserNameTypeһû +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcUserNameType[81]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcPartyNameTypeһ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcPartyNameType[81]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcErrorMsgTypeһϢ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcErrorMsgType[81]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcFieldNameTypeһֶ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcFieldNameType[2049]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcFieldContentTypeһֶ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcFieldContentType[2049]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcSystemNameTypeһϵͳ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcSystemNameType[41]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcContentTypeһϢ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcContentType[501]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcInvestorRangeTypeһͶ߷Χ +///////////////////////////////////////////////////////////////////////// +/// +#define THOST_FTDC_IR_All '1' +///Ͷ +#define THOST_FTDC_IR_Group '2' +///һͶ +#define THOST_FTDC_IR_Single '3' + +typedef char TThostFtdcInvestorRangeType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcDepartmentRangeTypeһͶ߷Χ +///////////////////////////////////////////////////////////////////////// +/// +#define THOST_FTDC_DR_All '1' +///ܹ֯ +#define THOST_FTDC_DR_Group '2' +///һͶ +#define THOST_FTDC_DR_Single '3' + +typedef char TThostFtdcDepartmentRangeType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcDataSyncStatusTypeһͬ״̬ +///////////////////////////////////////////////////////////////////////// +///δͬ +#define THOST_FTDC_DS_Asynchronous '1' +///ͬ +#define THOST_FTDC_DS_Synchronizing '2' +///ͬ +#define THOST_FTDC_DS_Synchronized '3' + +typedef char TThostFtdcDataSyncStatusType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcBrokerDataSyncStatusTypeһ͹˾ͬ״̬ +///////////////////////////////////////////////////////////////////////// +///ͬ +#define THOST_FTDC_BDS_Synchronized '1' +///ͬ +#define THOST_FTDC_BDS_Synchronizing '2' + +typedef char TThostFtdcBrokerDataSyncStatusType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcExchangeConnectStatusTypeһ״̬ +///////////////////////////////////////////////////////////////////////// +///ûκ +#define THOST_FTDC_ECS_NoConnection '1' +///ѾԼѯ +#define THOST_FTDC_ECS_QryInstrumentSent '2' +///ѾȡϢ +#define THOST_FTDC_ECS_GotInformation '9' + +typedef char TThostFtdcExchangeConnectStatusType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcTraderConnectStatusTypeһԱ״̬ +///////////////////////////////////////////////////////////////////////// +///ûκ +#define THOST_FTDC_TCS_NotConnected '1' +///Ѿ +#define THOST_FTDC_TCS_Connected '2' +///ѾԼѯ +#define THOST_FTDC_TCS_QryInstrumentSent '3' +///˽ +#define THOST_FTDC_TCS_SubPrivateFlow '4' + +typedef char TThostFtdcTraderConnectStatusType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcFunctionCodeTypeһܴ +///////////////////////////////////////////////////////////////////////// +///첽 +#define THOST_FTDC_FC_DataAsync '1' +///ǿûdz +#define THOST_FTDC_FC_ForceUserLogout '2' +///û +#define THOST_FTDC_FC_UserPasswordUpdate '3' +///͹˾ +#define THOST_FTDC_FC_BrokerPasswordUpdate '4' +///Ͷ߿ +#define THOST_FTDC_FC_InvestorPasswordUpdate '5' +/// +#define THOST_FTDC_FC_OrderInsert '6' +/// +#define THOST_FTDC_FC_OrderAction '7' +///ͬϵͳ +#define THOST_FTDC_FC_SyncSystemData '8' +///ͬ͹˾ +#define THOST_FTDC_FC_SyncBrokerData '9' +///ͬ͹˾ +#define THOST_FTDC_FC_BachSyncBrokerData 'A' +///ѯ +#define THOST_FTDC_FC_SuperQuery 'B' +///Ԥ񱨵 +#define THOST_FTDC_FC_ParkedOrderInsert 'C' +///Ԥ񱨵 +#define THOST_FTDC_FC_ParkedOrderAction 'D' +///̬ͬ +#define THOST_FTDC_FC_SyncOTP 'E' +///ɾδ֪ +#define THOST_FTDC_FC_DeleteOrder 'F' + +typedef char TThostFtdcFunctionCodeType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcBrokerFunctionCodeTypeһ͹˾ܴ +///////////////////////////////////////////////////////////////////////// +///ǿûdz +#define THOST_FTDC_BFC_ForceUserLogout '1' +///û +#define THOST_FTDC_BFC_UserPasswordUpdate '2' +///ͬ͹˾ +#define THOST_FTDC_BFC_SyncBrokerData '3' +///ͬ͹˾ +#define THOST_FTDC_BFC_BachSyncBrokerData '4' +/// +#define THOST_FTDC_BFC_OrderInsert '5' +/// +#define THOST_FTDC_BFC_OrderAction '6' +///ȫѯ +#define THOST_FTDC_BFC_AllQuery '7' +///ϵͳܣ/dz/޸ +#define THOST_FTDC_BFC_log 'a' +///ѯѯݣԼȳ +#define THOST_FTDC_BFC_BaseQry 'b' +///ײѯɽί +#define THOST_FTDC_BFC_TradeQry 'c' +///׹ܣ +#define THOST_FTDC_BFC_Trade 'd' +///ת +#define THOST_FTDC_BFC_Virement 'e' +///ռ +#define THOST_FTDC_BFC_Risk 'f' +///ѯ/ѯỰ˵ +#define THOST_FTDC_BFC_Session 'g' +///֪ͨ +#define THOST_FTDC_BFC_RiskNoticeCtl 'h' +///֪ͨ +#define THOST_FTDC_BFC_RiskNotice 'i' +///쿴͹˾ʽȨ +#define THOST_FTDC_BFC_BrokerDeposit 'j' +///ʽѯ +#define THOST_FTDC_BFC_QueryFund 'k' +///ѯ +#define THOST_FTDC_BFC_QueryOrder 'l' +///ɽѯ +#define THOST_FTDC_BFC_QueryTrade 'm' +///ֲֲѯ +#define THOST_FTDC_BFC_QueryPosition 'n' +///ѯ +#define THOST_FTDC_BFC_QueryMarketData 'o' +///û¼ѯ +#define THOST_FTDC_BFC_QueryUserEvent 'p' +///֪ͨѯ +#define THOST_FTDC_BFC_QueryRiskNotify 'q' +///ѯ +#define THOST_FTDC_BFC_QueryFundChange 'r' +///ͶϢѯ +#define THOST_FTDC_BFC_QueryInvestor 's' +///ױѯ +#define THOST_FTDC_BFC_QueryTradingCode 't' +///ǿƽ +#define THOST_FTDC_BFC_ForceClose 'u' +///ѹ +#define THOST_FTDC_BFC_PressTest 'v' +///Ȩ淴 +#define THOST_FTDC_BFC_RemainCalc 'w' +///ֱֲָ֤ +#define THOST_FTDC_BFC_NetPositionInd 'x' +///Ԥ +#define THOST_FTDC_BFC_RiskPredict 'y' +///ݵ +#define THOST_FTDC_BFC_DataExport 'z' +///ָ +#define THOST_FTDC_BFC_RiskTargetSetup 'A' +///Ԥ +#define THOST_FTDC_BFC_MarketDataWarn 'B' +///ҵ֪ͨѯ +#define THOST_FTDC_BFC_QryBizNotice 'C' +///ҵ֪ͨģ +#define THOST_FTDC_BFC_CfgBizNotice 'D' +///̬ͬ +#define THOST_FTDC_BFC_SyncOTP 'E' +///ҵ֪ͨ +#define THOST_FTDC_BFC_SendBizNotice 'F' +///ռ׼ +#define THOST_FTDC_BFC_CfgRiskLevelStd 'G' +///նӦ +#define THOST_FTDC_BFC_TbCommand 'H' +///ɾδ֪ +#define THOST_FTDC_BFC_DeleteOrder 'J' +///Ԥ񱨵 +#define THOST_FTDC_BFC_ParkedOrderInsert 'K' +///Ԥ񱨵 +#define THOST_FTDC_BFC_ParkedOrderAction 'L' +///ʽ𲻹Ȩ +#define THOST_FTDC_BFC_ExecOrderNoCheck 'M' + +typedef char TThostFtdcBrokerFunctionCodeType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcOrderActionStatusTypeһ״̬ +///////////////////////////////////////////////////////////////////////// +///Ѿύ +#define THOST_FTDC_OAS_Submitted 'a' +///Ѿ +#define THOST_FTDC_OAS_Accepted 'b' +///Ѿܾ +#define THOST_FTDC_OAS_Rejected 'c' + +typedef char TThostFtdcOrderActionStatusType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcOrderStatusTypeһ״̬ +///////////////////////////////////////////////////////////////////////// +///ȫɽ +#define THOST_FTDC_OST_AllTraded '0' +///ֳɽڶ +#define THOST_FTDC_OST_PartTradedQueueing '1' +///ֳɽڶ +#define THOST_FTDC_OST_PartTradedNotQueueing '2' +///δɽڶ +#define THOST_FTDC_OST_NoTradeQueueing '3' +///δɽڶ +#define THOST_FTDC_OST_NoTradeNotQueueing '4' +/// +#define THOST_FTDC_OST_Canceled '5' +///δ֪ +#define THOST_FTDC_OST_Unknown 'a' +///δ +#define THOST_FTDC_OST_NotTouched 'b' +///Ѵ +#define THOST_FTDC_OST_Touched 'c' + +typedef char TThostFtdcOrderStatusType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcOrderSubmitStatusTypeһύ״̬ +///////////////////////////////////////////////////////////////////////// +///Ѿύ +#define THOST_FTDC_OSS_InsertSubmitted '0' +///Ѿύ +#define THOST_FTDC_OSS_CancelSubmitted '1' +///޸Ѿύ +#define THOST_FTDC_OSS_ModifySubmitted '2' +///Ѿ +#define THOST_FTDC_OSS_Accepted '3' +///Ѿܾ +#define THOST_FTDC_OSS_InsertRejected '4' +///Ѿܾ +#define THOST_FTDC_OSS_CancelRejected '5' +///ĵѾܾ +#define THOST_FTDC_OSS_ModifyRejected '6' + +typedef char TThostFtdcOrderSubmitStatusType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcPositionDateTypeһֲ +///////////////////////////////////////////////////////////////////////// +///ճֲ +#define THOST_FTDC_PSD_Today '1' +///ʷֲ +#define THOST_FTDC_PSD_History '2' + +typedef char TThostFtdcPositionDateType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcPositionDateTypeTypeһֲ +///////////////////////////////////////////////////////////////////////// +///ʹʷֲ +#define THOST_FTDC_PDT_UseHistory '1' +///ʹʷֲ +#define THOST_FTDC_PDT_NoUseHistory '2' + +typedef char TThostFtdcPositionDateTypeType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcTradingRoleTypeһ׽ɫ +///////////////////////////////////////////////////////////////////////// +/// +#define THOST_FTDC_ER_Broker '1' +///Ӫ +#define THOST_FTDC_ER_Host '2' +/// +#define THOST_FTDC_ER_Maker '3' + +typedef char TThostFtdcTradingRoleType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcProductClassTypeһƷ +///////////////////////////////////////////////////////////////////////// +///ڻ +#define THOST_FTDC_PC_Futures '1' +///ڻȨ +#define THOST_FTDC_PC_Options '2' +/// +#define THOST_FTDC_PC_Combination '3' +/// +#define THOST_FTDC_PC_Spot '4' +///ת +#define THOST_FTDC_PC_EFP '5' +///ֻȨ +#define THOST_FTDC_PC_SpotOption '6' + +typedef char TThostFtdcProductClassType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcInstLifePhaseTypeһԼ״̬ +///////////////////////////////////////////////////////////////////////// +///δ +#define THOST_FTDC_IP_NotStart '0' +/// +#define THOST_FTDC_IP_Started '1' +///ͣ +#define THOST_FTDC_IP_Pause '2' +/// +#define THOST_FTDC_IP_Expired '3' + +typedef char TThostFtdcInstLifePhaseType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcDirectionTypeһ +///////////////////////////////////////////////////////////////////////// +/// +#define THOST_FTDC_D_Buy '0' +/// +#define THOST_FTDC_D_Sell '1' + +typedef char TThostFtdcDirectionType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcPositionTypeTypeһֲ +///////////////////////////////////////////////////////////////////////// +///ֲ +#define THOST_FTDC_PT_Net '1' +///ۺϳֲ +#define THOST_FTDC_PT_Gross '2' + +typedef char TThostFtdcPositionTypeType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcPosiDirectionTypeһֲֶշ +///////////////////////////////////////////////////////////////////////// +/// +#define THOST_FTDC_PD_Net '1' +///ͷ +#define THOST_FTDC_PD_Long '2' +///ͷ +#define THOST_FTDC_PD_Short '3' + +typedef char TThostFtdcPosiDirectionType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcSysSettlementStatusTypeһϵͳ״̬ +///////////////////////////////////////////////////////////////////////// +///Ծ +#define THOST_FTDC_SS_NonActive '1' +/// +#define THOST_FTDC_SS_Startup '2' +/// +#define THOST_FTDC_SS_Operating '3' +/// +#define THOST_FTDC_SS_Settlement '4' +/// +#define THOST_FTDC_SS_SettlementFinished '5' + +typedef char TThostFtdcSysSettlementStatusType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcRatioAttrTypeһ +///////////////////////////////////////////////////////////////////////// +///׷ +#define THOST_FTDC_RA_Trade '0' +/// +#define THOST_FTDC_RA_Settlement '1' + +typedef char TThostFtdcRatioAttrType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcHedgeFlagTypeһͶױ־ +///////////////////////////////////////////////////////////////////////// +///Ͷ +#define THOST_FTDC_HF_Speculation '1' +/// +#define THOST_FTDC_HF_Arbitrage '2' +///ױ +#define THOST_FTDC_HF_Hedge '3' +/// +#define THOST_FTDC_HF_MarketMaker '5' + +typedef char TThostFtdcHedgeFlagType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcBillHedgeFlagTypeһͶױ־ +///////////////////////////////////////////////////////////////////////// +///Ͷ +#define THOST_FTDC_BHF_Speculation '1' +/// +#define THOST_FTDC_BHF_Arbitrage '2' +///ױ +#define THOST_FTDC_BHF_Hedge '3' + +typedef char TThostFtdcBillHedgeFlagType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcClientIDTypeTypeһױ +///////////////////////////////////////////////////////////////////////// +///Ͷ +#define THOST_FTDC_CIDT_Speculation '1' +/// +#define THOST_FTDC_CIDT_Arbitrage '2' +///ױ +#define THOST_FTDC_CIDT_Hedge '3' +/// +#define THOST_FTDC_CIDT_MarketMaker '5' + +typedef char TThostFtdcClientIDTypeType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcOrderPriceTypeTypeһ۸ +///////////////////////////////////////////////////////////////////////// +/// +#define THOST_FTDC_OPT_AnyPrice '1' +///޼ +#define THOST_FTDC_OPT_LimitPrice '2' +///ż +#define THOST_FTDC_OPT_BestPrice '3' +///¼ +#define THOST_FTDC_OPT_LastPrice '4' +///¼۸ϸ1ticks +#define THOST_FTDC_OPT_LastPricePlusOneTicks '5' +///¼۸ϸ2ticks +#define THOST_FTDC_OPT_LastPricePlusTwoTicks '6' +///¼۸ϸ3ticks +#define THOST_FTDC_OPT_LastPricePlusThreeTicks '7' +///һ +#define THOST_FTDC_OPT_AskPrice1 '8' +///һ۸ϸ1ticks +#define THOST_FTDC_OPT_AskPrice1PlusOneTicks '9' +///һ۸ϸ2ticks +#define THOST_FTDC_OPT_AskPrice1PlusTwoTicks 'A' +///һ۸ϸ3ticks +#define THOST_FTDC_OPT_AskPrice1PlusThreeTicks 'B' +///һ +#define THOST_FTDC_OPT_BidPrice1 'C' +///һ۸ϸ1ticks +#define THOST_FTDC_OPT_BidPrice1PlusOneTicks 'D' +///һ۸ϸ2ticks +#define THOST_FTDC_OPT_BidPrice1PlusTwoTicks 'E' +///һ۸ϸ3ticks +#define THOST_FTDC_OPT_BidPrice1PlusThreeTicks 'F' +///嵵 +#define THOST_FTDC_OPT_FiveLevelPrice 'G' + +typedef char TThostFtdcOrderPriceTypeType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcOffsetFlagTypeһƽ־ +///////////////////////////////////////////////////////////////////////// +/// +#define THOST_FTDC_OF_Open '0' +///ƽ +#define THOST_FTDC_OF_Close '1' +///ǿƽ +#define THOST_FTDC_OF_ForceClose '2' +///ƽ +#define THOST_FTDC_OF_CloseToday '3' +///ƽ +#define THOST_FTDC_OF_CloseYesterday '4' +///ǿ +#define THOST_FTDC_OF_ForceOff '5' +///ǿƽ +#define THOST_FTDC_OF_LocalForceClose '6' + +typedef char TThostFtdcOffsetFlagType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcForceCloseReasonTypeһǿƽԭ +///////////////////////////////////////////////////////////////////////// +///ǿƽ +#define THOST_FTDC_FCC_NotForceClose '0' +///ʽ +#define THOST_FTDC_FCC_LackDeposit '1' +///ͻ +#define THOST_FTDC_FCC_ClientOverPositionLimit '2' +///Ա +#define THOST_FTDC_FCC_MemberOverPositionLimit '3' +///ֲַ +#define THOST_FTDC_FCC_NotMultiple '4' +///Υ +#define THOST_FTDC_FCC_Violation '5' +/// +#define THOST_FTDC_FCC_Other '6' +///Ȼٽ +#define THOST_FTDC_FCC_PersonDeliv '7' + +typedef char TThostFtdcForceCloseReasonType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcOrderTypeTypeһ +///////////////////////////////////////////////////////////////////////// +/// +#define THOST_FTDC_ORDT_Normal '0' +/// +#define THOST_FTDC_ORDT_DeriveFromQuote '1' +/// +#define THOST_FTDC_ORDT_DeriveFromCombination '2' +///ϱ +#define THOST_FTDC_ORDT_Combination '3' +/// +#define THOST_FTDC_ORDT_ConditionalOrder '4' +/// +#define THOST_FTDC_ORDT_Swap '5' + +typedef char TThostFtdcOrderTypeType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcTimeConditionTypeһЧ +///////////////////////////////////////////////////////////////////////// +///ɣ +#define THOST_FTDC_TC_IOC '1' +///Ч +#define THOST_FTDC_TC_GFS '2' +///Ч +#define THOST_FTDC_TC_GFD '3' +///ָǰЧ +#define THOST_FTDC_TC_GTD '4' +///ǰЧ +#define THOST_FTDC_TC_GTC '5' +///ϾЧ +#define THOST_FTDC_TC_GFA '6' + +typedef char TThostFtdcTimeConditionType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcVolumeConditionTypeһɽ +///////////////////////////////////////////////////////////////////////// +///κ +#define THOST_FTDC_VC_AV '1' +///С +#define THOST_FTDC_VC_MV '2' +///ȫ +#define THOST_FTDC_VC_CV '3' + +typedef char TThostFtdcVolumeConditionType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcContingentConditionTypeһ +///////////////////////////////////////////////////////////////////////// +/// +#define THOST_FTDC_CC_Immediately '1' +///ֹ +#define THOST_FTDC_CC_Touch '2' +///ֹӮ +#define THOST_FTDC_CC_TouchProfit '3' +///Ԥ +#define THOST_FTDC_CC_ParkedOrder '4' +///¼۴ +#define THOST_FTDC_CC_LastPriceGreaterThanStopPrice '5' +///¼۴ڵ +#define THOST_FTDC_CC_LastPriceGreaterEqualStopPrice '6' +///¼С +#define THOST_FTDC_CC_LastPriceLesserThanStopPrice '7' +///¼Сڵ +#define THOST_FTDC_CC_LastPriceLesserEqualStopPrice '8' +///һ۴ +#define THOST_FTDC_CC_AskPriceGreaterThanStopPrice '9' +///һ۴ڵ +#define THOST_FTDC_CC_AskPriceGreaterEqualStopPrice 'A' +///һС +#define THOST_FTDC_CC_AskPriceLesserThanStopPrice 'B' +///һСڵ +#define THOST_FTDC_CC_AskPriceLesserEqualStopPrice 'C' +///һ۴ +#define THOST_FTDC_CC_BidPriceGreaterThanStopPrice 'D' +///һ۴ڵ +#define THOST_FTDC_CC_BidPriceGreaterEqualStopPrice 'E' +///һС +#define THOST_FTDC_CC_BidPriceLesserThanStopPrice 'F' +///һСڵ +#define THOST_FTDC_CC_BidPriceLesserEqualStopPrice 'H' + +typedef char TThostFtdcContingentConditionType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcActionFlagTypeһ־ +///////////////////////////////////////////////////////////////////////// +///ɾ +#define THOST_FTDC_AF_Delete '0' +///޸ +#define THOST_FTDC_AF_Modify '3' + +typedef char TThostFtdcActionFlagType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcTradingRightTypeһȨ +///////////////////////////////////////////////////////////////////////// +///Խ +#define THOST_FTDC_TR_Allow '0' +///ֻƽ +#define THOST_FTDC_TR_CloseOnly '1' +///ܽ +#define THOST_FTDC_TR_Forbidden '2' + +typedef char TThostFtdcTradingRightType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcOrderSourceTypeһԴ +///////////////////////////////////////////////////////////////////////// +///Բ +#define THOST_FTDC_OSRC_Participant '0' +///ԹԱ +#define THOST_FTDC_OSRC_Administrator '1' + +typedef char TThostFtdcOrderSourceType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcTradeTypeTypeһɽ +///////////////////////////////////////////////////////////////////////// +///ϳֲֲΪһֲ,ʼӦ͵ijֲ +#define THOST_FTDC_TRDT_SplitCombination '#' +///ͨɽ +#define THOST_FTDC_TRDT_Common '0' +///Ȩִ +#define THOST_FTDC_TRDT_OptionsExecution '1' +/// OTCɽ +#define THOST_FTDC_TRDT_OTC '2' +///תɽ +#define THOST_FTDC_TRDT_EFPDerived '3' +///ɽ +#define THOST_FTDC_TRDT_CombinationDerived '4' + +typedef char TThostFtdcTradeTypeType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcPriceSourceTypeһɽԴ +///////////////////////////////////////////////////////////////////////// +///ǰɽ +#define THOST_FTDC_PSRC_LastPrice '0' +///ίм +#define THOST_FTDC_PSRC_Buy '1' +///ίм +#define THOST_FTDC_PSRC_Sell '2' + +typedef char TThostFtdcPriceSourceType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcInstrumentStatusTypeһԼ״̬ +///////////////////////////////////////////////////////////////////////// +///ǰ +#define THOST_FTDC_IS_BeforeTrading '0' +///ǽ +#define THOST_FTDC_IS_NoTrading '1' +/// +#define THOST_FTDC_IS_Continous '2' +///Ͼ۱ +#define THOST_FTDC_IS_AuctionOrdering '3' +///Ͼۼ۸ƽ +#define THOST_FTDC_IS_AuctionBalance '4' +///Ͼ۴ +#define THOST_FTDC_IS_AuctionMatch '5' +/// +#define THOST_FTDC_IS_Closed '6' + +typedef char TThostFtdcInstrumentStatusType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcInstStatusEnterReasonTypeһƷֽ뽻״̬ԭ +///////////////////////////////////////////////////////////////////////// +///Զл +#define THOST_FTDC_IER_Automatic '1' +///ֶл +#define THOST_FTDC_IER_Manual '2' +///۶ +#define THOST_FTDC_IER_Fuse '3' + +typedef char TThostFtdcInstStatusEnterReasonType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcOrderActionRefTypeһ +///////////////////////////////////////////////////////////////////////// +typedef int TThostFtdcOrderActionRefType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcInstallCountTypeһװ +///////////////////////////////////////////////////////////////////////// +typedef int TThostFtdcInstallCountType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcInstallIDTypeһװ +///////////////////////////////////////////////////////////////////////// +typedef int TThostFtdcInstallIDType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcErrorIDTypeһ +///////////////////////////////////////////////////////////////////////// +typedef int TThostFtdcErrorIDType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcSettlementIDTypeһ +///////////////////////////////////////////////////////////////////////// +typedef int TThostFtdcSettlementIDType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcVolumeTypeһ +///////////////////////////////////////////////////////////////////////// +typedef int TThostFtdcVolumeType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcFrontIDTypeһǰñ +///////////////////////////////////////////////////////////////////////// +typedef int TThostFtdcFrontIDType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcSessionIDTypeһỰ +///////////////////////////////////////////////////////////////////////// +typedef int TThostFtdcSessionIDType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcSequenceNoTypeһ +///////////////////////////////////////////////////////////////////////// +typedef int TThostFtdcSequenceNoType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcCommandNoTypeһDB +///////////////////////////////////////////////////////////////////////// +typedef int TThostFtdcCommandNoType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcMillisecTypeһʱ䣨룩 +///////////////////////////////////////////////////////////////////////// +typedef int TThostFtdcMillisecType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcVolumeMultipleTypeһԼ +///////////////////////////////////////////////////////////////////////// +typedef int TThostFtdcVolumeMultipleType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcTradingSegmentSNTypeһ׽׶α +///////////////////////////////////////////////////////////////////////// +typedef int TThostFtdcTradingSegmentSNType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcRequestIDTypeһ +///////////////////////////////////////////////////////////////////////// +typedef int TThostFtdcRequestIDType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcYearTypeһ +///////////////////////////////////////////////////////////////////////// +typedef int TThostFtdcYearType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcMonthTypeһ· +///////////////////////////////////////////////////////////////////////// +typedef int TThostFtdcMonthType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcBoolTypeһ +///////////////////////////////////////////////////////////////////////// +typedef int TThostFtdcBoolType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcPriceTypeһ۸ +///////////////////////////////////////////////////////////////////////// +typedef double TThostFtdcPriceType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcCombOffsetFlagTypeһϿƽ־ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcCombOffsetFlagType[5]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcCombHedgeFlagTypeһͶױ־ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcCombHedgeFlagType[5]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcRatioTypeһ +///////////////////////////////////////////////////////////////////////// +typedef double TThostFtdcRatioType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcMoneyTypeһʽ +///////////////////////////////////////////////////////////////////////// +typedef double TThostFtdcMoneyType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcLargeVolumeTypeһ +///////////////////////////////////////////////////////////////////////// +typedef double TThostFtdcLargeVolumeType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcSequenceSeriesTypeһϵк +///////////////////////////////////////////////////////////////////////// +typedef short TThostFtdcSequenceSeriesType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcCommPhaseNoTypeһͨѶʱα +///////////////////////////////////////////////////////////////////////// +typedef short TThostFtdcCommPhaseNoType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcSequenceLabelTypeһб +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcSequenceLabelType[2]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcUnderlyingMultipleTypeһƷ +///////////////////////////////////////////////////////////////////////// +typedef double TThostFtdcUnderlyingMultipleType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcPriorityTypeһȼ +///////////////////////////////////////////////////////////////////////// +typedef int TThostFtdcPriorityType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcContractCodeTypeһͬ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcContractCodeType[41]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcCityTypeһ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcCityType[51]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcIsStockTypeһǷ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcIsStockType[11]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcChannelTypeһ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcChannelType[51]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcAddressTypeһͨѶַ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcAddressType[101]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcZipCodeTypeһ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcZipCodeType[7]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcTelephoneTypeһϵ绰 +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcTelephoneType[41]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcFaxTypeһ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcFaxType[41]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcMobileTypeһֻ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcMobileType[41]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcEMailTypeһʼ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcEMailType[41]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcMemoTypeһע +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcMemoType[161]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcCompanyCodeTypeһҵ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcCompanyCodeType[51]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcWebsiteTypeһվַ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcWebsiteType[51]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcTaxNoTypeһ˰ǼǺ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcTaxNoType[31]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcBatchStatusTypeһ״̬ +///////////////////////////////////////////////////////////////////////// +///δϴ +#define THOST_FTDC_BS_NoUpload '1' +///ϴ +#define THOST_FTDC_BS_Uploaded '2' +///ʧ +#define THOST_FTDC_BS_Failed '3' + +typedef char TThostFtdcBatchStatusType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcPropertyIDTypeһԴ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcPropertyIDType[33]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcPropertyNameTypeһ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcPropertyNameType[65]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcLicenseNoTypeһӪҵִպ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcLicenseNoType[51]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcAgentIDTypeһ˴ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcAgentIDType[13]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcAgentNameTypeһ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcAgentNameType[41]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcAgentGroupIDTypeһ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcAgentGroupIDType[13]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcAgentGroupNameTypeһ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcAgentGroupNameType[41]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcReturnStyleTypeһƷַʽ +///////////////////////////////////////////////////////////////////////// +///Ʒ +#define THOST_FTDC_RS_All '1' +///Ʒ +#define THOST_FTDC_RS_ByProduct '2' + +typedef char TThostFtdcReturnStyleType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcReturnPatternTypeһģʽ +///////////////////////////////////////////////////////////////////////// +///ɽ +#define THOST_FTDC_RP_ByVolume '1' +/// +#define THOST_FTDC_RP_ByFeeOnHand '2' + +typedef char TThostFtdcReturnPatternType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcReturnLevelTypeһ +///////////////////////////////////////////////////////////////////////// +///1 +#define THOST_FTDC_RL_Level1 '1' +///2 +#define THOST_FTDC_RL_Level2 '2' +///3 +#define THOST_FTDC_RL_Level3 '3' +///4 +#define THOST_FTDC_RL_Level4 '4' +///5 +#define THOST_FTDC_RL_Level5 '5' +///6 +#define THOST_FTDC_RL_Level6 '6' +///7 +#define THOST_FTDC_RL_Level7 '7' +///8 +#define THOST_FTDC_RL_Level8 '8' +///9 +#define THOST_FTDC_RL_Level9 '9' + +typedef char TThostFtdcReturnLevelType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcReturnStandardTypeһ׼ +///////////////////////////////////////////////////////////////////////// +///ֽ׶η +#define THOST_FTDC_RSD_ByPeriod '1' +///ijһ׼ +#define THOST_FTDC_RSD_ByStandard '2' + +typedef char TThostFtdcReturnStandardType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcMortgageTypeTypeһѺ +///////////////////////////////////////////////////////////////////////// +///ʳ +#define THOST_FTDC_MT_Out '0' +/// +#define THOST_FTDC_MT_In '1' + +typedef char TThostFtdcMortgageTypeType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcInvestorSettlementParamIDTypeһͶ߽ +///////////////////////////////////////////////////////////////////////// +///Ѻ +#define THOST_FTDC_ISPI_MortgageRatio '4' +///֤㷨 +#define THOST_FTDC_ISPI_MarginWay '5' +///㵥ǷѺ +#define THOST_FTDC_ISPI_BillDeposit '9' + +typedef char TThostFtdcInvestorSettlementParamIDType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcExchangeSettlementParamIDTypeһ +///////////////////////////////////////////////////////////////////////// +///Ѻ +#define THOST_FTDC_ESPI_MortgageRatio '1' +///ʽ +#define THOST_FTDC_ESPI_OtherFundItem '2' +///ʽ뽻 +#define THOST_FTDC_ESPI_OtherFundImport '3' +///нͿý +#define THOST_FTDC_ESPI_CFFEXMinPrepa '6' +///֣㷽ʽ +#define THOST_FTDC_ESPI_CZCESettlementType '7' +///ȡʽ +#define THOST_FTDC_ESPI_ExchDelivFeeMode '9' +///Ͷ߽ȡʽ +#define THOST_FTDC_ESPI_DelivFeeMode '0' +///֣ϳֱֲ֤ȡʽ +#define THOST_FTDC_ESPI_CZCEComMarginType 'A' +///֤ǷŻ +#define THOST_FTDC_ESPI_DceComMarginType 'B' +///ֵȨ֤Żݱ +#define THOST_FTDC_ESPI_OptOutDisCountRate 'a' +///ͱϵ +#define THOST_FTDC_ESPI_OptMiniGuarantee 'b' + +typedef char TThostFtdcExchangeSettlementParamIDType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcSystemParamIDTypeһϵͳ +///////////////////////////////////////////////////////////////////////// +///ͶߴС +#define THOST_FTDC_SPI_InvestorIDMinLength '1' +///ͶʺŴС +#define THOST_FTDC_SPI_AccountIDMinLength '2' +///Ͷ߿Ĭϵ¼Ȩ +#define THOST_FTDC_SPI_UserRightLogon '3' +///Ͷ߽׽㵥ɽܷʽ +#define THOST_FTDC_SPI_SettlementBillTrade '4' +///ͳһ½ױ뷽ʽ +#define THOST_FTDC_SPI_TradingCode '5' +///Ƿжϴδ˵ijͷʽ +#define THOST_FTDC_SPI_CheckFund '6' +///ǷģȨ +#define THOST_FTDC_SPI_CommModelRight '7' +///Ƿñ֤ģȨ +#define THOST_FTDC_SPI_MarginModelRight '9' +///Ƿ淶ûܼ +#define THOST_FTDC_SPI_IsStandardActive '8' +///ϴĽļ· +#define THOST_FTDC_SPI_UploadSettlementFile 'U' +///ϱ֤ļ· +#define THOST_FTDC_SPI_DownloadCSRCFile 'D' +///ɵĽ㵥ļ· +#define THOST_FTDC_SPI_SettlementBillFile 'S' +///֤ļʶ +#define THOST_FTDC_SPI_CSRCOthersFile 'C' +///ͶƬ· +#define THOST_FTDC_SPI_InvestorPhoto 'P' +///ȫᾭ͹˾ϴļ· +#define THOST_FTDC_SPI_CSRCData 'R' +///¼뷽ʽ +#define THOST_FTDC_SPI_InvestorPwdModel 'I' +///Ͷнļ· +#define THOST_FTDC_SPI_CFFEXInvestorSettleFile 'F' +///Ͷߴ뷽ʽ +#define THOST_FTDC_SPI_InvestorIDType 'a' +///߻Ȩ +#define THOST_FTDC_SPI_FreezeMaxReMain 'r' +///زʵʱϳ +#define THOST_FTDC_SPI_IsSync 'A' +///Ȩ +#define THOST_FTDC_SPI_RelieveOpenLimit 'O' +///Ƿ淶û +#define THOST_FTDC_SPI_IsStandardFreeze 'X' +///֣Ƿ񿪷Ʒױ +#define THOST_FTDC_SPI_CZCENormalProductHedge 'B' + +typedef char TThostFtdcSystemParamIDType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcTradeParamIDTypeһϵͳ +///////////////////////////////////////////////////////////////////////// +///ϵͳ㷨 +#define THOST_FTDC_TPID_EncryptionStandard 'E' +///ϵͳ㷨 +#define THOST_FTDC_TPID_RiskMode 'R' +///ϵͳ㷨Ƿȫ 0- 1- +#define THOST_FTDC_TPID_RiskModeGlobal 'G' +///㷨 +#define THOST_FTDC_TPID_modeEncode 'P' +///۸Сλ +#define THOST_FTDC_TPID_tickMode 'T' +///ûỰ +#define THOST_FTDC_TPID_SingleUserSessionMaxNum 'S' +///¼ʧ +#define THOST_FTDC_TPID_LoginFailMaxNum 'L' +///Ƿǿ֤ +#define THOST_FTDC_TPID_IsAuthForce 'A' +///Ƿ񶳽֤ȯֲ +#define THOST_FTDC_TPID_IsPosiFreeze 'F' +///Ƿ޲ +#define THOST_FTDC_TPID_IsPosiLimit 'M' +///֣ѯʱ +#define THOST_FTDC_TPID_ForQuoteTimeInterval 'Q' +///Ƿڻ޲ +#define THOST_FTDC_TPID_IsFuturePosiLimit 'B' +///ǷڻµƵ +#define THOST_FTDC_TPID_IsFutureOrderFreq 'C' +///ȨǷӯ +#define THOST_FTDC_TPID_IsExecOrderProfit 'H' + +typedef char TThostFtdcTradeParamIDType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcSettlementParamValueTypeһֵ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcSettlementParamValueType[256]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcCounterIDTypeһ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcCounterIDType[33]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcInvestorGroupNameTypeһͶ߷ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcInvestorGroupNameType[41]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcBrandCodeTypeһƺ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcBrandCodeType[257]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcWarehouseTypeһֿ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcWarehouseType[257]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcProductDateTypeһ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcProductDateType[41]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcGradeTypeһȼ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcGradeType[41]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcClassifyTypeһ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcClassifyType[41]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcPositionTypeһλ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcPositionType[41]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcYieldlyTypeһ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcYieldlyType[41]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcWeightTypeһ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcWeightType[41]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcSubEntryFundNoTypeһʽˮ +///////////////////////////////////////////////////////////////////////// +typedef int TThostFtdcSubEntryFundNoType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcFileIDTypeһļʶ +///////////////////////////////////////////////////////////////////////// +///ʽ +#define THOST_FTDC_FI_SettlementFund 'F' +///ɽ +#define THOST_FTDC_FI_Trade 'T' +///Ͷֲ߳ +#define THOST_FTDC_FI_InvestorPosition 'P' +///Ͷ߷ʽ +#define THOST_FTDC_FI_SubEntryFund 'O' +///ϳֲ +#define THOST_FTDC_FI_CZCECombinationPos 'C' +///ϱ֤ +#define THOST_FTDC_FI_CSRCData 'R' +///֣ƽ˽ +#define THOST_FTDC_FI_CZCEClose 'L' +///֣ƽ˽ +#define THOST_FTDC_FI_CZCENoClose 'N' +///ֲϸ +#define THOST_FTDC_FI_PositionDtl 'D' +///Ȩִļ +#define THOST_FTDC_FI_OptionStrike 'S' +///۱ȶļ +#define THOST_FTDC_FI_SettlementPriceComparison 'M' +///dzֱֲ䶯ϸ +#define THOST_FTDC_FI_NonTradePosChange 'B' + +typedef char TThostFtdcFileIDType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcFileNameTypeһļ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcFileNameType[257]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcFileTypeTypeһļϴ +///////////////////////////////////////////////////////////////////////// +/// +#define THOST_FTDC_FUT_Settlement '0' +///˶ +#define THOST_FTDC_FUT_Check '1' + +typedef char TThostFtdcFileTypeType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcFileFormatTypeһļʽ +///////////////////////////////////////////////////////////////////////// +///ıļ(.txt) +#define THOST_FTDC_FFT_Txt '0' +///ѹļ(.zip) +#define THOST_FTDC_FFT_Zip '1' +/// DBFļ(.dbf) +#define THOST_FTDC_FFT_DBF '2' + +typedef char TThostFtdcFileFormatType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcFileUploadStatusTypeһļ״̬ +///////////////////////////////////////////////////////////////////////// +///ϴɹ +#define THOST_FTDC_FUS_SucceedUpload '1' +///ϴʧ +#define THOST_FTDC_FUS_FailedUpload '2' +///ɹ +#define THOST_FTDC_FUS_SucceedLoad '3' +///벿ֳɹ +#define THOST_FTDC_FUS_PartSucceedLoad '4' +///ʧ +#define THOST_FTDC_FUS_FailedLoad '5' + +typedef char TThostFtdcFileUploadStatusType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcTransferDirectionTypeһƲַ +///////////////////////////////////////////////////////////////////////// +///Ƴ +#define THOST_FTDC_TD_Out '0' +/// +#define THOST_FTDC_TD_In '1' + +typedef char TThostFtdcTransferDirectionType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcUploadModeTypeһϴļ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcUploadModeType[21]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcAccountIDTypeһͶʺ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcAccountIDType[13]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcBankFlagTypeһͳһʶ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcBankFlagType[4]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcBankAccountTypeһ˻ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcBankAccountType[41]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcOpenNameTypeһ˻Ŀ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcOpenNameType[61]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcOpenBankTypeһ˻Ŀ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcOpenBankType[101]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcBankNameTypeһ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcBankNameType[101]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcPublishPathTypeһ· +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcPublishPathType[257]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcOperatorIDTypeһԱ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcOperatorIDType[65]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcMonthCountTypeһ· +///////////////////////////////////////////////////////////////////////// +typedef int TThostFtdcMonthCountType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcAdvanceMonthArrayTypeһ·ǰ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcAdvanceMonthArrayType[13]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcDateExprTypeһڱʽ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcDateExprType[1025]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcInstrumentIDExprTypeһԼʽ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcInstrumentIDExprType[41]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcInstrumentNameExprTypeһԼƱʽ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcInstrumentNameExprType[41]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcSpecialCreateRuleTypeһĴ +///////////////////////////////////////////////////////////////////////// +///ûⴴ +#define THOST_FTDC_SC_NoSpecialRule '0' +/// +#define THOST_FTDC_SC_NoSpringFestival '1' + +typedef char TThostFtdcSpecialCreateRuleType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcBasisPriceTypeTypeһƻ׼ +///////////////////////////////////////////////////////////////////////// +///һԼ +#define THOST_FTDC_IPT_LastSettlement '1' +///һԼ̼ +#define THOST_FTDC_IPT_LaseClose '2' + +typedef char TThostFtdcBasisPriceTypeType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcProductLifePhaseTypeһƷ״̬ +///////////////////////////////////////////////////////////////////////// +///Ծ +#define THOST_FTDC_PLP_Active '1' +///Ծ +#define THOST_FTDC_PLP_NonActive '2' +///ע +#define THOST_FTDC_PLP_Canceled '3' + +typedef char TThostFtdcProductLifePhaseType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcDeliveryModeTypeһʽ +///////////////////////////////////////////////////////////////////////// +///ֽ𽻸 +#define THOST_FTDC_DM_CashDeliv '1' +///ʵサ +#define THOST_FTDC_DM_CommodityDeliv '2' + +typedef char TThostFtdcDeliveryModeType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcLogLevelTypeһ־ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcLogLevelType[33]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcProcessNameTypeһ洢 +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcProcessNameType[257]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcOperationMemoTypeһժҪ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcOperationMemoType[1025]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcFundIOTypeTypeһ +///////////////////////////////////////////////////////////////////////// +/// +#define THOST_FTDC_FIOT_FundIO '1' +///ת +#define THOST_FTDC_FIOT_Transfer '2' +///ڻ +#define THOST_FTDC_FIOT_SwapCurrency '3' + +typedef char TThostFtdcFundIOTypeType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcFundTypeTypeһʽ +///////////////////////////////////////////////////////////////////////// +///д +#define THOST_FTDC_FT_Deposite '1' +///ʽ +#define THOST_FTDC_FT_ItemFund '2' +///˾ +#define THOST_FTDC_FT_Company '3' +///ʽת +#define THOST_FTDC_FT_InnerTransfer '4' + +typedef char TThostFtdcFundTypeType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcFundDirectionTypeһ +///////////////////////////////////////////////////////////////////////// +/// +#define THOST_FTDC_FD_In '1' +/// +#define THOST_FTDC_FD_Out '2' + +typedef char TThostFtdcFundDirectionType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcFundStatusTypeһʽ״̬ +///////////////////////////////////////////////////////////////////////// +///¼ +#define THOST_FTDC_FS_Record '1' +///Ѹ +#define THOST_FTDC_FS_Check '2' +///ѳ +#define THOST_FTDC_FS_Charge '3' + +typedef char TThostFtdcFundStatusType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcBillNoTypeһƱݺ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcBillNoType[15]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcBillNameTypeһƱ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcBillNameType[33]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcPublishStatusTypeһ״̬ +///////////////////////////////////////////////////////////////////////// +///δ +#define THOST_FTDC_PS_None '1' +///ڷ +#define THOST_FTDC_PS_Publishing '2' +///ѷ +#define THOST_FTDC_PS_Published '3' + +typedef char TThostFtdcPublishStatusType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcEnumValueIDTypeһöֵ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcEnumValueIDType[65]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcEnumValueTypeTypeһöֵ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcEnumValueTypeType[33]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcEnumValueLabelTypeһöֵ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcEnumValueLabelType[65]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcEnumValueResultTypeһöֵ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcEnumValueResultType[33]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcSystemStatusTypeһϵͳ״̬ +///////////////////////////////////////////////////////////////////////// +///Ծ +#define THOST_FTDC_ES_NonActive '1' +/// +#define THOST_FTDC_ES_Startup '2' +///׿ʼʼ +#define THOST_FTDC_ES_Initialize '3' +///ɳʼ +#define THOST_FTDC_ES_Initialized '4' +///пʼ +#define THOST_FTDC_ES_Close '5' +/// +#define THOST_FTDC_ES_Closed '6' +/// +#define THOST_FTDC_ES_Settlement '7' + +typedef char TThostFtdcSystemStatusType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcSettlementStatusTypeһ״̬ +///////////////////////////////////////////////////////////////////////// +///ʼ +#define THOST_FTDC_STS_Initialize '0' +/// +#define THOST_FTDC_STS_Settlementing '1' +///ѽ +#define THOST_FTDC_STS_Settlemented '2' +/// +#define THOST_FTDC_STS_Finished '3' + +typedef char TThostFtdcSettlementStatusType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcRangeIntTypeTypeһ޶ֵ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcRangeIntTypeType[33]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcRangeIntFromTypeһ޶ֵ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcRangeIntFromType[33]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcRangeIntToTypeһ޶ֵ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcRangeIntToType[33]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcFunctionIDTypeһܴ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcFunctionIDType[25]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcFunctionValueCodeTypeһܱ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcFunctionValueCodeType[257]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcFunctionNameTypeһ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcFunctionNameType[65]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcRoleIDTypeһɫ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcRoleIDType[11]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcRoleNameTypeһɫ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcRoleNameType[41]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcDescriptionTypeһ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcDescriptionType[401]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcCombineIDTypeһϱ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcCombineIDType[25]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcCombineTypeTypeһ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcCombineTypeType[25]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcInvestorTypeTypeһͶ +///////////////////////////////////////////////////////////////////////// +///Ȼ +#define THOST_FTDC_CT_Person '0' +/// +#define THOST_FTDC_CT_Company '1' +///Ͷʻ +#define THOST_FTDC_CT_Fund '2' +///ⷨ +#define THOST_FTDC_CT_SpecialOrgan '3' +///ʹܻ +#define THOST_FTDC_CT_Asset '4' + +typedef char TThostFtdcInvestorTypeType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcBrokerTypeTypeһ͹˾ +///////////////////////////////////////////////////////////////////////// +///׻Ա +#define THOST_FTDC_BT_Trade '0' +///׽Ա +#define THOST_FTDC_BT_TradeSettle '1' + +typedef char TThostFtdcBrokerTypeType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcRiskLevelTypeһյȼ +///////////////////////////////////////////////////////////////////////// +///ͷտͻ +#define THOST_FTDC_FAS_Low '1' +///ͨͻ +#define THOST_FTDC_FAS_Normal '2' +///עͻ +#define THOST_FTDC_FAS_Focus '3' +///տͻ +#define THOST_FTDC_FAS_Risk '4' + +typedef char TThostFtdcRiskLevelType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcFeeAcceptStyleTypeһȡʽ +///////////////////////////////////////////////////////////////////////// +///ȡ +#define THOST_FTDC_FAS_ByTrade '1' +///ȡ +#define THOST_FTDC_FAS_ByDeliv '2' +/// +#define THOST_FTDC_FAS_None '3' +///ָȡ +#define THOST_FTDC_FAS_FixFee '4' + +typedef char TThostFtdcFeeAcceptStyleType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcPasswordTypeTypeһ +///////////////////////////////////////////////////////////////////////// +/// +#define THOST_FTDC_PWDT_Trade '1' +///ʽ +#define THOST_FTDC_PWDT_Account '2' + +typedef char TThostFtdcPasswordTypeType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcAlgorithmTypeһӯ㷨 +///////////////////////////////////////////////////////////////////////// +///ӯ +#define THOST_FTDC_AG_All '1' +///ӯƣ +#define THOST_FTDC_AG_OnlyLost '2' +///ӯƣ +#define THOST_FTDC_AG_OnlyGain '3' +///ӯ +#define THOST_FTDC_AG_None '4' + +typedef char TThostFtdcAlgorithmType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcIncludeCloseProfitTypeһǷƽӯ +///////////////////////////////////////////////////////////////////////// +///ƽӯ +#define THOST_FTDC_ICP_Include '0' +///ƽӯ +#define THOST_FTDC_ICP_NotInclude '2' + +typedef char TThostFtdcIncludeCloseProfitType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcAllWithoutTradeTypeһǷܿ +///////////////////////////////////////////////////////////////////////// +///޲޳ɽܿ +#define THOST_FTDC_AWT_Enable '0' +///ܿ +#define THOST_FTDC_AWT_Disable '2' +///޲ֲܿ +#define THOST_FTDC_AWT_NoHoldEnable '3' + +typedef char TThostFtdcAllWithoutTradeType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcCommentTypeһӯ㷨˵ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcCommentType[31]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcVersionTypeһ汾 +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcVersionType[4]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcTradeCodeTypeһ״ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcTradeCodeType[7]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcTradeDateTypeһ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcTradeDateType[9]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcTradeTimeTypeһʱ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcTradeTimeType[9]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcTradeSerialTypeһˮ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcTradeSerialType[9]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcTradeSerialNoTypeһˮ +///////////////////////////////////////////////////////////////////////// +typedef int TThostFtdcTradeSerialNoType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcFutureIDTypeһڻ˾ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcFutureIDType[11]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcBankIDTypeһд +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcBankIDType[4]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcBankBrchIDTypeһзĴ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcBankBrchIDType[5]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcBankBranchIDTypeһĴ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcBankBranchIDType[11]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcOperNoTypeһ׹Ա +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcOperNoType[17]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcDeviceIDTypeһ־ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcDeviceIDType[3]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcRecordNumTypeһ¼ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcRecordNumType[7]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcFutureAccountTypeһڻʽ˺ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcFutureAccountType[22]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcFuturePwdFlagTypeһʽ˶Ա־ +///////////////////////////////////////////////////////////////////////// +///˶ +#define THOST_FTDC_FPWD_UnCheck '0' +///˶ +#define THOST_FTDC_FPWD_Check '1' + +typedef char TThostFtdcFuturePwdFlagType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcTransferTypeTypeһת +///////////////////////////////////////////////////////////////////////// +///תڻ +#define THOST_FTDC_TT_BankToFuture '0' +///ڻת +#define THOST_FTDC_TT_FutureToBank '1' + +typedef char TThostFtdcTransferTypeType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcFutureAccPwdTypeһڻʽ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcFutureAccPwdType[17]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcCurrencyCodeTypeһ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcCurrencyCodeType[4]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcRetCodeTypeһӦ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcRetCodeType[5]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcRetInfoTypeһӦϢ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcRetInfoType[129]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcTradeAmtTypeһ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcTradeAmtType[20]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcUseAmtTypeһп +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcUseAmtType[20]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcFetchAmtTypeһпȡ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcFetchAmtType[20]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcTransferValidFlagTypeһתЧ־ +///////////////////////////////////////////////////////////////////////// +///Чʧ +#define THOST_FTDC_TVF_Invalid '0' +///Ч +#define THOST_FTDC_TVF_Valid '1' +/// +#define THOST_FTDC_TVF_Reverse '2' + +typedef char TThostFtdcTransferValidFlagType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcCertCodeTypeһ֤ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcCertCodeType[21]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcReasonTypeһ +///////////////////////////////////////////////////////////////////////// +/// +#define THOST_FTDC_RN_CD '0' +///ʽ; +#define THOST_FTDC_RN_ZT '1' +/// +#define THOST_FTDC_RN_QT '2' + +typedef char TThostFtdcReasonType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcFundProjectIDTypeһʽĿ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcFundProjectIDType[5]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcSexTypeһԱ +///////////////////////////////////////////////////////////////////////// +///δ֪ +#define THOST_FTDC_SEX_None '0' +/// +#define THOST_FTDC_SEX_Man '1' +///Ů +#define THOST_FTDC_SEX_Woman '2' + +typedef char TThostFtdcSexType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcProfessionTypeһְҵ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcProfessionType[101]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcNationalTypeһ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcNationalType[31]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcProvinceTypeһʡ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcProvinceType[51]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcRegionTypeһ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcRegionType[16]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcCountryTypeһ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcCountryType[16]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcLicenseNOTypeһӪҵִ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcLicenseNOType[33]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcCompanyTypeTypeһҵ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcCompanyTypeType[16]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcBusinessScopeTypeһӪΧ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcBusinessScopeType[1001]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcCapitalCurrencyTypeһעʱ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcCapitalCurrencyType[4]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcUserTypeTypeһû +///////////////////////////////////////////////////////////////////////// +///Ͷ +#define THOST_FTDC_UT_Investor '0' +///Ա +#define THOST_FTDC_UT_Operator '1' +///Ա +#define THOST_FTDC_UT_SuperUser '2' + +typedef char TThostFtdcUserTypeType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcBranchIDTypeһӪҵ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcBranchIDType[9]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcRateTypeTypeһ +///////////////////////////////////////////////////////////////////////// +///֤ +#define THOST_FTDC_RATETYPE_MarginRate '2' + +typedef char TThostFtdcRateTypeType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcNoteTypeTypeһ֪ͨ +///////////////////////////////////////////////////////////////////////// +///׽㵥 +#define THOST_FTDC_NOTETYPE_TradeSettleBill '1' +///׽± +#define THOST_FTDC_NOTETYPE_TradeSettleMonth '2' +///׷ӱ֤֪ͨ +#define THOST_FTDC_NOTETYPE_CallMarginNotes '3' +///ǿƽ֪ͨ +#define THOST_FTDC_NOTETYPE_ForceCloseNotes '4' +///ɽ֪ͨ +#define THOST_FTDC_NOTETYPE_TradeNotes '5' +///֪ͨ +#define THOST_FTDC_NOTETYPE_DelivNotes '6' + +typedef char TThostFtdcNoteTypeType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcSettlementStyleTypeһ㵥ʽ +///////////////////////////////////////////////////////////////////////// +///ն +#define THOST_FTDC_SBS_Day '1' +///ʶԳ +#define THOST_FTDC_SBS_Volume '2' + +typedef char TThostFtdcSettlementStyleType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcBrokerDNSTypeһ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcBrokerDNSType[256]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcSentenceTypeһ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcSentenceType[501]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcSettlementBillTypeTypeһ㵥 +///////////////////////////////////////////////////////////////////////// +///ձ +#define THOST_FTDC_ST_Day '0' +///± +#define THOST_FTDC_ST_Month '1' + +typedef char TThostFtdcSettlementBillTypeType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcUserRightTypeTypeһͻȨ +///////////////////////////////////////////////////////////////////////// +///¼ +#define THOST_FTDC_URT_Logon '1' +///ת +#define THOST_FTDC_URT_Transfer '2' +///ʼĽ㵥 +#define THOST_FTDC_URT_EMail '3' +///㵥 +#define THOST_FTDC_URT_Fax '4' +/// +#define THOST_FTDC_URT_ConditionOrder '5' + +typedef char TThostFtdcUserRightTypeType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcMarginPriceTypeTypeһ֤۸ +///////////////////////////////////////////////////////////////////////// +/// +#define THOST_FTDC_MPT_PreSettlementPrice '1' +///¼ +#define THOST_FTDC_MPT_SettlementPrice '2' +///ɽ +#define THOST_FTDC_MPT_AveragePrice '3' +///ּ +#define THOST_FTDC_MPT_OpenPrice '4' + +typedef char TThostFtdcMarginPriceTypeType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcBillGenStatusTypeһ㵥״̬ +///////////////////////////////////////////////////////////////////////// +///δ +#define THOST_FTDC_BGS_None '0' +/// +#define THOST_FTDC_BGS_NoGenerated '1' +/// +#define THOST_FTDC_BGS_Generated '2' + +typedef char TThostFtdcBillGenStatusType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcAlgoTypeTypeһ㷨 +///////////////////////////////////////////////////////////////////////// +///ֲִ㷨 +#define THOST_FTDC_AT_HandlePositionAlgo '1' +///Ѱұ֤㷨 +#define THOST_FTDC_AT_FindMarginRateAlgo '2' + +typedef char TThostFtdcAlgoTypeType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcHandlePositionAlgoIDTypeһֲִ㷨 +///////////////////////////////////////////////////////////////////////// +/// +#define THOST_FTDC_HPA_Base '1' +///Ʒ +#define THOST_FTDC_HPA_DCE '2' +///֣Ʒ +#define THOST_FTDC_HPA_CZCE '3' + +typedef char TThostFtdcHandlePositionAlgoIDType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcFindMarginRateAlgoIDTypeһѰұ֤㷨 +///////////////////////////////////////////////////////////////////////// +/// +#define THOST_FTDC_FMRA_Base '1' +///Ʒ +#define THOST_FTDC_FMRA_DCE '2' +///֣Ʒ +#define THOST_FTDC_FMRA_CZCE '3' + +typedef char TThostFtdcFindMarginRateAlgoIDType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcHandleTradingAccountAlgoIDTypeһʽ㷨 +///////////////////////////////////////////////////////////////////////// +/// +#define THOST_FTDC_HTAA_Base '1' +///Ʒ +#define THOST_FTDC_HTAA_DCE '2' +///֣Ʒ +#define THOST_FTDC_HTAA_CZCE '3' + +typedef char TThostFtdcHandleTradingAccountAlgoIDType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcPersonTypeTypeһϵ +///////////////////////////////////////////////////////////////////////// +///ָµ +#define THOST_FTDC_PST_Order '1' +///Ȩ +#define THOST_FTDC_PST_Open '2' +///ʽ +#define THOST_FTDC_PST_Fund '3' +///㵥ȷ +#define THOST_FTDC_PST_Settlement '4' +/// +#define THOST_FTDC_PST_Company '5' +///˴ +#define THOST_FTDC_PST_Corporation '6' +///Ͷϵ +#define THOST_FTDC_PST_LinkMan '7' +///ֻʲ +#define THOST_FTDC_PST_Ledger '8' +///У +#define THOST_FTDC_PST_Trustee '9' +///Уܻ˴ +#define THOST_FTDC_PST_TrusteeCorporation 'A' +///УܻȨ +#define THOST_FTDC_PST_TrusteeOpen 'B' +///Уܻϵ +#define THOST_FTDC_PST_TrusteeContact 'C' +///Ȼ˲ο֤ +#define THOST_FTDC_PST_ForeignerRefer 'D' +///˴ο֤ +#define THOST_FTDC_PST_CorporationRefer 'E' + +typedef char TThostFtdcPersonTypeType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcQueryInvestorRangeTypeһѯΧ +///////////////////////////////////////////////////////////////////////// +/// +#define THOST_FTDC_QIR_All '1' +///ѯ +#define THOST_FTDC_QIR_Group '2' +///һͶ +#define THOST_FTDC_QIR_Single '3' + +typedef char TThostFtdcQueryInvestorRangeType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcInvestorRiskStatusTypeһͶ߷״̬ +///////////////////////////////////////////////////////////////////////// +/// +#define THOST_FTDC_IRS_Normal '1' +/// +#define THOST_FTDC_IRS_Warn '2' +///׷ +#define THOST_FTDC_IRS_Call '3' +///ǿƽ +#define THOST_FTDC_IRS_Force '4' +///쳣 +#define THOST_FTDC_IRS_Exception '5' + +typedef char TThostFtdcInvestorRiskStatusType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcLegIDTypeһȱ +///////////////////////////////////////////////////////////////////////// +typedef int TThostFtdcLegIDType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcLegMultipleTypeһȳ +///////////////////////////////////////////////////////////////////////// +typedef int TThostFtdcLegMultipleType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcImplyLevelTypeһ +///////////////////////////////////////////////////////////////////////// +typedef int TThostFtdcImplyLevelType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcClearAccountTypeһ˻ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcClearAccountType[33]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcOrganNOTypeһ˻ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcOrganNOType[6]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcClearbarchIDTypeһ˻к +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcClearbarchIDType[6]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcUserEventTypeTypeһû¼ +///////////////////////////////////////////////////////////////////////// +///¼ +#define THOST_FTDC_UET_Login '1' +///dz +#define THOST_FTDC_UET_Logout '2' +///׳ɹ +#define THOST_FTDC_UET_Trading '3' +///ʧ +#define THOST_FTDC_UET_TradingError '4' +///޸ +#define THOST_FTDC_UET_UpdatePassword '5' +///ͻ֤ +#define THOST_FTDC_UET_Authenticate '6' +/// +#define THOST_FTDC_UET_Other '9' + +typedef char TThostFtdcUserEventTypeType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcUserEventInfoTypeһû¼Ϣ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcUserEventInfoType[1025]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcCloseStyleTypeһƽַʽ +///////////////////////////////////////////////////////////////////////// +///ȿƽ +#define THOST_FTDC_ICS_Close '0' +///ƽƽ +#define THOST_FTDC_ICS_CloseToday '1' + +typedef char TThostFtdcCloseStyleType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcStatModeTypeһͳƷʽ +///////////////////////////////////////////////////////////////////////// +///---- +#define THOST_FTDC_SM_Non '0' +///Լͳ +#define THOST_FTDC_SM_Instrument '1' +///Ʒͳ +#define THOST_FTDC_SM_Product '2' +///Ͷͳ +#define THOST_FTDC_SM_Investor '3' + +typedef char TThostFtdcStatModeType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcParkedOrderStatusTypeһԤ״̬ +///////////////////////////////////////////////////////////////////////// +///δ +#define THOST_FTDC_PAOS_NotSend '1' +///ѷ +#define THOST_FTDC_PAOS_Send '2' +///ɾ +#define THOST_FTDC_PAOS_Deleted '3' + +typedef char TThostFtdcParkedOrderStatusType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcParkedOrderIDTypeһԤ񱨵 +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcParkedOrderIDType[13]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcParkedOrderActionIDTypeһԤ񳷵 +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcParkedOrderActionIDType[13]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcVirDealStatusTypeһ״̬ +///////////////////////////////////////////////////////////////////////// +///ڴ +#define THOST_FTDC_VDS_Dealing '1' +///ɹ +#define THOST_FTDC_VDS_DeaclSucceed '2' + +typedef char TThostFtdcVirDealStatusType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcOrgSystemIDTypeһԭϵͳ +///////////////////////////////////////////////////////////////////////// +///ۺϽƽ̨ +#define THOST_FTDC_ORGS_Standard '0' +///ʢϵͳ +#define THOST_FTDC_ORGS_ESunny '1' +///˴V6ϵͳ +#define THOST_FTDC_ORGS_KingStarV6 '2' + +typedef char TThostFtdcOrgSystemIDType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcVirTradeStatusTypeһ״̬ +///////////////////////////////////////////////////////////////////////// +/// +#define THOST_FTDC_VTS_NaturalDeal '0' +///ɹ +#define THOST_FTDC_VTS_SucceedEnd '1' +///ʧܽ +#define THOST_FTDC_VTS_FailedEND '2' +///쳣 +#define THOST_FTDC_VTS_Exception '3' +///˹쳣 +#define THOST_FTDC_VTS_ManualDeal '4' +///ͨѶ쳣 ˹ +#define THOST_FTDC_VTS_MesException '5' +///ϵͳ˹ +#define THOST_FTDC_VTS_SysException '6' + +typedef char TThostFtdcVirTradeStatusType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcVirBankAccTypeTypeһʻ +///////////////////////////////////////////////////////////////////////// +/// +#define THOST_FTDC_VBAT_BankBook '1' +/// +#define THOST_FTDC_VBAT_BankCard '2' +///ÿ +#define THOST_FTDC_VBAT_CreditCard '3' + +typedef char TThostFtdcVirBankAccTypeType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcVirementStatusTypeһʻ +///////////////////////////////////////////////////////////////////////// +/// +#define THOST_FTDC_VMS_Natural '0' +/// +#define THOST_FTDC_VMS_Canceled '9' + +typedef char TThostFtdcVirementStatusType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcVirementAvailAbilityTypeһЧ־ +///////////////////////////////////////////////////////////////////////// +///δȷ +#define THOST_FTDC_VAA_NoAvailAbility '0' +///Ч +#define THOST_FTDC_VAA_AvailAbility '1' +/// +#define THOST_FTDC_VAA_Repeal '2' + +typedef char TThostFtdcVirementAvailAbilityType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcVirementTradeCodeTypeһ״ +///////////////////////////////////////////////////////////////////////// +///зʽתڻ +#define THOST_FTDC_VTC_BankBankToFuture '102001' +///зڻʽת +#define THOST_FTDC_VTC_BankFutureToBank '102002' +///ڻʽתڻ +#define THOST_FTDC_VTC_FutureBankToFuture '202001' +///ڻڻʽת +#define THOST_FTDC_VTC_FutureFutureToBank '202002' + +typedef char TThostFtdcVirementTradeCodeType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcPhotoTypeNameTypeһӰ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcPhotoTypeNameType[41]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcPhotoTypeIDTypeһӰʹ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcPhotoTypeIDType[5]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcPhotoNameTypeһӰ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcPhotoNameType[161]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcTopicIDTypeһ +///////////////////////////////////////////////////////////////////////// +typedef int TThostFtdcTopicIDType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcReportTypeIDTypeһױͱʶ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcReportTypeIDType[3]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcCharacterIDTypeһ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcCharacterIDType[5]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcAMLParamIDTypeһ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcAMLParamIDType[21]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcAMLInvestorTypeTypeһͶ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcAMLInvestorTypeType[3]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcAMLIdCardTypeTypeһ֤ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcAMLIdCardTypeType[3]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcAMLTradeDirectTypeһʽ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcAMLTradeDirectType[3]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcAMLTradeModelTypeһʽʽ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcAMLTradeModelType[3]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcAMLParamIDTypeһ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcAMLParamIDType[21]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcAMLOpParamValueTypeһҵֵ +///////////////////////////////////////////////////////////////////////// +typedef double TThostFtdcAMLOpParamValueType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcAMLCustomerCardTypeTypeһͻ֤/֤ļ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcAMLCustomerCardTypeType[81]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcAMLInstitutionNameTypeһڻ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcAMLInstitutionNameType[65]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcAMLDistrictIDTypeһڻڵ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcAMLDistrictIDType[7]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcAMLRelationShipTypeһڻ׵Ĺϵ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcAMLRelationShipType[3]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcAMLInstitutionTypeTypeһڻ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcAMLInstitutionTypeType[3]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcAMLInstitutionIDTypeһڻ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcAMLInstitutionIDType[13]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcAMLAccountTypeTypeһ˻ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcAMLAccountTypeType[5]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcAMLTradingTypeTypeһ׷ʽ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcAMLTradingTypeType[7]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcAMLTransactClassTypeһ֧׷ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcAMLTransactClassType[7]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcAMLCapitalIOTypeһʽոʶ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcAMLCapitalIOType[3]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcAMLSiteTypeһ׵ص +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcAMLSiteType[10]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcAMLCapitalPurposeTypeһʽ; +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcAMLCapitalPurposeType[129]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcAMLReportTypeTypeһ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcAMLReportTypeType[2]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcAMLSerialNoTypeһ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcAMLSerialNoType[5]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcAMLStatusTypeһ״̬ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcAMLStatusType[2]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcAMLGenStatusTypeһAmlɷʽ +///////////////////////////////////////////////////////////////////////// +/// +#define THOST_FTDC_GEN_Program '0' +///˹ +#define THOST_FTDC_GEN_HandWork '1' + +typedef char TThostFtdcAMLGenStatusType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcAMLSeqCodeTypeһҵʶ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcAMLSeqCodeType[65]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcAMLFileNameTypeһAMLļ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcAMLFileNameType[257]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcAMLMoneyTypeһϴǮʽ +///////////////////////////////////////////////////////////////////////// +typedef double TThostFtdcAMLMoneyType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcAMLFileAmountTypeһϴǮʽ +///////////////////////////////////////////////////////////////////////// +typedef int TThostFtdcAMLFileAmountType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcCFMMCKeyTypeһԿ(֤) +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcCFMMCKeyType[21]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcCFMMCTokenTypeһ(֤) +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcCFMMCTokenType[21]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcCFMMCKeyKindTypeһ̬Կ(֤) +///////////////////////////////////////////////////////////////////////// +/// +#define THOST_FTDC_CFMMCKK_REQUEST 'R' +/// CFMMCԶ +#define THOST_FTDC_CFMMCKK_AUTO 'A' +/// CFMMCֶ +#define THOST_FTDC_CFMMCKK_MANUAL 'M' + +typedef char TThostFtdcCFMMCKeyKindType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcAMLReportNameTypeһ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcAMLReportNameType[81]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcIndividualNameTypeһ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcIndividualNameType[51]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcCurrencyIDTypeһִ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcCurrencyIDType[4]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcCustNumberTypeһͻ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcCustNumberType[36]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcOrganCodeTypeһ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcOrganCodeType[36]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcOrganNameTypeһ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcOrganNameType[71]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcSuperOrganCodeTypeһϼ,ڻ˾ܲ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcSuperOrganCodeType[12]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcSubBranchIDTypeһ֧ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcSubBranchIDType[31]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcSubBranchNameTypeһ֧ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcSubBranchNameType[71]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcBranchNetCodeTypeһ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcBranchNetCodeType[31]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcBranchNetNameTypeһ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcBranchNetNameType[71]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcOrganFlagTypeһʶ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcOrganFlagType[2]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcBankCodingForFutureTypeһжڻ˾ı +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcBankCodingForFutureType[33]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcBankReturnCodeTypeһжԷĶ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcBankReturnCodeType[7]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcPlateReturnCodeTypeһתƽ̨ԷĶ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcPlateReturnCodeType[5]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcBankSubBranchIDTypeһз֧ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcBankSubBranchIDType[31]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcFutureBranchIDTypeһڻ֧ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcFutureBranchIDType[31]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcReturnCodeTypeһش +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcReturnCodeType[7]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcOperatorCodeTypeһԱ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcOperatorCodeType[17]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcClearDepIDTypeһʻ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcClearDepIDType[6]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcClearBrchIDTypeһʻк +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcClearBrchIDType[6]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcClearNameTypeһʻ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcClearNameType[71]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcBankAccountNameTypeһʻ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcBankAccountNameType[71]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcInvDepIDTypeһͶ˺Ż +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcInvDepIDType[6]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcInvBrchIDTypeһͶк +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcInvBrchIDType[6]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcMessageFormatVersionTypeһϢʽ汾 +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcMessageFormatVersionType[36]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcDigestTypeһժҪ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcDigestType[36]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcAuthenticDataTypeһ֤ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcAuthenticDataType[129]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcPasswordKeyTypeһԿ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcPasswordKeyType[129]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcFutureAccountNameTypeһڻʻ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcFutureAccountNameType[129]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcMobilePhoneTypeһֻ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcMobilePhoneType[21]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcFutureMainKeyTypeһڻ˾Կ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcFutureMainKeyType[129]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcFutureWorkKeyTypeһڻ˾Կ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcFutureWorkKeyType[129]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcFutureTransKeyTypeһڻ˾Կ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcFutureTransKeyType[129]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcBankMainKeyTypeһԿ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcBankMainKeyType[129]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcBankWorkKeyTypeһйԿ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcBankWorkKeyType[129]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcBankTransKeyTypeһдԿ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcBankTransKeyType[129]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcBankServerDescriptionTypeһзϢ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcBankServerDescriptionType[129]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcAddInfoTypeһϢ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcAddInfoType[129]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcDescrInfoForReturnCodeTypeһ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcDescrInfoForReturnCodeType[129]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcCountryCodeTypeһҴ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcCountryCodeType[21]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcSerialTypeһˮ +///////////////////////////////////////////////////////////////////////// +typedef int TThostFtdcSerialType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcPlateSerialTypeһƽ̨ˮ +///////////////////////////////////////////////////////////////////////// +typedef int TThostFtdcPlateSerialType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcBankSerialTypeһˮ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcBankSerialType[13]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcCorrectSerialTypeһˮ +///////////////////////////////////////////////////////////////////////// +typedef int TThostFtdcCorrectSerialType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcFutureSerialTypeһڻ˾ˮ +///////////////////////////////////////////////////////////////////////// +typedef int TThostFtdcFutureSerialType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcApplicationIDTypeһӦñʶ +///////////////////////////////////////////////////////////////////////// +typedef int TThostFtdcApplicationIDType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcBankProxyIDTypeһдʶ +///////////////////////////////////////////////////////////////////////// +typedef int TThostFtdcBankProxyIDType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcFBTCoreIDTypeһתʺϵͳʶ +///////////////////////////////////////////////////////////////////////// +typedef int TThostFtdcFBTCoreIDType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcServerPortTypeһ˿ں +///////////////////////////////////////////////////////////////////////// +typedef int TThostFtdcServerPortType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcRepealedTimesTypeһѾ +///////////////////////////////////////////////////////////////////////// +typedef int TThostFtdcRepealedTimesType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcRepealTimeIntervalTypeһʱ +///////////////////////////////////////////////////////////////////////// +typedef int TThostFtdcRepealTimeIntervalType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcTotalTimesTypeһÿۼתʴ +///////////////////////////////////////////////////////////////////////// +typedef int TThostFtdcTotalTimesType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcFBTRequestIDTypeһID +///////////////////////////////////////////////////////////////////////// +typedef int TThostFtdcFBTRequestIDType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcTIDTypeһID +///////////////////////////////////////////////////////////////////////// +typedef int TThostFtdcTIDType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcTradeAmountTypeһ׽Ԫ +///////////////////////////////////////////////////////////////////////// +typedef double TThostFtdcTradeAmountType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcCustFeeTypeһӦտͻãԪ +///////////////////////////////////////////////////////////////////////// +typedef double TThostFtdcCustFeeType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcFutureFeeTypeһӦڻ˾ãԪ +///////////////////////////////////////////////////////////////////////// +typedef double TThostFtdcFutureFeeType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcSingleMaxAmtTypeһ޶ +///////////////////////////////////////////////////////////////////////// +typedef double TThostFtdcSingleMaxAmtType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcSingleMinAmtTypeһ޶ +///////////////////////////////////////////////////////////////////////// +typedef double TThostFtdcSingleMinAmtType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcTotalAmtTypeһÿۼתʶ +///////////////////////////////////////////////////////////////////////// +typedef double TThostFtdcTotalAmtType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcCertificationTypeTypeһ֤ +///////////////////////////////////////////////////////////////////////// +///֤ +#define THOST_FTDC_CFT_IDCard '0' +/// +#define THOST_FTDC_CFT_Passport '1' +///֤ +#define THOST_FTDC_CFT_OfficerIDCard '2' +///ʿ֤ +#define THOST_FTDC_CFT_SoldierIDCard '3' +///֤ +#define THOST_FTDC_CFT_HomeComingCard '4' +///ڲ +#define THOST_FTDC_CFT_HouseholdRegister '5' +///Ӫҵִպ +#define THOST_FTDC_CFT_LicenseNo '6' +///֤֯ +#define THOST_FTDC_CFT_InstitutionCodeCard '7' +///ʱӪҵִպ +#define THOST_FTDC_CFT_TempLicenseNo '8' +///ҵǼ֤ +#define THOST_FTDC_CFT_NoEnterpriseLicenseNo '9' +///֤ +#define THOST_FTDC_CFT_OtherCard 'x' +///ܲ +#define THOST_FTDC_CFT_SuperDepAgree 'a' + +typedef char TThostFtdcCertificationTypeType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcFileBusinessCodeTypeһļҵ +///////////////////////////////////////////////////////////////////////// +/// +#define THOST_FTDC_FBC_Others '0' +///ת˽ϸ +#define THOST_FTDC_FBC_TransferDetails '1' +///ͻ˻״̬ +#define THOST_FTDC_FBC_CustAccStatus '2' +///˻ཻϸ +#define THOST_FTDC_FBC_AccountTradeDetails '3' +///ڻ˻Ϣϸ +#define THOST_FTDC_FBC_FutureAccountChangeInfoDetails '4' +///ͻʽ̨ϸ +#define THOST_FTDC_FBC_CustMoneyDetail '5' +///ͻϢϸ +#define THOST_FTDC_FBC_CustCancelAccountInfo '6' +///ͻʽ˽ +#define THOST_FTDC_FBC_CustMoneyResult '7' +///쳣ļ +#define THOST_FTDC_FBC_OthersExceptionResult '8' +///ͻϢϸ +#define THOST_FTDC_FBC_CustInterestNetMoneyDetails '9' +///ͻʽϸ +#define THOST_FTDC_FBC_CustMoneySendAndReceiveDetails 'a' +///˴ʽջ +#define THOST_FTDC_FBC_CorporationMoneyTotal 'b' +///ʽջ +#define THOST_FTDC_FBC_MainbodyMoneyTotal 'c' +///ܷƽ +#define THOST_FTDC_FBC_MainPartMonitorData 'd' +///б +#define THOST_FTDC_FBC_PreparationMoney 'e' +///Эʽ +#define THOST_FTDC_FBC_BankMoneyMonitorData 'f' + +typedef char TThostFtdcFileBusinessCodeType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcCashExchangeCodeTypeһ㳮־ +///////////////////////////////////////////////////////////////////////// +/// +#define THOST_FTDC_CEC_Exchange '1' +/// +#define THOST_FTDC_CEC_Cash '2' + +typedef char TThostFtdcCashExchangeCodeType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcYesNoIndicatorTypeһǻʶ +///////////////////////////////////////////////////////////////////////// +/// +#define THOST_FTDC_YNI_Yes '0' +/// +#define THOST_FTDC_YNI_No '1' + +typedef char TThostFtdcYesNoIndicatorType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcBanlanceTypeTypeһ +///////////////////////////////////////////////////////////////////////// +///ǰ +#define THOST_FTDC_BLT_CurrentMoney '0' +/// +#define THOST_FTDC_BLT_UsableMoney '1' +///ȡ +#define THOST_FTDC_BLT_FetchableMoney '2' +/// +#define THOST_FTDC_BLT_FreezeMoney '3' + +typedef char TThostFtdcBanlanceTypeType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcGenderTypeһԱ +///////////////////////////////////////////////////////////////////////// +///δ֪״̬ +#define THOST_FTDC_GD_Unknown '0' +/// +#define THOST_FTDC_GD_Male '1' +///Ů +#define THOST_FTDC_GD_Female '2' + +typedef char TThostFtdcGenderType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcFeePayFlagTypeһ֧־ +///////////////////////////////////////////////////////////////////////// +///淽֧ +#define THOST_FTDC_FPF_BEN '0' +///ɷͷ֧ +#define THOST_FTDC_FPF_OUR '1' +///ɷͷ֧ķã淽֧ܵķ +#define THOST_FTDC_FPF_SHA '2' + +typedef char TThostFtdcFeePayFlagType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcPassWordKeyTypeTypeһԿ +///////////////////////////////////////////////////////////////////////// +///Կ +#define THOST_FTDC_PWKT_ExchangeKey '0' +///Կ +#define THOST_FTDC_PWKT_PassWordKey '1' +/// MACԿ +#define THOST_FTDC_PWKT_MACKey '2' +///Կ +#define THOST_FTDC_PWKT_MessageKey '3' + +typedef char TThostFtdcPassWordKeyTypeType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcFBTPassWordTypeTypeһ +///////////////////////////////////////////////////////////////////////// +///ѯ +#define THOST_FTDC_PWT_Query '0' +///ȡ +#define THOST_FTDC_PWT_Fetch '1' +///ת +#define THOST_FTDC_PWT_Transfer '2' +/// +#define THOST_FTDC_PWT_Trade '3' + +typedef char TThostFtdcFBTPassWordTypeType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcFBTEncryModeTypeһܷʽ +///////////////////////////////////////////////////////////////////////// +/// +#define THOST_FTDC_EM_NoEncry '0' +/// DES +#define THOST_FTDC_EM_DES '1' +/// 3DES +#define THOST_FTDC_EM_3DES '2' + +typedef char TThostFtdcFBTEncryModeType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcBankRepealFlagTypeһг־ +///////////////////////////////////////////////////////////////////////// +///Զ +#define THOST_FTDC_BRF_BankNotNeedRepeal '0' +///дԶ +#define THOST_FTDC_BRF_BankWaitingRepeal '1' +///Զ +#define THOST_FTDC_BRF_BankBeenRepealed '2' + +typedef char TThostFtdcBankRepealFlagType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcBrokerRepealFlagTypeһ̳־ +///////////////////////////////////////////////////////////////////////// +///Զ +#define THOST_FTDC_BRORF_BrokerNotNeedRepeal '0' +///̴Զ +#define THOST_FTDC_BRORF_BrokerWaitingRepeal '1' +///Զ +#define THOST_FTDC_BRORF_BrokerBeenRepealed '2' + +typedef char TThostFtdcBrokerRepealFlagType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcInstitutionTypeTypeһ +///////////////////////////////////////////////////////////////////////// +/// +#define THOST_FTDC_TS_Bank '0' +/// +#define THOST_FTDC_TS_Future '1' +///ȯ +#define THOST_FTDC_TS_Store '2' + +typedef char TThostFtdcInstitutionTypeType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcLastFragmentTypeһƬ־ +///////////////////////////////////////////////////////////////////////// +///Ƭ +#define THOST_FTDC_LF_Yes '0' +///Ƭ +#define THOST_FTDC_LF_No '1' + +typedef char TThostFtdcLastFragmentType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcBankAccStatusTypeһ˻״̬ +///////////////////////////////////////////////////////////////////////// +/// +#define THOST_FTDC_BAS_Normal '0' +/// +#define THOST_FTDC_BAS_Freeze '1' +///ʧ +#define THOST_FTDC_BAS_ReportLoss '2' + +typedef char TThostFtdcBankAccStatusType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcMoneyAccountStatusTypeһʽ˻״̬ +///////////////////////////////////////////////////////////////////////// +/// +#define THOST_FTDC_MAS_Normal '0' +/// +#define THOST_FTDC_MAS_Cancel '1' + +typedef char TThostFtdcMoneyAccountStatusType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcManageStatusTypeһ״̬ +///////////////////////////////////////////////////////////////////////// +///ָ +#define THOST_FTDC_MSS_Point '0' +///Ԥָ +#define THOST_FTDC_MSS_PrePoint '1' +///ָ +#define THOST_FTDC_MSS_CancelPoint '2' + +typedef char TThostFtdcManageStatusType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcSystemTypeTypeһӦϵͳ +///////////////////////////////////////////////////////////////////////// +///ת +#define THOST_FTDC_SYT_FutureBankTransfer '0' +///֤ת +#define THOST_FTDC_SYT_StockBankTransfer '1' +/// +#define THOST_FTDC_SYT_TheThirdPartStore '2' + +typedef char TThostFtdcSystemTypeType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcTxnEndFlagTypeһתʻת־ +///////////////////////////////////////////////////////////////////////// +/// +#define THOST_FTDC_TEF_NormalProcessing '0' +///ɹ +#define THOST_FTDC_TEF_Success '1' +///ʧܽ +#define THOST_FTDC_TEF_Failed '2' +///쳣 +#define THOST_FTDC_TEF_Abnormal '3' +///˹쳣 +#define THOST_FTDC_TEF_ManualProcessedForException '4' +///ͨѶ쳣 ˹ +#define THOST_FTDC_TEF_CommuFailedNeedManualProcess '5' +///ϵͳ˹ +#define THOST_FTDC_TEF_SysErrorNeedManualProcess '6' + +typedef char TThostFtdcTxnEndFlagType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcProcessStatusTypeһתʷ״̬ +///////////////////////////////////////////////////////////////////////// +///δ +#define THOST_FTDC_PSS_NotProcess '0' +///ʼ +#define THOST_FTDC_PSS_StartProcess '1' +/// +#define THOST_FTDC_PSS_Finished '2' + +typedef char TThostFtdcProcessStatusType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcCustTypeTypeһͻ +///////////////////////////////////////////////////////////////////////// +///Ȼ +#define THOST_FTDC_CUSTT_Person '0' +/// +#define THOST_FTDC_CUSTT_Institution '1' + +typedef char TThostFtdcCustTypeType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcFBTTransferDirectionTypeһתʷ +///////////////////////////////////////////////////////////////////////// +///תڻ +#define THOST_FTDC_FBTTD_FromBankToFuture '1' +///ڻת +#define THOST_FTDC_FBTTD_FromFutureToBank '2' + +typedef char TThostFtdcFBTTransferDirectionType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcOpenOrDestroyTypeһ +///////////////////////////////////////////////////////////////////////// +/// +#define THOST_FTDC_OOD_Open '1' +/// +#define THOST_FTDC_OOD_Destroy '0' + +typedef char TThostFtdcOpenOrDestroyType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcAvailabilityFlagTypeһЧ־ +///////////////////////////////////////////////////////////////////////// +///δȷ +#define THOST_FTDC_AVAF_Invalid '0' +///Ч +#define THOST_FTDC_AVAF_Valid '1' +/// +#define THOST_FTDC_AVAF_Repeal '2' + +typedef char TThostFtdcAvailabilityFlagType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcOrganTypeTypeһ +///////////////////////////////////////////////////////////////////////// +///д +#define THOST_FTDC_OT_Bank '1' +///ǰ +#define THOST_FTDC_OT_Future '2' +///תƽ̨ +#define THOST_FTDC_OT_PlateForm '9' + +typedef char TThostFtdcOrganTypeType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcOrganLevelTypeһ +///////////////////////////////////////////////////////////////////////// +///лܲ +#define THOST_FTDC_OL_HeadQuarters '1' +///зĻڻ˾Ӫҵ +#define THOST_FTDC_OL_Branch '2' + +typedef char TThostFtdcOrganLevelType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcProtocalIDTypeһЭ +///////////////////////////////////////////////////////////////////////// +///Э +#define THOST_FTDC_PID_FutureProtocal '0' +///Э +#define THOST_FTDC_PID_ICBCProtocal '1' +///ũЭ +#define THOST_FTDC_PID_ABCProtocal '2' +///йЭ +#define THOST_FTDC_PID_CBCProtocal '3' +///Э +#define THOST_FTDC_PID_CCBProtocal '4' +///Э +#define THOST_FTDC_PID_BOCOMProtocal '5' +///תƽ̨Э +#define THOST_FTDC_PID_FBTPlateFormProtocal 'X' + +typedef char TThostFtdcProtocalIDType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcConnectModeTypeһ׽ӷʽ +///////////////////////////////////////////////////////////////////////// +/// +#define THOST_FTDC_CM_ShortConnect '0' +/// +#define THOST_FTDC_CM_LongConnect '1' + +typedef char TThostFtdcConnectModeType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcSyncModeTypeһ׽ͨŷʽ +///////////////////////////////////////////////////////////////////////// +///첽 +#define THOST_FTDC_SRM_ASync '0' +///ͬ +#define THOST_FTDC_SRM_Sync '1' + +typedef char TThostFtdcSyncModeType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcBankAccTypeTypeһʺ +///////////////////////////////////////////////////////////////////////// +///д +#define THOST_FTDC_BAT_BankBook '1' +/// +#define THOST_FTDC_BAT_SavingCard '2' +///ÿ +#define THOST_FTDC_BAT_CreditCard '3' + +typedef char TThostFtdcBankAccTypeType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcFutureAccTypeTypeһڻ˾ʺ +///////////////////////////////////////////////////////////////////////// +///д +#define THOST_FTDC_FAT_BankBook '1' +/// +#define THOST_FTDC_FAT_SavingCard '2' +///ÿ +#define THOST_FTDC_FAT_CreditCard '3' + +typedef char TThostFtdcFutureAccTypeType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcOrganStatusTypeһ״̬ +///////////////////////////////////////////////////////////////////////// +/// +#define THOST_FTDC_OS_Ready '0' +///ǩ +#define THOST_FTDC_OS_CheckIn '1' +///ǩ +#define THOST_FTDC_OS_CheckOut '2' +///ļ +#define THOST_FTDC_OS_CheckFileArrived '3' +/// +#define THOST_FTDC_OS_CheckDetail '4' +/// +#define THOST_FTDC_OS_DayEndClean '5' +///ע +#define THOST_FTDC_OS_Invalid '9' + +typedef char TThostFtdcOrganStatusType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcCCBFeeModeTypeһշģʽ +///////////////////////////////////////////////////////////////////////// +/// +#define THOST_FTDC_CCBFM_ByAmount '1' +///¿ +#define THOST_FTDC_CCBFM_ByMonth '2' + +typedef char TThostFtdcCCBFeeModeType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcCommApiTypeTypeһͨѶAPI +///////////////////////////////////////////////////////////////////////// +///ͻ +#define THOST_FTDC_CAPIT_Client '1' +/// +#define THOST_FTDC_CAPIT_Server '2' +///ϵͳUserApi +#define THOST_FTDC_CAPIT_UserApi '3' + +typedef char TThostFtdcCommApiTypeType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcServiceIDTypeһ +///////////////////////////////////////////////////////////////////////// +typedef int TThostFtdcServiceIDType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcServiceLineNoTypeһ· +///////////////////////////////////////////////////////////////////////// +typedef int TThostFtdcServiceLineNoType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcServiceNameTypeһ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcServiceNameType[61]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcLinkStatusTypeһ״̬ +///////////////////////////////////////////////////////////////////////// +///Ѿ +#define THOST_FTDC_LS_Connected '1' +///û +#define THOST_FTDC_LS_Disconnected '2' + +typedef char TThostFtdcLinkStatusType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcCommApiPointerTypeһͨѶAPIָ +///////////////////////////////////////////////////////////////////////// +typedef int TThostFtdcCommApiPointerType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcPwdFlagTypeһ˶Ա־ +///////////////////////////////////////////////////////////////////////// +///˶ +#define THOST_FTDC_BPWDF_NoCheck '0' +///ĺ˶ +#define THOST_FTDC_BPWDF_BlankCheck '1' +///ĺ˶ +#define THOST_FTDC_BPWDF_EncryptCheck '2' + +typedef char TThostFtdcPwdFlagType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcSecuAccTypeTypeһڻʺ +///////////////////////////////////////////////////////////////////////// +///ʽʺ +#define THOST_FTDC_SAT_AccountID '1' +///ʽ𿨺 +#define THOST_FTDC_SAT_CardID '2' +///Ϻɶʺ +#define THOST_FTDC_SAT_SHStockholderID '3' +///ڹɶʺ +#define THOST_FTDC_SAT_SZStockholderID '4' + +typedef char TThostFtdcSecuAccTypeType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcTransferStatusTypeһת˽״̬ +///////////////////////////////////////////////////////////////////////// +/// +#define THOST_FTDC_TRFS_Normal '0' +/// +#define THOST_FTDC_TRFS_Repealed '1' + +typedef char TThostFtdcTransferStatusType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcSponsorTypeTypeһ +///////////////////////////////////////////////////////////////////////// +/// +#define THOST_FTDC_SPTYPE_Broker '0' +/// +#define THOST_FTDC_SPTYPE_Bank '1' + +typedef char TThostFtdcSponsorTypeType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcReqRspTypeTypeһӦ +///////////////////////////////////////////////////////////////////////// +/// +#define THOST_FTDC_REQRSP_Request '0' +///Ӧ +#define THOST_FTDC_REQRSP_Response '1' + +typedef char TThostFtdcReqRspTypeType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcFBTUserEventTypeTypeһתû¼ +///////////////////////////////////////////////////////////////////////// +///ǩ +#define THOST_FTDC_FBTUET_SignIn '0' +///תڻ +#define THOST_FTDC_FBTUET_FromBankToFuture '1' +///ڻת +#define THOST_FTDC_FBTUET_FromFutureToBank '2' +/// +#define THOST_FTDC_FBTUET_OpenAccount '3' +/// +#define THOST_FTDC_FBTUET_CancelAccount '4' +///˻ +#define THOST_FTDC_FBTUET_ChangeAccount '5' +///תڻ +#define THOST_FTDC_FBTUET_RepealFromBankToFuture '6' +///ڻת +#define THOST_FTDC_FBTUET_RepealFromFutureToBank '7' +///ѯ˻ +#define THOST_FTDC_FBTUET_QueryBankAccount '8' +///ѯڻ˻ +#define THOST_FTDC_FBTUET_QueryFutureAccount '9' +///ǩ +#define THOST_FTDC_FBTUET_SignOut 'A' +///Կͬ +#define THOST_FTDC_FBTUET_SyncKey 'B' +///ԤԼ +#define THOST_FTDC_FBTUET_ReserveOpenAccount 'C' +///ԤԼ +#define THOST_FTDC_FBTUET_CancelReserveOpenAccount 'D' +///ԤԼȷ +#define THOST_FTDC_FBTUET_ReserveOpenAccountConfirm 'E' +/// +#define THOST_FTDC_FBTUET_Other 'Z' + +typedef char TThostFtdcFBTUserEventTypeType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcBankIDByBankTypeһԼı +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcBankIDByBankType[21]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcBankOperNoTypeһвԱ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcBankOperNoType[4]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcBankCustNoTypeһпͻ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcBankCustNoType[21]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcDBOPSeqNoTypeһк +///////////////////////////////////////////////////////////////////////// +typedef int TThostFtdcDBOPSeqNoType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcTableNameTypeһFBT +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcTableNameType[61]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcPKNameTypeһFBT +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcPKNameType[201]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcPKValueTypeһFBTֵ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcPKValueType[501]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcDBOperationTypeһ¼ +///////////////////////////////////////////////////////////////////////// +/// +#define THOST_FTDC_DBOP_Insert '0' +/// +#define THOST_FTDC_DBOP_Update '1' +///ɾ +#define THOST_FTDC_DBOP_Delete '2' + +typedef char TThostFtdcDBOperationType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcSyncFlagTypeһͬ +///////////////////////////////////////////////////////////////////////// +///ͬ +#define THOST_FTDC_SYNF_Yes '0' +///δͬ +#define THOST_FTDC_SYNF_No '1' + +typedef char TThostFtdcSyncFlagType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcTargetIDTypeһͬĿ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcTargetIDType[4]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcSyncTypeTypeһͬ +///////////////////////////////////////////////////////////////////////// +///һͬ +#define THOST_FTDC_SYNT_OneOffSync '0' +///ʱͬ +#define THOST_FTDC_SYNT_TimerSync '1' +///ʱȫͬ +#define THOST_FTDC_SYNT_TimerFullSync '2' + +typedef char TThostFtdcSyncTypeType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcFBETimeTypeһֻʱ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcFBETimeType[7]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcFBEBankNoTypeһк +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcFBEBankNoType[13]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcFBECertNoTypeһƾ֤ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcFBECertNoType[13]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcExDirectionTypeһ㷽 +///////////////////////////////////////////////////////////////////////// +/// +#define THOST_FTDC_FBEDIR_Settlement '0' +///ۻ +#define THOST_FTDC_FBEDIR_Sale '1' + +typedef char TThostFtdcExDirectionType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcFBEBankAccountTypeһ˻ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcFBEBankAccountType[33]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcFBEBankAccountNameTypeһ˻ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcFBEBankAccountNameType[61]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcFBEAmtTypeһֻ +///////////////////////////////////////////////////////////////////////// +typedef double TThostFtdcFBEAmtType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcFBEBusinessTypeTypeһҵ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcFBEBusinessTypeType[3]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcFBEPostScriptTypeһ㸽 +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcFBEPostScriptType[61]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcFBERemarkTypeһ㱸ע +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcFBERemarkType[71]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcExRateTypeһ +///////////////////////////////////////////////////////////////////////// +typedef double TThostFtdcExRateType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcFBEResultFlagTypeһɹ־ +///////////////////////////////////////////////////////////////////////// +///ɹ +#define THOST_FTDC_FBERES_Success '0' +///˻ +#define THOST_FTDC_FBERES_InsufficientBalance '1' +///׽δ֪ +#define THOST_FTDC_FBERES_UnknownTrading '8' +///ʧ +#define THOST_FTDC_FBERES_Fail 'x' + +typedef char TThostFtdcFBEResultFlagType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcFBERtnMsgTypeһ㷵Ϣ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcFBERtnMsgType[61]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcFBEExtendMsgTypeһչϢ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcFBEExtendMsgType[61]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcFBEBusinessSerialTypeһˮ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcFBEBusinessSerialType[31]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcFBESystemSerialTypeһˮ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcFBESystemSerialType[21]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcFBETotalExCntTypeһ㽻ܱ +///////////////////////////////////////////////////////////////////////// +typedef int TThostFtdcFBETotalExCntType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcFBEExchStatusTypeһ㽻״̬ +///////////////////////////////////////////////////////////////////////// +/// +#define THOST_FTDC_FBEES_Normal '0' +///ط +#define THOST_FTDC_FBEES_ReExchange '1' + +typedef char TThostFtdcFBEExchStatusType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcFBEFileFlagTypeһļ־ +///////////////////////////////////////////////////////////////////////// +///ݰ +#define THOST_FTDC_FBEFG_DataPackage '0' +///ļ +#define THOST_FTDC_FBEFG_File '1' + +typedef char TThostFtdcFBEFileFlagType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcFBEAlreadyTradeTypeһѽױ־ +///////////////////////////////////////////////////////////////////////// +///δ +#define THOST_FTDC_FBEAT_NotTrade '0' +///ѽ +#define THOST_FTDC_FBEAT_Trade '1' + +typedef char TThostFtdcFBEAlreadyTradeType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcFBEOpenBankTypeһ˻ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcFBEOpenBankType[61]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcFBEUserEventTypeTypeһڻû¼ +///////////////////////////////////////////////////////////////////////// +///ǩ +#define THOST_FTDC_FBEUET_SignIn '0' +/// +#define THOST_FTDC_FBEUET_Exchange '1' +///ط +#define THOST_FTDC_FBEUET_ReExchange '2' +///˻ѯ +#define THOST_FTDC_FBEUET_QueryBankAccount '3' +///ϸѯ +#define THOST_FTDC_FBEUET_QueryExchDetial '4' +///ܲѯ +#define THOST_FTDC_FBEUET_QueryExchSummary '5' +///ʲѯ +#define THOST_FTDC_FBEUET_QueryExchRate '6' +///ļ֪ͨ +#define THOST_FTDC_FBEUET_CheckBankAccount '7' +///ǩ +#define THOST_FTDC_FBEUET_SignOut '8' +/// +#define THOST_FTDC_FBEUET_Other 'Z' + +typedef char TThostFtdcFBEUserEventTypeType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcFBEFileNameTypeһļ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcFBEFileNameType[21]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcFBEBatchSerialTypeһκ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcFBEBatchSerialType[21]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcFBEReqFlagTypeһ㷢ͱ־ +///////////////////////////////////////////////////////////////////////// +///δ +#define THOST_FTDC_FBERF_UnProcessed '0' +///ȴ +#define THOST_FTDC_FBERF_WaitSend '1' +///ͳɹ +#define THOST_FTDC_FBERF_SendSuccess '2' +///ʧ +#define THOST_FTDC_FBERF_SendFailed '3' +///ȴط +#define THOST_FTDC_FBERF_WaitReSend '4' + +typedef char TThostFtdcFBEReqFlagType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcNotifyClassTypeһ֪ͨ +///////////////////////////////////////////////////////////////////////// +/// +#define THOST_FTDC_NC_NOERROR '0' +///ʾ +#define THOST_FTDC_NC_Warn '1' +///׷ +#define THOST_FTDC_NC_Call '2' +///ǿƽ +#define THOST_FTDC_NC_Force '3' +/// +#define THOST_FTDC_NC_CHUANCANG '4' +///쳣 +#define THOST_FTDC_NC_Exception '5' + +typedef char TThostFtdcNotifyClassType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcRiskNofityInfoTypeһͻ֪ͨϢ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcRiskNofityInfoType[257]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcForceCloseSceneIdTypeһǿƽ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcForceCloseSceneIdType[24]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcForceCloseTypeTypeһǿƽ +///////////////////////////////////////////////////////////////////////// +///ֹǿƽ +#define THOST_FTDC_FCT_Manual '0' +///һͶ߸ǿƽ +#define THOST_FTDC_FCT_Single '1' +///Ͷ߸ǿƽ +#define THOST_FTDC_FCT_Group '2' + +typedef char TThostFtdcForceCloseTypeType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcInstrumentIDsTypeһƷ,+ָ,cu+zn +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcInstrumentIDsType[101]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcRiskNotifyMethodTypeһ֪ͨ; +///////////////////////////////////////////////////////////////////////// +///ϵͳ֪ͨ +#define THOST_FTDC_RNM_System '0' +///֪ͨ +#define THOST_FTDC_RNM_SMS '1' +///ʼ֪ͨ +#define THOST_FTDC_RNM_EMail '2' +///˹֪ͨ +#define THOST_FTDC_RNM_Manual '3' + +typedef char TThostFtdcRiskNotifyMethodType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcRiskNotifyStatusTypeһ֪ͨ״̬ +///////////////////////////////////////////////////////////////////////// +///δ +#define THOST_FTDC_RNS_NotGen '0' +///δ +#define THOST_FTDC_RNS_Generated '1' +///ʧ +#define THOST_FTDC_RNS_SendError '2' +///ѷδ +#define THOST_FTDC_RNS_SendOk '3' +///ѽδȷ +#define THOST_FTDC_RNS_Received '4' +///ȷ +#define THOST_FTDC_RNS_Confirmed '5' + +typedef char TThostFtdcRiskNotifyStatusType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcRiskUserEventTypeһû¼ +///////////////////////////////////////////////////////////////////////// +/// +#define THOST_FTDC_RUE_ExportData '0' + +typedef char TThostFtdcRiskUserEventType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcParamIDTypeһ +///////////////////////////////////////////////////////////////////////// +typedef int TThostFtdcParamIDType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcParamNameTypeһ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcParamNameType[41]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcParamValueTypeһֵ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcParamValueType[41]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcConditionalOrderSortTypeTypeһ +///////////////////////////////////////////////////////////////////////// +///ʹ¼ +#define THOST_FTDC_COST_LastPriceAsc '0' +///ʹ¼۽ +#define THOST_FTDC_COST_LastPriceDesc '1' +///ʹ +#define THOST_FTDC_COST_AskPriceAsc '2' +///ʹ۽ +#define THOST_FTDC_COST_AskPriceDesc '3' +///ʹ +#define THOST_FTDC_COST_BidPriceAsc '4' +///ʹ۽ +#define THOST_FTDC_COST_BidPriceDesc '5' + +typedef char TThostFtdcConditionalOrderSortTypeType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcSendTypeTypeһ״̬ +///////////////////////////////////////////////////////////////////////// +///δ +#define THOST_FTDC_UOAST_NoSend '0' +///ѷ +#define THOST_FTDC_UOAST_Sended '1' +/// +#define THOST_FTDC_UOAST_Generated '2' +///ʧ +#define THOST_FTDC_UOAST_SendFail '3' +///ճɹ +#define THOST_FTDC_UOAST_Success '4' +///ʧ +#define THOST_FTDC_UOAST_Fail '5' +///ȡ +#define THOST_FTDC_UOAST_Cancel '6' + +typedef char TThostFtdcSendTypeType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcClientIDStatusTypeһױ״̬ +///////////////////////////////////////////////////////////////////////// +///δ +#define THOST_FTDC_UOACS_NoApply '1' +///ύ +#define THOST_FTDC_UOACS_Submited '2' +///ѷ +#define THOST_FTDC_UOACS_Sended '3' +/// +#define THOST_FTDC_UOACS_Success '4' +///ܾ +#define THOST_FTDC_UOACS_Refuse '5' +///ѳ +#define THOST_FTDC_UOACS_Cancel '6' + +typedef char TThostFtdcClientIDStatusType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcIndustryIDTypeһҵ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcIndustryIDType[17]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcQuestionIDTypeһϢ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcQuestionIDType[5]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcQuestionContentTypeһϢ˵ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcQuestionContentType[41]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcOptionIDTypeһѡ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcOptionIDType[13]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcOptionContentTypeһѡ˵ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcOptionContentType[61]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcQuestionTypeTypeһϢ +///////////////////////////////////////////////////////////////////////// +///ѡ +#define THOST_FTDC_QT_Radio '1' +///ѡ +#define THOST_FTDC_QT_Option '2' +/// +#define THOST_FTDC_QT_Blank '3' + +typedef char TThostFtdcQuestionTypeType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcProcessIDTypeһҵˮ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcProcessIDType[33]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcSeqNoTypeһˮ +///////////////////////////////////////////////////////////////////////// +typedef int TThostFtdcSeqNoType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcUOAProcessStatusTypeһ״̬ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcUOAProcessStatusType[3]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcProcessTypeTypeһ̹ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcProcessTypeType[3]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcBusinessTypeTypeһҵ +///////////////////////////////////////////////////////////////////////// +/// +#define THOST_FTDC_BT_Request '1' +///Ӧ +#define THOST_FTDC_BT_Response '2' +///֪ͨ +#define THOST_FTDC_BT_Notice '3' + +typedef char TThostFtdcBusinessTypeType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcCfmmcReturnCodeTypeһķ +///////////////////////////////////////////////////////////////////////// +///ɹ +#define THOST_FTDC_CRC_Success '0' +///ÿͻѾڴ +#define THOST_FTDC_CRC_Working '1' +///пͻϼʧ +#define THOST_FTDC_CRC_InfoFail '2' +///ʵƼʧ +#define THOST_FTDC_CRC_IDCardFail '3' +/// +#define THOST_FTDC_CRC_OtherFail '4' + +typedef char TThostFtdcCfmmcReturnCodeType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcExReturnCodeTypeһ +///////////////////////////////////////////////////////////////////////// +typedef int TThostFtdcExReturnCodeType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcClientTypeTypeһͻ +///////////////////////////////////////////////////////////////////////// +/// +#define THOST_FTDC_CfMMCCT_All '0' +/// +#define THOST_FTDC_CfMMCCT_Person '1' +///λ +#define THOST_FTDC_CfMMCCT_Company '2' +/// +#define THOST_FTDC_CfMMCCT_Other '3' +///ⷨ +#define THOST_FTDC_CfMMCCT_SpecialOrgan '4' +///ʹܻ +#define THOST_FTDC_CfMMCCT_Asset '5' + +typedef char TThostFtdcClientTypeType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcExchangeIDTypeTypeһ +///////////////////////////////////////////////////////////////////////// +///Ϻڻ +#define THOST_FTDC_EIDT_SHFE 'S' +///֣Ʒ +#define THOST_FTDC_EIDT_CZCE 'Z' +///Ʒ +#define THOST_FTDC_EIDT_DCE 'D' +///йڻ +#define THOST_FTDC_EIDT_CFFEX 'J' +///ϺԴĹɷ޹˾ +#define THOST_FTDC_EIDT_INE 'N' + +typedef char TThostFtdcExchangeIDTypeType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcExClientIDTypeTypeһױ +///////////////////////////////////////////////////////////////////////// +///ױ +#define THOST_FTDC_ECIDT_Hedge '1' +/// +#define THOST_FTDC_ECIDT_Arbitrage '2' +///Ͷ +#define THOST_FTDC_ECIDT_Speculation '3' + +typedef char TThostFtdcExClientIDTypeType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcClientClassifyTypeһͻ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcClientClassifyType[11]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcUOAOrganTypeTypeһλ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcUOAOrganTypeType[11]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcUOACountryCodeTypeһҴ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcUOACountryCodeType[11]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcAreaCodeTypeһ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcAreaCodeType[11]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcFuturesIDTypeһΪͻĴ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcFuturesIDType[21]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcCffmcDateTypeһ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcCffmcDateType[11]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcCffmcTimeTypeһʱ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcCffmcTimeType[11]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcNocIDTypeһ֯ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcNocIDType[21]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcUpdateFlagTypeһ״̬ +///////////////////////////////////////////////////////////////////////// +///δ +#define THOST_FTDC_UF_NoUpdate '0' +///ȫϢɹ +#define THOST_FTDC_UF_Success '1' +///ȫϢʧ +#define THOST_FTDC_UF_Fail '2' +///½ױɹ +#define THOST_FTDC_UF_TCSuccess '3' +///½ױʧ +#define THOST_FTDC_UF_TCFail '4' +///Ѷ +#define THOST_FTDC_UF_Cancel '5' + +typedef char TThostFtdcUpdateFlagType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcApplyOperateIDTypeһ붯 +///////////////////////////////////////////////////////////////////////// +/// +#define THOST_FTDC_AOID_OpenInvestor '1' +///޸Ϣ +#define THOST_FTDC_AOID_ModifyIDCard '2' +///޸һϢ +#define THOST_FTDC_AOID_ModifyNoIDCard '3' +///뽻ױ +#define THOST_FTDC_AOID_ApplyTradingCode '4' +///ױ +#define THOST_FTDC_AOID_CancelTradingCode '5' +/// +#define THOST_FTDC_AOID_CancelInvestor '6' +///˻ +#define THOST_FTDC_AOID_FreezeAccount '8' +///˻ +#define THOST_FTDC_AOID_ActiveFreezeAccount '9' + +typedef char TThostFtdcApplyOperateIDType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcApplyStatusIDTypeһ״̬ +///////////////////////////////////////////////////////////////////////// +///δȫ +#define THOST_FTDC_ASID_NoComplete '1' +///ύ +#define THOST_FTDC_ASID_Submited '2' +/// +#define THOST_FTDC_ASID_Checked '3' +///Ѿܾ +#define THOST_FTDC_ASID_Refused '4' +///ɾ +#define THOST_FTDC_ASID_Deleted '5' + +typedef char TThostFtdcApplyStatusIDType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcSendMethodTypeһͷʽ +///////////////////////////////////////////////////////////////////////// +///ļ +#define THOST_FTDC_UOASM_ByAPI '1' +///ӷ +#define THOST_FTDC_UOASM_ByFile '2' + +typedef char TThostFtdcSendMethodType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcEventTypeTypeһҵ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcEventTypeType[33]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcEventModeTypeһ +///////////////////////////////////////////////////////////////////////// +/// +#define THOST_FTDC_EvM_ADD '1' +///޸ +#define THOST_FTDC_EvM_UPDATE '2' +///ɾ +#define THOST_FTDC_EvM_DELETE '3' +/// +#define THOST_FTDC_EvM_CHECK '4' +/// +#define THOST_FTDC_EvM_COPY '5' +///ע +#define THOST_FTDC_EvM_CANCEL '6' +/// +#define THOST_FTDC_EvM_Reverse '7' + +typedef char TThostFtdcEventModeType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcUOAAutoSendTypeһͳһԶ +///////////////////////////////////////////////////////////////////////// +///ԶͲ +#define THOST_FTDC_UOAA_ASR '1' +///ԶͣԶ +#define THOST_FTDC_UOAA_ASNR '2' +///ԶͣԶ +#define THOST_FTDC_UOAA_NSAR '3' +///ԶͣҲԶ +#define THOST_FTDC_UOAA_NSR '4' + +typedef char TThostFtdcUOAAutoSendType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcQueryDepthTypeһѯ +///////////////////////////////////////////////////////////////////////// +typedef int TThostFtdcQueryDepthType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcDataCenterIDTypeһĴ +///////////////////////////////////////////////////////////////////////// +typedef int TThostFtdcDataCenterIDType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcFlowIDTypeһID +///////////////////////////////////////////////////////////////////////// +///Ͷ߶ӦͶ +#define THOST_FTDC_EvM_InvestorGroupFlow '1' +///Ͷ +#define THOST_FTDC_EvM_InvestorRate '2' +///Ͷģϵ +#define THOST_FTDC_EvM_InvestorCommRateModel '3' + +typedef char TThostFtdcFlowIDType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcCheckLevelTypeһ˼ +///////////////////////////////////////////////////////////////////////// +///㼶 +#define THOST_FTDC_CL_Zero '0' +///һ +#define THOST_FTDC_CL_One '1' +/// +#define THOST_FTDC_CL_Two '2' + +typedef char TThostFtdcCheckLevelType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcCheckNoTypeһ +///////////////////////////////////////////////////////////////////////// +typedef int TThostFtdcCheckNoType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcCheckStatusTypeһ˼ +///////////////////////////////////////////////////////////////////////// +///δ +#define THOST_FTDC_CHS_Init '0' +/// +#define THOST_FTDC_CHS_Checking '1' +///Ѹ +#define THOST_FTDC_CHS_Checked '2' +///ܾ +#define THOST_FTDC_CHS_Refuse '3' +/// +#define THOST_FTDC_CHS_Cancel '4' + +typedef char TThostFtdcCheckStatusType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcUsedStatusTypeһЧ״̬ +///////////////////////////////////////////////////////////////////////// +///δЧ +#define THOST_FTDC_CHU_Unused '0' +///Ч +#define THOST_FTDC_CHU_Used '1' +///Чʧ +#define THOST_FTDC_CHU_Fail '2' + +typedef char TThostFtdcUsedStatusType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcRateTemplateNameTypeһģ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcRateTemplateNameType[61]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcPropertyStringTypeһڲѯͶֶ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcPropertyStringType[2049]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcBankAcountOriginTypeһ˻Դ +///////////////////////////////////////////////////////////////////////// +///ֹ¼ +#define THOST_FTDC_BAO_ByAccProperty '0' +///ת +#define THOST_FTDC_BAO_ByFBTransfer '1' + +typedef char TThostFtdcBankAcountOriginType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcMonthBillTradeSumTypeһ㵥±ɽܷʽ +///////////////////////////////////////////////////////////////////////// +///ͬͬԼ +#define THOST_FTDC_MBTS_ByInstrument '0' +///ͬͬԼͬ۸ +#define THOST_FTDC_MBTS_ByDayInsPrc '1' +///ͬԼ +#define THOST_FTDC_MBTS_ByDayIns '2' + +typedef char TThostFtdcMonthBillTradeSumType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcFBTTradeCodeEnumTypeһڽ״ö +///////////////////////////////////////////////////////////////////////// +///зתڻ +#define THOST_FTDC_FTC_BankLaunchBankToBroker '102001' +///ڻתڻ +#define THOST_FTDC_FTC_BrokerLaunchBankToBroker '202001' +///зڻת +#define THOST_FTDC_FTC_BankLaunchBrokerToBank '102002' +///ڻڻת +#define THOST_FTDC_FTC_BrokerLaunchBrokerToBank '202002' + +typedef char TThostFtdcFBTTradeCodeEnumType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcRateTemplateIDTypeһģʹ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcRateTemplateIDType[9]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcRiskRateTypeһն +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcRiskRateType[21]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcTimestampTypeһʱ +///////////////////////////////////////////////////////////////////////// +typedef int TThostFtdcTimestampType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcInvestorIDRuleNameTypeһŶι +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcInvestorIDRuleNameType[61]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcInvestorIDRuleExprTypeһŶιʽ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcInvestorIDRuleExprType[513]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcLastDriftTypeһϴOTPƯֵ +///////////////////////////////////////////////////////////////////////// +typedef int TThostFtdcLastDriftType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcLastSuccessTypeһϴOTPɹֵ +///////////////////////////////////////////////////////////////////////// +typedef int TThostFtdcLastSuccessType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcAuthKeyTypeһԿ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcAuthKeyType[41]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcSerialNumberTypeһк +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcSerialNumberType[17]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcOTPTypeTypeһ̬ +///////////////////////////////////////////////////////////////////////// +///޶̬ +#define THOST_FTDC_OTP_NONE '0' +///ʱ +#define THOST_FTDC_OTP_TOTP '1' + +typedef char TThostFtdcOTPTypeType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcOTPVendorsIDTypeһ̬ṩ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcOTPVendorsIDType[2]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcOTPVendorsNameTypeһ̬ṩ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcOTPVendorsNameType[61]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcOTPStatusTypeһ̬״̬ +///////////////////////////////////////////////////////////////////////// +///δʹ +#define THOST_FTDC_OTPS_Unused '0' +///ʹ +#define THOST_FTDC_OTPS_Used '1' +///ע +#define THOST_FTDC_OTPS_Disuse '2' + +typedef char TThostFtdcOTPStatusType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcBrokerUserTypeTypeһù˾û +///////////////////////////////////////////////////////////////////////// +///Ͷ +#define THOST_FTDC_BUT_Investor '1' +///Ա +#define THOST_FTDC_BUT_BrokerUser '2' + +typedef char TThostFtdcBrokerUserTypeType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcFutureTypeTypeһڻ +///////////////////////////////////////////////////////////////////////// +///Ʒڻ +#define THOST_FTDC_FUTT_Commodity '1' +///ڻ +#define THOST_FTDC_FUTT_Financial '2' + +typedef char TThostFtdcFutureTypeType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcFundEventTypeTypeһʽ +///////////////////////////////////////////////////////////////////////// +///ת޶ +#define THOST_FTDC_FET_Restriction '0' +///ת޶ +#define THOST_FTDC_FET_TodayRestriction '1' +///ˮ +#define THOST_FTDC_FET_Transfer '2' +///ʽ𶳽 +#define THOST_FTDC_FET_Credit '3' +///Ͷ߿ʽ +#define THOST_FTDC_FET_InvestorWithdrawAlm '4' +///ʻת޶ +#define THOST_FTDC_FET_BankRestriction '5' +///ǩԼ˻ +#define THOST_FTDC_FET_Accountregister '6' +/// +#define THOST_FTDC_FET_ExchangeFundIO '7' +///Ͷ߳ +#define THOST_FTDC_FET_InvestorFundIO '8' + +typedef char TThostFtdcFundEventTypeType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcAccountSourceTypeTypeһʽ˻Դ +///////////////////////////////////////////////////////////////////////// +///ͬ +#define THOST_FTDC_AST_FBTransfer '0' +///ֹ¼ +#define THOST_FTDC_AST_ManualEntry '1' + +typedef char TThostFtdcAccountSourceTypeType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcCodeSourceTypeTypeһױԴ +///////////////////////////////////////////////////////////////////////// +///ͳһ(ѹ淶) +#define THOST_FTDC_CST_UnifyAccount '0' +///ֹ¼(δ淶) +#define THOST_FTDC_CST_ManualEntry '1' + +typedef char TThostFtdcCodeSourceTypeType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcUserRangeTypeһԱΧ +///////////////////////////////////////////////////////////////////////// +/// +#define THOST_FTDC_UR_All '0' +///һԱ +#define THOST_FTDC_UR_Single '1' + +typedef char TThostFtdcUserRangeType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcTimeSpanTypeһʱ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcTimeSpanType[9]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcImportSequenceIDTypeһ̬Ƶα +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcImportSequenceIDType[17]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcByGroupTypeһͳƱͻͳƷʽ +///////////////////////////////////////////////////////////////////////// +///Ͷͳ +#define THOST_FTDC_BG_Investor '2' +///ͳ +#define THOST_FTDC_BG_Group '1' + +typedef char TThostFtdcByGroupType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcTradeSumStatModeTypeһͳƱΧͳƷʽ +///////////////////////////////////////////////////////////////////////// +///Լͳ +#define THOST_FTDC_TSSM_Instrument '1' +///Ʒͳ +#define THOST_FTDC_TSSM_Product '2' +///ͳ +#define THOST_FTDC_TSSM_Exchange '3' + +typedef char TThostFtdcTradeSumStatModeType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcComTypeTypeһϳɽ +///////////////////////////////////////////////////////////////////////// +typedef int TThostFtdcComTypeType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcUserProductIDTypeһƷʶ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcUserProductIDType[33]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcUserProductNameTypeһƷ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcUserProductNameType[65]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcUserProductMemoTypeһƷ˵ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcUserProductMemoType[129]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcCSRCCancelFlagTypeһ־ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcCSRCCancelFlagType[2]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcCSRCDateTypeһ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcCSRCDateType[11]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcCSRCInvestorNameTypeһͻ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcCSRCInvestorNameType[201]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcCSRCOpenInvestorNameTypeһͻ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcCSRCOpenInvestorNameType[101]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcCSRCInvestorIDTypeһͻ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcCSRCInvestorIDType[13]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcCSRCIdentifiedCardNoTypeһ֤ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcCSRCIdentifiedCardNoType[51]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcCSRCClientIDTypeһױ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcCSRCClientIDType[11]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcCSRCBankFlagTypeһбʶ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcCSRCBankFlagType[3]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcCSRCBankAccountTypeһ˻ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcCSRCBankAccountType[23]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcCSRCOpenNameTypeһ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcCSRCOpenNameType[401]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcCSRCMemoTypeһ˵ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcCSRCMemoType[101]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcCSRCTimeTypeһʱ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcCSRCTimeType[11]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcCSRCTradeIDTypeһɽˮ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcCSRCTradeIDType[21]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcCSRCExchangeInstIDTypeһԼ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcCSRCExchangeInstIDType[31]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcCSRCMortgageNameTypeһѺƷ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcCSRCMortgageNameType[7]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcCSRCReasonTypeһ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcCSRCReasonType[3]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcIsSettlementTypeһǷΪǽԱ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcIsSettlementType[2]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcCSRCMoneyTypeһʽ +///////////////////////////////////////////////////////////////////////// +typedef double TThostFtdcCSRCMoneyType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcCSRCPriceTypeһ۸ +///////////////////////////////////////////////////////////////////////// +typedef double TThostFtdcCSRCPriceType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcCSRCOptionsTypeTypeһȨ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcCSRCOptionsTypeType[2]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcCSRCStrikePriceTypeһִм +///////////////////////////////////////////////////////////////////////// +typedef double TThostFtdcCSRCStrikePriceType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcCSRCTargetProductIDTypeһƷ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcCSRCTargetProductIDType[3]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcCSRCTargetInstrIDTypeһĺԼ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcCSRCTargetInstrIDType[31]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcCommModelNameTypeһģ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcCommModelNameType[161]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcCommModelMemoTypeһģ屸ע +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcCommModelMemoType[1025]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcExprSetModeTypeһڱʽ +///////////////////////////////////////////////////////////////////////// +///й +#define THOST_FTDC_ESM_Relative '1' +/// +#define THOST_FTDC_ESM_Typical '2' + +typedef char TThostFtdcExprSetModeType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcRateInvestorRangeTypeһͶ߷Χ +///////////////////////////////////////////////////////////////////////// +///˾׼ +#define THOST_FTDC_RIR_All '1' +///ģ +#define THOST_FTDC_RIR_Model '2' +///һͶ +#define THOST_FTDC_RIR_Single '3' + +typedef char TThostFtdcRateInvestorRangeType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcAgentBrokerIDTypeһ͹˾ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcAgentBrokerIDType[13]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcDRIdentityIDTypeһĴ +///////////////////////////////////////////////////////////////////////// +typedef int TThostFtdcDRIdentityIDType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcDRIdentityNameTypeһ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcDRIdentityNameType[65]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcDBLinkIDTypeһDBLinkʶ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcDBLinkIDType[31]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcSyncDataStatusTypeһϵͳͬ״̬ +///////////////////////////////////////////////////////////////////////// +///δͬ +#define THOST_FTDC_SDS_Initialize '0' +///ͬ +#define THOST_FTDC_SDS_Settlementing '1' +///ͬ +#define THOST_FTDC_SDS_Settlemented '2' + +typedef char TThostFtdcSyncDataStatusType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcTradeSourceTypeһɽԴ +///////////////////////////////////////////////////////////////////////// +///Խͨر +#define THOST_FTDC_TSRC_NORMAL '0' +///Բѯ +#define THOST_FTDC_TSRC_QUERY '1' + +typedef char TThostFtdcTradeSourceType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcFlexStatModeTypeһƷԼͳƷʽ +///////////////////////////////////////////////////////////////////////// +///Ʒͳ +#define THOST_FTDC_FSM_Product '1' +///ͳ +#define THOST_FTDC_FSM_Exchange '2' +///ͳ +#define THOST_FTDC_FSM_All '3' + +typedef char TThostFtdcFlexStatModeType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcByInvestorRangeTypeһͶ߷ΧͳƷʽ +///////////////////////////////////////////////////////////////////////// +///ͳ +#define THOST_FTDC_BIR_Property '1' +///ͳ +#define THOST_FTDC_BIR_All '2' + +typedef char TThostFtdcByInvestorRangeType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcSRiskRateTypeһն +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcSRiskRateType[21]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcSequenceNo12Typeһ +///////////////////////////////////////////////////////////////////////// +typedef int TThostFtdcSequenceNo12Type; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcPropertyInvestorRangeTypeһͶ߷Χ +///////////////////////////////////////////////////////////////////////// +/// +#define THOST_FTDC_PIR_All '1' +///Ͷ +#define THOST_FTDC_PIR_Property '2' +///һͶ +#define THOST_FTDC_PIR_Single '3' + +typedef char TThostFtdcPropertyInvestorRangeType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcFileStatusTypeһļ״̬ +///////////////////////////////////////////////////////////////////////// +///δ +#define THOST_FTDC_FIS_NoCreate '0' +/// +#define THOST_FTDC_FIS_Created '1' +///ʧ +#define THOST_FTDC_FIS_Failed '2' + +typedef char TThostFtdcFileStatusType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcFileGenStyleTypeһļɷʽ +///////////////////////////////////////////////////////////////////////// +///· +#define THOST_FTDC_FGS_FileTransmit '0' +/// +#define THOST_FTDC_FGS_FileGen '1' + +typedef char TThostFtdcFileGenStyleType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcSysOperModeTypeһϵͳ־ +///////////////////////////////////////////////////////////////////////// +/// +#define THOST_FTDC_SoM_Add '1' +///޸ +#define THOST_FTDC_SoM_Update '2' +///ɾ +#define THOST_FTDC_SoM_Delete '3' +/// +#define THOST_FTDC_SoM_Copy '4' +/// +#define THOST_FTDC_SoM_AcTive '5' +///ע +#define THOST_FTDC_SoM_CanCel '6' +/// +#define THOST_FTDC_SoM_ReSet '7' + +typedef char TThostFtdcSysOperModeType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcSysOperTypeTypeһϵͳ־ +///////////////////////////////////////////////////////////////////////// +///޸IJԱ +#define THOST_FTDC_SoT_UpdatePassword '0' +///Աܹ֯ϵ +#define THOST_FTDC_SoT_UserDepartment '1' +///ɫ +#define THOST_FTDC_SoT_RoleManager '2' +///ɫ +#define THOST_FTDC_SoT_RoleFunction '3' +/// +#define THOST_FTDC_SoT_BaseParam '4' +///òԱ +#define THOST_FTDC_SoT_SetUserID '5' +///ûɫ +#define THOST_FTDC_SoT_SetUserRole '6' +///ûIP +#define THOST_FTDC_SoT_UserIpRestriction '7' +///ܹ֯ +#define THOST_FTDC_SoT_DepartmentManager '8' +///ܹ֯ѯิ +#define THOST_FTDC_SoT_DepartmentCopy '9' +///ױ +#define THOST_FTDC_SoT_Tradingcode 'A' +///Ͷ״̬ά +#define THOST_FTDC_SoT_InvestorStatus 'B' +///ͶȨ޹ +#define THOST_FTDC_SoT_InvestorAuthority 'C' +/// +#define THOST_FTDC_SoT_PropertySet 'D' +///Ͷ +#define THOST_FTDC_SoT_ReSetInvestorPasswd 'E' +///Ͷ߸Ϣά +#define THOST_FTDC_SoT_InvestorPersonalityInfo 'F' + +typedef char TThostFtdcSysOperTypeType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcCSRCDataQueyTypeTypeһϱݲѯ +///////////////////////////////////////////////////////////////////////// +///ѯǰձ͵ +#define THOST_FTDC_CSRCQ_Current '0' +///ѯʷ͵Ĵ͹˾ +#define THOST_FTDC_CSRCQ_History '1' + +typedef char TThostFtdcCSRCDataQueyTypeType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcFreezeStatusTypeһ״̬ +///////////////////////////////////////////////////////////////////////// +///Ծ +#define THOST_FTDC_FRS_Normal '1' +/// +#define THOST_FTDC_FRS_Freeze '0' + +typedef char TThostFtdcFreezeStatusType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcStandardStatusTypeһ淶״̬ +///////////////////////////////////////////////////////////////////////// +///ѹ淶 +#define THOST_FTDC_STST_Standard '0' +///δ淶 +#define THOST_FTDC_STST_NonStandard '1' + +typedef char TThostFtdcStandardStatusType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcCSRCFreezeStatusTypeһ״̬ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcCSRCFreezeStatusType[2]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcRightParamTypeTypeһ +///////////////////////////////////////////////////////////////////////// +///߻ +#define THOST_FTDC_RPT_Freeze '1' +///߻ +#define THOST_FTDC_RPT_FreezeActive '2' +///Ȩ +#define THOST_FTDC_RPT_OpenLimit '3' +///Ȩ +#define THOST_FTDC_RPT_RelieveOpenLimit '4' + +typedef char TThostFtdcRightParamTypeType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcRightTemplateIDTypeһģ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcRightTemplateIDType[9]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcRightTemplateNameTypeһģ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcRightTemplateNameType[61]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcDataStatusTypeһϴǮ˱״̬ +///////////////////////////////////////////////////////////////////////// +/// +#define THOST_FTDC_AMLDS_Normal '0' +///ɾ +#define THOST_FTDC_AMLDS_Deleted '1' + +typedef char TThostFtdcDataStatusType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcAMLCheckStatusTypeһ״̬ +///////////////////////////////////////////////////////////////////////// +///δ +#define THOST_FTDC_AMLCHS_Init '0' +/// +#define THOST_FTDC_AMLCHS_Checking '1' +///Ѹ +#define THOST_FTDC_AMLCHS_Checked '2' +///ܾϱ +#define THOST_FTDC_AMLCHS_RefuseReport '3' + +typedef char TThostFtdcAMLCheckStatusType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcAmlDateTypeTypeһ +///////////////////////////////////////////////////////////////////////// +/// +#define THOST_FTDC_AMLDT_DrawDay '0' +/// +#define THOST_FTDC_AMLDT_TouchDay '1' + +typedef char TThostFtdcAmlDateTypeType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcAmlCheckLevelTypeһ˼ +///////////////////////////////////////////////////////////////////////// +///㼶 +#define THOST_FTDC_AMLCL_CheckLevel0 '0' +///һ +#define THOST_FTDC_AMLCL_CheckLevel1 '1' +/// +#define THOST_FTDC_AMLCL_CheckLevel2 '2' +/// +#define THOST_FTDC_AMLCL_CheckLevel3 '3' + +typedef char TThostFtdcAmlCheckLevelType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcAmlCheckFlowTypeһϴǮݳȡ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcAmlCheckFlowType[2]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcDataTypeTypeһ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcDataTypeType[129]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcExportFileTypeTypeһļ +///////////////////////////////////////////////////////////////////////// +/// CSV +#define THOST_FTDC_EFT_CSV '0' +/// Excel +#define THOST_FTDC_EFT_EXCEL '1' +/// DBF +#define THOST_FTDC_EFT_DBF '2' + +typedef char TThostFtdcExportFileTypeType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcSettleManagerTypeTypeһ +///////////////////////////////////////////////////////////////////////// +///ǰ׼ +#define THOST_FTDC_SMT_Before '1' +/// +#define THOST_FTDC_SMT_Settlement '2' +///˶ +#define THOST_FTDC_SMT_After '3' +/// +#define THOST_FTDC_SMT_Settlemented '4' + +typedef char TThostFtdcSettleManagerTypeType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcSettleManagerIDTypeһô +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcSettleManagerIDType[33]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcSettleManagerNameTypeһ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcSettleManagerNameType[129]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcSettleManagerLevelTypeһõȼ +///////////////////////////////////////////////////////////////////////// +///Ҫ +#define THOST_FTDC_SML_Must '1' +/// +#define THOST_FTDC_SML_Alarm '2' +///ʾ +#define THOST_FTDC_SML_Prompt '3' +/// +#define THOST_FTDC_SML_Ignore '4' + +typedef char TThostFtdcSettleManagerLevelType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcSettleManagerGroupTypeһģ +///////////////////////////////////////////////////////////////////////// +///˶ +#define THOST_FTDC_SMG_Exhcange '1' +///ڲ˶ +#define THOST_FTDC_SMG_ASP '2' +///ϱݺ˶ +#define THOST_FTDC_SMG_CSRC '3' + +typedef char TThostFtdcSettleManagerGroupType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcCheckResultMemoTypeһ˶Խ˵ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcCheckResultMemoType[1025]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcFunctionUrlTypeһ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcFunctionUrlType[1025]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcAuthInfoTypeһͻ֤Ϣ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcAuthInfoType[129]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcAuthCodeTypeһͻ֤ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcAuthCodeType[17]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcLimitUseTypeTypeһֵʹ +///////////////////////////////////////////////////////////////////////// +///ظʹ +#define THOST_FTDC_LUT_Repeatable '1' +///ظʹ +#define THOST_FTDC_LUT_Unrepeatable '2' + +typedef char TThostFtdcLimitUseTypeType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcDataResourceTypeһԴ +///////////////////////////////////////////////////////////////////////// +///ϵͳ +#define THOST_FTDC_DAR_Settle '1' +/// +#define THOST_FTDC_DAR_Exchange '2' +/// +#define THOST_FTDC_DAR_CSRC '3' + +typedef char TThostFtdcDataResourceType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcMarginTypeTypeһ֤ +///////////////////////////////////////////////////////////////////////// +///֤ +#define THOST_FTDC_MGT_ExchMarginRate '0' +///Ͷ֤߱ +#define THOST_FTDC_MGT_InstrMarginRate '1' +///Ͷ߽ױ֤ +#define THOST_FTDC_MGT_InstrMarginRateTrade '2' + +typedef char TThostFtdcMarginTypeType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcActiveTypeTypeһЧ +///////////////////////////////////////////////////////////////////////// +///Ч +#define THOST_FTDC_ACT_Intraday '1' +///Ч +#define THOST_FTDC_ACT_Long '2' + +typedef char TThostFtdcActiveTypeType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcMarginRateTypeTypeһͻ֤ +///////////////////////////////////////////////////////////////////////// +///֤ +#define THOST_FTDC_MRT_Exchange '1' +///Ͷ֤߱ +#define THOST_FTDC_MRT_Investor '2' +///Ͷ߽ױ֤ +#define THOST_FTDC_MRT_InvestorTrade '3' + +typedef char TThostFtdcMarginRateTypeType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcBackUpStatusTypeһ״̬ +///////////////////////////////////////////////////////////////////////// +///δɱ +#define THOST_FTDC_BUS_UnBak '0' +/// +#define THOST_FTDC_BUS_BakUp '1' +///ɱ +#define THOST_FTDC_BUS_BakUped '2' +///ʧ +#define THOST_FTDC_BUS_BakFail '3' + +typedef char TThostFtdcBackUpStatusType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcInitSettlementTypeһʼ״̬ +///////////////////////////////////////////////////////////////////////// +///ʼδʼ +#define THOST_FTDC_SIS_UnInitialize '0' +///ʼ +#define THOST_FTDC_SIS_Initialize '1' +///ʼ +#define THOST_FTDC_SIS_Initialized '2' + +typedef char TThostFtdcInitSettlementType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcReportStatusTypeһ״̬ +///////////////////////////////////////////////////////////////////////// +///δɱ +#define THOST_FTDC_SRS_NoCreate '0' +/// +#define THOST_FTDC_SRS_Create '1' +///ɱ +#define THOST_FTDC_SRS_Created '2' +///ɱʧ +#define THOST_FTDC_SRS_CreateFail '3' + +typedef char TThostFtdcReportStatusType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcSaveStatusTypeһݹ鵵״̬ +///////////////////////////////////////////////////////////////////////// +///鵵δ +#define THOST_FTDC_SSS_UnSaveData '0' +///鵵 +#define THOST_FTDC_SSS_SaveDatad '1' + +typedef char TThostFtdcSaveStatusType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcSettArchiveStatusTypeһȷݹ鵵״̬ +///////////////////////////////////////////////////////////////////////// +///δ鵵 +#define THOST_FTDC_SAS_UnArchived '0' +///ݹ鵵 +#define THOST_FTDC_SAS_Archiving '1' +///ѹ鵵 +#define THOST_FTDC_SAS_Archived '2' +///鵵ʧ +#define THOST_FTDC_SAS_ArchiveFail '3' + +typedef char TThostFtdcSettArchiveStatusType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcCTPTypeTypeһCTPϵͳ +///////////////////////////////////////////////////////////////////////// +///δ֪ +#define THOST_FTDC_CTPT_Unkown '0' +/// +#define THOST_FTDC_CTPT_MainCenter '1' +/// +#define THOST_FTDC_CTPT_BackUp '2' + +typedef char TThostFtdcCTPTypeType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcToolIDTypeһߴ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcToolIDType[9]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcToolNameTypeһ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcToolNameType[81]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcCloseDealTypeTypeһƽִ +///////////////////////////////////////////////////////////////////////// +/// +#define THOST_FTDC_CDT_Normal '0' +///Ͷƽ +#define THOST_FTDC_CDT_SpecFirst '1' + +typedef char TThostFtdcCloseDealTypeType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcMortgageFundUseRangeTypeһѺʽ÷Χ +///////////////////////////////////////////////////////////////////////// +///ʹ +#define THOST_FTDC_MFUR_None '0' +///ڱ֤ +#define THOST_FTDC_MFUR_Margin '1' +///ѡӯ֤ +#define THOST_FTDC_MFUR_All '2' + +typedef char TThostFtdcMortgageFundUseRangeType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcCurrencyUnitTypeһֵλ +///////////////////////////////////////////////////////////////////////// +typedef double TThostFtdcCurrencyUnitType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcExchangeRateTypeһ +///////////////////////////////////////////////////////////////////////// +typedef double TThostFtdcExchangeRateType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcSpecProductTypeTypeһƷ +///////////////////////////////////////////////////////////////////////// +///֣ױƷ +#define THOST_FTDC_SPT_CzceHedge '1' +///ѺƷ +#define THOST_FTDC_SPT_IneForeignCurrency '2' +///߿ƽֲƷ +#define THOST_FTDC_SPT_DceOpenClose '3' + +typedef char TThostFtdcSpecProductTypeType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcFundMortgageTypeTypeһѺ +///////////////////////////////////////////////////////////////////////// +///Ѻ +#define THOST_FTDC_FMT_Mortgage '1' +/// +#define THOST_FTDC_FMT_Redemption '2' + +typedef char TThostFtdcFundMortgageTypeType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcAccountSettlementParamIDTypeһͶ˻ +///////////////////////////////////////////////////////////////////////// +///֤ +#define THOST_FTDC_ASPI_BaseMargin '1' +///Ȩ׼ +#define THOST_FTDC_ASPI_LowestInterest '2' + +typedef char TThostFtdcAccountSettlementParamIDType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcCurrencyNameTypeһ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcCurrencyNameType[31]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcCurrencySignTypeһַ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcCurrencySignType[4]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcFundMortDirectionTypeһѺ +///////////////////////////////////////////////////////////////////////// +/// +#define THOST_FTDC_FMD_In '1' +///ʳ +#define THOST_FTDC_FMD_Out '2' + +typedef char TThostFtdcFundMortDirectionType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcBusinessClassTypeһ +///////////////////////////////////////////////////////////////////////// +///ӯ +#define THOST_FTDC_BT_Profit '0' +/// +#define THOST_FTDC_BT_Loss '1' +/// +#define THOST_FTDC_BT_Other 'Z' + +typedef char TThostFtdcBusinessClassType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcSwapSourceTypeTypeһԴ +///////////////////////////////////////////////////////////////////////// +///ֹ +#define THOST_FTDC_SST_Manual '0' +///Զ +#define THOST_FTDC_SST_Automatic '1' + +typedef char TThostFtdcSwapSourceTypeType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcCurrExDirectionTypeһ +///////////////////////////////////////////////////////////////////////// +/// +#define THOST_FTDC_CED_Settlement '0' +///ۻ +#define THOST_FTDC_CED_Sale '1' + +typedef char TThostFtdcCurrExDirectionType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcCurrencySwapStatusTypeһ״̬ +///////////////////////////////////////////////////////////////////////// +///¼ +#define THOST_FTDC_CSS_Entry '1' +/// +#define THOST_FTDC_CSS_Approve '2' +///Ѿܾ +#define THOST_FTDC_CSS_Refuse '3' +///ѳ +#define THOST_FTDC_CSS_Revoke '4' +///ѷ +#define THOST_FTDC_CSS_Send '5' +///ɹ +#define THOST_FTDC_CSS_Success '6' +///ʧ +#define THOST_FTDC_CSS_Failure '7' + +typedef char TThostFtdcCurrencySwapStatusType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcCurrExchCertNoTypeһƾ֤ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcCurrExchCertNoType[13]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcBatchSerialNoTypeһκ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcBatchSerialNoType[21]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcReqFlagTypeһ㷢ͱ־ +///////////////////////////////////////////////////////////////////////// +///δ +#define THOST_FTDC_REQF_NoSend '0' +///ͳɹ +#define THOST_FTDC_REQF_SendSuccess '1' +///ʧ +#define THOST_FTDC_REQF_SendFailed '2' +///ȴط +#define THOST_FTDC_REQF_WaitReSend '3' + +typedef char TThostFtdcReqFlagType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcResFlagTypeһ㷵سɹ־ +///////////////////////////////////////////////////////////////////////// +///ɹ +#define THOST_FTDC_RESF_Success '0' +///˻ +#define THOST_FTDC_RESF_InsuffiCient '1' +///׽δ֪ +#define THOST_FTDC_RESF_UnKnown '8' + +typedef char TThostFtdcResFlagType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcPageControlTypeһҳ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcPageControlType[2]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcRecordCountTypeһ¼ +///////////////////////////////////////////////////////////////////////// +typedef int TThostFtdcRecordCountType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcCurrencySwapMemoTypeһȷϢ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcCurrencySwapMemoType[101]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcExStatusTypeһ޸״̬ +///////////////////////////////////////////////////////////////////////// +///޸ǰ +#define THOST_FTDC_EXS_Before '0' +///޸ĺ +#define THOST_FTDC_EXS_After '1' + +typedef char TThostFtdcExStatusType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcClientRegionTypeһͻ +///////////////////////////////////////////////////////////////////////// +///ڿͻ +#define THOST_FTDC_CR_Domestic '1' +///۰̨ͻ +#define THOST_FTDC_CR_GMT '2' +///ͻ +#define THOST_FTDC_CR_Foreign '3' + +typedef char TThostFtdcClientRegionType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcWorkPlaceTypeһλ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcWorkPlaceType[101]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcBusinessPeriodTypeһӪ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcBusinessPeriodType[21]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcWebSiteTypeһַ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcWebSiteType[101]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcUOAIdCardTypeTypeһͳһ֤ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcUOAIdCardTypeType[3]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcClientModeTypeһģʽ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcClientModeType[3]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcInvestorFullNameTypeһͶȫ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcInvestorFullNameType[101]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcUOABrokerIDTypeһнID +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcUOABrokerIDType[11]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcUOAZipCodeTypeһ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcUOAZipCodeType[11]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcUOAEMailTypeһ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcUOAEMailType[101]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcOldCityTypeһ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcOldCityType[41]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcCorporateIdentifiedCardNoTypeһ˴֤ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcCorporateIdentifiedCardNoType[101]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcHasBoardTypeһǷж» +///////////////////////////////////////////////////////////////////////// +///û +#define THOST_FTDC_HB_No '0' +/// +#define THOST_FTDC_HB_Yes '1' + +typedef char TThostFtdcHasBoardType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcStartModeTypeһģʽ +///////////////////////////////////////////////////////////////////////// +/// +#define THOST_FTDC_SM_Normal '1' +///Ӧ +#define THOST_FTDC_SM_Emerge '2' +///ָ +#define THOST_FTDC_SM_Restore '3' + +typedef char TThostFtdcStartModeType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcTemplateTypeTypeһģ +///////////////////////////////////////////////////////////////////////// +///ȫ +#define THOST_FTDC_TPT_Full '1' +/// +#define THOST_FTDC_TPT_Increment '2' +/// +#define THOST_FTDC_TPT_BackUp '3' + +typedef char TThostFtdcTemplateTypeType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcLoginModeTypeһ¼ģʽ +///////////////////////////////////////////////////////////////////////// +/// +#define THOST_FTDC_LM_Trade '0' +///ת +#define THOST_FTDC_LM_Transfer '1' + +typedef char TThostFtdcLoginModeType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcPromptTypeTypeһʾ +///////////////////////////////////////////////////////////////////////// +///Լ +#define THOST_FTDC_CPT_Instrument '1' +///ֶ֤Ч +#define THOST_FTDC_CPT_Margin '2' + +typedef char TThostFtdcPromptTypeType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcLedgerManageIDTypeһֻʲ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcLedgerManageIDType[51]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcInvestVarietyTypeһͶƷ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcInvestVarietyType[101]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcBankAccountTypeTypeһ˻ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcBankAccountTypeType[2]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcLedgerManageBankTypeһ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcLedgerManageBankType[101]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcCffexDepartmentNameTypeһӪҵ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcCffexDepartmentNameType[101]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcCffexDepartmentCodeTypeһӪҵ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcCffexDepartmentCodeType[9]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcHasTrusteeTypeһǷй +///////////////////////////////////////////////////////////////////////// +/// +#define THOST_FTDC_HT_Yes '1' +///û +#define THOST_FTDC_HT_No '0' + +typedef char TThostFtdcHasTrusteeType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcCSRCMemo1Typeһ˵ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcCSRCMemo1Type[41]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcAssetmgrCFullNameTypeһʲҵڻ˾ȫ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcAssetmgrCFullNameType[101]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcAssetmgrApprovalNOTypeһʲҵĺ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcAssetmgrApprovalNOType[51]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcAssetmgrMgrNameTypeһʲҵ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcAssetmgrMgrNameType[401]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcAmTypeTypeһ +///////////////////////////////////////////////////////////////////////// +/// +#define THOST_FTDC_AMT_Bank '1' +///֤ȯ˾ +#define THOST_FTDC_AMT_Securities '2' +///˾ +#define THOST_FTDC_AMT_Fund '3' +///չ˾ +#define THOST_FTDC_AMT_Insurance '4' +///й˾ +#define THOST_FTDC_AMT_Trust '5' +/// +#define THOST_FTDC_AMT_Other '9' + +typedef char TThostFtdcAmTypeType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcCSRCAmTypeTypeһ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcCSRCAmTypeType[5]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcCSRCFundIOTypeTypeһ +///////////////////////////////////////////////////////////////////////// +/// +#define THOST_FTDC_CFIOT_FundIO '0' +///ڻ +#define THOST_FTDC_CFIOT_SwapCurrency '1' + +typedef char TThostFtdcCSRCFundIOTypeType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcCusAccountTypeTypeһ˻ +///////////////////////////////////////////////////////////////////////// +///ڻ˻ +#define THOST_FTDC_CAT_Futures '1' +///ڻʹҵµʹܽ˻ +#define THOST_FTDC_CAT_AssetmgrFuture '2' +///ۺʹҵµڻʹй˻ +#define THOST_FTDC_CAT_AssetmgrTrustee '3' +///ۺʹҵµʽת˻ +#define THOST_FTDC_CAT_AssetmgrTransfer '4' + +typedef char TThostFtdcCusAccountTypeType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcCSRCNationalTypeһ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcCSRCNationalType[4]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcCSRCSecAgentIDTypeһID +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcCSRCSecAgentIDType[11]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcLanguageTypeTypeһ֪ͨ +///////////////////////////////////////////////////////////////////////// +/// +#define THOST_FTDC_LT_Chinese '1' +///Ӣ +#define THOST_FTDC_LT_English '2' + +typedef char TThostFtdcLanguageTypeType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcAmAccountTypeһͶ˻ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcAmAccountType[23]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcAssetmgrClientTypeTypeһʲͻ +///////////////////////////////////////////////////////////////////////// +///ʹܿͻ +#define THOST_FTDC_AMCT_Person '1' +///λʹܿͻ +#define THOST_FTDC_AMCT_Organ '2' +///ⵥλʹܿͻ +#define THOST_FTDC_AMCT_SpecialOrgan '4' + +typedef char TThostFtdcAssetmgrClientTypeType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcAssetmgrTypeTypeһͶ +///////////////////////////////////////////////////////////////////////// +///ڻ +#define THOST_FTDC_ASST_Futures '3' +///ۺ +#define THOST_FTDC_ASST_SpecialOrgan '4' + +typedef char TThostFtdcAssetmgrTypeType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcUOMTypeһλ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcUOMType[11]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcSHFEInstLifePhaseTypeһԼ״̬ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcSHFEInstLifePhaseType[3]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcSHFEProductClassTypeһƷ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcSHFEProductClassType[11]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcPriceDecimalTypeһ۸Сλ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcPriceDecimalType[2]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcInTheMoneyFlagTypeһƽֵȨ־ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcInTheMoneyFlagType[2]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcCheckInstrTypeTypeһԼȽ +///////////////////////////////////////////////////////////////////////// +///Լ +#define THOST_FTDC_CIT_HasExch '0' +///Լϵͳ +#define THOST_FTDC_CIT_HasATP '1' +///ԼȽϲһ +#define THOST_FTDC_CIT_HasDiff '2' + +typedef char TThostFtdcCheckInstrTypeType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcDeliveryTypeTypeһ +///////////////////////////////////////////////////////////////////////// +///ֹ +#define THOST_FTDC_DT_HandDeliv '1' +///ڽ +#define THOST_FTDC_DT_PersonDeliv '2' + +typedef char TThostFtdcDeliveryTypeType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcBigMoneyTypeһʽ +///////////////////////////////////////////////////////////////////////// +typedef double TThostFtdcBigMoneyType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcMaxMarginSideAlgorithmTypeһ֤߱㷨 +///////////////////////////////////////////////////////////////////////// +///ʹô֤߱㷨 +#define THOST_FTDC_MMSA_NO '0' +///ʹô֤߱㷨 +#define THOST_FTDC_MMSA_YES '1' + +typedef char TThostFtdcMaxMarginSideAlgorithmType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcDAClientTypeTypeһʲͻ +///////////////////////////////////////////////////////////////////////// +///Ȼ +#define THOST_FTDC_CACT_Person '0' +/// +#define THOST_FTDC_CACT_Company '1' +/// +#define THOST_FTDC_CACT_Other '2' + +typedef char TThostFtdcDAClientTypeType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcCombinInstrIDTypeһԼ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcCombinInstrIDType[61]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcCombinSettlePriceTypeһȽ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcCombinSettlePriceType[61]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcDCEPriorityTypeһȼ +///////////////////////////////////////////////////////////////////////// +typedef int TThostFtdcDCEPriorityType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcTradeGroupIDTypeһɽ +///////////////////////////////////////////////////////////////////////// +typedef int TThostFtdcTradeGroupIDType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcIsCheckPrepaTypeһǷУ鿪ʽ +///////////////////////////////////////////////////////////////////////// +typedef int TThostFtdcIsCheckPrepaType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcUOAAssetmgrTypeTypeһͶ +///////////////////////////////////////////////////////////////////////// +///ڻ +#define THOST_FTDC_UOAAT_Futures '1' +///ۺ +#define THOST_FTDC_UOAAT_SpecialOrgan '2' + +typedef char TThostFtdcUOAAssetmgrTypeType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcDirectionEnTypeһ +///////////////////////////////////////////////////////////////////////// +/// Buy +#define THOST_FTDC_DEN_Buy '0' +/// Sell +#define THOST_FTDC_DEN_Sell '1' + +typedef char TThostFtdcDirectionEnType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcOffsetFlagEnTypeһƽ־ +///////////////////////////////////////////////////////////////////////// +/// Position Opening +#define THOST_FTDC_OFEN_Open '0' +/// Position Close +#define THOST_FTDC_OFEN_Close '1' +/// Forced Liquidation +#define THOST_FTDC_OFEN_ForceClose '2' +/// Close Today +#define THOST_FTDC_OFEN_CloseToday '3' +/// Close Prev. +#define THOST_FTDC_OFEN_CloseYesterday '4' +/// Forced Reduction +#define THOST_FTDC_OFEN_ForceOff '5' +/// Local Forced Liquidation +#define THOST_FTDC_OFEN_LocalForceClose '6' + +typedef char TThostFtdcOffsetFlagEnType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcHedgeFlagEnTypeһͶױ־ +///////////////////////////////////////////////////////////////////////// +/// Speculation +#define THOST_FTDC_HFEN_Speculation '1' +/// Arbitrage +#define THOST_FTDC_HFEN_Arbitrage '2' +/// Hedge +#define THOST_FTDC_HFEN_Hedge '3' + +typedef char TThostFtdcHedgeFlagEnType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcFundIOTypeEnTypeһ +///////////////////////////////////////////////////////////////////////// +/// Deposit/Withdrawal +#define THOST_FTDC_FIOTEN_FundIO '1' +/// Bank-Futures Transfer +#define THOST_FTDC_FIOTEN_Transfer '2' +/// Bank-Futures FX Exchange +#define THOST_FTDC_FIOTEN_SwapCurrency '3' + +typedef char TThostFtdcFundIOTypeEnType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcFundTypeEnTypeһʽ +///////////////////////////////////////////////////////////////////////// +/// Bank Deposit +#define THOST_FTDC_FTEN_Deposite '1' +/// Payment/Fee +#define THOST_FTDC_FTEN_ItemFund '2' +/// Brokerage Adj +#define THOST_FTDC_FTEN_Company '3' +/// Internal Transfer +#define THOST_FTDC_FTEN_InnerTransfer '4' + +typedef char TThostFtdcFundTypeEnType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcFundDirectionEnTypeһ +///////////////////////////////////////////////////////////////////////// +/// Deposit +#define THOST_FTDC_FDEN_In '1' +/// Withdrawal +#define THOST_FTDC_FDEN_Out '2' + +typedef char TThostFtdcFundDirectionEnType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcFundMortDirectionEnTypeһѺ +///////////////////////////////////////////////////////////////////////// +/// Pledge +#define THOST_FTDC_FMDEN_In '1' +/// Redemption +#define THOST_FTDC_FMDEN_Out '2' + +typedef char TThostFtdcFundMortDirectionEnType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcSwapBusinessTypeTypeһҵ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcSwapBusinessTypeType[3]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcOptionsTypeTypeһȨ +///////////////////////////////////////////////////////////////////////// +/// +#define THOST_FTDC_CP_CallOptions '1' +/// +#define THOST_FTDC_CP_PutOptions '2' + +typedef char TThostFtdcOptionsTypeType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcStrikeModeTypeһִзʽ +///////////////////////////////////////////////////////////////////////// +///ŷʽ +#define THOST_FTDC_STM_Continental '0' +///ʽ +#define THOST_FTDC_STM_American '1' +///Ľ +#define THOST_FTDC_STM_Bermuda '2' + +typedef char TThostFtdcStrikeModeType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcStrikeTypeTypeһִ +///////////////////////////////////////////////////////////////////////// +///Գ +#define THOST_FTDC_STT_Hedge '0' +///ƥִ +#define THOST_FTDC_STT_Match '1' + +typedef char TThostFtdcStrikeTypeType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcApplyTypeTypeһнȨִ +///////////////////////////////////////////////////////////////////////// +///ִ +#define THOST_FTDC_APPT_NotStrikeNum '4' + +typedef char TThostFtdcApplyTypeType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcGiveUpDataSourceTypeһִԴ +///////////////////////////////////////////////////////////////////////// +///ϵͳ +#define THOST_FTDC_GUDS_Gen '0' +///ֹ +#define THOST_FTDC_GUDS_Hand '1' + +typedef char TThostFtdcGiveUpDataSourceType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcExecOrderSysIDTypeһִϵͳ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcExecOrderSysIDType[21]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcExecResultTypeһִн +///////////////////////////////////////////////////////////////////////// +///ûִ +#define THOST_FTDC_OER_NoExec 'n' +///Ѿȡ +#define THOST_FTDC_OER_Canceled 'c' +///ִгɹ +#define THOST_FTDC_OER_OK '0' +///Ȩֲֲ +#define THOST_FTDC_OER_NoPosition '1' +///ʽ𲻹 +#define THOST_FTDC_OER_NoDeposit '2' +///Ա +#define THOST_FTDC_OER_NoParticipant '3' +///ͻ +#define THOST_FTDC_OER_NoClient '4' +///Լ +#define THOST_FTDC_OER_NoInstrument '6' +///ûִȨ +#define THOST_FTDC_OER_NoRight '7' +/// +#define THOST_FTDC_OER_InvalidVolume '8' +///û㹻ʷɽ +#define THOST_FTDC_OER_NoEnoughHistoryTrade '9' +///δ֪ +#define THOST_FTDC_OER_Unknown 'a' + +typedef char TThostFtdcExecResultType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcStrikeSequenceTypeһִ +///////////////////////////////////////////////////////////////////////// +typedef int TThostFtdcStrikeSequenceType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcStrikeTimeTypeһִʱ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcStrikeTimeType[13]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcCombinationTypeTypeһ +///////////////////////////////////////////////////////////////////////// +///ڻ +#define THOST_FTDC_COMBT_Future '0' +///ֱ۲BUL +#define THOST_FTDC_COMBT_BUL '1' +///ֱ۲BER +#define THOST_FTDC_COMBT_BER '2' +///ʽ +#define THOST_FTDC_COMBT_STD '3' +///ʽ +#define THOST_FTDC_COMBT_STG '4' +/// +#define THOST_FTDC_COMBT_PRT '5' +///ʱ۲ +#define THOST_FTDC_COMBT_CLD '6' + +typedef char TThostFtdcCombinationTypeType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcOptionRoyaltyPriceTypeTypeһȨȨ۸ +///////////////////////////////////////////////////////////////////////// +/// +#define THOST_FTDC_ORPT_PreSettlementPrice '1' +///ּ +#define THOST_FTDC_ORPT_OpenPrice '4' + +typedef char TThostFtdcOptionRoyaltyPriceTypeType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcBalanceAlgorithmTypeһȨ㷨 +///////////////////////////////////////////////////////////////////////// +///Ȩֵӯ +#define THOST_FTDC_BLAG_Default '1' +///Ȩֵ +#define THOST_FTDC_BLAG_IncludeOptValLost '2' + +typedef char TThostFtdcBalanceAlgorithmType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcActionTypeTypeһִ +///////////////////////////////////////////////////////////////////////// +///ִ +#define THOST_FTDC_ACTP_Exec '1' +/// +#define THOST_FTDC_ACTP_Abandon '2' + +typedef char TThostFtdcActionTypeType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcForQuoteStatusTypeһѯ״̬ +///////////////////////////////////////////////////////////////////////// +///Ѿύ +#define THOST_FTDC_FQST_Submitted 'a' +///Ѿ +#define THOST_FTDC_FQST_Accepted 'b' +///Ѿܾ +#define THOST_FTDC_FQST_Rejected 'c' + +typedef char TThostFtdcForQuoteStatusType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcValueMethodTypeһȡֵʽ +///////////////////////////////////////////////////////////////////////// +///ֵ +#define THOST_FTDC_VM_Absolute '0' +/// +#define THOST_FTDC_VM_Ratio '1' + +typedef char TThostFtdcValueMethodType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcExecOrderPositionFlagTypeһȨȨǷڻͷı +///////////////////////////////////////////////////////////////////////// +/// +#define THOST_FTDC_EOPF_Reserve '0' +/// +#define THOST_FTDC_EOPF_UnReserve '1' + +typedef char TThostFtdcExecOrderPositionFlagType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcExecOrderCloseFlagTypeһȨȨɵͷǷԶƽ +///////////////////////////////////////////////////////////////////////// +///Զƽ +#define THOST_FTDC_EOCF_AutoClose '0' +///Զƽ +#define THOST_FTDC_EOCF_NotToClose '1' + +typedef char TThostFtdcExecOrderCloseFlagType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcProductTypeTypeһƷ +///////////////////////////////////////////////////////////////////////// +///ڻ +#define THOST_FTDC_PTE_Futures '1' +///Ȩ +#define THOST_FTDC_PTE_Options '2' + +typedef char TThostFtdcProductTypeType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcCZCEUploadFileNameTypeһ֣ļ +///////////////////////////////////////////////////////////////////////// +///^\d{8}_zz_\d{4} +#define THOST_FTDC_CUFN_CUFN_O 'O' +///^\d{8}ɽ +#define THOST_FTDC_CUFN_CUFN_T 'T' +///^\d{8}ȳֱֲnew +#define THOST_FTDC_CUFN_CUFN_P 'P' +///^\d{8}ƽ˽ +#define THOST_FTDC_CUFN_CUFN_N 'N' +///^\d{8}ƽֱ +#define THOST_FTDC_CUFN_CUFN_L 'L' +///^\d{8}ʽ +#define THOST_FTDC_CUFN_CUFN_F 'F' +///^\d{8}ϳֱֲ +#define THOST_FTDC_CUFN_CUFN_C 'C' +///^\d{8}֤ +#define THOST_FTDC_CUFN_CUFN_M 'M' + +typedef char TThostFtdcCZCEUploadFileNameType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcDCEUploadFileNameTypeһļ +///////////////////////////////////////////////////////////////////////// +///^\d{8}_dl_\d{3} +#define THOST_FTDC_DUFN_DUFN_O 'O' +///^\d{8}_ɽ +#define THOST_FTDC_DUFN_DUFN_T 'T' +///^\d{8}_ֱֲ +#define THOST_FTDC_DUFN_DUFN_P 'P' +///^\d{8}_ʽ +#define THOST_FTDC_DUFN_DUFN_F 'F' +///^\d{8}_Żϳֲϸ +#define THOST_FTDC_DUFN_DUFN_C 'C' +///^\d{8}_ֲϸ +#define THOST_FTDC_DUFN_DUFN_D 'D' +///^\d{8}_֤ +#define THOST_FTDC_DUFN_DUFN_M 'M' +///^\d{8}_Ȩִб +#define THOST_FTDC_DUFN_DUFN_S 'S' + +typedef char TThostFtdcDCEUploadFileNameType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcSHFEUploadFileNameTypeһļ +///////////////////////////////////////////////////////////////////////// +///^\d{4}_\d{8}_\d{8}_DailyFundChg +#define THOST_FTDC_SUFN_SUFN_O 'O' +///^\d{4}_\d{8}_\d{8}_Trade +#define THOST_FTDC_SUFN_SUFN_T 'T' +///^\d{4}_\d{8}_\d{8}_SettlementDetail +#define THOST_FTDC_SUFN_SUFN_P 'P' +///^\d{4}_\d{8}_\d{8}_Capital +#define THOST_FTDC_SUFN_SUFN_F 'F' + +typedef char TThostFtdcSHFEUploadFileNameType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcCFFEXUploadFileNameTypeһнļ +///////////////////////////////////////////////////////////////////////// +///^\d{4}_SG\d{1}_\d{8}_\d{1}_Trade +#define THOST_FTDC_CFUFN_SUFN_T 'T' +///^\d{4}_SG\d{1}_\d{8}_\d{1}_SettlementDetail +#define THOST_FTDC_CFUFN_SUFN_P 'P' +///^\d{4}_SG\d{1}_\d{8}_\d{1}_Capital +#define THOST_FTDC_CFUFN_SUFN_F 'F' +///^\d{4}_SG\d{1}_\d{8}_\d{1}_OptionExec +#define THOST_FTDC_CFUFN_SUFN_S 'S' + +typedef char TThostFtdcCFFEXUploadFileNameType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcCombDirectionTypeһָ +///////////////////////////////////////////////////////////////////////// +/// +#define THOST_FTDC_CMDR_Comb '0' +/// +#define THOST_FTDC_CMDR_UnComb '1' + +typedef char TThostFtdcCombDirectionType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcStrikeOffsetTypeTypeһȨƫ +///////////////////////////////////////////////////////////////////////// +///ʵֵ +#define THOST_FTDC_STOV_RealValue '1' +///ӯ +#define THOST_FTDC_STOV_ProfitValue '2' +///ʵֵ +#define THOST_FTDC_STOV_RealRatio '3' +///ӯ +#define THOST_FTDC_STOV_ProfitRatio '4' + +typedef char TThostFtdcStrikeOffsetTypeType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcReserveOpenAccStasTypeһԤԼ״̬ +///////////////////////////////////////////////////////////////////////// +///ȴ +#define THOST_FTDC_ROAST_Processing '0' +///ѳ +#define THOST_FTDC_ROAST_Cancelled '1' +///ѿ +#define THOST_FTDC_ROAST_Opened '2' +///Ч +#define THOST_FTDC_ROAST_Invalid '3' + +typedef char TThostFtdcReserveOpenAccStasType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcLoginRemarkTypeһ¼ע +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcLoginRemarkType[36]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcInvestUnitIDTypeһͶʵԪ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcInvestUnitIDType[17]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcBulletinIDTypeһ +///////////////////////////////////////////////////////////////////////// +typedef int TThostFtdcBulletinIDType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcNewsTypeTypeһ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcNewsTypeType[3]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcNewsUrgencyTypeһ̶ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcNewsUrgencyType; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcAbstractTypeһϢժҪ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcAbstractType[81]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcComeFromTypeһϢԴ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcComeFromType[21]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcURLLinkTypeһWEBַ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcURLLinkType[201]; + +///////////////////////////////////////////////////////////////////////// +/// TFtdcLongIndividualNameTypeһ +///////////////////////////////////////////////////////////////////////// +typedef char TThostFtdcLongIndividualNameType[161]; + +#endif diff --git a/qbot/engine/trade/engine_apis/futures/CTPtest/src/CTP_API/ThostFtdcUserApiStruct.h b/qbot/engine/trade/engine_apis/futures/CTPtest/src/CTP_API/ThostFtdcUserApiStruct.h new file mode 100644 index 00000000..c145bf47 --- /dev/null +++ b/qbot/engine/trade/engine_apis/futures/CTPtest/src/CTP_API/ThostFtdcUserApiStruct.h @@ -0,0 +1,8111 @@ +///////////////////////////////////////////////////////////////////////// +///@system һϵͳ +///@company ϺڻϢ޹˾ +///@file ThostFtdcUserApiStruct.h +///@brief ˿ͻ˽ӿʹõҵݽṹ +///@history +/// 20060106 Ժ ļ +///////////////////////////////////////////////////////////////////////// + +#if !defined(THOST_FTDCSTRUCT_H) +#define THOST_FTDCSTRUCT_H + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 + +#include "ThostFtdcUserApiDataType.h" + +///Ϣַ +struct CThostFtdcDisseminationField { + ///ϵк + TThostFtdcSequenceSeriesType SequenceSeries; + ///к + TThostFtdcSequenceNoType SequenceNo; +}; + +///û¼ +struct CThostFtdcReqUserLoginField { + /// + TThostFtdcDateType TradingDay; + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///û + TThostFtdcUserIDType UserID; + /// + TThostFtdcPasswordType Password; + ///û˲ƷϢ + TThostFtdcProductInfoType UserProductInfo; + ///ӿڶ˲ƷϢ + TThostFtdcProductInfoType InterfaceProductInfo; + ///ЭϢ + TThostFtdcProtocolInfoType ProtocolInfo; + /// Macַ + TThostFtdcMacAddressType MacAddress; + ///̬ + TThostFtdcPasswordType OneTimePassword; + ///նIPַ + TThostFtdcIPAddressType ClientIPAddress; + ///¼ע + TThostFtdcLoginRemarkType LoginRemark; +}; + +///û¼Ӧ +struct CThostFtdcRspUserLoginField { + /// + TThostFtdcDateType TradingDay; + ///¼ɹʱ + TThostFtdcTimeType LoginTime; + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///û + TThostFtdcUserIDType UserID; + ///ϵͳ + TThostFtdcSystemNameType SystemName; + ///ǰñ + TThostFtdcFrontIDType FrontID; + ///Ự + TThostFtdcSessionIDType SessionID; + ///󱨵 + TThostFtdcOrderRefType MaxOrderRef; + ///ʱ + TThostFtdcTimeType SHFETime; + ///ʱ + TThostFtdcTimeType DCETime; + ///֣ʱ + TThostFtdcTimeType CZCETime; + ///нʱ + TThostFtdcTimeType FFEXTime; + ///Դʱ + TThostFtdcTimeType INETime; +}; + +///ûdz +struct CThostFtdcUserLogoutField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///û + TThostFtdcUserIDType UserID; +}; + +///ǿƽԱ˳ +struct CThostFtdcForceUserLogoutField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///û + TThostFtdcUserIDType UserID; +}; + +///ͻ֤ +struct CThostFtdcReqAuthenticateField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///û + TThostFtdcUserIDType UserID; + ///û˲ƷϢ + TThostFtdcProductInfoType UserProductInfo; + ///֤ + TThostFtdcAuthCodeType AuthCode; +}; + +///ͻ֤Ӧ +struct CThostFtdcRspAuthenticateField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///û + TThostFtdcUserIDType UserID; + ///û˲ƷϢ + TThostFtdcProductInfoType UserProductInfo; +}; + +///ͻ֤Ϣ +struct CThostFtdcAuthenticationInfoField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///û + TThostFtdcUserIDType UserID; + ///û˲ƷϢ + TThostFtdcProductInfoType UserProductInfo; + ///֤Ϣ + TThostFtdcAuthInfoType AuthInfo; + ///ǷΪ֤ + TThostFtdcBoolType IsResult; +}; + +///תʱͷ +struct CThostFtdcTransferHeaderField { + ///汾ţ1.0 + TThostFtdcVersionType Version; + ///״룬 + TThostFtdcTradeCodeType TradeCode; + ///ڣʽyyyymmdd + TThostFtdcTradeDateType TradeDate; + ///ʱ䣬ʽhhmmss + TThostFtdcTradeTimeType TradeTime; + ///ˮţN/A + TThostFtdcTradeSerialType TradeSerial; + ///ڻ˾룬 + TThostFtdcFutureIDType FutureID; + ///д룬ݲѯеõ + TThostFtdcBankIDType BankID; + ///зĴ룬ݲѯеõ + TThostFtdcBankBrchIDType BankBrchID; + ///ԱN/A + TThostFtdcOperNoType OperNo; + ///豸ͣN/A + TThostFtdcDeviceIDType DeviceID; + ///¼N/A + TThostFtdcRecordNumType RecordNum; + ///ỰţN/A + TThostFtdcSessionIDType SessionID; + ///ţN/A + TThostFtdcRequestIDType RequestID; +}; + +///ʽתڻTradeCode=202001 +struct CThostFtdcTransferBankToFutureReqField { + ///ڻʽ˻ + TThostFtdcAccountIDType FutureAccount; + ///־ + TThostFtdcFuturePwdFlagType FuturePwdFlag; + /// + TThostFtdcFutureAccPwdType FutureAccPwd; + ///ת˽ + TThostFtdcMoneyType TradeAmt; + ///ͻ + TThostFtdcMoneyType CustFee; + ///֣RMB- USD-Բ HKD-Ԫ + TThostFtdcCurrencyCodeType CurrencyCode; +}; + +///ʽתڻӦ +struct CThostFtdcTransferBankToFutureRspField { + ///Ӧ + TThostFtdcRetCodeType RetCode; + ///ӦϢ + TThostFtdcRetInfoType RetInfo; + ///ʽ˻ + TThostFtdcAccountIDType FutureAccount; + ///תʽ + TThostFtdcMoneyType TradeAmt; + ///Ӧտͻ + TThostFtdcMoneyType CustFee; + /// + TThostFtdcCurrencyCodeType CurrencyCode; +}; + +///ڻʽתTradeCode=202002 +struct CThostFtdcTransferFutureToBankReqField { + ///ڻʽ˻ + TThostFtdcAccountIDType FutureAccount; + ///־ + TThostFtdcFuturePwdFlagType FuturePwdFlag; + /// + TThostFtdcFutureAccPwdType FutureAccPwd; + ///ת˽ + TThostFtdcMoneyType TradeAmt; + ///ͻ + TThostFtdcMoneyType CustFee; + ///֣RMB- USD-Բ HKD-Ԫ + TThostFtdcCurrencyCodeType CurrencyCode; +}; + +///ڻʽתӦ +struct CThostFtdcTransferFutureToBankRspField { + ///Ӧ + TThostFtdcRetCodeType RetCode; + ///ӦϢ + TThostFtdcRetInfoType RetInfo; + ///ʽ˻ + TThostFtdcAccountIDType FutureAccount; + ///תʽ + TThostFtdcMoneyType TradeAmt; + ///Ӧտͻ + TThostFtdcMoneyType CustFee; + /// + TThostFtdcCurrencyCodeType CurrencyCode; +}; + +///ѯʽTradeCode=204002 +struct CThostFtdcTransferQryBankReqField { + ///ڻʽ˻ + TThostFtdcAccountIDType FutureAccount; + ///־ + TThostFtdcFuturePwdFlagType FuturePwdFlag; + /// + TThostFtdcFutureAccPwdType FutureAccPwd; + ///֣RMB- USD-Բ HKD-Ԫ + TThostFtdcCurrencyCodeType CurrencyCode; +}; + +///ѯʽӦ +struct CThostFtdcTransferQryBankRspField { + ///Ӧ + TThostFtdcRetCodeType RetCode; + ///ӦϢ + TThostFtdcRetInfoType RetInfo; + ///ʽ˻ + TThostFtdcAccountIDType FutureAccount; + /// + TThostFtdcMoneyType TradeAmt; + ///п + TThostFtdcMoneyType UseAmt; + ///пȡ + TThostFtdcMoneyType FetchAmt; + /// + TThostFtdcCurrencyCodeType CurrencyCode; +}; + +///ѯнϸTradeCode=204999 +struct CThostFtdcTransferQryDetailReqField { + ///ڻʽ˻ + TThostFtdcAccountIDType FutureAccount; +}; + +///ѯнϸӦ +struct CThostFtdcTransferQryDetailRspField { + /// + TThostFtdcDateType TradeDate; + ///ʱ + TThostFtdcTradeTimeType TradeTime; + ///״ + TThostFtdcTradeCodeType TradeCode; + ///ڻˮ + TThostFtdcTradeSerialNoType FutureSerial; + ///ڻ˾ + TThostFtdcFutureIDType FutureID; + ///ʽʺ + TThostFtdcFutureAccountType FutureAccount; + ///ˮ + TThostFtdcTradeSerialNoType BankSerial; + ///д + TThostFtdcBankIDType BankID; + ///зĴ + TThostFtdcBankBrchIDType BankBrchID; + ///˺ + TThostFtdcBankAccountType BankAccount; + ///֤ + TThostFtdcCertCodeType CertCode; + ///Ҵ + TThostFtdcCurrencyCodeType CurrencyCode; + /// + TThostFtdcMoneyType TxAmount; + ///Ч־ + TThostFtdcTransferValidFlagType Flag; +}; + +///ӦϢ +struct CThostFtdcRspInfoField { + /// + TThostFtdcErrorIDType ErrorID; + ///Ϣ + TThostFtdcErrorMsgType ErrorMsg; +}; + +/// +struct CThostFtdcExchangeField { + /// + TThostFtdcExchangeIDType ExchangeID; + /// + TThostFtdcExchangeNameType ExchangeName; + /// + TThostFtdcExchangePropertyType ExchangeProperty; +}; + +///Ʒ +struct CThostFtdcProductField { + ///Ʒ + TThostFtdcInstrumentIDType ProductID; + ///Ʒ + TThostFtdcProductNameType ProductName; + /// + TThostFtdcExchangeIDType ExchangeID; + ///Ʒ + TThostFtdcProductClassType ProductClass; + ///Լ + TThostFtdcVolumeMultipleType VolumeMultiple; + ///С䶯λ + TThostFtdcPriceType PriceTick; + ///м۵µ + TThostFtdcVolumeType MaxMarketOrderVolume; + ///м۵Сµ + TThostFtdcVolumeType MinMarketOrderVolume; + ///޼۵µ + TThostFtdcVolumeType MaxLimitOrderVolume; + ///޼۵Сµ + TThostFtdcVolumeType MinLimitOrderVolume; + ///ֲ + TThostFtdcPositionTypeType PositionType; + ///ֲ + TThostFtdcPositionDateTypeType PositionDateType; + ///ƽִ + TThostFtdcCloseDealTypeType CloseDealType; + ///ױ + TThostFtdcCurrencyIDType TradeCurrencyID; + ///Ѻʽ÷Χ + TThostFtdcMortgageFundUseRangeType MortgageFundUseRange; + ///Ʒ + TThostFtdcInstrumentIDType ExchangeProductID; + ///ԼƷ + TThostFtdcUnderlyingMultipleType UnderlyingMultiple; +}; + +///Լ +struct CThostFtdcInstrumentField { + ///Լ + TThostFtdcInstrumentIDType InstrumentID; + /// + TThostFtdcExchangeIDType ExchangeID; + ///Լ + TThostFtdcInstrumentNameType InstrumentName; + ///ԼڽĴ + TThostFtdcExchangeInstIDType ExchangeInstID; + ///Ʒ + TThostFtdcInstrumentIDType ProductID; + ///Ʒ + TThostFtdcProductClassType ProductClass; + /// + TThostFtdcYearType DeliveryYear; + /// + TThostFtdcMonthType DeliveryMonth; + ///м۵µ + TThostFtdcVolumeType MaxMarketOrderVolume; + ///м۵Сµ + TThostFtdcVolumeType MinMarketOrderVolume; + ///޼۵µ + TThostFtdcVolumeType MaxLimitOrderVolume; + ///޼۵Сµ + TThostFtdcVolumeType MinLimitOrderVolume; + ///Լ + TThostFtdcVolumeMultipleType VolumeMultiple; + ///С䶯λ + TThostFtdcPriceType PriceTick; + /// + TThostFtdcDateType CreateDate; + /// + TThostFtdcDateType OpenDate; + /// + TThostFtdcDateType ExpireDate; + ///ʼ + TThostFtdcDateType StartDelivDate; + /// + TThostFtdcDateType EndDelivDate; + ///Լ״̬ + TThostFtdcInstLifePhaseType InstLifePhase; + ///ǰǷ + TThostFtdcBoolType IsTrading; + ///ֲ + TThostFtdcPositionTypeType PositionType; + ///ֲ + TThostFtdcPositionDateTypeType PositionDateType; + ///ͷ֤ + TThostFtdcRatioType LongMarginRatio; + ///ͷ֤ + TThostFtdcRatioType ShortMarginRatio; + ///Ƿʹô֤߱㷨 + TThostFtdcMaxMarginSideAlgorithmType MaxMarginSideAlgorithm; + ///Ʒ + TThostFtdcInstrumentIDType UnderlyingInstrID; + ///ִм + TThostFtdcPriceType StrikePrice; + ///Ȩ + TThostFtdcOptionsTypeType OptionsType; + ///ԼƷ + TThostFtdcUnderlyingMultipleType UnderlyingMultiple; + /// + TThostFtdcCombinationTypeType CombinationType; +}; + +///͹˾ +struct CThostFtdcBrokerField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///͹˾ + TThostFtdcBrokerAbbrType BrokerAbbr; + ///͹˾ + TThostFtdcBrokerNameType BrokerName; + ///ǷԾ + TThostFtdcBoolType IsActive; +}; + +///Ա +struct CThostFtdcTraderField { + /// + TThostFtdcExchangeIDType ExchangeID; + ///Ա + TThostFtdcTraderIDType TraderID; + ///Ա + TThostFtdcParticipantIDType ParticipantID; + /// + TThostFtdcPasswordType Password; + ///װ + TThostFtdcInstallCountType InstallCount; + ///͹˾ + TThostFtdcBrokerIDType BrokerID; +}; + +///Ͷ +struct CThostFtdcInvestorField { + ///Ͷߴ + TThostFtdcInvestorIDType InvestorID; + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///Ͷ߷ + TThostFtdcInvestorIDType InvestorGroupID; + ///Ͷ + TThostFtdcPartyNameType InvestorName; + ///֤ + TThostFtdcIdCardTypeType IdentifiedCardType; + ///֤ + TThostFtdcIdentifiedCardNoType IdentifiedCardNo; + ///ǷԾ + TThostFtdcBoolType IsActive; + ///ϵ绰 + TThostFtdcTelephoneType Telephone; + ///ͨѶַ + TThostFtdcAddressType Address; + /// + TThostFtdcDateType OpenDate; + ///ֻ + TThostFtdcMobileType Mobile; + ///ģ + TThostFtdcInvestorIDType CommModelID; + ///֤ģ + TThostFtdcInvestorIDType MarginModelID; +}; + +///ױ +struct CThostFtdcTradingCodeField { + ///Ͷߴ + TThostFtdcInvestorIDType InvestorID; + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + /// + TThostFtdcExchangeIDType ExchangeID; + ///ͻ + TThostFtdcClientIDType ClientID; + ///ǷԾ + TThostFtdcBoolType IsActive; + ///ױ + TThostFtdcClientIDTypeType ClientIDType; +}; + +///Ա;͹˾ձ +struct CThostFtdcPartBrokerField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + /// + TThostFtdcExchangeIDType ExchangeID; + ///Ա + TThostFtdcParticipantIDType ParticipantID; + ///ǷԾ + TThostFtdcBoolType IsActive; +}; + +///û +struct CThostFtdcSuperUserField { + ///û + TThostFtdcUserIDType UserID; + ///û + TThostFtdcUserNameType UserName; + /// + TThostFtdcPasswordType Password; + ///ǷԾ + TThostFtdcBoolType IsActive; +}; + +///ûȨ +struct CThostFtdcSuperUserFunctionField { + ///û + TThostFtdcUserIDType UserID; + ///ܴ + TThostFtdcFunctionCodeType FunctionCode; +}; + +///Ͷ +struct CThostFtdcInvestorGroupField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///Ͷ߷ + TThostFtdcInvestorIDType InvestorGroupID; + ///Ͷ߷ + TThostFtdcInvestorGroupNameType InvestorGroupName; +}; + +///ʽ˻ +struct CThostFtdcTradingAccountField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///Ͷʺ + TThostFtdcAccountIDType AccountID; + ///ϴѺ + TThostFtdcMoneyType PreMortgage; + ///ϴö + TThostFtdcMoneyType PreCredit; + ///ϴδ + TThostFtdcMoneyType PreDeposit; + ///ϴν׼ + TThostFtdcMoneyType PreBalance; + ///ϴռõı֤ + TThostFtdcMoneyType PreMargin; + ///Ϣ + TThostFtdcMoneyType InterestBase; + ///Ϣ + TThostFtdcMoneyType Interest; + /// + TThostFtdcMoneyType Deposit; + /// + TThostFtdcMoneyType Withdraw; + ///ı֤ + TThostFtdcMoneyType FrozenMargin; + ///ʽ + TThostFtdcMoneyType FrozenCash; + /// + TThostFtdcMoneyType FrozenCommission; + ///ǰ֤ܶ + TThostFtdcMoneyType CurrMargin; + ///ʽ + TThostFtdcMoneyType CashIn; + /// + TThostFtdcMoneyType Commission; + ///ƽӯ + TThostFtdcMoneyType CloseProfit; + ///ֲӯ + TThostFtdcMoneyType PositionProfit; + ///ڻ׼ + TThostFtdcMoneyType Balance; + ///ʽ + TThostFtdcMoneyType Available; + ///ȡʽ + TThostFtdcMoneyType WithdrawQuota; + ///׼ + TThostFtdcMoneyType Reserve; + /// + TThostFtdcDateType TradingDay; + /// + TThostFtdcSettlementIDType SettlementID; + ///ö + TThostFtdcMoneyType Credit; + ///Ѻ + TThostFtdcMoneyType Mortgage; + ///֤ + TThostFtdcMoneyType ExchangeMargin; + ///Ͷ߽֤ + TThostFtdcMoneyType DeliveryMargin; + ///֤ + TThostFtdcMoneyType ExchangeDeliveryMargin; + ///ڻ׼ + TThostFtdcMoneyType ReserveBalance; + ///ִ + TThostFtdcCurrencyIDType CurrencyID; + ///ϴλ + TThostFtdcMoneyType PreFundMortgageIn; + ///ϴλʳ + TThostFtdcMoneyType PreFundMortgageOut; + /// + TThostFtdcMoneyType FundMortgageIn; + ///ʳ + TThostFtdcMoneyType FundMortgageOut; + ///Ѻ + TThostFtdcMoneyType FundMortgageAvailable; + ///Ѻҽ + TThostFtdcMoneyType MortgageableFund; + ///Ʒռñ֤ + TThostFtdcMoneyType SpecProductMargin; + ///Ʒᱣ֤ + TThostFtdcMoneyType SpecProductFrozenMargin; + ///Ʒ + TThostFtdcMoneyType SpecProductCommission; + ///Ʒ + TThostFtdcMoneyType SpecProductFrozenCommission; + ///Ʒֲӯ + TThostFtdcMoneyType SpecProductPositionProfit; + ///Ʒƽӯ + TThostFtdcMoneyType SpecProductCloseProfit; + ///ݳֲӯ㷨Ʒֲӯ + TThostFtdcMoneyType SpecProductPositionProfitByAlg; + ///Ʒ֤ + TThostFtdcMoneyType SpecProductExchangeMargin; +}; + +///Ͷֲ߳ +struct CThostFtdcInvestorPositionField { + ///Լ + TThostFtdcInstrumentIDType InstrumentID; + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///Ͷߴ + TThostFtdcInvestorIDType InvestorID; + ///ֲֶշ + TThostFtdcPosiDirectionType PosiDirection; + ///Ͷױ־ + TThostFtdcHedgeFlagType HedgeFlag; + ///ֲ + TThostFtdcPositionDateType PositionDate; + ///ճֲ + TThostFtdcVolumeType YdPosition; + ///ճֲ + TThostFtdcVolumeType Position; + ///ͷ + TThostFtdcVolumeType LongFrozen; + ///ͷ + TThostFtdcVolumeType ShortFrozen; + ///ֶ + TThostFtdcMoneyType LongFrozenAmount; + ///ֶ + TThostFtdcMoneyType ShortFrozenAmount; + /// + TThostFtdcVolumeType OpenVolume; + ///ƽ + TThostFtdcVolumeType CloseVolume; + ///ֽ + TThostFtdcMoneyType OpenAmount; + ///ƽֽ + TThostFtdcMoneyType CloseAmount; + ///ֲֳɱ + TThostFtdcMoneyType PositionCost; + ///ϴռõı֤ + TThostFtdcMoneyType PreMargin; + ///ռõı֤ + TThostFtdcMoneyType UseMargin; + ///ı֤ + TThostFtdcMoneyType FrozenMargin; + ///ʽ + TThostFtdcMoneyType FrozenCash; + /// + TThostFtdcMoneyType FrozenCommission; + ///ʽ + TThostFtdcMoneyType CashIn; + /// + TThostFtdcMoneyType Commission; + ///ƽӯ + TThostFtdcMoneyType CloseProfit; + ///ֲӯ + TThostFtdcMoneyType PositionProfit; + ///ϴν + TThostFtdcPriceType PreSettlementPrice; + ///ν + TThostFtdcPriceType SettlementPrice; + /// + TThostFtdcDateType TradingDay; + /// + TThostFtdcSettlementIDType SettlementID; + ///ֳɱ + TThostFtdcMoneyType OpenCost; + ///֤ + TThostFtdcMoneyType ExchangeMargin; + ///ϳɽγɵijֲ + TThostFtdcVolumeType CombPosition; + ///϶ͷ + TThostFtdcVolumeType CombLongFrozen; + ///Ͽͷ + TThostFtdcVolumeType CombShortFrozen; + ///նƽӯ + TThostFtdcMoneyType CloseProfitByDate; + ///ʶԳƽӯ + TThostFtdcMoneyType CloseProfitByTrade; + ///ճֲ + TThostFtdcVolumeType TodayPosition; + ///֤ + TThostFtdcRatioType MarginRateByMoney; + ///֤() + TThostFtdcRatioType MarginRateByVolume; + ///ִж + TThostFtdcVolumeType StrikeFrozen; + ///ִж + TThostFtdcMoneyType StrikeFrozenAmount; + ///ִж + TThostFtdcVolumeType AbandonFrozen; +}; + +///Լ֤ +struct CThostFtdcInstrumentMarginRateField { + ///Լ + TThostFtdcInstrumentIDType InstrumentID; + ///Ͷ߷Χ + TThostFtdcInvestorRangeType InvestorRange; + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///Ͷߴ + TThostFtdcInvestorIDType InvestorID; + ///Ͷױ־ + TThostFtdcHedgeFlagType HedgeFlag; + ///ͷ֤ + TThostFtdcRatioType LongMarginRatioByMoney; + ///ͷ֤ + TThostFtdcMoneyType LongMarginRatioByVolume; + ///ͷ֤ + TThostFtdcRatioType ShortMarginRatioByMoney; + ///ͷ֤ + TThostFtdcMoneyType ShortMarginRatioByVolume; + ///ǷԽȡ + TThostFtdcBoolType IsRelative; +}; + +///Լ +struct CThostFtdcInstrumentCommissionRateField { + ///Լ + TThostFtdcInstrumentIDType InstrumentID; + ///Ͷ߷Χ + TThostFtdcInvestorRangeType InvestorRange; + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///Ͷߴ + TThostFtdcInvestorIDType InvestorID; + /// + TThostFtdcRatioType OpenRatioByMoney; + /// + TThostFtdcRatioType OpenRatioByVolume; + ///ƽ + TThostFtdcRatioType CloseRatioByMoney; + ///ƽ + TThostFtdcRatioType CloseRatioByVolume; + ///ƽ + TThostFtdcRatioType CloseTodayRatioByMoney; + ///ƽ + TThostFtdcRatioType CloseTodayRatioByVolume; +}; + +/// +struct CThostFtdcDepthMarketDataField { + /// + TThostFtdcDateType TradingDay; + ///Լ + TThostFtdcInstrumentIDType InstrumentID; + /// + TThostFtdcExchangeIDType ExchangeID; + ///ԼڽĴ + TThostFtdcExchangeInstIDType ExchangeInstID; + ///¼ + TThostFtdcPriceType LastPrice; + ///ϴν + TThostFtdcPriceType PreSettlementPrice; + /// + TThostFtdcPriceType PreClosePrice; + ///ֲ + TThostFtdcLargeVolumeType PreOpenInterest; + /// + TThostFtdcPriceType OpenPrice; + ///߼ + TThostFtdcPriceType HighestPrice; + ///ͼ + TThostFtdcPriceType LowestPrice; + /// + TThostFtdcVolumeType Volume; + ///ɽ + TThostFtdcMoneyType Turnover; + ///ֲ + TThostFtdcLargeVolumeType OpenInterest; + /// + TThostFtdcPriceType ClosePrice; + ///ν + TThostFtdcPriceType SettlementPrice; + ///ͣ + TThostFtdcPriceType UpperLimitPrice; + ///ͣ + TThostFtdcPriceType LowerLimitPrice; + ///ʵ + TThostFtdcRatioType PreDelta; + ///ʵ + TThostFtdcRatioType CurrDelta; + ///޸ʱ + TThostFtdcTimeType UpdateTime; + ///޸ĺ + TThostFtdcMillisecType UpdateMillisec; + ///һ + TThostFtdcPriceType BidPrice1; + ///һ + TThostFtdcVolumeType BidVolume1; + ///һ + TThostFtdcPriceType AskPrice1; + ///һ + TThostFtdcVolumeType AskVolume1; + ///۶ + TThostFtdcPriceType BidPrice2; + /// + TThostFtdcVolumeType BidVolume2; + ///۶ + TThostFtdcPriceType AskPrice2; + /// + TThostFtdcVolumeType AskVolume2; + /// + TThostFtdcPriceType BidPrice3; + /// + TThostFtdcVolumeType BidVolume3; + /// + TThostFtdcPriceType AskPrice3; + /// + TThostFtdcVolumeType AskVolume3; + /// + TThostFtdcPriceType BidPrice4; + /// + TThostFtdcVolumeType BidVolume4; + /// + TThostFtdcPriceType AskPrice4; + /// + TThostFtdcVolumeType AskVolume4; + /// + TThostFtdcPriceType BidPrice5; + /// + TThostFtdcVolumeType BidVolume5; + /// + TThostFtdcPriceType AskPrice5; + /// + TThostFtdcVolumeType AskVolume5; + ///վ + TThostFtdcPriceType AveragePrice; + ///ҵ + TThostFtdcDateType ActionDay; +}; + +///ͶߺԼȨ +struct CThostFtdcInstrumentTradingRightField { + ///Լ + TThostFtdcInstrumentIDType InstrumentID; + ///Ͷ߷Χ + TThostFtdcInvestorRangeType InvestorRange; + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///Ͷߴ + TThostFtdcInvestorIDType InvestorID; + ///Ȩ + TThostFtdcTradingRightType TradingRight; +}; + +///͹˾û +struct CThostFtdcBrokerUserField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///û + TThostFtdcUserIDType UserID; + ///û + TThostFtdcUserNameType UserName; + ///û + TThostFtdcUserTypeType UserType; + ///ǷԾ + TThostFtdcBoolType IsActive; + ///Ƿʹ + TThostFtdcBoolType IsUsingOTP; +}; + +///͹˾û +struct CThostFtdcBrokerUserPasswordField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///û + TThostFtdcUserIDType UserID; + /// + TThostFtdcPasswordType Password; +}; + +///͹˾ûȨ +struct CThostFtdcBrokerUserFunctionField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///û + TThostFtdcUserIDType UserID; + ///͹˾ܴ + TThostFtdcBrokerFunctionCodeType BrokerFunctionCode; +}; + +///Ա̻ +struct CThostFtdcTraderOfferField { + /// + TThostFtdcExchangeIDType ExchangeID; + ///Ա + TThostFtdcTraderIDType TraderID; + ///Ա + TThostFtdcParticipantIDType ParticipantID; + /// + TThostFtdcPasswordType Password; + ///װ + TThostFtdcInstallIDType InstallID; + ///ر + TThostFtdcOrderLocalIDType OrderLocalID; + ///Ա״̬ + TThostFtdcTraderConnectStatusType TraderConnectStatus; + /// + TThostFtdcDateType ConnectRequestDate; + ///ʱ + TThostFtdcTimeType ConnectRequestTime; + ///ϴα + TThostFtdcDateType LastReportDate; + ///ϴαʱ + TThostFtdcTimeType LastReportTime; + /// + TThostFtdcDateType ConnectDate; + ///ʱ + TThostFtdcTimeType ConnectTime; + /// + TThostFtdcDateType StartDate; + ///ʱ + TThostFtdcTimeType StartTime; + /// + TThostFtdcDateType TradingDay; + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///ϯλɽ + TThostFtdcTradeIDType MaxTradeID; + ///ϯλ󱨵 + TThostFtdcReturnCodeType MaxOrderMessageReference; +}; + +///Ͷ߽ +struct CThostFtdcSettlementInfoField { + /// + TThostFtdcDateType TradingDay; + /// + TThostFtdcSettlementIDType SettlementID; + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///Ͷߴ + TThostFtdcInvestorIDType InvestorID; + /// + TThostFtdcSequenceNoType SequenceNo; + ///Ϣ + TThostFtdcContentType Content; +}; + +///Լ֤ʵ +struct CThostFtdcInstrumentMarginRateAdjustField { + ///Լ + TThostFtdcInstrumentIDType InstrumentID; + ///Ͷ߷Χ + TThostFtdcInvestorRangeType InvestorRange; + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///Ͷߴ + TThostFtdcInvestorIDType InvestorID; + ///Ͷױ־ + TThostFtdcHedgeFlagType HedgeFlag; + ///ͷ֤ + TThostFtdcRatioType LongMarginRatioByMoney; + ///ͷ֤ + TThostFtdcMoneyType LongMarginRatioByVolume; + ///ͷ֤ + TThostFtdcRatioType ShortMarginRatioByMoney; + ///ͷ֤ + TThostFtdcMoneyType ShortMarginRatioByVolume; + ///ǷԽȡ + TThostFtdcBoolType IsRelative; +}; + +///֤ +struct CThostFtdcExchangeMarginRateField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///Լ + TThostFtdcInstrumentIDType InstrumentID; + ///Ͷױ־ + TThostFtdcHedgeFlagType HedgeFlag; + ///ͷ֤ + TThostFtdcRatioType LongMarginRatioByMoney; + ///ͷ֤ + TThostFtdcMoneyType LongMarginRatioByVolume; + ///ͷ֤ + TThostFtdcRatioType ShortMarginRatioByMoney; + ///ͷ֤ + TThostFtdcMoneyType ShortMarginRatioByVolume; +}; + +///֤ʵ +struct CThostFtdcExchangeMarginRateAdjustField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///Լ + TThostFtdcInstrumentIDType InstrumentID; + ///Ͷױ־ + TThostFtdcHedgeFlagType HedgeFlag; + ///潻Ͷ߶ͷ֤ + TThostFtdcRatioType LongMarginRatioByMoney; + ///潻Ͷ߶ͷ֤ + TThostFtdcMoneyType LongMarginRatioByVolume; + ///潻Ͷ߿ͷ֤ + TThostFtdcRatioType ShortMarginRatioByMoney; + ///潻Ͷ߿ͷ֤ + TThostFtdcMoneyType ShortMarginRatioByVolume; + ///ͷ֤ + TThostFtdcRatioType ExchLongMarginRatioByMoney; + ///ͷ֤ + TThostFtdcMoneyType ExchLongMarginRatioByVolume; + ///ͷ֤ + TThostFtdcRatioType ExchShortMarginRatioByMoney; + ///ͷ֤ + TThostFtdcMoneyType ExchShortMarginRatioByVolume; + ///潻Ͷ߶ͷ֤ + TThostFtdcRatioType NoLongMarginRatioByMoney; + ///潻Ͷ߶ͷ֤ + TThostFtdcMoneyType NoLongMarginRatioByVolume; + ///潻Ͷ߿ͷ֤ + TThostFtdcRatioType NoShortMarginRatioByMoney; + ///潻Ͷ߿ͷ֤ + TThostFtdcMoneyType NoShortMarginRatioByVolume; +}; + +/// +struct CThostFtdcExchangeRateField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///Դ + TThostFtdcCurrencyIDType FromCurrencyID; + ///Դֵλ + TThostFtdcCurrencyUnitType FromCurrencyUnit; + ///Ŀ + TThostFtdcCurrencyIDType ToCurrencyID; + /// + TThostFtdcExchangeRateType ExchangeRate; +}; + +/// +struct CThostFtdcSettlementRefField { + /// + TThostFtdcDateType TradingDay; + /// + TThostFtdcSettlementIDType SettlementID; +}; + +///ǰʱ +struct CThostFtdcCurrentTimeField { + ///ǰ + TThostFtdcDateType CurrDate; + ///ǰʱ + TThostFtdcTimeType CurrTime; + ///ǰʱ䣨룩 + TThostFtdcMillisecType CurrMillisec; + ///ҵ + TThostFtdcDateType ActionDay; +}; + +///ͨѶ׶ +struct CThostFtdcCommPhaseField { + /// + TThostFtdcDateType TradingDay; + ///ͨѶʱα + TThostFtdcCommPhaseNoType CommPhaseNo; + ///ϵͳ + TThostFtdcSystemIDType SystemID; +}; + +///¼Ϣ +struct CThostFtdcLoginInfoField { + ///ǰñ + TThostFtdcFrontIDType FrontID; + ///Ự + TThostFtdcSessionIDType SessionID; + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///û + TThostFtdcUserIDType UserID; + ///¼ + TThostFtdcDateType LoginDate; + ///¼ʱ + TThostFtdcTimeType LoginTime; + /// IPַ + TThostFtdcIPAddressType IPAddress; + ///û˲ƷϢ + TThostFtdcProductInfoType UserProductInfo; + ///ӿڶ˲ƷϢ + TThostFtdcProductInfoType InterfaceProductInfo; + ///ЭϢ + TThostFtdcProtocolInfoType ProtocolInfo; + ///ϵͳ + TThostFtdcSystemNameType SystemName; + /// + TThostFtdcPasswordType Password; + ///󱨵 + TThostFtdcOrderRefType MaxOrderRef; + ///ʱ + TThostFtdcTimeType SHFETime; + ///ʱ + TThostFtdcTimeType DCETime; + ///֣ʱ + TThostFtdcTimeType CZCETime; + ///нʱ + TThostFtdcTimeType FFEXTime; + /// Macַ + TThostFtdcMacAddressType MacAddress; + ///̬ + TThostFtdcPasswordType OneTimePassword; + ///Դʱ + TThostFtdcTimeType INETime; + ///ѯʱǷҪ + TThostFtdcBoolType IsQryControl; + ///¼ע + TThostFtdcLoginRemarkType LoginRemark; +}; + +///¼Ϣ +struct CThostFtdcLogoutAllField { + ///ǰñ + TThostFtdcFrontIDType FrontID; + ///Ự + TThostFtdcSessionIDType SessionID; + ///ϵͳ + TThostFtdcSystemNameType SystemName; +}; + +///ǰ״̬ +struct CThostFtdcFrontStatusField { + ///ǰñ + TThostFtdcFrontIDType FrontID; + ///ϴα + TThostFtdcDateType LastReportDate; + ///ϴαʱ + TThostFtdcTimeType LastReportTime; + ///ǷԾ + TThostFtdcBoolType IsActive; +}; + +///û +struct CThostFtdcUserPasswordUpdateField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///û + TThostFtdcUserIDType UserID; + ///ԭĿ + TThostFtdcPasswordType OldPassword; + ///µĿ + TThostFtdcPasswordType NewPassword; +}; + +///뱨 +struct CThostFtdcInputOrderField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///Ͷߴ + TThostFtdcInvestorIDType InvestorID; + ///Լ + TThostFtdcInstrumentIDType InstrumentID; + /// + TThostFtdcOrderRefType OrderRef; + ///û + TThostFtdcUserIDType UserID; + ///۸ + TThostFtdcOrderPriceTypeType OrderPriceType; + /// + TThostFtdcDirectionType Direction; + ///Ͽƽ־ + TThostFtdcCombOffsetFlagType CombOffsetFlag; + ///Ͷױ־ + TThostFtdcCombHedgeFlagType CombHedgeFlag; + ///۸ + TThostFtdcPriceType LimitPrice; + /// + TThostFtdcVolumeType VolumeTotalOriginal; + ///Ч + TThostFtdcTimeConditionType TimeCondition; + /// GTD + TThostFtdcDateType GTDDate; + ///ɽ + TThostFtdcVolumeConditionType VolumeCondition; + ///Сɽ + TThostFtdcVolumeType MinVolume; + /// + TThostFtdcContingentConditionType ContingentCondition; + ///ֹ + TThostFtdcPriceType StopPrice; + ///ǿƽԭ + TThostFtdcForceCloseReasonType ForceCloseReason; + ///Զ־ + TThostFtdcBoolType IsAutoSuspend; + ///ҵԪ + TThostFtdcBusinessUnitType BusinessUnit; + /// + TThostFtdcRequestIDType RequestID; + ///ûǿ־ + TThostFtdcBoolType UserForceClose; + ///־ + TThostFtdcBoolType IsSwapOrder; + /// + TThostFtdcExchangeIDType ExchangeID; + ///ͶʵԪ + TThostFtdcInvestUnitIDType InvestUnitID; + ///ʽ˺ + TThostFtdcAccountIDType AccountID; + ///ִ + TThostFtdcCurrencyIDType CurrencyID; + ///ױ + TThostFtdcClientIDType ClientID; + /// IPַ + TThostFtdcIPAddressType IPAddress; + /// Macַ + TThostFtdcMacAddressType MacAddress; +}; + +/// +struct CThostFtdcOrderField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///Ͷߴ + TThostFtdcInvestorIDType InvestorID; + ///Լ + TThostFtdcInstrumentIDType InstrumentID; + /// + TThostFtdcOrderRefType OrderRef; + ///û + TThostFtdcUserIDType UserID; + ///۸ + TThostFtdcOrderPriceTypeType OrderPriceType; + /// + TThostFtdcDirectionType Direction; + ///Ͽƽ־ + TThostFtdcCombOffsetFlagType CombOffsetFlag; + ///Ͷױ־ + TThostFtdcCombHedgeFlagType CombHedgeFlag; + ///۸ + TThostFtdcPriceType LimitPrice; + /// + TThostFtdcVolumeType VolumeTotalOriginal; + ///Ч + TThostFtdcTimeConditionType TimeCondition; + /// GTD + TThostFtdcDateType GTDDate; + ///ɽ + TThostFtdcVolumeConditionType VolumeCondition; + ///Сɽ + TThostFtdcVolumeType MinVolume; + /// + TThostFtdcContingentConditionType ContingentCondition; + ///ֹ + TThostFtdcPriceType StopPrice; + ///ǿƽԭ + TThostFtdcForceCloseReasonType ForceCloseReason; + ///Զ־ + TThostFtdcBoolType IsAutoSuspend; + ///ҵԪ + TThostFtdcBusinessUnitType BusinessUnit; + /// + TThostFtdcRequestIDType RequestID; + ///ر + TThostFtdcOrderLocalIDType OrderLocalID; + /// + TThostFtdcExchangeIDType ExchangeID; + ///Ա + TThostFtdcParticipantIDType ParticipantID; + ///ͻ + TThostFtdcClientIDType ClientID; + ///ԼڽĴ + TThostFtdcExchangeInstIDType ExchangeInstID; + ///Ա + TThostFtdcTraderIDType TraderID; + ///װ + TThostFtdcInstallIDType InstallID; + ///ύ״̬ + TThostFtdcOrderSubmitStatusType OrderSubmitStatus; + ///ʾ + TThostFtdcSequenceNoType NotifySequence; + /// + TThostFtdcDateType TradingDay; + /// + TThostFtdcSettlementIDType SettlementID; + /// + TThostFtdcOrderSysIDType OrderSysID; + ///Դ + TThostFtdcOrderSourceType OrderSource; + ///״̬ + TThostFtdcOrderStatusType OrderStatus; + /// + TThostFtdcOrderTypeType OrderType; + ///ɽ + TThostFtdcVolumeType VolumeTraded; + ///ʣ + TThostFtdcVolumeType VolumeTotal; + /// + TThostFtdcDateType InsertDate; + ///ίʱ + TThostFtdcTimeType InsertTime; + ///ʱ + TThostFtdcTimeType ActiveTime; + ///ʱ + TThostFtdcTimeType SuspendTime; + ///޸ʱ + TThostFtdcTimeType UpdateTime; + ///ʱ + TThostFtdcTimeType CancelTime; + ///޸ĽԱ + TThostFtdcTraderIDType ActiveTraderID; + ///Ա + TThostFtdcParticipantIDType ClearingPartID; + /// + TThostFtdcSequenceNoType SequenceNo; + ///ǰñ + TThostFtdcFrontIDType FrontID; + ///Ự + TThostFtdcSessionIDType SessionID; + ///û˲ƷϢ + TThostFtdcProductInfoType UserProductInfo; + ///״̬Ϣ + TThostFtdcErrorMsgType StatusMsg; + ///ûǿ־ + TThostFtdcBoolType UserForceClose; + ///û + TThostFtdcUserIDType ActiveUserID; + ///͹˾ + TThostFtdcSequenceNoType BrokerOrderSeq; + ///ر + TThostFtdcOrderSysIDType RelativeOrderSysID; + ///֣ɽ + TThostFtdcVolumeType ZCETotalTradedVolume; + ///־ + TThostFtdcBoolType IsSwapOrder; + ///Ӫҵ + TThostFtdcBranchIDType BranchID; + ///ͶʵԪ + TThostFtdcInvestUnitIDType InvestUnitID; + ///ʽ˺ + TThostFtdcAccountIDType AccountID; + ///ִ + TThostFtdcCurrencyIDType CurrencyID; + /// IPַ + TThostFtdcIPAddressType IPAddress; + /// Macַ + TThostFtdcMacAddressType MacAddress; +}; + +/// +struct CThostFtdcExchangeOrderField { + ///۸ + TThostFtdcOrderPriceTypeType OrderPriceType; + /// + TThostFtdcDirectionType Direction; + ///Ͽƽ־ + TThostFtdcCombOffsetFlagType CombOffsetFlag; + ///Ͷױ־ + TThostFtdcCombHedgeFlagType CombHedgeFlag; + ///۸ + TThostFtdcPriceType LimitPrice; + /// + TThostFtdcVolumeType VolumeTotalOriginal; + ///Ч + TThostFtdcTimeConditionType TimeCondition; + /// GTD + TThostFtdcDateType GTDDate; + ///ɽ + TThostFtdcVolumeConditionType VolumeCondition; + ///Сɽ + TThostFtdcVolumeType MinVolume; + /// + TThostFtdcContingentConditionType ContingentCondition; + ///ֹ + TThostFtdcPriceType StopPrice; + ///ǿƽԭ + TThostFtdcForceCloseReasonType ForceCloseReason; + ///Զ־ + TThostFtdcBoolType IsAutoSuspend; + ///ҵԪ + TThostFtdcBusinessUnitType BusinessUnit; + /// + TThostFtdcRequestIDType RequestID; + ///ر + TThostFtdcOrderLocalIDType OrderLocalID; + /// + TThostFtdcExchangeIDType ExchangeID; + ///Ա + TThostFtdcParticipantIDType ParticipantID; + ///ͻ + TThostFtdcClientIDType ClientID; + ///ԼڽĴ + TThostFtdcExchangeInstIDType ExchangeInstID; + ///Ա + TThostFtdcTraderIDType TraderID; + ///װ + TThostFtdcInstallIDType InstallID; + ///ύ״̬ + TThostFtdcOrderSubmitStatusType OrderSubmitStatus; + ///ʾ + TThostFtdcSequenceNoType NotifySequence; + /// + TThostFtdcDateType TradingDay; + /// + TThostFtdcSettlementIDType SettlementID; + /// + TThostFtdcOrderSysIDType OrderSysID; + ///Դ + TThostFtdcOrderSourceType OrderSource; + ///״̬ + TThostFtdcOrderStatusType OrderStatus; + /// + TThostFtdcOrderTypeType OrderType; + ///ɽ + TThostFtdcVolumeType VolumeTraded; + ///ʣ + TThostFtdcVolumeType VolumeTotal; + /// + TThostFtdcDateType InsertDate; + ///ίʱ + TThostFtdcTimeType InsertTime; + ///ʱ + TThostFtdcTimeType ActiveTime; + ///ʱ + TThostFtdcTimeType SuspendTime; + ///޸ʱ + TThostFtdcTimeType UpdateTime; + ///ʱ + TThostFtdcTimeType CancelTime; + ///޸ĽԱ + TThostFtdcTraderIDType ActiveTraderID; + ///Ա + TThostFtdcParticipantIDType ClearingPartID; + /// + TThostFtdcSequenceNoType SequenceNo; + ///Ӫҵ + TThostFtdcBranchIDType BranchID; + /// IPַ + TThostFtdcIPAddressType IPAddress; + /// Macַ + TThostFtdcMacAddressType MacAddress; +}; + +///ʧ +struct CThostFtdcExchangeOrderInsertErrorField { + /// + TThostFtdcExchangeIDType ExchangeID; + ///Ա + TThostFtdcParticipantIDType ParticipantID; + ///Ա + TThostFtdcTraderIDType TraderID; + ///װ + TThostFtdcInstallIDType InstallID; + ///ر + TThostFtdcOrderLocalIDType OrderLocalID; + /// + TThostFtdcErrorIDType ErrorID; + ///Ϣ + TThostFtdcErrorMsgType ErrorMsg; +}; + +///뱨 +struct CThostFtdcInputOrderActionField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///Ͷߴ + TThostFtdcInvestorIDType InvestorID; + /// + TThostFtdcOrderActionRefType OrderActionRef; + /// + TThostFtdcOrderRefType OrderRef; + /// + TThostFtdcRequestIDType RequestID; + ///ǰñ + TThostFtdcFrontIDType FrontID; + ///Ự + TThostFtdcSessionIDType SessionID; + /// + TThostFtdcExchangeIDType ExchangeID; + /// + TThostFtdcOrderSysIDType OrderSysID; + ///־ + TThostFtdcActionFlagType ActionFlag; + ///۸ + TThostFtdcPriceType LimitPrice; + ///仯 + TThostFtdcVolumeType VolumeChange; + ///û + TThostFtdcUserIDType UserID; + ///Լ + TThostFtdcInstrumentIDType InstrumentID; + ///ͶʵԪ + TThostFtdcInvestUnitIDType InvestUnitID; + /// IPַ + TThostFtdcIPAddressType IPAddress; + /// Macַ + TThostFtdcMacAddressType MacAddress; +}; + +/// +struct CThostFtdcOrderActionField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///Ͷߴ + TThostFtdcInvestorIDType InvestorID; + /// + TThostFtdcOrderActionRefType OrderActionRef; + /// + TThostFtdcOrderRefType OrderRef; + /// + TThostFtdcRequestIDType RequestID; + ///ǰñ + TThostFtdcFrontIDType FrontID; + ///Ự + TThostFtdcSessionIDType SessionID; + /// + TThostFtdcExchangeIDType ExchangeID; + /// + TThostFtdcOrderSysIDType OrderSysID; + ///־ + TThostFtdcActionFlagType ActionFlag; + ///۸ + TThostFtdcPriceType LimitPrice; + ///仯 + TThostFtdcVolumeType VolumeChange; + /// + TThostFtdcDateType ActionDate; + ///ʱ + TThostFtdcTimeType ActionTime; + ///Ա + TThostFtdcTraderIDType TraderID; + ///װ + TThostFtdcInstallIDType InstallID; + ///ر + TThostFtdcOrderLocalIDType OrderLocalID; + ///ر + TThostFtdcOrderLocalIDType ActionLocalID; + ///Ա + TThostFtdcParticipantIDType ParticipantID; + ///ͻ + TThostFtdcClientIDType ClientID; + ///ҵԪ + TThostFtdcBusinessUnitType BusinessUnit; + ///״̬ + TThostFtdcOrderActionStatusType OrderActionStatus; + ///û + TThostFtdcUserIDType UserID; + ///״̬Ϣ + TThostFtdcErrorMsgType StatusMsg; + ///Լ + TThostFtdcInstrumentIDType InstrumentID; + ///Ӫҵ + TThostFtdcBranchIDType BranchID; + ///ͶʵԪ + TThostFtdcInvestUnitIDType InvestUnitID; + /// IPַ + TThostFtdcIPAddressType IPAddress; + /// Macַ + TThostFtdcMacAddressType MacAddress; +}; + +/// +struct CThostFtdcExchangeOrderActionField { + /// + TThostFtdcExchangeIDType ExchangeID; + /// + TThostFtdcOrderSysIDType OrderSysID; + ///־ + TThostFtdcActionFlagType ActionFlag; + ///۸ + TThostFtdcPriceType LimitPrice; + ///仯 + TThostFtdcVolumeType VolumeChange; + /// + TThostFtdcDateType ActionDate; + ///ʱ + TThostFtdcTimeType ActionTime; + ///Ա + TThostFtdcTraderIDType TraderID; + ///װ + TThostFtdcInstallIDType InstallID; + ///ر + TThostFtdcOrderLocalIDType OrderLocalID; + ///ر + TThostFtdcOrderLocalIDType ActionLocalID; + ///Ա + TThostFtdcParticipantIDType ParticipantID; + ///ͻ + TThostFtdcClientIDType ClientID; + ///ҵԪ + TThostFtdcBusinessUnitType BusinessUnit; + ///״̬ + TThostFtdcOrderActionStatusType OrderActionStatus; + ///û + TThostFtdcUserIDType UserID; + ///Ӫҵ + TThostFtdcBranchIDType BranchID; + /// IPַ + TThostFtdcIPAddressType IPAddress; + /// Macַ + TThostFtdcMacAddressType MacAddress; +}; + +///ʧ +struct CThostFtdcExchangeOrderActionErrorField { + /// + TThostFtdcExchangeIDType ExchangeID; + /// + TThostFtdcOrderSysIDType OrderSysID; + ///Ա + TThostFtdcTraderIDType TraderID; + ///װ + TThostFtdcInstallIDType InstallID; + ///ر + TThostFtdcOrderLocalIDType OrderLocalID; + ///ر + TThostFtdcOrderLocalIDType ActionLocalID; + /// + TThostFtdcErrorIDType ErrorID; + ///Ϣ + TThostFtdcErrorMsgType ErrorMsg; +}; + +///ɽ +struct CThostFtdcExchangeTradeField { + /// + TThostFtdcExchangeIDType ExchangeID; + ///ɽ + TThostFtdcTradeIDType TradeID; + /// + TThostFtdcDirectionType Direction; + /// + TThostFtdcOrderSysIDType OrderSysID; + ///Ա + TThostFtdcParticipantIDType ParticipantID; + ///ͻ + TThostFtdcClientIDType ClientID; + ///׽ɫ + TThostFtdcTradingRoleType TradingRole; + ///ԼڽĴ + TThostFtdcExchangeInstIDType ExchangeInstID; + ///ƽ־ + TThostFtdcOffsetFlagType OffsetFlag; + ///Ͷױ־ + TThostFtdcHedgeFlagType HedgeFlag; + ///۸ + TThostFtdcPriceType Price; + /// + TThostFtdcVolumeType Volume; + ///ɽʱ + TThostFtdcDateType TradeDate; + ///ɽʱ + TThostFtdcTimeType TradeTime; + ///ɽ + TThostFtdcTradeTypeType TradeType; + ///ɽԴ + TThostFtdcPriceSourceType PriceSource; + ///Ա + TThostFtdcTraderIDType TraderID; + ///ر + TThostFtdcOrderLocalIDType OrderLocalID; + ///Ա + TThostFtdcParticipantIDType ClearingPartID; + ///ҵԪ + TThostFtdcBusinessUnitType BusinessUnit; + /// + TThostFtdcSequenceNoType SequenceNo; + ///ɽԴ + TThostFtdcTradeSourceType TradeSource; +}; + +///ɽ +struct CThostFtdcTradeField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///Ͷߴ + TThostFtdcInvestorIDType InvestorID; + ///Լ + TThostFtdcInstrumentIDType InstrumentID; + /// + TThostFtdcOrderRefType OrderRef; + ///û + TThostFtdcUserIDType UserID; + /// + TThostFtdcExchangeIDType ExchangeID; + ///ɽ + TThostFtdcTradeIDType TradeID; + /// + TThostFtdcDirectionType Direction; + /// + TThostFtdcOrderSysIDType OrderSysID; + ///Ա + TThostFtdcParticipantIDType ParticipantID; + ///ͻ + TThostFtdcClientIDType ClientID; + ///׽ɫ + TThostFtdcTradingRoleType TradingRole; + ///ԼڽĴ + TThostFtdcExchangeInstIDType ExchangeInstID; + ///ƽ־ + TThostFtdcOffsetFlagType OffsetFlag; + ///Ͷױ־ + TThostFtdcHedgeFlagType HedgeFlag; + ///۸ + TThostFtdcPriceType Price; + /// + TThostFtdcVolumeType Volume; + ///ɽʱ + TThostFtdcDateType TradeDate; + ///ɽʱ + TThostFtdcTimeType TradeTime; + ///ɽ + TThostFtdcTradeTypeType TradeType; + ///ɽԴ + TThostFtdcPriceSourceType PriceSource; + ///Ա + TThostFtdcTraderIDType TraderID; + ///ر + TThostFtdcOrderLocalIDType OrderLocalID; + ///Ա + TThostFtdcParticipantIDType ClearingPartID; + ///ҵԪ + TThostFtdcBusinessUnitType BusinessUnit; + /// + TThostFtdcSequenceNoType SequenceNo; + /// + TThostFtdcDateType TradingDay; + /// + TThostFtdcSettlementIDType SettlementID; + ///͹˾ + TThostFtdcSequenceNoType BrokerOrderSeq; + ///ɽԴ + TThostFtdcTradeSourceType TradeSource; +}; + +///ûỰ +struct CThostFtdcUserSessionField { + ///ǰñ + TThostFtdcFrontIDType FrontID; + ///Ự + TThostFtdcSessionIDType SessionID; + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///û + TThostFtdcUserIDType UserID; + ///¼ + TThostFtdcDateType LoginDate; + ///¼ʱ + TThostFtdcTimeType LoginTime; + /// IPַ + TThostFtdcIPAddressType IPAddress; + ///û˲ƷϢ + TThostFtdcProductInfoType UserProductInfo; + ///ӿڶ˲ƷϢ + TThostFtdcProductInfoType InterfaceProductInfo; + ///ЭϢ + TThostFtdcProtocolInfoType ProtocolInfo; + /// Macַ + TThostFtdcMacAddressType MacAddress; + ///¼ע + TThostFtdcLoginRemarkType LoginRemark; +}; + +///ѯ󱨵 +struct CThostFtdcQueryMaxOrderVolumeField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///Ͷߴ + TThostFtdcInvestorIDType InvestorID; + ///Լ + TThostFtdcInstrumentIDType InstrumentID; + /// + TThostFtdcDirectionType Direction; + ///ƽ־ + TThostFtdcOffsetFlagType OffsetFlag; + ///Ͷױ־ + TThostFtdcHedgeFlagType HedgeFlag; + /// + TThostFtdcVolumeType MaxVolume; +}; + +///Ͷ߽ȷϢ +struct CThostFtdcSettlementInfoConfirmField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///Ͷߴ + TThostFtdcInvestorIDType InvestorID; + ///ȷ + TThostFtdcDateType ConfirmDate; + ///ȷʱ + TThostFtdcTimeType ConfirmTime; +}; + +///ͬ +struct CThostFtdcSyncDepositField { + ///ˮ + TThostFtdcDepositSeqNoType DepositSeqNo; + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///Ͷߴ + TThostFtdcInvestorIDType InvestorID; + /// + TThostFtdcMoneyType Deposit; + ///Ƿǿƽ + TThostFtdcBoolType IsForce; + ///ִ + TThostFtdcCurrencyIDType CurrencyID; +}; + +///Ѻͬ +struct CThostFtdcSyncFundMortgageField { + ///Ѻˮ + TThostFtdcDepositSeqNoType MortgageSeqNo; + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///Ͷߴ + TThostFtdcInvestorIDType InvestorID; + ///Դ + TThostFtdcCurrencyIDType FromCurrencyID; + ///Ѻ + TThostFtdcMoneyType MortgageAmount; + ///Ŀ + TThostFtdcCurrencyIDType ToCurrencyID; +}; + +///͹˾ͬ +struct CThostFtdcBrokerSyncField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; +}; + +///ͬеͶ +struct CThostFtdcSyncingInvestorField { + ///Ͷߴ + TThostFtdcInvestorIDType InvestorID; + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///Ͷ߷ + TThostFtdcInvestorIDType InvestorGroupID; + ///Ͷ + TThostFtdcPartyNameType InvestorName; + ///֤ + TThostFtdcIdCardTypeType IdentifiedCardType; + ///֤ + TThostFtdcIdentifiedCardNoType IdentifiedCardNo; + ///ǷԾ + TThostFtdcBoolType IsActive; + ///ϵ绰 + TThostFtdcTelephoneType Telephone; + ///ͨѶַ + TThostFtdcAddressType Address; + /// + TThostFtdcDateType OpenDate; + ///ֻ + TThostFtdcMobileType Mobile; + ///ģ + TThostFtdcInvestorIDType CommModelID; + ///֤ģ + TThostFtdcInvestorIDType MarginModelID; +}; + +///ͬеĽ״ +struct CThostFtdcSyncingTradingCodeField { + ///Ͷߴ + TThostFtdcInvestorIDType InvestorID; + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + /// + TThostFtdcExchangeIDType ExchangeID; + ///ͻ + TThostFtdcClientIDType ClientID; + ///ǷԾ + TThostFtdcBoolType IsActive; + ///ױ + TThostFtdcClientIDTypeType ClientIDType; +}; + +///ͬеͶ߷ +struct CThostFtdcSyncingInvestorGroupField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///Ͷ߷ + TThostFtdcInvestorIDType InvestorGroupID; + ///Ͷ߷ + TThostFtdcInvestorGroupNameType InvestorGroupName; +}; + +///ͬеĽ˺ +struct CThostFtdcSyncingTradingAccountField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///Ͷʺ + TThostFtdcAccountIDType AccountID; + ///ϴѺ + TThostFtdcMoneyType PreMortgage; + ///ϴö + TThostFtdcMoneyType PreCredit; + ///ϴδ + TThostFtdcMoneyType PreDeposit; + ///ϴν׼ + TThostFtdcMoneyType PreBalance; + ///ϴռõı֤ + TThostFtdcMoneyType PreMargin; + ///Ϣ + TThostFtdcMoneyType InterestBase; + ///Ϣ + TThostFtdcMoneyType Interest; + /// + TThostFtdcMoneyType Deposit; + /// + TThostFtdcMoneyType Withdraw; + ///ı֤ + TThostFtdcMoneyType FrozenMargin; + ///ʽ + TThostFtdcMoneyType FrozenCash; + /// + TThostFtdcMoneyType FrozenCommission; + ///ǰ֤ܶ + TThostFtdcMoneyType CurrMargin; + ///ʽ + TThostFtdcMoneyType CashIn; + /// + TThostFtdcMoneyType Commission; + ///ƽӯ + TThostFtdcMoneyType CloseProfit; + ///ֲӯ + TThostFtdcMoneyType PositionProfit; + ///ڻ׼ + TThostFtdcMoneyType Balance; + ///ʽ + TThostFtdcMoneyType Available; + ///ȡʽ + TThostFtdcMoneyType WithdrawQuota; + ///׼ + TThostFtdcMoneyType Reserve; + /// + TThostFtdcDateType TradingDay; + /// + TThostFtdcSettlementIDType SettlementID; + ///ö + TThostFtdcMoneyType Credit; + ///Ѻ + TThostFtdcMoneyType Mortgage; + ///֤ + TThostFtdcMoneyType ExchangeMargin; + ///Ͷ߽֤ + TThostFtdcMoneyType DeliveryMargin; + ///֤ + TThostFtdcMoneyType ExchangeDeliveryMargin; + ///ڻ׼ + TThostFtdcMoneyType ReserveBalance; + ///ִ + TThostFtdcCurrencyIDType CurrencyID; + ///ϴλ + TThostFtdcMoneyType PreFundMortgageIn; + ///ϴλʳ + TThostFtdcMoneyType PreFundMortgageOut; + /// + TThostFtdcMoneyType FundMortgageIn; + ///ʳ + TThostFtdcMoneyType FundMortgageOut; + ///Ѻ + TThostFtdcMoneyType FundMortgageAvailable; + ///Ѻҽ + TThostFtdcMoneyType MortgageableFund; + ///Ʒռñ֤ + TThostFtdcMoneyType SpecProductMargin; + ///Ʒᱣ֤ + TThostFtdcMoneyType SpecProductFrozenMargin; + ///Ʒ + TThostFtdcMoneyType SpecProductCommission; + ///Ʒ + TThostFtdcMoneyType SpecProductFrozenCommission; + ///Ʒֲӯ + TThostFtdcMoneyType SpecProductPositionProfit; + ///Ʒƽӯ + TThostFtdcMoneyType SpecProductCloseProfit; + ///ݳֲӯ㷨Ʒֲӯ + TThostFtdcMoneyType SpecProductPositionProfitByAlg; + ///Ʒ֤ + TThostFtdcMoneyType SpecProductExchangeMargin; +}; + +///ͬеͶֲ߳ +struct CThostFtdcSyncingInvestorPositionField { + ///Լ + TThostFtdcInstrumentIDType InstrumentID; + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///Ͷߴ + TThostFtdcInvestorIDType InvestorID; + ///ֲֶշ + TThostFtdcPosiDirectionType PosiDirection; + ///Ͷױ־ + TThostFtdcHedgeFlagType HedgeFlag; + ///ֲ + TThostFtdcPositionDateType PositionDate; + ///ճֲ + TThostFtdcVolumeType YdPosition; + ///ճֲ + TThostFtdcVolumeType Position; + ///ͷ + TThostFtdcVolumeType LongFrozen; + ///ͷ + TThostFtdcVolumeType ShortFrozen; + ///ֶ + TThostFtdcMoneyType LongFrozenAmount; + ///ֶ + TThostFtdcMoneyType ShortFrozenAmount; + /// + TThostFtdcVolumeType OpenVolume; + ///ƽ + TThostFtdcVolumeType CloseVolume; + ///ֽ + TThostFtdcMoneyType OpenAmount; + ///ƽֽ + TThostFtdcMoneyType CloseAmount; + ///ֲֳɱ + TThostFtdcMoneyType PositionCost; + ///ϴռõı֤ + TThostFtdcMoneyType PreMargin; + ///ռõı֤ + TThostFtdcMoneyType UseMargin; + ///ı֤ + TThostFtdcMoneyType FrozenMargin; + ///ʽ + TThostFtdcMoneyType FrozenCash; + /// + TThostFtdcMoneyType FrozenCommission; + ///ʽ + TThostFtdcMoneyType CashIn; + /// + TThostFtdcMoneyType Commission; + ///ƽӯ + TThostFtdcMoneyType CloseProfit; + ///ֲӯ + TThostFtdcMoneyType PositionProfit; + ///ϴν + TThostFtdcPriceType PreSettlementPrice; + ///ν + TThostFtdcPriceType SettlementPrice; + /// + TThostFtdcDateType TradingDay; + /// + TThostFtdcSettlementIDType SettlementID; + ///ֳɱ + TThostFtdcMoneyType OpenCost; + ///֤ + TThostFtdcMoneyType ExchangeMargin; + ///ϳɽγɵijֲ + TThostFtdcVolumeType CombPosition; + ///϶ͷ + TThostFtdcVolumeType CombLongFrozen; + ///Ͽͷ + TThostFtdcVolumeType CombShortFrozen; + ///նƽӯ + TThostFtdcMoneyType CloseProfitByDate; + ///ʶԳƽӯ + TThostFtdcMoneyType CloseProfitByTrade; + ///ճֲ + TThostFtdcVolumeType TodayPosition; + ///֤ + TThostFtdcRatioType MarginRateByMoney; + ///֤() + TThostFtdcRatioType MarginRateByVolume; + ///ִж + TThostFtdcVolumeType StrikeFrozen; + ///ִж + TThostFtdcMoneyType StrikeFrozenAmount; + ///ִж + TThostFtdcVolumeType AbandonFrozen; +}; + +///ͬеĺԼ֤ +struct CThostFtdcSyncingInstrumentMarginRateField { + ///Լ + TThostFtdcInstrumentIDType InstrumentID; + ///Ͷ߷Χ + TThostFtdcInvestorRangeType InvestorRange; + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///Ͷߴ + TThostFtdcInvestorIDType InvestorID; + ///Ͷױ־ + TThostFtdcHedgeFlagType HedgeFlag; + ///ͷ֤ + TThostFtdcRatioType LongMarginRatioByMoney; + ///ͷ֤ + TThostFtdcMoneyType LongMarginRatioByVolume; + ///ͷ֤ + TThostFtdcRatioType ShortMarginRatioByMoney; + ///ͷ֤ + TThostFtdcMoneyType ShortMarginRatioByVolume; + ///ǷԽȡ + TThostFtdcBoolType IsRelative; +}; + +///ͬеĺԼ +struct CThostFtdcSyncingInstrumentCommissionRateField { + ///Լ + TThostFtdcInstrumentIDType InstrumentID; + ///Ͷ߷Χ + TThostFtdcInvestorRangeType InvestorRange; + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///Ͷߴ + TThostFtdcInvestorIDType InvestorID; + /// + TThostFtdcRatioType OpenRatioByMoney; + /// + TThostFtdcRatioType OpenRatioByVolume; + ///ƽ + TThostFtdcRatioType CloseRatioByMoney; + ///ƽ + TThostFtdcRatioType CloseRatioByVolume; + ///ƽ + TThostFtdcRatioType CloseTodayRatioByMoney; + ///ƽ + TThostFtdcRatioType CloseTodayRatioByVolume; +}; + +///ͬеĺԼȨ +struct CThostFtdcSyncingInstrumentTradingRightField { + ///Լ + TThostFtdcInstrumentIDType InstrumentID; + ///Ͷ߷Χ + TThostFtdcInvestorRangeType InvestorRange; + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///Ͷߴ + TThostFtdcInvestorIDType InvestorID; + ///Ȩ + TThostFtdcTradingRightType TradingRight; +}; + +///ѯ +struct CThostFtdcQryOrderField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///Ͷߴ + TThostFtdcInvestorIDType InvestorID; + ///Լ + TThostFtdcInstrumentIDType InstrumentID; + /// + TThostFtdcExchangeIDType ExchangeID; + /// + TThostFtdcOrderSysIDType OrderSysID; + ///ʼʱ + TThostFtdcTimeType InsertTimeStart; + ///ʱ + TThostFtdcTimeType InsertTimeEnd; +}; + +///ѯɽ +struct CThostFtdcQryTradeField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///Ͷߴ + TThostFtdcInvestorIDType InvestorID; + ///Լ + TThostFtdcInstrumentIDType InstrumentID; + /// + TThostFtdcExchangeIDType ExchangeID; + ///ɽ + TThostFtdcTradeIDType TradeID; + ///ʼʱ + TThostFtdcTimeType TradeTimeStart; + ///ʱ + TThostFtdcTimeType TradeTimeEnd; +}; + +///ѯͶֲ߳ +struct CThostFtdcQryInvestorPositionField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///Ͷߴ + TThostFtdcInvestorIDType InvestorID; + ///Լ + TThostFtdcInstrumentIDType InstrumentID; +}; + +///ѯʽ˻ +struct CThostFtdcQryTradingAccountField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///Ͷߴ + TThostFtdcInvestorIDType InvestorID; + ///ִ + TThostFtdcCurrencyIDType CurrencyID; +}; + +///ѯͶ +struct CThostFtdcQryInvestorField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///Ͷߴ + TThostFtdcInvestorIDType InvestorID; +}; + +///ѯױ +struct CThostFtdcQryTradingCodeField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///Ͷߴ + TThostFtdcInvestorIDType InvestorID; + /// + TThostFtdcExchangeIDType ExchangeID; + ///ͻ + TThostFtdcClientIDType ClientID; + ///ױ + TThostFtdcClientIDTypeType ClientIDType; +}; + +///ѯͶ +struct CThostFtdcQryInvestorGroupField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; +}; + +///ѯԼ֤ +struct CThostFtdcQryInstrumentMarginRateField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///Ͷߴ + TThostFtdcInvestorIDType InvestorID; + ///Լ + TThostFtdcInstrumentIDType InstrumentID; + ///Ͷױ־ + TThostFtdcHedgeFlagType HedgeFlag; +}; + +///ѯ +struct CThostFtdcQryInstrumentCommissionRateField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///Ͷߴ + TThostFtdcInvestorIDType InvestorID; + ///Լ + TThostFtdcInstrumentIDType InstrumentID; +}; + +///ѯԼȨ +struct CThostFtdcQryInstrumentTradingRightField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///Ͷߴ + TThostFtdcInvestorIDType InvestorID; + ///Լ + TThostFtdcInstrumentIDType InstrumentID; +}; + +///ѯ͹˾ +struct CThostFtdcQryBrokerField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; +}; + +///ѯԱ +struct CThostFtdcQryTraderField { + /// + TThostFtdcExchangeIDType ExchangeID; + ///Ա + TThostFtdcParticipantIDType ParticipantID; + ///Ա + TThostFtdcTraderIDType TraderID; +}; + +///ѯûȨ +struct CThostFtdcQrySuperUserFunctionField { + ///û + TThostFtdcUserIDType UserID; +}; + +///ѯûỰ +struct CThostFtdcQryUserSessionField { + ///ǰñ + TThostFtdcFrontIDType FrontID; + ///Ự + TThostFtdcSessionIDType SessionID; + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///û + TThostFtdcUserIDType UserID; +}; + +///ѯ͹˾Ա +struct CThostFtdcQryPartBrokerField { + /// + TThostFtdcExchangeIDType ExchangeID; + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///Ա + TThostFtdcParticipantIDType ParticipantID; +}; + +///ѯǰ״̬ +struct CThostFtdcQryFrontStatusField { + ///ǰñ + TThostFtdcFrontIDType FrontID; +}; + +///ѯ +struct CThostFtdcQryExchangeOrderField { + ///Ա + TThostFtdcParticipantIDType ParticipantID; + ///ͻ + TThostFtdcClientIDType ClientID; + ///ԼڽĴ + TThostFtdcExchangeInstIDType ExchangeInstID; + /// + TThostFtdcExchangeIDType ExchangeID; + ///Ա + TThostFtdcTraderIDType TraderID; +}; + +///ѯ +struct CThostFtdcQryOrderActionField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///Ͷߴ + TThostFtdcInvestorIDType InvestorID; + /// + TThostFtdcExchangeIDType ExchangeID; +}; + +///ѯ +struct CThostFtdcQryExchangeOrderActionField { + ///Ա + TThostFtdcParticipantIDType ParticipantID; + ///ͻ + TThostFtdcClientIDType ClientID; + /// + TThostFtdcExchangeIDType ExchangeID; + ///Ա + TThostFtdcTraderIDType TraderID; +}; + +///ѯû +struct CThostFtdcQrySuperUserField { + ///û + TThostFtdcUserIDType UserID; +}; + +///ѯ +struct CThostFtdcQryExchangeField { + /// + TThostFtdcExchangeIDType ExchangeID; +}; + +///ѯƷ +struct CThostFtdcQryProductField { + ///Ʒ + TThostFtdcInstrumentIDType ProductID; + ///Ʒ + TThostFtdcProductClassType ProductClass; +}; + +///ѯԼ +struct CThostFtdcQryInstrumentField { + ///Լ + TThostFtdcInstrumentIDType InstrumentID; + /// + TThostFtdcExchangeIDType ExchangeID; + ///ԼڽĴ + TThostFtdcExchangeInstIDType ExchangeInstID; + ///Ʒ + TThostFtdcInstrumentIDType ProductID; +}; + +///ѯ +struct CThostFtdcQryDepthMarketDataField { + ///Լ + TThostFtdcInstrumentIDType InstrumentID; +}; + +///ѯ͹˾û +struct CThostFtdcQryBrokerUserField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///û + TThostFtdcUserIDType UserID; +}; + +///ѯ͹˾ûȨ +struct CThostFtdcQryBrokerUserFunctionField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///û + TThostFtdcUserIDType UserID; +}; + +///ѯԱ̻ +struct CThostFtdcQryTraderOfferField { + /// + TThostFtdcExchangeIDType ExchangeID; + ///Ա + TThostFtdcParticipantIDType ParticipantID; + ///Ա + TThostFtdcTraderIDType TraderID; +}; + +///ѯˮ +struct CThostFtdcQrySyncDepositField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///ˮ + TThostFtdcDepositSeqNoType DepositSeqNo; +}; + +///ѯͶ߽ +struct CThostFtdcQrySettlementInfoField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///Ͷߴ + TThostFtdcInvestorIDType InvestorID; + /// + TThostFtdcDateType TradingDay; +}; + +///ѯ֤ +struct CThostFtdcQryExchangeMarginRateField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///Լ + TThostFtdcInstrumentIDType InstrumentID; + ///Ͷױ־ + TThostFtdcHedgeFlagType HedgeFlag; +}; + +///ѯ֤ +struct CThostFtdcQryExchangeMarginRateAdjustField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///Լ + TThostFtdcInstrumentIDType InstrumentID; + ///Ͷױ־ + TThostFtdcHedgeFlagType HedgeFlag; +}; + +///ѯ +struct CThostFtdcQryExchangeRateField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///Դ + TThostFtdcCurrencyIDType FromCurrencyID; + ///Ŀ + TThostFtdcCurrencyIDType ToCurrencyID; +}; + +///ѯѺˮ +struct CThostFtdcQrySyncFundMortgageField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///Ѻˮ + TThostFtdcDepositSeqNoType MortgageSeqNo; +}; + +///ѯ +struct CThostFtdcQryHisOrderField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///Ͷߴ + TThostFtdcInvestorIDType InvestorID; + ///Լ + TThostFtdcInstrumentIDType InstrumentID; + /// + TThostFtdcExchangeIDType ExchangeID; + /// + TThostFtdcOrderSysIDType OrderSysID; + ///ʼʱ + TThostFtdcTimeType InsertTimeStart; + ///ʱ + TThostFtdcTimeType InsertTimeEnd; + /// + TThostFtdcDateType TradingDay; + /// + TThostFtdcSettlementIDType SettlementID; +}; + +///ǰȨԼС֤ +struct CThostFtdcOptionInstrMiniMarginField { + ///Լ + TThostFtdcInstrumentIDType InstrumentID; + ///Ͷ߷Χ + TThostFtdcInvestorRangeType InvestorRange; + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///Ͷߴ + TThostFtdcInvestorIDType InvestorID; + ///λ֣ȨԼС֤ + TThostFtdcMoneyType MinMargin; + ///ȡֵʽ + TThostFtdcValueMethodType ValueMethod; + ///Ƿ潻ȡ + TThostFtdcBoolType IsRelative; +}; + +///ǰȨԼ֤ϵ +struct CThostFtdcOptionInstrMarginAdjustField { + ///Լ + TThostFtdcInstrumentIDType InstrumentID; + ///Ͷ߷Χ + TThostFtdcInvestorRangeType InvestorRange; + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///Ͷߴ + TThostFtdcInvestorIDType InvestorID; + ///Ͷͷ֤ϵ + TThostFtdcRatioType SShortMarginRatioByMoney; + ///Ͷͷ֤ϵ + TThostFtdcMoneyType SShortMarginRatioByVolume; + ///ֵͷ֤ϵ + TThostFtdcRatioType HShortMarginRatioByMoney; + ///ֵͷ֤ϵ + TThostFtdcMoneyType HShortMarginRatioByVolume; + ///ͷ֤ϵ + TThostFtdcRatioType AShortMarginRatioByMoney; + ///ͷ֤ϵ + TThostFtdcMoneyType AShortMarginRatioByVolume; + ///Ƿ潻ȡ + TThostFtdcBoolType IsRelative; + ///̿ͷ֤ϵ + TThostFtdcRatioType MShortMarginRatioByMoney; + ///̿ͷ֤ϵ + TThostFtdcMoneyType MShortMarginRatioByVolume; +}; + +///ǰȨԼѵϸ +struct CThostFtdcOptionInstrCommRateField { + ///Լ + TThostFtdcInstrumentIDType InstrumentID; + ///Ͷ߷Χ + TThostFtdcInvestorRangeType InvestorRange; + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///Ͷߴ + TThostFtdcInvestorIDType InvestorID; + /// + TThostFtdcRatioType OpenRatioByMoney; + /// + TThostFtdcRatioType OpenRatioByVolume; + ///ƽ + TThostFtdcRatioType CloseRatioByMoney; + ///ƽ + TThostFtdcRatioType CloseRatioByVolume; + ///ƽ + TThostFtdcRatioType CloseTodayRatioByMoney; + ///ƽ + TThostFtdcRatioType CloseTodayRatioByVolume; + ///ִ + TThostFtdcRatioType StrikeRatioByMoney; + ///ִ + TThostFtdcRatioType StrikeRatioByVolume; +}; + +///Ȩ׳ɱ +struct CThostFtdcOptionInstrTradeCostField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///Ͷߴ + TThostFtdcInvestorIDType InvestorID; + ///Լ + TThostFtdcInstrumentIDType InstrumentID; + ///Ͷױ־ + TThostFtdcHedgeFlagType HedgeFlag; + ///ȨԼ֤𲻱䲿 + TThostFtdcMoneyType FixedMargin; + ///ȨԼС֤ + TThostFtdcMoneyType MiniMargin; + ///ȨԼȨ + TThostFtdcMoneyType Royalty; + ///ȨԼ֤𲻱䲿 + TThostFtdcMoneyType ExchFixedMargin; + ///ȨԼС֤ + TThostFtdcMoneyType ExchMiniMargin; +}; + +///Ȩ׳ɱѯ +struct CThostFtdcQryOptionInstrTradeCostField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///Ͷߴ + TThostFtdcInvestorIDType InvestorID; + ///Լ + TThostFtdcInstrumentIDType InstrumentID; + ///Ͷױ־ + TThostFtdcHedgeFlagType HedgeFlag; + ///ȨԼ + TThostFtdcPriceType InputPrice; + ///ļ۸,0 + TThostFtdcPriceType UnderlyingPrice; +}; + +///Ȩʲѯ +struct CThostFtdcQryOptionInstrCommRateField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///Ͷߴ + TThostFtdcInvestorIDType InvestorID; + ///Լ + TThostFtdcInstrumentIDType InstrumentID; +}; + +///ָָֻ +struct CThostFtdcIndexPriceField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///Լ + TThostFtdcInstrumentIDType InstrumentID; + ///ָֻ̼ + TThostFtdcPriceType ClosePrice; +}; + +///ִ +struct CThostFtdcInputExecOrderField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///Ͷߴ + TThostFtdcInvestorIDType InvestorID; + ///Լ + TThostFtdcInstrumentIDType InstrumentID; + ///ִ + TThostFtdcOrderRefType ExecOrderRef; + ///û + TThostFtdcUserIDType UserID; + /// + TThostFtdcVolumeType Volume; + /// + TThostFtdcRequestIDType RequestID; + ///ҵԪ + TThostFtdcBusinessUnitType BusinessUnit; + ///ƽ־ + TThostFtdcOffsetFlagType OffsetFlag; + ///Ͷױ־ + TThostFtdcHedgeFlagType HedgeFlag; + ///ִ + TThostFtdcActionTypeType ActionType; + ///ͷijֲַ + TThostFtdcPosiDirectionType PosiDirection; + ///ȨȨǷڻͷı + TThostFtdcExecOrderPositionFlagType ReservePositionFlag; + ///ȨȨɵͷǷԶƽ + TThostFtdcExecOrderCloseFlagType CloseFlag; + /// + TThostFtdcExchangeIDType ExchangeID; + ///ͶʵԪ + TThostFtdcInvestUnitIDType InvestUnitID; + ///ʽ˺ + TThostFtdcAccountIDType AccountID; + ///ִ + TThostFtdcCurrencyIDType CurrencyID; + ///ױ + TThostFtdcClientIDType ClientID; + /// IPַ + TThostFtdcIPAddressType IPAddress; + /// Macַ + TThostFtdcMacAddressType MacAddress; +}; + +///ִ +struct CThostFtdcInputExecOrderActionField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///Ͷߴ + TThostFtdcInvestorIDType InvestorID; + ///ִ + TThostFtdcOrderActionRefType ExecOrderActionRef; + ///ִ + TThostFtdcOrderRefType ExecOrderRef; + /// + TThostFtdcRequestIDType RequestID; + ///ǰñ + TThostFtdcFrontIDType FrontID; + ///Ự + TThostFtdcSessionIDType SessionID; + /// + TThostFtdcExchangeIDType ExchangeID; + ///ִ + TThostFtdcExecOrderSysIDType ExecOrderSysID; + ///־ + TThostFtdcActionFlagType ActionFlag; + ///û + TThostFtdcUserIDType UserID; + ///Լ + TThostFtdcInstrumentIDType InstrumentID; + ///ͶʵԪ + TThostFtdcInvestUnitIDType InvestUnitID; + /// IPַ + TThostFtdcIPAddressType IPAddress; + /// Macַ + TThostFtdcMacAddressType MacAddress; +}; + +///ִ +struct CThostFtdcExecOrderField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///Ͷߴ + TThostFtdcInvestorIDType InvestorID; + ///Լ + TThostFtdcInstrumentIDType InstrumentID; + ///ִ + TThostFtdcOrderRefType ExecOrderRef; + ///û + TThostFtdcUserIDType UserID; + /// + TThostFtdcVolumeType Volume; + /// + TThostFtdcRequestIDType RequestID; + ///ҵԪ + TThostFtdcBusinessUnitType BusinessUnit; + ///ƽ־ + TThostFtdcOffsetFlagType OffsetFlag; + ///Ͷױ־ + TThostFtdcHedgeFlagType HedgeFlag; + ///ִ + TThostFtdcActionTypeType ActionType; + ///ͷijֲַ + TThostFtdcPosiDirectionType PosiDirection; + ///ȨȨǷڻͷı + TThostFtdcExecOrderPositionFlagType ReservePositionFlag; + ///ȨȨɵͷǷԶƽ + TThostFtdcExecOrderCloseFlagType CloseFlag; + ///ִ + TThostFtdcOrderLocalIDType ExecOrderLocalID; + /// + TThostFtdcExchangeIDType ExchangeID; + ///Ա + TThostFtdcParticipantIDType ParticipantID; + ///ͻ + TThostFtdcClientIDType ClientID; + ///ԼڽĴ + TThostFtdcExchangeInstIDType ExchangeInstID; + ///Ա + TThostFtdcTraderIDType TraderID; + ///װ + TThostFtdcInstallIDType InstallID; + ///ִύ״̬ + TThostFtdcOrderSubmitStatusType OrderSubmitStatus; + ///ʾ + TThostFtdcSequenceNoType NotifySequence; + /// + TThostFtdcDateType TradingDay; + /// + TThostFtdcSettlementIDType SettlementID; + ///ִ + TThostFtdcExecOrderSysIDType ExecOrderSysID; + /// + TThostFtdcDateType InsertDate; + ///ʱ + TThostFtdcTimeType InsertTime; + ///ʱ + TThostFtdcTimeType CancelTime; + ///ִн + TThostFtdcExecResultType ExecResult; + ///Ա + TThostFtdcParticipantIDType ClearingPartID; + /// + TThostFtdcSequenceNoType SequenceNo; + ///ǰñ + TThostFtdcFrontIDType FrontID; + ///Ự + TThostFtdcSessionIDType SessionID; + ///û˲ƷϢ + TThostFtdcProductInfoType UserProductInfo; + ///״̬Ϣ + TThostFtdcErrorMsgType StatusMsg; + ///û + TThostFtdcUserIDType ActiveUserID; + ///͹˾ + TThostFtdcSequenceNoType BrokerExecOrderSeq; + ///Ӫҵ + TThostFtdcBranchIDType BranchID; + ///ͶʵԪ + TThostFtdcInvestUnitIDType InvestUnitID; + ///ʽ˺ + TThostFtdcAccountIDType AccountID; + ///ִ + TThostFtdcCurrencyIDType CurrencyID; + /// IPַ + TThostFtdcIPAddressType IPAddress; + /// Macַ + TThostFtdcMacAddressType MacAddress; +}; + +///ִ +struct CThostFtdcExecOrderActionField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///Ͷߴ + TThostFtdcInvestorIDType InvestorID; + ///ִ + TThostFtdcOrderActionRefType ExecOrderActionRef; + ///ִ + TThostFtdcOrderRefType ExecOrderRef; + /// + TThostFtdcRequestIDType RequestID; + ///ǰñ + TThostFtdcFrontIDType FrontID; + ///Ự + TThostFtdcSessionIDType SessionID; + /// + TThostFtdcExchangeIDType ExchangeID; + ///ִ + TThostFtdcExecOrderSysIDType ExecOrderSysID; + ///־ + TThostFtdcActionFlagType ActionFlag; + /// + TThostFtdcDateType ActionDate; + ///ʱ + TThostFtdcTimeType ActionTime; + ///Ա + TThostFtdcTraderIDType TraderID; + ///װ + TThostFtdcInstallIDType InstallID; + ///ִ + TThostFtdcOrderLocalIDType ExecOrderLocalID; + ///ر + TThostFtdcOrderLocalIDType ActionLocalID; + ///Ա + TThostFtdcParticipantIDType ParticipantID; + ///ͻ + TThostFtdcClientIDType ClientID; + ///ҵԪ + TThostFtdcBusinessUnitType BusinessUnit; + ///״̬ + TThostFtdcOrderActionStatusType OrderActionStatus; + ///û + TThostFtdcUserIDType UserID; + ///ִ + TThostFtdcActionTypeType ActionType; + ///״̬Ϣ + TThostFtdcErrorMsgType StatusMsg; + ///Լ + TThostFtdcInstrumentIDType InstrumentID; + ///Ӫҵ + TThostFtdcBranchIDType BranchID; + ///ͶʵԪ + TThostFtdcInvestUnitIDType InvestUnitID; + /// IPַ + TThostFtdcIPAddressType IPAddress; + /// Macַ + TThostFtdcMacAddressType MacAddress; +}; + +///ִѯ +struct CThostFtdcQryExecOrderField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///Ͷߴ + TThostFtdcInvestorIDType InvestorID; + ///Լ + TThostFtdcInstrumentIDType InstrumentID; + /// + TThostFtdcExchangeIDType ExchangeID; + ///ִ + TThostFtdcExecOrderSysIDType ExecOrderSysID; + ///ʼʱ + TThostFtdcTimeType InsertTimeStart; + ///ʱ + TThostFtdcTimeType InsertTimeEnd; +}; + +///ִϢ +struct CThostFtdcExchangeExecOrderField { + /// + TThostFtdcVolumeType Volume; + /// + TThostFtdcRequestIDType RequestID; + ///ҵԪ + TThostFtdcBusinessUnitType BusinessUnit; + ///ƽ־ + TThostFtdcOffsetFlagType OffsetFlag; + ///Ͷױ־ + TThostFtdcHedgeFlagType HedgeFlag; + ///ִ + TThostFtdcActionTypeType ActionType; + ///ͷijֲַ + TThostFtdcPosiDirectionType PosiDirection; + ///ȨȨǷڻͷı + TThostFtdcExecOrderPositionFlagType ReservePositionFlag; + ///ȨȨɵͷǷԶƽ + TThostFtdcExecOrderCloseFlagType CloseFlag; + ///ִ + TThostFtdcOrderLocalIDType ExecOrderLocalID; + /// + TThostFtdcExchangeIDType ExchangeID; + ///Ա + TThostFtdcParticipantIDType ParticipantID; + ///ͻ + TThostFtdcClientIDType ClientID; + ///ԼڽĴ + TThostFtdcExchangeInstIDType ExchangeInstID; + ///Ա + TThostFtdcTraderIDType TraderID; + ///װ + TThostFtdcInstallIDType InstallID; + ///ִύ״̬ + TThostFtdcOrderSubmitStatusType OrderSubmitStatus; + ///ʾ + TThostFtdcSequenceNoType NotifySequence; + /// + TThostFtdcDateType TradingDay; + /// + TThostFtdcSettlementIDType SettlementID; + ///ִ + TThostFtdcExecOrderSysIDType ExecOrderSysID; + /// + TThostFtdcDateType InsertDate; + ///ʱ + TThostFtdcTimeType InsertTime; + ///ʱ + TThostFtdcTimeType CancelTime; + ///ִн + TThostFtdcExecResultType ExecResult; + ///Ա + TThostFtdcParticipantIDType ClearingPartID; + /// + TThostFtdcSequenceNoType SequenceNo; + ///Ӫҵ + TThostFtdcBranchIDType BranchID; + /// IPַ + TThostFtdcIPAddressType IPAddress; + /// Macַ + TThostFtdcMacAddressType MacAddress; +}; + +///ִѯ +struct CThostFtdcQryExchangeExecOrderField { + ///Ա + TThostFtdcParticipantIDType ParticipantID; + ///ͻ + TThostFtdcClientIDType ClientID; + ///ԼڽĴ + TThostFtdcExchangeInstIDType ExchangeInstID; + /// + TThostFtdcExchangeIDType ExchangeID; + ///Ա + TThostFtdcTraderIDType TraderID; +}; + +///ִѯ +struct CThostFtdcQryExecOrderActionField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///Ͷߴ + TThostFtdcInvestorIDType InvestorID; + /// + TThostFtdcExchangeIDType ExchangeID; +}; + +///ִ +struct CThostFtdcExchangeExecOrderActionField { + /// + TThostFtdcExchangeIDType ExchangeID; + ///ִ + TThostFtdcExecOrderSysIDType ExecOrderSysID; + ///־ + TThostFtdcActionFlagType ActionFlag; + /// + TThostFtdcDateType ActionDate; + ///ʱ + TThostFtdcTimeType ActionTime; + ///Ա + TThostFtdcTraderIDType TraderID; + ///װ + TThostFtdcInstallIDType InstallID; + ///ִ + TThostFtdcOrderLocalIDType ExecOrderLocalID; + ///ر + TThostFtdcOrderLocalIDType ActionLocalID; + ///Ա + TThostFtdcParticipantIDType ParticipantID; + ///ͻ + TThostFtdcClientIDType ClientID; + ///ҵԪ + TThostFtdcBusinessUnitType BusinessUnit; + ///״̬ + TThostFtdcOrderActionStatusType OrderActionStatus; + ///û + TThostFtdcUserIDType UserID; + ///ִ + TThostFtdcActionTypeType ActionType; + ///Ӫҵ + TThostFtdcBranchIDType BranchID; + /// IPַ + TThostFtdcIPAddressType IPAddress; + /// Macַ + TThostFtdcMacAddressType MacAddress; +}; + +///ִѯ +struct CThostFtdcQryExchangeExecOrderActionField { + ///Ա + TThostFtdcParticipantIDType ParticipantID; + ///ͻ + TThostFtdcClientIDType ClientID; + /// + TThostFtdcExchangeIDType ExchangeID; + ///Ա + TThostFtdcTraderIDType TraderID; +}; + +///ִ +struct CThostFtdcErrExecOrderField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///Ͷߴ + TThostFtdcInvestorIDType InvestorID; + ///Լ + TThostFtdcInstrumentIDType InstrumentID; + ///ִ + TThostFtdcOrderRefType ExecOrderRef; + ///û + TThostFtdcUserIDType UserID; + /// + TThostFtdcVolumeType Volume; + /// + TThostFtdcRequestIDType RequestID; + ///ҵԪ + TThostFtdcBusinessUnitType BusinessUnit; + ///ƽ־ + TThostFtdcOffsetFlagType OffsetFlag; + ///Ͷױ־ + TThostFtdcHedgeFlagType HedgeFlag; + ///ִ + TThostFtdcActionTypeType ActionType; + ///ͷijֲַ + TThostFtdcPosiDirectionType PosiDirection; + ///ȨȨǷڻͷı + TThostFtdcExecOrderPositionFlagType ReservePositionFlag; + ///ȨȨɵͷǷԶƽ + TThostFtdcExecOrderCloseFlagType CloseFlag; + /// + TThostFtdcExchangeIDType ExchangeID; + ///ͶʵԪ + TThostFtdcInvestUnitIDType InvestUnitID; + ///ʽ˺ + TThostFtdcAccountIDType AccountID; + ///ִ + TThostFtdcCurrencyIDType CurrencyID; + ///ױ + TThostFtdcClientIDType ClientID; + /// IPַ + TThostFtdcIPAddressType IPAddress; + /// Macַ + TThostFtdcMacAddressType MacAddress; + /// + TThostFtdcErrorIDType ErrorID; + ///Ϣ + TThostFtdcErrorMsgType ErrorMsg; +}; + +///ѯִ +struct CThostFtdcQryErrExecOrderField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///Ͷߴ + TThostFtdcInvestorIDType InvestorID; +}; + +///ִ +struct CThostFtdcErrExecOrderActionField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///Ͷߴ + TThostFtdcInvestorIDType InvestorID; + ///ִ + TThostFtdcOrderActionRefType ExecOrderActionRef; + ///ִ + TThostFtdcOrderRefType ExecOrderRef; + /// + TThostFtdcRequestIDType RequestID; + ///ǰñ + TThostFtdcFrontIDType FrontID; + ///Ự + TThostFtdcSessionIDType SessionID; + /// + TThostFtdcExchangeIDType ExchangeID; + ///ִ + TThostFtdcExecOrderSysIDType ExecOrderSysID; + ///־ + TThostFtdcActionFlagType ActionFlag; + ///û + TThostFtdcUserIDType UserID; + ///Լ + TThostFtdcInstrumentIDType InstrumentID; + ///ͶʵԪ + TThostFtdcInvestUnitIDType InvestUnitID; + /// IPַ + TThostFtdcIPAddressType IPAddress; + /// Macַ + TThostFtdcMacAddressType MacAddress; + /// + TThostFtdcErrorIDType ErrorID; + ///Ϣ + TThostFtdcErrorMsgType ErrorMsg; +}; + +///ѯִ +struct CThostFtdcQryErrExecOrderActionField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///Ͷߴ + TThostFtdcInvestorIDType InvestorID; +}; + +///ͶȨԼȨ +struct CThostFtdcOptionInstrTradingRightField { + ///Լ + TThostFtdcInstrumentIDType InstrumentID; + ///Ͷ߷Χ + TThostFtdcInvestorRangeType InvestorRange; + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///Ͷߴ + TThostFtdcInvestorIDType InvestorID; + /// + TThostFtdcDirectionType Direction; + ///Ȩ + TThostFtdcTradingRightType TradingRight; +}; + +///ѯȨԼȨ +struct CThostFtdcQryOptionInstrTradingRightField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///Ͷߴ + TThostFtdcInvestorIDType InvestorID; + ///Լ + TThostFtdcInstrumentIDType InstrumentID; + /// + TThostFtdcDirectionType Direction; +}; + +///ѯ +struct CThostFtdcInputForQuoteField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///Ͷߴ + TThostFtdcInvestorIDType InvestorID; + ///Լ + TThostFtdcInstrumentIDType InstrumentID; + ///ѯ + TThostFtdcOrderRefType ForQuoteRef; + ///û + TThostFtdcUserIDType UserID; + /// + TThostFtdcExchangeIDType ExchangeID; + ///ͶʵԪ + TThostFtdcInvestUnitIDType InvestUnitID; + /// IPַ + TThostFtdcIPAddressType IPAddress; + /// Macַ + TThostFtdcMacAddressType MacAddress; +}; + +///ѯ +struct CThostFtdcForQuoteField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///Ͷߴ + TThostFtdcInvestorIDType InvestorID; + ///Լ + TThostFtdcInstrumentIDType InstrumentID; + ///ѯ + TThostFtdcOrderRefType ForQuoteRef; + ///û + TThostFtdcUserIDType UserID; + ///ѯ۱ + TThostFtdcOrderLocalIDType ForQuoteLocalID; + /// + TThostFtdcExchangeIDType ExchangeID; + ///Ա + TThostFtdcParticipantIDType ParticipantID; + ///ͻ + TThostFtdcClientIDType ClientID; + ///ԼڽĴ + TThostFtdcExchangeInstIDType ExchangeInstID; + ///Ա + TThostFtdcTraderIDType TraderID; + ///װ + TThostFtdcInstallIDType InstallID; + /// + TThostFtdcDateType InsertDate; + ///ʱ + TThostFtdcTimeType InsertTime; + ///ѯ״̬ + TThostFtdcForQuoteStatusType ForQuoteStatus; + ///ǰñ + TThostFtdcFrontIDType FrontID; + ///Ự + TThostFtdcSessionIDType SessionID; + ///״̬Ϣ + TThostFtdcErrorMsgType StatusMsg; + ///û + TThostFtdcUserIDType ActiveUserID; + ///͹˾ѯ۱ + TThostFtdcSequenceNoType BrokerForQutoSeq; + ///ͶʵԪ + TThostFtdcInvestUnitIDType InvestUnitID; + /// IPַ + TThostFtdcIPAddressType IPAddress; + /// Macַ + TThostFtdcMacAddressType MacAddress; +}; + +///ѯ۲ѯ +struct CThostFtdcQryForQuoteField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///Ͷߴ + TThostFtdcInvestorIDType InvestorID; + ///Լ + TThostFtdcInstrumentIDType InstrumentID; + /// + TThostFtdcExchangeIDType ExchangeID; + ///ʼʱ + TThostFtdcTimeType InsertTimeStart; + ///ʱ + TThostFtdcTimeType InsertTimeEnd; +}; + +///ѯϢ +struct CThostFtdcExchangeForQuoteField { + ///ѯ۱ + TThostFtdcOrderLocalIDType ForQuoteLocalID; + /// + TThostFtdcExchangeIDType ExchangeID; + ///Ա + TThostFtdcParticipantIDType ParticipantID; + ///ͻ + TThostFtdcClientIDType ClientID; + ///ԼڽĴ + TThostFtdcExchangeInstIDType ExchangeInstID; + ///Ա + TThostFtdcTraderIDType TraderID; + ///װ + TThostFtdcInstallIDType InstallID; + /// + TThostFtdcDateType InsertDate; + ///ʱ + TThostFtdcTimeType InsertTime; + ///ѯ״̬ + TThostFtdcForQuoteStatusType ForQuoteStatus; + /// IPַ + TThostFtdcIPAddressType IPAddress; + /// Macַ + TThostFtdcMacAddressType MacAddress; +}; + +///ѯ۲ѯ +struct CThostFtdcQryExchangeForQuoteField { + ///Ա + TThostFtdcParticipantIDType ParticipantID; + ///ͻ + TThostFtdcClientIDType ClientID; + ///ԼڽĴ + TThostFtdcExchangeInstIDType ExchangeInstID; + /// + TThostFtdcExchangeIDType ExchangeID; + ///Ա + TThostFtdcTraderIDType TraderID; +}; + +///ı +struct CThostFtdcInputQuoteField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///Ͷߴ + TThostFtdcInvestorIDType InvestorID; + ///Լ + TThostFtdcInstrumentIDType InstrumentID; + /// + TThostFtdcOrderRefType QuoteRef; + ///û + TThostFtdcUserIDType UserID; + ///۸ + TThostFtdcPriceType AskPrice; + ///۸ + TThostFtdcPriceType BidPrice; + /// + TThostFtdcVolumeType AskVolume; + /// + TThostFtdcVolumeType BidVolume; + /// + TThostFtdcRequestIDType RequestID; + ///ҵԪ + TThostFtdcBusinessUnitType BusinessUnit; + ///ƽ־ + TThostFtdcOffsetFlagType AskOffsetFlag; + ///ƽ־ + TThostFtdcOffsetFlagType BidOffsetFlag; + ///Ͷױ־ + TThostFtdcHedgeFlagType AskHedgeFlag; + ///Ͷױ־ + TThostFtdcHedgeFlagType BidHedgeFlag; + /// + TThostFtdcOrderRefType AskOrderRef; + ///򱨵 + TThostFtdcOrderRefType BidOrderRef; + ///Ӧ۱ + TThostFtdcOrderSysIDType ForQuoteSysID; + /// + TThostFtdcExchangeIDType ExchangeID; + ///ͶʵԪ + TThostFtdcInvestUnitIDType InvestUnitID; + ///ױ + TThostFtdcClientIDType ClientID; + /// IPַ + TThostFtdcIPAddressType IPAddress; + /// Macַ + TThostFtdcMacAddressType MacAddress; +}; + +///뱨۲ +struct CThostFtdcInputQuoteActionField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///Ͷߴ + TThostFtdcInvestorIDType InvestorID; + ///۲ + TThostFtdcOrderActionRefType QuoteActionRef; + /// + TThostFtdcOrderRefType QuoteRef; + /// + TThostFtdcRequestIDType RequestID; + ///ǰñ + TThostFtdcFrontIDType FrontID; + ///Ự + TThostFtdcSessionIDType SessionID; + /// + TThostFtdcExchangeIDType ExchangeID; + ///۲ + TThostFtdcOrderSysIDType QuoteSysID; + ///־ + TThostFtdcActionFlagType ActionFlag; + ///û + TThostFtdcUserIDType UserID; + ///Լ + TThostFtdcInstrumentIDType InstrumentID; + ///ͶʵԪ + TThostFtdcInvestUnitIDType InvestUnitID; + ///ױ + TThostFtdcClientIDType ClientID; + /// IPַ + TThostFtdcIPAddressType IPAddress; + /// Macַ + TThostFtdcMacAddressType MacAddress; +}; + +/// +struct CThostFtdcQuoteField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///Ͷߴ + TThostFtdcInvestorIDType InvestorID; + ///Լ + TThostFtdcInstrumentIDType InstrumentID; + /// + TThostFtdcOrderRefType QuoteRef; + ///û + TThostFtdcUserIDType UserID; + ///۸ + TThostFtdcPriceType AskPrice; + ///۸ + TThostFtdcPriceType BidPrice; + /// + TThostFtdcVolumeType AskVolume; + /// + TThostFtdcVolumeType BidVolume; + /// + TThostFtdcRequestIDType RequestID; + ///ҵԪ + TThostFtdcBusinessUnitType BusinessUnit; + ///ƽ־ + TThostFtdcOffsetFlagType AskOffsetFlag; + ///ƽ־ + TThostFtdcOffsetFlagType BidOffsetFlag; + ///Ͷױ־ + TThostFtdcHedgeFlagType AskHedgeFlag; + ///Ͷױ־ + TThostFtdcHedgeFlagType BidHedgeFlag; + ///ر۱ + TThostFtdcOrderLocalIDType QuoteLocalID; + /// + TThostFtdcExchangeIDType ExchangeID; + ///Ա + TThostFtdcParticipantIDType ParticipantID; + ///ͻ + TThostFtdcClientIDType ClientID; + ///ԼڽĴ + TThostFtdcExchangeInstIDType ExchangeInstID; + ///Ա + TThostFtdcTraderIDType TraderID; + ///װ + TThostFtdcInstallIDType InstallID; + ///ʾ + TThostFtdcSequenceNoType NotifySequence; + ///ύ״̬ + TThostFtdcOrderSubmitStatusType OrderSubmitStatus; + /// + TThostFtdcDateType TradingDay; + /// + TThostFtdcSettlementIDType SettlementID; + ///۱ + TThostFtdcOrderSysIDType QuoteSysID; + /// + TThostFtdcDateType InsertDate; + ///ʱ + TThostFtdcTimeType InsertTime; + ///ʱ + TThostFtdcTimeType CancelTime; + ///״̬ + TThostFtdcOrderStatusType QuoteStatus; + ///Ա + TThostFtdcParticipantIDType ClearingPartID; + /// + TThostFtdcSequenceNoType SequenceNo; + /// + TThostFtdcOrderSysIDType AskOrderSysID; + ///򷽱 + TThostFtdcOrderSysIDType BidOrderSysID; + ///ǰñ + TThostFtdcFrontIDType FrontID; + ///Ự + TThostFtdcSessionIDType SessionID; + ///û˲ƷϢ + TThostFtdcProductInfoType UserProductInfo; + ///״̬Ϣ + TThostFtdcErrorMsgType StatusMsg; + ///û + TThostFtdcUserIDType ActiveUserID; + ///͹˾۱ + TThostFtdcSequenceNoType BrokerQuoteSeq; + /// + TThostFtdcOrderRefType AskOrderRef; + ///򱨵 + TThostFtdcOrderRefType BidOrderRef; + ///Ӧ۱ + TThostFtdcOrderSysIDType ForQuoteSysID; + ///Ӫҵ + TThostFtdcBranchIDType BranchID; + ///ͶʵԪ + TThostFtdcInvestUnitIDType InvestUnitID; + ///ʽ˺ + TThostFtdcAccountIDType AccountID; + ///ִ + TThostFtdcCurrencyIDType CurrencyID; + /// IPַ + TThostFtdcIPAddressType IPAddress; + /// Macַ + TThostFtdcMacAddressType MacAddress; +}; + +///۲ +struct CThostFtdcQuoteActionField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///Ͷߴ + TThostFtdcInvestorIDType InvestorID; + ///۲ + TThostFtdcOrderActionRefType QuoteActionRef; + /// + TThostFtdcOrderRefType QuoteRef; + /// + TThostFtdcRequestIDType RequestID; + ///ǰñ + TThostFtdcFrontIDType FrontID; + ///Ự + TThostFtdcSessionIDType SessionID; + /// + TThostFtdcExchangeIDType ExchangeID; + ///۲ + TThostFtdcOrderSysIDType QuoteSysID; + ///־ + TThostFtdcActionFlagType ActionFlag; + /// + TThostFtdcDateType ActionDate; + ///ʱ + TThostFtdcTimeType ActionTime; + ///Ա + TThostFtdcTraderIDType TraderID; + ///װ + TThostFtdcInstallIDType InstallID; + ///ر۱ + TThostFtdcOrderLocalIDType QuoteLocalID; + ///ر + TThostFtdcOrderLocalIDType ActionLocalID; + ///Ա + TThostFtdcParticipantIDType ParticipantID; + ///ͻ + TThostFtdcClientIDType ClientID; + ///ҵԪ + TThostFtdcBusinessUnitType BusinessUnit; + ///״̬ + TThostFtdcOrderActionStatusType OrderActionStatus; + ///û + TThostFtdcUserIDType UserID; + ///״̬Ϣ + TThostFtdcErrorMsgType StatusMsg; + ///Լ + TThostFtdcInstrumentIDType InstrumentID; + ///Ӫҵ + TThostFtdcBranchIDType BranchID; + ///ͶʵԪ + TThostFtdcInvestUnitIDType InvestUnitID; + /// IPַ + TThostFtdcIPAddressType IPAddress; + /// Macַ + TThostFtdcMacAddressType MacAddress; +}; + +///۲ѯ +struct CThostFtdcQryQuoteField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///Ͷߴ + TThostFtdcInvestorIDType InvestorID; + ///Լ + TThostFtdcInstrumentIDType InstrumentID; + /// + TThostFtdcExchangeIDType ExchangeID; + ///۱ + TThostFtdcOrderSysIDType QuoteSysID; + ///ʼʱ + TThostFtdcTimeType InsertTimeStart; + ///ʱ + TThostFtdcTimeType InsertTimeEnd; +}; + +///Ϣ +struct CThostFtdcExchangeQuoteField { + ///۸ + TThostFtdcPriceType AskPrice; + ///۸ + TThostFtdcPriceType BidPrice; + /// + TThostFtdcVolumeType AskVolume; + /// + TThostFtdcVolumeType BidVolume; + /// + TThostFtdcRequestIDType RequestID; + ///ҵԪ + TThostFtdcBusinessUnitType BusinessUnit; + ///ƽ־ + TThostFtdcOffsetFlagType AskOffsetFlag; + ///ƽ־ + TThostFtdcOffsetFlagType BidOffsetFlag; + ///Ͷױ־ + TThostFtdcHedgeFlagType AskHedgeFlag; + ///Ͷױ־ + TThostFtdcHedgeFlagType BidHedgeFlag; + ///ر۱ + TThostFtdcOrderLocalIDType QuoteLocalID; + /// + TThostFtdcExchangeIDType ExchangeID; + ///Ա + TThostFtdcParticipantIDType ParticipantID; + ///ͻ + TThostFtdcClientIDType ClientID; + ///ԼڽĴ + TThostFtdcExchangeInstIDType ExchangeInstID; + ///Ա + TThostFtdcTraderIDType TraderID; + ///װ + TThostFtdcInstallIDType InstallID; + ///ʾ + TThostFtdcSequenceNoType NotifySequence; + ///ύ״̬ + TThostFtdcOrderSubmitStatusType OrderSubmitStatus; + /// + TThostFtdcDateType TradingDay; + /// + TThostFtdcSettlementIDType SettlementID; + ///۱ + TThostFtdcOrderSysIDType QuoteSysID; + /// + TThostFtdcDateType InsertDate; + ///ʱ + TThostFtdcTimeType InsertTime; + ///ʱ + TThostFtdcTimeType CancelTime; + ///״̬ + TThostFtdcOrderStatusType QuoteStatus; + ///Ա + TThostFtdcParticipantIDType ClearingPartID; + /// + TThostFtdcSequenceNoType SequenceNo; + /// + TThostFtdcOrderSysIDType AskOrderSysID; + ///򷽱 + TThostFtdcOrderSysIDType BidOrderSysID; + ///Ӧ۱ + TThostFtdcOrderSysIDType ForQuoteSysID; + ///Ӫҵ + TThostFtdcBranchIDType BranchID; + /// IPַ + TThostFtdcIPAddressType IPAddress; + /// Macַ + TThostFtdcMacAddressType MacAddress; +}; + +///۲ѯ +struct CThostFtdcQryExchangeQuoteField { + ///Ա + TThostFtdcParticipantIDType ParticipantID; + ///ͻ + TThostFtdcClientIDType ClientID; + ///ԼڽĴ + TThostFtdcExchangeInstIDType ExchangeInstID; + /// + TThostFtdcExchangeIDType ExchangeID; + ///Ա + TThostFtdcTraderIDType TraderID; +}; + +///۲ѯ +struct CThostFtdcQryQuoteActionField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///Ͷߴ + TThostFtdcInvestorIDType InvestorID; + /// + TThostFtdcExchangeIDType ExchangeID; +}; + +///۲ +struct CThostFtdcExchangeQuoteActionField { + /// + TThostFtdcExchangeIDType ExchangeID; + ///۲ + TThostFtdcOrderSysIDType QuoteSysID; + ///־ + TThostFtdcActionFlagType ActionFlag; + /// + TThostFtdcDateType ActionDate; + ///ʱ + TThostFtdcTimeType ActionTime; + ///Ա + TThostFtdcTraderIDType TraderID; + ///װ + TThostFtdcInstallIDType InstallID; + ///ر۱ + TThostFtdcOrderLocalIDType QuoteLocalID; + ///ر + TThostFtdcOrderLocalIDType ActionLocalID; + ///Ա + TThostFtdcParticipantIDType ParticipantID; + ///ͻ + TThostFtdcClientIDType ClientID; + ///ҵԪ + TThostFtdcBusinessUnitType BusinessUnit; + ///״̬ + TThostFtdcOrderActionStatusType OrderActionStatus; + ///û + TThostFtdcUserIDType UserID; + /// IPַ + TThostFtdcIPAddressType IPAddress; + /// Macַ + TThostFtdcMacAddressType MacAddress; +}; + +///۲ѯ +struct CThostFtdcQryExchangeQuoteActionField { + ///Ա + TThostFtdcParticipantIDType ParticipantID; + ///ͻ + TThostFtdcClientIDType ClientID; + /// + TThostFtdcExchangeIDType ExchangeID; + ///Ա + TThostFtdcTraderIDType TraderID; +}; + +///ȨԼdeltaֵ +struct CThostFtdcOptionInstrDeltaField { + ///Լ + TThostFtdcInstrumentIDType InstrumentID; + ///Ͷ߷Χ + TThostFtdcInvestorRangeType InvestorRange; + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///Ͷߴ + TThostFtdcInvestorIDType InvestorID; + /// Deltaֵ + TThostFtdcRatioType Delta; +}; + +///̵ѯ +struct CThostFtdcForQuoteRspField { + /// + TThostFtdcDateType TradingDay; + ///Լ + TThostFtdcInstrumentIDType InstrumentID; + ///ѯ۱ + TThostFtdcOrderSysIDType ForQuoteSysID; + ///ѯʱ + TThostFtdcTimeType ForQuoteTime; + ///ҵ + TThostFtdcDateType ActionDay; + /// + TThostFtdcExchangeIDType ExchangeID; +}; + +///ǰȨԼִƫֵϸ +struct CThostFtdcStrikeOffsetField { + ///Լ + TThostFtdcInstrumentIDType InstrumentID; + ///Ͷ߷Χ + TThostFtdcInvestorRangeType InvestorRange; + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///Ͷߴ + TThostFtdcInvestorIDType InvestorID; + ///ִƫֵ + TThostFtdcMoneyType Offset; + ///ִƫ + TThostFtdcStrikeOffsetTypeType OffsetType; +}; + +///Ȩִƫֵѯ +struct CThostFtdcQryStrikeOffsetField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///Ͷߴ + TThostFtdcInvestorIDType InvestorID; + ///Լ + TThostFtdcInstrumentIDType InstrumentID; +}; + +/// +struct CThostFtdcInputBatchOrderActionField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///Ͷߴ + TThostFtdcInvestorIDType InvestorID; + /// + TThostFtdcOrderActionRefType OrderActionRef; + /// + TThostFtdcRequestIDType RequestID; + ///ǰñ + TThostFtdcFrontIDType FrontID; + ///Ự + TThostFtdcSessionIDType SessionID; + /// + TThostFtdcExchangeIDType ExchangeID; + ///û + TThostFtdcUserIDType UserID; + ///ͶʵԪ + TThostFtdcInvestUnitIDType InvestUnitID; + /// IPַ + TThostFtdcIPAddressType IPAddress; + /// Macַ + TThostFtdcMacAddressType MacAddress; +}; + +/// +struct CThostFtdcBatchOrderActionField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///Ͷߴ + TThostFtdcInvestorIDType InvestorID; + /// + TThostFtdcOrderActionRefType OrderActionRef; + /// + TThostFtdcRequestIDType RequestID; + ///ǰñ + TThostFtdcFrontIDType FrontID; + ///Ự + TThostFtdcSessionIDType SessionID; + /// + TThostFtdcExchangeIDType ExchangeID; + /// + TThostFtdcDateType ActionDate; + ///ʱ + TThostFtdcTimeType ActionTime; + ///Ա + TThostFtdcTraderIDType TraderID; + ///װ + TThostFtdcInstallIDType InstallID; + ///ر + TThostFtdcOrderLocalIDType ActionLocalID; + ///Ա + TThostFtdcParticipantIDType ParticipantID; + ///ͻ + TThostFtdcClientIDType ClientID; + ///ҵԪ + TThostFtdcBusinessUnitType BusinessUnit; + ///״̬ + TThostFtdcOrderActionStatusType OrderActionStatus; + ///û + TThostFtdcUserIDType UserID; + ///״̬Ϣ + TThostFtdcErrorMsgType StatusMsg; + ///ͶʵԪ + TThostFtdcInvestUnitIDType InvestUnitID; + /// IPַ + TThostFtdcIPAddressType IPAddress; + /// Macַ + TThostFtdcMacAddressType MacAddress; +}; + +/// +struct CThostFtdcExchangeBatchOrderActionField { + /// + TThostFtdcExchangeIDType ExchangeID; + /// + TThostFtdcDateType ActionDate; + ///ʱ + TThostFtdcTimeType ActionTime; + ///Ա + TThostFtdcTraderIDType TraderID; + ///װ + TThostFtdcInstallIDType InstallID; + ///ر + TThostFtdcOrderLocalIDType ActionLocalID; + ///Ա + TThostFtdcParticipantIDType ParticipantID; + ///ͻ + TThostFtdcClientIDType ClientID; + ///ҵԪ + TThostFtdcBusinessUnitType BusinessUnit; + ///״̬ + TThostFtdcOrderActionStatusType OrderActionStatus; + ///û + TThostFtdcUserIDType UserID; + /// IPַ + TThostFtdcIPAddressType IPAddress; + /// Macַ + TThostFtdcMacAddressType MacAddress; +}; + +///ѯ +struct CThostFtdcQryBatchOrderActionField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///Ͷߴ + TThostFtdcInvestorIDType InvestorID; + /// + TThostFtdcExchangeIDType ExchangeID; +}; + +///ϺԼȫϵ +struct CThostFtdcCombInstrumentGuardField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///Լ + TThostFtdcInstrumentIDType InstrumentID; + /// + TThostFtdcRatioType GuarantRatio; +}; + +///ϺԼȫϵѯ +struct CThostFtdcQryCombInstrumentGuardField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///Լ + TThostFtdcInstrumentIDType InstrumentID; +}; + +/// +struct CThostFtdcInputCombActionField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///Ͷߴ + TThostFtdcInvestorIDType InvestorID; + ///Լ + TThostFtdcInstrumentIDType InstrumentID; + /// + TThostFtdcOrderRefType CombActionRef; + ///û + TThostFtdcUserIDType UserID; + /// + TThostFtdcDirectionType Direction; + /// + TThostFtdcVolumeType Volume; + ///ָ + TThostFtdcCombDirectionType CombDirection; + ///Ͷױ־ + TThostFtdcHedgeFlagType HedgeFlag; + /// + TThostFtdcExchangeIDType ExchangeID; + /// IPַ + TThostFtdcIPAddressType IPAddress; + /// Macַ + TThostFtdcMacAddressType MacAddress; +}; + +/// +struct CThostFtdcCombActionField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///Ͷߴ + TThostFtdcInvestorIDType InvestorID; + ///Լ + TThostFtdcInstrumentIDType InstrumentID; + /// + TThostFtdcOrderRefType CombActionRef; + ///û + TThostFtdcUserIDType UserID; + /// + TThostFtdcDirectionType Direction; + /// + TThostFtdcVolumeType Volume; + ///ָ + TThostFtdcCombDirectionType CombDirection; + ///Ͷױ־ + TThostFtdcHedgeFlagType HedgeFlag; + ///ϱ + TThostFtdcOrderLocalIDType ActionLocalID; + /// + TThostFtdcExchangeIDType ExchangeID; + ///Ա + TThostFtdcParticipantIDType ParticipantID; + ///ͻ + TThostFtdcClientIDType ClientID; + ///ԼڽĴ + TThostFtdcExchangeInstIDType ExchangeInstID; + ///Ա + TThostFtdcTraderIDType TraderID; + ///װ + TThostFtdcInstallIDType InstallID; + ///״̬ + TThostFtdcOrderActionStatusType ActionStatus; + ///ʾ + TThostFtdcSequenceNoType NotifySequence; + /// + TThostFtdcDateType TradingDay; + /// + TThostFtdcSettlementIDType SettlementID; + /// + TThostFtdcSequenceNoType SequenceNo; + ///ǰñ + TThostFtdcFrontIDType FrontID; + ///Ự + TThostFtdcSessionIDType SessionID; + ///û˲ƷϢ + TThostFtdcProductInfoType UserProductInfo; + ///״̬Ϣ + TThostFtdcErrorMsgType StatusMsg; + /// IPַ + TThostFtdcIPAddressType IPAddress; + /// Macַ + TThostFtdcMacAddressType MacAddress; +}; + +///ϲѯ +struct CThostFtdcQryCombActionField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///Ͷߴ + TThostFtdcInvestorIDType InvestorID; + ///Լ + TThostFtdcInstrumentIDType InstrumentID; + /// + TThostFtdcExchangeIDType ExchangeID; +}; + +///Ϣ +struct CThostFtdcExchangeCombActionField { + /// + TThostFtdcDirectionType Direction; + /// + TThostFtdcVolumeType Volume; + ///ָ + TThostFtdcCombDirectionType CombDirection; + ///Ͷױ־ + TThostFtdcHedgeFlagType HedgeFlag; + ///ϱ + TThostFtdcOrderLocalIDType ActionLocalID; + /// + TThostFtdcExchangeIDType ExchangeID; + ///Ա + TThostFtdcParticipantIDType ParticipantID; + ///ͻ + TThostFtdcClientIDType ClientID; + ///ԼڽĴ + TThostFtdcExchangeInstIDType ExchangeInstID; + ///Ա + TThostFtdcTraderIDType TraderID; + ///װ + TThostFtdcInstallIDType InstallID; + ///״̬ + TThostFtdcOrderActionStatusType ActionStatus; + ///ʾ + TThostFtdcSequenceNoType NotifySequence; + /// + TThostFtdcDateType TradingDay; + /// + TThostFtdcSettlementIDType SettlementID; + /// + TThostFtdcSequenceNoType SequenceNo; + /// IPַ + TThostFtdcIPAddressType IPAddress; + /// Macַ + TThostFtdcMacAddressType MacAddress; +}; + +///ϲѯ +struct CThostFtdcQryExchangeCombActionField { + ///Ա + TThostFtdcParticipantIDType ParticipantID; + ///ͻ + TThostFtdcClientIDType ClientID; + ///ԼڽĴ + TThostFtdcExchangeInstIDType ExchangeInstID; + /// + TThostFtdcExchangeIDType ExchangeID; + ///Ա + TThostFtdcTraderIDType TraderID; +}; + +///Ʒۻ +struct CThostFtdcProductExchRateField { + ///Ʒ + TThostFtdcInstrumentIDType ProductID; + ///۱ + TThostFtdcCurrencyIDType QuoteCurrencyID; + /// + TThostFtdcExchangeRateType ExchangeRate; +}; + +///Ʒۻʲѯ +struct CThostFtdcQryProductExchRateField { + ///Ʒ + TThostFtdcInstrumentIDType ProductID; +}; + +///ѯѯۼ۲ +struct CThostFtdcQryForQuoteParamField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///Լ + TThostFtdcInstrumentIDType InstrumentID; + /// + TThostFtdcExchangeIDType ExchangeID; +}; + +///ѯۼ۲ +struct CThostFtdcForQuoteParamField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///Լ + TThostFtdcInstrumentIDType InstrumentID; + /// + TThostFtdcExchangeIDType ExchangeID; + ///¼ + TThostFtdcPriceType LastPrice; + ///۲ + TThostFtdcPriceType PriceInterval; +}; + +///ǰȨԼѵϸ +struct CThostFtdcMMOptionInstrCommRateField { + ///Լ + TThostFtdcInstrumentIDType InstrumentID; + ///Ͷ߷Χ + TThostFtdcInvestorRangeType InvestorRange; + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///Ͷߴ + TThostFtdcInvestorIDType InvestorID; + /// + TThostFtdcRatioType OpenRatioByMoney; + /// + TThostFtdcRatioType OpenRatioByVolume; + ///ƽ + TThostFtdcRatioType CloseRatioByMoney; + ///ƽ + TThostFtdcRatioType CloseRatioByVolume; + ///ƽ + TThostFtdcRatioType CloseTodayRatioByMoney; + ///ƽ + TThostFtdcRatioType CloseTodayRatioByVolume; + ///ִ + TThostFtdcRatioType StrikeRatioByMoney; + ///ִ + TThostFtdcRatioType StrikeRatioByVolume; +}; + +///Ȩʲѯ +struct CThostFtdcQryMMOptionInstrCommRateField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///Ͷߴ + TThostFtdcInvestorIDType InvestorID; + ///Լ + TThostFtdcInstrumentIDType InstrumentID; +}; + +///̺Լ +struct CThostFtdcMMInstrumentCommissionRateField { + ///Լ + TThostFtdcInstrumentIDType InstrumentID; + ///Ͷ߷Χ + TThostFtdcInvestorRangeType InvestorRange; + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///Ͷߴ + TThostFtdcInvestorIDType InvestorID; + /// + TThostFtdcRatioType OpenRatioByMoney; + /// + TThostFtdcRatioType OpenRatioByVolume; + ///ƽ + TThostFtdcRatioType CloseRatioByMoney; + ///ƽ + TThostFtdcRatioType CloseRatioByVolume; + ///ƽ + TThostFtdcRatioType CloseTodayRatioByMoney; + ///ƽ + TThostFtdcRatioType CloseTodayRatioByVolume; +}; + +///ѯ̺Լ +struct CThostFtdcQryMMInstrumentCommissionRateField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///Ͷߴ + TThostFtdcInvestorIDType InvestorID; + ///Լ + TThostFtdcInstrumentIDType InstrumentID; +}; + +///ǰѵϸ +struct CThostFtdcInstrumentOrderCommRateField { + ///Լ + TThostFtdcInstrumentIDType InstrumentID; + ///Ͷ߷Χ + TThostFtdcInvestorRangeType InvestorRange; + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///Ͷߴ + TThostFtdcInvestorIDType InvestorID; + ///Ͷױ־ + TThostFtdcHedgeFlagType HedgeFlag; + /// + TThostFtdcRatioType OrderCommByVolume; + /// + TThostFtdcRatioType OrderActionCommByVolume; +}; + +///ʲѯ +struct CThostFtdcQryInstrumentOrderCommRateField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///Ͷߴ + TThostFtdcInvestorIDType InvestorID; + ///Լ + TThostFtdcInstrumentIDType InstrumentID; +}; + +///г +struct CThostFtdcMarketDataField { + /// + TThostFtdcDateType TradingDay; + ///Լ + TThostFtdcInstrumentIDType InstrumentID; + /// + TThostFtdcExchangeIDType ExchangeID; + ///ԼڽĴ + TThostFtdcExchangeInstIDType ExchangeInstID; + ///¼ + TThostFtdcPriceType LastPrice; + ///ϴν + TThostFtdcPriceType PreSettlementPrice; + /// + TThostFtdcPriceType PreClosePrice; + ///ֲ + TThostFtdcLargeVolumeType PreOpenInterest; + /// + TThostFtdcPriceType OpenPrice; + ///߼ + TThostFtdcPriceType HighestPrice; + ///ͼ + TThostFtdcPriceType LowestPrice; + /// + TThostFtdcVolumeType Volume; + ///ɽ + TThostFtdcMoneyType Turnover; + ///ֲ + TThostFtdcLargeVolumeType OpenInterest; + /// + TThostFtdcPriceType ClosePrice; + ///ν + TThostFtdcPriceType SettlementPrice; + ///ͣ + TThostFtdcPriceType UpperLimitPrice; + ///ͣ + TThostFtdcPriceType LowerLimitPrice; + ///ʵ + TThostFtdcRatioType PreDelta; + ///ʵ + TThostFtdcRatioType CurrDelta; + ///޸ʱ + TThostFtdcTimeType UpdateTime; + ///޸ĺ + TThostFtdcMillisecType UpdateMillisec; + ///ҵ + TThostFtdcDateType ActionDay; +}; + +/// +struct CThostFtdcMarketDataBaseField { + /// + TThostFtdcDateType TradingDay; + ///ϴν + TThostFtdcPriceType PreSettlementPrice; + /// + TThostFtdcPriceType PreClosePrice; + ///ֲ + TThostFtdcLargeVolumeType PreOpenInterest; + ///ʵ + TThostFtdcRatioType PreDelta; +}; + +///龲̬ +struct CThostFtdcMarketDataStaticField { + /// + TThostFtdcPriceType OpenPrice; + ///߼ + TThostFtdcPriceType HighestPrice; + ///ͼ + TThostFtdcPriceType LowestPrice; + /// + TThostFtdcPriceType ClosePrice; + ///ͣ + TThostFtdcPriceType UpperLimitPrice; + ///ͣ + TThostFtdcPriceType LowerLimitPrice; + ///ν + TThostFtdcPriceType SettlementPrice; + ///ʵ + TThostFtdcRatioType CurrDelta; +}; + +///³ɽ +struct CThostFtdcMarketDataLastMatchField { + ///¼ + TThostFtdcPriceType LastPrice; + /// + TThostFtdcVolumeType Volume; + ///ɽ + TThostFtdcMoneyType Turnover; + ///ֲ + TThostFtdcLargeVolumeType OpenInterest; +}; + +///ż +struct CThostFtdcMarketDataBestPriceField { + ///һ + TThostFtdcPriceType BidPrice1; + ///һ + TThostFtdcVolumeType BidVolume1; + ///һ + TThostFtdcPriceType AskPrice1; + ///һ + TThostFtdcVolumeType AskVolume1; +}; + +/// +struct CThostFtdcMarketDataBid23Field { + ///۶ + TThostFtdcPriceType BidPrice2; + /// + TThostFtdcVolumeType BidVolume2; + /// + TThostFtdcPriceType BidPrice3; + /// + TThostFtdcVolumeType BidVolume3; +}; + +/// +struct CThostFtdcMarketDataAsk23Field { + ///۶ + TThostFtdcPriceType AskPrice2; + /// + TThostFtdcVolumeType AskVolume2; + /// + TThostFtdcPriceType AskPrice3; + /// + TThostFtdcVolumeType AskVolume3; +}; + +///ġ +struct CThostFtdcMarketDataBid45Field { + /// + TThostFtdcPriceType BidPrice4; + /// + TThostFtdcVolumeType BidVolume4; + /// + TThostFtdcPriceType BidPrice5; + /// + TThostFtdcVolumeType BidVolume5; +}; + +///ġ +struct CThostFtdcMarketDataAsk45Field { + /// + TThostFtdcPriceType AskPrice4; + /// + TThostFtdcVolumeType AskVolume4; + /// + TThostFtdcPriceType AskPrice5; + /// + TThostFtdcVolumeType AskVolume5; +}; + +///ʱ +struct CThostFtdcMarketDataUpdateTimeField { + ///Լ + TThostFtdcInstrumentIDType InstrumentID; + ///޸ʱ + TThostFtdcTimeType UpdateTime; + ///޸ĺ + TThostFtdcMillisecType UpdateMillisec; + ///ҵ + TThostFtdcDateType ActionDay; +}; + +///齻 +struct CThostFtdcMarketDataExchangeField { + /// + TThostFtdcExchangeIDType ExchangeID; +}; + +///ָĺԼ +struct CThostFtdcSpecificInstrumentField { + ///Լ + TThostFtdcInstrumentIDType InstrumentID; +}; + +///Լ״̬ +struct CThostFtdcInstrumentStatusField { + /// + TThostFtdcExchangeIDType ExchangeID; + ///ԼڽĴ + TThostFtdcExchangeInstIDType ExchangeInstID; + /// + TThostFtdcSettlementGroupIDType SettlementGroupID; + ///Լ + TThostFtdcInstrumentIDType InstrumentID; + ///Լ״̬ + TThostFtdcInstrumentStatusType InstrumentStatus; + ///׽׶α + TThostFtdcTradingSegmentSNType TradingSegmentSN; + ///뱾״̬ʱ + TThostFtdcTimeType EnterTime; + ///뱾״̬ԭ + TThostFtdcInstStatusEnterReasonType EnterReason; +}; + +///ѯԼ״̬ +struct CThostFtdcQryInstrumentStatusField { + /// + TThostFtdcExchangeIDType ExchangeID; + ///ԼڽĴ + TThostFtdcExchangeInstIDType ExchangeInstID; +}; + +///Ͷ˻ +struct CThostFtdcInvestorAccountField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///Ͷߴ + TThostFtdcInvestorIDType InvestorID; + ///Ͷʺ + TThostFtdcAccountIDType AccountID; + ///ִ + TThostFtdcCurrencyIDType CurrencyID; +}; + +///ӯ㷨 +struct CThostFtdcPositionProfitAlgorithmField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///Ͷʺ + TThostFtdcAccountIDType AccountID; + ///ӯ㷨 + TThostFtdcAlgorithmType Algorithm; + ///ע + TThostFtdcMemoType Memo; + ///ִ + TThostFtdcCurrencyIDType CurrencyID; +}; + +///Աʽۿ +struct CThostFtdcDiscountField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///Ͷ߷Χ + TThostFtdcInvestorRangeType InvestorRange; + ///Ͷߴ + TThostFtdcInvestorIDType InvestorID; + ///ʽۿ۱ + TThostFtdcRatioType Discount; +}; + +///ѯת +struct CThostFtdcQryTransferBankField { + ///д + TThostFtdcBankIDType BankID; + ///зĴ + TThostFtdcBankBrchIDType BankBrchID; +}; + +///ת +struct CThostFtdcTransferBankField { + ///д + TThostFtdcBankIDType BankID; + ///зĴ + TThostFtdcBankBrchIDType BankBrchID; + /// + TThostFtdcBankNameType BankName; + ///ǷԾ + TThostFtdcBoolType IsActive; +}; + +///ѯͶֲ߳ϸ +struct CThostFtdcQryInvestorPositionDetailField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///Ͷߴ + TThostFtdcInvestorIDType InvestorID; + ///Լ + TThostFtdcInstrumentIDType InstrumentID; +}; + +///Ͷֲ߳ϸ +struct CThostFtdcInvestorPositionDetailField { + ///Լ + TThostFtdcInstrumentIDType InstrumentID; + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///Ͷߴ + TThostFtdcInvestorIDType InvestorID; + ///Ͷױ־ + TThostFtdcHedgeFlagType HedgeFlag; + /// + TThostFtdcDirectionType Direction; + /// + TThostFtdcDateType OpenDate; + ///ɽ + TThostFtdcTradeIDType TradeID; + /// + TThostFtdcVolumeType Volume; + ///ּ + TThostFtdcPriceType OpenPrice; + /// + TThostFtdcDateType TradingDay; + /// + TThostFtdcSettlementIDType SettlementID; + ///ɽ + TThostFtdcTradeTypeType TradeType; + ///ϺԼ + TThostFtdcInstrumentIDType CombInstrumentID; + /// + TThostFtdcExchangeIDType ExchangeID; + ///նƽӯ + TThostFtdcMoneyType CloseProfitByDate; + ///ʶԳƽӯ + TThostFtdcMoneyType CloseProfitByTrade; + ///նгֲӯ + TThostFtdcMoneyType PositionProfitByDate; + ///ʶԳֲӯ + TThostFtdcMoneyType PositionProfitByTrade; + ///Ͷ֤߱ + TThostFtdcMoneyType Margin; + ///֤ + TThostFtdcMoneyType ExchMargin; + ///֤ + TThostFtdcRatioType MarginRateByMoney; + ///֤() + TThostFtdcRatioType MarginRateByVolume; + /// + TThostFtdcPriceType LastSettlementPrice; + /// + TThostFtdcPriceType SettlementPrice; + ///ƽ + TThostFtdcVolumeType CloseVolume; + ///ƽֽ + TThostFtdcMoneyType CloseAmount; +}; + +///ʽ˻ +struct CThostFtdcTradingAccountPasswordField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///Ͷʺ + TThostFtdcAccountIDType AccountID; + /// + TThostFtdcPasswordType Password; + ///ִ + TThostFtdcCurrencyIDType CurrencyID; +}; + +///鱨̻ +struct CThostFtdcMDTraderOfferField { + /// + TThostFtdcExchangeIDType ExchangeID; + ///Ա + TThostFtdcTraderIDType TraderID; + ///Ա + TThostFtdcParticipantIDType ParticipantID; + /// + TThostFtdcPasswordType Password; + ///װ + TThostFtdcInstallIDType InstallID; + ///ر + TThostFtdcOrderLocalIDType OrderLocalID; + ///Ա״̬ + TThostFtdcTraderConnectStatusType TraderConnectStatus; + /// + TThostFtdcDateType ConnectRequestDate; + ///ʱ + TThostFtdcTimeType ConnectRequestTime; + ///ϴα + TThostFtdcDateType LastReportDate; + ///ϴαʱ + TThostFtdcTimeType LastReportTime; + /// + TThostFtdcDateType ConnectDate; + ///ʱ + TThostFtdcTimeType ConnectTime; + /// + TThostFtdcDateType StartDate; + ///ʱ + TThostFtdcTimeType StartTime; + /// + TThostFtdcDateType TradingDay; + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///ϯλɽ + TThostFtdcTradeIDType MaxTradeID; + ///ϯλ󱨵 + TThostFtdcReturnCodeType MaxOrderMessageReference; +}; + +///ѯ鱨̻ +struct CThostFtdcQryMDTraderOfferField { + /// + TThostFtdcExchangeIDType ExchangeID; + ///Ա + TThostFtdcParticipantIDType ParticipantID; + ///Ա + TThostFtdcTraderIDType TraderID; +}; + +///ѯͻ֪ͨ +struct CThostFtdcQryNoticeField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; +}; + +///ͻ֪ͨ +struct CThostFtdcNoticeField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///Ϣ + TThostFtdcContentType Content; + ///͹˾֪ͨк + TThostFtdcSequenceLabelType SequenceLabel; +}; + +///ûȨ +struct CThostFtdcUserRightField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///û + TThostFtdcUserIDType UserID; + ///ͻȨ + TThostFtdcUserRightTypeType UserRightType; + ///Ƿֹ + TThostFtdcBoolType IsForbidden; +}; + +///ѯϢȷ +struct CThostFtdcQrySettlementInfoConfirmField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///Ͷߴ + TThostFtdcInvestorIDType InvestorID; +}; + +///װؽϢ +struct CThostFtdcLoadSettlementInfoField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; +}; + +///͹˾ʽ㷨 +struct CThostFtdcBrokerWithdrawAlgorithmField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///ʽ㷨 + TThostFtdcAlgorithmType WithdrawAlgorithm; + ///ʽʹ + TThostFtdcRatioType UsingRatio; + ///Ƿƽӯ + TThostFtdcIncludeCloseProfitType IncludeCloseProfit; + ///޲޳ɽͻǷܿ + TThostFtdcAllWithoutTradeType AllWithoutTrade; + ///Ƿƽӯ + TThostFtdcIncludeCloseProfitType AvailIncludeCloseProfit; + ///Ƿû¼ + TThostFtdcBoolType IsBrokerUserEvent; + ///ִ + TThostFtdcCurrencyIDType CurrencyID; + ///Ѻ + TThostFtdcRatioType FundMortgageRatio; + ///Ȩ㷨 + TThostFtdcBalanceAlgorithmType BalanceAlgorithm; +}; + +///ʽ˻ +struct CThostFtdcTradingAccountPasswordUpdateV1Field { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///Ͷߴ + TThostFtdcInvestorIDType InvestorID; + ///ԭĿ + TThostFtdcPasswordType OldPassword; + ///µĿ + TThostFtdcPasswordType NewPassword; +}; + +///ʽ˻ +struct CThostFtdcTradingAccountPasswordUpdateField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///Ͷʺ + TThostFtdcAccountIDType AccountID; + ///ԭĿ + TThostFtdcPasswordType OldPassword; + ///µĿ + TThostFtdcPasswordType NewPassword; + ///ִ + TThostFtdcCurrencyIDType CurrencyID; +}; + +///ѯϺԼ +struct CThostFtdcQryCombinationLegField { + ///ϺԼ + TThostFtdcInstrumentIDType CombInstrumentID; + ///ȱ + TThostFtdcLegIDType LegID; + ///ȺԼ + TThostFtdcInstrumentIDType LegInstrumentID; +}; + +///ѯϺԼ +struct CThostFtdcQrySyncStatusField { + /// + TThostFtdcDateType TradingDay; +}; + +///Ͻ׺Լĵ +struct CThostFtdcCombinationLegField { + ///ϺԼ + TThostFtdcInstrumentIDType CombInstrumentID; + ///ȱ + TThostFtdcLegIDType LegID; + ///ȺԼ + TThostFtdcInstrumentIDType LegInstrumentID; + /// + TThostFtdcDirectionType Direction; + ///ȳ + TThostFtdcLegMultipleType LegMultiple; + /// + TThostFtdcImplyLevelType ImplyLevel; +}; + +///ͬ״̬ +struct CThostFtdcSyncStatusField { + /// + TThostFtdcDateType TradingDay; + ///ͬ״̬ + TThostFtdcDataSyncStatusType DataSyncStatus; +}; + +///ѯϵ +struct CThostFtdcQryLinkManField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///Ͷߴ + TThostFtdcInvestorIDType InvestorID; +}; + +///ϵ +struct CThostFtdcLinkManField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///Ͷߴ + TThostFtdcInvestorIDType InvestorID; + ///ϵ + TThostFtdcPersonTypeType PersonType; + ///֤ + TThostFtdcIdCardTypeType IdentifiedCardType; + ///֤ + TThostFtdcIdentifiedCardNoType IdentifiedCardNo; + /// + TThostFtdcPartyNameType PersonName; + ///ϵ绰 + TThostFtdcTelephoneType Telephone; + ///ͨѶַ + TThostFtdcAddressType Address; + /// + TThostFtdcZipCodeType ZipCode; + ///ȼ + TThostFtdcPriorityType Priority; + /// + TThostFtdcUOAZipCodeType UOAZipCode; + ///ȫ + TThostFtdcInvestorFullNameType PersonFullName; +}; + +///ѯ͹˾û¼ +struct CThostFtdcQryBrokerUserEventField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///û + TThostFtdcUserIDType UserID; + ///û¼ + TThostFtdcUserEventTypeType UserEventType; +}; + +///ѯ͹˾û¼ +struct CThostFtdcBrokerUserEventField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///û + TThostFtdcUserIDType UserID; + ///û¼ + TThostFtdcUserEventTypeType UserEventType; + ///û¼ + TThostFtdcSequenceNoType EventSequenceNo; + ///¼ + TThostFtdcDateType EventDate; + ///¼ʱ + TThostFtdcTimeType EventTime; + ///û¼Ϣ + TThostFtdcUserEventInfoType UserEventInfo; + ///Ͷߴ + TThostFtdcInvestorIDType InvestorID; + ///Լ + TThostFtdcInstrumentIDType InstrumentID; +}; + +///ѯǩԼ +struct CThostFtdcQryContractBankField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///д + TThostFtdcBankIDType BankID; + ///зĴ + TThostFtdcBankBrchIDType BankBrchID; +}; + +///ѯǩԼӦ +struct CThostFtdcContractBankField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///д + TThostFtdcBankIDType BankID; + ///зĴ + TThostFtdcBankBrchIDType BankBrchID; + /// + TThostFtdcBankNameType BankName; +}; + +///Ͷϳֲϸ +struct CThostFtdcInvestorPositionCombineDetailField { + /// + TThostFtdcDateType TradingDay; + /// + TThostFtdcDateType OpenDate; + /// + TThostFtdcExchangeIDType ExchangeID; + /// + TThostFtdcSettlementIDType SettlementID; + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///Ͷߴ + TThostFtdcInvestorIDType InvestorID; + ///ϱ + TThostFtdcTradeIDType ComTradeID; + ///ϱ + TThostFtdcTradeIDType TradeID; + ///Լ + TThostFtdcInstrumentIDType InstrumentID; + ///Ͷױ־ + TThostFtdcHedgeFlagType HedgeFlag; + /// + TThostFtdcDirectionType Direction; + ///ֲ + TThostFtdcVolumeType TotalAmt; + ///Ͷ֤߱ + TThostFtdcMoneyType Margin; + ///֤ + TThostFtdcMoneyType ExchMargin; + ///֤ + TThostFtdcRatioType MarginRateByMoney; + ///֤() + TThostFtdcRatioType MarginRateByVolume; + ///ȱ + TThostFtdcLegIDType LegID; + ///ȳ + TThostFtdcLegMultipleType LegMultiple; + ///ϳֲֺԼ + TThostFtdcInstrumentIDType CombInstrumentID; + ///ɽ + TThostFtdcTradeGroupIDType TradeGroupID; +}; + +///Ԥ +struct CThostFtdcParkedOrderField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///Ͷߴ + TThostFtdcInvestorIDType InvestorID; + ///Լ + TThostFtdcInstrumentIDType InstrumentID; + /// + TThostFtdcOrderRefType OrderRef; + ///û + TThostFtdcUserIDType UserID; + ///۸ + TThostFtdcOrderPriceTypeType OrderPriceType; + /// + TThostFtdcDirectionType Direction; + ///Ͽƽ־ + TThostFtdcCombOffsetFlagType CombOffsetFlag; + ///Ͷױ־ + TThostFtdcCombHedgeFlagType CombHedgeFlag; + ///۸ + TThostFtdcPriceType LimitPrice; + /// + TThostFtdcVolumeType VolumeTotalOriginal; + ///Ч + TThostFtdcTimeConditionType TimeCondition; + /// GTD + TThostFtdcDateType GTDDate; + ///ɽ + TThostFtdcVolumeConditionType VolumeCondition; + ///Сɽ + TThostFtdcVolumeType MinVolume; + /// + TThostFtdcContingentConditionType ContingentCondition; + ///ֹ + TThostFtdcPriceType StopPrice; + ///ǿƽԭ + TThostFtdcForceCloseReasonType ForceCloseReason; + ///Զ־ + TThostFtdcBoolType IsAutoSuspend; + ///ҵԪ + TThostFtdcBusinessUnitType BusinessUnit; + /// + TThostFtdcRequestIDType RequestID; + ///ûǿ־ + TThostFtdcBoolType UserForceClose; + /// + TThostFtdcExchangeIDType ExchangeID; + ///Ԥ񱨵 + TThostFtdcParkedOrderIDType ParkedOrderID; + ///û + TThostFtdcUserTypeType UserType; + ///Ԥ״̬ + TThostFtdcParkedOrderStatusType Status; + /// + TThostFtdcErrorIDType ErrorID; + ///Ϣ + TThostFtdcErrorMsgType ErrorMsg; + ///־ + TThostFtdcBoolType IsSwapOrder; + ///ʽ˺ + TThostFtdcAccountIDType AccountID; + ///ִ + TThostFtdcCurrencyIDType CurrencyID; + ///ױ + TThostFtdcClientIDType ClientID; + ///ͶʵԪ + TThostFtdcInvestUnitIDType InvestUnitID; + /// IPַ + TThostFtdcIPAddressType IPAddress; + /// Macַ + TThostFtdcMacAddressType MacAddress; +}; + +///Ԥ񵥲 +struct CThostFtdcParkedOrderActionField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///Ͷߴ + TThostFtdcInvestorIDType InvestorID; + /// + TThostFtdcOrderActionRefType OrderActionRef; + /// + TThostFtdcOrderRefType OrderRef; + /// + TThostFtdcRequestIDType RequestID; + ///ǰñ + TThostFtdcFrontIDType FrontID; + ///Ự + TThostFtdcSessionIDType SessionID; + /// + TThostFtdcExchangeIDType ExchangeID; + /// + TThostFtdcOrderSysIDType OrderSysID; + ///־ + TThostFtdcActionFlagType ActionFlag; + ///۸ + TThostFtdcPriceType LimitPrice; + ///仯 + TThostFtdcVolumeType VolumeChange; + ///û + TThostFtdcUserIDType UserID; + ///Լ + TThostFtdcInstrumentIDType InstrumentID; + ///Ԥ񳷵 + TThostFtdcParkedOrderActionIDType ParkedOrderActionID; + ///û + TThostFtdcUserTypeType UserType; + ///Ԥ񳷵״̬ + TThostFtdcParkedOrderStatusType Status; + /// + TThostFtdcErrorIDType ErrorID; + ///Ϣ + TThostFtdcErrorMsgType ErrorMsg; + ///ͶʵԪ + TThostFtdcInvestUnitIDType InvestUnitID; + /// IPַ + TThostFtdcIPAddressType IPAddress; + /// Macַ + TThostFtdcMacAddressType MacAddress; +}; + +///ѯԤ +struct CThostFtdcQryParkedOrderField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///Ͷߴ + TThostFtdcInvestorIDType InvestorID; + ///Լ + TThostFtdcInstrumentIDType InstrumentID; + /// + TThostFtdcExchangeIDType ExchangeID; +}; + +///ѯԤ񳷵 +struct CThostFtdcQryParkedOrderActionField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///Ͷߴ + TThostFtdcInvestorIDType InvestorID; + ///Լ + TThostFtdcInstrumentIDType InstrumentID; + /// + TThostFtdcExchangeIDType ExchangeID; +}; + +///ɾԤ +struct CThostFtdcRemoveParkedOrderField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///Ͷߴ + TThostFtdcInvestorIDType InvestorID; + ///Ԥ񱨵 + TThostFtdcParkedOrderIDType ParkedOrderID; +}; + +///ɾԤ񳷵 +struct CThostFtdcRemoveParkedOrderActionField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///Ͷߴ + TThostFtdcInvestorIDType InvestorID; + ///Ԥ񳷵 + TThostFtdcParkedOrderActionIDType ParkedOrderActionID; +}; + +///͹˾ʽ㷨 +struct CThostFtdcInvestorWithdrawAlgorithmField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///Ͷ߷Χ + TThostFtdcInvestorRangeType InvestorRange; + ///Ͷߴ + TThostFtdcInvestorIDType InvestorID; + ///ʽ + TThostFtdcRatioType UsingRatio; + ///ִ + TThostFtdcCurrencyIDType CurrencyID; + ///Ѻ + TThostFtdcRatioType FundMortgageRatio; +}; + +///ѯϳֲϸ +struct CThostFtdcQryInvestorPositionCombineDetailField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///Ͷߴ + TThostFtdcInvestorIDType InvestorID; + ///ϳֲֺԼ + TThostFtdcInstrumentIDType CombInstrumentID; +}; + +///ɽ +struct CThostFtdcMarketDataAveragePriceField { + ///վ + TThostFtdcPriceType AveragePrice; +}; + +///УͶ +struct CThostFtdcVerifyInvestorPasswordField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///Ͷߴ + TThostFtdcInvestorIDType InvestorID; + /// + TThostFtdcPasswordType Password; +}; + +///ûIP +struct CThostFtdcUserIPField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///û + TThostFtdcUserIDType UserID; + /// IPַ + TThostFtdcIPAddressType IPAddress; + /// IPַ + TThostFtdcIPAddressType IPMask; + /// Macַ + TThostFtdcMacAddressType MacAddress; +}; + +///û¼֪ͨϢ +struct CThostFtdcTradingNoticeInfoField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///Ͷߴ + TThostFtdcInvestorIDType InvestorID; + ///ʱ + TThostFtdcTimeType SendTime; + ///Ϣ + TThostFtdcContentType FieldContent; + ///ϵк + TThostFtdcSequenceSeriesType SequenceSeries; + ///к + TThostFtdcSequenceNoType SequenceNo; +}; + +///û¼֪ͨ +struct CThostFtdcTradingNoticeField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///Ͷ߷Χ + TThostFtdcInvestorRangeType InvestorRange; + ///Ͷߴ + TThostFtdcInvestorIDType InvestorID; + ///ϵк + TThostFtdcSequenceSeriesType SequenceSeries; + ///û + TThostFtdcUserIDType UserID; + ///ʱ + TThostFtdcTimeType SendTime; + ///к + TThostFtdcSequenceNoType SequenceNo; + ///Ϣ + TThostFtdcContentType FieldContent; +}; + +///ѯ¼֪ͨ +struct CThostFtdcQryTradingNoticeField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///Ͷߴ + TThostFtdcInvestorIDType InvestorID; +}; + +///ѯ󱨵 +struct CThostFtdcQryErrOrderField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///Ͷߴ + TThostFtdcInvestorIDType InvestorID; +}; + +///󱨵 +struct CThostFtdcErrOrderField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///Ͷߴ + TThostFtdcInvestorIDType InvestorID; + ///Լ + TThostFtdcInstrumentIDType InstrumentID; + /// + TThostFtdcOrderRefType OrderRef; + ///û + TThostFtdcUserIDType UserID; + ///۸ + TThostFtdcOrderPriceTypeType OrderPriceType; + /// + TThostFtdcDirectionType Direction; + ///Ͽƽ־ + TThostFtdcCombOffsetFlagType CombOffsetFlag; + ///Ͷױ־ + TThostFtdcCombHedgeFlagType CombHedgeFlag; + ///۸ + TThostFtdcPriceType LimitPrice; + /// + TThostFtdcVolumeType VolumeTotalOriginal; + ///Ч + TThostFtdcTimeConditionType TimeCondition; + /// GTD + TThostFtdcDateType GTDDate; + ///ɽ + TThostFtdcVolumeConditionType VolumeCondition; + ///Сɽ + TThostFtdcVolumeType MinVolume; + /// + TThostFtdcContingentConditionType ContingentCondition; + ///ֹ + TThostFtdcPriceType StopPrice; + ///ǿƽԭ + TThostFtdcForceCloseReasonType ForceCloseReason; + ///Զ־ + TThostFtdcBoolType IsAutoSuspend; + ///ҵԪ + TThostFtdcBusinessUnitType BusinessUnit; + /// + TThostFtdcRequestIDType RequestID; + ///ûǿ־ + TThostFtdcBoolType UserForceClose; + /// + TThostFtdcErrorIDType ErrorID; + ///Ϣ + TThostFtdcErrorMsgType ErrorMsg; + ///־ + TThostFtdcBoolType IsSwapOrder; + /// + TThostFtdcExchangeIDType ExchangeID; + ///ͶʵԪ + TThostFtdcInvestUnitIDType InvestUnitID; + ///ʽ˺ + TThostFtdcAccountIDType AccountID; + ///ִ + TThostFtdcCurrencyIDType CurrencyID; + ///ױ + TThostFtdcClientIDType ClientID; + /// IPַ + TThostFtdcIPAddressType IPAddress; + /// Macַ + TThostFtdcMacAddressType MacAddress; +}; + +///ѯ󱨵 +struct CThostFtdcErrorConditionalOrderField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///Ͷߴ + TThostFtdcInvestorIDType InvestorID; + ///Լ + TThostFtdcInstrumentIDType InstrumentID; + /// + TThostFtdcOrderRefType OrderRef; + ///û + TThostFtdcUserIDType UserID; + ///۸ + TThostFtdcOrderPriceTypeType OrderPriceType; + /// + TThostFtdcDirectionType Direction; + ///Ͽƽ־ + TThostFtdcCombOffsetFlagType CombOffsetFlag; + ///Ͷױ־ + TThostFtdcCombHedgeFlagType CombHedgeFlag; + ///۸ + TThostFtdcPriceType LimitPrice; + /// + TThostFtdcVolumeType VolumeTotalOriginal; + ///Ч + TThostFtdcTimeConditionType TimeCondition; + /// GTD + TThostFtdcDateType GTDDate; + ///ɽ + TThostFtdcVolumeConditionType VolumeCondition; + ///Сɽ + TThostFtdcVolumeType MinVolume; + /// + TThostFtdcContingentConditionType ContingentCondition; + ///ֹ + TThostFtdcPriceType StopPrice; + ///ǿƽԭ + TThostFtdcForceCloseReasonType ForceCloseReason; + ///Զ־ + TThostFtdcBoolType IsAutoSuspend; + ///ҵԪ + TThostFtdcBusinessUnitType BusinessUnit; + /// + TThostFtdcRequestIDType RequestID; + ///ر + TThostFtdcOrderLocalIDType OrderLocalID; + /// + TThostFtdcExchangeIDType ExchangeID; + ///Ա + TThostFtdcParticipantIDType ParticipantID; + ///ͻ + TThostFtdcClientIDType ClientID; + ///ԼڽĴ + TThostFtdcExchangeInstIDType ExchangeInstID; + ///Ա + TThostFtdcTraderIDType TraderID; + ///װ + TThostFtdcInstallIDType InstallID; + ///ύ״̬ + TThostFtdcOrderSubmitStatusType OrderSubmitStatus; + ///ʾ + TThostFtdcSequenceNoType NotifySequence; + /// + TThostFtdcDateType TradingDay; + /// + TThostFtdcSettlementIDType SettlementID; + /// + TThostFtdcOrderSysIDType OrderSysID; + ///Դ + TThostFtdcOrderSourceType OrderSource; + ///״̬ + TThostFtdcOrderStatusType OrderStatus; + /// + TThostFtdcOrderTypeType OrderType; + ///ɽ + TThostFtdcVolumeType VolumeTraded; + ///ʣ + TThostFtdcVolumeType VolumeTotal; + /// + TThostFtdcDateType InsertDate; + ///ίʱ + TThostFtdcTimeType InsertTime; + ///ʱ + TThostFtdcTimeType ActiveTime; + ///ʱ + TThostFtdcTimeType SuspendTime; + ///޸ʱ + TThostFtdcTimeType UpdateTime; + ///ʱ + TThostFtdcTimeType CancelTime; + ///޸ĽԱ + TThostFtdcTraderIDType ActiveTraderID; + ///Ա + TThostFtdcParticipantIDType ClearingPartID; + /// + TThostFtdcSequenceNoType SequenceNo; + ///ǰñ + TThostFtdcFrontIDType FrontID; + ///Ự + TThostFtdcSessionIDType SessionID; + ///û˲ƷϢ + TThostFtdcProductInfoType UserProductInfo; + ///״̬Ϣ + TThostFtdcErrorMsgType StatusMsg; + ///ûǿ־ + TThostFtdcBoolType UserForceClose; + ///û + TThostFtdcUserIDType ActiveUserID; + ///͹˾ + TThostFtdcSequenceNoType BrokerOrderSeq; + ///ر + TThostFtdcOrderSysIDType RelativeOrderSysID; + ///֣ɽ + TThostFtdcVolumeType ZCETotalTradedVolume; + /// + TThostFtdcErrorIDType ErrorID; + ///Ϣ + TThostFtdcErrorMsgType ErrorMsg; + ///־ + TThostFtdcBoolType IsSwapOrder; + ///Ӫҵ + TThostFtdcBranchIDType BranchID; + ///ͶʵԪ + TThostFtdcInvestUnitIDType InvestUnitID; + ///ʽ˺ + TThostFtdcAccountIDType AccountID; + ///ִ + TThostFtdcCurrencyIDType CurrencyID; + /// IPַ + TThostFtdcIPAddressType IPAddress; + /// Macַ + TThostFtdcMacAddressType MacAddress; +}; + +///ѯ󱨵 +struct CThostFtdcQryErrOrderActionField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///Ͷߴ + TThostFtdcInvestorIDType InvestorID; +}; + +///󱨵 +struct CThostFtdcErrOrderActionField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///Ͷߴ + TThostFtdcInvestorIDType InvestorID; + /// + TThostFtdcOrderActionRefType OrderActionRef; + /// + TThostFtdcOrderRefType OrderRef; + /// + TThostFtdcRequestIDType RequestID; + ///ǰñ + TThostFtdcFrontIDType FrontID; + ///Ự + TThostFtdcSessionIDType SessionID; + /// + TThostFtdcExchangeIDType ExchangeID; + /// + TThostFtdcOrderSysIDType OrderSysID; + ///־ + TThostFtdcActionFlagType ActionFlag; + ///۸ + TThostFtdcPriceType LimitPrice; + ///仯 + TThostFtdcVolumeType VolumeChange; + /// + TThostFtdcDateType ActionDate; + ///ʱ + TThostFtdcTimeType ActionTime; + ///Ա + TThostFtdcTraderIDType TraderID; + ///װ + TThostFtdcInstallIDType InstallID; + ///ر + TThostFtdcOrderLocalIDType OrderLocalID; + ///ر + TThostFtdcOrderLocalIDType ActionLocalID; + ///Ա + TThostFtdcParticipantIDType ParticipantID; + ///ͻ + TThostFtdcClientIDType ClientID; + ///ҵԪ + TThostFtdcBusinessUnitType BusinessUnit; + ///״̬ + TThostFtdcOrderActionStatusType OrderActionStatus; + ///û + TThostFtdcUserIDType UserID; + ///״̬Ϣ + TThostFtdcErrorMsgType StatusMsg; + ///Լ + TThostFtdcInstrumentIDType InstrumentID; + ///Ӫҵ + TThostFtdcBranchIDType BranchID; + ///ͶʵԪ + TThostFtdcInvestUnitIDType InvestUnitID; + /// IPַ + TThostFtdcIPAddressType IPAddress; + /// Macַ + TThostFtdcMacAddressType MacAddress; + /// + TThostFtdcErrorIDType ErrorID; + ///Ϣ + TThostFtdcErrorMsgType ErrorMsg; +}; + +///ѯ״̬ +struct CThostFtdcQryExchangeSequenceField { + /// + TThostFtdcExchangeIDType ExchangeID; +}; + +///״̬ +struct CThostFtdcExchangeSequenceField { + /// + TThostFtdcExchangeIDType ExchangeID; + /// + TThostFtdcSequenceNoType SequenceNo; + ///Լ״̬ + TThostFtdcInstrumentStatusType MarketStatus; +}; + +///ݼ۸ѯ󱨵 +struct CThostFtdcQueryMaxOrderVolumeWithPriceField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///Ͷߴ + TThostFtdcInvestorIDType InvestorID; + ///Լ + TThostFtdcInstrumentIDType InstrumentID; + /// + TThostFtdcDirectionType Direction; + ///ƽ־ + TThostFtdcOffsetFlagType OffsetFlag; + ///Ͷױ־ + TThostFtdcHedgeFlagType HedgeFlag; + /// + TThostFtdcVolumeType MaxVolume; + ///۸ + TThostFtdcPriceType Price; +}; + +///ѯ͹˾ײ +struct CThostFtdcQryBrokerTradingParamsField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///Ͷߴ + TThostFtdcInvestorIDType InvestorID; + ///ִ + TThostFtdcCurrencyIDType CurrencyID; +}; + +///͹˾ײ +struct CThostFtdcBrokerTradingParamsField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///Ͷߴ + TThostFtdcInvestorIDType InvestorID; + ///֤۸ + TThostFtdcMarginPriceTypeType MarginPriceType; + ///ӯ㷨 + TThostFtdcAlgorithmType Algorithm; + ///Ƿƽӯ + TThostFtdcIncludeCloseProfitType AvailIncludeCloseProfit; + ///ִ + TThostFtdcCurrencyIDType CurrencyID; + ///ȨȨ۸ + TThostFtdcOptionRoyaltyPriceTypeType OptionRoyaltyPriceType; +}; + +///ѯ͹˾㷨 +struct CThostFtdcQryBrokerTradingAlgosField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + /// + TThostFtdcExchangeIDType ExchangeID; + ///Լ + TThostFtdcInstrumentIDType InstrumentID; +}; + +///͹˾㷨 +struct CThostFtdcBrokerTradingAlgosField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + /// + TThostFtdcExchangeIDType ExchangeID; + ///Լ + TThostFtdcInstrumentIDType InstrumentID; + ///ֲִ㷨 + TThostFtdcHandlePositionAlgoIDType HandlePositionAlgoID; + ///Ѱұ֤㷨 + TThostFtdcFindMarginRateAlgoIDType FindMarginRateAlgoID; + ///ʽ㷨 + TThostFtdcHandleTradingAccountAlgoIDType HandleTradingAccountAlgoID; +}; + +///ѯ͹˾ʽ +struct CThostFtdcQueryBrokerDepositField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + /// + TThostFtdcExchangeIDType ExchangeID; +}; + +///͹˾ʽ +struct CThostFtdcBrokerDepositField { + /// + TThostFtdcTradeDateType TradingDay; + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///Ա + TThostFtdcParticipantIDType ParticipantID; + /// + TThostFtdcExchangeIDType ExchangeID; + ///ϴν׼ + TThostFtdcMoneyType PreBalance; + ///ǰ֤ܶ + TThostFtdcMoneyType CurrMargin; + ///ƽӯ + TThostFtdcMoneyType CloseProfit; + ///ڻ׼ + TThostFtdcMoneyType Balance; + /// + TThostFtdcMoneyType Deposit; + /// + TThostFtdcMoneyType Withdraw; + ///ʽ + TThostFtdcMoneyType Available; + ///׼ + TThostFtdcMoneyType Reserve; + ///ı֤ + TThostFtdcMoneyType FrozenMargin; +}; + +///ѯ֤ϵͳ͹˾Կ +struct CThostFtdcQryCFMMCBrokerKeyField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; +}; + +///֤ϵͳ͹˾Կ +struct CThostFtdcCFMMCBrokerKeyField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///͹˾ͳһ + TThostFtdcParticipantIDType ParticipantID; + ///Կ + TThostFtdcDateType CreateDate; + ///Կʱ + TThostFtdcTimeType CreateTime; + ///Կ + TThostFtdcSequenceNoType KeyID; + ///̬Կ + TThostFtdcCFMMCKeyType CurrentKey; + ///̬Կ + TThostFtdcCFMMCKeyKindType KeyKind; +}; + +///֤ϵͳ͹˾ʽ˻Կ +struct CThostFtdcCFMMCTradingAccountKeyField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///͹˾ͳһ + TThostFtdcParticipantIDType ParticipantID; + ///Ͷʺ + TThostFtdcAccountIDType AccountID; + ///Կ + TThostFtdcSequenceNoType KeyID; + ///̬Կ + TThostFtdcCFMMCKeyType CurrentKey; +}; + +///ѯ֤ϵͳ͹˾ʽ˻Կ +struct CThostFtdcQryCFMMCTradingAccountKeyField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///Ͷߴ + TThostFtdcInvestorIDType InvestorID; +}; + +///û̬Ʋ +struct CThostFtdcBrokerUserOTPParamField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///û + TThostFtdcUserIDType UserID; + ///̬ṩ + TThostFtdcOTPVendorsIDType OTPVendorsID; + ///̬к + TThostFtdcSerialNumberType SerialNumber; + ///Կ + TThostFtdcAuthKeyType AuthKey; + ///Ưֵ + TThostFtdcLastDriftType LastDrift; + ///ɹֵ + TThostFtdcLastSuccessType LastSuccess; + ///̬ + TThostFtdcOTPTypeType OTPType; +}; + +///ֹͬû̬ +struct CThostFtdcManualSyncBrokerUserOTPField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///û + TThostFtdcUserIDType UserID; + ///̬ + TThostFtdcOTPTypeType OTPType; + ///һ̬ + TThostFtdcPasswordType FirstOTP; + ///ڶ̬ + TThostFtdcPasswordType SecondOTP; +}; + +///Ͷģ +struct CThostFtdcCommRateModelField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///ģ + TThostFtdcInvestorIDType CommModelID; + ///ģ + TThostFtdcCommModelNameType CommModelName; +}; + +///ѯͶģ +struct CThostFtdcQryCommRateModelField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///ģ + TThostFtdcInvestorIDType CommModelID; +}; + +///Ͷ֤߱ģ +struct CThostFtdcMarginModelField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///֤ģ + TThostFtdcInvestorIDType MarginModelID; + ///ģ + TThostFtdcCommModelNameType MarginModelName; +}; + +///ѯͶ֤߱ģ +struct CThostFtdcQryMarginModelField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///֤ģ + TThostFtdcInvestorIDType MarginModelID; +}; + +///ֵ۵Ϣ +struct CThostFtdcEWarrantOffsetField { + /// + TThostFtdcTradeDateType TradingDay; + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///Ͷߴ + TThostFtdcInvestorIDType InvestorID; + /// + TThostFtdcExchangeIDType ExchangeID; + ///Լ + TThostFtdcInstrumentIDType InstrumentID; + /// + TThostFtdcDirectionType Direction; + ///Ͷױ־ + TThostFtdcHedgeFlagType HedgeFlag; + /// + TThostFtdcVolumeType Volume; +}; + +///ѯֵ۵Ϣ +struct CThostFtdcQryEWarrantOffsetField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///Ͷߴ + TThostFtdcInvestorIDType InvestorID; + /// + TThostFtdcExchangeIDType ExchangeID; + ///Լ + TThostFtdcInstrumentIDType InstrumentID; +}; + +///ѯͶƷ/Ʒֱ֤ +struct CThostFtdcQryInvestorProductGroupMarginField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///Ͷߴ + TThostFtdcInvestorIDType InvestorID; + ///Ʒ/Ʒֱʾ + TThostFtdcInstrumentIDType ProductGroupID; + ///Ͷױ־ + TThostFtdcHedgeFlagType HedgeFlag; +}; + +///ͶƷ/Ʒֱ֤ +struct CThostFtdcInvestorProductGroupMarginField { + ///Ʒ/Ʒֱʾ + TThostFtdcInstrumentIDType ProductGroupID; + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///Ͷߴ + TThostFtdcInvestorIDType InvestorID; + /// + TThostFtdcDateType TradingDay; + /// + TThostFtdcSettlementIDType SettlementID; + ///ı֤ + TThostFtdcMoneyType FrozenMargin; + ///ͷı֤ + TThostFtdcMoneyType LongFrozenMargin; + ///ͷı֤ + TThostFtdcMoneyType ShortFrozenMargin; + ///ռõı֤ + TThostFtdcMoneyType UseMargin; + ///ͷ֤ + TThostFtdcMoneyType LongUseMargin; + ///ͷ֤ + TThostFtdcMoneyType ShortUseMargin; + ///֤ + TThostFtdcMoneyType ExchMargin; + ///ͷ֤ + TThostFtdcMoneyType LongExchMargin; + ///ͷ֤ + TThostFtdcMoneyType ShortExchMargin; + ///ƽӯ + TThostFtdcMoneyType CloseProfit; + /// + TThostFtdcMoneyType FrozenCommission; + /// + TThostFtdcMoneyType Commission; + ///ʽ + TThostFtdcMoneyType FrozenCash; + ///ʽ + TThostFtdcMoneyType CashIn; + ///ֲӯ + TThostFtdcMoneyType PositionProfit; + ///۵ܽ + TThostFtdcMoneyType OffsetAmount; + ///ͷ۵ܽ + TThostFtdcMoneyType LongOffsetAmount; + ///ͷ۵ܽ + TThostFtdcMoneyType ShortOffsetAmount; + ///۵ܽ + TThostFtdcMoneyType ExchOffsetAmount; + ///ͷ۵ܽ + TThostFtdcMoneyType LongExchOffsetAmount; + ///ͷ۵ܽ + TThostFtdcMoneyType ShortExchOffsetAmount; + ///Ͷױ־ + TThostFtdcHedgeFlagType HedgeFlag; +}; + +///ѯû +struct CThostFtdcQueryCFMMCTradingAccountTokenField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///Ͷߴ + TThostFtdcInvestorIDType InvestorID; +}; + +///û +struct CThostFtdcCFMMCTradingAccountTokenField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///͹˾ͳһ + TThostFtdcParticipantIDType ParticipantID; + ///Ͷʺ + TThostFtdcAccountIDType AccountID; + ///Կ + TThostFtdcSequenceNoType KeyID; + ///̬ + TThostFtdcCFMMCTokenType Token; +}; + +///ѯƷ +struct CThostFtdcQryProductGroupField { + ///Ʒ + TThostFtdcInstrumentIDType ProductID; + /// + TThostFtdcExchangeIDType ExchangeID; +}; + +///ͶƷ/Ʒֱ֤Ʒ +struct CThostFtdcProductGroupField { + ///Ʒ + TThostFtdcInstrumentIDType ProductID; + /// + TThostFtdcExchangeIDType ExchangeID; + ///Ʒ + TThostFtdcInstrumentIDType ProductGroupID; +}; + +/// +struct CThostFtdcBulletinField { + /// + TThostFtdcExchangeIDType ExchangeID; + /// + TThostFtdcDateType TradingDay; + /// + TThostFtdcBulletinIDType BulletinID; + ///к + TThostFtdcSequenceNoType SequenceNo; + /// + TThostFtdcNewsTypeType NewsType; + ///̶ + TThostFtdcNewsUrgencyType NewsUrgency; + ///ʱ + TThostFtdcTimeType SendTime; + ///ϢժҪ + TThostFtdcAbstractType Abstract; + ///ϢԴ + TThostFtdcComeFromType ComeFrom; + ///Ϣ + TThostFtdcContentType Content; + /// WEBַ + TThostFtdcURLLinkType URLLink; + ///г + TThostFtdcMarketIDType MarketID; +}; + +///ѯ +struct CThostFtdcQryBulletinField { + /// + TThostFtdcExchangeIDType ExchangeID; + /// + TThostFtdcBulletinIDType BulletinID; + ///к + TThostFtdcSequenceNoType SequenceNo; + /// + TThostFtdcNewsTypeType NewsType; + ///̶ + TThostFtdcNewsUrgencyType NewsUrgency; +}; + +///תʿ +struct CThostFtdcReqOpenAccountField { + ///ҵ + TThostFtdcTradeCodeType TradeCode; + ///д + TThostFtdcBankIDType BankID; + ///з֧ + TThostFtdcBankBrchIDType BankBranchID; + ///̴ + TThostFtdcBrokerIDType BrokerID; + ///̷֧ + TThostFtdcFutureBranchIDType BrokerBranchID; + /// + TThostFtdcTradeDateType TradeDate; + ///ʱ + TThostFtdcTradeTimeType TradeTime; + ///ˮ + TThostFtdcBankSerialType BankSerial; + ///ϵͳ + TThostFtdcTradeDateType TradingDay; + ///ƽ̨Ϣˮ + TThostFtdcSerialType PlateSerial; + ///Ƭ־ + TThostFtdcLastFragmentType LastFragment; + ///Ự + TThostFtdcSessionIDType SessionID; + ///ͻ + TThostFtdcIndividualNameType CustomerName; + ///֤ + TThostFtdcIdCardTypeType IdCardType; + ///֤ + TThostFtdcIdentifiedCardNoType IdentifiedCardNo; + ///Ա + TThostFtdcGenderType Gender; + ///Ҵ + TThostFtdcCountryCodeType CountryCode; + ///ͻ + TThostFtdcCustTypeType CustType; + ///ַ + TThostFtdcAddressType Address; + ///ʱ + TThostFtdcZipCodeType ZipCode; + ///绰 + TThostFtdcTelephoneType Telephone; + ///ֻ + TThostFtdcMobilePhoneType MobilePhone; + /// + TThostFtdcFaxType Fax; + ///ʼ + TThostFtdcEMailType EMail; + ///ʽ˻״̬ + TThostFtdcMoneyAccountStatusType MoneyAccountStatus; + ///ʺ + TThostFtdcBankAccountType BankAccount; + /// + TThostFtdcPasswordType BankPassWord; + ///Ͷʺ + TThostFtdcAccountIDType AccountID; + ///ڻ + TThostFtdcPasswordType Password; + ///װ + TThostFtdcInstallIDType InstallID; + ///֤ͻ֤־ + TThostFtdcYesNoIndicatorType VerifyCertNoFlag; + ///ִ + TThostFtdcCurrencyIDType CurrencyID; + ///㳮־ + TThostFtdcCashExchangeCodeType CashExchangeCode; + ///ժҪ + TThostFtdcDigestType Digest; + ///ʺ + TThostFtdcBankAccTypeType BankAccType; + ///־ + TThostFtdcDeviceIDType DeviceID; + ///ڻλʺ + TThostFtdcBankAccTypeType BankSecuAccType; + ///ڻ˾б + TThostFtdcBankCodingForFutureType BrokerIDByBank; + ///ڻλʺ + TThostFtdcBankAccountType BankSecuAcc; + ///־ + TThostFtdcPwdFlagType BankPwdFlag; + ///ڻʽ˶Ա־ + TThostFtdcPwdFlagType SecuPwdFlag; + ///׹Ա + TThostFtdcOperNoType OperNo; + ///ID + TThostFtdcTIDType TID; + ///ûʶ + TThostFtdcUserIDType UserID; + ///ͻ + TThostFtdcLongIndividualNameType LongCustomerName; +}; + +///ת +struct CThostFtdcReqCancelAccountField { + ///ҵ + TThostFtdcTradeCodeType TradeCode; + ///д + TThostFtdcBankIDType BankID; + ///з֧ + TThostFtdcBankBrchIDType BankBranchID; + ///̴ + TThostFtdcBrokerIDType BrokerID; + ///̷֧ + TThostFtdcFutureBranchIDType BrokerBranchID; + /// + TThostFtdcTradeDateType TradeDate; + ///ʱ + TThostFtdcTradeTimeType TradeTime; + ///ˮ + TThostFtdcBankSerialType BankSerial; + ///ϵͳ + TThostFtdcTradeDateType TradingDay; + ///ƽ̨Ϣˮ + TThostFtdcSerialType PlateSerial; + ///Ƭ־ + TThostFtdcLastFragmentType LastFragment; + ///Ự + TThostFtdcSessionIDType SessionID; + ///ͻ + TThostFtdcIndividualNameType CustomerName; + ///֤ + TThostFtdcIdCardTypeType IdCardType; + ///֤ + TThostFtdcIdentifiedCardNoType IdentifiedCardNo; + ///Ա + TThostFtdcGenderType Gender; + ///Ҵ + TThostFtdcCountryCodeType CountryCode; + ///ͻ + TThostFtdcCustTypeType CustType; + ///ַ + TThostFtdcAddressType Address; + ///ʱ + TThostFtdcZipCodeType ZipCode; + ///绰 + TThostFtdcTelephoneType Telephone; + ///ֻ + TThostFtdcMobilePhoneType MobilePhone; + /// + TThostFtdcFaxType Fax; + ///ʼ + TThostFtdcEMailType EMail; + ///ʽ˻״̬ + TThostFtdcMoneyAccountStatusType MoneyAccountStatus; + ///ʺ + TThostFtdcBankAccountType BankAccount; + /// + TThostFtdcPasswordType BankPassWord; + ///Ͷʺ + TThostFtdcAccountIDType AccountID; + ///ڻ + TThostFtdcPasswordType Password; + ///װ + TThostFtdcInstallIDType InstallID; + ///֤ͻ֤־ + TThostFtdcYesNoIndicatorType VerifyCertNoFlag; + ///ִ + TThostFtdcCurrencyIDType CurrencyID; + ///㳮־ + TThostFtdcCashExchangeCodeType CashExchangeCode; + ///ժҪ + TThostFtdcDigestType Digest; + ///ʺ + TThostFtdcBankAccTypeType BankAccType; + ///־ + TThostFtdcDeviceIDType DeviceID; + ///ڻλʺ + TThostFtdcBankAccTypeType BankSecuAccType; + ///ڻ˾б + TThostFtdcBankCodingForFutureType BrokerIDByBank; + ///ڻλʺ + TThostFtdcBankAccountType BankSecuAcc; + ///־ + TThostFtdcPwdFlagType BankPwdFlag; + ///ڻʽ˶Ա־ + TThostFtdcPwdFlagType SecuPwdFlag; + ///׹Ա + TThostFtdcOperNoType OperNo; + ///ID + TThostFtdcTIDType TID; + ///ûʶ + TThostFtdcUserIDType UserID; + ///ͻ + TThostFtdcLongIndividualNameType LongCustomerName; +}; + +///˻ +struct CThostFtdcReqChangeAccountField { + ///ҵ + TThostFtdcTradeCodeType TradeCode; + ///д + TThostFtdcBankIDType BankID; + ///з֧ + TThostFtdcBankBrchIDType BankBranchID; + ///̴ + TThostFtdcBrokerIDType BrokerID; + ///̷֧ + TThostFtdcFutureBranchIDType BrokerBranchID; + /// + TThostFtdcTradeDateType TradeDate; + ///ʱ + TThostFtdcTradeTimeType TradeTime; + ///ˮ + TThostFtdcBankSerialType BankSerial; + ///ϵͳ + TThostFtdcTradeDateType TradingDay; + ///ƽ̨Ϣˮ + TThostFtdcSerialType PlateSerial; + ///Ƭ־ + TThostFtdcLastFragmentType LastFragment; + ///Ự + TThostFtdcSessionIDType SessionID; + ///ͻ + TThostFtdcIndividualNameType CustomerName; + ///֤ + TThostFtdcIdCardTypeType IdCardType; + ///֤ + TThostFtdcIdentifiedCardNoType IdentifiedCardNo; + ///Ա + TThostFtdcGenderType Gender; + ///Ҵ + TThostFtdcCountryCodeType CountryCode; + ///ͻ + TThostFtdcCustTypeType CustType; + ///ַ + TThostFtdcAddressType Address; + ///ʱ + TThostFtdcZipCodeType ZipCode; + ///绰 + TThostFtdcTelephoneType Telephone; + ///ֻ + TThostFtdcMobilePhoneType MobilePhone; + /// + TThostFtdcFaxType Fax; + ///ʼ + TThostFtdcEMailType EMail; + ///ʽ˻״̬ + TThostFtdcMoneyAccountStatusType MoneyAccountStatus; + ///ʺ + TThostFtdcBankAccountType BankAccount; + /// + TThostFtdcPasswordType BankPassWord; + ///ʺ + TThostFtdcBankAccountType NewBankAccount; + /// + TThostFtdcPasswordType NewBankPassWord; + ///Ͷʺ + TThostFtdcAccountIDType AccountID; + ///ڻ + TThostFtdcPasswordType Password; + ///ʺ + TThostFtdcBankAccTypeType BankAccType; + ///װ + TThostFtdcInstallIDType InstallID; + ///֤ͻ֤־ + TThostFtdcYesNoIndicatorType VerifyCertNoFlag; + ///ִ + TThostFtdcCurrencyIDType CurrencyID; + ///ڻ˾б + TThostFtdcBankCodingForFutureType BrokerIDByBank; + ///־ + TThostFtdcPwdFlagType BankPwdFlag; + ///ڻʽ˶Ա־ + TThostFtdcPwdFlagType SecuPwdFlag; + ///ID + TThostFtdcTIDType TID; + ///ժҪ + TThostFtdcDigestType Digest; + ///ͻ + TThostFtdcLongIndividualNameType LongCustomerName; +}; + +///ת +struct CThostFtdcReqTransferField { + ///ҵ + TThostFtdcTradeCodeType TradeCode; + ///д + TThostFtdcBankIDType BankID; + ///з֧ + TThostFtdcBankBrchIDType BankBranchID; + ///̴ + TThostFtdcBrokerIDType BrokerID; + ///̷֧ + TThostFtdcFutureBranchIDType BrokerBranchID; + /// + TThostFtdcTradeDateType TradeDate; + ///ʱ + TThostFtdcTradeTimeType TradeTime; + ///ˮ + TThostFtdcBankSerialType BankSerial; + ///ϵͳ + TThostFtdcTradeDateType TradingDay; + ///ƽ̨Ϣˮ + TThostFtdcSerialType PlateSerial; + ///Ƭ־ + TThostFtdcLastFragmentType LastFragment; + ///Ự + TThostFtdcSessionIDType SessionID; + ///ͻ + TThostFtdcIndividualNameType CustomerName; + ///֤ + TThostFtdcIdCardTypeType IdCardType; + ///֤ + TThostFtdcIdentifiedCardNoType IdentifiedCardNo; + ///ͻ + TThostFtdcCustTypeType CustType; + ///ʺ + TThostFtdcBankAccountType BankAccount; + /// + TThostFtdcPasswordType BankPassWord; + ///Ͷʺ + TThostFtdcAccountIDType AccountID; + ///ڻ + TThostFtdcPasswordType Password; + ///װ + TThostFtdcInstallIDType InstallID; + ///ڻ˾ˮ + TThostFtdcFutureSerialType FutureSerial; + ///ûʶ + TThostFtdcUserIDType UserID; + ///֤ͻ֤־ + TThostFtdcYesNoIndicatorType VerifyCertNoFlag; + ///ִ + TThostFtdcCurrencyIDType CurrencyID; + ///תʽ + TThostFtdcTradeAmountType TradeAmount; + ///ڻȡ + TThostFtdcTradeAmountType FutureFetchAmount; + ///֧־ + TThostFtdcFeePayFlagType FeePayFlag; + ///Ӧտͻ + TThostFtdcCustFeeType CustFee; + ///Ӧڻ˾ + TThostFtdcFutureFeeType BrokerFee; + ///ͷշϢ + TThostFtdcAddInfoType Message; + ///ժҪ + TThostFtdcDigestType Digest; + ///ʺ + TThostFtdcBankAccTypeType BankAccType; + ///־ + TThostFtdcDeviceIDType DeviceID; + ///ڻλʺ + TThostFtdcBankAccTypeType BankSecuAccType; + ///ڻ˾б + TThostFtdcBankCodingForFutureType BrokerIDByBank; + ///ڻλʺ + TThostFtdcBankAccountType BankSecuAcc; + ///־ + TThostFtdcPwdFlagType BankPwdFlag; + ///ڻʽ˶Ա־ + TThostFtdcPwdFlagType SecuPwdFlag; + ///׹Ա + TThostFtdcOperNoType OperNo; + /// + TThostFtdcRequestIDType RequestID; + ///ID + TThostFtdcTIDType TID; + ///ת˽״̬ + TThostFtdcTransferStatusType TransferStatus; + ///ͻ + TThostFtdcLongIndividualNameType LongCustomerName; +}; + +///зʽתڻӦ +struct CThostFtdcRspTransferField { + ///ҵ + TThostFtdcTradeCodeType TradeCode; + ///д + TThostFtdcBankIDType BankID; + ///з֧ + TThostFtdcBankBrchIDType BankBranchID; + ///̴ + TThostFtdcBrokerIDType BrokerID; + ///̷֧ + TThostFtdcFutureBranchIDType BrokerBranchID; + /// + TThostFtdcTradeDateType TradeDate; + ///ʱ + TThostFtdcTradeTimeType TradeTime; + ///ˮ + TThostFtdcBankSerialType BankSerial; + ///ϵͳ + TThostFtdcTradeDateType TradingDay; + ///ƽ̨Ϣˮ + TThostFtdcSerialType PlateSerial; + ///Ƭ־ + TThostFtdcLastFragmentType LastFragment; + ///Ự + TThostFtdcSessionIDType SessionID; + ///ͻ + TThostFtdcIndividualNameType CustomerName; + ///֤ + TThostFtdcIdCardTypeType IdCardType; + ///֤ + TThostFtdcIdentifiedCardNoType IdentifiedCardNo; + ///ͻ + TThostFtdcCustTypeType CustType; + ///ʺ + TThostFtdcBankAccountType BankAccount; + /// + TThostFtdcPasswordType BankPassWord; + ///Ͷʺ + TThostFtdcAccountIDType AccountID; + ///ڻ + TThostFtdcPasswordType Password; + ///װ + TThostFtdcInstallIDType InstallID; + ///ڻ˾ˮ + TThostFtdcFutureSerialType FutureSerial; + ///ûʶ + TThostFtdcUserIDType UserID; + ///֤ͻ֤־ + TThostFtdcYesNoIndicatorType VerifyCertNoFlag; + ///ִ + TThostFtdcCurrencyIDType CurrencyID; + ///תʽ + TThostFtdcTradeAmountType TradeAmount; + ///ڻȡ + TThostFtdcTradeAmountType FutureFetchAmount; + ///֧־ + TThostFtdcFeePayFlagType FeePayFlag; + ///Ӧտͻ + TThostFtdcCustFeeType CustFee; + ///Ӧڻ˾ + TThostFtdcFutureFeeType BrokerFee; + ///ͷշϢ + TThostFtdcAddInfoType Message; + ///ժҪ + TThostFtdcDigestType Digest; + ///ʺ + TThostFtdcBankAccTypeType BankAccType; + ///־ + TThostFtdcDeviceIDType DeviceID; + ///ڻλʺ + TThostFtdcBankAccTypeType BankSecuAccType; + ///ڻ˾б + TThostFtdcBankCodingForFutureType BrokerIDByBank; + ///ڻλʺ + TThostFtdcBankAccountType BankSecuAcc; + ///־ + TThostFtdcPwdFlagType BankPwdFlag; + ///ڻʽ˶Ա־ + TThostFtdcPwdFlagType SecuPwdFlag; + ///׹Ա + TThostFtdcOperNoType OperNo; + /// + TThostFtdcRequestIDType RequestID; + ///ID + TThostFtdcTIDType TID; + ///ת˽״̬ + TThostFtdcTransferStatusType TransferStatus; + /// + TThostFtdcErrorIDType ErrorID; + ///Ϣ + TThostFtdcErrorMsgType ErrorMsg; + ///ͻ + TThostFtdcLongIndividualNameType LongCustomerName; +}; + +/// +struct CThostFtdcReqRepealField { + ///ʱ + TThostFtdcRepealTimeIntervalType RepealTimeInterval; + ///Ѿ + TThostFtdcRepealedTimesType RepealedTimes; + ///г־ + TThostFtdcBankRepealFlagType BankRepealFlag; + ///̳־ + TThostFtdcBrokerRepealFlagType BrokerRepealFlag; + ///ƽ̨ˮ + TThostFtdcPlateSerialType PlateRepealSerial; + ///ˮ + TThostFtdcBankSerialType BankRepealSerial; + ///ڻˮ + TThostFtdcFutureSerialType FutureRepealSerial; + ///ҵ + TThostFtdcTradeCodeType TradeCode; + ///д + TThostFtdcBankIDType BankID; + ///з֧ + TThostFtdcBankBrchIDType BankBranchID; + ///̴ + TThostFtdcBrokerIDType BrokerID; + ///̷֧ + TThostFtdcFutureBranchIDType BrokerBranchID; + /// + TThostFtdcTradeDateType TradeDate; + ///ʱ + TThostFtdcTradeTimeType TradeTime; + ///ˮ + TThostFtdcBankSerialType BankSerial; + ///ϵͳ + TThostFtdcTradeDateType TradingDay; + ///ƽ̨Ϣˮ + TThostFtdcSerialType PlateSerial; + ///Ƭ־ + TThostFtdcLastFragmentType LastFragment; + ///Ự + TThostFtdcSessionIDType SessionID; + ///ͻ + TThostFtdcIndividualNameType CustomerName; + ///֤ + TThostFtdcIdCardTypeType IdCardType; + ///֤ + TThostFtdcIdentifiedCardNoType IdentifiedCardNo; + ///ͻ + TThostFtdcCustTypeType CustType; + ///ʺ + TThostFtdcBankAccountType BankAccount; + /// + TThostFtdcPasswordType BankPassWord; + ///Ͷʺ + TThostFtdcAccountIDType AccountID; + ///ڻ + TThostFtdcPasswordType Password; + ///װ + TThostFtdcInstallIDType InstallID; + ///ڻ˾ˮ + TThostFtdcFutureSerialType FutureSerial; + ///ûʶ + TThostFtdcUserIDType UserID; + ///֤ͻ֤־ + TThostFtdcYesNoIndicatorType VerifyCertNoFlag; + ///ִ + TThostFtdcCurrencyIDType CurrencyID; + ///תʽ + TThostFtdcTradeAmountType TradeAmount; + ///ڻȡ + TThostFtdcTradeAmountType FutureFetchAmount; + ///֧־ + TThostFtdcFeePayFlagType FeePayFlag; + ///Ӧտͻ + TThostFtdcCustFeeType CustFee; + ///Ӧڻ˾ + TThostFtdcFutureFeeType BrokerFee; + ///ͷշϢ + TThostFtdcAddInfoType Message; + ///ժҪ + TThostFtdcDigestType Digest; + ///ʺ + TThostFtdcBankAccTypeType BankAccType; + ///־ + TThostFtdcDeviceIDType DeviceID; + ///ڻλʺ + TThostFtdcBankAccTypeType BankSecuAccType; + ///ڻ˾б + TThostFtdcBankCodingForFutureType BrokerIDByBank; + ///ڻλʺ + TThostFtdcBankAccountType BankSecuAcc; + ///־ + TThostFtdcPwdFlagType BankPwdFlag; + ///ڻʽ˶Ա־ + TThostFtdcPwdFlagType SecuPwdFlag; + ///׹Ա + TThostFtdcOperNoType OperNo; + /// + TThostFtdcRequestIDType RequestID; + ///ID + TThostFtdcTIDType TID; + ///ת˽״̬ + TThostFtdcTransferStatusType TransferStatus; + ///ͻ + TThostFtdcLongIndividualNameType LongCustomerName; +}; + +///Ӧ +struct CThostFtdcRspRepealField { + ///ʱ + TThostFtdcRepealTimeIntervalType RepealTimeInterval; + ///Ѿ + TThostFtdcRepealedTimesType RepealedTimes; + ///г־ + TThostFtdcBankRepealFlagType BankRepealFlag; + ///̳־ + TThostFtdcBrokerRepealFlagType BrokerRepealFlag; + ///ƽ̨ˮ + TThostFtdcPlateSerialType PlateRepealSerial; + ///ˮ + TThostFtdcBankSerialType BankRepealSerial; + ///ڻˮ + TThostFtdcFutureSerialType FutureRepealSerial; + ///ҵ + TThostFtdcTradeCodeType TradeCode; + ///д + TThostFtdcBankIDType BankID; + ///з֧ + TThostFtdcBankBrchIDType BankBranchID; + ///̴ + TThostFtdcBrokerIDType BrokerID; + ///̷֧ + TThostFtdcFutureBranchIDType BrokerBranchID; + /// + TThostFtdcTradeDateType TradeDate; + ///ʱ + TThostFtdcTradeTimeType TradeTime; + ///ˮ + TThostFtdcBankSerialType BankSerial; + ///ϵͳ + TThostFtdcTradeDateType TradingDay; + ///ƽ̨Ϣˮ + TThostFtdcSerialType PlateSerial; + ///Ƭ־ + TThostFtdcLastFragmentType LastFragment; + ///Ự + TThostFtdcSessionIDType SessionID; + ///ͻ + TThostFtdcIndividualNameType CustomerName; + ///֤ + TThostFtdcIdCardTypeType IdCardType; + ///֤ + TThostFtdcIdentifiedCardNoType IdentifiedCardNo; + ///ͻ + TThostFtdcCustTypeType CustType; + ///ʺ + TThostFtdcBankAccountType BankAccount; + /// + TThostFtdcPasswordType BankPassWord; + ///Ͷʺ + TThostFtdcAccountIDType AccountID; + ///ڻ + TThostFtdcPasswordType Password; + ///װ + TThostFtdcInstallIDType InstallID; + ///ڻ˾ˮ + TThostFtdcFutureSerialType FutureSerial; + ///ûʶ + TThostFtdcUserIDType UserID; + ///֤ͻ֤־ + TThostFtdcYesNoIndicatorType VerifyCertNoFlag; + ///ִ + TThostFtdcCurrencyIDType CurrencyID; + ///תʽ + TThostFtdcTradeAmountType TradeAmount; + ///ڻȡ + TThostFtdcTradeAmountType FutureFetchAmount; + ///֧־ + TThostFtdcFeePayFlagType FeePayFlag; + ///Ӧտͻ + TThostFtdcCustFeeType CustFee; + ///Ӧڻ˾ + TThostFtdcFutureFeeType BrokerFee; + ///ͷշϢ + TThostFtdcAddInfoType Message; + ///ժҪ + TThostFtdcDigestType Digest; + ///ʺ + TThostFtdcBankAccTypeType BankAccType; + ///־ + TThostFtdcDeviceIDType DeviceID; + ///ڻλʺ + TThostFtdcBankAccTypeType BankSecuAccType; + ///ڻ˾б + TThostFtdcBankCodingForFutureType BrokerIDByBank; + ///ڻλʺ + TThostFtdcBankAccountType BankSecuAcc; + ///־ + TThostFtdcPwdFlagType BankPwdFlag; + ///ڻʽ˶Ա־ + TThostFtdcPwdFlagType SecuPwdFlag; + ///׹Ա + TThostFtdcOperNoType OperNo; + /// + TThostFtdcRequestIDType RequestID; + ///ID + TThostFtdcTIDType TID; + ///ת˽״̬ + TThostFtdcTransferStatusType TransferStatus; + /// + TThostFtdcErrorIDType ErrorID; + ///Ϣ + TThostFtdcErrorMsgType ErrorMsg; + ///ͻ + TThostFtdcLongIndividualNameType LongCustomerName; +}; + +///ѯ˻Ϣ +struct CThostFtdcReqQueryAccountField { + ///ҵ + TThostFtdcTradeCodeType TradeCode; + ///д + TThostFtdcBankIDType BankID; + ///з֧ + TThostFtdcBankBrchIDType BankBranchID; + ///̴ + TThostFtdcBrokerIDType BrokerID; + ///̷֧ + TThostFtdcFutureBranchIDType BrokerBranchID; + /// + TThostFtdcTradeDateType TradeDate; + ///ʱ + TThostFtdcTradeTimeType TradeTime; + ///ˮ + TThostFtdcBankSerialType BankSerial; + ///ϵͳ + TThostFtdcTradeDateType TradingDay; + ///ƽ̨Ϣˮ + TThostFtdcSerialType PlateSerial; + ///Ƭ־ + TThostFtdcLastFragmentType LastFragment; + ///Ự + TThostFtdcSessionIDType SessionID; + ///ͻ + TThostFtdcIndividualNameType CustomerName; + ///֤ + TThostFtdcIdCardTypeType IdCardType; + ///֤ + TThostFtdcIdentifiedCardNoType IdentifiedCardNo; + ///ͻ + TThostFtdcCustTypeType CustType; + ///ʺ + TThostFtdcBankAccountType BankAccount; + /// + TThostFtdcPasswordType BankPassWord; + ///Ͷʺ + TThostFtdcAccountIDType AccountID; + ///ڻ + TThostFtdcPasswordType Password; + ///ڻ˾ˮ + TThostFtdcFutureSerialType FutureSerial; + ///װ + TThostFtdcInstallIDType InstallID; + ///ûʶ + TThostFtdcUserIDType UserID; + ///֤ͻ֤־ + TThostFtdcYesNoIndicatorType VerifyCertNoFlag; + ///ִ + TThostFtdcCurrencyIDType CurrencyID; + ///ժҪ + TThostFtdcDigestType Digest; + ///ʺ + TThostFtdcBankAccTypeType BankAccType; + ///־ + TThostFtdcDeviceIDType DeviceID; + ///ڻλʺ + TThostFtdcBankAccTypeType BankSecuAccType; + ///ڻ˾б + TThostFtdcBankCodingForFutureType BrokerIDByBank; + ///ڻλʺ + TThostFtdcBankAccountType BankSecuAcc; + ///־ + TThostFtdcPwdFlagType BankPwdFlag; + ///ڻʽ˶Ա־ + TThostFtdcPwdFlagType SecuPwdFlag; + ///׹Ա + TThostFtdcOperNoType OperNo; + /// + TThostFtdcRequestIDType RequestID; + ///ID + TThostFtdcTIDType TID; + ///ͻ + TThostFtdcLongIndividualNameType LongCustomerName; +}; + +///ѯ˻ϢӦ +struct CThostFtdcRspQueryAccountField { + ///ҵ + TThostFtdcTradeCodeType TradeCode; + ///д + TThostFtdcBankIDType BankID; + ///з֧ + TThostFtdcBankBrchIDType BankBranchID; + ///̴ + TThostFtdcBrokerIDType BrokerID; + ///̷֧ + TThostFtdcFutureBranchIDType BrokerBranchID; + /// + TThostFtdcTradeDateType TradeDate; + ///ʱ + TThostFtdcTradeTimeType TradeTime; + ///ˮ + TThostFtdcBankSerialType BankSerial; + ///ϵͳ + TThostFtdcTradeDateType TradingDay; + ///ƽ̨Ϣˮ + TThostFtdcSerialType PlateSerial; + ///Ƭ־ + TThostFtdcLastFragmentType LastFragment; + ///Ự + TThostFtdcSessionIDType SessionID; + ///ͻ + TThostFtdcIndividualNameType CustomerName; + ///֤ + TThostFtdcIdCardTypeType IdCardType; + ///֤ + TThostFtdcIdentifiedCardNoType IdentifiedCardNo; + ///ͻ + TThostFtdcCustTypeType CustType; + ///ʺ + TThostFtdcBankAccountType BankAccount; + /// + TThostFtdcPasswordType BankPassWord; + ///Ͷʺ + TThostFtdcAccountIDType AccountID; + ///ڻ + TThostFtdcPasswordType Password; + ///ڻ˾ˮ + TThostFtdcFutureSerialType FutureSerial; + ///װ + TThostFtdcInstallIDType InstallID; + ///ûʶ + TThostFtdcUserIDType UserID; + ///֤ͻ֤־ + TThostFtdcYesNoIndicatorType VerifyCertNoFlag; + ///ִ + TThostFtdcCurrencyIDType CurrencyID; + ///ժҪ + TThostFtdcDigestType Digest; + ///ʺ + TThostFtdcBankAccTypeType BankAccType; + ///־ + TThostFtdcDeviceIDType DeviceID; + ///ڻλʺ + TThostFtdcBankAccTypeType BankSecuAccType; + ///ڻ˾б + TThostFtdcBankCodingForFutureType BrokerIDByBank; + ///ڻλʺ + TThostFtdcBankAccountType BankSecuAcc; + ///־ + TThostFtdcPwdFlagType BankPwdFlag; + ///ڻʽ˶Ա־ + TThostFtdcPwdFlagType SecuPwdFlag; + ///׹Ա + TThostFtdcOperNoType OperNo; + /// + TThostFtdcRequestIDType RequestID; + ///ID + TThostFtdcTIDType TID; + ///пý + TThostFtdcTradeAmountType BankUseAmount; + ///пȡ + TThostFtdcTradeAmountType BankFetchAmount; + ///ͻ + TThostFtdcLongIndividualNameType LongCustomerName; +}; + +///ǩǩ +struct CThostFtdcFutureSignIOField { + ///ҵ + TThostFtdcTradeCodeType TradeCode; + ///д + TThostFtdcBankIDType BankID; + ///з֧ + TThostFtdcBankBrchIDType BankBranchID; + ///̴ + TThostFtdcBrokerIDType BrokerID; + ///̷֧ + TThostFtdcFutureBranchIDType BrokerBranchID; + /// + TThostFtdcTradeDateType TradeDate; + ///ʱ + TThostFtdcTradeTimeType TradeTime; + ///ˮ + TThostFtdcBankSerialType BankSerial; + ///ϵͳ + TThostFtdcTradeDateType TradingDay; + ///ƽ̨Ϣˮ + TThostFtdcSerialType PlateSerial; + ///Ƭ־ + TThostFtdcLastFragmentType LastFragment; + ///Ự + TThostFtdcSessionIDType SessionID; + ///װ + TThostFtdcInstallIDType InstallID; + ///ûʶ + TThostFtdcUserIDType UserID; + ///ժҪ + TThostFtdcDigestType Digest; + ///ִ + TThostFtdcCurrencyIDType CurrencyID; + ///־ + TThostFtdcDeviceIDType DeviceID; + ///ڻ˾б + TThostFtdcBankCodingForFutureType BrokerIDByBank; + ///׹Ա + TThostFtdcOperNoType OperNo; + /// + TThostFtdcRequestIDType RequestID; + ///ID + TThostFtdcTIDType TID; +}; + +///ǩӦ +struct CThostFtdcRspFutureSignInField { + ///ҵ + TThostFtdcTradeCodeType TradeCode; + ///д + TThostFtdcBankIDType BankID; + ///з֧ + TThostFtdcBankBrchIDType BankBranchID; + ///̴ + TThostFtdcBrokerIDType BrokerID; + ///̷֧ + TThostFtdcFutureBranchIDType BrokerBranchID; + /// + TThostFtdcTradeDateType TradeDate; + ///ʱ + TThostFtdcTradeTimeType TradeTime; + ///ˮ + TThostFtdcBankSerialType BankSerial; + ///ϵͳ + TThostFtdcTradeDateType TradingDay; + ///ƽ̨Ϣˮ + TThostFtdcSerialType PlateSerial; + ///Ƭ־ + TThostFtdcLastFragmentType LastFragment; + ///Ự + TThostFtdcSessionIDType SessionID; + ///װ + TThostFtdcInstallIDType InstallID; + ///ûʶ + TThostFtdcUserIDType UserID; + ///ժҪ + TThostFtdcDigestType Digest; + ///ִ + TThostFtdcCurrencyIDType CurrencyID; + ///־ + TThostFtdcDeviceIDType DeviceID; + ///ڻ˾б + TThostFtdcBankCodingForFutureType BrokerIDByBank; + ///׹Ա + TThostFtdcOperNoType OperNo; + /// + TThostFtdcRequestIDType RequestID; + ///ID + TThostFtdcTIDType TID; + /// + TThostFtdcErrorIDType ErrorID; + ///Ϣ + TThostFtdcErrorMsgType ErrorMsg; + /// PINԿ + TThostFtdcPasswordKeyType PinKey; + /// MACԿ + TThostFtdcPasswordKeyType MacKey; +}; + +///ǩ +struct CThostFtdcReqFutureSignOutField { + ///ҵ + TThostFtdcTradeCodeType TradeCode; + ///д + TThostFtdcBankIDType BankID; + ///з֧ + TThostFtdcBankBrchIDType BankBranchID; + ///̴ + TThostFtdcBrokerIDType BrokerID; + ///̷֧ + TThostFtdcFutureBranchIDType BrokerBranchID; + /// + TThostFtdcTradeDateType TradeDate; + ///ʱ + TThostFtdcTradeTimeType TradeTime; + ///ˮ + TThostFtdcBankSerialType BankSerial; + ///ϵͳ + TThostFtdcTradeDateType TradingDay; + ///ƽ̨Ϣˮ + TThostFtdcSerialType PlateSerial; + ///Ƭ־ + TThostFtdcLastFragmentType LastFragment; + ///Ự + TThostFtdcSessionIDType SessionID; + ///װ + TThostFtdcInstallIDType InstallID; + ///ûʶ + TThostFtdcUserIDType UserID; + ///ժҪ + TThostFtdcDigestType Digest; + ///ִ + TThostFtdcCurrencyIDType CurrencyID; + ///־ + TThostFtdcDeviceIDType DeviceID; + ///ڻ˾б + TThostFtdcBankCodingForFutureType BrokerIDByBank; + ///׹Ա + TThostFtdcOperNoType OperNo; + /// + TThostFtdcRequestIDType RequestID; + ///ID + TThostFtdcTIDType TID; +}; + +///ǩӦ +struct CThostFtdcRspFutureSignOutField { + ///ҵ + TThostFtdcTradeCodeType TradeCode; + ///д + TThostFtdcBankIDType BankID; + ///з֧ + TThostFtdcBankBrchIDType BankBranchID; + ///̴ + TThostFtdcBrokerIDType BrokerID; + ///̷֧ + TThostFtdcFutureBranchIDType BrokerBranchID; + /// + TThostFtdcTradeDateType TradeDate; + ///ʱ + TThostFtdcTradeTimeType TradeTime; + ///ˮ + TThostFtdcBankSerialType BankSerial; + ///ϵͳ + TThostFtdcTradeDateType TradingDay; + ///ƽ̨Ϣˮ + TThostFtdcSerialType PlateSerial; + ///Ƭ־ + TThostFtdcLastFragmentType LastFragment; + ///Ự + TThostFtdcSessionIDType SessionID; + ///װ + TThostFtdcInstallIDType InstallID; + ///ûʶ + TThostFtdcUserIDType UserID; + ///ժҪ + TThostFtdcDigestType Digest; + ///ִ + TThostFtdcCurrencyIDType CurrencyID; + ///־ + TThostFtdcDeviceIDType DeviceID; + ///ڻ˾б + TThostFtdcBankCodingForFutureType BrokerIDByBank; + ///׹Ա + TThostFtdcOperNoType OperNo; + /// + TThostFtdcRequestIDType RequestID; + ///ID + TThostFtdcTIDType TID; + /// + TThostFtdcErrorIDType ErrorID; + ///Ϣ + TThostFtdcErrorMsgType ErrorMsg; +}; + +///ѯָˮŵĽ׽ +struct CThostFtdcReqQueryTradeResultBySerialField { + ///ҵ + TThostFtdcTradeCodeType TradeCode; + ///д + TThostFtdcBankIDType BankID; + ///з֧ + TThostFtdcBankBrchIDType BankBranchID; + ///̴ + TThostFtdcBrokerIDType BrokerID; + ///̷֧ + TThostFtdcFutureBranchIDType BrokerBranchID; + /// + TThostFtdcTradeDateType TradeDate; + ///ʱ + TThostFtdcTradeTimeType TradeTime; + ///ˮ + TThostFtdcBankSerialType BankSerial; + ///ϵͳ + TThostFtdcTradeDateType TradingDay; + ///ƽ̨Ϣˮ + TThostFtdcSerialType PlateSerial; + ///Ƭ־ + TThostFtdcLastFragmentType LastFragment; + ///Ự + TThostFtdcSessionIDType SessionID; + ///ˮ + TThostFtdcSerialType Reference; + ///ˮŷߵĻ + TThostFtdcInstitutionTypeType RefrenceIssureType; + ///ˮŷ߻ + TThostFtdcOrganCodeType RefrenceIssure; + ///ͻ + TThostFtdcIndividualNameType CustomerName; + ///֤ + TThostFtdcIdCardTypeType IdCardType; + ///֤ + TThostFtdcIdentifiedCardNoType IdentifiedCardNo; + ///ͻ + TThostFtdcCustTypeType CustType; + ///ʺ + TThostFtdcBankAccountType BankAccount; + /// + TThostFtdcPasswordType BankPassWord; + ///Ͷʺ + TThostFtdcAccountIDType AccountID; + ///ڻ + TThostFtdcPasswordType Password; + ///ִ + TThostFtdcCurrencyIDType CurrencyID; + ///תʽ + TThostFtdcTradeAmountType TradeAmount; + ///ժҪ + TThostFtdcDigestType Digest; + ///ͻ + TThostFtdcLongIndividualNameType LongCustomerName; +}; + +///ѯָˮŵĽ׽Ӧ +struct CThostFtdcRspQueryTradeResultBySerialField { + ///ҵ + TThostFtdcTradeCodeType TradeCode; + ///д + TThostFtdcBankIDType BankID; + ///з֧ + TThostFtdcBankBrchIDType BankBranchID; + ///̴ + TThostFtdcBrokerIDType BrokerID; + ///̷֧ + TThostFtdcFutureBranchIDType BrokerBranchID; + /// + TThostFtdcTradeDateType TradeDate; + ///ʱ + TThostFtdcTradeTimeType TradeTime; + ///ˮ + TThostFtdcBankSerialType BankSerial; + ///ϵͳ + TThostFtdcTradeDateType TradingDay; + ///ƽ̨Ϣˮ + TThostFtdcSerialType PlateSerial; + ///Ƭ־ + TThostFtdcLastFragmentType LastFragment; + ///Ự + TThostFtdcSessionIDType SessionID; + /// + TThostFtdcErrorIDType ErrorID; + ///Ϣ + TThostFtdcErrorMsgType ErrorMsg; + ///ˮ + TThostFtdcSerialType Reference; + ///ˮŷߵĻ + TThostFtdcInstitutionTypeType RefrenceIssureType; + ///ˮŷ߻ + TThostFtdcOrganCodeType RefrenceIssure; + ///ԭʼش + TThostFtdcReturnCodeType OriginReturnCode; + ///ԭʼ + TThostFtdcDescrInfoForReturnCodeType OriginDescrInfoForReturnCode; + ///ʺ + TThostFtdcBankAccountType BankAccount; + /// + TThostFtdcPasswordType BankPassWord; + ///Ͷʺ + TThostFtdcAccountIDType AccountID; + ///ڻ + TThostFtdcPasswordType Password; + ///ִ + TThostFtdcCurrencyIDType CurrencyID; + ///תʽ + TThostFtdcTradeAmountType TradeAmount; + ///ժҪ + TThostFtdcDigestType Digest; +}; + +///ļ +struct CThostFtdcReqDayEndFileReadyField { + ///ҵ + TThostFtdcTradeCodeType TradeCode; + ///д + TThostFtdcBankIDType BankID; + ///з֧ + TThostFtdcBankBrchIDType BankBranchID; + ///̴ + TThostFtdcBrokerIDType BrokerID; + ///̷֧ + TThostFtdcFutureBranchIDType BrokerBranchID; + /// + TThostFtdcTradeDateType TradeDate; + ///ʱ + TThostFtdcTradeTimeType TradeTime; + ///ˮ + TThostFtdcBankSerialType BankSerial; + ///ϵͳ + TThostFtdcTradeDateType TradingDay; + ///ƽ̨Ϣˮ + TThostFtdcSerialType PlateSerial; + ///Ƭ־ + TThostFtdcLastFragmentType LastFragment; + ///Ự + TThostFtdcSessionIDType SessionID; + ///ļҵ + TThostFtdcFileBusinessCodeType FileBusinessCode; + ///ժҪ + TThostFtdcDigestType Digest; +}; + +///ؽ +struct CThostFtdcReturnResultField { + ///ش + TThostFtdcReturnCodeType ReturnCode; + /// + TThostFtdcDescrInfoForReturnCodeType DescrInfoForReturnCode; +}; + +///֤ڻʽ +struct CThostFtdcVerifyFuturePasswordField { + ///ҵ + TThostFtdcTradeCodeType TradeCode; + ///д + TThostFtdcBankIDType BankID; + ///з֧ + TThostFtdcBankBrchIDType BankBranchID; + ///̴ + TThostFtdcBrokerIDType BrokerID; + ///̷֧ + TThostFtdcFutureBranchIDType BrokerBranchID; + /// + TThostFtdcTradeDateType TradeDate; + ///ʱ + TThostFtdcTradeTimeType TradeTime; + ///ˮ + TThostFtdcBankSerialType BankSerial; + ///ϵͳ + TThostFtdcTradeDateType TradingDay; + ///ƽ̨Ϣˮ + TThostFtdcSerialType PlateSerial; + ///Ƭ־ + TThostFtdcLastFragmentType LastFragment; + ///Ự + TThostFtdcSessionIDType SessionID; + ///Ͷʺ + TThostFtdcAccountIDType AccountID; + ///ڻ + TThostFtdcPasswordType Password; + ///ʺ + TThostFtdcBankAccountType BankAccount; + /// + TThostFtdcPasswordType BankPassWord; + ///װ + TThostFtdcInstallIDType InstallID; + ///ID + TThostFtdcTIDType TID; + ///ִ + TThostFtdcCurrencyIDType CurrencyID; +}; + +///֤ͻϢ +struct CThostFtdcVerifyCustInfoField { + ///ͻ + TThostFtdcIndividualNameType CustomerName; + ///֤ + TThostFtdcIdCardTypeType IdCardType; + ///֤ + TThostFtdcIdentifiedCardNoType IdentifiedCardNo; + ///ͻ + TThostFtdcCustTypeType CustType; + ///ͻ + TThostFtdcLongIndividualNameType LongCustomerName; +}; + +///֤ڻʽͿͻϢ +struct CThostFtdcVerifyFuturePasswordAndCustInfoField { + ///ͻ + TThostFtdcIndividualNameType CustomerName; + ///֤ + TThostFtdcIdCardTypeType IdCardType; + ///֤ + TThostFtdcIdentifiedCardNoType IdentifiedCardNo; + ///ͻ + TThostFtdcCustTypeType CustType; + ///Ͷʺ + TThostFtdcAccountIDType AccountID; + ///ڻ + TThostFtdcPasswordType Password; + ///ִ + TThostFtdcCurrencyIDType CurrencyID; + ///ͻ + TThostFtdcLongIndividualNameType LongCustomerName; +}; + +///֤ڻʽͿͻϢ +struct CThostFtdcDepositResultInformField { + ///ˮţˮΪڱ̷صˮ + TThostFtdcDepositSeqNoType DepositSeqNo; + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///Ͷߴ + TThostFtdcInvestorIDType InvestorID; + /// + TThostFtdcMoneyType Deposit; + /// + TThostFtdcRequestIDType RequestID; + ///ش + TThostFtdcReturnCodeType ReturnCode; + /// + TThostFtdcDescrInfoForReturnCodeType DescrInfoForReturnCode; +}; + +///׺ڱ̷Կͬ +struct CThostFtdcReqSyncKeyField { + ///ҵ + TThostFtdcTradeCodeType TradeCode; + ///д + TThostFtdcBankIDType BankID; + ///з֧ + TThostFtdcBankBrchIDType BankBranchID; + ///̴ + TThostFtdcBrokerIDType BrokerID; + ///̷֧ + TThostFtdcFutureBranchIDType BrokerBranchID; + /// + TThostFtdcTradeDateType TradeDate; + ///ʱ + TThostFtdcTradeTimeType TradeTime; + ///ˮ + TThostFtdcBankSerialType BankSerial; + ///ϵͳ + TThostFtdcTradeDateType TradingDay; + ///ƽ̨Ϣˮ + TThostFtdcSerialType PlateSerial; + ///Ƭ־ + TThostFtdcLastFragmentType LastFragment; + ///Ự + TThostFtdcSessionIDType SessionID; + ///װ + TThostFtdcInstallIDType InstallID; + ///ûʶ + TThostFtdcUserIDType UserID; + ///׺ĸڱ̵Ϣ + TThostFtdcAddInfoType Message; + ///־ + TThostFtdcDeviceIDType DeviceID; + ///ڻ˾б + TThostFtdcBankCodingForFutureType BrokerIDByBank; + ///׹Ա + TThostFtdcOperNoType OperNo; + /// + TThostFtdcRequestIDType RequestID; + ///ID + TThostFtdcTIDType TID; +}; + +///׺ڱ̷ԿͬӦ +struct CThostFtdcRspSyncKeyField { + ///ҵ + TThostFtdcTradeCodeType TradeCode; + ///д + TThostFtdcBankIDType BankID; + ///з֧ + TThostFtdcBankBrchIDType BankBranchID; + ///̴ + TThostFtdcBrokerIDType BrokerID; + ///̷֧ + TThostFtdcFutureBranchIDType BrokerBranchID; + /// + TThostFtdcTradeDateType TradeDate; + ///ʱ + TThostFtdcTradeTimeType TradeTime; + ///ˮ + TThostFtdcBankSerialType BankSerial; + ///ϵͳ + TThostFtdcTradeDateType TradingDay; + ///ƽ̨Ϣˮ + TThostFtdcSerialType PlateSerial; + ///Ƭ־ + TThostFtdcLastFragmentType LastFragment; + ///Ự + TThostFtdcSessionIDType SessionID; + ///װ + TThostFtdcInstallIDType InstallID; + ///ûʶ + TThostFtdcUserIDType UserID; + ///׺ĸڱ̵Ϣ + TThostFtdcAddInfoType Message; + ///־ + TThostFtdcDeviceIDType DeviceID; + ///ڻ˾б + TThostFtdcBankCodingForFutureType BrokerIDByBank; + ///׹Ա + TThostFtdcOperNoType OperNo; + /// + TThostFtdcRequestIDType RequestID; + ///ID + TThostFtdcTIDType TID; + /// + TThostFtdcErrorIDType ErrorID; + ///Ϣ + TThostFtdcErrorMsgType ErrorMsg; +}; + +///ѯ˻Ϣ֪ͨ +struct CThostFtdcNotifyQueryAccountField { + ///ҵ + TThostFtdcTradeCodeType TradeCode; + ///д + TThostFtdcBankIDType BankID; + ///з֧ + TThostFtdcBankBrchIDType BankBranchID; + ///̴ + TThostFtdcBrokerIDType BrokerID; + ///̷֧ + TThostFtdcFutureBranchIDType BrokerBranchID; + /// + TThostFtdcTradeDateType TradeDate; + ///ʱ + TThostFtdcTradeTimeType TradeTime; + ///ˮ + TThostFtdcBankSerialType BankSerial; + ///ϵͳ + TThostFtdcTradeDateType TradingDay; + ///ƽ̨Ϣˮ + TThostFtdcSerialType PlateSerial; + ///Ƭ־ + TThostFtdcLastFragmentType LastFragment; + ///Ự + TThostFtdcSessionIDType SessionID; + ///ͻ + TThostFtdcIndividualNameType CustomerName; + ///֤ + TThostFtdcIdCardTypeType IdCardType; + ///֤ + TThostFtdcIdentifiedCardNoType IdentifiedCardNo; + ///ͻ + TThostFtdcCustTypeType CustType; + ///ʺ + TThostFtdcBankAccountType BankAccount; + /// + TThostFtdcPasswordType BankPassWord; + ///Ͷʺ + TThostFtdcAccountIDType AccountID; + ///ڻ + TThostFtdcPasswordType Password; + ///ڻ˾ˮ + TThostFtdcFutureSerialType FutureSerial; + ///װ + TThostFtdcInstallIDType InstallID; + ///ûʶ + TThostFtdcUserIDType UserID; + ///֤ͻ֤־ + TThostFtdcYesNoIndicatorType VerifyCertNoFlag; + ///ִ + TThostFtdcCurrencyIDType CurrencyID; + ///ժҪ + TThostFtdcDigestType Digest; + ///ʺ + TThostFtdcBankAccTypeType BankAccType; + ///־ + TThostFtdcDeviceIDType DeviceID; + ///ڻλʺ + TThostFtdcBankAccTypeType BankSecuAccType; + ///ڻ˾б + TThostFtdcBankCodingForFutureType BrokerIDByBank; + ///ڻλʺ + TThostFtdcBankAccountType BankSecuAcc; + ///־ + TThostFtdcPwdFlagType BankPwdFlag; + ///ڻʽ˶Ա־ + TThostFtdcPwdFlagType SecuPwdFlag; + ///׹Ա + TThostFtdcOperNoType OperNo; + /// + TThostFtdcRequestIDType RequestID; + ///ID + TThostFtdcTIDType TID; + ///пý + TThostFtdcTradeAmountType BankUseAmount; + ///пȡ + TThostFtdcTradeAmountType BankFetchAmount; + /// + TThostFtdcErrorIDType ErrorID; + ///Ϣ + TThostFtdcErrorMsgType ErrorMsg; + ///ͻ + TThostFtdcLongIndividualNameType LongCustomerName; +}; + +///ת˽ˮ +struct CThostFtdcTransferSerialField { + ///ƽ̨ˮ + TThostFtdcPlateSerialType PlateSerial; + ///׷ + TThostFtdcTradeDateType TradeDate; + /// + TThostFtdcDateType TradingDay; + ///ʱ + TThostFtdcTradeTimeType TradeTime; + ///״ + TThostFtdcTradeCodeType TradeCode; + ///Ự + TThostFtdcSessionIDType SessionID; + ///б + TThostFtdcBankIDType BankID; + ///з֧ + TThostFtdcBankBrchIDType BankBranchID; + ///ʺ + TThostFtdcBankAccTypeType BankAccType; + ///ʺ + TThostFtdcBankAccountType BankAccount; + ///ˮ + TThostFtdcBankSerialType BankSerial; + ///ڻ˾ + TThostFtdcBrokerIDType BrokerID; + ///̷֧ + TThostFtdcFutureBranchIDType BrokerBranchID; + ///ڻ˾ʺ + TThostFtdcFutureAccTypeType FutureAccType; + ///Ͷʺ + TThostFtdcAccountIDType AccountID; + ///Ͷߴ + TThostFtdcInvestorIDType InvestorID; + ///ڻ˾ˮ + TThostFtdcFutureSerialType FutureSerial; + ///֤ + TThostFtdcIdCardTypeType IdCardType; + ///֤ + TThostFtdcIdentifiedCardNoType IdentifiedCardNo; + ///ִ + TThostFtdcCurrencyIDType CurrencyID; + ///׽ + TThostFtdcTradeAmountType TradeAmount; + ///Ӧտͻ + TThostFtdcCustFeeType CustFee; + ///Ӧڻ˾ + TThostFtdcFutureFeeType BrokerFee; + ///Ч־ + TThostFtdcAvailabilityFlagType AvailabilityFlag; + ///Ա + TThostFtdcOperatorCodeType OperatorCode; + ///ʺ + TThostFtdcBankAccountType BankNewAccount; + /// + TThostFtdcErrorIDType ErrorID; + ///Ϣ + TThostFtdcErrorMsgType ErrorMsg; +}; + +///ѯתˮ +struct CThostFtdcQryTransferSerialField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///Ͷʺ + TThostFtdcAccountIDType AccountID; + ///б + TThostFtdcBankIDType BankID; + ///ִ + TThostFtdcCurrencyIDType CurrencyID; +}; + +///ǩ֪ͨ +struct CThostFtdcNotifyFutureSignInField { + ///ҵ + TThostFtdcTradeCodeType TradeCode; + ///д + TThostFtdcBankIDType BankID; + ///з֧ + TThostFtdcBankBrchIDType BankBranchID; + ///̴ + TThostFtdcBrokerIDType BrokerID; + ///̷֧ + TThostFtdcFutureBranchIDType BrokerBranchID; + /// + TThostFtdcTradeDateType TradeDate; + ///ʱ + TThostFtdcTradeTimeType TradeTime; + ///ˮ + TThostFtdcBankSerialType BankSerial; + ///ϵͳ + TThostFtdcTradeDateType TradingDay; + ///ƽ̨Ϣˮ + TThostFtdcSerialType PlateSerial; + ///Ƭ־ + TThostFtdcLastFragmentType LastFragment; + ///Ự + TThostFtdcSessionIDType SessionID; + ///װ + TThostFtdcInstallIDType InstallID; + ///ûʶ + TThostFtdcUserIDType UserID; + ///ժҪ + TThostFtdcDigestType Digest; + ///ִ + TThostFtdcCurrencyIDType CurrencyID; + ///־ + TThostFtdcDeviceIDType DeviceID; + ///ڻ˾б + TThostFtdcBankCodingForFutureType BrokerIDByBank; + ///׹Ա + TThostFtdcOperNoType OperNo; + /// + TThostFtdcRequestIDType RequestID; + ///ID + TThostFtdcTIDType TID; + /// + TThostFtdcErrorIDType ErrorID; + ///Ϣ + TThostFtdcErrorMsgType ErrorMsg; + /// PINԿ + TThostFtdcPasswordKeyType PinKey; + /// MACԿ + TThostFtdcPasswordKeyType MacKey; +}; + +///ǩ֪ͨ +struct CThostFtdcNotifyFutureSignOutField { + ///ҵ + TThostFtdcTradeCodeType TradeCode; + ///д + TThostFtdcBankIDType BankID; + ///з֧ + TThostFtdcBankBrchIDType BankBranchID; + ///̴ + TThostFtdcBrokerIDType BrokerID; + ///̷֧ + TThostFtdcFutureBranchIDType BrokerBranchID; + /// + TThostFtdcTradeDateType TradeDate; + ///ʱ + TThostFtdcTradeTimeType TradeTime; + ///ˮ + TThostFtdcBankSerialType BankSerial; + ///ϵͳ + TThostFtdcTradeDateType TradingDay; + ///ƽ̨Ϣˮ + TThostFtdcSerialType PlateSerial; + ///Ƭ־ + TThostFtdcLastFragmentType LastFragment; + ///Ự + TThostFtdcSessionIDType SessionID; + ///װ + TThostFtdcInstallIDType InstallID; + ///ûʶ + TThostFtdcUserIDType UserID; + ///ժҪ + TThostFtdcDigestType Digest; + ///ִ + TThostFtdcCurrencyIDType CurrencyID; + ///־ + TThostFtdcDeviceIDType DeviceID; + ///ڻ˾б + TThostFtdcBankCodingForFutureType BrokerIDByBank; + ///׹Ա + TThostFtdcOperNoType OperNo; + /// + TThostFtdcRequestIDType RequestID; + ///ID + TThostFtdcTIDType TID; + /// + TThostFtdcErrorIDType ErrorID; + ///Ϣ + TThostFtdcErrorMsgType ErrorMsg; +}; + +///׺ڱ̷Կ֪ͬͨ +struct CThostFtdcNotifySyncKeyField { + ///ҵ + TThostFtdcTradeCodeType TradeCode; + ///д + TThostFtdcBankIDType BankID; + ///з֧ + TThostFtdcBankBrchIDType BankBranchID; + ///̴ + TThostFtdcBrokerIDType BrokerID; + ///̷֧ + TThostFtdcFutureBranchIDType BrokerBranchID; + /// + TThostFtdcTradeDateType TradeDate; + ///ʱ + TThostFtdcTradeTimeType TradeTime; + ///ˮ + TThostFtdcBankSerialType BankSerial; + ///ϵͳ + TThostFtdcTradeDateType TradingDay; + ///ƽ̨Ϣˮ + TThostFtdcSerialType PlateSerial; + ///Ƭ־ + TThostFtdcLastFragmentType LastFragment; + ///Ự + TThostFtdcSessionIDType SessionID; + ///װ + TThostFtdcInstallIDType InstallID; + ///ûʶ + TThostFtdcUserIDType UserID; + ///׺ĸڱ̵Ϣ + TThostFtdcAddInfoType Message; + ///־ + TThostFtdcDeviceIDType DeviceID; + ///ڻ˾б + TThostFtdcBankCodingForFutureType BrokerIDByBank; + ///׹Ա + TThostFtdcOperNoType OperNo; + /// + TThostFtdcRequestIDType RequestID; + ///ID + TThostFtdcTIDType TID; + /// + TThostFtdcErrorIDType ErrorID; + ///Ϣ + TThostFtdcErrorMsgType ErrorMsg; +}; + +///ѯǩԼϵ +struct CThostFtdcQryAccountregisterField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///Ͷʺ + TThostFtdcAccountIDType AccountID; + ///б + TThostFtdcBankIDType BankID; + ///з֧ + TThostFtdcBankBrchIDType BankBranchID; + ///ִ + TThostFtdcCurrencyIDType CurrencyID; +}; + +///ͻϢ +struct CThostFtdcAccountregisterField { + /// + TThostFtdcTradeDateType TradeDay; + ///б + TThostFtdcBankIDType BankID; + ///з֧ + TThostFtdcBankBrchIDType BankBranchID; + ///ʺ + TThostFtdcBankAccountType BankAccount; + ///ڻ˾ + TThostFtdcBrokerIDType BrokerID; + ///ڻ˾֧ + TThostFtdcFutureBranchIDType BrokerBranchID; + ///Ͷʺ + TThostFtdcAccountIDType AccountID; + ///֤ + TThostFtdcIdCardTypeType IdCardType; + ///֤ + TThostFtdcIdentifiedCardNoType IdentifiedCardNo; + ///ͻ + TThostFtdcIndividualNameType CustomerName; + ///ִ + TThostFtdcCurrencyIDType CurrencyID; + /// + TThostFtdcOpenOrDestroyType OpenOrDestroy; + ///ǩԼ + TThostFtdcTradeDateType RegDate; + ///Լ + TThostFtdcTradeDateType OutDate; + ///ID + TThostFtdcTIDType TID; + ///ͻ + TThostFtdcCustTypeType CustType; + ///ʺ + TThostFtdcBankAccTypeType BankAccType; + ///ͻ + TThostFtdcLongIndividualNameType LongCustomerName; +}; + +///ڿϢ +struct CThostFtdcOpenAccountField { + ///ҵ + TThostFtdcTradeCodeType TradeCode; + ///д + TThostFtdcBankIDType BankID; + ///з֧ + TThostFtdcBankBrchIDType BankBranchID; + ///̴ + TThostFtdcBrokerIDType BrokerID; + ///̷֧ + TThostFtdcFutureBranchIDType BrokerBranchID; + /// + TThostFtdcTradeDateType TradeDate; + ///ʱ + TThostFtdcTradeTimeType TradeTime; + ///ˮ + TThostFtdcBankSerialType BankSerial; + ///ϵͳ + TThostFtdcTradeDateType TradingDay; + ///ƽ̨Ϣˮ + TThostFtdcSerialType PlateSerial; + ///Ƭ־ + TThostFtdcLastFragmentType LastFragment; + ///Ự + TThostFtdcSessionIDType SessionID; + ///ͻ + TThostFtdcIndividualNameType CustomerName; + ///֤ + TThostFtdcIdCardTypeType IdCardType; + ///֤ + TThostFtdcIdentifiedCardNoType IdentifiedCardNo; + ///Ա + TThostFtdcGenderType Gender; + ///Ҵ + TThostFtdcCountryCodeType CountryCode; + ///ͻ + TThostFtdcCustTypeType CustType; + ///ַ + TThostFtdcAddressType Address; + ///ʱ + TThostFtdcZipCodeType ZipCode; + ///绰 + TThostFtdcTelephoneType Telephone; + ///ֻ + TThostFtdcMobilePhoneType MobilePhone; + /// + TThostFtdcFaxType Fax; + ///ʼ + TThostFtdcEMailType EMail; + ///ʽ˻״̬ + TThostFtdcMoneyAccountStatusType MoneyAccountStatus; + ///ʺ + TThostFtdcBankAccountType BankAccount; + /// + TThostFtdcPasswordType BankPassWord; + ///Ͷʺ + TThostFtdcAccountIDType AccountID; + ///ڻ + TThostFtdcPasswordType Password; + ///װ + TThostFtdcInstallIDType InstallID; + ///֤ͻ֤־ + TThostFtdcYesNoIndicatorType VerifyCertNoFlag; + ///ִ + TThostFtdcCurrencyIDType CurrencyID; + ///㳮־ + TThostFtdcCashExchangeCodeType CashExchangeCode; + ///ժҪ + TThostFtdcDigestType Digest; + ///ʺ + TThostFtdcBankAccTypeType BankAccType; + ///־ + TThostFtdcDeviceIDType DeviceID; + ///ڻλʺ + TThostFtdcBankAccTypeType BankSecuAccType; + ///ڻ˾б + TThostFtdcBankCodingForFutureType BrokerIDByBank; + ///ڻλʺ + TThostFtdcBankAccountType BankSecuAcc; + ///־ + TThostFtdcPwdFlagType BankPwdFlag; + ///ڻʽ˶Ա־ + TThostFtdcPwdFlagType SecuPwdFlag; + ///׹Ա + TThostFtdcOperNoType OperNo; + ///ID + TThostFtdcTIDType TID; + ///ûʶ + TThostFtdcUserIDType UserID; + /// + TThostFtdcErrorIDType ErrorID; + ///Ϣ + TThostFtdcErrorMsgType ErrorMsg; + ///ͻ + TThostFtdcLongIndividualNameType LongCustomerName; +}; + +///Ϣ +struct CThostFtdcCancelAccountField { + ///ҵ + TThostFtdcTradeCodeType TradeCode; + ///д + TThostFtdcBankIDType BankID; + ///з֧ + TThostFtdcBankBrchIDType BankBranchID; + ///̴ + TThostFtdcBrokerIDType BrokerID; + ///̷֧ + TThostFtdcFutureBranchIDType BrokerBranchID; + /// + TThostFtdcTradeDateType TradeDate; + ///ʱ + TThostFtdcTradeTimeType TradeTime; + ///ˮ + TThostFtdcBankSerialType BankSerial; + ///ϵͳ + TThostFtdcTradeDateType TradingDay; + ///ƽ̨Ϣˮ + TThostFtdcSerialType PlateSerial; + ///Ƭ־ + TThostFtdcLastFragmentType LastFragment; + ///Ự + TThostFtdcSessionIDType SessionID; + ///ͻ + TThostFtdcIndividualNameType CustomerName; + ///֤ + TThostFtdcIdCardTypeType IdCardType; + ///֤ + TThostFtdcIdentifiedCardNoType IdentifiedCardNo; + ///Ա + TThostFtdcGenderType Gender; + ///Ҵ + TThostFtdcCountryCodeType CountryCode; + ///ͻ + TThostFtdcCustTypeType CustType; + ///ַ + TThostFtdcAddressType Address; + ///ʱ + TThostFtdcZipCodeType ZipCode; + ///绰 + TThostFtdcTelephoneType Telephone; + ///ֻ + TThostFtdcMobilePhoneType MobilePhone; + /// + TThostFtdcFaxType Fax; + ///ʼ + TThostFtdcEMailType EMail; + ///ʽ˻״̬ + TThostFtdcMoneyAccountStatusType MoneyAccountStatus; + ///ʺ + TThostFtdcBankAccountType BankAccount; + /// + TThostFtdcPasswordType BankPassWord; + ///Ͷʺ + TThostFtdcAccountIDType AccountID; + ///ڻ + TThostFtdcPasswordType Password; + ///װ + TThostFtdcInstallIDType InstallID; + ///֤ͻ֤־ + TThostFtdcYesNoIndicatorType VerifyCertNoFlag; + ///ִ + TThostFtdcCurrencyIDType CurrencyID; + ///㳮־ + TThostFtdcCashExchangeCodeType CashExchangeCode; + ///ժҪ + TThostFtdcDigestType Digest; + ///ʺ + TThostFtdcBankAccTypeType BankAccType; + ///־ + TThostFtdcDeviceIDType DeviceID; + ///ڻλʺ + TThostFtdcBankAccTypeType BankSecuAccType; + ///ڻ˾б + TThostFtdcBankCodingForFutureType BrokerIDByBank; + ///ڻλʺ + TThostFtdcBankAccountType BankSecuAcc; + ///־ + TThostFtdcPwdFlagType BankPwdFlag; + ///ڻʽ˶Ա־ + TThostFtdcPwdFlagType SecuPwdFlag; + ///׹Ա + TThostFtdcOperNoType OperNo; + ///ID + TThostFtdcTIDType TID; + ///ûʶ + TThostFtdcUserIDType UserID; + /// + TThostFtdcErrorIDType ErrorID; + ///Ϣ + TThostFtdcErrorMsgType ErrorMsg; + ///ͻ + TThostFtdcLongIndividualNameType LongCustomerName; +}; + +///ڱ˺Ϣ +struct CThostFtdcChangeAccountField { + ///ҵ + TThostFtdcTradeCodeType TradeCode; + ///д + TThostFtdcBankIDType BankID; + ///з֧ + TThostFtdcBankBrchIDType BankBranchID; + ///̴ + TThostFtdcBrokerIDType BrokerID; + ///̷֧ + TThostFtdcFutureBranchIDType BrokerBranchID; + /// + TThostFtdcTradeDateType TradeDate; + ///ʱ + TThostFtdcTradeTimeType TradeTime; + ///ˮ + TThostFtdcBankSerialType BankSerial; + ///ϵͳ + TThostFtdcTradeDateType TradingDay; + ///ƽ̨Ϣˮ + TThostFtdcSerialType PlateSerial; + ///Ƭ־ + TThostFtdcLastFragmentType LastFragment; + ///Ự + TThostFtdcSessionIDType SessionID; + ///ͻ + TThostFtdcIndividualNameType CustomerName; + ///֤ + TThostFtdcIdCardTypeType IdCardType; + ///֤ + TThostFtdcIdentifiedCardNoType IdentifiedCardNo; + ///Ա + TThostFtdcGenderType Gender; + ///Ҵ + TThostFtdcCountryCodeType CountryCode; + ///ͻ + TThostFtdcCustTypeType CustType; + ///ַ + TThostFtdcAddressType Address; + ///ʱ + TThostFtdcZipCodeType ZipCode; + ///绰 + TThostFtdcTelephoneType Telephone; + ///ֻ + TThostFtdcMobilePhoneType MobilePhone; + /// + TThostFtdcFaxType Fax; + ///ʼ + TThostFtdcEMailType EMail; + ///ʽ˻״̬ + TThostFtdcMoneyAccountStatusType MoneyAccountStatus; + ///ʺ + TThostFtdcBankAccountType BankAccount; + /// + TThostFtdcPasswordType BankPassWord; + ///ʺ + TThostFtdcBankAccountType NewBankAccount; + /// + TThostFtdcPasswordType NewBankPassWord; + ///Ͷʺ + TThostFtdcAccountIDType AccountID; + ///ڻ + TThostFtdcPasswordType Password; + ///ʺ + TThostFtdcBankAccTypeType BankAccType; + ///װ + TThostFtdcInstallIDType InstallID; + ///֤ͻ֤־ + TThostFtdcYesNoIndicatorType VerifyCertNoFlag; + ///ִ + TThostFtdcCurrencyIDType CurrencyID; + ///ڻ˾б + TThostFtdcBankCodingForFutureType BrokerIDByBank; + ///־ + TThostFtdcPwdFlagType BankPwdFlag; + ///ڻʽ˶Ա־ + TThostFtdcPwdFlagType SecuPwdFlag; + ///ID + TThostFtdcTIDType TID; + ///ժҪ + TThostFtdcDigestType Digest; + /// + TThostFtdcErrorIDType ErrorID; + ///Ϣ + TThostFtdcErrorMsgType ErrorMsg; + ///ͻ + TThostFtdcLongIndividualNameType LongCustomerName; +}; + +///ԱȨ +struct CThostFtdcSecAgentACIDMapField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///û + TThostFtdcUserIDType UserID; + ///ʽ˻ + TThostFtdcAccountIDType AccountID; + /// + TThostFtdcCurrencyIDType CurrencyID; + ///нʽʺ + TThostFtdcAccountIDType BrokerSecAgentID; +}; + +///ԱȨ޲ѯ +struct CThostFtdcQrySecAgentACIDMapField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///û + TThostFtdcUserIDType UserID; + ///ʽ˻ + TThostFtdcAccountIDType AccountID; + /// + TThostFtdcCurrencyIDType CurrencyID; +}; + +///ֱĽȨ +struct CThostFtdcUserRightsAssignField { + ///ӦõԪ + TThostFtdcBrokerIDType BrokerID; + ///û + TThostFtdcUserIDType UserID; + ///Ĵ + TThostFtdcDRIdentityIDType DRIdentityID; +}; + +///ù˾ǷڱʾĽȨ +struct CThostFtdcBrokerUserRightAssignField { + ///ӦõԪ + TThostFtdcBrokerIDType BrokerID; + ///Ĵ + TThostFtdcDRIdentityIDType DRIdentityID; + ///ܷ + TThostFtdcBoolType Tradeable; +}; + +///ֱת +struct CThostFtdcDRTransferField { + ///ԭĴ + TThostFtdcDRIdentityIDType OrigDRIdentityID; + ///Ŀ꽻Ĵ + TThostFtdcDRIdentityIDType DestDRIdentityID; + ///ԭӦõԪ + TThostFtdcBrokerIDType OrigBrokerID; + ///ĿõԪ + TThostFtdcBrokerIDType DestBrokerID; +}; + +/// FensûϢ +struct CThostFtdcFensUserInfoField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///û + TThostFtdcUserIDType UserID; + ///¼ģʽ + TThostFtdcLoginModeType LoginMode; +}; + +///ǰ +struct CThostFtdcCurrTransferIdentityField { + ///Ĵ + TThostFtdcDRIdentityIDType IdentityID; +}; + +///ֹ¼û +struct CThostFtdcLoginForbiddenUserField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///û + TThostFtdcUserIDType UserID; + /// IPַ + TThostFtdcIPAddressType IPAddress; +}; + +///ѯֹ¼û +struct CThostFtdcQryLoginForbiddenUserField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///û + TThostFtdcUserIDType UserID; +}; + +/// UDP鲥Ϣ +struct CThostFtdcMulticastGroupInfoField { + ///鲥IPַ + TThostFtdcIPAddressType GroupIP; + ///鲥IP˿ + TThostFtdcIPPortType GroupPort; + ///Դַ + TThostFtdcIPAddressType SourceIP; +}; + +///ʽ˻׼ +struct CThostFtdcTradingAccountReserveField { + ///͹˾ + TThostFtdcBrokerIDType BrokerID; + ///Ͷʺ + TThostFtdcAccountIDType AccountID; + ///׼ + TThostFtdcMoneyType Reserve; + ///ִ + TThostFtdcCurrencyIDType CurrencyID; +}; + +///ԤԼȷ +struct CThostFtdcReserveOpenAccountConfirmField { + ///ҵ + TThostFtdcTradeCodeType TradeCode; + ///д + TThostFtdcBankIDType BankID; + ///з֧ + TThostFtdcBankBrchIDType BankBranchID; + ///̴ + TThostFtdcBrokerIDType BrokerID; + ///̷֧ + TThostFtdcFutureBranchIDType BrokerBranchID; + /// + TThostFtdcTradeDateType TradeDate; + ///ʱ + TThostFtdcTradeTimeType TradeTime; + ///ˮ + TThostFtdcBankSerialType BankSerial; + ///ϵͳ + TThostFtdcTradeDateType TradingDay; + ///ƽ̨Ϣˮ + TThostFtdcSerialType PlateSerial; + ///Ƭ־ + TThostFtdcLastFragmentType LastFragment; + ///Ự + TThostFtdcSessionIDType SessionID; + ///ͻ + TThostFtdcLongIndividualNameType CustomerName; + ///֤ + TThostFtdcIdCardTypeType IdCardType; + ///֤ + TThostFtdcIdentifiedCardNoType IdentifiedCardNo; + ///Ա + TThostFtdcGenderType Gender; + ///Ҵ + TThostFtdcCountryCodeType CountryCode; + ///ͻ + TThostFtdcCustTypeType CustType; + ///ַ + TThostFtdcAddressType Address; + ///ʱ + TThostFtdcZipCodeType ZipCode; + ///绰 + TThostFtdcTelephoneType Telephone; + ///ֻ + TThostFtdcMobilePhoneType MobilePhone; + /// + TThostFtdcFaxType Fax; + ///ʼ + TThostFtdcEMailType EMail; + ///ʽ˻״̬ + TThostFtdcMoneyAccountStatusType MoneyAccountStatus; + ///ʺ + TThostFtdcBankAccountType BankAccount; + /// + TThostFtdcPasswordType BankPassWord; + ///װ + TThostFtdcInstallIDType InstallID; + ///֤ͻ֤־ + TThostFtdcYesNoIndicatorType VerifyCertNoFlag; + ///ִ + TThostFtdcCurrencyIDType CurrencyID; + ///ժҪ + TThostFtdcDigestType Digest; + ///ʺ + TThostFtdcBankAccTypeType BankAccType; + ///ڻ˾б + TThostFtdcBankCodingForFutureType BrokerIDByBank; + ///ID + TThostFtdcTIDType TID; + ///Ͷʺ + TThostFtdcAccountIDType AccountID; + ///ڻ + TThostFtdcPasswordType Password; + ///ԤԼˮ + TThostFtdcBankSerialType BankReserveOpenSeq; + ///ԤԼ + TThostFtdcTradeDateType BookDate; + ///ԤԼ֤ + TThostFtdcPasswordType BookPsw; + /// + TThostFtdcErrorIDType ErrorID; + ///Ϣ + TThostFtdcErrorMsgType ErrorMsg; +}; + +///ԤԼ +struct CThostFtdcReserveOpenAccountField { + ///ҵ + TThostFtdcTradeCodeType TradeCode; + ///д + TThostFtdcBankIDType BankID; + ///з֧ + TThostFtdcBankBrchIDType BankBranchID; + ///̴ + TThostFtdcBrokerIDType BrokerID; + ///̷֧ + TThostFtdcFutureBranchIDType BrokerBranchID; + /// + TThostFtdcTradeDateType TradeDate; + ///ʱ + TThostFtdcTradeTimeType TradeTime; + ///ˮ + TThostFtdcBankSerialType BankSerial; + ///ϵͳ + TThostFtdcTradeDateType TradingDay; + ///ƽ̨Ϣˮ + TThostFtdcSerialType PlateSerial; + ///Ƭ־ + TThostFtdcLastFragmentType LastFragment; + ///Ự + TThostFtdcSessionIDType SessionID; + ///ͻ + TThostFtdcLongIndividualNameType CustomerName; + ///֤ + TThostFtdcIdCardTypeType IdCardType; + ///֤ + TThostFtdcIdentifiedCardNoType IdentifiedCardNo; + ///Ա + TThostFtdcGenderType Gender; + ///Ҵ + TThostFtdcCountryCodeType CountryCode; + ///ͻ + TThostFtdcCustTypeType CustType; + ///ַ + TThostFtdcAddressType Address; + ///ʱ + TThostFtdcZipCodeType ZipCode; + ///绰 + TThostFtdcTelephoneType Telephone; + ///ֻ + TThostFtdcMobilePhoneType MobilePhone; + /// + TThostFtdcFaxType Fax; + ///ʼ + TThostFtdcEMailType EMail; + ///ʽ˻״̬ + TThostFtdcMoneyAccountStatusType MoneyAccountStatus; + ///ʺ + TThostFtdcBankAccountType BankAccount; + /// + TThostFtdcPasswordType BankPassWord; + ///װ + TThostFtdcInstallIDType InstallID; + ///֤ͻ֤־ + TThostFtdcYesNoIndicatorType VerifyCertNoFlag; + ///ִ + TThostFtdcCurrencyIDType CurrencyID; + ///ժҪ + TThostFtdcDigestType Digest; + ///ʺ + TThostFtdcBankAccTypeType BankAccType; + ///ڻ˾б + TThostFtdcBankCodingForFutureType BrokerIDByBank; + ///ID + TThostFtdcTIDType TID; + ///ԤԼ״̬ + TThostFtdcReserveOpenAccStasType ReserveOpenAccStas; + /// + TThostFtdcErrorIDType ErrorID; + ///Ϣ + TThostFtdcErrorMsgType ErrorMsg; +}; + +#endif diff --git a/qbot/engine/trade/engine_apis/futures/CTPtest/src/CTP_API/error.dtd b/qbot/engine/trade/engine_apis/futures/CTPtest/src/CTP_API/error.dtd new file mode 100644 index 00000000..15e50b73 --- /dev/null +++ b/qbot/engine/trade/engine_apis/futures/CTPtest/src/CTP_API/error.dtd @@ -0,0 +1,9 @@ + + + + + diff --git a/qbot/engine/trade/engine_apis/futures/CTPtest/src/CTP_API/error.xml b/qbot/engine/trade/engine_apis/futures/CTPtest/src/CTP_API/error.xml new file mode 100644 index 00000000..5902604c --- /dev/null +++ b/qbot/engine/trade/engine_apis/futures/CTPtest/src/CTP_API/error.xml @@ -0,0 +1,191 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/qbot/engine/trade/engine_apis/futures/CTPtest/src/CTP_API/thostmduserapi.dll b/qbot/engine/trade/engine_apis/futures/CTPtest/src/CTP_API/thostmduserapi.dll new file mode 100644 index 00000000..89b7cec4 Binary files /dev/null and b/qbot/engine/trade/engine_apis/futures/CTPtest/src/CTP_API/thostmduserapi.dll differ diff --git a/qbot/engine/trade/engine_apis/futures/CTPtest/src/CTP_API/thostmduserapi.lib b/qbot/engine/trade/engine_apis/futures/CTPtest/src/CTP_API/thostmduserapi.lib new file mode 100644 index 00000000..a5384878 Binary files /dev/null and b/qbot/engine/trade/engine_apis/futures/CTPtest/src/CTP_API/thostmduserapi.lib differ diff --git a/qbot/engine/trade/engine_apis/futures/CTPtest/src/CTP_API/thosttraderapi.dll b/qbot/engine/trade/engine_apis/futures/CTPtest/src/CTP_API/thosttraderapi.dll new file mode 100644 index 00000000..9e386185 Binary files /dev/null and b/qbot/engine/trade/engine_apis/futures/CTPtest/src/CTP_API/thosttraderapi.dll differ diff --git a/qbot/engine/trade/engine_apis/futures/CTPtest/src/CTP_API/thosttraderapi.lib b/qbot/engine/trade/engine_apis/futures/CTPtest/src/CTP_API/thosttraderapi.lib new file mode 100644 index 00000000..11137c20 Binary files /dev/null and b/qbot/engine/trade/engine_apis/futures/CTPtest/src/CTP_API/thosttraderapi.lib differ diff --git a/qbot/engine/trade/engine_apis/futures/CTPtest/src/CustomMdSpi.cpp b/qbot/engine/trade/engine_apis/futures/CTPtest/src/CustomMdSpi.cpp new file mode 100644 index 00000000..3c2ef967 --- /dev/null +++ b/qbot/engine/trade/engine_apis/futures/CTPtest/src/CustomMdSpi.cpp @@ -0,0 +1,224 @@ +#include "CustomMdSpi.h" +#include "TickToKlineHelper.h" +#include +#include +#include + +// ---- ȫֲ ---- // +extern CThostFtdcMdApi *g_pMdUserApi; // ָ +extern char gMdFrontAddr[]; // ģǰõַ +extern TThostFtdcBrokerIDType gBrokerID; // ģ⾭̴ +extern TThostFtdcInvestorIDType gInvesterID; // Ͷ˻ +extern TThostFtdcPasswordType gInvesterPassword; // Ͷ +extern char + *g_pInstrumentID[]; // ԼбСϡ֣ѡһ +extern int instrumentNum; // Լ +extern std::unordered_map + g_KlineHash; // kߴ洢 + +// ---- ctp_apiص ---- // +// ӳɹӦ +void CustomMdSpi::OnFrontConnected() { + std::cout << "=====ӳɹ=====" << std::endl; + // ʼ¼ + CThostFtdcReqUserLoginField loginReq; + memset(&loginReq, 0, sizeof(loginReq)); + strcpy(loginReq.BrokerID, gBrokerID); + strcpy(loginReq.UserID, gInvesterID); + strcpy(loginReq.Password, gInvesterPassword); + static int requestID = 0; // + int rt = g_pMdUserApi->ReqUserLogin(&loginReq, requestID); + if (!rt) + std::cout << ">>>>>>͵¼ɹ" << std::endl; + else + std::cerr << "--->>>͵¼ʧ" << std::endl; +} + +// Ͽ֪ͨ +void CustomMdSpi::OnFrontDisconnected(int nReason) { + std::cerr << "=====ӶϿ=====" << std::endl; + std::cerr << "룺 " << nReason << std::endl; +} + +// ʱ +void CustomMdSpi::OnHeartBeatWarning(int nTimeLapse) { + std::cerr << "=====ʱ=====" << std::endl; + std::cerr << "ϴʱ䣺 " << nTimeLapse << std::endl; +} + +// ¼Ӧ +void CustomMdSpi::OnRspUserLogin(CThostFtdcRspUserLoginField *pRspUserLogin, + CThostFtdcRspInfoField *pRspInfo, + int nRequestID, bool bIsLast) { + bool bResult = pRspInfo && (pRspInfo->ErrorID != 0); + if (!bResult) { + std::cout << "=====˻¼ɹ=====" << std::endl; + std::cout << "գ " << pRspUserLogin->TradingDay << std::endl; + std::cout << "¼ʱ䣺 " << pRspUserLogin->LoginTime << std::endl; + std::cout << "̣ " << pRspUserLogin->BrokerID << std::endl; + std::cout << "ʻ " << pRspUserLogin->UserID << std::endl; + // ʼ + int rt = g_pMdUserApi->SubscribeMarketData(g_pInstrumentID, instrumentNum); + if (!rt) + std::cout << ">>>>>>Ͷɹ" << std::endl; + else + std::cerr << "--->>>Ͷʧ" << std::endl; + } else + std::cerr << "ش--->>> ErrorID=" << pRspInfo->ErrorID + << ", ErrorMsg=" << pRspInfo->ErrorMsg << std::endl; +} + +// dzӦ +void CustomMdSpi::OnRspUserLogout(CThostFtdcUserLogoutField *pUserLogout, + CThostFtdcRspInfoField *pRspInfo, + int nRequestID, bool bIsLast) { + bool bResult = pRspInfo && (pRspInfo->ErrorID != 0); + if (!bResult) { + std::cout << "=====˻dzɹ=====" << std::endl; + std::cout << "̣ " << pUserLogout->BrokerID << std::endl; + std::cout << "ʻ " << pUserLogout->UserID << std::endl; + } else + std::cerr << "ش--->>> ErrorID=" << pRspInfo->ErrorID + << ", ErrorMsg=" << pRspInfo->ErrorMsg << std::endl; +} + +// ֪ͨ +void CustomMdSpi::OnRspError(CThostFtdcRspInfoField *pRspInfo, int nRequestID, + bool bIsLast) { + bool bResult = pRspInfo && (pRspInfo->ErrorID != 0); + if (bResult) + std::cerr << "ش--->>> ErrorID=" << pRspInfo->ErrorID + << ", ErrorMsg=" << pRspInfo->ErrorMsg << std::endl; +} + +// Ӧ +void CustomMdSpi::OnRspSubMarketData( + CThostFtdcSpecificInstrumentField *pSpecificInstrument, + CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) { + bool bResult = pRspInfo && (pRspInfo->ErrorID != 0); + if (!bResult) { + std::cout << "=====ɹ=====" << std::endl; + std::cout << "Լ룺 " << pSpecificInstrument->InstrumentID + << std::endl; + // Ҫļݿ⣬ﴴͷ,ͬĺԼ洢 + char filePath[100] = {'\0'}; + sprintf(filePath, "%s_market_data.csv", pSpecificInstrument->InstrumentID); + std::ofstream outFile; + outFile.open(filePath, std::ios::out); // ¿ļ + outFile << "Լ" + << "," + << "ʱ" + << "," + << "¼" + << "," + << "ɽ" + << "," + << "һ" + << "," + << "һ" + << "," + << "һ" + << "," + << "һ" + << "," + << "ֲ" + << "," + << "" << std::endl; + outFile.close(); + } else + std::cerr << "ش--->>> ErrorID=" << pRspInfo->ErrorID + << ", ErrorMsg=" << pRspInfo->ErrorMsg << std::endl; +} + +// ȡӦ +void CustomMdSpi::OnRspUnSubMarketData( + CThostFtdcSpecificInstrumentField *pSpecificInstrument, + CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) { + bool bResult = pRspInfo && (pRspInfo->ErrorID != 0); + if (!bResult) { + std::cout << "=====ȡɹ=====" << std::endl; + std::cout << "Լ룺 " << pSpecificInstrument->InstrumentID + << std::endl; + } else + std::cerr << "ش--->>> ErrorID=" << pRspInfo->ErrorID + << ", ErrorMsg=" << pRspInfo->ErrorMsg << std::endl; +} + +// ѯӦ +void CustomMdSpi::OnRspSubForQuoteRsp( + CThostFtdcSpecificInstrumentField *pSpecificInstrument, + CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) { + bool bResult = pRspInfo && (pRspInfo->ErrorID != 0); + if (!bResult) { + std::cout << "=====ѯ۳ɹ=====" << std::endl; + std::cout << "Լ룺 " << pSpecificInstrument->InstrumentID + << std::endl; + } else + std::cerr << "ش--->>> ErrorID=" << pRspInfo->ErrorID + << ", ErrorMsg=" << pRspInfo->ErrorMsg << std::endl; +} + +// ȡѯӦ +void CustomMdSpi::OnRspUnSubForQuoteRsp( + CThostFtdcSpecificInstrumentField *pSpecificInstrument, + CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) { + bool bResult = pRspInfo && (pRspInfo->ErrorID != 0); + if (!bResult) { + std::cout << "=====ȡѯ۳ɹ=====" << std::endl; + std::cout << "Լ룺 " << pSpecificInstrument->InstrumentID + << std::endl; + } else + std::cerr << "ش--->>> ErrorID=" << pRspInfo->ErrorID + << ", ErrorMsg=" << pRspInfo->ErrorMsg << std::endl; +} + +// ֪ͨ +void CustomMdSpi::OnRtnDepthMarketData( + CThostFtdcDepthMarketDataField *pDepthMarketData) { + // ӡ飬ֶν϶࣬ȡ + std::cout << "==========" << std::endl; + std::cout << "գ " << pDepthMarketData->TradingDay << std::endl; + std::cout << "룺 " << pDepthMarketData->ExchangeID << std::endl; + std::cout << "Լ룺 " << pDepthMarketData->InstrumentID << std::endl; + std::cout << "ԼڽĴ룺 " << pDepthMarketData->ExchangeInstID + << std::endl; + std::cout << "¼ۣ " << pDepthMarketData->LastPrice << std::endl; + std::cout << " " << pDepthMarketData->Volume << std::endl; + // ֻȡijһԼ飬tickشļݿ + char filePath[100] = {'\0'}; + sprintf(filePath, "%s_market_data.csv", pDepthMarketData->InstrumentID); + std::ofstream outFile; + outFile.open(filePath, std::ios::app); // ļ׷д + outFile << pDepthMarketData->InstrumentID << "," + << pDepthMarketData->UpdateTime << "." + << pDepthMarketData->UpdateMillisec << "," + << pDepthMarketData->LastPrice << "," << pDepthMarketData->Volume + << "," << pDepthMarketData->BidPrice1 << "," + << pDepthMarketData->BidVolume1 << "," << pDepthMarketData->AskPrice1 + << "," << pDepthMarketData->AskVolume1 << "," + << pDepthMarketData->OpenInterest << "," << pDepthMarketData->Turnover + << std::endl; + outFile.close(); + + // ʵʱk + std::string instrumentKey = std::string(pDepthMarketData->InstrumentID); + if (g_KlineHash.find(instrumentKey) == g_KlineHash.end()) + g_KlineHash[instrumentKey] = TickToKlineHelper(); + g_KlineHash[instrumentKey].KLineFromRealtimeData(pDepthMarketData); + + // ȡ + // int rt = g_pMdUserApi->UnSubscribeMarketData(g_pInstrumentID, + // instrumentNum); if (!rt) std::cout << ">>>>>>ȡɹ" << + // std::endl; else std::cerr << "--->>>ȡʧ" << + // std::endl; +} + +// ѯ֪ͨ +void CustomMdSpi::OnRtnForQuoteRsp(CThostFtdcForQuoteRspField *pForQuoteRsp) { + // ѯ۽ + std::cout << "=====ѯ۽=====" << std::endl; + std::cout << "գ " << pForQuoteRsp->TradingDay << std::endl; + std::cout << "룺 " << pForQuoteRsp->ExchangeID << std::endl; + std::cout << "Լ룺 " << pForQuoteRsp->InstrumentID << std::endl; + std::cout << "ѯ۱ţ " << pForQuoteRsp->ForQuoteSysID << std::endl; +} \ No newline at end of file diff --git a/qbot/engine/trade/engine_apis/futures/CTPtest/src/CustomMdSpi.h b/qbot/engine/trade/engine_apis/futures/CTPtest/src/CustomMdSpi.h new file mode 100644 index 00000000..d8cc044c --- /dev/null +++ b/qbot/engine/trade/engine_apis/futures/CTPtest/src/CustomMdSpi.h @@ -0,0 +1,68 @@ +#pragma once +// ---- ---- // +#include "CTP_API/ThostFtdcMdApi.h" +#include + +class CustomMdSpi : public CThostFtdcMdSpi { + // ---- ̳CTPĻصӿڲʵ ---- // +public: + ///ͻ뽻׺̨ͨʱδ¼ǰ÷á + void OnFrontConnected(); + + ///ͻ뽻׺̨ͨӶϿʱ÷áAPIԶӣͻ˿ɲ + ///@param nReason ԭ + /// 0x1001 ʧ + /// 0x1002 дʧ + /// 0x2001 ʱ + /// 0x2002 ʧ + /// 0x2003 յ + void OnFrontDisconnected(int nReason); + + ///ʱ档ʱδյʱ÷á + ///@param nTimeLapse ϴνձĵʱ + void OnHeartBeatWarning(int nTimeLapse); + + ///¼Ӧ + void OnRspUserLogin(CThostFtdcRspUserLoginField *pRspUserLogin, + CThostFtdcRspInfoField *pRspInfo, int nRequestID, + bool bIsLast); + + ///dzӦ + void OnRspUserLogout(CThostFtdcUserLogoutField *pUserLogout, + CThostFtdcRspInfoField *pRspInfo, int nRequestID, + bool bIsLast); + + ///Ӧ + void OnRspError(CThostFtdcRspInfoField *pRspInfo, int nRequestID, + bool bIsLast); + + ///Ӧ + void + OnRspSubMarketData(CThostFtdcSpecificInstrumentField *pSpecificInstrument, + CThostFtdcRspInfoField *pRspInfo, int nRequestID, + bool bIsLast); + + ///ȡӦ + void + OnRspUnSubMarketData(CThostFtdcSpecificInstrumentField *pSpecificInstrument, + CThostFtdcRspInfoField *pRspInfo, int nRequestID, + bool bIsLast); + + ///ѯӦ + void + OnRspSubForQuoteRsp(CThostFtdcSpecificInstrumentField *pSpecificInstrument, + CThostFtdcRspInfoField *pRspInfo, int nRequestID, + bool bIsLast); + + ///ȡѯӦ + void + OnRspUnSubForQuoteRsp(CThostFtdcSpecificInstrumentField *pSpecificInstrument, + CThostFtdcRspInfoField *pRspInfo, int nRequestID, + bool bIsLast); + + ///֪ͨ + void OnRtnDepthMarketData(CThostFtdcDepthMarketDataField *pDepthMarketData); + + ///ѯ֪ͨ + void OnRtnForQuoteRsp(CThostFtdcForQuoteRspField *pForQuoteRsp); +}; diff --git a/qbot/engine/trade/engine_apis/futures/CTPtest/src/CustomTradeSpi.cpp b/qbot/engine/trade/engine_apis/futures/CTPtest/src/CustomTradeSpi.cpp new file mode 100644 index 00000000..b3bf0ac7 --- /dev/null +++ b/qbot/engine/trade/engine_apis/futures/CTPtest/src/CustomTradeSpi.cpp @@ -0,0 +1,442 @@ +#include "CustomTradeSpi.h" +#include "StrategyTrade.h" +#include +#include +#include +#include + +// ---- ȫֲ ---- // +extern TThostFtdcBrokerIDType gBrokerID; // ģ⾭̴ +extern TThostFtdcInvestorIDType gInvesterID; // Ͷ˻ +extern TThostFtdcPasswordType gInvesterPassword; // Ͷ +extern CThostFtdcTraderApi *g_pTradeUserApi; // ָ +extern char gTradeFrontAddr[]; // ģ⽻ǰõַ +extern TThostFtdcInstrumentIDType g_pTradeInstrumentID; // ׵ĺԼ +extern TThostFtdcDirectionType gTradeDirection; // +extern TThostFtdcPriceType gLimitPrice; // ׼۸ + +// Ự +TThostFtdcFrontIDType trade_front_id; //ǰñ +TThostFtdcSessionIDType session_id; //Ự +TThostFtdcOrderRefType order_ref; // +time_t lOrderTime; +time_t lOrderOkTime; + +void CustomTradeSpi::OnFrontConnected() { + std::cout << "=====ӳɹ=====" << std::endl; + // ʼ¼ + reqUserLogin(); +} + +void CustomTradeSpi::OnRspUserLogin(CThostFtdcRspUserLoginField *pRspUserLogin, + CThostFtdcRspInfoField *pRspInfo, + int nRequestID, bool bIsLast) { + if (!isErrorRspInfo(pRspInfo)) { + std::cout << "=====˻¼ɹ=====" << std::endl; + loginFlag = true; + std::cout << "գ " << pRspUserLogin->TradingDay << std::endl; + std::cout << "¼ʱ䣺 " << pRspUserLogin->LoginTime << std::endl; + std::cout << "̣ " << pRspUserLogin->BrokerID << std::endl; + std::cout << "ʻ " << pRspUserLogin->UserID << std::endl; + // Ự + trade_front_id = pRspUserLogin->FrontID; + session_id = pRspUserLogin->SessionID; + strcpy(order_ref, pRspUserLogin->MaxOrderRef); + + // Ͷ߽ȷ + reqSettlementInfoConfirm(); + } +} + +void CustomTradeSpi::OnRspError(CThostFtdcRspInfoField *pRspInfo, + int nRequestID, bool bIsLast) { + isErrorRspInfo(pRspInfo); +} + +void CustomTradeSpi::OnFrontDisconnected(int nReason) { + std::cerr << "=====ӶϿ=====" << std::endl; + std::cerr << "룺 " << nReason << std::endl; +} + +void CustomTradeSpi::OnHeartBeatWarning(int nTimeLapse) { + std::cerr << "=====ʱ=====" << std::endl; + std::cerr << "ϴʱ䣺 " << nTimeLapse << std::endl; +} + +void CustomTradeSpi::OnRspUserLogout(CThostFtdcUserLogoutField *pUserLogout, + CThostFtdcRspInfoField *pRspInfo, + int nRequestID, bool bIsLast) { + if (!isErrorRspInfo(pRspInfo)) { + loginFlag = false; // dzͲٽ + std::cout << "=====˻dzɹ=====" << std::endl; + std::cout << "̣ " << pUserLogout->BrokerID << std::endl; + std::cout << "ʻ " << pUserLogout->UserID << std::endl; + } +} + +void CustomTradeSpi::OnRspSettlementInfoConfirm( + CThostFtdcSettlementInfoConfirmField *pSettlementInfoConfirm, + CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) { + if (!isErrorRspInfo(pRspInfo)) { + std::cout << "=====Ͷ߽ȷϳɹ=====" << std::endl; + std::cout << "ȷڣ " << pSettlementInfoConfirm->ConfirmDate + << std::endl; + std::cout << "ȷʱ䣺 " << pSettlementInfoConfirm->ConfirmTime + << std::endl; + // ѯԼ + reqQueryInstrument(); + } +} + +void CustomTradeSpi::OnRspQryInstrument(CThostFtdcInstrumentField *pInstrument, + CThostFtdcRspInfoField *pRspInfo, + int nRequestID, bool bIsLast) { + if (!isErrorRspInfo(pRspInfo)) { + std::cout << "=====ѯԼɹ=====" << std::endl; + std::cout << "룺 " << pInstrument->ExchangeID << std::endl; + std::cout << "Լ룺 " << pInstrument->InstrumentID << std::endl; + std::cout << "ԼڽĴ룺 " << pInstrument->ExchangeInstID + << std::endl; + std::cout << "ִмۣ " << pInstrument->StrikePrice << std::endl; + std::cout << "գ " << pInstrument->EndDelivDate << std::endl; + std::cout << "ǰ״̬ " << pInstrument->IsTrading << std::endl; + // ѯͶʽ˻ + reqQueryTradingAccount(); + } +} + +void CustomTradeSpi::OnRspQryTradingAccount( + CThostFtdcTradingAccountField *pTradingAccount, + CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) { + if (!isErrorRspInfo(pRspInfo)) { + std::cout << "=====ѯͶʽ˻ɹ=====" << std::endl; + std::cout << "Ͷ˺ţ " << pTradingAccount->AccountID << std::endl; + std::cout << "ʽ " << pTradingAccount->Available << std::endl; + std::cout << "ȡʽ " << pTradingAccount->WithdrawQuota << std::endl; + std::cout << "ǰ֤: " << pTradingAccount->CurrMargin << std::endl; + std::cout << "ƽӯ " << pTradingAccount->CloseProfit << std::endl; + // ѯͶֲ߳ + reqQueryInvestorPosition(); + } +} + +void CustomTradeSpi::OnRspQryInvestorPosition( + CThostFtdcInvestorPositionField *pInvestorPosition, + CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) { + if (!isErrorRspInfo(pRspInfo)) { + std::cout << "=====ѯͶֲֳ߳ɹ=====" << std::endl; + if (pInvestorPosition) { + std::cout << "Լ룺 " << pInvestorPosition->InstrumentID + << std::endl; + std::cout << "ּ۸ " << pInvestorPosition->OpenAmount << std::endl; + std::cout << " " << pInvestorPosition->OpenVolume << std::endl; + std::cout << "ַ " << pInvestorPosition->PosiDirection + << std::endl; + std::cout << "ռñ֤" << pInvestorPosition->UseMargin << std::endl; + } else + std::cout << "----->úԼδֲ" << std::endl; + + // ¼һӿڣ˴ǰ˳ִУ + /*if (loginFlag) + reqOrderInsert();*/ + // if (loginFlag) + // reqOrderInsertWithParams(g_pTradeInstrumentID, gLimitPrice, 1, + // gTradeDirection); // Զһʽ + + // Խ + std::cout << "=====ʼԽ=====" << std::endl; + while (loginFlag) + StrategyCheckAndTrade(g_pTradeInstrumentID, this); + } +} + +void CustomTradeSpi::OnRspOrderInsert(CThostFtdcInputOrderField *pInputOrder, + CThostFtdcRspInfoField *pRspInfo, + int nRequestID, bool bIsLast) { + if (!isErrorRspInfo(pRspInfo)) { + std::cout << "=====¼ɹ=====" << std::endl; + std::cout << "Լ룺 " << pInputOrder->InstrumentID << std::endl; + std::cout << "۸ " << pInputOrder->LimitPrice << std::endl; + std::cout << " " << pInputOrder->VolumeTotalOriginal << std::endl; + std::cout << "ַ " << pInputOrder->Direction << std::endl; + } +} + +void CustomTradeSpi::OnRspOrderAction( + CThostFtdcInputOrderActionField *pInputOrderAction, + CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) { + if (!isErrorRspInfo(pRspInfo)) { + std::cout << "=====ɹ=====" << std::endl; + std::cout << "Լ룺 " << pInputOrderAction->InstrumentID << std::endl; + std::cout << "־ " << pInputOrderAction->ActionFlag; + } +} + +void CustomTradeSpi::OnRtnOrder(CThostFtdcOrderField *pOrder) { + char str[10]; + sprintf(str, "%d", pOrder->OrderSubmitStatus); + int orderState = atoi(str) - 48; //״̬0=Ѿύ3=Ѿ + + std::cout << "=====յӦ=====" << std::endl; + + if (isMyOrder(pOrder)) { + if (isTradingOrder(pOrder)) { + std::cout << "--->>> ȴɽУ" << std::endl; + // reqOrderAction(pOrder); // Գ + // reqUserLogout(); // dz + } else if (pOrder->OrderStatus == THOST_FTDC_OST_Canceled) + std::cout << "--->>> ɹ" << std::endl; + } +} + +void CustomTradeSpi::OnRtnTrade(CThostFtdcTradeField *pTrade) { + std::cout << "=====ɹɽ=====" << std::endl; + std::cout << "ɽʱ䣺 " << pTrade->TradeTime << std::endl; + std::cout << "Լ룺 " << pTrade->InstrumentID << std::endl; + std::cout << "ɽ۸ " << pTrade->Price << std::endl; + std::cout << "ɽ " << pTrade->Volume << std::endl; + std::cout << "ƽַ " << pTrade->Direction << std::endl; +} + +bool CustomTradeSpi::isErrorRspInfo(CThostFtdcRspInfoField *pRspInfo) { + bool bResult = pRspInfo && (pRspInfo->ErrorID != 0); + if (bResult) + std::cerr << "ش--->>> ErrorID=" << pRspInfo->ErrorID + << ", ErrorMsg=" << pRspInfo->ErrorMsg << std::endl; + return bResult; +} + +void CustomTradeSpi::reqUserLogin() { + CThostFtdcReqUserLoginField loginReq; + memset(&loginReq, 0, sizeof(loginReq)); + strcpy(loginReq.BrokerID, gBrokerID); + strcpy(loginReq.UserID, gInvesterID); + strcpy(loginReq.Password, gInvesterPassword); + static int requestID = 0; // + int rt = g_pTradeUserApi->ReqUserLogin(&loginReq, requestID); + if (!rt) + std::cout << ">>>>>>͵¼ɹ" << std::endl; + else + std::cerr << "--->>>͵¼ʧ" << std::endl; +} + +void CustomTradeSpi::reqUserLogout() { + CThostFtdcUserLogoutField logoutReq; + memset(&logoutReq, 0, sizeof(logoutReq)); + strcpy(logoutReq.BrokerID, gBrokerID); + strcpy(logoutReq.UserID, gInvesterID); + static int requestID = 0; // + int rt = g_pTradeUserApi->ReqUserLogout(&logoutReq, requestID); + if (!rt) + std::cout << ">>>>>>͵dzɹ" << std::endl; + else + std::cerr << "--->>>͵dzʧ" << std::endl; +} + +void CustomTradeSpi::reqSettlementInfoConfirm() { + CThostFtdcSettlementInfoConfirmField settlementConfirmReq; + memset(&settlementConfirmReq, 0, sizeof(settlementConfirmReq)); + strcpy(settlementConfirmReq.BrokerID, gBrokerID); + strcpy(settlementConfirmReq.InvestorID, gInvesterID); + static int requestID = 0; // + int rt = g_pTradeUserApi->ReqSettlementInfoConfirm(&settlementConfirmReq, + requestID); + if (!rt) + std::cout << ">>>>>>Ͷ߽ȷɹ" << std::endl; + else + std::cerr << "--->>>Ͷ߽ȷʧ" << std::endl; +} + +void CustomTradeSpi::reqQueryInstrument() { + CThostFtdcQryInstrumentField instrumentReq; + memset(&instrumentReq, 0, sizeof(instrumentReq)); + strcpy(instrumentReq.InstrumentID, g_pTradeInstrumentID); + static int requestID = 0; // + int rt = g_pTradeUserApi->ReqQryInstrument(&instrumentReq, requestID); + if (!rt) + std::cout << ">>>>>>ͺԼѯɹ" << std::endl; + else + std::cerr << "--->>>ͺԼѯʧ" << std::endl; +} + +void CustomTradeSpi::reqQueryTradingAccount() { + CThostFtdcQryTradingAccountField tradingAccountReq; + memset(&tradingAccountReq, 0, sizeof(tradingAccountReq)); + strcpy(tradingAccountReq.BrokerID, gBrokerID); + strcpy(tradingAccountReq.InvestorID, gInvesterID); + static int requestID = 0; // + std::this_thread::sleep_for( + std::chrono::milliseconds(700)); // ʱҪͣһܲѯɹ + int rt = g_pTradeUserApi->ReqQryTradingAccount(&tradingAccountReq, requestID); + if (!rt) + std::cout << ">>>>>>Ͷʽ˻ѯɹ" << std::endl; + else + std::cerr << "--->>>Ͷʽ˻ѯʧ" << std::endl; +} + +void CustomTradeSpi::reqQueryInvestorPosition() { + CThostFtdcQryInvestorPositionField postionReq; + memset(&postionReq, 0, sizeof(postionReq)); + strcpy(postionReq.BrokerID, gBrokerID); + strcpy(postionReq.InvestorID, gInvesterID); + strcpy(postionReq.InstrumentID, g_pTradeInstrumentID); + static int requestID = 0; // + std::this_thread::sleep_for( + std::chrono::milliseconds(700)); // ʱҪͣһܲѯɹ + int rt = g_pTradeUserApi->ReqQryInvestorPosition(&postionReq, requestID); + if (!rt) + std::cout << ">>>>>>Ͷֲֲ߳ѯɹ" << std::endl; + else + std::cerr << "--->>>Ͷֲֲ߳ѯʧ" << std::endl; +} + +void CustomTradeSpi::reqOrderInsert() { + CThostFtdcInputOrderField orderInsertReq; + memset(&orderInsertReq, 0, sizeof(orderInsertReq)); + ///͹˾ + strcpy(orderInsertReq.BrokerID, gBrokerID); + ///Ͷߴ + strcpy(orderInsertReq.InvestorID, gInvesterID); + ///Լ + strcpy(orderInsertReq.InstrumentID, g_pTradeInstrumentID); + /// + strcpy(orderInsertReq.OrderRef, order_ref); + ///۸: ޼ + orderInsertReq.OrderPriceType = THOST_FTDC_OPT_LimitPrice; + ///: + orderInsertReq.Direction = gTradeDirection; + ///Ͽƽ־: + orderInsertReq.CombOffsetFlag[0] = THOST_FTDC_OF_Open; + ///Ͷױ־ + orderInsertReq.CombHedgeFlag[0] = THOST_FTDC_HF_Speculation; + ///۸ + orderInsertReq.LimitPrice = gLimitPrice; + ///1 + orderInsertReq.VolumeTotalOriginal = 1; + ///Ч: Ч + orderInsertReq.TimeCondition = THOST_FTDC_TC_GFD; + ///ɽ: κ + orderInsertReq.VolumeCondition = THOST_FTDC_VC_AV; + ///Сɽ: 1 + orderInsertReq.MinVolume = 1; + ///: + orderInsertReq.ContingentCondition = THOST_FTDC_CC_Immediately; + ///ǿƽԭ: ǿƽ + orderInsertReq.ForceCloseReason = THOST_FTDC_FCC_NotForceClose; + ///Զ־: + orderInsertReq.IsAutoSuspend = 0; + ///ûǿ־: + orderInsertReq.UserForceClose = 0; + + static int requestID = 0; // + int rt = g_pTradeUserApi->ReqOrderInsert(&orderInsertReq, ++requestID); + if (!rt) + std::cout << ">>>>>>ͱ¼ɹ" << std::endl; + else + std::cerr << "--->>>ͱ¼ʧ" << std::endl; +} + +void CustomTradeSpi::reqOrderInsert(TThostFtdcInstrumentIDType instrumentID, + TThostFtdcPriceType price, + TThostFtdcVolumeType volume, + TThostFtdcDirectionType direction) { + CThostFtdcInputOrderField orderInsertReq; + memset(&orderInsertReq, 0, sizeof(orderInsertReq)); + ///͹˾ + strcpy(orderInsertReq.BrokerID, gBrokerID); + ///Ͷߴ + strcpy(orderInsertReq.InvestorID, gInvesterID); + ///Լ + strcpy(orderInsertReq.InstrumentID, instrumentID); + /// + strcpy(orderInsertReq.OrderRef, order_ref); + ///۸: ޼ + orderInsertReq.OrderPriceType = THOST_FTDC_OPT_LimitPrice; + ///: + orderInsertReq.Direction = direction; + ///Ͽƽ־: + orderInsertReq.CombOffsetFlag[0] = THOST_FTDC_OF_Open; + ///Ͷױ־ + orderInsertReq.CombHedgeFlag[0] = THOST_FTDC_HF_Speculation; + ///۸ + orderInsertReq.LimitPrice = price; + ///1 + orderInsertReq.VolumeTotalOriginal = volume; + ///Ч: Ч + orderInsertReq.TimeCondition = THOST_FTDC_TC_GFD; + ///ɽ: κ + orderInsertReq.VolumeCondition = THOST_FTDC_VC_AV; + ///Сɽ: 1 + orderInsertReq.MinVolume = 1; + ///: + orderInsertReq.ContingentCondition = THOST_FTDC_CC_Immediately; + ///ǿƽԭ: ǿƽ + orderInsertReq.ForceCloseReason = THOST_FTDC_FCC_NotForceClose; + ///Զ־: + orderInsertReq.IsAutoSuspend = 0; + ///ûǿ־: + orderInsertReq.UserForceClose = 0; + + static int requestID = 0; // + int rt = g_pTradeUserApi->ReqOrderInsert(&orderInsertReq, ++requestID); + if (!rt) + std::cout << ">>>>>>ͱ¼ɹ" << std::endl; + else + std::cerr << "--->>>ͱ¼ʧ" << std::endl; +} + +void CustomTradeSpi::reqOrderAction(CThostFtdcOrderField *pOrder) { + static bool orderActionSentFlag = false; // Ƿ˱ + if (orderActionSentFlag) + return; + + CThostFtdcInputOrderActionField orderActionReq; + memset(&orderActionReq, 0, sizeof(orderActionReq)); + ///͹˾ + strcpy(orderActionReq.BrokerID, pOrder->BrokerID); + ///Ͷߴ + strcpy(orderActionReq.InvestorID, pOrder->InvestorID); + /// + // TThostFtdcOrderActionRefType OrderActionRef; + /// + strcpy(orderActionReq.OrderRef, pOrder->OrderRef); + /// + // TThostFtdcRequestIDType RequestID; + ///ǰñ + orderActionReq.FrontID = trade_front_id; + ///Ự + orderActionReq.SessionID = session_id; + /// + // TThostFtdcExchangeIDType ExchangeID; + /// + // TThostFtdcOrderSysIDType OrderSysID; + ///־ + orderActionReq.ActionFlag = THOST_FTDC_AF_Delete; + ///۸ + // TThostFtdcPriceType LimitPrice; + ///仯 + // TThostFtdcVolumeType VolumeChange; + ///û + // TThostFtdcUserIDType UserID; + ///Լ + strcpy(orderActionReq.InstrumentID, pOrder->InstrumentID); + static int requestID = 0; // + int rt = g_pTradeUserApi->ReqOrderAction(&orderActionReq, ++requestID); + if (!rt) + std::cout << ">>>>>>ͱɹ" << std::endl; + else + std::cerr << "--->>>ͱʧ" << std::endl; + orderActionSentFlag = true; +} + +bool CustomTradeSpi::isMyOrder(CThostFtdcOrderField *pOrder) { + return ((pOrder->FrontID == trade_front_id) && + (pOrder->SessionID == session_id) && + (strcmp(pOrder->OrderRef, order_ref) == 0)); +} + +bool CustomTradeSpi::isTradingOrder(CThostFtdcOrderField *pOrder) { + return ((pOrder->OrderStatus != THOST_FTDC_OST_PartTradedNotQueueing) && + (pOrder->OrderStatus != THOST_FTDC_OST_Canceled) && + (pOrder->OrderStatus != THOST_FTDC_OST_AllTraded)); +} \ No newline at end of file diff --git a/qbot/engine/trade/engine_apis/futures/CTPtest/src/CustomTradeSpi.h b/qbot/engine/trade/engine_apis/futures/CTPtest/src/CustomTradeSpi.h new file mode 100644 index 00000000..3b9c06c8 --- /dev/null +++ b/qbot/engine/trade/engine_apis/futures/CTPtest/src/CustomTradeSpi.h @@ -0,0 +1,88 @@ +#pragma once +// ---- Ľ ---- // +#include "CTP_API/ThostFtdcTraderApi.h" + +class CustomTradeSpi : public CThostFtdcTraderSpi { + // ---- ctp_apiֻصӿ ---- // +public: + ///ͻ뽻׺̨ͨʱδ¼ǰ÷á + void OnFrontConnected(); + + ///¼Ӧ + void OnRspUserLogin(CThostFtdcRspUserLoginField *pRspUserLogin, + CThostFtdcRspInfoField *pRspInfo, int nRequestID, + bool bIsLast); + + ///Ӧ + void OnRspError(CThostFtdcRspInfoField *pRspInfo, int nRequestID, + bool bIsLast); + + ///ͻ뽻׺̨ͨӶϿʱ÷áAPIԶӣͻ˿ɲ + void OnFrontDisconnected(int nReason); + + ///ʱ档ʱδյʱ÷á + void OnHeartBeatWarning(int nTimeLapse); + + ///dzӦ + void OnRspUserLogout(CThostFtdcUserLogoutField *pUserLogout, + CThostFtdcRspInfoField *pRspInfo, int nRequestID, + bool bIsLast); + + ///Ͷ߽ȷӦ + void OnRspSettlementInfoConfirm( + CThostFtdcSettlementInfoConfirmField *pSettlementInfoConfirm, + CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast); + + ///ѯԼӦ + void OnRspQryInstrument(CThostFtdcInstrumentField *pInstrument, + CThostFtdcRspInfoField *pRspInfo, int nRequestID, + bool bIsLast); + + ///ѯʽ˻Ӧ + void OnRspQryTradingAccount(CThostFtdcTradingAccountField *pTradingAccount, + CThostFtdcRspInfoField *pRspInfo, int nRequestID, + bool bIsLast); + + ///ѯͶֲ߳Ӧ + void + OnRspQryInvestorPosition(CThostFtdcInvestorPositionField *pInvestorPosition, + CThostFtdcRspInfoField *pRspInfo, int nRequestID, + bool bIsLast); + + ///¼Ӧ + void OnRspOrderInsert(CThostFtdcInputOrderField *pInputOrder, + CThostFtdcRspInfoField *pRspInfo, int nRequestID, + bool bIsLast); + + ///Ӧ + void OnRspOrderAction(CThostFtdcInputOrderActionField *pInputOrderAction, + CThostFtdcRspInfoField *pRspInfo, int nRequestID, + bool bIsLast); + + ///֪ͨ + void OnRtnOrder(CThostFtdcOrderField *pOrder); + + ///ɽ֪ͨ + void OnRtnTrade(CThostFtdcTradeField *pTrade); + + // ---- Զ庯 ---- // +public: + bool loginFlag; // ½ɹıʶ + void + reqOrderInsert(TThostFtdcInstrumentIDType instrumentID, + TThostFtdcPriceType price, TThostFtdcVolumeType volume, + TThostFtdcDirectionType direction); // Ի¼룬ⲿ +private: + void reqUserLogin(); // ¼ + void reqUserLogout(); // dz + void reqSettlementInfoConfirm(); // Ͷ߽ȷ + void reqQueryInstrument(); // ѯԼ + void reqQueryTradingAccount(); // ѯʽʻ + void reqQueryInvestorPosition(); // ѯͶֲ߳ + void reqOrderInsert(); // 󱨵¼ + + void reqOrderAction(CThostFtdcOrderField *pOrder); // 󱨵 + bool isErrorRspInfo(CThostFtdcRspInfoField *pRspInfo); // ǷյϢ + bool isMyOrder(CThostFtdcOrderField *pOrder); // Ƿҵıر + bool isTradingOrder(CThostFtdcOrderField *pOrder); // Ƿڽ׵ı +}; \ No newline at end of file diff --git a/qbot/engine/trade/engine_apis/futures/CTPtest/src/StrategyTrade.cpp b/qbot/engine/trade/engine_apis/futures/CTPtest/src/StrategyTrade.cpp new file mode 100644 index 00000000..e25e9ada --- /dev/null +++ b/qbot/engine/trade/engine_apis/futures/CTPtest/src/StrategyTrade.cpp @@ -0,0 +1,34 @@ +#include "StrategyTrade.h" +#include "CustomTradeSpi.h" +#include +#include +#include +#include +#include + +extern std::unordered_map g_KlineHash; + +// ̻߳ +std::mutex marketDataMutex; + +void StrategyCheckAndTrade(TThostFtdcInstrumentIDType instrumentID, + CustomTradeSpi *customTradeSpi) { + // + std::lock_guard lk(marketDataMutex); + TickToKlineHelper tickToKlineObject = + g_KlineHash.at(std::string(instrumentID)); + // + std::vector priceVec = tickToKlineObject.m_priceVec; + if (priceVec.size() >= 3) { + int len = priceVec.size(); + // Ǿ򿪲,֮,ʱһ۸µ + if (priceVec[len - 1] > priceVec[len - 2] && + priceVec[len - 2] > priceVec[len - 3]) + customTradeSpi->reqOrderInsert(instrumentID, priceVec[len - 1], 1, + THOST_FTDC_D_Buy); + else if (priceVec[len - 1] < priceVec[len - 2] && + priceVec[len - 2] < priceVec[len - 3]) + customTradeSpi->reqOrderInsert(instrumentID, priceVec[len - 1], 1, + THOST_FTDC_D_Buy); + } +} diff --git a/qbot/engine/trade/engine_apis/futures/CTPtest/src/StrategyTrade.h b/qbot/engine/trade/engine_apis/futures/CTPtest/src/StrategyTrade.h new file mode 100644 index 00000000..53b40414 --- /dev/null +++ b/qbot/engine/trade/engine_apis/futures/CTPtest/src/StrategyTrade.h @@ -0,0 +1,19 @@ +#pragma once +// ---- 򵥲Խ׵ ---- // + +#include "CTP_API/ThostFtdcUserApiStruct.h" +#include "CustomTradeSpi.h" +#include "TickToKlineHelper.h" +#include + +typedef void (*reqOrderInsertFun)(TThostFtdcInstrumentIDType instrumentID, + TThostFtdcPriceType price, + TThostFtdcVolumeType volume, + TThostFtdcDirectionType direction); + +using ReqOrderInsertFunctionType = std::function; + +void StrategyCheckAndTrade(TThostFtdcInstrumentIDType instrumentID, + CustomTradeSpi *customTradeSpi); diff --git a/qbot/engine/trade/engine_apis/futures/CTPtest/src/TickToKlineHelper.cpp b/qbot/engine/trade/engine_apis/futures/CTPtest/src/TickToKlineHelper.cpp new file mode 100644 index 00000000..342f3dc4 --- /dev/null +++ b/qbot/engine/trade/engine_apis/futures/CTPtest/src/TickToKlineHelper.cpp @@ -0,0 +1,98 @@ +#include "TickToKlineHelper.h" +#include "CTP_API/ThostFtdcUserApiStruct.h" +#include +#include +#include +#include +#include + +const int kDataLineNum = 2 * 60; // 1k(ĩβһӵȥ) + +void TickToKlineHelper::KLineFromLocalData(const std::string &sFilePath, + const std::string &dFilePath) { + // + m_priceVec.clear(); + m_volumeVec.clear(); + m_KLineDataArray.clear(); + + std::cout << "ʼתtickk..." << std::endl; + // Ĭ϶ȡtickݱ4ֶΣԼ롢ʱ䡢¼ۡɽ + std::ifstream srcInFile; + std::ofstream dstOutFile; + srcInFile.open(sFilePath, std::ios::in); + dstOutFile.open(dFilePath, std::ios::out); + dstOutFile << "̼" << ',' << "߼" << ',' << "ͼ" << ',' + << "̼" << ',' << "ɽ" << std::endl; + + // һļһ߼kݣ1kÿζȡ60 * 2 = 120 + std::string lineStr; + bool isFirstLine = true; + while (std::getline(srcInFile, lineStr)) { + if (isFirstLine) { + // һбͷ + isFirstLine = false; + continue; + } + std::istringstream ss(lineStr); + std::string fieldStr; + int count = 4; + while (std::getline(ss, fieldStr, ',')) { + count--; + if (count == 1) + m_priceVec.push_back(std::atof(fieldStr.c_str())); + else if (count == 0) { + m_volumeVec.push_back(std::atoi(fieldStr.c_str())); + break; + } + } + + // k + + if (m_priceVec.size() == kDataLineNum) { + KLineDataType k_line_data; + k_line_data.open_price = m_priceVec.front(); + k_line_data.high_price = + *std::max_element(m_priceVec.cbegin(), m_priceVec.cend()); + k_line_data.low_price = + *std::min_element(m_priceVec.cbegin(), m_priceVec.cend()); + k_line_data.close_price = m_priceVec.back(); + // ɽʵ㷨ǵǰһɽȥȥһһɽ + k_line_data.volume = m_volumeVec.back() - m_volumeVec.front(); + // m_KLineDataArray.push_back(k_line_data); // ˴Դ浽ڴ + + dstOutFile << k_line_data.open_price << ',' << k_line_data.high_price + << ',' << k_line_data.low_price << ',' + << k_line_data.close_price << ',' << k_line_data.volume + << std::endl; + + m_priceVec.clear(); + m_volumeVec.clear(); + } + } + + srcInFile.close(); + dstOutFile.close(); + + std::cout << "kɳɹ" << std::endl; +} + +void TickToKlineHelper::KLineFromRealtimeData( + CThostFtdcDepthMarketDataField *pDepthMarketData) { + m_priceVec.push_back(pDepthMarketData->LastPrice); + m_volumeVec.push_back(pDepthMarketData->Volume); + if (m_priceVec.size() == kDataLineNum) { + KLineDataType k_line_data; + k_line_data.open_price = m_priceVec.front(); + k_line_data.high_price = + *std::max_element(m_priceVec.cbegin(), m_priceVec.cend()); + k_line_data.low_price = + *std::min_element(m_priceVec.cbegin(), m_priceVec.cend()); + k_line_data.close_price = m_priceVec.back(); + // ɽʵ㷨ǵǰһɽȥȥһһɽ + k_line_data.volume = m_volumeVec.back() - m_volumeVec.front(); + m_KLineDataArray.push_back(k_line_data); // ˴Դ浽ڴ + + m_priceVec.clear(); + m_volumeVec.clear(); + } +} diff --git a/qbot/engine/trade/engine_apis/futures/CTPtest/src/TickToKlineHelper.h b/qbot/engine/trade/engine_apis/futures/CTPtest/src/TickToKlineHelper.h new file mode 100644 index 00000000..359a550e --- /dev/null +++ b/qbot/engine/trade/engine_apis/futures/CTPtest/src/TickToKlineHelper.h @@ -0,0 +1,28 @@ +#pragma once +// ---- kߵ ---- // + +#include +#include + +// kݽṹ +struct KLineDataType { + double open_price; // + double high_price; // + double low_price; // + double close_price; // + int volume; // +}; + +class TickToKlineHelper { +public: + // ӱݹkߣ洢(ٶûж) + void KLineFromLocalData(const std::string &sFilePath, + const std::string &dFilePath); + // ʵʱݹk + void KLineFromRealtimeData(CThostFtdcDepthMarketDataField *pDepthMarketData); + +public: + std::vector m_priceVec; // 洢1ӵļ۸ + std::vector m_volumeVec; // 洢1ӵijɽ + std::vector m_KLineDataArray; +}; diff --git a/qbot/engine/trade/engine_apis/futures/CTPtest/src/main.cpp b/qbot/engine/trade/engine_apis/futures/CTPtest/src/main.cpp new file mode 100644 index 00000000..8bda49b2 --- /dev/null +++ b/qbot/engine/trade/engine_apis/futures/CTPtest/src/main.cpp @@ -0,0 +1,78 @@ +#include "CustomMdSpi.h" +#include "CustomTradeSpi.h" +#include "TickToKlineHelper.h" +#include +#include +#include +#include + +using namespace std; + +// ӿ +#pragma comment(lib, "thostmduserapi.lib") +#pragma comment(lib, "thosttraderapi.lib") + +// ---- ȫֱ ---- // +// +TThostFtdcBrokerIDType gBrokerID = "9999"; // ģ⾭̴ +TThostFtdcInvestorIDType gInvesterID = ""; // Ͷ˻ +TThostFtdcPasswordType gInvesterPassword = ""; // Ͷ + +// +CThostFtdcMdApi *g_pMdUserApi = nullptr; // ָ +char gMdFrontAddr[] = "tcp://180.168.146.187:10010"; // ģǰõַ +char *g_pInstrumentID[] = { + "TF1706", "zn1705", "cs1801", + "CF705"}; // ԼбСϡ֣ѡһ +int instrumentNum = 4; // Լ +unordered_map g_KlineHash; // ͬԼkߴ洢 + +// ײ +CThostFtdcTraderApi *g_pTradeUserApi = nullptr; // ָ +char gTradeFrontAddr[] = "tcp://180.168.146.187:10001"; // ģ⽻ǰõַ +TThostFtdcInstrumentIDType g_pTradeInstrumentID = "zn1705"; // ׵ĺԼ +TThostFtdcDirectionType gTradeDirection = THOST_FTDC_D_Sell; // +TThostFtdcPriceType gLimitPrice = 22735; // ׼۸ + +int main() { + // ˺ + cout << "˺ţ "; + scanf("%s", gInvesterID); + cout << "룺 "; + scanf("%s", gInvesterPassword); + + // ʼ߳ + cout << "ʼ..." << endl; + g_pMdUserApi = CThostFtdcMdApi::CreateFtdcMdApi(); // ʵ + CThostFtdcMdSpi *pMdUserSpi = new CustomMdSpi; // صʵ + g_pMdUserApi->RegisterSpi(pMdUserSpi); // ע¼ + g_pMdUserApi->RegisterFront(gMdFrontAddr); // ǰõַ + g_pMdUserApi->Init(); // + + // ʼ߳ + cout << "ʼ..." << endl; + g_pTradeUserApi = CThostFtdcTraderApi::CreateFtdcTraderApi(); // ʵ + // CThostFtdcTraderSpi *pTradeSpi = new CustomTradeSpi; + CustomTradeSpi *pTradeSpi = new CustomTradeSpi; // ׻صʵ + g_pTradeUserApi->RegisterSpi(pTradeSpi); // ע¼ + g_pTradeUserApi->SubscribePublicTopic(THOST_TERT_RESTART); // Ĺ + g_pTradeUserApi->SubscribePrivateTopic(THOST_TERT_RESTART); // ˽ + g_pTradeUserApi->RegisterFront(gTradeFrontAddr); // ýǰõַ + g_pTradeUserApi->Init(); // + + // ȵ߳˳ + g_pMdUserApi->Join(); + delete pMdUserSpi; + g_pMdUserApi->Release(); + + g_pTradeUserApi->Join(); + delete pTradeSpi; + g_pTradeUserApi->Release(); + + // תk + // TickToKlineHelper tickToKlineHelper; + // tickToKlineHelper.KLineFromLocalData("market_data.csv", "K_line_data.csv"); + + getchar(); + return 0; +} \ No newline at end of file diff --git a/qbot/engine/trade/engine_apis/futures/account.json.example b/qbot/engine/trade/engine_apis/futures/account.json.example new file mode 100644 index 00000000..21cd4cd7 --- /dev/null +++ b/qbot/engine/trade/engine_apis/futures/account.json.example @@ -0,0 +1,23 @@ +{ + "CTP": { + "/des": " account info", + "user": "", + "password": "" + }, + "易达": { + "/des": " account info", + "user": "", + "password": "" + }, + "艾克朗科": { + "/des": " account info", + "user": "", + "password": "" + } + , + "CTPMini": { + "/des": " account info", + "user": "", + "password": "" + } +} \ No newline at end of file diff --git a/qbot/engine/trade/engine_apis/futures/futures_engine.py b/qbot/engine/trade/engine_apis/futures/futures_engine.py new file mode 100644 index 00000000..73d2e0c2 --- /dev/null +++ b/qbot/engine/trade/engine_apis/futures/futures_engine.py @@ -0,0 +1,27 @@ +from qbot.common.logging.logger import LOGGER as logger + +class FuturesTradeEngine: + + def __init__(self, account, trade_opts: dict, syslog_obj): + self.account = account + self.strategy = trade_opts["strategy"] + self.syslog = syslog_obj + self.trade_engine = None + + def start_trade(self): + self.syslog.re_print("FuturesTradeEngine start trade ...\n") + pass + + +if __name__ == "__main__": + trade_opts = { + "class": "实盘", + "platform": "东方财富", + "trade_type": "股票", + "trade_code": "399006.SZ", + "strategy": "单因子-相对强弱指数RSI", + } + futures_engine = FuturesTradeEngine(trade_opts["platform"], trade_opts, self.syslog) + futures_engine.start_trade() + if trade_opts["platform"] not in accounts: + logger.error("当前还不支持该平台, 请联系微信 Yida_Zhang2") \ No newline at end of file diff --git a/qbot/engine/trade/engine_apis/options/account.json.example b/qbot/engine/trade/engine_apis/options/account.json.example new file mode 100644 index 00000000..c7f061bf --- /dev/null +++ b/qbot/engine/trade/engine_apis/options/account.json.example @@ -0,0 +1,12 @@ +{ + "东方财富": { + "/des": " account info", + "user": "", + "password": "" + }, + "华泰证券": { + "/des": " account info", + "user": "", + "password": "" + } +} \ No newline at end of file diff --git a/qbot/engine/trade/engine_apis/stocks/account.json.example b/qbot/engine/trade/engine_apis/stocks/account.json.example new file mode 100644 index 00000000..92bbbb61 --- /dev/null +++ b/qbot/engine/trade/engine_apis/stocks/account.json.example @@ -0,0 +1,33 @@ +{ + "东方财富": { + "/des": " account info", + "user": "", + "password": "" + }, + "华泰证券": { + "/des": " account info", + "user": "", + "password": "" + }, + "雪球": { + "cookies": "雪球 cookies,登陆后获取,获取方式见 https://smalltool.github.io/2016/08/02/cookie/", + "portfolio_code": "组合代码(例:ZH818559)", + "portfolio_market": "交易市场(例:us 或者 cn 或者 hk)" + }, + "银河证券": { + "user": "银河用户名", + "password": "银河明文密码" + }, + "海通证券": { + "user": "海通用户名", + "password": "海通明文密码" + }, + "国金证券": { + "user": "国金用户名", + "password": "国金明文密码" + }, + "通达信": { + "user": "通达信用户名", + "password": "通达信明文密码" + } +} \ No newline at end of file diff --git a/qbot/engine/trade/engine_apis/stocks/easytrader_example.py b/qbot/engine/trade/engine_apis/stocks/easytrader_example.py new file mode 100644 index 00000000..7126691b --- /dev/null +++ b/qbot/engine/trade/engine_apis/stocks/easytrader_example.py @@ -0,0 +1,60 @@ +""" +Author: Charmve yidazhang1@gmail.com +Date: 2023-06-02 22:04:52 +LastEditors: Charmve yidazhang1@gmail.com +LastEditTime: 2023-06-02 22:05:42 +FilePath: /newbasic/easytrader_example/easytrader_example.py +Version: 1.0.1 +Blogs: charmve.blog.csdn.net +GitHub: https://github.com/Charmve +Description: + +Copyright (c) 2023 by Charmve, All Rights Reserved. +Licensed under the MIT License. +""" + +import easytrader + + +# 定义一个网格交易策略类 +class GridTradeStrategy: + def __init__(self, user, symbol, grid_num, grid_width): + self.user = user # easytrader客户端对象 + self.symbol = symbol # 要交易的股票代码 + self.grid_num = grid_num # 网格数量 + self.grid_width = grid_width # 每个网格的宽度(百分比) + self.init_price = user.get_price(symbol) # 初始价格 + + def execute(self): + price = self.user.get_price(self.symbol) + grid_price = [ + self.init_price * (1 + self.grid_width * i) for i in range(self.grid_num) + ] + [self.init_price * (1 - self.grid_width * i) for i in range(self.grid_num)] + grid_price.sort() + + for i in range(self.grid_num * 2): + if ( + price > grid_price[i] + and self.user.position[self.symbol]["sellable"] > 0 + ): + self.user.sell(stock_code=self.symbol, price=price, amount=100) + self.init_price = grid_price[i] + break + elif price < grid_price[i] and self.user.cash_available // price >= 100: + self.user.buy(stock_code=self.symbol, price=price, amount=100) + self.init_price = grid_price[i] + break + + +# 登录华泰证券客户端 +user = easytrader.use("ht_client") +user.prepare("华泰", username="your_username", password="your_password") + +# 创建网格交易策略对象并执行交易 +symbol = "600000" # 要交易的股票代码 +grid_num = 10 # 网格数量 +grid_width = 0.01 # 每个网格的宽度(百分比) +strategy = GridTradeStrategy(user, symbol, grid_num, grid_width) + +while True: + strategy.execute() diff --git a/qbot/engine/trade/engine_apis/stocks/gmtrade_example.py b/qbot/engine/trade/engine_apis/stocks/gmtrade_example.py new file mode 100644 index 00000000..cd96dc2f --- /dev/null +++ b/qbot/engine/trade/engine_apis/stocks/gmtrade_example.py @@ -0,0 +1,81 @@ +""" +Author: Charmve yidazhang1@gmail.com +Date: 2023-05-18 15:18:40 +LastEditors: Charmve yidazhang1@gmail.com +LastEditTime: 2023-05-18 15:22:41 +FilePath: /newbasic/easytrader_example/gmtrade_example.py +Version: 1.0.1 +Blogs: charmve.blog.csdn.net +GitHub: https://github.com/Charmve +Description: + +https://sim.myquant.cn/sim/help/#仿真账户登录 + +Copyright (c) 2023 by Charmve, All Rights Reserved. +Licensed under the MIT License. +""" + +# 本示例运行于python3.6及以上版本 +from gmtrade.api import * # noqa: F403 + +# token身份认证,掘金登录后可在仿真交易官网获取 +set_token("c793349a885556506e27c2081c73091b4e77f28b") + +# 示例中为掘金官方仿真服务地址,如接入掘金终端,则填空 +set_endpoint("api.myquant.cn:9000") + +# 登录账户,账户ID由登录并申请仿真账户后,可复制获取;account_alias为账号别名,选填 +a1 = account(account_id="5e4cdda3-f2fb-11ed-ae27-00163e022aa6", account_alias="") +login(a1) # 注意,可以输入账户也可以输入账户组成的list + + +# 回报到达时触发 +def on_execution_report(rpt): + print(f"exec_rpt_count={rpt}") + + +# 委托状态变化时触发 +def on_order_status(order): + print(f"order_stats_count={order}") + + +# 交易服务连接成功后触发 +def on_trade_data_connected(): + print("已连接交易服务.................") + + +# 交易服务断开后触发 +def on_trade_data_disconnected(): + print("已断开交易服务.................") + + +# 回报到达时触发 +def on_account_status(account_status): + print(f"on_account_status status={account_status}") + + +if __name__ == "__main__": + # start函数用于启动回调事件接收,非必要;事件函数为非阻塞函数,如需要同步执行需自行阻塞 + # filename=__file__用于指定当前运行的文件,如需要指定其他文件filename=‘xxx’ + status = start(filename=__file__) + if status == 0: + print("连接交易服务成功.................") + else: + print("接交易服务失败.................") + stop() + + # 开始交易业务 + # 获取登录账户的资金,如登录多个账户需要指定账户ID + cash = get_cash() + print(f"get_cash cash={cash}") + + # 获取登录账户的持仓,如登录多个账户需要指定账户ID + poses = get_positions() + print(f"get_positions poes={poses}") + + # 限价、定量委托买入浦发银行股票 + # data = order_volume(symbol='SHSE.600000', volume=1000, side=OrderSide_Buy, order_type=OrderType_Limit, position_effect=PositionEffect_Open, price=11) + # 结束交易业务 + + # 保持进程不退出,否则回调不再生效 + info = input("输入任字符退出") diff --git a/qbot/engine/trade/engine_apis/stocks/stock_engine.py b/qbot/engine/trade/engine_apis/stocks/stock_engine.py new file mode 100644 index 00000000..4615dfb6 --- /dev/null +++ b/qbot/engine/trade/engine_apis/stocks/stock_engine.py @@ -0,0 +1,230 @@ +from qbot.common.logging.logger import LOGGER as logger + + +class StockTradeEngine: + def __init__(self, account, trade_opts: dict, syslog_obj): + self.account = account + self.strategy = trade_opts["strategy"] + self.syslog = syslog_obj + self.trade_engine = None + if trade_opts["platform"] == "掘金" and trade_opts["class"] == "虚拟盘": + self.trade_engine = GmSimTrader(self.account, trade_opts, syslog_obj) + elif trade_opts["platform"] == "东方财富": + self.trade_engine = EastmoneyTrader(self.account, trade_opts, syslog_obj) + else: + logger.warnning( + f"{trade_opts['platform']} 还未支持,可联系微信 Yida_Zhang2" + ) + + if not self.trade_engine: + logger.error("trade engine is null") + return + + def login(self): + self.trade_engine.login() + + def get_balance(self): + self.trade_engine.get_balance() + + def get_positions(self): + self.trade_engine.get_positions() + + def load_strategy(self): + pass + + def close(self): + self.trade_engine.close() + + def start_trade(self): + self.syslog.re_print("StockTradeEngine start trade ...\n") + # logger.info(f"start trade, {self.account}") + self.trade_engine.start_trade() + # self.trade_engine.close() + pass + + +# 掘金 +# 本示例运行于python3.6及以上版本 +from gmtrade.api import * # noqa:F403 + +from qbot.engine.tokens import GMTRADE_ACCOUNT, GMTRADE_TOKEN + +# token身份认证,掘金登录后可在仿真交易官网获取 +set_token(GMTRADE_TOKEN) + +# 示例中为掘金官方仿真服务地址,如接入掘金终端,则填空 +set_endpoint("api.myquant.cn:9000") + +# 登录账户,账户ID由登录并申请仿真账户后,可复制获取;account_alias为账号别名,选填 +a1 = account(account_id=GMTRADE_ACCOUNT, account_alias="") +login(a1) # 注意,可以输入账户也可以输入账户组成的list + + +# 回报到达时触发 +def on_execution_report(rpt): + print(f"exec_rpt_count={rpt}") + + +# 委托状态变化时触发 +def on_order_status(order): + print(f"order_stats_count={order}") + + +# 交易服务连接成功后触发 +def on_trade_data_connected(): + print("已连接交易服务.................") + + +# 交易服务断开后触发 +def on_trade_data_disconnected(): + print("已断开交易服务.................") + + +# 回报到达时触发 +def on_account_status(account_status): + print(f"on_account_status status={account_status}") + + +class GmSimTrader: + def __init__(self, account, trade_opts: dict, syslog_obj): + self.account = account + self.trade_opts = trade_opts + self.syslog = syslog_obj + + def __del__(self): + self.close() + + def login(self): + # start函数用于启动回调事件接收,非必要;事件函数为非阻塞函数,如需要同步执行需自行阻塞 + # filename=__file__用于指定当前运行的文件,如需要指定其他文件filename=‘xxx’ + status = start(filename=__file__) + if status == 0: + print("连接交易服务成功.................") + else: + print("接交易服务失败.................") + stop() + + def load_strategy(self): + self.strategy = self.trade_opts["strategy"] + print("交易策略: ", self.strategy) + pass + + def get_balance(self): + # 获取登录账户的资金,如登录多个账户需要指定账户ID + cash = get_cash() + print(f"get_cash cash={cash}") + self.syslog.re_print(f"get_cash cash: \n{cash}") + + def get_positions(self): + # 获取登录账户的持仓,如登录多个账户需要指定账户ID + poses = get_positions() + print(f"get_positions poes=\n{poses}") + self.syslog.re_print(f"get_positions poes: \n{poses}") + + def start_trade(self): + self.syslog.re_print("GmSimTrader start trade ...\n") + logger.info(f"start trade, {self.account}") + self.load_strategy() + + symbol = self.trade_opts["trade_code"] + # data = order_volume(symbol=symbol, volume=1000, side=OrderSide_Buy, order_type=OrderType_Limit, position_effect=PositionEffect_Open, price=11) + + # 限价、定量委托买入浦发银行股票 + # data = order_volume(symbol='SHSE.600000', volume=1000, side=OrderSide_Buy, order_type=OrderType_Limit, position_effect=PositionEffect_Open, price=11) + # 结束交易业务 + pass + + def close(self): + # 保持进程不退出,否则回调不再生效 + info = input("输入任字符退出") + + +# 东方财富 +class EastmoneyTrader: + def __init__(self, account, trade_opts: dict, syslog_obj): + self.account = account + self.trade_opts = trade_opts + self.syslog = syslog_obj + + def __del__(self): + self.close() + + def login(self): + pass + + def load_strategy(self): + self.strategy = self.trade_opts["strategy"] + print("交易策略: ", self.strategy) + pass + + def get_balance(self): + # 获取登录账户的资金,如登录多个账户需要指定账户ID + cash = get_cash() + print(f"get_cash cash={cash}") + + def get_positions(self): + # 获取登录账户的持仓,如登录多个账户需要指定账户ID + poses = get_positions() + print(f"get_positions poes={poses}") + + def start_trade(self): + self.syslog.re_print("EastmoneyTrader start trade ...\n") + # logger.info(f"start trade, {self.account}") + self.load_strategy() + + symbol = self.trade_opts["trade_code"] + # data = order_volume(symbol=symbol, volume=1000, side=OrderSide_Buy, order_type=OrderType_Limit, position_effect=PositionEffect_Open, price=11) + + # 限价、定量委托买入浦发银行股票 + # data = order_volume(symbol='SHSE.600000', volume=1000, side=OrderSide_Buy, order_type=OrderType_Limit, position_effect=PositionEffect_Open, price=11) + # 结束交易业务 + pass + + def close(self): + # 保持进程不退出,否则回调不再生效 + info = input("输入任字符退出") + + +if __name__ == "__main__": + trade_opts = { + "class": "虚拟盘", + "platform": "掘金", + "trade_type": "股票", + "trade_code": "399006.SZ", + "strategy": "单因子-相对强弱指数RSI", + } + + from qbot.common.file_utils import file2dict + from qbot.engine.config import STOCK_REAL_ACCOUNT, STOCK_SIM_ACCOUNT # noqa: F401 + + # 实盘交易 + real_accounts = file2dict(STOCK_SIM_ACCOUNT) + + stock_engine = StockTradeEngine( + account=real_accounts[trade_opts["platform"]], + trade_opts=trade_opts, + syslog_obj=None, + ) + stock_engine.login() + stock_engine.get_balance() + stock_engine.get_positions() + stock_engine.start_trade() + if trade_opts["platform"] not in real_accounts: + logger.error("当前还不支持该平台, 请联系微信 Yida_Zhang2") + + # 虚拟交易 + trade_opts["class"] = "虚拟盘" + trade_opts["platform"] = "东方财富" + sim_accounts = file2dict(STOCK_SIM_ACCOUNT) + + stock_engine = StockTradeEngine( + account=sim_accounts[trade_opts["platform"]], + trade_opts=trade_opts, + syslog_obj=None, + ) + stock_engine.login() + stock_engine.get_balance() + stock_engine.get_positions() + stock_engine.start_trade() + if trade_opts["platform"] not in sim_accounts: + logger.error("当前还不支持该平台, 请联系微信 Yida_Zhang2") diff --git a/qbot/engine/trade/trade_engine.py b/qbot/engine/trade/trade_engine.py new file mode 100644 index 00000000..71d1ba62 --- /dev/null +++ b/qbot/engine/trade/trade_engine.py @@ -0,0 +1,73 @@ +from qbot.common.logging.logger import LOGGER as logger +from qbot.engine.trade.trade_real import RealTradeEngine +from qbot.engine.trade.trade_sim import SimTradeEngine + + +class TradeEngine: + def __init__(self, trade_opts: dict, syslog_obj): + + if syslog_obj: + self.syslog = syslog_obj + else: + logger.error("syslog_obj is null.") + return + + self.syslog.re_print("TradeEngine start init ...\n") + + if trade_opts: + logger.info(f"trade_opts: {trade_opts}") + else: + logger.error("trade_opts is empty.") + return + + self.trade_opts = trade_opts + if self.trade_opts["class"] == "虚拟盘": + self.TradeEngine = SimTradeEngine(self.trade_opts, syslog_obj=self.syslog) + elif self.trade_opts["class"] == "实盘": + self.TradeEngine = RealTradeEngine(self.trade_opts, syslog_obj=self.syslog) + else: + logger.error( + f"parameter is invalid, trade class is {self.trade_opts['class']}" + ) + + def login(self): + logger.info(f"{self.trade_opts['platform']} login ....") + self.syslog.re_print(f"{self.trade_opts['platform']} login ....\n") + self.TradeEngine.login() + pass + + def get_cash(self): + self.TradeEngine.get_cash() + + def get_positions(self): + self.TradeEngine.get_positions() + + def load_strategy(self): + pass + + def start_trade(self): + logger.info("start_trade ....") + self.TradeEngine.start_trade() + pass + + def close(self): + logger.info("close engine ....") + self.TradeEngine.close() + pass + + +if __name__ == "__main__": + trade_opts = { + "class": "虚拟盘", + "platform": "掘金", + "trade_type": "股票", + "trade_code": "399006.SZ", + "strategy": "单因子-相对强弱指数RSI", + } + + trade_engine = TradeEngine(trade_opts, syslog_obj=None) + trade_engine.login() + trade_engine.get_cash() + trade_engine.get_positions() + trade_engine.start_trade() + trade_engine.close() diff --git a/qbot/engine/trade/trade_real.py b/qbot/engine/trade/trade_real.py new file mode 100644 index 00000000..c4d4c8c1 --- /dev/null +++ b/qbot/engine/trade/trade_real.py @@ -0,0 +1,177 @@ +import easytrader + +from qbot.common.file_utils import file2dict +from qbot.common.logging.logger import LOGGER as logger + + +class RealTradeEngine: + def __init__(self, trade_opts: dict, syslog_obj, user=None): + if syslog_obj: + self.syslog = syslog_obj + else: + logger.error("syslog_obj is null.") + return + + self.syslog.re_print("RealTradeEngine start init ...\n") + + if trade_opts: + logger.info(trade_opts) + else: + logger.error("trade_opts is empty.") + return + + if not user: + if trade_opts["trade_type"] == "股票": + from qbot.engine.config import STOCK_REAL_ACCOUNT + + accounts = file2dict(STOCK_REAL_ACCOUNT) + + from qbot.engine.trade.engine_apis.stocks.stock_engine import ( + StockTradeEngine, + ) + + if trade_opts["platform"] not in accounts: + logger.error("当前还不支持该平台, 请联系微信 Yida_Zhang2") + return + + self.trade_engine = StockTradeEngine( + account=accounts[trade_opts["platform"]], + trade_opts=trade_opts, + syslog_obj=self.syslog, + ) + self.trade_engine.login() + + if trade_opts["platform"] == "华泰证券": + self.user = easytrader.use("ht_client") + self.user.prepare( + "华泰证券", + username = accounts["华泰证券"]["user"], + password = accounts["华泰证券"]["password"], + ) + elif trade_opts["platform"] == "通达信": + self.user = easytrader.use("tongda") + self.user.prepare( + "通达信", + username = accounts["通达信"]["user"], + password = accounts["通达信"]["password"], + ) + elif trade_opts["platform"] == "银河证券": + self.user = easytrader.use("yinhe") + self.user.prepare( + "银河证券", + username = accounts["银河证券"]["user"], + password = accounts["银河证券"]["password"], + ) + elif trade_opts["platform"] == "同花顺": + self.user = easytrader.use("tonghuashun") + self.user.prepare( + "同花顺", + username = accounts["同花顺"]["user"], + password = accounts["同花顺"]["password"], + ) + elif trade_opts["platform"] == "雪球": + self.user = easytrader.use("xuqiu") + self.user.prepare( + "雪球", + username = accounts["雪球"]["user"], + password = accounts["雪球"]["password"], + ) + else: + logger.error("当前还不支持该平台, 请联系微信 Yida_Zhang2") + elif trade_opts["trade_type"] == "基金": + from qbot.engine.config import FUNDS_REAL_ACCOUNT + + accounts = file2dict(FUNDS_REAL_ACCOUNT) + + elif trade_opts["trade_type"] == "期货": + from qbot.engine.config import FUTURES_REAL_ACCOUNT + + accounts = file2dict(FUTURES_REAL_ACCOUNT) + + from qbot.engine.trade.engine_apis.futures.futures_engine import ( + FuturesTradeEngine, + ) + + btc_engine = FuturesTradeEngine( + accounts[trade_opts["platform"]], trade_opts, self.syslog + ) + btc_engine.start_trade() + if trade_opts["platform"] not in accounts: + logger.error("当前还不支持该平台, 请联系微信 Yida_Zhang2") + + elif trade_opts["trade_type"] == "BTC": + from qbot.engine.config import BTC_REAL_ACCOUNT + + accounts = file2dict(BTC_REAL_ACCOUNT) + + from qbot.engine.trade.engine_apis.btc.btc_engine import BtcTradeEngine + + btc_engine = BtcTradeEngine( + accounts[trade_opts["platform"]], trade_opts, self.syslog + ) + btc_engine.start_trade() + if trade_opts["platform"] not in accounts: + logger.error("当前还不支持该平台, 请联系微信 Yida_Zhang2") + + elif trade_opts["trade_type"] == "期权": + from qbot.engine.config import OPTIONS_REAL_ACCOUNT + + accounts = file2dict(OPTIONS_REAL_ACCOUNT) + + else: + logger.error("当前还不支持该交易标的, 请联系微信 Yida_Zhang2") + else: + self.user = user + + if not self.trade_engine: + logger.error("trade engine is null") + return + + def login(self): + self.trade_engine.login() + + def get_cash(self): + self.trade_engine.get_cash() + + def get_positions(self): + self.trade_engine.get_positions() + + def load_strategy(self): + pass + + def start_trade(self): + self.trade_engine.start_trade() + + def close(self): + self.trade_engine.close() + + +if __name__ == "__main__": + trade_opts = { + "class": "实盘", + "platform": "掘金", + "trade_type": "股票", + "trade_code": "399006.SZ", + "strategy": "单因子-相对强弱指数RSI", + } + + # 实盘交易 + sim_trade_engine = SimTradeEngine(trade_opts=trade_opts, syslog_obj=None) + sim_trade_engine.login() + sim_trade_engine.get_cash() + sim_trade_engine.get_positions() + sim_trade_engine.start_trade() + sim_trade_engine.close() + + # 虚拟交易 + trade_opts["class"] = "虚拟盘" + trade_opts["platform"] = "东方财富" + real_accounts = file2dict(STOCK_SIM_ACCOUNT) + + real_trade_engine = RealTradeEngine(trade_opts=trade_opts, syslog_obj=None) + real_trade_engine.login() + real_trade_engine.get_cash() + real_trade_engine.get_positions() + real_trade_engine.start_trade() + if trade_opts["platform"] not in sim_accounts: + logger.error("当前还不支持该平台, 请联系微信 Yida_Zhang2") diff --git a/qbot/engine/trade/trade_sim.py b/qbot/engine/trade/trade_sim.py new file mode 100644 index 00000000..5d8fa82e --- /dev/null +++ b/qbot/engine/trade/trade_sim.py @@ -0,0 +1,166 @@ +import easytrader + +from qbot.common.file_utils import file2dict +from qbot.common.logging.logger import LOGGER as logger + + +class SimTradeEngine: + def __init__(self, trade_opts: dict, syslog_obj, user=None): + if syslog_obj: + self.syslog = syslog_obj + else: + logger.error("syslog_obj is null.") + return + + self.syslog.re_print("SimTradeEngine start init ...\n") + + if trade_opts: + logger.info(f"trade_opts: {trade_opts}") + else: + logger.error("trade_opts is empty.") + return + + self.trade_opts = trade_opts + if not user: + if self.trade_opts["trade_type"] == "股票": + from qbot.engine.config import STOCK_SIM_ACCOUNT + + sim_accounts = file2dict(STOCK_SIM_ACCOUNT) + + from qbot.engine.trade.engine_apis.stocks.stock_engine import ( + StockTradeEngine, + ) + + self.trade_engine = StockTradeEngine( + account=sim_accounts[self.trade_opts["platform"]], + trade_opts=trade_opts, + syslog_obj=self.syslog, + ) + self.trade_engine.login() + + if self.trade_opts["platform"] not in sim_accounts: + logger.error("当前还不支持该平台, 请联系微信 Yida_Zhang2") + + if self.trade_opts["platform"] == "华泰证券": + self.user = easytrader.use("ht_client") + self.user.prepare( + "华泰证券", + username=sim_accounts["华泰证券"]["user"], + password=accounts["华泰证券"]["password"], + ) + elif self.trade_opts["platform"] == "通达信": + self.user = easytrader.use("tongda") + self.user.prepare( + "通达信", + username=sim_accounts["通达信"]["user"], + password=accounts["通达信"]["password"], + ) + elif self.trade_opts["platform"] == "银河证券": + self.user = easytrader.use("yinhe") + self.user.prepare( + "银河证券", + username=sim_accounts["银河证券"]["user"], + password=accounts["银河证券"]["password"], + ) + elif self.trade_opts["platform"] == "同花顺": + self.user = easytrader.use("tonghuashun") + self.user.prepare( + "同花顺", + username=sim_accounts["同花顺"]["user"], + password=accounts["同花顺"]["password"], + ) + elif self.trade_opts["platform"] == "雪球": + self.user = easytrader.use("xuqiu") + self.user.prepare( + "雪球", + username=sim_accounts["雪球"]["user"], + password=accounts["雪球"]["password"], + ) + else: + logger.error( + f"{self.trade_opts['platform']} 当前还不支持该平台, 请联系微信 Yida_Zhang2" + ) + elif self.trade_opts["trade_type"] == "基金": + from qbot.engine.config import FUNDS_SIM_ACCOUNT + + accounts = file2dict(FUNDS_SIM_ACCOUNT) + + elif self.trade_opts["trade_type"] == "期货": + from qbot.engine.config import FUTURES_SIM_ACCOUNT + + accounts = file2dict(FUTURES_SIM_ACCOUNT) + + from qbot.engine.trade.engine_apis.futures.futures_engine import ( + FuturesTradeEngine, + ) + + self.trade_engine = FuturesTradeEngine( + accounts[self.trade_opts["platform"]], trade_opts, self.syslog + ) + self.trade_engine.start_trade() + if self.trade_opts["platform"] not in accounts: + logger.error("当前还不支持该平台, 请联系微信 Yida_Zhang2") + + elif trade_opts["trade_type"] == "BTC": + from qbot.engine.config import BTC_SIM_ACCOUNT + + accounts = file2dict(BTC_SIM_ACCOUNT) + + from qbot.engine.trade.engine_apis.btc.btc_engine import BtcTradeEngine + + self.trade_engine = BtcTradeEngine( + accounts[trade_opts["platform"]], trade_opts, self.syslog + ) + self.trade_engine.start_trade() + if trade_opts["platform"] not in accounts: + logger.error("当前还不支持该平台, 请联系微信 Yida_Zhang2") + + elif self.trade_opts["trade_type"] == "期权": + from qbot.engine.config import OPTIONS_SIM_ACCOUNT + + accounts = file2dict(OPTIONS_SIM_ACCOUNT) + + else: + logger.error("当前还不支持该交易标的, 请联系微信 Yida_Zhang2") + else: + self.user = user + + if not self.trade_engine: + logger.error("trade engine is null") + return + + def login(self): + self.trade_engine.login() + + def get_cash(self): + self.trade_engine.get_cash() + + def get_positions(self): + self.trade_engine.get_positions() + + def load_strategy(self): + pass + + def start_trade(self): + self.trade_engine.start_trade() + + def close(self): + self.trade_engine.close() + + +if __name__ == "__main__": + trade_opts = { + "class": "虚拟盘", + "platform": "掘金", + "trade_type": "股票", + "trade_code": "399006.SZ", + "strategy": "单因子-相对强弱指数RSI", + } + + sim_trade_engine = SimTradeEngine(trade_opts=trade_opts, syslog_obj=None) + + # sim_trade_engine.login() + sim_trade_engine.get_cash() + sim_trade_engine.get_positions() + sim_trade_engine.start_trade() + sim_trade_engine.close() diff --git a/qbot/engine/trade/trader/.github/workflows/auto-sync.yml b/qbot/engine/trade/trader/.github/workflows/auto-sync.yml new file mode 100644 index 00000000..123e14c5 --- /dev/null +++ b/qbot/engine/trade/trader/.github/workflows/auto-sync.yml @@ -0,0 +1,22 @@ +on: + push: + branches: [master] +name: Mirror GitHub Repos to Gitee +jobs: + run: + name: Sync-GitHub-to-Gitee + runs-on: ubuntu-latest + steps: + - name: Mirror the Github repos to Gitee. + uses: Yikun/hub-mirror-action@master + with: + src: github/BigBrotherTrade + dst: gitee/timercrack + dst_key: ${{ secrets.GITEE_PRIVATE_KEY }} + dst_token: ${{ secrets.GITEE_TOKEN }} + force_update: true + src_account_type: org + dst_account_type: user + mappings: "dashboard=>dashboards" + static_list: "trader" + cache_path: /github/workspace/hub-mirror-cache diff --git a/qbot/engine/trade/trader/.gitignore b/qbot/engine/trade/trader/.gitignore new file mode 100644 index 00000000..5ecf59cf --- /dev/null +++ b/qbot/engine/trade/trader/.gitignore @@ -0,0 +1,144 @@ +# Created by .ignore support plugin (hsz.mobi) +### JetBrains template +# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm +# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 + +.idea + +# Sensitive or high-churn files: +.idea/dataSources.ids +.idea/dataSources.xml +.idea/dataSources.local.xml +.idea/sqlDataSources.xml +.idea/dynamic.xml +.idea/uiDesigner.xml + +# Gradle: +.idea/gradle.xml +.idea/libraries + +# Mongo Explorer plugin: +.idea/mongoSettings.xml + +## File-based project format: +*.iws + +## Plugin-specific files: + +# IntelliJ +/out/ + +# mpeltonen/sbt-idea plugin +.idea_modules/ + +# JIRA plugin +atlassian-ide-plugin.xml + +# Crashlytics plugin (for Android Studio and IntelliJ) +com_crashlytics_export_strings.xml +crashlytics.properties +crashlytics-build.properties +fabric.properties +### VirtualEnv template +# Virtualenv +# http://iamzed.com/2009/05/07/a-primer-on-virtualenv/ +.Python +[Bb]in +[Ii]nclude +[Ll]ib +[Ll]ib64 +[Ll]ocal +[Ss]cripts +pyvenv.cfg +.venv +pip-selfcheck.json +### Python template +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +env/ +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +*.egg-info/ +.installed.cfg +*.egg + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*,cover +.hypothesis/ +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +target/ + +# IPython Notebook +.ipynb_checkpoints + +# pyenv +.python-version + +# celery beat schedule file +celerybeat-schedule + +# dotenv +.env + +# virtualenv +venv/ +ENV/ + +# Spyder project settings +.spyderproject + +# Rope project settings +.ropeproject +/test/test_jq2.py +/test/test_jq.py diff --git a/qbot/engine/trade/trader/README.md b/qbot/engine/trade/trader/README.md new file mode 100644 index 00000000..725f4c72 --- /dev/null +++ b/qbot/engine/trade/trader/README.md @@ -0,0 +1,25 @@ +trader +====== + +操盘大哥的交易组件 + + +INSTALL +======= + +先装talib的C库,再用pip装依赖。 + +修改 mysql 配置文件 /etc/my.cnf.d/server.cnf ,增加如下配置: + + [mysqld] + + wait_timeout=31536000 + + interactive_timeout=31536000 + +重启mysql服务 + +License +------- + +``trader`` is offered under the Apache 2 license. diff --git a/qbot/engine/trade/trader/panel/__init__.py b/qbot/engine/trade/trader/panel/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/qbot/engine/trade/trader/panel/apps.py b/qbot/engine/trade/trader/panel/apps.py new file mode 100644 index 00000000..f47bfc91 --- /dev/null +++ b/qbot/engine/trade/trader/panel/apps.py @@ -0,0 +1,21 @@ +# coding=utf-8 +# +# Copyright 2016 timercrack +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +from django.apps import AppConfig + + +class PanelConfig(AppConfig): + name = 'panel' + verbose_name = "交易后台" diff --git a/qbot/engine/trade/trader/panel/const.py b/qbot/engine/trade/trader/panel/const.py new file mode 100644 index 00000000..335b1cf2 --- /dev/null +++ b/qbot/engine/trade/trader/panel/const.py @@ -0,0 +1,175 @@ +# coding=utf-8 +# +# Copyright 2016 timercrack +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +from djchoices import DjangoChoices, C + + +class ContractType(DjangoChoices): + STOCK = C(label='股票') + FUTURE = C(label='期货') + OPTION = C(label='期权') + + +class ExchangeType(DjangoChoices): + SHFE = C(value='SHFE', label='上期所') + DCE = C(value='DCE', label='大商所') + CZCE = C(value='CZCE', label='郑商所') + CFFEX = C(value='CFFEX', label='中金所') + INE = C(value='INE', label='上期能源') + GFEX = C(value='GFEX', label='广交所') + + +class SectionType(DjangoChoices): + Stock = C(label='股票') + Bond = C(label='债券') + Metal = C(label='基本金属') + Agricultural = C(label='农产品') + EnergyChemical = C(label='能源化工') + BlackMaterial = C(label='黑色建材') + + +class SortType(DjangoChoices): + Stock = C(label='股票') + Bond = C(label='债券') + Rare = C(label='贵金属') + Metal = C(label='基本金属') + EdibleOil = C(label='食用油') + Feed = C(label='动物饲料') + Cotton = C(label='棉') + EnergyChemical = C(label='能源化工') + BlackMaterial = C(label='黑色建材') + + +class AddressType(DjangoChoices): + TRADE = C(label='交易') + MARKET = C(label='行情') + + +class OperatorType(DjangoChoices): + TELECOM = C(label='电信') + UNICOM = C(label='联通') + + +class DirectionType(DjangoChoices): + LONG = C(label='多', value=b'0'[0]) + SHORT = C(label='空', value=b'1'[0]) + + +class CombOffsetFlag(DjangoChoices): # 订单开平标志 + Open = C(label='开', value='0') + Close = C(label='平', value='1') + ForceClose = C(label='强平', value='2') + CloseToday = C(label='平', value='3') + CloseYesterday = C(label='平昨', value='4') + ForceOff = C(label='强减', value='5') + LocalForceClose = C(label='本地强平', value='6') + + +class OffsetFlag(DjangoChoices): # 开平标志 + Open = C(label='开', value=b'0'[0]) + Close = C(label='平', value=b'1'[0]) + ForceClose = C(label='强平', value=b'2'[0]) + CloseToday = C(label='平今', value=b'3'[0]) + CloseYesterday = C(label='平昨', value=b'4'[0]) + ForceOff = C(label='强减', value=b'5'[0]) + LocalForceClose = C(label='本地强平', value=b'6'[0]) + + +class OrderStatus(DjangoChoices): # 报单状态 + AllTraded = C(value=b'0'[0], label='全部成交') + PartTradedQueueing = C(value=b'1'[0], label='部分成交还在队列中') + PartTradedNotQueueing = C(value=b'2'[0], label='部分成交不在队列中') + NoTradeQueueing = C(value=b'3'[0], label='未成交还在队列中') + NoTradeNotQueueing = C(value=b'4'[0], label='未成交不在队列中') + Canceled = C(value=b'5'[0], label='撤单') + Unknown = C(value=b'a'[0], label='未知') + NotTouched = C(value=b'b'[0], label='尚未触发') + Touched = C(value=b'c'[0], label='已触发') + + +class OrderSubmitStatus(DjangoChoices): # 报单提交状态 + InsertSubmitted = C(value=b'0'[0], label='已经提交') + CancelSubmitted = C(value=b'1'[0], label='撤单已经提交') + ModifySubmitted = C(value=b'2'[0], label='修改已经提交') + Accepted = C(value=b'3'[0], label='已经接受') + InsertRejected = C(value=b'4'[0], label='报单已经被拒绝') + CancelRejected = C(value=b'5'[0], label='撤单已经被拒绝') + ModifyRejected = C(value=b'6'[0], label='改单已经被拒绝') + + +DCE_NAME_CODE = { + '豆一': 'a', + '豆二': 'b', + '胶合板': 'bb', + '玉米': 'c', + '玉米淀粉': 'cs', + '纤维板': 'fb', + '铁矿石': 'i', + '焦炭': 'j', + '鸡蛋': 'jd', + '焦煤': 'jm', + '聚乙烯': 'l', + '豆粕': 'm', + '棕榈油': 'p', + '聚丙烯': 'pp', + '聚氯乙烯': 'v', + '苯乙烯': 'eb', + '乙二醇': 'eg', + '液化石油气': 'pg', + '生猪': 'lh', + '粳米': 'rr', + '豆油': 'y', +} + +MONTH_CODE = { + 1: "F", + 2: "G", + 3: "H", + 4: "J", + 5: "K", + 6: "M", + 7: "N", + 8: "Q", + 9: "U", + 10: "V", + 11: "X", + 12: "Z" +} + + +KT_MARKET = { + 'DL': 'DCE', + 'DY': 'DCE', + 'SQ': 'SHFE', + 'SY': 'SHFE', + 'ZJ': 'CFFEX', + 'ZZ': 'CZCE', + 'ZY': 'CZCE', +} + + +class SignalType(DjangoChoices): + ROLL_CLOSE = C(label='换月平旧') + ROLL_OPEN = C(label='换月开新') + BUY = C(label='买开') + SELL_SHORT = C(label='卖开') + SELL = C(label='卖平') + BUY_COVER = C(label='买平') + + +class PriorityType(DjangoChoices): + LOW = C(label='低', value=0) + Normal = C(label='普通', value=1) + High = C(label='高', value=2) diff --git a/qbot/engine/trade/trader/panel/models.py b/qbot/engine/trade/trader/panel/models.py new file mode 100644 index 00000000..157475d0 --- /dev/null +++ b/qbot/engine/trade/trader/panel/models.py @@ -0,0 +1,288 @@ +# coding=utf-8 +# +# Copyright 2016 timercrack +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +import pandas as pd +from pandas.io.sql import read_sql_query +from django.db import models +from django.db import connection +from django.core.exceptions import EmptyResultSet + +from .const import * + + +def to_df(queryset, index_col=None, parse_dates=None): + """ + :param queryset: django.db.models.query.QuerySet + :param index_col: str or list of str, optional, default: None + :param parse_dates: list or dict, default: None + :return: pandas.core.frame.DataFrame + """ + try: + query, params = queryset.query.sql_with_params() + except EmptyResultSet: + # Occurs when Django tries to create an expression for a + # query which will certainly be empty + # e.g. Book.objects.filter(author__in=[]) + return pd.DataFrame() + return read_sql_query(query, connection, params=params, index_col=index_col, parse_dates=parse_dates) + + +class Autonumber(models.Model): + id = models.AutoField(verbose_name='自增值', primary_key=True) + create_date = models.DateTimeField(verbose_name='生成时间', auto_now_add=True) + + +class Address(models.Model): + name = models.CharField(verbose_name='名称', max_length=64) + url = models.CharField(verbose_name='地址', max_length=128) + type = models.CharField(verbose_name='类型', max_length=16, choices=AddressType.choices) + operator = models.CharField(verbose_name='运营商', max_length=16, choices=OperatorType.choices) + + class Meta: + verbose_name = '前置地址' + verbose_name_plural = '前置地址列表' + + def __str__(self): + return '{}{}-{}'.format(self.name, self.get_operator_display(), self.get_type_display()) + + +class Broker(models.Model): + name = models.CharField(verbose_name='名称', max_length=64) + contract_type = models.CharField(verbose_name='市场', max_length=32, choices=ContractType.choices) + trade_address = models.ForeignKey(Address, verbose_name='交易前置', on_delete=models.CASCADE, + related_name='trade_address') + market_address = models.ForeignKey(Address, verbose_name='行情前置', on_delete=models.CASCADE, + related_name='market_address') + identify = models.CharField(verbose_name='唯一标志', max_length=32) + username = models.CharField(verbose_name='用户名', max_length=32) + password = models.CharField(verbose_name='密码', max_length=32) + fake = models.DecimalField(verbose_name='虚拟资金', null=True, max_digits=12, decimal_places=2) + cash = models.DecimalField(verbose_name='可用资金', null=True, max_digits=12, decimal_places=2) + current = models.DecimalField(verbose_name='动态权益', null=True, max_digits=12, decimal_places=2) + pre_balance = models.DecimalField(verbose_name='静态权益', null=True, max_digits=12, decimal_places=2) + margin = models.DecimalField(verbose_name='保证金', null=True, max_digits=12, decimal_places=2) + + class Meta: + verbose_name = '账户' + verbose_name_plural = '账户列表' + + def __str__(self): + return '{}-{}'.format(self.name, self.get_contract_type_display()) + + +class Performance(models.Model): + broker = models.ForeignKey(Broker, verbose_name='账户', on_delete=models.CASCADE) + day = models.DateField(verbose_name='日期') + capital = models.DecimalField(verbose_name='资金', max_digits=12, decimal_places=2) + unit_count = models.IntegerField(verbose_name='单位乘数', null=True) + NAV = models.DecimalField(verbose_name='单位净值', max_digits=8, decimal_places=3, null=True) + accumulated = models.DecimalField(verbose_name='累计净值', max_digits=8, decimal_places=3, null=True) + dividend = models.DecimalField(verbose_name='分红', max_digits=12, decimal_places=2, null=True) + used_margin = models.DecimalField(verbose_name='占用保证金', null=True, max_digits=12, decimal_places=2) + fake = models.DecimalField(verbose_name='虚拟', max_digits=12, decimal_places=2, null=True) + + class Meta: + verbose_name = '绩效' + verbose_name_plural = '绩效列表' + + def __str__(self): + return '{}-{}'.format(self.broker, self.NAV) + + +class Strategy(models.Model): + broker = models.ForeignKey(Broker, verbose_name='账户', on_delete=models.CASCADE) + name = models.CharField(verbose_name='名称', max_length=64) + instruments = models.ManyToManyField('Instrument', verbose_name='交易品种') + force_opens = models.ManyToManyField('Instrument', verbose_name='手动开仓', related_name='force_opens', blank=True) + + class Meta: + verbose_name = '策略' + verbose_name_plural = '策略列表' + + def __str__(self): + return '{}'.format(self.name) + + def get_instruments(self): + return [inst for inst in self.instruments.all()] + get_instruments.short_description = '交易合约' + get_instruments.allow_tags = True + + def get_force_opens(self): + return [inst for inst in self.force_opens.all()] + get_force_opens.short_description = '手动开仓' + get_force_opens.allow_tags = True + + +class Param(models.Model): + strategy = models.ForeignKey(Strategy, verbose_name='策略', on_delete=models.CASCADE) + code = models.CharField('参数名', max_length=64) + str_value = models.CharField('字符串值', max_length=128, null=True, blank=True) + int_value = models.IntegerField('整数值', null=True, blank=True) + float_value = models.DecimalField('浮点值', null=True, max_digits=12, decimal_places=3, blank=True) + update_time = models.DateTimeField('更新时间', auto_now=True) + + class Meta: + verbose_name = '策略参数' + verbose_name_plural = '策略参数列表' + + def __str__(self): + return '{}: {} = {}'.format( + self.strategy, self.code, + next((v for v in [self.str_value, self.int_value, self.float_value] if v is not None), '-')) + + +class Instrument(models.Model): + exchange = models.CharField('交易所', max_length=8, choices=ExchangeType.choices) + section = models.CharField('分类', max_length=48, null=True, blank=True, choices=SectionType.choices) + sort = models.CharField('品种', max_length=48, null=True, blank=True, choices=SortType.choices) + name = models.CharField('名称', max_length=32, null=True, blank=True) + product_code = models.CharField('代码', max_length=16, unique=True) + all_inst = models.CharField('品种列表', max_length=256, null=True, blank=True) + main_code = models.CharField('主力合约', max_length=16, null=True, blank=True) + last_main = models.CharField('上个主力', max_length=16, null=True, blank=True) + change_time = models.DateTimeField('切换时间', null=True, blank=True) + night_trade = models.BooleanField('夜盘', default=False) + volume_multiple = models.IntegerField('合约乘数', null=True, blank=True) + price_tick = models.DecimalField('最小变动', max_digits=8, decimal_places=3, null=True, blank=True) + margin_rate = models.DecimalField('保证金率', max_digits=6, decimal_places=5, null=True, blank=True) + fee_money = models.DecimalField('金额手续费', max_digits=7, decimal_places=6, null=True, blank=True) + fee_volume = models.DecimalField('手数手续费', max_digits=6, decimal_places=2, null=True, blank=True) + up_limit_ratio = models.DecimalField('涨停幅度', max_digits=3, decimal_places=2, null=True, blank=True) + down_limit_ratio = models.DecimalField('跌停幅度', max_digits=3, decimal_places=2, null=True, blank=True) + + class Meta: + verbose_name = '合约' + verbose_name_plural = '合约列表' + + def __str__(self): + return '{}.{}'.format(self.get_exchange_display(), self.name) + + +class Signal(models.Model): + strategy = models.ForeignKey(Strategy, verbose_name='策略', on_delete=models.CASCADE) + instrument = models.ForeignKey(Instrument, verbose_name='品种', on_delete=models.CASCADE) + code = models.CharField('当前合约', max_length=16, null=True) + type = models.CharField('信号类型', max_length=16, choices=SignalType.choices) + trigger_value = models.DecimalField(max_digits=12, decimal_places=3, verbose_name='触发值', null=True, blank=True) + price = models.DecimalField('价格', max_digits=12, decimal_places=3, null=True, blank=True) + volume = models.IntegerField('数量', null=True, blank=True) + trigger_time = models.DateTimeField('发生时间') + priority = models.IntegerField('优先级', choices=PriorityType.choices, default=PriorityType.Normal) + processed = models.BooleanField('已处理', default=False, blank=True) + + class Meta: + verbose_name = '信号' + verbose_name_plural = '信号列表' + + def __str__(self): + return f"{self.instrument}({self.code}){self.type}{self.volume}手" \ + f"{'(夜)' if self.instrument.night_trade else ''}" + + +class MainBar(models.Model): + exchange = models.CharField('交易所', max_length=8, choices=ExchangeType.choices) + product_code = models.CharField('品种代码', max_length=8, null=True, db_index=True) + code = models.CharField('合约代码', max_length=16, null=True, blank=True) + time = models.DateField('时间', db_index=True) + open = models.DecimalField(max_digits=12, decimal_places=3, verbose_name='开盘价') + high = models.DecimalField(max_digits=12, decimal_places=3, verbose_name='最高价') + low = models.DecimalField(max_digits=12, decimal_places=3, verbose_name='最低价') + close = models.DecimalField(max_digits=12, decimal_places=3, verbose_name='收盘价') + settlement = models.DecimalField(max_digits=12, decimal_places=3, verbose_name='结算价', null=True) + volume = models.IntegerField('成交量') + open_interest = models.DecimalField(max_digits=12, decimal_places=3, verbose_name='持仓量') + basis = models.DecimalField(max_digits=12, decimal_places=3, verbose_name='基差', null=True) + + class Meta: + verbose_name = '主力连续日K线' + verbose_name_plural = '主力连续日K线列表' + + def __str__(self): + return '{}.{}'.format(self.exchange, self.product_code) + + +class DailyBar(models.Model): + exchange = models.CharField('交易所', max_length=8, choices=ExchangeType.choices) + code = models.CharField('品种代码', max_length=16, null=True, db_index=True) + expire_date = models.IntegerField('交割时间', null=True) + time = models.DateField('时间', db_index=True) + open = models.DecimalField(max_digits=12, decimal_places=3, verbose_name='开盘价') + high = models.DecimalField(max_digits=12, decimal_places=3, verbose_name='最高价') + low = models.DecimalField(max_digits=12, decimal_places=3, verbose_name='最低价') + close = models.DecimalField(max_digits=12, decimal_places=3, verbose_name='收盘价') + settlement = models.DecimalField(max_digits=12, decimal_places=3, verbose_name='结算价', null=True) + volume = models.IntegerField('成交量') + open_interest = models.DecimalField(max_digits=12, decimal_places=3, verbose_name='持仓量') + + class Meta: + verbose_name = '日K线' + verbose_name_plural = '日K线列表' + + def __str__(self): + return '{}.{}'.format(self.exchange, self.code) + + +class Order(models.Model): + broker = models.ForeignKey(Broker, verbose_name='账户', on_delete=models.CASCADE) + strategy = models.ForeignKey(Strategy, verbose_name='策略', on_delete=models.SET_NULL, null=True, blank=True) + order_ref = models.CharField('报单号', max_length=13) + instrument = models.ForeignKey(Instrument, verbose_name='品种', on_delete=models.CASCADE) + code = models.CharField('合约代码', max_length=16, null=True, blank=True) + front = models.IntegerField('前置编号') + session = models.IntegerField('会话编号') + price = models.DecimalField(max_digits=12, decimal_places=3, verbose_name='报单价格') + volume = models.IntegerField('手数', blank=True, null=True) + direction = models.CharField('方向', max_length=8, choices=DirectionType.choices) + offset_flag = models.CharField('开平', max_length=8, choices=OffsetFlag.choices) + status = models.CharField('状态', max_length=16, choices=OrderStatus.choices) + send_time = models.DateTimeField('发送时间') + update_time = models.DateTimeField('更新时间') + signal = models.OneToOneField(Signal, verbose_name='信号', on_delete=models.SET_NULL, null=True, blank=True) + + class Meta: + verbose_name = '报单' + verbose_name_plural = '报单列表' + + def __str__(self): + return '{}-{}'.format(self.instrument, self.get_offset_flag_display()) + + +class Trade(models.Model): + broker = models.ForeignKey(Broker, verbose_name='账户', on_delete=models.CASCADE) + strategy = models.ForeignKey(Strategy, verbose_name='策略', on_delete=models.SET_NULL, null=True, blank=True) + instrument = models.ForeignKey(Instrument, verbose_name='品种', on_delete=models.CASCADE) + open_order = models.OneToOneField(Order, verbose_name='开仓报单', on_delete=models.SET_NULL, + related_name='open_order', null=True, blank=True) + close_order = models.OneToOneField(Order, verbose_name='平仓报单', on_delete=models.SET_NULL, + related_name='close_order', null=True, blank=True) + code = models.CharField('合约代码', max_length=16, null=True, blank=True) + direction = models.CharField('方向', max_length=8, choices=DirectionType.choices) + open_time = models.DateTimeField('开仓日期') + close_time = models.DateTimeField('平仓日期', null=True, blank=True) + shares = models.IntegerField('手数', null=True, blank=True) + filled_shares = models.IntegerField('已成交手数', null=True, blank=True) + closed_shares = models.IntegerField('已平仓手数', null=True, blank=True) + avg_entry_price = models.DecimalField(max_digits=12, decimal_places=3, verbose_name='持仓均价', null=True, blank=True) + avg_exit_price = models.DecimalField(max_digits=12, decimal_places=3, verbose_name='平仓均价', null=True, blank=True) + profit = models.DecimalField(max_digits=12, decimal_places=3, verbose_name='持仓盈亏', null=True, blank=True) + frozen_margin = models.DecimalField(max_digits=12, decimal_places=3, verbose_name='冻结保证金', null=True, blank=True) + cost = models.DecimalField(max_digits=12, decimal_places=2, verbose_name='手续费', null=True, blank=True) + + class Meta: + verbose_name = '交易记录' + verbose_name_plural = '交易记录列表' + + def __str__(self): + return '{}{}{}手'.format(self.instrument, self.direction, self.shares) diff --git a/qbot/engine/trade/trader/requirements.txt b/qbot/engine/trade/trader/requirements.txt new file mode 100644 index 00000000..1cc8ef10 --- /dev/null +++ b/qbot/engine/trade/trader/requirements.txt @@ -0,0 +1,20 @@ +aiohttp[speedups] +aioredis[hiredis] +redis +ujson +appdirs +django +beautifulsoup4 +lxml +requests +numpy +pandas +TA-Lib +croniter +asynctest +django-redis +django-choices +mysqlclient +tqdm +pytz +tzdata diff --git a/qbot/engine/trade/trader/test/__init__.py b/qbot/engine/trade/trader/test/__init__.py new file mode 100644 index 00000000..b981f96d --- /dev/null +++ b/qbot/engine/trade/trader/test/__init__.py @@ -0,0 +1,15 @@ +#!/usr/bin/env python +# +# Copyright 2016 timercrack +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. diff --git a/qbot/engine/trade/trader/test/test.py b/qbot/engine/trade/trader/test/test.py new file mode 100644 index 00000000..f12f6849 --- /dev/null +++ b/qbot/engine/trade/trader/test/test.py @@ -0,0 +1,44 @@ +import aioredis +import asyncio + + +async def reader(message): + print(f"in reader: {message}, type={type(message)}") + + +async def monitor1(pb: aioredis.client.PubSub): + async for msg in pb.listen(): + print(f"in monitor1: {msg}, type={type(msg)}") + asyncio.create_task(reader(msg)) + if msg['type'] == 'punsubscribe': + print('quit monitor1') + break + + +async def main(): + redis = await aioredis.from_url("redis://192.168.123.142", decode_responses=True) + pubsub1 = redis.pubsub() + pubsub2 = redis.pubsub() + await pubsub1.psubscribe('channel:*') + await pubsub2.psubscribe('channel*') + await redis.publish("channel:1", "1") + await redis.publish("channel:2", "6") + await redis.publish("channel:3", "3") + await pubsub1.punsubscribe() + await pubsub2.punsubscribe() + loop = asyncio.get_running_loop() + asyncio.run_coroutine_threadsafe(monitor1(pubsub1), loop) + asyncio.run_coroutine_threadsafe(monitor1(pubsub2), loop) + # await asyncio.gather(monitor1(pubsub1), monitor1(pubsub2)) + # await pubsub2.run() + print('main done!') + +if __name__ == "__main__": + try: + loop = asyncio.new_event_loop() + asyncio.set_event_loop(loop) + loop.create_task(main()) + loop.run_forever() + except KeyboardInterrupt: + pass + diff --git a/qbot/engine/trade/trader/test/test_api.py b/qbot/engine/trade/trader/test/test_api.py new file mode 100644 index 00000000..382a0f59 --- /dev/null +++ b/qbot/engine/trade/trader/test/test_api.py @@ -0,0 +1,94 @@ +#!/usr/bin/env python +# +# Copyright 2016 timercrack +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +import sys +import os +import django +if sys.platform == 'darwin': + sys.path.append('/Users/jeffchen/Documents/gitdir/dashboard') +elif sys.platform == 'win32': + sys.path.append(r'D:\GitHub\dashboard') +else: + sys.path.append('/root/dashboard') +os.environ["DJANGO_SETTINGS_MODULE"] = "dashboard.settings" +os.environ["DJANGO_ALLOW_ASYNC_UNSAFE"] = "true" +django.setup() +import asynctest +from trader.utils import * +from datetime import datetime +from trader.utils.read_config import config + + +class APITest(asynctest.TestCase): + def setUp(self): + self.redis_client = redis.StrictRedis( + host=config.get('REDIS', 'host', fallback='localhost'), + db=config.getint('REDIS', 'db', fallback=1), decode_responses=True) + self.trading_day = datetime.strptime(self.redis_client.get("LastTradingDay"), '%Y%m%d') + + def tearDown(self) -> None: + self.redis_client.close() + + @asynctest.skipIf(True, 'no need') + async def test_get_shfe_data(self): + self.assertTrue(await update_from_shfe(self.trading_day)) + + @asynctest.skipIf(True, 'no need') + async def test_get_dce_data(self): + self.assertTrue(await update_from_dce(self.trading_day)) + + @asynctest.skipIf(True, 'no need') + async def test_get_czce_data(self): + self.assertTrue(await update_from_czce(self.trading_day)) + + @asynctest.skipIf(True, 'no need') + async def test_get_cffex_data(self): + self.assertTrue(await update_from_cffex(self.trading_day)) + + @asynctest.skipIf(True, 'no need') + async def test_get_contracts_argument(self): + self.assertTrue(await get_contracts_argument(self.trading_day)) + + @asynctest.skipIf(True, 'no need') + async def test_get_all(self): + print(f'tradingday: {self.trading_day}') + tasks = [ + update_from_shfe(self.trading_day), + update_from_dce(self.trading_day), + update_from_czce(self.trading_day), + update_from_cffex(self.trading_day), + get_contracts_argument(self.trading_day) + ] + result = await asyncio.gather(*tasks, return_exceptions=True) + self.assertEqual(result, [True, True, True, True, True]) + + @asynctest.skipIf(False, 'no need') + async def test_load_from_kt(self): + self.assertTrue(load_kt_data(r'D:\test')) + + @asynctest.skipIf(True, 'no need') + async def test_create_main(self): + inst = Instrument.objects.get(product_code='eb') + self.assertTrue(create_main(inst)) + + @asynctest.skipIf(True, 'no need') + async def test_calc_profit(self): + for trade in Trade.objects.filter(close_time__isnull=True): + bar = DailyBar.objects.filter(code=trade.code).order_by('-time').first() + trade.profit = (bar.close - trade.avg_entry_price) * trade.filled_shares * trade.instrument.volume_multiple + if trade.direction == DirectionType.values[DirectionType.SHORT]: + trade.profit *= -1 + trade.save(update_fields=['profit']) + self.assertTrue(True) diff --git a/qbot/engine/trade/trader/trader/__init__.py b/qbot/engine/trade/trader/trader/__init__.py new file mode 100644 index 00000000..853b6855 --- /dev/null +++ b/qbot/engine/trade/trader/trader/__init__.py @@ -0,0 +1,26 @@ +# coding=utf-8 +# +# Copyright 2016 timercrack +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +# version is a human-readable version number. + +# version_info is a four-tuple for programmatic comparison. The first +# three numbers are the components of the version number. The fourth +# is zero for an official release, positive for a development branch, +# or negative for a release candidate or beta (after the base version +# number has been incremented) + +version = "0.1" +version_info = (0, 1, 0, 0) diff --git a/qbot/engine/trade/trader/trader/main.py b/qbot/engine/trade/trader/trader/main.py new file mode 100644 index 00000000..0a3f8111 --- /dev/null +++ b/qbot/engine/trade/trader/trader/main.py @@ -0,0 +1,83 @@ +# coding=utf-8 +# +# Copyright 2016 timercrack +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +import sys +import os +import django +if sys.platform == 'darwin': + sys.path.append('/Users/jeffchen/Documents/gitdir/dashboard') +elif sys.platform == 'win32': + sys.path.append(r'D:\github\dashboard') +else: + sys.path.append('/root/gitee/dashboard') +os.environ["DJANGO_SETTINGS_MODULE"] = "dashboard.settings" +os.environ["DJANGO_ALLOW_ASYNC_UNSAFE"] = "true" +django.setup() +import redis +import logging +from logging import handlers +from trader.strategy.brother2 import TradeStrategy +from trader.utils.read_config import config_file, app_dir, config + + +class RedislHandler(logging.StreamHandler): + def __init__(self, channel: str): + super().__init__() + self.redis_client = redis.StrictRedis( + host=config.get('REDIS', 'host', fallback='localhost'), port=config.getint('REDIS', 'port', fallback=6379), + db=config.getint('REDIS', 'db', fallback=0), decode_responses=True) + self.channel = channel + + def emit(self, message: logging.LogRecord): + content = str(message.msg) + self.redis_client.publish(self.channel, content) + + +if __name__ == '__main__': + os.path.exists(app_dir.user_log_dir) or os.makedirs(app_dir.user_log_dir) + log_file = os.path.join(app_dir.user_log_dir, 'trader.log') + + file_handler = handlers.RotatingFileHandler(log_file, encoding='utf-8', maxBytes=1024*1024, backupCount=1) + general_formatter = logging.Formatter(config.get('LOG', 'format')) + file_handler.setFormatter(general_formatter) + file_handler.setLevel(config.get('LOG', 'file_level', fallback='DEBUG')) + + console_handler = logging.StreamHandler() + console_handler.setFormatter(general_formatter) + console_handler.setLevel('DEBUG') + + redis_handler = RedislHandler(config.get('MSG_CHANNEL', 'weixin_log')) + redis_handler.setFormatter(config.get('LOG', 'weixin_format')) + redis_handler.setLevel(config.get('LOG', 'flower_level', fallback='INFO')) + + logger = logging.getLogger() + logger.setLevel('DEBUG') + logger.addHandler(file_handler) + logger.addHandler(console_handler) + logger.addHandler(redis_handler) + logger = logging.getLogger("main") + + pid_path = os.path.join(app_dir.user_cache_dir, 'trader.pid') + if not os.path.exists(pid_path): + if not os.path.exists(app_dir.user_cache_dir): + os.makedirs(app_dir.user_cache_dir) + with open(pid_path, 'w') as pid_file: + pid_file.write(str(os.getpid())) + print('Big Brother is watching you!') + print('used config file:', config_file) + print('log stored in:', app_dir.user_log_dir) + print('pid file:', pid_path) + TradeStrategy(name='大哥2.2').run() diff --git a/qbot/engine/trade/trader/trader/strategy/__init__.py b/qbot/engine/trade/trader/trader/strategy/__init__.py new file mode 100644 index 00000000..1e8788f0 --- /dev/null +++ b/qbot/engine/trade/trader/trader/strategy/__init__.py @@ -0,0 +1,139 @@ +# coding=utf-8 +# +# Copyright 2016 timercrack +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +import redis +import ujson as json + +import pytz +import time +import datetime +import logging +from collections import defaultdict +from django.utils import timezone +from croniter import croniter +import asyncio +from abc import abstractmethod, ABCMeta +import aioredis + +from trader.utils.func_container import CallbackFunctionContainer +from trader.utils.read_config import config + +logger = logging.getLogger('BaseModule') + + +class BaseModule(CallbackFunctionContainer, metaclass=ABCMeta): + def __init__(self): + super().__init__() + self.io_loop = asyncio.new_event_loop() + asyncio.set_event_loop(self.io_loop) + self.redis_client = aioredis.from_url( + f"redis://{config.get('REDIS', 'host', fallback='localhost')}:" + f"{config.getint('REDIS', 'port', fallback=6379)}/{config.getint('REDIS', 'db', fallback=0)}", + decode_responses=True) + self.raw_redis = redis.StrictRedis(host=config.get('REDIS', 'host', fallback='localhost'), + port=config.getint('REDIS', 'port', fallback=6379), + db=config.getint('REDIS', 'db', fallback=0), decode_responses=True) + self.sub_client = self.redis_client.pubsub() + self.initialized = False + self.sub_tasks = list() + self.sub_channels = list() + self.channel_router = dict() + self.crontab_router = defaultdict(dict) + self.datetime = None + self.time = None + self.loop_time = None + + def _register_callback(self): + self.datetime = timezone.localtime() + self.time = time.time() + self.loop_time = self.io_loop.time() + for fun_name, args in self.callback_fun_args.items(): + if 'crontab' in args: + key = args['crontab'] + self.crontab_router[key]['func'] = getattr(self, fun_name) + self.crontab_router[key]['iter'] = croniter(args['crontab'], self.datetime) + self.crontab_router[key]['handle'] = None + elif 'channel' in args: + self.channel_router[args['channel']] = getattr(self, fun_name) + + def _get_next(self, key): + return self.loop_time + (self.crontab_router[key]['iter'].get_next() - self.time) + + def _call_next(self, key): + if self.crontab_router[key]['handle'] is not None: + self.crontab_router[key]['handle'].cancel() + self.crontab_router[key]['handle'] = self.io_loop.call_at(self._get_next(key), self._call_next, key) + self.io_loop.create_task(self.crontab_router[key]['func']()) + + async def install(self): + try: + self._register_callback() + await self.sub_client.psubscribe(*self.channel_router.keys()) + asyncio.run_coroutine_threadsafe(self._msg_reader(), self.io_loop) + # self.io_loop.create_task(self._msg_reader()) + for key, cron_dict in self.crontab_router.items(): + if cron_dict['handle'] is not None: + cron_dict['handle'].cancel() + cron_dict['handle'] = self.io_loop.call_at(self._get_next(key), self._call_next, key) + self.initialized = True + logger.debug('%s plugin installed', type(self).__name__) + except Exception as e: + logger.error('%s plugin install failed: %s', type(self).__name__, repr(e), exc_info=True) + + async def uninstall(self): + try: + await self.sub_client.punsubscribe() + # await asyncio.wait(self.sub_tasks, loop=self.io_loop) + self.sub_tasks.clear() + await self.sub_client.close() + for key, cron_dict in self.crontab_router.items(): + if self.crontab_router[key]['handle'] is not None: + self.crontab_router[key]['handle'].cancel() + self.crontab_router[key]['handle'] = None + self.initialized = False + logger.debug('%s plugin uninstalled', type(self).__name__) + except Exception as e: + logger.error('%s plugin uninstall failed: %s', type(self).__name__, repr(e), exc_info=True) + + async def _msg_reader(self): + # {'type': 'pmessage', 'pattern': 'channel:*', 'channel': 'channel:1', 'data': 'Hello'} + async for msg in self.sub_client.listen(): + if msg['type'] == 'pmessage': + channel = msg['channel'] + pattern = msg['pattern'] + data = json.loads(msg['data']) + # logger.debug("%s channel[%s] Got Message:%s", type(self).__name__, channel, msg) + self.io_loop.create_task(self.channel_router[pattern](channel, data)) + elif msg['type'] == 'punsubscribe': + break + logger.debug('%s quit _msg_reader!', type(self).__name__) + + async def start(self): + await self.install() + + async def stop(self): + await self.uninstall() + + def run(self): + try: + self.io_loop.create_task(self.start()) + self.io_loop.run_forever() + except KeyboardInterrupt: + self.io_loop.run_until_complete(self.stop()) + except Exception as ee: + logger.error('发生错误: %s', repr(ee), exc_info=True) + self.io_loop.run_until_complete(self.stop()) + finally: + logger.debug('程序已退出') diff --git a/qbot/engine/trade/trader/trader/strategy/brother2.py b/qbot/engine/trade/trader/trader/strategy/brother2.py new file mode 100644 index 00000000..2f0b7b8e --- /dev/null +++ b/qbot/engine/trade/trader/trader/strategy/brother2.py @@ -0,0 +1,865 @@ +# coding=utf-8 +# +# Copyright 2016 timercrack +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +import asyncio +import re +from collections import defaultdict +import datetime +from decimal import Decimal +import logging +from django.db.models import Q, F, Sum +from django.utils import timezone +from talib import ATR +import ujson as json +import aioredis +from trader.strategy import BaseModule +from trader.utils.func_container import RegisterCallback +from trader.utils.read_config import config, ctp_errors +from trader.utils import ApiStruct, price_round, is_trading_day, update_from_shfe, update_from_dce, update_from_czce, update_from_cffex, \ + get_contracts_argument, calc_main_inst, str_to_number, get_next_id, ORDER_REF_SIGNAL_ID_START, update_from_gfex +from panel.models import * + +logger = logging.getLogger('CTPApi') +HANDLER_TIME_OUT = config.getint('TRADE', 'command_timeout', fallback=10) + + +class TradeStrategy(BaseModule): + def __init__(self, name: str): + super().__init__() + self.__market_response_format = config.get('MSG_CHANNEL', 'market_response_format') + self.__trade_response_format = config.get('MSG_CHANNEL', 'trade_response_format') + self.__request_format = config.get('MSG_CHANNEL', 'request_format') + self.__ignore_inst_list = config.get('TRADE', 'ignore_inst', fallback="WH,bb,JR,RI,RS,LR,PM,im").split(',') + self.__strategy = Strategy.objects.get(name=name) + self.__inst_ids = self.__strategy.instruments.all().values_list('product_code', flat=True) + self.__broker = self.__strategy.broker + self.__fake = self.__broker.fake # 虚拟资金 + self.__current = self.__broker.current # 当前动态权益 + self.__pre_balance = self.__broker.pre_balance # 静态权益 + self.__cash = self.__broker.cash # 可用资金 + self.__shares = dict() # { instrument : position } + self.__cur_account = None + self.__margin = self.__broker.margin # 占用保证金 + self.__withdraw = 0 # 出金 + self.__deposit = 0 # 入金 + self.__activeOrders = dict() # 未成交委托单 + self.__cur_pos = dict() # 持有头寸 + self.__re_extract_code = re.compile(r'([a-zA-Z]*)(\d+)') # 提合约字母部分 IF1509 -> IF + self.__re_extract_name = re.compile('(.*?)([0-9]+)(.*?)$') # 提取合约文字部分 + self.__trading_day = timezone.make_aware(datetime.datetime.strptime(self.raw_redis.get("TradingDay")+'08', '%Y%m%d%H')) + self.__last_trading_day = timezone.make_aware(datetime.datetime.strptime(self.raw_redis.get("LastTradingDay")+'08', '%Y%m%d%H')) + + async def start(self): + await self.install() + self.raw_redis.set('HEARTBEAT:TRADER', 1, ex=61) + today = timezone.localtime() + now = int(today.strftime('%H%M')) + if today.isoweekday() < 6 and (820 <= now <= 1550 or 2010 <= now <= 2359): # 非交易时间查不到数据 + await self.refresh_account() + order_list = await self.query('Order') + for order in order_list: + # 未成交订单 + if int(order['OrderStatus']) in range(1, 5) and order['OrderSubmitStatus'] == ApiStruct.OSS_Accepted: + direct_str = DirectionType.values[order['Direction']] + logger.info(f"撤销未成交订单: 合约{order['InstrumentID']} {direct_str}单 {order['VolumeTotal']}手 价格{order['LimitPrice']}") + await self.cancel_order(order) + # 已成交订单 + elif order['OrderSubmitStatus'] == ApiStruct.OSS_Accepted: + self.save_order(order) + await self.refresh_position() + # today = timezone.make_aware(datetime.datetime.strptime(self.raw_redis.get('LastTradingDay'), '%Y%m%d')) + # self.calculate(today, create_main_bar=False) + # await self.processing_signal3() + + async def refresh_account(self): + try: + logger.debug('更新账户') + account = await self.query('TradingAccount') + account = account[0] + self.__withdraw = Decimal(account['Withdraw']) + self.__deposit = Decimal(account['Deposit']) + # 虚拟=虚拟(原始)-入金+出金 + fake = self.__fake - self.__deposit + self.__withdraw + if fake < 1: + fake = 0 + # 静态权益=上日结算+入金金额-出金金额 + self.__pre_balance = Decimal(account['PreBalance']) + self.__deposit - self.__withdraw + # 动态权益=静态权益+平仓盈亏+持仓盈亏-手续费 + self.__current = self.__pre_balance + Decimal(account['CloseProfit']) + Decimal(account['PositionProfit']) - Decimal(account['Commission']) + self.__margin = Decimal(account['CurrMargin']) + self.__cash = Decimal(account['Available']) + self.__cur_account = account + self.__broker.cash = self.__cash + self.__broker.current = self.__current + self.__broker.pre_balance = self.__pre_balance + self.__broker.margin = self.__margin + self.__broker.save(update_fields=['cash', 'current', 'pre_balance', 'margin']) + logger.debug(f"更新账户,可用资金: {self.__cash:,.0f} 静态权益: {self.__pre_balance:,.0f} 动态权益: {self.__current:,.0f} " + f"出入金: {self.__withdraw - self.__deposit:,.0f} 虚拟: {fake:,.0f}") + except Exception as e: + logger.warning(f'refresh_account 发生错误: {repr(e)}', exc_info=True) + + async def refresh_position(self): + try: + logger.debug('更新持仓...') + pos_list = await self.query('InvestorPositionDetail') + self.__cur_pos.clear() + for pos in pos_list: + if 'empty' in pos and pos['empty'] is True: + continue + if pos['Volume'] > 0: + old_pos = self.__cur_pos.get(pos['InstrumentID']) + if old_pos is None: + self.__cur_pos[pos['InstrumentID']] = pos + else: + old_pos['OpenPrice'] = (old_pos['OpenPrice'] * old_pos['Volume'] + pos['OpenPrice'] * pos['Volume']) / (old_pos['Volume'] + pos['Volume']) + old_pos['Volume'] += pos['Volume'] + old_pos['PositionProfitByTrade'] += pos['PositionProfitByTrade'] + old_pos['Margin'] += pos['Margin'] + Trade.objects.filter(~Q(code__in=self.__cur_pos.keys()), close_time__isnull=True).delete() # 删除不存在的头寸 + for _, pos in self.__cur_pos.items(): + p_code = self.__re_extract_code.match(pos['InstrumentID']).group(1) + inst = Instrument.objects.get(product_code=p_code) + trade = Trade.objects.filter(broker=self.__broker, strategy=self.__strategy, instrument=inst, code=pos['InstrumentID'], close_time__isnull=True, + direction=DirectionType.values[pos['Direction']]).first() + bar = DailyBar.objects.filter(code=pos['InstrumentID']).order_by('-time').first() + profit = (bar.close - Decimal(pos['OpenPrice'])) * pos['Volume'] * inst.volume_multiple + if pos['Direction'] == DirectionType.values[DirectionType.SHORT]: + profit *= -1 + if trade: + trade.shares = (trade.closed_shares if trade.closed_shares else 0) + pos['Volume'] + trade.filled_shares = trade.shares + trade.profit = profit + trade.save(update_fields=['shares', 'filled_shares', 'profit']) + else: + Trade.objects.create( + broker=self.__broker, strategy=self.__strategy, instrument=inst, code=pos['InstrumentID'], profit=profit, filled_shares=pos['Volume'], + direction=DirectionType.values[pos['Direction']], avg_entry_price=Decimal(pos['OpenPrice']), shares=pos['Volume'], + open_time=timezone.make_aware(datetime.datetime.strptime(pos['OpenDate'] + '08', '%Y%m%d%H')), frozen_margin=Decimal(pos['Margin']), + cost=pos['Volume'] * Decimal(pos['OpenPrice']) * inst.fee_money * inst.volume_multiple + pos['Volume'] * inst.fee_volume) + logger.debug('更新持仓完成!') + except Exception as e: + logger.warning(f'refresh_position 发生错误: {repr(e)}', exc_info=True) + + async def refresh_instrument(self): + try: + logger.debug("更新合约...") + inst_dict = defaultdict(dict) + inst_list = await self.query('Instrument') + for inst in inst_list: + if inst['empty']: + continue + if inst['IsTrading'] == 1 and chr(inst['ProductClass']) == ApiStruct.PC_Futures and int(str_to_number(inst['StrikePrice'])) == 0: + if inst['ProductID'] in self.__ignore_inst_list or inst['LongMarginRatio'] > 1: + continue + inst_dict[inst['ProductID']][inst['InstrumentID']] = dict() + inst_dict[inst['ProductID']][inst['InstrumentID']]['name'] = inst['InstrumentName'] + inst_dict[inst['ProductID']][inst['InstrumentID']]['exchange'] = inst['ExchangeID'] + inst_dict[inst['ProductID']][inst['InstrumentID']]['multiple'] = inst['VolumeMultiple'] + inst_dict[inst['ProductID']][inst['InstrumentID']]['price_tick'] = inst['PriceTick'] + for code in inst_dict.keys(): + all_inst = ','.join(sorted(inst_dict[code].keys())) + inst_data = list(inst_dict[code].values())[0] + valid_name = self.__re_extract_name.match(inst_data['name']) + if valid_name is not None: + valid_name = valid_name.group(1) + else: + valid_name = inst_data['name'] + if valid_name == code: + valid_name = '' + inst_data['name'] = valid_name + inst, created = Instrument.objects.update_or_create(product_code=code, exchange=inst_data['exchange']) + print(f"inst:{inst} created:{created} main_code:{inst.main_code}") + update_field_list = list() + # 更新主力合约的保证金和手续费 + if inst.main_code: + margin_rate = await self.query('InstrumentMarginRate', InstrumentID=inst.main_code) + inst.margin_rate = margin_rate[0]['LongMarginRatioByMoney'] + fee = await self.query('InstrumentCommissionRate', InstrumentID=inst.main_code) + inst.fee_money = Decimal(fee[0]['CloseRatioByMoney']) + inst.fee_volume = Decimal(fee[0]['CloseRatioByVolume']) + update_field_list += ['margin_rate', 'fee_money', 'fee_volume'] + if created: + inst.name = inst_data['name'] + inst.volume_multiple = inst_data['multiple'] + inst.price_tick = inst_data['price_tick'] + update_field_list += ['name', 'volume_multiple', 'price_tick'] + elif inst.main_code: + inst.all_inst = all_inst + update_field_list.append('all_inst') + inst.save(update_fields=update_field_list) + logger.debug("更新合约完成!") + except Exception as e: + logger.warning(f'refresh_instrument 发生错误: {repr(e)}', exc_info=True) + + def getShares(self, instrument: str): + # 这个函数只能处理持有单一方向仓位的情况,若同时持有多空的头寸,返回结果不正确 + shares = 0 + pos_price = 0 + for pos in self.__shares[instrument]: + pos_price += pos['Volume'] * pos['OpenPrice'] + shares += pos['Volume'] * (-1 if pos['Direction'] == DirectionType.SHORT else 1) + return shares, pos_price / abs(shares), self.__shares[instrument][0]['OpenDate'] + + def getPositions(self, inst_id: int): + # 这个函数只能处理持有单一方向仓位的情况,若同时持有多空的头寸,返回结果不正确 + return self.__shares[inst_id][0] + + def async_query(self, query_type: str, **kwargs): + request_id = get_next_id() + kwargs['RequestID'] = request_id + self.raw_redis.publish(self.__request_format.format('ReqQry' + query_type), json.dumps(kwargs)) + + @staticmethod + async def query_reader(pb: aioredis.client.PubSub): + msg_list = [] + async for msg in pb.listen(): + # print(f"query_reader msg: {msg}") + msg_dict = json.loads(msg['data']) + if 'empty' not in msg_dict or not msg_dict['empty']: + msg_list.append(msg_dict) + if 'bIsLast' not in msg_dict or msg_dict['bIsLast']: + return msg_list + + async def query(self, query_type: str, **kwargs): + sub_client = None + channel_rsp_qry, channel_rsp_err = None, None + try: + sub_client = self.redis_client.pubsub(ignore_subscribe_messages=True) + request_id = get_next_id() + kwargs['RequestID'] = request_id + channel_rsp_qry = self.__trade_response_format.format('OnRspQry' + query_type, request_id) + channel_rsp_err = self.__trade_response_format.format('OnRspError', request_id) + await sub_client.psubscribe(channel_rsp_qry, channel_rsp_err) + task = asyncio.create_task(self.query_reader(sub_client)) + self.raw_redis.publish(self.__request_format.format('ReqQry' + query_type), json.dumps(kwargs)) + await asyncio.wait_for(task, HANDLER_TIME_OUT) + await sub_client.punsubscribe() + await sub_client.close() + return task.result() + except Exception as e: + logger.warning(f'{query_type} 发生错误: {repr(e)}', exc_info=True) + if sub_client and channel_rsp_qry: + await sub_client.unsubscribe() + await sub_client.close() + return None + + async def SubscribeMarketData(self, inst_ids: list): + sub_client = None + channel_rsp_dat, channel_rsp_err = None, None + try: + sub_client = self.redis_client.pubsub(ignore_subscribe_messages=True) + channel_rsp_dat = self.__market_response_format.format('OnRspSubMarketData', 0) + channel_rsp_err = self.__market_response_format.format('OnRspError', 0) + await sub_client.psubscribe(channel_rsp_dat, channel_rsp_err) + task = asyncio.create_task(self.query_reader(sub_client)) + self.raw_redis.publish(self.__request_format.format('SubscribeMarketData'), json.dumps(inst_ids)) + await asyncio.wait_for(task, HANDLER_TIME_OUT) + await sub_client.punsubscribe() + await sub_client.close() + return task.result() + except Exception as e: + logger.warning(f'SubscribeMarketData 发生错误: {repr(e)}', exc_info=True) + if sub_client and sub_client.in_pubsub and channel_rsp_dat: + await sub_client.unsubscribe() + await sub_client.close() + return None + + async def UnSubscribeMarketData(self, inst_ids: list): + sub_client = None + channel_rsp_dat, channel_rsp_err = None, None + try: + sub_client = self.redis_client.pubsub(ignore_subscribe_messages=True) + channel_rsp_dat = self.__market_response_format.format('OnRspUnSubMarketData', 0) + channel_rsp_err = self.__market_response_format.format('OnRspError', 0) + await sub_client.psubscribe(channel_rsp_dat, channel_rsp_err) + task = asyncio.create_task(self.query_reader(sub_client)) + self.raw_redis.publish(self.__request_format.format('UnSubscribeMarketData'), json.dumps(inst_ids)) + await asyncio.wait_for(task, HANDLER_TIME_OUT) + await sub_client.punsubscribe() + await sub_client.close() + return task.result() + except Exception as e: + logger.warning(f'UnSubscribeMarketData 发生错误: {repr(e)}', exc_info=True) + if sub_client and sub_client.in_pubsub and channel_rsp_dat: + await sub_client.unsubscribe() + await sub_client.close() + return None + + def ReqOrderInsert(self, sig: Signal): + try: + request_id = get_next_id() + autoid = Autonumber.objects.create() + order_ref = f"{autoid.id:07}{sig.id:05}" + param_dict = dict() + param_dict['RequestID'] = request_id + param_dict['OrderRef'] = order_ref + param_dict['InstrumentID'] = sig.code + param_dict['VolumeTotalOriginal'] = sig.volume + param_dict['LimitPrice'] = float(sig.price) + match sig.type: + case SignalType.BUY | SignalType.SELL_SHORT: + param_dict['Direction'] = ApiStruct.D_Buy if sig.type == SignalType.BUY else ApiStruct.D_Sell + param_dict['CombOffsetFlag'] = ApiStruct.OF_Open + logger.info(f'{sig.instrument} {sig.type}{sig.volume}手 价格: {sig.price}') + case SignalType.BUY_COVER | SignalType.SELL: + param_dict['Direction'] = ApiStruct.D_Buy if sig.type == SignalType.BUY_COVER else ApiStruct.D_Sell + param_dict['CombOffsetFlag'] = ApiStruct.OF_Close + pos = Trade.objects.filter( + broker=self.__broker, strategy=self.__strategy, code=sig.code, shares=sig.volume, close_time__isnull=True, + direction=DirectionType.values[DirectionType.SHORT] if sig.type == SignalType.BUY_COVER else DirectionType.values[ + DirectionType.LONG]).first() + if pos.open_time.astimezone().date() == timezone.localtime().date() and pos.instrument.exchange == ExchangeType.SHFE: + param_dict['CombOffsetFlag'] = ApiStruct.OF_CloseToday # 上期所区分平今和平昨 + logger.info(f'{sig.instrument} {sig.type}{sig.volume}手 价格: {sig.price}') + case SignalType.ROLL_CLOSE: + param_dict['CombOffsetFlag'] = ApiStruct.OF_Close + pos = Trade.objects.filter(broker=self.__broker, strategy=self.__strategy, code=sig.code, shares=sig.volume, close_time__isnull=True).first() + param_dict['Direction'] = ApiStruct.D_Sell if pos.direction == DirectionType.values[DirectionType.LONG] else ApiStruct.D_Buy + if pos.open_time.astimezone().date() == timezone.localtime().date() and pos.instrument.exchange == ExchangeType.SHFE: + param_dict['CombOffsetFlag'] = ApiStruct.OF_CloseToday # 上期所区分平今和平昨 + logger.info(f'{sig.code}->{sig.instrument.main_code} {pos.direction}头换月平旧{sig.volume}手 价格: {sig.price}') + case SignalType.ROLL_OPEN: + param_dict['CombOffsetFlag'] = ApiStruct.OF_Open + pos = Trade.objects.filter( + Q(close_time__isnull=True) | Q(close_time__date__gte=timezone.localtime().now().date()), + broker=self.__broker, strategy=self.__strategy, code=sig.instrument.last_main, shares=sig.volume).first() + param_dict['Direction'] = ApiStruct.D_Buy if pos.direction == DirectionType.values[DirectionType.LONG] else ApiStruct.D_Sell + logger.info(f'{pos.code}->{sig.code} {pos.direction}头换月开新{sig.volume}手 价格: {sig.price}') + self.raw_redis.publish(self.__request_format.format('ReqOrderInsert'), json.dumps(param_dict)) + except Exception as e: + logger.warning(f'ReqOrderInsert 发生错误: {repr(e)}', exc_info=True) + + async def cancel_order(self, order: dict): + sub_client = None + channel_rsp_odr_act, channel_rsp_err = None, None + try: + sub_client = self.redis_client.pubsub(ignore_subscribe_messages=True) + request_id = get_next_id() + order['RequestID'] = request_id + channel_rtn_odr = self.__trade_response_format.format('OnRtnOrder', order['OrderRef']) + channel_rsp_odr_act = self.__trade_response_format.format('OnRspOrderAction', 0) + channel_rsp_err = self.__trade_response_format.format('OnRspError', request_id) + await sub_client.psubscribe(channel_rtn_odr, channel_rsp_odr_act, channel_rsp_err) + task = asyncio.create_task(self.query_reader(sub_client)) + self.raw_redis.publish(self.__request_format.format('ReqOrderAction'), json.dumps(order)) + await asyncio.wait_for(task, HANDLER_TIME_OUT) + await sub_client.punsubscribe() + await sub_client.close() + result = task.result()[0] + if 'ErrorID' in result: + logger.warning(f"撤销订单出错: {ctp_errors[result['ErrorID']]}") + return False + return True + except Exception as e: + logger.warning('cancel_order 发生错误: %s', repr(e), exc_info=True) + if sub_client and sub_client.in_pubsub and channel_rsp_odr_act: + await sub_client.unsubscribe() + await sub_client.close() + return False + + @RegisterCallback(channel='MSG:CTP:RSP:MARKET:OnRtnDepthMarketData:*') + async def OnRtnDepthMarketData(self, channel, tick: dict): + try: + inst = channel.split(':')[-1] + tick['UpdateTime'] = datetime.datetime.strptime(tick['UpdateTime'], "%Y%m%d %H:%M:%S:%f") + logger.debug('inst=%s, tick: %s', inst, tick) + except Exception as ee: + logger.warning('OnRtnDepthMarketData 发生错误: %s', repr(ee), exc_info=True) + + @staticmethod + def get_trade_string(trade: dict) -> str: + if trade['OffsetFlag'] == OffsetFlag.Open: + open_direct = DirectionType.values[trade['Direction']] + else: + open_direct = DirectionType.values[DirectionType.LONG] if trade['Direction'] == DirectionType.SHORT else DirectionType.values[DirectionType.SHORT] + return f"{trade['ExchangeID']}.{trade['InstrumentID']} {OffsetFlag.values[trade['OffsetFlag']]}{open_direct}已成交{trade['Volume']}手 " \ + f"价格:{trade['Price']} 时间:{trade['TradeTime']} 订单号: {trade['OrderRef']}" + + @RegisterCallback(channel='MSG:CTP:RSP:TRADE:OnRtnTrade:*') + async def OnRtnTrade(self, channel, trade: dict): + try: + signal = None + new_trade = False + trade_completed = False + order_ref: str = channel.split(':')[-1] + manual_trade = int(order_ref) < 10000 + if not manual_trade: + signal = Signal.objects.get(id=int(order_ref[ORDER_REF_SIGNAL_ID_START:])) + logger.info(f"成交回报: {self.get_trade_string(trade)}") + inst = Instrument.objects.get(product_code=self.__re_extract_code.match(trade['InstrumentID']).group(1)) + order = Order.objects.filter(order_ref=order_ref, code=trade['InstrumentID']).order_by('-send_time').first() + trade_cost = trade['Volume'] * Decimal(trade['Price']) * inst.fee_money * inst.volume_multiple + trade['Volume'] * inst.fee_volume + trade_margin = trade['Volume'] * Decimal(trade['Price']) * inst.margin_rate + now = timezone.localtime() + trade_time = timezone.make_aware(datetime.datetime.strptime(trade['TradeDate'] + trade['TradeTime'], '%Y%m%d%H:%M:%S')) + if trade_time.date() > now.date(): + trade_time.replace(year=now.year, month=now.month, day=now.day) + if trade['OffsetFlag'] == OffsetFlag.Open: # 开仓 + last_trade = Trade.objects.filter( + broker=self.__broker, strategy=self.__strategy, instrument=inst, code=trade['InstrumentID'], open_time__lte=trade_time, + close_time__isnull=True, + direction=DirectionType.values[trade['Direction']]).first() if manual_trade else Trade.objects.filter(open_order=order).first() + # print(connection.queries[-1]['sql']) + if last_trade is None: + new_trade = True + last_trade = Trade.objects.create( + broker=self.__broker, strategy=self.__strategy, instrument=inst, code=trade['InstrumentID'], open_order=order if order else None, + direction=DirectionType.values[trade['Direction']], open_time=trade_time, shares=order.volume if order else trade['Volume'], + cost=trade_cost, filled_shares=trade['Volume'], avg_entry_price=trade['Price'], frozen_margin=trade_margin) + if order is None or order.status == OrderStatus.values[OrderStatus.AllTraded]: + trade_completed = True + if (not new_trade and not manual_trade) or (trade_completed and not new_trade and manual_trade): + last_trade.avg_entry_price = (last_trade.avg_entry_price * last_trade.filled_shares + trade['Volume'] * Decimal(trade['Price'])) / \ + (last_trade.filled_shares + trade['Volume']) + last_trade.filled_shares += trade['Volume'] + if trade_completed and not new_trade and manual_trade: + last_trade.shares += trade['Volume'] + last_trade.cost += trade_cost + last_trade.frozen_margin += trade_margin + last_trade.save() + else: # 平仓 + open_direct = DirectionType.values[DirectionType.LONG] if trade['Direction'] == DirectionType.SHORT else DirectionType.values[DirectionType.SHORT] + last_trade = Trade.objects.filter(Q(closed_shares__isnull=True) | Q(closed_shares__lt=F('shares')), shares=F('filled_shares'), + broker=self.__broker, strategy=self.__strategy, instrument=inst, code=trade['InstrumentID'], + direction=open_direct).first() + # print(connection.queries[-1]['sql']) + logger.debug(f'trade={last_trade}') + if last_trade: + if last_trade.closed_shares and last_trade.avg_exit_price: + last_trade.avg_exit_price = (last_trade.avg_exit_price * last_trade.closed_shares + trade['Volume'] * Decimal(trade['Price'])) / \ + (last_trade.closed_shares + trade['Volume']) + last_trade.closed_shares += trade['Volume'] + else: + last_trade.avg_exit_price = trade['Volume'] * Decimal(trade['Price']) / trade['Volume'] + last_trade.closed_shares = trade['Volume'] + last_trade.cost += trade_cost + last_trade.close_order = order + if last_trade.closed_shares == last_trade.shares: # 全部成交 + trade_completed = True + last_trade.close_time = trade_time + if last_trade.direction == DirectionType.values[DirectionType.LONG]: + profit_point = last_trade.avg_exit_price - last_trade.avg_entry_price + else: + profit_point = last_trade.avg_entry_price - last_trade.avg_exit_price + last_trade.profit = profit_point * last_trade.shares * inst.volume_multiple + last_trade.save(force_update=True) + logger.debug(f"new_trade:{new_trade} manual_trade:{manual_trade} trade_completed:{trade_completed} " + f"order:{order} signal: {signal}") + if trade_completed and not manual_trade: + signal.processed = True + signal.save(update_fields=['processed']) + order.signal = signal + order.save(update_fields=['signal']) + except Exception as ee: + logger.warning(f'OnRtnTrade 发生错误: {repr(ee)}', exc_info=True) + + @staticmethod + def save_order(order: dict): + try: + if int(order['OrderRef']) < 10000: # 非本程序生成订单 + return None, None + signal = Signal.objects.get(id=int(order['OrderRef'][ORDER_REF_SIGNAL_ID_START:])) + odr, created = Order.objects.update_or_create( + code=order['InstrumentID'], order_ref=order['OrderRef'], defaults={ + 'broker': signal.strategy.broker, 'strategy': signal.strategy, 'instrument': signal.instrument, 'front': order['FrontID'], + 'session': order['SessionID'], 'price': order['LimitPrice'], 'volume': order['VolumeTotalOriginal'], + 'direction': DirectionType.values[order['Direction']], 'status': OrderStatus.values[order['OrderStatus']], + 'offset_flag': CombOffsetFlag.values[order['CombOffsetFlag']], 'update_time': timezone.localtime(), + 'send_time': timezone.make_aware(datetime.datetime.strptime(order['InsertDate'] + order['InsertTime'], '%Y%m%d%H:%M:%S'))}) + if order['OrderStatus'] == ApiStruct.OST_Canceled: # 删除错误订单 + odr.delete() + return None, None + now = timezone.localtime().date() + if created and odr.send_time.date() > timezone.localtime().date(): # 夜盘成交时返回的时间是下一个交易日,需要改成今天 + odr.send_time.replace(year=now.year, month=now.month, day=now.day) + odr.save(update_fields=['send_time']) + odr.signal = signal + return odr, created + except Exception as ee: + logger.warning(f'save_order 发生错误: {repr(ee)}', exc_info=True) + return None, None + + @staticmethod + def get_order_string(order: dict) -> str: + off_set_flag = CombOffsetFlag.values[order['CombOffsetFlag']] if order['CombOffsetFlag'] in CombOffsetFlag.values else \ + OffsetFlag.values[order['CombOffsetFlag']] + order_str = f"订单号:{order['OrderRef']},{order['ExchangeID']}.{order['InstrumentID']} {off_set_flag}{DirectionType.values[order['Direction']]}" \ + f"{order['VolumeTotalOriginal']}手 价格:{order['LimitPrice']} 报单时间:{order['InsertTime']} " \ + f"提交状态:{OrderSubmitStatus.values[order['OrderSubmitStatus']]} " + if order['OrderStatus'] != OrderStatus.Unknown: + order_str += f"成交状态:{OrderStatus.values[order['OrderStatus']]} 消息:{order['StatusMsg']} " + if order['OrderStatus'] == OrderStatus.PartTradedQueueing: + order_str += f"成交数量:{order['VolumeTraded']} 剩余数量:{order['VolumeTotal']}" + return order_str + + @RegisterCallback(channel='MSG:CTP:RSP:TRADE:OnRtnOrder:*') + async def OnRtnOrder(self, _: str, order: dict): + try: + if order["OrderSysID"]: + logger.debug(f"订单回报: {self.get_order_string(order)}") + order_obj, _ = self.save_order(order) + if not order_obj: + return + signal = order_obj.signal + inst = Instrument.objects.get(product_code=self.__re_extract_code.match(order['InstrumentID']).group(1)) + # 处理由于委托价格超出交易所涨跌停板而被撤单的报单,将委托价格下调50%,重新报单 + if order['OrderStatus'] == OrderStatus.Canceled and order['OrderSubmitStatus'] == OrderSubmitStatus.InsertRejected: + last_bar = DailyBar.objects.filter(exchange=inst.exchange, code=order['InstrumentID']).order_by('-time').first() + volume = int(order['VolumeTotalOriginal']) + price = Decimal(order['LimitPrice']) + if order['CombOffsetFlag'] == CombOffsetFlag.Open: + if order['Direction'] == DirectionType.LONG: + delta = (price - last_bar.settlement) * Decimal(0.5) + price = price_round(last_bar.settlement + delta, inst.price_tick) + if delta / last_bar.settlement < 0.01: + logger.warning(f"{inst} 新价格: {price} 过低难以成交,放弃报单!") + return + logger.info(f"{inst} 以价格 {price} 开多{volume}手 重新报单...") + signal.price = price + self.io_loop.call_soon(self.ReqOrderInsert, signal) + else: + delta = (last_bar.settlement - price) * Decimal(0.5) + price = price_round(last_bar.settlement - delta, inst.price_tick) + if delta / last_bar.settlement < 0.01: + logger.warning(f"{inst} 新价格: {price} 过低难以成交,放弃报单!") + return + logger.info(f"{inst} 以价格 {price} 开空{volume}手 重新报单...") + signal.price = price + self.io_loop.call_soon(self.ReqOrderInsert, signal) + else: + if order['Direction'] == DirectionType.LONG: + delta = (price - last_bar.settlement) * Decimal(0.5) + price = price_round(last_bar.settlement + delta, inst.price_tick) + if delta / last_bar.settlement < 0.01: + logger.warning(f"{inst} 新价格: {price} 过低难以成交,放弃报单!") + return + logger.info(f"{inst} 以价格 {price} 买平{volume}手 重新报单...") + signal.price = price + self.io_loop.call_soon(self.ReqOrderInsert, signal) + else: + delta = (last_bar.settlement - price) * Decimal(0.5) + price = price_round(last_bar.settlement - delta, inst.price_tick) + if delta / last_bar.settlement < 0.01: + logger.warning(f"{inst} 新价格: {price} 过低难以成交,放弃报单!") + return + logger.info(f"{inst} 以价格 {price} 卖平{volume}手 重新报单...") + signal.price = price + self.io_loop.call_soon(self.ReqOrderInsert, signal) + except Exception as ee: + logger.warning(f'OnRtnOrder 发生错误: {repr(ee)}', exc_info=True) + + @RegisterCallback(crontab='*/1 * * * *') + async def heartbeat(self): + self.raw_redis.set('HEARTBEAT:TRADER', 1, ex=301) + + @RegisterCallback(crontab='55 8 * * *') + async def processing_signal1(self): + await asyncio.sleep(5) + day = timezone.localtime() + _, trading = await is_trading_day(day) + if trading: + logger.debug('查询日盘信号..') + for sig in Signal.objects.filter(~Q(instrument__exchange=ExchangeType.CFFEX), trigger_time__gte=self.__last_trading_day, strategy=self.__strategy, + instrument__night_trade=False, processed=False).order_by('-priority'): + logger.info(f'发现日盘信号: {sig}') + self.io_loop.call_soon(self.ReqOrderInsert, sig) + if (self.__trading_day - self.__last_trading_day).days > 3: + logger.info(f'假期后第一天,处理节前未成交夜盘信号.') + self.io_loop.call_soon(asyncio.create_task, self.processing_signal3()) + + @RegisterCallback(crontab='1 9 * * *') + async def check_signal1_processed(self): + day = timezone.localtime() + _, trading = await is_trading_day(day) + if trading: + logger.debug('查询遗漏的日盘信号..') + for sig in Signal.objects.filter(~Q(instrument__exchange=ExchangeType.CFFEX), trigger_time__gte=self.__last_trading_day, strategy=self.__strategy, + instrument__night_trade=False, processed=False).order_by('-priority'): + logger.info(f'发现遗漏信号: {sig}') + self.io_loop.call_soon(self.ReqOrderInsert, sig) + + @RegisterCallback(crontab='25 9 * * *') + async def processing_signal2(self): + await asyncio.sleep(5) + day = timezone.localtime() + _, trading = await is_trading_day(day) + if trading: + logger.debug('查询股指和国债信号..') + for sig in Signal.objects.filter(instrument__exchange=ExchangeType.CFFEX, trigger_time__gte=self.__last_trading_day, strategy=self.__strategy, + instrument__night_trade=False, processed=False).order_by('-priority'): + logger.info(f'发现股指和国债信号: {sig}') + self.io_loop.call_soon(self.ReqOrderInsert, sig) + + @RegisterCallback(crontab='31 9 * * *') + async def check_signal2_processed(self): + day = timezone.localtime() + _, trading = await is_trading_day(day) + if trading: + logger.debug('查询遗漏的股指和国债信号..') + for sig in Signal.objects.filter(instrument__exchange=ExchangeType.CFFEX, trigger_time__gte=self.__last_trading_day, strategy=self.__strategy, + instrument__night_trade=False, processed=False).order_by('-priority'): + logger.info(f'发现遗漏的股指和国债信号: {sig}') + self.io_loop.call_soon(self.ReqOrderInsert, sig) + + @RegisterCallback(crontab='55 20 * * *') + async def processing_signal3(self): + await asyncio.sleep(5) + day = timezone.localtime() + _, trading = await is_trading_day(day) + if trading: + logger.debug('查询夜盘信号..') + for sig in Signal.objects.filter( + trigger_time__gte=self.__last_trading_day, strategy=self.__strategy, instrument__night_trade=True, processed=False).order_by('-priority'): + logger.info(f'发现夜盘信号: {sig}') + self.io_loop.call_soon(self.ReqOrderInsert, sig) + + @RegisterCallback(crontab='1 21 * * *') + async def check_signal3_processed(self): + day = timezone.localtime() + _, trading = await is_trading_day(day) + if trading: + logger.debug('查询遗漏的夜盘信号..') + for sig in Signal.objects.filter( + trigger_time__gte=self.__last_trading_day, strategy=self.__strategy, instrument__night_trade=True, processed=False).order_by('-priority'): + logger.info(f'发现遗漏的夜盘信号: {sig}') + self.io_loop.call_soon(self.ReqOrderInsert, sig) + + @RegisterCallback(crontab='20 15 * * *') + async def refresh_all(self): + day = timezone.localtime() + _, trading = await is_trading_day(day) + if not trading: + logger.info('今日是非交易日, 不更新任何数据。') + return + await self.refresh_account() + await self.refresh_position() + await self.refresh_instrument() + logger.debug('全部更新完成!') + + @RegisterCallback(crontab='30 15 * * *') + async def update_equity(self): + today, trading = await is_trading_day(timezone.localtime()) + if trading: + dividend = Performance.objects.filter( + broker=self.__broker, day__lt=today.date()).aggregate(Sum('dividend'))['dividend__sum'] + if dividend is None: + dividend = Decimal(0) + dividend = dividend + self.__deposit - self.__withdraw + # 虚拟=虚拟(原始)-入金+出金 + self.__fake = self.__fake - self.__deposit + self.__withdraw + if self.__fake < 1: + self.__fake = 0 + self.__broker.fake = self.__fake + self.__broker.save(update_fields=['fake']) + unit = dividend + self.__fake + nav = (self.__current + self.__fake) / unit # 单位净值 + accumulated = self.__current / (unit - self.__fake) # 累计净值 + Performance.objects.update_or_create(broker=self.__broker, day=today.date(), defaults={ + 'used_margin': self.__margin, 'dividend': self.__deposit - self.__withdraw, 'fake': self.__fake, 'capital': self.__current, 'unit_count': unit, + 'NAV': nav, 'accumulated': accumulated}) + logger.info(f"动态权益: {self.__current:,.0f}({self.__current/10000:.1f}万) " + f"静态权益: {self.__pre_balance:,.0f}({self.__pre_balance/10000:.1f}万) " + f"可用资金: {self.__cash:,.0f}({self.__cash/10000:.1f}万) " + f"保证金占用: {self.__margin:,.0f}({self.__margin/10000:.1f}万) " + f"虚拟资金: {self.__fake:,.0f}({self.__fake/10000:.1f}万) 当日入金: {self.__deposit:,.0f} " + f"当日出金: {self.__withdraw:,.0f} 单位净值: {nav:,.2f} 累计净值: {accumulated:,.2f}") + + @RegisterCallback(crontab='0 17 * * *') + async def collect_quote(self, tasks=None): + try: + day = timezone.localtime() + _, trading = await is_trading_day(day) + if not trading: + logger.info('今日是非交易日, 不计算任何数据。') + return + logger.debug(f'{day}盘后计算,获取交易所日线数据..') + if tasks is None: + tasks = [update_from_shfe, update_from_dce, update_from_czce, update_from_cffex, update_from_gfex, get_contracts_argument] + result = await asyncio.gather(*[func(day) for func in tasks], return_exceptions=True) + if all(result): + self.io_loop.call_soon(self.calculate, day) + else: + failed_tasks = [tasks[i] for i, rst in enumerate(result) if not rst] + self.io_loop.call_later(10*60, asyncio.create_task, self.collect_quote(failed_tasks)) + except Exception as e: + logger.warning(f'collect_quote 发生错误: {repr(e)}', exc_info=True) + logger.debug('盘后计算完毕!') + + def calculate(self, day, create_main_bar=True): + try: + p_code_set = set(self.__inst_ids) + for code in self.__cur_pos.keys(): + p_code_set.add(self.__re_extract_code.match(code).group(1)) + all_margin = 0 + for inst in Instrument.objects.all().order_by('section', 'exchange', 'name'): + if create_main_bar: + logger.debug(f'生成连续合约: {inst.name}') + calc_main_inst(inst, day) + if inst.product_code in p_code_set: + logger.debug(f'计算交易信号: {inst.name}') + sig, margin = self.calc_signal(inst, day) + all_margin += margin + if (all_margin + self.__margin) / self.__current > 0.8: + logger.info(f"!!!风险提示!!!开仓保证金共计: {all_margin:.0f}({all_margin/10000:.1f}万) " + f"账户风险度将达到: {100 * (all_margin + self.__margin) / self.__current:.0f}% 建议追加保证金或减少开仓手数!") + except Exception as e: + logger.warning(f'calculate 发生错误: {repr(e)}', exc_info=True) + + def calc_signal(self, inst: Instrument, day: datetime.datetime) -> (Signal, Decimal): + try: + break_n = self.__strategy.param_set.get(code='BreakPeriod').int_value + atr_n = self.__strategy.param_set.get(code='AtrPeriod').int_value + long_n = self.__strategy.param_set.get(code='LongPeriod').int_value + short_n = self.__strategy.param_set.get(code='ShortPeriod').int_value + stop_n = self.__strategy.param_set.get(code='StopLoss').int_value + risk = self.__strategy.param_set.get(code='Risk').float_value + # 只读取最近400条记录,减少运算量 + df = to_df(MainBar.objects.filter(time__lte=day.date(), exchange=inst.exchange, product_code=inst.product_code).order_by('-time').values_list( + 'time', 'open', 'high', 'low', 'close')[:400], index_col='time', parse_dates=['time']) + df = df.iloc[::-1] # 日期升序排列 + df["atr"] = ATR(df.high, df.low, df.close, timeperiod=atr_n) + df["short_trend"] = df.close + df["long_trend"] = df.close + for idx in range(1, df.shape[0]): # 手动计算SMA + df.short_trend[idx] = (df.short_trend[idx-1] * (short_n - 1) + df.close[idx]) / short_n + df.long_trend[idx] = (df.long_trend[idx-1] * (long_n - 1) + df.close[idx]) / long_n + df["high_line"] = df.close.rolling(window=break_n).max() + df["low_line"] = df.close.rolling(window=break_n).min() + idx = -1 + buy_sig = df.short_trend[idx] > df.long_trend[idx] and price_round(df.close[idx], inst.price_tick) >= price_round(df.high_line[idx - 1], inst.price_tick) + sell_sig = df.short_trend[idx] < df.long_trend[idx] and price_round(df.close[idx], inst.price_tick) <= price_round(df.low_line[idx - 1], inst.price_tick) + pos = Trade.objects.filter(close_time__isnull=True, broker=self.__broker, strategy=self.__strategy, instrument=inst, shares__gt=0).first() + roll_over = False + if pos: + roll_over = pos.code != inst.main_code and pos.code < inst.main_code + elif self.__strategy.force_opens.filter(id=inst.id).exists() and not buy_sig and not sell_sig: + logger.info(f'强制开仓: {inst}') + if df.short_trend[idx] > df.long_trend[idx]: + buy_sig = True + else: + sell_sig = True + self.__strategy.force_opens.remove(inst) + signal = signal_code = price = volume = volume_ori = use_margin = None + priority = PriorityType.LOW + if pos: + # 多头持仓 + if pos.direction == DirectionType.values[DirectionType.LONG]: + first_pos = pos + while hasattr(first_pos, 'open_order') and first_pos.open_order and first_pos.open_order.signal and first_pos.open_order.signal.type == \ + SignalType.ROLL_OPEN: + last_pos = Trade.objects.filter( + close_order__signal__type=SignalType.ROLL_CLOSE, instrument=first_pos.instrument, strategy=first_pos.strategy, + shares=first_pos.shares, direction=first_pos.direction, close_time__date=first_pos.open_time.date()).first() + if last_pos is None: + break + logger.debug(f"发现换月前持仓:{last_pos} 开仓时间: {last_pos.open_time}") + first_pos = last_pos + pos_idx = df.index.get_loc(first_pos.open_time.astimezone().date().isoformat()) + # 多头止损 + if df.close[idx] <= df.high[pos_idx:idx].max() - df.atr[pos_idx - 1] * stop_n: + signal = SignalType.SELL + signal_code = pos.code + volume = pos.shares + last_bar = DailyBar.objects.filter(exchange=inst.exchange, code=pos.code, time=day.date()).first() + price = self.calc_down_limit(inst, last_bar) + priority = PriorityType.High + # 多头换月 + elif roll_over: + signal = SignalType.ROLL_OPEN + volume = pos.shares + last_bar = DailyBar.objects.filter(exchange=inst.exchange, code=pos.code, time=day.date()).first() + new_bar = DailyBar.objects.filter(exchange=inst.exchange, code=inst.main_code, time=day.date()).first() + price = self.calc_up_limit(inst, new_bar) + priority = PriorityType.Normal + Signal.objects.update_or_create( + code=pos.code, strategy=self.__strategy, instrument=inst, type=SignalType.ROLL_CLOSE, trigger_time=day, + defaults={'price': self.calc_down_limit(inst, last_bar), 'volume': volume, 'priority': priority, 'processed': False}) + # 空头持仓 + else: + first_pos = pos + while hasattr(first_pos, 'open_order') and first_pos.open_order and first_pos.open_order.signal \ + and first_pos.open_order.signal.type == SignalType.ROLL_OPEN: + last_pos = Trade.objects.filter( + close_order__signal__type=SignalType.ROLL_CLOSE, instrument=first_pos.instrument, strategy=first_pos.strategy, + shares=first_pos.shares, direction=first_pos.direction,close_time__date=first_pos.open_time.date()).first() + if last_pos is None: + break + logger.debug(f"发现换月前持仓:{last_pos} 开仓时间: {last_pos.open_time}") + first_pos = last_pos + pos_idx = df.index.get_loc(first_pos.open_time.astimezone().date().isoformat()) + # 空头止损 + if df.close[idx] >= df.low[pos_idx:idx].min() + df.atr[pos_idx - 1] * stop_n: + signal = SignalType.BUY_COVER + signal_code = pos.code + volume = pos.shares + last_bar = DailyBar.objects.filter(exchange=inst.exchange, code=pos.code, time=day.date()).first() + price = self.calc_up_limit(inst, last_bar) + priority = PriorityType.High + # 空头换月 + elif roll_over: + signal = SignalType.ROLL_OPEN + volume = pos.shares + last_bar = DailyBar.objects.filter(exchange=inst.exchange, code=pos.code, time=day.date()).first() + new_bar = DailyBar.objects.filter(exchange=inst.exchange, code=inst.main_code, time=day.date()).first() + price = self.calc_down_limit(inst, new_bar) + priority = PriorityType.Normal + Signal.objects.update_or_create( + code=pos.code, strategy=self.__strategy, instrument=inst, type=SignalType.ROLL_CLOSE, trigger_time=day, + defaults={'price': self.calc_up_limit(inst, last_bar), 'volume': volume, 'priority': priority, 'processed': False}) + # 开新仓 + elif buy_sig or sell_sig: + start_cash = Performance.objects.last().unit_count + # 原始扎堆儿 + profit = Trade.objects.filter(strategy=self.__strategy, instrument__section=inst.section).aggregate(sum=Sum('profit'))['sum'] + profit = profit if profit else 0 + risk_each = Decimal(df.atr[idx]) * Decimal(inst.volume_multiple) + volume_ori = (start_cash + profit) * risk / risk_each + volume = round(volume_ori) + print(f"{inst}: ({start_cash:,.0f} + {profit:,.0f}) / {risk_each:,.0f} = {volume_ori}") + if volume > 0: + new_bar = DailyBar.objects.filter(exchange=inst.exchange, code=inst.main_code, time=day.date()).first() + use_margin = new_bar.settlement * inst.volume_multiple * inst.margin_rate * volume + price = self.calc_up_limit(inst, new_bar) if buy_sig else self.calc_down_limit(inst, new_bar) + signal = SignalType.BUY if buy_sig else SignalType.SELL_SHORT + else: + logger.info(f"做{'多' if buy_sig else '空'}{inst},单手风险:{risk_each:.0f},超出风控额度,放弃。") + if signal: + use_margin = use_margin if use_margin else 0 + sig, _ = Signal.objects.update_or_create( + code=signal_code if signal_code else inst.main_code,strategy=self.__strategy, instrument=inst, type=signal, trigger_time=day, + defaults={'price': price, 'volume': volume, 'priority': priority, 'processed': False}) + volume_ori = volume_ori if volume_ori else volume + logger.info(f"新信号: {sig}({volume_ori:.1f}手) " + f"预估保证金: {use_margin:.0f}({use_margin/10000:.1f}万)") + return signal, use_margin + except Exception as e: + logger.warning(f'calc_signal 发生错误: {repr(e)}', exc_info=True) + return None, 0 + + def calc_up_limit(self, inst: Instrument, bar: DailyBar): + settlement = bar.settlement + limit_ratio = str_to_number(self.raw_redis.get(f"LIMITRATIO:{inst.exchange}:{inst.product_code}:{bar.code}")) + price_tick = inst.price_tick + price = price_round(settlement * (Decimal(1) + Decimal(limit_ratio)), price_tick) + return price - price_tick + + def calc_down_limit(self, inst: Instrument, bar: DailyBar): + settlement = bar.settlement + limit_ratio = str_to_number(self.raw_redis.get(f"LIMITRATIO:{inst.exchange}:{inst.product_code}:{bar.code}")) + price_tick = inst.price_tick + price = price_round(settlement * (Decimal(1) - Decimal(limit_ratio)), price_tick) + return price + price_tick diff --git a/qbot/engine/trade/trader/trader/utils/ApiStruct.py b/qbot/engine/trade/trader/trader/utils/ApiStruct.py new file mode 100644 index 00000000..ff58e7a1 --- /dev/null +++ b/qbot/engine/trade/trader/trader/utils/ApiStruct.py @@ -0,0 +1,1984 @@ +# coding=utf-8 +T = dict() +T['TE_RESUME'] = 'int' # 流重传方式 +TERT_RESTART = 0 # 从本交易日开始重传 +TERT_RESUME = 1 # 从上次收到的续传 +TERT_QUICK = 2 # 只传送登录后的流内容 +T['TraderID'] = 'char[21]' # 交易所交易员代码 +T['InvestorID'] = 'char[13]' # 投资者代码 +T['BrokerID'] = 'char[11]' # 经纪公司代码 +T['BrokerAbbr'] = 'char[9]' # 经纪公司简称 +T['BrokerName'] = 'char[81]' # 经纪公司名称 +T['ExchangeInstID'] = 'char[31]' # 合约在交易所的代码 +T['OrderRef'] = 'char[13]' # 报单引用 +T['ParticipantID'] = 'char[11]' # 会员代码 +T['UserID'] = 'char[16]' # 用户代码 +T['Password'] = 'char[41]' # 密码 +T['ClientID'] = 'char[11]' # 交易编码 +T['InstrumentID'] = 'char[31]' # 合约代码 +T['MarketID'] = 'char[31]' # 市场代码 +T['ProductName'] = 'char[21]' # 产品名称 +T['ExchangeID'] = 'char[9]' # 交易所代码 +T['ExchangeName'] = 'char[61]' # 交易所名称 +T['ExchangeAbbr'] = 'char[9]' # 交易所简称 +T['ExchangeFlag'] = 'char[2]' # 交易所标志 +T['MacAddress'] = 'char[21]' # Mac地址 +T['SystemID'] = 'char[21]' # 系统编号 +T['ExchangeProperty'] = 'char' # 交易所属性 +EXP_Normal = '0' # 正常 +EXP_GenOrderByTrade = '1' # 根据成交生成报单 +T['Date'] = 'char[9]' # 日期 +T['Time'] = 'char[9]' # 时间 +T['LongTime'] = 'char[13]' # 长时间 +T['InstrumentName'] = 'char[21]' # 合约名称 +T['SettlementGroupID'] = 'char[9]' # 结算组代码 +T['OrderSysID'] = 'char[21]' # 报单编号 +T['TradeID'] = 'char[21]' # 成交编号 +T['CommandType'] = 'char[65]' # DB命令类型 +T['IPAddress'] = 'char[16]' # IP地址 +T['IPPort'] = 'int' # IP端口 +T['ProductInfo'] = 'char[11]' # 产品信息 +T['ProtocolInfo'] = 'char[11]' # 协议信息 +T['BusinessUnit'] = 'char[21]' # 业务单元 +T['DepositSeqNo'] = 'char[15]' # 出入金流水号 +T['IdentifiedCardNo'] = 'char[51]' # 证件号码 +T['IdCardType'] = 'char' # 证件类型 +ICT_EID = '0' # 组织机构代码 +ICT_IDCard = '1' # 中国公民身份证 +ICT_OfficerIDCard = '2' # 军官证 +ICT_PoliceIDCard = '3' # 警官证 +ICT_SoldierIDCard = '4' # 士兵证 +ICT_HouseholdRegister = '5' # 户口簿 +ICT_Passport = '6' # 护照 +ICT_TaiwanCompatriotIDCard = '7' # 台胞证 +ICT_HomeComingCard = '8' # 回乡证 +ICT_LicenseNo = '9' # 营业执照号 +ICT_TaxNo = 'A' # 税务登记号/当地纳税ID +ICT_HMMainlandTravelPermit = 'B' # 港澳居民来往内地通行证 +ICT_TwMainlandTravelPermit = 'C' # 台湾居民来往大陆通行证 +ICT_DrivingLicense = 'D' # 驾照 +ICT_SocialID = 'F' # 当地社保ID +ICT_LocalID = 'G' # 当地身份证 +ICT_BusinessRegistration = 'H' # 商业登记证 +ICT_HKMCIDCard = 'I' # 港澳永久性居民身份证 +ICT_AccountsPermits = 'J' # 人行开户许可证 +ICT_OtherCard = 'x' # 其他证件 +T['OrderLocalID'] = 'char[13]' # 本地报单编号 +T['UserName'] = 'char[81]' # 用户名称 +T['PartyName'] = 'char[81]' # 参与人名称 +T['ErrorMsg'] = 'char[81]' # 错误信息 +T['FieldName'] = 'char[2049]' # 字段名 +T['FieldContent'] = 'char[2049]' # 字段内容 +T['SystemName'] = 'char[41]' # 系统名称 +T['Content'] = 'char[501]' # 消息正文 +T['InvestorRange'] = 'char' # 投资者范围 +IR_All = '1' # 所有 +IR_Group = '2' # 投资者组 +IR_Single = '3' # 单一投资者 +T['DepartmentRange'] = 'char' # 投资者范围 +DR_All = '1' # 所有 +DR_Group = '2' # 组织架构 +DR_Single = '3' # 单一投资者 +T['DataSyncStatus'] = 'char' # 数据同步状态 +DS_Asynchronous = '1' # 未同步 +DS_Synchronizing = '2' # 同步中 +DS_Synchronized = '3' # 已同步 +T['BrokerDataSyncStatus'] = 'char' # 经纪公司数据同步状态 +BDS_Synchronized = '1' # 已同步 +BDS_Synchronizing = '2' # 同步中 +T['ExchangeConnectStatus'] = 'char' # 交易所连接状态 +ECS_NoConnection = '1' # 没有任何连接 +ECS_QryInstrumentSent = '2' # 已经发出合约查询请求 +ECS_GotInformation = '9' # 已经获取信息 +T['TraderConnectStatus'] = 'char' # 交易所交易员连接状态 +TCS_NotConnected = '1' # 没有任何连接 +TCS_Connected = '2' # 已经连接 +TCS_QryInstrumentSent = '3' # 已经发出合约查询请求 +TCS_SubPrivateFlow = '4' # 订阅私有流 +T['FunctionCode'] = 'char' # 功能代码 +FC_DataAsync = '1' # 数据异步化 +FC_ForceUserLogout = '2' # 强制用户登出 +FC_UserPasswordUpdate = '3' # 变更管理用户口令 +FC_BrokerPasswordUpdate = '4' # 变更经纪公司口令 +FC_InvestorPasswordUpdate = '5' # 变更投资者口令 +FC_OrderInsert = '6' # 报单插入 +FC_OrderAction = '7' # 报单操作 +FC_SyncSystemData = '8' # 同步系统数据 +FC_SyncBrokerData = '9' # 同步经纪公司数据 +FC_BachSyncBrokerData = 'A' # 批量同步经纪公司数据 +FC_SuperQuery = 'B' # 超级查询 +FC_ParkedOrderInsert = 'C' # 预埋报单插入 +FC_ParkedOrderAction = 'D' # 预埋报单操作 +FC_SyncOTP = 'E' # 同步动态令牌 +FC_DeleteOrder = 'F' # 删除未知单 +T['BrokerFunctionCode'] = 'char' # 经纪公司功能代码 +BFC_ForceUserLogout = '1' # 强制用户登出 +BFC_UserPasswordUpdate = '2' # 变更用户口令 +BFC_SyncBrokerData = '3' # 同步经纪公司数据 +BFC_BachSyncBrokerData = '4' # 批量同步经纪公司数据 +BFC_OrderInsert = '5' # 报单插入 +BFC_OrderAction = '6' # 报单操作 +BFC_AllQuery = '7' # 全部查询 +BFC_log = 'a' # 系统功能:登入/登出/修改密码等 +BFC_BaseQry = 'b' # 基本查询:查询基础数据,如合约,交易所等常量 +BFC_TradeQry = 'c' # 交易查询:如查成交,委托 +BFC_Trade = 'd' # 交易功能:报单,撤单 +BFC_Virement = 'e' # 银期转账 +BFC_Risk = 'f' # 风险监控 +BFC_Session = 'g' # 查询/管理:查询会话,踢人等 +BFC_RiskNoticeCtl = 'h' # 风控通知控制 +BFC_RiskNotice = 'i' # 风控通知发送 +BFC_BrokerDeposit = 'j' # 察看经纪公司资金权限 +BFC_QueryFund = 'k' # 资金查询 +BFC_QueryOrder = 'l' # 报单查询 +BFC_QueryTrade = 'm' # 成交查询 +BFC_QueryPosition = 'n' # 持仓查询 +BFC_QueryMarketData = 'o' # 行情查询 +BFC_QueryUserEvent = 'p' # 用户事件查询 +BFC_QueryRiskNotify = 'q' # 风险通知查询 +BFC_QueryFundChange = 'r' # 出入金查询 +BFC_QueryInvestor = 's' # 投资者信息查询 +BFC_QueryTradingCode = 't' # 交易编码查询 +BFC_ForceClose = 'u' # 强平 +BFC_PressTest = 'v' # 压力测试 +BFC_RemainCalc = 'w' # 权益反算 +BFC_NetPositionInd = 'x' # 净持仓保证金指标 +BFC_RiskPredict = 'y' # 风险预算 +BFC_DataExport = 'z' # 数据导出 +BFC_RiskTargetSetup = 'A' # 风控指标设置 +BFC_MarketDataWarn = 'B' # 行情预警 +BFC_QryBizNotice = 'C' # 业务通知查询 +BFC_CfgBizNotice = 'D' # 业务通知模板设置 +BFC_SyncOTP = 'E' # 同步动态令牌 +BFC_SendBizNotice = 'F' # 发送业务通知 +BFC_CfgRiskLevelStd = 'G' # 风险级别标准设置 +BFC_TbCommand = 'H' # 交易终端应急功能 +BFC_DeleteOrder = 'J' # 删除未知单 +BFC_ParkedOrderInsert = 'K' # 预埋报单插入 +BFC_ParkedOrderAction = 'L' # 预埋报单操作 +T['OrderActionStatus'] = 'char' # 报单操作状态 +OAS_Submitted = 'a' # 已经提交 +OAS_Accepted = 'b' # 已经接受 +OAS_Rejected = 'c' # 已经被拒绝 +T['OrderStatus'] = 'char' # 报单状态 +OST_AllTraded = '0' # 全部成交 +OST_PartTradedQueueing = '1' # 部分成交还在队列中 +OST_PartTradedNotQueueing = '2' # 部分成交不在队列中 +OST_NoTradeQueueing = '3' # 未成交还在队列中 +OST_NoTradeNotQueueing = '4' # 未成交不在队列中 +OST_Canceled = '5' # 撤单 +OST_Unknown = 'a' # 未知 +OST_NotTouched = 'b' # 尚未触发 +OST_Touched = 'c' # 已触发 +T['OrderSubmitStatus'] = 'char' # 报单提交状态 +OSS_InsertSubmitted = '0' # 已经提交 +OSS_CancelSubmitted = '1' # 撤单已经提交 +OSS_ModifySubmitted = '2' # 修改已经提交 +OSS_Accepted = '3' # 已经接受 +OSS_InsertRejected = '4' # 报单已经被拒绝 +OSS_CancelRejected = '5' # 撤单已经被拒绝 +OSS_ModifyRejected = '6' # 改单已经被拒绝 +T['PositionDate'] = 'char' # 持仓日期 +PSD_Today = '1' # 今日持仓 +PSD_History = '2' # 历史持仓 +T['PositionDateType'] = 'char' # 持仓日期类型 +PDT_UseHistory = '1' # 使用历史持仓 +PDT_NoUseHistory = '2' # 不使用历史持仓 +T['TradingRole'] = 'char' # 交易角色 +ER_Broker = '1' # 代理 +ER_Host = '2' # 自营 +ER_Maker = '3' # 做市商 +T['ProductClass'] = 'char' # 产品类型 +PC_Futures = '1' # 期货 +PC_Options = '2' # 期货期权 +PC_Combination = '3' # 组合 +PC_Spot = '4' # 即期 +PC_EFP = '5' # 期转现 +PC_SpotOption = '6' # 现货期权 +T['InstLifePhase'] = 'char' # 合约生命周期状态 +IP_NotStart = '0' # 未上市 +IP_Started = '1' # 上市 +IP_Pause = '2' # 停牌 +IP_Expired = '3' # 到期 +T['Direction'] = 'char' # 买卖方向 +D_Buy = '0' # 买 +D_Sell = '1' # 卖 +T['PositionType'] = 'char' # 持仓类型 +PT_Net = '1' # 净持仓 +PT_Gross = '2' # 综合持仓 +T['PosiDirection'] = 'char' # 持仓多空方向 +PD_Net = '1' # 净 +PD_Long = '2' # 多头 +PD_Short = '3' # 空头 +T['SysSettlementStatus'] = 'char' # 系统结算状态 +SS_NonActive = '1' # 不活跃 +SS_Startup = '2' # 启动 +SS_Operating = '3' # 操作 +SS_Settlement = '4' # 结算 +SS_SettlementFinished = '5' # 结算完成 +T['RatioAttr'] = 'char' # 费率属性 +RA_Trade = '0' # 交易费率 +RA_Settlement = '1' # 结算费率 +T['HedgeFlag'] = 'char' # 投机套保标志 +HF_Speculation = '1' # 投机 +HF_Arbitrage = '2' # 套利 +HF_Hedge = '3' # 套保 +T['BillHedgeFlag'] = 'char' # 投机套保标志 +BHF_Speculation = '1' # 投机 +BHF_Arbitrage = '2' # 套利 +BHF_Hedge = '3' # 套保 +T['ClientIDType'] = 'char' # 交易编码类型 +CIDT_Speculation = '1' # 投机 +CIDT_Arbitrage = '2' # 套利 +CIDT_Hedge = '3' # 套保 +T['OrderPriceType'] = 'char' # 报单价格条件 +OPT_AnyPrice = '1' # 任意价 +OPT_LimitPrice = '2' # 限价 +OPT_BestPrice = '3' # 最优价 +OPT_LastPrice = '4' # 最新价 +OPT_LastPricePlusOneTicks = '5' # 最新价浮动上浮1个ticks +OPT_LastPricePlusTwoTicks = '6' # 最新价浮动上浮2个ticks +OPT_LastPricePlusThreeTicks = '7' # 最新价浮动上浮3个ticks +OPT_AskPrice1 = '8' # 卖一价 +OPT_AskPrice1PlusOneTicks = '9' # 卖一价浮动上浮1个ticks +OPT_AskPrice1PlusTwoTicks = 'A' # 卖一价浮动上浮2个ticks +OPT_AskPrice1PlusThreeTicks = 'B' # 卖一价浮动上浮3个ticks +OPT_BidPrice1 = 'C' # 买一价 +OPT_BidPrice1PlusOneTicks = 'D' # 买一价浮动上浮1个ticks +OPT_BidPrice1PlusTwoTicks = 'E' # 买一价浮动上浮2个ticks +OPT_BidPrice1PlusThreeTicks = 'F' # 买一价浮动上浮3个ticks +OPT_FiveLevelPrice = 'G' # 五档价 +T['OffsetFlag'] = 'char' # 开平标志 +OF_Open = '0' # 开仓 +OF_Close = '1' # 平仓 +OF_ForceClose = '2' # 强平 +OF_CloseToday = '3' # 平今 +OF_CloseYesterday = '4' # 平昨 +OF_ForceOff = '5' # 强减 +OF_LocalForceClose = '6' # 本地强平 +T['ForceCloseReason'] = 'char' # 强平原因 +FCC_NotForceClose = '0' # 非强平 +FCC_LackDeposit = '1' # 资金不足 +FCC_ClientOverPositionLimit = '2' # 客户超仓 +FCC_MemberOverPositionLimit = '3' # 会员超仓 +FCC_NotMultiple = '4' # 持仓非整数倍 +FCC_Violation = '5' # 违规 +FCC_Other = '6' # 其它 +FCC_PersonDeliv = '7' # 自然人临近交割 +T['OrderType'] = 'char' # 报单类型 +ORDT_Normal = '0' # 正常 +ORDT_DeriveFromQuote = '1' # 报价衍生 +ORDT_DeriveFromCombination = '2' # 组合衍生 +ORDT_Combination = '3' # 组合报单 +ORDT_ConditionalOrder = '4' # 条件单 +ORDT_Swap = '5' # 互换单 +T['TimeCondition'] = 'char' # 有效期类型 +TC_IOC = '1' # 立即完成,否则撤销 +TC_GFS = '2' # 本节有效 +TC_GFD = '3' # 当日有效 +TC_GTD = '4' # 指定日期前有效 +TC_GTC = '5' # 撤销前有效 +TC_GFA = '6' # 集合竞价有效 +T['VolumeCondition'] = 'char' # 成交量类型 +VC_AV = '1' # 任何数量 +VC_MV = '2' # 最小数量 +VC_CV = '3' # 全部数量 +T['ContingentCondition'] = 'char' # 触发条件 +CC_Immediately = '1' # 立即 +CC_Touch = '2' # 止损 +CC_TouchProfit = '3' # 止赢 +CC_ParkedOrder = '4' # 预埋单 +CC_LastPriceGreaterThanStopPrice = '5' # 最新价大于条件价 +CC_LastPriceGreaterEqualStopPrice = '6' # 最新价大于等于条件价 +CC_LastPriceLesserThanStopPrice = '7' # 最新价小于条件价 +CC_LastPriceLesserEqualStopPrice = '8' # 最新价小于等于条件价 +CC_AskPriceGreaterThanStopPrice = '9' # 卖一价大于条件价 +CC_AskPriceGreaterEqualStopPrice = 'A' # 卖一价大于等于条件价 +CC_AskPriceLesserThanStopPrice = 'B' # 卖一价小于条件价 +CC_AskPriceLesserEqualStopPrice = 'C' # 卖一价小于等于条件价 +CC_BidPriceGreaterThanStopPrice = 'D' # 买一价大于条件价 +CC_BidPriceGreaterEqualStopPrice = 'E' # 买一价大于等于条件价 +CC_BidPriceLesserThanStopPrice = 'F' # 买一价小于条件价 +CC_BidPriceLesserEqualStopPrice = 'H' # 买一价小于等于条件价 +T['ActionFlag'] = 'char' # 操作标志 +AF_Delete = '0' # 删除 +AF_Modify = '3' # 修改 +T['TradingRight'] = 'char' # 交易权限 +TR_Allow = '0' # 可以交易 +TR_CloseOnly = '1' # 只能平仓 +TR_Forbidden = '2' # 不能交易 +T['OrderSource'] = 'char' # 报单来源 +OSRC_Participant = '0' # 来自参与者 +OSRC_Administrator = '1' # 来自管理员 +T['TradeType'] = 'char' # 成交类型 +TRDT_SplitCombination = '#' # 组合持仓拆分为单一持仓,初始化不应包含该类型的持仓 +TRDT_Common = '0' # 普通成交 +TRDT_OptionsExecution = '1' # 期权执行 +TRDT_OTC = '2' # OTC成交 +TRDT_EFPDerived = '3' # 期转现衍生成交 +TRDT_CombinationDerived = '4' # 组合衍生成交 +T['PriceSource'] = 'char' # 成交价来源 +PSRC_LastPrice = '0' # 前成交价 +PSRC_Buy = '1' # 买委托价 +PSRC_Sell = '2' # 卖委托价 +T['InstrumentStatus'] = 'char' # 合约交易状态 +IS_BeforeTrading = '0' # 开盘前 +IS_NoTrading = '1' # 非交易 +IS_Continous = '2' # 连续交易 +IS_AuctionOrdering = '3' # 集合竞价报单 +IS_AuctionBalance = '4' # 集合竞价价格平衡 +IS_AuctionMatch = '5' # 集合竞价撮合 +IS_Closed = '6' # 收盘 +T['InstStatusEnterReason'] = 'char' # 品种进入交易状态原因 +IER_Automatic = '1' # 自动切换 +IER_Manual = '2' # 手动切换 +IER_Fuse = '3' # 熔断 +T['OrderActionRef'] = 'int' # 报单操作引用 +T['InstallCount'] = 'int' # 安装数量 +T['InstallID'] = 'int' # 安装编号 +T['ErrorID'] = 'int' # 错误代码 +T['SettlementID'] = 'int' # 结算编号 +T['Volume'] = 'int' # 数量 +T['FrontID'] = 'int' # 前置编号 +T['SessionID'] = 'int' # 会话编号 +T['SequenceNo'] = 'int' # 序号 +T['CommandNo'] = 'int' # DB命令序号 +T['Millisec'] = 'int' # 时间(毫秒) +T['VolumeMultiple'] = 'int' # 合约数量乘数 +T['TradingSegmentSN'] = 'int' # 交易阶段编号 +T['RequestID'] = 'int' # 请求编号 +T['Year'] = 'int' # 年份 +T['Month'] = 'int' # 月份 +T['Bool'] = 'int' # 布尔型 +T['Price'] = 'double' # 价格 +T['CombOffsetFlag'] = 'char[5]' # 组合开平标志 +T['CombHedgeFlag'] = 'char[5]' # 组合投机套保标志 +T['Ratio'] = 'double' # 比率 +T['Money'] = 'double' # 资金 +T['LargeVolume'] = 'double' # 大额数量 +T['SequenceSeries'] = 'short' # 序列系列号 +T['CommPhaseNo'] = 'short' # 通讯时段编号 +T['SequenceLabel'] = 'char[2]' # 序列编号 +T['UnderlyingMultiple'] = 'double' # 基础商品乘数 +T['Priority'] = 'int' # 优先级 +T['ContractCode'] = 'char[41]' # 合同编号 +T['City'] = 'char[51]' # 市 +T['IsStock'] = 'char[11]' # 是否股民 +T['Channel'] = 'char[51]' # 渠道 +T['Address'] = 'char[101]' # 通讯地址 +T['ZipCode'] = 'char[7]' # 邮政编码 +T['Telephone'] = 'char[41]' # 联系电话 +T['Fax'] = 'char[41]' # 传真 +T['Mobile'] = 'char[41]' # 手机 +T['EMail'] = 'char[41]' # 电子邮件 +T['Memo'] = 'char[161]' # 备注 +T['CompanyCode'] = 'char[51]' # 企业代码 +T['Website'] = 'char[51]' # 网站地址 +T['TaxNo'] = 'char[31]' # 税务登记号 +T['BatchStatus'] = 'char' # 处理状态 +BS_NoUpload = '1' # 未上传 +BS_Uploaded = '2' # 已上传 +BS_Failed = '3' # 审核失败 +T['PropertyID'] = 'char[33]' # 属性代码 +T['PropertyName'] = 'char[65]' # 属性名称 +T['LicenseNo'] = 'char[51]' # 营业执照号 +T['AgentID'] = 'char[13]' # 经纪人代码 +T['AgentName'] = 'char[41]' # 经纪人名称 +T['AgentGroupID'] = 'char[13]' # 经纪人组代码 +T['AgentGroupName'] = 'char[41]' # 经纪人组名称 +T['ReturnStyle'] = 'char' # 按品种返还方式 +RS_All = '1' # 按所有品种 +RS_ByProduct = '2' # 按品种 +T['ReturnPattern'] = 'char' # 返还模式 +RP_ByVolume = '1' # 按成交手数 +RP_ByFeeOnHand = '2' # 按留存手续费 +T['ReturnLevel'] = 'char' # 返还级别 +RL_Level1 = '1' # 级别1 +RL_Level2 = '2' # 级别2 +RL_Level3 = '3' # 级别3 +RL_Level4 = '4' # 级别4 +RL_Level5 = '5' # 级别5 +RL_Level6 = '6' # 级别6 +RL_Level7 = '7' # 级别7 +RL_Level8 = '8' # 级别8 +RL_Level9 = '9' # 级别9 +T['ReturnStandard'] = 'char' # 返还标准 +RSD_ByPeriod = '1' # 分阶段返还 +RSD_ByStandard = '2' # 按某一标准 +T['MortgageType'] = 'char' # 质押类型 +MT_Out = '0' # 质出 +MT_In = '1' # 质入 +T['InvestorSettlementParamID'] = 'char' # 投资者结算参数代码 +ISPI_MortgageRatio = '4' # 质押比例 +ISPI_MarginWay = '5' # 保证金算法 +ISPI_BillDeposit = '9' # 结算单结存是否包含质押 +T['ExchangeSettlementParamID'] = 'char' # 交易所结算参数代码 +ESPI_MortgageRatio = '1' # 质押比例 +ESPI_OtherFundItem = '2' # 分项资金导入项 +ESPI_OtherFundImport = '3' # 分项资金入交易所出入金 +ESPI_CFFEXMinPrepa = '6' # 中金所开户最低可用金额 +ESPI_CZCESettlementType = '7' # 郑商所结算方式 +ESPI_ExchDelivFeeMode = '9' # 交易所交割手续费收取方式 +ESPI_DelivFeeMode = '0' # 投资者交割手续费收取方式 +ESPI_CZCEComMarginType = 'A' # 郑商所组合持仓保证金收取方式 +ESPI_DceComMarginType = 'B' # 大商所套利保证金是否优惠 +ESPI_OptOutDisCountRate = 'a' # 虚值期权保证金优惠比率 +ESPI_OptMiniGuarantee = 'b' # 最低保障系数 +T['SystemParamID'] = 'char' # 系统参数代码 +SPI_InvestorIDMinLength = '1' # 投资者代码最小长度 +SPI_AccountIDMinLength = '2' # 投资者帐号代码最小长度 +SPI_UserRightLogon = '3' # 投资者开户默认登录权限 +SPI_SettlementBillTrade = '4' # 投资者交易结算单成交汇总方式 +SPI_TradingCode = '5' # 统一开户更新交易编码方式 +SPI_CheckFund = '6' # 结算是否判断存在未复核的出入金和分项资金 +SPI_CommModelRight = '7' # 是否启用手续费模板数据权限 +SPI_MarginModelRight = '9' # 是否启用保证金率模板数据权限 +SPI_IsStandardActive = '8' # 是否规范用户才能激活 +SPI_UploadSettlementFile = 'U' # 上传的交易所结算文件路径 +SPI_DownloadCSRCFile = 'D' # 上报保证金监控中心文件路径 +SPI_SettlementBillFile = 'S' # 生成的结算单文件路径 +SPI_CSRCOthersFile = 'C' # 证监会文件标识 +SPI_InvestorPhoto = 'P' # 投资者照片路径 +SPI_CSRCData = 'R' # 全结经纪公司上传文件路径 +SPI_InvestorPwdModel = 'I' # 开户密码录入方式 +SPI_CFFEXInvestorSettleFile = 'F' # 投资者中金所结算文件下载路径 +SPI_InvestorIDType = 'a' # 投资者代码编码方式 +SPI_FreezeMaxReMain = 'r' # 休眠户最高权益 +SPI_IsSync = 'A' # 手续费相关操作实时上场开关 +SPI_RelieveOpenLimit = 'O' # 解除开仓权限限制 +SPI_IsStandardFreeze = 'X' # 是否规范用户才能休眠 +SPI_CZCENormalProductHedge = 'B' # 郑商所是否开放所有品种套保交易 +T['TradeParamID'] = 'char' # 交易系统参数代码 +TPID_EncryptionStandard = 'E' # 系统加密算法 +TPID_RiskMode = 'R' # 系统风险算法 +TPID_RiskModeGlobal = 'G' # 系统风险算法是否全局 0-否 1-是 +TPID_modeEncode = 'P' # 密码加密算法 +TPID_tickMode = 'T' # 价格小数位数参数 +TPID_SingleUserSessionMaxNum = 'S' # 用户最大会话数 +TPID_LoginFailMaxNum = 'L' # 最大连续登录失败数 +TPID_IsAuthForce = 'A' # 是否强制认证 +TPID_IsPosiFreeze = 'F' # 是否冻结证券持仓 +TPID_IsPosiLimit = 'M' # 是否限仓 +TPID_ForQuoteTimeInterval = 'Q' # 郑商所询价时间间隔 +T['SettlementParamValue'] = 'char[256]' # 参数代码值 +T['CounterID'] = 'char[33]' # 计数器代码 +T['InvestorGroupName'] = 'char[41]' # 投资者分组名称 +T['BrandCode'] = 'char[257]' # 牌号 +T['Warehouse'] = 'char[257]' # 仓库 +T['ProductDate'] = 'char[41]' # 产期 +T['Grade'] = 'char[41]' # 等级 +T['Classify'] = 'char[41]' # 类别 +T['Position'] = 'char[41]' # 货位 +T['Yieldly'] = 'char[41]' # 产地 +T['Weight'] = 'char[41]' # 公定重量 +T['SubEntryFundNo'] = 'int' # 分项资金流水号 +T['FileID'] = 'char' # 文件标识 +FI_SettlementFund = 'F' # 资金数据 +FI_Trade = 'T' # 成交数据 +FI_InvestorPosition = 'P' # 投资者持仓数据 +FI_SubEntryFund = 'O' # 投资者分项资金数据 +FI_CZCECombinationPos = 'C' # 组合持仓数据 +FI_CSRCData = 'R' # 上报保证金监控中心数据 +FI_CZCEClose = 'L' # 郑商所平仓了结数据 +FI_CZCENoClose = 'N' # 郑商所非平仓了结数据 +FI_PositionDtl = 'D' # 持仓明细数据 +FI_OptionStrike = 'S' # 期权执行文件 +FI_SettlementPriceComparison = 'M' # 结算价比对文件 +FI_NonTradePosChange = 'B' # 上期所非持仓变动明细 +T['FileName'] = 'char[257]' # 文件名称 +T['FileType'] = 'char' # 文件上传类型 +FUT_Settlement = '0' # 结算 +FUT_Check = '1' # 核对 +T['FileFormat'] = 'char' # 文件格式 +FFT_Txt = '0' # 文本文件(.txt) +FFT_Zip = '1' # 压缩文件(.zip) +FFT_DBF = '2' # DBF文件(.dbf) +T['FileUploadStatus'] = 'char' # 文件状态 +FUS_SucceedUpload = '1' # 上传成功 +FUS_FailedUpload = '2' # 上传失败 +FUS_SucceedLoad = '3' # 导入成功 +FUS_PartSucceedLoad = '4' # 导入部分成功 +FUS_FailedLoad = '5' # 导入失败 +T['TransferDirection'] = 'char' # 移仓方向 +TD_Out = '0' # 移出 +TD_In = '1' # 移入 +T['UploadMode'] = 'char[21]' # 上传文件类型 +T['AccountID'] = 'char[13]' # 投资者帐号 +T['BankFlag'] = 'char[4]' # 银行统一标识类型 +T['BankAccount'] = 'char[41]' # 银行账户 +T['OpenName'] = 'char[61]' # 银行账户的开户人名称 +T['OpenBank'] = 'char[101]' # 银行账户的开户行 +T['BankName'] = 'char[101]' # 银行名称 +T['PublishPath'] = 'char[257]' # 发布路径 +T['OperatorID'] = 'char[65]' # 操作员代码 +T['MonthCount'] = 'int' # 月份数量 +T['AdvanceMonthArray'] = 'char[13]' # 月份提前数组 +T['DateExpr'] = 'char[1025]' # 日期表达式 +T['InstrumentIDExpr'] = 'char[41]' # 合约代码表达式 +T['InstrumentNameExpr'] = 'char[41]' # 合约名称表达式 +T['SpecialCreateRule'] = 'char' # 特殊的创建规则 +SC_NoSpecialRule = '0' # 没有特殊创建规则 +SC_NoSpringFestival = '1' # 不包含春节 +T['BasisPriceType'] = 'char' # 挂牌基准价类型 +IPT_LastSettlement = '1' # 上一合约结算价 +IPT_LaseClose = '2' # 上一合约收盘价 +T['ProductLifePhase'] = 'char' # 产品生命周期状态 +PLP_Active = '1' # 活跃 +PLP_NonActive = '2' # 不活跃 +PLP_Canceled = '3' # 注销 +T['DeliveryMode'] = 'char' # 交割方式 +DM_CashDeliv = '1' # 现金交割 +DM_CommodityDeliv = '2' # 实物交割 +T['LogLevel'] = 'char[33]' # 日志级别 +T['ProcessName'] = 'char[257]' # 存储过程名称 +T['OperationMemo'] = 'char[1025]' # 操作摘要 +T['FundIOType'] = 'char' # 出入金类型 +FIOT_FundIO = '1' # 出入金 +FIOT_Transfer = '2' # 银期转帐 +FIOT_SwapCurrency = '3' # 银期换汇 +T['FundType'] = 'char' # 资金类型 +FT_Deposite = '1' # 银行存款 +FT_ItemFund = '2' # 分项资金 +FT_Company = '3' # 公司调整 +FT_InnerTransfer = '4' # 资金内转 +T['FundDirection'] = 'char' # 出入金方向 +FD_In = '1' # 入金 +FD_Out = '2' # 出金 +T['FundStatus'] = 'char' # 资金状态 +FS_Record = '1' # 已录入 +FS_Check = '2' # 已复核 +FS_Charge = '3' # 已冲销 +T['BillNo'] = 'char[15]' # 票据号 +T['BillName'] = 'char[33]' # 票据名称 +T['PublishStatus'] = 'char' # 发布状态 +PS_None = '1' # 未发布 +PS_Publishing = '2' # 正在发布 +PS_Published = '3' # 已发布 +T['EnumValueID'] = 'char[65]' # 枚举值代码 +T['EnumValueType'] = 'char[33]' # 枚举值类型 +T['EnumValueLabel'] = 'char[65]' # 枚举值名称 +T['EnumValueResult'] = 'char[33]' # 枚举值结果 +T['SystemStatus'] = 'char' # 系统状态 +ES_NonActive = '1' # 不活跃 +ES_Startup = '2' # 启动 +ES_Initialize = '3' # 交易开始初始化 +ES_Initialized = '4' # 交易完成初始化 +ES_Close = '5' # 收市开始 +ES_Closed = '6' # 收市完成 +ES_Settlement = '7' # 结算 +T['SettlementStatus'] = 'char' # 结算状态 +STS_Initialize = '0' # 初始 +STS_Settlementing = '1' # 结算中 +STS_Settlemented = '2' # 已结算 +STS_Finished = '3' # 结算完成 +T['RangeIntType'] = 'char[33]' # 限定值类型 +T['RangeIntFrom'] = 'char[33]' # 限定值下限 +T['RangeIntTo'] = 'char[33]' # 限定值上限 +T['FunctionID'] = 'char[25]' # 功能代码 +T['FunctionValueCode'] = 'char[257]' # 功能编码 +T['FunctionName'] = 'char[65]' # 功能名称 +T['RoleID'] = 'char[11]' # 角色编号 +T['RoleName'] = 'char[41]' # 角色名称 +T['Description'] = 'char[401]' # 描述 +T['CombineID'] = 'char[25]' # 组合编号 +T['CombineType'] = 'char[25]' # 组合类型 +T['InvestorType'] = 'char' # 投资者类型 +CT_Person = '0' # 自然人 +CT_Company = '1' # 法人 +CT_Fund = '2' # 投资基金 +CT_SpecialOrgan = '3' # 特殊法人 +CT_Asset = '4' # 资管户 +T['BrokerType'] = 'char' # 经纪公司类型 +BT_Trade = '0' # 交易会员 +BT_TradeSettle = '1' # 交易结算会员 +T['RiskLevel'] = 'char' # 风险等级 +FAS_Low = '1' # 低风险客户 +FAS_Normal = '2' # 普通客户 +FAS_Focus = '3' # 关注客户 +FAS_Risk = '4' # 风险客户 +T['FeeAcceptStyle'] = 'char' # 手续费收取方式 +FAS_ByTrade = '1' # 按交易收取 +FAS_ByDeliv = '2' # 按交割收取 +FAS_None = '3' # 不收 +FAS_FixFee = '4' # 按指定手续费收取 +T['PasswordType'] = 'char' # 密码类型 +PWDT_Trade = '1' # 交易密码 +PWDT_Account = '2' # 资金密码 +T['Algorithm'] = 'char' # 盈亏算法 +AG_All = '1' # 浮盈浮亏都计算 +AG_OnlyLost = '2' # 浮盈不计,浮亏计 +AG_OnlyGain = '3' # 浮盈计,浮亏不计 +AG_None = '4' # 浮盈浮亏都不计算 +T['IncludeCloseProfit'] = 'char' # 是否包含平仓盈利 +ICP_Include = '0' # 包含平仓盈利 +ICP_NotInclude = '2' # 不包含平仓盈利 +T['AllWithoutTrade'] = 'char' # 是否受可提比例限制 +AWT_Enable = '0' # 无仓无成交不受可提比例限制 +AWT_Disable = '2' # 受可提比例限制 +AWT_NoHoldEnable = '3' # 无仓不受可提比例限制 +T['Comment'] = 'char[31]' # 盈亏算法说明 +T['Version'] = 'char[4]' # 版本号 +T['TradeCode'] = 'char[7]' # 交易代码 +T['TradeDate'] = 'char[9]' # 交易日期 +T['TradeTime'] = 'char[9]' # 交易时间 +T['TradeSerial'] = 'char[9]' # 发起方流水号 +T['TradeSerialNo'] = 'int' # 发起方流水号 +T['FutureID'] = 'char[11]' # 期货公司代码 +T['BankID'] = 'char[4]' # 银行代码 +T['BankBrchID'] = 'char[5]' # 银行分中心代码 +T['BankBranchID'] = 'char[11]' # 分中心代码 +T['OperNo'] = 'char[17]' # 交易柜员 +T['DeviceID'] = 'char[3]' # 渠道标志 +T['RecordNum'] = 'char[7]' # 记录数 +T['FutureAccount'] = 'char[22]' # 期货资金账号 +T['FuturePwdFlag'] = 'char' # 资金密码核对标志 +FPWD_UnCheck = '0' # 不核对 +FPWD_Check = '1' # 核对 +T['TransferType'] = 'char' # 银期转账类型 +TT_BankToFuture = '0' # 银行转期货 +TT_FutureToBank = '1' # 期货转银行 +T['FutureAccPwd'] = 'char[17]' # 期货资金密码 +T['CurrencyCode'] = 'char[4]' # 币种 +T['RetCode'] = 'char[5]' # 响应代码 +T['RetInfo'] = 'char[129]' # 响应信息 +T['TradeAmt'] = 'char[20]' # 银行总余额 +T['UseAmt'] = 'char[20]' # 银行可用余额 +T['FetchAmt'] = 'char[20]' # 银行可取余额 +T['TransferValidFlag'] = 'char' # 转账有效标志 +TVF_Invalid = '0' # 无效或失败 +TVF_Valid = '1' # 有效 +TVF_Reverse = '2' # 冲正 +T['CertCode'] = 'char[21]' # 证件号码 +T['Reason'] = 'char' # 事由 +RN_CD = '0' # 错单 +RN_ZT = '1' # 资金在途 +RN_QT = '2' # 其它 +T['FundProjectID'] = 'char[5]' # 资金项目编号 +T['Sex'] = 'char' # 性别 +SEX_None = '0' # 未知 +SEX_Man = '1' # 男 +SEX_Woman = '2' # 女 +T['Profession'] = 'char[101]' # 职业 +T['National'] = 'char[31]' # 国籍 +T['Province'] = 'char[51]' # 省 +T['Region'] = 'char[16]' # 区 +T['Country'] = 'char[16]' # 国家 +T['LicenseNO'] = 'char[33]' # 营业执照 +T['CompanyType'] = 'char[16]' # 企业性质 +T['BusinessScope'] = 'char[1001]' # 经营范围 +T['CapitalCurrency'] = 'char[4]' # 注册资本币种 +T['UserType'] = 'char' # 用户类型 +UT_Investor = '0' # 投资者 +UT_Operator = '1' # 操作员 +UT_SuperUser = '2' # 管理员 +T['RateType'] = 'char' # 费率类型 +RATETYPE_MarginRate = '2' # 保证金率 +T['NoteType'] = 'char' # 通知类型 +NOTETYPE_TradeSettleBill = '1' # 交易结算单 +NOTETYPE_TradeSettleMonth = '2' # 交易结算月报 +NOTETYPE_CallMarginNotes = '3' # 追加保证金通知书 +NOTETYPE_ForceCloseNotes = '4' # 强行平仓通知书 +NOTETYPE_TradeNotes = '5' # 成交通知书 +NOTETYPE_DelivNotes = '6' # 交割通知书 +T['SettlementStyle'] = 'char' # 结算单方式 +SBS_Day = '1' # 逐日盯市 +SBS_Volume = '2' # 逐笔对冲 +T['BrokerDNS'] = 'char[256]' # 域名 +T['Sentence'] = 'char[501]' # 语句 +T['SettlementBillType'] = 'char' # 结算单类型 +ST_Day = '0' # 日报 +ST_Month = '1' # 月报 +T['UserRightType'] = 'char' # 客户权限类型 +URT_Logon = '1' # 登录 +URT_Transfer = '2' # 银期转帐 +URT_EMail = '3' # 邮寄结算单 +URT_Fax = '4' # 传真结算单 +URT_ConditionOrder = '5' # 条件单 +T['MarginPriceType'] = 'char' # 保证金价格类型 +MPT_PreSettlementPrice = '1' # 昨结算价 +MPT_SettlementPrice = '2' # 最新价 +MPT_AveragePrice = '3' # 成交均价 +MPT_OpenPrice = '4' # 开仓价 +T['BillGenStatus'] = 'char' # 结算单生成状态 +BGS_None = '0' # 未生成 +BGS_NoGenerated = '1' # 生成中 +BGS_Generated = '2' # 已生成 +T['AlgoType'] = 'char' # 算法类型 +AT_HandlePositionAlgo = '1' # 持仓处理算法 +AT_FindMarginRateAlgo = '2' # 寻找保证金率算法 +T['HandlePositionAlgoID'] = 'char' # 持仓处理算法编号 +HPA_Base = '1' # 基本 +HPA_DCE = '2' # 大连商品交易所 +HPA_CZCE = '3' # 郑州商品交易所 +T['FindMarginRateAlgoID'] = 'char' # 寻找保证金率算法编号 +FMRA_Base = '1' # 基本 +FMRA_DCE = '2' # 大连商品交易所 +FMRA_CZCE = '3' # 郑州商品交易所 +T['HandleTradingAccountAlgoID'] = 'char' # 资金处理算法编号 +HTAA_Base = '1' # 基本 +HTAA_DCE = '2' # 大连商品交易所 +HTAA_CZCE = '3' # 郑州商品交易所 +T['PersonType'] = 'char' # 联系人类型 +PST_Order = '1' # 指定下单人 +PST_Open = '2' # 开户授权人 +PST_Fund = '3' # 资金调拨人 +PST_Settlement = '4' # 结算单确认人 +PST_Company = '5' # 法人 +PST_Corporation = '6' # 法人代表 +PST_LinkMan = '7' # 投资者联系人 +PST_Ledger = '8' # 分户管理资产负责人 +PST_Trustee = '9' # 托(保)管人 +PST_TrusteeCorporation = 'A' # 托(保)管机构法人代表 +PST_TrusteeOpen = 'B' # 托(保)管机构开户授权人 +PST_TrusteeContact = 'C' # 托(保)管机构联系人 +PST_ForeignerRefer = 'D' # 境外自然人参考证件 +PST_CorporationRefer = 'E' # 法人代表参考证件 +T['QueryInvestorRange'] = 'char' # 查询范围 +QIR_All = '1' # 所有 +QIR_Group = '2' # 查询分类 +QIR_Single = '3' # 单一投资者 +T['InvestorRiskStatus'] = 'char' # 投资者风险状态 +IRS_Normal = '1' # 正常 +IRS_Warn = '2' # 警告 +IRS_Call = '3' # 追保 +IRS_Force = '4' # 强平 +IRS_Exception = '5' # 异常 +T['LegID'] = 'int' # 单腿编号 +T['LegMultiple'] = 'int' # 单腿乘数 +T['ImplyLevel'] = 'int' # 派生层数 +T['ClearAccount'] = 'char[33]' # 结算账户 +T['OrganNO'] = 'char[6]' # 结算账户 +T['ClearbarchID'] = 'char[6]' # 结算账户联行号 +T['UserEventType'] = 'char' # 用户事件类型 +UET_Login = '1' # 登录 +UET_Logout = '2' # 登出 +UET_Trading = '3' # 交易成功 +UET_TradingError = '4' # 交易失败 +UET_UpdatePassword = '5' # 修改密码 +UET_Authenticate = '6' # 客户端认证 +UET_Other = '9' # 其他 +T['UserEventInfo'] = 'char[1025]' # 用户事件信息 +T['CloseStyle'] = 'char' # 平仓方式 +ICS_Close = '0' # 先开先平 +ICS_CloseToday = '1' # 先平今再平昨 +T['StatMode'] = 'char' # 统计方式 +SM_Non = '0' # ---- +SM_Instrument = '1' # 按合约统计 +SM_Product = '2' # 按产品统计 +SM_Investor = '3' # 按投资者统计 +T['ParkedOrderStatus'] = 'char' # 预埋单状态 +PAOS_NotSend = '1' # 未发送 +PAOS_Send = '2' # 已发送 +PAOS_Deleted = '3' # 已删除 +T['ParkedOrderID'] = 'char[13]' # 预埋报单编号 +T['ParkedOrderActionID'] = 'char[13]' # 预埋撤单编号 +T['VirDealStatus'] = 'char' # 处理状态 +VDS_Dealing = '1' # 正在处理 +VDS_DeaclSucceed = '2' # 处理成功 +T['OrgSystemID'] = 'char' # 原有系统代码 +ORGS_Standard = '0' # 综合交易平台 +ORGS_ESunny = '1' # 易盛系统 +ORGS_KingStarV6 = '2' # 金仕达V6系统 +T['VirTradeStatus'] = 'char' # 交易状态 +VTS_NaturalDeal = '0' # 正常处理中 +VTS_SucceedEnd = '1' # 成功结束 +VTS_FailedEND = '2' # 失败结束 +VTS_Exception = '3' # 异常中 +VTS_ManualDeal = '4' # 已人工异常处理 +VTS_MesException = '5' # 通讯异常 ,请人工处理 +VTS_SysException = '6' # 系统出错,请人工处理 +T['VirBankAccType'] = 'char' # 银行帐户类型 +VBAT_BankBook = '1' # 存折 +VBAT_BankCard = '2' # 储蓄卡 +VBAT_CreditCard = '3' # 信用卡 +T['VirementStatus'] = 'char' # 银行帐户类型 +VMS_Natural = '0' # 正常 +VMS_Canceled = '9' # 销户 +T['VirementAvailAbility'] = 'char' # 有效标志 +VAA_NoAvailAbility = '0' # 未确认 +VAA_AvailAbility = '1' # 有效 +VAA_Repeal = '2' # 冲正 +T['VirementTradeCode'] = 'char[7]' # 交易代码 +VTC_BankBankToFuture = '102001' # 银行发起银行资金转期货 +VTC_BankFutureToBank = '102002' # 银行发起期货资金转银行 +VTC_FutureBankToFuture = '202001' # 期货发起银行资金转期货 +VTC_FutureFutureToBank = '202002' # 期货发起期货资金转银行 +T['PhotoTypeName'] = 'char[41]' # 影像类型名称 +T['PhotoTypeID'] = 'char[5]' # 影像类型代码 +T['PhotoName'] = 'char[161]' # 影像名称 +T['TopicID'] = 'int' # 主题代码 +T['ReportTypeID'] = 'char[3]' # 交易报告类型标识 +T['CharacterID'] = 'char[5]' # 交易特征代码 +T['AMLParamID'] = 'char[21]' # 参数代码 +T['AMLInvestorType'] = 'char[3]' # 投资者类型 +T['AMLIdCardType'] = 'char[3]' # 证件类型 +T['AMLTradeDirect'] = 'char[3]' # 资金进出方向 +T['AMLTradeModel'] = 'char[3]' # 资金进出方式 +T['AMLParamID'] = 'char[21]' # 参数代码 +T['AMLOpParamValue'] = 'double' # 业务参数代码值 +T['AMLCustomerCardType'] = 'char[81]' # 客户身份证件/证明文件类型 +T['AMLInstitutionName'] = 'char[65]' # 金融机构网点名称 +T['AMLDistrictID'] = 'char[7]' # 金融机构网点所在地区行政区划代码 +T['AMLRelationShip'] = 'char[3]' # 金融机构网点与大额交易的关系 +T['AMLInstitutionType'] = 'char[3]' # 金融机构网点代码类型 +T['AMLInstitutionID'] = 'char[13]' # 金融机构网点代码 +T['AMLAccountType'] = 'char[5]' # 账户类型 +T['AMLTradingType'] = 'char[7]' # 交易方式 +T['AMLTransactClass'] = 'char[7]' # 涉外收支交易分类与代码 +T['AMLCapitalIO'] = 'char[3]' # 资金收付标识 +T['AMLSite'] = 'char[10]' # 交易地点 +T['AMLCapitalPurpose'] = 'char[129]' # 资金用途 +T['AMLReportType'] = 'char[2]' # 报文类型 +T['AMLSerialNo'] = 'char[5]' # 编号 +T['AMLStatus'] = 'char[2]' # 状态 +T['AMLGenStatus'] = 'char' # Aml生成方式 +GEN_Program = '0' # 程序生成 +GEN_HandWork = '1' # 人工生成 +T['AMLSeqCode'] = 'char[65]' # 业务标识号 +T['AMLFileName'] = 'char[257]' # AML文件名 +T['AMLMoney'] = 'double' # 反洗钱资金 +T['AMLFileAmount'] = 'int' # 反洗钱资金 +T['CFMMCKey'] = 'char[21]' # 密钥类型(保证金监管) +T['CFMMCToken'] = 'char[21]' # 令牌类型(保证金监管) +T['CFMMCKeyKind'] = 'char' # 动态密钥类别(保证金监管) +CFMMCKK_REQUEST = 'R' # 主动请求更新 +CFMMCKK_AUTO = 'A' # CFMMC自动更新 +CFMMCKK_MANUAL = 'M' # CFMMC手动更新 +T['AMLReportName'] = 'char[81]' # 报文名称 +T['IndividualName'] = 'char[51]' # 个人姓名 +T['CurrencyID'] = 'char[4]' # 币种代码 +T['CustNumber'] = 'char[36]' # 客户编号 +T['OrganCode'] = 'char[36]' # 机构编码 +T['OrganName'] = 'char[71]' # 机构名称 +T['SuperOrganCode'] = 'char[12]' # 上级机构编码,即期货公司总部、银行总行 +T['SubBranchID'] = 'char[31]' # 分支机构 +T['SubBranchName'] = 'char[71]' # 分支机构名称 +T['BranchNetCode'] = 'char[31]' # 机构网点号 +T['BranchNetName'] = 'char[71]' # 机构网点名称 +T['OrganFlag'] = 'char[2]' # 机构标识 +T['BankCodingForFuture'] = 'char[33]' # 银行对期货公司的编码 +T['BankReturnCode'] = 'char[7]' # 银行对返回码的定义 +T['PlateReturnCode'] = 'char[5]' # 银期转帐平台对返回码的定义 +T['BankSubBranchID'] = 'char[31]' # 银行分支机构编码 +T['FutureBranchID'] = 'char[31]' # 期货分支机构编码 +T['ReturnCode'] = 'char[7]' # 返回代码 +T['OperatorCode'] = 'char[17]' # 操作员 +T['ClearDepID'] = 'char[6]' # 机构结算帐户机构号 +T['ClearBrchID'] = 'char[6]' # 机构结算帐户联行号 +T['ClearName'] = 'char[71]' # 机构结算帐户名称 +T['BankAccountName'] = 'char[71]' # 银行帐户名称 +T['InvDepID'] = 'char[6]' # 机构投资人账号机构号 +T['InvBrchID'] = 'char[6]' # 机构投资人联行号 +T['MessageFormatVersion'] = 'char[36]' # 信息格式版本 +T['Digest'] = 'char[36]' # 摘要 +T['AuthenticData'] = 'char[129]' # 认证数据 +T['PasswordKey'] = 'char[129]' # 密钥 +T['FutureAccountName'] = 'char[129]' # 期货帐户名称 +T['MobilePhone'] = 'char[21]' # 手机 +T['FutureMainKey'] = 'char[129]' # 期货公司主密钥 +T['FutureWorkKey'] = 'char[129]' # 期货公司工作密钥 +T['FutureTransKey'] = 'char[129]' # 期货公司传输密钥 +T['BankMainKey'] = 'char[129]' # 银行主密钥 +T['BankWorkKey'] = 'char[129]' # 银行工作密钥 +T['BankTransKey'] = 'char[129]' # 银行传输密钥 +T['BankServerDescription'] = 'char[129]' # 银行服务器描述信息 +T['AddInfo'] = 'char[129]' # 附加信息 +T['DescrInfoForReturnCode'] = 'char[129]' # 返回码描述 +T['CountryCode'] = 'char[21]' # 国家代码 +T['Serial'] = 'int' # 流水号 +T['PlateSerial'] = 'int' # 平台流水号 +T['BankSerial'] = 'char[13]' # 银行流水号 +T['CorrectSerial'] = 'int' # 被冲正交易流水号 +T['FutureSerial'] = 'int' # 期货公司流水号 +T['ApplicationID'] = 'int' # 应用标识 +T['BankProxyID'] = 'int' # 银行代理标识 +T['FBTCoreID'] = 'int' # 银期转帐核心系统标识 +T['ServerPort'] = 'int' # 服务端口号 +T['RepealedTimes'] = 'int' # 已经冲正次数 +T['RepealTimeInterval'] = 'int' # 冲正时间间隔 +T['TotalTimes'] = 'int' # 每日累计转帐次数 +T['FBTRequestID'] = 'int' # 请求ID +T['TID'] = 'int' # 交易ID +T['TradeAmount'] = 'double' # 交易金额(元) +T['CustFee'] = 'double' # 应收客户费用(元) +T['FutureFee'] = 'double' # 应收期货公司费用(元) +T['SingleMaxAmt'] = 'double' # 单笔最高限额 +T['SingleMinAmt'] = 'double' # 单笔最低限额 +T['TotalAmt'] = 'double' # 每日累计转帐额度 +T['CertificationType'] = 'char' # 证件类型 +CFT_IDCard = '0' # 身份证 +CFT_Passport = '1' # 护照 +CFT_OfficerIDCard = '2' # 军官证 +CFT_SoldierIDCard = '3' # 士兵证 +CFT_HomeComingCard = '4' # 回乡证 +CFT_HouseholdRegister = '5' # 户口簿 +CFT_LicenseNo = '6' # 营业执照号 +CFT_InstitutionCodeCard = '7' # 组织机构代码证 +CFT_TempLicenseNo = '8' # 临时营业执照号 +CFT_NoEnterpriseLicenseNo = '9' # 民办非企业登记证书 +CFT_OtherCard = 'x' # 其他证件 +CFT_SuperDepAgree = 'a' # 主管部门批文 +T['FileBusinessCode'] = 'char' # 文件业务功能 +FBC_Others = '0' # 其他 +FBC_TransferDetails = '1' # 转账交易明细对账 +FBC_CustAccStatus = '2' # 客户账户状态对账 +FBC_AccountTradeDetails = '3' # 账户类交易明细对账 +FBC_FutureAccountChangeInfoDetails = '4' # 期货账户信息变更明细对账 +FBC_CustMoneyDetail = '5' # 客户资金台账余额明细对账 +FBC_CustCancelAccountInfo = '6' # 客户销户结息明细对账 +FBC_CustMoneyResult = '7' # 客户资金余额对账结果 +FBC_OthersExceptionResult = '8' # 其它对账异常结果文件 +FBC_CustInterestNetMoneyDetails = '9' # 客户结息净额明细 +FBC_CustMoneySendAndReceiveDetails = 'a' # 客户资金交收明细 +FBC_CorporationMoneyTotal = 'b' # 法人存管银行资金交收汇总 +FBC_MainbodyMoneyTotal = 'c' # 主体间资金交收汇总 +FBC_MainPartMonitorData = 'd' # 总分平衡监管数据 +FBC_PreparationMoney = 'e' # 存管银行备付金余额 +FBC_BankMoneyMonitorData = 'f' # 协办存管银行资金监管数据 +T['CashExchangeCode'] = 'char' # 汇钞标志 +CEC_Exchange = '1' # 汇 +CEC_Cash = '2' # 钞 +T['YesNoIndicator'] = 'char' # 是或否标识 +YNI_Yes = '0' # 是 +YNI_No = '1' # 否 +T['BanlanceType'] = 'char' # 余额类型 +BLT_CurrentMoney = '0' # 当前余额 +BLT_UsableMoney = '1' # 可用余额 +BLT_FetchableMoney = '2' # 可取余额 +BLT_FreezeMoney = '3' # 冻结余额 +T['Gender'] = 'char' # 性别 +GD_Unknown = '0' # 未知状态 +GD_Male = '1' # 男 +GD_Female = '2' # 女 +T['FeePayFlag'] = 'char' # 费用支付标志 +FPF_BEN = '0' # 由受益方支付费用 +FPF_OUR = '1' # 由发送方支付费用 +FPF_SHA = '2' # 由发送方支付发起的费用,受益方支付接受的费用 +T['PassWordKeyType'] = 'char' # 密钥类型 +PWKT_ExchangeKey = '0' # 交换密钥 +PWKT_PassWordKey = '1' # 密码密钥 +PWKT_MACKey = '2' # MAC密钥 +PWKT_MessageKey = '3' # 报文密钥 +T['FBTPassWordType'] = 'char' # 密码类型 +PWT_Query = '0' # 查询 +PWT_Fetch = '1' # 取款 +PWT_Transfer = '2' # 转帐 +PWT_Trade = '3' # 交易 +T['FBTEncryMode'] = 'char' # 加密方式 +EM_NoEncry = '0' # 不加密 +EM_DES = '1' # DES +EM_3DES = '2' # 3DES +T['BankRepealFlag'] = 'char' # 银行冲正标志 +BRF_BankNotNeedRepeal = '0' # 银行无需自动冲正 +BRF_BankWaitingRepeal = '1' # 银行待自动冲正 +BRF_BankBeenRepealed = '2' # 银行已自动冲正 +T['BrokerRepealFlag'] = 'char' # 期商冲正标志 +BRORF_BrokerNotNeedRepeal = '0' # 期商无需自动冲正 +BRORF_BrokerWaitingRepeal = '1' # 期商待自动冲正 +BRORF_BrokerBeenRepealed = '2' # 期商已自动冲正 +T['InstitutionType'] = 'char' # 机构类别 +TS_Bank = '0' # 银行 +TS_Future = '1' # 期商 +TS_Store = '2' # 券商 +T['LastFragment'] = 'char' # 最后分片标志 +LF_Yes = '0' # 是最后分片 +LF_No = '1' # 不是最后分片 +T['BankAccStatus'] = 'char' # 银行账户状态 +BAS_Normal = '0' # 正常 +BAS_Freeze = '1' # 冻结 +BAS_ReportLoss = '2' # 挂失 +T['MoneyAccountStatus'] = 'char' # 资金账户状态 +MAS_Normal = '0' # 正常 +MAS_Cancel = '1' # 销户 +T['ManageStatus'] = 'char' # 存管状态 +MSS_Point = '0' # 指定存管 +MSS_PrePoint = '1' # 预指定 +MSS_CancelPoint = '2' # 撤销指定 +T['SystemType'] = 'char' # 应用系统类型 +SYT_FutureBankTransfer = '0' # 银期转帐 +SYT_StockBankTransfer = '1' # 银证转帐 +SYT_TheThirdPartStore = '2' # 第三方存管 +T['TxnEndFlag'] = 'char' # 银期转帐划转结果标志 +TEF_NormalProcessing = '0' # 正常处理中 +TEF_Success = '1' # 成功结束 +TEF_Failed = '2' # 失败结束 +TEF_Abnormal = '3' # 异常中 +TEF_ManualProcessedForException = '4' # 已人工异常处理 +TEF_CommuFailedNeedManualProcess = '5' # 通讯异常 ,请人工处理 +TEF_SysErrorNeedManualProcess = '6' # 系统出错,请人工处理 +T['ProcessStatus'] = 'char' # 银期转帐服务处理状态 +PSS_NotProcess = '0' # 未处理 +PSS_StartProcess = '1' # 开始处理 +PSS_Finished = '2' # 处理完成 +T['CustType'] = 'char' # 客户类型 +CUSTT_Person = '0' # 自然人 +CUSTT_Institution = '1' # 机构户 +T['FBTTransferDirection'] = 'char' # 银期转帐方向 +FBTTD_FromBankToFuture = '1' # 入金,银行转期货 +FBTTD_FromFutureToBank = '2' # 出金,期货转银行 +T['OpenOrDestroy'] = 'char' # 开销户类别 +OOD_Open = '1' # 开户 +OOD_Destroy = '0' # 销户 +T['AvailabilityFlag'] = 'char' # 有效标志 +AVAF_Invalid = '0' # 未确认 +AVAF_Valid = '1' # 有效 +AVAF_Repeal = '2' # 冲正 +T['OrganType'] = 'char' # 机构类型 +OT_Bank = '1' # 银行代理 +OT_Future = '2' # 交易前置 +OT_PlateForm = '9' # 银期转帐平台管理 +T['OrganLevel'] = 'char' # 机构级别 +OL_HeadQuarters = '1' # 银行总行或期商总部 +OL_Branch = '2' # 银行分中心或期货公司营业部 +T['ProtocalID'] = 'char' # 协议类型 +PID_FutureProtocal = '0' # 期商协议 +PID_ICBCProtocal = '1' # 工行协议 +PID_ABCProtocal = '2' # 农行协议 +PID_CBCProtocal = '3' # 中国银行协议 +PID_CCBProtocal = '4' # 建行协议 +PID_BOCOMProtocal = '5' # 交行协议 +PID_FBTPlateFormProtocal = 'X' # 银期转帐平台协议 +T['ConnectMode'] = 'char' # 套接字连接方式 +CM_ShortConnect = '0' # 短连接 +CM_LongConnect = '1' # 长连接 +T['SyncMode'] = 'char' # 套接字通信方式 +SRM_ASync = '0' # 异步 +SRM_Sync = '1' # 同步 +T['BankAccType'] = 'char' # 银行帐号类型 +BAT_BankBook = '1' # 银行存折 +BAT_SavingCard = '2' # 储蓄卡 +BAT_CreditCard = '3' # 信用卡 +T['FutureAccType'] = 'char' # 期货公司帐号类型 +FAT_BankBook = '1' # 银行存折 +FAT_SavingCard = '2' # 储蓄卡 +FAT_CreditCard = '3' # 信用卡 +T['OrganStatus'] = 'char' # 接入机构状态 +OS_Ready = '0' # 启用 +OS_CheckIn = '1' # 签到 +OS_CheckOut = '2' # 签退 +OS_CheckFileArrived = '3' # 对帐文件到达 +OS_CheckDetail = '4' # 对帐 +OS_DayEndClean = '5' # 日终清理 +OS_Invalid = '9' # 注销 +T['CCBFeeMode'] = 'char' # 建行收费模式 +CCBFM_ByAmount = '1' # 按金额扣收 +CCBFM_ByMonth = '2' # 按月扣收 +T['CommApiType'] = 'char' # 通讯API类型 +CAPIT_Client = '1' # 客户端 +CAPIT_Server = '2' # 服务端 +CAPIT_UserApi = '3' # 交易系统的UserApi +T['ServiceID'] = 'int' # 服务编号 +T['ServiceLineNo'] = 'int' # 服务线路编号 +T['ServiceName'] = 'char[61]' # 服务名 +T['LinkStatus'] = 'char' # 连接状态 +LS_Connected = '1' # 已经连接 +LS_Disconnected = '2' # 没有连接 +T['CommApiPointer'] = 'int' # 通讯API指针 +T['PwdFlag'] = 'char' # 密码核对标志 +BPWDF_NoCheck = '0' # 不核对 +BPWDF_BlankCheck = '1' # 明文核对 +BPWDF_EncryptCheck = '2' # 密文核对 +T['SecuAccType'] = 'char' # 期货帐号类型 +SAT_AccountID = '1' # 资金帐号 +SAT_CardID = '2' # 资金卡号 +SAT_SHStockholderID = '3' # 上海股东帐号 +SAT_SZStockholderID = '4' # 深圳股东帐号 +T['TransferStatus'] = 'char' # 转账交易状态 +TRFS_Normal = '0' # 正常 +TRFS_Repealed = '1' # 被冲正 +T['SponsorType'] = 'char' # 发起方 +SPTYPE_Broker = '0' # 期商 +SPTYPE_Bank = '1' # 银行 +T['ReqRspType'] = 'char' # 请求响应类别 +REQRSP_Request = '0' # 请求 +REQRSP_Response = '1' # 响应 +T['FBTUserEventType'] = 'char' # 银期转帐用户事件类型 +FBTUET_SignIn = '0' # 签到 +FBTUET_FromBankToFuture = '1' # 银行转期货 +FBTUET_FromFutureToBank = '2' # 期货转银行 +FBTUET_OpenAccount = '3' # 开户 +FBTUET_CancelAccount = '4' # 销户 +FBTUET_ChangeAccount = '5' # 变更银行账户 +FBTUET_RepealFromBankToFuture = '6' # 冲正银行转期货 +FBTUET_RepealFromFutureToBank = '7' # 冲正期货转银行 +FBTUET_QueryBankAccount = '8' # 查询银行账户 +FBTUET_QueryFutureAccount = '9' # 查询期货账户 +FBTUET_SignOut = 'A' # 签退 +FBTUET_SyncKey = 'B' # 密钥同步 +FBTUET_Other = 'Z' # 其他 +T['BankIDByBank'] = 'char[21]' # 银行自己的编码 +T['BankOperNo'] = 'char[4]' # 银行操作员号 +T['BankCustNo'] = 'char[21]' # 银行客户号 +T['DBOPSeqNo'] = 'int' # 递增的序列号 +T['TableName'] = 'char[61]' # FBT表名 +T['PKName'] = 'char[201]' # FBT表操作主键名 +T['PKValue'] = 'char[501]' # FBT表操作主键值 +T['DBOperation'] = 'char' # 记录操作类型 +DBOP_Insert = '0' # 插入 +DBOP_Update = '1' # 更新 +DBOP_Delete = '2' # 删除 +T['SyncFlag'] = 'char' # 同步标记 +SYNF_Yes = '0' # 已同步 +SYNF_No = '1' # 未同步 +T['TargetID'] = 'char[4]' # 同步目标编号 +T['SyncType'] = 'char' # 同步类型 +SYNT_OneOffSync = '0' # 一次同步 +SYNT_TimerSync = '1' # 定时同步 +SYNT_TimerFullSync = '2' # 定时完全同步 +T['FBETime'] = 'char[7]' # 各种换汇时间 +T['FBEBankNo'] = 'char[13]' # 换汇银行行号 +T['FBECertNo'] = 'char[13]' # 换汇凭证号 +T['ExDirection'] = 'char' # 换汇方向 +FBEDIR_Settlement = '0' # 结汇 +FBEDIR_Sale = '1' # 售汇 +T['FBEBankAccount'] = 'char[33]' # 换汇银行账户 +T['FBEBankAccountName'] = 'char[61]' # 换汇银行账户名 +T['FBEAmt'] = 'double' # 各种换汇金额 +T['FBEBusinessType'] = 'char[3]' # 换汇业务类型 +T['FBEPostScript'] = 'char[61]' # 换汇附言 +T['FBERemark'] = 'char[71]' # 换汇备注 +T['ExRate'] = 'double' # 换汇汇率 +T['FBEResultFlag'] = 'char' # 换汇成功标志 +FBERES_Success = '0' # 成功 +FBERES_InsufficientBalance = '1' # 账户余额不足 +FBERES_UnknownTrading = '8' # 交易结果未知 +FBERES_Fail = 'x' # 失败 +T['FBERtnMsg'] = 'char[61]' # 换汇返回信息 +T['FBEExtendMsg'] = 'char[61]' # 换汇扩展信息 +T['FBEBusinessSerial'] = 'char[31]' # 换汇记账流水号 +T['FBESystemSerial'] = 'char[21]' # 换汇流水号 +T['FBETotalExCnt'] = 'int' # 换汇交易总笔数 +T['FBEExchStatus'] = 'char' # 换汇交易状态 +FBEES_Normal = '0' # 正常 +FBEES_ReExchange = '1' # 交易重发 +T['FBEFileFlag'] = 'char' # 换汇文件标志 +FBEFG_DataPackage = '0' # 数据包 +FBEFG_File = '1' # 文件 +T['FBEAlreadyTrade'] = 'char' # 换汇已交易标志 +FBEAT_NotTrade = '0' # 未交易 +FBEAT_Trade = '1' # 已交易 +T['FBEOpenBank'] = 'char[61]' # 换汇账户开户行 +T['FBEUserEventType'] = 'char' # 银期换汇用户事件类型 +FBEUET_SignIn = '0' # 签到 +FBEUET_Exchange = '1' # 换汇 +FBEUET_ReExchange = '2' # 换汇重发 +FBEUET_QueryBankAccount = '3' # 银行账户查询 +FBEUET_QueryExchDetial = '4' # 换汇明细查询 +FBEUET_QueryExchSummary = '5' # 换汇汇总查询 +FBEUET_QueryExchRate = '6' # 换汇汇率查询 +FBEUET_CheckBankAccount = '7' # 对账文件通知 +FBEUET_SignOut = '8' # 签退 +FBEUET_Other = 'Z' # 其他 +T['FBEFileName'] = 'char[21]' # 换汇相关文件名 +T['FBEBatchSerial'] = 'char[21]' # 换汇批次号 +T['FBEReqFlag'] = 'char' # 换汇发送标志 +FBERF_UnProcessed = '0' # 未处理 +FBERF_WaitSend = '1' # 等待发送 +FBERF_SendSuccess = '2' # 发送成功 +FBERF_SendFailed = '3' # 发送失败 +FBERF_WaitReSend = '4' # 等待重发 +T['NotifyClass'] = 'char' # 风险通知类型 +NC_NOERROR = '0' # 正常 +NC_Warn = '1' # 警示 +NC_Call = '2' # 追保 +NC_Force = '3' # 强平 +NC_CHUANCANG = '4' # 穿仓 +NC_Exception = '5' # 异常 +T['RiskNofityInfo'] = 'char[257]' # 客户风险通知消息 +T['ForceCloseSceneId'] = 'char[24]' # 强平场景编号 +T['ForceCloseType'] = 'char' # 强平单类型 +FCT_Manual = '0' # 手工强平 +FCT_Single = '1' # 单一投资者辅助强平 +FCT_Group = '2' # 批量投资者辅助强平 +T['InstrumentIDs'] = 'char[101]' # 多个产品代码,用+分隔,如cu+zn +T['RiskNotifyMethod'] = 'char' # 风险通知途径 +RNM_System = '0' # 系统通知 +RNM_SMS = '1' # 短信通知 +RNM_EMail = '2' # 邮件通知 +RNM_Manual = '3' # 人工通知 +T['RiskNotifyStatus'] = 'char' # 风险通知状态 +RNS_NotGen = '0' # 未生成 +RNS_Generated = '1' # 已生成未发送 +RNS_SendError = '2' # 发送失败 +RNS_SendOk = '3' # 已发送未接收 +RNS_Received = '4' # 已接收未确认 +RNS_Confirmed = '5' # 已确认 +T['RiskUserEvent'] = 'char' # 风控用户操作事件 +RUE_ExportData = '0' # 导出数据 +T['ParamID'] = 'int' # 参数代码 +T['ParamName'] = 'char[41]' # 参数名 +T['ParamValue'] = 'char[41]' # 参数值 +T['ConditionalOrderSortType'] = 'char' # 条件单索引条件 +COST_LastPriceAsc = '0' # 使用最新价升序 +COST_LastPriceDesc = '1' # 使用最新价降序 +COST_AskPriceAsc = '2' # 使用卖价升序 +COST_AskPriceDesc = '3' # 使用卖价降序 +COST_BidPriceAsc = '4' # 使用买价升序 +COST_BidPriceDesc = '5' # 使用买价降序 +T['SendType'] = 'char' # 报送状态 +UOAST_NoSend = '0' # 未发送 +UOAST_Sended = '1' # 已发送 +UOAST_Generated = '2' # 已生成 +UOAST_SendFail = '3' # 报送失败 +UOAST_Success = '4' # 接收成功 +UOAST_Fail = '5' # 接收失败 +UOAST_Cancel = '6' # 取消报送 +T['ClientIDStatus'] = 'char' # 交易编码状态 +UOACS_NoApply = '1' # 未申请 +UOACS_Submited = '2' # 已提交申请 +UOACS_Sended = '3' # 已发送申请 +UOACS_Success = '4' # 完成 +UOACS_Refuse = '5' # 拒绝 +UOACS_Cancel = '6' # 已撤销编码 +T['IndustryID'] = 'char[17]' # 行业编码 +T['QuestionID'] = 'char[5]' # 特有信息编号 +T['QuestionContent'] = 'char[41]' # 特有信息说明 +T['OptionID'] = 'char[13]' # 选项编号 +T['OptionContent'] = 'char[61]' # 选项说明 +T['QuestionType'] = 'char' # 特有信息类型 +QT_Radio = '1' # 单选 +QT_Option = '2' # 多选 +QT_Blank = '3' # 填空 +T['ProcessID'] = 'char[33]' # 业务流水号 +T['SeqNo'] = 'int' # 流水号 +T['UOAProcessStatus'] = 'char[3]' # 流程状态 +T['ProcessType'] = 'char[3]' # 流程功能类型 +T['BusinessType'] = 'char' # 业务类型 +BT_Request = '1' # 请求 +BT_Response = '2' # 应答 +BT_Notice = '3' # 通知 +T['CfmmcReturnCode'] = 'char' # 监控中心返回码 +CRC_Success = '0' # 成功 +CRC_Working = '1' # 该客户已经有流程在处理中 +CRC_InfoFail = '2' # 监控中客户资料检查失败 +CRC_IDCardFail = '3' # 监控中实名制检查失败 +CRC_OtherFail = '4' # 其他错误 +T['ExReturnCode'] = 'int' # 交易所返回码 +T['ClientType'] = 'char' # 客户类型 +CfMMCCT_All = '0' # 所有 +CfMMCCT_Person = '1' # 个人 +CfMMCCT_Company = '2' # 单位 +CfMMCCT_Other = '3' # 其他 +CfMMCCT_SpecialOrgan = '4' # 特殊法人 +CfMMCCT_Asset = '5' # 资管户 +T['ExchangeIDType'] = 'char' # 交易所编号 +EIDT_SHFE = 'S' # 上海期货交易所 +EIDT_CZCE = 'Z' # 郑州商品交易所 +EIDT_DCE = 'D' # 大连商品交易所 +EIDT_CFFEX = 'J' # 中国金融期货交易所 +EIDT_INE = 'N' # 上海国际能源交易中心股份有限公司 +T['ExClientIDType'] = 'char' # 交易编码类型 +ECIDT_Hedge = '1' # 套保 +ECIDT_Arbitrage = '2' # 套利 +ECIDT_Speculation = '3' # 投机 +T['ClientClassify'] = 'char[11]' # 客户分类码 +T['UOAOrganType'] = 'char[11]' # 单位性质 +T['UOACountryCode'] = 'char[11]' # 国家代码 +T['AreaCode'] = 'char[11]' # 区号 +T['FuturesID'] = 'char[21]' # 监控中心为客户分配的代码 +T['CffmcDate'] = 'char[11]' # 日期 +T['CffmcTime'] = 'char[11]' # 时间 +T['NocID'] = 'char[21]' # 组织机构代码 +T['UpdateFlag'] = 'char' # 更新状态 +UF_NoUpdate = '0' # 未更新 +UF_Success = '1' # 更新全部信息成功 +UF_Fail = '2' # 更新全部信息失败 +UF_TCSuccess = '3' # 更新交易编码成功 +UF_TCFail = '4' # 更新交易编码失败 +UF_Cancel = '5' # 已丢弃 +T['ApplyOperateID'] = 'char' # 申请动作 +AOID_OpenInvestor = '1' # 开户 +AOID_ModifyIDCard = '2' # 修改身份信息 +AOID_ModifyNoIDCard = '3' # 修改一般信息 +AOID_ApplyTradingCode = '4' # 申请交易编码 +AOID_CancelTradingCode = '5' # 撤销交易编码 +AOID_CancelInvestor = '6' # 销户 +AOID_FreezeAccount = '8' # 账户休眠 +AOID_ActiveFreezeAccount = '9' # 激活休眠账户 +T['ApplyStatusID'] = 'char' # 申请状态 +ASID_NoComplete = '1' # 未补全 +ASID_Submited = '2' # 已提交 +ASID_Checked = '3' # 已审核 +ASID_Refused = '4' # 已拒绝 +ASID_Deleted = '5' # 已删除 +T['SendMethod'] = 'char' # 发送方式 +UOASM_ByAPI = '1' # 文件发送 +UOASM_ByFile = '2' # 电子发送 +T['EventType'] = 'char[33]' # 业务操作类型 +T['EventMode'] = 'char' # 操作方法 +EvM_ADD = '1' # 增加 +EvM_UPDATE = '2' # 修改 +EvM_DELETE = '3' # 删除 +EvM_CHECK = '4' # 复核 +EvM_COPY = '5' # 复制 +EvM_CANCEL = '6' # 注销 +EvM_Reverse = '7' # 冲销 +T['UOAAutoSend'] = 'char' # 统一开户申请自动发送 +UOAA_ASR = '1' # 自动发送并接收 +UOAA_ASNR = '2' # 自动发送,不自动接收 +UOAA_NSAR = '3' # 不自动发送,自动接收 +UOAA_NSR = '4' # 不自动发送,也不自动接收 +T['QueryDepth'] = 'int' # 查询深度 +T['DataCenterID'] = 'int' # 数据中心代码 +T['FlowID'] = 'char' # 流程ID +EvM_InvestorGroupFlow = '1' # 投资者对应投资者组设置 +EvM_InvestorRate = '2' # 投资者手续费率设置 +EvM_InvestorCommRateModel = '3' # 投资者手续费率模板关系设置 +T['CheckLevel'] = 'char' # 复核级别 +CL_Zero = '0' # 零级复核 +CL_One = '1' # 一级复核 +CL_Two = '2' # 二级复核 +T['CheckNo'] = 'int' # 操作次数 +T['CheckStatus'] = 'char' # 复核级别 +CHS_Init = '0' # 未复核 +CHS_Checking = '1' # 复核中 +CHS_Checked = '2' # 已复核 +CHS_Refuse = '3' # 拒绝 +CHS_Cancel = '4' # 作废 +T['UsedStatus'] = 'char' # 生效状态 +CHU_Unused = '0' # 未生效 +CHU_Used = '1' # 已生效 +CHU_Fail = '2' # 生效失败 +T['RateTemplateName'] = 'char[61]' # 模型名称 +T['PropertyString'] = 'char[2049]' # 用于查询的投资属性字段 +T['BankAcountOrigin'] = 'char' # 账户来源 +BAO_ByAccProperty = '0' # 手工录入 +BAO_ByFBTransfer = '1' # 银期转账 +T['MonthBillTradeSum'] = 'char' # 结算单月报成交汇总方式 +MBTS_ByInstrument = '0' # 同日同合约 +MBTS_ByDayInsPrc = '1' # 同日同合约同价格 +MBTS_ByDayIns = '2' # 同合约 +T['FBTTradeCodeEnum'] = 'char[7]' # 银期交易代码枚举 +FTC_BankLaunchBankToBroker = '102001' # 银行发起银行转期货 +FTC_BrokerLaunchBankToBroker = '202001' # 期货发起银行转期货 +FTC_BankLaunchBrokerToBank = '102002' # 银行发起期货转银行 +FTC_BrokerLaunchBrokerToBank = '202002' # 期货发起期货转银行 +T['RateTemplateID'] = 'char[9]' # 模型代码 +T['RiskRate'] = 'char[21]' # 风险度 +T['Timestamp'] = 'int' # 时间戳 +T['InvestorIDRuleName'] = 'char[61]' # 号段规则名称 +T['InvestorIDRuleExpr'] = 'char[513]' # 号段规则表达式 +T['LastDrift'] = 'int' # 上次OTP漂移值 +T['LastSuccess'] = 'int' # 上次OTP成功值 +T['AuthKey'] = 'char[41]' # 令牌密钥 +T['SerialNumber'] = 'char[17]' # 序列号 +T['OTPType'] = 'char' # 动态令牌类型 +OTP_NONE = '0' # 无动态令牌 +OTP_TOTP = '1' # 时间令牌 +T['OTPVendorsID'] = 'char[2]' # 动态令牌提供商 +T['OTPVendorsName'] = 'char[61]' # 动态令牌提供商名称 +T['OTPStatus'] = 'char' # 动态令牌状态 +OTPS_Unused = '0' # 未使用 +OTPS_Used = '1' # 已使用 +OTPS_Disuse = '2' # 注销 +T['BrokerUserType'] = 'char' # 经济公司用户类型 +BUT_Investor = '1' # 投资者 +BUT_BrokerUser = '2' # 操作员 +T['FutureType'] = 'char' # 期货类型 +FUTT_Commodity = '1' # 商品期货 +FUTT_Financial = '2' # 金融期货 +T['FundEventType'] = 'char' # 资金管理操作类型 +FET_Restriction = '0' # 转账限额 +FET_TodayRestriction = '1' # 当日转账限额 +FET_Transfer = '2' # 期商流水 +FET_Credit = '3' # 资金冻结 +FET_InvestorWithdrawAlm = '4' # 投资者可提资金比例 +FET_BankRestriction = '5' # 单个银行帐户转账限额 +FET_Accountregister = '6' # 银期签约账户 +FET_ExchangeFundIO = '7' # 交易所出入金 +FET_InvestorFundIO = '8' # 投资者出入金 +T['AccountSourceType'] = 'char' # 资金账户来源 +AST_FBTransfer = '0' # 银期同步 +AST_ManualEntry = '1' # 手工录入 +T['CodeSourceType'] = 'char' # 交易编码来源 +CST_UnifyAccount = '0' # 统一开户(已规范) +CST_ManualEntry = '1' # 手工录入(未规范) +T['UserRange'] = 'char' # 操作员范围 +UR_All = '0' # 所有 +UR_Single = '1' # 单一操作员 +T['TimeSpan'] = 'char[9]' # 时间跨度 +T['ImportSequenceID'] = 'char[17]' # 动态令牌导入批次编号 +T['ByGroup'] = 'char' # 交易统计表按客户统计方式 +BG_Investor = '2' # 按投资者统计 +BG_Group = '1' # 按类统计 +T['TradeSumStatMode'] = 'char' # 交易统计表按范围统计方式 +TSSM_Instrument = '1' # 按合约统计 +TSSM_Product = '2' # 按产品统计 +TSSM_Exchange = '3' # 按交易所统计 +T['ComType'] = 'int' # 组合成交类型 +T['UserProductID'] = 'char[33]' # 产品标识 +T['UserProductName'] = 'char[65]' # 产品名称 +T['UserProductMemo'] = 'char[129]' # 产品说明 +T['CSRCCancelFlag'] = 'char[2]' # 新增或变更标志 +T['CSRCDate'] = 'char[11]' # 日期 +T['CSRCInvestorName'] = 'char[201]' # 客户名称 +T['CSRCOpenInvestorName'] = 'char[101]' # 客户名称 +T['CSRCInvestorID'] = 'char[13]' # 客户代码 +T['CSRCIdentifiedCardNo'] = 'char[51]' # 证件号码 +T['CSRCClientID'] = 'char[11]' # 交易编码 +T['CSRCBankFlag'] = 'char[3]' # 银行标识 +T['CSRCBankAccount'] = 'char[23]' # 银行账户 +T['CSRCOpenName'] = 'char[401]' # 开户人 +T['CSRCMemo'] = 'char[101]' # 说明 +T['CSRCTime'] = 'char[11]' # 时间 +T['CSRCTradeID'] = 'char[21]' # 成交流水号 +T['CSRCExchangeInstID'] = 'char[31]' # 合约代码 +T['CSRCMortgageName'] = 'char[7]' # 质押品名称 +T['CSRCReason'] = 'char[3]' # 事由 +T['IsSettlement'] = 'char[2]' # 是否为非结算会员 +T['CSRCMoney'] = 'double' # 资金 +T['CSRCPrice'] = 'double' # 价格 +T['CSRCOptionsType'] = 'char[2]' # 期权类型 +T['CSRCStrikePrice'] = 'double' # 执行价 +T['CSRCTargetProductID'] = 'char[3]' # 标的品种 +T['CSRCTargetInstrID'] = 'char[31]' # 标的合约 +T['CommModelName'] = 'char[161]' # 手续费率模板名称 +T['CommModelMemo'] = 'char[1025]' # 手续费率模板备注 +T['ExprSetMode'] = 'char' # 日期表达式设置类型 +ESM_Relative = '1' # 相对已有规则设置 +ESM_Typical = '2' # 典型设置 +T['RateInvestorRange'] = 'char' # 投资者范围 +RIR_All = '1' # 公司标准 +RIR_Model = '2' # 模板 +RIR_Single = '3' # 单一投资者 +T['AgentBrokerID'] = 'char[13]' # 代理经纪公司代码 +T['DRIdentityID'] = 'int' # 交易中心代码 +T['DRIdentityName'] = 'char[65]' # 交易中心名称 +T['DBLinkID'] = 'char[31]' # DBLink标识号 +T['SyncDataStatus'] = 'char' # 主次用系统数据同步状态 +SDS_Initialize = '0' # 未同步 +SDS_Settlementing = '1' # 同步中 +SDS_Settlemented = '2' # 已同步 +T['TradeSource'] = 'char' # 成交来源 +TSRC_NORMAL = '0' # 来自交易所普通回报 +TSRC_QUERY = '1' # 来自查询 +T['FlexStatMode'] = 'char' # 产品合约统计方式 +FSM_Product = '1' # 产品统计 +FSM_Exchange = '2' # 交易所统计 +FSM_All = '3' # 统计所有 +T['ByInvestorRange'] = 'char' # 投资者范围统计方式 +BIR_Property = '1' # 属性统计 +BIR_All = '2' # 统计所有 +T['SRiskRate'] = 'char[21]' # 风险度 +T['SequenceNo12'] = 'int' # 序号 +T['PropertyInvestorRange'] = 'char' # 投资者范围 +PIR_All = '1' # 所有 +PIR_Property = '2' # 投资者属性 +PIR_Single = '3' # 单一投资者 +T['FileStatus'] = 'char' # 文件状态 +FIS_NoCreate = '0' # 未生成 +FIS_Created = '1' # 已生成 +FIS_Failed = '2' # 生成失败 +T['FileGenStyle'] = 'char' # 文件生成方式 +FGS_FileTransmit = '0' # 下发 +FGS_FileGen = '1' # 生成 +T['SysOperMode'] = 'char' # 系统日志操作方法 +SoM_Add = '1' # 增加 +SoM_Update = '2' # 修改 +SoM_Delete = '3' # 删除 +SoM_Copy = '4' # 复制 +SoM_AcTive = '5' # 激活 +SoM_CanCel = '6' # 注销 +SoM_ReSet = '7' # 重置 +T['SysOperType'] = 'char' # 系统日志操作类型 +SoT_UpdatePassword = '0' # 修改操作员密码 +SoT_UserDepartment = '1' # 操作员组织架构关系 +SoT_RoleManager = '2' # 角色管理 +SoT_RoleFunction = '3' # 角色功能设置 +SoT_BaseParam = '4' # 基础参数设置 +SoT_SetUserID = '5' # 设置操作员 +SoT_SetUserRole = '6' # 用户角色设置 +SoT_UserIpRestriction = '7' # 用户IP限制 +SoT_DepartmentManager = '8' # 组织架构管理 +SoT_DepartmentCopy = '9' # 组织架构向查询分类复制 +SoT_Tradingcode = 'A' # 交易编码管理 +SoT_InvestorStatus = 'B' # 投资者状态维护 +SoT_InvestorAuthority = 'C' # 投资者权限管理 +SoT_PropertySet = 'D' # 属性设置 +SoT_ReSetInvestorPasswd = 'E' # 重置投资者密码 +SoT_InvestorPersonalityInfo = 'F' # 投资者个性信息维护 +T['CSRCDataQueyType'] = 'char' # 上报数据查询类型 +CSRCQ_Current = '0' # 查询当前交易日报送的数据 +CSRCQ_History = '1' # 查询历史报送的代理经纪公司的数据 +T['FreezeStatus'] = 'char' # 休眠状态 +FRS_Normal = '1' # 活跃 +FRS_Freeze = '0' # 休眠 +T['StandardStatus'] = 'char' # 规范状态 +STST_Standard = '0' # 已规范 +STST_NonStandard = '1' # 未规范 +T['CSRCFreezeStatus'] = 'char[2]' # 休眠状态 +T['RightParamType'] = 'char' # 配置类型 +RPT_Freeze = '1' # 休眠户 +RPT_FreezeActive = '2' # 激活休眠户 +RPT_OpenLimit = '3' # 开仓权限限制 +RPT_RelieveOpenLimit = '4' # 解除开仓权限限制 +T['RightTemplateID'] = 'char[9]' # 模板代码 +T['RightTemplateName'] = 'char[61]' # 模板名称 +T['DataStatus'] = 'char' # 反洗钱审核表数据状态 +AMLDS_Normal = '0' # 正常 +AMLDS_Deleted = '1' # 已删除 +T['AMLCheckStatus'] = 'char' # 审核状态 +AMLCHS_Init = '0' # 未复核 +AMLCHS_Checking = '1' # 复核中 +AMLCHS_Checked = '2' # 已复核 +AMLCHS_RefuseReport = '3' # 拒绝上报 +T['AmlDateType'] = 'char' # 日期类型 +AMLDT_DrawDay = '0' # 检查日期 +AMLDT_TouchDay = '1' # 发生日期 +T['AmlCheckLevel'] = 'char' # 审核级别 +AMLCL_CheckLevel0 = '0' # 零级审核 +AMLCL_CheckLevel1 = '1' # 一级审核 +AMLCL_CheckLevel2 = '2' # 二级审核 +AMLCL_CheckLevel3 = '3' # 三级审核 +T['AmlCheckFlow'] = 'char[2]' # 反洗钱数据抽取审核流程 +T['DataType'] = 'char[129]' # 数据类型 +T['ExportFileType'] = 'char' # 导出文件类型 +EFT_CSV = '0' # CSV +EFT_EXCEL = '1' # Excel +EFT_DBF = '2' # DBF +T['SettleManagerType'] = 'char' # 结算配置类型 +SMT_Before = '1' # 结算前准备 +SMT_Settlement = '2' # 结算 +SMT_After = '3' # 结算后核对 +SMT_Settlemented = '4' # 结算后处理 +T['SettleManagerID'] = 'char[33]' # 结算配置代码 +T['SettleManagerName'] = 'char[129]' # 结算配置名称 +T['SettleManagerLevel'] = 'char' # 结算配置等级 +SML_Must = '1' # 必要 +SML_Alarm = '2' # 警告 +SML_Prompt = '3' # 提示 +SML_Ignore = '4' # 不检查 +T['SettleManagerGroup'] = 'char' # 模块分组 +SMG_Exhcange = '1' # 交易所核对 +SMG_ASP = '2' # 内部核对 +SMG_CSRC = '3' # 上报数据核对 +T['CheckResultMemo'] = 'char[1025]' # 核对结果说明 +T['FunctionUrl'] = 'char[1025]' # 功能链接 +T['AuthInfo'] = 'char[129]' # 客户端认证信息 +T['AuthCode'] = 'char[17]' # 客户端认证码 +T['LimitUseType'] = 'char' # 保值额度使用类型 +LUT_Repeatable = '1' # 可重复使用 +LUT_Unrepeatable = '2' # 不可重复使用 +T['DataResource'] = 'char' # 数据来源 +DAR_Settle = '1' # 本系统 +DAR_Exchange = '2' # 交易所 +DAR_CSRC = '3' # 报送数据 +T['MarginType'] = 'char' # 保证金类型 +MGT_ExchMarginRate = '0' # 交易所保证金率 +MGT_InstrMarginRate = '1' # 投资者保证金率 +MGT_InstrMarginRateTrade = '2' # 投资者交易保证金率 +T['ActiveType'] = 'char' # 生效类型 +ACT_Intraday = '1' # 仅当日生效 +ACT_Long = '2' # 长期生效 +T['MarginRateType'] = 'char' # 冲突保证金率类型 +MRT_Exchange = '1' # 交易所保证金率 +MRT_Investor = '2' # 投资者保证金率 +MRT_InvestorTrade = '3' # 投资者交易保证金率 +T['BackUpStatus'] = 'char' # 备份数据状态 +BUS_UnBak = '0' # 未生成备份数据 +BUS_BakUp = '1' # 备份数据生成中 +BUS_BakUped = '2' # 已生成备份数据 +BUS_BakFail = '3' # 备份数据失败 +T['InitSettlement'] = 'char' # 结算初始化状态 +SIS_UnInitialize = '0' # 结算初始化未开始 +SIS_Initialize = '1' # 结算初始化中 +SIS_Initialized = '2' # 结算初始化完成 +T['ReportStatus'] = 'char' # 报表数据生成状态 +SRS_NoCreate = '0' # 未生成报表数据 +SRS_Create = '1' # 报表数据生成中 +SRS_Created = '2' # 已生成报表数据 +SRS_CreateFail = '3' # 生成报表数据失败 +T['SaveStatus'] = 'char' # 数据归档状态 +SSS_UnSaveData = '0' # 归档未完成 +SSS_SaveDatad = '1' # 归档完成 +T['SettArchiveStatus'] = 'char' # 结算确认数据归档状态 +SAS_UnArchived = '0' # 未归档数据 +SAS_Archiving = '1' # 数据归档中 +SAS_Archived = '2' # 已归档数据 +SAS_ArchiveFail = '3' # 归档数据失败 +T['CTPType'] = 'char' # CTP交易系统类型 +CTPT_Unkown = '0' # 未知类型 +CTPT_MainCenter = '1' # 主中心 +CTPT_BackUp = '2' # 备中心 +T['ToolID'] = 'char[9]' # 工具代码 +T['ToolName'] = 'char[81]' # 工具名称 +T['CloseDealType'] = 'char' # 平仓处理类型 +CDT_Normal = '0' # 正常 +CDT_SpecFirst = '1' # 投机平仓优先 +T['MortgageFundUseRange'] = 'char' # 货币质押资金可用范围 +MFUR_None = '0' # 不能使用 +MFUR_Margin = '1' # 用于保证金 +MFUR_All = '2' # 用于手续费、盈亏、保证金 +T['CurrencyUnit'] = 'double' # 币种单位数量 +T['ExchangeRate'] = 'double' # 汇率 +T['SpecProductType'] = 'char' # 特殊产品类型 +SPT_CzceHedge = '1' # 郑商所套保产品 +SPT_IneForeignCurrency = '2' # 货币质押产品 +SPT_DceOpenClose = '3' # 大连短线开平仓产品 +T['FundMortgageType'] = 'char' # 货币质押类型 +FMT_Mortgage = '1' # 质押 +FMT_Redemption = '2' # 解质 +T['AccountSettlementParamID'] = 'char' # 投资者账户结算参数代码 +ASPI_BaseMargin = '1' # 基础保证金 +ASPI_LowestInterest = '2' # 最低权益标准 +T['CurrencyName'] = 'char[31]' # 币种名称 +T['CurrencySign'] = 'char[4]' # 币种符号 +T['FundMortDirection'] = 'char' # 货币质押方向 +FMD_In = '1' # 货币质入 +FMD_Out = '2' # 货币质出 +T['BusinessClass'] = 'char' # 换汇类别 +BT_Profit = '0' # 盈利 +BT_Loss = '1' # 亏损 +BT_Other = 'Z' # 其他 +T['SwapSourceType'] = 'char' # 换汇数据来源 +SST_Manual = '0' # 手工 +SST_Automatic = '1' # 自动生成 +T['CurrExDirection'] = 'char' # 换汇类型 +CED_Settlement = '0' # 结汇 +CED_Sale = '1' # 售汇 +T['CurrencySwapStatus'] = 'char' # 申请状态 +CSS_Entry = '1' # 已录入 +CSS_Approve = '2' # 已审核 +CSS_Refuse = '3' # 已拒绝 +CSS_Revoke = '4' # 已撤销 +CSS_Send = '5' # 已发送 +CSS_Success = '6' # 换汇成功 +CSS_Failure = '7' # 换汇失败 +T['CurrExchCertNo'] = 'char[13]' # 凭证号 +T['BatchSerialNo'] = 'char[21]' # 批次号 +T['ReqFlag'] = 'char' # 换汇发送标志 +REQF_NoSend = '0' # 未发送 +REQF_SendSuccess = '1' # 发送成功 +REQF_SendFailed = '2' # 发送失败 +REQF_WaitReSend = '3' # 等待重发 +T['ResFlag'] = 'char' # 换汇返回成功标志 +RESF_Success = '0' # 成功 +RESF_InsuffiCient = '1' # 账户余额不足 +RESF_UnKnown = '8' # 交易结果未知 +T['PageControl'] = 'char[2]' # 换汇页面控制 +T['RecordCount'] = 'int' # 记录数 +T['CurrencySwapMemo'] = 'char[101]' # 换汇需确认信息 +T['ExStatus'] = 'char' # 修改状态 +EXS_Before = '0' # 修改前 +EXS_After = '1' # 修改后 +T['ClientRegion'] = 'char' # 开户客户地域 +CR_Domestic = '1' # 国内客户 +CR_GMT = '2' # 港澳台客户 +CR_Foreign = '3' # 国外客户 +T['WorkPlace'] = 'char[101]' # 工作单位 +T['BusinessPeriod'] = 'char[21]' # 经营期限 +T['WebSite'] = 'char[101]' # 网址 +T['UOAIdCardType'] = 'char[3]' # 统一开户证件类型 +T['ClientMode'] = 'char[3]' # 开户模式 +T['InvestorFullName'] = 'char[101]' # 投资者全称 +T['UOABrokerID'] = 'char[11]' # 境外中介机构ID +T['UOAZipCode'] = 'char[11]' # 邮政编码 +T['UOAEMail'] = 'char[101]' # 电子邮箱 +T['OldCity'] = 'char[41]' # 城市 +T['CorporateIdentifiedCardNo'] = 'char[101]' # 法人代表证件号码 +T['HasBoard'] = 'char' # 是否有董事会 +HB_No = '0' # 没有 +HB_Yes = '1' # 有 +T['StartMode'] = 'char' # 启动模式 +SM_Normal = '1' # 正常 +SM_Emerge = '2' # 应急 +SM_Restore = '3' # 恢复 +T['TemplateType'] = 'char' # 模型类型 +TPT_Full = '1' # 全量 +TPT_Increment = '2' # 增量 +TPT_BackUp = '3' # 备份 +T['LoginMode'] = 'char' # 登录模式 +LM_Trade = '0' # 交易 +LM_Transfer = '1' # 转账 +T['PromptType'] = 'char' # 日历提示类型 +CPT_Instrument = '1' # 合约上下市 +CPT_Margin = '2' # 保证金分段生效 +T['LedgerManageID'] = 'char[51]' # 分户管理资产编码 +T['InvestVariety'] = 'char[101]' # 投资品种 +T['BankAccountType'] = 'char[2]' # 账户类别 +T['LedgerManageBank'] = 'char[101]' # 开户银行 +T['CffexDepartmentName'] = 'char[101]' # 开户营业部 +T['CffexDepartmentCode'] = 'char[9]' # 营业部代码 +T['HasTrustee'] = 'char' # 是否有托管人 +HT_Yes = '1' # 有 +HT_No = '0' # 没有 +T['CSRCMemo1'] = 'char[41]' # 说明 +T['AssetmgrCFullName'] = 'char[101]' # 代理资产管理业务的期货公司全称 +T['AssetmgrApprovalNO'] = 'char[51]' # 资产管理业务批文号 +T['AssetmgrMgrName'] = 'char[401]' # 资产管理业务负责人姓名 +T['AmType'] = 'char' # 机构类型 +AMT_Bank = '1' # 银行 +AMT_Securities = '2' # 证券公司 +AMT_Fund = '3' # 基金公司 +AMT_Insurance = '4' # 保险公司 +AMT_Trust = '5' # 信托公司 +AMT_Other = '9' # 其他 +T['CSRCAmType'] = 'char[5]' # 机构类型 +T['CSRCFundIOType'] = 'char' # 出入金类型 +CFIOT_FundIO = '0' # 出入金 +CFIOT_SwapCurrency = '1' # 银期换汇 +T['CusAccountType'] = 'char' # 结算账户类型 +CAT_Futures = '1' # 期货结算账户 +CAT_AssetmgrFuture = '2' # 纯期货资管业务下的资管结算账户 +CAT_AssetmgrTrustee = '3' # 综合类资管业务下的期货资管托管账户 +CAT_AssetmgrTransfer = '4' # 综合类资管业务下的资金中转账户 +T['CSRCNational'] = 'char[4]' # 国籍 +T['CSRCSecAgentID'] = 'char[11]' # 二级代理ID +T['LanguageType'] = 'char' # 通知语言类型 +LT_Chinese = '1' # 中文 +LT_English = '2' # 英文 +T['AmAccount'] = 'char[23]' # 投资账户 +T['AssetmgrClientType'] = 'char' # 资产管理客户类型 +AMCT_Person = '1' # 个人资管客户 +AMCT_Organ = '2' # 单位资管客户 +AMCT_SpecialOrgan = '4' # 特殊单位资管客户 +T['AssetmgrType'] = 'char' # 投资类型 +ASST_Futures = '3' # 期货类 +ASST_SpecialOrgan = '4' # 综合类 +T['UOM'] = 'char[11]' # 计量单位 +T['SHFEInstLifePhase'] = 'char[3]' # 上期所合约生命周期状态 +T['SHFEProductClass'] = 'char[11]' # 产品类型 +T['PriceDecimal'] = 'char[2]' # 价格小数位 +T['InTheMoneyFlag'] = 'char[2]' # 平值期权标志 +T['CheckInstrType'] = 'char' # 合约比较类型 +CIT_HasExch = '0' # 合约交易所不存在 +CIT_HasATP = '1' # 合约本系统不存在 +CIT_HasDiff = '2' # 合约比较不一致 +T['DeliveryType'] = 'char' # 交割类型 +DT_HandDeliv = '1' # 手工交割 +DT_PersonDeliv = '2' # 到期交割 +T['BigMoney'] = 'double' # 资金 +T['MaxMarginSideAlgorithm'] = 'char' # 大额单边保证金算法 +MMSA_NO = '0' # 不使用大额单边保证金算法 +MMSA_YES = '1' # 使用大额单边保证金算法 +T['DAClientType'] = 'char' # 资产管理客户类型 +CACT_Person = '0' # 自然人 +CACT_Company = '1' # 法人 +CACT_Other = '2' # 其他 +T['CombinInstrID'] = 'char[61]' # 套利合约代码 +T['CombinSettlePrice'] = 'char[61]' # 各腿结算价 +T['DCEPriority'] = 'int' # 优先级 +T['TradeGroupID'] = 'int' # 成交组号 +T['IsCheckPrepa'] = 'int' # 是否校验开户可用资金 +T['UOAAssetmgrType'] = 'char' # 投资类型 +UOAAT_Futures = '1' # 期货类 +UOAAT_SpecialOrgan = '2' # 综合类 +T['DirectionEn'] = 'char' # 买卖方向 +DEN_Buy = '0' # Buy +DEN_Sell = '1' # Sell +T['OffsetFlagEn'] = 'char' # 开平标志 +OFEN_Open = '0' # Position Opening +OFEN_Close = '1' # Position Close +OFEN_ForceClose = '2' # Forced Liquidation +OFEN_CloseToday = '3' # Close Today +OFEN_CloseYesterday = '4' # Close Prev. +OFEN_ForceOff = '5' # Forced Reduction +OFEN_LocalForceClose = '6' # Local Forced Liquidation +T['HedgeFlagEn'] = 'char' # 投机套保标志 +HFEN_Speculation = '1' # Speculation +HFEN_Arbitrage = '2' # Arbitrage +HFEN_Hedge = '3' # Hedge +T['FundIOTypeEn'] = 'char' # 出入金类型 +FIOTEN_FundIO = '1' # Deposit/Withdrawal +FIOTEN_Transfer = '2' # Bank-Futures Transfer +FIOTEN_SwapCurrency = '3' # Bank-Futures FX Exchange +T['FundTypeEn'] = 'char' # 资金类型 +FTEN_Deposite = '1' # Bank Deposit +FTEN_ItemFund = '2' # Payment/Fee +FTEN_Company = '3' # Brokerage Adj +FTEN_InnerTransfer = '4' # Internal Transfer +T['FundDirectionEn'] = 'char' # 出入金方向 +FDEN_In = '1' # Deposit +FDEN_Out = '2' # Withdrawal +T['FundMortDirectionEn'] = 'char' # 货币质押方向 +FMDEN_In = '1' # Pledge +FMDEN_Out = '2' # Redemption +T['SwapBusinessType'] = 'char[3]' # 换汇业务种类 +T['OptionsType'] = 'char' # 期权类型 +CP_CallOptions = '1' # 看涨 +CP_PutOptions = '2' # 看跌 +T['StrikeMode'] = 'char' # 执行方式 +STM_Continental = '0' # 欧式 +STM_American = '1' # 美式 +STM_Bermuda = '2' # 百慕大 +T['StrikeType'] = 'char' # 执行类型 +STT_Hedge = '0' # 自身对冲 +STT_Match = '1' # 匹配执行 +T['ApplyType'] = 'char' # 中金所期权放弃执行申请类型 +APPT_NotStrikeNum = '4' # 不执行数量 +T['GiveUpDataSource'] = 'char' # 放弃执行申请数据来源 +GUDS_Gen = '0' # 系统生成 +GUDS_Hand = '1' # 手工添加 +T['ExecOrderSysID'] = 'char[21]' # 执行宣告系统编号 +T['ExecResult'] = 'char' # 执行结果 +OER_NoExec = 'n' # 没有执行 +OER_Canceled = 'c' # 已经取消 +OER_OK = '0' # 执行成功 +OER_NoPosition = '1' # 期权持仓不够 +OER_NoDeposit = '2' # 资金不够 +OER_NoParticipant = '3' # 会员不存在 +OER_NoClient = '4' # 客户不存在 +OER_NoInstrument = '6' # 合约不存在 +OER_NoRight = '7' # 没有执行权限 +OER_InvalidVolume = '8' # 不合理的数量 +OER_NoEnoughHistoryTrade = '9' # 没有足够的历史成交 +OER_Unknown = 'a' # 未知 +T['StrikeSequence'] = 'int' # 执行序号 +T['StrikeTime'] = 'char[13]' # 执行时间 +T['CombinationType'] = 'char' # 组合类型 +COMBT_Future = '0' # 期货组合 +COMBT_BUL = '1' # 垂直价差BUL +COMBT_BER = '2' # 垂直价差BER +COMBT_STD = '3' # 跨式组合 +COMBT_STG = '4' # 宽跨式组合 +COMBT_PRT = '5' # 备兑组合 +COMBT_CLD = '6' # 时间价差组合 +T['OptionRoyaltyPriceType'] = 'char' # 期权权利金价格类型 +ORPT_PreSettlementPrice = '1' # 昨结算价 +ORPT_OpenPrice = '4' # 开仓价 +T['BalanceAlgorithm'] = 'char' # 权益算法 +BLAG_Default = '1' # 不计算期权市值盈亏 +BLAG_IncludeOptValLost = '2' # 计算期权市值亏损 +T['ActionType'] = 'char' # 执行类型 +ACTP_Exec = '1' # 执行 +ACTP_Abandon = '2' # 放弃 +T['ForQuoteStatus'] = 'char' # 询价状态 +FQST_Submitted = 'a' # 已经提交 +FQST_Accepted = 'b' # 已经接受 +FQST_Rejected = 'c' # 已经被拒绝 +T['ValueMethod'] = 'char' # 取值方式 +VM_Absolute = '0' # 按绝对值 +VM_Ratio = '1' # 按比率 +T['ExecOrderPositionFlag'] = 'char' # 期权行权后是否保留期货头寸的标记 +EOPF_Reserve = '0' # 保留 +EOPF_UnReserve = '1' # 不保留 +T['ExecOrderCloseFlag'] = 'char' # 期权行权后生成的头寸是否自动平仓 +EOCF_AutoClose = '0' # 自动平仓 +EOCF_NotToClose = '1' # 免于自动平仓 +T['ProductType'] = 'char' # 产品类型 +PTE_Futures = '1' # 期货 +PTE_Options = '2' # 期权 +T['CZCEUploadFileName'] = 'char' # 郑商所结算文件名 +CUFN_CUFN_O = 'O' # ^\d{8}_zz_\d{4} +CUFN_CUFN_T = 'T' # ^\d{8}成交表 +CUFN_CUFN_P = 'P' # ^\d{8}单腿持仓表new +CUFN_CUFN_N = 'N' # ^\d{8}非平仓了结表 +CUFN_CUFN_L = 'L' # ^\d{8}平仓表 +CUFN_CUFN_F = 'F' # ^\d{8}资金表 +CUFN_CUFN_C = 'C' # ^\d{8}组合持仓表 +CUFN_CUFN_M = 'M' # ^\d{8}保证金参数表 +T['DCEUploadFileName'] = 'char' # 大商所结算文件名 +DUFN_DUFN_O = 'O' # ^\d{8}_dl_\d{3} +DUFN_DUFN_T = 'T' # ^\d{8}_成交表 +DUFN_DUFN_P = 'P' # ^\d{8}_持仓表 +DUFN_DUFN_F = 'F' # ^\d{8}_资金结算表 +DUFN_DUFN_C = 'C' # ^\d{8}_优惠组合持仓明细表 +DUFN_DUFN_D = 'D' # ^\d{8}_持仓明细表 +DUFN_DUFN_M = 'M' # ^\d{8}_保证金参数表 +DUFN_DUFN_S = 'S' # ^\d{8}_期权执行表 +T['SHFEUploadFileName'] = 'char' # 上期所结算文件名 +SUFN_SUFN_O = 'O' # ^\d{4}_\d{8}_\d{8}_DailyFundChg +SUFN_SUFN_T = 'T' # ^\d{4}_\d{8}_\d{8}_Trade +SUFN_SUFN_P = 'P' # ^\d{4}_\d{8}_\d{8}_SettlementDetail +SUFN_SUFN_F = 'F' # ^\d{4}_\d{8}_\d{8}_Capital +T['CFFEXUploadFileName'] = 'char' # 中金所结算文件名 +CFUFN_SUFN_T = 'T' # ^\d{4}_SG\d{1}_\d{8}_\d{1}_Trade +CFUFN_SUFN_P = 'P' # ^\d{4}_SG\d{1}_\d{8}_\d{1}_SettlementDetail +CFUFN_SUFN_F = 'F' # ^\d{4}_SG\d{1}_\d{8}_\d{1}_Capital +CFUFN_SUFN_S = 'S' # ^\d{4}_SG\d{1}_\d{8}_\d{1}_OptionExec +T['CombDirection'] = 'char' # 组合指令方向 +CMDR_Comb = '0' # 申请组合 +CMDR_UnComb = '1' # 申请拆分 + + +error = { + 'NONE': 0, 0: 'CTP:正确', 'INVALID_DATA_SYNC_STATUS': 1, 1: 'CTP:不在已同步状态', 'INCONSISTENT_INFORMATION': 2, + 2: 'CTP:会话信息不一致', 'INVALID_LOGIN': 3, 3: 'CTP:不合法的登录', 'USER_NOT_ACTIVE': 4, 4: 'CTP:用户不活跃', + 'DUPLICATE_LOGIN': 5, 5: 'CTP:重复的登录', 'NOT_LOGIN_YET': 6, 6: 'CTP:还没有登录', 'NOT_INITED': 7, 7: 'CTP:还没有初始化', + 'FRONT_NOT_ACTIVE': 8, 8: 'CTP:前置不活跃', 'NO_PRIVILEGE': 9, 9: 'CTP:无此权限', 'CHANGE_OTHER_PASSWORD': 10, + 10: 'CTP:修改别人的口令', 'USER_NOT_FOUND': 11, 11: 'CTP:找不到该用户', 'BROKER_NOT_FOUND': 12, 12: 'CTP:找不到该经纪公司', + 'INVESTOR_NOT_FOUND': 13, 13: 'CTP:找不到投资者', 'OLD_PASSWORD_MISMATCH': 14, 14: 'CTP:原口令不匹配', 'BAD_FIELD': 15, + 15: 'CTP:报单字段有误', 'INSTRUMENT_NOT_FOUND': 16, 16: 'CTP:找不到合约', 'INSTRUMENT_NOT_TRADING': 17, 17: 'CTP:合约不能交易', + 'NOT_EXCHANGE_PARTICIPANT': 18, 18: 'CTP:经纪公司不是交易所的会员', 'INVESTOR_NOT_ACTIVE': 19, 19: 'CTP:投资者不活跃', + 'NOT_EXCHANGE_CLIENT': 20, 20: 'CTP:投资者未在交易所开户', 'NO_VALID_TRADER_AVAILABLE': 21, 21: 'CTP:该交易席位未连接到交易所', + 'DUPLICATE_ORDER_REF': 22, 22: 'CTP:报单错误:不允许重复报单', 'BAD_ORDER_ACTION_FIELD': 23, 23: 'CTP:错误的报单操作字段', + 'DUPLICATE_ORDER_ACTION_REF': 24, 24: 'CTP:撤单已报送,不允许重复撤单', 'ORDER_NOT_FOUND': 25, 25: 'CTP:撤单找不到相应报单', + 'INSUITABLE_ORDER_STATUS': 26, 26: 'CTP:报单已全成交或已撤销,不能再撤', 'UNSUPPORTED_FUNCTION': 27, 27: 'CTP:不支持的功能', + 'NO_TRADING_RIGHT': 28, 28: 'CTP:没有报单交易权限', 'CLOSE_ONLY': 29, 29: 'CTP:只能平仓', 'OVER_CLOSE_POSITION': 30, + 30: 'CTP:平仓量超过持仓量', 'INSUFFICIENT_MONEY': 31, 31: 'CTP:资金不足', 'DUPLICATE_PK': 32, 32: 'CTP:主键重复', + 'CANNOT_FIND_PK': 33, 33: 'CTP:找不到主键', 'CAN_NOT_INACTIVE_BROKER': 34, 34: 'CTP:设置经纪公司不活跃状态失败', + 'BROKER_SYNCHRONIZING': 35, 35: 'CTP:经纪公司正在同步', 'BROKER_SYNCHRONIZED': 36, 36: 'CTP:经纪公司已同步', 'SHORT_SELL': 37, + 37: 'CTP:现货交易不能卖空', 'INVALID_SETTLEMENT_REF': 38, 38: 'CTP:不合法的结算引用', 'CFFEX_NETWORK_ERROR': 39, + 39: 'CTP:交易所网络连接失败', 'CFFEX_OVER_REQUEST': 40, 40: 'CTP:交易所未处理请求超过许可数', 'CFFEX_OVER_REQUEST_PER_SECOND': 41, + 41: 'CTP:交易所每秒发送请求数超过许可数', 'SETTLEMENT_INFO_NOT_CONFIRMED': 42, 42: 'CTP:结算结果未确认', 'DEPOSIT_NOT_FOUND': 43, + 43: 'CTP:没有对应的入金记录', 'EXCHANG_TRADING': 44, 44: 'CTP:交易所已经进入连续交易状态', 'PARKEDORDER_NOT_FOUND': 45, + 45: 'CTP:找不到预埋(撤单)单', 'PARKEDORDER_HASSENDED': 46, 46: 'CTP:预埋(撤单)单已经发送', 'PARKEDORDER_HASDELETE': 47, + 47: 'CTP:预埋(撤单)单已经删除', 'INVALID_INVESTORIDORPASSWORD': 48, 48: 'CTP:无效的投资者或者密码', 'INVALID_LOGIN_IPADDRESS': 49, + 49: 'CTP:不合法的登录IP地址', 'OVER_CLOSETODAY_POSITION': 50, 50: 'CTP:平今仓位不足', 'OVER_CLOSEYESTERDAY_POSITION': 51, + 51: 'CTP:平昨仓位不足', 'BROKER_NOT_ENOUGH_CONDORDER': 52, 52: 'CTP:经纪公司没有足够可用的条件单数量', + 'INVESTOR_NOT_ENOUGH_CONDORDER': 53, 53: 'CTP:投资者没有足够可用的条件单数量', 'BROKER_NOT_SUPPORT_CONDORDER': 54, + 54: 'CTP:经纪公司不支持条件单', 'RESEND_ORDER_BROKERINVESTOR_NOTMATCH': 55, 55: 'CTP:重发未知单经济公司/投资者不匹配', + 'SYC_OTP_FAILED': 56, 56: 'CTP:同步动态令牌失败', 'OTP_MISMATCH': 57, 57: 'CTP:动态令牌校验错误', 'OTPPARAM_NOT_FOUND': 58, + 58: 'CTP:找不到动态令牌配置信息', 'UNSUPPORTED_OTPTYPE': 59, 59: 'CTP:不支持的动态令牌类型', 'SINGLEUSERSESSION_EXCEED_LIMIT': 60, + 60: 'CTP:用户在线会话超出上限', 'EXCHANGE_UNSUPPORTED_ARBITRAGE': 61, 61: 'CTP:该交易所不支持套利类型报单', + 'NO_CONDITIONAL_ORDER_RIGHT': 62, 62: 'CTP:没有条件单交易权限', 'AUTH_FAILED': 63, 63: 'CTP:客户端认证失败', 'NOT_AUTHENT': 64, + 64: 'CTP:客户端未认证', 'SWAPORDER_UNSUPPORTED': 65, 65: 'CTP:该合约不支持互换类型报单', 'OPTIONS_ONLY_SUPPORT_SPEC': 66, + 66: 'CTP:该期权合约只支持投机类型报单', 'DUPLICATE_EXECORDER_REF': 67, 67: 'CTP:执行宣告错误,不允许重复执行', + 'RESEND_EXECORDER_BROKERINVESTOR_NOTMATCH': 68, 68: 'CTP:重发未知执行宣告经纪公司/投资者不匹配', 'EXECORDER_NOTOPTIONS': 69, + 69: 'CTP:只有期权合约可执行', 'OPTIONS_NOT_SUPPORT_EXEC': 70, 70: 'CTP:该期权合约不支持执行', 'BAD_EXECORDER_ACTION_FIELD': 71, + 71: 'CTP:执行宣告字段有误', 'DUPLICATE_EXECORDER_ACTION_REF': 72, 72: 'CTP:执行宣告撤单已报送,不允许重复撤单', + 'EXECORDER_NOT_FOUND': 73, 73: 'CTP:执行宣告撤单找不到相应执行宣告', 'OVER_EXECUTE_POSITION': 74, 74: 'CTP:执行仓位不足', + 'LOGIN_FORBIDDEN': 75, 75: 'CTP:连续登录失败次数超限,登录被禁止', 'INVALID_TRANSFER_AGENT': 76, 76: 'CTP:非法银期代理关系', + 'NO_FOUND_FUNCTION': 77, 77: 'CTP:无此功能', 'SEND_EXCHANGEORDER_FAILED': 78, 78: 'CTP:发送报单失败', + 'SEND_EXCHANGEORDERACTION_FAILED': 79, 79: 'CTP:发送报单操作失败', 'PRICETYPE_NOTSUPPORT_BYEXCHANGE': 80, + 80: 'CTP:交易所不支持的价格类型', 'BAD_EXECUTE_TYPE': 81, 81: 'CTP:错误的执行类型', 'BAD_OPTION_INSTR': 82, 82: 'CTP:无效的组合合约', + 'INSTR_NOTSUPPORT_FORQUOTE': 83, 83: 'CTP:该合约不支持询价', 'RESEND_QUOTE_BROKERINVESTOR_NOTMATCH': 84, + 84: 'CTP:重发未知报价经纪公司/投资者不匹配', 'INSTR_NOTSUPPORT_QUOTE': 85, 85: 'CTP:该合约不支持报价', 'QUOTE_NOT_FOUND': 86, + 86: 'CTP:报价撤单找不到相应报价', 'OPTIONS_NOT_SUPPORT_ABANDON': 87, 87: 'CTP:该期权合约不支持放弃执行', + 'COMBOPTIONS_SUPPORT_IOC_ONLY': 88, 88: 'CTP:该组合期权合约只支持IOC', 'OPEN_FILE_FAILED': 89, 89: 'CTP:打开文件失败', + 'NEED_RETRY': 90, 90: 'CTP:查询未就绪,请稍后重试', 'EXCHANGE_RTNERROR': 91, 91: 'CTP:交易所返回的错误', + 'QUOTE_DERIVEDORDER_ACTIONERROR': 92, 92: 'CTP:报价衍生单要等待交易所返回才能撤单', 'INSTRUMENTMAP_NOT_FOUND': 93, + 93: 'CTP:找不到组合合约映射', 'NO_TRADING_RIGHT_IN_SEPC_DR': 101, 101: 'CTP:用户在本系统没有报单权限', 'NO_DR_NO': 102, + 102: 'CTP:系统缺少灾备标示号', 'BATCHACTION_NOSUPPORT': 103, 103: 'CTP:该交易所不支持批量撤单', 'OUT_OF_TIMEINTERVAL': 113, + 113: 'CTP:当前时间禁止询价', 'OUT_OF_PRICEINTERVAL': 114, 114: 'CTP:当前价差禁止询价', 'SEND_INSTITUTION_CODE_ERROR': 1000, + 1000: 'CTP:银期转账:发送机构代码错误', 'NO_GET_PLATFORM_SN': 1001, 1001: 'CTP:银期转账:取平台流水号错误', + 'ILLEGAL_TRANSFER_BANK': 1002, 1002: 'CTP:银期转账:不合法的转账银行', 'ALREADY_OPEN_ACCOUNT': 1003, 1003: 'CTP:银期转账:已经开户', + 'NOT_OPEN_ACCOUNT': 1004, 1004: 'CTP:银期转账:未开户', 'PROCESSING': 1005, 1005: 'CTP:银期转账:处理中', 'OVERTIME': 1006, + 1006: 'CTP:银期转账:交易超时', 'RECORD_NOT_FOUND': 1007, 1007: 'CTP:银期转账:找不到记录', + 'NO_FOUND_REVERSAL_ORIGINAL_TRANSACTION': 1008, 1008: 'CTP:银期转账:找不到被冲正的原始交易', 'CONNECT_HOST_FAILED': 1009, + 1009: 'CTP:银期转账:连接主机失败', 'SEND_FAILED': 1010, 1010: 'CTP:银期转账:发送失败', 'LATE_RESPONSE': 1011, + 1011: 'CTP:银期转账:迟到应答', 'REVERSAL_BANKID_NOT_MATCH': 1012, 1012: 'CTP:银期转账:冲正交易银行代码错误', + 'REVERSAL_BANKACCOUNT_NOT_MATCH': 1013, 1013: 'CTP:银期转账:冲正交易银行账户错误', 'REVERSAL_BROKERID_NOT_MATCH': 1014, + 1014: 'CTP:银期转账:冲正交易经纪公司代码错误', 'REVERSAL_ACCOUNTID_NOT_MATCH': 1015, 1015: 'CTP:银期转账:冲正交易资金账户错误', + 'REVERSAL_AMOUNT_NOT_MATCH': 1016, 1016: 'CTP:银期转账:冲正交易交易金额错误', 'DB_OPERATION_FAILED': 1017, + 1017: 'CTP:银期转账:数据库操作错误', 'SEND_ASP_FAILURE': 1018, 1018: 'CTP:银期转账:发送到交易系统失败', 'NOT_SIGNIN': 1019, + 1019: 'CTP:银期转账:没有签到', 'ALREADY_SIGNIN': 1020, 1020: 'CTP:银期转账:已经签到', 'AMOUNT_OR_TIMES_OVER': 1021, + 1021: 'CTP:银期转账:金额或次数超限', 'NOT_IN_TRANSFER_TIME': 1022, 1022: 'CTP:银期转账:这一时间段不能转账', 'BANK_SERVER_ERROR': 1023, + 1023: '银行主机错', 'BANK_SERIAL_IS_REPEALED': 1024, 1024: 'CTP:银期转账:银行已经冲正', 'BANK_SERIAL_NOT_EXIST': 1025, + 1025: 'CTP:银期转账:银行流水不存在', 'NOT_ORGAN_MAP': 1026, 1026: 'CTP:银期转账:机构没有签约', 'EXIST_TRANSFER': 1027, + 1027: 'CTP:银期转账:存在转账,不能销户', 'BANK_FORBID_REVERSAL': 1028, 1028: 'CTP:银期转账:银行不支持冲正', 'DUP_BANK_SERIAL': 1029, + 1029: 'CTP:银期转账:重复的银行流水', 'FBT_SYSTEM_BUSY': 1030, 1030: 'CTP:银期转账:转账系统忙,稍后再试', 'MACKEY_SYNCING': 1031, + 1031: 'CTP:银期转账:MAC密钥正在同步', 'ACCOUNTID_ALREADY_REGISTER': 1032, 1032: 'CTP:银期转账:资金账户已经登记', + 'BANKACCOUNT_ALREADY_REGISTER': 1033, 1033: 'CTP:银期转账:银行账户已经登记', 'DUP_BANK_SERIAL_REDO_OK': 1034, + 1034: 'CTP:银期转账:重复的银行流水,重发成功', 'CURRENCYID_NOT_SUPPORTED': 1035, 1035: 'CTP:银期转账:该币种代码不支持', + 'INVALID_MAC': 1036, 1036: 'CTP:银期转账:MAC值验证失败', 'NOT_SUPPORT_SECAGENT_BY_BANK': 1037, + 1037: 'CTP:银期转账:不支持银行端发起的二级代理商转账和查询', 'PINKEY_SYNCING': 1038, 1038: 'CTP:银期转账:PIN密钥正在同步', + 'SECAGENT_QUERY_BY_CCB': 1039, 1039: 'CTP:银期转账:建行发起的二级代理商查询', 'NO_VALID_BANKOFFER_AVAILABLE': 2000, + 2000: 'CTP:该报盘未连接到银行', 'PASSWORD_MISMATCH': 2001, 2001: 'CTP:资金密码错误', 'DUPLATION_BANK_SERIAL': 2004, + 2004: 'CTP:银行流水号重复', 'DUPLATION_OFFER_SERIAL': 2005, 2005: 'CTP:报盘流水号重复', 'SERIAL_NOT_EXSIT': 2006, + 2006: 'CTP:被冲正流水不存在(冲正交易)', 'SERIAL_IS_REPEALED': 2007, 2007: 'CTP:原流水已冲正(冲正交易)', 'SERIAL_MISMATCH': 2008, + 2008: 'CTP:与原流水信息不符(冲正交易)', 'IdentifiedCardNo_MISMATCH': 2009, 2009: 'CTP:证件号码或类型错误', 'ACCOUNT_NOT_FUND': 2011, + 2011: 'CTP:资金账户不存在', 'ACCOUNT_NOT_ACTIVE': 2012, 2012: 'CTP:资金账户已经销户', 'NOT_ALLOW_REPEAL_BYMANUAL': 2013, + 2013: 'CTP:该交易不能执行手工冲正', 'AMOUNT_OUTOFTHEWAY': 2014, 2014: 'CTP:转帐金额错误', 'EXCHANGERATE_NOT_FOUND': 2015, + 2015: 'CTP:找不到汇率', 'WAITING_OFFER_RSP': 999999, 999999: 'CTP:等待银期报盘处理结果', 'FBE_NO_GET_PLATFORM_SN': 3001, + 3001: 'CTP:银期换汇:取平台流水号错误', 'FBE_ILLEGAL_TRANSFER_BANK': 3002, 3002: 'CTP:银期换汇:不合法的转账银行', + 'FBE_PROCESSING': 3005, 3005: 'CTP:银期换汇:处理中', 'FBE_OVERTIME': 3006, 3006: 'CTP:银期换汇:交易超时', + 'FBE_RECORD_NOT_FOUND': 3007, 3007: 'CTP:银期换汇:找不到记录', 'FBE_CONNECT_HOST_FAILED': 3009, 3009: 'CTP:银期换汇:连接主机失败', + 'FBE_SEND_FAILED': 3010, 3010: 'CTP:银期换汇:发送失败', 'FBE_LATE_RESPONSE': 3011, 3011: 'CTP:银期换汇:迟到应答', + 'FBE_DB_OPERATION_FAILED': 3017, 3017: 'CTP:银期换汇:数据库操作错误', 'FBE_NOT_SIGNIN': 3019, 3019: 'CTP:银期换汇:没有签到', + 'FBE_ALREADY_SIGNIN': 3020, 3020: 'CTP:银期换汇:已经签到', 'FBE_AMOUNT_OR_TIMES_OVER': 3021, 3021: 'CTP:银期换汇:金额或次数超限', + 'FBE_NOT_IN_TRANSFER_TIME': 3022, 3022: 'CTP:银期换汇:这一时间段不能换汇', 'FBE_BANK_SERVER_ERROR': 3023, + 3023: 'CTP:银期换汇:银行主机错', 'FBE_NOT_ORGAN_MAP': 3026, 3026: 'CTP:银期换汇:机构没有签约', 'FBE_SYSTEM_BUSY': 3030, + 3030: 'CTP:银期换汇:换汇系统忙,稍后再试', 'FBE_CURRENCYID_NOT_SUPPORTED': 3035, 3035: 'CTP:银期换汇:该币种代码不支持', + 'FBE_WRONG_BANK_ACCOUNT': 3036, 3036: 'CTP:银期换汇:银行帐号不正确', 'FBE_BANK_ACCOUNT_NO_FUNDS': 3037, + 3037: 'CTP:银期换汇:银行帐户余额不足', 'FBE_DUP_CERT_NO': 3038, 3038: 'CTP:银期换汇:凭证号重复'} diff --git a/qbot/engine/trade/trader/trader/utils/__init__.py b/qbot/engine/trade/trader/trader/utils/__init__.py new file mode 100644 index 00000000..9ce52a0e --- /dev/null +++ b/qbot/engine/trade/trader/trader/utils/__init__.py @@ -0,0 +1,796 @@ +# coding=utf-8 +# +# Copyright 2016 timercrack +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +import logging +import ujson as json +from decimal import Decimal +import datetime +import math +import re +import xml.etree.ElementTree as ET +import asyncio +import os +from functools import reduce +from itertools import combinations + +import pytz +import aiohttp +from django.db.models import Q, F, Max, Min +from django.utils import timezone +import redis +from talib import ATR +from tqdm import tqdm + +from panel.models import * +from trader.utils import ApiStruct +from trader.utils.read_config import config + +logger = logging.getLogger('utils') + +max_conn_shfe = asyncio.Semaphore(15) +max_conn_dce = asyncio.Semaphore(5) +max_conn_gfex = asyncio.Semaphore(5) +max_conn_czce = asyncio.Semaphore(15) +max_conn_cffex = asyncio.Semaphore(15) +max_conn_sina = asyncio.Semaphore(15) +cffex_ip = 'www.cffex.com.cn' # www.cffex.com.cn +shfe_ip = 'www.shfe.com.cn' # www.shfe.com.cn +czce_ip = 'www.czce.com.cn' # www.czce.com.cn +dce_ip = 'www.dce.com.cn' # www.dce.com.cn +gfex_ip = 'www.gfex.com.cn' +IGNORE_INST_LIST = config.get('TRADE', 'ignore_inst').split(',') +INE_INST_LIST = ['sc', 'bc', 'nr', 'lu'] +ORDER_REF_SIGNAL_ID_START = -5 + + +def str_to_number(s): + try: + if not isinstance(s, str): + return s + return int(s) + except ValueError: + return float(s) + + +def price_round(x: Decimal, base: Decimal): + """ + 根据最小精度取整,例如对于IF最小精度是0.2,那么 1.3 -> 1.2, 1.5 -> 1.4 + :param x: Decimal 待取整的数 + :param base: Decimal 最小精度 + :return: float 取整结果 + """ + if not type(x) is Decimal: + x = Decimal(x) + if not type(base) is Decimal: + base = Decimal(base) + precision = 0 + s = str(round(base, 3) % 1) + s = s.rstrip('0').rstrip('.') if '.' in s else s + p1, *p2 = s.split('.') + if p2: + precision = len(p2[0]) + return round(base * round(x / base), precision) + + +def get_next_id(): + if not hasattr(get_next_id, "request_id"): + get_next_id.request_id = 0 + get_next_id.request_id = 1 if get_next_id.request_id == 65535 else get_next_id.request_id + 1 + return get_next_id.request_id + + +async def is_trading_day(day: datetime.datetime): + s = redis.StrictRedis( + host=config.get('REDIS', 'host', fallback='localhost'), + db=config.getint('REDIS', 'db', fallback=0), decode_responses=True) + return day, day.strftime('%Y%m%d') in (s.get('TradingDay'), s.get('LastTradingDay')) + + +async def check_trading_day(day: datetime.datetime) -> (datetime.datetime, bool): + async with aiohttp.ClientSession() as session: + await max_conn_cffex.acquire() + async with session.get( + 'http://{}/fzjy/mrhq/{}/index.xml'.format(cffex_ip, day.strftime('%Y%m/%d')), + allow_redirects=False) as response: + max_conn_cffex.release() + return day, response.status == 200 + + +def get_expire_date(inst_code: str, day: datetime.datetime): + expire_date = int(re.findall(r'\d+', inst_code)[0]) + if expire_date < 1000: + year_exact = math.floor(day.year % 100 / 10) + if expire_date < 100 and day.year % 10 == 9: + year_exact += 1 + expire_date += year_exact * 1000 + return expire_date + + +async def update_from_shfe(day: datetime.datetime) -> bool: + try: + async with aiohttp.ClientSession() as session: + day_str = day.strftime('%Y%m%d') + await max_conn_shfe.acquire() + async with session.get(f'http://{shfe_ip}/data/dailydata/kx/kx{day_str}.dat') as response: + rst = await response.read() + rst_json = json.loads(rst) + max_conn_shfe.release() + inst_name_dict = {} + for inst_data in rst_json['o_curinstrument']: + """ + {"PRODUCTID":"cu_f ","PRODUCTGROUPID":"cu ","PRODUCTSORTNO":10,"PRODUCTNAME":"铜 ", + "DELIVERYMONTH":"2112","PRESETTLEMENTPRICE":69850,"OPENPRICE":69770,"HIGHESTPRICE":70280,"LOWESTPRICE":69600, + "CLOSEPRICE":69900,"SETTLEMENTPRICE":69950,"ZD1_CHG":50,"ZD2_CHG":100,"VOLUME":19450,"TURNOVER":680294.525, + "TASVOLUME":"","OPENINTEREST":19065,"OPENINTERESTCHG":-5585,"ORDERNO":0,"ORDERNO2":0} + """ + # error_data = inst_data + if inst_data['DELIVERYMONTH'] == '小计' or inst_data['PRODUCTID'] == '总计': + continue + if '_f' not in inst_data['PRODUCTID']: + continue + # logger.info(f'inst_data: {inst_data}') + code = inst_data['PRODUCTGROUPID'].strip() + if code in IGNORE_INST_LIST: + continue + name = inst_data['PRODUCTNAME'].strip() + if code not in inst_name_dict: + inst_name_dict[code] = name + exchange_str = ExchangeType.SHFE + # 上期能源的四个品种 + if code in INE_INST_LIST: + exchange_str = ExchangeType.INE + DailyBar.objects.update_or_create( + code=code + inst_data['DELIVERYMONTH'], + exchange=exchange_str, time=day, defaults={ + 'expire_date': inst_data['DELIVERYMONTH'], + 'open': inst_data['OPENPRICE'] if inst_data['OPENPRICE'] else inst_data['CLOSEPRICE'], + 'high': inst_data['HIGHESTPRICE'] if inst_data['HIGHESTPRICE'] else + inst_data['CLOSEPRICE'], + 'low': inst_data['LOWESTPRICE'] if inst_data['LOWESTPRICE'] + else inst_data['CLOSEPRICE'], + 'close': inst_data['CLOSEPRICE'], + 'settlement': inst_data['SETTLEMENTPRICE'] if inst_data['SETTLEMENTPRICE'] else + inst_data['PRESETTLEMENTPRICE'], + 'volume': inst_data['VOLUME'] if inst_data['VOLUME'] else 0, + 'open_interest': inst_data['OPENINTEREST'] if inst_data['OPENINTEREST'] else 0}) + # 更新上期所合约中文名称 + for code, name in inst_name_dict.items(): + Instrument.objects.filter(product_code=code).update(name=name) + return True + except Exception as e: + logger.warning(f'update_from_shfe failed: {repr(e)}', exc_info=True) + return False + + +async def update_from_czce(day: datetime.datetime) -> bool: + try: + async with aiohttp.ClientSession() as session: + day_str = day.strftime('%Y%m%d') + async with session.get( + f'http://{czce_ip}/cn/DFSStaticFiles/Future/{day.year}/{day_str}/FutureDataDaily.txt') as response: + rst = await response.text() + for lines in rst.split('\n')[1:-3]: + if '小计' in lines or '合约' in lines or '品种' in lines: + continue + inst_data = [x.strip() for x in lines.split('|' if '|' in lines else ',')] + """ + [0'合约代码', 1'昨结算', 2'今开盘', 3'最高价', 4'最低价', 5'今收盘', 6'今结算', 7'涨跌1', 8'涨跌2', 9'成交量(手)', + 10'持仓量', 11'增减量', 12'成交额(万元)', 13'交割结算价'] + ['CF601', '11,970.00', '11,970.00', '11,970.00', '11,800.00', '11,870.00', '11,905.00', '-100.00', + '-65.00', '13,826', '59,140', '-10,760', '82,305.24', ''] + """ + # print(f'inst_data: {inst_data}') + if re.findall('[A-Za-z]+', inst_data[0])[0] in IGNORE_INST_LIST: + continue + close = inst_data[5].replace(',', '') if Decimal(inst_data[5].replace(',', '')) > 0.1 \ + else inst_data[6].replace(',', '') + DailyBar.objects.update_or_create( + code=inst_data[0], + exchange=ExchangeType.CZCE, time=day, defaults={ + 'expire_date': get_expire_date(inst_data[0], day), + 'open': inst_data[2].replace(',', '') if Decimal(inst_data[2].replace(',', '')) > 0.1 + else close, + 'high': inst_data[3].replace(',', '') if Decimal(inst_data[3].replace(',', '')) > 0.1 + else close, + 'low': inst_data[4].replace(',', '') if Decimal(inst_data[4].replace(',', '')) > 0.1 + else close, + 'close': close, + 'settlement': inst_data[6].replace(',', '') if + Decimal(inst_data[6].replace(',', '')) > 0.1 else inst_data[1].replace(',', ''), + 'volume': inst_data[9].replace(',', ''), + 'open_interest': inst_data[10].replace(',', '')}) + return True + except Exception as e: + logger.warning(f'update_from_czce failed: {repr(e)}', exc_info=True) + return False + + +async def update_from_dce(day: datetime.datetime) -> bool: + try: + async with aiohttp.ClientSession() as session: + await max_conn_dce.acquire() + async with session.post(f'http://{dce_ip}/publicweb/quotesdata/exportDayQuotesChData.html', data={ + 'dayQuotes.variety': 'all', 'dayQuotes.trade_type': 0, 'exportFlag': 'txt', + 'year': day.year, 'month': day.month-1, 'day': day.day}) as response: + rst = await response.text() + max_conn_dce.release() + for lines in rst.split('\r\n')[1:-3]: + if '小计' in lines or '品种' in lines: + continue + inst_data_raw = [x.strip() for x in lines.split('\t')] + inst_data = [] + for cell in inst_data_raw: + if len(cell) > 0: + inst_data.append(cell) + """ + [0'商品名称', 1'交割月份', 2'开盘价', 3'最高价', 4'最低价', 5'收盘价', 6'前结算价', 7'结算价', 8'涨跌', 9'涨跌1', 10'成交量', + 11'持仓量', 12'持仓量变化', 13'成交额'] + ['豆一', '1611', '3,760', '3,760', '3,760', '3,760', '3,860', '3,760', '-100', '-100', '2', '0', '0', '7.52'] + """ + if '小计' in inst_data[0]: + continue + if DCE_NAME_CODE[inst_data[0]] in IGNORE_INST_LIST: + continue + expire_date = inst_data[1].removeprefix(DCE_NAME_CODE[inst_data[0]]) + DailyBar.objects.update_or_create( + code=inst_data[1], + exchange=ExchangeType.DCE, time=day, defaults={ + 'expire_date': expire_date, + 'open': inst_data[2].replace(',', '') if inst_data[2] != '-' else + inst_data[5].replace(',', ''), + 'high': inst_data[3].replace(',', '') if inst_data[3] != '-' else + inst_data[5].replace(',', ''), + 'low': inst_data[4].replace(',', '') if inst_data[4] != '-' else + inst_data[5].replace(',', ''), + 'close': inst_data[5].replace(',', ''), + 'settlement': inst_data[7].replace(',', '') if inst_data[7] != '-' else + inst_data[6].replace(',', ''), + 'volume': inst_data[10].replace(',', ''), + 'open_interest': inst_data[11].replace(',', '')}) + return True + except Exception as e: + logger.warning(f'update_from_dce failed: {repr(e)}', exc_info=True) + return False + + +async def update_from_gfex(day: datetime.datetime) -> bool: + try: + async with aiohttp.ClientSession() as session: + await max_conn_gfex.acquire() + for ids in ['lc', 'si']: + async with session.post(f'http://{gfex_ip}/gfexweb/Quote/getQuote_ftr', data={'varietyid': ids}) as response: + rst = await response.text() + rst = json.loads(rst) + max_conn_gfex.release() + for inst_code, inst_data in rst['contractQuote'].items(): + expire_date = inst_code.removeprefix(ids) + DailyBar.objects.update_or_create( + code=inst_code, + exchange=ExchangeType.GFEX, time=day, defaults={ + 'expire_date': expire_date, + 'open': inst_data['openPrice'] if inst_data['openPrice'] != "--" else inst_data['closePrice'], + 'high': inst_data['highPrice'] if inst_data['highPrice'] != "--" else inst_data['closePrice'], + 'low': inst_data['lowPrice'] if inst_data['lowPrice'] != "--" else inst_data['closePrice'], + 'close': inst_data['closePrice'], + 'settlement': inst_data['clearPrice'], + 'volume': inst_data['matchTotQty'] if inst_data['matchTotQty'] != "--" else 0, + 'open_interest': inst_data['openInterest'] if inst_data['openInterest'] != "--" else 0}) + except Exception as e: + logger.warning(f'update_from_gfex failed: {repr(e)}', exc_info=True) + return False + return True + + +async def update_from_cffex(day: datetime.datetime) -> bool: + try: + async with aiohttp.ClientSession() as session: + await max_conn_cffex.acquire() + async with session.get(f"http://{cffex_ip}/fzjy/mrhq/{day.strftime('%Y%m/%d')}/index.xml") as response: + rst = await response.text() + max_conn_cffex.release() + tree = ET.fromstring(rst) + for inst_data in tree: + """ + + IC2112 + 20211209 + 7272 + 7330 + 7264.4 + 7302.4 + 107546 + 101956 + 7274.4 + 7314.2 + 7314.2 + 51752 + 75570943720 + IC + + 20211217 + + """ + # 不存储期权合约 + if len(inst_data.findtext('instrumentid').strip()) > 6: + continue + if inst_data.findtext('productid').strip() in IGNORE_INST_LIST: + continue + DailyBar.objects.update_or_create( + code=inst_data.findtext('instrumentid').strip(), + exchange=ExchangeType.CFFEX, time=day, defaults={ + 'expire_date': inst_data.findtext('expiredate')[2:6], + 'open': inst_data.findtext('openprice').replace(',', '') if inst_data.findtext( + 'openprice') else inst_data.findtext('closeprice').replace(',', ''), + 'high': inst_data.findtext('highestprice').replace(',', '') if inst_data.findtext( + 'highestprice') else inst_data.findtext('closeprice').replace(',', ''), + 'low': inst_data.findtext('lowestprice').replace(',', '') if inst_data.findtext( + 'lowestprice') else inst_data.findtext('closeprice').replace(',', ''), + 'close': inst_data.findtext('closeprice').replace(',', ''), + 'settlement': inst_data.findtext('settlementprice').replace(',', '') + if inst_data.findtext('settlementprice') else + inst_data.findtext('presettlementprice').replace(',', ''), + 'volume': inst_data.findtext('volume').replace(',', ''), + 'open_interest': inst_data.findtext('openinterest').replace(',', '')}) + return True + except Exception as e: + logger.warning(f'update_from_cffex failed: {repr(e)}', exc_info=True) + return False + + +def store_main_bar(inst: Instrument, bar: DailyBar): + MainBar.objects.update_or_create( + exchange=inst.exchange, product_code=inst.product_code, time=bar.time, defaults={ + 'code': bar.code, + 'open': bar.open, + 'high': bar.high, + 'low': bar.low, + 'close': bar.close, + 'settlement': bar.settlement, + 'volume': bar.volume, + 'open_interest': bar.open_interest}) + + +def handle_rollover(inst: Instrument, new_bar: DailyBar): + """ + 换月处理, 基差=新合约收盘价-旧合约收盘价, 从今日起之前的所有连续合约的OHLC加上基差 + """ + old_bar = DailyBar.objects.filter(exchange=inst.exchange, code=inst.last_main, time=new_bar.time).first() + main_bar = MainBar.objects.get(exchange=inst.exchange, product_code=inst.product_code, time=new_bar.time) + old_close = old_bar.close if old_bar else new_bar.close + basis = new_bar.close - old_close + main_bar.basis = basis + basis = float(basis) + main_bar.save(update_fields=['basis']) + MainBar.objects.filter(exchange=inst.exchange, product_code=inst.product_code, time__lt=new_bar.time).update( + open=F('open') + basis, high=F('high') + basis, low=F('low') + basis, close=F('close') + basis, + settlement=F('settlement') + basis) + + +def calc_main_inst(inst: Instrument, day: datetime.datetime): + updated = False + expire_date = get_expire_date(inst.main_code, day) if inst.main_code else day.strftime('%y%m') + # 条件1: 成交量最大 & (成交量>1万 & 持仓量>1万 or 股指) = 主力合约 + check_bar = DailyBar.objects.filter( + (Q(exchange=ExchangeType.CFFEX) | (Q(volume__gte=10000) & Q(open_interest__gte=10000))), + exchange=inst.exchange, code__regex=f"^{inst.product_code}[0-9]+", + expire_date__gte=expire_date, time=day.date()).order_by('-volume').first() + # 条件2: 不满足条件1但是连续3天成交量最大 = 主力合约 + if check_bar is None: + check_bars = DailyBar.objects.raw( + "SELECT a.* from panel_dailybar a INNER JOIN (SELECT time, max(volume) v FROM panel_dailybar " + "WHERE CODE RLIKE %s and time<=%s GROUP BY time ORDER BY time DESC LIMIT 3) b " + "WHERE a.time=b.time and a.volume=b.v ORDER BY a.time DESC LIMIT 3", [f"^{inst.product_code}[0-9]+", day]) + check_bar = check_bars[0] if len(set(bar.code for bar in check_bars)) == 1 else None + # 条件3: 取当前成交量最大的作为主力 + if check_bar is None: + check_bar = DailyBar.objects.filter( + exchange=inst.exchange, code__regex=f"^{inst.product_code}[0-9]+", + expire_date__gte=expire_date, time=day.date()).order_by('-volume', '-open_interest', 'code').first() + if check_bar is None: + check_bar = DailyBar.objects.filter(code=inst.main_code).last() + logger.error(f"calc_main_inst 未找到主力合约:{inst} 使用上一个主力合约") + if inst.main_code is None: # 之前没有主力合约 + inst.main_code = check_bar.code + inst.change_time = day + inst.save(update_fields=['main_code', 'change_time']) + store_main_bar(inst, check_bar) + else: + # 主力合约发生变化, 做换月处理 + if check_bar and inst.main_code != check_bar.code and check_bar.code > inst.main_code: + inst.last_main = inst.main_code + inst.main_code = check_bar.code + inst.change_time = day + inst.save(update_fields=['last_main', 'main_code', 'change_time']) + store_main_bar(inst, check_bar) + handle_rollover(inst, check_bar) + updated = True + else: + store_main_bar(inst, check_bar) + return inst.main_code, updated + + +def create_main(inst: Instrument): + print('processing ', inst.product_code) + if inst.change_time is None: + for day in DailyBar.objects.filter( + # time__gte=datetime.datetime.strptime('20211211', '%Y%m%d'), + exchange=inst.exchange, code__regex='^{}[0-9]+'.format(inst.product_code)).order_by( + 'time').values_list('time', flat=True).distinct(): + print(day, calc_main_inst(inst, timezone.make_aware(datetime.datetime.combine(day, datetime.time.min)))) + else: + for day in DailyBar.objects.filter( + time__gt=inst.change_time, + exchange=inst.exchange, code__regex='^{}[0-9]+'.format(inst.product_code)).order_by( + 'time').values_list('time', flat=True).distinct(): + print(day, calc_main_inst(inst, timezone.make_aware(datetime.datetime.combine(day, datetime.time.min)))) + return True + + +def create_main_all(): + for inst in Instrument.objects.all(): + create_main(inst) + print('all done!') + + +def is_auction_time(inst: Instrument, status: dict): + if status['InstrumentStatus'] == ApiStruct.IS_AuctionOrdering: + now = timezone.localtime() + if inst.exchange == ExchangeType.CFFEX: + return True + # 夜盘集合竞价时间是 20:55 + if inst.night_trade and now.hour == 20: + return True + # 日盘集合竞价时间是 8:55 + if not inst.night_trade and now.hour == 8: + return True + return False + + +def calc_sma(price, period): + return reduce(lambda x, y: ((period - 1) * x + y) / period, price) + + +def calc_corr(day: datetime.datetime): + price_dict = dict() + begin_day = day.replace(year=day.year - 3) + for code in Strategy.objects.get(name='大哥2.0').instruments.all().order_by('id').values_list( + 'product_code', flat=True): + price_dict[code] = to_df(MainBar.objects.filter( + time__gte=begin_day.date(), + product_code=code).order_by('time').values_list('time', 'close'), index_col='time', parse_dates=['time']) + price_dict[code].index = pd.DatetimeIndex(price_dict[code].time) + price_dict[code]['price'] = price_dict[code].close.pct_change() + return pd.DataFrame({k: v.price for k, v in price_dict.items()}).corr() + + +def nCr(n, r): + f = math.factorial + return f(n) / f(r) / f(n-r) + + +def find_best_score(n: int = 20): + """ + 一秒钟算5个组合,要算100年.. + """ + corr_matrix = calc_corr(datetime.datetime.today()) + code_list = Strategy.objects.get(name='大哥2.0').instruments.all().order_by('id').values_list( + 'product_code', flat=True) + result = list() + for code_list in tqdm(combinations(code_list, n), total=nCr(code_list.count(), n)): + score_df = pd.DataFrame([corr_matrix.iloc[i, j] for i, j in combinations(code_list, 2)]) + score = (round((1 - (score_df.abs() ** 2).mean()[0]) * 100, 3) - 50) * 2 + result.append((score, ','.join(code_list))) + result.sort(key=lambda tup: tup[0]) + print('得分最高: ', result[-3:]) + print('得分最低: ', result[:3]) + + +def calc_history_signal(inst: Instrument, day: datetime.datetime, strategy: Strategy): + break_n = strategy.param_set.get(code='BreakPeriod').int_value + atr_n = strategy.param_set.get(code='AtrPeriod').int_value + long_n = strategy.param_set.get(code='LongPeriod').int_value + short_n = strategy.param_set.get(code='ShortPeriod').int_value + stop_n = strategy.param_set.get(code='StopLoss').int_value + df = to_df(MainBar.objects.filter( + time__lte=day.date(), + exchange=inst.exchange, product_code=inst.product_code).order_by('time').values_list( + 'time', 'open', 'high', 'low', 'close', 'settlement'), index_col='time', parse_dates=['time']) + df.index = pd.DatetimeIndex(df.time, tz=pytz.FixedOffset(480)) + df['atr'] = ATR(df.high, df.low, df.close, timeperiod=atr_n) + # df columns: 0:time,1:open,2:high,3:low,4:close,5:settlement,6:atr,7:short_trend,8:long_trend + df['short_trend'] = df.close + df['long_trend'] = df.close + for idx in range(1, df.shape[0]): + df.iloc[idx, 7] = (df.iloc[idx - 1, 7] * (short_n - 1) + df.iloc[idx, 4]) / short_n + df.iloc[idx, 8] = (df.iloc[idx - 1, 8] * (long_n - 1) + df.iloc[idx, 4]) / long_n + df['high_line'] = df.close.rolling(window=break_n).max() + df['low_line'] = df.close.rolling(window=break_n).min() + cur_pos = 0 + last_trade = None + for cur_idx in range(break_n+1, df.shape[0]): + idx = cur_idx - 1 + cur_date = df.index[cur_idx].to_pydatetime() + prev_date = df.index[idx].to_pydatetime() + if cur_pos == 0: + if df.short_trend[idx] > df.long_trend[idx] and int(df.close[idx]) >= int(df.high_line[idx-1]): + new_bar = MainBar.objects.filter( + exchange=inst.exchange, product_code=inst.product_code, time=cur_date).first() + Signal.objects.create( + code=new_bar.code, trigger_value=df.atr[idx], + strategy=strategy, instrument=inst, type=SignalType.BUY, processed=True, + trigger_time=prev_date, price=new_bar.open, volume=1, priority=PriorityType.LOW) + last_trade = Trade.objects.create( + broker=strategy.broker, strategy=strategy, instrument=inst, + code=new_bar.code, direction=DirectionType.values[DirectionType.LONG], + open_time=cur_date, shares=1, filled_shares=1, avg_entry_price=new_bar.open) + cur_pos = cur_idx + elif df.short_trend[idx] < df.long_trend[idx] and int(df.close[idx]) < int(df.low_line[idx-1]): + new_bar = MainBar.objects.filter( + exchange=inst.exchange, product_code=inst.product_code, + time=df.index[cur_idx].to_pydatetime().date()).first() + Signal.objects.create( + code=new_bar.code, trigger_value=df.atr[idx], + strategy=strategy, instrument=inst, type=SignalType.SELL_SHORT, processed=True, + trigger_time=prev_date, price=new_bar.open, volume=1, priority=PriorityType.LOW) + last_trade = Trade.objects.create( + broker=strategy.broker, strategy=strategy, instrument=inst, + code=new_bar.code, direction=DirectionType.values[DirectionType.SHORT], + open_time=cur_date, shares=1, filled_shares=1, avg_entry_price=new_bar.open) + cur_pos = cur_idx * -1 + elif cur_pos > 0 and prev_date > last_trade.open_time: + hh = float(MainBar.objects.filter( + exchange=inst.exchange, product_code=inst.product_code, + time__gte=last_trade.open_time, + time__lt=prev_date).aggregate(Max('high'))['high__max']) + if df.close[idx] <= hh - df.atr[cur_pos-1] * stop_n: + new_bar = MainBar.objects.filter( + exchange=inst.exchange, product_code=inst.product_code, + time=df.index[cur_idx].to_pydatetime().date()).first() + Signal.objects.create( + strategy=strategy, instrument=inst, type=SignalType.SELL, processed=True, + code=new_bar.code, + trigger_time=prev_date, price=new_bar.open, volume=1, priority=PriorityType.LOW) + last_trade.avg_exit_price = new_bar.open + last_trade.close_time = cur_date + last_trade.closed_shares = 1 + last_trade.profit = (new_bar.open - last_trade.avg_entry_price) * inst.volume_multiple + last_trade.save() + cur_pos = 0 + elif cur_pos < 0 and prev_date > last_trade.open_time: + ll = float(MainBar.objects.filter( + exchange=inst.exchange, product_code=inst.product_code, + time__gte=last_trade.open_time, + time__lt=prev_date).aggregate(Min('low'))['low__min']) + if df.close[idx] >= ll + df.atr[cur_pos * -1-1] * stop_n: + new_bar = MainBar.objects.filter( + exchange=inst.exchange, product_code=inst.product_code, + time=df.index[cur_idx].to_pydatetime().date()).first() + Signal.objects.create( + code=new_bar.code, + strategy=strategy, instrument=inst, type=SignalType.BUY_COVER, processed=True, + trigger_time=prev_date, price=new_bar.open, volume=1, priority=PriorityType.LOW) + last_trade.avg_exit_price = new_bar.open + last_trade.close_time = cur_date + last_trade.closed_shares = 1 + last_trade.profit = (last_trade.avg_entry_price - new_bar.open) * inst.volume_multiple + last_trade.save() + cur_pos = 0 + if cur_pos != 0 and cur_date.date() == day.date(): + last_trade.avg_exit_price = df.open[cur_idx] + last_trade.close_time = cur_date + last_trade.closed_shares = 1 + if last_trade.direction == DirectionType.values[DirectionType.LONG]: + last_trade.profit = (last_trade.avg_entry_price - Decimal(df.open[cur_idx])) * \ + inst.volume_multiple + else: + last_trade.profit = (Decimal(df.open[cur_idx]) - last_trade.avg_entry_price) * \ + inst.volume_multiple + last_trade.save() + + +def calc_his_all(day: datetime.datetime): + strategy = Strategy.objects.get(name='大哥2.0') + print(f'calc_his_all day: {day} stragety: {strategy}') + for inst in strategy.instruments.all(): + print('process', inst) + last_day = Trade.objects.filter(instrument=inst, close_time__isnull=True).values_list( + 'open_time', flat=True).first() + if last_day is None: + last_day = datetime.datetime.combine( + MainBar.objects.filter(product_code=inst.product_code, time__lte=day).order_by( + '-time').values_list('time', flat=True).first(), timezone.make_aware(datetime.time.min)) + calc_history_signal(inst, last_day, strategy) + + +def calc_his_up_limit(inst: Instrument, bar: DailyBar): + ratio = inst.up_limit_ratio + ratio = Decimal(round(ratio, 3)) + price = price_round(bar.settlement * (Decimal(1) + ratio), inst.price_tick) + return price - inst.price_tick + + +def calc_his_down_limit(inst: Instrument, bar: DailyBar): + ratio = inst.down_limit_ratio + ratio = Decimal(round(ratio, 3)) + price = price_round(bar.settlement * (Decimal(1) - ratio), inst.price_tick) + return price + inst.price_tick + + +async def clean_daily_bar(): + day = timezone.make_aware(datetime.datetime.strptime('20100416', '%Y%m%d')) + end = timezone.make_aware(datetime.datetime.strptime('20160118', '%Y%m%d')) + tasks = [] + while day <= end: + tasks.append(is_trading_day(day)) + day += datetime.timedelta(days=1) + trading_days = [] + for f in tqdm(asyncio.as_completed(tasks), total=len(tasks)): + rst = await f + trading_days.append(rst) + tasks.clear() + for day, trading in trading_days: + if not trading: + DailyBar.objects.filter(time=day.date()).delete() + print('done!') + + +def load_kt_data(directory: str = r'D:\test'): + """PK99.txt + 1210224,10944.000 ,10992.000 ,10758.000 ,10904.000 ,10702.000 ,42202 ,20897 ,PK2110 + """ + try: + for filename in os.listdir(directory): + if not filename.endswith(".txt"): + continue + code = filename.split('9', maxsplit=1)[0] + inst = Instrument.objects.get(product_code=code) + print('process', inst) + cur_main = last_main = change_time = None + insert_list = [] + with open(os.path.join(directory, filename)) as f: + for line in f: + date, oo, hh, ll, cc, se, oi, vo, main_code = [part.strip() for part in line.split(',')] + date = f'{int(date[:3])+1900}-{date[3:5]}-{date[5:7]}' + date = timezone.make_aware(datetime.datetime.strptime(date, '%Y-%m-%d')) + if cur_main != main_code: + if last_main != main_code: + last_main = cur_main + cur_main = main_code + change_time = date + insert_list.append(MainBar( + exchange=inst.exchange, product_code=code, code=main_code, time=date, open=oo, high=hh, low=ll, + close=cc, settlement=se, open_interest=oi, volume=vo, basis=None)) + MainBar.objects.bulk_create(insert_list) + Instrument.objects.filter(product_code=code).update( + last_main=last_main, main_code=cur_main, change_time=change_time) + return True + except Exception as e: + logger.warning(f'load_kt_data failed: {repr(e)}', exc_info=True) + return False + + +# 从交易所获取合约当日的涨跌停幅度 TODO: 广期所 +async def get_contracts_argument(day: datetime.datetime = None) -> bool: + try: + if day is None: + day = timezone.localtime() + day_str = day.strftime('%Y%m%d') + redis_client = redis.StrictRedis( + host=config.get('REDIS', 'host', fallback='localhost'), + db=config.getint('REDIS', 'db', fallback=0), decode_responses=True) + async with aiohttp.ClientSession() as session: + # 上期所 + async with session.get( + f'http://{shfe_ip}/data/instrument/ContractDailyTradeArgument{day_str}.dat') as response: + rst = await response.read() + rst_json = json.loads(rst) + for inst_data in rst_json['ContractDailyTradeArgument']: + """ +{"HDEGE_LONGMARGINRATIO":".10000000","HDEGE_SHORTMARGINRATIO":".10000000","INSTRUMENTID":"cu2201", +"LOWER_VALUE":".08000000","PRICE_LIMITS":"","SPEC_LONGMARGINRATIO":".10000000","SPEC_SHORTMARGINRATIO":".10000000", +"TRADINGDAY":"20211217","UPDATE_DATE":"2021-12-17 09:51:20","UPPER_VALUE":".08000000","id":124468118} + """ + # logger.info(f'inst_data: {inst_data}') + code = re.findall('[A-Za-z]+', inst_data['INSTRUMENTID'])[0] + if code in IGNORE_INST_LIST: + continue + exchange = ExchangeType.INE if code in INE_INST_LIST else ExchangeType.SHFE + limit_ratio = str_to_number(inst_data['UPPER_VALUE']) + redis_client.set(f"LIMITRATIO:{exchange}:{code}:{inst_data['INSTRUMENTID']}", limit_ratio) + # 大商所 + async with session.post(f'http://{dce_ip}/publicweb/notificationtips/exportDayTradPara.html', + data={'exportFlag': 'txt'}) as response: + rst = await response.text() + for lines in rst.split('\r\n')[3:400]: + # 跳过期权合约 + if '本系列限额' in lines: + break + inst_data_raw = [x.strip() for x in lines.split('\t')] + inst_data = [] + for cell in inst_data_raw: + if len(cell) > 0: + inst_data.append(cell) + if len(inst_data) == 0: + continue + """ +[0合约,1交易保证金比例(投机),2交易保证金金额(元/手)(投机),3交易保证金比例(套保),4交易保证金金额(元/手)(套保),5涨跌停板比例, + 6涨停板价位(元),7跌停板价位(元)] +['a2201','0.12','7,290','0.08','4,860','0.08','6,561','5,589','30,000','15,000'] + """ + code = re.findall('[A-Za-z]+', inst_data[0])[0] + if code in IGNORE_INST_LIST: + continue + limit_ratio = str_to_number(inst_data[5]) + redis_client.set(f"LIMITRATIO:{ExchangeType.DCE}:{code}:{inst_data[0]}", limit_ratio) + # 郑商所 + async with session.get(f'http://{czce_ip}/cn/DFSStaticFiles/Future/{day.year}/{day_str}/' + f'FutureDataClearParams.txt') as response: + rst = await response.text() + for lines in rst.split('\n')[2:]: + if not lines: + continue + inst_data = [x.strip() for x in lines.split('|' if '|' in lines else ',')] + """ +[0合约代码,1当日结算价,2是否单边市,3连续单边市天数,4交易保证金率(%),5涨跌停板(%),6交易手续费,7交割手续费,8日内平今仓交易手续费,9日持仓限额] +['AP201','8,148.00','N','0','10','±9','5.00','0.00','20.00','200',''] + """ + code = re.findall('[A-Za-z]+', inst_data[0])[0] + if code in IGNORE_INST_LIST: + continue + limit_ratio = str_to_number(inst_data[5][1:]) / 100 + redis_client.set(f"LIMITRATIO:{ExchangeType.CZCE}:{code}:{inst_data[0]}", limit_ratio) + # 中金所 + async with session.get(f"http://{cffex_ip}/sj/jycs/{day.strftime('%Y%m/%d')}/index.xml") as response: + rst = await response.text() + max_conn_cffex.release() + tree = ET.fromstring(rst) + for inst_data in tree: + """ + + 20211216 + IC + IC2112 + 2112 + 6072.8 + 20210419 + 20211217 + 0.1 + 0.1 + 8063.6 + 6597.6 + 1200 + + """ + inst_id = inst_data.findtext('INSTRUMENT_ID').strip() + # 不存储期权合约 + if len(inst_id) > 6: + continue + code = inst_data.findtext('PRODUCT_ID').strip() + if code in IGNORE_INST_LIST: + continue + limit_ratio = str_to_number(inst_data.findtext('UPPER_VALUE').strip()) + redis_client.set(f"LIMITRATIO:{ExchangeType.CFFEX}:{code}:{inst_id}", limit_ratio) + # 保存数据 + for inst in Instrument.objects.all(): + ratio = redis_client.get(f"LIMITRATIO:{inst.exchange}:{inst.product_code}:{inst.main_code}") + if ratio: + ratio = str_to_number(ratio) + inst.up_limit_ratio = ratio + inst.down_limit_ratio = ratio + inst.save(update_fields=['up_limit_ratio', 'down_limit_ratio']) + return True + except Exception as e: + logger.warning(f'get_contracts_argument failed: {repr(e)}', exc_info=True) + return False diff --git a/qbot/engine/trade/trader/trader/utils/error.xml b/qbot/engine/trade/trader/trader/utils/error.xml new file mode 100644 index 00000000..0afb43a9 --- /dev/null +++ b/qbot/engine/trade/trader/trader/utils/error.xml @@ -0,0 +1,266 @@ + + + +]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +~ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/qbot/engine/trade/trader/trader/utils/fetch_data.py b/qbot/engine/trade/trader/trader/utils/fetch_data.py new file mode 100644 index 00000000..63b366a0 --- /dev/null +++ b/qbot/engine/trade/trader/trader/utils/fetch_data.py @@ -0,0 +1,72 @@ +import sys +import os +import datetime +import asyncio +import pytz + +from tqdm import tqdm +import django + +if sys.platform == 'darwin': + sys.path.append('/Users/jeffchen/Documents/gitdir/dashboard') +elif sys.platform == 'win32': + sys.path.append(r'D:\UserData\Documents\GitHub\dashboard') +else: + sys.path.append('/home/cyh/bigbrother/dashboard') +os.environ["DJANGO_SETTINGS_MODULE"] = "dashboard.settings" +os.environ["DJANGO_ALLOW_ASYNC_UNSAFE"] = "true" +django.setup() +from trader.utils import is_trading_day, update_from_shfe, update_from_dce, update_from_czce, update_from_cffex, \ + create_main_all, fetch_from_quandl_all, clean_daily_bar, load_kt_data, calc_his_all, check_trading_day +from django.utils import timezone + + +async def fetch_bar(): + day_end = timezone.localtime() + day_start = day_end - datetime.timedelta(days=365) + tasks = [] + while day_start <= day_end: + tasks.append(check_trading_day(day_start)) + day_start += datetime.timedelta(days=1) + trading_days = [] + for f in tqdm(asyncio.as_completed(tasks), total=len(tasks)): + rst = await f + trading_days.append(rst) + tasks.clear() + for day, trading in trading_days: + if trading: + tasks += [ + asyncio.ensure_future(update_from_shfe(day)), + asyncio.ensure_future(update_from_dce(day)), + asyncio.ensure_future(update_from_czce(day)), + asyncio.ensure_future(update_from_cffex(day)), + ] + print('task len=', len(tasks)) + for f in tqdm(asyncio.as_completed(tasks), total=len(tasks)): + await f + + +async def fetch_bar2(): + day_end = timezone.localtime() + day_start = day_end - datetime.timedelta(days=365) + while day_start <= day_end: + day, trading = await check_trading_day(day_start) + if trading: + print('process ', day) + tasks = [ + asyncio.ensure_future(update_from_shfe(day)), + asyncio.ensure_future(update_from_dce(day)), + asyncio.ensure_future(update_from_czce(day)), + asyncio.ensure_future(update_from_cffex(day)), + ] + await asyncio.wait(tasks) + day_start += datetime.timedelta(days=1) + print('all done!') + + +# asyncio.get_event_loop().run_until_complete(fetch_bar2()) +create_main_all() +# fetch_from_quandl_all() +# clean_dailybar() +# load_kt_data() +# calc_his_all(timezone.localtime()-datetime.timedelta(days=1)) diff --git a/qbot/engine/trade/trader/trader/utils/func_container.py b/qbot/engine/trade/trader/trader/utils/func_container.py new file mode 100644 index 00000000..d81b677f --- /dev/null +++ b/qbot/engine/trade/trader/trader/utils/func_container.py @@ -0,0 +1,48 @@ +# coding=utf-8 +# +# Copyright 2016 timercrack +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +from abc import ABCMeta +from functools import wraps + + +def RegisterCallback(**out_kwargs): + def _callback_handler(func): + @wraps(func) + def wrapper(self, *args, **kwargs): + return func(self, *args, *kwargs) + + for key, value in out_kwargs.items(): + setattr(wrapper, f'arg_{key}', value) + setattr(wrapper, 'is_callback_function', True) + return wrapper + + return _callback_handler + + +class CallbackFunctionContainer(object, metaclass=ABCMeta): + def __init__(self): + self.callback_fun_args = dict() + self._collect_all() + + def _collect_all(self): + for fun_name in dir(self): + fun = getattr(self, fun_name) + if hasattr(fun, 'is_callback_function'): + params = dict() + for arg in dir(fun): + if arg.startswith('arg_'): + params[arg[4:]] = getattr(fun, arg) + self.callback_fun_args[fun_name] = params diff --git a/qbot/engine/trade/trader/trader/utils/my_logger.py b/qbot/engine/trade/trader/trader/utils/my_logger.py new file mode 100644 index 00000000..46b0bb98 --- /dev/null +++ b/qbot/engine/trade/trader/trader/utils/my_logger.py @@ -0,0 +1,37 @@ +# coding=utf-8 +# +# Copyright 2016 timercrack +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +import logging +from trader.utils.read_config import * + + +def get_my_logger(logger_name='main'): + logger = logging.getLogger(logger_name) + if logger.handlers: + return logger + log_file = os.path.join(app_dir.user_log_dir, '{}.log'.format(logger_name)) + if not os.path.exists(app_dir.user_log_dir): + os.makedirs(app_dir.user_log_dir) + formatter = logging.Formatter(config.get('LOG', 'format', + fallback="%(asctime)s %(name)s [%(levelname)s] %(message)s")) + file_handler = logging.FileHandler(log_file, encoding='utf-8') + file_handler.setFormatter(formatter) + console_handler = logging.StreamHandler() + console_handler.setFormatter(formatter) + logger.setLevel(config.get('LOG', 'level', fallback='ERROR')) + logger.addHandler(file_handler) + logger.addHandler(console_handler) + return logger diff --git a/qbot/engine/trade/trader/trader/utils/read_config.py b/qbot/engine/trade/trader/trader/utils/read_config.py new file mode 100644 index 00000000..f39986b7 --- /dev/null +++ b/qbot/engine/trade/trader/trader/utils/read_config.py @@ -0,0 +1,78 @@ +# coding=utf-8 +# +# Copyright 2016 timercrack +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +import sys +import os +import xml.etree.ElementTree as ET +import configparser +from appdirs import AppDirs +from trader import version as app_ver + +config_example = """# trader configuration file +[MSG_CHANNEL] +request_pattern = MSG:CTP:REQ:* +request_format = MSG:CTP:REQ:{} +trade_response_prefix = MSG:CTP:RSP:TRADE: +trade_response_format = MSG:CTP:RSP:TRADE:{}:{} +market_response_prefix = MSG:CTP:RSP:MARKET: +market_response_format = MSG:CTP:RSP:MARKET:{}:{} +weixin_log = MSG:LOG:WEIXIN + +[TRADE] +command_timeout = 5 +ignore_inst = WH,bb,JR,RI,RS,LR,PM,im + +[REDIS] +host = 127.0.0.1 +port = 6379 +db = 0 +encoding = utf-8 + +[MYSQL] +host = 127.0.0.1 +port = 3306 +db = QuantDB +user = quant +password = 123456 + +[QuantDL] +api_key = 123456 + +[Tushare] +token = 123456 + +[LOG] +level = DEBUG +format = %(asctime)s %(name)s [%(levelname)s] %(message)s +weixin_format = [%(levelname)s] %(message)s +""" + +app_dir = AppDirs('trader') +config_file = os.path.join(app_dir.user_config_dir, 'config.ini') +if not os.path.exists(config_file): + if not os.path.exists(app_dir.user_config_dir): + os.makedirs(app_dir.user_config_dir) + with open(config_file, 'wt') as f: + f.write(config_example) + print('create config file:', config_file) + +config = configparser.ConfigParser(interpolation=None) +config.read(config_file) + +ctp_errors = {} +ctp_xml_path = 'D:/github/trader/trader/utils/error.xml' if sys.platform == 'win32' \ + else '/root/gitee/trader/trader/utils/error.xml' +for error in ET.parse(ctp_xml_path).getroot(): + ctp_errors[int(error.attrib['value'])] = error.attrib['prompt'] diff --git a/qbot/engine/trade/trader/trader/utils/tick.py b/qbot/engine/trade/trader/trader/utils/tick.py new file mode 100644 index 00000000..23cb75c1 --- /dev/null +++ b/qbot/engine/trade/trader/trader/utils/tick.py @@ -0,0 +1,27 @@ +# coding=utf-8 +import datetime + + +class TickBar(object): + def __init__(self, day, data, last_volume): + """ + pData的格式转换和整理, 交易数据都转换为整数,tick的后四个字段在模拟行情中经常出错 + :param data: ApiStruct.DepthMarketData + :return: + """ + self.instrument = data.InstrumentID + self.bid_price = data.BidPrice1 + self.bid_volume = data.BidVolume1 + self.ask_price = data.AskPrice1 + self.ask_volume = data.AskVolume1 + self.holding = data.OpenInterest + self.up_limit_price = data.UpperLimitPrice + self.down_limit_price = data.LowerLimitPrice + self.volume = data.Volume - last_volume + self.price = data.LastPrice + self.day_high = data.HighestPrice + self.day_low = data.LowestPrice + self.open = data.OpenPrice + self.pre_close = data.PreClosePrice + self.dateTime = datetime.datetime.strptime(day+data.UpdateTime, "%Y%m%d%H:%M:%S") + self.dateTime = self.dateTime + datetime.timedelta(microseconds=datetime.datetime.now().microsecond) diff --git a/qbot/engine/trade/trading/bitcoin-arbitrage/.flake8 b/qbot/engine/trade/trading/bitcoin-arbitrage/.flake8 new file mode 100644 index 00000000..20853681 --- /dev/null +++ b/qbot/engine/trade/trading/bitcoin-arbitrage/.flake8 @@ -0,0 +1,5 @@ +# Keep in sync with setup.cfg which is used for source packages. + +[flake8] +max-line-length = 100 +max-complexity = 20 diff --git a/qbot/engine/trade/trading/bitcoin-arbitrage/.gitignore b/qbot/engine/trade/trading/bitcoin-arbitrage/.gitignore new file mode 100644 index 00000000..0f831405 --- /dev/null +++ b/qbot/engine/trade/trading/bitcoin-arbitrage/.gitignore @@ -0,0 +1,43 @@ +*.py[cod] + +# C extensions +*.so + +# Packages +*.egg +*.egg-info +dist +build +eggs +parts +bin +var +sdist +develop-eggs +.installed.cfg +lib +lib64 + +# Installer logs +pip-log.txt + +# Unit test / coverage reports +.coverage +.tox +nosetests.xml + +# Translations +*.mo + +# Mr Developer +.mr.developer.cfg +.project +.pydevproject + +# dumped data +*.json + +# Project +config.py +old/ +tmp/ diff --git a/qbot/engine/trade/trading/bitcoin-arbitrage/.travis.yml b/qbot/engine/trade/trading/bitcoin-arbitrage/.travis.yml new file mode 100644 index 00000000..f2f2751c --- /dev/null +++ b/qbot/engine/trade/trading/bitcoin-arbitrage/.travis.yml @@ -0,0 +1,30 @@ +dist: xenial +language: python +python: + - "3.6" + - "3.7" + - "3.8-dev" # 3.8 development branch + - "nightly" # nightly build + +install: + # Install dependencies + - pip install -r requirements.txt + + # Run setup install + - python setup.py -q install + + # Install dev dependencies + - pip install nose black flake8 + + # Create the config file from the example + - cp arbitrage/config.py-example arbitrage/config.py + +script: + # Run formatter + - ./tools/inplace-code-formatting.sh + + # Run linter - TODO: fix lint issues before running it in travis + # - flake8 . + + # Run tests + - nosetests arbitrage/ diff --git a/qbot/engine/trade/trading/bitcoin-arbitrage/LICENSE b/qbot/engine/trade/trading/bitcoin-arbitrage/LICENSE new file mode 100644 index 00000000..bcdf4955 --- /dev/null +++ b/qbot/engine/trade/trading/bitcoin-arbitrage/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2019 Maxime Biais + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/qbot/engine/trade/trading/bitcoin-arbitrage/MANIFEST.in b/qbot/engine/trade/trading/bitcoin-arbitrage/MANIFEST.in new file mode 100644 index 00000000..7efa8d0c --- /dev/null +++ b/qbot/engine/trade/trading/bitcoin-arbitrage/MANIFEST.in @@ -0,0 +1,2 @@ +include *.md +recursive-include doc *.md diff --git a/qbot/engine/trade/trading/bitcoin-arbitrage/README.md b/qbot/engine/trade/trading/bitcoin-arbitrage/README.md new file mode 100644 index 00000000..ee27369b --- /dev/null +++ b/qbot/engine/trade/trading/bitcoin-arbitrage/README.md @@ -0,0 +1,117 @@ +# bitcoin-arbitrage - opportunity detector and automated trading + +It gets order books from supported exchanges and calculate arbitrage +opportunities between each markets. It takes market depth into account. + +Currently supported exchanges to get data: + +- Bitstamp (USD, EUR) +- Paymium (EUR) +- Bitfinex (USD, EUR) +- bitFlyer (USD, EUR) +- Kraken (USD, EUR) +- OkCoin (CNY) +- Gemini (USD) +- BTCC (CNY) +- GDAX (USD, EUR) +- CEX.io (USD, EUR) +- Binance (USD) + +Currently supported exchanges to automate trade: + +- Bitstamp (USD) +- Paymium (EUR) + +## WARNING + +**Real trading bots are included. Don't put your API keys in config.py +if you don't know what you are doing.** + +## Installation And Configuration + +```sh +cp arbitrage/config.py-example arbitrage/config.py +``` + +Then edit config.py file to setup your preferences: watched markets +and observers + +You need Python3 to run this program. To install on Debian, Ubuntu, or +variants of them, use: + +```sh +sudo apt-get install python3 python3-pip python-nose +``` + +To use the observer XMPPMessager you will need to install sleekxmpp: + +```sh +pip3 install sleekxmpp +``` + +## Run + +To run the opportunity watcher: + +```sh +$ python3 -m arbitrage -v +2013-03-12 03:52:14,341 [INFO] profit: 30.539722 EUR with volume: 10 BTC - buy at 29.3410 (MtGoxEUR) sell at29.4670 (Bitcoin24EUR) ~10.41% +2013-03-12 03:52:14,356 [INFO] profit: 66.283642 EUR with volume: 10 BTC - buy at 29.3410 (MtGoxEUR) sell at30.0000 (PaymiumEUR) ~22.59% +2013-03-12 03:52:14,357 [INFO] profit: 31.811390 EUR with volume: 10 BTC - buy at 29.3410 (MtGoxEUR) sell at30.0000 (IntersangoEUR) ~10.84% +2013-03-12 03:52:45,090 [INFO] profit: 9.774324 EUR with volume: 10 BTC - buy at 35.3630 (Bitcoin24EUR) sellat 35.4300 (PaymiumEUR) ~2.76% +``` + +To check your balance on an exchange (also a good way to check your accounts configuration): + +```sh +python3 -m arbitrage -m Paymium get-balance +python3 -m arbitrage -m Paymium,BitstampUSD get-balance +``` + +Run tests + +```sh +nosetests arbitrage/ +``` + +### Alternative usage + +List supported public markets: + +```sh +python3 -m arbitrage list-public-markets +``` + +Help: + +```sh +python3 -m arbitrage -h +``` + +## TODO + +- Tests +- Write documentation +- Add other exchanges: + - icbit +- Update order books with a WebSocket client for supported exchanges + (Kraken, Bitfinex, Paymium) +- Better history handling for observer "HistoryDumper" (Redis ?) +- Move EUR / USD from a market to an other: + - Coupons + - Ripple ? + - Stable coins + - Negative Operations + - Add support for other cryptocurrencies and triangular arbitrage + +## LICENSE + +MIT + +Copyright (c) 2013 Maxime Biais + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/__init__.py b/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/__init__.py new file mode 100644 index 00000000..4ce21ad2 --- /dev/null +++ b/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/__init__.py @@ -0,0 +1,3 @@ +from arbitrage import arbitrage + +arbitrage.main() diff --git a/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/arbitrage.py b/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/arbitrage.py new file mode 100644 index 00000000..660322b4 --- /dev/null +++ b/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/arbitrage.py @@ -0,0 +1,149 @@ +# Copyright (C) 2013, Maxime Biais + +import argparse +import glob +import inspect +import logging +import os +import sys + +from arbitrage import public_markets +from arbitrage.arbitrer import Arbitrer + + +class ArbitrerCLI: + def __init__(self): + self.inject_verbose_info() + + def inject_verbose_info(self): + logging.VERBOSE = 15 + logging.verbose = lambda x: logging.log(logging.VERBOSE, x) + logging.addLevelName(logging.VERBOSE, "VERBOSE") + + def exec_command(self, args): + if "watch" in args.command: + self.create_arbitrer(args) + self.arbitrer.loop() + if "replay-history" in args.command: + self.create_arbitrer(args) + self.arbitrer.replay_history(args.replay_history) + if "get-balance" in args.command: + self.get_balance(args) + if "list-public-markets" in args.command: + self.list_markets() + if "generate-config" in args.command: + self.generate_sample_config() + + def get_market_list(self): + markets = [] + for filename in glob.glob(os.path.join(public_markets.__path__[0], "*.py")): + module_name = os.path.basename(filename).replace(".py", "") + if not module_name.startswith("_"): + module = __import__("arbitrage.public_markets." + module_name) + test = eval("module.public_markets." + module_name) + for name, obj in inspect.getmembers(test): + if inspect.isclass(obj) and "Market" in ( + j.__name__ for j in obj.mro()[1:] + ): + if not obj.__module__.split(".")[-1].startswith("_"): + markets.append(obj.__name__) + return markets + + def list_markets(self): + markets = self.get_market_list() + markets.sort() + print("\n".join(markets)) + sys.exit(0) + + def generate_sample_config(self): + markets = self.get_market_list() + markets.sort() + print("markets = [") + print('",\n'.join([' "' + i for i in markets]) + '"') + print("]") + print('observers = ["Logger"]') + print( + """ +refresh_rate = 60 +market_expiration_time = 120 # in seconds: 2 minutes + +# SafeGuards +max_tx_volume = 1 # in BTC +min_tx_volume = 0.01 # in BTC +balance_margin = 0.05 # 5% +profit_thresh = 0 # in USD +perc_thresh = 0 # in %""" + ) + sys.exit(0) + + def get_balance(self, args): + if not args.markets: + logging.error("You must use --markets argument to specify markets") + sys.exit(2) + pmarkets = args.markets.split(",") + pmarketsi = [] + for pmarket in pmarkets: + exec("import arbitrage.private_markets." + pmarket.lower()) + market = eval( + "arbitrage.private_markets." + + pmarket.lower() + + ".Private" + + pmarket + + "()" + ) + pmarketsi.append(market) + for market in pmarketsi: + print(market) + + def create_arbitrer(self, args): + self.arbitrer = Arbitrer() + if args.observers: + self.arbitrer.init_observers(args.observers.split(",")) + if args.markets: + self.arbitrer.init_markets(args.markets.split(",")) + + def init_logger(self, args): + level = logging.INFO + if args.verbose: + level = logging.VERBOSE + if args.debug: + level = logging.DEBUG + logging.basicConfig( + format="%(asctime)s [%(levelname)s] %(message)s", level=level + ) + + def main(self): + parser = argparse.ArgumentParser() + parser.add_argument( + "-d", "--debug", help="debug verbose mode", action="store_true" + ) + parser.add_argument( + "-v", "--verbose", help="info verbose mode", action="store_true" + ) + parser.add_argument( + "-o", "--observers", type=str, help="observers, example: -oLogger,Emailer" + ) + parser.add_argument( + "-m", + "--markets", + type=str, + help="markets, example: -m BitstampEUR,KrakenEUR", + ) + parser.add_argument( + "command", + nargs="*", + default="watch", + help='verb: "watch|replay-history|get-balance|list-public-markets"', + ) + args = parser.parse_args() + self.init_logger(args) + self.exec_command(args) + + +def main(): + cli = ArbitrerCLI() + cli.main() + + +if __name__ == "__main__": + main() diff --git a/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/arbitrer.py b/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/arbitrer.py new file mode 100644 index 00000000..6e8abb8e --- /dev/null +++ b/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/arbitrer.py @@ -0,0 +1,243 @@ +# Copyright (C) 2013, Maxime Biais + +import json +import logging +import time +from concurrent.futures import ThreadPoolExecutor, wait + +from arbitrage import config, observers, public_markets # noqa:F401 + + +class Arbitrer(object): + def __init__(self): + self.markets = [] + self.observers = [] + self.depths = {} + self.init_markets(config.markets) + self.init_observers(config.observers) + self.max_tx_volume = config.max_tx_volume + self.threadpool = ThreadPoolExecutor(max_workers=10) + + def init_markets(self, markets): + self.market_names = markets + for market_name in markets: + try: + exec("import arbitrage.public_markets." + market_name.lower()) + market = eval( + "arbitrage.public_markets." + + market_name.lower() + + "." + + market_name + + "()" + ) + self.markets.append(market) + except (ImportError, AttributeError) as e: + print( + "%s market name is invalid: Ignored (you should check your config file)" + % (market_name) + ) + + def init_observers(self, _observers): + self.observer_names = _observers + for observer_name in _observers: + try: + exec("import arbitrage.observers." + observer_name.lower()) + observer = eval( + "arbitrage.observers." + + observer_name.lower() + + "." + + observer_name + + "()" + ) + self.observers.append(observer) + except (ImportError, AttributeError) as e: + print( + "%s observer name is invalid: Ignored (you should check your config file)" + % (observer_name) + ) + + def get_profit_for(self, mi, mj, kask, kbid): + if ( + self.depths[kask]["asks"][mi]["price"] + >= self.depths[kbid]["bids"][mj]["price"] + ): + return 0, 0, 0, 0 + + max_amount_buy = 0 + for i in range(mi + 1): + max_amount_buy += self.depths[kask]["asks"][i]["amount"] + max_amount_sell = 0 + for j in range(mj + 1): + max_amount_sell += self.depths[kbid]["bids"][j]["amount"] + max_amount = min(max_amount_buy, max_amount_sell, self.max_tx_volume) + + buy_total = 0 + w_buyprice = 0 + for i in range(mi + 1): + price = self.depths[kask]["asks"][i]["price"] + amount = ( + min(max_amount, buy_total + self.depths[kask]["asks"][i]["amount"]) + - buy_total + ) + if amount <= 0: + break + buy_total += amount + if w_buyprice == 0: + w_buyprice = price + else: + w_buyprice = ( + w_buyprice * (buy_total - amount) + price * amount + ) / buy_total + + sell_total = 0 + w_sellprice = 0 + for j in range(mj + 1): + price = self.depths[kbid]["bids"][j]["price"] + amount = ( + min(max_amount, sell_total + self.depths[kbid]["bids"][j]["amount"]) + - sell_total + ) + if amount < 0: + break + sell_total += amount + if w_sellprice == 0 or sell_total == 0: + w_sellprice = price + else: + w_sellprice = ( + w_sellprice * (sell_total - amount) + price * amount + ) / sell_total + + profit = sell_total * w_sellprice - buy_total * w_buyprice + return profit, sell_total, w_buyprice, w_sellprice + + def get_max_depth(self, kask, kbid): + i = 0 + if len(self.depths[kbid]["bids"]) != 0 and len(self.depths[kask]["asks"]) != 0: + while ( + self.depths[kask]["asks"][i]["price"] + < self.depths[kbid]["bids"][0]["price"] + ): + if i >= len(self.depths[kask]["asks"]) - 1: + break + i += 1 + j = 0 + if len(self.depths[kask]["asks"]) != 0 and len(self.depths[kbid]["bids"]) != 0: + while ( + self.depths[kask]["asks"][0]["price"] + < self.depths[kbid]["bids"][j]["price"] + ): + if j >= len(self.depths[kbid]["bids"]) - 1: + break + j += 1 + return i, j + + def arbitrage_depth_opportunity(self, kask, kbid): + maxi, maxj = self.get_max_depth(kask, kbid) + best_profit = 0 + best_i, best_j = (0, 0) + best_w_buyprice, best_w_sellprice = (0, 0) + best_volume = 0 + for i in range(maxi + 1): + for j in range(maxj + 1): + profit, volume, w_buyprice, w_sellprice = self.get_profit_for( + i, j, kask, kbid + ) + if profit >= 0 and profit >= best_profit: + best_profit = profit + best_volume = volume + best_i, best_j = (i, j) + best_w_buyprice, best_w_sellprice = (w_buyprice, w_sellprice) + return ( + best_profit, + best_volume, + self.depths[kask]["asks"][best_i]["price"], + self.depths[kbid]["bids"][best_j]["price"], + best_w_buyprice, + best_w_sellprice, + ) + + def arbitrage_opportunity(self, kask, ask, kbid, bid): + perc = (bid["price"] - ask["price"]) / bid["price"] * 100 + profit, volume, buyprice, sellprice, weighted_buyprice, weighted_sellprice = ( + self.arbitrage_depth_opportunity(kask, kbid) + ) + if volume == 0 or buyprice == 0: + return + perc2 = (1 - (volume - (profit / buyprice)) / volume) * 100 + for observer in self.observers: + observer.opportunity( + profit, + volume, + buyprice, + kask, + sellprice, + kbid, + perc2, + weighted_buyprice, + weighted_sellprice, + ) + + def __get_market_depth(self, market, depths): + depths[market.name] = market.get_depth() + + def update_depths(self): + depths = {} + futures = [] + for market in self.markets: + futures.append( + self.threadpool.submit(self.__get_market_depth, market, depths) + ) + wait(futures, timeout=20) + return depths + + def tickers(self): + for market in self.markets: + logging.verbose("ticker: " + market.name + " - " + str(market.get_ticker())) + + def replay_history(self, directory): + import os + + # import pprint + + files = os.listdir(directory) + files.sort() + for f in files: + depths = json.load(open(directory + "/" + f, "r")) + self.depths = {} + for market in self.market_names: + if market in depths: + self.depths[market] = depths[market] + self.tick() + + def tick(self): + for observer in self.observers: + observer.begin_opportunity_finder(self.depths) + + for kmarket1 in self.depths: + for kmarket2 in self.depths: + if kmarket1 == kmarket2: # same market + continue + market1 = self.depths[kmarket1] + market2 = self.depths[kmarket2] + if ( + market1["asks"] + and market2["bids"] + and len(market1["asks"]) > 0 + and len(market2["bids"]) > 0 + ): + if float(market1["asks"][0]["price"]) < float( + market2["bids"][0]["price"] + ): + self.arbitrage_opportunity( + kmarket1, market1["asks"][0], kmarket2, market2["bids"][0] + ) + + for observer in self.observers: + observer.end_opportunity_finder() + + def loop(self): + while True: + self.depths = self.update_depths() + self.tickers() + self.tick() + time.sleep(config.refresh_rate) diff --git a/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/config.py-example b/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/config.py-example new file mode 100644 index 00000000..6d19e83e --- /dev/null +++ b/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/config.py-example @@ -0,0 +1,55 @@ +markets = [ + "BitFlyerEUR", + "BitFlyerUSD", + "BitfinexEUR", + "BitfinexUSD", + "BitstampEUR", + "BitstampUSD", + "CampBXUSD", + "CEXEUR", + "CEXUSD", + "GDAXEUR", + "GDAXUSD", + "GeminiUSD", + "KrakenEUR", + "KrakenUSD", + "OKCoinCNY", + "PaymiumEUR", +] + +# observers if any +# ["Logger", "DetailedLogger", "TraderBot", "TraderBotSim", "HistoryDumper", "Emailer"] +observers = ["Logger"] + +market_expiration_time = 120 # in seconds: 2 minutes + +refresh_rate = 60 + +#### Trader Bot Config +# Access to Private APIs + +paymium_username = "FIXME" +paymium_password = "FIXME" +paymium_address = "FIXME" # to deposit btc from markets / wallets + +bitstamp_username = "FIXME" +bitstamp_password = "FIXME" + +# SafeGuards +max_tx_volume = 10 # in BTC +min_tx_volume = 1 # in BTC +balance_margin = 0.05 # 5% +profit_thresh = 1 # in EUR +perc_thresh = 2 # in % + +#### Emailer Observer Config +smtp_host = "FIXME" +smtp_login = "FIXME" +smtp_passwd = "FIXME" +smtp_from = "FIXME" +smtp_to = "FIXME" + +#### XMPP Observer +xmpp_jid = "FROM@jabber.org" +xmpp_password = "FIXME" +xmpp_to = "TO@jabber.org" diff --git a/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/fiatconverter.py b/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/fiatconverter.py new file mode 100644 index 00000000..94ed120a --- /dev/null +++ b/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/fiatconverter.py @@ -0,0 +1,71 @@ +# Copyright (C) 2013-2019, Maxime Biais + +# import logging +# import sys +import time +import urllib.request +import xml.sax + + +class XmlHandler(xml.sax.ContentHandler): + def __init__(self): + self.currentTag = "" + self.rates = {} + + def startElement(self, tag, attributes): + if "currency" in attributes and "rate" in attributes: + self.rates[attributes["currency"]] = float(attributes["rate"]) + + def endElement(self, tag): + pass + + def characters(self, content): + pass + + +class FiatConverter: + __shared_state = {} + # Europa.eu is the official european central bank + rate_exchange_url = "https://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml" + + def __init__(self): + self.__dict__ = self.__shared_state + self.rates = {} + self.update_delay = 60 * 60 * 6 # every 6 hours + self.last_update = 0 + self.bank_fee = 0.007 # TODO: bank fee + self.handler = XmlHandler() + + def change_pivot(self, rates, pivot): + PVTEUR = 1.0 / rates[pivot] + for k in rates: + rates[k] = rates[k] * PVTEUR + return rates + + def update_pairs(self): + url = self.rate_exchange_url + res = urllib.request.urlopen(url) + xml.sax.parseString(res.read().decode("utf8"), self.handler) + self.rates = self.handler.rates + self.rates["EUR"] = 1 + + def update(self): + timediff = time.time() - self.last_update + if timediff < self.update_delay: + return + self.last_update = time.time() + self.update_pairs() + + def convert(self, price, code_from, code_to): + self.update() + rate_from = self.rates[code_from] + rate_to = self.rates[code_to] + return price / rate_from * rate_to + + +if __name__ == "__main__": + fc = FiatConverter() + print(fc.convert(12.0, "USD", "EUR")) + print(fc.convert(12.0, "EUR", "USD")) + print(fc.convert(fc.convert(12.0, "EUR", "USD"), "USD", "EUR")) + print(fc.rates) diff --git a/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/observers/__init__.py b/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/observers/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/observers/detailedlogger.py b/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/observers/detailedlogger.py new file mode 100644 index 00000000..6d450b32 --- /dev/null +++ b/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/observers/detailedlogger.py @@ -0,0 +1,22 @@ +import logging + +from arbitrage.observers.observer import Observer + + +class DetailedLogger(Observer): + def opportunity( + self, + profit, + volume, + buyprice, + kask, + sellprice, + kbid, + perc, + weighted_buyprice, + weighted_sellprice, + ): + logging.info( + "profit: %f USD with volume: %f BTC - buy at %.4f (%s) sell at %.4f (%s) ~%.2f%%" + % (profit, volume, buyprice, kask, sellprice, kbid, perc) + ) diff --git a/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/observers/emailer.py b/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/observers/emailer.py new file mode 100644 index 00000000..510af30e --- /dev/null +++ b/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/observers/emailer.py @@ -0,0 +1,52 @@ +import logging +import smtplib + +from arbitrage import config +from arbitrage.observers.observer import Observer + + +def send_email(subject, message): + _to = config.smtp_to + _from = config.smtp_from + mime_message = ( + """From: Python Arbitrage Script <%(_from)s> +To: <%(_to)s> +Subject: %(subject)s + +%(message)s +""" + % locals() + ) + try: + smtpObj = smtplib.SMTP(config.smtp_host) + smtpObj.sendmail(_from, [_to], mime_message) + except smtplib.SMTPException: + logging.warn("Unable to send email") + + +class Emailer(Observer): + def opportunity( + self, + profit, + volume, + buyprice, + kask, + sellprice, + kbid, + perc, + weighted_buyprice, + weighted_sellprice, + ): + if profit > config.profit_thresh and perc > config.perc_thresh: + message = """profit: %f USD with volume: %f BTC +buy at %.4f (%s) sell at %.4f (%s) ~%.2f%% +""" % ( + profit, + volume, + buyprice, + kask, + sellprice, + kbid, + perc, + ) + send_email("Arbitrage Bot", message) diff --git a/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/observers/historydumper.py b/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/observers/historydumper.py new file mode 100644 index 00000000..06a2ddc2 --- /dev/null +++ b/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/observers/historydumper.py @@ -0,0 +1,37 @@ +import json +import os +import time + +from arbitrage.observers.observer import Observer + + +class HistoryDumper(Observer): + out_dir = "history/" + + def __init__(self): + try: + os.mkdir(self.out_dir) + except Exception: + pass + + def begin_opportunity_finder(self, depths): + filename = self.out_dir + "order-book-" + str(int(time.time())) + ".json" + fp = open(filename, "w") + json.dump(depths, fp) + + def end_opportunity_finder(self): + pass + + def opportunity( + self, + profit, + volume, + buyprice, + kask, + sellprice, + kbid, + perc, + weighted_buyprice, + weighted_sellprice, + ): + pass diff --git a/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/observers/logger.py b/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/observers/logger.py new file mode 100644 index 00000000..3b20c1ba --- /dev/null +++ b/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/observers/logger.py @@ -0,0 +1,22 @@ +import logging + +from arbitrage.observers.observer import Observer + + +class Logger(Observer): + def opportunity( + self, + profit, + volume, + buyprice, + kask, + sellprice, + kbid, + perc, + weighted_buyprice, + weighted_sellprice, + ): + logging.info( + "profit: %f USD with volume: %f BTC - buy from %s sell to %s ~%.2f%%" + % (profit, volume, kask, kbid, perc) + ) diff --git a/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/observers/observer.py b/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/observers/observer.py new file mode 100644 index 00000000..255aae1b --- /dev/null +++ b/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/observers/observer.py @@ -0,0 +1,25 @@ +import abc + + +class Observer(object, metaclass=abc.ABCMeta): + def begin_opportunity_finder(self, depths): + pass + + def end_opportunity_finder(self): + pass + + # abstract + @abc.abstractmethod + def opportunity( + self, + profit, + volume, + buyprice, + kask, + sellprice, + kbid, + perc, + weighted_buyprice, + weighted_sellprice, + ): + pass diff --git a/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/observers/specializedtraderbot.py b/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/observers/specializedtraderbot.py new file mode 100644 index 00000000..f2f096f7 --- /dev/null +++ b/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/observers/specializedtraderbot.py @@ -0,0 +1,118 @@ +import logging +import time + +from arbitrage import config +from arbitrage.observers.emailer import send_email +from arbitrage.observers.observer import Observer +from arbitrage.private_markets import bitstampusd, paymium + + +class SpecializedTraderBot(Observer): + def __init__(self): + self.bitstamp = bitstampusd.PrivateBitstampUSD() + self.btcentral = paymium.PrivatePaymium() + self.clients = {"BitStampUSD": self.bitstamp, "PaymiumEUR": self.btcentral} + self.profit_percentage_thresholds = { # Graph + "BitStampUSD": {"PaymiumEUR": 3.5}, + "PaymiumEUR": {"BitStampUSD": 1}, + } + self.trade_wait = 60 * 5 # in seconds + self.last_trade = 0 + self.potential_trades = [] + + def begin_opportunity_finder(self, depths): + self.potential_trades = [] + + def end_opportunity_finder(self): + if not self.potential_trades: + return + self.potential_trades.sort(key=lambda x: x[0]) + # Execute only the best (more profitable) + self.execute_trade(*self.potential_trades[0][1:]) + + def get_min_tradeable_volume(self, buyprice, eur_bal, btc_bal): + min1 = float(eur_bal) / ((1.0 + config.balance_margin) * buyprice) + min2 = float(btc_bal) / (1.0 + config.balance_margin) + return min(min1, min2) * 0.95 + + def update_balance(self): + for kclient in self.clients: + self.clients[kclient].get_info() + + def opportunity( + self, + profit, + volume, + buyprice, + kask, + sellprice, + kbid, + perc, + weighted_buyprice, + weighted_sellprice, + ): + if kask not in self.clients: + logging.warn("Can't automate this trade, client not available: %s" % (kask)) + return + if kbid not in self.clients: + logging.warn("Can't automate this trade, client not available: %s" % (kbid)) + return + if perc < self.profit_percentage_thresholds[kask][kbid]: + logging.warn( + "Can't automate this trade, profit=%f is lower than defined threshold %f" + % (perc, self.profit_percentage_thresholds[kask][kbid]) + ) + return + + if ( + perc > 20 + ): # suspicous profit, added after discovering btc-central may send corrupted order book + logging.warn("Profit=%f seems malformed" % (perc,)) + return + + # Update client balance + self.update_balance() + + # maximum volume transaction with current balances + max_volume = self.get_min_tradeable_volume( + buyprice, self.clients[kask].eur_balance, self.clients[kbid].btc_balance + ) + volume = min(volume, max_volume, config.max_tx_volume) + if volume < config.min_tx_volume: + logging.warn( + "Can't automate this trade, minimum volume transaction not reached %f/%f" + % (volume, config.min_tx_volume) + ) + logging.info( + "Balance on %s: %f EUR - Balance on %s: %f BTC" + % ( + kask, + self.clients[kask].eur_balance, + kbid, + self.clients[kbid].btc_balance, + ) + ) + return + + current_time = time.time() + if current_time - self.last_trade < self.trade_wait: + logging.warn( + "Can't automate this trade, last trade occured %s seconds ago" + % (current_time - self.last_trade) + ) + return + + self.potential_trades.append( + [profit, volume, kask, kbid, weighted_buyprice, weighted_sellprice] + ) + + def execute_trade(self, volume, kask, kbid, weighted_buyprice, weighted_sellprice): + self.last_trade = time.time() + logging.info("Buy @%s %f BTC and sell @%s" % (kask, volume, kbid)) + send_email( + "Bought @%s %f BTC and sold @%s" % (kask, volume, kbid), + "weighted_buyprice=%f weighted_sellprice=%f" + % (weighted_buyprice, weighted_sellprice), + ) + self.clients[kask].buy(volume) + self.clients[kbid].sell(volume) diff --git a/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/observers/traderbot.py b/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/observers/traderbot.py new file mode 100644 index 00000000..ecad8302 --- /dev/null +++ b/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/observers/traderbot.py @@ -0,0 +1,129 @@ +import logging +import time + +from arbitrage import config +from arbitrage.fiatconverter import FiatConverter + +# from arbitrage.observers.emailer import send_email +from arbitrage.observers.observer import Observer + + +class TraderBot(Observer): + def __init__(self): + self.clients = { + # TODO: move that to the config file + # "BitstampUSD": bitstampusd.PrivateBitstampUSD(), + } + self.fc = FiatConverter() + self.trade_wait = 120 # in seconds + self.last_trade = 0 + self.potential_trades = [] + + def begin_opportunity_finder(self, depths): + self.potential_trades = [] + + def end_opportunity_finder(self): + if not self.potential_trades: + return + self.potential_trades.sort(key=lambda x: x[0]) + # Execute only the best (more profitable) + self.execute_trade(*self.potential_trades[0][1:]) + + def get_min_tradeable_volume(self, buyprice, usd_bal, btc_bal): + min1 = float(usd_bal) / ((1 + config.balance_margin) * buyprice) + min2 = float(btc_bal) / (1 + config.balance_margin) + return min(min1, min2) + + def update_balance(self): + for kclient in self.clients: + self.clients[kclient].get_info() + + def opportunity( + self, + profit, + volume, + buyprice, + kask, + sellprice, + kbid, + perc, + weighted_buyprice, + weighted_sellprice, + ): + if profit < config.profit_thresh or perc < config.perc_thresh: + logging.verbose( + "[TraderBot] Profit or profit percentage lower than" + " thresholds" + ) + return + if kask not in self.clients: + logging.warn( + "[TraderBot] Can't automate this trade, client not " + + "available: %s" % kask + ) + return + if kbid not in self.clients: + logging.warn( + "[TraderBot] Can't automate this trade, " + + "client not available: %s" % kbid + ) + return + volume = min(config.max_tx_volume, volume) + + # Update client balance + self.update_balance() + max_volume = self.get_min_tradeable_volume( + buyprice, self.clients[kask].usd_balance, self.clients[kbid].btc_balance + ) + volume = min(volume, max_volume, config.max_tx_volume) + if volume < config.min_tx_volume: + logging.warn( + "Can't automate this trade, minimum volume transaction" + + " not reached %f/%f" % (volume, config.min_tx_volume) + ) + logging.warn( + "Balance on %s: %f USD - Balance on %s: %f BTC" + % ( + kask, + self.clients[kask].usd_balance, + kbid, + self.clients[kbid].btc_balance, + ) + ) + return + current_time = time.time() + if current_time - self.last_trade < self.trade_wait: + logging.warn( + "[TraderBot] Can't automate this trade, last trade " + + "occured %.2f seconds ago" % (current_time - self.last_trade) + ) + return + self.potential_trades.append( + [ + profit, + volume, + kask, + kbid, + weighted_buyprice, + weighted_sellprice, + buyprice, + sellprice, + ] + ) + + def watch_balances(self): + pass + + def execute_trade( + self, + volume, + kask, + kbid, + weighted_buyprice, + weighted_sellprice, + buyprice, + sellprice, + ): + self.last_trade = time.time() + logging.info("Buy @%s %f BTC and sell @%s" % (kask, volume, kbid)) + self.clients[kask].buy(volume, buyprice) + self.clients[kbid].sell(volume, sellprice) diff --git a/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/observers/traderbotsim.py b/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/observers/traderbotsim.py new file mode 100644 index 00000000..4a486653 --- /dev/null +++ b/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/observers/traderbotsim.py @@ -0,0 +1,97 @@ +import json +import logging + +from arbitrage import config +from arbitrage.observers.traderbot import TraderBot + + +class MockMarket(object): + def __init__( + self, name, fee=0, usd_balance=500.0, btc_balance=15.0, persistent=True + ): + self.name = name + self.filename = "traderbot-sim-" + name + ".json" + self.usd_balance = usd_balance + self.btc_balance = btc_balance + self.fee = fee + self.persistent = persistent + if self.persistent: + try: + self.load() + except IOError: + pass + + def buy(self, volume, price): + logging.info( + "[TraderBotSim] execute buy %f BTC @ %f on %s" % (volume, price, self.name) + ) + self.usd_balance -= price * volume + self.btc_balance += volume - volume * self.fee + if self.persistent: + self.save() + + def sell(self, volume, price): + logging.info( + "[TraderBotSim] execute sell %f BTC @ %f on %s" % (volume, price, self.name) + ) + self.btc_balance -= volume + self.usd_balance += price * volume - price * volume * self.fee + if self.persistent: + self.save() + + def load(self): + data = json.load(open(self.filename, "r")) + self.usd_balance = data["usd"] + self.btc_balance = data["btc"] + + def save(self): + data = {"usd": self.usd_balance, "btc": self.btc_balance} + json.dump(data, open(self.filename, "w")) + + def balance_total(self, price): + return self.usd_balance + self.btc_balance * price + + def get_info(self): + pass + + +class TraderBotSim(TraderBot): + def __init__(self): + self.clients = {} + for configured_market in config.markets: + self.clients[configured_market] = MockMarket( + configured_market, 0.005, 10000 + ) + self.profit_thresh = 10 # in EUR + self.perc_thresh = 0.01 # in % + self.trade_wait = 120 + self.last_trade = 0 + + def total_balance(self, price): + market_balances = [i.balance_total(price) for i in set(self.clients.values())] + return sum(market_balances) + + def total_usd_balance(self): + return sum([i.usd_balance for i in set(self.clients.values())]) + + def total_btc_balance(self): + return sum([i.btc_balance for i in set(self.clients.values())]) + + def execute_trade( + self, + volume, + kask, + kbid, + weighted_buyprice, + weighted_sellprice, + buyprice, + sellprice, + ): + self.clients[kask].buy(volume, buyprice) + self.clients[kbid].sell(volume, sellprice) + + +if __name__ == "__main__": + t = TraderBotSim() + print("Total BTC: %f" % t.total_btc_balance()) + print("Total USD: %f" % t.total_usd_balance()) diff --git a/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/observers/xmppmessager.py b/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/observers/xmppmessager.py new file mode 100644 index 00000000..dd7097d2 --- /dev/null +++ b/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/observers/xmppmessager.py @@ -0,0 +1,54 @@ +import logging + +from arbitrage import config +from arbitrage.observers.observer import Observer +from sleekxmpp import ClientXMPP + +# from sleekxmpp.exceptions import IqError, IqTimeout + + +class MyXMPPClient(ClientXMPP): + def __init__(self): + logger = logging.getLogger("sleekxmpp") + logger.setLevel(logging.ERROR) + ClientXMPP.__init__(self, config.xmpp_jid, config.xmpp_password) + self.add_event_handler("session_start", self.session_start) + self.add_event_handler("message", self.message) + self.connect() + self.process(block=False) + + def session_start(self, event): + self.send_presence() + self.get_roster() + + def msend_message(self, message): + logging.debug('Sending XMPP message: "%s" to %s' % (message, config.xmpp_to)) + self.send_message(mto=config.xmpp_to, mbody=message, mtype="chat") + + def message(self, msg): + # TODO: Use this to control / re-config + pass # msg.reply("%(body)s" % msg).send() + + +class XmppMessager(Observer): + def __init__(self): + self.xmppclient = MyXMPPClient() + + def opportunity( + self, + profit, + volume, + buyprice, + kask, + sellprice, + kbid, + perc, + weighted_buyprice, + weighted_sellprice, + ): + if profit > config.profit_thresh and perc > config.perc_thresh: + message = ( + "profit: %f USD with volume: %f BTC - buy at %.4f (%s) sell at %.4f (%s) ~%.2f%%" + % (profit, volume, buyprice, kask, sellprice, kbid, perc) + ) + self.xmppclient.msend_message(message) diff --git a/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/private_markets/__init__.py b/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/private_markets/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/private_markets/bitstampusd.py b/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/private_markets/bitstampusd.py new file mode 100644 index 00000000..e5cd25bb --- /dev/null +++ b/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/private_markets/bitstampusd.py @@ -0,0 +1,69 @@ +# Copyright (C) 2013, Maxime Biais + +# import base64 +# import hashlib +# import hmac +import json + +# import sys +import urllib.error +import urllib.parse +import urllib.request + +from arbitrage import config +from arbitrage.private_markets.market import Market, TradeException + + +class PrivateBitstampUSD(Market): + balance_url = "https://www.bitstamp.net/api/balance/" + buy_url = "https://www.bitstamp.net/api/buy/" + sell_url = "https://www.bitstamp.net/api/sell/" + + def __init__(self): + super().__init__() + self.username = config.bitstamp_username + self.password = config.bitstamp_password + self.currency = "USD" + self.get_info() + + def _send_request(self, url, params={}, extra_headers=None): + headers = { + "Content-type": "application/json", + "Accept": "application/json, text/javascript, */*; q=0.01", + "User-Agent": "Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)", + } + if extra_headers is not None: + for k, v in extra_headers.items(): + headers[k] = v + + params["user"] = self.username + params["password"] = self.password + postdata = urllib.parse.urlencode(params).encode("utf-8") + req = urllib.request.Request(url, postdata, headers=headers) + response = urllib.request.urlopen(req) + code = response.getcode() + if code == 200: + jsonstr = response.read().decode("utf-8") + return json.loads(jsonstr) + return None + + def _buy(self, amount, price): + """Create a buy limit order""" + params = {"amount": amount, "price": price} + response = self._send_request(self.buy_url, params) + if "error" in response: + raise TradeException(response["error"]) + + def _sell(self, amount, price): + """Create a sell limit order""" + params = {"amount": amount, "price": price} + response = self._send_request(self.sell_url, params) + if "error" in response: + raise TradeException(response["error"]) + + def get_info(self): + """Get balance""" + response = self._send_request(self.balance_url) + if response: + self.btc_balance = float(response["btc_available"]) + self.usd_balance = float(response["usd_available"]) diff --git a/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/private_markets/market.py b/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/private_markets/market.py new file mode 100644 index 00000000..88028802 --- /dev/null +++ b/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/private_markets/market.py @@ -0,0 +1,63 @@ +# Copyright (C) 2013, Maxime Biais + +import logging + +from arbitrage.fiatconverter import FiatConverter + + +class TradeException(Exception): + pass + + +class Market: + def __init__(self): + self.name = self.__class__.__name__ + self.btc_balance = 0.0 + self.eur_balance = 0.0 + self.usd_balance = 0.0 + self.fc = FiatConverter() + + def __str__(self): + return "%s: %s" % ( + self.name, + str( + { + "btc_balance": self.btc_balance, + "eur_balance": self.eur_balance, + "usd_balance": self.usd_balance, + } + ), + ) + + def buy(self, amount, price): + """Orders are always priced in USD""" + local_currency_price = self.fc.convert(price, "USD", self.currency) + logging.info( + "Buy %f BTC at %f %s (%f USD) @%s" + % (amount, local_currency_price, self.currency, price, self.name) + ) + self._buy(amount, local_currency_price) + + def sell(self, amount, price): + """Orders are always priced in USD""" + local_currency_price = self.fc.convert(price, "USD", self.currency) + logging.info( + "Sell %f BTC at %f %s (%f USD) @%s" + % (amount, local_currency_price, self.currency, price, self.name) + ) + self._sell(amount, local_currency_price) + + def _buy(self, amount, price): + raise NotImplementedError("%s.sell(self, amount, price)" % self.name) + + def _sell(self, amount, price): + raise NotImplementedError("%s.sell(self, amount, price)" % self.name) + + def deposit(self): + raise NotImplementedError("%s.sell(self, amount, price)" % self.name) + + def withdraw(self, amount, address): + raise NotImplementedError("%s.sell(self, amount, price)" % self.name) + + def get_info(self): + raise NotImplementedError("%s.sell(self, amount, price)" % self.name) diff --git a/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/private_markets/paymium.py b/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/private_markets/paymium.py new file mode 100644 index 00000000..431d0179 --- /dev/null +++ b/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/private_markets/paymium.py @@ -0,0 +1,94 @@ +import base64 + +# import hashlib +# import hmac +import json + +# import sys +import time +import urllib.error +import urllib.parse +import urllib.request + +from arbitrage import config +from arbitrage.private_markets.market import Market + + +class PrivatePaymium(Market): + balance_url = "https://paymium.com/api/v1/balances/" + trade_url = "https://paymium.com/api/v1/trade_orders/" + withdraw_url = "https://paymium.com/api/v1/transfers/send_bitcoins/" + + def __init__(self): + # FIXME: update this file when bitcoin central re-opens + raise Exception("Paymium is closed") + super().__init__() + self.username = config.paymium_username + self.password = config.paymium_password + self.currency = "EUR" + self.get_info() + + def _create_nonce(self): + return int(time.time() * 1000000) + + def _send_request(self, url, params=[], extra_headers=None): + headers = { + "Content-type": "application/json", + "Accept": "application/json, text/javascript, */*; q=0.01", + "User-Agent": "Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)", + } + if extra_headers is not None: + for k, v in extra_headers.items(): + headers[k] = v + + req = None + if params: + req = urllib.request.Request(url, json.dumps(params), headers=headers) + else: + req = urllib.request.Request(url, headers=headers) + userpass = "%s:%s" % (self.username, self.password) + base64string = base64.b64encode(bytes(userpass, "utf-8")).decode("ascii") + req.add_header("Authorization", "Basic %s" % base64string) + response = urllib.request.urlopen(req) + code = response.getcode() + if code == 200: + jsonstr = response.read().decode("utf-8") + return json.loads(jsonstr) + return None + + def trade(self, amount, ttype, price=None): + # params = [("amount", amount), ("currency", self.currency), ("type", + # ttype)] + params = {"amount": amount, "currency": self.currency, "type": ttype} + if price: + params["price"] = price + response = self._send_request(self.trade_url, params) + return response + + def buy(self, amount, price=None): + response = self.trade(amount, "buy", price) + + def sell(self, amount, price=None): + response = self.trade(amount, "sell", price) + print(response) + + def withdraw(self, amount, address): + params = {"amount": amount, "address": address} + response = self._send_request(self.trade_url, params) + return response + + def deposit(self): + return config.paymium_address + + def get_info(self): + response = self._send_request(self.balance_url) + if response: + self.btc_balance = response["BTC"] + self.eur_balance = response["EUR"] + self.usd_balance = self.fc.convert(self.eur_balance, "EUR", "USD") + + +if __name__ == "__main__": + market = PrivatePaymium() + market.get_info() + print(market) diff --git a/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/public_markets/__init__.py b/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/public_markets/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/public_markets/_binance.py b/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/public_markets/_binance.py new file mode 100644 index 00000000..37f0633f --- /dev/null +++ b/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/public_markets/_binance.py @@ -0,0 +1,32 @@ +import json +import urllib.error +import urllib.parse +import urllib.request + +from arbitrage.public_markets.market import Market + + +class Binance(Market): + def __init__(self, currency, code): + super().__init__(currency) + self.code = code + self.update_rate = 30 + + def update_depth(self): + url = "https://api.binance.com/api/v1/depth?symbol=%s" % self.code + req = urllib.request.Request(url, headers={"Accept": "*/*"}) + res = urllib.request.urlopen(req) + depth = json.loads(res.read().decode("utf8")) + self.depth = self.format_depth(depth) + + def sort_and_format(self, l, reverse=False): + l.sort(key=lambda x: float(x[0]), reverse=reverse) + r = [] + for i in l: + r.append({"price": float(i[0]), "amount": float(i[1])}) + return r + + def format_depth(self, depth): + bids = self.sort_and_format(depth["bids"], True) + asks = self.sort_and_format(depth["asks"], False) + return {"asks": asks, "bids": bids} diff --git a/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/public_markets/_bitfinex.py b/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/public_markets/_bitfinex.py new file mode 100644 index 00000000..5b815a0c --- /dev/null +++ b/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/public_markets/_bitfinex.py @@ -0,0 +1,35 @@ +import json +import logging +import urllib.error +import urllib.parse +import urllib.request + +from arbitrage.public_markets.market import Market + + +class Bitfinex(Market): + def __init__(self, currency, code): + super().__init__(currency) + self.code = code + self.update_rate = 20 + + def update_depth(self): + res = urllib.request.urlopen("https://api.bitfinex.com/v1/book/" + self.code) + jsonstr = res.read().decode("utf8") + try: + depth = json.loads(jsonstr) + except Exception: + logging.error("%s - Can't parse json: %s" % (self.name, jsonstr)) + self.depth = self.format_depth(depth) + + def sort_and_format(self, l, reverse=False): + l.sort(key=lambda x: float(x["price"]), reverse=reverse) + r = [] + for i in l: + r.append({"price": float(i["price"]), "amount": float(i["amount"])}) + return r + + def format_depth(self, depth): + bids = self.sort_and_format(depth["bids"], True) + asks = self.sort_and_format(depth["asks"], False) + return {"asks": asks, "bids": bids} diff --git a/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/public_markets/_bitflyer.py b/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/public_markets/_bitflyer.py new file mode 100644 index 00000000..aa296f33 --- /dev/null +++ b/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/public_markets/_bitflyer.py @@ -0,0 +1,60 @@ +import json +import logging +import urllib.error +import urllib.parse +import urllib.request + +from arbitrage.public_markets.market import Market + + +# { +# "mid_price": 33320, +# "bids": [ +# { +# "price": 30000, +# "size": 0.1 +# }, +# { +# "price": 25570, +# "size": 3 +# } +# ], +# "asks": [ +# { +# "price": 36640, +# "size": 5 +# }, +# { +# "price": 36700, +# "size": 1.2 +# } +# ] +# } +class BitFlyer(Market): + def __init__(self, currency, code): + super().__init__(currency) + self.code = code + self.update_rate = 20 + + def update_depth(self): + res = urllib.request.urlopen( + "https://api.bitflyer.com/v1/board?product_code=" + self.code + ) + jsonstr = res.read().decode("utf8") + try: + depth = json.loads(jsonstr) + except Exception: + logging.error("%s - Can't parse json: %s" % (self.name, jsonstr)) + self.depth = self.format_depth(depth) + + def sort_and_format(self, l, reverse=False): + l.sort(key=lambda x: float(x["price"]), reverse=reverse) + r = [] + for i in l: + r.append({"price": float(i["price"]), "amount": float(i["size"])}) + return r + + def format_depth(self, depth): + bids = self.sort_and_format(depth["bids"], True) + asks = self.sort_and_format(depth["asks"], False) + return {"asks": asks, "bids": bids} diff --git a/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/public_markets/_bitstamp.py b/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/public_markets/_bitstamp.py new file mode 100644 index 00000000..09af7fb4 --- /dev/null +++ b/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/public_markets/_bitstamp.py @@ -0,0 +1,40 @@ +import json +import urllib.error +import urllib.parse +import urllib.request + +from arbitrage.public_markets.market import Market + + +class Bitstamp(Market): + def __init__(self, currency, code): + super().__init__(currency) + self.code = code + self.update_rate = 20 + + def update_depth(self): + url = "https://www.bitstamp.net/api/v2/order_book/" + self.code + req = urllib.request.Request( + url, + None, + headers={ + "Content-Type": "application/x-www-form-urlencoded", + "Accept": "*/*", + "User-Agent": "curl/7.24.0 (x86_64-apple-darwin12.0)", + }, + ) + res = urllib.request.urlopen(req) + depth = json.loads(res.read().decode("utf8")) + self.depth = self.format_depth(depth) + + def sort_and_format(self, l, reverse): + r = [] + for i in l: + r.append({"price": float(i[0]), "amount": float(i[1])}) + r.sort(key=lambda x: float(x["price"]), reverse=reverse) + return r + + def format_depth(self, depth): + bids = self.sort_and_format(depth["bids"], True) + asks = self.sort_and_format(depth["asks"], False) + return {"asks": asks, "bids": bids} diff --git a/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/public_markets/_btcc.py b/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/public_markets/_btcc.py new file mode 100644 index 00000000..992149c1 --- /dev/null +++ b/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/public_markets/_btcc.py @@ -0,0 +1,39 @@ +import json +import urllib.error +import urllib.parse +import urllib.request + +from arbitrage.public_markets.market import Market + + +class BTCC(Market): + def __init__(self, currency, symbol): + super().__init__(currency) + self.symbol = symbol + self.update_rate = 30 + + def update_depth(self): + url = "https://data.btcc.com/data/orderbook?market=" + self.symbol + req = urllib.request.Request( + url, + headers={ + "Content-Type": "application/x-www-form-urlencoded", + "Accept": "*/*", + "User-Agent": "curl/7.24.0 (x86_64-apple-darwin12.0)", + }, + ) + res = urllib.request.urlopen(req) + depth = json.loads(res.read().decode("utf8")) + self.depth = self.format_depth(depth) + + def sort_and_format(self, l, reverse=False): + l.sort(key=lambda x: float(x[0]), reverse=reverse) + r = [] + for i in l: + r.append({"price": float(i[0]), "amount": float(i[1])}) + return r + + def format_depth(self, depth): + bids = self.sort_and_format(depth["bids"], True) + asks = self.sort_and_format(depth["asks"], False) + return {"asks": asks, "bids": bids} diff --git a/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/public_markets/_cex.py b/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/public_markets/_cex.py new file mode 100644 index 00000000..9023bdaa --- /dev/null +++ b/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/public_markets/_cex.py @@ -0,0 +1,39 @@ +import json +import urllib.error +import urllib.parse +import urllib.request + +from arbitrage.public_markets.market import Market + + +class CEX(Market): + def __init__(self, currency, code): + super().__init__(currency) + self.code = code + self.update_rate = 30 + + def update_depth(self): + url = "https://cex.io/api/order_book/BTC/%s/" % self.code + req = urllib.request.Request( + url, + headers={ + "Content-Type": "application/x-www-form-urlencoded", + "Accept": "*/*", + "User-Agent": "curl/7.24.0 (x86_64-apple-darwin12.0)", + }, + ) + res = urllib.request.urlopen(req) + depth = json.loads(res.read().decode("utf8")) + self.depth = self.format_depth(depth) + + def sort_and_format(self, l, reverse=False): + l.sort(key=lambda x: float(x[0]), reverse=reverse) + r = [] + for i in l: + r.append({"price": float(i[0]), "amount": float(i[1])}) + return r + + def format_depth(self, depth): + bids = self.sort_and_format(depth["bids"], True) + asks = self.sort_and_format(depth["asks"], False) + return {"asks": asks, "bids": bids} diff --git a/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/public_markets/_gdax.py b/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/public_markets/_gdax.py new file mode 100644 index 00000000..c6fbc010 --- /dev/null +++ b/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/public_markets/_gdax.py @@ -0,0 +1,39 @@ +import json +import urllib.error +import urllib.parse +import urllib.request + +from arbitrage.public_markets.market import Market + + +class GDAX(Market): + def __init__(self, currency, code): + super().__init__(currency) + self.code = code + self.update_rate = 30 + + def update_depth(self): + url = "https://api.gdax.com/products/%s/book?level=2" % self.code + req = urllib.request.Request( + url, + headers={ + "Content-Type": "application/x-www-form-urlencoded", + "Accept": "*/*", + "User-Agent": "curl/7.24.0 (x86_64-apple-darwin12.0)", + }, + ) + res = urllib.request.urlopen(req) + depth = json.loads(res.read().decode("utf8")) + self.depth = self.format_depth(depth) + + def sort_and_format(self, l, reverse=False): + l.sort(key=lambda x: float(x[0]), reverse=reverse) + r = [] + for i in l: + r.append({"price": float(i[0]), "amount": float(i[1])}) + return r + + def format_depth(self, depth): + bids = self.sort_and_format(depth["bids"], True) + asks = self.sort_and_format(depth["asks"], False) + return {"asks": asks, "bids": bids} diff --git a/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/public_markets/_gemini.py b/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/public_markets/_gemini.py new file mode 100644 index 00000000..12001dcb --- /dev/null +++ b/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/public_markets/_gemini.py @@ -0,0 +1,39 @@ +import json +import urllib.error +import urllib.parse +import urllib.request + +from arbitrage.public_markets.market import Market + + +class Gemini(Market): + def __init__(self, currency, symbol): + super().__init__(currency) + self.symbol = symbol + self.update_rate = 30 + + def update_depth(self): + url = "https://api.gemini.com/v1/book/" + self.symbol + req = urllib.request.Request( + url, + headers={ + "Content-Type": "application/x-www-form-urlencoded", + "Accept": "*/*", + "User-Agent": "curl/7.24.0 (x86_64-apple-darwin12.0)", + }, + ) + res = urllib.request.urlopen(req) + depth = json.loads(res.read().decode("utf8")) + self.depth = self.format_depth(depth) + + def sort_and_format(self, l, reverse=False): + l.sort(key=lambda x: float(x["price"]), reverse=reverse) + r = [] + for i in l: + r.append({"price": float(i["price"]), "amount": float(i["amount"])}) + return r + + def format_depth(self, depth): + bids = self.sort_and_format(depth["bids"], True) + asks = self.sort_and_format(depth["asks"], False) + return {"asks": asks, "bids": bids} diff --git a/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/public_markets/_kraken.py b/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/public_markets/_kraken.py new file mode 100644 index 00000000..a19ceec2 --- /dev/null +++ b/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/public_markets/_kraken.py @@ -0,0 +1,40 @@ +import json +import urllib.error +import urllib.parse +import urllib.request + +from arbitrage.public_markets.market import Market + + +class Kraken(Market): + def __init__(self, currency, code): + super().__init__(currency) + self.code = code + self.update_rate = 30 + + def update_depth(self): + url = "https://api.kraken.com/0/public/Depth" + req = urllib.request.Request( + url, + b"pair=" + bytes(self.code, "ascii"), + headers={ + "Content-Type": "application/x-www-form-urlencoded", + "Accept": "*/*", + "User-Agent": "curl/7.24.0 (x86_64-apple-darwin12.0)", + }, + ) + res = urllib.request.urlopen(req) + depth = json.loads(res.read().decode("utf8")) + self.depth = self.format_depth(depth) + + def sort_and_format(self, l, reverse=False): + l.sort(key=lambda x: float(x[0]), reverse=reverse) + r = [] + for i in l: + r.append({"price": float(i[0]), "amount": float(i[1])}) + return r + + def format_depth(self, depth): + bids = self.sort_and_format(depth["result"][self.code]["bids"], True) + asks = self.sort_and_format(depth["result"][self.code]["asks"], False) + return {"asks": asks, "bids": bids} diff --git a/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/public_markets/_okcoin.py b/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/public_markets/_okcoin.py new file mode 100644 index 00000000..047efaf6 --- /dev/null +++ b/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/public_markets/_okcoin.py @@ -0,0 +1,39 @@ +import json +import urllib.error +import urllib.parse +import urllib.request + +from arbitrage.public_markets.market import Market + + +class OKCoin(Market): + def __init__(self, currency, code): + super().__init__(currency) + self.code = code + self.update_rate = 30 + + def update_depth(self): + url = "https://www.okcoin.cn/api/depth.do?symbol=" + self.code + req = urllib.request.Request( + url, + headers={ + "Content-Type": "application/x-www-form-urlencoded", + "Accept": "*/*", + "User-Agent": "curl/7.24.0 (x86_64-apple-darwin12.0)", + }, + ) + res = urllib.request.urlopen(req) + depth = json.loads(res.read().decode("utf8")) + self.depth = self.format_depth(depth) + + def sort_and_format(self, l, reverse=False): + l.sort(key=lambda x: float(x[0]), reverse=reverse) + r = [] + for i in l: + r.append({"price": float(i[0]), "amount": float(i[1])}) + return r + + def format_depth(self, depth): + bids = self.sort_and_format(depth["bids"], True) + asks = self.sort_and_format(depth["asks"], False) + return {"asks": asks, "bids": bids} diff --git a/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/public_markets/binanceusd.py b/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/public_markets/binanceusd.py new file mode 100644 index 00000000..8384178a --- /dev/null +++ b/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/public_markets/binanceusd.py @@ -0,0 +1,6 @@ +from arbitrage.public_markets._binance import Binance + + +class BinanceUSD(Binance): + def __init__(self): + super().__init__("USD", "BTCUSDT") diff --git a/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/public_markets/bitfinexeur.py b/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/public_markets/bitfinexeur.py new file mode 100644 index 00000000..8d08d1e3 --- /dev/null +++ b/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/public_markets/bitfinexeur.py @@ -0,0 +1,6 @@ +from arbitrage.public_markets._bitfinex import Bitfinex + + +class BitfinexEUR(Bitfinex): + def __init__(self): + super().__init__("EUR", "btceur") diff --git a/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/public_markets/bitfinexusd.py b/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/public_markets/bitfinexusd.py new file mode 100644 index 00000000..0da38a2c --- /dev/null +++ b/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/public_markets/bitfinexusd.py @@ -0,0 +1,6 @@ +from arbitrage.public_markets._bitfinex import Bitfinex + + +class BitfinexUSD(Bitfinex): + def __init__(self): + super().__init__("USD", "btcusd") diff --git a/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/public_markets/bitflyereur.py b/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/public_markets/bitflyereur.py new file mode 100644 index 00000000..bb453363 --- /dev/null +++ b/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/public_markets/bitflyereur.py @@ -0,0 +1,6 @@ +from arbitrage.public_markets._bitflyer import BitFlyer + + +class BitFlyerEUR(BitFlyer): + def __init__(self): + super().__init__("EUR", "BTC_EUR") diff --git a/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/public_markets/bitflyerusd.py b/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/public_markets/bitflyerusd.py new file mode 100644 index 00000000..60eae3f6 --- /dev/null +++ b/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/public_markets/bitflyerusd.py @@ -0,0 +1,6 @@ +from arbitrage.public_markets._bitflyer import BitFlyer + + +class BitFlyerUSD(BitFlyer): + def __init__(self): + super().__init__("USD", "BTC_USD") diff --git a/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/public_markets/bitstampeur.py b/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/public_markets/bitstampeur.py new file mode 100644 index 00000000..02e914f9 --- /dev/null +++ b/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/public_markets/bitstampeur.py @@ -0,0 +1,12 @@ +from arbitrage.public_markets._bitstamp import Bitstamp + + +class BitstampEUR(Bitstamp): + def __init__(self): + super().__init__("EUR", "btceur") + + +if __name__ == "__main__": + market = BitstampEUR() + market.update_depth() + print(market.get_ticker()) diff --git a/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/public_markets/bitstampusd.py b/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/public_markets/bitstampusd.py new file mode 100644 index 00000000..8ca27efa --- /dev/null +++ b/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/public_markets/bitstampusd.py @@ -0,0 +1,12 @@ +from arbitrage.public_markets._bitstamp import Bitstamp + + +class BitstampUSD(Bitstamp): + def __init__(self): + super().__init__("USD", "btcusd") + + +if __name__ == "__main__": + market = BitstampUSD() + market.update_depth() + print(market.get_ticker()) diff --git a/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/public_markets/btcccny.py b/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/public_markets/btcccny.py new file mode 100644 index 00000000..b99c25ae --- /dev/null +++ b/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/public_markets/btcccny.py @@ -0,0 +1,6 @@ +from arbitrage.public_markets._btcc import BTCC + + +class BTCCCNY(BTCC): + def __init__(self): + super().__init__("CNY", "btccny") diff --git a/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/public_markets/cexeur.py b/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/public_markets/cexeur.py new file mode 100644 index 00000000..1f3c281c --- /dev/null +++ b/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/public_markets/cexeur.py @@ -0,0 +1,6 @@ +from arbitrage.public_markets._cex import CEX + + +class CEXEUR(CEX): + def __init__(self): + super().__init__("EUR", "EUR") diff --git a/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/public_markets/cexusd.py b/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/public_markets/cexusd.py new file mode 100644 index 00000000..f803f04a --- /dev/null +++ b/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/public_markets/cexusd.py @@ -0,0 +1,6 @@ +from arbitrage.public_markets._cex import CEX + + +class CEXUSD(CEX): + def __init__(self): + super().__init__("USD", "USD") diff --git a/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/public_markets/gdaxeur.py b/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/public_markets/gdaxeur.py new file mode 100644 index 00000000..c6890bdf --- /dev/null +++ b/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/public_markets/gdaxeur.py @@ -0,0 +1,6 @@ +from arbitrage.public_markets._gdax import GDAX + + +class GDAXEUR(GDAX): + def __init__(self): + super().__init__("EUR", "BTC-EUR") diff --git a/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/public_markets/gdaxusd.py b/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/public_markets/gdaxusd.py new file mode 100644 index 00000000..3e0329b4 --- /dev/null +++ b/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/public_markets/gdaxusd.py @@ -0,0 +1,6 @@ +from arbitrage.public_markets._gdax import GDAX + + +class GDAXUSD(GDAX): + def __init__(self): + super().__init__("USD", "BTC-USD") diff --git a/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/public_markets/geminiusd.py b/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/public_markets/geminiusd.py new file mode 100644 index 00000000..2f300453 --- /dev/null +++ b/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/public_markets/geminiusd.py @@ -0,0 +1,6 @@ +from arbitrage.public_markets._gemini import Gemini + + +class GeminiUSD(Gemini): + def __init__(self): + super().__init__("USD", "btcusd") diff --git a/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/public_markets/krakeneur.py b/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/public_markets/krakeneur.py new file mode 100644 index 00000000..04138710 --- /dev/null +++ b/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/public_markets/krakeneur.py @@ -0,0 +1,6 @@ +from arbitrage.public_markets._kraken import Kraken + + +class KrakenEUR(Kraken): + def __init__(self): + super().__init__("EUR", "XXBTZEUR") diff --git a/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/public_markets/krakenusd.py b/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/public_markets/krakenusd.py new file mode 100644 index 00000000..a9a6b536 --- /dev/null +++ b/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/public_markets/krakenusd.py @@ -0,0 +1,6 @@ +from arbitrage.public_markets._kraken import Kraken + + +class KrakenUSD(Kraken): + def __init__(self): + super().__init__("USD", "XXBTZUSD") diff --git a/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/public_markets/market.py b/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/public_markets/market.py new file mode 100644 index 00000000..1d20c78b --- /dev/null +++ b/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/public_markets/market.py @@ -0,0 +1,68 @@ +import logging +import time +import urllib.error +import urllib.parse +import urllib.request + +from arbitrage import config +from arbitrage.fiatconverter import FiatConverter +from arbitrage.utils import log_exception + + +class Market(object): + def __init__(self, currency): + self.name = self.__class__.__name__ + self.currency = currency + self.depth_updated = 0 + self.update_rate = 60 + self.fc = FiatConverter() + self.fc.update() + + def get_depth(self): + timediff = time.time() - self.depth_updated + if timediff > self.update_rate: + self.ask_update_depth() + timediff = time.time() - self.depth_updated + if timediff > config.market_expiration_time: + logging.warn("Market: %s order book is expired" % self.name) + self.depth = { + "asks": [{"price": 0, "amount": 0}], + "bids": [{"price": 0, "amount": 0}], + } + return self.depth + + def convert_to_usd(self): + if self.currency == "USD": + return + for direction in ("asks", "bids"): + for order in self.depth[direction]: + order["price"] = self.fc.convert(order["price"], self.currency, "USD") + + def ask_update_depth(self): + try: + self.update_depth() + self.convert_to_usd() + self.depth_updated = time.time() + except (urllib.error.HTTPError, urllib.error.URLError) as e: + logging.error("HTTPError, can't update market: %s" % self.name) + log_exception(logging.DEBUG) + except Exception as e: + logging.error("Can't update market: %s - %s" % (self.name, str(e))) + log_exception(logging.DEBUG) + + def get_ticker(self): + depth = self.get_depth() + res = {"ask": 0, "bid": 0} + if len(depth["asks"]) > 0 and len(depth["bids"]) > 0: + res = {"ask": depth["asks"][0], "bid": depth["bids"][0]} + return res + + # Abstract methods + def update_depth(self): + pass + + def buy(self, price, amount): + pass + + def sell(self, price, amount): + pass diff --git a/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/public_markets/okcoincny.py b/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/public_markets/okcoincny.py new file mode 100644 index 00000000..8448cc96 --- /dev/null +++ b/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/public_markets/okcoincny.py @@ -0,0 +1,6 @@ +from arbitrage.public_markets._okcoin import OKCoin + + +class OKCoinCNY(OKCoin): + def __init__(self): + super().__init__("CNY", "btc_cny") diff --git a/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/public_markets/paymiumeur.py b/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/public_markets/paymiumeur.py new file mode 100644 index 00000000..bc3555e8 --- /dev/null +++ b/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/public_markets/paymiumeur.py @@ -0,0 +1,45 @@ +import json +import urllib.error +import urllib.parse +import urllib.request + +from arbitrage.public_markets.market import Market + + +class PaymiumEUR(Market): + def __init__(self): + super(PaymiumEUR, self).__init__("EUR") + # bitcoin central maximum call / day = 5000 + # keep 2500 for other operations + self.update_rate = 24 * 60 * 60 / 2500 + + def update_depth(self): + url = "https://paymium.com/api/data/eur/depth" + req = urllib.request.Request( + url, + headers={ + "Content-Type": "application/x-www-form-urlencoded", + "Accept": "*/*", + "User-Agent": "curl/7.24.0 (x86_64-apple-darwin12.0)", + }, + ) + res = urllib.request.urlopen(req) + depth = json.loads(res.read().decode("utf8")) + self.depth = self.format_depth(depth) + + def sort_and_format(self, l, reverse=False): + l.sort(key=lambda x: float(x["price"]), reverse=reverse) + r = [] + for i in l: + r.append({"price": float(i["price"]), "amount": float(i["amount"])}) + return r + + def format_depth(self, depth): + bids = self.sort_and_format(depth["bids"], True) + asks = self.sort_and_format(depth["asks"], False) + return {"asks": asks, "bids": bids} + + +if __name__ == "__main__": + market = PaymiumEUR() + print(market.get_ticker()) diff --git a/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/test/arbitrage_speed_test.py b/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/test/arbitrage_speed_test.py new file mode 100644 index 00000000..0cf2f735 --- /dev/null +++ b/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/test/arbitrage_speed_test.py @@ -0,0 +1,45 @@ +import sys + +sys.path.append("../") +import json +import time + +import arbitrage +from arbitrage.observers import observer + + +class TestObserver(observer.Observer): + def opportunity( + self, + profit, + volume, + buyprice, + kask, + sellprice, + kbid, + perc, + weighted_buyprice, + weighted_sellprice, + ): + print("Time: %.3f" % profit) + + +def main(): + arbitrer = arbitrage.Arbitrer() + depths = arbitrer.depths = json.load(open("speed-test.json")) + start_time = time.time() + testobs = TestObserver() + arbitrer.observers = [testobs] + arbitrer.arbitrage_opportunity( + "BitstampUSD", + depths["BitstampUSD"]["asks"][0], + "KrakenEUR", + depths["KrakenEUR"]["asks"][0], + ) + # FIXME: add asserts + elapsed = time.time() - start_time + print("Time: %.3f" % elapsed) + + +if __name__ == "__main__": + main() diff --git a/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/test/arbitrage_test.py b/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/test/arbitrage_test.py new file mode 100644 index 00000000..ef1330c3 --- /dev/null +++ b/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/test/arbitrage_test.py @@ -0,0 +1,109 @@ +import sys + +sys.path.append("../") +import unittest + +from arbitrage import arbitrer + +depths1 = { + "BitstampEUR": { + "asks": [ + {"amount": 4, "price": 32.8}, + {"amount": 8, "price": 32.9}, + {"amount": 2, "price": 33.0}, + {"amount": 3, "price": 33.6}, + ], + "bids": [ + {"amount": 2, "price": 31.8}, + {"amount": 4, "price": 31.6}, + {"amount": 6, "price": 31.4}, + {"amount": 2, "price": 30}, + ], + }, + "KrakenEUR": { + "asks": [ + {"amount": 1, "price": 34.2}, + {"amount": 2, "price": 34.3}, + {"amount": 3, "price": 34.5}, + {"amount": 3, "price": 35.0}, + ], + "bids": [ + {"amount": 2, "price": 33.2}, + {"amount": 3, "price": 33.1}, + {"amount": 5, "price": 32.6}, + {"amount": 10, "price": 32.3}, + ], + }, +} + +depths2 = { + "BitstampEUR": { + "asks": [ + {"amount": 4, "price": 32.8}, + {"amount": 8, "price": 32.9}, + {"amount": 2, "price": 33.0}, + {"amount": 3, "price": 33.6}, + ] + }, + "KrakenEUR": { + "bids": [ + {"amount": 2, "price": 33.2}, + {"amount": 3, "price": 33.1}, + {"amount": 5, "price": 32.6}, + {"amount": 10, "price": 32.3}, + ] + }, +} + +depths3 = { + "BitstampEUR": { + "asks": [ + {"amount": 1, "price": 34.2}, + {"amount": 2, "price": 34.3}, + {"amount": 3, "price": 34.5}, + {"amount": 3, "price": 35.0}, + ] + }, + "KrakenEUR": { + "bids": [ + {"amount": 2, "price": 33.2}, + {"amount": 3, "price": 33.1}, + {"amount": 5, "price": 32.6}, + {"amount": 10, "price": 32.3}, + ] + }, +} + + +class TestArbitrage(unittest.TestCase): + def setUp(self): + self.arbitrer = arbitrer.Arbitrer() + self.arbitrer.max_tx_volume = 10000 + + def test_getprofit1(self): + self.arbitrer.depths = depths2 + profit, vol, wb, ws = self.arbitrer.get_profit_for( + 0, 0, "BitstampEUR", "KrakenEUR" + ) + assert 80 == int(profit * 100) + assert vol == 2 + + def test_getprofit2(self): + self.arbitrer.depths = depths2 + profit, vol, wb, ws = self.arbitrer.get_profit_for( + 2, 1, "BitstampEUR", "KrakenEUR" + ) + assert 159 == int(profit * 100) + assert vol == 5 + + def test_getprofit3(self): + self.arbitrer.depths = depths3 + profit, vol, wb, ws = self.arbitrer.get_profit_for( + 2, 1, "BitstampEUR", "KrakenEUR" + ) + assert profit == 0 + assert vol == 0 + + +if __name__ == "__main__": + unittest.main() diff --git a/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/utils.py b/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/utils.py new file mode 100644 index 00000000..c8da6b1d --- /dev/null +++ b/qbot/engine/trade/trading/bitcoin-arbitrage/arbitrage/utils.py @@ -0,0 +1,12 @@ +import logging +import sys +import traceback + + +def log_exception(level): + exc_type, exc_value, exc_traceback = sys.exc_info() + for i in traceback.extract_tb(exc_traceback): + # line = (os.path.basename(i[0]), i[1], i[2]) + line = (i[0], i[1], i[2]) + logging.log(level, 'File "%s", line %d, in %s' % line) + logging.log(level, "\t%s" % i[3]) diff --git a/qbot/engine/trade/trading/bitcoin-arbitrage/docs/add-new-exchange.md b/qbot/engine/trade/trading/bitcoin-arbitrage/docs/add-new-exchange.md new file mode 100644 index 00000000..1a224ee2 --- /dev/null +++ b/qbot/engine/trade/trading/bitcoin-arbitrage/docs/add-new-exchange.md @@ -0,0 +1 @@ +# How To Add A New Exchange diff --git a/qbot/engine/trade/trading/bitcoin-arbitrage/requirements.txt b/qbot/engine/trade/trading/bitcoin-arbitrage/requirements.txt new file mode 100644 index 00000000..e69de29b diff --git a/qbot/engine/trade/trading/bitcoin-arbitrage/setup.cfg b/qbot/engine/trade/trading/bitcoin-arbitrage/setup.cfg new file mode 100644 index 00000000..27fe394d --- /dev/null +++ b/qbot/engine/trade/trading/bitcoin-arbitrage/setup.cfg @@ -0,0 +1,5 @@ +[bdist_wheel] +python-tag = py37 + +[metadata] +license_file = LICENSE diff --git a/qbot/engine/trade/trading/bitcoin-arbitrage/setup.py b/qbot/engine/trade/trading/bitcoin-arbitrage/setup.py new file mode 100644 index 00000000..9abf3261 --- /dev/null +++ b/qbot/engine/trade/trading/bitcoin-arbitrage/setup.py @@ -0,0 +1,22 @@ +#!/usr/bin/env python + +import sys + +from setuptools import setup + +if sys.version_info < (3,): + print("bitcoin-arbitrage requires Python version >= 3.0") + sys.exit(1) + +setup( + name="bitcoin-arbitrage", + packages=["arbitrage"], + version="0.1", + description="Bitcoin arbitrage opportunity watcher", + author="Maxime Biais", + author_email="maxime.biais@gmail.com", + url="https://github.com/maxme/bitcoin-arbitrage", + arbitrage=["bin/bitcoin-arbitrage"], + test_suite="nose.collector", + tests_require=["nose"], +) diff --git a/qbot/engine/trade/trading/bitcoin-arbitrage/tools/inplace-code-formatting.sh b/qbot/engine/trade/trading/bitcoin-arbitrage/tools/inplace-code-formatting.sh new file mode 100755 index 00000000..76767a76 --- /dev/null +++ b/qbot/engine/trade/trading/bitcoin-arbitrage/tools/inplace-code-formatting.sh @@ -0,0 +1,3 @@ +#!/bin/sh + +find . -name "*.py" -or -name "config.py-example" | xargs black --line-length 100 diff --git a/qbot/engine/trade/trading/emt_api/EMQuantAPI_Python.pdf b/qbot/engine/trade/trading/emt_api/EMQuantAPI_Python.pdf new file mode 100644 index 00000000..85701060 Binary files /dev/null and b/qbot/engine/trade/trading/emt_api/EMQuantAPI_Python.pdf differ diff --git a/qbot/engine/trade/trading/emt_api/EmQuantAPI.py b/qbot/engine/trade/trading/emt_api/EmQuantAPI.py new file mode 100644 index 00000000..ddaa87c0 --- /dev/null +++ b/qbot/engine/trade/trading/emt_api/EmQuantAPI.py @@ -0,0 +1,2309 @@ +# -*- coding:utf-8 -*- +__author__ = "weijie,zzx" + +""" +* EmQuantAPI for python +* version 2.5.4.0 +* c++ version 2.5.4.0 +* Copyright(c)2016-2022, EastMoney Information Co,. Ltd. All Rights Reserved. +""" + +import os as _os +import platform as _platform +import sys as _sys +from ctypes import * # noqa: F403 +from datetime import date as _date +from datetime import datetime as _datetime + +OS_Window = 1 +OS_Linux = 2 +OS_Mac = 3 + +OS_Bit32 = 1 +OS_Bit64 = 2 + +PY_Python2 = 1 +PY_Python3 = 2 + +PY_Bit32 = 1 +PY_Bit64 = 2 + +eVT_null = 0 +eVT_char = 1 +eVT_byte = 2 +eVT_bool = 3 +eVT_short = 4 +eVT_ushort = 5 +eVT_int = 6 +eVT_uInt = 7 +eVT_int64 = 8 +eVT_uInt64 = 9 +eVT_float = 10 +eVT_double = 11 +eVT_byteArray = 12 +eVT_asciiString = 13 +eVT_unicodeString = 14 + +ePT_NONE = 0 # 不使用代理 +ePT_HTTP = 1 # HTTP代理 +ePT_HTTPS = 2 # HTTPS代理 +ePT_SOCK4 = 3 # SOCK4代理 +ePT_SOCK5 = 4 # SOCK5代理 + +eOT_default = 0 # 默认(默认则根据传入数量的正负标志买入eOT_buy卖出eOT_Sell,其余类型对数量作正负转换) +eOT_buy = 1 # 买入 +eOT_sell = 2 # 卖出 +eOT_purchase = 3 # 申购 +eOT_redemption = 4 # 赎回 + +eCfnMode_StartToEnd = 1 # starttime和endtime中间的所有资讯 +eCfnMode_EndCount = 2 # 提取endtime的近count条数据 + + +class c_safe_union(Union): + _fields_ = [ + ("charValue", c_char), + ("boolValue", c_bool), + ("shortValue", c_short), + ("uShortValue", c_ushort), + ("intValue", c_int), + ("uIntValue", c_uint), + ("int64Value", c_longlong), + ("uInt64Value", c_ulonglong), + ("floatValue", c_float), + ("doubleValue", c_double), + ] + + +class stEQChar(Structure): + _fields_ = [("pChar", c_char_p), ("nSize", c_uint)] + + +class stEQCharArray(Structure): + _fields_ = [("pChArray", POINTER(stEQChar)), ("nSize", c_uint)] + + +class stEQVarient(Structure): + _fields_ = [("vtype", c_int), ("unionValues", c_safe_union), ("eqchar", stEQChar)] + + +class stEQVarientArray(Structure): + _fields_ = [("pEQVarient", POINTER(stEQVarient)), ("nSize", c_uint)] + + +class stEQData(Structure): + _fields_ = [ + ("codeArray", stEQCharArray), + ("indicatorArray", stEQCharArray), + ("dateArray", stEQCharArray), + ("valueArray", stEQVarientArray), + ] + + +class stEQLoginInfo(Structure): + _fields_ = [("userName", c_char * 255), ("password", c_char * 255)] + + +class stEQMessage(Structure): + _fields_ = [ + ("version", c_int), + ("msgType", c_int), + ("err", c_int), + ("requestID", c_int), + ("serialID", c_int), + ("pEQData", POINTER(stEQData)), + ] + + +class stEQCtrData(Structure): + _fields_ = [ + ("row", c_int), + ("column", c_int), + ("indicatorArray", stEQCharArray), + ("valueArray", stEQVarientArray), + ] + + +class stOrderInfo(Structure): + _pack_ = 8 + _fields_ = [ + ("code", c_char * 20), + ("volume", c_double), + ("price", c_float), + ("date", c_int), + ("time", c_int), + ("optype", c_int), + ("cost", c_float), + ("rate", c_float), + ("reserve", c_int), + ] + + +class Adapter: + def __init__(self): + self.__os_name = OS_Window + self.__os_bit = OS_Bit32 + self.__py_name = PY_Python2 + self.__py_bit = PY_Bit32 + + self.InitSysInfo() + + def InitSysInfo(self): + osname = _platform.system() + osbit = _platform.machine() + pyname = _platform.python_version() + pybit = _platform.architecture()[0] + + if osname == "Windows": + self.__os_name = OS_Window + elif osname == "Linux": + self.__os_name = OS_Linux + elif osname == "Darwin": + self.__os_name = OS_Mac + + self.__os_bit = OS_Bit32 + if ( + (self.__os_name == OS_Window and osbit == "AMD64") + or (self.__os_name == OS_Linux and osbit == "x86_64") + or (self.__os_name == OS_Mac and osbit == "x86_64") + ): + self.__os_bit = OS_Bit64 + + if pyname[0] == "2": + self.__py_name = PY_Python2 + elif pyname[0] == "3": + self.__py_name = PY_Python3 + + if pybit == "32bit": + self.__py_bit = PY_Bit32 + elif pybit == "64bit": + self.__py_bit = PY_Bit64 + + def get_os_name(self): + return self.__os_name + + def get_os_bit(self): + return self.__os_bit + + def get_py_name(self): + return self.__py_name + + def get_py_bit(self): + return self.__py_bit + + +class UtilAccess: + adapter = Adapter() + + @staticmethod + def GetLibraryPath(): + os_name = UtilAccess.adapter.get_os_name() + if os_name == OS_Window: + return UtilAccess.__getLibraryPath_window() + elif os_name == OS_Linux: + return UtilAccess.__getLibraryPath_linux() + elif os_name == OS_Mac: + return UtilAccess.__getLibraryPath_mac() + + @staticmethod + def GetEncodeType(): + if UtilAccess.adapter.get_os_name() == OS_Window: + return "gbk" + else: + return "utf-8" + + @staticmethod + def GetLanguageVersion(): + os_name = UtilAccess.adapter.get_os_name() + if os_name == OS_Window: + return "LANGUAGEVERSION=403" + elif os_name == OS_Linux: + return "LANGUAGEVERSION=503" + elif os_name == OS_Mac: + return "LANGUAGEVERSION=603" + + @staticmethod + def __getLibraryPath_window(): + apiPackagePath = "." + for x in _sys.path: + xx = x.find("site-packages") + if xx >= 0 and x[xx:] == "site-packages": + apiPackagePath = x + break + + apiPackagePath = _os.path.join(apiPackagePath, "EmQuantAPI.pth") + if not _os.path.exists(apiPackagePath): + return "" + pthFile = open(apiPackagePath, "r") + baseDir = pthFile.readline().strip() + pthFile.close() + + apiDllPath = "" + if baseDir != "": + libsDir = _os.path.join(baseDir, "libs", "windows") + if UtilAccess.adapter.get_py_bit() == PY_Bit32: + apiDllPath = _os.path.join(libsDir, "EmQuantAPI.dll") + else: + apiDllPath = _os.path.join(libsDir, "EmQuantAPI_x64.dll") + return apiDllPath + + @staticmethod + def __getLibraryPath_linux(): + baseDir = "" + + site_pkg_names = ["site-packages", "dist-packages"] + + for site_pkg_name in site_pkg_names: + if baseDir != "": + break + for spath in _sys.path: + pos = spath.find(site_pkg_name) + if pos >= 0 and spath[pos:] == site_pkg_name: + apiPackagePath = _os.path.join(spath, "EmQuantAPI.pth") + if not _os.path.exists(apiPackagePath): + continue + pthFile = open(apiPackagePath, "r") + baseDir = pthFile.readline().strip() + pthFile.close() + break + + apiDllPath = "" + if baseDir != "": + libsDir = _os.path.join(baseDir, "libs", "linux") + if UtilAccess.adapter.get_py_bit() == PY_Bit32: + apiDllPath = _os.path.join(libsDir, "x86", "libEMQuantAPI.so") + else: + apiDllPath = _os.path.join(libsDir, "x64", "libEMQuantAPIx64.so") + return apiDllPath + + @staticmethod + def __getLibraryPath_mac(): + baseDir = "" + site_pkg_name = "site-packages" + for x in _sys.path: + xi = x.find(site_pkg_name) + if xi >= 0 and x[xi:] == site_pkg_name: + apiPackagePath = x + apiPackagePath = _os.path.join(apiPackagePath, "EmQuantAPI.pth") + if not _os.path.exists(apiPackagePath): + continue + pthFile = open(apiPackagePath, "r") + baseDir = pthFile.readline().strip() + pthFile.close() + if len(baseDir) > 0: + break + apiDllPath = "" + if baseDir != "": + apiDllPath = _os.path.join(baseDir, "libs", "mac", "libEMQuantAPIx64.dylib") + return apiDllPath + + +def DemoCallback(quantdata): + """ + DemoCallback 是csq订阅时提供的回调函数模板。该函数只有一个为c.EmQuantData类型的参数quantdata + :param quantdata:cls.EmQuantData + :return: + """ + print("QuoteCallback,", str(quantdata)) + + +def chqDemoCallback(quantdata): + """ + chqDemoCallback 是chq订阅时提供的回调函数模板。该函数只有一个为c.EmQuantData类型的参数quantdata + :param quantdata:cls.EmQuantData + :return: + """ + print("chqQuoteCallback,", str(quantdata)) + + +def cstCallBack(quantdata): + """ + cstCallBack 是日内跳价服务提供的回调函数模板 + """ + for i in range(0, len(quantdata.Codes)): + length = len(quantdata.Dates) + for it in quantdata.Data.keys(): + print(it) + for k in range(0, length): + for j in range(0, len(quantdata.Indicators)): + print(quantdata.Data[it][j * length + k], " ", end="") + print() + + +def cnqdemoCallBack(quantdata): + """ + cnqdemoCallBack 是cnq订阅时提供的回调函数模板。该函数只有一个为c.EmQuantData类型的参数quantdata + :param quantdata:c.EmQuantData + :return: + """ + # print("InfoCallback,", str(quantdata)) + print("cnqCallback,") + for code in quantdata.Data: + total = len(quantdata.Data[code]) + for k in range(0, len(quantdata.Data[code])): + print(quantdata.Data[code][k]) + + +class c: + class EmQuantData: + def __init__(self, NullValue=None): + self.ErrorCode = 0 + self.ErrorMsg = "success" + self.Codes = list() + self.Indicators = list() + self.Dates = list() + self.RequestID = 0 + self.SerialID = 0 + self.Data = dict() + self.__NullValue = NullValue + + def __str__(self): + return "ErrorCode=%s, ErrorMsg=%s, Data=%s" % ( + self.ErrorCode, + self.ErrorMsg, + str(self.Data), + ) + + def __repr__(self): + return "ErrorCode=%s, ErrorMsg=%s, Data=%s" % ( + self.ErrorCode, + self.ErrorMsg, + str(self.Data), + ) + + def resolve2RankData(self, indicatorData, **arga): + for i in range(0, indicatorData.codeArray.nSize): + self.Codes.append( + indicatorData.codeArray.pChArray[i].pChar.decode(c.EncodeType) + ) + for k in range(0, indicatorData.indicatorArray.nSize): + self.Indicators.append( + indicatorData.indicatorArray.pChArray[k].pChar.decode(c.EncodeType) + ) + for j in range(0, indicatorData.dateArray.nSize): + self.Dates.append( + indicatorData.dateArray.pChArray[j].pChar.decode(c.EncodeType) + ) + + self.Data = [] + + for i in range(0, len(self.Codes)): + for j in range(0, len(self.Indicators)): + for k in range(0, len(self.Dates)): + self.Data.append( + self.getIndicatorDataByIndex(i, j, k, indicatorData) + ) + + def resolve25RankData(self, indicatorData, **arga): + for i in range(0, indicatorData.codeArray.nSize): + self.Codes.append( + indicatorData.codeArray.pChArray[i].pChar.decode(c.EncodeType) + ) + for k in range(0, indicatorData.indicatorArray.nSize): + self.Indicators.append( + indicatorData.indicatorArray.pChArray[k].pChar.decode(c.EncodeType) + ) + for j in range(0, indicatorData.dateArray.nSize): + self.Dates.append( + indicatorData.dateArray.pChArray[j].pChar.decode(c.EncodeType) + ) + for i in range(0, len(self.Codes)): + stockCode = self.Codes[i] + self.Data[stockCode] = [] + for j in range(0, len(self.Indicators)): + tempData = None + for k in range(0, len(self.Dates)): + tempData = self.getIndicatorDataByIndex(i, j, k, indicatorData) + self.Data[stockCode].append(tempData) + + def resolve25RankDataEx(self, indicatorData, **arga): + for i in range(0, indicatorData.codeArray.nSize): + self.Codes.append( + indicatorData.codeArray.pChArray[i].pChar.decode(c.EncodeType) + ) + for k in range(0, indicatorData.indicatorArray.nSize): + self.Indicators.append( + indicatorData.indicatorArray.pChArray[k].pChar.decode(c.EncodeType) + ) + for j in range(0, indicatorData.dateArray.nSize): + self.Dates.append( + indicatorData.dateArray.pChArray[j].pChar.decode(c.EncodeType) + ) + for i in range(0, len(self.Codes)): + stockCode = self.Codes[i] + if not (stockCode in self.Data.keys()): + self.Data[stockCode] = [] + thislist = [] + for j in range(0, len(self.Indicators)): + tempData = None + for k in range(0, len(self.Dates)): + tempData = self.getIndicatorDataByIndex(i, j, k, indicatorData) + thislist.append(tempData) + self.Data[stockCode].append(thislist) + + def resolve26RankData(self, indicatorData, **arga): + for i in range(0, indicatorData.codeArray.nSize): + self.Codes.append( + indicatorData.codeArray.pChArray[i].pChar.decode(c.EncodeType) + ) + for k in range(0, indicatorData.indicatorArray.nSize): + self.Indicators.append( + indicatorData.indicatorArray.pChArray[k].pChar.decode(c.EncodeType) + ) + for j in range(0, indicatorData.dateArray.nSize): + self.Dates.append( + indicatorData.dateArray.pChArray[j].pChar.decode(c.EncodeType) + ) + self.Data = [] + for i in range(0, len(self.Codes)): + for j in range(0, len(self.Indicators)): + tempData = [] + for k in range(0, len(self.Dates)): + tempData.append( + self.getIndicatorDataByIndex(i, j, k, indicatorData) + ) + self.Data.append(tempData) + + def resolve3RankData(self, indicatorData, **arga): + for i in range(0, indicatorData.codeArray.nSize): + self.Codes.append( + indicatorData.codeArray.pChArray[i].pChar.decode(c.EncodeType) + ) + for k in range(0, indicatorData.indicatorArray.nSize): + self.Indicators.append( + indicatorData.indicatorArray.pChArray[k].pChar.decode(c.EncodeType) + ) + for j in range(0, indicatorData.dateArray.nSize): + self.Dates.append( + indicatorData.dateArray.pChArray[j].pChar.decode(c.EncodeType) + ) + for i in range(0, len(self.Codes)): + stockCode = self.Codes[i] + self.Data[stockCode] = [] + for j in range(0, len(self.Indicators)): + tempData = [] + for k in range(0, len(self.Dates)): + tempData.append( + self.getIndicatorDataByIndex(i, j, k, indicatorData) + ) + self.Data[stockCode].append(tempData) + + def resolveCtrData(self, indicatorData, **arga): + for i in range(0, indicatorData.column): + self.Indicators.append( + indicatorData.indicatorArray.pChArray[i].pChar.decode(c.EncodeType) + ) + for r in range(0, indicatorData.row): + list1 = [] + for n in range(0, indicatorData.column): + list1.append( + self.resolve( + indicatorData.valueArray.pEQVarient[ + indicatorData.column * r + n + ] + ) + ) + self.Data[str(r)] = list1 + + def resolve(self, variant): + if variant.vtype == eVT_null: + return self.__NullValue + elif variant.vtype == eVT_char: + return variant.unionValues.charValue + elif variant.vtype == eVT_bool: + return variant.unionValues.boolValue + elif variant.vtype == eVT_short: + return variant.unionValues.shortValue + elif variant.vtype == eVT_ushort: + return variant.unionValues.uShortValue + elif variant.vtype == eVT_int: + return variant.unionValues.intValue + elif variant.vtype == eVT_uInt: + return variant.unionValues.uIntValue + elif variant.vtype == eVT_int64: + return variant.unionValues.int64Value + elif variant.vtype == eVT_uInt64: + return variant.unionValues.uInt64Value + elif variant.vtype == eVT_float: + return round(variant.unionValues.floatValue, 6) + elif variant.vtype == eVT_double: + return round(variant.unionValues.doubleValue, 6) + elif variant.vtype == eVT_asciiString: + if variant.eqchar.pChar is not None: + return variant.eqchar.pChar.decode(c.EncodeType) + else: + return "" + elif variant.vtype == eVT_unicodeString: + if variant.eqchar.pChar is not None: + return variant.eqchar.pChar.decode(c.EncodeType) + else: + return "" + return self.__NullValue + + def getIndicatorDataByIndex( + self, codeIndex, indicatorIndex, dateIndex, indicatorData + ): + if indicatorData.valueArray.nSize == 0: + return self.__NullValue + codeSize = indicatorData.codeArray.nSize + indicatorSize = indicatorData.indicatorArray.nSize + dateSize = indicatorData.dateArray.nSize + valueSize = indicatorData.valueArray.nSize + if valueSize != codeSize * dateSize * indicatorSize: + return self.__NullValue + if ( + codeIndex + <= codeSize * indicatorSize * dateIndex + + indicatorSize * codeIndex + + indicatorIndex + ): + tempIndex = ( + codeSize * indicatorSize * dateIndex + + indicatorSize * codeIndex + + indicatorIndex + ) + return self.resolve(indicatorData.valueArray.pEQVarient[tempIndex]) + + EncodeType = "" + Type_logOutFunc = CFUNCTYPE(c_int, c_char_p) + Type_AsynDataFunc = CFUNCTYPE(c_int, POINTER(stEQMessage), c_void_p) + + __InitSucceed = False + __apiDllPath = "" + __quantLib = None + __QuantFuncDict = {} + + __logOutFunc = None + __AsynDataFunc = None + __HandleAsynDataFuncDict = { + 0: {}, + 10000: {}, + 10001: {}, + 10002: {}, + 10003: {}, + } # 0:main 10000:csq 10001:cst 10002:cnq 10003:chq + + __setCsqSerialID = set() + __setChqSerialID = set() + + @classmethod + def __Init(cls): + if cls.__InitSucceed: + return + cls.EncodeType = UtilAccess.GetEncodeType() + cls.__InitSucceed = True + cls.__apiDllPath = UtilAccess.GetLibraryPath() + cls.__quantLib = CDLL(cls.__apiDllPath) + cls.__AsynDataFunc = cls.Type_AsynDataFunc(cls.__HandleAsynData) + + quantLib = cls.__quantLib + + quant_start = quantLib.start + quant_start.restype = c_int + quant_start.argtypes = [c_void_p, c_char_p, cls.Type_logOutFunc] + + quant_stop = quantLib.stop + quant_stop.restype = c_int + quant_stop.argtypes = [] + + quant_setcallback = quantLib.setcallback + quant_setcallback.restype = c_int + quant_setcallback.argtypes = [cls.Type_AsynDataFunc] + + quant_geterrstring = quantLib.geterrstring + quant_geterrstring.restype = c_char_p + quant_geterrstring.argtypes = [c_int, c_int] + + quant_csd = quantLib.csd + quant_csd.restype = c_int + quant_csd.argtypes = [ + c_char_p, + c_char_p, + c_char_p, + c_char_p, + c_char_p, + c_void_p, + ] + + quant_css = quantLib.css + quant_css.restype = c_int + quant_css.argtypes = [c_char_p, c_char_p, c_char_p, c_void_p] + + quant_cses = quantLib.cses + quant_cses.restype = c_int + quant_cses.argtypes = [c_char_p, c_char_p, c_char_p, c_void_p] + + quant_tradedates = quantLib.tradedates + quant_tradedates.restype = c_int + quant_tradedates.argtypes = [c_char_p, c_char_p, c_char_p, c_void_p] + + quant_sector = quantLib.sector + quant_sector.restype = c_int + quant_sector.argtypes = [c_char_p, c_char_p, c_char_p, c_void_p] + + quant_getdate = None + if UtilAccess.adapter.get_os_name() == OS_Window: + quant_getdate = quantLib.getdate + else: + quant_getdate = quantLib.gettradedate + quant_getdate.restype = c_int + quant_getdate.argtypes = [c_char_p, c_int, c_char_p, c_void_p] + + quant_csc = quantLib.csc + quant_csc.restype = c_int + quant_csc.argtypes = [ + c_char_p, + c_char_p, + c_char_p, + c_char_p, + c_char_p, + c_void_p, + ] + + quant_cmc = quantLib.cmc + quant_cmc.restype = c_int + quant_cmc.argtypes = [ + c_char_p, + c_char_p, + c_char_p, + c_char_p, + c_char_p, + c_void_p, + ] + + quant_chmc = quantLib.chmc + quant_chmc.restype = c_int + quant_chmc.argtypes = [ + c_char_p, + c_char_p, + c_char_p, + c_char_p, + c_char_p, + c_void_p, + ] + + quant_releasedata = quantLib.releasedata + quant_releasedata.restype = c_int + quant_releasedata.argtypes = [c_void_p] + + quant_csq = quantLib.csq + quant_csq.restype = c_int + quant_csq.argtypes = [ + c_char_p, + c_char_p, + c_char_p, + cls.Type_AsynDataFunc, + c_void_p, + c_void_p, + ] + + quant_csqcancel = quantLib.csqcancel + quant_csqcancel.restype = c_int + quant_csqcancel.argtypes = [c_int] + + quant_cst = quantLib.cst + quant_cst.restype = c_int + quant_cst.argtypes = [ + c_char_p, + c_char_p, + c_char_p, + c_char_p, + c_char_p, + cls.Type_AsynDataFunc, + c_void_p, + c_void_p, + ] + + quant_csqsnapshot = quantLib.csqsnapshot + quant_csqsnapshot.restype = c_int + quant_csqsnapshot.argtypes = [c_char_p, c_char_p, c_char_p, c_void_p] + + quant_chq = quantLib.chq + quant_chq.restype = c_int + quant_chq.argtypes = [ + c_char_p, + c_char_p, + c_char_p, + cls.Type_AsynDataFunc, + c_void_p, + c_void_p, + ] + + quant_chqcancel = quantLib.chqcancel + quant_chqcancel.restype = c_int + quant_chqcancel.argtypes = [c_int] + + quant_chqsnapshot = quantLib.chqsnapshot + quant_chqsnapshot.restype = c_int + quant_chqsnapshot.argtypes = [c_char_p, c_char_p, c_char_p, c_void_p] + + quant_ctr = quantLib.ctr + quant_ctr.restype = c_int + quant_ctr.argtypes = [c_char_p, c_char_p, c_char_p, c_void_p] + + quant_cfc = quantLib.cfc + quant_cfc.restype = c_int + quant_cfc.argtypes = [c_char_p, c_char_p, c_char_p, c_void_p] + + quant_cec = quantLib.cec + quant_cec.restype = c_int + quant_cec.argtypes = [c_char_p, c_char_p, c_void_p] + + quant_cps = quantLib.cps + quant_cps.restype = c_int + quant_cps.argtypes = [c_char_p, c_char_p, c_char_p, c_char_p, c_void_p] + + quant_setserverlistdir = quantLib.setserverlistdir + quant_setserverlistdir.restype = c_voidp + quant_setserverlistdir.argtypes = [c_char_p] + + quant_setproxy = quantLib.setproxy + quant_setproxy.restype = c_int + quant_setproxy.argtypes = [ + c_int, + c_char_p, + c_ushort, + c_bool, + c_char_p, + c_char_p, + ] + + quant_manualactivate = quantLib.manualactivate + quant_manualactivate.restype = c_int + quant_manualactivate.argtypes = [ + POINTER(stEQLoginInfo), + c_char_p, + cls.Type_logOutFunc, + ] + + quant_pquery = quantLib.pquery + quant_pquery.restype = c_int + quant_pquery.argtypes = [c_char_p, c_void_p] + + quant_porder = quantLib.porder + quant_porder.restype = c_int + quant_porder.argtypes = [ + POINTER(stOrderInfo), + c_int, + c_char_p, + c_char_p, + c_char_p, + ] + + quant_edb = quantLib.edb + quant_edb.restype = c_int + quant_edb.argtypes = [c_char_p, c_char_p, c_void_p] + + quant_edbquery = quantLib.edbquery + quant_edbquery.restype = c_int + quant_edbquery.argtypes = [c_char_p, c_char_p, c_char_p, c_void_p] + + quant_pcreate = quantLib.pcreate + quant_pcreate.restype = c_int + quant_pcreate.argtypes = [c_char_p, c_char_p, c_int64, c_char_p, c_char_p] + + quant_pdelete = quantLib.pdelete + quant_pdelete.restype = c_int + quant_pdelete.argtypes = [c_char_p, c_char_p] + + quant_preport = quantLib.preport + quant_preport.restype = c_int + quant_preport.argtypes = [c_char_p, c_char_p, c_char_p, c_void_p] + + quant_tradedatesnum = quantLib.tradedatesnum + quant_tradedatesnum.restype = c_int + quant_tradedatesnum.argtypes = [c_char_p, c_char_p, c_char_p, c_void_p] + + quant_cfn = quantLib.cfn + quant_cfn.restype = c_int + quant_cfn.argtypes = [c_char_p, c_char_p, c_int, c_char_p, c_void_p] + + quant_cfnquery = quantLib.cfnquery + quant_cfnquery.restype = c_int + quant_cfnquery.argtypes = [c_char_p, c_void_p] + + quant_cnq = quantLib.cnq + quant_cnq.restype = c_int + quant_cnq.argtypes = [ + c_char_p, + c_char_p, + c_char_p, + cls.Type_AsynDataFunc, + c_void_p, + c_void_p, + ] + + quant_cnqcancel = quantLib.cnqcancel + quant_cnqcancel.restype = c_int + quant_cnqcancel.argtypes = [c_int] + + quant_pctransfer = quantLib.pctransfer + quant_pctransfer.restype = c_int + quant_pctransfer.argtypes = [ + c_char_p, + c_char_p, + c_char_p, + c_double, + c_char_p, + c_char_p, + ] + + #################################### + + cls.__QuantFuncDict["start"] = quant_start + cls.__QuantFuncDict["stop"] = quant_stop + cls.__QuantFuncDict["setcallback"] = quant_setcallback + cls.__QuantFuncDict["geterrstring"] = quant_geterrstring + cls.__QuantFuncDict["csd"] = quant_csd + cls.__QuantFuncDict["css"] = quant_css + cls.__QuantFuncDict["cses"] = quant_cses + cls.__QuantFuncDict["tradedates"] = quant_tradedates + cls.__QuantFuncDict["sector"] = quant_sector + cls.__QuantFuncDict["getdate"] = quant_getdate + cls.__QuantFuncDict["csc"] = quant_csc + cls.__QuantFuncDict["cmc"] = quant_cmc + cls.__QuantFuncDict["chmc"] = quant_chmc + cls.__QuantFuncDict["releasedata"] = quant_releasedata + cls.__QuantFuncDict["csq"] = quant_csq + cls.__QuantFuncDict["csqcancel"] = quant_csqcancel + cls.__QuantFuncDict["cst"] = quant_cst + cls.__QuantFuncDict["csqsnapshot"] = quant_csqsnapshot + cls.__QuantFuncDict["chq"] = quant_chq + cls.__QuantFuncDict["chqcancel"] = quant_chqcancel + cls.__QuantFuncDict["chqsnapshot"] = quant_chqsnapshot + cls.__QuantFuncDict["ctr"] = quant_ctr + cls.__QuantFuncDict["cfc"] = quant_cfc + cls.__QuantFuncDict["cec"] = quant_cec + cls.__QuantFuncDict["cps"] = quant_cps + cls.__QuantFuncDict["setserverlistdir"] = quant_setserverlistdir + cls.__QuantFuncDict["setproxy"] = quant_setproxy + cls.__QuantFuncDict["manualactivate"] = quant_manualactivate + cls.__QuantFuncDict["pquery"] = quant_pquery + cls.__QuantFuncDict["porder"] = quant_porder + cls.__QuantFuncDict["edb"] = quant_edb + cls.__QuantFuncDict["edbquery"] = quant_edbquery + cls.__QuantFuncDict["pcreate"] = quant_pcreate + cls.__QuantFuncDict["pdelete"] = quant_pdelete + cls.__QuantFuncDict["preport"] = quant_preport + cls.__QuantFuncDict["tradedatesnum"] = quant_tradedatesnum + cls.__QuantFuncDict["cfn"] = quant_cfn + cls.__QuantFuncDict["cfnquery"] = quant_cfnquery + cls.__QuantFuncDict["cnq"] = quant_cnq + cls.__QuantFuncDict["cnqcancel"] = quant_cnqcancel + cls.__QuantFuncDict["pctransfer"] = quant_pctransfer + + @classmethod + def __Fun(cls, funcname): + return cls.__QuantFuncDict[funcname] + + @classmethod + def __Exec(cls, funcname, *args): + if not cls.__InitSucceed: + cls.__Init() + args = list(args) + for index in range(0, len(args)): + if type(args[index]) == str: + args[index] = args[index].encode(cls.EncodeType) + return cls.__Fun(funcname)(*args) + + @classmethod + def start(cls, options="", logcallback=None, mainCallBack=None): + """ + 初始化和登陆(开始时调用) options:附加参数 "TestLatency=1" + :param uname: 用户名 + :param password: 密码 + :param options:可选参数 + :param logcallback:启动结果提示回调函数 + :return EmQuantData: + """ + if not cls.__InitSucceed: + cls.__Init() + + if options.upper().find("LANGUAGEVERSION") == -1: + options = UtilAccess.GetLanguageVersion() + "," + options + data = cls.EmQuantData() + + cls.__HandleAsynDataFuncDict[0][0] = mainCallBack + if callable(logcallback): + cls.__logOutFunc = cls.Type_logOutFunc(logcallback) + else: + + def log(logMessage): + print("[EmQuantAPI Python]", logMessage.decode(cls.EncodeType)) + return 1 + + cls.__logOutFunc = cls.Type_logOutFunc(log) + + cls.__Exec("setserverlistdir", _os.path.dirname(cls.__apiDllPath)) + cls.__Exec("setcallback", cls.__AsynDataFunc) + loginResult = cls.__Exec("start", 0, options, cls.__logOutFunc) + + if loginResult != 0: + data.ErrorCode = loginResult + data.ErrorMsg = cls.geterrstring(data.ErrorCode) + + return data + + @classmethod + def stop(cls): + """ + 退出(结束时调用) + :return: 0-成功 + """ + data = cls.EmQuantData() + data.ErrorCode = cls.__Exec("stop") + data.ErrorMsg = cls.geterrstring(data.ErrorCode) + return data + + @classmethod + def geterrstring(cls, errcode, lang=1): + """ + 获取错误码文本说明 + :param errcode:错误代码 + :param lang:语言类型 0-中文 1-英文 + :return: + """ + return cls.__Exec("geterrstring", errcode, lang).decode(cls.EncodeType) + + @classmethod + def csd( + cls, codes, indicators, startdate=None, enddate=None, options="", *arga, **argb + ): + """ + 序列数据查询(同步请求) + :param codes: 东财代码 多个代码间用半角逗号隔开,支持大小写。如 "300059.SZ,000002.SZ,000003.SZ,000004.SZ" + :param indicators:东财指标 多个指标间用半角逗号隔开,支持大小写。如 "open,close,high" + :param startdate:开始日期。如无分隔符,则必须为8位数字。格式支持:YYYYMMDD YYYY/MM/DD YYYY/M/D YYYY-MM-DD YYYY-M-D + :param enddate:截止日期。如无分隔符,则必须为8位数字。格式支持:YYYYMMDD YYYY/MM/DD YYYY/M/D YYYY-MM-DD YYYY-M-D + :param options:附加参数 多个参数以半角逗号隔开,"Period=1,Market=CNSESH,Order=1,Adjustflag=1,Curtype=1,Pricetype=1,Type=1" + :return EmQuantData: + """ + codes = cls.__toString(codes) + indicators = cls.__toString(indicators) + result = cls.__PandasOptionFilter(options) + options = result[0] + + ShowBlank = cls.__ShowBlankOption(options) + data = cls.EmQuantData(ShowBlank) + + if enddate is None: + enddate = _datetime.today().strftime("%Y-%m-%d") + if startdate is None: + startdate = enddate + if isinstance(startdate, _datetime) or isinstance(startdate, _date): + startdate = startdate.strftime("%Y-%m-%d") + if isinstance(enddate, _datetime) or isinstance(enddate, _date): + enddate = enddate.strftime("%Y-%m-%d") + eqData = stEQData() + refEqData = byref(pointer(eqData)) + coutResult = cls.__Exec( + "csd", codes, indicators, startdate, enddate, options, refEqData + ) + if coutResult != 0: + data.ErrorCode = coutResult + data.ErrorMsg = cls.geterrstring(data.ErrorCode) + return data + tempData = refEqData._obj.contents + if not isinstance(tempData, stEQData): + data.ErrorCode = coutResult + data.ErrorMsg = cls.geterrstring(data.ErrorCode) + else: + data.resolve3RankData(tempData) + cls.__Exec("releasedata", pointer(tempData)) + return cls.__tryResolvePandas(data, result[1]) + + @classmethod + def css(cls, codes, indicators, options="", *arga, **argb): + """ + 截面数据查询(同步请求) + :param codes:东财代码 多个代码间用半角逗号隔开,支持大小写。如 "300059.SZ,000002.SZ,000003.SZ,000004.SZ" + :param indicators:东财指标 多个指标间用半角逗号隔开,支持大小写。如 "open,close,high" + :param options:附加参数 多个参数以半角逗号隔开,"Period=1,Market=CNSESH,Order=1,Adjustflag=1,Curtype=1,Pricetype=1,Type=1" + :return EmQuantData: + """ + codes = cls.__toString(codes) + indicators = cls.__toString(indicators) + result = cls.__PandasOptionFilter(options) + options = result[0] + ShowBlank = cls.__ShowBlankOption(options) + + data = cls.EmQuantData(ShowBlank) + eqData = stEQData() + refEqData = byref(pointer(eqData)) + coutResult = cls.__Exec("css", codes, indicators, options, refEqData) + if coutResult != 0: + data.ErrorCode = coutResult + data.ErrorMsg = cls.geterrstring(data.ErrorCode) + return data + tempData = refEqData._obj.contents + if not isinstance(tempData, stEQData): + data.ErrorCode = coutResult + data.ErrorMsg = cls.geterrstring(data.ErrorCode) + else: + data.resolve25RankData(tempData) + cls.__Exec("releasedata", pointer(tempData)) + return cls.__tryResolvePandas(data, result[1]) + + @classmethod + def cses(cls, blockcodes, indicators, options="", *arga, **argb): + """ + 板块截面数据查询(同步请求) + :param blockcodes:板块代码 多个代码间用半角逗号隔开。 + :param indicators:板块指标 多个指标间用半角逗号隔开,支持大小写。 + :param options:附加参数 多个参数以半角逗号隔开。 + :return:EmQuantData + """ + blockcodes = cls.__toString(blockcodes) + indicators = cls.__toString(indicators) + result = cls.__PandasOptionFilter(options) + options = result[0] + ShowBlank = cls.__ShowBlankOption(options) + + data = cls.EmQuantData(ShowBlank) + eqData = stEQData() + refEqData = byref(pointer(eqData)) + coutResult = cls.__Exec("cses", blockcodes, indicators, options, refEqData) + if coutResult != 0: + data.ErrorCode = coutResult + data.ErrorMsg = cls.geterrstring(data.ErrorCode) + return data + tempData = refEqData._obj.contents + if not isinstance(tempData, stEQData): + data.ErrorCode = coutResult + data.ErrorMsg = cls.geterrstring(data.ErrorCode) + else: + data.resolve25RankData(tempData) + cls.__Exec("releasedata", pointer(tempData)) + return cls.__tryResolvePandas(data, result[1]) + + @classmethod + def tradedates(cls, startdate=None, enddate=None, options=None, *arga, **argb): + """ + 获取区间日期内的交易日(同步请求) + :param startdate:开始日期。如无分隔符,则必须为8位数字。格式支持:YYYYMMDD YYYY/MM/DD YYYY/M/D YYYY-MM-DD YYYY-M-D + :param enddate:截止日期。如无分隔符,则必须为8位数字。格式支持:YYYYMMDD YYYY/MM/DD YYYY/M/D YYYY-MM-DD YYYY-M-D + :param options:附加参数 多个参数以半角逗号隔开,"Period=1,Market=CNSESH,Order=1,Adjustflag=1,Curtype=1,Pricetype=1,Type=1" + :return EmQuantData: + """ + + if options is None: + options = "" + data = cls.EmQuantData() + + if enddate is None: + enddate = _datetime.today().strftime("%Y-%m-%d") + if startdate is None: + startdate = enddate + if isinstance(startdate, _datetime) or isinstance(startdate, _date): + startdate = startdate.strftime("%Y-%m-%d") + if isinstance(enddate, _datetime) or isinstance(enddate, _date): + enddate = enddate.strftime("%Y-%m-%d") + eqData = stEQData() + refEqData = byref(pointer(eqData)) + coutResult = cls.__Exec("tradedates", startdate, enddate, options, refEqData) + if coutResult != 0: + data.ErrorCode = coutResult + data.ErrorMsg = cls.geterrstring(data.ErrorCode) + return data + tempData = refEqData._obj.contents + if not isinstance(tempData, stEQData): + data.ErrorCode = coutResult + data.ErrorMsg = cls.geterrstring(data.ErrorCode) + else: + data.resolve2RankData(tempData) + cls.__Exec("releasedata", pointer(tempData)) + return data + + @classmethod + def sector(cls, pukeycode, tradedate, options="", *arga, **argb): + """ + 获取系统板块成分(同步请求) + :param pukeycode: + :param tradedate:交易日 + :param options:附加参数 多个参数以半角逗号隔开,"Period=1,Market=CNSESH,Order=1,Adjustflag=1,Curtype=1,Pricetype=1,Type=1" + :param arga: + :param argb: + :return EmQuantData: + """ + + result = cls.__PandasOptionFilter(options) + options = result[0] + data = cls.EmQuantData() + + if tradedate is None: + tradedate = _datetime.today().strftime("%Y-%m-%d") + if isinstance(tradedate, _datetime) or isinstance(tradedate, _date): + tradedate = tradedate.strftime("%Y-%m-%d") + eqData = stEQData() + refEqData = byref(pointer(eqData)) + coutResult = cls.__Exec("sector", pukeycode, tradedate, options, refEqData) + if coutResult != 0: + data.ErrorCode = coutResult + data.ErrorMsg = cls.geterrstring(data.ErrorCode) + return data + tempData = refEqData._obj.contents + if not isinstance(tempData, stEQData): + data.ErrorCode = coutResult + data.ErrorMsg = cls.geterrstring(data.ErrorCode) + else: + data.resolve2RankData(tempData) + cls.__Exec("releasedata", pointer(tempData)) + return cls.__tryResolvePandas(data, result[1]) + + @classmethod + def getdate(cls, tradedate, offday=0, options="", *arga, **argb): + """ + 获取偏移N的交易日(同步请求) + :param tradedate:交易日期 + :param offday:偏移天数 + :param options: + :param arga: + :param argb: + :return EmQuantData: + """ + data = cls.EmQuantData() + if tradedate is None: + tradedate = _datetime.today().strftime("%Y-%m-%d") + if isinstance(tradedate, _datetime) or isinstance(tradedate, _date): + tradedate = tradedate.strftime("%Y-%m-%d") + eqData = stEQData() + refEqData = byref(pointer(eqData)) + coutResult = cls.__Exec("getdate", tradedate, offday, options, refEqData) + if coutResult != 0: + data.ErrorCode = coutResult + data.ErrorMsg = cls.geterrstring(data.ErrorCode) + return data + tempData = refEqData._obj.contents + if not isinstance(tempData, stEQData): + data.ErrorCode = coutResult + data.ErrorMsg = cls.geterrstring(data.ErrorCode) + else: + data.resolve2RankData(tempData) + cls.__Exec("releasedata", pointer(tempData)) + return data + + @classmethod + def csc( + cls, code, indicators, startdate=None, enddate=None, options="", *arga, **argb + ): + """ + 历史分钟K线(同步请求) //code只支持单个股票 + :param code: 东财代码 多个代码间用半角逗号隔开,支持大小写。如 "300059.SZ" + :param indicators:东财指标 多个指标间用半角逗号隔开,支持大小写。如 "open,close,high" + :param startdate:开始日期。日期格式或日期时间14位数字年月日时分秒格式 + :param enddate:截止日期。日期格式或日期时间14位数字年月日时分秒格式 + :param options:附加参数 多个参数以半角逗号隔开,"Period=1,Market=CNSESH,Order=1,Adjustflag=1,Curtype=1,Pricetype=1,Type=1" + :return EmQuantData: + """ + code = cls.__toString(code) + indicators = cls.__toString(indicators) + result = cls.__PandasOptionFilter(options) + options = result[0] + data = cls.EmQuantData() + + if enddate is None: + enddate = _datetime.today().strftime("%Y-%m-%d") + if startdate is None: + startdate = enddate + if isinstance(startdate, _datetime) or isinstance(startdate, _date): + startdate = startdate.strftime("%Y-%m-%d") + if isinstance(enddate, _datetime) or isinstance(enddate, _date): + enddate = enddate.strftime("%Y-%m-%d") + eqData = stEQData() + refEqData = byref(pointer(eqData)) + coutResult = cls.__Exec( + "csc", code, indicators, startdate, enddate, options, refEqData + ) + if coutResult != 0: + data.ErrorCode = coutResult + data.ErrorMsg = cls.geterrstring(data.ErrorCode) + return data + tempData = refEqData._obj.contents + if not isinstance(tempData, stEQData): + data.ErrorCode = coutResult + data.ErrorMsg = cls.geterrstring(data.ErrorCode) + else: + data.resolve26RankData(tempData) + cls.__Exec("releasedata", pointer(tempData)) + return cls.__tryResolvePandas(data, result[1]) + + @classmethod + def cmc( + cls, code, indicators, startdate=None, enddate=None, options="", *arga, **argb + ): + """ + 历史分钟K线(同步请求) //code只支持单个股票 + :param code: 东财代码 多个代码间用半角逗号隔开,支持大小写。如 "300059.SZ" + :param indicators:东财指标 多个指标间用半角逗号隔开,支持大小写。如 "open,close,high" + :param startdate:开始日期。日期格式或日期时间14位数字年月日时分秒格式 + :param enddate:截止日期。日期格式或日期时间14位数字年月日时分秒格式 + :param options:附加参数 多个参数以半角逗号隔开,"Period=1,Market=CNSESH,Order=1,Adjustflag=1,Curtype=1,Pricetype=1,Type=1" + :return EmQuantData: + """ + code = cls.__toString(code) + indicators = cls.__toString(indicators) + result = cls.__PandasOptionFilter(options) + options = result[0] + data = cls.EmQuantData() + + if enddate is None: + enddate = _datetime.today().strftime("%Y-%m-%d") + if startdate is None: + startdate = enddate + if isinstance(startdate, _datetime) or isinstance(startdate, _date): + startdate = startdate.strftime("%Y-%m-%d") + if isinstance(enddate, _datetime) or isinstance(enddate, _date): + enddate = enddate.strftime("%Y-%m-%d") + eqData = stEQData() + refEqData = byref(pointer(eqData)) + coutResult = cls.__Exec( + "cmc", code, indicators, startdate, enddate, options, refEqData + ) + if coutResult != 0: + data.ErrorCode = coutResult + data.ErrorMsg = cls.geterrstring(data.ErrorCode) + return data + tempData = refEqData._obj.contents + if not isinstance(tempData, stEQData): + data.ErrorCode = coutResult + data.ErrorMsg = cls.geterrstring(data.ErrorCode) + else: + data.resolve26RankData(tempData) + cls.__Exec("releasedata", pointer(tempData)) + return cls.__tryResolvePandas(data, result[1]) + + @classmethod + def chmc( + cls, code, indicators, startdate=None, enddate=None, options="", *arga, **argb + ): + """ + 历史分钟K线(同步请求) //code只支持单个股票 + :param code: 东财代码 多个代码间用半角逗号隔开,支持大小写。如 "300059.SZ" + :param indicators:东财指标 多个指标间用半角逗号隔开,支持大小写。如 "open,close,high" + :param startdate:开始日期。日期格式或日期时间14位数字年月日时分秒格式 + :param enddate:截止日期。日期格式或日期时间14位数字年月日时分秒格式 + :param options:附加参数 多个参数以半角逗号隔开,"Period=1,Market=CNSESH,Order=1,Adjustflag=1,Curtype=1,Pricetype=1,Type=1" + :return EmQuantData: + """ + code = cls.__toString(code) + indicators = cls.__toString(indicators) + result = cls.__PandasOptionFilter(options) + options = result[0] + data = cls.EmQuantData() + + if enddate is None: + enddate = _datetime.today().strftime("%Y-%m-%d") + if startdate is None: + startdate = enddate + if isinstance(startdate, _datetime) or isinstance(startdate, _date): + startdate = startdate.strftime("%Y-%m-%d") + if isinstance(enddate, _datetime) or isinstance(enddate, _date): + enddate = enddate.strftime("%Y-%m-%d") + eqData = stEQData() + refEqData = byref(pointer(eqData)) + coutResult = cls.__Exec( + "chmc", code, indicators, startdate, enddate, options, refEqData + ) + if coutResult != 0: + data.ErrorCode = coutResult + data.ErrorMsg = cls.geterrstring(data.ErrorCode) + return data + tempData = refEqData._obj.contents + if not isinstance(tempData, stEQData): + data.ErrorCode = coutResult + data.ErrorMsg = cls.geterrstring(data.ErrorCode) + else: + data.resolve26RankData(tempData) + cls.__Exec("releasedata", pointer(tempData)) + return cls.__tryResolvePandas(data, result[1]) + + @classmethod + def csq( + cls, + codes, + indicators, + options="", + fncallback=None, + userparams=None, + *arga, + **argb + ): + """ + 实时行情(异步) 每次indicators最多为64个 + :param codes:东财代码 多个代码间用半角逗号隔开,支持大小写。如 "300059.SZ,000002.SZ,000003.SZ,000004.SZ" + :param indicators:东财指标 多个指标间用半角逗号隔开,支持大小写。如 "open,close,high" + :param options:Pushtype=0 增量推送 1全量推送 2增量模式2(证券增量,指标全量) + :param fncallback:不同的接口可以设定不同的回调,传NULL则使用默认的主回调函数 + :param userparams:用户参数,回调时原样返回 + :param arga: + :param argb: + :return EmQuantData: + """ + codes = cls.__toString(codes) + indicators = cls.__toString(indicators) + data = cls.EmQuantData() + + cbfunc = None + if not callable(fncallback): + cbfunc = DemoCallback + else: + cbfunc = fncallback + cls.__HandleAsynDataFuncDict[10000][0] = cbfunc + ErrorCode = c_int(0) + data.SerialID = cls.__Exec( + "csq", + codes, + indicators, + options, + cls.__AsynDataFunc, + userparams, + byref(ErrorCode), + ) + data.ErrorCode = ErrorCode.value + data.ErrorMsg = cls.geterrstring(data.ErrorCode) + cls.__HandleAsynDataFuncDict[10000][data.SerialID] = cbfunc + if options.replace(" ", "").upper().find("ALLTICK=1") >= 0: + cls.__setCsqSerialID.add(data.SerialID) + return data + + @classmethod + def csqcancel(cls, serialID): + """ + 取消实时行情订阅 + :param serialID: + :return EmQuantData: + """ + data = cls.EmQuantData() + data.ErrorCode = cls.__Exec("csqcancel", serialID) + data.ErrorMsg = cls.geterrstring(data.ErrorCode) + cls.__setCsqSerialID.discard(serialID) + return data + + @classmethod + def cst( + cls, + codes, + indicators, + startdatetime, + enddatetime, + options="", + fncallback=None, + userparams=None, + ): + """ + 日内跳价服务(异步) startdatetime和enddatetime格式(YYYYMMDDHHMMSS或HHMMSS表示系统日期当天的时间,两者需使用同一种格式) + :param codes:东财代码 多个代码间用半角逗号隔开,支持大小写。如 "300059.SZ,000002.SZ,000003.SZ,000004.SZ" + :param indicators:东财指标 多个指标间用半角逗号隔开,支持大小写。如 "open,close,high" + :param startdate:开始时间 + :param enddate:结束时间 + :param options: + :param fncallback:不同的接口可以设定不同的回调,传NULL则使用默认的主回调函数 + :param userparams:用户参数,回调时原样返回 + :param arga: + :param argb: + :return EmQuantData: + """ + codes = cls.__toString(codes) + indicators = cls.__toString(indicators) + data = cls.EmQuantData() + + cbfunc = None + if not callable(fncallback): + cbfunc = cstCallBack + else: + cbfunc = fncallback + cls.__HandleAsynDataFuncDict[10001][0] = cbfunc + ErrorCode = c_int(0) + data.SerialID = cls.__Exec( + "cst", + codes, + indicators, + startdatetime, + enddatetime, + options, + cls.__AsynDataFunc, + userparams, + byref(ErrorCode), + ) + data.ErrorCode = ErrorCode.value + data.ErrorMsg = cls.geterrstring(data.ErrorCode) + cls.__HandleAsynDataFuncDict[10001][data.SerialID] = cbfunc + return data + + @classmethod + def csqsnapshot(cls, codes, indicators, options=""): + """ + 行情快照(同步请求) 每次indicators最多为64个 + :param codes:东财代码 多个代码间用半角逗号隔开,支持大小写。如 "300059.SZ,000002.SZ,000003.SZ,000004.SZ" + :param indicators:东财指标 多个指标间用半角逗号隔开,支持大小写。如 "open,close,high" + :param options:附加参数 多个参数以半角逗号隔开 + """ + codes = cls.__toString(codes) + indicators = cls.__toString(indicators) + result = cls.__PandasOptionFilter(options) + options = result[0] + + data = cls.EmQuantData() + eqData = stEQData() + refEqData = byref(pointer(eqData)) + coutResult = cls.__Exec("csqsnapshot", codes, indicators, options, refEqData) + if coutResult != 0: + data.ErrorCode = coutResult + data.ErrorMsg = cls.geterrstring(data.ErrorCode) + return data + tempData = refEqData._obj.contents + if not isinstance(tempData, stEQData): + data.ErrorCode = coutResult + data.ErrorMsg = cls.geterrstring(data.ErrorCode) + else: + data.resolve25RankData(tempData) + cls.__Exec("releasedata", pointer(tempData)) + return cls.__tryResolvePandas(data, result[1]) + + @classmethod + def chq( + cls, + codes, + indicators, + options="", + fncallback=None, + userparams=None, + *arga, + **argb + ): + """ + 专项服务订阅(异步) 每次indicators最多为64个 + :param codes:东财代码 多个代码间用半角逗号隔开,支持大小写。如 "515030.SH,512170.SH,515050.SH" + :param indicators:东财指标 多个指标间用半角逗号隔开,支持大小写。如 "TIME,PDNUM,PAMT" + :param options:Pushtype=0 增量推送 1全量推送 2增量模式2(证券增量,指标全量) + :param fncallback:不同的接口可以设定不同的回调,传NULL则使用默认的主回调函数 + :param userparams:用户参数,回调时原样返回 + :param arga: + :param argb: + :return EmQuantData: + """ + codes = cls.__toString(codes) + indicators = cls.__toString(indicators) + data = cls.EmQuantData() + + cbfunc = None + if not callable(fncallback): + cbfunc = chqDemoCallback + else: + cbfunc = fncallback + cls.__HandleAsynDataFuncDict[10003][0] = cbfunc + ErrorCode = c_int(0) + data.SerialID = cls.__Exec( + "chq", + codes, + indicators, + options, + cls.__AsynDataFunc, + userparams, + byref(ErrorCode), + ) + data.ErrorCode = ErrorCode.value + data.ErrorMsg = cls.geterrstring(data.ErrorCode) + cls.__HandleAsynDataFuncDict[10003][data.SerialID] = cbfunc + if options.replace(" ", "").upper().find("ALLTICK=1") >= 0: + cls.__setChqSerialID.add(data.SerialID) + return data + + @classmethod + def chqcancel(cls, serialID): + """ + 取消专项服务订阅 + :param serialID: + :return EmQuantData: + """ + data = cls.EmQuantData() + data.ErrorCode = cls.__Exec("chqcancel", serialID) + data.ErrorMsg = cls.geterrstring(data.ErrorCode) + cls.__setChqSerialID.discard(serialID) + return data + + @classmethod + def chqsnapshot(cls, codes, indicators, options=""): + """ + 专项服务快照(同步请求) 每次indicators最多为64个 + :param codes:东财代码 多个代码间用半角逗号隔开,支持大小写。如 "515030.SH,512170.SH,515050.SH" + :param indicators:东财指标 多个指标间用半角逗号隔开,支持大小写。如 "TIME,PDNUM,PAMT" + :param options:附加参数 多个参数以半角逗号隔开 + """ + codes = cls.__toString(codes) + indicators = cls.__toString(indicators) + result = cls.__PandasOptionFilter(options) + options = result[0] + + data = cls.EmQuantData() + eqData = stEQData() + refEqData = byref(pointer(eqData)) + coutResult = cls.__Exec("chqsnapshot", codes, indicators, options, refEqData) + if coutResult != 0: + data.ErrorCode = coutResult + data.ErrorMsg = cls.geterrstring(data.ErrorCode) + return data + tempData = refEqData._obj.contents + if not isinstance(tempData, stEQData): + data.ErrorCode = coutResult + data.ErrorMsg = cls.geterrstring(data.ErrorCode) + else: + data.resolve25RankData(tempData) + cls.__Exec("releasedata", pointer(tempData)) + return cls.__tryResolvePandas(data, result[1]) + + @classmethod + def ctr(cls, ctrName, indicators="", options=""): + """ + 获取专题报表(同步请求) + :param ctrName: 报表名称 + :param indicator: 指标简称 多个参数以半角逗号隔开 + :param options:附加参数 多个参数以半角逗号隔开 + """ + indicators = cls.__toString(indicators) + data = cls.EmQuantData() + + eqData = stEQCtrData() + refEqData = byref(pointer(eqData)) + coutResult = cls.__Exec("ctr", ctrName, indicators, options, refEqData) + if coutResult != 0: + data.ErrorCode = coutResult + data.ErrorMsg = cls.geterrstring(data.ErrorCode) + return data + tempData = refEqData._obj.contents + if not isinstance(tempData, stEQCtrData): + data.ErrorCode = coutResult + data.ErrorMsg = cls.geterrstring(data.ErrorCode) + else: + data.resolveCtrData(tempData) + cls.__Exec("releasedata", pointer(tempData)) + pos = options.upper().find("ISPANDAS=1") + if pos > 0 and data.ErrorCode == 0: + import pandas as pd + + table = pd.DataFrame(data.Data, index=data.Indicators) + table = table.T + return table + else: + return data + + @classmethod + def cfc(cls, codes, indicators, options): + """ + 证券与指标校验函数,获取相匹配的csd/css/cses的证券和指标请求参数,并按证券品种区分 + :param codes: 证券代码 + :param indicators:指标简称 + :param options:附加参数 多个参数以半角逗号隔开,必须传入FunType=CSD 或CSS 或 CSES之一 + """ + codes = cls.__toString(codes) + indicators = cls.__toString(indicators) + data = cls.EmQuantData() + + eqData = stEQCtrData() + refEqData = byref(pointer(eqData)) + coutResult = cls.__Exec("cfc", codes, indicators, options, refEqData) + if coutResult != 0: + data.ErrorCode = coutResult + data.ErrorMsg = cls.geterrstring(data.ErrorCode) + return data + tempData = refEqData._obj.contents + if not isinstance(tempData, stEQCtrData): + data.ErrorCode = coutResult + data.ErrorMsg = cls.geterrstring(data.ErrorCode) + else: + data.resolveCtrData(tempData) + cls.__Exec("releasedata", pointer(tempData)) + return data + + @classmethod + def cec(cls, codes, options=""): + """ + 校验或补全东财证券代码函数 + :param codes: 证券代码 + :param options:附加参数 多个参数以半角逗号隔开 ReturnType=0/1 0:返回并标记代码是否正确 1:根据SecuType与SecuMarket补全代码后缀(有可能返回多个不同的后缀) + """ + codes = cls.__toString(codes) + data = cls.EmQuantData() + + eqData = stEQCtrData() + refEqData = byref(pointer(eqData)) + coutResult = cls.__Exec("cec", codes, options, refEqData) + if coutResult != 0: + data.ErrorCode = coutResult + data.ErrorMsg = cls.geterrstring(data.ErrorCode) + return data + tempData = refEqData._obj.contents + if not isinstance(tempData, stEQCtrData): + data.ErrorCode = coutResult + data.ErrorMsg = cls.geterrstring(data.ErrorCode) + else: + data.resolveCtrData(tempData) + cls.__Exec("releasedata", pointer(tempData)) + return data + + @classmethod + def cps(cls, cpsCodes, cpsIndicators, cpsConditions, cpsOptions=""): + """ + 条件选股函数 + :param cpsCodes 代码 + :param cpsIndicators 指标 + :param cpsConditions 条件 + :param cpsOptions 附加参数 + """ + cpsCodes = cls.__toString(cpsCodes) + cpsIndicators = cls.__toString(cpsIndicators) + cpsConditions = cls.__toString(cpsConditions) + + data = cls.EmQuantData() + + eqData = stEQData() + refEqData = byref(pointer(eqData)) + coutResult = cls.__Exec( + "cps", cpsCodes, cpsIndicators, cpsConditions, cpsOptions, refEqData + ) + if coutResult != 0: + data.ErrorCode = coutResult + data.ErrorMsg = cls.geterrstring(data.ErrorCode) + return data + tempData = refEqData._obj.contents + if not isinstance(tempData, stEQData): + data.ErrorCode = coutResult + data.ErrorMsg = cls.geterrstring(data.ErrorCode) + else: + data.resolve2RankData(tempData) + cls.__Exec("releasedata", pointer(tempData)) + return data + + @classmethod + def setserverlistdir(cls, serlistpath): + """ + 设置serverlist.json函数 + :param serlistpath 文件的路径 + """ + cls.__Exec("setserverlistdir", serlistpath) + + @classmethod + def setproxy(cls, type, proxyip, port, verify, usr, pwd): + """ + 设置代理函数 + :param type 代理类型 + :param proxyip 代理ip + :param port 端口 + :param verify 是否验证 + :param usr 代理用户名 + :param pwd 密码 + """ + data = cls.EmQuantData() + coutResult = cls.__Exec("setproxy", type, proxyip, port, verify, usr, pwd) + if coutResult != 0: + data.ErrorCode = coutResult + data.ErrorMsg = cls.geterrstring(data.ErrorCode) + return data + + @classmethod + def manualactivate(cls, uname, password, options="", logcallback=None): + """ + 手动激活函数 + :param uname 用户名 + :param propasswordxyip 密码 + """ + if not cls.__InitSucceed: + cls.__Init() + data = cls.EmQuantData() + loginInfo = stEQLoginInfo() + uname = uname.encode(cls.EncodeType) + password = password.encode(cls.EncodeType) + loginInfo.userName = uname + loginInfo.password = password + + appLogCallback = None + if callable(logcallback): + appLogCallback = cls.Type_logOutFunc(logcallback) + else: + + def log(logMessage): + print("[EmQuantAPI Python]", logMessage.decode(cls.EncodeType)) + return 1 + + appLogCallback = cls.Type_logOutFunc(log) + cls.__Exec("setserverlistdir", _os.path.dirname(cls.__apiDllPath)) + loginResult = cls.__Exec( + "manualactivate", pointer(loginInfo), options, appLogCallback + ) + + if loginResult != 0: + data.ErrorCode = loginResult + data.ErrorMsg = cls.geterrstring(data.ErrorCode) + return data + + @classmethod + def pquery(cls, options=""): + """ + 查询函数 + :param options 可选参数 + """ + data = cls.EmQuantData() + eqData = stEQData() + refEqData = byref(pointer(eqData)) + coutResult = cls.__Exec("pquery", options, refEqData) + if coutResult != 0: + data.ErrorCode = coutResult + data.ErrorMsg = cls.geterrstring(data.ErrorCode) + return data + tempData = refEqData._obj.contents + if not isinstance(tempData, stEQData): + data.ErrorCode = coutResult + data.ErrorMsg = cls.geterrstring(data.ErrorCode) + else: + data.resolve25RankData(tempData) + cls.__Exec("releasedata", pointer(tempData)) + return data + + @classmethod + def porder(cls, combincode, orderdict, remark="", options=""): # noqa: C901 + """ + 下单函数 + :param combincode 组合代码 + :param orderdict 下单参数 + :param remark 备注 + :param options 可选参数 + """ + if not isinstance(orderdict, dict): + return None + OrderMode = 0 + num = len(orderdict["code"]) + size = sizeof(stOrderInfo) + orderinfo = (stOrderInfo * num)() + data = cls.EmQuantData() + volumenum = 0 + destvolumenum = 0 + weightnum = 0 + for index in range(0, num): + for key, value in orderdict.items(): + if key == "destvolume": + destvolumenum = destvolumenum + 1 + elif key == "weight": + weightnum = weightnum + 1 + elif key == "volume": + volumenum = volumenum + 1 + if options.replace(" ", "").upper().find("ORDERMODE=1") >= 0: + OrderMode = 1 + if destvolumenum != num: + data.ErrorCode = 10003003 + data.ErrorMsg = cls.geterrstring(data.ErrorCode) + return data + if options.replace(" ", "").upper().find("ORDERMODE=2") >= 0: + OrderMode = 2 + if weightnum != num: + data.ErrorCode = 10003003 + data.ErrorMsg = cls.geterrstring(data.ErrorCode) + return data + if OrderMode == 0: + if volumenum != num: + data.ErrorCode = 10003003 + data.ErrorMsg = cls.geterrstring(data.ErrorCode) + return data + for index in range(0, num): + for key, value in orderdict.items(): + if key == "code": + if isinstance(value[index], str): + setattr(orderinfo[index], key, str.encode(value[index])) + elif isinstance(value[index], bytes): + setattr(orderinfo[index], key, value[index]) + else: + data.ErrorCode = 10003003 + data.ErrorMsg = cls.geterrstring(data.ErrorCode) + return data + elif key == "volume": + setattr(orderinfo[index], key, value[index]) + elif key == "price": + setattr(orderinfo[index], key, value[index]) + elif key == "date": + setattr( + orderinfo[index], + key, + int(value[index].replace("-", "").replace("/", "")), + ) + elif key == "time": + setattr(orderinfo[index], key, int(value[index].replace(":", ""))) + elif key == "optype": + setattr(orderinfo[index], key, value[index]) + elif key == "cost": + setattr(orderinfo[index], key, value[index]) + elif key == "rate": + setattr(orderinfo[index], key, value[index]) + elif key == "reserve": + setattr(orderinfo[index], key, value[index]) + elif key == "destvolume" and OrderMode == 1: + setattr(orderinfo[index], "volume", value[index]) + elif key == "weight" and OrderMode == 2: + setattr(orderinfo[index], "volume", value[index]) + else: + continue + + coutResult = cls.__Exec( + "porder", pointer(orderinfo[0]), num, combincode, remark, options + ) + if coutResult != 0: + data.ErrorCode = coutResult + data.ErrorMsg = cls.geterrstring(data.ErrorCode) + return data + + @classmethod + def edb(cls, edbids, options): + """ + 宏观指标服务 + """ + edbids = cls.__toString(edbids) + result = cls.__PandasOptionFilter(options) + options = result[0] + + data = cls.EmQuantData() + eqData = stEQData() + refEqData = byref(pointer(eqData)) + coutResult = cls.__Exec("edb", edbids, options, refEqData) + if coutResult != 0: + data.ErrorCode = coutResult + data.ErrorMsg = cls.geterrstring(data.ErrorCode) + return data + tempData = refEqData._obj.contents + if not isinstance(tempData, stEQData): + data.ErrorCode = coutResult + data.ErrorMsg = cls.geterrstring(data.ErrorCode) + else: + data.resolve3RankData(tempData) + cls.__Exec("releasedata", pointer(tempData)) + return cls.__tryResolvePandas(data, result[1]) + + @classmethod + def edbquery(cls, edbids, indicators="", options=""): + """ + 宏观指标id详情查询 + """ + edbids = cls.__toString(edbids) + indicators = cls.__toString(indicators) + + data = cls.EmQuantData() + eqData = stEQData() + refEqData = byref(pointer(eqData)) + coutResult = cls.__Exec("edbquery", edbids, indicators, options, refEqData) + if coutResult != 0: + data.ErrorCode = coutResult + data.ErrorMsg = cls.geterrstring(data.ErrorCode) + return data + tempData = refEqData._obj.contents + if not isinstance(tempData, stEQData): + data.ErrorCode = coutResult + data.ErrorMsg = cls.geterrstring(data.ErrorCode) + else: + data.resolve3RankData(tempData) + cls.__Exec("releasedata", pointer(tempData)) + return data + + @classmethod + def pcreate(cls, combinCode, combinName, initialFound, remark, options=""): + """ + 新建组合 + """ + combinCode = cls.__toString(combinCode) + data = cls.EmQuantData() + coutResult = cls.__Exec( + "pcreate", combinCode, combinName, initialFound, remark, options + ) + if coutResult != 0: + data.ErrorCode = coutResult + data.ErrorMsg = cls.geterrstring(data.ErrorCode) + return data + return data + + @classmethod + def pdelete(cls, combinCode, options=""): + """ + 删除组合 + """ + combinCode = cls.__toString(combinCode) + data = cls.EmQuantData() + + coutResult = cls.__Exec("pdelete", combinCode, options) + if coutResult != 0: + data.ErrorCode = coutResult + data.ErrorMsg = cls.geterrstring(data.ErrorCode) + return data + return data + + @classmethod + def preport(cls, combinCode, indicator, options=""): + """ + 组合报表查询 + """ + combinCode = cls.__toString(combinCode) + data = cls.EmQuantData() + eqData = stEQData() + refEqData = byref(pointer(eqData)) + coutResult = cls.__Exec("preport", combinCode, indicator, options, refEqData) + if coutResult != 0: + data.ErrorCode = coutResult + data.ErrorMsg = cls.geterrstring(data.ErrorCode) + return data + tempData = refEqData._obj.contents + if not isinstance(tempData, stEQData): + data.ErrorCode = coutResult + data.ErrorMsg = cls.geterrstring(data.ErrorCode) + else: + data.resolve25RankData(tempData) + cls.__Exec("releasedata", pointer(tempData)) + return data + + @classmethod + def tradedatesnum(cls, startdate, enddate, options=""): + """ + 获取区间日期内的交易日天数(同步请求) + """ + data = cls.EmQuantData() + if startdate is None: + startdate = _datetime.today().strftime("%Y-%m-%d") + if isinstance(startdate, _datetime) or isinstance(startdate, _date): + startdate = startdate.strftime("%Y-%m-%d") + if enddate is None: + enddate = _datetime.today().strftime("%Y-%m-%d") + if isinstance(enddate, _datetime) or isinstance(enddate, _date): + enddate = enddate.strftime("%Y-%m-%d") + nSumDays = c_int(0) + refSumDays = byref(nSumDays) + coutResult = cls.__Exec( + "tradedatesnum", startdate, enddate, options, refSumDays + ) + if coutResult != 0: + data.ErrorCode = coutResult + data.ErrorMsg = cls.geterrstring(data.ErrorCode) + return data + data.Data = refSumDays._obj.value + return data + + @classmethod + def pctransfer(cls, combinCode, transferdirect, date, opCash, remark, options=""): + """ + 组合资金调配(同步请求) + :param combinCode:组合代码 + :param transferdirect:调配方向 in 增加资金 out 减少资金 + :param date: 调配日期 + :param opCash: 增量或减少的资金量 + :param remark: 备注说明 + :param options:附加参数 多个参数以半角逗号隔开 + :return EmQuantData: + """ + combinCode = cls.__toString(combinCode) + if date is None: + date = _datetime.today().strftime("%Y-%m-%d") + data = cls.EmQuantData() + coutResult = cls.__Exec( + "pctransfer", combinCode, transferdirect, date, opCash, remark, options + ) + if coutResult != 0: + data.ErrorCode = coutResult + data.ErrorMsg = cls.geterrstring(data.ErrorCode) + return data + return data + + @classmethod + def cfn(cls, codes, content, mode, options=""): + """ + 资讯数据查询(同步请求) + :param codes:东财代码或板块代码(不可混合) 多个代码间用半角逗号隔开,支持大小写。如 "300059.SZ,000002.SZ,000003.SZ,000004.SZ" + :param content:查询内容 多个指标间用半角逗号隔开,支持大小写。如 "companynews,industrynews,report,regularreport,tradeinfo" or "sectornews" + :param mode: 查询模式 eCfnMode_StartToEnd 和 eCfnMode_EndCount + :param options:附加参数 多个参数以半角逗号隔开,"starttime=20190501010000,endtime=20190725,count=10" + :return EmQuantData: + """ + codes = cls.__toString(codes) + content = cls.__toString(content) + result = cls.__PandasOptionFilter(options) + options = result[0] + ShowBlank = cls.__ShowBlankOption(options) + + data = cls.EmQuantData(ShowBlank) + eqData = stEQData() + refEqData = byref(pointer(eqData)) + coutResult = cls.__Exec("cfn", codes, content, mode, options, refEqData) + if coutResult != 0: + data.ErrorCode = coutResult + data.ErrorMsg = cls.geterrstring(data.ErrorCode) + return data + tempData = refEqData._obj.contents + if not isinstance(tempData, stEQData): + data.ErrorCode = coutResult + data.ErrorMsg = cls.geterrstring(data.ErrorCode) + else: + data.resolve25RankDataEx(tempData) + cls.__Exec("releasedata", pointer(tempData)) + return cls.__tryResolvePandas(data, result[1]) + + @classmethod + def cfnquery(cls, options=""): + """ + 板块树查询(同步请求) + :param options:附加参数 多个参数以半角逗号隔开 + :return EmQuantData: + """ + result = cls.__PandasOptionFilter(options) + options = result[0] + ShowBlank = cls.__ShowBlankOption(options) + + data = cls.EmQuantData(ShowBlank) + eqData = stEQData() + refEqData = byref(pointer(eqData)) + coutResult = cls.__Exec("cfnquery", options, refEqData) + if coutResult != 0: + data.ErrorCode = coutResult + data.ErrorMsg = cls.geterrstring(data.ErrorCode) + return data + tempData = refEqData._obj.contents + if not isinstance(tempData, stEQData): + data.ErrorCode = coutResult + data.ErrorMsg = cls.geterrstring(data.ErrorCode) + else: + data.resolve25RankData(tempData) + cls.__Exec("releasedata", pointer(tempData)) + return cls.__tryResolvePandas(data, result[1]) + + @classmethod + def cnq(cls, codes, content, options="", fncallback=None, userparams=None): + """ + 资讯订阅(异步) + :param codes:东财代码或板块代码(不可混合) 多个代码间用半角逗号隔开,支持大小写。如 "300059.SZ,000002.SZ,000003.SZ,000004.SZ" + :param content:查询内容 多个指标间用半角逗号隔开,支持大小写。如 "companynews,industrynews,report,regularreport,tradeinfo" or "sectornews" + :param options:附加参数 + :param fncallback:不同的接口可以设定不同的回调,传NULL则使用默认的示例回调函数 + :param userparams:用户参数,回调时原样返回 + :return EmQuantData: + """ + codes = cls.__toString(codes) + content = cls.__toString(content) + data = cls.EmQuantData() + + cbfunc = None + if not callable(fncallback): + cbfunc = cnqdemoCallBack + else: + cbfunc = fncallback + cls.__HandleAsynDataFuncDict[10002][0] = cbfunc + ErrorCode = c_int(0) + data.SerialID = cls.__Exec( + "cnq", + codes, + content, + options, + cls.__AsynDataFunc, + userparams, + byref(ErrorCode), + ) + data.ErrorCode = ErrorCode.value + data.ErrorMsg = cls.geterrstring(data.ErrorCode) + cls.__HandleAsynDataFuncDict[10002][data.SerialID] = cbfunc + return data + + @classmethod + def cnqcancel(cls, serialID): + """ + 取消资讯订阅 + :param serialID: + :return EmQuantData: + """ + data = cls.EmQuantData() + data.ErrorCode = cls.__Exec("cnqcancel", serialID) + data.ErrorMsg = cls.geterrstring(data.ErrorCode) + return data + + @staticmethod + def __ShowBlankOption(options=""): + pos = options.lower().find("showblank") + ShowBlank = None + if pos >= 0: + info = options[pos:] + pos = info.find(",") + if pos > 0: + info = info[0:pos] + snum = info.split("=")[1] + if snum.isdigit() or (snum.startswith("-") and snum[1:].isdigit()): + ShowBlank = int(snum) + return ShowBlank + + @staticmethod + def __PandasOptionFilter(arg=""): + # Ispandas=1,RowIndex=1 + result_list = [] + pdDict = {} + up_str = arg.upper() + pos = up_str.find("ISPANDAS") + if pos >= 0: + item = up_str[pos : pos + 10] + pdDict["ISPANDAS"] = item[9:10] + arg = arg[0:pos] + arg[pos + 10 :] + else: + pdDict["ISPANDAS"] = "0" + up_str = arg.upper() + pos = up_str.find("ROWINDEX") + if pos >= 0: + item = up_str[pos : pos + 10] + pdDict[item[0:8]] = item[9:10] + arg = arg[0:pos] + arg[pos + 10 :] + else: + pdDict["ROWINDEX"] = "1" + result_list.append(arg) + result_list.append(pdDict) + return result_list + + @staticmethod + def __tryResolvePandas(data, args={}, fun_name=None): # noqa: C901 + if data.ErrorCode != 0: + return data + if not ( + args + and len(args) > 0 + and "ISPANDAS" in args.keys() + and "ROWINDEX" in args.keys() + and args["ISPANDAS"] == "1" + ): + return data + + if fun_name is None: + import inspect + + fun_name = inspect.stack()[1][3] + + import pandas as pd + + code_list = [] + date_list = [] + data_list = [] + indictor_list = ["CODES", "DATES"] + for ind in data.Indicators: + data_list.append([]) + indictor_list.extend(data.Indicators) + + if fun_name == "csc" or fun_name == "cmc" or fun_name == "chmc": + for code_index in range(0, len(data.Codes)): + code = data.Codes[code_index] + date_list.extend(data.Dates) + for nIndex in range(0, len(data.Dates)): + code_list.append(code) + for cIndex in range(0, len(data.Data)): + data_list[cIndex].extend(data.Data[cIndex]) + elif fun_name == "csd" or fun_name == "edb": + data.Dates = [ + _datetime.strptime(it, "%Y/%m/%d").strftime("%Y/%m/%d") + for it in data.Dates + ] + for code_index in range(0, len(data.Codes)): + code = data.Codes[code_index] + date_list.extend(data.Dates) + for nIndex in range(0, len(data.Dates)): + code_list.append(code) + for cIndex in range(0, len(data.Data[code])): + data_list[cIndex].extend(data.Data[code][cIndex]) + elif ( + fun_name == "css" + or fun_name == "cses" + or fun_name == "csqsnapshot" + or fun_name == "chqsnapshot" + ): + for code_index in range(0, len(data.Codes)): + code = data.Codes[code_index] + date_list.extend(data.Dates) + for nIndex in range(0, len(data.Dates)): + code_list.append(code) + for cIndex in range(0, len(data.Data[code])): + data_list[cIndex].append(data.Data[code][cIndex]) + elif fun_name == "sector": + indilen = len(data.Indicators) + for code_index in range(0, len(data.Codes)): + code = data.Codes[code_index] + date_list.extend(data.Dates) + for nIndex in range(0, len(data.Dates)): + code_list.append(code) + for ii in range(0, indilen): + data_list[ii].append(data.Data[code_index * indilen + ii]) + else: + return data + + data_list.insert(0, date_list) + data_list.insert(0, code_list) + table = pd.DataFrame(data_list, indictor_list) + table = table.T + + if args["ROWINDEX"] == "1": + table = table.sort_values(by=["CODES", "DATES"]).set_index(["CODES"]) + elif args["ROWINDEX"] == "2": + table = table.sort_values(by=["DATES", "CODES"]).set_index(["DATES"]) + return table + + @staticmethod + def __toStrArray(args): + if args is None or args == "": + return [""] + if isinstance(args, str): + return [args] + if isinstance(args, int) or isinstance(args, float): + return [str(args)] + if isinstance(args, tuple) or isinstance(args, list): + result = [] + for item in args: + result.extend(c.__toStrArray(item)) + return result + return [str(args)] + + @staticmethod + def __toNumArray(args): + if args is None or args == "": + return None + if isinstance(args, tuple): + return [int(x) for x in args] + if isinstance(args, list): + return [int(x) for x in args] + if isinstance(args, int): + return [args] + return None + + @staticmethod + def __toString(args, joinStr=","): + v = c.__toStrArray(args) + if v is None: + return None + return joinStr.join(v) + + @staticmethod + def __HandleAsynData(quotemessage, userparams): + """ + 实时行情回调处理函数 + :param quotemessage: + :param userparams: + :return: + """ + quoteReceiveData = quotemessage.contents + + quotecallbackhandle = None + data = c.EmQuantData() + data.SerialID = quoteReceiveData.serialID + data.RequestID = quoteReceiveData.requestID + if quoteReceiveData.msgType == 0 or quoteReceiveData.msgType == 3: + data.ErrorCode = quoteReceiveData.err + data.ErrorMsg = c.geterrstring(data.ErrorCode) + quotecallbackhandle = c.__HandleAsynDataFuncDict[ + quoteReceiveData.requestID + ].get(0) + else: + if ( + data.SerialID in c.__setCsqSerialID + or data.SerialID in c.__setChqSerialID + or quoteReceiveData.requestID == 10002 + ): + data.resolve25RankDataEx(quoteReceiveData.pEQData[0]) + else: + data.resolve25RankData(quoteReceiveData.pEQData[0]) + quotecallbackhandle = c.__HandleAsynDataFuncDict[ + quoteReceiveData.requestID + ].get(quoteReceiveData.serialID) + if not callable(quotecallbackhandle): + quotecallbackhandle = DemoCallback + quotecallbackhandle(data) + return 1 diff --git a/qbot/engine/trade/trading/emt_api/demo.py b/qbot/engine/trade/trading/emt_api/demo.py new file mode 100644 index 00000000..246fa1e6 --- /dev/null +++ b/qbot/engine/trade/trading/emt_api/demo.py @@ -0,0 +1,513 @@ +# -*- coding:utf-8 -*- + +__author__ = "weijie" + +import time as _time +import traceback +from datetime import datetime, timedelta + +from EmQuantAPI import * # noqa: F403 + + +def mainCallback(quantdata): + """ + mainCallback 是主回调函数,可捕捉如下错误 + 在start函数第三个参数位传入,该函数只有一个为c.EmQuantData类型的参数quantdata + :param quantdata:c.EmQuantData + :return: + """ + print("mainCallback", str(quantdata)) + # 登录掉线或者 登陆数达到上线(即登录被踢下线) 这时所有的服务都会停止 + if str(quantdata.ErrorCode) == "10001011" or str(quantdata.ErrorCode) == "10001009": + print( + "Your account is disconnect. You can force login automatically here if you need." + ) + # 行情登录验证失败(每次连接行情服务器时需要登录验证)或者行情流量验证失败时,会取消所有订阅,用户需根据具体情况处理 + elif ( + str(quantdata.ErrorCode) == "10001021" or str(quantdata.ErrorCode) == "10001022" + ): + print("Your all csq subscribe have stopped.") + # 行情服务器断线自动重连连续6次失败(1分钟左右)不过重连尝试还会继续进行直到成功为止,遇到这种情况需要确认两边的网络状况 + elif str(quantdata.ErrorCode) == "10002009": + print("Your all csq subscribe have stopped, reconnect 6 times fail.") + # 行情订阅遇到一些错误(这些错误会导致重连,错误原因通过日志输出,统一转换成EQERR_QUOTE_RECONNECT在这里通知),正自动重连并重新订阅,可以做个监控 + elif str(quantdata.ErrorCode) == "10002012": + print("csq subscribe break on some error, reconnect and request automatically.") + # 资讯服务器断线自动重连连续6次失败(1分钟左右)不过重连尝试还会继续进行直到成功为止,遇到这种情况需要确认两边的网络状况 + elif str(quantdata.ErrorCode) == "10002014": + print("Your all cnq subscribe have stopped, reconnect 6 times fail.") + # 资讯订阅遇到一些错误(这些错误会导致重连,错误原因通过日志输出,统一转换成EQERR_INFO_RECONNECT在这里通知),正自动重连并重新订阅,可以做个监控 + elif str(quantdata.ErrorCode) == "10002013": + print("cnq subscribe break on some error, reconnect and request automatically.") + # 资讯登录验证失败(每次连接资讯服务器时需要登录验证)或者资讯流量验证失败时,会取消所有订阅,用户需根据具体情况处理 + elif ( + str(quantdata.ErrorCode) == "10001024" or str(quantdata.ErrorCode) == "10001025" + ): + print("Your all cnq subscribe have stopped.") + else: + pass + + +def startCallback(message): + print("[EmQuantAPI Python]", message) + return 1 + + +def csqCallback(quantdata): + """ + csqCallback 是csq订阅时提供的回调函数模板。该函数只有一个为c.EmQuantData类型的参数quantdata + :param quantdata:c.EmQuantData + :return: + """ + print("csqCallback,", str(quantdata)) + + +def cstCallBack(quantdata): + """ + cstCallBack 是日内跳价服务提供的回调函数模板 + """ + for i in range(0, len(quantdata.Codes)): + length = len(quantdata.Dates) + for it in quantdata.Data.keys(): + print(it) + for k in range(0, length): + for j in range(0, len(quantdata.Indicators)): + print(quantdata.Data[it][j * length + k], " ", end="") + print() + + +def cnqCallback(quantdata): + """ + cnqCallback 是cnq订阅时提供的回调函数模板。该函数只有一个为c.EmQuantData类型的参数quantdata + :param quantdata:c.EmQuantData + :return: + """ + # print ("cnqCallback,", str(quantdata)) + print("cnqCallback,") + for code in quantdata.Data: + total = len(quantdata.Data[code]) + for k in range(0, len(quantdata.Data[code])): + print(quantdata.Data[code][k]) + + +try: # noqa: C901 + # 调用登录函数(激活后使用,不需要用户名密码) + loginResult = c.start("ForceLogin=1", "", mainCallback) + if loginResult.ErrorCode != 0: + print("login in fail") + exit() + + # Ispandas获取专题报表使用范例 + data = c.ctr( + "INDEXCOMPOSITION", "", "IndexCode=000300.SH,EndDate=2017-01-13,Ispandas=1" + ) + if not isinstance(data, c.EmQuantData): + print(data) + else: + if data.ErrorCode != 0: + print("request ctr Error, ", data.ErrorMsg) + else: + print("ctr输出结果======分割线======") + for indicator in data.Indicators: + print(indicator, " ", end="") + print() + for key, value in data.Data.items(): + for v in value: + print(v, " ", end="") + print() + + # sector Ispandas使用范例 + data = c.sector("001004", "2022-05-26", "RowIndex=1,Ispandas=1") + if not isinstance(data, c.EmQuantData): + print(data) + else: + if data.ErrorCode != 0: + print("request sector Error, ", data.ErrorMsg) + else: + print("sector输出结果======分隔线======") + print(data) + + # cfc使用范例 + data = c.cfc( + "000001.SZ,000001.SH,600000.SH,000000.TEST", "CODE,NAME,TEST", "FunType=css" + ) + if data.ErrorCode != 0: + print("request cfc Error, ", data.ErrorMsg) + else: + print("cfc======分割线======") + for indicator in data.Indicators: + print(indicator, " ", end="") + print() + for key, value in data.Data.items(): + for v in value: + print(v, " ", end="") + print() + + # cec使用范例 + # data = c.cec("000001,600000,000000", "ReturnType=1,SecuType=1,SecuMarket=0") + data = c.cec("000001.SZ,000001.SH,600000.SH,000000.TEST", "ReturnType=0") + if data.ErrorCode != 0: + print("request cec Error, ", data.ErrorMsg) + else: + print("cec======分割线======") + for indicator in data.Indicators: + print(indicator, " ", end="") + print() + for key, value in data.Data.items(): + for v in value: + print(v, " ", end="") + print() + + # 资讯查询使用范例 + data = c.cfn( + "300059.SZ,600519.SH,300024.SZ", + "companynews,industrynews", + eCfnMode_EndCount, + "starttime=20190501010000,endtime=20190725,count=10", + ) + print("cfn输出结果======分隔线======") + if not isinstance(data, c.EmQuantData): + print(data) + else: + if data.ErrorCode != 0: + print("request cfn Error, ", data.ErrorMsg) + else: + for code in data.Data: + total = len(data.Data[code]) + for k in range(0, len(data.Data[code])): + print(data.Data[code][k]) + + # 板块树查询使用范例 + data = c.cfnquery("") + print("cfnquery输出结果======分隔线======") + if not isinstance(data, c.EmQuantData): + print(data) + else: + if data.ErrorCode != 0: + print("request cfnquery Error, ", data.ErrorMsg) + else: + for code in data.Codes: + for i in range(0, len(data.Indicators)): + print(data.Data[code][i]) + + # 资讯订阅使用范例 + data = c.cnq("S888005002API", "sectornews", "", cnqCallback) + if data.ErrorCode != 0: + print("request cnq Error, ", data.ErrorMsg) + else: + print("cnq输出结果======分隔线======") + _time.sleep(60) + text = input("press any key to cancel cnq \r\n") + # 取消订阅 + data = c.cnqcancel(data.SerialID) + + # cmc使用范例 + data = c.cmc( + "300059.SZ", + "OPEN,CLOSE,HIGH", + (datetime.today() + timedelta(-6)).strftime("%Y-%m-%d"), + datetime.today().strftime("%Y-%m-%d"), + "RowIndex=2,Ispandas=0", + ) + print("cmc输出结果======分隔线======") + if not isinstance(data, c.EmQuantData): + print(data) + else: + if data.ErrorCode != 0: + print("request cmc Error, ", data.ErrorMsg) + else: + for i in range(0, len(data.Indicators)): + for j in range(0, len(data.Dates)): + print( + "indicator=%s, value=%s" + % (data.Indicators[i], str(data.Data[i][j])) + ) + + # csd使用范例 + data = c.csd( + "300059.SZ,600425.SH", + "open,close", + "2016-07-01", + "2016-07-06", + "RowIndex=1,period=1,adjustflag=1,curtype=1,pricetype=1,year=2016,Ispandas=0", + ) + + print("csd输出结果======分隔线======") + if not isinstance(data, c.EmQuantData): + print(data) + else: + if data.ErrorCode != 0: + print("request csd Error, ", data.ErrorMsg) + else: + for code in data.Codes: + for i in range(0, len(data.Indicators)): + for j in range(0, len(data.Dates)): + print(data.Data[code][i][j]) + + # css使用范例 + data = c.css("300059.SZ,000002.SZ", "open,close", "TradeDate=20170308, Ispandas=0") + print("css输出结果======分隔线======") + if not isinstance(data, c.EmQuantData): + print(data) + else: + if data.ErrorCode != 0: + print("request css Error, ", data.ErrorMsg) + else: + for code in data.Codes: + for i in range(0, len(data.Indicators)): + print(data.Data[code][i]) + + # cses使用范例 + data = c.cses( + "B_011001003,B_018005001001,B_007159,B_014010016006002,B_003002001005,B_027004002003001", + "SECTOPREAVG,CFOPSAVG,MANAEXPAVG,SECTORCOUNT", + "TradeDate=2020-10-19,DelType=1,IsHistory=0,type=1,ReportDate=2020-06-30,DataAdjustType=1,PREDICTYEAR=2020,StartDate=2019-05-30,EndDate=2020-10-19,Payyear=2019", + ) + print("cses输出结果======分隔线======") + if not isinstance(data, c.EmQuantData): + print(data) + else: + if data.ErrorCode != 0: + print("request cses Error, ", data.ErrorMsg) + else: + for code in data.Codes: + for i in range(0, len(data.Indicators)): + print(data.Data[code][i]) + + # sector使用范例 + # 001004 全部A股板块 + data = c.sector("001004", "2022-05-26") + if not isinstance(data, c.EmQuantData): + print(data) + else: + if data.ErrorCode != 0: + print("request sector Error, ", data.ErrorMsg) + else: + print("sector输出结果======分隔线======") + print(data) + + # tradedate使用范例 + data = c.tradedates("2016-07-01", "2016-07-12") + if data.ErrorCode != 0: + print("request tradedates Error, ", data.ErrorMsg) + else: + print("tradedate输出结果======分隔线======") + for item in data.Data: + print(item) + + # getdate使用范例 + data = c.getdate("20160426", -3, "Market=CNSESH") + if data.ErrorCode != 0: + print("request getdate Error, ", data.ErrorMsg) + else: + print("getdate输出结果======分隔线======") + print(data.Data) + + # 实时行情订阅使用范例 + data = c.csq("600000.SH,300059.SZ", "TIME,Now,Volume", "Pushtype=2", csqCallback) + if data.ErrorCode != 0: + print("request csq Error, ", data.ErrorMsg) + else: + print("csq输出结果======分隔线======") + _time.sleep(2) + text = input("press any key to cancel csq \r\n") + # 取消订阅 + data = c.csqcancel(data.SerialID) + + # 实时行情订阅使用范例 + data = c.csq("AUDUSD.FX", "Time,now", "Pushtype=0,alltick=1", csqCallback) + if data.ErrorCode != 0: + print("request csq Error, ", data.ErrorMsg) + else: + print("csq输出结果======分隔线======") + _time.sleep(2) + text = input("press any key to cancel csq \r\n") + # 取消订阅 + data = c.csqcancel(data.SerialID) + + # 日内跳价使用范例 + data = c.cst( + "600000.SH,300059.SZ", + "TIME,OPEN,HIGH,LOW,NOW", + "093000", + "094000", + "", + cstCallBack, + ) + if data.ErrorCode != 0: + print("request cst Error, ", data.ErrorMsg) + else: + print("cst输出结果======分割线======") + _time.sleep(2) + input("press any key to quit cst \r\n") + + # 行情快照使用范例 + data = c.csqsnapshot( + "000005.SZ,600602.SH,600652.SH,600653.SH,600654.SH,600601.SH,600651.SH,000004.SZ,000002.SZ,000001.SZ,000009.SZ", + "PRECLOSE,OPEN,HIGH,LOW,NOW,AMOUNT", + "Ispandas=0", + ) + if not isinstance(data, c.EmQuantData): + print(data) + else: + if data.ErrorCode != 0: + print("request csqsnapshot Error, ", data.ErrorMsg) + else: + print("csqsnapshot输出结果======分割线======") + for key, value in data.Data.items(): + print(key, ">>> ", end="") + for v in value: + print(v, " ", end="") + print() + + # 获取专题报表使用范例 + data = c.ctr("INDEXCOMPOSITION", "", "IndexCode=000300.SH,EndDate=2017-01-13") + if not isinstance(data, c.EmQuantData): + print(data) + else: + if data.ErrorCode != 0: + print("request ctr Error, ", data.ErrorMsg) + else: + print("ctr输出结果======分割线======") + for indicator in data.Indicators: + print(indicator, " ", end="") + print() + for key, value in data.Data.items(): + for v in value: + print(v, " ", end="") + print() + + # 选股使用范例 + data = c.cps( + "B_001004", + "s0,OPEN,2017/2/27,1;s1,NAME", + "[s0]>0", + "orderby=rd([s0]),top=max([s0],100)", + ) + if data.ErrorCode != 0: + print("request cps Error, ", data.ErrorMsg) + else: + print("cps输出结果======分割线======") + for it in data.Data: + print(it) + + # 宏观指标服务 + data = c.edb("EMM00087117", "IsPublishDate=1,RowIndex=1,Ispandas=1") + if not isinstance(data, c.EmQuantData): + print(data) + else: + if data.ErrorCode != 0: + print("request edb Error, ", data.ErrorMsg) + else: + print("edbid date ", end="") + for ind in data.Indicators: + print(ind, end=" ") + print("") + for code in data.Codes: + for j in range(0, len(data.Dates)): + print(code, " ", data.Dates[j], end=" ") + for i in range(0, len(data.Indicators)): + print(data.Data[code][i][j], end=" ") + print("") + + # 宏观指标id详情查询 + data = c.edbquery("EMM00058124,EMM00087117,EMG00147350") + if data.ErrorCode != 0: + print("request edbquery Error, ", data.ErrorMsg) + else: + print("edbid ", end="") + for ind in data.Indicators: + print(ind, end=" ") + print("") + for code in data.Codes: + for j in range(0, len(data.Dates)): + print(code, " ", end=" ") + for i in range(0, len(data.Indicators)): + print(data.Data[code][i][j], end=" ") + print("") + + # 新建组合 + data = c.pcreate("quant001", "组合牛股", 100000000, "这是一个牛股的组合") + if data.ErrorCode != 0: + print("request pcreate Error, ", data.ErrorMsg) + else: + print("create succeed") + + # 组合资金调配 + data = c.pctransfer( + "quant001", "IN", "2019-08-13", 10000, "追加资金", "TRANSFERTYPE=1" + ) + if data.ErrorCode != 0: + print("request pctransfer Error, ", data.ErrorMsg) + else: + print("pctransfer succeed") + + # 组合下单 + orderdict = { + "code": ["300059.SZ", "600000.SH"], + "volume": [1000, 200], + "price": [13.11, 12.12], + "date": ["2017-08-14", "2017-08-24"], + "time": ["14:22:18", "14:22:52"], + "optype": [eOT_buy, eOT_buy], + "cost": [0, 3], + "rate": [0, 2], + "destvolume": [0, 0], + "weight": [0.1, 0.1], + } + data = c.porder("quant001", orderdict, "this is a test") + if data.ErrorCode != 0: + print("porder Error, ", data.ErrorMsg) + else: + print("order succeed") + + # 组合报表查询 + data = c.preport("quant001", "record", "startdate=2017/07/12,enddate=2018/01/15") + if data.ErrorCode != 0: + print("request preport Error, ", data.ErrorMsg) + else: + for ind in data.Indicators: + print(ind, end=" ") + print("") + for k in data.Data: + for it in data.Data[k]: + print(it, end=" ") + print("") + + # 组合信息查询 + data = c.pquery() + if data.ErrorCode != 0: + print("request pquery Error, ", data.ErrorMsg) + else: + print("[key]:", end="") + for index in range(0, len(data.Indicators)): + print("\t", data.Indicators[index], end="") + print("") + for k, v in data.Data.items(): + print(k, ": ", end="") + for vv in v: + print("\t", vv, end="") + print("") + + # 删除组合 + data = c.pdelete("quant001") + if data.ErrorCode != 0: + print("request pdelete Error, ", data.ErrorMsg) + else: + print("delete succeed") + + # 获取区间日期内的交易日天数 + data = c.tradedatesnum("2018-01-01", "2018-09-15") + if data.ErrorCode != 0: + print("request tradedatesnum Error, ", data.ErrorMsg) + else: + print("tradedatesnum======分割线======") + print(data.Data) + + # 退出 + data = logoutResult = c.stop() +except Exception as ee: + print("error >>>", ee) + traceback.print_exc() +else: + print("demo end") diff --git a/qbot/engine/trade/trading/emt_api/example/highgrowth/DemoStrategy_HighGrowth.py b/qbot/engine/trade/trading/emt_api/example/highgrowth/DemoStrategy_HighGrowth.py new file mode 100644 index 00000000..4dcefc07 --- /dev/null +++ b/qbot/engine/trade/trading/emt_api/example/highgrowth/DemoStrategy_HighGrowth.py @@ -0,0 +1,305 @@ +# -*- coding:utf-8 -*- +__author__ = "Administrator" +import sys + +from EmQuantAPI import * # noqa: F403 + +reload(sys) +sys.setdefaultencoding("Cp1252") + +import matplotlib.pyplot as plt +import pandas as pd + +reportdate, adjustlist = [], [] +tcode = {} +revnuedata = pd.DataFrame() + + +# 筛选EPS、净利润、营业收入、净资产、销售收入增长率、PEG符合高增长条件的股票 +def pick(number, startyear, code): + EpsMr, EPS3, MBREVENUE3 = pd.DataFrame(), pd.DataFrame(), pd.DataFrame() + for i in range(0, number): + reportdate = str(startyear - 4 + i) + "/12/31" + # 获取每股收益EPS(基本):EPS、主营营业收入:MBREVENUE的数据 + data = c.css( + code.Codes, "EPSBASIC,MBREVENUE", "ispandas=1,ReportDate=" + reportdate + ) + data.rename(columns=lambda x: x + "_" + reportdate, inplace=True) + EpsMr = pd.concat( + [ + EpsMr, + data[["EPSBASIC" + "_" + reportdate, "MBREVENUE" + "_" + reportdate]], + ], + axis=1, + ) + if i > 2: + # 计算3年EPS增长率,以及3年销售收入增长率 + EPS3 = ( + (EpsMr[EpsMr.columns[i * 2]] - EpsMr[EpsMr.columns[i * 2 - 2]]) + / EpsMr[EpsMr.columns[i * 2 - 2]] + + (EpsMr[EpsMr.columns[i * 2 - 2]] - EpsMr[EpsMr.columns[i * 2 - 4]]) + / EpsMr[EpsMr.columns[i * 2 - 4]] + + (EpsMr[EpsMr.columns[i * 2 - 4]] - EpsMr[EpsMr.columns[i * 2 - 6]]) + / EpsMr[EpsMr.columns[i * 2 - 6]] + ) / 3 + MBREVENUE3 = ( + (EpsMr[EpsMr.columns[i * 2 + 1]] - EpsMr[EpsMr.columns[i * 2 - 1]]) + / EpsMr[EpsMr.columns[i * 2 - 1]] + + (EpsMr[EpsMr.columns[i * 2 - 1]] - EpsMr[EpsMr.columns[i * 2 - 3]]) + / EpsMr[EpsMr.columns[i * 2 - 3]] + + (EpsMr[EpsMr.columns[i * 2 - 3]] - EpsMr[EpsMr.columns[i * 2 - 5]]) + / EpsMr[EpsMr.columns[i * 2 - 5]] + ) / 3 + EPS3 = pd.DataFrame(EPS3, columns=["EPS3"]) + MBREVENUE3 = pd.DataFrame(MBREVENUE3, columns=["MBREVENUE3"]) + # 获取净利润同比增长率:YOYNI,营业总收入同比增长率:YOYGR,净资产同比增长率:YOYEQUITY的数据 + df = c.css( + code.Codes, + "YOYNI,YOYGR,YOYEQUITY", + "ispandas=1,ReportDate=" + reportdate, + ) + FinancialData = pd.concat( + [df[["YOYNI", "YOYGR", "YOYEQUITY"]], EPS3, MBREVENUE3], axis=1 + ) + FinancialData = FinancialData.dropna(axis=0, how="any") + # 筛选3年EPS增长率大于股票池中间值,筛选3年销售收入增长率大于股票池中间值的股票 + FinancialData = FinancialData.ix[ + (FinancialData["EPS3"] > FinancialData["EPS3"].median()) + & (FinancialData["MBREVENUE3"] > FinancialData["MBREVENUE3"].median()) + ] + # 筛选所有增长率为正的股票 + FinancialData = FinancialData[FinancialData > 0.0] + FinancialData = FinancialData.dropna(how="any") + newcode = FinancialData.index.tolist() + # 筛选当年PEG<1的的股票 + newcode = c.cps(",".join(newcode), "s2,PEG," + reportdate + ",6", "[s2]<1") + # tcode为符合持仓的股票池 + tcode[startyear - 3 + i] = newcode.Codes + FinancialData = pd.DataFrame() + return tcode + + +# 获取每年调仓日的持仓数据,包括持仓比例:STOCKPRO,持仓量:STOCKNUMBER,持仓金额:STOCKAMOUNT,流动资金:CAPITAL等 +# 获取每年持仓变动明细数据,包括持仓变动量:NUMADJ,买卖类型:TYPE,持仓变动次数:ADJUSTNUMBER,价格:PRICE等 +def transfer(number, startyear, code): + k = 0 + ADJUSTdata, STOCKdata, ADJUST = pd.DataFrame(), pd.DataFrame(), pd.DataFrame() + for i in range(startyear, endyear): + try: + # 获取每年调仓日的股票的简称:NAME,收盘价:CLOSE和市值:MV + data = c.css( + ",".join(tcode[i]), + "NAME,CLOSE,MV", + "ispandas=1,adjustflag=2,TradeDate=" + adjustlist[i - startyear], + ) + data.insert(0, "ADJUSTDATE", adjustlist[i - startyear]) + except Exception: + # 当持仓为空时,判断首次持仓不为空,且前次持仓不为空的,将前次持仓全部卖出 + if tcode[i] == [] and k == 1: + if tcode[i - 1] != [] and k == 1: + ADJUSTdata = STOCKdata[ + STOCKdata["ADJUSTDATE"] == adjustlist[i - startyear - 1] + ] + ADJUSTdata = pd.DataFrame( + ADJUSTdata[["STOCKNUMBER", "ADJUSTDATE", "CLOSE"]] + ) + ADJUSTdata.rename( + columns={"STOCKNUMBER": "NUMADJ", "CLOSE": "PRICE"}, + inplace=True, + ) + ADJUSTdata["NUMADJ"] = (-1) * ADJUSTdata["NUMADJ"] + ADJUSTdata["ADJUSTNUMBER"] = i - startyear + 1 + ADJUSTdata["TYPE"] = -1 + else: + pass + else: + continue + # 当持仓不为空时,判断为首次持仓时,全部持仓买入 + if tcode[i] != [] and k == 0: + data["STOCKPRO"] = data["MV"] / data["MV"].sum() + data["STOCKNUMBER"] = capital * data["STOCKPRO"] // data["CLOSE"] + data["STOCKAMOUNT"] = data["STOCKNUMBER"] * data["CLOSE"] + ADJUSTdata = pd.DataFrame(data[["STOCKNUMBER", "ADJUSTDATE", "CLOSE"]]) + ADJUSTdata.rename( + columns={"STOCKNUMBER": "NUMADJ", "CLOSE": "PRICE"}, inplace=True + ) + ADJUSTdata["ADJUSTNUMBER"] = i - startyear + 1 + # TYPE=1时为买入,TYPE=-1为卖出,TYPE=0时无买入卖出 + ADJUSTdata["TYPE"] = 1 + data["CAPITAL"] = capital - data["STOCKAMOUNT"].sum() + STOCKdata = STOCKdata.append(data) + ADJUST = ADJUST.append(ADJUSTdata) + ADJUSTdata = pd.DataFrame() + k = 1 + # 当持仓不为空时,判断为非首次持仓时,根据前后持仓明细计算持仓变动 + elif tcode[i] != [] and k == 1: + # 获取调仓当日,调仓前的股票池的收盘价 + data1 = c.css( + ",".join(tcode[i - 1]), + "CLOSE", + "ispandas=1,adjustflag=2,TradeDate=" + adjustlist[i - startyear], + ) + data["STOCKPRO"] = data["MV"] / data["MV"].sum() + data["STOCKNUMBER"] = ( + ( + ( + STOCKdata[ + STOCKdata["ADJUSTDATE"] == adjustlist[i - startyear - 1] + ]["CAPITAL"].sum() + / len(tcode[i]) + + ( + STOCKdata[ + STOCKdata["ADJUSTDATE"] == adjustlist[i - startyear - 1] + ]["STOCKNUMBER"] + * data1["CLOSE"] + ) + ).sum() + ) + * data["STOCKPRO"] + // data["CLOSE"] + ) + data["STOCKAMOUNT"] = data["STOCKNUMBER"] * data["CLOSE"] + # 流动资金=调仓前股票当日持股数量*当日价格+调仓前流动资金-调仓后股票当日持仓金额 + data["CAPITAL"] = ( + STOCKdata[STOCKdata["ADJUSTDATE"] == adjustlist[i - startyear - 1]][ + "CAPITAL" + ].sum() + / len(tcode[i]) + + ( + STOCKdata[STOCKdata["ADJUSTDATE"] == adjustlist[i - startyear - 1]][ + "STOCKNUMBER" + ] + * data1["CLOSE"] + ) + ).sum() - (data["STOCKAMOUNT"].sum()) + ADJUSTdata = pd.DataFrame( + 0, + index=list(set(tcode[i - 1]).union(set(tcode[i]))), + columns=["NUMADJ"], + ) + # 当股票调仓前和调仓后都有时,持仓变动=调仓前持股数——调仓后持股数 + ADJUSTdata.ix[[l for l in tcode[i] if l in tcode[i - 1]], "NUMADJ"] = ( + data["STOCKNUMBER"] + - STOCKdata[STOCKdata["ADJUSTDATE"] == adjustlist[i - startyear - 1]][ + "STOCKNUMBER" + ] + ) + # 当股票调仓后新买入时,持仓变动=调仓后持股数 + ADJUSTdata.ix[[l for l in tcode[i] if l not in tcode[i - 1]], "NUMADJ"] = ( + data.ix[[l for l in tcode[i] if l not in tcode[i - 1]], "STOCKNUMBER"] + ) + # 当股票调仓后全部卖出时,持仓变动=-调仓前持股数 + ADJUSTdata.ix[[l for l in tcode[i - 1] if l not in tcode[i]], "NUMADJ"] = ( + -1 + ) * STOCKdata[STOCKdata["ADJUSTDATE"] == adjustlist[i - startyear - 1]].ix[ + [l for l in tcode[i - 1] if l not in tcode[i]], "STOCKNUMBER" + ] + ADJUSTdata["ADJUSTDATE"] = data["ADJUSTDATE"] + ADJUSTdata.ix[ + [l for l in tcode[i - 1] if l not in tcode[i]], "ADJUSTDATE" + ] = adjustlist[i - startyear] + ADJUSTdata["PRICE"] = data["CLOSE"] + ADJUSTdata.ix[[l for l in tcode[i - 1] if l not in tcode[i]], "PRICE"] = ( + data1.ix[[l for l in tcode[i - 1] if l not in tcode[i]], "CLOSE"] + ) + ADJUSTdata["ADJUSTNUMBER"] = i - startyear + 1 + # 根据持仓变动的正负判定买卖类型 + ADJUSTdata.ix[ADJUSTdata["NUMADJ"] < 0, "TYPE"] = -1 + ADJUSTdata.ix[ADJUSTdata["NUMADJ"] > 0, "TYPE"] = 1 + ADJUSTdata["TYPE"].fillna(0) + STOCKdata = STOCKdata.append(data) + ADJUST = ADJUST.append(ADJUSTdata) + ADJUSTdata = pd.DataFrame() + STOCKdata = STOCKdata.reset_index() + # 输出调仓日当日持仓数据,输出调仓日当日持仓变动数据 + STOCKdata.to_csv("STOCKdata.csv", encoding="gbk") + ADJUST.to_csv("AdjustData.csv") + return STOCKdata + + +# 登录Choice接口 +loginResult = c.start("ForceLogin=1") +startyear = 2012 # 设置起始年份 +endyear = 2017 # 设置截止年份 +index = "000016.SH" # 以上证指数为标的指数 +capital = 10000000 # 设置初始资金 +today = datetime.date.today() +codeyear = str(startyear - 4) + "/01/01" +# 筛选上市为起始年份前四年之前上市的股票,009007063为上证50板块 +code = c.cps("B_009007063", "s1,LISTDATE", "s13月,大于时调仓次数+1 +if datetime.datetime.now().month > 3: + number = endyear - startyear + 4 +else: + number = endyear - startyear + 3 + +# 筛选EPS、净利润、营业收入、净资产、销售收入增长率、PEG符合高增长条件的股票 +tcode = pick(number, startyear, code) + +# 获取每年4月第一周交易日期 +for i in range(startyear, endyear): + adjustdate = c.tradedates(str(i) + "/04/01", str(i) + "/04/20", "period=2") + adjustlist.append(adjustdate.Dates[0]) +# 获取每年调仓日持仓数据和持仓变动数据 +STOCKdata = transfer(tcode, startyear, endyear) + +# 根据每周持仓情况,计算净值,收益率和最大回撤率 +for i in range(startyear, endyear): + try: + # 获取每年持仓股票的每周的收盘价 + data = c.csd( + ",".join(tcode[i]), + "CLOSE", + str(i) + "/04/01", + str(i + 1) + "/03/31", + "ispandas=1,period=2,adjustflag=2", + ) + except Exception: + continue + data = data.reset_index() + STOCK = STOCKdata[STOCKdata["ADJUSTDATE"] == adjustlist[i - startyear]] + # 填充持仓股票每周持股数量 + for n in tcode[i]: + data.ix[data["CODES"] == n, "STOCKNUMBER"] = STOCK.ix[ + STOCK["CODES"] == n, "STOCKNUMBER" + ][(STOCK.ix[STOCK["CODES"] == n].index.tolist())[0]] + data["STOCKAMOUNT"] = data["STOCKNUMBER"] * data["CLOSE"] + # revnue=pd.DataFrame(((data['STOCKNUMBER']*data['CLOSE']).sum()+STOCK.iat[0,9]),columns=['TOTAL']) + # 根据日期,分组计算组合市值 + revnue = data.groupby("DATES")[["STOCKAMOUNT"]].sum() + # 计算组合收益 + revnue["REVNUE"] = revnue["STOCKAMOUNT"] + STOCK.iat[0, 9] + revnuedata = revnuedata.append(revnue) + revnue = pd.DataFrame() + data = pd.DataFrame() +# 计算回撤率 +revnuedata["MAX"] = revnuedata["REVNUE"].expanding(min_periods=1).max() +revnuedata["DD"] = revnuedata["REVNUE"] / revnuedata["MAX"] - 1 +# 计算最大回撤率 +RETREAT = revnuedata.sort_values(by="DD").iloc[0]["DD"] +print("最大回撤率为%s:" % RETREAT) +# 计算组合收益率 +revnuedata["REVNUE"] = (revnuedata["REVNUE"] / capital) - 1 + +# 获取上证指数每周的收盘价 +indexdata = c.csd( + index, + "CLOSE", + str(startyear) + "/04/01", + str(endyear) + "/03/31", + "ispandas=1,period=2,Rowindex=2", +) +closef = c.css(index, "CLOSE", "Tradedate=" + adjustlist[0]) +# 计算上证指数收益率 +indexdata["REVNUE"] = indexdata["CLOSE"] / closef.Data[index][0] - 1 + +# 绘制收益率曲线 +indexdata["COMBINE"] = revnuedata["REVNUE"] +indexdata["000001.SH"] = indexdata["REVNUE"] +finaldata = indexdata[["000001.SH", "COMBINE"]] +finaldata[["000001.SH", "COMBINE"]].plot(figsize=(10, 8)) +plt.legend() +plt.xlabel("date") +plt.ylabel("revnue") +plt.title("CombineRevnue") +plt.show() diff --git a/qbot/engine/trade/trading/emt_api/example/highgrowth/HighGrowth.docx b/qbot/engine/trade/trading/emt_api/example/highgrowth/HighGrowth.docx new file mode 100644 index 00000000..33769bb1 Binary files /dev/null and b/qbot/engine/trade/trading/emt_api/example/highgrowth/HighGrowth.docx differ diff --git "a/qbot/engine/trade/trading/emt_api/example/hindenburg_omen/A\350\202\241\345\270\202\345\234\272\345\205\264\347\231\273\345\240\241\345\207\266\345\205\206.docx" "b/qbot/engine/trade/trading/emt_api/example/hindenburg_omen/A\350\202\241\345\270\202\345\234\272\345\205\264\347\231\273\345\240\241\345\207\266\345\205\206.docx" new file mode 100644 index 00000000..c2554e00 Binary files /dev/null and "b/qbot/engine/trade/trading/emt_api/example/hindenburg_omen/A\350\202\241\345\270\202\345\234\272\345\205\264\347\231\273\345\240\241\345\207\266\345\205\206.docx" differ diff --git a/qbot/engine/trade/trading/emt_api/example/hindenburg_omen/DemoStrategy_HindenburgOmen.py b/qbot/engine/trade/trading/emt_api/example/hindenburg_omen/DemoStrategy_HindenburgOmen.py new file mode 100644 index 00000000..c2b7a511 --- /dev/null +++ b/qbot/engine/trade/trading/emt_api/example/hindenburg_omen/DemoStrategy_HindenburgOmen.py @@ -0,0 +1,109 @@ +# -*- coding:utf-8 -*- +__author__ = "Administrator" +import sys + +from EmQuantAPI import * # noqa: F403 + +reload(sys) +sys.setdefaultencoding("Cp1252") + +import matplotlib.pyplot as plt +import pandas as pd +from sklearn import linear_model + +tcode = {} +codenumber = [] +xcode, k, X, Y = [], [], [], [] +Rsq = pd.DataFrame() +loginResult = c.start("ForceLogin=1") + +index = "000001.SH" # 上证指数 +sectorcode = "2000032255" # 上证A股成分 +startdate = "20160101" # 起始日期 +enddate = "20161231" # 截止日期 +# 后推30日获取 + +Ndate = c.getdate(enddate, 30) +enddateN30 = Ndate.Dates[0] +date = c.tradedates(startdate, enddateN30) + +# 获取上证A股的板块成分,每日新增的代码也获取对应的收盘价数据 +for i in range(len(date.Dates) - 30): + if i == 0: + code = c.sector(sectorcode, date.Dates[i]) + data = c.csd(code.Codes, "CLOSE", startdate, enddateN30, "Period=1,ispandas=1") + codenumber = code.Codes + code2 = code + else: + code1 = c.sector(sectorcode, date.Dates[i]) + addcode = [i for i in code1.Codes if i not in code2.Codes] + if len(addcode) != 0: + adddata = c.csd( + addcode, "CLOSE", startdate, enddateN30, "Period=1,ispandas=1" + ) + data = data.append(adddata) + codenumber = codenumber + addcode + code2 = code1 +data.to_csv("data.csv") +data = pd.read_csv("data.csv") +data = data.set_index("CODES") +# 获取对比指数收盘价数据 +indexdata = c.csd( + index, "CLOSE", startdate, enddateN30, "Period=1,ispandas=1,rowindex=1" +) +# 板块成分和指数线性回归,并计算30日间隔的Rsq系数 +for i in range(len(codenumber)): + for x, y in zip(data.ix[codenumber[i], "CLOSE"], indexdata["CLOSE"]): + X.append([float(x)]) + Y.append(float(y)) + for j in range(0, len(Y)): + try: + regr = linear_model.LinearRegression() + regr = regr.fit(X[j : j + 30], Y[j : j + 30]) + regr = regr.score(X[j : j + 30], Y[j : j + 30]) + xcode.append(regr) + if j + 30 >= len(Y) - 1: + break + except Exception: + xcode.append(0) + tcode[codenumber[i]] = xcode + xcode = [] + X = [] + Y = [] +Rsq = pd.DataFrame(tcode) +Rsq.to_csv("rsq.csv", index=None) +Rsq = pd.read_csv("rsq.csv") +# 求每日Rsq系数的均值 +FORMAT = "%d/%02d/%02d" +Rsq = Rsq.T +mean = pd.DataFrame(Rsq.mean(), columns=["MEAN"]) +for i in range(Rsq.columns.size): + mean["MEAN"] = mean["MEAN"] * len(Rsq) / len(Rsq[Rsq[i] != 0.0]) +mean["DATE"] = date.Dates[30:] + +# 求每日Rsq系数的均值间隔3日变动幅度超过30%的日期进行标记 +for i in range(len(mean) - 33): + x = (mean.ix[i, "MEAN"] - mean.ix[i + 3, "MEAN"]) / mean.ix[i, "MEAN"] + if x > 0.3 or x < -0.3: + k.append(mean.ix[i + 3, "DATE"]) + list1 = mean.ix[i + 3, "DATE"].split("/") + list1 = FORMAT % (int(list1[0]), int(list1[1]), int(list1[2])) + indexdata.ix[indexdata["DATES"] == list1, "MARKER"] = 1 + else: + pass +# 绘制指数收盘价 +indexdata = indexdata.set_index("DATES") +indexdata.index = pd.to_datetime(indexdata.index) +# 标记吉登堡凶兆所标记的时间点 +for i in range(0, len(indexdata.ix[indexdata["MARKER"] == 1, "CLOSE"])): + plt.scatter( + pd.to_datetime((indexdata.ix[indexdata["MARKER"] == 1, "CLOSE"]).index)[i], + indexdata.ix[indexdata["MARKER"] == 1, "CLOSE"][i], + color="red", + marker="o", + ) +indexdata["CLOSE"].plot(figsize=(10, 8)) +plt.xlabel("date") +plt.ylabel("close") +plt.title("000001.SH") +plt.show() diff --git a/qbot/engine/trade/trading/emt_api/example/ma_strategy/DemoStrategy_MA.py b/qbot/engine/trade/trading/emt_api/example/ma_strategy/DemoStrategy_MA.py new file mode 100644 index 00000000..0fab56f8 --- /dev/null +++ b/qbot/engine/trade/trading/emt_api/example/ma_strategy/DemoStrategy_MA.py @@ -0,0 +1,239 @@ +# -*-coding:utf-8-*- +__author__ = "Administrator" + +import matplotlib.pyplot as plt +import numpy as np + +# reload(sys) +# sys.setdefaultencoding('Cp1252') +import pandas as pd +from EmQuantAPI import * # noqa: F403 + +stock = pd.DataFrame() +MAstock = {} + + +def trade(data): + # 计算长线金叉,长线死叉,短线金叉,短线死叉,长线金叉全部买入,长线死叉全部卖出,短线金叉买入30%,短线死叉卖出30% + data.ix[ + (data["MA_5"].shift(1) < data["MA_10"].shift(1)) + & (data["MA_5"] > data["MA_10"]) + & (data["VOLUME"] > 0), + "POSITION", + ] = 0.3 + data.ix[ + (data["MA_5"].shift(1) > data["MA_10"].shift(1)) + & (data["MA_5"] < data["MA_10"]) + & (data["VOLUME"] > 0), + "POSITION", + ] = -0.3 + data.ix[ + (data["MA_10"].shift(1) < data["MA_15"].shift(1)) + & (data["MA_10"] > data["MA_15"]) + & (data["VOLUME"] > 0), + "POSITION", + ] = 1 + data.ix[ + (data["MA_10"].shift(1) > data["MA_15"].shift(1)) + & (data["MA_10"] < data["MA_15"]) + & (data["VOLUME"] > 0), + "POSITION", + ] = -1 + # POSITION:买卖点,TRUEPOSITION:实际持仓,TYPE:实际买卖点,STOCKNUMBER:持仓数量,CAPITAL:流动资金,STOCKAMOUNT:持仓总额,REVNUE:市值,DD:回撤率 + # 首次出现长线金叉时设为首次买入点 + if len(data[(data["POSITION"] == 1)]) == 0: + startposition = data["DATES"].tolist()[-1] + data["TRUEPOSITION"] = 0 + data["TYPE"] = 0 + data["STOCKNUMBER"] = 0 + data["CAPITAL"] = capital + data["STOCKAMOUNT"] = 0 + data["REVNUE"] = capital + data["MAX"] = capital + data["DD"] = 0 + return data + else: + startposition = data[(data["POSITION"] == 1)]["DATES"].tolist()[0] + first = data["DATES"].tolist()[0] + data.ix[ + (data["DATES"] >= first) & (data["DATES"] < startposition), "POSITION" + ] = 0 + data = data.fillna(0) + position = data["POSITION"].tolist() + Trueposition = [] + Trueposition.append(position[0]) + # 计算实际买卖点,满仓时不再买入卖出,非满仓时执行买入卖出 + for i in range(0, len(position) - 1): + try: + if (position[i + 1] + Trueposition[i]) >= 0 and ( + position[i + 1] + Trueposition[i] + ) <= 1: + Trueposition.append(position[i + 1] + Trueposition[i]) + elif (position[i + 1] + Trueposition[i]) > 1: + Trueposition.append(1) + elif (position[i + 1] + Trueposition[i]) < 0: + Trueposition.append(0) + except Exception: + pass + data.insert(0, "TRUEPOSITION", 0) + data["TRUEPOSITION"] = np.array(Trueposition) # 实际仓位 + data["TYPE"] = data["TRUEPOSITION"] - data["TRUEPOSITION"].shift(1) + data["TYPE"] = data["TYPE"].fillna(0) # 减仓幅度 + DATA = data[data["TYPE"] != 0] + DATA = DATA.reset_index() # 发生仓位变化的表 + for j in range(0, len(DATA)): + # 首次全仓买入时计算持仓数量和流动资金,CAPITAL为流动资金 + if j == 0: + DATA.ix[j, "STOCKNUMBER"] = capital // DATA.ix[j, "CLOSE"] // 100 * 100 + DATA.ix[j, "CAPITAL"] = ( + capital - DATA.ix[j, "CLOSE"] * DATA.ix[j, "STOCKNUMBER"] + ) + else: + # 实际持仓为0时,卖出持仓的数量和流动资金 + if DATA.ix[j - 1, "TRUEPOSITION"] == 0: + DATA.ix[j, "STOCKNUMBER"] = ( + DATA.ix[j - 1, "CAPITAL"] + // DATA.ix[j, "CLOSE"] + // 100 + * 100 + * DATA.ix[j, "TYPE"] + ) + DATA.ix[j, "CAPITAL"] = ( + DATA.ix[j - 1, "CAPITAL"] + - DATA.ix[j, "CLOSE"] * DATA.ix[j, "STOCKNUMBER"] + ) + # 实际持仓不为0时,卖出持仓的数量和流动资金 + else: + DATA.ix[j, "STOCKNUMBER"] = ( + DATA.ix[j - 1, "STOCKNUMBER"] + / DATA.ix[j - 1, "TRUEPOSITION"] + * DATA.ix[j, "TRUEPOSITION"] + ) + DATA.ix[j, "CAPITAL"] = ( + DATA.ix[j - 1, "STOCKNUMBER"] - DATA.ix[j, "STOCKNUMBER"] + ) * DATA.ix[j, "CLOSE"] + DATA.ix[j - 1, "CAPITAL"] + data.ix[data["DATES"] == DATA.ix[j, "DATES"], "STOCKNUMBER"] = DATA.ix[ + j, "STOCKNUMBER" + ] + data.ix[data["DATES"] == DATA.ix[j, "DATES"], "CAPITAL"] = DATA.ix[ + j, "CAPITAL" + ] + # 计算非买卖点的持仓数量、持仓金额、流动资金、市值、回撤率 + data["STOCKNUMBER"] = data["STOCKNUMBER"].fillna(method="pad") + data["STOCKNUMBER"] = data["STOCKNUMBER"].fillna(0) + data["CAPITAL"] = data["CAPITAL"].fillna(method="pad") + data["STOCKAMOUNT"] = data["STOCKNUMBER"] * data["CLOSE"] + data["REVNUE"] = data["STOCKAMOUNT"] + data["CAPITAL"] + data["MAX"] = pd.expanding_max(data["REVNUE"]) + data["DD"] = data["REVNUE"] / data["MAX"] - 1 + data["REVNUE"] = data["REVNUE"].fillna(capital) + return data + + +# 获取均线短线、长线数据 +def ma(MA, Tradedate): + Ma, Mx = pd.DataFrame(), pd.DataFrame() + for i in range(len(MA)): + for j in range(len(Tradedate)): + try: + ma = c.css( + code, + "MA", + "Period=1,ispandas=1,AdjustFlag=2,n=" + + str(MA[i]) + + ",Tradedate=" + + Tradedate[j], + ) + # time.sleep(1) + except Exception: + loginResult = c.start("ForceLogin=1") + ma = c.css( + code, + "MA", + "Period=1,ispandas=1,AdjustFlag=2,n=" + + str(MA[i]) + + ",Tradedate=" + + Tradedate[j], + ) + ma.insert(0, "Tradedate", Tradedate[j]) + Ma = Ma.append(ma) + Mx = pd.concat([Ma, Mx], axis=1, ignore_index=True) + Ma = pd.DataFrame() + Mx = Mx[[0, 2, 5, 8]] + Mx.rename(columns={0: "Tradedate", 8: "MA_5", 5: "MA_10", 2: "MA_15"}, inplace=True) + return Mx + + +# 登录Choice接口 +loginResult = c.start("ForceLogin=1") +# 获取股票池 #获取当日的上证50指数成分股票 +code = c.sector("2000043296", "2016-12-31") +# code=["000002.SZ","600004.SH"]#code=c.sector("2000043296",time.strftime("%Y-%m-%d")) +code = ["600519.SH", "600999.SH", "601318.SH", "600837.SH"] +index = "000016.SH" +startdate = "20170101" # 设置起始日期 +enddate = "20170630" # 设置截止日期 +MA = [5, 10, 15] # 设置均线短线、长线周期 +capital = 1000000 # 设置初始资金 +Tradedate = [] +FORMAT = "%d-%02d-%02d" +# 获取交易日序列 +date = c.tradedates(startdate, enddate) +# 获取交易日序列八位标准格式 +for i in range(len(date.Dates)): + list1 = date.Dates[i].split("/") + Tradedate.append(FORMAT % (int(list1[0]), int(list1[1]), int(list1[2]))) + +# 获取均线短线、长线数据 +Mx = ma(MA, Tradedate) + +# 获取股票的不复权和后复权收盘价:CLOSE,成交量:VOLUME +stockdata = c.csd(code, "CLOSE,VOLUME", startdate, enddate, "ispandas=1,AdjustFlag=2") +stockdata1 = c.csd(code, "CLOSE", startdate, enddate, "ispandas=1,AdjustFlag=1") +stockdata = stockdata[["CLOSE", "VOLUME"]] +stockdata.rename(columns={"CLOSE": "ADJCLOSE"}, inplace=True) + +# 调用函数计算金叉,死叉 +for i in range(0, len(code)): + data = pd.concat( + [stockdata1.ix[code[i]], stockdata.ix[code[i]], Mx.ix[code[i], [1, 2, 3]]], + axis=1, + ) + data = data.dropna(axis=0, how="any") + data = trade(data) + # 计算每个代码的最大回撤率:RETREAT、收益率:REVNUE + RETREAT = data.sort_values(by="DD").iloc[0]["DD"] + REVNUE = (data.ix[-1, "REVNUE"] - capital) / capital + MAstock[code[i]] = [RETREAT, REVNUE] + data = data.set_index("DATES") + # 获取每个代码的每日收益率变化值 + data[code[i] + "_RTN"] = (data["REVNUE"] / capital) - 1 + if i == 0: + stock = data[code[i] + "_RTN"] + else: + stock = pd.concat([stock, data[code[i] + "_RTN"]], axis=1) +MAstock = pd.DataFrame(MAstock, index=["RETREAT", "REVNUE"]) +MAstock = MAstock.T +# 个股最大回撤率 +RETREATMAX = MAstock.sort_values(by="RETREAT").iloc[0]["RETREAT"] +print("最大回撤率为%s:" % RETREATMAX) +# 输出股票池的回撤率和收益变化率数据 +MAstock.to_csv("MAstock.csv") +# 计算得到股票池的收益率变化均值 +combine = pd.DataFrame(stock.mean(1), columns=["RTN"]) + +# 上证50指数 +indexdata = c.csd( + index, "CLOSE", startdate, enddate, "rowindex=2,ispandas=1,AdjustFlag=2" +) +# 计算上证指数收益率变化值 +indexdata["000016.SH"] = (indexdata["CLOSE"] / indexdata.ix[0, "CLOSE"]) - 1 +# 绘制上证指数和股票池收益率曲线变化曲线 +indexdata["COMBINE"] = combine["RTN"] +finaldata = indexdata[["000016.SH", "COMBINE"]] +finaldata[["000016.SH", "COMBINE"]].plot(figsize=(10, 8)) +plt.legend() +plt.xlabel("date") +plt.ylabel("revnue") +plt.title("CombineRevnue") +plt.show() diff --git "a/qbot/engine/trade/trading/emt_api/example/ma_strategy/\345\235\207\347\272\277\347\255\226\347\225\245.docx" "b/qbot/engine/trade/trading/emt_api/example/ma_strategy/\345\235\207\347\272\277\347\255\226\347\225\245.docx" new file mode 100644 index 00000000..e4213a11 Binary files /dev/null and "b/qbot/engine/trade/trading/emt_api/example/ma_strategy/\345\235\207\347\272\277\347\255\226\347\225\245.docx" differ diff --git a/qbot/engine/trade/trading/emt_api/installEmQuantAPI.py b/qbot/engine/trade/trading/emt_api/installEmQuantAPI.py new file mode 100644 index 00000000..0a232fd2 --- /dev/null +++ b/qbot/engine/trade/trading/emt_api/installEmQuantAPI.py @@ -0,0 +1,43 @@ +__author__ = "weijie" + +import os as _os +import sys as _sys + +from EmQuantAPI import * # noqa: F403 + + +def installEmQuantAPI(): + print("Start to install EmQuantAPI...") + + if UtilAccess.adapter.get_py_name() != PY_Python3: + print("Error: Python version must be 3.x!") + return + + currDir = _os.path.split(_os.path.realpath(__file__))[0] + site_pkg_names = ["site-packages"] + if UtilAccess.adapter.get_os_name() == OS_Linux: + site_pkg_names.append("dist-packages") + + # get site-packages path + packagepath = "" + for site_pkg_name in site_pkg_names: + if packagepath != "": + break + for spath in _sys.path: + pos = spath.find(site_pkg_name) + if pos >= 0 and spath[pos:] == site_pkg_name: + packagepath = spath + break + + if packagepath != "": + pthPath = _os.path.join(packagepath, "EmQuantAPI.pth") + pthFile = open(pthPath, "w") + pthFile.writelines(currDir) + pthFile.close() + print("Success:", "EmQuantAPI installed.") + else: + print("Error: EmQuantApi install fail!(in get pth)") + + +if __name__ == "__main__": + installEmQuantAPI() diff --git a/qbot/engine/trade/trading/emt_api/libs/linux/x64/ServerList.json.e b/qbot/engine/trade/trading/emt_api/libs/linux/x64/ServerList.json.e new file mode 100644 index 00000000..78b3f67f --- /dev/null +++ b/qbot/engine/trade/trading/emt_api/libs/linux/x64/ServerList.json.e @@ -0,0 +1 @@ +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 \ No newline at end of file diff --git a/qbot/engine/trade/trading/emt_api/libs/linux/x64/loginactivator b/qbot/engine/trade/trading/emt_api/libs/linux/x64/loginactivator new file mode 100644 index 00000000..c0ddf09d Binary files /dev/null and b/qbot/engine/trade/trading/emt_api/libs/linux/x64/loginactivator differ diff --git a/qbot/engine/trade/trading/emt_api/libs/linux/x64/loginactivator_ubuntu b/qbot/engine/trade/trading/emt_api/libs/linux/x64/loginactivator_ubuntu new file mode 100644 index 00000000..344082ed Binary files /dev/null and b/qbot/engine/trade/trading/emt_api/libs/linux/x64/loginactivator_ubuntu differ diff --git a/qbot/engine/trade/trading/emt_api/libs/linux/x86/ServerList.json.e b/qbot/engine/trade/trading/emt_api/libs/linux/x86/ServerList.json.e new file mode 100644 index 00000000..78b3f67f --- /dev/null +++ b/qbot/engine/trade/trading/emt_api/libs/linux/x86/ServerList.json.e @@ -0,0 +1 @@ +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 \ No newline at end of file diff --git a/qbot/engine/trade/trading/emt_api/libs/linux/x86/loginactivator b/qbot/engine/trade/trading/emt_api/libs/linux/x86/loginactivator new file mode 100644 index 00000000..f05e6575 Binary files /dev/null and b/qbot/engine/trade/trading/emt_api/libs/linux/x86/loginactivator differ diff --git a/qbot/engine/trade/trading/emt_api/libs/linux/x86/loginactivator_ubuntu b/qbot/engine/trade/trading/emt_api/libs/linux/x86/loginactivator_ubuntu new file mode 100644 index 00000000..1e631b24 Binary files /dev/null and b/qbot/engine/trade/trading/emt_api/libs/linux/x86/loginactivator_ubuntu differ diff --git a/qbot/engine/trade/trading/emt_api/libs/mac/ServerList.json.e b/qbot/engine/trade/trading/emt_api/libs/mac/ServerList.json.e new file mode 100644 index 00000000..78b3f67f --- /dev/null +++ b/qbot/engine/trade/trading/emt_api/libs/mac/ServerList.json.e @@ -0,0 +1 @@ +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 \ No newline at end of file diff --git a/qbot/engine/trade/trading/emt_api/libs/mac/image/EMApp.ico b/qbot/engine/trade/trading/emt_api/libs/mac/image/EMApp.ico new file mode 100644 index 00000000..2c17ecae Binary files /dev/null and b/qbot/engine/trade/trading/emt_api/libs/mac/image/EMApp.ico differ diff --git a/qbot/engine/trade/trading/emt_api/libs/mac/image/Tips_error.png b/qbot/engine/trade/trading/emt_api/libs/mac/image/Tips_error.png new file mode 100644 index 00000000..8ff3a5e9 Binary files /dev/null and b/qbot/engine/trade/trading/emt_api/libs/mac/image/Tips_error.png differ diff --git a/qbot/engine/trade/trading/emt_api/libs/mac/image/edit_bg.png b/qbot/engine/trade/trading/emt_api/libs/mac/image/edit_bg.png new file mode 100644 index 00000000..117843a9 Binary files /dev/null and b/qbot/engine/trade/trading/emt_api/libs/mac/image/edit_bg.png differ diff --git a/qbot/engine/trade/trading/emt_api/libs/mac/image/tab1_bg.png b/qbot/engine/trade/trading/emt_api/libs/mac/image/tab1_bg.png new file mode 100644 index 00000000..4b8206e1 Binary files /dev/null and b/qbot/engine/trade/trading/emt_api/libs/mac/image/tab1_bg.png differ diff --git a/qbot/engine/trade/trading/emt_api/libs/mac/image/tab2_bg.png b/qbot/engine/trade/trading/emt_api/libs/mac/image/tab2_bg.png new file mode 100644 index 00000000..ac3e037c Binary files /dev/null and b/qbot/engine/trade/trading/emt_api/libs/mac/image/tab2_bg.png differ diff --git a/qbot/engine/trade/trading/emt_api/libs/mac/image/tab3_bg.png b/qbot/engine/trade/trading/emt_api/libs/mac/image/tab3_bg.png new file mode 100644 index 00000000..0f1ded28 Binary files /dev/null and b/qbot/engine/trade/trading/emt_api/libs/mac/image/tab3_bg.png differ diff --git a/qbot/engine/trade/trading/emt_api/libs/mac/libEMQuantAPIx64.dylib b/qbot/engine/trade/trading/emt_api/libs/mac/libEMQuantAPIx64.dylib new file mode 100644 index 00000000..b7e4a5ff Binary files /dev/null and b/qbot/engine/trade/trading/emt_api/libs/mac/libEMQuantAPIx64.dylib differ diff --git a/qbot/engine/trade/trading/emt_api/libs/mac/loginactivator_mac b/qbot/engine/trade/trading/emt_api/libs/mac/loginactivator_mac new file mode 100644 index 00000000..3f74dff3 Binary files /dev/null and b/qbot/engine/trade/trading/emt_api/libs/mac/loginactivator_mac differ diff --git a/qbot/engine/trade/trading/emt_api/libs/windows/EmQuantAPI.dll b/qbot/engine/trade/trading/emt_api/libs/windows/EmQuantAPI.dll new file mode 100644 index 00000000..69d18d32 Binary files /dev/null and b/qbot/engine/trade/trading/emt_api/libs/windows/EmQuantAPI.dll differ diff --git a/qbot/engine/trade/trading/emt_api/libs/windows/EmQuantAPI_x64.dll b/qbot/engine/trade/trading/emt_api/libs/windows/EmQuantAPI_x64.dll new file mode 100644 index 00000000..45952193 Binary files /dev/null and b/qbot/engine/trade/trading/emt_api/libs/windows/EmQuantAPI_x64.dll differ diff --git a/qbot/engine/trade/trading/emt_api/libs/windows/LoginActivator.exe b/qbot/engine/trade/trading/emt_api/libs/windows/LoginActivator.exe new file mode 100644 index 00000000..8fbeef95 Binary files /dev/null and b/qbot/engine/trade/trading/emt_api/libs/windows/LoginActivator.exe differ diff --git a/qbot/engine/trade/trading/emt_api/libs/windows/ServerList.json.e b/qbot/engine/trade/trading/emt_api/libs/windows/ServerList.json.e new file mode 100644 index 00000000..78b3f67f --- /dev/null +++ b/qbot/engine/trade/trading/emt_api/libs/windows/ServerList.json.e @@ -0,0 +1 @@ +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 \ No newline at end of file diff --git a/qbot/engine/trade/trading/thsauto/.gitignore b/qbot/engine/trade/trading/thsauto/.gitignore new file mode 100644 index 00000000..c57c7108 --- /dev/null +++ b/qbot/engine/trade/trading/thsauto/.gitignore @@ -0,0 +1,3 @@ +**/__pycache__ +**/.vscode +ocr.png \ No newline at end of file diff --git a/qbot/engine/trade/trading/thsauto/README.md b/qbot/engine/trade/trading/thsauto/README.md new file mode 100644 index 00000000..db7dcdea --- /dev/null +++ b/qbot/engine/trade/trading/thsauto/README.md @@ -0,0 +1,32 @@ +# thsauto +同花顺自动下单工具 + +``` +python .\server.py 192.168.0.116 5000 C:\Users\match\Desktop\THS\xiadan.exe +``` +- 查询资金账户 +http://192.168.0.116:5000/thsauto/balance +- 查询持仓 +http://192.168.0.116:5000/thsauto/position +- 买入下单 +http://192.168.0.116:5000/thsauto/buy?stock_no=600000&price=10.00&amount=100 +- 卖出下单 +http://192.168.0.116:5000/thsauto/sell?stock_no=600000&price=10.00&amount=100 +- 科创板买入下单 +http://192.168.0.116:5000/thsauto/buy/kc?stock_no=688819&price=40.00&amount=200 +- 科创板卖出下单 +http://192.168.0.116:5000/thsauto/sell/kc?stock_no=688819&price=40.00&amount=200 +- 查询未成订单 +http://192.168.0.116:5000/thsauto/orders/active +- 查询已成订单 +http://192.168.0.116:5000/thsauto/orders/filled +- 撤单 +http://192.168.0.116:5000/thsauto/cancel?entrust_no=2060704404 +- 关闭同花顺客户端 +http://192.168.0.116:5000/thsauto/client/kill +- 重启同花顺客户端 +http://192.168.0.116:5000/thsauto/client/restart + + + +more: https://blog.csdn.net/liuyukuan/article/details/117828103 diff --git a/qbot/engine/trade/trading/thsauto/const.py b/qbot/engine/trade/trading/thsauto/const.py new file mode 100644 index 00000000..cf854fb2 --- /dev/null +++ b/qbot/engine/trade/trading/thsauto/const.py @@ -0,0 +1,159 @@ +VK_CODE = { + "backspace": 0x08, + "tab": 0x09, + "clear": 0x0C, + "enter": 0x0D, + "shift": 0x10, + "ctrl": 0x11, + "alt": 0x12, + "pause": 0x13, + "caps_lock": 0x14, + "esc": 0x1B, + "spacebar": 0x20, + "page_up": 0x21, + "page_down": 0x22, + "end": 0x23, + "home": 0x24, + "left_arrow": 0x25, + "up_arrow": 0x26, + "right_arrow": 0x27, + "down_arrow": 0x28, + "select": 0x29, + "print": 0x2A, + "execute": 0x2B, + "print_screen": 0x2C, + "ins": 0x2D, + "del": 0x2E, + "help": 0x2F, + "0": 0x30, + "1": 0x31, + "2": 0x32, + "3": 0x33, + "4": 0x34, + "5": 0x35, + "6": 0x36, + "7": 0x37, + "8": 0x38, + "9": 0x39, + "a": 0x41, + "b": 0x42, + "c": 0x43, + "d": 0x44, + "e": 0x45, + "f": 0x46, + "g": 0x47, + "h": 0x48, + "i": 0x49, + "j": 0x4A, + "k": 0x4B, + "l": 0x4C, + "m": 0x4D, + "n": 0x4E, + "o": 0x4F, + "p": 0x50, + "q": 0x51, + "r": 0x52, + "s": 0x53, + "t": 0x54, + "u": 0x55, + "v": 0x56, + "w": 0x57, + "x": 0x58, + "y": 0x59, + "z": 0x5A, + "numpad_0": 0x60, + "numpad_1": 0x61, + "numpad_2": 0x62, + "numpad_3": 0x63, + "numpad_4": 0x64, + "numpad_5": 0x65, + "numpad_6": 0x66, + "numpad_7": 0x67, + "numpad_8": 0x68, + "numpad_9": 0x69, + "multiply_key": 0x6A, + "add_key": 0x6B, + "separator_key": 0x6C, + "subtract_key": 0x6D, + "decimal_key": 0x6E, + "divide_key": 0x6F, + "F1": 0x70, + "F2": 0x71, + "F3": 0x72, + "F4": 0x73, + "F5": 0x74, + "F6": 0x75, + "F7": 0x76, + "F8": 0x77, + "F9": 0x78, + "F10": 0x79, + "F11": 0x7A, + "F12": 0x7B, + "F13": 0x7C, + "F14": 0x7D, + "F15": 0x7E, + "F16": 0x7F, + "F17": 0x80, + "F18": 0x81, + "F19": 0x82, + "F20": 0x83, + "F21": 0x84, + "F22": 0x85, + "F23": 0x86, + "F24": 0x87, + "num_lock": 0x90, + "scroll_lock": 0x91, + "left_shift": 0xA0, + "right_shift ": 0xA1, + "left_control": 0xA2, + "right_control": 0xA3, + "left_menu": 0xA4, + "right_menu": 0xA5, + "browser_back": 0xA6, + "browser_forward": 0xA7, + "browser_refresh": 0xA8, + "browser_stop": 0xA9, + "browser_search": 0xAA, + "browser_favorites": 0xAB, + "browser_start_and_home": 0xAC, + "volume_mute": 0xAD, + "volume_Down": 0xAE, + "volume_up": 0xAF, + "next_track": 0xB0, + "previous_track": 0xB1, + "stop_media": 0xB2, + "play/pause_media": 0xB3, + "start_mail": 0xB4, + "select_media": 0xB5, + "start_application_1": 0xB6, + "start_application_2": 0xB7, + "attn_key": 0xF6, + "crsel_key": 0xF7, + "exsel_key": 0xF8, + "play_key": 0xFA, + "zoom_key": 0xFB, + "clear_key": 0xFE, + "+": 0xBB, + ",": 0xBC, + "-": 0xBD, + ".": 0xBE, + "/": 0xBF, + ";": 0xBA, + "[": 0xDB, + "\\": 0xDC, + "]": 0xDD, + "'": 0xDE, + "`": 0xC0, +} + +BALANCE_CONTROL_ID_GROUP = { + "资金余额": 0x3F4, + "冻结金额": 0x3F5, + "可用金额": 0x3F8, + "可取金额": 0x3F9, + "股票市值": 0x3F6, + "总资产": 0x3F7, + "持仓盈亏": 0x403, + "当日盈亏": 0x402, + "当日盈亏比": 0x405, +} diff --git a/qbot/engine/trade/trading/thsauto/server.py b/qbot/engine/trade/trading/thsauto/server.py new file mode 100644 index 00000000..17babf9a --- /dev/null +++ b/qbot/engine/trade/trading/thsauto/server.py @@ -0,0 +1,183 @@ +import functools +import os +import sys +import threading +import time + +from flask import Flask, jsonify, request +from thsauto import ThsAuto + +app = Flask(__name__) +app.config["JSON_AS_ASCII"] = False + +auto = ThsAuto() + +client_path = None + + +def run_client(): + os.system("start " + client_path) + + +lock = threading.Lock() +next_time = 0 +interval = 0.5 + + +def interval_call(func): + @functools.wraps(func) + def wrapper(*args, **kwargs): + global interval + global lock + global next_time + lock.acquire() + now = time.time() + if now < next_time: + time.sleep(next_time - now) + try: + rt = func(*args, **kwargs) + except Exception as e: + rt = ({"code": 1, "status": "failed", "msg": "{}".format(e)}, 400) + next_time = time.time() + interval + lock.release() + return rt + + return wrapper + + +@app.route("/thsauto/balance", methods=["GET"]) +@interval_call +def get_balance(): + auto.active_mian_window() + result = auto.get_balance() + return jsonify(result), 200 + + +@app.route("/thsauto/position", methods=["GET"]) +@interval_call +def get_position(): + auto.active_mian_window() + result = auto.get_position() + return jsonify(result), 200 + + +@app.route("/thsauto/orders/active", methods=["GET"]) +@interval_call +def get_active_orders(): + auto.active_mian_window() + result = auto.get_active_orders() + return jsonify(result), 200 + + +@app.route("/thsauto/orders/filled", methods=["GET"]) +@interval_call +def get_filled_orders(): + auto.active_mian_window() + result = auto.get_filled_orders() + return jsonify(result), 200 + + +@app.route("/thsauto/sell", methods=["GET"]) +@interval_call +def sell(): + auto.active_mian_window() + stock = request.args["stock_no"] + amount = request.args["amount"] + price = request.args.get("price", None) + if price is not None: + price = float(price) + result = auto.sell(stock_no=stock, amount=int(amount), price=price) + return jsonify(result), 200 + + +@app.route("/thsauto/buy", methods=["GET"]) +@interval_call +def buy(): + auto.active_mian_window() + stock = request.args["stock_no"] + amount = request.args["amount"] + price = request.args.get("price", None) + if price is not None: + price = float(price) + result = auto.buy(stock_no=stock, amount=int(amount), price=price) + return jsonify(result), 200 + + +@app.route("/thsauto/buy/kc", methods=["GET"]) +@interval_call +def buy_kc(): + auto.active_mian_window() + stock = request.args["stock_no"] + amount = request.args["amount"] + price = request.args.get("price", None) + if price is not None: + price = float(price) + result = auto.buy_kc(stock_no=stock, amount=int(amount), price=price) + return jsonify(result), 200 + + +@app.route("/thsauto/sell/kc", methods=["GET"]) +@interval_call +def sell_kc(): + auto.active_mian_window() + stock = request.args["stock_no"] + amount = request.args["amount"] + price = request.args.get("price", None) + if price is not None: + price = float(price) + result = auto.sell_kc(stock_no=stock, amount=int(amount), price=price) + return jsonify(result), 200 + + +@app.route("/thsauto/cancel", methods=["GET"]) +@interval_call +def cancel(): + auto.active_mian_window() + entrust_no = request.args["entrust_no"] + result = auto.cancel(entrust_no=entrust_no) + return jsonify(result), 200 + + +@app.route("/thsauto/client/kill", methods=["GET"]) +@interval_call +def kill_client(): + auto.active_mian_window() + auto.kill_client() + return jsonify({"code": 0, "status": "succeed"}), 200 + + +@app.route("/thsauto/client/restart", methods=["GET"]) +@interval_call +def restart_client(): + auto.active_mian_window() + auto.kill_client() + run_client() + time.sleep(5) + auto.bind_client() + if auto.hwnd_main is None: + return jsonify({"code": 1, "status": "failed"}), 200 + else: + return jsonify({"code": 0, "status": "succeed"}), 200 + + +@app.route("/thsauto/test", methods=["GET"]) +@interval_call +def test(): + auto.active_mian_window() + auto.test() + return jsonify({}), 200 + + +if __name__ == "__main__": + host = "127.0.0.1" + port = 5000 + if len(sys.argv) > 1: + host = sys.argv[1] + if len(sys.argv) > 2: + port = int(sys.argv[2]) + if len(sys.argv) > 3: + client_path = sys.argv[3] + auto.bind_client() + if auto.hwnd_main is None and client_path is not None: + restart_client() + app.run(host=host, port=port) diff --git a/qbot/engine/trade/trading/thsauto/test.py b/qbot/engine/trade/trading/thsauto/test.py new file mode 100644 index 00000000..39e14688 --- /dev/null +++ b/qbot/engine/trade/trading/thsauto/test.py @@ -0,0 +1,29 @@ +# -*- coding: utf-8 -*- + +from thsauto import ThsAuto + +if __name__ == "__main__": + + auto = ThsAuto() # 连接客户端 + + print("可用资金") + print(auto.get_balance()) # 获取当前可用资金 + print("持仓") + print(auto.get_position()) # 获取当前持有的股票 + + print("卖出") + print(auto.sell(stock_no="162411", amount=200, price=0.4035)) # 卖出股票 + + print("买入") + result = auto.buy(stock_no="162411", amount=100, price=0.41) # 买入股票 + print(result) + + print("已成交") + print(auto.get_filled_orders()) # 获取已成交订单 + + print("未成交") + print(auto.get_active_orders()) # 获取未成交订单 + + if result and result["code"] == 0: # 如果买入下单成功,尝试撤单 + print("撤单") + print(auto.cancel(entrust_no=result["entrust_no"])) diff --git a/qbot/engine/trade/trading/thsauto/thsauto.py b/qbot/engine/trade/trading/thsauto/thsauto.py new file mode 100644 index 00000000..869642e5 --- /dev/null +++ b/qbot/engine/trade/trading/thsauto/thsauto.py @@ -0,0 +1,575 @@ +import ctypes +import os +import time + +import ddddocr +import win32api +import win32clipboard +import win32con +import win32gui +import win32process +import win32ui +from const import BALANCE_CONTROL_ID_GROUP, VK_CODE +from PIL import Image + +DdddOcr = ddddocr.DdddOcr() + +sleep_time = 0.2 +refresh_sleep_time = 0.5 +retry_time = 10 + +window_title = "网上股票交易系统5.0" + + +def get_clipboard_data(): + win32clipboard.OpenClipboard() + try: + data = win32clipboard.GetClipboardData(win32clipboard.CF_UNICODETEXT) + finally: + win32clipboard.CloseClipboard() + return data + + +def hot_key(keys): + time.sleep(sleep_time) + for key in keys: + win32api.keybd_event(VK_CODE[key], 0, 0, 0) + for key in reversed(keys): + win32api.keybd_event(VK_CODE[key], 0, win32con.KEYEVENTF_KEYUP, 0) + + +def set_text(hwnd, string): + win32gui.SetForegroundWindow(hwnd) + win32api.SendMessage(hwnd, win32con.EM_SETSEL, 0, -1) + win32api.keybd_event(VK_CODE["backspace"], 0, 0, 0) + win32api.keybd_event(VK_CODE["backspace"], 0, win32con.KEYEVENTF_KEYUP, 0) + for char in string: + if char.isupper(): + win32api.keybd_event(0xA0, 0, 0, 0) + win32api.keybd_event(VK_CODE[char.lower()], 0, 0, 0) + win32api.keybd_event(VK_CODE[char.lower()], 0, win32con.KEYEVENTF_KEYUP, 0) + win32api.keybd_event(0xA0, 0, win32con.KEYEVENTF_KEYUP, 0) + else: + win32api.keybd_event(VK_CODE[char], 0, 0, 0) + win32api.keybd_event(VK_CODE[char], 0, win32con.KEYEVENTF_KEYUP, 0) + + +def get_text(hwnd): + length = ctypes.windll.user32.SendMessageW(hwnd, win32con.WM_GETTEXTLENGTH) + buf = ctypes.create_unicode_buffer(length + 1) + ctypes.windll.user32.SendMessageW( + hwnd, win32con.WM_GETTEXT, length, ctypes.byref(buf) + ) + return buf.value + + +def parse_table(text): + lines = text.split("\t\r\n") + keys = lines[0].split("\t") + result = [] + for i in range(1, len(lines)): + info = {} + items = lines[i].split("\t") + for j in range(len(keys)): + info[keys[j]] = items[j] + result.append(info) + return result + + +class ThsAuto: + + def __init__(self): + self.hwnd_main = None + + def bind_client(self): + hwnd = win32gui.FindWindow(None, window_title) + if hwnd > 0: + win32gui.SetForegroundWindow(hwnd) + self.hwnd_main = hwnd + + def kill_client(self): + self.hwnd_main = None + retry = 5 + while retry > 0: + hwnd = win32gui.FindWindow(None, window_title) + if hwnd == 0: + time.sleep(1) + break + else: + win32gui.SetForegroundWindow(hwnd) + time.sleep(sleep_time) + hot_key(["alt", "F4"]) + time.sleep(1) + retry -= 1 + + def get_tree_hwnd(self): + hwnd = self.hwnd_main + hwnd = win32gui.FindWindowEx(hwnd, None, "AfxMDIFrame140s", None) + hwnd = win32gui.FindWindowEx(hwnd, None, "AfxWnd140s", None) + hwnd = win32gui.FindWindowEx(hwnd, None, None, "HexinScrollWnd") + hwnd = win32gui.FindWindowEx(hwnd, None, "AfxWnd140s", None) + hwnd = win32gui.FindWindowEx(hwnd, None, "SysTreeView32", None) + return hwnd + + def get_right_hwnd(self): + hwnd = self.hwnd_main + hwnd = win32gui.FindWindowEx(hwnd, None, "AfxMDIFrame140s", None) + hwnd = win32gui.GetDlgItem(hwnd, 0xE901) + return hwnd + + def get_left_bottom_tabs(self): + hwnd = self.hwnd_main + hwnd = win32gui.FindWindowEx(hwnd, None, "AfxMDIFrame140s", None) + hwnd = win32gui.FindWindowEx(hwnd, None, "AfxWnd140s", None) + hwnd = win32gui.FindWindowEx(hwnd, None, "CCustomTabCtrl", None) + return hwnd + + def get_ocr_hwnd(self): + tid, pid = win32process.GetWindowThreadProcessId(self.hwnd_main) + + def enum_children(hwnd, results): + try: + if win32gui.IsWindowVisible(hwnd) and win32gui.IsWindowEnabled(hwnd): + win32gui.EnumChildWindows(hwnd, handler, results) + except Exception: + return + + def handler(hwnd, results): + if win32gui.GetClassName(hwnd) == "Static": + results.append(hwnd) + return False + enum_children(hwnd, results) + return len(results) == 0 + + popups = [] + windows = [] + win32gui.EnumThreadWindows(tid, lambda hwnd, line: line.append(hwnd), windows) + for hwnd in windows: + if not handler(hwnd, popups): + break + for ctrl in popups: + text = get_text(ctrl) + if "检测到您正在拷贝数据" in text: + return ctypes.windll.user32.GetWindow(ctrl, win32con.GW_HWNDNEXT) + return 0 + + def get_balance(self): + self.switch_to_normal() + hot_key(["F4"]) + self.refresh() + hwnd = self.get_right_hwnd() + data = {} + for key, cid in BALANCE_CONTROL_ID_GROUP.items(): + ctrl = win32gui.GetDlgItem(hwnd, cid) + if ctrl > 0 and win32gui.IsWindowVisible(ctrl): + data[key] = get_text(ctrl) + return { + "code": 0, + "status": "succeed", + "data": data, + } + + def get_position(self): + self.switch_to_normal() + hot_key(["F1"]) + hot_key(["F6"]) + self.refresh() + hwnd = self.get_right_hwnd() + ctrl = win32gui.GetDlgItem(hwnd, 0x417) + + self.copy_table(ctrl) + + data = None + retry = 0 + while not data and retry < retry_time: + retry += 1 + time.sleep(sleep_time) + data = get_clipboard_data() + if data: + return { + "code": 0, + "status": "succeed", + "data": parse_table(data), + } + return {"code": 1, "status": "failed"} + + def get_active_orders(self): + self.switch_to_normal() + hot_key(["F1"]) + hot_key(["F8"]) + self.refresh() + hwnd = self.get_right_hwnd() + ctrl = win32gui.GetDlgItem(hwnd, 0x417) + + self.copy_table(ctrl) + + data = None + retry = 0 + while not data and retry < retry_time: + retry += 1 + time.sleep(sleep_time) + data = get_clipboard_data() + if data: + return { + "code": 0, + "status": "succeed", + "data": parse_table(data), + } + return {"code": 1, "status": "failed"} + + def get_filled_orders(self): + self.switch_to_normal() + hot_key(["F2"]) + hot_key(["F7"]) + self.refresh() + hwnd = self.get_right_hwnd() + ctrl = win32gui.GetDlgItem(hwnd, 0x417) + + self.copy_table(ctrl) + + data = None + retry = 0 + while not data and retry < retry_time: + retry += 1 + time.sleep(sleep_time) + data = get_clipboard_data() + if data: + return { + "code": 0, + "status": "succeed", + "data": parse_table(data), + } + return {"code": 1, "status": "failed"} + + def sell(self, stock_no, amount, price): + self.switch_to_normal() + hot_key(["F2"]) + time.sleep(sleep_time) + hwnd = self.get_right_hwnd() + ctrl = win32gui.GetDlgItem(hwnd, 0x408) + set_text(ctrl, stock_no) + time.sleep(sleep_time) + if price is not None: + time.sleep(sleep_time) + price = "%.3f" % price + ctrl = win32gui.GetDlgItem(hwnd, 0x409) + set_text(ctrl, price) + time.sleep(sleep_time) + ctrl = win32gui.GetDlgItem(hwnd, 0x40A) + set_text(ctrl, str(amount)) + time.sleep(sleep_time) + hot_key(["enter"]) + result = None + retry = 0 + while retry < retry_time: + time.sleep(sleep_time) + result = self.get_result() + if result: + hot_key(["enter"]) + return result + hot_key(["y"]) + retry += 1 + return { + "code": 2, + "status": "unknown", + "msg": "获取结果失败,请自行确认订单状态", + } + + def buy(self, stock_no, amount, price): + self.switch_to_normal() + hot_key(["F1"]) + time.sleep(sleep_time) + hwnd = self.get_right_hwnd() + ctrl = win32gui.GetDlgItem(hwnd, 0x408) + set_text(ctrl, stock_no) + time.sleep(sleep_time) + if price is not None: + time.sleep(sleep_time) + price = "%.3f" % price + ctrl = win32gui.GetDlgItem(hwnd, 0x409) + set_text(ctrl, price) + time.sleep(sleep_time) + ctrl = win32gui.GetDlgItem(hwnd, 0x40A) + set_text(ctrl, str(amount)) + time.sleep(sleep_time) + hot_key(["enter"]) + result = None + retry = 0 + while retry < retry_time: + time.sleep(sleep_time) + result = self.get_result() + if result: + hot_key(["enter"]) + return result + hot_key(["y"]) + retry += 1 + return { + "code": 2, + "status": "unknown", + "msg": "获取结果失败,请自行确认订单状态", + } + + def sell_kc(self, stock_no, amount, price): + self.switch_to_kechuang() + self.click_kc_sell() + hwnd = self.get_right_hwnd() + ctrl = win32gui.GetDlgItem(hwnd, 0x408) + set_text(ctrl, stock_no) + time.sleep(sleep_time) + if price is not None: + time.sleep(sleep_time) + price = "%.3f" % price + ctrl = win32gui.GetDlgItem(hwnd, 0x409) + set_text(ctrl, price) + time.sleep(sleep_time) + ctrl = win32gui.GetDlgItem(hwnd, 0x40A) + set_text(ctrl, str(amount)) + time.sleep(sleep_time) + hot_key(["enter"]) + result = None + retry = 0 + while retry < retry_time: + time.sleep(sleep_time) + result = self.get_result() + if result: + hot_key(["enter"]) + return result + hot_key(["y"]) + retry += 1 + return { + "code": 2, + "status": "unknown", + "msg": "获取结果失败,请自行确认订单状态", + } + + def buy_kc(self, stock_no, amount, price): + self.switch_to_kechuang() + self.click_kc_buy() + hwnd = self.get_right_hwnd() + ctrl = win32gui.GetDlgItem(hwnd, 0x408) + set_text(ctrl, stock_no) + time.sleep(sleep_time) + if price is not None: + time.sleep(sleep_time) + price = "%.3f" % price + ctrl = win32gui.GetDlgItem(hwnd, 0x409) + set_text(ctrl, price) + time.sleep(sleep_time) + ctrl = win32gui.GetDlgItem(hwnd, 0x40A) + set_text(ctrl, str(amount)) + time.sleep(sleep_time) + hot_key(["enter"]) + result = None + retry = 0 + while retry < retry_time: + time.sleep(sleep_time) + result = self.get_result() + if result: + hot_key(["enter"]) + return result + hot_key(["y"]) + retry += 1 + return { + "code": 2, + "status": "unknown", + "msg": "获取结果失败,请自行确认订单状态", + } + + def cancel(self, entrust_no): + self.switch_to_normal() + hot_key(["F3"]) + self.refresh() + hwnd = self.get_right_hwnd() + ctrl = win32gui.GetDlgItem(hwnd, 0x417) + + self.copy_table(ctrl) + + data = None + retry = 0 + while not data and retry < retry_time: + retry += 1 + time.sleep(sleep_time) + data = get_clipboard_data() + if data: + entrusts = parse_table(data) + find = None + for i, entrust in enumerate(entrusts): + if str(entrust["合同编号"]) == str(entrust_no): + find = i + break + if find is None: + return {"code": 1, "status": "failed", "msg": "没找到指定订单"} + left, top, right, bottom = win32gui.GetWindowRect(ctrl) + x = 50 + left + y = 30 + 16 * find + top + win32api.SetCursorPos((x, y)) + win32api.mouse_event(win32con.MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0) + win32api.mouse_event(win32con.MOUSEEVENTF_LEFTUP, 0, 0, 0, 0) + time.sleep(sleep_time) + win32api.mouse_event(win32con.MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0) + win32api.mouse_event(win32con.MOUSEEVENTF_LEFTUP, 0, 0, 0, 0) + time.sleep(sleep_time) + hot_key(["enter"]) + return {"code": 0, "status": "succeed"} + return {"code": 1, "status": "failed"} + + def get_result(self, cid=0x3EC): + tid, pid = win32process.GetWindowThreadProcessId(self.hwnd_main) + + def enum_children(hwnd, results): + try: + if win32gui.IsWindowVisible(hwnd) and win32gui.IsWindowEnabled(hwnd): + win32gui.EnumChildWindows(hwnd, handler, results) + except Exception: + return + + def handler(hwnd, results): + if ( + win32api.GetWindowLong(hwnd, win32con.GWL_ID) == cid + and win32gui.GetClassName(hwnd) == "Static" + ): + results.append(hwnd) + return False + enum_children(hwnd, results) + return len(results) == 0 + + popups = [] + windows = [] + win32gui.EnumThreadWindows(tid, lambda hwnd, line: line.append(hwnd), windows) + for hwnd in windows: + if not handler(hwnd, popups): + break + if popups: + ctrl = popups[0] + text = get_text(ctrl) + if "已成功提交" in text: + return { + "code": 0, + "status": "succeed", + "msg": text, + "entrust_no": text.split("合同编号:")[1].split("。")[0], + } + else: + return { + "code": 1, + "status": "failed", + "msg": text, + } + + def refresh(self): + hot_key(["F5"]) + time.sleep(refresh_sleep_time) + + def active_mian_window(self): + if self.hwnd_main is not None: + ctypes.windll.user32.SwitchToThisWindow(self.hwnd_main, True) + time.sleep(sleep_time) + + def right_click_menu(self, hwnd, x, y, idx=None, key=None): + left, top, right, bottom = win32gui.GetWindowRect(hwnd) + x = left + x if x > 0 else right + x + y = top + y if y > 0 else bottom + y + win32api.SetCursorPos((x, y)) + win32api.mouse_event(win32con.MOUSEEVENTF_RIGHTDOWN, 0, 0, 0, 0) + win32api.mouse_event(win32con.MOUSEEVENTF_RIGHTUP, 0, 0, 0, 0) + time.sleep(sleep_time) + if idx is not None: + while idx >= 0: + hot_key(["down_arrow"]) + idx -= 1 + hot_key(["enter"]) + elif hot_key is not None: + if isinstance(key, list): + hot_key(key) + else: + hot_key([key]) + + def switch_to_normal(self): + tabs = self.get_left_bottom_tabs() + left, top, right, bottom = win32gui.GetWindowRect(tabs) + x = left + 10 + y = top + 5 + win32api.SetCursorPos((x, y)) + win32api.mouse_event(win32con.MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0) + win32api.mouse_event(win32con.MOUSEEVENTF_LEFTUP, 0, 0, 0, 0) + time.sleep(sleep_time) + + def switch_to_kechuang(self): + tabs = self.get_left_bottom_tabs() + left, top, right, bottom = win32gui.GetWindowRect(tabs) + x = left + 200 + y = top + 5 + win32api.SetCursorPos((x, y)) + win32api.mouse_event(win32con.MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0) + win32api.mouse_event(win32con.MOUSEEVENTF_LEFTUP, 0, 0, 0, 0) + time.sleep(sleep_time) + + def click_kc_buy(self): + tree = self.get_tree_hwnd() + left, top, right, bottom = win32gui.GetWindowRect(tree) + x = left + 10 + y = top + 10 + win32api.SetCursorPos((x, y)) + win32api.mouse_event(win32con.MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0) + win32api.mouse_event(win32con.MOUSEEVENTF_LEFTUP, 0, 0, 0, 0) + win32api.mouse_event(win32con.MOUSEEVENTF_LEFTUP, 0, 0, 0, 0) + time.sleep(sleep_time) + + def click_kc_sell(self): + tree = self.get_tree_hwnd() + left, top, right, bottom = win32gui.GetWindowRect(tree) + x = left + 10 + y = top + 30 + win32api.SetCursorPos((x, y)) + win32api.mouse_event(win32con.MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0) + win32api.mouse_event(win32con.MOUSEEVENTF_LEFTUP, 0, 0, 0, 0) + win32api.mouse_event(win32con.MOUSEEVENTF_LEFTUP, 0, 0, 0, 0) + time.sleep(sleep_time) + + def copy_table(self, hwnd): + win32gui.SetForegroundWindow(hwnd) + os.system("echo off | clip") + hot_key(["ctrl", "c"]) + self.input_ocr() + + def input_ocr(self): + ocr = self.get_ocr_hwnd() + if ocr > 0: + self.capture_window(ocr, "ocr.png") + with open("ocr.png", "rb") as f: + data = f.read() + code = DdddOcr.classification(data) + ctrl = ctypes.windll.user32.GetWindow(ocr, win32con.GW_HWNDNEXT) + ctrl = ctypes.windll.user32.GetWindow(ctrl, win32con.GW_HWNDNEXT) + ctrl = ctypes.windll.user32.GetWindow(ctrl, win32con.GW_HWNDNEXT) + set_text(ctrl, code) + hot_key(["enter"]) + + def capture_window(self, hwnd, file_name): + left, top, right, bottom = win32gui.GetWindowRect(hwnd) + width = right - left + height = bottom - top + + hdc = win32gui.GetWindowDC(hwnd) + dc = win32ui.CreateDCFromHandle(hdc) + cdc = dc.CreateCompatibleDC() + bmp = win32ui.CreateBitmap() + bmp.CreateCompatibleBitmap(dc, width, height) + cdc.SelectObject(bmp) + cdc.BitBlt((0, 0), (width, height), dc, (0, 0), win32con.SRCCOPY) + + info = bmp.GetInfo() + bits = bmp.GetBitmapBits(True) + img = Image.frombuffer( + "RGB", (info["bmWidth"], info["bmHeight"]), bits, "raw", "BGRX", 0, 1 + ) + + win32gui.DeleteObject(bmp.GetHandle()) + dc.DeleteDC() + cdc.DeleteDC() + win32gui.ReleaseDC(hwnd, hdc) + + img.save(file_name) + + def test(self): + pass diff --git a/qbot/gui/common/PrintLog.py b/qbot/gui/common/PrintLog.py new file mode 100644 index 00000000..6bacc3e0 --- /dev/null +++ b/qbot/gui/common/PrintLog.py @@ -0,0 +1,37 @@ +#! /usr/bin/env python +# -*- encoding: utf-8 -*- + +from datetime import datetime + + +class SysLogIf: + + error = "错误" + warning = "警告" + info = "信息" + ind = "通知" + + def __init__(self, descr_obj): + self.time = datetime.now().strftime("%Y-%m-%d %H:%M:%S") + self.descr_obj = descr_obj + + def re_print(self, cont): + self.descr_obj.AppendText(self.time + ":\n" + cont + "\n") + + def clr_print(self): + self.descr_obj.Clear() + + +class PatLogIf: + + def __init__(self, descr_obj): + self.descr_obj = descr_obj + + def re_print(self, cont): + self.descr_obj.AppendText(cont + "\n") + + def get_values(self): + return self.descr_obj.GetValue() + + def clr_print(self): + self.descr_obj.Clear() diff --git a/qbot/gui/common/SysFile.py b/qbot/gui/common/SysFile.py new file mode 100644 index 00000000..f1c3a27b --- /dev/null +++ b/qbot/gui/common/SysFile.py @@ -0,0 +1,110 @@ +#! /usr/bin/env python +# -*- encoding: utf-8 -*- + +import json +import os + +import pandas as pd + +QBOT_TOP_PATH = os.path.dirname( + os.path.dirname(os.path.dirname(os.path.dirname(__file__))) +) + + +class Base_File_Oper: + rel_path = QBOT_TOP_PATH + "/qbot/common/configs/" + + @staticmethod + def load_sys_para(filename, filepath=None): + if filepath is None: + filepath = Base_File_Oper.rel_path + with open(filepath + filename, "r", encoding="utf-8") as load_f: + para_dict = json.load(load_f) + return para_dict + + @staticmethod + def save_sys_para(filename, para_dict): + with open(Base_File_Oper.rel_path + filename, "w", encoding="utf-8") as save_f: + json.dump(para_dict, save_f, ensure_ascii=False, indent=4) + + @staticmethod + def load_tushare_basic(): + # 加载tushare basic接口的本地数据 + df_basic = pd.read_csv( + Base_File_Oper.rel_path + "tushare_basic_info.csv", + parse_dates=True, + index_col=0, + encoding="GBK", + ) + return df_basic + + @staticmethod + def save_tushare_basic(df_basic): + # 存储tushare basic接口的本地数据 + df_basic.to_csv( + Base_File_Oper.rel_path + "tushare_basic_info.csv", + columns=df_basic.columns, + index=True, + encoding="GBK", + ) + + @staticmethod + def read_tushare_token(): + # 设置token + with open(Base_File_Oper.rel_path + "token.txt", "r", encoding="utf-8") as f: + token = f.read() # 读取你的token + return token + + @staticmethod + def save_patten_analysis(df_basic, filename): + # 存储形态识别分析结果 + df_basic.to_csv( + Base_File_Oper.rel_path + filename + ".csv", + columns=df_basic.columns, + index=True, + encoding="GBK", + ) + + @staticmethod + def read_log_trade(log_txt="logtrade.txt"): + with open(Base_File_Oper.rel_path + log_txt, "r", encoding="gbk") as f: + info = f.read() + return info + + @staticmethod + def txt2html(txt_file, html_file): + # 读取TXT文件内容 + with open(txt_file, "r", encoding="utf-8") as file: + txt_content = file.read() + + txt_content = [] + with open(txt_file, "r", encoding="utf-8") as file: + for line in file: + txt_content.append(line.strip()) + # print(line.strip()) + + txt_content = "
".join(txt_content) + # 创建HTML内容 + html_content = f""" + + + + Converted from TXT + + +

{txt_content}

+ + + """ + + # 将HTML内容写入文件 + with open(html_file, "w", encoding="utf-8") as file: + file.write(html_content) + + # 打印消息 + print(f"TXT file '{txt_file}' has been converted to HTML file '{html_file}'.") + + +if __name__ == "__main__": + + Base_File_Oper.txt2html("test.log", "test1.html") diff --git a/qbot/gui/elements/def_dialog.py b/qbot/gui/elements/def_dialog.py new file mode 100644 index 00000000..bd7e317d --- /dev/null +++ b/qbot/gui/elements/def_dialog.py @@ -0,0 +1,773 @@ +#! /usr/bin/env python +# -*- encoding: utf-8 -*- + +import datetime +import os + +import matplotlib.pyplot as plt +import numpy as np +import wx +from functools import partial + +from qbot.gui.common.SysFile import Base_File_Oper +from qbot.common.logging.logger import LOGGER as logger + +QBOT_TOP_PATH = os.path.dirname( + os.path.dirname(os.path.dirname(os.path.dirname(__file__))) +) + + +def MessageDialog(info): + # 提示对话框 + # info:提示内容 + back_info = "" + dlg_mesg = wx.MessageDialog(None, info, "温馨提示", wx.YES_NO | wx.ICON_INFORMATION) + if dlg_mesg.ShowModal() == wx.ID_YES: + back_info = "点击Yes" + else: + back_info = "点击No" + dlg_mesg.Destroy() + return back_info + + +def ChoiceDialog(info, choice): + + dlg_mesg = wx.SingleChoiceDialog(None, info, "单选提示", choice) + dlg_mesg.SetSelection(0) # default selection + + if dlg_mesg.ShowModal() == wx.ID_OK: + select = dlg_mesg.GetStringSelection() + else: + select = None + dlg_mesg.Destroy() + return select + +class WebDialog(wx.Dialog): # user-defined + + load_path = os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(__file__)))) + "/data/" + + def __init__( + self, parent, title="Web显示", file_name="treemap_base.html", size=(1200, 900) + ): + + wx.Dialog.__init__( + self, parent, -1, title, size=size, style=wx.DEFAULT_FRAME_STYLE + ) + + self.browser = wx.html2.WebView.New(self, -1, size=size) + with open(self.load_path + file_name, "r") as f: + html_cont = f.read() + self.browser.SetPage(html_cont, "") + self.browser.Show() + +class InputsDialog(wx.Dialog): + def __init__(self, parent, id, title): + wx.Dialog.__init__(self, parent, id, title) + + self.panel = wx.Panel(self) + + self.text1 = wx.TextCtrl(self.panel, pos=(20, 20)) + self.text2 = wx.TextCtrl(self.panel, pos=(20, 60), style=wx.TE_PASSWORD) + + self.ok_button = wx.Button(self.panel, wx.ID_OK, "OK", pos=(20, 100)) + self.cancel_button = wx.Button(self.panel, wx.ID_CANCEL, "Cancel", pos=(120, 100)) + + self.Bind(wx.EVT_BUTTON, self.OnOk, self.ok_button) + + self.Fit() + + def OnOk(self, event): + user = self.text1.GetValue() + password = self.text2.GetValue() + logger.info(f"User: {user}, Password: {password}") + self.EndModal(wx.ID_OK) + + +class InputDialogTwoParameters(wx.Dialog): + def __init__(self, parent, id, title, input_name1="用户名:", input_name2="密码:"): + wx.Dialog.__init__(self, parent, id, title) + + self.panel = wx.Panel(self) + + mainBoxSizer = wx.BoxSizer(wx.VERTICAL) + + # 输入参数1 + textSizer1 = wx.BoxSizer(wx.HORIZONTAL) + self.textLabel1 = wx.StaticText( + self.panel, 0, label=input_name1, pos=(40, 25) + ) + # textFont = wx.Font(12, wx.DECORATIVE, wx.NORMAL, wx.BOLD) + # textLabel1.SetFont(textFont) + textSizer1.Add(self.textLabel1) + textSizer1.Add((10, 10)) + self.text_ctrl1 = wx.TextCtrl(self.panel, pos=(120, 20)) + textSizer1.Add(self.text_ctrl1) + + # 输入参数2 + textSizer2 = wx.BoxSizer(wx.HORIZONTAL) + self.textLabel2 = wx.StaticText( + self.panel, 0, label=input_name2, pos=(40, 70) + ) + # textFont = wx.Font(12, wx.DECORATIVE, wx.NORMAL, wx.BOLD) + # textLabel1.SetFont(textFont) + textSizer2.Add(self.textLabel2) + # textSizer2.Add((10, 10)) + self.text_ctrl2 = wx.TextCtrl(self.panel, pos=(120, 60)) + textSizer2.Add(self.text_ctrl2) + + mainBoxSizer.Add(textSizer1, + proportion=0, + flag=wx.EXPAND | wx.ALL | wx.CENTER, + border=2, + ) + mainBoxSizer.Add(textSizer2, + proportion=0, + flag=wx.EXPAND | wx.ALL | wx.CENTER, + border=2, + ) + + # 创建确认和取消按钮 + self.button_cancel = wx.Button(self.panel, wx.ID_CANCEL, "Cancel", pos=(40, 100)) + self.button_ok = wx.Button(self.panel, wx.ID_OK, "OK", pos=(140, 100)) + self.Bind(wx.EVT_BUTTON, self.OnOk, self.button_ok) + + # 设置对话框的大小 + self.SetSize((300, 200)) + self.Centre() + + def OnOk(self, event): + user = self.text_ctrl1.GetValue() + password = self.text_ctrl1.GetValue() + logger.info(f"User: {user}, Password: {password}") + self.EndModal(wx.ID_OK) + + +class UserDialog(wx.Dialog): # user-defined + def __init__( + self, parent, title="自定义提示信息", label="自定义日志", size=(1024, 768) + ): + wx.Dialog.__init__( + self, parent, -1, title, size=size, style=wx.DEFAULT_FRAME_STYLE + ) + + self.log_tx_input = wx.TextCtrl( + self, -1, "", size=(600, 400), style=wx.TE_MULTILINE | wx.TE_READONLY + ) # 多行|只读 + self.log_tx_input.SetFont(wx.Font(14, wx.DEFAULT, wx.NORMAL, wx.BOLD)) + + self.ok_btn = wx.Button(self, wx.ID_OK, "确认") + self.ok_btn.SetDefault() + + self.dialog_info_box = wx.StaticBox(self, -1, label) + self.dialog_info_sizer = wx.StaticBoxSizer(self.dialog_info_box, wx.VERTICAL) + self.dialog_info_sizer.Add( + self.log_tx_input, + proportion=0, + flag=wx.EXPAND | wx.ALL | wx.CENTER, + border=10, + ) + self.dialog_info_sizer.Add(self.ok_btn, proportion=0, flag=wx.ALIGN_CENTER) + self.SetSizer(self.dialog_info_sizer) + + self.disp_loginfo() + + def disp_loginfo(self): + self.log_tx_input.Clear() + self.log_tx_input.AppendText(Base_File_Oper.read_log_trade()) + +class ParamsConfigDialog(wx.Dialog): + def __init__( + self, parent=None, title="参数配置", displaySize=(1440, 1120) + ): + displaySize_shrink = int(0.7 * displaySize[0]), int(0.6 * displaySize[1]) + wx.Dialog.__init__( + self, parent, -1, title, size=displaySize_shrink, style=wx.DEFAULT_FRAME_STYLE + ) + + # 加载配置文件 + self.firm_para = Base_File_Oper.load_sys_para("firm_para.json") + self.back_para = Base_File_Oper.load_sys_para("back_para.json") + self.sys_para = Base_File_Oper.load_sys_para("sys_para.json") + self.trade_plat_para = Base_File_Oper.load_sys_para("trade_plat_para.json") + self.btc_trade_plat_para = Base_File_Oper.load_sys_para( + "btc_trade_plat_para.json" + ) + + # 创建系统参数配置面板 + self.SysPanel = wx.Panel(self, -1) + + sys_input_box = wx.StaticBox(self.SysPanel, -1, "系统选项") + sys_input_sizer = wx.StaticBoxSizer(sys_input_box, wx.VERTICAL) + + # 初始化操作系统类别 + self.sel_operate_val = ["macos", "windows", "linux_86"] + + self.sel_operate_cmbo = wx.ComboBox( + self.SysPanel, + -1, + self.sys_para["operate_sys"], + choices=self.sel_operate_val, + style=wx.CB_SIMPLE | wx.CB_DROPDOWN | wx.CB_READONLY, + ) # 选择操作系统 + sel_operate_text = wx.StaticText(self.SysPanel, -1, "当前操作系统") + sel_operate_text.SetFont(wx.Font(11, wx.SWISS, wx.NORMAL, wx.NORMAL)) + + # 界面尺寸大小提示 + disp_size_text = wx.StaticText( + self.SysPanel, + -1, + "显示器屏幕尺寸:\n长:{};宽:{}".format(displaySize[0], displaySize[1]), + ) + disp_size_text.SetFont(wx.Font(11, wx.SWISS, wx.NORMAL, wx.NORMAL)) + + sys_input_sizer.Add( + sel_operate_text, proportion=0, flag=wx.EXPAND | wx.ALL, border=2 + ) + sys_input_sizer.Add(self.sel_operate_cmbo, 0, wx.EXPAND | wx.ALL | wx.CENTER, 2) + sys_input_sizer.Add(disp_size_text, 0, wx.EXPAND | wx.ALL | wx.CENTER, 2) + + # 初始化数据存储方式 + data_store_list = ["本地csv", "Sqlite"] + self.data_store_box = wx.RadioBox( + self.SysPanel, + -1, + label="数据存储", + choices=data_store_list, + majorDimension=2, + style=wx.RA_SPECIFY_COLS, + ) + # 初始化存储变量 + self.data_store_val = self.data_store_box.GetStringSelection() + + # 初始化数据源 + data_src_list = ["tushare", "新浪爬虫", "baostock", "离线csv"] + self.data_src_box = wx.RadioBox( + self.SysPanel, + -1, + label="数据源", + choices=data_src_list, + majorDimension=2, + style=wx.RA_SPECIFY_ROWS, + ) + # 初始化指标变量 + self.data_src_Val = self.data_src_box.GetStringSelection() + + self.hbox_btt = wx.BoxSizer(wx.HORIZONTAL) + + # 保存按钮 + self.save_but = wx.Button(self.SysPanel, -1, "保存参数") + self.save_but.Bind(wx.EVT_BUTTON, self._ev_save_para) # 绑定按钮事件 + + # 取消按钮 + self.cancel_but = wx.Button(self.SysPanel, -1, "取消") + self.cancel_but.Bind(wx.EVT_BUTTON, self.OnClose) # 绑定按钮事件 + self.Bind(wx.EVT_CLOSE, self.OnCloseWindow) + + self.hbox_btt.Add(self.save_but, border=2, flag=wx.EXPAND | wx.ALL) + self.hbox_btt.AddSpacer(20) + self.hbox_btt.Add(self.cancel_but, border=2, flag=wx.EXPAND | wx.ALL) + + vboxnetA = wx.BoxSizer(wx.VERTICAL) # 纵向box + vboxnetA.Add( + sys_input_sizer, proportion=0, flag=wx.EXPAND | wx.BOTTOM, border=10 + ) # proportion参数控制容器尺寸比例 + vboxnetA.Add( + self.data_store_box, proportion=0, flag=wx.EXPAND | wx.BOTTOM, border=10 + ) + vboxnetA.Add( + self.data_src_box, proportion=0, flag=wx.EXPAND | wx.BOTTOM, border=10 + ) + vboxnetA.AddSpacer(30) + vboxnetA.Add( + self.hbox_btt, proportion=0, flag=wx.EXPAND | wx.BOTTOM, border=10 + ) + self.SysPanel.SetSizer(vboxnetA) + + # 创建显示参数配置面板 + self.CtrlPanel = wx.Panel(self, -1) + + # 创建FlexGridSizer布局网格 + # rows 定义GridSizer行数 + # cols 定义GridSizer列数 + # vgap 定义垂直方向上行间距 + # hgap 定义水平方向上列间距 + self.FlexGridSizer = wx.FlexGridSizer(rows=4, cols=4, vgap=10, hgap=10) + + self.trade_plat_ind = { + "国信证券": ["", 201], + "兴业证券": ["", 202], + "国金证券": ["", 203], + "国投证券(原安信)": ["", 204], + "华泰证券": ["", 205], + "银河证券": ["", 206], + "财通证券": ["", 207], + "海通证券": ["", 208], + "国联证券": ["", 209], + "通达信": ["", 210], + "东方财富": ["", 211], + "同花顺": ["", 212], + } + + self.btc_trade_plat_ind = { + "欧易OKX": ["", 201], + "币安Binance": ["", 202], + "火币Huobi": ["", 203], + "CoinBase": ["", 204], + "BitGet": ["", 205], + "Bybit": ["", 206], + } + + # 界面参数配置 + self.sys_ind = { + "多子图MPL的单幅X大小": ["mpl_fig_x", 201], + "多子图MPL的单幅Y大小": ["mpl_fig_y", 202], + "多子图WEB的单幅X大小": ["web_size_x", 203], + "多子图WEB的单幅Y大小": ["web_size_y", 204], + "多子图MPL与左边框距离": ["mpl_fig_left", 205], + "多子图MPL与右边框距离": ["mpl_fig_right", 206], + "多子图MPL与上边框距离": ["mpl_fig_top", 207], + "多子图MPL与下边框距离": ["mpl_fig_bottom", 208], + } + + self.firm_mpl = { + "行情MPL与左边框距离": ["left", 301], + "行情MPL与右边框距离": ["right", 302], + "行情MPL与上边框距离": ["top", 303], + "行情MPL与下边框距离": ["bottom", 304], + } + + self.back_mpl = { + "回测MPL与左边框距离": ["left", 401], + "回测MPL与右边框距离": ["right", 401], + "回测MPL与上边框距离": ["top", 401], + "回测MPL与下边框距离": ["bottom", 401], + } + + self.TradePlatFlexGridSizer = wx.FlexGridSizer(rows=4, cols=4, vgap=10, hgap=10) + trade_plat_box = wx.StaticBox(self.CtrlPanel, -1, "证券交易平台配置") + trade_plat_sizer = wx.StaticBoxSizer(trade_plat_box, wx.HORIZONTAL) + tradePlatLabelFont = wx.Font(8, wx.DEFAULT, wx.NORMAL, wx.BOLD, underline=False) + tradePlatAdsFont = wx.Font( + 8, wx.FONTFAMILY_ROMAN, wx.NORMAL, wx.NORMAL, underline=False + ) + for k, v in self.trade_plat_ind.items(): + self.trade_plat_box = wx.StaticBox(self.CtrlPanel, -1, k) + self.plat_ind_sizer = wx.StaticBoxSizer(self.trade_plat_box, wx.VERTICAL) + + # lable and logo + self.hbox_sizer = wx.BoxSizer(wx.HORIZONTAL) + + bitmap = wx.Bitmap(self.trade_plat_para[k]["icon"]) + image = bitmap.ConvertToImage() + image = image.Rescale(24, 24) + bitmap = wx.Bitmap(image) + static_bitmap = wx.StaticBitmap(self.CtrlPanel, wx.ID_ANY, bitmap) + self.hbox_sizer.Add(static_bitmap, 0, wx.ALL | wx.CENTER, 5) + + self.plat_label_text = wx.StaticText( + self.CtrlPanel, + v[1], + str(self.trade_plat_para[k]["labels"][0]) + + " " + + str(self.trade_plat_para[k]["labels"][1]), + style=wx.TE_PROCESS_ENTER, + ) + self.plat_label_text.SetFont(tradePlatLabelFont) + self.plat_label_text.SetForegroundColour("red") + self.hbox_sizer.Add(self.plat_label_text, 0, wx.ALL | wx.CENTER, 5) + + self.plat_ads_text = wx.StaticText( + self.CtrlPanel, + v[1], + str(self.trade_plat_para[k]["ads"][0]) + + " " + + str(self.trade_plat_para[k]["ads"][1]), + style=wx.TE_PROCESS_ENTER, + ) + self.plat_ads_text.SetFont(tradePlatAdsFont) + self.btn_open_account = wx.Button(self.CtrlPanel, label="立即开户") + self.Bind( + wx.EVT_BUTTON, + partial(self.OnClickOpenAccunt, trade_plat=k), + self.btn_open_account, + ) + + if k in ["国金证券", "华泰证券", "银河证券", "财通证券", "银河证券", "海通证券"]: + self.btn_open_account.SetBackgroundColour("red") + self.btn_open_account.SetForegroundColour("white") + + self.plat_ind_sizer.Add( + self.hbox_sizer, + proportion=0, + flag=wx.EXPAND | wx.ALL | wx.CENTER, + border=2, + ) + self.plat_ind_sizer.Add( + self.plat_ads_text, + proportion=0, + flag=wx.EXPAND | wx.ALL | wx.CENTER, + border=2, + ) + self.plat_ind_sizer.Add( + self.btn_open_account, + proportion=0, + flag=wx.EXPAND | wx.ALL | wx.CENTER, + border=2, + ) + # 加入Sizer中 + self.TradePlatFlexGridSizer.Add( + self.plat_ind_sizer, proportion=1, border=1, flag=wx.ALL | wx.EXPAND + ) + trade_plat_sizer.Add( + self.TradePlatFlexGridSizer, + proportion=0, + flag=wx.EXPAND | wx.ALL | wx.CENTER, + border=2, + ) + + # 虚拟货币交易平台配置 + self.BtcTradePlatFlexGridSizer = wx.FlexGridSizer( + rows=1, cols=6, vgap=10, hgap=10 + ) + btc_trade_plat_box = wx.StaticBox(self.CtrlPanel, -1, "虚拟货币交易平台配置") + btc_trade_plat_sizer = wx.StaticBoxSizer(btc_trade_plat_box, wx.HORIZONTAL) + btcTradePlatLabelFont = wx.Font( + 8, wx.DEFAULT, wx.NORMAL, wx.BOLD, underline=False + ) + btcTradePlatAdsFont = wx.Font( + 8, wx.FONTFAMILY_ROMAN, wx.NORMAL, wx.NORMAL, underline=False + ) + for k, v in self.btc_trade_plat_ind.items(): + self.trade_plat_box1 = wx.StaticBox(self.CtrlPanel, -1, k) + self.btc_plat_ind_vbox_sizer = wx.StaticBoxSizer( + self.trade_plat_box1, wx.VERTICAL + ) + + # lable and logo + self.hbox_sizer2 = wx.BoxSizer(wx.HORIZONTAL) + + bitmap = wx.Bitmap(self.btc_trade_plat_para[k]["icon"]) + image = bitmap.ConvertToImage() + image = image.Rescale(24, 24) + bitmap = wx.Bitmap(image) + static_bitmap = wx.StaticBitmap(self.CtrlPanel, wx.ID_ANY, bitmap) + self.hbox_sizer2.Add(static_bitmap, 0, wx.ALL | wx.CENTER, 5) + + self.btc_plat_label_text = wx.StaticText( + self.CtrlPanel, + v[1], + str(self.btc_trade_plat_para[k]["labels"][0]) + + " " + + str(self.btc_trade_plat_para[k]["labels"][1]), + style=wx.TE_PROCESS_ENTER, + ) + self.btc_plat_label_text.SetFont(btcTradePlatLabelFont) + self.btc_plat_label_text.SetForegroundColour("red") + self.hbox_sizer2.Add(self.btc_plat_label_text, 0, wx.ALL | wx.CENTER, 5) + + self.btc_plat_ads_text = wx.StaticText( + self.CtrlPanel, + v[1], + str(self.btc_trade_plat_para[k]["ads"][0]) + + " " + + str(self.btc_trade_plat_para[k]["ads"][1]), + style=wx.TE_PROCESS_ENTER, + ) + self.btc_plat_ads_text.SetFont(btcTradePlatAdsFont) + self.btn_open_btc_account = wx.Button(self.CtrlPanel, label="立即开户") + self.Bind( + wx.EVT_BUTTON, + partial(self.OnClickOpenBtcAccunt, trade_plat=k), + self.btn_open_btc_account, + ) + + if k in ["欧易OKX", "CoinBase", "BitGet"]: + self.btn_open_btc_account.SetBackgroundColour("red") + self.btn_open_btc_account.SetForegroundColour("white") + + self.btc_plat_ind_vbox_sizer.Add( + self.hbox_sizer2, + proportion=0, + flag=wx.EXPAND | wx.ALL | wx.CENTER, + border=2, + ) + self.btc_plat_ind_vbox_sizer.Add( + self.btc_plat_ads_text, + proportion=0, + flag=wx.EXPAND | wx.ALL | wx.CENTER, + border=2, + ) + self.btc_plat_ind_vbox_sizer.Add( + self.btn_open_btc_account, + proportion=0, + flag=wx.EXPAND | wx.ALL | wx.CENTER, + border=2, + ) + # 加入Sizer中 + self.BtcTradePlatFlexGridSizer.Add( + self.btc_plat_ind_vbox_sizer, proportion=1, border=1, flag=wx.ALL | wx.EXPAND + ) + btc_trade_plat_sizer.Add( + self.BtcTradePlatFlexGridSizer, + proportion=0, + flag=wx.EXPAND | wx.ALL | wx.CENTER, + border=2, + ) + + kdata_plot_box = wx.StaticBox(self.CtrlPanel, -1, "行情可视化参数") + kdata_plot_sizer = wx.StaticBoxSizer(kdata_plot_box, wx.HORIZONTAL) + for k, v in self.sys_ind.items(): + self.sys_ind_box = wx.StaticBox(self.CtrlPanel, -1, k) + self.sys_ind_sizer = wx.StaticBoxSizer(self.sys_ind_box, wx.VERTICAL) + self.sys_ind_input = wx.TextCtrl( + self.CtrlPanel, + v[1], + str(self.sys_para["multi-panels"][v[0]]), + style=wx.TE_PROCESS_ENTER, + ) + self.sys_ind_input.Bind(wx.EVT_TEXT_ENTER, self._ev_enter_stcode) + self.sys_ind_sizer.Add( + self.sys_ind_input, + proportion=0, + flag=wx.EXPAND | wx.ALL | wx.CENTER, + border=2, + ) + # 加入Sizer中 + self.FlexGridSizer.Add( + self.sys_ind_sizer, proportion=1, border=1, flag=wx.ALL | wx.EXPAND + ) + kdata_plot_sizer.Add( + self.FlexGridSizer, + proportion=0, + flag=wx.EXPAND | wx.ALL | wx.CENTER, + border=2, + ) + + vboxnetB = wx.BoxSizer(wx.VERTICAL) # 纵向box + vboxnetB.Add( + trade_plat_sizer, + proportion=0, + flag=wx.EXPAND | wx.ALL | wx.CENTER, + border=10, + ) # proportion参数控制容器尺寸比例 + vboxnetB.Add( + btc_trade_plat_sizer, + proportion=0, + flag=wx.EXPAND | wx.ALL | wx.CENTER, + border=10, + ) + vboxnetB.Add( + kdata_plot_sizer, + proportion=0, + flag=wx.EXPAND | wx.ALL | wx.CENTER, + border=10, + ) # proportion参数控制容器尺寸比例 + + # for k, v in self.firm_mpl.items(): + # self.firm_mpl_box = wx.StaticBox(self.CtrlPanel, -1, k) + # self.firm_mpl_sizer = wx.StaticBoxSizer(self.firm_mpl_box, wx.VERTICAL) + # self.firm_mpl_input = wx.TextCtrl( + # self.CtrlPanel, + # v[1], + # str(self.firm_para["layout_dict"][v[0]]), + # style=wx.TE_PROCESS_ENTER, + # ) + # self.firm_mpl_input.Bind(wx.EVT_TEXT_ENTER, self._ev_enter_stcode) + # self.firm_mpl_sizer.Add( + # self.firm_mpl_input, + # proportion=0, + # flag=wx.EXPAND | wx.ALL | wx.CENTER, + # border=2, + # ) + # # 加入Sizer中 + # self.FlexGridSizer.Add( + # self.firm_mpl_sizer, proportion=1, border=1, flag=wx.ALL | wx.EXPAND + # ) + + # for k, v in self.back_mpl.items(): + # self.back_mpl_box = wx.StaticBox(self.CtrlPanel, -1, k) + # self.back_mpl_sizer = wx.StaticBoxSizer(self.back_mpl_box, wx.VERTICAL) + # self.back_mpl_input = wx.TextCtrl( + # self.CtrlPanel, + # v[1], + # str(self.back_para["layout_dict"][v[0]]), + # style=wx.TE_PROCESS_ENTER, + # ) + # self.back_mpl_input.Bind(wx.EVT_TEXT_ENTER, self._ev_enter_stcode) + # self.back_mpl_sizer.Add( + # self.back_mpl_input, + # proportion=0, + # flag=wx.EXPAND | wx.ALL | wx.CENTER, + # border=2, + # ) + # # 加入Sizer中 + # self.FlexGridSizer.Add( + # self.back_mpl_sizer, proportion=1, border=1, flag=wx.ALL | wx.EXPAND + # ) + + # self.FlexGridSizer.SetFlexibleDirection(wx.BOTH) + + # self.CtrlPanel.SetSizer(self.FlexGridSizer) + self.CtrlPanel.SetSizer(vboxnetB) + + self.HBoxPanel = wx.BoxSizer(wx.HORIZONTAL) + self.HBoxPanel.Add( + self.SysPanel, proportion=2, border=2, flag=wx.EXPAND | wx.ALL + ) + self.HBoxPanel.Add( + self.CtrlPanel, proportion=10, border=2, flag=wx.EXPAND | wx.ALL + ) + self.SetSizer(self.HBoxPanel) + + def OnClickOpenAccunt(self, event, trade_plat): + back_info = "" + current_license = self.trade_plat_para[trade_plat]['license'] + if current_license is not None and current_license: + back_info = MessageDialog(f"当前{trade_plat}交易接口授权码为: {current_license},是否要更新?") + else: + back_info = MessageDialog(f"微信联系Yida_Zhang2 获取自动化实盘交易接口后,填写参数:") + + if back_info == "点击No": + return 0 + + dialog = wx.TextEntryDialog(None, "Enter Parameter", "交易接口授权License") + if dialog.ShowModal() == wx.ID_OK: + parameter = dialog.GetValue() + logger.info(f"The License is: {parameter}") + + self.trade_plat_para[trade_plat]["license"] = parameter + + Base_File_Oper.save_sys_para("trade_plat_para.json", self.trade_plat_para) + # MessageDialog("存储完成!点击界面顶部的菜单栏->主菜单->返回") + + dialog.Destroy() + self.Close() + + def OnClickOpenBtcAccunt(self, event, trade_plat): + select_mode = ChoiceDialog( + "请选择填写key对应的交易模式", + [ + "模拟交易", + "实盘交易", + ], + ) + dlg = InputDialogTwoParameters( + None, -1, select_mode+" - "+trade_plat, input_name1="apikey:", input_name2="secretkey:" + ) + if dlg.ShowModal() == wx.ID_OK: + apikey = dlg.text_ctrl1.GetValue() + secretkey = dlg.text_ctrl2.GetValue() + logger.info(f"apikey: {apikey}, secretkey: {secretkey}") + + current_uid = "123456" + if select_mode == "实盘交易": + current_uid = self.btc_trade_plat_para[trade_plat]["api_key"][ + "real_trade" + ]["uid"] + self.btc_trade_plat_para[trade_plat]["api_key"]["real_trade"][ + "apikey" + ] = apikey + self.btc_trade_plat_para[trade_plat]["api_key"]["real_trade"][ + "secretkey" + ] = secretkey + elif select_mode == "模拟交易": + current_uid = self.btc_trade_plat_para[trade_plat]["api_key"][ + "sim_trade" + ]["uid"] + self.btc_trade_plat_para[trade_plat]["api_key"]["sim_trade"][ + "apikey" + ] = apikey + self.btc_trade_plat_para[trade_plat]["api_key"]["sim_trade"][ + "secretkey" + ] = secretkey + + back_info = "" + if ( + current_uid is not None + and current_uid + and current_uid != "" + ): + back_info = MessageDialog( + f"当前{trade_plat}[{select_mode}]交易接口用户ID为: {current_uid},是否要更新?" + ) + else: + back_info = MessageDialog( + f"微信联系Yida_Zhang2 或者自行获取{trade_plat}账户uid后,填写参数." + ) + if back_info == "点击Yes": + dialog = wx.TextEntryDialog( + None, + "Enter Parameter", + f"{trade_plat}[{select_mode}]交易接口用户ID", + ) + if dialog.ShowModal() == wx.ID_OK: + uid = dialog.GetValue() + logger.info(f"The uid is: {uid}") + + if select_mode == "实盘交易": + self.btc_trade_plat_para[trade_plat]["api_key"]["real_trade"][ + "uid" + ] = uid + elif select_mode == "模拟交易": + self.btc_trade_plat_para[trade_plat]["api_key"]["sim_trade"][ + "uid" + ] = uid + + Base_File_Oper.save_sys_para( + "btc_trade_plat_para.json", self.btc_trade_plat_para + ) + dialog.Destroy() + + Base_File_Oper.save_sys_para( + "btc_trade_plat_para.json", self.btc_trade_plat_para + ) + dlg.Destroy() + self.Close() + + def OnClose(self, event): + self.Close() + event.Skip() + + def OnCloseWindow(self, event): + logger.info("Dialog is closing...") + # 在这里执行关闭前需要的操作 + self.Destroy() + event.Skip() + + def _ev_switch_menu(self, event): + pass + + def _ev_save_para(self, event): + + self.sys_para["operate_sys"] = self.sel_operate_cmbo.GetStringSelection() + Base_File_Oper.save_sys_para("sys_para.json", self.sys_para) + MessageDialog("存储完成!") + self.Close() + + def _ev_enter_stcode(self, event): + + if event.GetId() < 300: + # 系统级显示 + for k, v in self.sys_ind.items(): + if v[1] == event.GetId(): + self.sys_para["multi-panels"][v[0]] = int(event.GetString()) + break + Base_File_Oper.save_sys_para("sys_para.json", self.sys_para) + + elif event.GetId() < 400: + # 行情MPL + for k, v in self.firm_mpl.items(): + if v[1] == event.GetId(): + self.firm_para["layout_dict"][v[0]] = float(event.GetString()) + break + Base_File_Oper.save_sys_para("firm_para.json", self.firm_para) + + else: + # 回测MPL + for k, v in self.back_mpl.items(): + if v[1] == event.GetId(): + self.back_para["layout_dict"][v[0]] = float(event.GetString()) + break + Base_File_Oper.save_sys_para("back_para.json", self.back_para) + MessageDialog("存储完成!") + diff --git a/qbot/gui/elements/def_grid.py b/qbot/gui/elements/def_grid.py new file mode 100644 index 00000000..47433423 --- /dev/null +++ b/qbot/gui/elements/def_grid.py @@ -0,0 +1,84 @@ +#! /usr/bin/env python +# -*- encoding: utf-8 -*- + +import wx +import wx.grid + + +class GridTable(wx.grid.Grid): + + def __init__(self, parent=None, nrow=30, ncol=20): + + wx.grid.Grid.__init__(self, parent, id=-1) + self.CreateGrid(nrow, ncol) + + def AutoRowNums(self, cur_rows=0, to_rows=0): + + if cur_rows < to_rows: + self.InsertRows(to_rows, to_rows - cur_rows, updateLabels=True) + elif cur_rows > to_rows: + self.DeleteRows(to_rows, cur_rows - to_rows, updateLabels=True) + else: + pass + + def AutoColNums(self, cur_cols=0, to_cols=0): + + if cur_cols < to_cols: + self.InsertCols(cur_cols, to_cols - cur_cols, updateLabels=True) + elif cur_cols > to_cols: + self.DeleteCols(to_cols, cur_cols - to_cols, updateLabels=True) + else: + pass + + def DeleteAllRows(self): + + if self.GetNumberRows() > 0: + self.DeleteRows(0, self.GetNumberRows(), updateLabels=True) + + def SetSelectCol(self, col_label): + + m = self.list_columns.index(col_label) + self.SelectCol(m, addToSelected=False) + + def SetTable(self, data, tran_col): + + if isinstance(data, dict): + # 字典类型 仅支持2列 key&value + self.DeleteAllRows() + for i, element in enumerate(tran_col): + self.SetColLabelValue(i, element) + + id = 0 + for m_k, m_v in data.items(): + st_name_code_dict = m_v + for s_k, s_v in st_name_code_dict.items(): + self.InsertRows(id, 2) + self.SetCellValue(id, 0, s_k) + self.SetCellValue(id, 1, s_v) + id = id + 1 + else: + # dataframe 类型 + df_data = data + # try: + if not df_data.empty: + + self.ClearGrid() + self.list_columns = df_data.columns.tolist() + + self.AutoRowNums(self.GetNumberRows(), df_data.shape[0]) + self.AutoColNums(self.GetNumberCols(), df_data.shape[1]) + + for col, series in df_data.iteritems(): + + m = self.list_columns.index(col) + if col in tran_col: + self.SetColLabelValue(m, tran_col.get(col, "")) + else: + self.SetColLabelValue(m, col) + + for n, val in enumerate(series): + self.SetCellValue(n, m, str(val)) + + self.AutoSizeColumn(m, True) # 自动调整列尺寸 + # except: + # print("set df grid table error") diff --git a/qbot/gui/elements/def_treelist.py b/qbot/gui/elements/def_treelist.py new file mode 100644 index 00000000..cf7aa97f --- /dev/null +++ b/qbot/gui/elements/def_treelist.py @@ -0,0 +1,104 @@ +#! /usr/bin/env python +# -*- encoding: utf-8 -*- + +import wx +import wx.adv +import wx.gizmos +import wx.grid +import wx.html2 + + +class CollegeTreeListCtrl(wx.gizmos.TreeListCtrl): + + colleges = { + "经典策略": [ + { + "名称": "N日突破", + "标识": "趋势", + "函数": "已定义", + "define": "get_ndays_signal", + }, + { + "名称": "ATR止盈止损", + "标识": "趋势", + "函数": "已定义", + "define": "get_ndays_atr_signal", + }, + ], + "自定义策略": [ + {"名称": "yx-zl-1", "标识": "综合", "函数": "未定义"}, + {"名称": "yx-zl-2", "标识": "趋势", "函数": "未定义"}, + {"名称": "yx-zl-3", "标识": "波动", "函数": "未定义"}, + ], + "衍生指标": [ + {"名称": "均线交叉", "标识": "cross", "函数": "已定义"}, + {"名称": "跳空缺口", "标识": "jump", "函数": "已定义"}, + {"名称": "黄金分割", "标识": "fibonacci", "函数": "已定义"}, + ], + "K线形态": [ + {"名称": "乌云盖顶", "标识": "CDLDARKCLOUDCOVER", "函数": "已定义"}, + {"名称": "三只乌鸦", "标识": "CDL3BLACKCROWS", "函数": "已定义"}, + {"名称": "十字星", "标识": "CDLDOJISTAR", "函数": "已定义"}, + {"名称": "锤头", "标识": "CDLHAMMER", "函数": "已定义"}, + {"名称": "射击之星", "标识": "CDLSHOOTINGSTAR", "函数": "已定义"}, + ], + } + + def __init__( + self, + parent=None, + id=-1, + pos=(0, 0), + size=wx.DefaultSize, + style=wx.TR_DEFAULT_STYLE | wx.TR_FULL_ROW_HIGHLIGHT, + ): + + wx.gizmos.TreeListCtrl.__init__(self, parent, id, pos, size, style) + + self.root = None + self.InitUI() + self.refDataShow(self.colleges) + + def InitUI(self): + self.il = wx.ImageList(16, 16, True) + self.il.Add(wx.ArtProvider.GetBitmap(wx.ART_FOLDER, wx.ART_OTHER, (16, 16))) + self.il.Add(wx.ArtProvider.GetBitmap(wx.ART_FILE_OPEN, wx.ART_OTHER, (16, 16))) + self.il.Add( + wx.ArtProvider.GetBitmap(wx.ART_NORMAL_FILE, wx.ART_OTHER, (16, 16)) + ) + self.SetImageList(self.il) + self.AddColumn("名称") + self.AddColumn("函数") + self.SetColumnWidth(0, 150) + self.SetColumnWidth(1, 100) + + def refDataShow(self, newDatas): + # if self.root is not None: + # self.DeleteAllItems() + + if newDatas is not None: + self.root = self.AddRoot("择时策略") + self.SetItemText(self.root, "", 1) # 第1列上添加 + + for cityID in newDatas.keys(): # 填充整个树 + child = self.AppendItem(self.root, cityID) + lastList = newDatas.get(cityID, []) + self.SetItemText(child, cityID + " (共" + str(len(lastList)) + "个)", 0) + self.SetItemImage( + child, 0, which=wx.TreeItemIcon_Normal + ) # wx.TreeItemIcon_Expanded + + for index in range(len(lastList)): + college = lastList[index] # TreeItemData是每一个ChildItem的唯一标示 + # 以便在点击事件中获得点击项的位置信息 + # "The TreeItemData class no longer exists, just pass your object directly to the tree instead + # data = wx.TreeItemData(cityID + "|" + str(index)) + last = self.AppendItem( + child, str(index), data=cityID + "|" + str(index) + ) + self.SetItemText(last, college.get("名称", ""), 0) + self.SetItemText(last, str(college.get("函数", "")), 1) + self.SetItemImage( + last, 0, which=wx.TreeItemIcon_Normal + ) # wx.TreeItemIcon_Expanded + self.Expand(self.root) diff --git a/qbot/gui/mainframe.py b/qbot/gui/mainframe.py index 23a3fb3a..78f94914 100644 --- a/qbot/gui/mainframe.py +++ b/qbot/gui/mainframe.py @@ -1,180 +1,72 @@ import os -import subprocess -import threading import time from pathlib import Path -import matplotlib.pyplot as plt -import psutil import wx +from qbot.gui.elements.def_dialog import ParamsConfigDialog from qbot.gui.panels.panel_backtest import PanelBacktest -# from qbot.gui.panels.panel_trade import TradePanel -# from qbot.gui.panels.panel_userframe import UserFrame +from qbot.gui.panels.panel_trade import TradePanel from qbot.gui.panels.panel_zhiku import ZhikuPanel +from qbot.gui.widgets.widget_web import WebPanel +from qbot.version import version + +# from qbot.gui.panels.panel_userframe import UserFrame # from qbot.gui.panels.actions import ActionsPanel # from qbot.gui.panels.page_timeseries import PageTimeSeries # from qbot.gui.panels.panels import TimeSeriesAnalysis -from qbot.gui.widgets.widget_web import WebPanel -from qbot.version import version TOP_DIR = Path(__file__).parent.parent APP_NAME = "Qbot - AI Quant Robot" -class ShellThread(threading.Thread): - def __init__(self, command): - super().__init__() - self.command = command - - def run(self): - subprocess.call(self.command, shell=True) - - -def run_notebook_local(): - cmd = "cd ~/Qbot/backend/pytrader/strategies/ && jupyter-notebook" - t = ShellThread(cmd) - t.start() - # os.system(cmd) - # subprocess.call(cmd) - - -def grep_pid(key="investool"): - all_processes = psutil.process_iter() - investool_processes = [p for p in all_processes if key in p.name()] - pids = [p.pid for p in investool_processes] - return pids - - -def get_investool_bin(): - import platform - - system_name = platform.system() - investoll_bin = "investool" - if system_name == "Darwin": # MacOs - investoll_bin = "investool_app_mac" - elif system_name == "Linux": - ubuntu_version = os.system("uname -a | grep Ubuntu | awk '{print $4}'") - if "22.04" in ubuntu_version: - investoll_bin = "investool_ubuntu22" - elif "18.04" in ubuntu_version: - investoll_bin = "investool_ubuntu18" - else: - print("investool 目前只支持mac、ubuntu22、ubuntu18.04") - os.system(f"notify-send ['Qbot - {symbol}{type}'] '{symbol}当前价格为{price}'") - else: - print("investool 目前只支持mac、ubuntu22、ubuntu18.04") - return investoll_bin - - -def run_qinvestool(): - investool_pids = grep_pid("investoll") - if not investool_pids: - for pid in investool_pids: - os.system(f"kill -9 {pid}") - - print("Start QInvesTool ...") - investoll_bin = get_investool_bin() - - if os.getenv("QBOT_RELEASE") == 1: - cmd = f"cd backend/investool && ./{investoll_bin} webserver" - os.system(cmd) - else: - shell_thread = ShellThread( - "cd backend/investool && go build && ./main webserver" - ) - shell_thread.start() - - cmd = "cd backend/investool && ./investool json -d" # dump funds json data - os.system(cmd) - - -def run_fund_tool(): - print("Start fund strategy analyse server ...") - t = ShellThread( - "docker run -dp 8000:8000 fund_strategy --name=fund_strategy_instance" - ) - t.start() - # cmd = '' - # subprocess.call(cmd) - # os.system(cmd) - - class MainFrame(wx.Frame): - def __init__(self, *args, **kw): displaySize = wx.DisplaySize() displaySize = 0.75 * displaySize[0], 0.70 * displaySize[1] - super().__init__(parent=None, title="Qbot - AI量化投研平台", size=displaySize) + super().__init__(parent=None, title="Qbot - AI智能量化投研平台", size=displaySize) # 设置程序图标 icon_file = "qbot/gui/imgs/logo.ico" icon = wx.Icon(icon_file, wx.BITMAP_TYPE_ICO) self.SetIcon(icon) - # 屏幕居中显示 - self.SetMenuBar(self.make_menubar(self)) - self.SetMinSize((1448, 802)) - self.init_statusbar() - # self.init_menu_bar() + self.init_menu_bar() self.init_main_tabs() - def __del__(self): - # win.Close(True) - self.Destroy() - - def OnAbout(self, event): - wx.MessageBox( - "公众号: 迈微AI研习社", - "关于 Qbot智能量化投研平台", - wx.OK | wx.ICON_INFORMATION, - ) - - def OnExit(event): - # win.Close(True) - self.Destroy() - def init_menu_bar(self): - # 屏幕居中显示 - self.Centre() - self.SetMenuBar(self.make_menubar(self)) - # self.Maximize() + # 创建窗口面板 + menuBar = wx.MenuBar(style=wx.MB_DOCKABLE) + self.SetMenuBar(menuBar) + self.SetMinSize((1618, 902)) - def make_menubar(self, win): - menuBar = wx.MenuBar() - - fileMenu = wx.Menu() - fileMenu.AppendSeparator() - exitItem = fileMenu.Append(wx.ID_EXIT, "退出") - menuBar.Append(fileMenu, "&菜单") + setting = wx.Menu() + menuBar.Append(setting, "&设置") + params_conf = wx.MenuItem(setting, 0, "&参数配置") + setting.Append(params_conf) + self.Bind(wx.EVT_MENU, self.on_params_conf, params_conf) tools = wx.Menu() menuBar.Append(tools, "&工具") - # Now a help menu for the about item - helpMenu = wx.Menu() - aboutItem = helpMenu.Append(wx.ID_ABOUT, "关于") - menuBar.Append(helpMenu, "&帮助") - valuation = wx.MenuItem(tools, 1, "&蛋卷估值") tools.Append(valuation) self.Bind(wx.EVT_MENU, self.on_menu, valuation) - tools.AppendSeparator() - jisilu = wx.MenuItem(tools, 2, "&集思录") tools.Append(jisilu) self.Bind(wx.EVT_MENU, self.on_menu, jisilu) - - monitoring = wx.MenuItem(tools, 1, "&后台监控") + monitoring = wx.MenuItem(tools, 3, "&后台监控") tools.Append(monitoring) - self.Bind(wx.EVT_MENU, self.monitoring, monitoring) + self.Bind(wx.EVT_MENU, self.start_monitoring, monitoring) - win.Bind(wx.EVT_MENU, self.OnAbout, aboutItem) - win.Bind(wx.EVT_MENU, self.OnExit, exitItem) - return menuBar + # Now a help menu for the about item + helpMenu = wx.Menu() + aboutItem = helpMenu.Append(wx.ID_ABOUT, "关于") + menuBar.Append(helpMenu, "&帮助") + self.Bind(wx.EVT_MENU, self.OnAbout, aboutItem) def on_menu(self, event): web = WebPanel(self.tabs) @@ -183,6 +75,17 @@ def on_menu(self, event): if event.Id == 2: web.show_url("https://www.jisilu.cn/") + def on_params_conf(self, event): + dialog = ParamsConfigDialog(self) + dialog.Show() + + def OnAbout(self, event): + wx.MessageBox( + "公众号: 迈微AI研习社", + "关于 Qbot智能量化投研平台", + wx.OK | wx.ICON_INFORMATION, + ) + def init_statusbar(self): self.statusBar = self.CreateStatusBar() # 创建状态条 # 将状态栏分割为3个区域,比例为4:1 @@ -201,13 +104,13 @@ def _update_sys_time(self, event): t = time.localtime(time.time()) self.SetStatusText(time.strftime("%Y-%B-%d %I:%M:%S", t), 2) - def monitoring(self, event): + def start_monitoring(self, event): monitor_pids = grep_pid("monitoring") if not monitor_pids: for pid in monitor_pids: os.system(f"kill -9 {pid}") - os.system("python monitoring.py > qmonitoring.log") - wx.MessageBox("股票监控程序已开启,后台查看日志。 'tail -f qmonitoring.log' ") + os.system("nohup python backend/auto_monitor.py > monitoring.log &") + wx.MessageBox("股票监控程序已开启,后台查看日志。 'tail -f monitoring.log' ") def init_main_tabs(self): # self.SetBackgroundColour(wx.GREEN) @@ -221,46 +124,28 @@ def init_main_tabs(self): self.tabs.AddPage(ZhikuPanel(self.tabs), "Qbot 投研智库", True) - web = WebPanel(self.tabs) - self.tabs.AddPage(web, "ChatGPT 策略编写", True) - web.show_url("https://wo2qwg.aitianhu.com/") - - plt.rc("grid", color="#316931", linewidth=1, linestyle="-") - plt.rc("xtick", labelsize=15) - plt.rc("ytick", labelsize=15) - - web = WebPanel(self.tabs) - self.tabs.AddPage(web, "AI 选股/选基", True) - web.show_url("http://111.229.117.200:4868") + web1 = WebPanel(self.tabs) + self.tabs.AddPage(web1, "ChatGPT 策略编写", True) + web1.show_url("https://wo2qwg.aitianhu.com/") - web = WebPanel(self.tabs) - self.tabs.AddPage(web, "基金投资策略分析", True) - web.show_url("https://ufund-me.github.io/funds-web/#/") + web2 = WebPanel(self.tabs) + self.tabs.AddPage(web2, "AI 选股/选基", True) + web2.show_url("http://111.229.117.200:4868") - # web = WebPanel(self.tabs) - # self.tabs.AddPage(web, "我的自选", True) - # attention_file = ( - # os.path.dirname(__file__) + "/../../frontend/web-extension/index.html" - # ) - # web.show_file(attention_file) + web3 = WebPanel(self.tabs) + self.tabs.AddPage(web3, "基金投资策略分析", True) + web3.show_url("https://ufund-me.github.io/funds-web/#/") - #TODO(Charmve): + # TODO(Charmve): # 多线程实现提高系统启动速度 - self.tabs.AddPage(PanelBacktest(self.tabs), "可视化股票/基金回测系统", True) - web = WebPanel(self.tabs) - self.tabs.AddPage(web, "交易策略在线交易", True) - web.show_url("https://sim.myquant.cn/sim?acc=5e4cdda3-f2fb-11ed-ae27-00163e022aa6") + # web4 = WebPanel(self.tabs) + # self.tabs.AddPage(web4, "交易策略在线交易", True) + # web4.show_url("https://sim.myquant.cn/sim?acc=5e4cdda3-f2fb-11ed-ae27-00163e022aa6") # self.tabs.AddPage(UserFrame(self.tabs), "Qbot 量化投研", True) - # self.tabs.AddPage(ActionsPanel(self.tabs), "资产轮动策略分析", True) - - # self.tabs.AddPage(TradePanel(self.tabs), "在线交易(实盘/虚拟盘)", True) + self.tabs.AddPage(TradePanel(self.tabs), "在线交易(实盘/虚拟盘)", True) self.tabs.SetSelection(4) # 可视化股票/基金回测系统 as hometab - - def Destroy(self): - return True - pass diff --git a/qbot/gui/panels/panel_backtest.py b/qbot/gui/panels/panel_backtest.py index 18003769..33fbc986 100644 --- a/qbot/gui/panels/panel_backtest.py +++ b/qbot/gui/panels/panel_backtest.py @@ -14,12 +14,14 @@ """ import wx -from qbot.gui import gui_utils -from qbot.gui.config import DATA_DIR_BKT_RESULT -from qbot.gui.widgets.widget_web import WebPanel from qbot.common.file_utils import extract_content from qbot.common.logging.logger import LOGGER as logger from qbot.common.macros import strategy_choices +from qbot.gui import gui_utils +from qbot.gui.config import DATA_DIR_BKT_RESULT +from qbot.gui.elements.def_dialog import MessageDialog +from qbot.gui.widgets.widget_web import WebPanel + # https://zhuanlan.zhihu.com/p/376248349 def OnBkt(event): @@ -76,7 +78,12 @@ def __init__(self, parent=None, id=-1, displaySize=(1600, 900)): # self.patten_log_tx, proportion=10, flag=wx.EXPAND | wx.BOTTOM, border=5 # ) - self.vbox_sizer_b.Add(self.BackWebPanel, proportion=10, flag=wx.EXPAND|wx.ALL|wx.CENTER, border=5) + self.vbox_sizer_b.Add( + self.BackWebPanel, + proportion=10, + flag=wx.EXPAND | wx.ALL | wx.CENTER, + border=5, + ) # 第一层布局 self.HBoxPanelSizer = wx.BoxSizer(wx.HORIZONTAL) @@ -186,9 +193,7 @@ def add_stock_para_lay(self, sub_panel): ).strftime("%Y%m%d") # 行情参数——输入股票代码 - self.stock_code_box = wx.StaticBox( - sub_panel, -1, "交易标的(股票/期货/比特币)代码" - ) + self.stock_code_box = wx.StaticBox(sub_panel, -1, "交易标的(股票/期货/比特币)代码") self.stock_code_sizer = wx.StaticBoxSizer(self.stock_code_box, wx.VERTICAL) self.stock_code_input = wx.TextCtrl( sub_panel, -1, "399006.SZ", style=wx.TE_PROCESS_ENTER @@ -284,7 +289,7 @@ def add_stock_para_lay(self, sub_panel): # self.group_analy_cmbo.Bind(wx.EVT_COMBOBOX, self._ev_group_analy) # 绑定ComboBox事件 # 回测按钮 - self.load_data_but = wx.Button(sub_panel, -1, "加载数据") + self.load_data_but = wx.Button(sub_panel, -1, "加载行情数据") self.load_data_but.SetBackgroundColour(wx.Colour(76, 187, 23)) # 设置背景颜色 # self.load_data_but.Bind(wx.EVT_BUTTON, self._ev_start_run) # 绑定按钮事件 self.load_data_but.Bind(wx.EVT_BUTTON, self.LoadData) # 绑定按钮事件 @@ -540,7 +545,7 @@ def _ev_enter_stcode(self, event): # 输入股票代码 st_name = self.code_table.get_name(st_code) self.backtest_opts["code"] = st_code logger.info(f"回测股票/基金: You select {st_code}") - + def _on_start_time_changed(self, event): start_time = gui_utils._wxdate2pydate(self.dpc_start_time.GetValue()).strftime( "%Y%m%d" @@ -600,9 +605,13 @@ def _ev_trade_log(self, event): pass def StartBacktest(self, event): - print("在线回测属于付费功能,请联系微信:Yida_Zhang2") + msg = "在线回测属于付费功能,请联系微信:Yida_Zhang2" + MessageDialog(msg) + print(msg) pass - + def LoadData(self, event): - print("请联系微信:Yida_Zhang2 开通功能") + msg = "请联系微信:Yida_Zhang2 开通功能" + MessageDialog(msg) + print(msg) pass diff --git a/qbot/gui/panels/panel_real_trade.py b/qbot/gui/panels/panel_real_trade.py new file mode 100644 index 00000000..50b8171a --- /dev/null +++ b/qbot/gui/panels/panel_real_trade.py @@ -0,0 +1,548 @@ +#! /usr/bin/env python +# -*- encoding: utf-8 -*- + +import matplotlib.pyplot as plt +import pandas as pd +import wx +import wx.adv +import wx.grid +import wx.html2 + +from qbot.common.logging.logger import LOGGER as logger + +# 分离控件事件中调用的子事件 +from qbot.common.macros import ( + btc_trade_platforms, + futures_trade_platforms, + strategy_choices, + trade_platforms, +) + +# from qbot.engine.config import MULTI_FACTS_DIR +from qbot.engine.trade.trade_engine import TradeEngine + +# from qbot.gui.common.CodePool import ManageCodePool +# from qbot.gui.common.CodeTable import ManageCodeTable +from qbot.gui.common.PrintLog import SysLogIf + +# from qbot.gui.common.SysFile import Base_File_Oper +from qbot.gui.elements.def_dialog import MessageDialog, UserDialog +from qbot.gui.elements.def_grid import GridTable +from qbot.gui.elements.def_treelist import CollegeTreeListCtrl +from qbot.gui.widgets.widget_web import WebPanel + +# from qbot.strategy.strategy_gath.StrategyGath import Base_Strategy_Group + + +plt.rcParams["font.sans-serif"] = ["SimHei"] # 用来正常显示中文标签 +plt.rcParams["axes.unicode_minus"] = False # 用来正常显示负号 + + +class RealTradePanel(wx.Panel): + def __init__( + self, parent=None, trader_opts={}, displaySize=(1600, 900), Fun_SwFrame=None + ): + super(RealTradePanel, self).__init__(parent) + + self.ClickNum = 0 # OnClickTrade + + # trade_class = ("虚拟盘") + # trade_type = ("股票") + # trade_platform = ("东方财富") + # trade_code = ("399006.SZ") + # trade_strategy = ("单因子-相对强弱指数RSI") + + self.trader_opts = { + "class": trader_opts["class"], + "platform": trader_opts["platform"], + "trade_type": trader_opts["trade_type"], + "trade_code": trader_opts["trade_code"], + "strategy": trader_opts["strategy"], + } + + # M1 与 M2 横向布局时宽度分割 + self.M1_width = int(displaySize[0] * 0.1) + self.M2_width = int(displaySize[0] * 0.9) + # M1 纵向100% + self.M1_length = int(displaySize[1]) + + # M1中S1 S2 S3 纵向布局高度分割 + self.M1S1_length = int(self.M1_length * 0.2) + self.M1S2_length = int(self.M1_length * 0.2) + self.M1S3_length = int(self.M1_length * 0.6) + + # 用于量化工具集成到整体系统中 + self.fun_swframe = Fun_SwFrame + + # 存储单个行情数据 + self.stock_dat = pd.DataFrame() + + # 多子图布局对象 + self.FlexGridSizer = None + + # 存储策略函数 + self.function = "" + + self.trader_class = trader_opts["class"] + self.multi_facts_config = "ROC(20)动量信号周频Top1" + self.multi_facts_list = list() + self.init_ui() + + def init_ui(self): + + # 添加参数布局 + self.vbox_sizer_a = wx.BoxSizer(wx.VERTICAL) # 纵向box + self.vbox_sizer_a.Add( + self._init_text_log(), proportion=1, flag=wx.EXPAND | wx.BOTTOM, border=5 + ) + self.vbox_sizer_a.Add( + self._init_listbox_mult(), + proportion=1, + flag=wx.EXPAND | wx.BOTTOM, + border=5, + ) + self.vbox_sizer_a.Add( + self._init_nav_notebook(), + proportion=2, + flag=wx.EXPAND | wx.BOTTOM, + border=5, + ) + + # 创建显示区面板 + self.RealTradeWebPanel = WebPanel(self) + + # 第二层布局 + self.vbox_sizer_b = wx.BoxSizer(wx.VERTICAL) # 纵向box + self.vbox_sizer_b.Add( + self._init_trade_para_notebook(), + proportion=1, + flag=wx.EXPAND | wx.BOTTOM, + border=5, + ) # 添加行情参数布局 + self.vbox_sizer_b.Add(self.RealTradeWebPanel, 10, wx.EXPAND) + + # 第一层布局 + self.HBoxPanelSizer = wx.BoxSizer(wx.HORIZONTAL) + self.HBoxPanelSizer.Add( + self.vbox_sizer_a, proportion=1, border=2, flag=wx.EXPAND | wx.ALL + ) + self.HBoxPanelSizer.Add( + self.vbox_sizer_b, proportion=10, border=2, flag=wx.EXPAND | wx.ALL + ) + self.SetSizer(self.HBoxPanelSizer) # 使布局有效 + + # ################################## 辅助配置 ################################### + self.syslog = SysLogIf(self.sys_log_tx) + + # ################################## 加载股票代码表 ################################### + # self.code_table = ManageCodeTable(self.syslog) + # self.code_table.update_stock_code() + + # ################################## 加载自选股票池 ################################### + # self.code_pool = ManageCodePool(self.syslog) + # self.grid_pl.SetTable(self.code_pool.load_self_pool(), ["自选股", "代码"]) + + def _init_grid_pl(self, subpanel): + # 初始化股票池表格 + self.grid_pl = GridTable(parent=subpanel, nrow=0, ncol=2) + self.Bind( + wx.grid.EVT_GRID_CELL_LEFT_DCLICK, self._ev_click_plcode, self.grid_pl + ) + return self.grid_pl + + def _ev_click_plcode(self, event): # 点击股票池股票代码 + + # 收集股票池中名称和代码 + st_code = self.grid_pl.GetCellValue(event.GetRow(), 1) + st_name = self.grid_pl.GetCellValue(event.GetRow(), 0) + + # self.handle_active_code(st_code, st_name) + + def _init_listbox_mult(self): + + self.mult_analyse_box = wx.StaticBox(self, -1, "组合分析股票池") + self.mult_analyse_sizer = wx.StaticBoxSizer(self.mult_analyse_box, wx.VERTICAL) + self.listBox = wx.ListBox( + self, + -1, + size=(self.M1_width, self.M1S2_length), + choices=[], + style=wx.LB_EXTENDED, + ) + self.listBox.Bind(wx.EVT_LISTBOX_DCLICK, self._ev_list_select) + self.mult_analyse_sizer.Add( + self.listBox, proportion=0, flag=wx.EXPAND | wx.ALL | wx.CENTER, border=2 + ) + + return self.mult_analyse_sizer + + def _ev_list_select(self, event): # 双击从列表中剔除股票 + + # 等价与GetSelection() and indexSelected + if MessageDialog("是否从组合分析股票池中删除该股票?") == "点击Yes": + indexSelected = event.GetEventObject().GetSelections() + event.GetEventObject().Delete(indexSelected[0]) + + def _init_text_log(self): + + # 创建并初始化系统日志框 + self.sys_log_box = wx.StaticBox(self, -1, "系统日志") + self.sys_log_sizer = wx.StaticBoxSizer(self.sys_log_box, wx.VERTICAL) + self.sys_log_tx = wx.TextCtrl( + self, style=wx.TE_MULTILINE, size=(self.M1_width, self.M1S1_length) + ) + self.sys_log_sizer.Add( + self.sys_log_tx, proportion=1, flag=wx.EXPAND | wx.ALL | wx.CENTER, border=2 + ) + return self.sys_log_sizer + + def _init_trade_para_notebook(self): + + # 创建参数区面板 + self.ParaNoteb = wx.Notebook(self) + self.RealTradePanel = wx.Panel(self.ParaNoteb, -1) # 实盘交易 + # self.ParaLogPanel = wx.Panel(self.ParaNoteb, -1) # 交易日志 + + # 第二层布局 + self.RealTradePanel.SetSizer(self.add_trade_para_layer(self.RealTradePanel)) + + self.ParaNoteb.AddPage(self.RealTradePanel, "实盘交易") + + return self.ParaNoteb + + def add_trade_para_layer(self, sub_panel): + + # 交易参数 + trade_para_sizer = wx.BoxSizer(wx.HORIZONTAL) + + # 交易参数——输入交易类型 + self.stocks_select_box = wx.StaticBox(sub_panel, -1, "交易标的") + self.stocks_select_sizer = wx.StaticBoxSizer( + self.stocks_select_box, wx.VERTICAL + ) + self.stocks_select_cbox = wx.ComboBox( + sub_panel, + -1, + "", + choices=["股票", "基金", "期货", "BTC"], + ) + self.stocks_select_cbox.SetSelection(0) + self.stocks_select_cbox.Bind( + wx.EVT_COMBOBOX, self.on_combobox_trade_type_changed + ) # noqa: E501 + select_trade_type = self.stocks_select_cbox.GetValue() + self.trader_opts["trade_type"] = select_trade_type + logger.debug(f"select_trade_type: {select_trade_type}") + self.stocks_select_sizer.Add( + self.stocks_select_cbox, + proportion=0, + flag=wx.EXPAND | wx.ALL | wx.CENTER, + border=2, + ) + + # 交易参数——交易标的代码 + self.init_code_box = wx.StaticBox(sub_panel, -1, "交易标的代码") + self.init_code_sizer = wx.StaticBoxSizer(self.init_code_box, wx.VERTICAL) + self.init_code_input = wx.TextCtrl( + sub_panel, -1, str("600519.SH"), style=wx.TE_LEFT # 贵州茅台 + ) + self.Bind(wx.EVT_TEXT, self._on_input_code_changed, self.init_code_input) + select_code = self.init_code_input.GetValue() + logger.debug(f"select_code: {select_code}") + self.trader_opts["trade_code"] = select_code + self.init_code_sizer.Add( + self.init_code_input, + proportion=0, + flag=wx.EXPAND | wx.ALL | wx.CENTER, + border=2, + ) + + # 交易参数——选择交易平台 + self.trade_platform_box = wx.StaticBox(sub_panel, -1, "选择证券交易平台") + self.trade_platform_sizer = wx.StaticBoxSizer( + self.trade_platform_box, wx.VERTICAL + ) + self.trade_platform_cbox = wx.ComboBox( + sub_panel, + -1, + "", + choices=list(trade_platforms)[0], + ) + self.trade_platform_cbox.SetSelection(1) + self.trade_platform_cbox.Bind( + wx.EVT_COMBOBOX, self.on_combobox_trade_platform_changed + ) # noqa: E501 + select_trade_platform = self.trade_platform_cbox.GetValue() + self.trader_opts["platform"] = select_trade_platform + logger.debug(f"select_trade_platform: {select_trade_platform}") + self.trade_platform_sizer.Add( + self.trade_platform_cbox, + proportion=0, + flag=wx.EXPAND | wx.ALL | wx.CENTER, + border=2, + ) + + # 交易参数——交易策略 + self.strategy_select_box = wx.StaticBox(sub_panel, -1, "交易策略选择") + self.strategy_select_sizer = wx.StaticBoxSizer( + self.strategy_select_box, wx.VERTICAL + ) + self.strategy_select_cbox = wx.ComboBox( + sub_panel, + -1, + "", + choices=list(strategy_choices)[0], + ) + self.strategy_select_cbox.SetSelection(0) + self.strategy_select_cbox.Bind( + wx.EVT_COMBOBOX, self._on_combobox_strategy_changed + ) # noqa: E501 + select_strategy = self.strategy_select_cbox.GetValue() + self.trader_opts["strategy"] = select_strategy + logger.debug(f"[{self.trader_class}] select_trade_strategy: {select_strategy}") + if "多因子" in select_strategy: + self.multi_fact_layout() + self.strategy_select_sizer.Add( + self.strategy_select_cbox, + proportion=0, + flag=wx.EXPAND | wx.ALL | wx.CENTER, + border=2, + ) + + # 交易按钮 + self.start_trade_butt = wx.Button(sub_panel, -1, "开始交易") + self.start_trade_butt.SetBackgroundColour(wx.Colour(76, 187, 23)) # 设置背景颜色 + self.start_trade_butt.Bind(wx.EVT_BUTTON, self.OnClickTrade) # 绑定按钮事件 + + # 交易日志 + self.trade_log_butt = wx.Button(sub_panel, -1, "交易日志") + self.trade_log_butt.Bind(wx.EVT_BUTTON, self._ev_trade_log) # 绑定按钮事件 + + self.show_trade_boardview() + + trade_para_sizer.Add( + self.stocks_select_sizer, + proportion=0, + flag=wx.EXPAND | wx.ALL | wx.CENTER, + border=5, + ) + trade_para_sizer.Add( + self.init_code_sizer, + proportion=0, + flag=wx.EXPAND | wx.ALL | wx.CENTER, + border=5, + ) + trade_para_sizer.Add( + self.trade_platform_sizer, + proportion=0, + flag=wx.EXPAND | wx.ALL | wx.CENTER, + border=5, + ) + trade_para_sizer.Add( + self.strategy_select_sizer, + proportion=0, + flag=wx.EXPAND | wx.ALL | wx.CENTER, + border=5, + ) + trade_para_sizer.Add( + self.start_trade_butt, + proportion=0, + flag=wx.EXPAND | wx.ALL | wx.CENTER, + border=5, + ) + trade_para_sizer.Add( + self.trade_log_butt, + proportion=0, + flag=wx.EXPAND | wx.ALL | wx.CENTER, + border=5, + ) + + return trade_para_sizer + + def _on_combobox_strategy_changed(self, event): + select_strategy = self.strategy_select_cbox.GetValue() + self.trader_opts["strategy"] = select_strategy + logger.info(f"交易策略: You select {select_strategy}") + + def _on_input_code_changed(self, event): + select_code = self.init_code_input.GetValue() + self.trader_opts["trade_code"] = select_code + logger.info(f"回测股票/基金: You select {select_code}") + + def on_combobox_multi_facts_changed(self, event): + self.multi_facts_config = self.combo_multi_facts.GetValue() + logger.info( + f"[{self.trader_class}] 多因子交易策略: You select {self.multi_facts_config}" + ) + # self.trader_opts["strategy"] = self.trade_platform + + def on_combobox_trade_type_changed(self, event): + self.trade_type = self.stocks_select_cbox.GetValue() + logger.info(f"[{self.trader_class}] 交易类型: You select {self.trade_type}") + self.trader_opts["trade_type"] = self.trade_type + + if self.trade_type == "股票": + self.trade_platform_cbox.SetItems(list(trade_platforms)[0]) + self.trader_opts["platform"] = "东方财富" + self.trade_platform_cbox.SetValue("东方财富") + elif self.trade_type == "期货": + self.trade_platform_cbox.SetItems(list(futures_trade_platforms[0])) + self.trader_opts["platform"] = "CTP" + self.trade_platform_cbox.SetValue("CTP") + + self.trader_opts["trade_code"] = "zn2409" # 沪锌2409 + self.init_code_input.SetValue("zn2409") + elif self.trade_type == "BTC": + self.trade_platform_cbox.SetItems(list(btc_trade_platforms)[0]) + self.trader_opts["platform"] = "欧易OKX" + self.trade_platform_cbox.SetValue("欧易OKX") + + self.trader_opts["trade_code"] = "BTCUSDT" + self.init_code_input.SetValue("BTCUSDT") + + print(self.trader_opts) + self.show_trade_boardview() + + def on_combobox_trade_platform_changed(self, event): + self.trade_platform = self.trade_platform_cbox.GetValue() + logger.info(f"[{self.trader_class}] 交易平台: You select {self.trade_platform}") + self.trader_opts["platform"] = self.trade_platform + + self.show_trade_boardview() + + def on_combobox_strategy_changed(self, event): + select_strategy = self.strategy_select_cbox.GetValue() + self.trader_opts["strategy"] = select_strategy + logger.info(f"[{self.trader_class}] 交易策略: You select {select_strategy}") + if "多因子" in select_strategy: + self.multi_fact_layout() + else: + self.remove_multi_fact_layout() + + def OnClickTrade(self, event): + + # MessageDialog("请联系微信:Yida_Zhang2") + + self.start_trade_butt.SetLabel("暂停交易") + self.ClickNum += 1 + if self.ClickNum % 2 == 1: + self.start_trade_butt.SetLabel("开始交易") + self.syslog.re_print("开始实盘交易...\n") + else: + self.start_trade_butt.SetLabel("暂停交易") + self.ClickNum = 0 + logger.info(self.start_trade_butt.GetLabel()) + self.syslog.re_print("暂停实盘交易...\n") + return + + sim_trade_opts = { + "class": "实盘", + "platform": "东方财富", + "trade_type": "股票", + "trade_code": "399006.SZ", + "strategy": "单因子-相对强弱指数RSI", + } + # logger.info(self.trader_opts) + + # ######## 开始实盘交易 ######### + self.trade_engine = TradeEngine(self.trader_opts, self.syslog) + self.trade_engine.login() + self.trade_engine.get_positions() + self.trade_engine.start_trade() + # self.trade_engine.close() + + def show_trade_boardview(self): + print( + "$$$$$$$$$$$$\n####", + self.trader_opts["trade_type"], + self.trader_opts["class"], + ) + if self.trader_opts["trade_type"] == "股票": + juejin_sim = ( + "https://sim.myquant.cn/sim?acc=5e4cdda3-f2fb-11ed-ae27-00163e022aa6" + ) + self.RealTradeWebPanel.show_url(juejin_sim) + logger.info(f"RealTradeWebPanel - {juejin_sim}") + elif self.trader_opts["trade_type"] == "BTC": + huobi_platform = "https://www.htx.com/zh-cn/grid-exchange/" + if self.trader_opts["platform"] == "火币Huobi": + self.RealTradeWebPanel.show_url(huobi_platform) + logger.info(f"RealTradeWebPanel - {huobi_platform}") + elif self.trader_opts["platform"] == "欧易OKX": + okx_url = "https://www.okx.com/zh-hans/trade-spot/btc-usdt" + self.RealTradeWebPanel.show_url(okx_url) + logger.info(f"RealTradeWebPanel - {okx_url}") + elif self.trader_opts["platform"] == "币安Binance": + binance_url = "https://www.binance.com/zh-CN/trade/BTC_USDT?type=spot" + self.RealTradeWebPanel.show_url(binance_url) + logger.info(f"RealTradeWebPanel - {binance_url}") + else: + self.RealTradeWebPanel.show_url( + "https://www.okx.com/zh-hans/trade-spot/btc-usdt" + ) + logger.info( + "RealTradeWebPanel - https://www.okx.com/zh-hans/trade-spot/btc-usdt" + ) + # https://crypto-labs.miladsdgh.ir/ + else: + MessageDialog("交易平台尚未接入,请联系微信:Yida_Zhang2") + + def _ev_trade_log(self, event): + + user_trade_log = UserDialog(self, title="回测提示信息", label="交易详细日志") + + """ 自定义提示框 """ + if user_trade_log.ShowModal() == wx.ID_OK: + pass + else: + pass + + def _ev_click_on_treelist(self, event): + + self.curTreeItem = self.treeListCtrl.GetItemText(event.GetItem()) + + if not self.curTreeItem: + # 当前选中的TreeItemId对象操作 + + MessageDialog("当前点击:{0}!".format(self.curTreeItem)) + for m_key, m_val in self.treeListCtrl.colleges.items(): + for s_key in m_val: + if s_key.get("名称", "") == self.curTreeItem: + if s_key.get("函数", "") != "未定义": + if (m_key == "衍生指标") or (m_key == "K线形态"): + # 第一步:收集控件中设置的选项 + st_label = s_key["标识"] + st_code = self.init_code_input.GetValue() + st_name = self.code_table.get_name(st_code) + + # 第二步:获取股票数据-使用self.stock_dat存储数据 + if self.stock_dat.empty: + MessageDialog("获取股票数据出错!\n") + else: + MessageDialog("该接口未定义!") + # self.function = getattr( + # Base_Strategy_Group, s_key.get("define", "") + # ) + else: + MessageDialog("该接口未定义!") + break + + def _init_treelist_ctrl(self, subpanel): + + # 创建一个 treeListCtrl object + self.treeListCtrl = CollegeTreeListCtrl( + parent=subpanel, pos=(-1, 39), size=(250, 200) + ) + self.treeListCtrl.Bind(wx.EVT_TREE_SEL_CHANGED, self._ev_click_on_treelist) + + return self.treeListCtrl + + def _init_nav_notebook(self): + + # 创建参数区面板 + self.NavNoteb = wx.Notebook(self) + + self.NavNoteb.AddPage(self._init_treelist_ctrl(self.NavNoteb), "策略导航") + self.NavNoteb.AddPage(self._init_grid_pl(self.NavNoteb), "股票池索引") + + return self.NavNoteb diff --git a/qbot/gui/panels/panel_results.py b/qbot/gui/panels/panel_results.py new file mode 100644 index 00000000..02cf446e --- /dev/null +++ b/qbot/gui/panels/panel_results.py @@ -0,0 +1,165 @@ +""" +Author: Charmve yidazhang1@gmail.com +Date: 2023-05-14 18:18:42 +LastEditors: Charmve yidazhang1@gmail.com +LastEditTime: 2024-03-29 11:49:42 +FilePath: /qbot_pro/qbot/gui/panels/results.py +Version: 1.0.1 +Blogs: charmve.blog.csdn.net +GitHub: https://github.com/Charmve +Description: + +Copyright (c) 2023 by Charmve, All Rights Reserved. +Licensed under the MIT License. +""" + +import wx + +from qbot.common.logging.logger import LOGGER as logger +from qbot.gui.widgets.widget_web import WebPanel +from qbot.gui.widgets.widgets import MatplotlibPanel, PandasGrid + + +class ResultsPanel(wx.Panel): + def __init__(self, parent): + super(ResultsPanel, self).__init__(parent) + self.init_tabs() + + def handle_data(self, data_dict): + logger.info(f"{data_dict.keys()}") + if "raw" in data_dict.keys(): + # logger.debug('data_dict["raw"]: ') + # print(data_dict["raw"]) + self.panel_raw.show_df(data_dict["raw"]) + + self.tabs.SetSelection(0) + + if "features" in data_dict.keys(): + self.panel_features.show_df(data_dict["features"]) + + self.tabs.SetSelection(3) + + if "ratio" in data_dict.keys(): + self.pd.show_df(data_dict["ratio"]) + + if "corr" in data_dict.keys(): + # print("corr: ", corr) + self.pd_corr.show_df(data_dict["corr"]) + + if "plot" in data_dict.keys(): + plot = data_dict["plot"] + # print("plot: ", plot) + self.plot.show_data(plot) + + if "indicator" in data_dict.keys(): + logger.debug("plot_file: {}".format(data_dict["indicator"])) + plot_kline_file = data_dict["indicator"] + self.kline_plot.show_file(plot_kline_file) + + self.tabs.SetSelection(1) + + if "bolling" in data_dict.keys(): + logger.debug("plot_file: {}".format(data_dict["bolling"])) + plot_kline_boll_file = str(data_dict["bolling"]) + self.kline_boll_plot.show_file(plot_kline_boll_file) + + if "yearly" in data_dict.keys(): + yearly = data_dict["yearly"] + self.pd_yearly.show_df(yearly) + + # self.pd.show_df() + + def init_tabs(self): + vbox = wx.BoxSizer(wx.VERTICAL) + self.SetSizer(vbox) + + self.tabs = wx.Notebook(self) + vbox.Add(self.tabs, 1, wx.EXPAND) + + self.panel_raw = PandasGrid(self.tabs) + self.panel_features = PandasGrid(self.tabs, nrow=1000, ncol=20) + + panel_tab = wx.Panel(self.tabs) + panel_yearly = wx.Panel(self.tabs) + panel_corr = wx.Panel(self.tabs) + panel_plot = wx.Panel(self.tabs) + panel_kline_plot = wx.Panel(self.tabs) + panel_kline_boll_plot = wx.Panel(self.tabs) + + self.tabs.AddPage(self.panel_raw, "行情数据") + self.tabs.AddPage(panel_kline_plot, "可视化数据(K线)") + self.tabs.AddPage(panel_kline_boll_plot, "可视化数据(布林带)") + self.tabs.AddPage(self.panel_features, "特征提取") + + self.tabs.AddPage(panel_plot, "序列绘图") + self.tabs.AddPage(panel_tab, "风险收益") + self.tabs.AddPage(panel_yearly, "年度收益") + self.tabs.AddPage(panel_corr, "相关性分析") + + self.pd = PandasGrid(panel_tab, nrow=30, ncol=20) + self.pd_yearly = PandasGrid(panel_yearly, nrow=30, ncol=20) + + vbox_panel = wx.BoxSizer(wx.VERTICAL) + vbox_panel.Add(self.pd, 1, wx.EXPAND) + + vbox_yearly = wx.BoxSizer(wx.VERTICAL) + vbox_yearly.Add(self.pd_yearly, 1, wx.EXPAND) + panel_tab.SetSizer(vbox_panel) + panel_yearly.SetSizer(vbox_yearly) + + self.init_corr(panel_corr) + self.init_plot(panel_plot) + self.init_kline_plot(panel_kline_plot) + self.init_kline_boll_plot(panel_kline_boll_plot) + + def init_corr(self, parent): + vbox = wx.BoxSizer(wx.VERTICAL) + parent.SetSizer(vbox) + self.pd_corr = PandasGrid(parent) + vbox.Add(self.pd_corr, 1, wx.EXPAND) + + def init_plot(self, parent): + vbox = wx.BoxSizer(wx.VERTICAL) + parent.SetSizer(vbox) + self.plot = MatplotlibPanel(parent) + vbox.Add(self.plot, 1, wx.EXPAND) + + def init_kline_plot(self, parent): + vbox = wx.BoxSizer(wx.VERTICAL) + parent.SetSizer(vbox) + self.kline_plot = WebPanel(parent) + vbox.Add(self.kline_plot, 1, wx.EXPAND) + + def init_kline_boll_plot(self, parent): + vbox = wx.BoxSizer(wx.VERTICAL) + parent.SetSizer(vbox) + self.kline_boll_plot = WebPanel(parent) + vbox.Add(self.kline_boll_plot, 1, wx.EXPAND) + + # def init_kline_plot(self, parent): + # vbox = wx.BoxSizer(wx.VERTICAL) + # self.SetSizer(vbox) + + # self.tabs = wx.Notebook(self) + # vbox.Add(self.tabs, 1, wx.EXPAND) + + # panel_plot_ma = wx.Panel(self.tabs) + # panel_plot_boll = wx.Panel(self.tabs) + + # self.tabs.AddPage(panel_plot_ma, "K均线") + # self.tabs.AddPage(panel_plot_boll, "K线布林带") + + # self.init_kline_ma_plot(panel_plot_ma) + # self.init_kline_boll_plot(panel_plot_boll) + + # def init_kline_ma_plot(self, parent): + # vbox = wx.BoxSizer(wx.VERTICAL) + # parent.SetSizer(vbox) + # parent.kline_plot = WebPanel(parent) + # vbox.Add(parent.kline_plot, 1, wx.EXPAND) + + # def init_kline_boll_plot(self, parent): + # vbox = wx.BoxSizer(wx.VERTICAL) + # parent.SetSizer(vbox) + # parent.kline_boll_plot = WebPanel(parent) + # vbox.Add(parent.kline_boll_plot, 1, wx.EXPAND) diff --git a/qbot/gui/panels/panel_sim_trade.py b/qbot/gui/panels/panel_sim_trade.py new file mode 100644 index 00000000..38666191 --- /dev/null +++ b/qbot/gui/panels/panel_sim_trade.py @@ -0,0 +1,547 @@ +#! /usr/bin/env python +# -*- encoding: utf-8 -*- + +import matplotlib.pyplot as plt +import pandas as pd +import wx +import wx.adv +import wx.grid +import wx.html2 + +from qbot.common.logging.logger import LOGGER as logger + +# 分离控件事件中调用的子事件 +from qbot.common.macros import ( + btc_trade_platforms, + futures_trade_platforms, + strategy_choices, + trade_platforms, +) +from qbot.engine.trade.trade_engine import TradeEngine + +# from qbot.gui.common.CodePool import ManageCodePool +# from qbot.gui.common.CodeTable import ManageCodeTable +from qbot.gui.common.PrintLog import SysLogIf + +# from qbot.gui.common.SysFile import Base_File_Oper +from qbot.gui.elements.def_dialog import MessageDialog, UserDialog +from qbot.gui.elements.def_grid import GridTable +from qbot.gui.elements.def_treelist import CollegeTreeListCtrl +from qbot.gui.widgets.widget_web import WebPanel + +# from qbot.strategy.strategy_gath.StrategyGath import Base_Strategy_Group + + +plt.rcParams["font.sans-serif"] = ["SimHei"] # 用来正常显示中文标签 +plt.rcParams["axes.unicode_minus"] = False # 用来正常显示负号 + + +class SimTradePanel(wx.Panel): + def __init__( + self, parent=None, trader_opts={}, displaySize=(1600, 900), Fun_SwFrame=None + ): + super(SimTradePanel, self).__init__(parent) + + self.ClickNum = 0 # OnClickTrade + + # trade_class = ("虚拟盘") + # trade_type = ("股票") + # trade_platform = ("东方财富") + # trade_code = ("399006.SZ") + # trade_strategy = ("单因子-相对强弱指数RSI") + + self.trader_opts = { + "class": trader_opts["class"], + "platform": trader_opts["platform"], + "trade_type": trader_opts["trade_type"], + "trade_code": trader_opts["trade_code"], + "strategy": trader_opts["strategy"], + } + + # M1 与 M2 横向布局时宽度分割 + self.M1_width = int(displaySize[0] * 0.1) + self.M2_width = int(displaySize[0] * 0.9) + # M1 纵向100% + self.M1_length = int(displaySize[1]) + + # M1中S1 S2 S3 纵向布局高度分割 + self.M1S1_length = int(self.M1_length * 0.2) + self.M1S2_length = int(self.M1_length * 0.2) + self.M1S3_length = int(self.M1_length * 0.6) + + # 用于量化工具集成到整体系统中 + self.fun_swframe = Fun_SwFrame + + # 存储单个行情数据 + self.stock_dat = pd.DataFrame() + + # 多子图布局对象 + self.FlexGridSizer = None + + # 存储策略函数 + self.function = "" + + self.trader_class = trader_opts["class"] + self.multi_facts_config = "ROC(20)动量信号周频Top1" + self.multi_facts_list = list() + self.init_ui() + + def init_ui(self): + + # 添加参数布局 + self.vbox_sizer_a = wx.BoxSizer(wx.VERTICAL) # 纵向box + self.vbox_sizer_a.Add( + self._init_text_log(), proportion=1, flag=wx.EXPAND | wx.BOTTOM, border=5 + ) + self.vbox_sizer_a.Add( + self._init_listbox_mult(), + proportion=1, + flag=wx.EXPAND | wx.BOTTOM, + border=5, + ) + self.vbox_sizer_a.Add( + self._init_nav_notebook(), + proportion=2, + flag=wx.EXPAND | wx.BOTTOM, + border=5, + ) + + # 创建显示区面板 + self.SimTradeWebPanel = WebPanel(self) + + # 第二层布局 + self.vbox_sizer_b = wx.BoxSizer(wx.VERTICAL) # 纵向box + self.vbox_sizer_b.Add( + self._init_trade_para_notebook(), + proportion=1, + flag=wx.EXPAND | wx.BOTTOM, + border=5, + ) # 添加行情参数布局 + self.vbox_sizer_b.Add(self.SimTradeWebPanel, 10, wx.EXPAND) + + # 第一层布局 + self.HBoxPanelSizer = wx.BoxSizer(wx.HORIZONTAL) + self.HBoxPanelSizer.Add( + self.vbox_sizer_a, proportion=1, border=2, flag=wx.EXPAND | wx.ALL + ) + self.HBoxPanelSizer.Add( + self.vbox_sizer_b, proportion=10, border=2, flag=wx.EXPAND | wx.ALL + ) + self.SetSizer(self.HBoxPanelSizer) # 使布局有效 + + # ################################## 辅助配置 ################################### + self.syslog = SysLogIf(self.sys_log_tx) + + # ################################## 加载股票代码表 ################################### + # self.code_table = ManageCodeTable(self.syslog) + # self.code_table.update_stock_code() + + # ################################## 加载自选股票池 ################################### + # self.code_pool = ManageCodePool(self.syslog) + # self.grid_pl.SetTable(self.code_pool.load_self_pool(), ["自选股", "代码"]) + + def _init_grid_pl(self, subpanel): + # 初始化股票池表格 + self.grid_pl = GridTable(parent=subpanel, nrow=0, ncol=2) + self.Bind( + wx.grid.EVT_GRID_CELL_LEFT_DCLICK, self._ev_click_plcode, self.grid_pl + ) + return self.grid_pl + + def _ev_click_plcode(self, event): # 点击股票池股票代码 + + # 收集股票池中名称和代码 + st_code = self.grid_pl.GetCellValue(event.GetRow(), 1) + st_name = self.grid_pl.GetCellValue(event.GetRow(), 0) + + # self.handle_active_code(st_code, st_name) + + def _init_listbox_mult(self): + + self.mult_analyse_box = wx.StaticBox(self, -1, "组合分析股票池") + self.mult_analyse_sizer = wx.StaticBoxSizer(self.mult_analyse_box, wx.VERTICAL) + self.listBox = wx.ListBox( + self, + -1, + size=(self.M1_width, self.M1S2_length), + choices=[], + style=wx.LB_EXTENDED, + ) + self.listBox.Bind(wx.EVT_LISTBOX_DCLICK, self._ev_list_select) + self.mult_analyse_sizer.Add( + self.listBox, proportion=0, flag=wx.EXPAND | wx.ALL | wx.CENTER, border=2 + ) + + return self.mult_analyse_sizer + + def _ev_list_select(self, event): # 双击从列表中剔除股票 + + # 等价与GetSelection() and indexSelected + if MessageDialog("是否从组合分析股票池中删除该股票?") == "点击Yes": + indexSelected = event.GetEventObject().GetSelections() + event.GetEventObject().Delete(indexSelected[0]) + + def _init_text_log(self): + + # 创建并初始化系统日志框 + self.sys_log_box = wx.StaticBox(self, -1, "系统日志") + self.sys_log_sizer = wx.StaticBoxSizer(self.sys_log_box, wx.VERTICAL) + self.sys_log_tx = wx.TextCtrl( + self, style=wx.TE_MULTILINE, size=(self.M1_width, self.M1S1_length) + ) + self.sys_log_sizer.Add( + self.sys_log_tx, proportion=1, flag=wx.EXPAND | wx.ALL | wx.CENTER, border=2 + ) + return self.sys_log_sizer + + def _init_trade_para_notebook(self): + + # 创建参数区面板 + self.ParaNoteb = wx.Notebook(self) + self.SimTradePanel = wx.Panel(self.ParaNoteb, -1) # 模拟交易 + # self.ParaLogPanel = wx.Panel(self.ParaNoteb, -1) # 交易日志 + + # 第二层布局 + self.SimTradePanel.SetSizer(self.add_trade_para_layer(self.SimTradePanel)) + + self.ParaNoteb.AddPage(self.SimTradePanel, "模拟交易") + + return self.ParaNoteb + + def add_trade_para_layer(self, sub_panel): + + # 交易参数 + trade_para_sizer = wx.BoxSizer(wx.HORIZONTAL) + + # 交易参数——输入交易类型 + self.stocks_select_box = wx.StaticBox(sub_panel, -1, "交易标的") + self.stocks_select_sizer = wx.StaticBoxSizer( + self.stocks_select_box, wx.VERTICAL + ) + self.stocks_select_cbox = wx.ComboBox( + sub_panel, + -1, + "", + choices=["股票", "基金", "期货", "BTC"], + ) + self.stocks_select_cbox.SetSelection(0) + self.stocks_select_cbox.Bind( + wx.EVT_COMBOBOX, self.on_combobox_trade_type_changed + ) # noqa: E501 + select_trade_type = self.stocks_select_cbox.GetValue() + self.trader_opts["trade_type"] = select_trade_type + logger.debug(f"select_trade_type: {select_trade_type}") + self.stocks_select_sizer.Add( + self.stocks_select_cbox, + proportion=0, + flag=wx.EXPAND | wx.ALL | wx.CENTER, + border=2, + ) + + # 交易参数——交易标的代码 + self.init_code_box = wx.StaticBox(sub_panel, -1, "交易标的代码") + self.init_code_sizer = wx.StaticBoxSizer(self.init_code_box, wx.VERTICAL) + self.init_code_input = wx.TextCtrl( + sub_panel, -1, str("600519.SH"), style=wx.TE_LEFT # 贵州茅台 + ) + self.Bind(wx.EVT_TEXT, self._on_input_code_changed, self.init_code_input) + select_code = self.init_code_input.GetValue() + logger.debug(f"select_code: {select_code}") + self.trader_opts["trade_code"] = select_code + self.init_code_sizer.Add( + self.init_code_input, + proportion=0, + flag=wx.EXPAND | wx.ALL | wx.CENTER, + border=2, + ) + + # 交易参数——选择交易平台 + self.trade_platform_box = wx.StaticBox(sub_panel, -1, "选择证券交易平台") + self.trade_platform_sizer = wx.StaticBoxSizer( + self.trade_platform_box, wx.VERTICAL + ) + self.trade_platform_cbox = wx.ComboBox( + sub_panel, + -1, + "", + choices=list(trade_platforms)[0], + ) + self.trade_platform_cbox.SetSelection(1) + self.trade_platform_cbox.Bind( + wx.EVT_COMBOBOX, self.on_combobox_trade_platform_changed + ) # noqa: E501 + select_trade_platform = self.trade_platform_cbox.GetValue() + self.trader_opts["platform"] = select_trade_platform + logger.debug(f"select_trade_platform: {select_trade_platform}") + self.trade_platform_sizer.Add( + self.trade_platform_cbox, + proportion=0, + flag=wx.EXPAND | wx.ALL | wx.CENTER, + border=2, + ) + + # 交易参数——交易策略 + self.strategy_select_box = wx.StaticBox(sub_panel, -1, "交易策略选择") + self.strategy_select_sizer = wx.StaticBoxSizer( + self.strategy_select_box, wx.VERTICAL + ) + self.strategy_select_cbox = wx.ComboBox( + sub_panel, + -1, + "", + choices=list(strategy_choices)[0], + ) + self.strategy_select_cbox.SetSelection(0) + self.strategy_select_cbox.Bind( + wx.EVT_COMBOBOX, self._on_combobox_strategy_changed + ) # noqa: E501 + select_strategy = self.strategy_select_cbox.GetValue() + self.trader_opts["strategy"] = select_strategy + logger.debug(f"[{self.trader_class}] select_trade_strategy: {select_strategy}") + if "多因子" in select_strategy: + self.multi_fact_layout() + self.strategy_select_sizer.Add( + self.strategy_select_cbox, + proportion=0, + flag=wx.EXPAND | wx.ALL | wx.CENTER, + border=2, + ) + + # 回测按钮 + self.start_trade_butt = wx.Button(sub_panel, -1, "开始交易") + self.start_trade_butt.SetBackgroundColour(wx.Colour(76, 187, 23)) # 设置背景颜色 + self.start_trade_butt.Bind(wx.EVT_BUTTON, self.OnClickTrade) # 绑定按钮事件 + + # 交易日志 + self.trade_log_butt = wx.Button(sub_panel, -1, "交易日志") + self.trade_log_butt.Bind(wx.EVT_BUTTON, self._ev_trade_log) # 绑定按钮事件 + + self.show_trade_boardview() + + trade_para_sizer.Add( + self.stocks_select_sizer, + proportion=0, + flag=wx.EXPAND | wx.ALL | wx.CENTER, + border=5, + ) + trade_para_sizer.Add( + self.init_code_sizer, + proportion=0, + flag=wx.EXPAND | wx.ALL | wx.CENTER, + border=5, + ) + trade_para_sizer.Add( + self.trade_platform_sizer, + proportion=0, + flag=wx.EXPAND | wx.ALL | wx.CENTER, + border=5, + ) + trade_para_sizer.Add( + self.strategy_select_sizer, + proportion=0, + flag=wx.EXPAND | wx.ALL | wx.CENTER, + border=5, + ) + trade_para_sizer.Add( + self.start_trade_butt, + proportion=0, + flag=wx.EXPAND | wx.ALL | wx.CENTER, + border=5, + ) + trade_para_sizer.Add( + self.trade_log_butt, + proportion=0, + flag=wx.EXPAND | wx.ALL | wx.CENTER, + border=5, + ) + # trade_para_sizer.SetSizeHints(sub_panel) + + return trade_para_sizer + + def _on_combobox_strategy_changed(self, event): + select_strategy = self.strategy_select_cbox.GetValue() + self.trader_opts["strategy"] = select_strategy + logger.info(f"交易策略: You select {select_strategy}") + + def _on_input_code_changed(self, event): + select_code = self.init_code_input.GetValue() + self.trader_opts["trade_code"] = select_code + logger.info(f"回测股票/基金: You select {select_code}") + + def on_combobox_multi_facts_changed(self, event): + self.multi_facts_config = self.combo_multi_facts.GetValue() + logger.info( + f"[{self.trader_class}] 多因子交易策略: You select {self.multi_facts_config}" + ) + # self.trader_opts["strategy"] = self.trade_platform + + def on_combobox_trade_type_changed(self, event): + self.trade_type = self.stocks_select_cbox.GetValue() + logger.info(f"[{self.trader_class}] 交易类型: You select {self.trade_type}") + self.trader_opts["trade_type"] = self.trade_type + + if self.trade_type == "股票": + self.trade_platform_cbox.SetItems(list(trade_platforms)[0]) + self.trader_opts["platform"] = "东方财富" + self.trade_platform_cbox.SetValue("东方财富") + elif self.trade_type == "期货": + self.trade_platform_cbox.SetItems(list(futures_trade_platforms[0])) + self.trader_opts["platform"] = "CTP" + self.trade_platform_cbox.SetValue("CTP") + + self.trader_opts["trade_code"] = "zn2409" # 沪锌2409 + self.init_code_input.SetValue("zn2409") + elif self.trade_type == "BTC": + self.trade_platform_cbox.SetItems(list(btc_trade_platforms)[0]) + self.trader_opts["platform"] = "欧易OKX" + self.trade_platform_cbox.SetValue("欧易OKX") + + self.trader_opts["trade_code"] = "BTCUSDT" + self.init_code_input.SetValue("BTCUSDT") + + print(self.trader_opts) + self.show_trade_boardview() + + def on_combobox_trade_platform_changed(self, event): + self.trade_platform = self.trade_platform_cbox.GetValue() + logger.info(f"[{self.trader_class}] 交易平台: You select {self.trade_platform}") + self.trader_opts["platform"] = self.trade_platform + + self.show_trade_boardview() + + def on_combobox_strategy_changed(self, event): + select_strategy = self.strategy_select_cbox.GetValue() + self.trader_opts["strategy"] = select_strategy + logger.info(f"[{self.trader_class}] 交易策略: You select {select_strategy}") + if "多因子" in select_strategy: + self.multi_fact_layout() + else: + self.remove_multi_fact_layout() + + def OnClickTrade(self, event): + + # MessageDialog("请联系微信:Yida_Zhang2") + + self.start_trade_butt.SetLabel("暂停交易") + self.ClickNum += 1 + if self.ClickNum % 2 == 1: + self.start_trade_butt.SetLabel("开始交易") + self.syslog.re_print("开始虚拟盘交易...\n") + else: + self.start_trade_butt.SetLabel("暂停交易") + self.ClickNum = 0 + logger.info(self.start_trade_butt.GetLabel()) + self.syslog.re_print("暂停虚拟盘交易...\n") + return + + sim_trade_opts = { + "class": "虚拟盘", + "platform": "东方财富", + "trade_type": "股票", + "trade_code": "399006.SZ", + "strategy": "单因子-相对强弱指数RSI", + } + # logger.info(self.trader_opts) + + # ######## 开始虚拟盘交易 ######### + self.trade_engine = TradeEngine(self.trader_opts, self.syslog) + self.trade_engine.login() + self.trade_engine.get_positions() + self.trade_engine.start_trade() + # self.trade_engine.close() + + def show_trade_boardview(self): + print( + "$$$$$$$$$$$$\n####", + self.trader_opts["trade_type"], + self.trader_opts["class"], + ) + if self.trader_opts["trade_type"] == "股票": + juejin_sim = ( + "https://sim.myquant.cn/sim?acc=5e4cdda3-f2fb-11ed-ae27-00163e022aa6" + ) + self.SimTradeWebPanel.show_url(juejin_sim) + logger.info(f"SimTradeWebPanel - {juejin_sim}") + elif self.trader_opts["trade_type"] == "BTC": + huobi_web_url = "https://www.htx.com/zh-cn/grid-exchange/" + if self.trader_opts["platform"] == "火币Huobi": + self.SimTradeWebPanel.show_url(huobi_web_url) + logger.info(f"SimTradeWebPanel - {huobi_web_url}") + elif self.trader_opts["platform"] == "欧易OKX": + okx_url = "https://www.okx.com/zh-hans/trade-spot/btc-usdt" + self.SimTradeWebPanel.show_url(okx_url) + logger.info(f"SimTradeWebPanel - {okx_url}") + elif self.trader_opts["platform"] == "币安Binance": + binance_url = "https://www.binance.com/zh-CN/trade/BTC_USDT?type=spot" + self.SimTradeWebPanel.show_url(binance_url) + logger.info(f"SimTradeWebPanel - {binance_url}") + else: + self.SimTradeWebPanel.show_url( + "https://www.okx.com/zh-hans/trade-spot/btc-usdt" + ) + logger.info( + "SimTradeWebPanel - https://www.okx.com/zh-hans/trade-spot/btc-usdt" + ) + # https://crypto-labs.miladsdgh.ir/ + else: + MessageDialog("交易平台尚未接入,请联系微信:Yida_Zhang2") + + def _ev_trade_log(self, event): + + user_trade_log = UserDialog(self, title="回测提示信息", label="交易详细日志") + + """ 自定义提示框 """ + if user_trade_log.ShowModal() == wx.ID_OK: + pass + else: + pass + + def _ev_click_on_treelist(self, event): + + self.curTreeItem = self.treeListCtrl.GetItemText(event.GetItem()) + + if not self.curTreeItem: + # 当前选中的TreeItemId对象操作 + + MessageDialog("当前点击:{0}!".format(self.curTreeItem)) + for m_key, m_val in self.treeListCtrl.colleges.items(): + for s_key in m_val: + if s_key.get("名称", "") == self.curTreeItem: + if s_key.get("函数", "") != "未定义": + if (m_key == "衍生指标") or (m_key == "K线形态"): + # 第一步:收集控件中设置的选项 + st_label = s_key["标识"] + st_code = self.init_code_input.GetValue() + # st_name = self.code_table.get_name(st_code) + + # 第二步:获取股票数据-使用self.stock_dat存储数据 + if self.stock_dat.empty: + MessageDialog("获取股票数据出错!\n") + else: + MessageDialog("该接口未定义!") + # self.function = getattr( + # Base_Strategy_Group, s_key.get("define", "") + # ) + else: + MessageDialog("该接口未定义!") + break + + def _init_treelist_ctrl(self, subpanel): + + # 创建一个 treeListCtrl object + self.treeListCtrl = CollegeTreeListCtrl( + parent=subpanel, pos=(-1, 39), size=(250, 200) + ) + self.treeListCtrl.Bind(wx.EVT_TREE_SEL_CHANGED, self._ev_click_on_treelist) + + return self.treeListCtrl + + def _init_nav_notebook(self): + + # 创建参数区面板 + self.NavNoteb = wx.Notebook(self) + + self.NavNoteb.AddPage(self._init_treelist_ctrl(self.NavNoteb), "策略导航") + self.NavNoteb.AddPage(self._init_grid_pl(self.NavNoteb), "股票池索引") + + return self.NavNoteb diff --git a/qbot/gui/panels/panel_trade.py b/qbot/gui/panels/panel_trade.py new file mode 100644 index 00000000..0c185566 --- /dev/null +++ b/qbot/gui/panels/panel_trade.py @@ -0,0 +1,47 @@ +#! /usr/bin/env python +# -*- encoding: utf-8 -*- + +import wx + +from qbot.gui.panels.panel_real_trade import RealTradePanel +from qbot.gui.panels.panel_sim_trade import SimTradePanel + +# from qbot.gui.panels.panel_focus_symbs import FocusSymsPanel + + +class TradePanel(wx.Panel): + def __init__(self, parent): + super(TradePanel, self).__init__(parent) + self.init_ui() + + def init_ui(self): + vbox = wx.BoxSizer(wx.VERTICAL) + self.SetSizer(vbox) + + self.trade_tabs = wx.Notebook(self) + + # self.trade_tabs.AddPage(FocusSymsPanel(self.trade_tabs), "我的自选(预留)") + + sim_trade_opts = { + "class": "虚拟盘", + "platform": "东方财富", + "trade_type": "股票", + "trade_code": "399006.SZ", + "strategy": "单因子-相对强弱指数RSI", + } + self.trade_tabs.AddPage(SimTradePanel(self.trade_tabs, sim_trade_opts), "模拟交易") + + real_trade_opts = { + "class": "实盘", + "platform": "东方财富", + "trade_type": "股票", + "trade_code": "399006.SZ", + "strategy": "单因子-相对强弱指数RSI", + } + self.trade_tabs.AddPage( + RealTradePanel(self.trade_tabs, real_trade_opts), "实盘交易" + ) + + self.trade_tabs.SetSelection(1) + + vbox.Add(self.trade_tabs, 1, flag=wx.EXPAND | wx.ALL, border=5) diff --git a/qbot/gui/panels/panel_zhiku.py b/qbot/gui/panels/panel_zhiku.py index eb29c4de..4fac9b5d 100644 --- a/qbot/gui/panels/panel_zhiku.py +++ b/qbot/gui/panels/panel_zhiku.py @@ -5,11 +5,12 @@ import wx import wx.adv -from qbot.common.logging.logger import LOGGER as logger from qbot.common.config import RESEARCH_REPORTS from qbot.common.file_utils import list_files_in_directory -from qbot.gui.widgets.widget_web import WebPanel +from qbot.common.logging.logger import LOGGER as logger from qbot.common.utils import check_port_in_use +from qbot.gui.widgets.widget_web import WebPanel + class QbotHomePanel(wx.Panel): def __init__(self, parent):