
QMT 作为目前国内主流的量化交易终端,凭借低延迟、全行情、极速交易等核心优势,成为量化交易者的首选工具之一。但QMT 的功能集中于基础行情、交易接口,所以第三方库是拓展QMT量化能力的核心,覆盖数据处理、策略回测、指标计算、可视化、风险分析等全流程。
这篇文章我们将从QMT第三方库的详细作用、安装部署、代码实战分析、报错指南等多个维度进行详细讲解,提供专业级 QMT 第三方库使用教程,覆盖新手入门到进阶实战。
QMT的第三方库是一系列预先封装好的、功能强大的Python工具包,核心作用是扩展和增强了QMT系统自身的策略开发与分析能力。我们下载QMT量化软件后,第一步就是下载Python库,打开QMT系统界面,点击【我的】页面正中间找到【下载python库】按钮,点击就可以下载。下载后大部分第三方库就下载到我们QMT目录下了。具体来说,第三方库的作用体现在三个方面:

让开发者无需从零编写底层算法,可以直接调用像Pandas进行高效数据处理、NumPy进行复杂数值计算、TA-Lib计算技术指标、Statsmodels进行统计分析等专业功能,这样就可以将大量精力集中于策略逻辑本身。

利用这些成熟、稳定的开源库,可以快速搭建复杂的量化模型,不需要我们计算大量数据,大量减少我们搭建策略所需要的时间;比如说你想写一个策略,找出过去一个月“股价突破20日均线,且成交量是前一日两倍”的所有股票。
如果没有第三方库,那你就需要自己写复杂的循环代码,从成千上万条股票数据里,一天一天地计算20天的平均价格,还要写代码对比每天的收盘价和这个平均值,再写代码计算每天的成交量,并和前一天的对比,这个过程非常繁琐,代码冗长,且容易出错。

QMT系统提供了一个标准的Python环境。它核心的Python语法、数据结构(如DataFrame)以及常用的第三方库(如Pandas、NumPy)在其他量化软件中是通用的,无需重写,比如说聚宽,那就可以直接把在聚宽上面写的策略平移过来。
聚宽代码结构示例:
def initialize(context):# 定义一个全局变量, 保存要操作的股票 g.security = '******.XSHE'# 运行函数 run_daily(market_open, time='every_bar')# 每个单位时间(如果按天回测,则每天调用一次,如果按分钟,则每分钟调用一次)调用一次def market_open(context):if g.security not in context.portfolio.positions: order(g.security, 1000)else: order(g.security, -800)QMT代码结构示例:
#示例说明:本策略,在回测的每个周期买入主图标的def init(C):#init handlebar函数的入参是ContextInfo对象 可以缩写为C#设置测试标的为主图品种 C.stock= C.stockcode + '.' +C.market#accountid为测试的ID 回测模式资金账号可以填任意字符串 C.accountid = "testS"def handlebar(C):# handlebar在回测时,会在回测周期的每根bar被执行一次# handlebar在实时行情下,会随着主图tick的更新被调用# passorder是QMT的综合下单函数,具体参数字段参考官方文档 passorder(23, 1101,C.accountid, C.stock, 5, -1, 1, C)QMT中,所有数据都存储在本地,所有的策略计算都在电脑本地运行,用户可以自由使用下载到的数据与python库。
QMT除了自带的第三方库,如果我们交易过程中策略比较复杂,自带的第三方库如果不够用,还可以自行导所需的库,现在我们来给大家详细介绍一下如何在QMT系统中安装和调用第三方Python库,以pytdx为例。
Python官网:https://www.python.org/downloads/release/python-360/
新增环境变量:我的电脑--属性--高级系统设置--高级--环境变量---path:C:\Python36;C:\Python36\Scripts

(1) Win+R 打开运行,输入 cmd

(2)检查 Python 版本
在命令提示符窗口中,输入python ,回车

如果 Python 已经正确安装且环境变量配置无误,会显示 Python 的版本信息,以及进入 Python 交互式命令行模式(显示>>>提示符)

安装前得知道 QMT 交易端装在你电脑的哪个位置,比如我的就是 D:\国金QMT交易端模拟\bin.x64\Lib\site-packages ,每个人路径可能不同,找到自己的路径记下来,后面要用。

安装三方库命令: pip install openpyxl -t D:\国金QMT交易端模拟\bin.x64\Lib\site-packages

检查路径:安装位置\bin.x64\Lib\site-packages检查安装库。
首先找到我们下载在电脑桌面的QMT软件,右击鼠标找到【打开文件所在的位置】,打开 QMT 安装目录,进入对应的 Python 环境文件夹,找到Lib\site-packages子目录,该目录下的所有文件夹和文件就是已安装的第三方库,这里就可以直接查看库的名称、版本及相关文件,并且确认第三方库是否安装成功。

OK,整个第三方库就安装完成了!
在编写策略代码时,可以直接通过import语句导入安装的第三方库。例如:
import openpyxl现在我们以QMT 客户端自带的策略模板作为案例,让大家直观掌握第三方库在 QMT策略 中的实际运用,轻松拿捏如何在 QMT 中正确导入、调用第三方库,以及如何搭建一个完整的QMT策略框架。
登录QMT,在QMT主页面直接点击【新建策略】→选择python策略,然后就可以开始新建一个完整策略,以我们下面的代码为参考,第一行代码就是导入第三方库,其中:
pandas :用于高效处理和分析表格型数据(如股票行情)。
numpy :用于进行快速的数组运算和数学计算。
talib :专门用于计算技术分析指标,如CCI、MACD、RSI等
import pandas as pdimport numpy as npimport talibdef init(ContextInfo): passdef handlebar(ContextInfo): pass这段代码是QMT的一个完整的策略框架,除了第三方库以外,还有QMT核心函数,其中策略初始化函数 init 在策略启动时只执行一次, 它的参数 ContextInfo 是一个上下文对象,用于存储和传递策略的全局状态、参数和数据。
def init(ContextInfo): pass另外一个是行情处理函数 handlebar 是策略的核心逻辑执行函数。它在历史回测时,会对每一根K线依次执行一次;在实盘运行时,会在每个新的tick数据到来时触发执行。
def handlebar(ContextInfo): pass上面代码提供了一个完整的策略框架,但它相当于只是一个空壳,我们需要根据补充交易思想,在 init 函数中完成策略参数和股票池的设定,并在 handlebar 函数中补全数据获取、指标计算和买卖下单的具体代码,下面我们来看一个完整的QMT双均线策略。
#coding:gbk"""回测模型示例(非实盘交易策略)#HS300日线下运行,20个交易日进行 一次调仓,每次买入在买入备选中因子评分前10的股票,每支股票各分配当前可用资金的10%(权重可调整)#扩展数据需要在补完HS300成分股数据之后生成,本模型中扩展数据暂时使用VBA指标ATR和ADTM生成,命名为atr和adtm"""import pandas as pdimport numpy as npimport timeimport datetimedef init(ContextInfo): ContextInfo.s = ContextInfo.get_sector('******.SH') ContextInfo.set_universe(ContextInfo.s) ContextInfo.day = 0 ContextInfo.holdings = {i:0 for i in ContextInfo.s} ContextInfo.weight = [0.1]*10 #设置资金分配权重 ContextInfo.buypoint = {} ContextInfo.money = ContextInfo.capital ContextInfo.profit = 0 ContextInfo.accountID='testS'def handlebar(ContextInfo): rank1 = {} rank2 = {} rank_total = {} tmp_stock = {} d = ContextInfo.barpos price = ContextInfo.get_history_data(1,'1d','open',3)if d > 60 and d % 20 == 0: #每月一调仓 nowDate = timetag_to_datetime(ContextInfo.get_bar_timetag(d),'%Y%m%d')print(nowDate) buys, sells = signal(ContextInfo) order = {}for k in list(buys.keys()):if buys[k] == 1: rank1[k] = ext_data_rank('atr',k[-2:]+k[0:6],0,ContextInfo) rank2[k] = ext_data_rank('adtm',k[-2:]+k[0:6],0,ContextInfo)#print rank1[k], rank2[k] rank_total[k] = 1.0 * rank1[k] #因子的权重需要人为设置,此处取了0.5和-0.5print (1111111, rank1[k]) tmp = sorted(list(rank_total.items()), key = lambda item:item[1])#print tmpif len(tmp) >= 10: tmp_stock = {i[0] for i in tmp[:10]}else: tmp_stock = {i[0] for i in tmp} #买入备选中若超过10只股票则选10支,不足10支则全选for k in list(buys.keys()):if k not in tmp_stock: buys[k] = 0if tmp_stock:print('stock pool:',tmp_stock)for k in ContextInfo.s:if ContextInfo.holdings[k] > 0 and sells[k] == 1:print('ready to sell') order_shares(k,-ContextInfo.holdings[k]*100,'fix',price[k][-1],ContextInfo,ContextInfo.accountID) ContextInfo.money += price[k][-1] * ContextInfo.holdings[k] * 100 - 0.0003*ContextInfo.holdings[k]*100*price[k][-1] #手续费按万三设定 ContextInfo.profit += (price[k][-1]-ContextInfo.buypoint[k]) * ContextInfo.holdings[k] * 100 - 0.0003*ContextInfo.holdings[k]*100*price[k][-1]#print price[k][-1]print(k)#print ContextInfo.money ContextInfo.holdings[k] = 0 ContextInfo.money_distribution = {k:i*ContextInfo.money for (k,i) in zip(tmp_stock,ContextInfo.weight)}for k in tmp_stock:if ContextInfo.holdings[k] == 0 and buys[k] == 1:print('ready to buy') order[k] = int(ContextInfo.money_distribution[k]/(price[k][-1]))/100 order_shares(k,order[k]*100,'fix',price[k][-1],ContextInfo,ContextInfo.accountID) ContextInfo.buypoint[k] = price[k][-1] ContextInfo.money -= price[k][-1] * order[k] * 100 - 0.0003*order[k]*100*price[k][-1] ContextInfo.profit -= 0.0003*order[k]*100*price[k][-1]print(k) ContextInfo.holdings[k] = order[k]print(ContextInfo.money,ContextInfo.profit,ContextInfo.capital) profit = ContextInfo.profit/ContextInfo.capitalif not ContextInfo.do_back_test: ContextInfo.paint('profit_ratio', profit, -1, 0)def signal(ContextInfo): buy = {i:0 for i in ContextInfo.s} sell = {i:0 for i in ContextInfo.s} data_high = ContextInfo.get_history_data(22,'1d','high',3) data_high_pre = ContextInfo.get_history_data(2,'1d','high',3) data_close60 = ContextInfo.get_history_data(62,'1d','close',3)#print data_high#print data_close#print data_close60for k in ContextInfo.s:if k in data_close60:if len(data_high_pre[k]) == 2 and len(data_high[k]) == 22 and len(data_close60[k]) == 62:if data_high_pre[k][-2] > max(data_high[k][:-2]): buy[k] = 1 #超过20日最高价,加入买入备选elif data_high_pre[k][-2] < np.mean(data_close60[k][:-2]): sell[k] = 1 #低于60日均线,加入卖出备选#print buy#print sellreturn buy,sell #买入卖出备选上面的QMT策略代码中,第三方库(特别是NumPy)极大地简化并实现了策略中的核心计算逻辑。
策略需要判断卖出信号时,使用了 np.mean(data_close60[k][:-2]) 这一行代码来计算过去60个交易日的收盘价均值(即60日均线)。如果没有NumPy库,开发者就需要自行编写复杂的循环来遍历数组并求和、求平均值,这不仅需要写很长的代码,效率低下,还容易出错。而借助NumPy这个成熟、高效的数值计算库,仅用一行简洁的代码就完成了复杂的统计运算。
报错信息:
"ImportError:Forbidden:Moduleopenpyxl not in whitelist!"
问题解答:
该报错是由于券商后台开启了 Python 库白名单,联系您的所在券商开通对应 Python 库白名单权限即可。
报错信息1:
NameError: name 'pandas' is not defined
解决方法1:
这个报错是指当前环境下没有找到pandas库,请QMT在设置-模型设置中检查正确设置了路径,正确路径应指向{安装目录}\bin.x64

另外,请检查是否已经下载了python环境

报错信息2 :
AttributeError: module 'pandas' has no attribute 'core'
解决方法2:
重启QMT客户端即可。
(1)开户成功后入金10万后提交QMT申请流程
(2)申请过程全程线上,预计2个工作日申请完成。
(3)等待开通过程中,可以提供测试账号、安装配置流程、量化会员资料。
(4)开通成功后,会通过邮件发送你软件下载地址,登录账号后就可以使用。

福利1:惊喜佣金
福利2:领取完整教程
福利3:添加量化讨论群
福利4:提供专业量化问题解答
福利5:量化工具安装使用教程、视频
福利6:极速柜台,量化投资者专用,速度微秒级
福利7:提供服务器托管模式:ptrade+ldp极速柜台+vip定向服务器(限50人)
