通知设置 新通知
迅投官网的示例代码真的无眼看。。。
李魔佛 发表了文章 • 0 个评论 • 171 次浏览 • 2023-11-10 01:17
变量名,类名用A ,B,C 噗, 没有一点含义,做什么鬼
class a():
pass
A = a()而且也不符合python风格。。。python类名推荐的大写字母开头,实例化对象用小写字母。
所以退一万步讲,上面的代码正常点的程序员写也应该是这样的。
class A():
pass
a = A()
其实正确的应该class GlobalCls():
pass
g = GlobalCls()
其他地方也是有这个毛病。
把代码喂给GPT,让它来分析一下:
得到如下结果:文件编码声明: #coding:gbk 是指定源文件的编码格式为GBK。在Python 3中,通常使用UTF-8作为文件编码格式,因此可以将该行删除或更改为#coding:utf-8。
类名和函数名: 根据PEP 8命名约定,类名应该使用大写字母开头的驼峰命名法(例如A改为A)。同样,函数名应该使用小写字母开头的小写命名法(例如init改为init,f改为f)。
类和实例: 在代码中定义了一个空类a,但没有给它任何属性或方法。如果不需要这个类,可以将其删除。
缩进和代码格式: Python非常依赖于正确的缩进,以指示代码块的层次结构。请确保代码的缩进是一致的,并使用适当的缩进级别(通常是4个空格)。
代码注释: 代码中有一些注释,但是大部分是被注释掉的。良好的注释可以增加代码的可读性和可维护性,建议在关键部分添加更多有用的注释。
异常处理: 代码中没有包含任何异常处理机制。在实际应用中,建议对可能引发异常的操作进行适当的异常处理,以提高代码的健壮性。
然后里面计算涨停是这样的: 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)
用昨收价* 1.2和1.1判断当前是否涨跌停。 首先,没有考虑到ST股,部分ST是5%涨停的。
其次,是直接用的昨收价,如果当天是分红除权日,昨收价没有做除权处理,得到的涨跌幅也是不准的。
当然这个文档最大的问题是,很多示例代码运行是直接报错的!!
查看全部
如果拿去做code review,估计会被喷的体无完肤。
变量名,类名用A ,B,C 噗, 没有一点含义,做什么鬼
class a():而且也不符合python风格。。。python类名推荐的大写字母开头,实例化对象用小写字母。
pass
A = a()
所以退一万步讲,上面的代码正常点的程序员写也应该是这样的。
class A():
pass
a = A()
其实正确的应该
class GlobalCls():
pass
g = GlobalCls()
其他地方也是有这个毛病。
把代码喂给GPT,让它来分析一下:
得到如下结果:
文件编码声明: #coding:gbk 是指定源文件的编码格式为GBK。在Python 3中,通常使用UTF-8作为文件编码格式,因此可以将该行删除或更改为#coding:utf-8。
类名和函数名: 根据PEP 8命名约定,类名应该使用大写字母开头的驼峰命名法(例如A改为A)。同样,函数名应该使用小写字母开头的小写命名法(例如init改为init,f改为f)。
类和实例: 在代码中定义了一个空类a,但没有给它任何属性或方法。如果不需要这个类,可以将其删除。
缩进和代码格式: Python非常依赖于正确的缩进,以指示代码块的层次结构。请确保代码的缩进是一致的,并使用适当的缩进级别(通常是4个空格)。
代码注释: 代码中有一些注释,但是大部分是被注释掉的。良好的注释可以增加代码的可读性和可维护性,建议在关键部分添加更多有用的注释。
异常处理: 代码中没有包含任何异常处理机制。在实际应用中,建议对可能引发异常的操作进行适当的异常处理,以提高代码的健壮性。
然后里面计算涨停是这样的:
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)
用昨收价* 1.2和1.1判断当前是否涨跌停。 首先,没有考虑到ST股,部分ST是5%涨停的。
其次,是直接用的昨收价,如果当天是分红除权日,昨收价没有做除权处理,得到的涨跌幅也是不准的。
当然这个文档最大的问题是,很多示例代码运行是直接报错的!!

QMT获取A股全市场股票代码
李魔佛 发表了文章 • 0 个评论 • 248 次浏览 • 2023-10-25 15:23
"沪深A股"
完整代码:#-*-coding:gbk-*-
import time
start = False
ACCOUNT = ''
def init(ContextInfo):
now = time.ctime()
print(now)
ContextInfo.run_time("execution","30nSecond","2023-04-14 13:20:00")
def execution(ContextInfo):
data = ContextInfo.get_stock_list_in_sector('沪深A股')
print(len(data))
def handlebar(ContextInfo):
pass
当前共有5047只股票【2023-10-25 15:18:45.533】 start trading mode
【2023-10-25 15:18:45.533】 Wed Oct 25 15:18:45 2023
【2023-10-25 15:18:45.533】 5074
['000001.SZ', '000002.SZ', '000004.SZ', '000005.SZ', '000006.SZ', '000007.SZ', '000008.SZ', '000009.SZ', '000010.SZ', '000011.SZ', '000012.SZ', '000014.SZ', '000016.SZ', '000017.SZ', '000019.SZ', '000020.SZ', '000021.SZ', '000023.SZ', '000025.SZ', '000026.SZ', '000027.SZ', '000028.SZ', '000029.SZ', '000030.SZ', '000031.SZ', '000032.SZ', '000034.SZ', '000035.SZ', '000036.SZ', '000037.SZ', '000039.SZ', '000040.SZ', '000042.SZ', '000045.SZ', '000046.SZ', '000048.SZ', '000049.SZ', '000050.SZ', '000055.SZ', '000056.SZ', '000058.SZ', '000059.SZ', '000060.SZ', '000061.SZ', '000062.SZ', '000063.SZ', '000065.SZ', '000066.SZ', '000068.SZ', '000069.SZ', '000070.SZ', '000078.SZ', '000088.SZ', '000089.SZ', '000090.SZ', '000096.SZ', '000099.SZ', '000100.SZ', '000151.SZ', '000153.SZ', '000155.SZ', '000156.SZ', '000157.SZ', '000158.SZ', '000159.SZ', '000166.SZ', '000301.SZ', '000333.SZ', '000338.SZ', '000400.SZ', '000401.SZ', '000402.SZ', '000403.SZ', '000404.SZ', '000407.SZ', '000408.SZ', '000409.SZ', '000410.SZ', '000411.SZ', '000413.SZ', '000415.SZ', '000416.SZ', '000417.SZ', '000419.SZ', '000420.SZ', '000421.SZ', '000422.SZ', '000423.SZ', '000425.SZ', '000426.SZ',省略若干...
点击查看大图
是否遇到QMT或Ptrade的问题, 无从入手? 或者咨询无门 ?
来加入 知识星球 , 获取专业的技术解答, 量化实盘代码, 技术交流群
查看全部
"沪深A股"
完整代码:
#-*-coding:gbk-*-
import time
start = False
ACCOUNT = ''
def init(ContextInfo):
now = time.ctime()
print(now)
ContextInfo.run_time("execution","30nSecond","2023-04-14 13:20:00")
def execution(ContextInfo):
data = ContextInfo.get_stock_list_in_sector('沪深A股')
print(len(data))
def handlebar(ContextInfo):
pass
当前共有5047只股票
【2023-10-25 15:18:45.533】 start trading mode省略若干...
【2023-10-25 15:18:45.533】 Wed Oct 25 15:18:45 2023
【2023-10-25 15:18:45.533】 5074
['000001.SZ', '000002.SZ', '000004.SZ', '000005.SZ', '000006.SZ', '000007.SZ', '000008.SZ', '000009.SZ', '000010.SZ', '000011.SZ', '000012.SZ', '000014.SZ', '000016.SZ', '000017.SZ', '000019.SZ', '000020.SZ', '000021.SZ', '000023.SZ', '000025.SZ', '000026.SZ', '000027.SZ', '000028.SZ', '000029.SZ', '000030.SZ', '000031.SZ', '000032.SZ', '000034.SZ', '000035.SZ', '000036.SZ', '000037.SZ', '000039.SZ', '000040.SZ', '000042.SZ', '000045.SZ', '000046.SZ', '000048.SZ', '000049.SZ', '000050.SZ', '000055.SZ', '000056.SZ', '000058.SZ', '000059.SZ', '000060.SZ', '000061.SZ', '000062.SZ', '000063.SZ', '000065.SZ', '000066.SZ', '000068.SZ', '000069.SZ', '000070.SZ', '000078.SZ', '000088.SZ', '000089.SZ', '000090.SZ', '000096.SZ', '000099.SZ', '000100.SZ', '000151.SZ', '000153.SZ', '000155.SZ', '000156.SZ', '000157.SZ', '000158.SZ', '000159.SZ', '000166.SZ', '000301.SZ', '000333.SZ', '000338.SZ', '000400.SZ', '000401.SZ', '000402.SZ', '000403.SZ', '000404.SZ', '000407.SZ', '000408.SZ', '000409.SZ', '000410.SZ', '000411.SZ', '000413.SZ', '000415.SZ', '000416.SZ', '000417.SZ', '000419.SZ', '000420.SZ', '000421.SZ', '000422.SZ', '000423.SZ', '000425.SZ', '000426.SZ',
点击查看大图
是否遇到QMT或Ptrade的问题, 无从入手? 或者咨询无门 ?
来加入 知识星球 , 获取专业的技术解答, 量化实盘代码, 技术交流群

国金QMT测试版|模拟盘 安装程序 下载
李魔佛 发表了文章 • 0 个评论 • 1072 次浏览 • 2023-09-02 12:16
登录账号:******* 登录密码:*********
QMT交易测试客户端下载链接 链接:https://download.gjzq.com.cn/temp/organ/gjzqqmt_ceshi.rar
在线接口文档:
https://qmt.ptradeapi.com
需要开通QMT的视频的朋友可以扫码咨询开通,目前国金开通门槛是入金2W就可以了。费率万一,可半年后免五。
开户后可提供技术相关解答。
查看全部
国金证券QMT测试账号信息:
登录账号:******* 登录密码:*********
QMT交易测试客户端下载链接 链接:https://download.gjzq.com.cn/temp/organ/gjzqqmt_ceshi.rar

在线接口文档:
https://qmt.ptradeapi.com
需要开通QMT的视频的朋友可以扫码咨询开通,目前国金开通门槛是入金2W就可以了。费率万一,可半年后免五。
开户后可提供技术相关解答。

国金QMT实盘版本下载地址
李魔佛 发表了文章 • 0 个评论 • 910 次浏览 • 2023-08-22 22:00
QMT实盘版下载地址:
https://download.gjzq.com.cn/gjty/organ/gjzqqmt.rar
安装路径最好不要有中文,和空格。
实盘版里面可以切换模拟和实盘。
在线接口文档:
https://qmt.ptradeapi.com
需要开通QMT的朋友可以扫码咨询开通,目前国金开通门槛是入金2W就可以了。
开户后可提供技术相关解答。
附一个国金Ptrade的下载地址:
Ptrade实盘版下载地址:
https://download.gjzq.com.cn/gjty/organ/gjzqptd.rar
查看全部

QMT实盘版下载地址:
https://download.gjzq.com.cn/gjty/organ/gjzqqmt.rar
安装路径最好不要有中文,和空格。
实盘版里面可以切换模拟和实盘。
在线接口文档:
https://qmt.ptradeapi.com
需要开通QMT的朋友可以扫码咨询开通,目前国金开通门槛是入金2W就可以了。
开户后可提供技术相关解答。

附一个国金Ptrade的下载地址:
Ptrade实盘版下载地址:
https://download.gjzq.com.cn/gjty/organ/gjzqptd.rar
哪些券商有miniqmt? 门槛如何
李魔佛 发表了文章 • 0 个评论 • 814 次浏览 • 2023-08-11 12:04
它属于一个精简版的QMT,把回测功能,UI界面操作功能去除。
你可以把miniqmt导入到你的项目里面,直接操作下单。
from xtquant import xtdata
data = xtdata.get_market_data(field_list=['time', 'open', 'close', 'high', 'low', 'volume', 'amount'], stock_list=['603000.SH'], period='1d', start_time='20230101')
print(data)上面代码 可以直接在你的pycharm里面运行, 提前把 xtquant 这个包复制到系统路径,site-packages,或者自己加到环境变量。
MiniQMT支持新版本的Python
最新已经支持python3.6-3.11
更新方式:主QMT-设置-交易设置-模型设置里更新Python库
目前支持miniQTM的券商有哪些?
其实miniqmt是附属在QMT上的,正常有QMT的,默认就可以使用miniqmt,除非券商作妖,阉割了。
国金,国盛支持miniqmt,开通QMT后 miniqmt就是直接可以使用的。
而国信的miniqmt默认被阉割了,需要额外去申请。(可能还有些经理不敬业的,会和你说不支持miniqmt,曾经遇到过),不过国信的miniqmt开通后,个人只能拉取行情数据,是没有下单权限,下单券商是需要机构才可以申请。
国金的QMT,miniqmt的开通门槛会低一些,有入金2W就可以开通的营业部; 也有入金50W开通的营业部。 需要的盆友可以扫码咨询开通。
国盛的QMT,目前门槛比较高,需要资产100W才能开通。本身之前门槛还只是入金30W就可以的了,后面他们不断地提高门槛,提到50W,后面提高到100W,不过最近几天,营业部的经理和我说目前我这边开通只需要50W即可。
所以平时有优惠费率的时候就不要犹犹豫豫,把账户和权限开了再说,因为好事不常有,过了这个桥就没有这个店。
需要开户的盆友可以扫码咨询
查看全部
它属于一个精简版的QMT,把回测功能,UI界面操作功能去除。
你可以把miniqmt导入到你的项目里面,直接操作下单。
from xtquant import xtdata上面代码 可以直接在你的pycharm里面运行, 提前把 xtquant 这个包复制到系统路径,site-packages,或者自己加到环境变量。
data = xtdata.get_market_data(field_list=['time', 'open', 'close', 'high', 'low', 'volume', 'amount'], stock_list=['603000.SH'], period='1d', start_time='20230101')
print(data)
MiniQMT支持新版本的Python
最新已经支持python3.6-3.11
更新方式:主QMT-设置-交易设置-模型设置里更新Python库
目前支持miniQTM的券商有哪些?
其实miniqmt是附属在QMT上的,正常有QMT的,默认就可以使用miniqmt,除非券商作妖,阉割了。
国金,国盛支持miniqmt,开通QMT后 miniqmt就是直接可以使用的。
而国信的miniqmt默认被阉割了,需要额外去申请。(可能还有些经理不敬业的,会和你说不支持miniqmt,曾经遇到过),不过国信的miniqmt开通后,个人只能拉取行情数据,是没有下单权限,下单券商是需要机构才可以申请。
国金的QMT,miniqmt的开通门槛会低一些,有入金2W就可以开通的营业部; 也有入金50W开通的营业部。 需要的盆友可以扫码咨询开通。
国盛的QMT,目前门槛比较高,需要资产100W才能开通。本身之前门槛还只是入金30W就可以的了,后面他们不断地提高门槛,提到50W,后面提高到100W,不过最近几天,营业部的经理和我说目前我这边开通只需要50W即可。
所以平时有优惠费率的时候就不要犹犹豫豫,把账户和权限开了再说,因为好事不常有,过了这个桥就没有这个店。
需要开户的盆友可以扫码咨询

国金证券QMT量化新人培训教程
李魔佛 发表了文章 • 0 个评论 • 2110 次浏览 • 2023-05-29 00:37
视频已经整理放到B站:
https://space.bilibili.com/73827743/channel/seriesdetail?sid=3326385&ctype=0
视频目录:
量化新人用QMT+chat GPT快速上手量化策略(一)QMT基础介绍
量化新人用QMT+chat GPT快速上手量化策略(二)QMT均线盘后选股
量化新人用QMT+chat GPT快速上手量化策略(三)一个基本的回测策略代码
量化新人用QMT+chat GPT快速上手量化策略(四) QMT运行一个策略的整体流程
量化新人用QMT+chat GPT快速上手量化策略(五) 获取股票数据
量化新人用QMT+chat GPT快速上手量化策略(六) tablib计算指标
量化新人用QMT+chat GPT快速上手量化策略(七) 下单代码编写
欢迎观看并提出疑问。
公众号:可转债量化分析 查看全部
视频已经整理放到B站:
https://space.bilibili.com/73827743/channel/seriesdetail?sid=3326385&ctype=0
视频目录:
量化新人用QMT+chat GPT快速上手量化策略(一)QMT基础介绍
量化新人用QMT+chat GPT快速上手量化策略(二)QMT均线盘后选股
量化新人用QMT+chat GPT快速上手量化策略(三)一个基本的回测策略代码
量化新人用QMT+chat GPT快速上手量化策略(四) QMT运行一个策略的整体流程
量化新人用QMT+chat GPT快速上手量化策略(五) 获取股票数据
量化新人用QMT+chat GPT快速上手量化策略(六) tablib计算指标
量化新人用QMT+chat GPT快速上手量化策略(七) 下单代码编写
欢迎观看并提出疑问。
公众号:可转债量化分析

QMT获取实时分笔委托数据用哪个函数?
李魔佛 发表了文章 • 0 个评论 • 819 次浏览 • 2023-05-24 15:31
现在官方更加推荐使用第二版,速度要比第一版的要快,也就是推荐使用 .get_market_data_ex。
具体怎么使用呢?
def init(ContextInfo):
ContextInfo.run_time('execution', '3nSecond', '2019-10-14 13:20:00',)
def execution(ContextInfo):
if not ContextInfo.is_last_bar():
return
data = ContextInfo.get_market_data_ex(
[], ['123136.SZ'], period='tick'
, start_time='', end_time='', count=1
, dividend_type='follow', fill_data=True
, subscribe=True)
print(data)
def handlebar(ContextInfo):
#计算当前主图的cci
pass上面代码是每个3秒获取一次 城市转债 的分笔/逐笔数据。
然后在实盘重运行得到下面的结果:
(点击放大)
可以拿到分笔委托的价格,委卖1到5,委托量也可以看到,买和卖的5挡数据。
更多QMT的知识分享: 查看全部
现在官方更加推荐使用第二版,速度要比第一版的要快,也就是推荐使用 .get_market_data_ex。
具体怎么使用呢?
def init(ContextInfo):上面代码是每个3秒获取一次 城市转债 的分笔/逐笔数据。
ContextInfo.run_time('execution', '3nSecond', '2019-10-14 13:20:00',)
def execution(ContextInfo):
if not ContextInfo.is_last_bar():
return
data = ContextInfo.get_market_data_ex(
[], ['123136.SZ'], period='tick'
, start_time='', end_time='', count=1
, dividend_type='follow', fill_data=True
, subscribe=True)
print(data)
def handlebar(ContextInfo):
#计算当前主图的cci
pass
然后在实盘重运行得到下面的结果:
(点击放大)
可以拿到分笔委托的价格,委卖1到5,委托量也可以看到,买和卖的5挡数据。
更多QMT的知识分享:

QMT委托对象orderInfo的属性以及对应的值
李魔佛 发表了文章 • 0 个评论 • 857 次浏览 • 2023-05-18 15:43
官网给出了来的oderInfo里面的字段以及简单的介绍(已经简单得不能再简单了,连对应的是什么类型都不写,懒的一笔)
m_strAccountID: 资金账号,账号,账号,资金账号
m_strExchangeID: 证券市场
m_strExchangeName: 交易市场
m_strProductID: 品种代码
m_strProductName: 品种名称
m_strInstrumentID: 证券代码
m_strInstrumentName: 证券名称,合约名称
m_strOrderRef: 内部委托号,下单引用等于股票的内部委托号
m_nOrderPriceType: EBrokerPriceType 类型,例如市价单、限价单
m_nDirection: EEntrustBS 类型,操作,多空,期货多空,股票买卖永远是 48,其他的 dir 同理
m_nOffsetFlag: EOffset_Flag_Type类型,买卖/开平,用此字段区分股票买卖,期货开、平仓,期权买卖等
m_nHedgeFlag: EHedge_Flag_Type 类型,投保
m_dLimitPrice: 委托价格,限价单的限价,就是报价
m_nVolumeTotalOriginal: 委托量,最初委托量
m_nOrderSubmitStatus: EEntrustSubmitStatus 类型,报单状态,提交状态,股票中不需要报单状态
m_strOrderSysID: 合同编号,委托号
m_nOrderStatus: EEntrustStatus,委托状态
m_nVolumeTraded: 成交数量,已成交量
m_nVolumeTotal: 委托剩余量,当前总委托量,股票的含义是总委托量减去成交量
m_nErrorID: 状态信息
m_strErrorMsg: 状态信息
m_nTaskId:任务号
m_dFrozenMargin: 冻结金额,冻结保证金
m_dFrozenCommission: 冻结手续费
m_strInsertDate: 委托日期,报单日期
m_strInsertTime: 委托时间
m_dTradedPrice: 成交均价(股票)
m_dCancelAmount: 已撤数量
m_strOptName: 买卖标记,展示委托属性的中文
m_dTradeAmount: 成交金额,成交额,期货 = 均价 * 量 * 合约乘数
m_eEntrustType: EEntrustTypes,委托类别
m_strCancelInfo: 废单原因
m_strUnderCode: 标的证券代码
m_eCoveredFlag: ECoveredFlag,备兑标记 '0' - 非备兑,'1' - 备兑
m_dOrderPriceRMB: 委托价格(人民币),目前用于港股通
m_dTradeAmountRMB: 成交金额(人民币),目前用于港股通
m_dReferenceRate: 汇率,目前用于港股通
m_strCompactNo: 合约编号
m_eCashgroupProp: EXTCompactBrushSource类型,头寸来源
m_dShortOccupedMargin: 预估在途占用保证金,用于期权
m_strXTTrade: 是否是迅投交易
m_strAccountKey: 账号key,唯一区别不同账号的key
m_strRemark:投资备注但我们可以直接使用枚举的方法,把上面的属性和对应的值列出来。
attr EBrokerPriceType value <class 'EBrokerPriceType'>
attr ECoveredFlag value <class 'ECoveredFlag'>
attr EEntrustBS value <class 'EEntrustBS'>
attr EEntrustStatus value <class 'EEntrustStatus'>
attr EEntrustSubmitStatus value <class 'EEntrustSubmitStatus'>
attr EEntrustTypes value <class 'EEntrustTypes'>
attr EFutureTradeType value <class 'EFutureTradeType'>
attr EHedge_Flag_Type value <class 'EHedge_Flag_Type'>
attr EOffset_Flag_Type value <class 'EOffset_Flag_Type'>
attr ESideFlag value <class 'ESideFlag'>
attr EXTCompactBrushSource value <class 'EXTCompactBrushSource'>
attr EXTCompactStatus value <class 'EXTCompactStatus'>
attr EXTCompactType value <class 'EXTCompactType'>
attr EXTSloTypeQueryMode value <class 'EXTSloTypeQueryMode'>
attr EXTSubjectsStatus value <class 'EXTSubjectsStatus'>
attr __class__ value <class 'COrderDetail'>
attr __delattr__ value <method-wrapper '__delattr__' of COrderDetail object at 0x000000004AD59A60>
attr __dict__ value {}
attr __dir__ value <built-in method __dir__ of COrderDetail object at 0x000000004AD59A60>
attr __doc__ value None
attr __eq__ value <method-wrapper '__eq__' of COrderDetail object at 0x000000004AD59A60>
attr __format__ value <built-in method __format__ of COrderDetail object at 0x000000004AD59A60>
attr __ge__ value <method-wrapper '__ge__' of COrderDetail object at 0x000000004AD59A60>
attr __getattribute__ value <method-wrapper '__getattribute__' of COrderDetail object at 0x000000004AD59A60>
attr __gt__ value <method-wrapper '__gt__' of COrderDetail object at 0x000000004AD59A60>
attr __hash__ value <method-wrapper '__hash__' of COrderDetail object at 0x000000004AD59A60>
attr __init__ value <bound method __init__ of <COrderDetail object at 0x000000004AD59A60>>
attr __init_subclass__ value <built-in method __init_subclass__ of Boost.Python.class object at 0x0000000044C55368>
attr __instance_size__ value 1088
attr __le__ value <method-wrapper '__le__' of COrderDetail object at 0x000000004AD59A60>
attr __lt__ value <method-wrapper '__lt__' of COrderDetail object at 0x000000004AD59A60>
attr __ne__ value <method-wrapper '__ne__' of COrderDetail object at 0x000000004AD59A60>
attr __new__ value <built-in method __new__ of Boost.Python.class object at 0x000007FEDCF525C0>
attr __reduce__ value <bound method <unnamed Boost.Python function> of <COrderDetail object at 0x000000004AD59A60>>
attr __reduce_ex__ value <built-in method __reduce_ex__ of COrderDetail object at 0x000000004AD59A60>
attr __repr__ value <method-wrapper '__repr__' of COrderDetail object at 0x000000004AD59A60>
attr __setattr__ value <method-wrapper '__setattr__' of COrderDetail object at 0x000000004AD59A60>
attr __sizeof__ value <built-in method __sizeof__ of COrderDetail object at 0x000000004AD59A60>
attr __str__ value <method-wrapper '__str__' of COrderDetail object at 0x000000004AD59A60>
attr __subclasshook__ value <built-in method __subclasshook__ of Boost.Python.class object at 0x0000000044C55368>
attr __weakref__ value None
attr j value j
attr m_bEnable value True
attr m_dCancelAmount value 0.0
attr m_dFrozenCommission value 0.15
attr m_dFrozenMargin value 1000.0
attr m_dLimitPrice value 2.3
具体的获取方式,可以到个人的知识星球获取。
星球也会不定时更新一些QMT常见的坑和问题,也可以提问:
这里简单介绍一下几个常用的字段:
attr m_nOrderStatus value 50
委托状态: 50代表已报, 注意,这里有个坑, 委托状态会返回2次,一次是先显示49,下一次是显示50,状态从待报-变成已报。
查看全部
官网给出了来的oderInfo里面的字段以及简单的介绍(已经简单得不能再简单了,连对应的是什么类型都不写,懒的一笔)
m_strAccountID: 资金账号,账号,账号,资金账号但我们可以直接使用枚举的方法,把上面的属性和对应的值列出来。
m_strExchangeID: 证券市场
m_strExchangeName: 交易市场
m_strProductID: 品种代码
m_strProductName: 品种名称
m_strInstrumentID: 证券代码
m_strInstrumentName: 证券名称,合约名称
m_strOrderRef: 内部委托号,下单引用等于股票的内部委托号
m_nOrderPriceType: EBrokerPriceType 类型,例如市价单、限价单
m_nDirection: EEntrustBS 类型,操作,多空,期货多空,股票买卖永远是 48,其他的 dir 同理
m_nOffsetFlag: EOffset_Flag_Type类型,买卖/开平,用此字段区分股票买卖,期货开、平仓,期权买卖等
m_nHedgeFlag: EHedge_Flag_Type 类型,投保
m_dLimitPrice: 委托价格,限价单的限价,就是报价
m_nVolumeTotalOriginal: 委托量,最初委托量
m_nOrderSubmitStatus: EEntrustSubmitStatus 类型,报单状态,提交状态,股票中不需要报单状态
m_strOrderSysID: 合同编号,委托号
m_nOrderStatus: EEntrustStatus,委托状态
m_nVolumeTraded: 成交数量,已成交量
m_nVolumeTotal: 委托剩余量,当前总委托量,股票的含义是总委托量减去成交量
m_nErrorID: 状态信息
m_strErrorMsg: 状态信息
m_nTaskId:任务号
m_dFrozenMargin: 冻结金额,冻结保证金
m_dFrozenCommission: 冻结手续费
m_strInsertDate: 委托日期,报单日期
m_strInsertTime: 委托时间
m_dTradedPrice: 成交均价(股票)
m_dCancelAmount: 已撤数量
m_strOptName: 买卖标记,展示委托属性的中文
m_dTradeAmount: 成交金额,成交额,期货 = 均价 * 量 * 合约乘数
m_eEntrustType: EEntrustTypes,委托类别
m_strCancelInfo: 废单原因
m_strUnderCode: 标的证券代码
m_eCoveredFlag: ECoveredFlag,备兑标记 '0' - 非备兑,'1' - 备兑
m_dOrderPriceRMB: 委托价格(人民币),目前用于港股通
m_dTradeAmountRMB: 成交金额(人民币),目前用于港股通
m_dReferenceRate: 汇率,目前用于港股通
m_strCompactNo: 合约编号
m_eCashgroupProp: EXTCompactBrushSource类型,头寸来源
m_dShortOccupedMargin: 预估在途占用保证金,用于期权
m_strXTTrade: 是否是迅投交易
m_strAccountKey: 账号key,唯一区别不同账号的key
m_strRemark:投资备注
attr EBrokerPriceType value <class 'EBrokerPriceType'>
attr ECoveredFlag value <class 'ECoveredFlag'>
attr EEntrustBS value <class 'EEntrustBS'>
attr EEntrustStatus value <class 'EEntrustStatus'>
attr EEntrustSubmitStatus value <class 'EEntrustSubmitStatus'>
attr EEntrustTypes value <class 'EEntrustTypes'>
attr EFutureTradeType value <class 'EFutureTradeType'>
attr EHedge_Flag_Type value <class 'EHedge_Flag_Type'>
attr EOffset_Flag_Type value <class 'EOffset_Flag_Type'>
attr ESideFlag value <class 'ESideFlag'>
attr EXTCompactBrushSource value <class 'EXTCompactBrushSource'>
attr EXTCompactStatus value <class 'EXTCompactStatus'>
attr EXTCompactType value <class 'EXTCompactType'>
attr EXTSloTypeQueryMode value <class 'EXTSloTypeQueryMode'>
attr EXTSubjectsStatus value <class 'EXTSubjectsStatus'>
attr __class__ value <class 'COrderDetail'>
attr __delattr__ value <method-wrapper '__delattr__' of COrderDetail object at 0x000000004AD59A60>
attr __dict__ value {}
attr __dir__ value <built-in method __dir__ of COrderDetail object at 0x000000004AD59A60>
attr __doc__ value None
attr __eq__ value <method-wrapper '__eq__' of COrderDetail object at 0x000000004AD59A60>
attr __format__ value <built-in method __format__ of COrderDetail object at 0x000000004AD59A60>
attr __ge__ value <method-wrapper '__ge__' of COrderDetail object at 0x000000004AD59A60>
attr __getattribute__ value <method-wrapper '__getattribute__' of COrderDetail object at 0x000000004AD59A60>
attr __gt__ value <method-wrapper '__gt__' of COrderDetail object at 0x000000004AD59A60>
attr __hash__ value <method-wrapper '__hash__' of COrderDetail object at 0x000000004AD59A60>
attr __init__ value <bound method __init__ of <COrderDetail object at 0x000000004AD59A60>>
attr __init_subclass__ value <built-in method __init_subclass__ of Boost.Python.class object at 0x0000000044C55368>
attr __instance_size__ value 1088
attr __le__ value <method-wrapper '__le__' of COrderDetail object at 0x000000004AD59A60>
attr __lt__ value <method-wrapper '__lt__' of COrderDetail object at 0x000000004AD59A60>
attr __ne__ value <method-wrapper '__ne__' of COrderDetail object at 0x000000004AD59A60>
attr __new__ value <built-in method __new__ of Boost.Python.class object at 0x000007FEDCF525C0>
attr __reduce__ value <bound method <unnamed Boost.Python function> of <COrderDetail object at 0x000000004AD59A60>>
attr __reduce_ex__ value <built-in method __reduce_ex__ of COrderDetail object at 0x000000004AD59A60>
attr __repr__ value <method-wrapper '__repr__' of COrderDetail object at 0x000000004AD59A60>
attr __setattr__ value <method-wrapper '__setattr__' of COrderDetail object at 0x000000004AD59A60>
attr __sizeof__ value <built-in method __sizeof__ of COrderDetail object at 0x000000004AD59A60>
attr __str__ value <method-wrapper '__str__' of COrderDetail object at 0x000000004AD59A60>
attr __subclasshook__ value <built-in method __subclasshook__ of Boost.Python.class object at 0x0000000044C55368>
attr __weakref__ value None
attr j value j
attr m_bEnable value True
attr m_dCancelAmount value 0.0
attr m_dFrozenCommission value 0.15
attr m_dFrozenMargin value 1000.0
attr m_dLimitPrice value 2.3
具体的获取方式,可以到个人的知识星球获取。
星球也会不定时更新一些QMT常见的坑和问题,也可以提问:
这里简单介绍一下几个常用的字段:
attr m_nOrderStatus value 50
委托状态: 50代表已报, 注意,这里有个坑, 委托状态会返回2次,一次是先显示49,下一次是显示50,状态从待报-变成已报。
QMT运行后的历史日志保存在哪个位置?
李魔佛 发表了文章 • 0 个评论 • 771 次浏览 • 2023-05-11 14:10
PS: 知乎上这位是抄袭我的:
https://zhuanlan.zhihu.com/p/650119640
我这里有很多QMT的文章,都是没有原创没有加水印的
如果想要找回以前的历史日志,可以到下面的路径寻找;
以国信证券的iquant为例:
C:\iquant_gx\userdata\log
具体以你的券商路径安装名字为准
个人的日志输出在文件名:
XtClient_FormulaOutput_20230426 (后面的是日期,具体根据你要查找的时间来找)
看到没?
上面的日志就是记录当时的策略输出。
国信证券iQuant, 万一免五 开户,无门槛开通,
需要的可以联系:
可开通miniqmt 查看全部
PS: 知乎上这位是抄袭我的:
https://zhuanlan.zhihu.com/p/650119640
我这里有很多QMT的文章,都是没有原创没有加水印的
如果想要找回以前的历史日志,可以到下面的路径寻找;
以国信证券的iquant为例:
C:\iquant_gx\userdata\log
具体以你的券商路径安装名字为准
个人的日志输出在文件名:
XtClient_FormulaOutput_20230426 (后面的是日期,具体根据你要查找的时间来找)
看到没?
上面的日志就是记录当时的策略输出。
国信证券iQuant, 万一免五 开户,无门槛开通,
需要的可以联系:
可开通miniqmt

迅投QMT修改编辑器字体大小,4个空格缩进(默认是TAB),背景颜色
李魔佛 发表了文章 • 0 个评论 • 852 次浏览 • 2023-04-25 12:22
而且在菜单里面也找不到设置的地方。
其实用户是可以修改这个编辑器的配置的。
找到QMT的安装目录,找到config文件夹,里面有个editor.xml 的文件,用记事本或者notepad++等文本编辑器打开。
如果要修改字体大小,可以修改:
<font FamilyName="Courier New" IsBold="false" size="16"/>
把size设置大一点,字体即可变大。
如果要把tab缩进改为空格缩进(主流IDE,pycharm vscode都是4个空格缩进的),可以改成下面的
<font FamilyName="Courier New" IsBold="false" size="20"/>
<align TabStop="4" AutoIndent="true" IndentationsUseTabs="false" WrapWord="false"/>
如果需要修改背景色:
同理:
<color bgcolor="255,255,255"/>
修改这一行,
比如变成黑色背景
<color bgcolor="0,0,0"/>
PS: 上述配置部分券商可以在QMT的IDE上设置,比如字体大小等,而在这个xml里面修改却生效不了
改为后记得重启QMT生效
公众号后台回复:
qmt配置文件
可以获取修改为tab缩进的配置文件
查看全部
而且在菜单里面也找不到设置的地方。
其实用户是可以修改这个编辑器的配置的。
找到QMT的安装目录,找到config文件夹,里面有个editor.xml 的文件,用记事本或者notepad++等文本编辑器打开。
如果要修改字体大小,可以修改:
<font FamilyName="Courier New" IsBold="false" size="16"/>
把size设置大一点,字体即可变大。
如果要把tab缩进改为空格缩进(主流IDE,pycharm vscode都是4个空格缩进的),可以改成下面的
<font FamilyName="Courier New" IsBold="false" size="20"/>
<align TabStop="4" AutoIndent="true" IndentationsUseTabs="false" WrapWord="false"/>
如果需要修改背景色:
同理:
<color bgcolor="255,255,255"/>
修改这一行,
比如变成黑色背景
<color bgcolor="0,0,0"/>
PS: 上述配置部分券商可以在QMT的IDE上设置,比如字体大小等,而在这个xml里面修改却生效不了
改为后记得重启QMT生效
公众号后台回复:
qmt配置文件
可以获取修改为tab缩进的配置文件

QMT vs Ptrade 速度对比 (二)实时行情速度对比
李魔佛 发表了文章 • 0 个评论 • 959 次浏览 • 2023-04-23 00:33
本文以获取市场所有可转债的实时行情为例子,比较二者的速度。
Ptrade获取所有可转债实时行情
目前市场上有480多只可转债,由于Ptrade内置的数据源不足以支撑可转债的大部分策略,所以需要调用外部数据源,因此使用国盛证券的Ptrade进行交易,因为目前只有它可以链接外网,你可以把可转债的数据写入到数据库或者写成自己的接口,传递给Ptrade就可以了。
比如下面的基础数据接口。
【目前星球用户可以提供数据接口免费调用功能,提供实时数据功能,强赎倒数多个API接口】
然后调用端使用python的requests库请求下就有了。下面代码可以在Ptrade里面部署运行,用于获取可转债溢价率,剩余规模等数据。
然后在Ptrade的定时执行函数里面获取实时tick数据,使用get_snapshot,把所有的转债代码传入get_snapshot就可以拿到可转债的行情数据了,行情数据3秒更新一次。
在Ptrade里面的运行情况
红框的地方是几个时间点要关注的。
481:获取的转债个数有481
红色数字1的位置: time used
获取行情数据所用的时间,大概在17毫秒(ms)左右,数据一直比较稳定。返回的数据里面字段除了价格,还有昨收价,委买卖1队列,涨停价,成交量等多个数据,参考上图里面的那个字典格式的数据。 具体可以参考接口文档(http://ptradeapi.com)
红色数字2的位置:日志输出时候的时间,也就是程序当前所在时刻,在目前程序在14:42:51,红色数字3的时间,是当前价格的里面的时间,也就tick对应的时间,当前的tick时间是hsTimeStamp: 20230419144251000, 也就是 2023-04-19 14:42:51:000, 所以当前时间程序获取的tick时间是一致的。为什么这里要强调这个呢? 假如当前程序时刻是14:42:51, 而获取的tick timestamp数据是14:42:48,那么说明当前程序拿到的最新tick数据却是在48秒时的数据,也就是数据延时了3秒。所以Ptrade里面的tick数据并没有出现延时滞后。
QMT 实时行情
同样QMT提供的可转债基础也是少的可怜,几乎为零。所以同样调用个人部署的可转债接口数据,如法炮制。PS:通过数据解耦的方式,不同数据可以在不同的量化软件里面使用,省去很多重复编写的代码,即使后面接入掘金,聚宽等平台,你只需要编写下单接口逻辑即可。
QMT取实时行情代码如下:
Bond是一个类,和ptrade里面的一样的,用来获取转债基础数据。
同样在QMT的实盘模式下执行:
网络环境:500M宽带网络,PC:CPU I7 - 内存24GB
stock num : 481 同样获取的是481个转债实时行情数据
红色数字1时间:日志输出的当前时间,获取行情数据前的时间14:43:25
红色数字2时间:日志输出的当前时间,此时为已经获取行情数据后的时间:14:43:34
红色数字3:第一次获取行情数据时间差,达到了9.5秒! 这个数字简直惊呆了。 反复测试几次后,依然如此,使用get_market_data获取实时行情数据,第一次数据到达的时候都要挺久的。
新人刚使用这个函数获取实时行情的时候,往往会以为自己代码出bug,等待很久没数据出来,尤其是获取超过1000个股票代码的行情的时候,等待时候更久,等待时间随着输入的个数增加而增加; 同时QMT占用内存也会稳步增加,如果机子的内存太小,可能还会卡死了。(qmt里面的坑还挺多的)
红色数字6,第二次获取实时行情所用的时间,这一次就快很多了,只用了800毫秒。
随着后续运行,获取实时行情的时间就趋于稳定,从800毫秒慢慢降到150毫秒,最后到13-20毫秒,基本和ptrade差不多级别了。
实时行情延时方面,对比通达信
取110048.SH 这个转债的行情数据作为参考,因为QMT返回字段里面没有带tick的时间戳,所以拿通达信作的分时数据作为的对比,没有用L2,所以框住的位置时间约在14:47:03 ~ 14:47:06
图片上半部分通达信的分时数据,左下角的数据时间是14:47:06,所以数据并没有出现很大的延时。
总结
QMT稳定运行的时候,实时行情基本和Ptrade同一级别水平。但QMT的行情波动性大一些。而在初始启动获取数据时,QMT会非常耗费资源,且等待时间较长,而Ptrade则不存在这种问题。
QMT可以随意获取外部数据,所以对券商没有很高要求;而Ptrade目前只有一家券商(国盛证券)可以自由访问外部数据,如果缺少需要的数据或者指标,将无法实现相应的策略。
参考API接口文档:
Ptrade: http://ptradeapi.com/
QMT: http://qmt.ptradeapi.com/
公众号: 查看全部
上一篇文章(QMT vs Ptrade 速度对比 (一) 历史行情获取速度)对了了QMT和Ptrade的获取历史行情速度,本篇文章继续对它俩的实时行情速度。
本文以获取市场所有可转债的实时行情为例子,比较二者的速度。
Ptrade获取所有可转债实时行情
目前市场上有480多只可转债,由于Ptrade内置的数据源不足以支撑可转债的大部分策略,所以需要调用外部数据源,因此使用国盛证券的Ptrade进行交易,因为目前只有它可以链接外网,你可以把可转债的数据写入到数据库或者写成自己的接口,传递给Ptrade就可以了。
比如下面的基础数据接口。

【目前星球用户可以提供数据接口免费调用功能,提供实时数据功能,强赎倒数多个API接口】
然后调用端使用python的requests库请求下就有了。下面代码可以在Ptrade里面部署运行,用于获取可转债溢价率,剩余规模等数据。

然后在Ptrade的定时执行函数里面获取实时tick数据,使用get_snapshot,把所有的转债代码传入get_snapshot就可以拿到可转债的行情数据了,行情数据3秒更新一次。

在Ptrade里面的运行情况

红框的地方是几个时间点要关注的。
481:获取的转债个数有481
红色数字1的位置: time used
获取行情数据所用的时间,大概在17毫秒(ms)左右,数据一直比较稳定。返回的数据里面字段除了价格,还有昨收价,委买卖1队列,涨停价,成交量等多个数据,参考上图里面的那个字典格式的数据。 具体可以参考接口文档(http://ptradeapi.com)
红色数字2的位置:日志输出时候的时间,也就是程序当前所在时刻,在目前程序在14:42:51,红色数字3的时间,是当前价格的里面的时间,也就tick对应的时间,当前的tick时间是hsTimeStamp: 20230419144251000, 也就是 2023-04-19 14:42:51:000, 所以当前时间程序获取的tick时间是一致的。为什么这里要强调这个呢? 假如当前程序时刻是14:42:51, 而获取的tick timestamp数据是14:42:48,那么说明当前程序拿到的最新tick数据却是在48秒时的数据,也就是数据延时了3秒。所以Ptrade里面的tick数据并没有出现延时滞后。
QMT 实时行情
同样QMT提供的可转债基础也是少的可怜,几乎为零。所以同样调用个人部署的可转债接口数据,如法炮制。PS:通过数据解耦的方式,不同数据可以在不同的量化软件里面使用,省去很多重复编写的代码,即使后面接入掘金,聚宽等平台,你只需要编写下单接口逻辑即可。
QMT取实时行情代码如下:
Bond是一个类,和ptrade里面的一样的,用来获取转债基础数据。
同样在QMT的实盘模式下执行:

网络环境:500M宽带网络,PC:CPU I7 - 内存24GB
stock num : 481 同样获取的是481个转债实时行情数据
红色数字1时间:日志输出的当前时间,获取行情数据前的时间14:43:25
红色数字2时间:日志输出的当前时间,此时为已经获取行情数据后的时间:14:43:34
红色数字3:第一次获取行情数据时间差,达到了9.5秒! 这个数字简直惊呆了。 反复测试几次后,依然如此,使用get_market_data获取实时行情数据,第一次数据到达的时候都要挺久的。
新人刚使用这个函数获取实时行情的时候,往往会以为自己代码出bug,等待很久没数据出来,尤其是获取超过1000个股票代码的行情的时候,等待时候更久,等待时间随着输入的个数增加而增加; 同时QMT占用内存也会稳步增加,如果机子的内存太小,可能还会卡死了。(qmt里面的坑还挺多的)


红色数字6,第二次获取实时行情所用的时间,这一次就快很多了,只用了800毫秒。
随着后续运行,获取实时行情的时间就趋于稳定,从800毫秒慢慢降到150毫秒,最后到13-20毫秒,基本和ptrade差不多级别了。


实时行情延时方面,对比通达信
取110048.SH 这个转债的行情数据作为参考,因为QMT返回字段里面没有带tick的时间戳,所以拿通达信作的分时数据作为的对比,没有用L2,所以框住的位置时间约在14:47:03 ~ 14:47:06
图片上半部分通达信的分时数据,左下角的数据时间是14:47:06,所以数据并没有出现很大的延时。
总结
QMT稳定运行的时候,实时行情基本和Ptrade同一级别水平。但QMT的行情波动性大一些。而在初始启动获取数据时,QMT会非常耗费资源,且等待时间较长,而Ptrade则不存在这种问题。
QMT可以随意获取外部数据,所以对券商没有很高要求;而Ptrade目前只有一家券商(国盛证券)可以自由访问外部数据,如果缺少需要的数据或者指标,将无法实现相应的策略。
参考API接口文档:
Ptrade: http://ptradeapi.com/
QMT: http://qmt.ptradeapi.com/
公众号:

QMT vs Ptrade 速度对比 (一) 历史行情获取速度
李魔佛 发表了文章 • 0 个评论 • 1355 次浏览 • 2023-04-11 16:45
Ptrade(恒生电子)则是在券商部署的服务器上执行,你下载的Ptrade在你的本地电脑,只是负责写代码,把代码部署到券商服务器,然后在券商服务其执行你的策略,当然你的代码在券商服务器运行时是被加密的。行情获取,计算指标,下单委托都在券商机房内部执行,属于云策略的类型,策略部署好了,就不需要开着本地电脑观察它的状态。
对比环境均为同一个券商下的QMT和Ptrade,均为生产环境的实盘版本。(PS:温馨提示,平时少用模拟版本,bug多,交易不准,还浪费时间。我平时调试都直接在实盘上调试的,要对自己的策略有信心哈,至少回测过了的嘛O(∩_∩)O~~)
历史行情数据获取
目标:获取2022年到昨天的沪深300所有股票的日线收盘价数据。
QMT
获取行情数据 使用这个函数:ContextInfo.get_market_data()用法: ContextInfo.get_market_data(fields, stock_code = , start_time = '',
end_time = '', skip_paused = True, period = 'follow',
dividend_type = 'follow', count = -1)
open -- 开盘价(str:numpy.float64);
high -- 最高价(str:numpy.float64);
low --最低价(str:numpy.float64);
close -- 收盘价(str:numpy.float64);
volume -- 交易量(str:numpy.float64);
money -- 交易金额(str:numpy.float64);
price -- 最新价(str:numpy.float64);
preclose -- 昨收盘价(str:numpy.float64)(仅日线返回);
high_limit -- 涨停价(str:numpy.float64)(仅日线返回);
low_limit -- 跌停价(str:numpy.float64)(仅日线返回);
unlimited -- 判断查询日是否无涨跌停限制(1:该日无涨跌停限制;0:该日有涨跌停限制)(str:numpy.float64)(仅日线返回);
在fields里面指定只获取close价格即可。
QMT测试代码如下:(需要的也可以后台留言回复获取)
[vscode里面的代码,需要复制到qmt里面执行]
把代码复制到QMT里面,然后切换到模型交易,在中间切换到实盘模式,就会运行上面代码。
注意,这里需要第一次运行上面的代码来计算时间,因为QMT会有个cache缓存机制,它会把曾经跑过的历史数据自动下载下来,保存到你的电脑硬盘里,从而加快QMT后续的读取速度,同样的数据没有必要每次再去网络上拉。
大部分情况下网络IO都会是任何一个量化交易系通最大的性能瓶颈。
运行得到下面的结果:
上面运行时间是22秒。不要惊讶哦,首次获取历史行情数据都是挺慢的。如果你的电脑网速够快,或者但在阿里云,腾讯云之类的云服务上跑,获取历史行情速度会有所提高。
在你运行了上面的代码之后,QMT会在某个时刻,在后台把数据下载到本地QMT安装目录下。
文件按照股票代码作为文件名存储。当然里面不是txt格式,而是QMT做了相应的封装的。上面按照修改日期排序,4月11日多了很多新的DAT数据文件,显然是刚刚生成的。
QMT在获取历史行情数据后,会有个触发器,在后台一次性保存大量的文件,所以QMT会在某一个瞬间,界面会出现卡顿,甚至无响应,而看任务管理器会看到内存飙升甚至爆满100%,有些新人菜鸟就认为QMT太占内存,太垃圾的结论,这也是片面的。实际上在数据完备的情况下,QMT需要的内存4GB就够的了。如果你经常会有扫描全市场股票代码历史数据的话,内存还是尽量选大一点的。如果无法避免内存突然飙升,可以每次把获取行情的股票代码列表减少,细分多几批获取,用时间换空间。
当然 QMT也提供了一个下载历史数据的一个菜单入口,用于在图形界面下手动下载历史行情,从而加速历史行情读取速度。
等数据下载完成后,
第二次跑上面的同一个代码,运行时间明显快了。
但用时还是要7.9秒,反复测试几次,获取时间依然是在6-8秒之间波动。 因为程序读取历史行情数据的一个个独立的文件,所以这里硬盘的性能因素对获取行情影响还是很大的。
笔者感觉7.9秒这个速度还是很慢的,换了台性能好一点的的windows机子,下载了历史数据后再跑了一次:
但用时依然在6秒左右。
所以个人是不推荐大家在tick策略里面,在盘中去获取历史数据的,这个动作应该在盘前就应该完成,把数据保存到内存列表或者dataframe变量中,盘中用的时候去取就可以了。 当然低频策略就无所谓啦。
Ptrade
操作上ptrade相对而言更加简洁,容易上手。
它的API设计和它对应的API文档更加规范,可读性更好。
直接把代码复制到量化->策略,新建策略,然后在交易里面添加策略,直接启动策略。代码设置定时运行,在启动策略后的一分钟后运行。
同样获取沪深300的日线数据,2022年1月到2023年4月10日。
get_price - 获取历史数据 get_price(security, start_date=None, end_date=None, frequency='1d', fields=None, fq=None, count=None)
运行
上面的结果显示,Ptrade获取同样的历史数据耗时只有700毫秒,0.7秒左右。测试多几次,获取时间基本每次都比较平稳,在0.6-0.8秒之间。(下面打印的306不是沪深300的个数,而是获取到的日期的天数,它返回的结构虽然都是panel,但和QMT的轴有点不同)。
结论
总的来说,获取历史行情数据的速度,Ptrade是秒杀了QMT的,不在一个量级上的。
本来想继续对比实时行情,下单延时对比等等,但开盘时间有限,写了一下时间就不够用了。所以把教程拆分为多个系列,下一篇再对比QMT和PTrade的实时行情数据,下单回调等等啦。
如果想要自己测试文中的数据,可以获取代码,公众号 后台回复: 历史行情数据代码
参考API接口文档:
Ptrade: http://ptradeapi.com/
QMT: http://qmt.ptradeapi.com/
公众号: 查看全部
Ptrade(恒生电子)则是在券商部署的服务器上执行,你下载的Ptrade在你的本地电脑,只是负责写代码,把代码部署到券商服务器,然后在券商服务其执行你的策略,当然你的代码在券商服务器运行时是被加密的。行情获取,计算指标,下单委托都在券商机房内部执行,属于云策略的类型,策略部署好了,就不需要开着本地电脑观察它的状态。
对比环境均为同一个券商下的QMT和Ptrade,均为生产环境的实盘版本。(PS:温馨提示,平时少用模拟版本,bug多,交易不准,还浪费时间。我平时调试都直接在实盘上调试的,要对自己的策略有信心哈,至少回测过了的嘛O(∩_∩)O~~)
历史行情数据获取
目标:获取2022年到昨天的沪深300所有股票的日线收盘价数据。
QMT
获取行情数据 使用这个函数:ContextInfo.get_market_data()
用法: ContextInfo.get_market_data(fields, stock_code = , start_time = '',
end_time = '', skip_paused = True, period = 'follow',
dividend_type = 'follow', count = -1)
open -- 开盘价(str:numpy.float64);
high -- 最高价(str:numpy.float64);
low --最低价(str:numpy.float64);
close -- 收盘价(str:numpy.float64);
volume -- 交易量(str:numpy.float64);
money -- 交易金额(str:numpy.float64);
price -- 最新价(str:numpy.float64);
preclose -- 昨收盘价(str:numpy.float64)(仅日线返回);
high_limit -- 涨停价(str:numpy.float64)(仅日线返回);
low_limit -- 跌停价(str:numpy.float64)(仅日线返回);
unlimited -- 判断查询日是否无涨跌停限制(1:该日无涨跌停限制;0:该日有涨跌停限制)(str:numpy.float64)(仅日线返回);
在fields里面指定只获取close价格即可。
QMT测试代码如下:(需要的也可以后台留言回复获取)
[vscode里面的代码,需要复制到qmt里面执行]
把代码复制到QMT里面,然后切换到模型交易,在中间切换到实盘模式,就会运行上面代码。
注意,这里需要第一次运行上面的代码来计算时间,因为QMT会有个cache缓存机制,它会把曾经跑过的历史数据自动下载下来,保存到你的电脑硬盘里,从而加快QMT后续的读取速度,同样的数据没有必要每次再去网络上拉。
大部分情况下网络IO都会是任何一个量化交易系通最大的性能瓶颈。
运行得到下面的结果:
上面运行时间是22秒。不要惊讶哦,首次获取历史行情数据都是挺慢的。如果你的电脑网速够快,或者但在阿里云,腾讯云之类的云服务上跑,获取历史行情速度会有所提高。
在你运行了上面的代码之后,QMT会在某个时刻,在后台把数据下载到本地QMT安装目录下。
文件按照股票代码作为文件名存储。当然里面不是txt格式,而是QMT做了相应的封装的。上面按照修改日期排序,4月11日多了很多新的DAT数据文件,显然是刚刚生成的。
QMT在获取历史行情数据后,会有个触发器,在后台一次性保存大量的文件,所以QMT会在某一个瞬间,界面会出现卡顿,甚至无响应,而看任务管理器会看到内存飙升甚至爆满100%,有些新人菜鸟就认为QMT太占内存,太垃圾的结论,这也是片面的。实际上在数据完备的情况下,QMT需要的内存4GB就够的了。如果你经常会有扫描全市场股票代码历史数据的话,内存还是尽量选大一点的。如果无法避免内存突然飙升,可以每次把获取行情的股票代码列表减少,细分多几批获取,用时间换空间。
当然 QMT也提供了一个下载历史数据的一个菜单入口,用于在图形界面下手动下载历史行情,从而加速历史行情读取速度。
等数据下载完成后,
第二次跑上面的同一个代码,运行时间明显快了。
但用时还是要7.9秒,反复测试几次,获取时间依然是在6-8秒之间波动。 因为程序读取历史行情数据的一个个独立的文件,所以这里硬盘的性能因素对获取行情影响还是很大的。
笔者感觉7.9秒这个速度还是很慢的,换了台性能好一点的的windows机子,下载了历史数据后再跑了一次:
但用时依然在6秒左右。
所以个人是不推荐大家在tick策略里面,在盘中去获取历史数据的,这个动作应该在盘前就应该完成,把数据保存到内存列表或者dataframe变量中,盘中用的时候去取就可以了。 当然低频策略就无所谓啦。
Ptrade
操作上ptrade相对而言更加简洁,容易上手。
它的API设计和它对应的API文档更加规范,可读性更好。
直接把代码复制到量化->策略,新建策略,然后在交易里面添加策略,直接启动策略。代码设置定时运行,在启动策略后的一分钟后运行。
同样获取沪深300的日线数据,2022年1月到2023年4月10日。
get_price - 获取历史数据 get_price(security, start_date=None, end_date=None, frequency='1d', fields=None, fq=None, count=None)
运行
上面的结果显示,Ptrade获取同样的历史数据耗时只有700毫秒,0.7秒左右。测试多几次,获取时间基本每次都比较平稳,在0.6-0.8秒之间。(下面打印的306不是沪深300的个数,而是获取到的日期的天数,它返回的结构虽然都是panel,但和QMT的轴有点不同)。
结论
总的来说,获取历史行情数据的速度,Ptrade是秒杀了QMT的,不在一个量级上的。
本来想继续对比实时行情,下单延时对比等等,但开盘时间有限,写了一下时间就不够用了。所以把教程拆分为多个系列,下一篇再对比QMT和PTrade的实时行情数据,下单回调等等啦。
如果想要自己测试文中的数据,可以获取代码,公众号 后台回复: 历史行情数据代码
参考API接口文档:
Ptrade: http://ptradeapi.com/
QMT: http://qmt.ptradeapi.com/
公众号:

国信如何运行miniQMT
李魔佛 发表了文章 • 0 个评论 • 1496 次浏览 • 2023-03-30 02:31
不过它需要额外申请。就看你的经理愿不愿意帮你去申请了。
毕竟申请这个没有资金要求,纯粹看经理的心情了。申请需要打印纸质电子版文件并签字,拍照发给营业部审核。
而且开通了miniQMT后,只能拉取数据,无法进行交易,因为个人是没有交易权限的,只有机构才可以申请miniQMT的交易权限。
这也是经理不愿意帮你开通的原因,他们有可能会说国信目前不支持miniQMT这样的胡话来推搪打发你。如果需要申请开通,可以联系文末二维码开通国信iquant和miniQMT,这位经理比较热心肠,只要申请,就可以帮你开通miniQMT权限。
如何打开国信的miniQMT?
国信的miniQMT并不是和iQuant绑定的,笔者怀疑是因为iQuant定制化过多,甚至把miniQMT给阉割了。以至于为了补回miniQMT,他们还得特意要下载一个QMT的客户端(其实这个就是其他券商的QMT客户端),然后使用这个客户端和xtquant通讯。
输入个人的账户和密码后,登录极速版,对,国信的极速版即使miniQMT了。勾选极简模式。 国信的miniQMT支持自动登录,这个比国金的要好。国金的由于没有自动登录,每天还得自己手动的登录一次。(笔者之前也提供了几个版本的自动登录脚本,需要的可以到星球获取)
行情源这里要注意,如果你选择的获取最新价,那么在获取行情数据的返回值里面,只有最新价格,没有5档委托价格。( 国信iquant并没有这个选择菜单,估计是深度定制了,删除了)。
由于没有交易权限,账户里面没有显示个人的持仓信息,直接是空白一片
然后把xtquant的文件夹复制到本地的python site-package目录下。用以下下载数据的代码测试一下:
import pandas as pd
import datetime
def get_tick(code, start_time, end_time, period='tick'):
from xtquant import xtdata
xtdata.download_history_data(code, period=period, start_time=start_time, end_time=end_time)
data = xtdata.get_local_data(field_list=, stock_code=, period=period, count=10)
result_list = data df = pd.DataFrame(result_list)
df['time_str'] = df['time'].apply(lambda x: datetime.datetime.fromtimestamp(x / 1000.0))
return df
def process_timestamp(df, filename):
df = df.set_index('time_str')
result = df.resample('3S').first().ffill()
# result = result[(result.index >= '2022-07-20 09:30') & (result.index <= '2022-07-20 15:00')]
result = result.reset_index()
result.to_csv(filename + '.csv')
def dump_single_code_tick():
# 导出单个转债的tick数据
code='128022'
start_date = '20210113'
end_date = '20210130'
post_fix = 'SZ' if code.startswith('12') else 'SH'
code = '{}.{}'.format(code,post_fix)
filename = '{}'.format(code)
df = get_tick(code, start_date, end_date)
process_timestamp(df, filename)
dump_single_code_tick()保存上述代码为app.py
运行python app.py
稍等片刻,数据导出到当前路径,名字为:
128022.sz
打开看一下,数据在csv里面的了。
可关注下面关注号; 如需要开通国信,可以后台回复:开通国信证券
查看全部
不过它需要额外申请。就看你的经理愿不愿意帮你去申请了。
毕竟申请这个没有资金要求,纯粹看经理的心情了。申请需要打印纸质电子版文件并签字,拍照发给营业部审核。
而且开通了miniQMT后,只能拉取数据,无法进行交易,因为个人是没有交易权限的,只有机构才可以申请miniQMT的交易权限。
这也是经理不愿意帮你开通的原因,他们有可能会说国信目前不支持miniQMT这样的胡话来推搪打发你。如果需要申请开通,可以联系文末二维码开通国信iquant和miniQMT,这位经理比较热心肠,只要申请,就可以帮你开通miniQMT权限。
如何打开国信的miniQMT?
国信的miniQMT并不是和iQuant绑定的,笔者怀疑是因为iQuant定制化过多,甚至把miniQMT给阉割了。以至于为了补回miniQMT,他们还得特意要下载一个QMT的客户端(其实这个就是其他券商的QMT客户端),然后使用这个客户端和xtquant通讯。
输入个人的账户和密码后,登录极速版,对,国信的极速版即使miniQMT了。勾选极简模式。 国信的miniQMT支持自动登录,这个比国金的要好。国金的由于没有自动登录,每天还得自己手动的登录一次。(笔者之前也提供了几个版本的自动登录脚本,需要的可以到星球获取)
行情源这里要注意,如果你选择的获取最新价,那么在获取行情数据的返回值里面,只有最新价格,没有5档委托价格。( 国信iquant并没有这个选择菜单,估计是深度定制了,删除了)。
由于没有交易权限,账户里面没有显示个人的持仓信息,直接是空白一片
然后把xtquant的文件夹复制到本地的python site-package目录下。用以下下载数据的代码测试一下:
import pandas as pd
import datetime
def get_tick(code, start_time, end_time, period='tick'):
from xtquant import xtdata
xtdata.download_history_data(code, period=period, start_time=start_time, end_time=end_time)
data = xtdata.get_local_data(field_list=, stock_code=
, period=period, count=10)
result_list = data
df = pd.DataFrame(result_list)保存上述代码为app.py
df['time_str'] = df['time'].apply(lambda x: datetime.datetime.fromtimestamp(x / 1000.0))
return df
def process_timestamp(df, filename):
df = df.set_index('time_str')
result = df.resample('3S').first().ffill()
# result = result[(result.index >= '2022-07-20 09:30') & (result.index <= '2022-07-20 15:00')]
result = result.reset_index()
result.to_csv(filename + '.csv')
def dump_single_code_tick():
# 导出单个转债的tick数据
code='128022'
start_date = '20210113'
end_date = '20210130'
post_fix = 'SZ' if code.startswith('12') else 'SH'
code = '{}.{}'.format(code,post_fix)
filename = '{}'.format(code)
df = get_tick(code, start_date, end_date)
process_timestamp(df, filename)
dump_single_code_tick()
运行python app.py
稍等片刻,数据导出到当前路径,名字为:
128022.sz
打开看一下,数据在csv里面的了。
可关注下面关注号; 如需要开通国信,可以后台回复:开通国信证券

qmt position对象里面有哪些属性?
李魔佛 发表了文章 • 0 个评论 • 759 次浏览 • 2023-02-27 22:12
obj_list = get_trade_detail_data(ACCOUNT,'stock','position')
for obj in obj_list:
print(obj.m_strInstrumentID,obj.m_strInstrumentName,'----')
# 查看有哪些属性字段
print('='*10)
for item in dir(obj):
if not item.startswith('__'):
print(item)
print('='*10)
得到的position的内置属性有下面的:m_bIsToday
m_dAvgOpenPrice
m_dCloseAmount
m_dCloseProfit
m_dFloatProfit
m_dInstrumentValue
m_dLastPrice
m_dLastSettlementPrice
m_dMargin
m_dMarketValue
m_dOpenCost
m_dOpenPrice
m_dPositionCost
m_dPositionProfit
m_dProfitRate
m_dRealUsedMargin
m_dRedemptionVolume
m_dReferenceRate
m_dRoyalty
m_dSettlementPrice
m_dSingleCost
m_dStaticHoldMargin
m_dStockLastPrice
m_dStructFundVol
m_dTotalCost
m_eFutureTradeType
m_eSideFlag
m_nCanUseVolume
m_nCidIncrease
m_nCidIsDelist
m_nCidRateOfCurrentLine
m_nCidRateOfTotalValue
m_nCloseVolume
m_nCoveredVolume
m_nDirection
m_nEnableExerciseVolume
m_nFrozenVolume
m_nHedgeFlag
m_nLegId
m_nOnRoadVolume
m_nOptCombUsedVolume
m_nPREnableVolume
m_nVolume
m_nYesterdayVolume
m_strAccountID
m_strAccountKey
m_strComTradeID
m_strExchangeID
m_strExchangeName
m_strExpireDate
m_strInstrumentID
m_strInstrumentName
m_strOpenDate
m_strProductID
m_strProductName
m_strStockHolder
m_strTradeID
m_strTradingDay
m_xtTag
虽然有上面的属性,但是实际上很可能是空的,并没有值。
查看全部
obj_list = get_trade_detail_data(ACCOUNT,'stock','position')
for obj in obj_list:
print(obj.m_strInstrumentID,obj.m_strInstrumentName,'----')
# 查看有哪些属性字段
print('='*10)
for item in dir(obj):
if not item.startswith('__'):
print(item)
print('='*10)
得到的position的内置属性有下面的:
m_bIsToday
m_dAvgOpenPrice
m_dCloseAmount
m_dCloseProfit
m_dFloatProfit
m_dInstrumentValue
m_dLastPrice
m_dLastSettlementPrice
m_dMargin
m_dMarketValue
m_dOpenCost
m_dOpenPrice
m_dPositionCost
m_dPositionProfit
m_dProfitRate
m_dRealUsedMargin
m_dRedemptionVolume
m_dReferenceRate
m_dRoyalty
m_dSettlementPrice
m_dSingleCost
m_dStaticHoldMargin
m_dStockLastPrice
m_dStructFundVol
m_dTotalCost
m_eFutureTradeType
m_eSideFlag
m_nCanUseVolume
m_nCidIncrease
m_nCidIsDelist
m_nCidRateOfCurrentLine
m_nCidRateOfTotalValue
m_nCloseVolume
m_nCoveredVolume
m_nDirection
m_nEnableExerciseVolume
m_nFrozenVolume
m_nHedgeFlag
m_nLegId
m_nOnRoadVolume
m_nOptCombUsedVolume
m_nPREnableVolume
m_nVolume
m_nYesterdayVolume
m_strAccountID
m_strAccountKey
m_strComTradeID
m_strExchangeID
m_strExchangeName
m_strExpireDate
m_strInstrumentID
m_strInstrumentName
m_strOpenDate
m_strProductID
m_strProductName
m_strStockHolder
m_strTradeID
m_strTradingDay
m_xtTag
虽然有上面的属性,但是实际上很可能是空的,并没有值。

qmt 可转债 双低(阈值)轮动 实盘代码
李魔佛 发表了文章 • 0 个评论 • 1336 次浏览 • 2023-02-26 15:18
用已有的ptrade的代码,然后部分获取行情和交易接口按照qmt的接口文档(http://qmt.ptradeapi.com )重写,就给了一版。(对,很早以前就有一版ptrade的转债双低的了)
无论是qmt还是ptrade,都只是一个工具,用熟悉了,都无所哪个好哪个不好。
完整代码在个人星球。
觉得之前星球太便宜了,不仅给了代码,还部署了接口免费使用,通过接口获取可转债的实时数据,强赎天数,规模,溢价率,评级等等一系列数据。 而且随着时间的推移,里面积累的数据,代码也越来越多,感觉这样对前面进去并不断续费的星友有点公平,尽管以后他们续费都直接打折扣。所以还是按照一些大v运营的意见,逐年涨价策略。
越往后的朋友,因为前面积累的内容越多,因此价格也随之增长。
当然有能力可以自己写接口,部署,实盘,获取三方数据的大v,就没必要加了。
查看全部
用已有的ptrade的代码,然后部分获取行情和交易接口按照qmt的接口文档(http://qmt.ptradeapi.com )重写,就给了一版。(对,很早以前就有一版ptrade的转债双低的了)
无论是qmt还是ptrade,都只是一个工具,用熟悉了,都无所哪个好哪个不好。
完整代码在个人星球。
觉得之前星球太便宜了,不仅给了代码,还部署了接口免费使用,通过接口获取可转债的实时数据,强赎天数,规模,溢价率,评级等等一系列数据。 而且随着时间的推移,里面积累的数据,代码也越来越多,感觉这样对前面进去并不断续费的星友有点公平,尽管以后他们续费都直接打折扣。所以还是按照一些大v运营的意见,逐年涨价策略。
越往后的朋友,因为前面积累的内容越多,因此价格也随之增长。
当然有能力可以自己写接口,部署,实盘,获取三方数据的大v,就没必要加了。

qmt软件里面的快速计算是在什么模式下使用的?
李魔佛 发表了文章 • 0 个评论 • 768 次浏览 • 2023-02-25 13:35
即点击运行模型时,模型是从第 0 根 K 线开始运行到最后一根 K 线(如想加快模型运行速度,可以策略编辑器 - 基本信息中设置快速计算,限制计算范围,只计算最新的指定数量的 K 线范围),每根 K 线调用一次 Python 模型中的 handlebar(ContextInfo) 函数。
也就是你点击“运行”按钮的时候,如果你的快速计算默认设置的是0,
handlebar里面的k线是从2005年1月1日运行的,即使你在代码里面设置了运行时间:
def init(ContextInfo):
print("==============start==========")
ContextInfo.start = '2023-02-20 10:00:00'
ContextInfo.end = '2023-02-23 10:00:00'或者在回测参数里面设置的时间:
都是不管用的。
需要在代码里添加一句:
if not ContextInfo.is_last_bar():
return
或者 把快速计算的值设置为1, 就只会以最新的k线计算。也就是只会执行1次handlebar。
不得不说,qmt的说明文档很让人困惑的。笔者也多次吐槽了。
如果没有编程的朋友,不建议自己折腾了。不少编程大咖都惊呼这软件和文档入门太难,文档太扯淡。
如果需要qmt策略代码 和实盘代码 代写,可以在公众号后台留言:qmt代写
查看全部
即点击运行模型时,模型是从第 0 根 K 线开始运行到最后一根 K 线(如想加快模型运行速度,可以策略编辑器 - 基本信息中设置快速计算,限制计算范围,只计算最新的指定数量的 K 线范围),每根 K 线调用一次 Python 模型中的 handlebar(ContextInfo) 函数。
也就是你点击“运行”按钮的时候,如果你的快速计算默认设置的是0,
handlebar里面的k线是从2005年1月1日运行的,即使你在代码里面设置了运行时间:
def init(ContextInfo):或者在回测参数里面设置的时间:
print("==============start==========")
ContextInfo.start = '2023-02-20 10:00:00'
ContextInfo.end = '2023-02-23 10:00:00'
都是不管用的。
需要在代码里添加一句:
if not ContextInfo.is_last_bar():
return
或者 把快速计算的值设置为1, 就只会以最新的k线计算。也就是只会执行1次handlebar。
不得不说,qmt的说明文档很让人困惑的。笔者也多次吐槽了。
如果没有编程的朋友,不建议自己折腾了。不少编程大咖都惊呼这软件和文档入门太难,文档太扯淡。
如果需要qmt策略代码 和实盘代码 代写,可以在公众号后台留言:qmt代写

qmt隔夜文件单(python代码实现)实盘代码
李魔佛 发表了文章 • 0 个评论 • 1058 次浏览 • 2023-02-24 14:17
import logging
import pandas as pd
from datetime import datetime, timedelta, time
from decimal import InvalidOperation
from decimal import Decimal as D
from READFILE import read_file
logging.basicConfig(level=logging.INFO)
# 挂单失败后的等待时长,以秒计
TIMEOUT_ON_FAIL_SEC = 30
# 规避 account_callback 的 Racing Condition
RUN_TIME_DELAY = 10
# global FILEPATH, DIR, PRICE, VOL, START_TIME, account
SH_pattern = r'^[1-9]\d{5}\.(sh|SH)$'
SZ_pattern = r'^(?!39)\d{6}\.(sz|SZ)$'
SH_prefix = ['5', '6', '9', '11']
SZ_prefix = ['0', '2', '30', '12', '159']
COLNAMES = ['direction', 'vol', 'price', 'start_time']
def init(ContextInfo):
ContextInfo.accID = account
ContextInfo.set_account(ContextInfo.accID)
ContextInfo.can_order = False
ContextInfo.all_order_done = False
if not load_file_order(ContextInfo):
load_sys_order(ContextInfo)
# load_file_order(ContextInfo)
ContextInfo.run_time("place_order", "{0}nSecond".format(TIMEOUT_ON_FAIL_SEC),
(datetime.now() + timedelta(seconds=RUN_TIME_DELAY)).strftime('%Y-%m-%d %H:%M:%S'), 'SH')
def account_callback(ContextInfo, accountInfo):
if not ContextInfo.can_order:
ContextInfo.can_order = True
def handlebar(ContextInfo):
return
def load_file_order(ContextInfo):
def _price_vol_filtering(row):
if not isinstance(row.start_time, time):
logging.warning('读取{0}指令时间失败: {1}'.format(row.name, row.start_time))
return None
if row.direction not in ['买', '卖']:
logging.warning('读取{0}买卖方向失败: {1}'.format(row.name, row.direction))
return None
try:
# parse start_time
curr_start_time = datetime.now().strftime('%Y-%m-%d ') + row.start_time.strftime('%H:%M:%S')
curr_start_time = datetime.strptime(curr_start_time, '%Y-%m-%d %H:%M:%S')
# parse direction
curr_direction = 23 if row.direction == '买' else 24
# parse price and vol
price = D(row.price)
vol = int(row.vol)
return pd.Series([curr_direction, vol, price, curr_start_time])
except InvalidOperation:
logging.warning("读取 {0} 指令价格失败: {1}".format(row.name, row.price))
return None
except ValueError:
logging.warning('读取 {0} 下单总量失败: {1}'.format(row.name, row.vol))
return None
def _name_parser(asset_name):
# 目前默认用户输入.SH 或.SZ时标的名称正确
if '.SH' in asset_name or '.SZ' in asset_name:
# todo: SH/SZ_pattern regex check here?
return asset_name
else:
raise ValueError('{0} 标的代码不合法'.format(asset_name))
try:
tmp_df = read_file(FILEPATH, names=COLNAMES, index_col=0)
except:
logging.warning('读取挂单配置文件失败或挂单配置文件为空,尝试交易读取配置面板参数')
return None
if tmp_df.empty:
logging.warning('读取挂单配置文件失败或挂单配置文件为空,尝试交易读取配置面板参数')
return None
tmp_df.index = tmp_df.index.to_series().astype(str)
tmp_df.index = tmp_df.index.str.strip()
tmp_df.index = tmp_df.index.str.upper()
tmp_df.index = tmp_df.index.to_series().apply(_name_parser).dropna()
tmp_df = tmp_df.apply(_price_vol_filtering, axis=1, broadcast=True).dropna()
if tmp_df.empty:
logging.warning('读取挂单配置文件失败或挂单配置文件为空,尝试交易读取配置面板参数')
return False
tmp_df.set_axis(COLNAMES, axis='columns', inplace=True)
# 挂单成功Flag
tmp_df['finished'] = [False] * tmp_df.shape[0]
ContextInfo.order_df = tmp_df
ContextInfo.set_universe(ContextInfo.order_df.index.tolist())
return True
def load_sys_order(ContextInfo):
try:
asset_name = ContextInfo.stockcode + '.' + ContextInfo.market
ContextInfo.set_universe([asset_name])
direction = 23 if DIR == '买入' else 24
start_time = datetime.strptime(datetime.now().strftime('%Y%m%d') + str(START_TIME), '%Y%m%d%H%M%S')
price = D(PRICE)
vol = int(VOL)
except BaseException:
raise ValueError("读取策略面板交易配置失败。请尝试修正挂单配置文件或者策略面板参数。")
price = float(price)
ContextInfo.order_df = pd.DataFrame(data=[direction, vol, price, start_time], index=COLNAMES,
columns=[asset_name]).T
ContextInfo.order_df['finished'] = False
return
def place_order(ContextInfo):
if not ContextInfo.can_order or ContextInfo.all_order_done:
return
for curr_asset in ContextInfo.get_universe():
if not ContextInfo.order_df.loc[curr_asset].finished \
and datetime.now() > ContextInfo.order_df.loc[curr_asset].start_time:
curr_order = ContextInfo.order_df.loc[curr_asset]
direction = int(curr_order.direction)
txt_direction = '买入' if direction == 23 else '卖出'
price = float(D(curr_order.price))
vol = int(curr_order.vol)
order_remark = '隔日文件挂单: 以 {0} {1} {2}'.format(price, txt_direction, curr_asset)
passorder(direction, 1101, ContextInfo.accID, curr_asset, 11, price, vol, order_remark, 1, order_remark,
ContextInfo)
ContextInfo.order_df.loc[curr_asset, 'finished'] = True
ContextInfo.all_order_done = all(ContextInfo.order_df['finished'].tolist())
def order_callback(ContextInfo, orderInfo):
curr_asset = orderInfo.m_strInstrumentID + '.' + orderInfo.m_strExchangeID
curr_remark = orderInfo.m_strRemark
curr_status = orderInfo.m_nOrderStatus
if '隔日文件挂单' in curr_remark and curr_status == 57:
ContextInfo.order_df.loc[curr_asset, 'finished'] = False
ContextInfo.all_order_done = False
logging.error('{0} 隔日文件挂单:报单废单 (柜台返回失败),原因:{1} 尝试重报'.format(curr_asset, orderInfo.m_strCancelInfo))
elif '隔日文件挂单' in curr_remark and curr_status == 50:
logging.info('{0} 隔日文件挂单:报单成功'.format(curr_asset))
return
def orderError_callback(ContextInfo, orderArgs, errMsg):
curr_asset = orderArgs.orderCode
if '隔日文件挂单' in orderArgs.strategyName:
ContextInfo.order_df.loc[curr_asset, 'finished'] = False
ContextInfo.all_order_done = False
logging.error('{0} 隔日文件挂单:账号下单异常 (COS/iQuant校验失败), 错误消息:{1} 尝试重报'.format(curr_asset, errMsg))
return
把上述代码复制到iquant里面,然后部署到策略运行,运行策略,切换为实盘 查看全部
代码基于iquant平台编写。可以拿去参考参考。
# encoding:gbk
import logging
import pandas as pd
from datetime import datetime, timedelta, time
from decimal import InvalidOperation
from decimal import Decimal as D
from READFILE import read_file
logging.basicConfig(level=logging.INFO)
# 挂单失败后的等待时长,以秒计
TIMEOUT_ON_FAIL_SEC = 30
# 规避 account_callback 的 Racing Condition
RUN_TIME_DELAY = 10
# global FILEPATH, DIR, PRICE, VOL, START_TIME, account
SH_pattern = r'^[1-9]\d{5}\.(sh|SH)$'
SZ_pattern = r'^(?!39)\d{6}\.(sz|SZ)$'
SH_prefix = ['5', '6', '9', '11']
SZ_prefix = ['0', '2', '30', '12', '159']
COLNAMES = ['direction', 'vol', 'price', 'start_time']
def init(ContextInfo):
ContextInfo.accID = account
ContextInfo.set_account(ContextInfo.accID)
ContextInfo.can_order = False
ContextInfo.all_order_done = False
if not load_file_order(ContextInfo):
load_sys_order(ContextInfo)
# load_file_order(ContextInfo)
ContextInfo.run_time("place_order", "{0}nSecond".format(TIMEOUT_ON_FAIL_SEC),
(datetime.now() + timedelta(seconds=RUN_TIME_DELAY)).strftime('%Y-%m-%d %H:%M:%S'), 'SH')
def account_callback(ContextInfo, accountInfo):
if not ContextInfo.can_order:
ContextInfo.can_order = True
def handlebar(ContextInfo):
return
def load_file_order(ContextInfo):
def _price_vol_filtering(row):
if not isinstance(row.start_time, time):
logging.warning('读取{0}指令时间失败: {1}'.format(row.name, row.start_time))
return None
if row.direction not in ['买', '卖']:
logging.warning('读取{0}买卖方向失败: {1}'.format(row.name, row.direction))
return None
try:
# parse start_time
curr_start_time = datetime.now().strftime('%Y-%m-%d ') + row.start_time.strftime('%H:%M:%S')
curr_start_time = datetime.strptime(curr_start_time, '%Y-%m-%d %H:%M:%S')
# parse direction
curr_direction = 23 if row.direction == '买' else 24
# parse price and vol
price = D(row.price)
vol = int(row.vol)
return pd.Series([curr_direction, vol, price, curr_start_time])
except InvalidOperation:
logging.warning("读取 {0} 指令价格失败: {1}".format(row.name, row.price))
return None
except ValueError:
logging.warning('读取 {0} 下单总量失败: {1}'.format(row.name, row.vol))
return None
def _name_parser(asset_name):
# 目前默认用户输入.SH 或.SZ时标的名称正确
if '.SH' in asset_name or '.SZ' in asset_name:
# todo: SH/SZ_pattern regex check here?
return asset_name
else:
raise ValueError('{0} 标的代码不合法'.format(asset_name))
try:
tmp_df = read_file(FILEPATH, names=COLNAMES, index_col=0)
except:
logging.warning('读取挂单配置文件失败或挂单配置文件为空,尝试交易读取配置面板参数')
return None
if tmp_df.empty:
logging.warning('读取挂单配置文件失败或挂单配置文件为空,尝试交易读取配置面板参数')
return None
tmp_df.index = tmp_df.index.to_series().astype(str)
tmp_df.index = tmp_df.index.str.strip()
tmp_df.index = tmp_df.index.str.upper()
tmp_df.index = tmp_df.index.to_series().apply(_name_parser).dropna()
tmp_df = tmp_df.apply(_price_vol_filtering, axis=1, broadcast=True).dropna()
if tmp_df.empty:
logging.warning('读取挂单配置文件失败或挂单配置文件为空,尝试交易读取配置面板参数')
return False
tmp_df.set_axis(COLNAMES, axis='columns', inplace=True)
# 挂单成功Flag
tmp_df['finished'] = [False] * tmp_df.shape[0]
ContextInfo.order_df = tmp_df
ContextInfo.set_universe(ContextInfo.order_df.index.tolist())
return True
def load_sys_order(ContextInfo):
try:
asset_name = ContextInfo.stockcode + '.' + ContextInfo.market
ContextInfo.set_universe([asset_name])
direction = 23 if DIR == '买入' else 24
start_time = datetime.strptime(datetime.now().strftime('%Y%m%d') + str(START_TIME), '%Y%m%d%H%M%S')
price = D(PRICE)
vol = int(VOL)
except BaseException:
raise ValueError("读取策略面板交易配置失败。请尝试修正挂单配置文件或者策略面板参数。")
price = float(price)
ContextInfo.order_df = pd.DataFrame(data=[direction, vol, price, start_time], index=COLNAMES,
columns=[asset_name]).T
ContextInfo.order_df['finished'] = False
return
def place_order(ContextInfo):
if not ContextInfo.can_order or ContextInfo.all_order_done:
return
for curr_asset in ContextInfo.get_universe():
if not ContextInfo.order_df.loc[curr_asset].finished \
and datetime.now() > ContextInfo.order_df.loc[curr_asset].start_time:
curr_order = ContextInfo.order_df.loc[curr_asset]
direction = int(curr_order.direction)
txt_direction = '买入' if direction == 23 else '卖出'
price = float(D(curr_order.price))
vol = int(curr_order.vol)
order_remark = '隔日文件挂单: 以 {0} {1} {2}'.format(price, txt_direction, curr_asset)
passorder(direction, 1101, ContextInfo.accID, curr_asset, 11, price, vol, order_remark, 1, order_remark,
ContextInfo)
ContextInfo.order_df.loc[curr_asset, 'finished'] = True
ContextInfo.all_order_done = all(ContextInfo.order_df['finished'].tolist())
def order_callback(ContextInfo, orderInfo):
curr_asset = orderInfo.m_strInstrumentID + '.' + orderInfo.m_strExchangeID
curr_remark = orderInfo.m_strRemark
curr_status = orderInfo.m_nOrderStatus
if '隔日文件挂单' in curr_remark and curr_status == 57:
ContextInfo.order_df.loc[curr_asset, 'finished'] = False
ContextInfo.all_order_done = False
logging.error('{0} 隔日文件挂单:报单废单 (柜台返回失败),原因:{1} 尝试重报'.format(curr_asset, orderInfo.m_strCancelInfo))
elif '隔日文件挂单' in curr_remark and curr_status == 50:
logging.info('{0} 隔日文件挂单:报单成功'.format(curr_asset))
return
def orderError_callback(ContextInfo, orderArgs, errMsg):
curr_asset = orderArgs.orderCode
if '隔日文件挂单' in orderArgs.strategyName:
ContextInfo.order_df.loc[curr_asset, 'finished'] = False
ContextInfo.all_order_done = False
logging.error('{0} 隔日文件挂单:账号下单异常 (COS/iQuant校验失败), 错误消息:{1} 尝试重报'.format(curr_asset, errMsg))
return
把上述代码复制到iquant里面,然后部署到策略运行,运行策略,切换为实盘

qmt的文档写的有点稀烂
李魔佛 发表了文章 • 0 个评论 • 708 次浏览 • 2023-02-21 12:41
这也是当时不用QMT的一个重要原因。
不仅仅是文档,而且还有它的函数接口的涉及。
比如最常用的交易函数,passorder综合交易下单 passorder()
用法: passorder(opType, orderType, accountid, orderCode, prType, modelprice, volume[, strategyName, quickTrade, userOrderId], ContextInfo)
里面有11个参数,可选参数有2个。 对于一个常用函数来说,这个参数有点多了。
而更为令人费解的,是它参数里面额设定值
比如第一个opType,操作类型。
里面有59个数字:期货六键:
0:开多
1:平昨多
2:平今多
3:开空
4:平昨空
5:平今空
期货四键:
6:平多,优先平今
7:平多,优先平昨
8:平空,优先平今
9:平空,优先平昨
期货两键:
10:卖出,如有多仓,优先平仓,优先平今,如有余量,再开空
11:卖出,如有多仓,优先平仓,优先平昨,如有余量,再开空
12:买入,如有空仓,优先平仓,优先平今,如有余量,再开多
13:买入,如有空仓,优先平仓,优先平昨,如有余量,再开多
14:买入,不优先平仓
15:卖出,不优先平仓
股票买卖:
23:股票买入,或沪港通、深港通股票买入
24:股票卖出,或沪港通、深港通股票卖出
融资融券:
27:融资买入
28:融券卖出
29:买券还券
30:直接还券
31:卖券还款
32:直接还款
33:信用账号股票买入
34:信用账号股票卖出
组合交易:
25:组合买入,或沪港通、深港通的组合买入
26:组合卖出,或沪港通、深港通的组合卖出
27:融资买入
28:融券卖出
29:买券还券
31:卖券还款
33:信用账号股票买入
34:信用账号股票卖出
40:期货组合开多
43:期货组合开空
46:期货组合平多,优先平今
47:期货组合平多,优先平昨
48:期货组合平空,优先平今
49:期货组合平空,优先平昨
期权交易:
50:买入开仓
51:卖出平仓
52:卖出开仓
53:买入平仓
54:备兑开仓
55:备兑平仓
56:认购行权
57:认沽行权
58:证券锁定
59:证券解锁
它把期货,股票,期权所有品种压缩到一起,通过参数数字来辨认交易类别。
那么我们来看一看一个例子,就拿一个官网的一个例子来说:
最简单的例子:passorder(23,1101,account,s,11,14.00,100,2,ContextInfo)
一般人看了上面的代码,里面全部是数字,简直就像灾难一样。 但是我要明白它的交易品种和交易逻辑,
就得对着文档去查,编号23是啥,1101是啥,11,14又是啥。
如果我是代码reviewer,底下的员工这种文档,或者写代码的人,提交上这样的代码,绝对100%是要reject这个提交的。
然后orderType 更加让人吐血。。
1101:单股、单账号、普通、股/手方式下单
1102:单股、单账号、普通、金额(元)方式下单(只支持股票)
1113:单股、单账号、总资产、比例 [0 ~ 1] 方式下单
1123:单股、单账号、可用、比例[0 ~ 1]方式下单
1201:单股、账号组(无权重)、普通、股/手方式下单
1202:单股、账号组(无权重)、普通、金额(元)方式下单(只支持股票)
1213:单股、账号组(无权重)、总资产、比例 [0 ~ 1] 方式下单
1223:单股、账号组(无权重)、可用、比例 [0 ~ 1] 方式下单
2101:组合、单账号、普通、按组合股票数量(篮子中股票设定的数量)方式下单 > 对应 volume 的单位为篮子的份
2102:组合、单账号、普通、按组合股票权重(篮子中股票设定的权重)方式下单 > 对应 volume 的单位为元
2103:组合、单账号、普通、按账号可用方式下单 > (底层篮子股票怎么分配?答:按可用资金比例后按篮子中股票权重分配,如用户没填权重则按相等权重分配)只对股票篮子支持
2201:组合、账号组(无权重)、普通、按组合股票数量方式下单
2202:组合、账号组(无权重)、普通、按组合股票权重方式下单
这排列组合,谁能记得住,逼着你去查文档,或者每次复制粘贴旧代码。
然后下单 类型,继续来各种枚举:
-1:无效(实际下单时,需要用交易面板交易函数那设定的选价类型)
0:卖5价
1:卖4价
2:卖3价
3:卖2价
4:卖1价
5:最新价
6:买1价
7:买2价(组合不支持)
8:买3价(组合不支持)
9:买4价(组合不支持)
10:买5价(组合不支持)
11:(指定价)模型价(只对单股情况支持,对组合交易不支持)
12:涨跌停价
13:挂单价
14:对手价
27:市价即成剩撤(仅对股票期权申报有效)
28:市价即全成否则撤(仅对股票期权申报有效)
29:市价剩转限价(仅对股票期权申报有效)
42:最优五档即时成交剩余撤销申报(仅对上交所申报有效)
43:最优五档即时成交剩转限价申报(仅对上交所申报有效)
44:对手方最优价格委托(仅对深交所申报有效)
45:本方最优价格委托(仅对深交所申报有效)
46:即时成交剩余撤销委托(仅对深交所申报有效)
47:最优五档即时成交剩余撤销委托(仅对深交所申报有效)
48:全额成交或撤销委托(仅对深交所申报有效)
49:科创板盘后定价
会不会用常量定义个值给客户调用呢?
passorder(
ContextInfo.TYPE_STOCK,
ContextInfo.TYPE_BUY,
100,
ContextInfo.LIMIT_PRICE,
ContextInfo)
没有标注类型:
虽然python是若类型的语言,可是qmt底层是c++,有些参数不对,就会导致异常:
比如交易软件:
比如下单函数passorder的参数列表:
volume,下单数量(股 / 手 / 元 / %)
passorder(opType, orderType, accountID, orderCode, prType, price, volume, ContextInfo)
根据 orderType 值最后一位确定 volume 的单位:
单股下单时:
1:股 / 手
2:金额(元)
3:比例(%)这个类型如果用了浮点,前面类型用了以股为但是,是会报错的,因为不存在100.11 股这样的非100单位的下单数据。
看完不想吐槽了,一群文科生设计的软件。。。
查看全部
这也是当时不用QMT的一个重要原因。
不仅仅是文档,而且还有它的函数接口的涉及。
比如最常用的交易函数,passorder
综合交易下单 passorder()
用法: passorder(opType, orderType, accountid, orderCode, prType, modelprice, volume[, strategyName, quickTrade, userOrderId], ContextInfo)
里面有11个参数,可选参数有2个。 对于一个常用函数来说,这个参数有点多了。
而更为令人费解的,是它参数里面额设定值
比如第一个opType,操作类型。
里面有59个数字:
期货六键:
0:开多
1:平昨多
2:平今多
3:开空
4:平昨空
5:平今空
期货四键:
6:平多,优先平今
7:平多,优先平昨
8:平空,优先平今
9:平空,优先平昨
期货两键:
10:卖出,如有多仓,优先平仓,优先平今,如有余量,再开空
11:卖出,如有多仓,优先平仓,优先平昨,如有余量,再开空
12:买入,如有空仓,优先平仓,优先平今,如有余量,再开多
13:买入,如有空仓,优先平仓,优先平昨,如有余量,再开多
14:买入,不优先平仓
15:卖出,不优先平仓
股票买卖:
23:股票买入,或沪港通、深港通股票买入
24:股票卖出,或沪港通、深港通股票卖出
融资融券:
27:融资买入
28:融券卖出
29:买券还券
30:直接还券
31:卖券还款
32:直接还款
33:信用账号股票买入
34:信用账号股票卖出
组合交易:
25:组合买入,或沪港通、深港通的组合买入
26:组合卖出,或沪港通、深港通的组合卖出
27:融资买入
28:融券卖出
29:买券还券
31:卖券还款
33:信用账号股票买入
34:信用账号股票卖出
40:期货组合开多
43:期货组合开空
46:期货组合平多,优先平今
47:期货组合平多,优先平昨
48:期货组合平空,优先平今
49:期货组合平空,优先平昨
期权交易:
50:买入开仓
51:卖出平仓
52:卖出开仓
53:买入平仓
54:备兑开仓
55:备兑平仓
56:认购行权
57:认沽行权
58:证券锁定
59:证券解锁
它把期货,股票,期权所有品种压缩到一起,通过参数数字来辨认交易类别。
那么我们来看一看一个例子,就拿一个官网的一个例子来说:
最简单的例子:
passorder(23,1101,account,s,11,14.00,100,2,ContextInfo)
一般人看了上面的代码,里面全部是数字,简直就像灾难一样。 但是我要明白它的交易品种和交易逻辑,
就得对着文档去查,编号23是啥,1101是啥,11,14又是啥。
如果我是代码reviewer,底下的员工这种文档,或者写代码的人,提交上这样的代码,绝对100%是要reject这个提交的。
然后orderType 更加让人吐血。。
1101:单股、单账号、普通、股/手方式下单这排列组合,谁能记得住,逼着你去查文档,或者每次复制粘贴旧代码。
1102:单股、单账号、普通、金额(元)方式下单(只支持股票)
1113:单股、单账号、总资产、比例 [0 ~ 1] 方式下单
1123:单股、单账号、可用、比例[0 ~ 1]方式下单
1201:单股、账号组(无权重)、普通、股/手方式下单
1202:单股、账号组(无权重)、普通、金额(元)方式下单(只支持股票)
1213:单股、账号组(无权重)、总资产、比例 [0 ~ 1] 方式下单
1223:单股、账号组(无权重)、可用、比例 [0 ~ 1] 方式下单
2101:组合、单账号、普通、按组合股票数量(篮子中股票设定的数量)方式下单 > 对应 volume 的单位为篮子的份
2102:组合、单账号、普通、按组合股票权重(篮子中股票设定的权重)方式下单 > 对应 volume 的单位为元
2103:组合、单账号、普通、按账号可用方式下单 > (底层篮子股票怎么分配?答:按可用资金比例后按篮子中股票权重分配,如用户没填权重则按相等权重分配)只对股票篮子支持
2201:组合、账号组(无权重)、普通、按组合股票数量方式下单
2202:组合、账号组(无权重)、普通、按组合股票权重方式下单
然后下单 类型,继续来各种枚举:
-1:无效(实际下单时,需要用交易面板交易函数那设定的选价类型)
0:卖5价
1:卖4价
2:卖3价
3:卖2价
4:卖1价
5:最新价
6:买1价
7:买2价(组合不支持)
8:买3价(组合不支持)
9:买4价(组合不支持)
10:买5价(组合不支持)
11:(指定价)模型价(只对单股情况支持,对组合交易不支持)
12:涨跌停价
13:挂单价
14:对手价
27:市价即成剩撤(仅对股票期权申报有效)
28:市价即全成否则撤(仅对股票期权申报有效)
29:市价剩转限价(仅对股票期权申报有效)
42:最优五档即时成交剩余撤销申报(仅对上交所申报有效)
43:最优五档即时成交剩转限价申报(仅对上交所申报有效)
44:对手方最优价格委托(仅对深交所申报有效)
45:本方最优价格委托(仅对深交所申报有效)
46:即时成交剩余撤销委托(仅对深交所申报有效)
47:最优五档即时成交剩余撤销委托(仅对深交所申报有效)
48:全额成交或撤销委托(仅对深交所申报有效)
49:科创板盘后定价
会不会用常量定义个值给客户调用呢?
passorder(
ContextInfo.TYPE_STOCK,
ContextInfo.TYPE_BUY,
100,
ContextInfo.LIMIT_PRICE,
ContextInfo)
没有标注类型:
虽然python是若类型的语言,可是qmt底层是c++,有些参数不对,就会导致异常:
比如交易软件:
比如下单函数passorder的参数列表:
volume,下单数量(股 / 手 / 元 / %)这个类型如果用了浮点,前面类型用了以股为但是,是会报错的,因为不存在100.11 股这样的非100单位的下单数据。
passorder(opType, orderType, accountID, orderCode, prType, price, volume, ContextInfo)
根据 orderType 值最后一位确定 volume 的单位:
单股下单时:
1:股 / 手
2:金额(元)
3:比例(%)
看完不想吐槽了,一群文科生设计的软件。。。
为什么我的QMT安装目录下没有miniqmt的包xtquant
李魔佛 发表了文章 • 0 个评论 • 811 次浏览 • 2023-02-20 21:00
他安装的也是实盘正式版本的QMT。
那么问题出现在哪里呢?
主要问题在于它没有在qmt内部 下载内置的python库。
经过这个下载过程后。
然后就可以看到有site-packages了
查看全部
qmt iquant最新接口文档
李魔佛 发表了文章 • 0 个评论 • 1045 次浏览 • 2023-02-19 15:16
http://qmt.ptradeapi.com
除了官方的接口文档,还加入了一些个人平时编写的写法与回测,实盘代码。 不定期更新。
欢迎关注收藏。 查看全部
http://qmt.ptradeapi.com
除了官方的接口文档,还加入了一些个人平时编写的写法与回测,实盘代码。 不定期更新。
欢迎关注收藏。
迅投qmt入门教程(一)
李魔佛 发表了文章 • 0 个评论 • 5596 次浏览 • 2023-02-06 19:43
1. 准备:
首先得开一个支持qmt的券商,目前市面上支持qmt的券商越来越丰富了。
初学者可以开一个门槛第一点的,一般入金1w-2w 不等,就可以申请开通了。
鉴于以学习为目的,真正投入到实盘中的资金不会很大,所以初始阶段也不一定就找万一免五的券商,毕竟目前要给免五,资金门槛比较高,一般要100w甚至以上。
笔者推荐国信,国金的qmt, 门槛只要1-2w就足够了,股票费率在万一,可转债万0.4-万0.5。适合初学者,这两家也可以在虚拟机运行,适合苹果mac的用户。 需要的朋友也可以在公众号后台留言: qmt开通
2. 假设已经在券商那里开通了qmt功能,接下来就开始进入教学:
这里以国信的qmt(iquant)为例:
首先要做的就是下载python库。 这个python库指的是qmt的python库,它的版本是3.6.8; 如果你只用qmt内置的python,你就不用自己到网上下载python安装程序,只需要在qmt的设置里面,点一下按钮,就可以安装python库。这里用默认的系统路径就可以了。
3. 第一个量化程序 hello world
新建策略后:
在编辑器里面输入下面的代码:#encoding:gbk
def init(ContextInfo):
print('hello world')
def handlebar(ContextInfo):
#计算当前主图的cci
print("handle bar")
点击回测:
得到输出结果
这里介绍2个概念:(3)Handlebar
handlebar 是整个 Python 模型中的核心执行函数。当模型从数据层获取到运行所需要的数据之后,会对数据集上的每一根 bar,调用一次 handlebar 函数,处理当前这根 bar 上的数据。也就是说,用户模型的核心逻辑都是写在该函数中的,如获取数据,设置下单条件等。在 handlebar 中处理完数据后,用户可以通过 paint 方法将需要绘图输出的结果返回给界面。界面会将输出结果如实的展示出来。 (4)ContextInfo
ContextInfo 是整个 Python 框架中的一个核心对象。它包含了各种与 Python 底层框架交互的 API 方法,也是一个全局的上下文环境,可以在 init 以及 handlebar 这两个函数中自由地传递用户创建的各种自定义数据。
文绉绉的,实际写一个策略,必须包含下面两个函数,而且参数也要一致,参数名随意,不过用默认的就好了。你随便改成没有意义的字符,后面自己看代码也是很麻烦。def init(ContextInfo):
pass
def handlebar(ContextInfo):
pass
init 和 handlebar 是 Python 模型中最重要的方法,也是唯二由 C++ 直接调用的方法,所有的执行代码都尽量写在这两个方法中或由其中的函数调用。【个人不太喜欢这样】
回测时间设置,在右边的菜单栏,有个回测参数,里面设置时间;在菜单“基本信息”里面 ,可以设置回测的时间间隔,可以使用分钟线,日线,小时等等不同周期,不过无法做到tick的回测。最小的只能到分钟。
但是如果你有秒的tick数据,自己写个回测框架也是可以做到秒级的tick级别的回测。很早前笔者就在星球上提供了完整的源码和数据,初学者也可以拿着去改,只要后续更新tick数据,就可以不断的回测策略的最新状态。
你写的回测实盘python代码,是保存在本地的文件夹的:
C:\iquant_gx\python, 前面的C:\iquant_gx 是你的iquant安装路径。
而且底下也有很多的现成的代码:
部分代码可以直接用pycharm就可以打开,没有加密的,但也有一些是加密了的。
比如这个自动逆回购是现成的:
对,这里就有,很多人还到处找人写;# encoding:gbk
import logging
from datetime import datetime, timedelta
from decimal import Decimal as D
from decimal import InvalidOperation
logging.basicConfig(level=logging.INFO)
# 挂单失败后的等待时长,以秒计
TIMEOUT_ON_FAIL_SEC = 30
# 等待account_callback的时长
# RUN_TIME_DELAY = 30
# how is this not defined in package??
MORNING_START = datetime.strptime(datetime.now().strftime('%Y%m%d') + '093000', '%Y%m%d%H%M%S')
MORNING_END = datetime.strptime(datetime.now().strftime('%Y%m%d') + '113000', '%Y%m%d%H%M%S')
NOON_START = datetime.strptime(datetime.now().strftime('%Y%m%d') + '130000', '%Y%m%d%H%M%S')
NOON_END = datetime.strptime(datetime.now().strftime('%Y%m%d') + '153000', '%Y%m%d%H%M%S')
# for SH only
TRANS_COST_1D = D('5e-6')
TRANS_COST_LONG = D('1.5e-7')
TRANS_COST_MAX = 100
# ORDER LIMITS
SH_UPPER = 1e7
SH_LOWER = 1e5
SZ_UPPER = 1e8
SZ_LOWER = 1e3
# ASSET NAME DICT
SH_REV_REPO = {'上交所1天': '204001.SH', '上交所2天': '204002.SH', '上交所3天': '204003.SH',
'上交所4天': '204004.SH', '上交所7天': '204007.SH', '上交所14天': '204014.SH',
'上交所28天': '204028.SH', '上交所91天': '204091.SH', '上交所182天': '204182.SH',
}
SZ_REV_REPO = {'深交所3天': '131800.SZ', '深交所7天': '131801.SZ', '深交所14天': '131802.SZ',
'深交所28天': '131803.SZ', '深交所91天': '131805.SZ', '深交所182天': '131806.SZ',
'深交所4天': '131809.SZ', '深交所1天': '131810.SZ', '深交所2天': '131811.SZ',
}
def init(ContextInfo):
ContextInfo.accID = account
ContextInfo.set_account(ContextInfo.accID)
ContextInfo.use_all_cap = False if ALL_CAP == '否' else True
# global trading control, set to False if detected error on user's side
# stop() does not halt strat
ContextInfo.order_control = False
if not ContextInfo.use_all_cap:
try:
ContextInfo.dollar_vol = float(D(DOLLAR_VOL))
except InvalidOperation:
ContextInfo.order_control = True
raise ValueError('读取资金量失败')
else:
if DOLLAR_VOL != '':
logging.warning('已设定使用全部账户资金,忽略所设置资金量')
try:
ContextInfo.start_time = datetime.strptime(datetime.now().strftime('%Y%m%d') + str(START_TIME), '%Y%m%d%H%M%S')
ContextInfo.asset_name = SH_REV_REPO[ASSET_NAME]
except KeyError:
ContextInfo.asset_name = SZ_REV_REPO[ASSET_NAME]
except ValueError as error:
if 'unconverted data remains' in str(error):
ContextInfo.order_control = True
raise ValueError('读取挂单时间失败')
if not (MORNING_END > ContextInfo.start_time >= MORNING_START) \
and not (NOON_END > ContextInfo.start_time >= NOON_START):
ContextInfo.order_control = True
raise ValueError('挂单时间不在可交易时间内')
ContextInfo.can_order = False
ContextInfo.order_done = False
if not ContextInfo.order_control:
ContextInfo.run_time("place_order", "{0}nSecond".format(TIMEOUT_ON_FAIL_SEC),
ContextInfo.start_time.strftime('%Y-%m-%d %H:%M:%S'), 'SH')
def account_callback(ContextInfo, accountInfo):
if not ContextInfo.can_order:
ContextInfo.can_order = True
if ContextInfo.use_all_cap:
ContextInfo.dollar_vol = accountInfo.m_dAvailable
else:
if ContextInfo.dollar_vol > accountInfo.m_dAvailable:
ContextInfo.order_control = True
raise ValueError('下单额度大于账户可用资金')
# check if order satisfies lower limit for each exchange
if ('SH' in ContextInfo.asset_name and ContextInfo.dollar_vol < SH_LOWER) \
or ('SZ' in ContextInfo.asset_name and ContextInfo.dollar_vol < SZ_LOWER):
ContextInfo.order_control = True
raise ValueError('下单额度低于交易所最低限额')
# checks dollar_vol and rounds the total amount
if 'SH' in ContextInfo.asset_name and ContextInfo.dollar_vol % SH_LOWER != 0:
ContextInfo.dollar_vol = (ContextInfo.dollar_vol // SH_LOWER) * SH_LOWER
logging.warning('下单额度已规整为:{0}'.format(ContextInfo.dollar_vol))
elif 'SZ' in ContextInfo.asset_name and ContextInfo.dollar_vol % SZ_LOWER != 0:
ContextInfo.dollar_vol = (ContextInfo.dollar_vol // SZ_LOWER) * SZ_LOWER
logging.warning('下单额度已规整为:{0}'.format(ContextInfo.dollar_vol))
'''
if 'SH' in ContextInfo.asset_name:
num_batch_order = int(ContextInfo.dollar_vol // SH_UPPER)
remain_order = ContextInfo.dollar_vol - num_batch_order * SH_UPPER
if ContextInfo.asset_name == '204001.SH':
transaction_cost = TRANS_COST_MAX * num_batch_order + remain_order * TRANS_COST_1D
else:
transaction_cost = TRANS_COST_MAX * num_batch_order + remain_order * TRANS_COST_LONG
if transaction_cost + ContextInfo.dollar_vol > accountInfo.m_dAvailable:
ContextInfo.order_control = True
raise ValueError('可用资金不足以垫付交易金额与手续费')
'''
ContextInfo.remain_vol = ContextInfo.dollar_vol
def handlebar(ContextInfo):
return
def place_order(ContextInfo):
if not ContextInfo.can_order or ContextInfo.order_control:
return
if not ContextInfo.order_done:
if 'SH' in ContextInfo.asset_name:
num_batch_order = int(ContextInfo.remain_vol // SH_UPPER)
remain_order = ContextInfo.remain_vol - num_batch_order * SH_UPPER
for _ in range(num_batch_order):
order_remark = '国债逆回购:尝试报单{0}元 {1}'.format(SH_UPPER, ContextInfo.asset_name)
passorder(24, 1102, ContextInfo.accID, ContextInfo.asset_name, 5, -1, SH_UPPER, order_remark, 1,
order_remark, ContextInfo)
else:
num_batch_order = int(ContextInfo.remain_vol // SZ_UPPER)
remain_order = ContextInfo.remain_vol - num_batch_order * SZ_UPPER
for _ in range(num_batch_order):
order_remark = '国债逆回购:尝试报单{0}元 {1}'.format(SZ_UPPER, ContextInfo.asset_name)
passorder(24, 1102, ContextInfo.accID, ContextInfo.asset_name, 5, -1, SZ_UPPER, order_remark, 1,
order_remark, ContextInfo)
order_remark = '国债逆回购:尝试报单{0}元 {1}'.format(remain_order, ContextInfo.asset_name)
passorder(24, 1102, ContextInfo.accID, ContextInfo.asset_name, 5, -1, remain_order, order_remark, 1,
order_remark, ContextInfo)
ContextInfo.remain_vol = 0
ContextInfo.order_done = True
def order_callback(ContextInfo, orderInfo):
curr_remark = orderInfo.m_strRemark
curr_status = orderInfo.m_nOrderStatus
if '国债逆回购' in curr_remark and ContextInfo.asset_name in curr_remark and curr_status == 57:
ContextInfo.order_done = False
# up the leftover dollar vol by failed amount
# logging.info('reported trade amount:{0}, reported_trade_volume:{1}'.format(orderInfo.m_dTradeAmount, orderInfo.m_nVolumeTotal))
# 单张100元
ContextInfo.remain_vol += orderInfo.m_nVolumeTotal * 100
if '交易时间不合法' in orderInfo.m_strCancelInfo:
ContextInfo.order_control = True
raise ValueError('国债逆回购:未能在交易时间内完成下单,停止报单。余量{0}元未报'.format(ContextInfo.remain_vol))
logging.warning('国债逆回购:报单废单,原因:\"{0}\",尝试重报'.format(orderInfo.m_strCancelInfo))
elif '国债逆回购' in curr_remark and ContextInfo.asset_name in curr_remark and curr_status == 50:
logging.info('国债逆回购:报单{0}元成功'.format(orderInfo.m_nVolumeTotal * 100))
return
待续,不定期更新
公众号:
星球:
查看全部
1. 准备:
首先得开一个支持qmt的券商,目前市面上支持qmt的券商越来越丰富了。
初学者可以开一个门槛第一点的,一般入金1w-2w 不等,就可以申请开通了。
鉴于以学习为目的,真正投入到实盘中的资金不会很大,所以初始阶段也不一定就找万一免五的券商,毕竟目前要给免五,资金门槛比较高,一般要100w甚至以上。
笔者推荐国信,国金的qmt, 门槛只要1-2w就足够了,股票费率在万一,可转债万0.4-万0.5。适合初学者,这两家也可以在虚拟机运行,适合苹果mac的用户。 需要的朋友也可以在公众号后台留言: qmt开通
2. 假设已经在券商那里开通了qmt功能,接下来就开始进入教学:
这里以国信的qmt(iquant)为例:
首先要做的就是下载python库。 这个python库指的是qmt的python库,它的版本是3.6.8; 如果你只用qmt内置的python,你就不用自己到网上下载python安装程序,只需要在qmt的设置里面,点一下按钮,就可以安装python库。这里用默认的系统路径就可以了。
3. 第一个量化程序 hello world
新建策略后:
在编辑器里面输入下面的代码:
#encoding:gbk
def init(ContextInfo):
print('hello world')
def handlebar(ContextInfo):
#计算当前主图的cci
print("handle bar")
点击回测:
得到输出结果
这里介绍2个概念:
(3)Handlebar
handlebar 是整个 Python 模型中的核心执行函数。当模型从数据层获取到运行所需要的数据之后,会对数据集上的每一根 bar,调用一次 handlebar 函数,处理当前这根 bar 上的数据。也就是说,用户模型的核心逻辑都是写在该函数中的,如获取数据,设置下单条件等。在 handlebar 中处理完数据后,用户可以通过 paint 方法将需要绘图输出的结果返回给界面。界面会将输出结果如实的展示出来。
(4)ContextInfo
ContextInfo 是整个 Python 框架中的一个核心对象。它包含了各种与 Python 底层框架交互的 API 方法,也是一个全局的上下文环境,可以在 init 以及 handlebar 这两个函数中自由地传递用户创建的各种自定义数据。
文绉绉的,实际写一个策略,必须包含下面两个函数,而且参数也要一致,参数名随意,不过用默认的就好了。你随便改成没有意义的字符,后面自己看代码也是很麻烦。
def init(ContextInfo):
pass
def handlebar(ContextInfo):
pass
init 和 handlebar 是 Python 模型中最重要的方法,也是唯二由 C++ 直接调用的方法,所有的执行代码都尽量写在这两个方法中或由其中的函数调用。【个人不太喜欢这样】
回测时间设置,在右边的菜单栏,有个回测参数,里面设置时间;在菜单“基本信息”里面 ,可以设置回测的时间间隔,可以使用分钟线,日线,小时等等不同周期,不过无法做到tick的回测。最小的只能到分钟。
但是如果你有秒的tick数据,自己写个回测框架也是可以做到秒级的tick级别的回测。很早前笔者就在星球上提供了完整的源码和数据,初学者也可以拿着去改,只要后续更新tick数据,就可以不断的回测策略的最新状态。
你写的回测实盘python代码,是保存在本地的文件夹的:
C:\iquant_gx\python, 前面的C:\iquant_gx 是你的iquant安装路径。
而且底下也有很多的现成的代码:
部分代码可以直接用pycharm就可以打开,没有加密的,但也有一些是加密了的。
比如这个自动逆回购是现成的:
对,这里就有,很多人还到处找人写;
# encoding:gbk
import logging
from datetime import datetime, timedelta
from decimal import Decimal as D
from decimal import InvalidOperation
logging.basicConfig(level=logging.INFO)
# 挂单失败后的等待时长,以秒计
TIMEOUT_ON_FAIL_SEC = 30
# 等待account_callback的时长
# RUN_TIME_DELAY = 30
# how is this not defined in package??
MORNING_START = datetime.strptime(datetime.now().strftime('%Y%m%d') + '093000', '%Y%m%d%H%M%S')
MORNING_END = datetime.strptime(datetime.now().strftime('%Y%m%d') + '113000', '%Y%m%d%H%M%S')
NOON_START = datetime.strptime(datetime.now().strftime('%Y%m%d') + '130000', '%Y%m%d%H%M%S')
NOON_END = datetime.strptime(datetime.now().strftime('%Y%m%d') + '153000', '%Y%m%d%H%M%S')
# for SH only
TRANS_COST_1D = D('5e-6')
TRANS_COST_LONG = D('1.5e-7')
TRANS_COST_MAX = 100
# ORDER LIMITS
SH_UPPER = 1e7
SH_LOWER = 1e5
SZ_UPPER = 1e8
SZ_LOWER = 1e3
# ASSET NAME DICT
SH_REV_REPO = {'上交所1天': '204001.SH', '上交所2天': '204002.SH', '上交所3天': '204003.SH',
'上交所4天': '204004.SH', '上交所7天': '204007.SH', '上交所14天': '204014.SH',
'上交所28天': '204028.SH', '上交所91天': '204091.SH', '上交所182天': '204182.SH',
}
SZ_REV_REPO = {'深交所3天': '131800.SZ', '深交所7天': '131801.SZ', '深交所14天': '131802.SZ',
'深交所28天': '131803.SZ', '深交所91天': '131805.SZ', '深交所182天': '131806.SZ',
'深交所4天': '131809.SZ', '深交所1天': '131810.SZ', '深交所2天': '131811.SZ',
}
def init(ContextInfo):
ContextInfo.accID = account
ContextInfo.set_account(ContextInfo.accID)
ContextInfo.use_all_cap = False if ALL_CAP == '否' else True
# global trading control, set to False if detected error on user's side
# stop() does not halt strat
ContextInfo.order_control = False
if not ContextInfo.use_all_cap:
try:
ContextInfo.dollar_vol = float(D(DOLLAR_VOL))
except InvalidOperation:
ContextInfo.order_control = True
raise ValueError('读取资金量失败')
else:
if DOLLAR_VOL != '':
logging.warning('已设定使用全部账户资金,忽略所设置资金量')
try:
ContextInfo.start_time = datetime.strptime(datetime.now().strftime('%Y%m%d') + str(START_TIME), '%Y%m%d%H%M%S')
ContextInfo.asset_name = SH_REV_REPO[ASSET_NAME]
except KeyError:
ContextInfo.asset_name = SZ_REV_REPO[ASSET_NAME]
except ValueError as error:
if 'unconverted data remains' in str(error):
ContextInfo.order_control = True
raise ValueError('读取挂单时间失败')
if not (MORNING_END > ContextInfo.start_time >= MORNING_START) \
and not (NOON_END > ContextInfo.start_time >= NOON_START):
ContextInfo.order_control = True
raise ValueError('挂单时间不在可交易时间内')
ContextInfo.can_order = False
ContextInfo.order_done = False
if not ContextInfo.order_control:
ContextInfo.run_time("place_order", "{0}nSecond".format(TIMEOUT_ON_FAIL_SEC),
ContextInfo.start_time.strftime('%Y-%m-%d %H:%M:%S'), 'SH')
def account_callback(ContextInfo, accountInfo):
if not ContextInfo.can_order:
ContextInfo.can_order = True
if ContextInfo.use_all_cap:
ContextInfo.dollar_vol = accountInfo.m_dAvailable
else:
if ContextInfo.dollar_vol > accountInfo.m_dAvailable:
ContextInfo.order_control = True
raise ValueError('下单额度大于账户可用资金')
# check if order satisfies lower limit for each exchange
if ('SH' in ContextInfo.asset_name and ContextInfo.dollar_vol < SH_LOWER) \
or ('SZ' in ContextInfo.asset_name and ContextInfo.dollar_vol < SZ_LOWER):
ContextInfo.order_control = True
raise ValueError('下单额度低于交易所最低限额')
# checks dollar_vol and rounds the total amount
if 'SH' in ContextInfo.asset_name and ContextInfo.dollar_vol % SH_LOWER != 0:
ContextInfo.dollar_vol = (ContextInfo.dollar_vol // SH_LOWER) * SH_LOWER
logging.warning('下单额度已规整为:{0}'.format(ContextInfo.dollar_vol))
elif 'SZ' in ContextInfo.asset_name and ContextInfo.dollar_vol % SZ_LOWER != 0:
ContextInfo.dollar_vol = (ContextInfo.dollar_vol // SZ_LOWER) * SZ_LOWER
logging.warning('下单额度已规整为:{0}'.format(ContextInfo.dollar_vol))
'''
if 'SH' in ContextInfo.asset_name:
num_batch_order = int(ContextInfo.dollar_vol // SH_UPPER)
remain_order = ContextInfo.dollar_vol - num_batch_order * SH_UPPER
if ContextInfo.asset_name == '204001.SH':
transaction_cost = TRANS_COST_MAX * num_batch_order + remain_order * TRANS_COST_1D
else:
transaction_cost = TRANS_COST_MAX * num_batch_order + remain_order * TRANS_COST_LONG
if transaction_cost + ContextInfo.dollar_vol > accountInfo.m_dAvailable:
ContextInfo.order_control = True
raise ValueError('可用资金不足以垫付交易金额与手续费')
'''
ContextInfo.remain_vol = ContextInfo.dollar_vol
def handlebar(ContextInfo):
return
def place_order(ContextInfo):
if not ContextInfo.can_order or ContextInfo.order_control:
return
if not ContextInfo.order_done:
if 'SH' in ContextInfo.asset_name:
num_batch_order = int(ContextInfo.remain_vol // SH_UPPER)
remain_order = ContextInfo.remain_vol - num_batch_order * SH_UPPER
for _ in range(num_batch_order):
order_remark = '国债逆回购:尝试报单{0}元 {1}'.format(SH_UPPER, ContextInfo.asset_name)
passorder(24, 1102, ContextInfo.accID, ContextInfo.asset_name, 5, -1, SH_UPPER, order_remark, 1,
order_remark, ContextInfo)
else:
num_batch_order = int(ContextInfo.remain_vol // SZ_UPPER)
remain_order = ContextInfo.remain_vol - num_batch_order * SZ_UPPER
for _ in range(num_batch_order):
order_remark = '国债逆回购:尝试报单{0}元 {1}'.format(SZ_UPPER, ContextInfo.asset_name)
passorder(24, 1102, ContextInfo.accID, ContextInfo.asset_name, 5, -1, SZ_UPPER, order_remark, 1,
order_remark, ContextInfo)
order_remark = '国债逆回购:尝试报单{0}元 {1}'.format(remain_order, ContextInfo.asset_name)
passorder(24, 1102, ContextInfo.accID, ContextInfo.asset_name, 5, -1, remain_order, order_remark, 1,
order_remark, ContextInfo)
ContextInfo.remain_vol = 0
ContextInfo.order_done = True
def order_callback(ContextInfo, orderInfo):
curr_remark = orderInfo.m_strRemark
curr_status = orderInfo.m_nOrderStatus
if '国债逆回购' in curr_remark and ContextInfo.asset_name in curr_remark and curr_status == 57:
ContextInfo.order_done = False
# up the leftover dollar vol by failed amount
# logging.info('reported trade amount:{0}, reported_trade_volume:{1}'.format(orderInfo.m_dTradeAmount, orderInfo.m_nVolumeTotal))
# 单张100元
ContextInfo.remain_vol += orderInfo.m_nVolumeTotal * 100
if '交易时间不合法' in orderInfo.m_strCancelInfo:
ContextInfo.order_control = True
raise ValueError('国债逆回购:未能在交易时间内完成下单,停止报单。余量{0}元未报'.format(ContextInfo.remain_vol))
logging.warning('国债逆回购:报单废单,原因:\"{0}\",尝试重报'.format(orderInfo.m_strCancelInfo))
elif '国债逆回购' in curr_remark and ContextInfo.asset_name in curr_remark and curr_status == 50:
logging.info('国债逆回购:报单{0}元成功'.format(orderInfo.m_nVolumeTotal * 100))
return
待续,不定期更新
公众号:

星球:

qmt界面的运行和回测按钮功能有什么不同?
李魔佛 发表了文章 • 0 个评论 • 771 次浏览 • 2023-02-06 19:00
在模型编辑器中,有“回测”和“运行”两个按钮,分别代表两种模式,它们之间的区别如下:
(1)回测模式指策略以历史行情为依据,以回测参数中的开始时间、结束时间为回测时间区间进行运
算,投资者可观察该策略在历史行情所获得的年化收益率、夏普比率、最大回撤、信息比率等指标表
现。
(2)运行模式指策略根据实时行情信号进行运算,以主图行情开始时间到当前时间为运行区间,进行策
略的模拟运行,但不进行真实的委托。
注:如果需要向模拟/实盘柜台发送真实的委托,请将策略加入到“模型交易”中。
盘后运行可能会有抽风现象。
回测的时候日期问题,只能选副图,不知道为何 查看全部
国信可以使用miniqmt吗?
李魔佛 发表了文章 • 0 个评论 • 2023 次浏览 • 2023-01-21 15:52
所以笔者特意去问了下国信的好友兼营业部经理,但他回复说,个人只要申请,就可以开通mini qmt。如果不申请,是无法使用的,无法连接上去。
但因为开通这个是不用门槛的,可能会有部分不懂的或者不愿意的经理会和客户说不支持,或者需要机构这样话语。
具体情况,具体分析。
1. 国信证券iQuant策略交易平台精简版是指国信证券iQuant策略交易平台更专业快速且简洁的版本,满足股票、期货、期权、基金等全品种交易需求。
2. 风险等级:R4
投资期限:0-1年
投资品种:权益类投资品种如股票、混合型基金、偏股型基金、股票型基金等。
3. 平台使用不收取费用。
具体的申请表如下:
不过申请了这个权限后,只能进行拉取数据,并没有交易权限。。交易权限需要机构才能开通。郁闷,看来国信的miniqmt是无法进行交易的了,只能白嫖点数据。
如果需要文字word版本,
可以到公众号后台回复: 国信mini申请
获取word版本。
或者加微信开通指定的营业部的国信qmt(iquant), 也可以帮你开通mini qmt。
查看全部
之前群里有国信的小伙伴说,国信的mini qmt无法使用的。
所以笔者特意去问了下国信的好友兼营业部经理,但他回复说,个人只要申请,就可以开通mini qmt。如果不申请,是无法使用的,无法连接上去。
但因为开通这个是不用门槛的,可能会有部分不懂的或者不愿意的经理会和客户说不支持,或者需要机构这样话语。
具体情况,具体分析。
1. 国信证券iQuant策略交易平台精简版是指国信证券iQuant策略交易平台更专业快速且简洁的版本,满足股票、期货、期权、基金等全品种交易需求。
2. 风险等级:R4
投资期限:0-1年
投资品种:权益类投资品种如股票、混合型基金、偏股型基金、股票型基金等。
3. 平台使用不收取费用。
具体的申请表如下:
不过申请了这个权限后,只能进行拉取数据,并没有交易权限。。交易权限需要机构才能开通。郁闷,看来国信的miniqmt是无法进行交易的了,只能白嫖点数据。
如果需要文字word版本,
可以到公众号后台回复: 国信mini申请
获取word版本。

或者加微信开通指定的营业部的国信qmt(iquant), 也可以帮你开通mini qmt。
