QMT Python API
行情示例
获取行情示例
1
# 用前须知2
3
## xtdata提供和MiniQmt的交互接口,本质是和MiniQmt建立连接,由MiniQmt处理行情数据请求,再把结果回传返回到python层。使用的行情服务器以及能获取到的行情数据和MiniQmt是一致的,要检查数据或者切换连接时直接操作MiniQmt即可。4
5
## 对于数据获取接口,使用时需要先确保MiniQmt已有所需要的数据,如果不足可以通过补充数据接口补充,再调用数据获取接口获取。6
7
## 对于订阅接口,直接设置数据回调,数据到来时会由回调返回。订阅接收到的数据一般会保存下来,同种数据不需要再单独补充。8
9
# 代码讲解10
11
# 从本地python导入xtquant库,如果出现报错则说明安装失败12
from xtquant import xtdata13
import time14
15
# 设定一个标的列表16
code_list = ["000001.SZ"]17
# 设定获取数据的周期18
period = "1d"19
20
# 下载标的行情数据21
if 1:22
## 为了方便用户进行数据管理,xtquant的大部分历史数据都是以压缩形式存储在本地的23
## 比如行情数据,需要通过download_history_data下载,财务数据需要通过24
## 所以在取历史数据之前,我们需要调用数据下载接口,将数据下载到本地25
for i in code_list:26
xtdata.download_history_data(i,period=period,incrementally=True) # 增量下载行情数据(开高低收,等等)到本地27
28
xtdata.download_financial_data(code_list) # 下载财务数据到本地29
xtdata.download_sector_data() # 下载板块数据到本地30
# 更多数据的下载方式可以通过数据字典查询31
32
# 读取本地历史行情数据33
history_data = xtdata.get_market_data_ex([],code_list,period=period,count=-1)34
print(history_data)35
print("=" * 20)36
37
# 如果需要盘中的实时行情,需要向服务器进行订阅后才能获取38
# 订阅后,get_market_data函数于get_market_data_ex函数将会自动拼接本地历史行情与服务器实时行情39
40
# 向服务器订阅数据41
for i in code_list:42
xtdata.subscribe_quote(i,period=period,count=-1) # 设置count = -1来取到当天所有实时行情43
44
# 等待订阅完成45
time.sleep(1)46
47
# 获取订阅后的行情48
kline_data = xtdata.get_market_data_ex([],code_list,period=period)49
print(kline_data)50
51
# 获取订阅后的行情,并以固定间隔进行刷新,预期会循环打印10次52
for i in range(10):53
# 这边做演示,就用for来循环了,实际使用中可以用while True54
kline_data = xtdata.get_market_data_ex([],code_list,period=period)55
print(kline_data)56
time.sleep(3) # 三秒后再次获取行情57
58
# 如果不想用固定间隔触发,可以以用订阅后的回调来执行59
# 这种模式下当订阅的callback回调函数将会异步的执行,每当订阅的标的tick发生变化更新,callback回调函数就会被调用一次60
# 本地已有的数据不会触发callback61
62
# 定义的回测函数63
## 回调函数中,data是本次触发回调的数据,只有一条64
def f(data):65
# print(data)66
67
code_list = list(data.keys()) # 获取到本次触发的标的代码68
69
kline_in_callabck = xtdata.get_market_data_ex([],code_list,period = period) # 在回调中获取klines数据70
print(kline_in_callabck)71
72
for i in code_list:73
xtdata.subscribe_quote(i,period=period,count=-1,callback=f) # 订阅时设定回调函数74
75
# 使用回调时,必须要同时使用xtdata.run()来阻塞程序,否则程序运行到最后一行就直接结束退出了。76
xtdata.run()77
78
79
连接VIP服务器
1
# 导入 xtdatacenter 模块2
import sys3
4
print("Python 版本:", sys.version)5
6
7
import time8
import pandas as pd9
from xtquant import xtdatacenter as xtdc10
from xtquant import xtdata11
''' 12
设置用于登录行情服务的token,此接口应该先于 init_quote 调用13
14
token可以从投研用户中心获取15
https://xuntou.net/#/userInfo16
'''17
xtdc.set_token('这里输入token')18
19
'''20
设置连接池,使服务器只在连接池内优选21
22
建议将VIP服务器设为连接池23
'''24
addr_list = [25
'115.231.218.73:55310', 26
'115.231.218.79:55310', 27
'42.228.16.211:55300',28
'42.228.16.210:55300',29
'36.99.48.20:55300',30
'36.99.48.21:55300'31
]32
xtdc.set_allow_optmize_address(addr_list)33
34
xtdc.set_kline_mirror_enabled(True) # 开启K线全推功能(vip),以获取全市场实时K线数据35
36
37
"""38
初始化39
"""40
xtdc.init()41
## 监听端口42
port = xtdc.listen(port = 58621) # 指定固定端口进行连接43
# port = xtdc.listen(port = (58620, 58630))[1] 通过指定port范围,可以让xtdc在范围内自动寻找可用端口44
45
xtdata.connect(port=port)46
47
print('-----连接上了------')48
print(xtdata.data_dir)49
50
51
52
servers = xtdata.get_quote_server_status()53
# print(servers)54
for k, v in servers.items():55
print(k, v)56
57
xtdata.run()58
连接指定服务器
1
2
import time3
from xtquant import xtdata4
5
#用token方式连接,不需要账号密码6
#其他连接方式,需要账号密码7
info = {"ip": '115.231.218.73', "port": 55300, "username": '', "pwd": ''}8
9
connect_success = 010
def func(d):11
ip = d.get('ip', '')12
port = d.get('port')13
status = d.get('status', 'disconnected')14
15
global connect_success16
if ip == info['ip'] and port == info['port']:17
if status == 'connected':18
connect_success = 119
else:20
connect_success = 221
22
# 注册连接回调信息23
xtdata.watch_quote_server_status(func)24
25
# 行情连接26
qs = xtdata.QuoteServer(info)27
qs.connect()28
29
# 获取当前数据连接站点30
data_server_info = xtdata.get_quote_server_status()31
# 显示当前数据连接站点32
if 1:33
for k,v in data_server_info.items():34
print(f"data:{k}, connect info:{v.info}")35
36
37
# 等待连接状态38
while connect_success == 0:39
time.sleep(0.3)40
41
if connect_success == 2:42
print("连接失败")43
指定初始化行情连接范围
1
if 1:2
from xtquant import xtdatacenter as xtdc3
4
## 设置数据目录5
xtdc.set_data_home_dir('data')6
7
## 设置token8
token = "你的token"9
xtdc.set_token(token)10
11
## 限定行情站点的优选范围12
opt_list = [13
'115.231.218.73:55310',14
'115.231.218.79:55310',15
'42.228.16.210:55300',16
'42.228.16.211:55300',17
'36.99.48.20:55300',18
'36.99.48.21:55300',19
]20
xtdc.set_allow_optmize_address(opt_list)21
22
## 开启指定市场的K线全推23
xtdc.set_kline_mirror_markets(['SH', 'SZ', 'BJ'])24
25
## 设置要初始化的市场列表26
init_markets = [27
'SH', 'SZ', 'BJ',28
#'DF', 'GF', 'IF', 'SF', 'ZF', 'INE',29
#'SHO', 'SZO',30
]31
xtdc.set_init_markets(init_markets)32
33
## 初始化xtdc模块34
xtdc.init(start_local_service = False)35
36
## 监听端口37
#xtdc.listen(port = 58620)38
listen_port = xtdc.listen(port = (58620, 58650))39
40
#import code; code.interact(local = locals())41
42
43
import xtquant.xtdata as xtdata44
45
xtdata.connect(port = listen_port)46
47
48
49
import code; code.interact(local = locals())50
51
52
53
订阅全推数据/下载历史数据
1
2
# coding:utf-83
import time4
5
from xtquant import xtdata6
7
code = '600000.SH'8
9
#取全推数据10
full_tick = xtdata.get_full_tick([code])11
print('全推数据 日线最新值', full_tick)12
13
#下载历史数据 下载接口本身不返回数据14
xtdata.download_history_data(code, period='1m', start_time='20230701')15
16
#订阅最新行情17
def callback_func(data):18
print('回调触发', data)19
20
xtdata.subscribe_quote(code, period='1m', count=-1, callback= callback_func)21
data = xtdata.get_market_data(['close'], [code], period='1m', start_time='20230701')22
print('一次性取数据', data)23
24
#死循环 阻塞主线程退出25
xtdata.run()26
获取对手价
1
# 以卖出为例2
3
import pandas as pd4
import numpy as np5
from xtquant import xtdata6
7
to_do_trade_list = ["000001.SZ"]8
tick = xtdata.get_full_tick(to_do_trade_list)9
10
11
# 取买一价为对手价,若买一价为0,说明已经跌停,则取最新价12
for i in tick:13
fix_price = tick[i]["bidPrice"][0] if tick[i]["bidPrice"][0] != 0 else tick[i]["lastPrice"]14
print(fix_price)复权计算方式
1
#coding:utf-82
3
import numpy as np4
import pandas as pd5
6
from xtquant import xtdata7
8
#def gen_divid_ratio(quote_datas, divid_datas):9
# drl = []10
# for qi in range(len(quote_datas)):11
# q = quote_datas.iloc[qi]12
# dr = 1.013
# for di in range(len(divid_datas)):14
# d = divid_datas.iloc[di]15
# if d.name <= q.name:16
# dr *= d['dr']17
# drl.append(dr)18
# return pd.DataFrame(drl, index = quote_datas.index, columns = quote_datas.columns)19
20
def gen_divid_ratio(quote_datas, divid_datas):21
drl = []22
dr = 1.023
qi = 024
qdl = len(quote_datas)25
di = 026
ddl = len(divid_datas)27
while qi < qdl and di < ddl:28
qd = quote_datas.iloc[qi]29
dd = divid_datas.iloc[di]30
if qd.name >= dd.name:31
dr *= dd['dr']32
di += 133
if qd.name <= dd.name:34
drl.append(dr)35
qi += 136
while qi < qdl:37
drl.append(dr)38
qi += 139
return pd.DataFrame(drl, index = quote_datas.index, columns = quote_datas.columns)40
41
def process_forward_ratio(quote_datas, divid_datas):42
drl = gen_divid_ratio(quote_datas, divid_datas)43
drlf = drl / drl.iloc[-1]44
result = (quote_datas * drlf).apply(lambda x: round(x, 2))45
return result46
47
def process_backward_ratio(quote_datas, divid_datas):48
drl = gen_divid_ratio(quote_datas, divid_datas)49
result = (quote_datas * drl).apply(lambda x: round(x, 2))50
return result51
52
def process_forward(quote_datas1, divid_datas):53
quote_datas = quote_datas1.copy()54
def calc_front(v, d):55
return ((v - d['interest'] + d['allotPrice'] * d['allotNum'])56
/ (1 + d['allotNum'] + d['stockBonus'] + d['stockGift']))57
for qi in range(len(quote_datas)):58
q = quote_datas.iloc[qi]59
for di in range(len(divid_datas)):60
d = divid_datas.iloc[di]61
if d.name <= q.name:62
continue63
q.iloc[0] = calc_front(q.iloc[0], d)64
return quote_datas65
66
def process_backward(quote_datas1, divid_datas):67
quote_datas = quote_datas1.copy()68
def calc_back(v, d):69
return ((v * (1.0 + d['stockGift'] + d['stockBonus'] + d['allotNum'])70
+ d['interest'] - d['allotNum'] * d['allotPrice']))71
for qi in range(len(quote_datas)):72
q = quote_datas.iloc[qi]73
for di in range(len(divid_datas) - 1, -1, -1):74
d = divid_datas.iloc[di]75
if d.name > q.name:76
continue77
q.iloc[0] = calc_back(q.iloc[0], d)78
return quote_datas79
80
81
#--------------------------------82
83
s = '002594.SZ'84
85
#xtdata.download_history_data(s, '1d', '20100101', '')86
87
dd = xtdata.get_divid_factors(s)88
print(dd)89
90
#复权计算用于处理价格字段91
field_list = ['open', 'high', 'low', 'close']92
datas_ori = xtdata.get_market_data(field_list, [s], '1d', dividend_type = 'none')['close'].T93
#print(datas_ori)94
95
#等比前复权96
datas_forward_ratio = process_forward_ratio(datas_ori, dd)97
print('datas_forward_ratio', datas_forward_ratio)98
99
#等比后复权100
datas_backward_ratio = process_backward_ratio(datas_ori, dd)101
print('datas_backward_ratio', datas_backward_ratio)102
103
#前复权104
datas_forward = process_forward(datas_ori, dd)105
print('datas_forward', datas_forward)106
107
#后复权108
datas_backward = process_backward(datas_ori, dd)109
print('datas_backward', datas_backward)110
根据商品期货期权代码获取对应的商品期货合约代码
1
from xtquant import xtdata2
3
def get_option_underline_code(code:str) -> str:4
"""5
注意:该函数不适用于股指期货期权与ETF期权6
Todo: 根据商品期权代码获取对应的具体商品期货合约7
Args:8
code:str 期权代码9
Return:10
对应的期货合约代码11
"""12
Exchange_dict = {13
"SHFE":"SF",14
"CZCE":"ZF",15
"DCE":"DF",16
"INE":"INE",17
"GFEX":"GF"18
}19
20
if code.split(".")[-1] not in [v for k,v in Exchange_dict.items()]:21
raise KeyError("此函数不支持该交易所合约")22
info = xtdata.get_option_detail_data(code)23
underline_code = info["OptUndlCode"] + "." + Exchange_dict[info["OptUndlMarket"]]24
25
return underline_code26
27
if __name__ == "__main__":28
29
symbol_code = get_option_underline_code('sc2403C465.INE') # 获取期权合约'sc2403C465.INE'对应的期货合约代码30
print(symbol_code)31
根据指数代码,返回对应的期货合约
1
2
from xtquant import xtdata3
import re4
5
def get_financial_futures_code_from_index(index_code:str) -> list:6
"""7
ToDo:传入指数代码,返回对应的期货合约(当前)8
Args:9
index_code:指数代码,如"000300.SH","000905.SH"10
Retuen:11
list: 对应期货合约列表12
"""13
financial_futures = xtdata.get_stock_list_in_sector("中金所")14
future_list = []15
pattern = r'^[a-zA-Z]{1,2}\d{3,4}\.[A-Z]{2}$'16
for i in financial_futures:17
18
if re.match(pattern,i):19
future_list.append(i)20
ls = []21
for i in future_list:22
_info = xtdata._get_instrument_detail(i)23
_index_code = _info["ExtendInfo"]['OptUndlCode'] + "." + _info["ExtendInfo"]['OptUndlMarket']24
if _index_code == index_code:25
ls.append(i)26
return ls27
28
if __name__ == "__main__":29
ls = get_financial_futures_code_from_index("000905.SH")30
print(ls)31
高频因子数据创建
1
#coding:utf-82
3
4
import xtquant.invadv as xtia5
6
7
remote_host = '115.231.218.7'8
remote_port = 553009
user_name = '授权账号'10
password = '授权账号对应密码'11
12
# 连接云服务13
api = xtia.InvAdv()14
api.set_remote_addr(remote_host, remote_port)15
api.set_user(user_name, password)16
api.connect()17
18
# 查询高频因子数据列表19
ret_sector_dict = api.get_block_list()20
new_dict = {v: k for k, v in ret_sector_dict.items()}21
22
# 创建新的因子23
fp_name = '盘口价差'24
if fp_name not in new_dict:25
api.create_block(fp_name)26
print(f'创建{fp_name}表')27
28
# 格式 {股票1: 因子值, 股票2: 因子值 ...}29
codes = {'002594.SZ': 0.009, '300750.SZ': 0.007, '688001.SH': 0.1, '000001.SZ':0.2, '300751.SZ':0.3}30
31
# 查询高频因子数据列表32
ret_sector_dict = api.get_block_list()33
print(f'查询高频因子数据列表:{ret_sector_dict}')34
35
36
# 创建高频因子内容37
for k_msg_id, v in ret_sector_dict.items():38
write_codes = []39
if v == fp_name:40
for code, value in codes.items():41
write_codes.append(f'{code}|{value}')42
# 创建代码43
api.push_block(k_msg_id, write_codes)44
print(f'表:{fp_name} id:{k_msg_id} {write_codes}')45
print(f'创建结束!')46
47
48
print('====end====')49
50
交易示例
简单买卖各一笔示例
需要调整的参数:
98行的path变量需要改为本地客户端路径,券商端指定到 f"{安装目录}\userdata_mini",投研端指定到f"{安装目录}\userdata"107行的资金账号需要调整为自身资金账号
1
# coding:utf-82
import time, datetime, traceback, sys3
from xtquant import xtdata4
from xtquant.xttrader import XtQuantTrader, XtQuantTraderCallback5
from xtquant.xttype import StockAccount6
from xtquant import xtconstant7
8
9
# 定义一个类 创建类的实例 作为状态的容器10
class _a():11
pass12
13
14
A = _a()15
A.bought_list = []16
A.hsa = xtdata.get_stock_list_in_sector('沪深A股')17
18
19
def interact():20
"""执行后进入repl模式"""21
import code22
code.InteractiveConsole(locals=globals()).interact()23
24
25
xtdata.download_sector_data()26
27
28
29
class MyXtQuantTraderCallback(XtQuantTraderCallback):30
def on_disconnected(self):31
"""32
连接断开33
:return:34
"""35
print(datetime.datetime.now(), '连接断开回调')36
37
def on_stock_order(self, order):38
"""39
委托回报推送40
:param order: XtOrder对象41
:return:42
"""43
print(datetime.datetime.now(), '委托回调 投资备注', order.order_remark)44
45
def on_stock_trade(self, trade):46
"""47
成交变动推送48
:param trade: XtTrade对象49
:return:50
"""51
print(datetime.datetime.now(), '成交回调', trade.order_remark, f"委托方向(48买 49卖) {trade.offset_flag} 成交价格 {trade.traded_price} 成交数量 {trade.traded_volume}")52
53
def on_order_error(self, order_error):54
"""55
委托失败推送56
:param order_error:XtOrderError 对象57
:return:58
"""59
# print("on order_error callback")60
# print(order_error.order_id, order_error.error_id, order_error.error_msg)61
print(f"委托报错回调 {order_error.order_remark} {order_error.error_msg}")62
63
def on_cancel_error(self, cancel_error):64
"""65
撤单失败推送66
:param cancel_error: XtCancelError 对象67
:return:68
"""69
print(datetime.datetime.now(), sys._getframe().f_code.co_name)70
71
def on_order_stock_async_response(self, response):72
"""73
异步下单回报推送74
:param response: XtOrderResponse 对象75
:return:76
"""77
print(f"异步委托回调 投资备注: {response.order_remark}")78
79
def on_cancel_order_stock_async_response(self, response):80
"""81
:param response: XtCancelOrderResponse 对象82
:return:83
"""84
print(datetime.datetime.now(), sys._getframe().f_code.co_name)85
86
def on_account_status(self, status):87
"""88
:param response: XtAccountStatus 对象89
:return:90
"""91
print(datetime.datetime.now(), sys._getframe().f_code.co_name)92
93
94
if __name__ == '__main__':95
print("start")96
# 指定客户端所在路径, 券商端指定到 userdata_mini文件夹97
# 注意:如果是连接投研端进行交易,文件目录需要指定到f"{安装目录}\userdata"98
path = r'D:\qmt\投研\迅投极速交易终端睿智融科版\userdata'99
# 生成session id 整数类型 同时运行的策略不能重复100
session_id = int(time.time())101
xt_trader = XtQuantTrader(path, session_id)102
# 开启主动请求接口的专用线程 开启后在on_stock_xxx回调函数里调用XtQuantTrader.query_xxx函数不会卡住回调线程,但是查询和推送的数据在时序上会变得不确定103
# 详见: /docs/xtquant/xttrader.html#开启主动请求接口的专用线程104
# xt_trader.set_relaxed_response_order_enabled(True)105
106
# 创建资金账号为 800068 的证券账号对象 股票账号为STOCK 信用CREDIT 期货FUTURE107
acc = StockAccount('2000128', 'STOCK')108
# 创建交易回调类对象,并声明接收回调109
callback = MyXtQuantTraderCallback()110
xt_trader.register_callback(callback)111
# 启动交易线程112
xt_trader.start()113
# 建立交易连接,返回0表示连接成功114
connect_result = xt_trader.connect()115
print('建立交易连接,返回0表示连接成功', connect_result)116
# 对交易回调进行订阅,订阅后可以收到交易主推,返回0表示订阅成功117
subscribe_result = xt_trader.subscribe(acc)118
print('对交易回调进行订阅,订阅后可以收到交易主推,返回0表示订阅成功', subscribe_result)119
#取账号信息120
account_info = xt_trader.query_stock_asset(acc)121
#取可用资金122
available_cash = account_info.m_dCash123
124
print(acc.account_id, '可用资金', available_cash)125
#查账号持仓126
positions = xt_trader.query_stock_positions(acc)127
#取各品种 总持仓 可用持仓128
position_total_dict = {i.stock_code : i.m_nVolume for i in positions}129
position_available_dict = {i.stock_code : i.m_nCanUseVolume for i in positions}130
print(acc.account_id, '持仓字典', position_total_dict)131
print(acc.account_id, '可用持仓字典', position_available_dict)132
133
#买入 浦发银行 最新价 两万元134
stock = '600000.SH'135
target_amount = 20000136
full_tick = xtdata.get_full_tick([stock])137
print(f"{stock} 全推行情: {full_tick}")138
current_price = full_tick[stock]['lastPrice']139
#买入金额 取目标金额 与 可用金额中较小的140
buy_amount = min(target_amount, available_cash)141
#买入数量 取整为100的整数倍142
buy_vol = int(buy_amount / current_price / 100) * 100143
print(f"当前可用资金 {available_cash} 目标买入金额 {target_amount} 买入股数 {buy_vol}股")144
async_seq = xt_trader.order_stock_async(acc, stock, xtconstant.STOCK_BUY, buy_vol, xtconstant.FIX_PRICE, current_price,145
'strategy_name', stock)146
147
#卖出 500股148
stock = '513130.SH'149
#目标数量150
target_vol = 500151
#可用数量152
available_vol = position_available_dict[stock] if stock in position_available_dict else 0153
#卖出量取目标量与可用量中较小的154
sell_vol = min(target_vol, available_vol)155
print(f"{stock} 目标卖出量 {target_vol} 可用数量 {available_vol} 卖出 {sell_vol}股")156
if sell_vol > 0:157
async_seq = xt_trader.order_stock_async(acc, stock, xtconstant.STOCK_SELL, sell_vol, xtconstant.LATEST_PRICE,158
-1,159
'strategy_name', stock)160
print(f"下单完成 等待回调")161
# 阻塞主线程退出162
xt_trader.run_forever()163
# 如果使用vscode pycharm等本地编辑器 可以进入交互模式 方便调试 (把上一行的run_forever注释掉 否则不会执行到这里)164
interact()165
166
单股订阅实盘示例
需要调整的参数:
113行的path变量需要改为本地客户端路径,券商端指定到 f"{安装目录}\userdata_mini",投研端指定到f"{安装目录}\userdata"122行的资金账号需要调整为自身资金账号
1
# coding:utf-82
import time, datetime, traceback, sys3
from xtquant import xtdata4
from xtquant.xttrader import XtQuantTrader, XtQuantTraderCallback5
from xtquant.xttype import StockAccount6
from xtquant import xtconstant7
8
9
# 定义一个类 创建类的实例 作为状态的容器10
class _a():11
pass12
13
14
A = _a()15
A.bought_list = []16
A.hsa = xtdata.get_stock_list_in_sector('沪深A股')17
18
19
def interact():20
"""执行后进入repl模式"""21
import code22
code.InteractiveConsole(locals=globals()).interact()23
24
25
xtdata.download_sector_data()26
27
28
def f(data):29
print(data)30
now = datetime.datetime.now()31
for stock in data:32
if stock not in A.hsa:33
continue34
cuurent_price = data[stock][0]['close']35
pre_price = data[stock][0]['preClose']36
ratio = cuurent_price / pre_price - 1 if pre_price > 0 else 037
if ratio > 0.09 and stock not in A.bought_list:38
print(f"{now} 最新价 买入 {stock} 100股")39
async_seq = xt_trader.order_stock_async(acc, stock, xtconstant.STOCK_BUY, 100, xtconstant.LATEST_PRICE, -1,40
'strategy_name', stock)41
A.bought_list.append(stock)42
43
44
class MyXtQuantTraderCallback(XtQuantTraderCallback):45
def on_disconnected(self):46
"""47
连接断开48
:return:49
"""50
print(datetime.datetime.now(), '连接断开回调')51
52
def on_stock_order(self, order):53
"""54
委托回报推送55
:param order: XtOrder对象56
:return:57
"""58
print(datetime.datetime.now(), '委托回调', order.order_remark)59
60
def on_stock_trade(self, trade):61
"""62
成交变动推送63
:param trade: XtTrade对象64
:return:65
"""66
print(datetime.datetime.now(), '成交回调', trade.order_remark)67
68
def on_order_error(self, order_error):69
"""70
委托失败推送71
:param order_error:XtOrderError 对象72
:return:73
"""74
# print("on order_error callback")75
# print(order_error.order_id, order_error.error_id, order_error.error_msg)76
print(f"委托报错回调 {order_error.order_remark} {order_error.error_msg}")77
78
def on_cancel_error(self, cancel_error):79
"""80
撤单失败推送81
:param cancel_error: XtCancelError 对象82
:return:83
"""84
print(datetime.datetime.now(), sys._getframe().f_code.co_name)85
86
def on_order_stock_async_response(self, response):87
"""88
异步下单回报推送89
:param response: XtOrderResponse 对象90
:return:91
"""92
print(f"异步委托回调 {response.order_remark}")93
94
def on_cancel_order_stock_async_response(self, response):95
"""96
:param response: XtCancelOrderResponse 对象97
:return:98
"""99
print(datetime.datetime.now(), sys._getframe().f_code.co_name)100
101
def on_account_status(self, status):102
"""103
:param response: XtAccountStatus 对象104
:return:105
"""106
print(datetime.datetime.now(), sys._getframe().f_code.co_name)107
108
109
if __name__ == '__main__':110
print("start")111
# 指定客户端所在路径, 券商端指定到 userdata_mini文件夹112
# 注意:如果是连接投研端进行交易,文件目录需要指定到f"{安装目录}\userdata"113
path = r'D:\qmt\投研\迅投极速交易终端睿智融科版\userdata'114
# 生成session id 整数类型 同时运行的策略不能重复115
session_id = int(time.time())116
xt_trader = XtQuantTrader(path, session_id)117
# 开启主动请求接口的专用线程 开启后在on_stock_xxx回调函数里调用XtQuantTrader.query_xxx函数不会卡住回调线程,但是查询和推送的数据在时序上会变得不确定118
# 详见: /docs/xtquant/xttrader.html#开启主动请求接口的专用线程119
# xt_trader.set_relaxed_response_order_enabled(True)120
121
# 创建资金账号为 800068 的证券账号对象 股票账号为STOCK 信用CREDIT 期货FUTURE122
acc = StockAccount('2000128', 'STOCK')123
# 创建交易回调类对象,并声明接收回调124
callback = MyXtQuantTraderCallback()125
xt_trader.register_callback(callback)126
# 启动交易线程127
xt_trader.start()128
# 建立交易连接,返回0表示连接成功129
connect_result = xt_trader.connect()130
print('建立交易连接,返回0表示连接成功', connect_result)131
# 对交易回调进行订阅,订阅后可以收到交易主推,返回0表示订阅成功132
subscribe_result = xt_trader.subscribe(acc)133
print('对交易回调进行订阅,订阅后可以收到交易主推,返回0表示订阅成功', subscribe_result)134
135
#订阅的品种列表136
code_list = ['600000.SH', '000001.SZ']137
138
for code in code_list:139
xtdata.subscribe_quote(code, '1d', callback = f)140
141
# 阻塞主线程退出142
xt_trader.run_forever()143
# 如果使用vscode pycharm等本地编辑器 可以进入交互模式 方便调试 (把上一行的run_forever注释掉 否则不会执行到这里)144
interact()145
146
全推订阅实盘示例
本示例用于展示如何订阅上海及深圳市场全推,对于沪深A股品种策略进行判断当前涨幅超过 9 个点的买入 200 股
需要调整的参数:
111行的path变量需要改为本地客户端路径116行的资金账号需要调整为自身资金账号
注意
本策略只用于提供策略写法及参考,若您直接进行实盘下单,造成损失本网站不负担责任。
1
#coding:utf-82
import time, datetime, traceback, sys3
from xtquant import xtdata4
from xtquant.xttrader import XtQuantTrader, XtQuantTraderCallback5
from xtquant.xttype import StockAccount6
from xtquant import xtconstant7
8
#定义一个类 创建类的实例 作为状态的容器9
class _a():10
pass11
A = _a()12
A.bought_list = []13
A.hsa = xtdata.get_stock_list_in_sector('沪深A股')14
15
def interact():16
"""执行后进入repl模式"""17
import code18
code.InteractiveConsole(locals=globals()).interact()19
xtdata.download_sector_data()20
21
def f(data):22
now = datetime.datetime.now()23
for stock in data:24
if stock not in A.hsa:25
continue26
cuurent_price = data[stock][0]['lastPrice']27
pre_price = data[stock][0]['lastClose']28
ratio = cuurent_price / pre_price - 1 if pre_price > 0 else 029
if ratio > 0.09 and stock not in A.bought_list:30
print(f"{now} 最新价 买入 {stock} 200股")31
async_seq = xt_trader.order_stock_async(acc, stock, xtconstant.STOCK_BUY, 200, xtconstant.LATEST_PRICE, -1, 'strategy_name', stock)32
A.bought_list.append(stock)33
34
class MyXtQuantTraderCallback(XtQuantTraderCallback):35
def on_disconnected(self):36
"""37
连接断开38
:return:39
"""40
print(datetime.datetime.now(),'连接断开回调')41
42
def on_stock_order(self, order):43
"""44
委托回报推送45
:param order: XtOrder对象46
:return:47
"""48
print(datetime.datetime.now(), '委托回调', order.order_remark)49
50
51
def on_stock_trade(self, trade):52
"""53
成交变动推送54
:param trade: XtTrade对象55
:return:56
"""57
print(datetime.datetime.now(), '成交回调', trade.order_remark)58
59
60
def on_order_error(self, order_error):61
"""62
委托失败推送63
:param order_error:XtOrderError 对象64
:return:65
"""66
# print("on order_error callback")67
# print(order_error.order_id, order_error.error_id, order_error.error_msg)68
print(f"委托报错回调 {order_error.order_remark} {order_error.error_msg}")69
70
def on_cancel_error(self, cancel_error):71
"""72
撤单失败推送73
:param cancel_error: XtCancelError 对象74
:return:75
"""76
print(datetime.datetime.now(), sys._getframe().f_code.co_name)77
78
def on_order_stock_async_response(self, response):79
"""80
异步下单回报推送81
:param response: XtOrderResponse 对象82
:return:83
"""84
print(f"异步委托回调 {response.order_remark}")85
86
def on_cancel_order_stock_async_response(self, response):87
"""88
:param response: XtCancelOrderResponse 对象89
:return:90
"""91
print(datetime.datetime.now(), sys._getframe().f_code.co_name)92
93
def on_account_status(self, status):94
"""95
:param response: XtAccountStatus 对象96
:return:97
"""98
print(datetime.datetime.now(), sys._getframe().f_code.co_name)99
100
101
if __name__ == '__main__':102
print("start")103
#指定客户端所在路径,104
# 注意:如果是连接投研端进行交易,文件目录需要指定到f"{安装目录}\userdata"105
path = r'D:\qmt\sp3\迅投极速交易终端 睿智融科版\userdata_mini'106
# 生成session id 整数类型 同时运行的策略不能重复107
session_id = int(time.time())108
xt_trader = XtQuantTrader(path, session_id)109
# 开启主动请求接口的专用线程 开启后在on_stock_xxx回调函数里调用XtQuantTrader.query_xxx函数不会卡住回调线程,但是查询和推送的数据在时序上会变得不确定110
# 详见: /docs/xtquant/xttrader.html#开启主动请求接口的专用线程111
# xt_trader.set_relaxed_response_order_enabled(True)112
113
# 创建资金账号为 800068 的证券账号对象114
acc = StockAccount('800068', 'STOCK')115
# 创建交易回调类对象,并声明接收回调116
callback = MyXtQuantTraderCallback()117
xt_trader.register_callback(callback)118
# 启动交易线程119
xt_trader.start()120
# 建立交易连接,返回0表示连接成功121
connect_result = xt_trader.connect()122
print('建立交易连接,返回0表示连接成功', connect_result)123
# 对交易回调进行订阅,订阅后可以收到交易主推,返回0表示订阅成功124
subscribe_result = xt_trader.subscribe(acc)125
print('对交易回调进行订阅,订阅后可以收到交易主推,返回0表示订阅成功', subscribe_result)126
127
#这一行是注册全推回调函数 包括下单判断 安全起见处于注释状态 确认理解效果后再放开128
# xtdata.subscribe_whole_quote(["SH", "SZ"], callback=f)129
# 阻塞主线程退出130
xt_trader.run_forever()131
# 如果使用vscode pycharm等本地编辑器 可以进入交互模式 方便调试 (把上一行的run_forever注释掉 否则不会执行到这里)132
interact()定时判断实盘示例
1
# coding:utf-82
import time, datetime, traceback, sys3
from xtquant import xtdata4
from xtquant.xttrader import XtQuantTrader, XtQuantTraderCallback5
from xtquant.xttype import StockAccount6
from xtquant import xtconstant7
8
9
# 定义一个类 创建类的实例 作为状态的容器10
class _a():11
pass12
13
14
A = _a()15
A.bought_list = []16
A.hsa = xtdata.get_stock_list_in_sector('沪深A股')17
18
19
def interact():20
"""执行后进入repl模式"""21
import code22
code.InteractiveConsole(locals=globals()).interact()23
24
25
xtdata.download_sector_data()26
27
28
def f(data):29
now = datetime.datetime.now()30
# print(data)31
for stock in data:32
if stock not in A.hsa:33
continue34
cuurent_price = data[stock].iloc[-1, 0]35
pre_price = data[stock].iloc[-2, 0]36
ratio = cuurent_price / pre_price - 1 if pre_price > 0 else 037
if ratio > 0.09 and stock not in A.bought_list:38
print(f"{now} 最新价 买入 {stock} 100股")39
async_seq = xt_trader.order_stock_async(acc, stock, xtconstant.STOCK_BUY, 100, xtconstant.LATEST_PRICE, -1,40
'strategy_name', stock)41
A.bought_list.append(stock)42
43
44
class MyXtQuantTraderCallback(XtQuantTraderCallback):45
def on_disconnected(self):46
"""47
连接断开48
:return:49
"""50
print(datetime.datetime.now(), '连接断开回调')51
52
def on_stock_order(self, order):53
"""54
委托回报推送55
:param order: XtOrder对象56
:return:57
"""58
print(datetime.datetime.now(), '委托回调', order.order_remark)59
60
def on_stock_trade(self, trade):61
"""62
成交变动推送63
:param trade: XtTrade对象64
:return:65
"""66
print(datetime.datetime.now(), '成交回调', trade.order_remark)67
68
def on_order_error(self, order_error):69
"""70
委托失败推送71
:param order_error:XtOrderError 对象72
:return:73
"""74
# print("on order_error callback")75
# print(order_error.order_id, order_error.error_id, order_error.error_msg)76
print(f"委托报错回调 {order_error.order_remark} {order_error.error_msg}")77
78
def on_cancel_error(self, cancel_error):79
"""80
撤单失败推送81
:param cancel_error: XtCancelError 对象82
:return:83
"""84
print(datetime.datetime.now(), sys._getframe().f_code.co_name)85
86
def on_order_stock_async_response(self, response):87
"""88
异步下单回报推送89
:param response: XtOrderResponse 对象90
:return:91
"""92
print(f"异步委托回调 {response.order_remark}")93
94
def on_cancel_order_stock_async_response(self, response):95
"""96
:param response: XtCancelOrderResponse 对象97
:return:98
"""99
print(datetime.datetime.now(), sys._getframe().f_code.co_name)100
101
def on_account_status(self, status):102
"""103
:param response: XtAccountStatus 对象104
:return:105
"""106
print(datetime.datetime.now(), sys._getframe().f_code.co_name)107
108
109
if __name__ == '__main__':110
print("start")111
# 指定客户端所在路径, 券商端指定到 userdata_mini文件夹112
# 注意:如果是连接投研端进行交易,文件目录需要指定到f"{安装目录}\userdata"113
path = r'D:\qmt\投研\迅投极速交易终端睿智融科版\userdata'114
# 生成session id 整数类型 同时运行的策略不能重复115
session_id = int(time.time())116
xt_trader = XtQuantTrader(path, session_id)117
# 开启主动请求接口的专用线程 开启后在on_stock_xxx回调函数里调用XtQuantTrader.query_xxx函数不会卡住回调线程,但是查询和推送的数据在时序上会变得不确定118
# 详见: /docs/xtquant/xttrader.html#开启主动请求接口的专用线程119
# xt_trader.set_relaxed_response_order_enabled(True)120
121
# 创建资金账号为 800068 的证券账号对象 股票账号为STOCK 信用CREDIT 期货FUTURE122
acc = StockAccount('2000128', 'STOCK')123
# 创建交易回调类对象,并声明接收回调124
callback = MyXtQuantTraderCallback()125
xt_trader.register_callback(callback)126
# 启动交易线程127
xt_trader.start()128
# 建立交易连接,返回0表示连接成功129
connect_result = xt_trader.connect()130
print('建立交易连接,返回0表示连接成功', connect_result)131
# 对交易回调进行订阅,订阅后可以收到交易主推,返回0表示订阅成功132
subscribe_result = xt_trader.subscribe(acc)133
print('对交易回调进行订阅,订阅后可以收到交易主推,返回0表示订阅成功', subscribe_result)134
135
#订阅的品种列表136
code_list = ['600000.SH', '000001.SZ']137
#遍历品种 下载历史k线 订阅当日行情138
for code in code_list:139
xtdata.download_history_data(code, period='1d', start_time='20200101')140
xtdata.subscribe_quote(code, '1d', callback = None)141
142
while True:143
now = datetime.datetime.now()144
now_time = now.strftime('%H%M%S')145
if not '093000' <= now_time < '150000':146
print(f"{now} 非交易时间 循环退出")147
break148
#取k线数据149
data = xtdata.get_market_data_ex(['close'], code_list, period= '1d', start_time= '20240101')150
#判断交易151
f(data)152
#每次循环 睡眠三秒后继续153
time.sleep(3)154
155
156
# 阻塞主线程退出157
xt_trader.run_forever()158
# 如果使用vscode pycharm等本地编辑器 可以进入交互模式 方便调试 (把上一行的run_forever注释掉 否则不会执行到这里)159
interact()160
交易接口重连
该示例演示交易连接断开时重连的代码处理。
提示
- 该示例不是线程安全的,仅演示断开连接时应该怎么处理重连代码,实际使用时请注意避免潜在的问题
- 本策略只用于提供策略写法及参考,若您直接进行实盘下单,造成损失本网站不负担责任。
1
2
#本文用一个均线策略演示交易连接断开时怎么处理交易接口重连3
# 策略本身不严谨,不能作为实盘策略或者参考策略,本策略仅是演示重连用法4
import time5
from xtquant.xttrader import XtQuantTrader, XtQuantTraderCallback6
from xtquant.xttype import StockAccount7
from xtquant import xtconstant8
from xtquant import xtdata9
10
11
class MyXtQuantTraderCallback(XtQuantTraderCallback):12
# 更多说明见 /docs/xtquant/xttrader.html#委托xtorder13
def on_disconnected(self):14
"""15
连接断开16
:return:17
"""18
print("connection lost, 交易接口断开,即将重连")19
global xt_trader20
xt_trader = None21
22
def on_stock_order(self, order):23
print(f'委托回报: 股票代码:{order.stock_code} 账号:{order.account_id}, 订单编号:{order.order_id} 柜台合同编号:{order.order_sysid} \24
委托状态:{order.order_status} 成交数量:{order.order_status} 委托数量:{order.order_volume} 已成数量:{order.traded_volume}')25
26
def on_stock_trade(self, trade):27
print(f'成交回报: 股票代码:{trade.stock_code} 账号:{trade.account_id}, 订单编号:{trade.order_id} 柜台合同编号:{trade.order_sysid} \28
成交编号:{trade.traded_id} 成交数量:{trade.traded_volume} 委托数量:{trade.direction} ')29
30
def on_order_error(self, order_error):31
print(f"报单失败: 订单编号:{order_error.order_id} 下单失败具体信息:{order_error.error_msg} 委托备注:{order_error.order_remark}")32
33
def on_cancel_error(self, cancel_error):34
print(f"撤单失败: 订单编号:{cancel_error.order_id} 失败具体信息:{cancel_error.error_msg} 市场:{cancel_error.market}")35
36
def on_order_stock_async_response(self, response):37
print(f"异步下单的请求序号:{response.seq}, 订单编号:{response.order_id} ")38
39
def on_account_status(self, status):40
print(f"账号状态发生变化, 账号:{status.account_id} 最新状态:{status.status}")41
42
def create_trader(xt_acc,path, session_id):43
trader = XtQuantTrader(path, session_id,callback=MyXtQuantTraderCallback())44
trader.start()45
connect_result = trader.connect()46
trader.subscribe(xt_acc)47
return trader if connect_result == 0 else None48
49
50
def try_connect(xt_acc,path):51
session_id_range = [i for i in range(100, 120)]52
53
import random54
random.shuffle(session_id_range)55
56
# 遍历尝试session_id列表尝试连接57
for session_id in session_id_range:58
trader = create_trader(xt_acc,path, session_id)59
if trader:60
print('连接成功,session_id:{}', session_id)61
return trader62
else:63
print('连接失败,session_id:{},继续尝试下一个id', session_id)64
continue65
66
print('所有id都尝试后仍失败,放弃连接')67
return None68
69
70
def get_xttrader(xt_acc,path):71
global xt_trader72
if xt_trader is None:73
xt_trader = try_connect(xt_acc,path)74
return xt_trader75
76
77
if __name__ == "__main__":78
79
# 注意实际连接XtQuantTrader时不要写类似while True 这种无限循环的尝试,因为每次连接都会用session_id创建一个对接文件,这样就会占满硬盘导致电脑运行异常80
# 要控制session_id在有限的范围内尝试,这里提供10个session_id供重连尝试81
# 当所有session_id都尝试后,程序会抛出异常。实际使用过程中当session_id用完时,可以增加邮件等通知方式提醒人工处理 82
83
#指定客户端所在路径84
path = 'E:\qmt\\userdata_mini'85
xt_trader = None86
xt_acc = StockAccount('2000204')87
xt_trader = get_xttrader(xt_acc,path)88
if not xt_trader:89
raise Exception('交易接口连接失败')90
print('交易接口连接成功, 策略开始')91
92
stock = '513050.SH'93
xtdata.subscribe_quote(stock, '5m','','',count=-1)94
time.sleep(1)95
order_record = []96
while '093000'<=time.strftime('%H%M%S')<'150000':97
time.sleep(3)98
xt_trader = get_xttrader(xt_acc,path)99
100
price = xtdata.get_market_data_ex(['close'],[stock],period='5m',)[stock]101
#计算均线102
ma5 = price['close'].rolling(5).mean()103
ma10 = price['close'].rolling(10).mean()104
105
if ma5.iloc[-1]>ma5.iloc[-10]:106
t = price.index[-1]107
order_flag = (t, '买')108
if order_flag not in order_record: #防止重复下单109
print(f'发起买入 {stock} k线时间:{t}')110
111
# 用最新价买100股112
xt_trader.order_stock_async(xt_acc, stock, xtconstant.STOCK_BUY,100,xtconstant.LATEST_PRICE,0)113
order_record.append(order_flag)114
elif ma5.iloc[-1]<ma5[-10]:115
t = price.index[-1]116
order_flag = (t, '卖')117
if order_flag not in order_record: #防止重复下单118
print(f'发起卖出 {stock} k线时间:{t}')119
# 用最新价买100股120
xt_trader.order_stock_async(xt_acc, stock, xtconstant.STOCK_SELL,100,xtconstant.LATEST_PRICE,0)121
122
order_record.append(order_flag)123
124
指定session id范围连接交易
该示例演示指定session重试连接次数的代码处理。
1
2
#coding:utf-83
4
def connect(path, session):5
from xtquant import xttrader6
7
trader = xttrader.XtQuantTrader(path, session)8
trader.start()9
10
connect_result = trader.connect()11
return trader if connect_result == 0 else None12
13
14
def try_connect_range():15
# 随机 session_id 的待尝试列表16
# 100以内的id保留17
ids = [i for i in range(100, 200)]18
19
import random20
random.shuffle(ids)21
22
# 要连接到的对接路径23
path = r'userdata_mini'24
25
# 遍历id列表尝试连接26
for session_id in ids:27
print(f'尝试id:{session_id}')28
trader = connect(path, session_id)29
30
if trader:31
print('连接成功')32
return trader33
else:34
print('连接失败,继续尝试下一个id')35
continue36
37
# 所有id都尝试后仍失败,放弃连接38
raise Exception('XtQuantTrader 连接失败,请重试')39
40
41
try:42
trader = try_connect_range()43
except Exception as e:44
import traceback45
print(e, traceback.format_exc())46
47
48
import time49
while True:50
print('.', end = '')51
time.sleep(2)52
53
54
55
信用账号执行还款
本示例用于展示如何使用xtquant库对信用账号执行还款的操作
提示
本策略只用于提供策略写法及参考,若您直接进行实盘下单,造成损失本网站不负担责任。
1
#coding=utf-82
from xtquant.xttrader import XtQuantTrader, XtQuantTraderCallback3
from xtquant.xttype import StockAccount4
from xtquant import xtconstant5
6
# 修改参数7
# path为mini qmt客户端安装目录下userdata_mini路径8
path = 'E:\\qmt\\userdata_mini'9
# session_id为会话编号,策略使用方对于不同的Python策略需要使用不同的会话编号10
session_id = 123456711
repay_money = 1000.51 # 元,需要执行还款的金额12
13
class MyXtQuantTraderCallback(XtQuantTraderCallback):14
def on_disconnected(self):15
"""16
连接断开17
:return:18
"""19
print("connection lost")20
def on_stock_order(self, order):21
"""22
委托回报推送23
:param order: XtOrder对象24
:return:25
"""26
print("on order callback:")27
print(order.stock_code, order.order_status, order.order_sysid)28
def on_stock_asset(self, asset):29
"""30
资金变动推送31
:param asset: XtAsset对象32
:return:33
"""34
print("on asset callback")35
print(asset.account_id, asset.cash, asset.total_asset)36
def on_stock_trade(self, trade):37
"""38
成交变动推送39
:param trade: XtTrade对象40
:return:41
"""42
print("on trade callback")43
print(trade.account_id, trade.stock_code, trade.order_id)44
def on_order_error(self, order_error):45
"""46
委托失败推送47
:param order_error:XtOrderError 对象48
:return:49
"""50
print("on order_error callback")51
print(order_error.order_id, order_error.error_id, order_error.error_msg)52
def on_cancel_error(self, cancel_error):53
"""54
撤单失败推送55
:param cancel_error: XtCancelError 对象56
:return:57
"""58
print("on cancel_error callback")59
print(cancel_error.order_id, cancel_error.error_id, cancel_error.error_msg)60
def on_order_stock_async_response(self, response):61
"""62
异步下单回报推送63
:param response: XtOrderResponse 对象64
:return:65
"""66
print("on_order_stock_async_response")67
print(response.account_id, response.order_id, response.seq)68
def on_account_status(self, status):69
"""70
:param response: XtAccountStatus 对象71
:return:72
"""73
print("on_account_status")74
print(status.account_id, status.account_type, status.status)75
76
77
if __name__ == "__main__":78
print("demo test")79
80
81
xt_trader = XtQuantTrader(path, session_id)82
# 创建资金账号为1000000365的证券账号对象83
acc = StockAccount('200035', 'CREDIT')84
# StockAccount可以用第二个参数指定账号类型,如沪港通传'HUGANGTONG',深港通传'SHENGANGTONG'85
# acc = StockAccount('1000000365','STOCK')86
# 创建交易回调类对象,并声明接收回调87
callback = MyXtQuantTraderCallback()88
xt_trader.register_callback(callback)89
# 启动交易线程90
xt_trader.start()91
# 建立交易连接,返回0表示连接成功92
connect_result = xt_trader.connect()93
if connect_result != 0:94
import sys95
sys.exit('连接失败,程序即将退出 %d'%connect_result)96
# 对交易回调进行订阅,订阅后可以收到交易主推,返回0表示订阅成功97
subscribe_result = xt_trader.subscribe(acc)98
if subscribe_result != 0:99
print('账号订阅失败 %d'%subscribe_result)100
print(subscribe_result)101
stock_code = '600000.SH' # 参数占位用,任意股票代码都可以102
volume = 200 # 参数占位用,任意数量103
# 使用指定价下单,接口返回订单编号,后续可以用于撤单操作以及查询委托状态104
fix_result_order_id = xt_trader.order_stock(acc, stock_code, xtconstant.CREDIT_DIRECT_CASH_REPAY, repay_money, xtconstant.FIX_PRICE, -1, 'strategy_name', 'remark')105
106
# 阻塞线程,接收交易推送107
xt_trader.run_forever()下单后通过回调撤单
1
import pandas as pd2
import numpy as np3
import datetime4
from xtquant import xtdata,xttrader5
from xtquant.xttype import StockAccount6
from xtquant import xtconstant7
from xtquant.xttrader import XtQuantTraderCallback8
import sys9
import time10
11
12
"""13
异步下单委托流程为14
1.order_stock_async发出委托15
2.回调on_order_stock_async_response收到回调信息16
3.回调on_stock_order收到委托信息17
4.回调cancel_order_stock_sysid_async发出异步撤单指令18
5.回调on_cancel_order_stock_async_response收到撤单回调信息19
6.回调on_stock_order收到委托信息20
"""21
strategy_name = "委托撤单测试"22
23
class MyXtQuantTraderCallback(XtQuantTraderCallback):24
# 用于接收回调信息的类25
def on_stock_order(self, order):26
"""27
委托回报推送28
:param order: XtOrder对象29
:return:30
"""31
# 属性赋值32
account_type = order.account_type # 账号类型33
account_id = order.account_id # 资金账号34
stock_code = order.stock_code # 证券代码,例如"600000.SH"35
order_id = order.order_id # 订单编号36
order_sysid = order.order_sysid # 柜台合同编号37
order_time = order.order_time # 报单时间38
order_type = order.order_type # 委托类型,参见数据字典39
order_volume = order.order_volume # 委托数量40
price_type = order.price_type # 报价类型,该字段在返回时为柜台返回类型,不等价于下单传入的price_type,枚举值不一样功能一样,参见数据字典41
price = order.price # 委托价格42
traded_volume = order.traded_volume # 成交数量43
traded_price = order.traded_price # 成交均价44
order_status = order.order_status # 委托状态,参见数据字典45
status_msg = order.status_msg # 委托状态描述,如废单原因46
strategy_name = order.strategy_name # 策略名称47
order_remark = order.order_remark # 委托备注48
direction = order.direction # 多空方向,股票不适用;参见数据字典49
offset_flag = order.offset_flag # 交易操作,用此字段区分股票买卖,期货开、平仓,期权买卖等;参见数据字典50
51
# 打印输出52
print(f"""53
=============================54
委托信息55
=============================56
账号类型: {order.account_type}, 57
资金账号: {order.account_id},58
证券代码: {order.stock_code},59
订单编号: {order.order_id}, 60
柜台合同编号: {order.order_sysid},61
报单时间: {order.order_time},62
委托类型: {order.order_type},63
委托数量: {order.order_volume},64
报价类型: {order.price_type},65
委托价格: {order.price},66
成交数量: {order.traded_volume},67
成交均价: {order.traded_price},68
委托状态: {order.order_status},69
委托状态描述: {order.status_msg},70
策略名称: {order.strategy_name},71
委托备注: {order.order_remark},72
多空方向: {order.direction},73
交易操作: {order.offset_flag}74
""")75
if order.strategy_name == strategy_name:76
# 该委托是由本策略发出77
ssid = order.order_sysid78
status = order.order_status79
market = order.stock_code.split(".")[1]80
# print(ssid)81
if ssid and status in [50,55]:82
## 使用cancel_order_stock_sysid_async时,投研端market参数可以填写为0,券商端按实际情况填写83
print(xt_trade.cancel_order_stock_sysid_async(account,0,ssid))84
85
def on_stock_trade(self, trade):86
"""87
成交变动推送88
:param trade: XtTrade对象89
:return:90
"""91
print(datetime.datetime.now(), '成交回调', trade.order_remark,trade.stock_code,trade.traded_volume,trade.offset_flag)92
93
def on_order_stock_async_response(self, response):94
"""95
异步下单回报推送96
:param response: XtOrderResponse 对象97
:return:98
"""99
100
print(datetime.datetime.now(),'异步下单编号为:',response.seq)101
102
def on_cancel_order_stock_async_response(self, response):103
"""104
异步撤单回报105
:param response: XtCancelOrderResponse 对象106
:return:107
"""108
account_type = response.account_type # 账号类型109
account_id = response.account_id # 资金账号110
order_id = response.order_id # 订单编号111
order_sysid = response.order_sysid # 柜台委托编号112
cancel_result = response.cancel_result # 撤单结果113
seq = response.seq # 异步撤单的请求序号114
115
print(f"""116
===========================117
异步撤单回调信息118
===========================119
账号类型: {response.account_type}, 120
资金账号: {response.account_id},121
订单编号: {response.order_id}, 122
柜台委托编号: {response.order_sysid},123
撤单结果: {response.cancel_result},124
异步撤单的请求序号: {response.seq}""")125
pass126
127
128
callback = MyXtQuantTraderCallback()129
# 填投研端的期货账号130
account = StockAccount("1000024",account_type = "FUTURE")131
# 填写投研端的股票账号132
# account = StockAccount("2000567")133
# 填投研端的userdata路径,miniqmt指定到userdata_mini134
xt_trade = xttrader.XtQuantTrader(r"C:\Program Files\测试1\迅投极速交易终端睿智融科版\userdata",int(time.time()))135
# 注册接受回调136
xt_trade.register_callback(callback) 137
# 启动交易线程138
xt_trade.start()139
# 链接交易140
connect_result = xt_trade.connect()141
# 订阅账号信息,接受这个账号的回调,回调是账号维度的142
subscribe_result = xt_trade.subscribe(account)143
print(subscribe_result)144
145
146
code = "rb2410.SF"147
# code = "000001.SZ"148
149
tick = xtdata.get_full_tick([code])[code]150
151
last_price = tick["lastPrice"] # 最新价152
153
ask_price = round(tick["askPrice"][0],3) # 卖方1档价154
bid_price = round(tick["bidPrice"][4],3) # 买方5档价155
156
symbol_info = xtdata.get_instrument_detail(code)157
158
up_limit = symbol_info["UpStopPrice"]159
down_limit = symbol_info["DownStopPrice"]160
161
lots = 1162
res_id = xt_trade.order_stock_async(account, code, xtconstant.FUTURE_OPEN_LONG, lots, xtconstant.FIX_PRICE, down_limit, strategy_name, "跌停价/固定手数")163
164
165
# lots = 100166
# res_id = xt_trade.order_stock_async(account, code, xtconstant.STOCK_BUY, lots, xtconstant.FIX_PRICE, bid_price, strategy_name, "跌停价/固定手数")167
168
169
xtdata.run()170
171
172
173