QMT Python API

完整示例

获取行情示例

按品种划分

两融

获取融资融券账户可融资买入标的
qmt://docs/python
Python
1#coding:gbk
2def init(C):
3
4 r = get_assure_contract('123456789')
5 if len(r) == 0:
6 print('未取到担保明细')
7 else:
8 finable = [o.m_strInstrumentID+'.'+o.m_strExchangeID for o in r if o.m_eFinStatus==48]
9 print('可融资买入标的:', finable)
10 

按功能划分

订阅K线全推

提示

  1. K线全推需要VIP权限,非VIP用户请勿使用此功能

订阅全市场1m周期K线

qmt://docs/python
Python
1#coding:gbk
2 
3import pandas as pd
4import numpy as np
5 
6def init(C):
7 stock_list = C.get_stock_list_in_sector("沪深A股")
8 sub_num_dict = {i:C.subscribe_quote(
9 stock_code = i,
10 period = '1m',
11 dividend_type = 'none',
12 result_type = 'dict', # 回调函数的行情数据格式
13 callback = call_back # 指定一个自定义的函数接收行情,自定义的函数只能有一个位置参数
14 ) for i in stock_list}
15 
16def call_back(data):
17 print(data)
18 

获取N分钟周期K线数据

提示

  1. 获取历史N分钟数据前,需要先下载历史数据
  2. 1m以上,5m以下的数据,是通过1m数据合成的
  3. 5m以上,1d以下的数据,是通过5m数据合成的
  4. 1d以上的数据,是通过1d的数据合成的
qmt://docs/python
Python
1#coding:gbk
2 
3import pandas as pd
4import numpy as np
5 
6def init(C):
7 
8 # start_date = '20231001'# 格式"YYYYMMDD",开始下载的日期,date = ""时全量下载
9 start_date = '20231001'# 格式"YYYYMMDD",开始下载的日期,date = ""时增量下载
10 end_date = "" # 格式同上,下载结束时间
11 period = "3m" # 数据周期
12 need_download = 1 # 取数据是空值时,将need_download赋值为1,确保正确下载了历史数据
13 # code_list = ["110052.SH"] # 可转债
14 # code_list = ["rb2401.SF", "FG403.ZF"] # 期货列表
15 # code_list = ["HO2310-P-2500.IF"] # 期权列表
16 code_list = ["000001.SZ", "600519.SH"] # 股票列表
17
18 # 判断要不要下载数据
19 if need_download:
20 my_download(code_list, period, start_date, end_date)
21 # 取数据
22 data = C.get_market_data_ex([],code_list,period = period, start_time = start_date, end_time = end_date,dividend_type = "back_ratio")
23 
24 print(data)# 行情数据查看
25 print(C.get_instrumentdetail(code_list[0])) # 合约信息查看
26
27def hanldebar(C):
28 return
29 
30def my_download(stock_list,period,start_date = '', end_date = ''):
31 '''
32 用于显示下载进度
33 '''
34 if "d" in period:
35 period = "1d"
36 elif "m" in period:
37 if int(period[0]) < 5:
38 period = "1m"
39 else:
40 period = "5m"
41 elif "tick" == period:
42 pass
43 else:
44 raise KeyboardInterrupt("周期传入错误")
45 
46 
47 n = 1
48 num = len(stock_list)
49 for i in stock_list:
50 print(f"当前正在下载{n}/{num}")
51
52 download_history_data(i,period,start_date, end_date)
53 n += 1
54 print("下载任务结束")

获取2小时行情数据

提示

  1. 获取历史N分钟数据前,需要先下载历史数据
  2. 1m以上,5m以下的数据,是通过1m数据合成的
  3. 5m以上,1d以下的数据,是通过5m数据合成的
  4. 1d以上的数据,是通过1d的数据合成的
  5. 本示例是获取120分钟周期,需要先下载5分钟周期
qmt://docs/python
Python
1#coding:gbk
2 
3def after_init(ContextInfo):
4 stock = '000012.SZ'
5 #下载历史5分钟行情(2小时周期是接口由基础周期5m合并)
6 download_history_data(stock, '5m', '20260101', '')
7
8
9def handlebar(ContextInfo):
10 if not ContextInfo.is_last_bar():
11 return
12 stock = '000012.SZ'
13 # 获取120分钟线(2小时线)数据
14 data = ContextInfo.get_market_data_ex(
15 ['open', 'high', 'low', 'close', 'volume'], [stock], period='2h'
16 , start_time='20260101', end_time='', count=-1
17 , dividend_type='follow', fill_data=False
18 , subscribe = True
19 )
20 print(data)

获取 Lv1 行情数据

本示例用于说明如何通过函数获取行情数据。

qmt://docs/python
Python
1#coding:gbk
2# get_market_data_ex(subscribe=True)有订阅股票数量限制
3# 即stock_list参数的数量不能超过500
4 
5# get_market_data_ex(subscribe=False) 该模式下(非订阅模式),接口会从本地行情文件里获取数据,不会获取动态行情数,且不受订阅数限制,但需要提前下载数据
6# 下载数据在 操作/数据管理/补充数据选项卡里,按照页面提示下载数据
7 
8# get_market_data_ex(subscribe=True) 该模式下(订阅模式),受订阅数量上限限制,可以取到动态行情
9 
10# 建议每天盘后增量补充对应周期的行情
11 
12import time
13 
14 
15def init(C):
16 C.stock = C.stockcode + '.' + C.market
17 # 获取指定时间的k线
18 price = C.get_market_data_ex(['open','high','low','close'], [C.stock], start_time='', end_time='',period='1d', subscribe=False)
19 print(price[C.stock].head())
20 
21 
22def handlebar(C):
23 
24 bar_timetag = C.get_bar_timetag(C.barpos)
25 bar_date = timetag_to_datetime(bar_timetag, '%Y%m%d%H%M%S')
26 print('获取截至到%s为止前5根k线的开高低收等字段:'%(bar_date))
27 # 获取截至今天为止前30根k线
28 price = C.get_market_data_ex(
29 [], [C.stock],
30 end_time=bar_date,
31 period=C.period,
32 subscribe=True,
33 count=5,
34 )
35 print(price[C.stock].to_dict('dict'))
36 

获取 Lv2 数据(需要数据源支持)

方法1 - 查询LV2数据

使用该函数后,会定期查询最新数据,并进行数据返回。

qmt://docs/python
Python
1#coding:gbk
2def init(C):
3 C.sub_nums = []
4 
5 C.stock = C.stockcode+'.'+C.market
6 for field in ['l2transaction', 'l2order', 'l2transactioncount', 'l2quote']:
7 num = C.subscribe_quote(C.stock, period=field,
8 dividend_type='follow',
9 )
10
11 C.sub_nums.append(num)
12 
13def handlebar(C):
14 if not C.is_last_bar():
15 return
16 price = C.get_market_data_ex([],[C.stock],period='l2transaction',count=10)[C.stock]
17 price_dict = price.to_dict('index')
18 print(price_dict)
19 for pos, t in enumerate(price_dict):
20 print(f" 逐笔成交:{pos+1} 时间:{price_dict[t]['stime']}, 时间戳:{price_dict[t]['time']}, 成交价:{price_dict[t]['price']}, \
21成交量:{price_dict[t]['volume']}, 成交额:{price_dict[t]['amount']} \
22成交记录号:{price_dict[t]['tradeIndex']}, 买方委托号:{price_dict[t]['buyNo']},\
23卖方委托号:{price_dict[t]['sellNo']}, 成交类型:{price_dict[t]['tradeType']}, \
24成交标志:{price_dict[t]['tradeFlag']}, ")
25 
26 price = C.get_market_data_ex([],[C.stock],period='l2quote',count=10)[C.stock]
27 price_dict = price.to_dict('index')
28 print(price_dict)
29 for pos, t in enumerate(price_dict):
30 print(f" 十档快照:{pos+1} 时间:{price_dict[t]['stime']}, 时间戳:{price_dict[t]['time']}, 最新价:{price_dict[t]['lastPrice']}, \
31开盘价:{price_dict[t]['open']}, 最高价:{price_dict[t]['high']} 最低价:{price_dict[t]['low']}, 成交额:{price_dict[t]['amount']},\
32成交总量:{price_dict[t]['volume']}, 原始成交总量:{price_dict[t]['pvolume']}, 证券状态:{price_dict[t]['stockStatus']}, 持仓量:{price_dict[t]['openInt']},\
33成交笔数:{price_dict[t]['transactionNum']},前收盘价:{price_dict[t]['lastClose']},多档委卖价:{price_dict[t]['askPrice']},多档委卖量:{price_dict[t]['askVol']},\
34多档委买价:{price_dict[t]['bidPrice']},多档委买量:{price_dict[t]['bidVol']}")
35 
36 
37 price = C.get_market_data_ex([],[C.stock],period='l2order',count=10)[C.stock]
38 price_dict = price.to_dict('index')
39 for pos, t in enumerate(price_dict):
40 print(f" 逐笔委托:{pos+1} 时间:{price_dict[t]['stime']}, 时间戳:{price_dict[t]['time']}, 委托价:{price_dict[t]['price']}, \
41委托量:{price_dict[t]['volume']}, 委托号:{price_dict[t]['entrustNo']} \
42委托类型:{price_dict[t]['entrustType']}, 委托方向:{price_dict[t]['entrustDirection']},\
43")
44# 委托类型: 0:未知 1: 买入,2: 卖出,3: 撤单
45 
46 
47 price = C.get_market_data_ex([],[C.stock],period='l2transactioncount',count=10)[C.stock]
48 price_dict = price.to_dict('index')
49 for pos, t in enumerate(price_dict):
50 print('大单统计:', price_dict[t])
51 
52def stop(C):
53 for num in C.sub_nums:
54 C.unsubscribe_quote(num)
55 
56 
方法2 - 订阅LV2数据

此方法在发起订阅后,会自动收到所订阅数据,订阅方需要记录订阅函数返回的订阅号,并在不需要订阅时调用unsubscribe_quote反订阅数据,释放资源。

qmt://docs/python
Python
1#coding:gbk
2 
3def l2_quote_callback(data):
4 for s in data:
5 print('lv2快照:',s, data[s])
6 
7def l2transaction_callback(data):
8 for s in data:
9 print('逐笔成交',s, data[s])
10 
11 
12def l2order_callback(data):
13 for s in data:
14 print('逐笔委托',s, data[s])
15 
16def l2quoteaux_callback(data):
17 for s in data:
18 print('行情快照补充',s, data[s])
19 
20 
21def l2transactioncount_callback(data):
22 for s in data:
23 print('大单统计',s, data[s])
24 
25 
26def l2orderqueue_callback(data):
27 for s in data:
28 print('委买委卖队列',s, data[s])
29 
30 
31def init(C):
32 C.stock = C.stockcode + '.' + C.market
33 
34 # Level2 逐笔快照
35 C.subscribe_quote(C.stock, 'l2quote', result_type='dict', callback=l2_quote_callback)
36 # Level2 行情快照补充
37 C.subscribe_quote(C.stock, 'l2quoteaux', result_type='dict', callback=l2quoteaux_callback)
38 # Level2 逐笔成交
39 C.subscribe_quote(C.stock, 'l2transaction', result_type='dict', callback=l2transaction_callback)
40 # Level2 逐笔委托
41 C.subscribe_quote(C.stock, 'l2order', result_type='dict', callback=l2order_callback)
42 # Level2大单统计
43 C.subscribe_quote(C.stock, 'l2transactioncount', result_type='dict', callback=l2transactioncount_callback)
44 # Level2委买委卖队列
45 C.subscribe_quote(C.stock, 'l2orderqueue', result_type='dict', callback=l2orderqueue_callback)
46 
47def handlebar(C):
48 return
49 

使用 Lv1 全推数据计算全市场涨幅

qmt://docs/python
Python
1#coding:gbk
2 
3import time
4 
5class a():pass
6 
7A = a()
8 
9def init(C):
10 A.hsa = C.get_stock_list_in_sector('沪深A股') + C.get_stock_list_in_sector('京市A股')
11 print('股票池大小', len(A.hsa))
12 A.vol_dict = {}
13 for stock in A.hsa:
14 A.vol_dict[stock] = C.get_last_volume(stock)
15 C.run_time("f","3nSecond","2019-10-14 13:20:00")
16 
17 
18def to_zw(a):
19 '''0.中文价格字符串'''
20 import numpy as np
21 if np.isnan(a):
22 return '问题数据'
23 if abs(a) < 1000:
24 print(a, str(round(int(a) / 1000.0, 2)) + "千")
25 return str(round(int(a) / 1000.0, 2)) + "千"
26 if abs(a) < 10000:
27 return str(int(a))[0] + "千"
28 if abs(a) < 100000000:
29 return str(int(a))[:-4] + "万" + str(int(a))[-4]
30 return f"{int(a / 100000000)}亿"
31 
32 
33 
34def f(C):
35 t0 = time.time()
36 full_tick = C.get_full_tick(A.hsa)
37 total_market_value = 0
38 total_ratio = 0
39 count = 0
40 total_amount = 0
41 ratio_list = []
42 for stock in A.hsa:
43 ratio = full_tick[stock]['lastPrice'] / full_tick[stock]['lastClose'] - 1
44 amount = full_tick[stock]['amount']
45 total_amount += amount
46 rise_price = round(full_tick[stock]['lastClose'] *1.2,2) if stock[0] == '3' or stock[:3] == '688' else round(full_tick[stock]['lastClose'] *1.1,2)
47 #如果要打印涨停品种
48 #if abs(full_tick[stock]['lastPrice'] - rise_price) <0.01:
49 # print(f"涨停品种 {stock} {C.get_stock_name(stock)}")
50 market_value = full_tick[stock]['lastPrice'] * A.vol_dict[stock]
51 total_ratio += ratio * market_value
52 total_market_value += market_value
53 count += 1
54 ratio_list.append(ratio)
55 #print(count)
56 total_ratio /= total_market_value
57 total_ratio *= 100
58 middle = int(len(ratio_list) / 2)
59 middle_ratio = ratio_list[middle]
60 rise_num = len([i for i in ratio_list if i > 0])
61 down_num = len([i for i in ratio_list if i < 0])
62 print(f'A股加权涨幅 {round(total_ratio,2)}% 涨幅中位数 {round(middle_ratio,2)}% {rise_num}个上涨 {down_num}个下跌 成交金额 {to_zw(total_amount)} 耗时{round(time.time()- t0,5)}秒')
63 

在行情回调函数里处理动态行情

ContextInfo.subscribe_quote - 订阅行情函数说明
行情回调函数字段说明

qmt://docs/python
Python
1#coding:gbk
2 
3sub_nums = []
4 
5 
6def init(C):
7 global sub_nums
8 
9 # def on_quote(data1, data2): # 错误写法
10 def on_quote(data):
11 for s in data:
12 q = data[s]
13 print(type(q), q)
14
15 stocks = [C.stockcode + '.' + C.market] # 获取到当前主图股票代码
16 for s in stocks:
17 num = C.subscribe_quote(s, period='1d',
18 dividend_type='none',
19 result_type='dict', # 回调函数的行情数据格式
20 callback=on_quote # 指定一个自定义的函数接收行情,自定义的函数只能有一个位置参数
21 )
22 sub_nums.append(num)
23 
24 
25def stop(C):
26 # 反订阅
27 for num in sub_nums:
28 C.unsubscribe_quote(num)

python写入扩展数据

qmt://docs/python
Python
1# coding:gbk
2'''
3python写扩展数据,投研接口
4'''
5 
6def init(C):
7 # 创建扩展数据
8 extencd_name = 'test' # 创建名为test的扩展数据
9 create_extend_data# (父节点, 扩展数据名称, 是否覆盖)
10 C.extencd_name = create_extend_data('扩展数据', extencd_name, True)
11
12 
13def handlebar(C):
14 if C.is_last_bar():
15 data = {'SH600177': 0.43, 'SZ000767': 0.18, 'SH600362': 0.27, 'SH600171': 0.25, 'SH600170': 0.18, 'SH600073': 0.13, 'SZ000768': 0.17, 'SH600282': 0.19, 'SH600601': 0.42, 'SH600569': 0.26, 'SZ000401': 0.21, 'SH600602': 0.17, 'SZ000806': 0.13, 'SZ000807': 0.15, 'SH600608': 0.08, 'SH600874': 0.09, 'SZ000825': 0.44, 'SZ000652': 0.19, 'SH600078': 0.11, 'SH600871': 0.1, 'SZ000573': 0.1, 'SZ000520': 0.14, 'SH600879': 0.43, 'SZ000960': 0.2, 'SH600597': 0.21, 'SZ000550': 0.1, 'SH600591': 0.14, 'SZ000059': 0.13, 'SH600215': 0.12, 'SZ000968': 0.11, 'SZ000969': 0.14, 'SZ000568': 0.22, 'SH600598': 0.22, 'SH600028': 1.85, 'SH600270': 0.27, 'SH600060': 0.22, 'SH600062': 0.15, 'SH600779': 0.14, 'SH600997': 0.2, 'SZ000707': 0.12, 'SH600068': 0.16, 'SH600770': 0.14, 'SZ000680': 0.14, 'SH600674': 0.1, 'SH600675': 0.25, 'SZ000488': 0.28, 'SZ000012': 0.11, 'SH600863': 0.17, 'SZ000429': 0.17, 'SH600027': 0.32, 'SH600866': 0.13, 'SH600001': 0.43, 'SZ000636': 0.11, 'SH600900': 2.73, 'SH600600': 0.31, 'SH600895': 0.26, 'SH600029': 0.43, 'SH600020': 0.24, 'SH600205': 0.39, 'SH600688': 0.76, 'SH600207': 0.1, 'SZ000970': 0.3, 'SZ000601': 0.19, 'SH600200': 0.35, 'SZ000975': 0.08, 'SZ000538': 0.39, 'SZ000422': 0.14, 'SZ000858': 0.88, 'SZ000651': 0.44, 'SH600780': 0.21, 'SH600007': 0.11, 'SH600016': 2.36, 'SZ000866': 0.84, 'SH600267': 0.12, 'SH600266': 0.16, 'SH600786': 0.27, 'SZ000406': 0.39, 'SH600269': 0.47, 'SZ000528': 0.19, 'SH600694': 0.51, 'SZ000786': 0.14, 'SH600004': 0.4, 'SH600663': 0.25, 'SH600662': 0.21, 'SH600548': 0.11, 'SH600383': 0.42, 'SH600357': 0.12, 'SH600705': 0.13, 'SH600812': 0.18, 'SH600707': 0.06, 'SZ000895': 0.49, 'SZ000898': 0.68, 'SZ000400': 0.17, 'SZ000607': 0.1, 'SH600894': 0.1, 'SH600418': 0.4, 'SZ000061': 0.15, 'SH600653': 0.31, 'SZ000682': 0.17, 'SZ000543': 0.07, 'SZ000541': 0.25, 'SH600377': 0.12, 'SZ000949': 0.06, 'SH600256': 0.17, 'SH600006': 0.23, 'SH600005': 1.13, 'SH600790': 0.1, 'SH600797': 0.2, 'SH600002': 0.51, 'SH600795': 0.49, 'SH600000': 1.64, 'SH600652': 0.17, 'SH600121': 0.13, 'SH600123': 0.3, 'SH600125': 0.27, 'SH600126': 0.12, 'SH600008': 0.51, 'SZ000016': 0.14, 'SH600550': 0.24, 'SH600718': 0.16, 'SH600654': 0.2, 'SZ000157': 0.2, 'SH600808': 0.42, 'SZ000666': 0.1, 'SH600805': 0.11, 'SZ000527': 0.39, 'SH600717': 0.5, 'SH600399': 0.07, 'SZ000828': 0.14, 'SZ000959': 0.17, 'SZ000729': 0.29, 'SH600098': 0.43, 'SZ000886': 0.09, 'SZ000099': 0.13, 'SZ000800': 0.29, 'SH600096': 0.29, 'SZ001872': 0.17, 'SH600091': 0.12, 'SZ000956': 0.41, 'SH600887': 0.63, 'SH600886': 0.2, 'SH600884': 0.12, 'SH600308': 0.32, 'SH600309': 0.64, 'SH600881': 0.21, 'SH600307': 0.14, 'SZ000069': 0.8, 'SZ000068': 0.1, 'SH600153': 0.19, 'SZ000792': 0.55, 'SZ000060': 0.38, 'SZ000002': 2.25, 'SZ000001': 1.25, 'SH600138': 0.1, 'SH600649': 0.44, 'SH600015': 0.99, 'SZ000533': 0.07, 'SZ000009': 0.24, 'SH600408': 0.09, 'SZ000778': 0.23, 'SH600643': 0.17, 'SH600642': 0.71, 'SH600832': 0.71, 'SZ000089': 0.36, 'SZ000088': 0.44, 'SZ000539': 0.3, 'SH600835': 0.19, 'SH600726': 0.09, 'SH600010': 0.42, 'SH600724': 0.16, 'SH600839': 0.61, 'SH600011': 0.38, 'SH600012': 0.27, 'SH600089': 0.23, 'SH600088': 0.12, 'SH600087': 0.12, 'SH600085': 0.38, 'SZ000927': 0.2, 'SZ000920': 0.11, 'SZ000962': 0.13, 'SZ000559': 0.16, 'SH600050': 2.98, 'SZ000708': 0.09, 'SZ000503': 0.36, 'SZ000839': 0.44, 'SZ000717': 0.28, 'SZ000100': 0.31, 'SZ000036': 0.18, 'SZ000878': 0.24, 'SZ000511': 0.09, 'SZ000410': 0.19, 'SH600033': 0.24, 'SH600108': 0.13, 'SZ000031': 0.21, 'SZ000507': 0.09, 'SH600104': 0.78, 'SZ002024': 0.45, 'SH600102': 0.18, 'SH600103': 0.14, 'SH600100': 0.41, 'SH600019': 2.84, 'SH600009': 1.5, 'SH600639': 0.19, 'SZ000709': 0.34, 'SH600820': 0.14, 'SZ000571': 0.1, 'SH600739': 0.13, 'SH600631': 0.25, 'SH600021': 0.24, 'SH600635': 0.22, 'SH600637': 0.15, 'SZ000733': 0.09, 'SZ000780': 0.09, 'SH600210': 0.25, 'SZ000939': 0.12, 'SZ000937': 0.26, 'SZ000875': 0.15, 'SZ000933': 0.22, 'SZ000932': 0.51, 'SZ000659': 0.15, 'SZ000930': 0.38, 'SH600320': 0.8, 'SZ000822': 0.17, 'SZ000726': 0.14, 'SZ000727': 0.1, 'SZ000725': 0.13, 'SH600380': 0.14, 'SH600030': 0.63, 'SH600031': 0.16, 'SH600036': 3.93, 'SH600037': 0.62, 'SH600035': 0.16, 'SH600058': 0.2, 'SH600110': 0.13, 'SH600508': 0.19, 'SZ000402': 0.62, 'SH600115': 0.1, 'SH600117': 0.13, 'SZ000423': 0.22, 'SH600348': 0.34, 'SZ000518': 0.14, 'SH600500': 0.26, 'SH600660': 0.37, 'SH600057': 0.09, 'SH600744': 0.12, 'SH600747': 0.11, 'SH600740': 0.09, 'SH600741': 0.17, 'SH600621': 0.11, 'SZ000698': 0.14, 'SH600851': 0.19, 'SZ000900': 0.28, 'SH600854': 0.1, 'SH600868': 0.25, 'SH600428': 0.3, 'SZ000630': 0.36, 'SH600811': 0.3, 'SZ000735': 0.1, 'SZ000737': 0.09, 'SZ000066': 0.19, 'SH600331': 0.25, 'SH600183': 0.27, 'SH600333': 0.1, 'SZ000581': 0.25, 'SZ000425': 0.11, 'SZ000983': 0.49, 'SH600236': 0.25, 'SH600026': 0.45, 'SH600339': 0.08, 'SH600231': 0.16, 'SH600188': 0.27, 'SH600022': 0.2, 'SH600166': 0.08, 'SH600350': 0.37, 'SH600519': 1.14, 'SZ000063': 1.49, 'SH600690': 0.44, 'SZ000758': 0.24, 'SH600296': 0.26, 'SH601607': 0.17, 'SHT00018': 0.8, 'SZ000039': 0.78, 'SZ000599': 0.1, 'SH600198': 0.21, 'SZ000917': 0.15, 'SZ000916': 0.22, 'SZ000912': 0.21, 'SH600190': 0.11, 'SH600196': 0.25, 'SH600583': 0.54, 'SH600581': 0.12, 'SZ000027': 0.6, 'SZ000629': 0.52, 'SH600585': 0.32, 'SZ000021': 0.26, 'SZ000625': 0.25, 'SZ000623': 0.18, 'SZ000024': 0.42, 'SH600221': 0.13, 'SH600220': 0.17}
16 timetag = C.get_bar_timetag(C.barpos)
17 stock_list = list(data.keys())
18 print(stock_list)
19 
20 #设置需要写入的扩展数据股票列表
21 #reset_extend_data_stock_list(扩展数据名称, 股票列表)
22 reset_extend_data_stock_list(C.extencd_name, stock_list)
23 # 执行写入扩展数据
24 # set_extend_data_value(扩展数据名称,时间戳(毫秒),数据)
25 set_extend_data_value(C.extencd_name, timetag, data)
26 print('写入完成')
27 

每1分钟统计一次市场涨跌情况

qmt://docs/python
Python
1# coding:gbk
2import datetime as dt
3def on_timer(ContextInfo):
4 ls = globals().get("stock_list")
5 now_time = dt.datetime.now().strftime("%Y%m%d %H:%M:%S")
6 # 取tick数据
7 ticks = ContextInfo.get_full_tick(ls)
8
9 # 涨跌统计,并去除停牌股
10 profit_ls = [i for i in ticks if ticks[i]["lastPrice"] > ticks[i]["lastClose"] and ticks[i]["openInt"] != 1]
11 loss_ls = [i for i in ticks if ticks[i]["lastPrice"] < ticks[i]["lastClose"] and ticks[i]["openInt"] != 1]
12 print(f"{now_time}: 涨家数{len(profit_ls)}; 跌家数{len(loss_ls)}")
13 
14def init(ContextInfo):
15 globals()["stock_list"] = get_stock_list_in_sector("沪深京A股")
16 # 自2023-12-31 23:59:59后每60s运行一次on_timer
17 tid=ContextInfo.schedule_run(on_timer,'20231231235959',3,dt.timedelta(seconds=60),'my_timer')
18 # 取消任务组为"my_timer"的任务
19 # # ContextInfo.cancel_schedule_run('my_timer')
20 
21 # 关于schedule_run函数的用法请阅读文档/docs/python/system_function.html#设置定时器-contextinfo-schedule-run
22

交易下单示例

按品种划分

股票

qmt://docs/python
Python
1#coding:gbk
2def handlebar(ContextInfo):
3 if not ContextInfo.is_last_bar():
4 return
5 # 单股单账号股票最新价买入 100 股(1 手)
6 passorder(23, 1101, 'test', '600000.SH', 5, 0, 100, '',1,'',ContextInfo)
7 # 单股单账号股票最新价卖出 100 股(1 手)
8 passorder(24, 1101, 'test', '600000.SH', 5, 0, 100, '',1,'',ContextInfo)
9 # 单股单账号沪市股票市价买入 100 股(1 手),沪市市价存在保护限价,Price参数为保护限价,买入为投资者能够接受的最高买价,填0会自动填为涨停价
10 passorder(23, 1101, 'test', '600000.SH', 42, 0, 100, '',1,'',ContextInfo)
11 # 单股单账号沪市股票市价卖出 100 股(1 手),沪市市价存在保护限价,Price参数为保护限价,卖出为投资者能够接受的最低卖价,填0会自动填为跌停价
12 passorder(24, 1101, 'test', '600000.SH', 42, 0, 100, '',1,'',ContextInfo)
13 # 单股单账号京市股票最新价买入 101 股(1 手零 1 股)
14 passorder(23, 1101, 'test', '430047.BJ', 5, 0, 101, '',1,'',ContextInfo)
15 # 单股单账号京市股票最新价卖出 101 股(1 手零 1 股)
16 passorder(24, 1101, 'test', '430047.BJ', 5, 0, 101, '',1,'',ContextInfo)

基金

qmt://docs/python
Python
1def handlebar(ContextInfo):
2 if not ContextInfo.is_last_bar():
3 return
4 
5 # 申购 中证500指数ETF
6 passorder(60, 1101, 'test', '510030.SH', 5, 0, 1, 2, ContextInfo)
7
8 # 赎回 中证500指数ETF
9 passorder(61, 1101, 'test', '510030.SH', 5, 0, 1, 2, ContextInfo)
10 

两融

qmt://docs/python
Python
1#coding:gbk
2def handlebar(ContextInfo):
3 if not ContextInfo.is_last_bar():
4 return
5 target = '000001.SZ'
6 # 单股单账号股票指定价担保品买入 100 股(1 手)
7 passorder(33, 1101, 'test', target, 11, 7, 100, ContextInfo)
8 # 单股单账号股票指定价融资买入 100 股(1 手)
9 passorder(27, 1101, 'test', target, 11, 7, 100, ContextInfo)

期货

qmt://docs/python
Python
1#coding:gbk
2def handlebar(ContextInfo):
3 if not ContextInfo.is_last_bar():
4 return
5
6 # 单股单账号期货最新价开多螺纹钢2401 10 手
7 target = 'rb2401.SF'
8 passorder(0, 1101, 'test', target, 5, -1, 10, 1, ContextInfo)
9 
10
11 # 单股单账号期货指定价开空甲醇2401 10 手
12 target = 'MA401.ZF'
13 passorder(3, 1101, 'test', target, 11, 3000, 10, 1, ContextInfo)
14 
15 
16 #期货四键平多300股指2311,优先平今 2手
17 target = 'IF2311.IF'
18 passorder(6, 1101, 'test', target, 5, -1, 2, 1, ContextInfo)
19

期权

qmt://docs/python
Python
1#coding:gbk
2def handlebar(ContextInfo):
3 if not ContextInfo.is_last_bar():
4 return
5 target = '10005330.SHO' # 50ETF购12月2450合约
6 
7 # 单股单账号用最新价买入开仓期权合约target 2张
8 passorder(50, 1101, 'test', target, 5, -1, 2, 1, ContextInfo)
9
10 # 单股单账号用最新价卖出平仓期权合约target 2张
11 passorder(51, 1101, 'test', target, 5, -1, 2, 1, ContextInfo)
12 

新股申购

qmt://docs/python
Python
1#coding:gbk
2def init(C):
3 ipoStock=get_ipo_data("STOCK")#返回新股信息
4 print(ipoStock)
5 accont = '123456789'
6 for stock in ipoStock:
7 ipo_price = ipoStock[stock]['issuePrice'] # 发行价
8 maxPurchaseNum = ipoStock[stock]['maxPurchaseNum'] # 可申购额度
9 passorder(23,1101, accont, stock,11,ipo_price, maxPurchaseNum,'新股申购',2,stock,C)
10 

债券

qmt://docs/python
Python
1#coding:gbk
2def handlebar(ContextInfo):
3 if not ContextInfo.is_last_bar():
4 return
5 # 单股单账号最新价可转债买入 20张
6 passorder(23, 1101, 'test', '128123.SZ', 5, -1, 10, 1, ContextInfo)
7
8 

ETF

qmt://docs/python
Python
1#coding:gbk
2def handlebar(ContextInfo):
3 if not ContextInfo.is_last_bar():
4 return
5 # 单股单账号 最新价买入上证etf 2000份
6 passorder(23, 1101, 'test', '510050.SH', 5, -1, 2000, ContextInfo)
7

组合交易

一键买卖(一篮子下单)

功能描述: 该示例演示如何用python进行一揽子股票买卖的交易操作

代码示例:

qmt://docs/python
Python
1#coding:gbk
2 
3def init(C):
4
5 table=[
6 {'stock':'600000.SH','weight':0.11,'quantity':100,'optType':23},
7 {'stock':'600028.SH','weight':0.11,'quantity':200,'optType':24},
8 ]
9 basket={'name':'basket1','stocks':table}
10 set_basket(basket)
11 # 按篮子数量下单, 下2份 # 即下两倍篮子
12 pice = 2
13 passorder(35, #一键买卖
14 2101, # 表示按股票数量下单
15 account,
16 'basket1', # 篮子名称
17 5, # 最新价下单
18 1, # 价格,最新价时 该参数无效,需要填任意数占位
19 pice, # 篮子份数
20 '',2,'strReMark',C)
21
22 # 按篮子权重下单
23 table=[
24 {'stock':'600000.SH','weight':0.4,'quantity':0,'optType':23}, # 40%
25 {'stock':'600028.SH','weight':0.6,'quantity':0,'optType':24}, # 60%
26 ]
27 basket={'name':'basket2','stocks':table}
28 set_basket(basket)
29 # 按组合权重 总额10000元
30 money = 10000
31 passorder(35,2102,account,'basket2',5,1,money,'',2,'strReMark',C)

组合套利交易

提示

accountIDorderType 特殊设置)

用法

qmt://docs/python
Python
1passorder(opType, orderType, accountID, orderCode, prType, hedgeRatio, volume, ContextInfo)

释义

参数

参数名称描述
accountID'stockAccountID, futureAccountID'
orderCode'basketName, futureName'
hedgeRatio套利比例(0 ~ 2 之间值,相当于 %0 至 200% 套利)
volume份数 \ 资金 \ 比例
orderType参考下方orderType-下单方式(特殊设置)

orderType - 下单方式(特殊设置)

编号项目
2331组合、套利、合约价值自动套利、按组合股票数量方式下单
2332组合、套利、按合约价值自动套利、按组合股票权重方式下单
2333组合、套利、按合约价值自动套利、按账号可用方式下单

示例

qmt://docs/python
Python
1 

按功能划分

passorder 下单函数

本示例用于演示K线走完下单及立即下单的参数写法差异,旨在帮助您了解如何快速实现下单操作。

qmt://docs/python
Python
1#coding:gbk
2c = 0
3s = '000001.SZ'
4def init(ContextInfo):
5 # 立即下单 用最新价买入股票s 100股,且指定投资备注
6 passorder(23,1101,account,s,5,0,100,'1',2,'tzbz',ContextInfo)
7 pass
8 
9 
10def handlebar(ContextInfo):
11 if not ContextInfo.is_last_bar():
12 #历史k线不应该发出实盘信号 跳过
13 return
14 
15 if ContextInfo.is_last_bar():
16 global c
17 c +=1
18 if c ==1:
19 # 用14.00元限价买入股票s 100股
20 passorder(23,1101,account,s,11,14.00,100,1,ContextInfo) # 当前k线为最新k线 则立即下单
21 # 用最新价限价买入股票s 100股
22 passorder(23,1101,account,s,5,-1,100,0,ContextInfo) # K线走完下单
23 # 用最新价限价买入股票s 1000元
24 passorder(23, 1102, account, s, 5, 0,1000, 2, ContextInfo) # 不管是不是最新K线,立即下单

集合竞价下单

本示例演示了利用定时器函数和passorder下单函数在集合竞价期间以指定价买入平安银行100股。

qmt://docs/python
Python
1#coding:gbk
2 
3import time
4c = 0
5s = '000001.SZ'
6def init(ContextInfo):
7 # 设置定时器,历史时间表示会在一次间隔时间后开始调用回调函数 比如本例中 5秒后会后第一次触发myHandlebar调用 之后五秒触发一次
8 ContextInfo.run_time("myHandlebar","5nSecond","2019-10-14 13:20:00")
9 
10 
11def myHandlebar(ContextInfo):
12 global c
13 now = time.strftime('%H%M%S')
14 if c ==0 and '092500' >= now >= '091500':
15 c += 1
16 passorder(23,1101,account,s,11,14.00,100,2,ContextInfo) # 立即下单
17 
18def handlebar(ContextInfo):
19 return

止盈止损示例

qmt://docs/python
Python
1 
2#coding:gbk
3 
4"""
51.账户内所有股票,当股价低于买入价10%止损卖出。
62.账户内所有股票,当股价高于前一天的收盘价10%时,开始监控一旦股价炸板(开板),以买三价卖出
7"""
8 
9def init(C):
10 C.ratio = 1
11 if accountType == 'STOCK':
12 C.sell_code = 24
13 if accountType == 'CREDIT':
14 C.sell_code = 34
15 C.spare_list = C.get_stock_list_in_sector('不卖品种')
16 
17def handlebar(C):
18 if not C.is_last_bar():
19 return
20 holdings = get_trade_detail_data(account, accountType, 'position')
21 stock_list = [holding.m_strInstrumentID + '.' + holding.m_strExchangeID for holding in holdings]
22 if stock_list:
23 full_tick = C.get_full_tick(stock_list)
24 for holding in holdings:
25 stock = holding.m_strInstrumentID + '.' + holding.m_strExchangeID
26 rate = holding.m_dProfitRate
27 volume = holding.m_nCanUseVolume
28 if not volume >= 100:
29 continue
30 if stock in C.spare_list:
31 continue
32 if rate < -0.1:
33 msg = f'{stock} 盈亏比例 {rate} 小于-10% 卖出 {volume}股'
34 print(msg)
35 passorder(C.sell_code, 1101, account, stock, 14, -1, volume, '减仓模型', 2, msg, C)
36 continue
37 if stock in full_tick:
38 current_price = full_tick[stock]['lastPrice']
39 pre_price = full_tick[stock]['lastClose']
40 high_price = full_tick[stock]['high']
41 stop_price = pre_price * 1.2 if stock[:2] in ['30', '68'] else pre_price * 1.1
42 stop_price = round(stop_price, 2)
43 ask_price_3 = full_tick[stock]['bidPrice'][2]
44 if not ask_price_3:
45 print(f"{stock} {full_tick[stock]} 未取到三档盘口价 请检查客户端右下角 行情界面 是否选择了五档行情 本次跳过卖出")
46 continue
47 if high_price == stop_price and current_price < stop_price:
48 msg = f"{stock} 涨停后 开板 卖出 {volume}股"
49 print(msg)
50 passorder(C.sell_code, 1101, account, stock, 14, -1, volume, '减仓模型', 2, msg, C)
51 continue
52 
53 

passorder 下算法单函数

本示例由于演示如何下达算法单,具体算法参数请参考迅投投研平台客户端参数说明。

qmt://docs/python
Python
1#coding:gbk
2import time
3 
4def init(C):
5 userparam={
6 'OrderType':1, #表示要下算法
7 'PriceType':0, # 卖5价下单
8 'MaxOrderCount':12, # 最大委托次数
9 'SuperPriceType':0, # 超价类型,0表示按比例
10 'SuperPriceRate':0.02, # 超价2%下单
11 'VolumeRate':0.1, # 单笔下单比率 每次拆10%
12 'VolumeType': 10, # 单笔基准量类型
13 'SingleNumMax':1000000, # 单笔拆单最大值
14 'PriceRangeType':0, # 波动区间类型
15 'PriceRangeRate':1, # 波动区间值
16 'ValidTimeType':1, # 有效时间类型 1 表示按执行时间
17 'ValidTimeStart':int(time.time()), # 算法开始时间
18 'ValidTimeEnd':int(time.time()+60*60), # 算法结束时间
19 'PlaceOrderInterval':10, # 报撤间隔
20 'UndealtEntrustRule':0, # 未成委托处理数值 用卖5加挂单
21 }
22 target_vol = 2000000 # 股, 算法目标总量
23 algo_passorder(23, 1101, account, '600000.SH', -1, -1, target_vol, '', 2, '普通算法', userparam, C)
24 print('finish')
25def handlebar(C):
26 pass

如何使用投资备注

投资备注功能是模型下单时指定的任意字符串(长度小于24),即passorder的userOrderId参数,可以用于匹配委托或成交。有且只有passorder, algo_passorder, smart_algo_passorder下单函数支持投资备注功能。

qmt://docs/python
Python
1# encoding:gbk
2 
3note = 0
4 
5def get_new_note():
6 global note
7 note += 1
8 return str(note)
9 
10def init(ContextInfo):
11 ContextInfo.set_account(account)
12 passorder(23, 1101, account, '000001.SZ', 5 ,0, 100, '', 2, get_new_note(), ContextInfo)
13 
14 orders = get_trade_detail_data(account, accountType, 'order')
15 remark = [o.m_strRemark for o in orders]
16 sysid_list = [o.m_strOrderSysID for o in orders]
17 print(remark)
18 
19 
20 
21def handlebar(C):
22 pass
23 
24 
25def order_callback(C, O):
26 print(O.m_strRemark, O.m_strOrderSysID)
27 
28
29def deal_callback(C, D):
30 print(D.m_strRemark, D.m_strOrderSysID)

如何获取委托持仓及资金数据

本示例用于演示如何通过函数获取指定账户的委托、持仓、资金数据。

qmt://docs/python
Python
1#coding:gbk
2 
3 
4def to_dict(obj):
5 attr_dict = {}
6 for attr in dir(obj):
7 try:
8 if attr[:2] == 'm_':
9 attr_dict[attr] = getattr(obj, attr)
10 except:
11 pass
12 return attr_dict
13 
14 
15def init(C):
16 pass
17 #orders, deals, positions, accounts = query_info(C)
18 
19 
20def handlebar(C):
21 if not C.is_last_bar():
22 return
23 orders, deals, positions, accounts = query_info(C)
24 
25 
26def query_info(C):
27 orders = get_trade_detail_data('8000000213', 'stock', 'order')
28 for o in orders:
29 print(f'股票代码: {o.m_strInstrumentID}, 市场类型: {o.m_strExchangeID}, 证券名称: {o.m_strInstrumentName}, 买卖方向: {o.m_nOffsetFlag}',
30 f'委托数量: {o.m_nVolumeTotalOriginal}, 成交均价: {o.m_dTradedPrice}, 成交数量: {o.m_nVolumeTraded}, 成交金额:{o.m_dTradeAmount}')
31 
32 
33 deals = get_trade_detail_data('8000000213', 'stock', 'deal')
34 for dt in deals:
35 print(f'股票代码: {dt.m_strInstrumentID}, 市场类型: {dt.m_strExchangeID}, 证券名称: {dt.m_strInstrumentName}, 买卖方向: {dt.m_nOffsetFlag}',
36 f'成交价格: {dt.m_dPrice}, 成交数量: {dt.m_nVolume}, 成交金额: {dt.m_dTradeAmount}')
37 
38 positions = get_trade_detail_data('8000000213', 'stock', 'position')
39 for dt in positions:
40 print(f'股票代码: {dt.m_strInstrumentID}, 市场类型: {dt.m_strExchangeID}, 证券名称: {dt.m_strInstrumentName}, 持仓量: {dt.m_nVolume}, 可用数量: {dt.m_nCanUseVolume}',
41 f'成本价: {dt.m_dOpenPrice:.2f}, 市值: {dt.m_dInstrumentValue:.2f}, 持仓成本: {dt.m_dPositionCost:.2f}, 盈亏: {dt.m_dPositionProfit:.2f}')
42 
43 
44 accounts = get_trade_detail_data('8000000213', 'stock', 'account')
45 for dt in accounts:
46 print(f'总资产: {dt.m_dBalance:.2f}, 净资产: {dt.m_dAssureAsset:.2f}, 总市值: {dt.m_dInstrumentValue:.2f}',
47 f'总负债: {dt.m_dTotalDebit:.2f}, 可用金额: {dt.m_dAvailable:.2f}, 盈亏: {dt.m_dPositionProfit:.2f}')
48 
49 return orders, deals, positions, accounts

使用快速交易参数委托

本例展示如何使用快速交易参数(quickTrade)立刻进行委托。

qmt://docs/python
Python
1#coding:gbk
2 
3def after_init(C):
4 #account变量是模型交易界面 添加策略时选择的资金账号 不需要手动填写
5 #快速交易参数(quickTrade )填2 passorder函数执行后立刻下单 不会等待k线走完再委托。 可以在after_init函数 run_time函数注册的回调函数里进行委托
6 msg = f"投资备注字符串 用来区分不同委托"
7 passorder(23, 1101, account, '600000.SH', 5, -1, 200, '测试下单', 2, msg, C)

调整至目标持仓

本示例由于演示如何调仓。

qmt://docs/python
Python
1#encoding:gbk
2 
3'''
4调仓到指定篮子
5'''
6 
7import pandas as pd
8import numpy as np
9import time
10from datetime import timedelta,datetime
11 
12#自定义类 用来保存状态
13class a():pass
14A=a()
15A.waiting_dict = {}
16A.all_order_ref_dict = {}
17#撤单间隔 单位秒 超过间隔未成交的委托撤回重报
18A.withdraw_secs = 30
19#定义策略开始结束时间 在两者间时进行下单判断 其他时间跳过
20A.start_time = '093000'
21A.end_time = '150000'
22 
23def init(C):
24 '''读取目标仓位 字典格式 品种代码:持仓股数, 可以读本地文件/数据库,当前在代码里写死'''
25 A.final_dict = {"600000.SH" :10000, '000001.SZ' : 20000}
26 '''设置交易账号 acount accountType是界面上选的账号 账号类型'''
27 A.acct = account
28 A.acct_type = accountType
29 #定时器 定时触发指定函数
30 C.run_time("f","1nSecond","2019-10-14 13:20:00","SH")
31 
32 
33def f(C):
34 '''定义定时触发的函数 入参是ContextInfo对象'''
35 #记录本次调用时间戳
36 t0 = time.time()
37 final_dict=A.final_dict
38 #本次运行时间字符串
39 now = datetime.now()
40 now_timestr = now.strftime("%H%M%S")
41 #跳过非交易时间
42 if now_timestr < A.start_time or now_timestr > A.end_time:
43 return
44 #获取账号信息
45 acct = get_trade_detail_data(A.acct, A.acct_type, 'account')
46 if len(acct) == 0:
47 print(A.acct, '账号未登录 停止委托')
48 return
49 acct = acct[0]
50 #获取可用资金
51 available_cash = acct.m_dAvailable
52 print(now, '可用资金', available_cash)
53 #获取持仓信息
54 position_list = get_trade_detail_data(A.acct, A.acct_type, 'position')
55 #持仓数据 组合为字典
56 position_dict = {i.m_strInstrumentID + '.' + i.m_strExchangeID : int(i.m_nVolume) for i in position_list}
57 position_dict_available = {i.m_strInstrumentID + '.' + i.m_strExchangeID : int(i.m_nCanUseVolume) for i in position_list}
58 #未持有的品种填充持股数0
59 not_in_position_stock_dict = {i : 0 for i in final_dict if i not in position_dict}
60 position_dict.update(not_in_position_stock_dict)
61 #print(position_dict)
62 stock_list = list(position_dict.keys())
63 # print(stock_list)
64 #获取全推行情
65 full_tick = C.get_full_tick(stock_list)
66 #print('fulltick', full_tick)
67 #更新持仓状态记录
68 refresh_waiting_dict(C)
69 #撤超时委托
70 order_list = get_trade_detail_data(A.acct, 'stock', 'order')
71 if '091500'<= now_timestr <= '093000':#指定的范围內不撤单
72 pass
73 else:
74 for order in order_list:
75 #非本策略 本次运行记录的委托 不撤
76 if order.m_strRemark not in A.all_order_ref_dict:
77 continue
78 #委托后 时间不到撤单等待时间的 不撤
79 if time.time() - A.all_order_ref_dict[order.m_strRemark] < A.withdraw_secs:
80 continue
81 #对所有可撤状态的委托 撤单
82 if order.m_nOrderStatus in [48,49,50,51,52,55,86,255]:
83 print(f"超时撤单 停止等待 {order.m_strRemark}")
84 cancel(order.m_strOrderSysID,A.acct,'stock',C)
85 #下单判断
86 for stock in position_dict:
87 #有未查到的委托的品种 跳过下单 防止超单
88 if stock in A.waiting_dict:
89 print(f"{stock} 未查到或存在未撤回委托 {A.waiting_dict[stock]} 暂停后续报单")
90 continue
91 if stock in position_dict.keys():
92 #print(position_dict[stock],target_vol,'1111')
93 #到达目标数量的品种 停止委托
94 target_vol = final_dict[stock] if stock in final_dict else 0
95 if int(abs(position_dict[stock] - target_vol)) == 0:
96 print(stock, C.get_stock_name(stock), '与目标一致')
97 continue
98 #与目标数量差值小于100股的品种 停止委托
99 if abs(position_dict[stock] - target_vol) < 100:
100 print(f"{stock} {C.get_stock_name(stock)} 目标持仓{target_vol} 当前持仓{position_dict[stock]} 差额小于100 停止委托")
101 continue
102 #持仓大于目标持仓 卖出
103 if position_dict[stock]>target_vol:
104 vol = int((position_dict[stock] - target_vol)/100)*100
105 if stock not in position_dict_available:
106 continue
107 vol = min(vol, position_dict_available[stock])
108 #获取买一价
109 print(stock,'应该卖出')
110 buy_one_price = full_tick[stock]['bidPrice'][0]
111 #买一价无效时 跳过委托
112 if not buy_one_price > 0:
113 print(f"{stock} {C.get_stock_name(stock)} 取到的价格{buy_one_price}无效,跳过此次推送")
114 continue
115 print(f"{stock} {C.get_stock_name(stock)} 目标股数{target_vol} 当前股数{position_dict[stock]}")
116 msg = f"{now.strftime('%Y%m%d%H%M%S')}_{stock}_sell_{vol}股"
117 print(msg)
118 #对手价卖出
119 passorder(24,1101,A.acct,stock,14,-1,vol,'调仓策略',2,msg,C)
120 A.waiting_dict[stock] = msg
121 A.all_order_ref_dict[msg] = time.time()
122 #持仓小于目标持仓 买入
123 if position_dict[stock]<target_vol:
124 vol = int((target_vol-position_dict[stock])/100)*100
125 #获取卖一价
126 sell_one_price = full_tick[stock]['askPrice'][0]
127 #卖一价无效时 跳过委托
128 if not sell_one_price > 0:
129 print(f"{stock} {C.get_stock_name(stock)} 取到的价格{sell_one_price}无效,跳过此次推送")
130 continue
131 target_value = sell_one_price * vol
132 if target_value > available_cash:
133 print(f"{stock} 目标市值{target_value} 大于 可用资金{available_cash} 跳过委托")
134 continue
135 print(f"{stock} {C.get_stock_name(stock)} 目标股数{target_vol} 当前股数{position_dict[stock]}")
136 msg = f"{now.strftime('%Y%m%d%H%M%S')}_{stock}_buy_{vol}股"
137 print(msg)
138 #对手价买入
139 passorder(23,1101,A.acct,stock,14,-1,vol,'调仓策略',2,msg,C)
140 A.waiting_dict[stock] = msg
141 A.all_order_ref_dict[msg] = time.time()
142 available_cash -= target_value
143 #打印函数运行耗时 定时器间隔应大于该值
144 print(f"下单判断函数运行完成 耗时{time.time() - t0}秒")
145 
146 
147def refresh_waiting_dict(C):
148 """更新委托状态 入参为ContextInfo对象"""
149 #获取委托信息
150 order_list = get_trade_detail_data(A.acct,A.acct_type,'order')
151 #取出委托对象的 投资备注 : 委托状态
152 ref_dict = {i.m_strRemark : int(i.m_nOrderStatus) for i in order_list}
153 del_list = []
154 for stock in A.waiting_dict:
155 if A.waiting_dict[stock] in ref_dict and ref_dict[A.waiting_dict[stock]] in [56, 53, 54]:
156 #查到对应投资备注 且状态为成交 / 已撤 / 部撤, 从等待字典中删除
157 print(f'查到投资备注 {A.waiting_dict[stock]},的委托 状态{ref_dict[A.waiting_dict[stock]]} (56已成 53部撤 54已撤)从等待等待字典中删除')
158 del_list.append(stock)
159 if A.waiting_dict[stock] in ref_dict and ref_dict[A.waiting_dict[stock]] == 57:
160 #委托状态是废单的 也停止等待 从等待字典中删除
161 print(f"投资备注为{A.waiting_dict[stock]}的委托状态为废单 停止等待")
162 del_list.append(stock)
163 for stock in del_list:
164 del A.waiting_dict[stock]

获取融资融券账户可融资买入标的

qmt://docs/python
Python
1#coding:gbk
2def init(C):
3
4 r = get_assure_contract('123456789')
5 if len(r) == 0:
6 print('未取到担保明细')
7 else:
8 finable = [o.m_strInstrumentID+'.'+o.m_strExchangeID for o in r if o.m_eFinStatus==48]
9 print('可融资买入标的:', finable)

获取两融账号信息示例

qmt://docs/python
Python
1#coding:gbk
2 
3def init(C):
4 account_str = '11800028'
5 credit_account = query_credit_account(account_str, 1234, C)
6 
7def credit_account_callback(C,seq,result):
8 print('可买担保品资金', result.m_dAssureEnbuyBalance)

直接还款示例

该示例演示使用python进行融资融券账户的还款操作。

qmt://docs/python
Python
1#coding:gbk
2 
3 
4def init(ContextInfo):
5 # 用passorder函数进行融资融券账号的直接还款操作
6 
7 money = 10000 #还款金额
8 #account='123456'
9 s = '000001.SZ' # 代码填任意股票,占位用
10 passorder(32, 1101, account, s, 5, 0, money, 2, ContextInfo)
11 # passorder(75, 1101, account, s, 5, 0, money, 2, ContextInfo) 专项直接还款

交易数据查询示例

qmt://docs/python
Python
1#coding:gbk
2 
3 
4def to_dict(obj):
5 attr_dict = {}
6 for attr in dir(obj):
7 try:
8 if attr[:2] == 'm_':
9 attr_dict[attr] = getattr(obj, attr)
10 except:
11 pass
12 return attr_dict
13 
14 
15def init(C):
16 pass
17 #orders, deals, positions, accounts = query_info(C)
18 
19 
20def handlebar(C):
21 if not C.is_last_bar():
22 return
23 orders, deals, positions, accounts = query_info(C)
24 
25 
26def query_info(C):
27 orders = get_trade_detail_data('8000000213', 'stock', 'order')
28 for o in orders:
29 print(f'股票代码: {o.m_strInstrumentID}, 市场类型: {o.m_strExchangeID}, 证券名称: {o.m_strInstrumentName}, 买卖方向: {o.m_nOffsetFlag}',
30 f'委托数量: {o.m_nVolumeTotalOriginal}, 成交均价: {o.m_dTradedPrice}, 成交数量: {o.m_nVolumeTraded}, 成交金额:{o.m_dTradeAmount}')
31 
32 
33 deals = get_trade_detail_data('8000000213', 'stock', 'deal')
34 for dt in deals:
35 print(f'股票代码: {dt.m_strInstrumentID}, 市场类型: {dt.m_strExchangeID}, 证券名称: {dt.m_strInstrumentName}, 买卖方向: {dt.m_nOffsetFlag}',
36 f'成交价格: {dt.m_dPrice}, 成交数量: {dt.m_nVolume}, 成交金额: {dt.m_dTradeAmount}')
37 
38 positions = get_trade_detail_data('8000000213', 'stock', 'position')
39 for dt in positions:
40 print(f'股票代码: {dt.m_strInstrumentID}, 市场类型: {dt.m_strExchangeID}, 证券名称: {dt.m_strInstrumentName}, 持仓量: {dt.m_nVolume}, 可用数量: {dt.m_nCanUseVolume}',
41 f'成本价: {dt.m_dOpenPrice:.2f}, 市值: {dt.m_dInstrumentValue:.2f}, 持仓成本: {dt.m_dPositionCost:.2f}, 盈亏: {dt.m_dPositionProfit:.2f}')
42 
43 
44 accounts = get_trade_detail_data('8000000213', 'stock', 'account')
45 for dt in accounts:
46 print(f'总资产: {dt.m_dBalance:.2f}, 净资产: {dt.m_dAssureAsset:.2f}, 总市值: {dt.m_dInstrumentValue:.2f}',
47 f'总负债: {dt.m_dTotalDebit:.2f}, 可用金额: {dt.m_dAvailable:.2f}, 盈亏: {dt.m_dPositionProfit:.2f}')
48 
49 return orders, deals, positions, accounts

智能助手

咨询式 AI · 带入当前文档

智能助手加载中...