国金QMT实盘教程
由qxiao创建,最终由qxiao 被浏览 21 用户
本篇主要讲述如何获取BigQuant平台模拟交易信号,并将信号通过本地原生Python API (xtquant)将每日交易信号提交到国金QMT终端,进行实盘交易。
(这里我们假设您已经开通了国金证券账户,并下载了国金证券交易APP:佣金宝。 开户链接)
1.申请QMT实盘交易权限
首先,下载佣金宝APP-登录账户(在您的短信里面,888开头的资金账户)-按图提示操作提交社申请,预计2-3天开通
在最后一个图中, 1、2项勾选以后,就是QMT专业版,且开通miniQMT,因此,我们只需开通 "基础交易权限"和"策略交易权限"即可,没有特殊需求不建议去开通"可转债程序化交易"和"ETF趋势交易"。
如果遇到以下"资格审查未通过"的情形,请联系您的客户经理。
因为是合规进行程序化交易,因此申请时要填写报备资料,遇到下图时,勾选第二项:"国金QMT(版本:v1.0.0)"
开通流程需要把信息报送到交易所,大概3个工作日开通。或者您点进,佣金宝-我的-我的业务-QMT申请页面,会有进度提示,如果没下来会显示处理中。如下图所示:
2.信号获取
当订阅策略社区的某策略后,可以在”我的策略“板块查看该策略的每日持仓和每日信号,以及策略表现概述。
在实际的量化交易实践中,自动化信号获取和下单是至关重要的。这样做可以确保交易的时效性和一致性,同时减少人为错误。通过BigQuant平台的模拟交易信号,我们可以在实盘或模拟盘交易终端实现自动化下单。为了实现这一过程,首先需要将模拟交易信号提取到本地。在之前的帖子中,我们已经详细描述了如何通过BigQuant平台的API方式获取账号和持仓信息。详见《BigTrader AI量化交易终端 - 实盘交易终端》
3.环境准备
由于本篇主要目的为通过本地原生Python环境向QMT终端提交交易指令,所以环境准备方面,使用者需要下载国金QMT终端,并在本地准备合适的Python环境。
QMT终端安装
使用以下安装包安装QMT终端:
https://download.gjzq.com.cn/gjty/organ/gjzqqmt.rar
这个压缩包里,包含了实盘交易QMT终端和使用教程。
Python环境准备
xtquant文档:快速开始 | 迅投知识库
您可以直接下载xtquant包,并放入python对应的site-packages目录下导入。
我们建议直接使用如下指令:pip3 install xtquant,安装成功后再python编写环境即可导入xtquant.
4.终端登录
在使用程序下单前,需要先行启动QMT客户端。在完成第2步环境准备之后,我们启动客户端来到登录界面,勾选"行情+交易"。填写股票资金账号和交易密码。值得注意的是,使用XtQuant下单的客户需要勾选下方的”独立交易“。
\
5.BigQuant 我的策略如何实盘
这里我们介绍当我们把一段能回测的代码提交模拟交易后,我们在"我的策略"页面可以查看,接下来我们介绍如何通过将信号拉到本地,并通过xtquant api下单实现自动化实盘的例子。
当我们将这个代码运行后,每天自动定时会拉取信号并下单。
安装并导入依赖库
在本地环境中安装XtQuant包,可以使用如下指令:pip3 install xtquant。上面第三章已介绍,我们在后续创建交易前需要先导入依赖库xtquant。
创建交易对象
from xtquant.xttrader import XtQuantTrader
path = r'------\userdata_mini'
session_id = int(time.time())
xt_trader = XtQuantTrader(path, session_id)
创建xt_trader对象需要两个参数:\npath:路径,就是安装QMT软件的文件下下的/userdata_mini文件夹。\nsession_id : 回话id,当创建多个xt_trader对象时,需要不同,这里我们使用时间整数
连接QMT客户端
xt_trader.start()
connect_result = xt_trader.connect()
print(connect_result)
if connect_result == 0:
print('连接成功')
执行xt_trader.connect(),需要保证已登录QMT极简模式并保持客户端运行状态,即可连接成功。connect_result结果返回0即表示连接成功。
订阅账户
from xtquant.xttype import StockAccount
acc = StockAccount('xxxxx')
subscribe_result = xt_trader.subscribe(acc)
print(subscribe_result)
订阅资金账户,xxxxx替换成你正在登录的资金账户号,subscribe_result结果返回0表示订阅成功。
交易下单代码
这里给出示例代码,以市价单下单,开发者可自己加入撤单追单逻辑。
接下来可以开始编写核心的交易程序,根据BigQuant平台上抓取到的今日交易信号,在QMT终端上开始进行下单和换仓。本文使用的核心函数是股票异步报单xt_trader.order_stock_async。更多操作接口说明和交易模块数据字典和数据结构说明详见迅投官网,XtQuant.Xttrade 交易模块 | 迅投知识库
#coding:utf-8
def fetch_volume(positions, ins):
for pos in positions:
if pos.stock_code == ins:
volume = pos.volume
return volume
def exec_func(xt_trader, acc, order_df, positions):
now = datetime.now()
# 持仓字典里多空方向股票不适用
if positions:
cur_pos = [pos.stock_code for pos in positions]
else:
cur_pos = []
if order_df.empty:
buy_signal = []
sell_signal = []
order_df['trade_time'] = order_df['order_dt'].apply(lambda x:15 if 'T15:00' in x else 9 ) # 标记订单预期撮合时间
if now.hour == 9:
# 如果是开盘时间,只交易早盘的订单
order_df = order_df[order_df['trade_time'] == 9 ]
elif now.hour == 14:
# 如果是收盘时间,只交易尾盘的订单
order_df = order_df[order_df['trade_time'] == 15 ]
buy_signal = order_df[order_df['direction']=='1']['instrument'].tolist()
sell_signal = order_df[order_df['direction']=='2']['instrument'].tolist()
print('买入信号:', buy_signal, '卖出信号:', sell_signal)
for ins in buy_signal:
volume = order_df[order_df['instrument'] == ins]['order_qty'].iloc[0]
price = order_df[order_df['instrument'] == ins]['order_price'].iloc[0]
print(f"{now} 最新价 买入 {ins} {volume}股")
async_seq = xt_trader.order_stock_async(acc, ins, xtconstant.STOCK_BUY, volume, xtconstant.LATEST_PRICE, -1, '您的策略备注', '您的订单备注')
for ins in sell_signal:
cur_volume = fetch_volume(positions, ins)
print(f"{now} 最新价 卖出 {ins} {cur_volume}股")
async_seq = xt_trader.order_stock_async(acc, ins, xtconstant.STOCK_SELL, cur_volume, xtconstant.LATEST_PRICE, -1, '您的策略备注', '您的订单备注')
def trade(xt_trader, order_df, account):
#获取当前持仓
positions = xt_trader.query_stock_positions(account)
pos_dict = {}
for pos in positions:
pos_dict[pos.stock_code] = pos.volume
print("pos", pos_dict)
# 执行交易任务
exec_func(xt_trader, account, order_df, positions)
\
7.查看持仓
经过以上步骤后,可以在终端查看是否成功提交委托。可以在QMT终端上查看”委托“和”持仓“页面
8.完整代码
本篇提供了完整的通过BigQuant平台获取模拟信号,整合成变量dataframe的格式,再通过xtquant包在QMT终端上进行下单的全流程程序。并且本程序对上述任务进行了定时,每日早上集合竞价期间9点25执行一次。
完整代码请克隆:
https://bigquant.com/codesharev3/2baa0925-3a80-41f5-88f1-56639e5a6b8a
9.xtquant API熟悉
为便于开发者理解xtquant API,文末我们简单介绍下几个重要的交易API的使用。
策略实盘交易需要使用QMT交易终端的API,这些API集成在Python包xtquant, 这里我们简单介绍下查询持仓、下单、查询委托、撤单的API,以便帮助开发者更灵活的实盘交易。
记住,要使用xtquant API, 需要提前启动并登录QMT交易终端,在上一步我们详细介绍了。
首先导入相应的包
# 导入系统包
import os
import json
import logging
import requests
from typing import Dict, List, Optional, Tuple
import time, datetime, traceback, sys
from datetime import datetime
import schedule
# 导入qmt相关的包
from xtquant import xtdata
from xtquant.xttrader import XtQuantTrader, XtQuantTraderCallback
from xtquant.xttype import StockAccount
from xtquant import xtconstant
print('导入包完成!')
账号初始化
# 指定客户端所在路径
path = r'C:\Users\shtshao\国金证券QMT交易端\userdata_mini'
# 生成session id 整数类型 同时运行的策略不能重复
session_id = int(time.time())
xt_trader = XtQuantTrader(path, session_id)
# 证券账号对象
account = '88832571'
acc = StockAccount(account, 'STOCK')
# 启动交易线程
xt_trader.start()
# 建立交易连接,返回0表示连接成功
connect_result = xt_trader.connect()
print('建立交易连接,返回0表示连接成功', connect_result)
# 对交易回调进行订阅,订阅后可以收到交易主推,返回0表示订阅成功
subscribe_result = xt_trader.subscribe(acc)
print('对交易回调进行订阅,订阅后可以收到交易主推,返回0表示订阅成功', subscribe_result)
查询账号权益
#xt_trader为XtQuant API实例对象,获取可用金额属性
cash = xt_trader.query_stock_asset(acc).cash
total_asset = xt_trader.query_stock_asset(acc).total_asset
print(total_asset)
查询账号持仓
positions = xt_trader.query_stock_positions(acc)
pos_dict = {}
for pos in positions:
pos_dict[pos.stock_code] = pos.volume
print("position===:", pos_dict)
下单
## ins需要根据下单需求定义
# 股票异步报单函数
ins = '510300.SH'
# 市价下单
order_id = xt_trader.order_stock(acc, ins, xtconstant.STOCK_BUY, 1000, xtconstant.LATEST_PRICE, -1, 'strategy1', 'order_test')
# 限价下单
order_id = xt_trader.order_stock(acc, ins, xtconstant.STOCK_BUY, 1000, xtconstant.FIX_PRICE , 3.9, 'strategy1', 'order_test')
查询委托
orders = xt_trader.query_stock_orders(acc, False)
a = orders[0]
a.order_id,a.price,a.order_volume
撤单
# # 返回是否成功发出撤单指令,0: 成功, -1: 表示撤单失败
# # 股票同步撤单(按订单号)
cancel_result = xt_trader.cancel_order_stock(acc, order_id)
# # 股票异步撤单(按订单号)
# cancel_result = xt_trader.cancel_order_stock_async(account, order_id)
\