
QMT
ptrade精确参与集合竞价交易 时间设置问题
Ptrade • 李魔佛 发表了文章 • 0 个评论 • 167 次浏览 • 2023-11-16 10:10
查了下日志。run_daily 设置的9:25运行,下单委托的时间在9:25:01 这个时间就被推到9:30开盘去成交了。
所以实际没有参与到9:25的集合竞价。
所以要参与集合竞价,需要设定在9:24分开始,然后不断在一个循环里面,用更小的时间颗粒,比如100ms去监听。
等到9:24:59的时间,才去下单。
具体代码可以参照我的知识星球
查看全部
迅投官网的示例代码真的无眼看。。。
QMT • 李魔佛 发表了文章 • 0 个评论 • 189 次浏览 • 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 | Ptrade 量化策略代写服务
量化交易 • 李魔佛 发表了文章 • 0 个评论 • 297 次浏览 • 2023-11-01 10:43
多年交易经验,量化交易与开发经验。所以很多策略,其实用户大体描述,就知道要注意哪些地方,会提出一些建议,用户要注意,需不需要添加一些判读条件等等。(当然,策略的具体参数都是设置可以调节的,你不需要把实际的参数告诉我,代码给你后,你自己运行策略的时候把你策略的真正参数填上去就好了。)
有偿,收费,价格美丽。根据策略实际的复杂程度与预估的工时,收费。(不根据代码数量,因为我写代码很精简)
我也帮你们咨询过了迅投的客服。 因为他们官网也有提供策略代写服务。他们是不问你策略,直接是5000起步哦。然后根据策略,在5000的基础上不断加。
咨询完,我都感觉我自己以前的报价太低了,呜。
PS: 之前还有迅投的前员工私底下接单写策略,然后到我的星球里面白嫖我的代码,调用我接口数据,被我发现后举报到星球的。后面那个客户发现代码里面藏有我的公众号信息哈,找到我让我修改接口数据哈。
需要的代写策略的盆友,可以关注公众号,在菜单栏那里的“代写量化程序”或者 后台回复:策略代写,获取联系方式哦
扫码关注公众号:
查看全部
迅投的QMT和恒生电子的Ptrade, 还有掘金, 量化策略编程, 实盘和回测都行。只要你的需求明确,白纸黑字描述清楚,都可以做。股票,ETF,可转债都行。
多年交易经验,量化交易与开发经验。所以很多策略,其实用户大体描述,就知道要注意哪些地方,会提出一些建议,用户要注意,需不需要添加一些判读条件等等。(当然,策略的具体参数都是设置可以调节的,你不需要把实际的参数告诉我,代码给你后,你自己运行策略的时候把你策略的真正参数填上去就好了。)
有偿,收费,价格美丽。根据策略实际的复杂程度与预估的工时,收费。(不根据代码数量,因为我写代码很精简)
我也帮你们咨询过了迅投的客服。 因为他们官网也有提供策略代写服务。他们是不问你策略,直接是5000起步哦。然后根据策略,在5000的基础上不断加。
咨询完,我都感觉我自己以前的报价太低了,呜。
PS: 之前还有迅投的前员工私底下接单写策略,然后到我的星球里面白嫖我的代码,调用我接口数据,被我发现后举报到星球的。后面那个客户发现代码里面藏有我的公众号信息哈,找到我让我修改接口数据哈。
需要的代写策略的盆友,可以关注公众号,在菜单栏那里的“代写量化程序”或者 后台回复:策略代写,获取联系方式哦
扫码关注公众号:

QMT获取A股全市场股票代码
QMT • 李魔佛 发表了文章 • 0 个评论 • 261 次浏览 • 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仿真客户端 PTrade仿真客户端 QMT测试版 Ptrade测试版
量化交易 • 李魔佛 发表了文章 • 0 个评论 • 458 次浏览 • 2023-10-22 12:54
国金证券 - QMT测试账号信息: 登录账号:*********** 登录密码:**********
QMT交易测试客户端下载链接 链接:
https://download.gjzq.com.cn/temp/organ/gjzqqmt_ceshi.rar
国金证券 - ptrade测试账号信息: 登录账号:********* 登录密码:********
ptrade交易测试客户端下载链接 链接:
https://download.gjzq.com.cn/temp/organ/gjzqptrade_ceshi.rar
测试时间10:00--17:00 如有什么问题,请和我们联系。谢谢!
下面是国盛证券提供的试用账户:
国盛证券 - 国盛智投软件下载(测试版)Ptrade
https://download.gszq.com/ptrade/PTrade1.0-Client-V201906-00-000.zip
仿真账户:******* / ********
量化回测:支持1分钟、日线回测。
量化交易:支持LEVEL1 tick股票交易。
量化研究:提供云Ipython Notebook研究环境、行情数据2005年至今、可使用全市场金融数据。
国盛证券-迅投QMT软件下载(测试版)
https://download.gszq.com/xt/XtItClient_x64_QMT_test_1.0.0.22650.exe
仿真账户:*******/********
支持VBA、Python开发策略 可以安装第三方库 软件帮助有文档,测试版历史数据不是很准确,以熟悉界面为主。
如果需要测试账号, 需要开通券商账号后找券商经理获取.
可以扫码联系开通
查看全部
下面是国金证券提供的试用账户:
国金证券 - QMT测试账号信息: 登录账号:*********** 登录密码:**********
QMT交易测试客户端下载链接 链接:
https://download.gjzq.com.cn/temp/organ/gjzqqmt_ceshi.rar
国金证券 - ptrade测试账号信息: 登录账号:********* 登录密码:********
ptrade交易测试客户端下载链接 链接:
https://download.gjzq.com.cn/temp/organ/gjzqptrade_ceshi.rar
测试时间10:00--17:00 如有什么问题,请和我们联系。谢谢!
下面是国盛证券提供的试用账户:
国盛证券 - 国盛智投软件下载(测试版)Ptrade
https://download.gszq.com/ptrade/PTrade1.0-Client-V201906-00-000.zip
仿真账户:******* / ********
量化回测:支持1分钟、日线回测。
量化交易:支持LEVEL1 tick股票交易。
量化研究:提供云Ipython Notebook研究环境、行情数据2005年至今、可使用全市场金融数据。
国盛证券-迅投QMT软件下载(测试版)
https://download.gszq.com/xt/XtItClient_x64_QMT_test_1.0.0.22650.exe
仿真账户:*******/********
支持VBA、Python开发策略 可以安装第三方库 软件帮助有文档,测试版历史数据不是很准确,以熟悉界面为主。
如果需要测试账号, 需要开通券商账号后找券商经理获取.
可以扫码联系开通

ptrade 全局对象g持久化对象保存失败
Ptrade • 李魔佛 发表了文章 • 0 个评论 • 154 次浏览 • 2023-10-18 09:36
File "./fly_docker/IQEngine/utils/global_variable.py", line 50, in save
_pickle.PicklingError: Can't pickle <class 'IQEngine.user_module.PositionManager'>: attribute lookup PositionManager on IQEngine.user_module failed
原因是全局变量g 不能被持久化, 需要前面加__, 比如g.Name 要改成 g.__Name
全局变量g中不能被序列化的变量将不会被保存。您可在initialize中初始化该变量时名字以'__'开头;
涉及到IO(打开的文件,实例化的类对象等)的对象是不能被序列化的;
全局变量g中以'__'开头的变量为私有变量,持久化时将不会被保存;
具体可以参加 API文档:
https://ptradeapi.com 查看全部
2023-10-18 09:25:12 - ERROR - 全局对象g持久化对象保存失败,对象名:TARGET_STOCK_CODE,错误原因:Traceback (most recent call last):
File "./fly_docker/IQEngine/utils/global_variable.py", line 50, in save
_pickle.PicklingError: Can't pickle <class 'IQEngine.user_module.PositionManager'>: attribute lookup PositionManager on IQEngine.user_module failed
原因是全局变量g 不能被持久化, 需要前面加__, 比如g.Name 要改成 g.__Name
全局变量g中不能被序列化的变量将不会被保存。您可在initialize中初始化该变量时名字以'__'开头;
涉及到IO(打开的文件,实例化的类对象等)的对象是不能被序列化的;
全局变量g中以'__'开头的变量为私有变量,持久化时将不会被保存;
具体可以参加 API文档:
https://ptradeapi.com
ptrade/qmt 判断股票是否涨停
Ptrade • 李魔佛 发表了文章 • 0 个评论 • 355 次浏览 • 2023-10-09 11:03
以ptrade为例:
先通过 get_snapshot - 取行情快照
其中里面有2个字段:
up_px:涨停价格(str:float);
down_px:跌停价格(str:float);用当前的最新价格和涨停跌停价格比较:
last_px:最新成交价(str:float);
if last_px>=up_px 就是达到涨停价,
还有判断此时的卖一上是否有挂单. 如果还有卖单, 说明此时的涨停板并没有封住, 被人砸开了.
跌停板的判断也是如此.
2. 使用现有的API函数, 更加简单方便, 这个方法只适用于ptrade, qmt没有类似的函数.
check_limit - 代码涨跌停状态判断
使用场景
该函数仅在交易模块可用。
接口说明
该接口用于标识当日股票的涨跌停情况。
注意事项:
无
参数
security:单只股票代码或者多只股票代码组成的列表,必填字段(list[str]/str);
返回
正常返回一个dict类型数据,包含每只股票代码的涨停状态。多只股票代码查询时其中部分股票代码查询异常则该代码返回既不涨停也不跌停状态0。(dict[str:int])
涨跌停状态说明:
2:触板涨停(已经是涨停价格,但还有卖盘);
1:涨停;
0:既不涨停也不跌停;
-1:跌停;
-2:触板跌停(已经是跌停价格,但还有买盘);
示例代码:
def initialize(context):
g.security = '600570.SS'
set_universe(g.security)
def handle_data(context, data):
# 代码涨跌停状态
stock_flag = check_limit(g.security)
log.info(stock_flag)
公众号: 可转债量化分析
查看全部
以ptrade为例:
先通过 get_snapshot - 取行情快照
其中里面有2个字段:
up_px:涨停价格(str:float);用当前的最新价格和涨停跌停价格比较:
down_px:跌停价格(str:float);
last_px:最新成交价(str:float);
if last_px>=up_px 就是达到涨停价,
还有判断此时的卖一上是否有挂单. 如果还有卖单, 说明此时的涨停板并没有封住, 被人砸开了.
跌停板的判断也是如此.
2. 使用现有的API函数, 更加简单方便, 这个方法只适用于ptrade, qmt没有类似的函数.
check_limit - 代码涨跌停状态判断
使用场景
该函数仅在交易模块可用。
接口说明
该接口用于标识当日股票的涨跌停情况。
注意事项:
无
参数
security:单只股票代码或者多只股票代码组成的列表,必填字段(list[str]/str);
返回
正常返回一个dict类型数据,包含每只股票代码的涨停状态。多只股票代码查询时其中部分股票代码查询异常则该代码返回既不涨停也不跌停状态0。(dict[str:int])
涨跌停状态说明:
2:触板涨停(已经是涨停价格,但还有卖盘);
1:涨停;
0:既不涨停也不跌停;
-1:跌停;
-2:触板跌停(已经是跌停价格,但还有买盘);
示例代码:
def initialize(context):
g.security = '600570.SS'
set_universe(g.security)
def handle_data(context, data):
# 代码涨跌停状态
stock_flag = check_limit(g.security)
log.info(stock_flag)
公众号: 可转债量化分析

小市值轮动-量化交易-程序化交易-Ptrade实盘
Ptrade • 李魔佛 发表了文章 • 0 个评论 • 461 次浏览 • 2023-10-07 14:14
当前策略持有30只。
点击查看大图
点击查看大图
基于股票的策略不敢多买,属于试验阶段,后期仍然会不断根据市场调仓; 主仓依然在可转债。
公众号:可转债量化分析
如果需要策略代写,(ptrade、qmt,其他量化平台)
可以公众号后台回复:
策略代写
查看全部
一个因为蓝盾退债引起的报错【Ptrade/QMT】
量化交易 • 李魔佛 发表了文章 • 0 个评论 • 238 次浏览 • 2023-09-25 02:49
上去一看。
每一个tick都在报错:
好家伙? 怎么会有个 404001.SS的可转债代码的?
于是顺着代码去调试。 这个代码是从我的接口传过去的。
于是我看了下数据库。
赫然发现了一个蓝盾退债的玩意, 代码正是 404001, 无语中。 怎么这个代码不按常理来的呢。 虽说是三板的股票,可是转债代码改成4字头, 也是奇葩。
刚好也碰巧我的拼接后缀代码:
def modify_code(self, x):
return x + '.SZ' if x.startswith('12') else x + '.SS'
401开头,于是拼接了个.SS 后缀,导致ptrade无法正确识别这个代码行情。
可能用401001.SZ 可以拿到行情呢。
查看全部
上去一看。
每一个tick都在报错:
好家伙? 怎么会有个 404001.SS的可转债代码的?
于是顺着代码去调试。 这个代码是从我的接口传过去的。
于是我看了下数据库。
赫然发现了一个蓝盾退债的玩意, 代码正是 404001, 无语中。 怎么这个代码不按常理来的呢。 虽说是三板的股票,可是转债代码改成4字头, 也是奇葩。
刚好也碰巧我的拼接后缀代码:
def modify_code(self, x):
return x + '.SZ' if x.startswith('12') else x + '.SS'
401开头,于是拼接了个.SS 后缀,导致ptrade无法正确识别这个代码行情。
可能用401001.SZ 可以拿到行情呢。

ptrade最多支持同时运行多少个策略?
Ptrade • 李魔佛 发表了文章 • 0 个评论 • 325 次浏览 • 2023-09-21 17:16
但同时运行的策略只有5个。
如果不需要的策略,可以把它暂停了,记住,不要随意暂停。 因为暂停了,重启后你的日志就会随之被清空。
平时也应该做好日志备份的习惯。 部分券商可以连接mysql,可以把数据导出,也可以顺便把日志也导出。
需要开通Ptrade或者代写的朋友可以咨询:
查看全部
Ptrade跟踪雪球组合自动调仓
Ptrade • 李魔佛 发表了文章 • 0 个评论 • 354 次浏览 • 2023-09-19 20:25
根据指定的雪球组合, 自动跟踪组合的调仓与比例.
图随便截取的,具体跟踪的组合,客户自己可以直接配置.
目前是每10分钟刷新一次 组合数据,如果有更新就马上根据调仓.
盘前和收盘前2分钟, 会定期扫码, 以免到了收盘来不及成交, 留够足够的时间下单与撤单.
PS:图片与策略无关
耗时地方仍然是调试.
查看全部
ptrade量化策略:低位首板启动板-首板+低吸+单阳不破
Ptrade • 李魔佛 发表了文章 • 0 个评论 • 469 次浏览 • 2023-09-05 22:44
Ptrade实现实盘自动交易代码。
(图片截图非本策略,随意贴的)

里面细节比较多。
得慢慢调。

国金QMT测试版|模拟盘 安装程序 下载
QMT • 李魔佛 发表了文章 • 0 个评论 • 1095 次浏览 • 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就可以了。费率万一,可半年后免五。
开户后可提供技术相关解答。

国盛证券Ptrade测试版下载 Ptrade模拟客户端 模拟账号
Ptrade • 李魔佛 发表了文章 • 0 个评论 • 557 次浏览 • 2023-09-01 22:53
国盛证券Ptrade测试版下载 Ptrade模拟客户端 模拟账号
仿真客户端
国盛Ptrade测试版 模拟账户下载:
https://download.gszq.com/ptrade/PTrade1.0-Client-V201906-00-000.zip
仿真账户: ***** / ****** 量化回测:支持1分钟、日线回测。 量化交易:支持LEVEL1 tick股票交易。 量化研究:提供云Ipython Notebook研究环境、行情数据2005年至今、可使用全市场金融数据。
虽然ptrade有测试版本,但是个人还是非常不推荐使用测试版本。 以前在上面写过回测或者模拟盘,发现问题非常多,一个是数据缺了,数据错乱。以前被它坑过,后面基本都就不敢用了。 群里的兄弟大部分也被坑过,进群公告就是告诫他们,远离测试版。。。哈
实盘版本的需要开通才能申请,不同券商的门槛不一样。需要的朋友可以扫码咨询:
查看全部
国盛证券Ptrade测试版下载 Ptrade模拟客户端 模拟账号
仿真客户端
国盛Ptrade测试版 模拟账户下载:
https://download.gszq.com/ptrade/PTrade1.0-Client-V201906-00-000.zip
仿真账户: ***** / ****** 量化回测:支持1分钟、日线回测。 量化交易:支持LEVEL1 tick股票交易。 量化研究:提供云Ipython Notebook研究环境、行情数据2005年至今、可使用全市场金融数据。
虽然ptrade有测试版本,但是个人还是非常不推荐使用测试版本。 以前在上面写过回测或者模拟盘,发现问题非常多,一个是数据缺了,数据错乱。以前被它坑过,后面基本都就不敢用了。 群里的兄弟大部分也被坑过,进群公告就是告诫他们,远离测试版。。。哈
实盘版本的需要开通才能申请,不同券商的门槛不一样。需要的朋友可以扫码咨询:

万0.854 免5 量化开户|QMT|Ptrade|掘金量化|国盛证券
券商万一免五 • 李魔佛 发表了文章 • 0 个评论 • 868 次浏览 • 2023-09-01 22:25
为贯彻落实7月24日中央政治局会议精神和国务院相关会议部署,进一步活跃资本市场,提振投资者信心,形成推动经济持续回升向好的工作合力,证监会指导上海证券交易所、深圳证券交易所、北京证券交易所自8月28日起进一步降低证券交易经手费。沪深交易所此次将A股、B股证券交易经手费从按成交金额的0.00487%双向收取下调为按成交金额的0.00341%双向收取,降幅达30%;北交所在2022年12月调降证券交易经手费50%的基础上,再次将证券交易经手费标准降低50%,由按成交金额的0.025%双边收取下调至按成交金额的0.0125%双边收取。同时,将引导证券公司稳妥做好与客户合同变更及相关交易参数的调整,依法降低经纪业务佣金费率,切实将此次证券交易经手费下降的政策效果传导至广大投资者
在今年8月的时候,交易所下调经手费,经手费是交易所收取的。 所以国盛证券响应国家号召,第一时间下调经手费。
从原来的万1免5,下降到现在的万0.854 免5
对于量化交易Ptrade,QMT,交易费率也是一样,下调到万0.854 免五 !!! 简直良心证券呀,有木有!
目前国盛证券的QMT,miniQMT的开通门槛是入金50W, Ptrade的入金门槛也是50W,而且国盛的Ptrade是可以访问外部数据的。比如你的自己的mysql数据库,还有爬虫获取问财数据等等。 开ptrade的我一般推荐你们开通国盛证券的。 而其他 的湘财证券ptrade,是无法获取外部数据,外部网络的。
需要开通的可以扫码微信开通:
备注: 量化开户
非诚勿扰,欢迎其他券商合作!
查看全部
为贯彻落实7月24日中央政治局会议精神和国务院相关会议部署,进一步活跃资本市场,提振投资者信心,形成推动经济持续回升向好的工作合力,证监会指导上海证券交易所、深圳证券交易所、北京证券交易所自8月28日起进一步降低证券交易经手费。沪深交易所此次将A股、B股证券交易经手费从按成交金额的0.00487%双向收取下调为按成交金额的0.00341%双向收取,降幅达30%;北交所在2022年12月调降证券交易经手费50%的基础上,再次将证券交易经手费标准降低50%,由按成交金额的0.025%双边收取下调至按成交金额的0.0125%双边收取。同时,将引导证券公司稳妥做好与客户合同变更及相关交易参数的调整,依法降低经纪业务佣金费率,切实将此次证券交易经手费下降的政策效果传导至广大投资者
在今年8月的时候,交易所下调经手费,经手费是交易所收取的。 所以国盛证券响应国家号召,第一时间下调经手费。
从原来的万1免5,下降到现在的万0.854 免5
对于量化交易Ptrade,QMT,交易费率也是一样,下调到万0.854 免五 !!! 简直良心证券呀,有木有!
目前国盛证券的QMT,miniQMT的开通门槛是入金50W, Ptrade的入金门槛也是50W,而且国盛的Ptrade是可以访问外部数据的。比如你的自己的mysql数据库,还有爬虫获取问财数据等等。 开ptrade的我一般推荐你们开通国盛证券的。 而其他 的湘财证券ptrade,是无法获取外部数据,外部网络的。
需要开通的可以扫码微信开通:

备注: 量化开户
非诚勿扰,欢迎其他券商合作!
国金QMT实盘版本下载地址
QMT • 李魔佛 发表了文章 • 0 个评论 • 945 次浏览 • 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
QMT iQuant miniQMT它们有什么区别?
量化交易 • 李魔佛 发表了文章 • 0 个评论 • 653 次浏览 • 2023-08-18 15:46
对于第一次接触的朋友来说,经常会问到几个问题,QMT和iQuant,miniQMT有什么区别。
首先,QMT和iQuant都是有迅投开发的。miniQMT是在QMT底下的运行的一个极简模式。
接下来将详细的讲讲。
QMT vs iQuant
一般券商采购了迅投的QMT,接入行情数据服务器和交易服务器,和用户资金账户,就可以让他成为自己的量化交易软件。
而iQuant是有国信定制开发的。iQuant它的大部分券商的QMT的功能基本一样。 不同的地方有:
iQuant移除了VBA模型
下图是国金QMT,在新建策略下面,有VBA模型和python模型
而在国信的iQuant的策略开发模式下,只支持python模型,VBA编写模型的功能被移除了。
对于VBA而言,实际是一门古老的语言,至少在互联网领域,已经没见过几个人在用的了。
不过我在查询了一下它的在QMT里面的实盘交易代码,其实它还是挺适合熟悉通达信公式的朋友使用,很多语法是从通达信的公式演变而来的。
iQuant支持投资研究,使用jupyter notebook逐行运行,为了便于调试。
而其他的QMT均没有这个功能。 不过这个功能我试了下,它只是调用我系统的jupyter notebook,而且它有严重的bug,居然运行不了任何代码。(ptrade也有个类似这样的功能,可以逐行调用内置的获取行情的函数,ptrade的是可以正常运行的)
少数券商的QMT无法在虚拟机运行
QMT可以在虚拟机运行,大部分券商的QMT可以在虚拟机里面运行,这也意味这可以云主机服务器运行,比如阿里云,腾讯云这种,在云服务器上网络和系统稳定性都要比你在家里放的主机要好,因为QMT需要一台正在运行的Windows系统,且网络畅通。
只有少数券商的QMT无法在虚拟机里面运行。
之前笔者粗略地对比了下QMT读取的系统信息,异同点字在于磁盘序列号,想要硬刚的读者朋友在可以尝试修改虚拟机的硬盘序列号。
在python编写策略的代码层面,QMT和iQuant的接口文档也基本一致的,可能在一些功能函数上会有些少出入。二者写的python代码可互相在彼此上运行。
QMT 与 miniQMT
miniQMT属于QMT的一个子功能,一个精简功能下的自动交易框架,只支持实盘交易,不支持回测。在miniQMT模式下,你的策略代码将不在固定在自带的那个QMT软件下编写,而是可以自由地使用pycharm,vscode等编辑器,运行的时候直接使用 python xxxx.py 这样的形式启动。
只是券商很少对它进行宣传,以至于用它的人不多。
进入miniQMT的方法: 点击QMT程序,登录时勾选极简模式
注意:极简模式下,需要一直保持者这个miniQMT的登录程序在运行,意味者miniQMT也只能在windows系统下运行。
XtQuant
miniQMT的核心是XtQuant,XtQuant能提供哪些服务?
XtQuant是基于迅投MiniQMT衍生出来的一套完善的Python策略运行框架,对外以Python库的形式提供策略交易所需要的行情和交易相关的API接口。
XtQuant运行依赖环境
XtQuant目前提供的库包括Python3.6、3.7、3.8版本,不同版本的python导入时会自动切换。根据群友反馈,最新的版本可以支持到python3.11。
在运行使用XtQuant的程序前需要先启动MiniQMT客户端。
然后把你的QMT目录下的\bin.x64\Lib\site-packages\xtquant复制到你系统python目录下的site-packages。
然后就可以在你的代码里面导入QMT的函数,包括获取行情数据,下单函数。
它的帮助文档在bin.x64\Lib\site-packages\xtquant\doc 目录下。
从它的帮助文档来看,它是一套和QMT接口函数完全不一样的交易框架。
所以QMT的代码,无法直接拷贝到miniQMT中使用。虽然名字叫miniQMT,但感觉它提供的很多函数功能,要比QMT更为丰富,用户可以掌控的流程更多,更灵活。
iQuant版虽然也有精简版的miniQMT,但它对个人用户不提供下单功能呢,只有获取行情数据,财务数据等的数据权限。
还有一个与之配套的xtdata库,是专门用来获取行情数据的,而xttrade是专门用来交易下单的。
因为xtdata可以获取很多股票,可转债,ETF等等历史数据,所以即使你不用miniQMT做交易,你也可以白嫖它的数据,这比用积分的tushare简直不要太爽。比如可以获取到股票或可转债的日线,分钟线,甚至tick数据。
比如下面的代码就可以获取 众信转债 的某个时间的历史tick数据,并保存到文件。 只要稍微改造下,就可以获取全市场的转债的tick数据。
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)
dump_single_code_tick()
把上面保存为main.py, 然后执行python main.py , 片刻就可以看到生成的文件数据了。
结语
为了便于读者快速浏览帮助文档,可以在公众号后台回复对应的关键词获取对应的帮助文档:
qmt文档
miniqmt文档
如果想要体验qmt或者miniqmt自动交易的朋友,可以后台回复:开通qmt
即可获取低门槛低费率的开通qmt/iQuant的券商开户方式。
知识星球: 查看全部
对于第一次接触的朋友来说,经常会问到几个问题,QMT和iQuant,miniQMT有什么区别。
首先,QMT和iQuant都是有迅投开发的。miniQMT是在QMT底下的运行的一个极简模式。

接下来将详细的讲讲。
QMT vs iQuant
一般券商采购了迅投的QMT,接入行情数据服务器和交易服务器,和用户资金账户,就可以让他成为自己的量化交易软件。

而iQuant是有国信定制开发的。iQuant它的大部分券商的QMT的功能基本一样。 不同的地方有:
iQuant移除了VBA模型
下图是国金QMT,在新建策略下面,有VBA模型和python模型

而在国信的iQuant的策略开发模式下,只支持python模型,VBA编写模型的功能被移除了。

对于VBA而言,实际是一门古老的语言,至少在互联网领域,已经没见过几个人在用的了。
不过我在查询了一下它的在QMT里面的实盘交易代码,其实它还是挺适合熟悉通达信公式的朋友使用,很多语法是从通达信的公式演变而来的。

iQuant支持投资研究,使用jupyter notebook逐行运行,为了便于调试。
而其他的QMT均没有这个功能。 不过这个功能我试了下,它只是调用我系统的jupyter notebook,而且它有严重的bug,居然运行不了任何代码。(ptrade也有个类似这样的功能,可以逐行调用内置的获取行情的函数,ptrade的是可以正常运行的)

少数券商的QMT无法在虚拟机运行
QMT可以在虚拟机运行,大部分券商的QMT可以在虚拟机里面运行,这也意味这可以云主机服务器运行,比如阿里云,腾讯云这种,在云服务器上网络和系统稳定性都要比你在家里放的主机要好,因为QMT需要一台正在运行的Windows系统,且网络畅通。
只有少数券商的QMT无法在虚拟机里面运行。

之前笔者粗略地对比了下QMT读取的系统信息,异同点字在于磁盘序列号,想要硬刚的读者朋友在可以尝试修改虚拟机的硬盘序列号。

在python编写策略的代码层面,QMT和iQuant的接口文档也基本一致的,可能在一些功能函数上会有些少出入。二者写的python代码可互相在彼此上运行。
QMT 与 miniQMT
miniQMT属于QMT的一个子功能,一个精简功能下的自动交易框架,只支持实盘交易,不支持回测。在miniQMT模式下,你的策略代码将不在固定在自带的那个QMT软件下编写,而是可以自由地使用pycharm,vscode等编辑器,运行的时候直接使用 python xxxx.py 这样的形式启动。
只是券商很少对它进行宣传,以至于用它的人不多。
进入miniQMT的方法: 点击QMT程序,登录时勾选极简模式

注意:极简模式下,需要一直保持者这个miniQMT的登录程序在运行,意味者miniQMT也只能在windows系统下运行。
XtQuant
miniQMT的核心是XtQuant,XtQuant能提供哪些服务?
XtQuant是基于迅投MiniQMT衍生出来的一套完善的Python策略运行框架,对外以Python库的形式提供策略交易所需要的行情和交易相关的API接口。
XtQuant运行依赖环境
XtQuant目前提供的库包括Python3.6、3.7、3.8版本,不同版本的python导入时会自动切换。根据群友反馈,最新的版本可以支持到python3.11。
在运行使用XtQuant的程序前需要先启动MiniQMT客户端。
然后把你的QMT目录下的\bin.x64\Lib\site-packages\xtquant复制到你系统python目录下的site-packages。

然后就可以在你的代码里面导入QMT的函数,包括获取行情数据,下单函数。

它的帮助文档在bin.x64\Lib\site-packages\xtquant\doc 目录下。
从它的帮助文档来看,它是一套和QMT接口函数完全不一样的交易框架。

所以QMT的代码,无法直接拷贝到miniQMT中使用。虽然名字叫miniQMT,但感觉它提供的很多函数功能,要比QMT更为丰富,用户可以掌控的流程更多,更灵活。
iQuant版虽然也有精简版的miniQMT,但它对个人用户不提供下单功能呢,只有获取行情数据,财务数据等的数据权限。
还有一个与之配套的xtdata库,是专门用来获取行情数据的,而xttrade是专门用来交易下单的。

因为xtdata可以获取很多股票,可转债,ETF等等历史数据,所以即使你不用miniQMT做交易,你也可以白嫖它的数据,这比用积分的tushare简直不要太爽。比如可以获取到股票或可转债的日线,分钟线,甚至tick数据。
比如下面的代码就可以获取 众信转债 的某个时间的历史tick数据,并保存到文件。 只要稍微改造下,就可以获取全市场的转债的tick数据。
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)
dump_single_code_tick()
把上面保存为main.py, 然后执行python main.py , 片刻就可以看到生成的文件数据了。
结语
为了便于读者快速浏览帮助文档,可以在公众号后台回复对应的关键词获取对应的帮助文档:
qmt文档
miniqmt文档
如果想要体验qmt或者miniqmt自动交易的朋友,可以后台回复:开通qmt
即可获取低门槛低费率的开通qmt/iQuant的券商开户方式。

知识星球:

Ptrade无法获取lof基金的历史数据
量化交易-Ptrade-QMT • 李魔佛 回复了问题 • 2 人关注 • 1 个回复 • 405 次浏览 • 2023-08-17 01:41
哪些券商有miniqmt? 门槛如何
QMT • 李魔佛 发表了文章 • 0 个评论 • 828 次浏览 • 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即可。
所以平时有优惠费率的时候就不要犹犹豫豫,把账户和权限开了再说,因为好事不常有,过了这个桥就没有这个店。
需要开户的盆友可以扫码咨询

ptrade qmt无法登录问题
量化交易 • 李魔佛 发表了文章 • 0 个评论 • 497 次浏览 • 2023-08-08 14:44
实际上这是在周五晚上和周末出现的问题,这是计划内的维护。部分券商没有技术服务支持,用户可能连服务器日常维护服务通知都无法及时得到通知。
PS:其实,大部分券商基本也就那样,ptrade和qmt的技术支持基本等于0,不敢说全部,至少90%的情况是这样的。 以至于我自己维护了一个ptrade,qmt的技术群(审核才可以加),日常有空就在里面解决群友的问题。基本都是些基础问题,部分可能是券商数据问题,大部分是用户的代码问题。 查看全部
20行代码实现Ptrade一键清仓
Ptrade • 李魔佛 发表了文章 • 0 个评论 • 478 次浏览 • 2023-07-28 02:16
万一遇到特殊情况要核的话,管快,1秒清空
def func(context):
pos_dict = get_positions()
for code,pos in pos_dict.items():
enable_amount = pos.enable_amount
if enable_amount>0:
order_target(code, 0)
# 标准
def initialize(context):
# 初始化策略
run_daily(context, func, time='9:25')
def handle_data(context, data):
pass
实际只用11行代码。
如果只清除转债或者股票某个品种,可以在code那里加个判断def func(context):
pos_dict = get_positions()
for code,pos in pos_dict.items():
enable_amount = pos.enable_amount
if enable_amount>0 and code.startswith(('12','11')): # 只清除转债
order_target(code, 0) 查看全部
万一遇到特殊情况要核的话,管快,1秒清空
def func(context):
pos_dict = get_positions()
for code,pos in pos_dict.items():
enable_amount = pos.enable_amount
if enable_amount>0:
order_target(code, 0)
# 标准
def initialize(context):
# 初始化策略
run_daily(context, func, time='9:25')
def handle_data(context, data):
pass
实际只用11行代码。
如果只清除转债或者股票某个品种,可以在code那里加个判断
def func(context):
pos_dict = get_positions()
for code,pos in pos_dict.items():
enable_amount = pos.enable_amount
if enable_amount>0 and code.startswith(('12','11')): # 只清除转债
order_target(code, 0)

ptrade重启策略后日志被清空,正常的操作方式
Ptrade • 李魔佛 发表了文章 • 0 个评论 • 475 次浏览 • 2023-07-25 04:36
然后就心满意足的退出Ptrade。
然后想起来有个日志想要查一下的。再进去一看,里面的几个月的日志就被清除了。 OMG
这个清除日志的操作虽然说是软件设置的。但是产品经理应该也要评估一下,哪怕我只是改一个时间,比如我把策略从9:15分执行改成9:16执行,只要改动,策略就需要被重启,才能生效。
试问,哪个策略能够几年不出错,不修改,一直在上面运行的呢? 退一万步讲,其实如果我知道我即将修改后重启策略,面对这几百个按时间切割的日志,我用什么工具导出呢?
软件自带的导出功能只能按照天数的。
所以对于运行很久的策略,如果需要修改里面的内容,我的建议是,直接停止程序,而不是重启。
然后把你的策略复制到一个新的策略里面,在新的策略里面改动参数。
然后直接运行这个新的策略,这样之前那个策略因为没有被重启,只是停止了,它的日志依然保存在ptrade的日历里面,你只需要选择指定的日期,就可以看到对应的历史数据。
更多ptrade、qmt,掘金的量化交易技巧,请查看星球。
查看全部
然后就心满意足的退出Ptrade。
然后想起来有个日志想要查一下的。再进去一看,里面的几个月的日志就被清除了。 OMG
这个清除日志的操作虽然说是软件设置的。但是产品经理应该也要评估一下,哪怕我只是改一个时间,比如我把策略从9:15分执行改成9:16执行,只要改动,策略就需要被重启,才能生效。
试问,哪个策略能够几年不出错,不修改,一直在上面运行的呢? 退一万步讲,其实如果我知道我即将修改后重启策略,面对这几百个按时间切割的日志,我用什么工具导出呢?
软件自带的导出功能只能按照天数的。
所以对于运行很久的策略,如果需要修改里面的内容,我的建议是,直接停止程序,而不是重启。
然后把你的策略复制到一个新的策略里面,在新的策略里面改动参数。
然后直接运行这个新的策略,这样之前那个策略因为没有被重启,只是停止了,它的日志依然保存在ptrade的日历里面,你只需要选择指定的日期,就可以看到对应的历史数据。
更多ptrade、qmt,掘金的量化交易技巧,请查看星球。

ptrade批量获取股票的昨天的收盘价,转为字典json【一】
Ptrade • 李魔佛 发表了文章 • 0 个评论 • 553 次浏览 • 2023-07-17 19:50
ptrade接口文档:https://ptradeapi.com
笔者这里接写几个最简单的方式,供读者朋友参考。
下面代码适用于实盘,回测。
code_list = ['113578.SS','123014.SZ'] # 股票池,这里可以填几千个股票也没问题的
zz_df_price = get_price(code_list, start_date=None, end_date=None, frequency='1d', fields='close', fq=None, count=1)
yesterday_price_dict = zz_df_price.iloc[0].to_json()
讲解:
1.
code_list = ['113578.SS','123014.SZ'] # 股票池,这里可以填几千个股票也没问题的,比如你可以先拿沪深300指数的成分股,然后传入这个函数。
2.
zz_df_price = get_price(code_list, start_date=None, end_date=None, frequency='1d', fields='close', fq=None, count=1)
get_price: 获取历史数据。 这里不用get_history,因为这个函数太多bug了,主要是券商数据可能是缺的。拿历史数据我基本不敢用get_history。
因为我拿昨天的收盘价,所以我就不指定日期,只用count=1,获取1条数据,因为数据是从最新开始的,那么这一条数据肯定是上一个交易日的。
正常情况返回的数据是一个Pannel,三维的。不过因为filed=‘close',单个字段,特殊情况,这里返回的是一个dataframe
输出:
zz_df_price.iloc[0].to_json()
index 113578.SS 123014.SZ
2023-07-14 93.036 118.36
所以接下来要做的是,获取dataframe的第一行数据,直接转为json
得到:
'{"113578.SS":93.036,"123014.SZ":118.36}'
更多技术支持与解答,欢迎加入星球。
查看全部
ptrade接口文档:https://ptradeapi.com
笔者这里接写几个最简单的方式,供读者朋友参考。
下面代码适用于实盘,回测。
code_list = ['113578.SS','123014.SZ'] # 股票池,这里可以填几千个股票也没问题的
zz_df_price = get_price(code_list, start_date=None, end_date=None, frequency='1d', fields='close', fq=None, count=1)
yesterday_price_dict = zz_df_price.iloc[0].to_json()
讲解:
1.
code_list = ['113578.SS','123014.SZ'] # 股票池,这里可以填几千个股票也没问题的,比如你可以先拿沪深300指数的成分股,然后传入这个函数。
2.
zz_df_price = get_price(code_list, start_date=None, end_date=None, frequency='1d', fields='close', fq=None, count=1)
get_price: 获取历史数据。 这里不用get_history,因为这个函数太多bug了,主要是券商数据可能是缺的。拿历史数据我基本不敢用get_history。
因为我拿昨天的收盘价,所以我就不指定日期,只用count=1,获取1条数据,因为数据是从最新开始的,那么这一条数据肯定是上一个交易日的。
正常情况返回的数据是一个Pannel,三维的。不过因为filed=‘close',单个字段,特殊情况,这里返回的是一个dataframe
输出:
zz_df_price.iloc[0].to_json()
index 113578.SS 123014.SZ
2023-07-14 93.036 118.36
所以接下来要做的是,获取dataframe的第一行数据,直接转为json
得到:
'{"113578.SS":93.036,"123014.SZ":118.36}'
更多技术支持与解答,欢迎加入星球。

Ptrade几个order下单接口 order_target order_value order_target_value order_market的不同
Ptrade • 李魔佛 发表了文章 • 0 个评论 • 555 次浏览 • 2023-07-10 02:23
https://ptradeapi.com
注意:大部分函数自适用于交易模块,回测模式不支持部分order函数。
order_target :
接口通过持仓数量比较将入参的目标数量转换成需要交易的成交,传入 order
接口
order_value:
接口通过 金额/限价 或者 金额/默认最新价 两种方式转换成需要交易的数量,
传入 order 接口
order_target_value:
接口通过持仓金额比较得到需要交易的金额, 金额/限价 或者 金额/默
认最新价 两种方式转换成需要交易的数量,传入 order 接口
order 接口:
一、
先判断 limit_price 是否传入,传入则用传入价格限价,不传入则最新价代替,都是
限价方式报单。
二、
判断隔夜单和交易时间,交易时间(9:10(系统可配)~15:00)范围的订单会马上
加入未处理订单队列,其他订单先放到一个队列,等时间到交易时间就放到未处理订单
队列
三、
未处理订单队列的订单会进行限价判断,如果没有传入限价就按当前最新价处理,
然后报柜台。
order_market 接口:
一、
按照传入的 market_type 参数,市价委托方式报单。
二、
判断隔夜单和交易时间,交易时间(9:10(系统可配)~15:00)范围的订单会马上
加入未处理订单队列,其他订单先放到一个队列,等时间到交易时间就翻到未处理订单
队列
三、
未处理订单队列的订单会进行限价判断,如果没有传入限价就按当前最新价处理,
之后买单和卖单处理有所不同,买单直接报柜台,卖单会校验持仓最大可卖然后调整数
量再报柜台。
tick_order:
一、
先判断 limit_price 是否传入,传入则用传入价格限价,不传入则取档位价格(默
认第一档)
,都是限价方式报单。
二、
直接放到未处理订单队列
三、
未处理订单队列的订单会进行限价判断,如果没有传入限价就按当前最新价处理,
然后报柜台。
低门槛入金(2W)开通Ptrade量化API,扫码联系: 查看全部
https://ptradeapi.com
注意:大部分函数自适用于交易模块,回测模式不支持部分order函数。
order_target :
接口通过持仓数量比较将入参的目标数量转换成需要交易的成交,传入 order
接口
order_value:
接口通过 金额/限价 或者 金额/默认最新价 两种方式转换成需要交易的数量,
传入 order 接口
order_target_value:
接口通过持仓金额比较得到需要交易的金额, 金额/限价 或者 金额/默
认最新价 两种方式转换成需要交易的数量,传入 order 接口
order 接口:
一、
先判断 limit_price 是否传入,传入则用传入价格限价,不传入则最新价代替,都是
限价方式报单。
二、
判断隔夜单和交易时间,交易时间(9:10(系统可配)~15:00)范围的订单会马上
加入未处理订单队列,其他订单先放到一个队列,等时间到交易时间就放到未处理订单
队列
三、
未处理订单队列的订单会进行限价判断,如果没有传入限价就按当前最新价处理,
然后报柜台。
order_market 接口:
一、
按照传入的 market_type 参数,市价委托方式报单。
二、
判断隔夜单和交易时间,交易时间(9:10(系统可配)~15:00)范围的订单会马上
加入未处理订单队列,其他订单先放到一个队列,等时间到交易时间就翻到未处理订单
队列
三、
未处理订单队列的订单会进行限价判断,如果没有传入限价就按当前最新价处理,
之后买单和卖单处理有所不同,买单直接报柜台,卖单会校验持仓最大可卖然后调整数
量再报柜台。
tick_order:
一、
先判断 limit_price 是否传入,传入则用传入价格限价,不传入则取档位价格(默
认第一档)
,都是限价方式报单。
二、
直接放到未处理订单队列
三、
未处理订单队列的订单会进行限价判断,如果没有传入限价就按当前最新价处理,
然后报柜台。
低门槛入金(2W)开通Ptrade量化API,扫码联系:

QMT vs PTrade资金更新速度|高频中如何处理
Ptrade • 李魔佛 发表了文章 • 0 个评论 • 634 次浏览 • 2023-07-06 17:35
平时在手动交易中,下单委托后,再切换回去持仓页面,可以看到你的可用资金变少了。而在QMT和PTrade里面,却可能会表现得不一样。本文用代码和实盘来作对比。希望本文对量化新手有所帮助,记得收藏哦! 公众号首页链接了视频号,里面也有不少的新手入门教程和进阶教程,欢迎观看。
了解量化交易程序里面的资金更新速度,无论对量化T+0日内交易(可转债,T+0 ETF),还是轮动策略调仓,都是必须的。
Ptrade
以交易逆回购为例,这也便于量化新手也可以实践,可以放心跑,不会亏钱。
代码很简单,每个tick_data行情更新时间(3秒)里打印当前的可用资金。中途买入(借出)逆回购后,看看当面打印的可用资金什么时候发生变化。
import datetime
def initialize(context):
# 初始化策略
g.already_run = False
def handle_data(context, data):
pass
def get_available_cash(context):
# 读取变量protfolio里的可用资金的值
return context.portfolio.cash
def current_time():
return datetime.datetime.now().strftime('%H:%M:%S.%f')
def tick_data(context, data):
log.info('可用资金{}'.format(get_available_cash(context)))
if not g.already_run:
g.already_run = True
# 卖出100手 R-001
ret = order_tick('131810.SZ', -10, priceGear='1', limit_price=None)
def on_order_response(context, trade_list):
# 委托回调函数,有委托出现就调用此函数
log.info('已委托下单 {}'.format(current_time()))
放到Ptrade的实盘里执行,得到下面日志
下单前可用资金为17902,程序启动后下单时间在10:41:08,卖出10张R-001,市值1000元;间隔3s后打印可用资金,在10:41:13的时候,可用资金依然是17902,此时时间已经过去了5秒;
在10:41:18打印的时候资产才发生了变化,此时可用资金为16902,此时距离下单时的10:41:08,已经过去了10秒。所以如果在高频下单时,使用读取内置的context.portfolio.cash 来获取可用资金,那就寄了。那是不是意味着Ptrade无法进行高频率的交易了呢?当然不是的,此时可以使用内置的成交主推函数来更新可用资金,后面下面再介绍。
QMT
而qmt的代码如下,把打印的可用资金的操作放到handlebar里面,它和上面的Ptrade作用一样,每隔3s执行一次。
# encoding:gbk
import datetime
ACCOUNT = '你的账户ID'
start = True
def init(ContextInfo):
ContextInfo.set_account(ACCOUNT)
def current_time():
return datetime.datetime.now().strftime('%H:%M:%S.%f')
def get_available_cash(ContextInfo):
acct_info = get_trade_detail_data(ACCOUNT, 'stock', 'account')
return acct_info[0].m_dAvailable
def deal_callback(ContextInfo, dealInfo):
print('before')
print(dealInfo.m_strProductID)
print(dealInfo.m_nDirection)
print(dealInfo.m_dTradeAmount)
print(dealInfo.m_nVolume)
print(dealInfo.m_dPrice)
print('call back --- ')
print(current_time())
def buy_action(ContextInfo):
opType = 24
orderType = 1101
accountID = ACCOUNT
orderCode = '131810.SZ'
prType = 11
price = 1.8
volume = 10
quickTrade = 2
passorder(opType, orderType, accountID, orderCode, prType, price, volume, quickTrade, ContextInfo)
def handlebar(ContextInfo):
global start
if ContextInfo.is_last_bar():
cash = get_available_cash(ContextInfo)
print('{} 可用资金{}'.format(current_time(),cash))
if start:
print('下单逆回购 131810 ')
buy_action(ContextInfo)
start = False
部署到QMT实盘后,执行。
得到下面的运行日志:
从上面的日志看出,程序在14:35:11启动,马上使用passorder下单,卖出1000元的R-001,此时时间14:35:12,马上成交了。而可用资金在下单后的0.47秒后,14:35:12,显示少了1000元。此时的资金状态已经被更新了。
所以QMT的资金持仓更新速度要比Ptrade快出不少的,如果不是追求毫秒级别的话,这个速度足够满足大部分的轮动和T+0操作了。
虽然QMT的资金持仓更新很快,但如果你的策略是高频或偏高频运行,比如你这一个时刻刚刚买入,下一个tick来到时就要卖出,或者采用驱动成交型的网格交易,你无法知道挂单是在哪一个时刻成交的,此时也亦不能一直循环读取你的可以资金或者持仓来判断是否成交,因为这样会阻塞QMT无法进行下一步的操作(除非你本身就是一直在等待成交,成交后才进行下程序一步)。
委托、成交回调函数
Ptrade和QMT都有对应的委托成交回调函数,用于应对需要即时获取成交状态的情景下。
接口文档介绍如下
Ptrade http://ptradeapi.com/#on_trade_response
QMT:http://qmt.ptradeapi.com/QMT_Python_API_Doc.html#deal-callback
里面就说明了,“该函数会在成交主推回调时响应,比引擎和get_trades()函数更新Order状态的速度更快,适合对速度要求比较高的策略。”
Ptrade的部分代码片段如下:
# 交易回调
def on_trade_response(context, trade_list):
# 成交主推
now = context.blotter.current_dt.strftime("%H:%M:%S")
for trade_info in trade_list:
if trade_info['order_id'] == '':
# 不是本策略跳过
log.info('非本策略订单')
continue
code = trade_info['stock_code']
code = post_fix_convert(code)
business_time = trade_info['business_time']
business_amount = trade_info['business_amount'] # 这个是负数,如果卖出
business_price = trade_info['business_price']
g.total_cash -= business_amount # 马上更新资金状态
g.total_cash -= business_amount # 马上更新资金状态g.total_cash是一个全局的可用资金, 可以提前设定好,亦可以是开盘前读取一次你的账户可用资金。
每次成交的那一刻,on_trade_response这个函数就会被动触发,在这里就可以简单的更新你的资金状态了。上面的例子是最基础的更新资金。
实际可以使用其他的诸如dict或类对象来更新仓位。
上面代码是把仓位更新放到一个全局dict里面,key是股票代码,value也是一个dict,里面包含交易时间,持仓数目,价格等等。
好了,时间有限,今天的教程就到这里了,码字不易,欢迎点赞+收藏哦~
查看全部
平时在手动交易中,下单委托后,再切换回去持仓页面,可以看到你的可用资金变少了。而在QMT和PTrade里面,却可能会表现得不一样。本文用代码和实盘来作对比。希望本文对量化新手有所帮助,记得收藏哦! 公众号首页链接了视频号,里面也有不少的新手入门教程和进阶教程,欢迎观看。
了解量化交易程序里面的资金更新速度,无论对量化T+0日内交易(可转债,T+0 ETF),还是轮动策略调仓,都是必须的。
Ptrade
以交易逆回购为例,这也便于量化新手也可以实践,可以放心跑,不会亏钱。
代码很简单,每个tick_data行情更新时间(3秒)里打印当前的可用资金。中途买入(借出)逆回购后,看看当面打印的可用资金什么时候发生变化。
import datetime
def initialize(context):
# 初始化策略
g.already_run = False
def handle_data(context, data):
pass
def get_available_cash(context):
# 读取变量protfolio里的可用资金的值
return context.portfolio.cash
def current_time():
return datetime.datetime.now().strftime('%H:%M:%S.%f')
def tick_data(context, data):
log.info('可用资金{}'.format(get_available_cash(context)))
if not g.already_run:
g.already_run = True
# 卖出100手 R-001
ret = order_tick('131810.SZ', -10, priceGear='1', limit_price=None)
def on_order_response(context, trade_list):
# 委托回调函数,有委托出现就调用此函数
log.info('已委托下单 {}'.format(current_time()))
放到Ptrade的实盘里执行,得到下面日志
下单前可用资金为17902,程序启动后下单时间在10:41:08,卖出10张R-001,市值1000元;间隔3s后打印可用资金,在10:41:13的时候,可用资金依然是17902,此时时间已经过去了5秒;
在10:41:18打印的时候资产才发生了变化,此时可用资金为16902,此时距离下单时的10:41:08,已经过去了10秒。所以如果在高频下单时,使用读取内置的context.portfolio.cash 来获取可用资金,那就寄了。那是不是意味着Ptrade无法进行高频率的交易了呢?当然不是的,此时可以使用内置的成交主推函数来更新可用资金,后面下面再介绍。
QMT
而qmt的代码如下,把打印的可用资金的操作放到handlebar里面,它和上面的Ptrade作用一样,每隔3s执行一次。
# encoding:gbk
import datetime
ACCOUNT = '你的账户ID'
start = True
def init(ContextInfo):
ContextInfo.set_account(ACCOUNT)
def current_time():
return datetime.datetime.now().strftime('%H:%M:%S.%f')
def get_available_cash(ContextInfo):
acct_info = get_trade_detail_data(ACCOUNT, 'stock', 'account')
return acct_info[0].m_dAvailable
def deal_callback(ContextInfo, dealInfo):
print('before')
print(dealInfo.m_strProductID)
print(dealInfo.m_nDirection)
print(dealInfo.m_dTradeAmount)
print(dealInfo.m_nVolume)
print(dealInfo.m_dPrice)
print('call back --- ')
print(current_time())
def buy_action(ContextInfo):
opType = 24
orderType = 1101
accountID = ACCOUNT
orderCode = '131810.SZ'
prType = 11
price = 1.8
volume = 10
quickTrade = 2
passorder(opType, orderType, accountID, orderCode, prType, price, volume, quickTrade, ContextInfo)
def handlebar(ContextInfo):
global start
if ContextInfo.is_last_bar():
cash = get_available_cash(ContextInfo)
print('{} 可用资金{}'.format(current_time(),cash))
if start:
print('下单逆回购 131810 ')
buy_action(ContextInfo)
start = False
部署到QMT实盘后,执行。
得到下面的运行日志:
从上面的日志看出,程序在14:35:11启动,马上使用passorder下单,卖出1000元的R-001,此时时间14:35:12,马上成交了。而可用资金在下单后的0.47秒后,14:35:12,显示少了1000元。此时的资金状态已经被更新了。
所以QMT的资金持仓更新速度要比Ptrade快出不少的,如果不是追求毫秒级别的话,这个速度足够满足大部分的轮动和T+0操作了。
虽然QMT的资金持仓更新很快,但如果你的策略是高频或偏高频运行,比如你这一个时刻刚刚买入,下一个tick来到时就要卖出,或者采用驱动成交型的网格交易,你无法知道挂单是在哪一个时刻成交的,此时也亦不能一直循环读取你的可以资金或者持仓来判断是否成交,因为这样会阻塞QMT无法进行下一步的操作(除非你本身就是一直在等待成交,成交后才进行下程序一步)。
委托、成交回调函数
Ptrade和QMT都有对应的委托成交回调函数,用于应对需要即时获取成交状态的情景下。
接口文档介绍如下
Ptrade http://ptradeapi.com/#on_trade_response
QMT:http://qmt.ptradeapi.com/QMT_Python_API_Doc.html#deal-callback
里面就说明了,“该函数会在成交主推回调时响应,比引擎和get_trades()函数更新Order状态的速度更快,适合对速度要求比较高的策略。”
Ptrade的部分代码片段如下:
# 交易回调
def on_trade_response(context, trade_list):
# 成交主推
now = context.blotter.current_dt.strftime("%H:%M:%S")
for trade_info in trade_list:
if trade_info['order_id'] == '':
# 不是本策略跳过
log.info('非本策略订单')
continue
code = trade_info['stock_code']
code = post_fix_convert(code)
business_time = trade_info['business_time']
business_amount = trade_info['business_amount'] # 这个是负数,如果卖出
business_price = trade_info['business_price']
g.total_cash -= business_amount # 马上更新资金状态
g.total_cash -= business_amount # 马上更新资金状态g.total_cash是一个全局的可用资金, 可以提前设定好,亦可以是开盘前读取一次你的账户可用资金。
每次成交的那一刻,on_trade_response这个函数就会被动触发,在这里就可以简单的更新你的资金状态了。上面的例子是最基础的更新资金。
实际可以使用其他的诸如dict或类对象来更新仓位。
上面代码是把仓位更新放到一个全局dict里面,key是股票代码,value也是一个dict,里面包含交易时间,持仓数目,价格等等。
好了,时间有限,今天的教程就到这里了,码字不易,欢迎点赞+收藏哦~

目前支持量化接口的万一免五的券商有哪些?
量化交易-Ptrade-QMT • 李魔佛 发表了文章 • 0 个评论 • 1443 次浏览 • 2023-07-04 22:52
其中能够股票免五的有国金证券,国盛证券,国信证券,安信证券。
其中,国金证券,国盛证券支持QMT、MiniQMT、Ptrade。
国信证券,安信证券支持QMT。
东莞证券支持Ptrade
可转债默认免五。
开户后可加入量化技术交流群,可获得编程技术指导。
【提问者需要把问题描述清楚即可,PS: 有些人动不动就说:“Ptrade不行呀”,“QMT垃圾呀”,结果让他贴代码上来瞅瞅,是他本身代码写的拉垮,目前贴出来的已知的问题,90%是个人代码问题。】
扫码添加微信咨询开户:
查看全部
Ptrade/QMT 可转债转股操作 python代码
量化交易 • 李魔佛 发表了文章 • 0 个评论 • 843 次浏览 • 2023-06-19 18:14
而这个转股操作是要在交易时间,也就是盘中时间下一个债转股的命令,然后盘后交易所会更会你盘中下的转股指令,将对应的可转债转为对应的股票,这是,持仓里面的可转债会消失,变成该可转债对应的正股。
(当然这是在全部转股的前提下的情况,也有可能有部分人转债只转一部分,这样持仓里面还仍然会有部分可转债没有被转为股票)
那么在Ptrade和QMT里面,如何调用API接口进行可转债转股呢?
Ptrade:
def initialize(context):
g.security = "600570.SS"
set_universe(g.security)
def before_trading_start(context, data):
g.count = 0
def handle_data(context, data):
if g.count == 0:
# 对持仓内的贝斯进行转股操作
debt_to_stock_order("123075.SZ", -1000)
g.count += 1
# 查看委托状态
log.info(get_orders())
g.count += 1
主要是上面的函数,
debt_to_stock_order 传入可转债代码和转股的数量,注意数量用加一个负号。
QMT可转债转股操作
#coding:gbk
c = True
account = '11111111' # 个人账户
def init(ContextInfo):
pass
def handlebar(ContextInfo):
if not ContextInfo.is_last_bar():
#历史k线不应该发出实盘信号 跳过
return
if c:
passorder(80,1101,account,s,5,0,-100,'1',2,'tzbz',ContextInfo)
c=False
passorder 里面的 80是 普通账户可转债转股
更多Ptrade,qmt知识,可以关注公众号
查看全部
而这个转股操作是要在交易时间,也就是盘中时间下一个债转股的命令,然后盘后交易所会更会你盘中下的转股指令,将对应的可转债转为对应的股票,这是,持仓里面的可转债会消失,变成该可转债对应的正股。
(当然这是在全部转股的前提下的情况,也有可能有部分人转债只转一部分,这样持仓里面还仍然会有部分可转债没有被转为股票)
那么在Ptrade和QMT里面,如何调用API接口进行可转债转股呢?
Ptrade:
def initialize(context):
g.security = "600570.SS"
set_universe(g.security)
def before_trading_start(context, data):
g.count = 0
def handle_data(context, data):
if g.count == 0:
# 对持仓内的贝斯进行转股操作
debt_to_stock_order("123075.SZ", -1000)
g.count += 1
# 查看委托状态
log.info(get_orders())
g.count += 1
主要是上面的函数,
debt_to_stock_order 传入可转债代码和转股的数量,注意数量用加一个负号。
QMT可转债转股操作
#coding:gbk
c = True
account = '11111111' # 个人账户
def init(ContextInfo):
pass
def handlebar(ContextInfo):
if not ContextInfo.is_last_bar():
#历史k线不应该发出实盘信号 跳过
return
if c:
passorder(80,1101,account,s,5,0,-100,'1',2,'tzbz',ContextInfo)
c=False
passorder 里面的 80是 普通账户可转债转股
更多Ptrade,qmt知识,可以关注公众号

国盛Ptrade又可以重新开了,需要的小伙伴抓紧开啦
Ptrade • 李魔佛 发表了文章 • 0 个评论 • 823 次浏览 • 2023-06-14 11:34
而目前又可以重新开启这个量化业务了。
如果不太懂的小伙伴,笔者这里可以稍加详细解释。
这里的外网,指的外部网络,相对券商部署的服务器内网而言的,并不是指墙外的网络哈,这里小伙伴们注意一下哈。
在大部分券商里,Ptrade是封闭环境下运行的,Ptrade是在券商的内部服务器上执行,所以它无法把数据传出外部的服务器,同样也不能访问外面服务器的数据。比如我想获取同花顺的热门概念,由于Ptrade无法访问外部网络,如果内置的Ptrade数据没有提供,就没有办法了。或者用Ptrade想要搞点可转债溢价率,规模的数据,如果没办法联通外网,实际你的策略就无法下手,因为基础数据已经缺乏了。
好在国盛的Ptrade支持外网联通,可以用爬虫的方式,读取mysql的方式,读取MQ队列的方式的等等获取外部数据,弥补内置数据的不足。
具体可以看这个文章:
http://30daydo.com/article/44453
比如下面代码是在ptrade里面访问百度的:
import requests
def initialize(context):
# 初始化策略
g.security = "600570.SS"
set_universe(g.security)
def handle_data(context, data):
url='http://www.baidu.com'
headers={'User-Agent':'Google'}
try:
r=requests.get(url,headers=headers)
r.encoding='utf8'
print(r.text)
except Exception as e:
print('error')
print(e)
可以看到能够使用requests这个库正常获取数据的,当然requests库是ptrade本身就有的,不需要你再pip安装,当然ptrade也无法pip安装第三方库。
ptrade支持的内置库名单:
http://www.30daydo.com/article/44458
APScheduler (3.3.1)
arch (3.2)
bcolz (1.2.1)
beautifulsoup4 (4.6.0)
bleach (1.5.0)
boto (2.43.0)
Bottleneck (1.0.0)
bz2file (0.98)
cachetools (3.1.0)
click (4.0)
contextlib2 (0.4.0)
crypto (1.4.1)
cvxopt (1.1.8)
cx-Oracle (8.0.1)
cycler (0.10.0)
cyordereddict (0.2.2)
Cython (0.22.1)
decorator (4.0.10)
entrypoints (0.2.2)
fastcache (1.0.2)
gensim (0.13.3)
h5py (2.6.0)
hmmlearn (0.2.0)
hs-udata (0.3.6)
html5lib (0.9999999)
ipykernel (4.5.0)
ipython (5.1.0)
ipython-genutils (0.1.0)
ipywidgets (5.2.2)
jieba (0.38)
Jinja2 (2.8)
jsonpickle (1.0)
jsonschema (2.5.1)
jupyter (1.0.0)
jupyter-client (4.4.0)
jupyter-console (5.0.0)
jupyter-core (4.2.0)
jupyter-kernel-gateway (1.1.1)
Keras (2.3.1)
Keras-Applications (1.0.8)
Keras-Preprocessing (1.1.0)
line-profiler (2.1.2)
Logbook (1.4.3)
lxml (4.5.0)
Markdown (2.2.0)
MarkupSafe (0.23)
matplotlib (1.5.3)
mistune (0.7.3)
Naked (0.1.31)
nbconvert (4.2.0)
nbformat (4.1.0)
networkx (1.9.1)
nose (1.3.6)
notebook (4.2.3)
numexpr (2.6.1)
numpy (1.11.2)
pandas (0.23.4)
patsy (0.4.0)
pexpect (4.2.1)
pickleshare (0.7.4)
pip (9.0.1)
pkgconfig (1.0.0)
prompt-toolkit (1.0.8)
protobuf (3.3.0)
ptvsd (2.2.0)
ptyprocess (0.5.1)
PyBrain (0.3)
pycrypto (2.6.1)
Pygments (2.1.3)
PyMySQL (0.9.3)
pyparsing (2.1.10)
python-dateutil (2.7.5)
pytz (2015.4)
PyWavelets (0.4.0)
PyYAML (5.3.1)
pyzmq (16.1.0.dev0)
qtconsole (4.2.1)
requests (2.7.0)
retrying (1.3.3)
scikit-learn (0.18)
scipy (0.18.0)
seaborn (0.7.1)
setuptools (28.7.1)
setuptools-scm (3.1.0)
shellescape (3.4.1)
simplegeneric (0.8.1)
simplejson (3.17.0)
six (1.10.0)
sklearn (0.0)
smart-open (1.3.5)
SQLAlchemy (1.0.8)
statsmodels (0.10.2)
TA-Lib (0.4.10)
tables (3.3.0)
tabulate (0.7.5)
tensorflow (1.3.0rc1)
tensorflow-tensorboard (0.1.2)
terminado (0.6)
Theano (0.8.2)
toolz (0.7.4)
tornado (4.4.2)
traitlets (4.3.1)
tushare (1.2.48)
tzlocal (1.3)
wcwidth (0.1.7)
Werkzeug (0.12.2)
wheel (0.29.0)
widgetsnbextension (1.2.6)
xcsc-tushare (1.0.0)
xgboost (0.6a2)
xlrd (1.1.0)
xlwt (1.3.0)
zipline (0.8.3)
You are using pip version 9.0.1, however version 22.1.2 is available.
You should consider upgrading via the 'pip install --upgrade pip' command.
需要开户可以关注微信公众号
费率优惠多多(万一免五)
后台回复:ptrade开通
查看全部
而目前又可以重新开启这个量化业务了。
如果不太懂的小伙伴,笔者这里可以稍加详细解释。
这里的外网,指的外部网络,相对券商部署的服务器内网而言的,并不是指墙外的网络哈,这里小伙伴们注意一下哈。
在大部分券商里,Ptrade是封闭环境下运行的,Ptrade是在券商的内部服务器上执行,所以它无法把数据传出外部的服务器,同样也不能访问外面服务器的数据。比如我想获取同花顺的热门概念,由于Ptrade无法访问外部网络,如果内置的Ptrade数据没有提供,就没有办法了。或者用Ptrade想要搞点可转债溢价率,规模的数据,如果没办法联通外网,实际你的策略就无法下手,因为基础数据已经缺乏了。
好在国盛的Ptrade支持外网联通,可以用爬虫的方式,读取mysql的方式,读取MQ队列的方式的等等获取外部数据,弥补内置数据的不足。
具体可以看这个文章:
http://30daydo.com/article/44453
比如下面代码是在ptrade里面访问百度的:
import requests
def initialize(context):
# 初始化策略
g.security = "600570.SS"
set_universe(g.security)
def handle_data(context, data):
url='http://www.baidu.com'
headers={'User-Agent':'Google'}
try:
r=requests.get(url,headers=headers)
r.encoding='utf8'
print(r.text)
except Exception as e:
print('error')
print(e)

可以看到能够使用requests这个库正常获取数据的,当然requests库是ptrade本身就有的,不需要你再pip安装,当然ptrade也无法pip安装第三方库。
ptrade支持的内置库名单:
http://www.30daydo.com/article/44458
APScheduler (3.3.1)
arch (3.2)
bcolz (1.2.1)
beautifulsoup4 (4.6.0)
bleach (1.5.0)
boto (2.43.0)
Bottleneck (1.0.0)
bz2file (0.98)
cachetools (3.1.0)
click (4.0)
contextlib2 (0.4.0)
crypto (1.4.1)
cvxopt (1.1.8)
cx-Oracle (8.0.1)
cycler (0.10.0)
cyordereddict (0.2.2)
Cython (0.22.1)
decorator (4.0.10)
entrypoints (0.2.2)
fastcache (1.0.2)
gensim (0.13.3)
h5py (2.6.0)
hmmlearn (0.2.0)
hs-udata (0.3.6)
html5lib (0.9999999)
ipykernel (4.5.0)
ipython (5.1.0)
ipython-genutils (0.1.0)
ipywidgets (5.2.2)
jieba (0.38)
Jinja2 (2.8)
jsonpickle (1.0)
jsonschema (2.5.1)
jupyter (1.0.0)
jupyter-client (4.4.0)
jupyter-console (5.0.0)
jupyter-core (4.2.0)
jupyter-kernel-gateway (1.1.1)
Keras (2.3.1)
Keras-Applications (1.0.8)
Keras-Preprocessing (1.1.0)
line-profiler (2.1.2)
Logbook (1.4.3)
lxml (4.5.0)
Markdown (2.2.0)
MarkupSafe (0.23)
matplotlib (1.5.3)
mistune (0.7.3)
Naked (0.1.31)
nbconvert (4.2.0)
nbformat (4.1.0)
networkx (1.9.1)
nose (1.3.6)
notebook (4.2.3)
numexpr (2.6.1)
numpy (1.11.2)
pandas (0.23.4)
patsy (0.4.0)
pexpect (4.2.1)
pickleshare (0.7.4)
pip (9.0.1)
pkgconfig (1.0.0)
prompt-toolkit (1.0.8)
protobuf (3.3.0)
ptvsd (2.2.0)
ptyprocess (0.5.1)
PyBrain (0.3)
pycrypto (2.6.1)
Pygments (2.1.3)
PyMySQL (0.9.3)
pyparsing (2.1.10)
python-dateutil (2.7.5)
pytz (2015.4)
PyWavelets (0.4.0)
PyYAML (5.3.1)
pyzmq (16.1.0.dev0)
qtconsole (4.2.1)
requests (2.7.0)
retrying (1.3.3)
scikit-learn (0.18)
scipy (0.18.0)
seaborn (0.7.1)
setuptools (28.7.1)
setuptools-scm (3.1.0)
shellescape (3.4.1)
simplegeneric (0.8.1)
simplejson (3.17.0)
six (1.10.0)
sklearn (0.0)
smart-open (1.3.5)
SQLAlchemy (1.0.8)
statsmodels (0.10.2)
TA-Lib (0.4.10)
tables (3.3.0)
tabulate (0.7.5)
tensorflow (1.3.0rc1)
tensorflow-tensorboard (0.1.2)
terminado (0.6)
Theano (0.8.2)
toolz (0.7.4)
tornado (4.4.2)
traitlets (4.3.1)
tushare (1.2.48)
tzlocal (1.3)
wcwidth (0.1.7)
Werkzeug (0.12.2)
wheel (0.29.0)
widgetsnbextension (1.2.6)
xcsc-tushare (1.0.0)
xgboost (0.6a2)
xlrd (1.1.0)
xlwt (1.3.0)
zipline (0.8.3)
You are using pip version 9.0.1, however version 22.1.2 is available.
You should consider upgrading via the 'pip install --upgrade pip' command.
需要开户可以关注微信公众号
费率优惠多多(万一免五)

后台回复:ptrade开通
国金证券QMT量化新人培训教程
QMT • 李魔佛 发表了文章 • 0 个评论 • 2122 次浏览 • 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获取实时分笔委托数据用哪个函数?
QMT • 李魔佛 发表了文章 • 0 个评论 • 824 次浏览 • 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 | Ptrade 量化策略代写服务
量化交易 • 李魔佛 发表了文章 • 0 个评论 • 297 次浏览 • 2023-11-01 10:43
多年交易经验,量化交易与开发经验。所以很多策略,其实用户大体描述,就知道要注意哪些地方,会提出一些建议,用户要注意,需不需要添加一些判读条件等等。(当然,策略的具体参数都是设置可以调节的,你不需要把实际的参数告诉我,代码给你后,你自己运行策略的时候把你策略的真正参数填上去就好了。)
有偿,收费,价格美丽。根据策略实际的复杂程度与预估的工时,收费。(不根据代码数量,因为我写代码很精简)
我也帮你们咨询过了迅投的客服。 因为他们官网也有提供策略代写服务。他们是不问你策略,直接是5000起步哦。然后根据策略,在5000的基础上不断加。
咨询完,我都感觉我自己以前的报价太低了,呜。
PS: 之前还有迅投的前员工私底下接单写策略,然后到我的星球里面白嫖我的代码,调用我接口数据,被我发现后举报到星球的。后面那个客户发现代码里面藏有我的公众号信息哈,找到我让我修改接口数据哈。
需要的代写策略的盆友,可以关注公众号,在菜单栏那里的“代写量化程序”或者 后台回复:策略代写,获取联系方式哦
扫码关注公众号:
查看全部
迅投的QMT和恒生电子的Ptrade, 还有掘金, 量化策略编程, 实盘和回测都行。只要你的需求明确,白纸黑字描述清楚,都可以做。股票,ETF,可转债都行。
多年交易经验,量化交易与开发经验。所以很多策略,其实用户大体描述,就知道要注意哪些地方,会提出一些建议,用户要注意,需不需要添加一些判读条件等等。(当然,策略的具体参数都是设置可以调节的,你不需要把实际的参数告诉我,代码给你后,你自己运行策略的时候把你策略的真正参数填上去就好了。)
有偿,收费,价格美丽。根据策略实际的复杂程度与预估的工时,收费。(不根据代码数量,因为我写代码很精简)
我也帮你们咨询过了迅投的客服。 因为他们官网也有提供策略代写服务。他们是不问你策略,直接是5000起步哦。然后根据策略,在5000的基础上不断加。
咨询完,我都感觉我自己以前的报价太低了,呜。
PS: 之前还有迅投的前员工私底下接单写策略,然后到我的星球里面白嫖我的代码,调用我接口数据,被我发现后举报到星球的。后面那个客户发现代码里面藏有我的公众号信息哈,找到我让我修改接口数据哈。
需要的代写策略的盆友,可以关注公众号,在菜单栏那里的“代写量化程序”或者 后台回复:策略代写,获取联系方式哦
扫码关注公众号:

小市值轮动-量化交易-程序化交易-Ptrade实盘
Ptrade • 李魔佛 发表了文章 • 0 个评论 • 461 次浏览 • 2023-10-07 14:14
当前策略持有30只。
点击查看大图
点击查看大图
基于股票的策略不敢多买,属于试验阶段,后期仍然会不断根据市场调仓; 主仓依然在可转债。
公众号:可转债量化分析
如果需要策略代写,(ptrade、qmt,其他量化平台)
可以公众号后台回复:
策略代写
查看全部
ptrade qmt无法登录问题
量化交易 • 李魔佛 发表了文章 • 0 个评论 • 497 次浏览 • 2023-08-08 14:44
实际上这是在周五晚上和周末出现的问题,这是计划内的维护。部分券商没有技术服务支持,用户可能连服务器日常维护服务通知都无法及时得到通知。
PS:其实,大部分券商基本也就那样,ptrade和qmt的技术支持基本等于0,不敢说全部,至少90%的情况是这样的。 以至于我自己维护了一个ptrade,qmt的技术群(审核才可以加),日常有空就在里面解决群友的问题。基本都是些基础问题,部分可能是券商数据问题,大部分是用户的代码问题。 查看全部
ptrade批量获取股票的昨天的收盘价,转为字典json【一】
Ptrade • 李魔佛 发表了文章 • 0 个评论 • 553 次浏览 • 2023-07-17 19:50
ptrade接口文档:https://ptradeapi.com
笔者这里接写几个最简单的方式,供读者朋友参考。
下面代码适用于实盘,回测。
code_list = ['113578.SS','123014.SZ'] # 股票池,这里可以填几千个股票也没问题的
zz_df_price = get_price(code_list, start_date=None, end_date=None, frequency='1d', fields='close', fq=None, count=1)
yesterday_price_dict = zz_df_price.iloc[0].to_json()
讲解:
1.
code_list = ['113578.SS','123014.SZ'] # 股票池,这里可以填几千个股票也没问题的,比如你可以先拿沪深300指数的成分股,然后传入这个函数。
2.
zz_df_price = get_price(code_list, start_date=None, end_date=None, frequency='1d', fields='close', fq=None, count=1)
get_price: 获取历史数据。 这里不用get_history,因为这个函数太多bug了,主要是券商数据可能是缺的。拿历史数据我基本不敢用get_history。
因为我拿昨天的收盘价,所以我就不指定日期,只用count=1,获取1条数据,因为数据是从最新开始的,那么这一条数据肯定是上一个交易日的。
正常情况返回的数据是一个Pannel,三维的。不过因为filed=‘close',单个字段,特殊情况,这里返回的是一个dataframe
输出:
zz_df_price.iloc[0].to_json()
index 113578.SS 123014.SZ
2023-07-14 93.036 118.36
所以接下来要做的是,获取dataframe的第一行数据,直接转为json
得到:
'{"113578.SS":93.036,"123014.SZ":118.36}'
更多技术支持与解答,欢迎加入星球。
查看全部
ptrade接口文档:https://ptradeapi.com
笔者这里接写几个最简单的方式,供读者朋友参考。
下面代码适用于实盘,回测。
code_list = ['113578.SS','123014.SZ'] # 股票池,这里可以填几千个股票也没问题的
zz_df_price = get_price(code_list, start_date=None, end_date=None, frequency='1d', fields='close', fq=None, count=1)
yesterday_price_dict = zz_df_price.iloc[0].to_json()
讲解:
1.
code_list = ['113578.SS','123014.SZ'] # 股票池,这里可以填几千个股票也没问题的,比如你可以先拿沪深300指数的成分股,然后传入这个函数。
2.
zz_df_price = get_price(code_list, start_date=None, end_date=None, frequency='1d', fields='close', fq=None, count=1)
get_price: 获取历史数据。 这里不用get_history,因为这个函数太多bug了,主要是券商数据可能是缺的。拿历史数据我基本不敢用get_history。
因为我拿昨天的收盘价,所以我就不指定日期,只用count=1,获取1条数据,因为数据是从最新开始的,那么这一条数据肯定是上一个交易日的。
正常情况返回的数据是一个Pannel,三维的。不过因为filed=‘close',单个字段,特殊情况,这里返回的是一个dataframe
输出:
zz_df_price.iloc[0].to_json()
index 113578.SS 123014.SZ
2023-07-14 93.036 118.36
所以接下来要做的是,获取dataframe的第一行数据,直接转为json
得到:
'{"113578.SS":93.036,"123014.SZ":118.36}'
更多技术支持与解答,欢迎加入星球。

目前支持量化接口的万一免五的券商有哪些?
量化交易-Ptrade-QMT • 李魔佛 发表了文章 • 0 个评论 • 1443 次浏览 • 2023-07-04 22:52
其中能够股票免五的有国金证券,国盛证券,国信证券,安信证券。
其中,国金证券,国盛证券支持QMT、MiniQMT、Ptrade。
国信证券,安信证券支持QMT。
东莞证券支持Ptrade
可转债默认免五。
开户后可加入量化技术交流群,可获得编程技术指导。
【提问者需要把问题描述清楚即可,PS: 有些人动不动就说:“Ptrade不行呀”,“QMT垃圾呀”,结果让他贴代码上来瞅瞅,是他本身代码写的拉垮,目前贴出来的已知的问题,90%是个人代码问题。】
扫码添加微信咨询开户:
查看全部
Ptrade/QMT 可转债转股操作 python代码
量化交易 • 李魔佛 发表了文章 • 0 个评论 • 843 次浏览 • 2023-06-19 18:14
而这个转股操作是要在交易时间,也就是盘中时间下一个债转股的命令,然后盘后交易所会更会你盘中下的转股指令,将对应的可转债转为对应的股票,这是,持仓里面的可转债会消失,变成该可转债对应的正股。
(当然这是在全部转股的前提下的情况,也有可能有部分人转债只转一部分,这样持仓里面还仍然会有部分可转债没有被转为股票)
那么在Ptrade和QMT里面,如何调用API接口进行可转债转股呢?
Ptrade:
def initialize(context):
g.security = "600570.SS"
set_universe(g.security)
def before_trading_start(context, data):
g.count = 0
def handle_data(context, data):
if g.count == 0:
# 对持仓内的贝斯进行转股操作
debt_to_stock_order("123075.SZ", -1000)
g.count += 1
# 查看委托状态
log.info(get_orders())
g.count += 1
主要是上面的函数,
debt_to_stock_order 传入可转债代码和转股的数量,注意数量用加一个负号。
QMT可转债转股操作
#coding:gbk
c = True
account = '11111111' # 个人账户
def init(ContextInfo):
pass
def handlebar(ContextInfo):
if not ContextInfo.is_last_bar():
#历史k线不应该发出实盘信号 跳过
return
if c:
passorder(80,1101,account,s,5,0,-100,'1',2,'tzbz',ContextInfo)
c=False
passorder 里面的 80是 普通账户可转债转股
更多Ptrade,qmt知识,可以关注公众号
查看全部
而这个转股操作是要在交易时间,也就是盘中时间下一个债转股的命令,然后盘后交易所会更会你盘中下的转股指令,将对应的可转债转为对应的股票,这是,持仓里面的可转债会消失,变成该可转债对应的正股。
(当然这是在全部转股的前提下的情况,也有可能有部分人转债只转一部分,这样持仓里面还仍然会有部分可转债没有被转为股票)
那么在Ptrade和QMT里面,如何调用API接口进行可转债转股呢?
Ptrade:
def initialize(context):
g.security = "600570.SS"
set_universe(g.security)
def before_trading_start(context, data):
g.count = 0
def handle_data(context, data):
if g.count == 0:
# 对持仓内的贝斯进行转股操作
debt_to_stock_order("123075.SZ", -1000)
g.count += 1
# 查看委托状态
log.info(get_orders())
g.count += 1
主要是上面的函数,
debt_to_stock_order 传入可转债代码和转股的数量,注意数量用加一个负号。
QMT可转债转股操作
#coding:gbk
c = True
account = '11111111' # 个人账户
def init(ContextInfo):
pass
def handlebar(ContextInfo):
if not ContextInfo.is_last_bar():
#历史k线不应该发出实盘信号 跳过
return
if c:
passorder(80,1101,account,s,5,0,-100,'1',2,'tzbz',ContextInfo)
c=False
passorder 里面的 80是 普通账户可转债转股
更多Ptrade,qmt知识,可以关注公众号

国金证券QMT量化新人培训教程
QMT • 李魔佛 发表了文章 • 0 个评论 • 2122 次浏览 • 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快速上手量化策略(七) 下单代码编写
欢迎观看并提出疑问。
公众号:可转债量化分析

用户问的比较多的关于ptrade基础问题
Ptrade • 李魔佛 发表了文章 • 0 个评论 • 1040 次浏览 • 2023-05-04 01:19
1. 国金的Ptrade 实盘交易客户端是无法进行回测的,在任何时间段;
而模拟客户端可以,可以找自己的经理申请一个Ptrade模拟客户端账户;
2. 国盛的Ptrade实盘交易客户端仅在交易时间无法回测,但非交易时间可以回测;
主要是因为实盘回测和交易在同一个服务器,回测占用过多资源会影响实盘交易;模拟客户端没有这个问题;
任何时间段均可以回测; (之前某个券商的ptrade实盘服务器,因为某个用户开了40多个回测策略,一直在后台运行,而且是关于运算密集型的,导致实盘交易的程序也崩溃了)
3. 国金Ptrade无法回测星球上面的可转债实盘代码,实盘代码是基于当前的实时数据,用来进行回测没有意义,因为获取不到可转债的历史数据(溢价率,规模等),只有历史的价格数据;
4. 国金Ptrade无法使用星球上的可转债代码进行实盘,因为无法访问外网,无法访问我部署的接口数据; 而国盛的Ptrade可以;如果国金Ptrade需要实盘交易可转债,需要手工上传一些基础数据,Ptrade提供上传功能,具体操作可查找星球相关文章;
5. 在共享的Ptrade模拟试用账户上,不要保留个人代码记录,跑完后记得删除,否则其他共有同一个账户的人可以进去修改复制你的策略和代码;如果是单独的个人模拟账户,则没有这个问题。
查看全部
1. 国金的Ptrade 实盘交易客户端是无法进行回测的,在任何时间段;
而模拟客户端可以,可以找自己的经理申请一个Ptrade模拟客户端账户;
2. 国盛的Ptrade实盘交易客户端仅在交易时间无法回测,但非交易时间可以回测;
主要是因为实盘回测和交易在同一个服务器,回测占用过多资源会影响实盘交易;模拟客户端没有这个问题;
任何时间段均可以回测; (之前某个券商的ptrade实盘服务器,因为某个用户开了40多个回测策略,一直在后台运行,而且是关于运算密集型的,导致实盘交易的程序也崩溃了)
3. 国金Ptrade无法回测星球上面的可转债实盘代码,实盘代码是基于当前的实时数据,用来进行回测没有意义,因为获取不到可转债的历史数据(溢价率,规模等),只有历史的价格数据;
4. 国金Ptrade无法使用星球上的可转债代码进行实盘,因为无法访问外网,无法访问我部署的接口数据; 而国盛的Ptrade可以;如果国金Ptrade需要实盘交易可转债,需要手工上传一些基础数据,Ptrade提供上传功能,具体操作可查找星球相关文章;
5. 在共享的Ptrade模拟试用账户上,不要保留个人代码记录,跑完后记得删除,否则其他共有同一个账户的人可以进去修改复制你的策略和代码;如果是单独的个人模拟账户,则没有这个问题。

Ptrade QMT实盘策略记录 - 不定期更新
量化交易 • 李魔佛 发表了文章 • 0 个评论 • 1261 次浏览 • 2023-04-03 15:27
写出来的是已经实现且实盘稳定运行的;
涨停板;依赖ptrade的高速行情自动配合手动;两融账户的股票日内做T,持有底仓;股票小市值轮动+多因子可转债多因子(有N个版本+不同的排除因子 组合)可转债日内高频股票趋势动量ETF轮动套利脉冲卖出扫描
纯粹自己做的记录,便于自己平时复盘。
有兴趣的朋友可以关注公众号交流。 查看全部
Ptrade担保品买入卖出
Ptrade • 李魔佛 发表了文章 • 0 个评论 • 630 次浏览 • 2023-03-31 01:31
实际上是买卖股票,但在信用账户上,用只有资金买卖股票。
ptrade支持两融操作。
比如下面的示例代告诉我们,担保品买入股票的3个不同参数的效果:def initialize(context):
g.security = '600570.SS'
set_universe(g.security)
def handle_data(context, data):
# 以系统最新价委托
margin_trade(g.security, 100)
# 以72块价格下一个限价单
margin_trade(g.security, 100, limit_price=72)
# 以最优五档即时成交剩余撤销委托
margin_trade(g.security, 200, market_type=4) security:股票代码(str);
amount:交易数量,正数表示买入,负数表示卖出(int);
limit_price:买卖限价(float);
market_type:市价委托类型,上证非科创板股票支持参数1、4,上证科创板股票支持参数0、1、2、4,深证股票支持参数0、2、3、4、5(int);
0:对手方最优价格;
1:最优五档即时成交剩余转限价;
2:本方最优价格;
3:即时成交剩余撤销;
4:最优五档即时成交剩余撤销;
5:全额成交或撤单; 查看全部
担保品卖出指的是融资融券交易当中,用自有资金进行买卖的行为
实际上是买卖股票,但在信用账户上,用只有资金买卖股票。
ptrade支持两融操作。
比如下面的示例代告诉我们,担保品买入股票的3个不同参数的效果:
def initialize(context):
g.security = '600570.SS'
set_universe(g.security)
def handle_data(context, data):
# 以系统最新价委托
margin_trade(g.security, 100)
# 以72块价格下一个限价单
margin_trade(g.security, 100, limit_price=72)
# 以最优五档即时成交剩余撤销委托
margin_trade(g.security, 200, market_type=4)
security:股票代码(str);
amount:交易数量,正数表示买入,负数表示卖出(int);
limit_price:买卖限价(float);
market_type:市价委托类型,上证非科创板股票支持参数1、4,上证科创板股票支持参数0、1、2、4,深证股票支持参数0、2、3、4、5(int);
0:对手方最优价格;
1:最优五档即时成交剩余转限价;
2:本方最优价格;
3:即时成交剩余撤销;
4:最优五档即时成交剩余撤销;
5:全额成交或撤单;

qmt 可转债 双低(阈值)轮动 实盘代码
QMT • 李魔佛 发表了文章 • 0 个评论 • 1343 次浏览 • 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 iquant最新接口文档
QMT • 李魔佛 发表了文章 • 0 个评论 • 1056 次浏览 • 2023-02-19 15:16
http://qmt.ptradeapi.com
除了官方的接口文档,还加入了一些个人平时编写的写法与回测,实盘代码。 不定期更新。
欢迎关注收藏。 查看全部
http://qmt.ptradeapi.com
除了官方的接口文档,还加入了一些个人平时编写的写法与回测,实盘代码。 不定期更新。
欢迎关注收藏。
迅投qmt入门教程(一)
QMT • 李魔佛 发表了文章 • 0 个评论 • 5684 次浏览 • 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
待续,不定期更新
公众号:

星球:

ptrade获取分时成交数据-LEVEL2数据逐笔数据
Ptrade • 李魔佛 发表了文章 • 0 个评论 • 1359 次浏览 • 2023-02-04 12:27
中提供了获取分时成交的数据。
使用场景
该函数在交易模块可用
接口说明
该接口用于获取当日分时成交行情数据。
注意事项:
1、沪深市场都有分时成交数据;
2、分时成交数据需开通level2行情才有数据推送,否则无数据返回;
返回字段:
返回
返回一个OrderedDict对象,包含每只代码的分时成交行情数据。(OrderedDict([(),()...]))
返回结果字段介绍:
time_stamp: 时间戳毫秒级(str:numpy.int64);
hq_px: 价格(str:numpy.float64);
hq_px64: 价格(str:numpy.int64)(行情暂不支持,返回均为0);
business_amount: 成交数量(str:numpy.int64);
business_balance: 成交金额(str:numpy.int64);
business_count: 成交笔数(str:numpy.int64);
business_direction: 成交方向(0:卖,1:买,2:平盘)(str:numpy.int64);
amount: 持仓量(str:numpy.int64)(行情暂不支持,返回均为0);
start_index: 分笔关联的逐笔开始序号(str:numpy.int64)(行情暂不支持,返回均为0);
end_index: 分笔关联的逐笔结束序号(str:numpy.int64)(行情暂不支持,返回均为0);
示例代码:
def initialize(context):
g.security = '000001.SZ'
set_universe(g.security)
def handle_data(context, data):
#获取000001.SZ的分时成交数据
direction_data = get_tick_direction(g.security)
log.info(direction_data)
#获取指定股票列表分时成交数据
direction_data = get_tick_direction(['000002.SZ','000032.SZ'])
log.info(direction_data)
#获取成交量
business_amount = direction_data['000002.SZ']['business_amount']
log.info('分时成交的成交量为:%s' % business_amount)
不过在handle_bar中或者tick_data中,实际行情推送最快也要3s,所以拿到的level2的是切片数据,即使拿到很多数据,可是行情获取时间间隔还是3s, 无法做到和qmt那样的level2逐笔订阅驱动。还有level2数据需要收费。ptrade目前常用的几个券商都不支持level2的。
目前有万一免五的qmt ptrade量化交易接口的券商吗?
查看全部
中提供了获取分时成交的数据。
使用场景
该函数在交易模块可用
接口说明
该接口用于获取当日分时成交行情数据。
注意事项:
1、沪深市场都有分时成交数据;
2、分时成交数据需开通level2行情才有数据推送,否则无数据返回;
返回字段:
返回
返回一个OrderedDict对象,包含每只代码的分时成交行情数据。(OrderedDict([(),()...]))
返回结果字段介绍:
time_stamp: 时间戳毫秒级(str:numpy.int64);
hq_px: 价格(str:numpy.float64);
hq_px64: 价格(str:numpy.int64)(行情暂不支持,返回均为0);
business_amount: 成交数量(str:numpy.int64);
business_balance: 成交金额(str:numpy.int64);
business_count: 成交笔数(str:numpy.int64);
business_direction: 成交方向(0:卖,1:买,2:平盘)(str:numpy.int64);
amount: 持仓量(str:numpy.int64)(行情暂不支持,返回均为0);
start_index: 分笔关联的逐笔开始序号(str:numpy.int64)(行情暂不支持,返回均为0);
end_index: 分笔关联的逐笔结束序号(str:numpy.int64)(行情暂不支持,返回均为0);
示例代码:
def initialize(context):
g.security = '000001.SZ'
set_universe(g.security)
def handle_data(context, data):
#获取000001.SZ的分时成交数据
direction_data = get_tick_direction(g.security)
log.info(direction_data)
#获取指定股票列表分时成交数据
direction_data = get_tick_direction(['000002.SZ','000032.SZ'])
log.info(direction_data)
#获取成交量
business_amount = direction_data['000002.SZ']['business_amount']
log.info('分时成交的成交量为:%s' % business_amount)
不过在handle_bar中或者tick_data中,实际行情推送最快也要3s,所以拿到的level2的是切片数据,即使拿到很多数据,可是行情获取时间间隔还是3s, 无法做到和qmt那样的level2逐笔订阅驱动。还有level2数据需要收费。ptrade目前常用的几个券商都不支持level2的。
目前有万一免五的qmt ptrade量化交易接口的券商吗?

国信可以使用miniqmt吗?
QMT • 李魔佛 发表了文章 • 0 个评论 • 2043 次浏览 • 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。

Ptrade获取可转债强赎数据
Ptrade • 李魔佛 发表了文章 • 0 个评论 • 1031 次浏览 • 2022-12-21 15:50
所以在可转债的策略里面,把强赎的转债排除掉,是一个不错的因子。
但内置的ptrade接口数据并无提供任何转债相关的数据。
不过笔者这里提供了一个自研的数据接口。
http://ptradeapi.com/#%E5%8F%AF%E8%BD%AC%E5%80%BA%E5%BC%BA%E8%B5%8E%E4%B8%8E%E6%95%B0%E6%97%A5%E5%AD%90
方便在ptrade里面调用。
查看全部
所以在可转债的策略里面,把强赎的转债排除掉,是一个不错的因子。
但内置的ptrade接口数据并无提供任何转债相关的数据。
不过笔者这里提供了一个自研的数据接口。
http://ptradeapi.com/#%E5%8F%AF%E8%BD%AC%E5%80%BA%E5%BC%BA%E8%B5%8E%E4%B8%8E%E6%95%B0%E6%97%A5%E5%AD%90
方便在ptrade里面调用。

Ptrade QMT 哪家费率最便宜,门槛最低?
券商万一免五 • 绫波丽 发表了文章 • 0 个评论 • 3389 次浏览 • 2022-11-27 19:09
笔者只会推荐合适的券商和量化接口给你,而不会推荐坑爹的券商给你。
如果你不信任,绕路即可,莫浪费大家时间。或者你有好的资源或者券商,你也可以推荐给我,可以给你发红包,奖励你提供有用的情报信息。
目前支持ptrade,qmt可以股票可以免五(0.1元起步)的券商,只有国盛,需要的可以找我开。 但是有入金门槛,ptrade门槛30w, qmt 的门槛50w。 国盛的ptrade可以链接外网。其他家的不行。但国盛的qmt不支持运行在云服务器。
其他家的qmt是支持的云服务器的,但国金的qmt会每天自动退出,需要每次手动点击登录,我也写了一个自动登录的小脚本,开完户的朋友可以拿去用用。
门槛低的国信,适合新手使用,但是没有miniqmt,这个东西也不一定适合你。 真的需要这个功能,在qmt里面可以写一段代码,让它把下单接口变成http指令,把下单功能独立出来,也是可以的。不过这个属于进阶功能。 需要的也可以把代码给你。
笔者用过大部分券商的ptrade qmt,所以个人的指导与推荐还是很有指导意见的。 写过的策略也大部分人(99%)多, 平台好坏,坑的多寡,哪里有雷,都已经摸清摸楚。 可以大大节省你们的时间。 当然你也可以忽略,自己去折腾折腾。选ptrade 还是qmt,然后哪个券商,什么费率。
需要开通ptrade - qmt 低门槛 低费率 的 或者可以提供更低费用的资源的可以加微信:
ptrade 接口文档: http://ptradeapi.com
查看全部
笔者只会推荐合适的券商和量化接口给你,而不会推荐坑爹的券商给你。
如果你不信任,绕路即可,莫浪费大家时间。或者你有好的资源或者券商,你也可以推荐给我,可以给你发红包,奖励你提供有用的情报信息。
目前支持ptrade,qmt可以股票可以免五(0.1元起步)的券商,只有国盛,需要的可以找我开。 但是有入金门槛,ptrade门槛30w, qmt 的门槛50w。 国盛的ptrade可以链接外网。其他家的不行。但国盛的qmt不支持运行在云服务器。
其他家的qmt是支持的云服务器的,但国金的qmt会每天自动退出,需要每次手动点击登录,我也写了一个自动登录的小脚本,开完户的朋友可以拿去用用。
门槛低的国信,适合新手使用,但是没有miniqmt,这个东西也不一定适合你。 真的需要这个功能,在qmt里面可以写一段代码,让它把下单接口变成http指令,把下单功能独立出来,也是可以的。不过这个属于进阶功能。 需要的也可以把代码给你。
笔者用过大部分券商的ptrade qmt,所以个人的指导与推荐还是很有指导意见的。 写过的策略也大部分人(99%)多, 平台好坏,坑的多寡,哪里有雷,都已经摸清摸楚。 可以大大节省你们的时间。 当然你也可以忽略,自己去折腾折腾。选ptrade 还是qmt,然后哪个券商,什么费率。
需要开通ptrade - qmt 低门槛 低费率 的 或者可以提供更低费用的资源的可以加微信:

ptrade 接口文档: http://ptradeapi.com
不同券商的ptrade的异同
量化交易-Ptrade-QMT • 李魔佛 发表了文章 • 0 个评论 • 2140 次浏览 • 2022-06-17 16:36
1. 湘财无法访问外网,国盛的可以
2.
get_cb_list 获取可转债列表 的 国盛没有
get_history 获取历史数据函数
get_history(5, frequency='1d', field='close', security_list=['123084.SZ'], fq=None, include=False, fill='nan')国盛是没有fill参数的。
持续更新。。。待续
Ptrade开户联系:
查看全部
ptrade qmt量化平台收费吗?
券商万一免五 • 李魔佛 回复了问题 • 2 人关注 • 1 个回复 • 3429 次浏览 • 2022-07-13 17:04
开通Ptrade Python量化接口 国金证券/国盛证券
股票 • 绫波丽 发表了文章 • 0 个评论 • 16491 次浏览 • 2021-07-06 08:40
而退而求其次使用按键精灵,模拟点击交易软件进行点击下单,非常不稳定,无法判断下单后是否成交,也无法实时获取行情数据。如果使用tushare或者新浪接口数据,扫描一次全市场的行情用时很久且不稳定,等扫描结束,再下单,此时价格可能已经是几分钟前的了,且此类接口调用次数多是会被封IP的。
笔者使用的是券商提供的量化软件:Ptrade。是恒生电子研发的提供给机构使用的程序化交易软件。提供策略回测,下单API接口,实时行情获取,并且使用的开发语言python,易于上手。
策略回测与实盘交易
研究页面
研究页面,熟悉python jupyter notebook的朋友对这个界面肯定很熟悉。
研究的页面实际就运行你逐行输出调试程序,了解每个函数的具体使用,或者你策略的中途结果调试。
回测策略
实际代码需要在回测策略里面写,写完后确定无误,就可以放在仿真环境下真实运行。如果你运行得到的结果很满意,那么就可以直接部署到实盘服务器上。实盘服务器是在券商那边,不需要个人购买服务器,也不需要本地开着这个Ptrade,就是说不需要在个人电脑上一直开着跑,你的最终代码和程序是在券商服务器上部署与运行,除非有报错异常停止,不然在你不暂停或者停止的前提下,可以一直运行下去。
条件满足后下单
可视化量化
同时也提供一些常见的现成的量化策略,选中后只要鼠标点点点也能够自动化跑这些策略了,当然里面很多参数都可以用鼠标点点点修改。
接口文档也非常详细:
一些常见策略代码:
集合竞价追涨停策略def initialize(context):
# 初始化此策略
# 设置我们要操作的股票池, 这里我们只操作一支股票
g.security = '600570.SS'
set_universe(g.security)
#每天9:23分运行集合竞价处理函数
run_daily(context, aggregate_auction_func, time='9:23')
def aggregate_auction_func(context):
stock = g.security
#最新价
snapshot = get_snapshot(stock)
price = snapshot[stock]['last_px']
#涨停价
up_limit = snapshot[stock]['up_px']
#如果最新价不小于涨停价,买入
if float(price) >= float(up_limit):
order(g.security, 100, limit_price=up_limit)
def handle_data(context, data):
pass
双均线策略def initialize(context):
# 初始化此策略
# 设置我们要操作的股票池, 这里我们只操作一支股票
g.security = '600570.SS'
set_universe(g.security)
pass
#当五日均线高于十日均线时买入,当五日均线低于十日均线时卖出
def handle_data(context, data):
security = g.security
#得到十日历史价格
df = get_history(10, '1d', 'close', security, fq=None, include=False)
# 得到五日均线价格
ma5 = round(df['close'][-5:].mean(), 3)
# 得到十日均线价格
ma10 = round(df['close'][-10:].mean(), 3)
# 取得昨天收盘价
price = data[security]['close']
# 得到当前资金余额
cash = context.portfolio.cash
# 如果当前有余额,并且五日均线大于十日均线
if ma5 > ma10:
# 用所有 cash 买入股票
order_value(security, cash)
# 记录这次买入
log.info("Buying %s" % (security))
# 如果五日均线小于十日均线,并且目前有头寸
elif ma5 < ma10 and get_position(security).amount > 0:
# 全部卖出
order_target(security, 0)
# 记录这次卖出
log.info("Selling %s" % (security))
tick级别均线策略
通俗点就是按照秒级别进行操作。def initialize(context):
# 初始化此策略
# 设置我们要操作的股票池, 这里我们只操作一支股票
g.security = '600570.SS'
set_universe(g.security)
#每3秒运行一次主函数
run_interval(context, func, seconds=3)
#盘前准备历史数据
def before_trading_start(context, data):
history = get_history(10, '1d', 'close', g.security, fq='pre', include=False)
g.close_array = history['close'].values
#当五日均线高于十日均线时买入,当五日均线低于十日均线时卖出
def func(context):
stock = g.security
#获取最新价
snapshot = get_snapshot(stock)
price = snapshot[stock]['last_px']
# 得到五日均线价格
days = 5
ma5 = get_MA_day(stock, days, g.close_array[-4:], price)
# 得到十日均线价格
days = 10
ma10 = get_MA_day(stock, days, g.close_array[-9:], price)
# 得到当前资金余额
cash = context.portfolio.cash
# 如果当前有余额,并且五日均线大于十日均线
if ma5 > ma10:
# 用所有 cash 买入股票
order_value(stock, cash)
# 记录这次买入
log.info("Buying %s" % (stock))
# 如果五日均线小于十日均线,并且目前有头寸
elif ma5 < ma10 and get_position(stock).amount > 0:
# 全部卖出
order_target(stock, 0)
# 记录这次卖出
log.info("Selling %s" % (stock))
#计算实时均线函数
def get_MA_day(stock,days,close_array,current_price):
close_sum = close_array[-(days-1):].sum()
MA = (current_price + close_sum)/days
return MA
def handle_data(context, data):
pass
macd策略def f_expma(N,m,EXPMA1,price):
a = m/(N+1)
EXPMA2 = a * price + (1 - a)*EXPMA1
return EXPMA2 #2为后一天值
#定义macd函数,输入平滑系数参数、前一日值,输出当日值
def macd(N1,N2,N3,m,EXPMA12_1,EXPMA26_1,DEA1,price):
EXPMA12_2 = f_expma(N1,m,EXPMA12_1,price)
EXPMA26_2 = f_expma(N2,m,EXPMA26_1,price)
DIF2 = EXPMA12_2 - EXPMA26_2
a = m/(N3+1)
DEA2 = a * DIF2 + (1 - a)*DEA1
BAR2=2*(DIF2-DEA2)
return EXPMA12_2,EXPMA26_2,DIF2,DEA2,BAR2
def initialize(context):
global init_price
init_price = None
# 获取沪深300股票
g.security = get_index_stocks('000300.SS')
#g.security = ['600570.SS']
# 设置我们要操作的股票池, 这里我们只操作一支股票
set_universe(g.security)
def handle_data(context, data):
# 获取历史数据,这里只获取了2天的数据,如果希望最终MACD指标结果更准确最好是获取
# 从股票上市至今的所有历史数据,即增加获取的天数
close_price = get_history(2, '1d', field='close', security_list=g.security)
#如果是停牌不进行计算
for security in g.security:
if data[security].is_open >0:
global init_price,EXPMA12_1,EXPMA26_1,EXPMA12_2,EXPMA26_2,DIF1,DIF2,DEA1,DEA2
if init_price is None:
init_price = close_price[security].mean()#nan和N-1个数,mean为N-1个数的均值
EXPMA12_1 = init_price
EXPMA26_1 = init_price
DIF1 = init_price
DEA1 = init_price
# m用于计算平滑系数a=m/(N+1)
m = 2.0
#设定指数平滑基期数
N1 = 12
N2 = 26
N3 = 9
EXPMA12_2,EXPMA26_2,DIF2,DEA2,BAR2 = macd(N1,N2,N3,m,EXPMA12_1,EXPMA26_1,DEA1,close_price[security][-1])
# 取得当前价格
current_price = data[security].price
# 取得当前的现金
cash = context.portfolio.cash
# DIF、DEA均为正,DIF向上突破DEA,买入信号参考
if DIF2 > 0 and DEA2 > 0 and DIF1 < DEA1 and DIF2 > DEA2:
# 计算可以买多少只股票
number_of_shares = int(cash/current_price)
# 购买量大于0时,下单
if number_of_shares > 0:
# 以市单价买入股票,日回测时即是开盘价
order(security, +number_of_shares)
# 记录这次买入
log.info("Buying %s" % (security))
# DIF、DEA均为负,DIF向下突破DEA,卖出信号参考
elif DIF2 < 0 and DEA2 < 0 and DIF1 > DEA1 and DIF2 < DEA2 and get_position(security).amount > 0:
# 卖出所有股票,使这只股票的最终持有量为0
order_target(security, 0)
# 记录这次卖出
log.info("Selling %s" % (security))
# 将今日的值赋给全局变量作为下一次前一日的值
DEA1 = DEA2
DIF1 = DIF2
EXPMA12_1 = EXPMA12_2
EXPMA26_1 = EXPMA26_2
软件与交易接口开通条件:
开通该券商后,存入资金指定资金即可开通。开通后股票交易费率万一
本身券商的交易费率为股票万一,可转债沪百万分之五,深十万分之五,基金万0.5,非常厚道。
不太了解量化行业的可以了解下,不少面向机构的量化交易软件的佣金是万2.5的,且开户门槛高,基本是500W以上,比如华泰的matic量化的门槛是1千万元起步。
所以笔者还是很推荐目前该券商的量化交易接口。
需要开通咨询了解的朋友可以扫码联系:
开通券商账户后可以 可以先试用,再考虑是否开通量化接口权限 查看全部
而退而求其次使用按键精灵,模拟点击交易软件进行点击下单,非常不稳定,无法判断下单后是否成交,也无法实时获取行情数据。如果使用tushare或者新浪接口数据,扫描一次全市场的行情用时很久且不稳定,等扫描结束,再下单,此时价格可能已经是几分钟前的了,且此类接口调用次数多是会被封IP的。
笔者使用的是券商提供的量化软件:Ptrade。是恒生电子研发的提供给机构使用的程序化交易软件。提供策略回测,下单API接口,实时行情获取,并且使用的开发语言python,易于上手。
策略回测与实盘交易
研究页面
研究页面,熟悉python jupyter notebook的朋友对这个界面肯定很熟悉。
研究的页面实际就运行你逐行输出调试程序,了解每个函数的具体使用,或者你策略的中途结果调试。
回测策略
实际代码需要在回测策略里面写,写完后确定无误,就可以放在仿真环境下真实运行。如果你运行得到的结果很满意,那么就可以直接部署到实盘服务器上。实盘服务器是在券商那边,不需要个人购买服务器,也不需要本地开着这个Ptrade,就是说不需要在个人电脑上一直开着跑,你的最终代码和程序是在券商服务器上部署与运行,除非有报错异常停止,不然在你不暂停或者停止的前提下,可以一直运行下去。
条件满足后下单
可视化量化
同时也提供一些常见的现成的量化策略,选中后只要鼠标点点点也能够自动化跑这些策略了,当然里面很多参数都可以用鼠标点点点修改。
接口文档也非常详细:
一些常见策略代码:
集合竞价追涨停策略
def initialize(context):
# 初始化此策略
# 设置我们要操作的股票池, 这里我们只操作一支股票
g.security = '600570.SS'
set_universe(g.security)
#每天9:23分运行集合竞价处理函数
run_daily(context, aggregate_auction_func, time='9:23')
def aggregate_auction_func(context):
stock = g.security
#最新价
snapshot = get_snapshot(stock)
price = snapshot[stock]['last_px']
#涨停价
up_limit = snapshot[stock]['up_px']
#如果最新价不小于涨停价,买入
if float(price) >= float(up_limit):
order(g.security, 100, limit_price=up_limit)
def handle_data(context, data):
pass
双均线策略
def initialize(context):
# 初始化此策略
# 设置我们要操作的股票池, 这里我们只操作一支股票
g.security = '600570.SS'
set_universe(g.security)
pass
#当五日均线高于十日均线时买入,当五日均线低于十日均线时卖出
def handle_data(context, data):
security = g.security
#得到十日历史价格
df = get_history(10, '1d', 'close', security, fq=None, include=False)
# 得到五日均线价格
ma5 = round(df['close'][-5:].mean(), 3)
# 得到十日均线价格
ma10 = round(df['close'][-10:].mean(), 3)
# 取得昨天收盘价
price = data[security]['close']
# 得到当前资金余额
cash = context.portfolio.cash
# 如果当前有余额,并且五日均线大于十日均线
if ma5 > ma10:
# 用所有 cash 买入股票
order_value(security, cash)
# 记录这次买入
log.info("Buying %s" % (security))
# 如果五日均线小于十日均线,并且目前有头寸
elif ma5 < ma10 and get_position(security).amount > 0:
# 全部卖出
order_target(security, 0)
# 记录这次卖出
log.info("Selling %s" % (security))
tick级别均线策略
通俗点就是按照秒级别进行操作。
def initialize(context):
# 初始化此策略
# 设置我们要操作的股票池, 这里我们只操作一支股票
g.security = '600570.SS'
set_universe(g.security)
#每3秒运行一次主函数
run_interval(context, func, seconds=3)
#盘前准备历史数据
def before_trading_start(context, data):
history = get_history(10, '1d', 'close', g.security, fq='pre', include=False)
g.close_array = history['close'].values
#当五日均线高于十日均线时买入,当五日均线低于十日均线时卖出
def func(context):
stock = g.security
#获取最新价
snapshot = get_snapshot(stock)
price = snapshot[stock]['last_px']
# 得到五日均线价格
days = 5
ma5 = get_MA_day(stock, days, g.close_array[-4:], price)
# 得到十日均线价格
days = 10
ma10 = get_MA_day(stock, days, g.close_array[-9:], price)
# 得到当前资金余额
cash = context.portfolio.cash
# 如果当前有余额,并且五日均线大于十日均线
if ma5 > ma10:
# 用所有 cash 买入股票
order_value(stock, cash)
# 记录这次买入
log.info("Buying %s" % (stock))
# 如果五日均线小于十日均线,并且目前有头寸
elif ma5 < ma10 and get_position(stock).amount > 0:
# 全部卖出
order_target(stock, 0)
# 记录这次卖出
log.info("Selling %s" % (stock))
#计算实时均线函数
def get_MA_day(stock,days,close_array,current_price):
close_sum = close_array[-(days-1):].sum()
MA = (current_price + close_sum)/days
return MA
def handle_data(context, data):
pass
macd策略
def f_expma(N,m,EXPMA1,price):
a = m/(N+1)
EXPMA2 = a * price + (1 - a)*EXPMA1
return EXPMA2 #2为后一天值
#定义macd函数,输入平滑系数参数、前一日值,输出当日值
def macd(N1,N2,N3,m,EXPMA12_1,EXPMA26_1,DEA1,price):
EXPMA12_2 = f_expma(N1,m,EXPMA12_1,price)
EXPMA26_2 = f_expma(N2,m,EXPMA26_1,price)
DIF2 = EXPMA12_2 - EXPMA26_2
a = m/(N3+1)
DEA2 = a * DIF2 + (1 - a)*DEA1
BAR2=2*(DIF2-DEA2)
return EXPMA12_2,EXPMA26_2,DIF2,DEA2,BAR2
def initialize(context):
global init_price
init_price = None
# 获取沪深300股票
g.security = get_index_stocks('000300.SS')
#g.security = ['600570.SS']
# 设置我们要操作的股票池, 这里我们只操作一支股票
set_universe(g.security)
def handle_data(context, data):
# 获取历史数据,这里只获取了2天的数据,如果希望最终MACD指标结果更准确最好是获取
# 从股票上市至今的所有历史数据,即增加获取的天数
close_price = get_history(2, '1d', field='close', security_list=g.security)
#如果是停牌不进行计算
for security in g.security:
if data[security].is_open >0:
global init_price,EXPMA12_1,EXPMA26_1,EXPMA12_2,EXPMA26_2,DIF1,DIF2,DEA1,DEA2
if init_price is None:
init_price = close_price[security].mean()#nan和N-1个数,mean为N-1个数的均值
EXPMA12_1 = init_price
EXPMA26_1 = init_price
DIF1 = init_price
DEA1 = init_price
# m用于计算平滑系数a=m/(N+1)
m = 2.0
#设定指数平滑基期数
N1 = 12
N2 = 26
N3 = 9
EXPMA12_2,EXPMA26_2,DIF2,DEA2,BAR2 = macd(N1,N2,N3,m,EXPMA12_1,EXPMA26_1,DEA1,close_price[security][-1])
# 取得当前价格
current_price = data[security].price
# 取得当前的现金
cash = context.portfolio.cash
# DIF、DEA均为正,DIF向上突破DEA,买入信号参考
if DIF2 > 0 and DEA2 > 0 and DIF1 < DEA1 and DIF2 > DEA2:
# 计算可以买多少只股票
number_of_shares = int(cash/current_price)
# 购买量大于0时,下单
if number_of_shares > 0:
# 以市单价买入股票,日回测时即是开盘价
order(security, +number_of_shares)
# 记录这次买入
log.info("Buying %s" % (security))
# DIF、DEA均为负,DIF向下突破DEA,卖出信号参考
elif DIF2 < 0 and DEA2 < 0 and DIF1 > DEA1 and DIF2 < DEA2 and get_position(security).amount > 0:
# 卖出所有股票,使这只股票的最终持有量为0
order_target(security, 0)
# 记录这次卖出
log.info("Selling %s" % (security))
# 将今日的值赋给全局变量作为下一次前一日的值
DEA1 = DEA2
DIF1 = DIF2
EXPMA12_1 = EXPMA12_2
EXPMA26_1 = EXPMA26_2
软件与交易接口开通条件:
开通该券商后,存入资金指定资金即可开通。开通后股票交易费率万一
本身券商的交易费率为股票万一,可转债沪百万分之五,深十万分之五,基金万0.5,非常厚道。
不太了解量化行业的可以了解下,不少面向机构的量化交易软件的佣金是万2.5的,且开户门槛高,基本是500W以上,比如华泰的matic量化的门槛是1千万元起步。
所以笔者还是很推荐目前该券商的量化交易接口。
需要开通咨询了解的朋友可以扫码联系:

开通券商账户后可以 可以先试用,再考虑是否开通量化接口权限
量化交易接口python A股
股票 • 绫波丽 发表了文章 • 0 个评论 • 6061 次浏览 • 2021-07-01 11:22
实际操作也好,几乎没见几个人教你怎么用程序下单,实盘交易。
稍微好点的easytrader使用的是模拟点击交易软件进行点击下单,基本无法判断下单后是否成交,也无法实时获取行情数据。别跟我说用tushare或者新浪这些接口数据,除非你做的是低频交易。
试试扫描一次全市场的行情看看用时多少?等得到满足条件了,再下单,此时价格可能已经在涨停板上封住了。
笔者使用的是券商提供的量化软件:Ptrade。
是恒生电子研发的提供给券商机构使用的程序化交易软件。提供策略回测,自动下单功能,使用的开发语言python。
策略回测与实盘交易
研究页面
研究页面,熟悉python jupyter notebook的朋友对这个界面肯定很熟悉。
研究的页面实际就运行你逐行输出调试程序,了解每个函数的具体使用,或者你策略的中途结果调试。
回测策略
实际代码需要在回测策略里面写,写完后确定无误,就可以放在仿真环境下真实运行。
如果你运行得到的结果很满意,那么就可以直接部署到实盘服务器上。
实盘服务器是在券商那边,不需要个人购买服务器,也不需要本地开着这个Ptrade,就是说不需要在个人电脑上一直开着跑,你的最终代码和程序是在券商服务器上部署与运行,除非有报错异常停止,不然在你不暂停或者停止的前提下,可以一直运行下去。
条件满足后下单
可视化量化
同时也提供一些常见的现成的量化策略,选中后只要鼠标点点点也能够自动化跑这些策略了,当然里面很多参数都可以用鼠标点点点修改。
接口文档也非常详细:
一些常见策略代码:
双均线策略 def initialize(context):
2 # 初始化此策略
3 # 设置我们要操作的股票池, 这里我们只操作一支股票
4 g.security = '600570.SS'
5 set_universe(g.security)
6 pass
7
8 #当五日均线高于十日均线时买入,当五日均线低于十日均线时卖出
9 def handle_data(context, data):
10 security = g.security
11
12 #得到十日历史价格
13 df = get_history(10, '1d', 'close', security, fq=None, include=False)
14
15 # 得到五日均线价格
16 ma5 = round(df['close'][-5:].mean(), 3)
17
18 # 得到十日均线价格
19 ma10 = round(df['close'][-10:].mean(), 3)
20
21 # 取得昨天收盘价
22 price = data[security]['close']
23
24 # 得到当前资金余额
25 cash = context.portfolio.cash
26
27 # 如果当前有余额,并且五日均线大于十日均线
28 if ma5 > ma10:
29 # 用所有 cash 买入股票
30 order_value(security, cash)
31 # 记录这次买入
32 log.info("Buying %s" % (security))
33
34 # 如果五日均线小于十日均线,并且目前有头寸
35 elif ma5 < ma10 and get_position(security).amount > 0:
36 # 全部卖出
37 order_target(security, 0)
38 # 记录这次卖出
39 log.info("Selling %s" % (security))
macd策略
指数平滑均线函数,以price计算,可以选择收盘、开盘价等价格,N为时间周期,m用于计算平滑系数a=m/(N+1),EXPMA1为前一日值 def f_expma(N,m,EXPMA1,price):
2 a = m/(N+1)
3 EXPMA2 = a * price + (1 - a)*EXPMA1
4 return EXPMA2 #2为后一天值
5
6 #定义macd函数,输入平滑系数参数、前一日值,输出当日值
7 def macd(N1,N2,N3,m,EXPMA12_1,EXPMA26_1,DEA1,price):
8 EXPMA12_2 = f_expma(N1,m,EXPMA12_1,price)
9 EXPMA26_2 = f_expma(N2,m,EXPMA26_1,price)
10 DIF2 = EXPMA12_2 - EXPMA26_2
11 a = m/(N3+1)
12 DEA2 = a * DIF2 + (1 - a)*DEA1
13 BAR2=2*(DIF2-DEA2)
14 return EXPMA12_2,EXPMA26_2,DIF2,DEA2,BAR2
15
16 def initialize(context):
17 global init_price
18 init_price = None
19 # 获取沪深300股票
20 g.security = get_index_stocks('000300.SS')
21 #g.security = ['600570.SS']
22 # 设置我们要操作的股票池, 这里我们只操作一支股票
23 set_universe(g.security)
24
25 def handle_data(context, data):
26 # 获取历史数据,这里只获取了2天的数据,如果希望最终MACD指标结果更准确最好是获取
27 # 从股票上市至今的所有历史数据,即增加获取的天数
28 close_price = get_history(2, '1d', field='close', security_list=g.security)
29 #如果是停牌不进行计算
30 for security in g.security:
31 if data[security].is_open >0:
32 global init_price,EXPMA12_1,EXPMA26_1,EXPMA12_2,EXPMA26_2,DIF1,DIF2,DEA1,DEA2
33 if init_price is None:
34 init_price = close_price[security].mean()#nan和N-1个数,mean为N-1个数的均值
35 EXPMA12_1 = init_price
36 EXPMA26_1 = init_price
37 DIF1 = init_price
38 DEA1 = init_price
39 # m用于计算平滑系数a=m/(N+1)
40 m = 2.0
41 #设定指数平滑基期数
42 N1 = 12
43 N2 = 26
44 N3 = 9
45 EXPMA12_2,EXPMA26_2,DIF2,DEA2,BAR2 = macd(N1,N2,N3,m,EXPMA12_1,EXPMA26_1,DEA1,close_price[security][-1])
46 # 取得当前价格
47 current_price = data[security].price
48 # 取得当前的现金
49 cash = context.portfolio.cash
50 # DIF、DEA均为正,DIF向上突破DEA,买入信号参考
51 if DIF2 > 0 and DEA2 > 0 and DIF1 < DEA1 and DIF2 > DEA2:
52 # 计算可以买多少只股票
53 number_of_shares = int(cash/current_price)
54 # 购买量大于0时,下单
55 if number_of_shares > 0:
56 # 以市单价买入股票,日回测时即是开盘价
57 order(security, +number_of_shares)
58 # 记录这次买入
59 log.info("Buying %s" % (security))
60 # DIF、DEA均为负,DIF向下突破DEA,卖出信号参考
61 elif DIF2 < 0 and DEA2 < 0 and DIF1 > DEA1 and DIF2 < DEA2 and get_position(security).amount > 0:
62 # 卖出所有股票,使这只股票的最终持有量为0
63 order_target(security, 0)
64 # 记录这次卖出
65 log.info("Selling %s" % (security))
66 # 将今日的值赋给全局变量作为下一次前一日的值
67 DEA1 = DEA2
68 DIF1 = DIF2
69 EXPMA12_1 = EXPMA12_2
70 EXPMA26_1 = EXPMA26_2
同时也支持可转债T+0交易,笔者平时也主要是进行的可转债的交易。
软件与交易接口开通条件,
开通改券商后,存入资金50W放2周即可开通,开通后可取出。
本身券商的交易费率为股票万一免五,可转债百万分之二,非常厚道,因为不少面向机构的量化交易软件的佣金是万2.5的,笔者之前在国金渠道开的就是,坑的一比。所以笔者还是很推荐目前该券商的量化交易接口。
需要可以关注公众号获取开通链接: 查看全部
实际操作也好,几乎没见几个人教你怎么用程序下单,实盘交易。
稍微好点的easytrader使用的是模拟点击交易软件进行点击下单,基本无法判断下单后是否成交,也无法实时获取行情数据。别跟我说用tushare或者新浪这些接口数据,除非你做的是低频交易。
试试扫描一次全市场的行情看看用时多少?等得到满足条件了,再下单,此时价格可能已经在涨停板上封住了。
笔者使用的是券商提供的量化软件:Ptrade。
是恒生电子研发的提供给券商机构使用的程序化交易软件。提供策略回测,自动下单功能,使用的开发语言python。
策略回测与实盘交易
研究页面
研究页面,熟悉python jupyter notebook的朋友对这个界面肯定很熟悉。
研究的页面实际就运行你逐行输出调试程序,了解每个函数的具体使用,或者你策略的中途结果调试。
回测策略
实际代码需要在回测策略里面写,写完后确定无误,就可以放在仿真环境下真实运行。
如果你运行得到的结果很满意,那么就可以直接部署到实盘服务器上。
实盘服务器是在券商那边,不需要个人购买服务器,也不需要本地开着这个Ptrade,就是说不需要在个人电脑上一直开着跑,你的最终代码和程序是在券商服务器上部署与运行,除非有报错异常停止,不然在你不暂停或者停止的前提下,可以一直运行下去。
条件满足后下单
可视化量化
同时也提供一些常见的现成的量化策略,选中后只要鼠标点点点也能够自动化跑这些策略了,当然里面很多参数都可以用鼠标点点点修改。
接口文档也非常详细:
一些常见策略代码:
双均线策略
def initialize(context):
2 # 初始化此策略
3 # 设置我们要操作的股票池, 这里我们只操作一支股票
4 g.security = '600570.SS'
5 set_universe(g.security)
6 pass
7
8 #当五日均线高于十日均线时买入,当五日均线低于十日均线时卖出
9 def handle_data(context, data):
10 security = g.security
11
12 #得到十日历史价格
13 df = get_history(10, '1d', 'close', security, fq=None, include=False)
14
15 # 得到五日均线价格
16 ma5 = round(df['close'][-5:].mean(), 3)
17
18 # 得到十日均线价格
19 ma10 = round(df['close'][-10:].mean(), 3)
20
21 # 取得昨天收盘价
22 price = data[security]['close']
23
24 # 得到当前资金余额
25 cash = context.portfolio.cash
26
27 # 如果当前有余额,并且五日均线大于十日均线
28 if ma5 > ma10:
29 # 用所有 cash 买入股票
30 order_value(security, cash)
31 # 记录这次买入
32 log.info("Buying %s" % (security))
33
34 # 如果五日均线小于十日均线,并且目前有头寸
35 elif ma5 < ma10 and get_position(security).amount > 0:
36 # 全部卖出
37 order_target(security, 0)
38 # 记录这次卖出
39 log.info("Selling %s" % (security))
macd策略
指数平滑均线函数,以price计算,可以选择收盘、开盘价等价格,N为时间周期,m用于计算平滑系数a=m/(N+1),EXPMA1为前一日值
def f_expma(N,m,EXPMA1,price):
2 a = m/(N+1)
3 EXPMA2 = a * price + (1 - a)*EXPMA1
4 return EXPMA2 #2为后一天值
5
6 #定义macd函数,输入平滑系数参数、前一日值,输出当日值
7 def macd(N1,N2,N3,m,EXPMA12_1,EXPMA26_1,DEA1,price):
8 EXPMA12_2 = f_expma(N1,m,EXPMA12_1,price)
9 EXPMA26_2 = f_expma(N2,m,EXPMA26_1,price)
10 DIF2 = EXPMA12_2 - EXPMA26_2
11 a = m/(N3+1)
12 DEA2 = a * DIF2 + (1 - a)*DEA1
13 BAR2=2*(DIF2-DEA2)
14 return EXPMA12_2,EXPMA26_2,DIF2,DEA2,BAR2
15
16 def initialize(context):
17 global init_price
18 init_price = None
19 # 获取沪深300股票
20 g.security = get_index_stocks('000300.SS')
21 #g.security = ['600570.SS']
22 # 设置我们要操作的股票池, 这里我们只操作一支股票
23 set_universe(g.security)
24
25 def handle_data(context, data):
26 # 获取历史数据,这里只获取了2天的数据,如果希望最终MACD指标结果更准确最好是获取
27 # 从股票上市至今的所有历史数据,即增加获取的天数
28 close_price = get_history(2, '1d', field='close', security_list=g.security)
29 #如果是停牌不进行计算
30 for security in g.security:
31 if data[security].is_open >0:
32 global init_price,EXPMA12_1,EXPMA26_1,EXPMA12_2,EXPMA26_2,DIF1,DIF2,DEA1,DEA2
33 if init_price is None:
34 init_price = close_price[security].mean()#nan和N-1个数,mean为N-1个数的均值
35 EXPMA12_1 = init_price
36 EXPMA26_1 = init_price
37 DIF1 = init_price
38 DEA1 = init_price
39 # m用于计算平滑系数a=m/(N+1)
40 m = 2.0
41 #设定指数平滑基期数
42 N1 = 12
43 N2 = 26
44 N3 = 9
45 EXPMA12_2,EXPMA26_2,DIF2,DEA2,BAR2 = macd(N1,N2,N3,m,EXPMA12_1,EXPMA26_1,DEA1,close_price[security][-1])
46 # 取得当前价格
47 current_price = data[security].price
48 # 取得当前的现金
49 cash = context.portfolio.cash
50 # DIF、DEA均为正,DIF向上突破DEA,买入信号参考
51 if DIF2 > 0 and DEA2 > 0 and DIF1 < DEA1 and DIF2 > DEA2:
52 # 计算可以买多少只股票
53 number_of_shares = int(cash/current_price)
54 # 购买量大于0时,下单
55 if number_of_shares > 0:
56 # 以市单价买入股票,日回测时即是开盘价
57 order(security, +number_of_shares)
58 # 记录这次买入
59 log.info("Buying %s" % (security))
60 # DIF、DEA均为负,DIF向下突破DEA,卖出信号参考
61 elif DIF2 < 0 and DEA2 < 0 and DIF1 > DEA1 and DIF2 < DEA2 and get_position(security).amount > 0:
62 # 卖出所有股票,使这只股票的最终持有量为0
63 order_target(security, 0)
64 # 记录这次卖出
65 log.info("Selling %s" % (security))
66 # 将今日的值赋给全局变量作为下一次前一日的值
67 DEA1 = DEA2
68 DIF1 = DIF2
69 EXPMA12_1 = EXPMA12_2
70 EXPMA26_1 = EXPMA26_2
同时也支持可转债T+0交易,笔者平时也主要是进行的可转债的交易。
软件与交易接口开通条件,
开通改券商后,存入资金50W放2周即可开通,开通后可取出。
本身券商的交易费率为股票万一免五,可转债百万分之二,非常厚道,因为不少面向机构的量化交易软件的佣金是万2.5的,笔者之前在国金渠道开的就是,坑的一比。所以笔者还是很推荐目前该券商的量化交易接口。
需要可以关注公众号获取开通链接:

python判断可转债是否强赎
量化交易-Ptrade-QMT • 李魔佛 发表了文章 • 0 个评论 • 1907 次浏览 • 2021-04-02 13:41
更新:
制作好了一个接口,用户可以直接调用。
数据来源与集思录。
获取 排除满足强赎天数剩余N天的可转债,排除强赎可转债。
比如:DAY=4 ,那么假设强赎满足天数为15天,那么返回市场上强赎强赎倒数天数大于4天的可转债,即返回小于或者等于11天以下的转债。把满足条件还差4天的转债排除掉了,当然,已经公告强赎的也会被排除。
import requests
URL = 'http://11.11.11.11/api/redeem/'
# DAY 强赎倒数剩余天数小于 DAY (4)天, 已经公告强赎的也是被排除的
DAY = 4
SIGN = '私信星主获取' # sign和以前一致
data = {'day': DAY,
'sign': SIGN}
r = requests.post(URL, data=data)
print(r.json())
具体用户可以关注知识星球: 查看全部
更新:
制作好了一个接口,用户可以直接调用。
数据来源与集思录。
获取 排除满足强赎天数剩余N天的可转债,排除强赎可转债。
比如:DAY=4 ,那么假设强赎满足天数为15天,那么返回市场上强赎强赎倒数天数大于4天的可转债,即返回小于或者等于11天以下的转债。把满足条件还差4天的转债排除掉了,当然,已经公告强赎的也会被排除。
import requests
URL = 'http://11.11.11.11/api/redeem/'
# DAY 强赎倒数剩余天数小于 DAY (4)天, 已经公告强赎的也是被排除的
DAY = 4
SIGN = '私信星主获取' # sign和以前一致
data = {'day': DAY,
'sign': SIGN}
r = requests.post(URL, data=data)
print(r.json())
具体用户可以关注知识星球:

PTrade使用教程 新手入门
股票 • 李魔佛 发表了文章 • 0 个评论 • 9388 次浏览 • 2021-03-18 08:55
记录一下曾经的入门经验与使用心得:
好像PTrade有几个版本,本人使用的界面如下,基于python写交易策略和回测:
1. 仿真系统的回测可以在交易时间运行,交易系统的回测无法在交易时间运行回测。
2. 在研究板块中,API函数带有研究字样的,可以直接使用,不需要import 导入任何库。比如:#获取当日的股票池
g.stock_list = get_Ashares(g.current_date)可以自己使用。
而get_history(70, '1d', ['close','volume'], g.stock_list, fq='dypre', include=False)
没有带研究字样的,是无法直接在研究板块使用,只能在回测或者实盘使用。
3. 内置的python版本是:
'3.5.1 (default, Nov 1 2016, 01:53:03) \n[GCC 4.8.5 20150623 (Red Hat 4.8.5-4)]'
也就是无法使用fstring的方式格式化字符串
name='jack'
a=f'{name}'
4. log.debug log.error 等调试标记符不会有任何输出,bug!
只能使用log.info 或者print输出,还害我调试了半天,以为程序哪里的问题,导致我的输出不显示。
PTrade新手入门教程 二
需要开通Ptrade的朋友,可以扫描二维码开户,并可开通PTrade交易功能。
股票费率万分之一,转债十万分之二。
非诚勿扰。
原创文章,转载请注明出处
http://30daydo.com/article/44151
查看全部
记录一下曾经的入门经验与使用心得:
好像PTrade有几个版本,本人使用的界面如下,基于python写交易策略和回测:
1. 仿真系统的回测可以在交易时间运行,交易系统的回测无法在交易时间运行回测。
2. 在研究板块中,API函数带有研究字样的,可以直接使用,不需要import 导入任何库。比如:
#获取当日的股票池可以自己使用。
g.stock_list = get_Ashares(g.current_date)
而
get_history(70, '1d', ['close','volume'], g.stock_list, fq='dypre', include=False)
没有带研究字样的,是无法直接在研究板块使用,只能在回测或者实盘使用。
3. 内置的python版本是:
'3.5.1 (default, Nov 1 2016, 01:53:03) \n[GCC 4.8.5 20150623 (Red Hat 4.8.5-4)]'
也就是无法使用fstring的方式格式化字符串
name='jack'
a=f'{name}'
4. log.debug log.error 等调试标记符不会有任何输出,bug!
只能使用log.info 或者print输出,还害我调试了半天,以为程序哪里的问题,导致我的输出不显示。
PTrade新手入门教程 二
需要开通Ptrade的朋友,可以扫描二维码开户,并可开通PTrade交易功能。
股票费率万分之一,转债十万分之二。
非诚勿扰。

原创文章,转载请注明出处
http://30daydo.com/article/44151
a股券商开户 万1免五 没有最低消费
券商万一免五 • 李魔佛 发表了文章 • 0 个评论 • 12232 次浏览 • 2021-03-07 17:51
不过之前还找到一家万一免五的,没有最低费率,用多少算多少,比如买了1000元股票,那么费率只有1000*万分之一,等于1分钱,略等于不用钱哈。
优势杠杆的。
需要的点击下面链接即可开户: 注意:当前默认的免五已经取消了,需要开通量化交易权限后可以进行免五操作。
开通ptrade和qmt量化交易接口的条件,入金30万,过3天左右可以开通,开通后可以免五!
交割单:
心动不,赶紧心动吧。
该券商也支持同花顺客户端登录,做量化的使用easytrader也可以友好支持。
如果有疑问,可以扫码咨询。备注:开户
查看全部
可转债如何配债
股票 • 李魔佛 发表了文章 • 0 个评论 • 11720 次浏览 • 2019-03-29 16:24
1、如果你在登记日也就是12月11日收盘时还持有一定数量歌尔声学正股的话,那么你在配债日也就是12月12日就会看到账户里有相应数量的歌尔配债。注意这里的单位是张,如图,
由于我只有800股歌尔声学,因此获得了13张配债,1张对应100元,这时双击它,左侧出现了卖出菜单,价格和配债代码都自动填好了,输入13张或者点击全部,然后点“卖出”。(需要注意的是:有些券商这里是买入。)
2、不管是卖出还是买入,然后检查下委托情况和扣款情况,如下图:
可以看到我已经被扣款1300元,这样就算成功完成了这次的13张配债.
可转债低佣金开户,沪市转债费率百分之二,全市场最低。
有兴趣的朋友可以扫描开户:
查看全部
1、如果你在登记日也就是12月11日收盘时还持有一定数量歌尔声学正股的话,那么你在配债日也就是12月12日就会看到账户里有相应数量的歌尔配债。注意这里的单位是张,如图,
由于我只有800股歌尔声学,因此获得了13张配债,1张对应100元,这时双击它,左侧出现了卖出菜单,价格和配债代码都自动填好了,输入13张或者点击全部,然后点“卖出”。(需要注意的是:有些券商这里是买入。)
2、不管是卖出还是买入,然后检查下委托情况和扣款情况,如下图:
可以看到我已经被扣款1300元,这样就算成功完成了这次的13张配债.
可转债低佣金开户,沪市转债费率百分之二,全市场最低。
有兴趣的朋友可以扫描开户:

可转债价格分布堆叠图 绘制 可视化 python+pyecharts
量化交易-Ptrade-QMT • 李魔佛 发表了文章 • 0 个评论 • 6795 次浏览 • 2019-01-30 10:59
即使你有很多数据,可是,你无法直观地看到数据的总体趋势。使用可视化的绘图,可以帮助我们看到数据背后看不到的数据。 比如我已经有每一个可转债的价格,评级。数据如下:
点击查看大图
如果我用下面的图形就可以看出规律:
点击查看大图
横坐标是价格,纵坐标是落在该价格的可转债数量,不同颜色代表不同评级的可转债。
可以看到大部分AA-评级(浅橙色)的可转债价格都在100元以下,而AA(浅蓝色)的可转债价格分布较为平均,从90到110都有。而AA+和AAA的一般都在100以上。
那么如何使用代码实现呢?from setting import get_mysql_conn,get_engine
import pandas as pd
import pymongo
from pyecharts import Geo,Style,Map
engine = get_engine('db_stock',local='local')
# 堆叠图
from pyecharts import Bar
df = pd.read_sql('tb_bond_jisilu',con=engine)
result ={}
for name,grades in df.groupby('评级'):
# print(name,grades[['可转债名称','可转债价格']])
for each in grades['可转债价格']:
result.setdefault(name,)
result[name].append(each)
# 确定价格的范围
value = [str(i) for i in range(85,140)]
ret = [0]*len(value)
ret1 = dict(zip(value,ret))
ret_A_add = ret1.copy()
for item in result['A+']:
for k in ret1:
if float(k)+0.5>item and float(k)-0.5<=item:
ret_A_add[k]+=1
retAA_ = ret1.copy()
for item in result['']:
for k in ret1:
if float(k)+0.5>item and float(k)-0.5<=item:
retAA_[k]+=1
retAA = ret1.copy()
for item in result['AA']:
for k in ret1:
if float(k)+0.5>item and float(k)-0.5<=item:
retAA[k]+=1
retAA_add = ret1.copy()
for item in result['AA+']:
for k in ret1:
if float(k)+0.5>item and float(k)-0.5<=item:
retAA_add[k]+=1
retAAA = ret1.copy()
for item in result['AAA']:
for k in ret1:
if float(k)+0.5>item and float(k)-0.5<=item:
retAAA[k]+=1
bar = Bar('可转债价格分布')
bar.add('A+',value,list(ret_A_add.values()),is_stack=True,yaxis_max=11)
bar.add('',value,list(retAA_.values()),is_stack=True,yaxis_max=11)
bar.add('AA',value,list(retAA.values()),is_stack=True,yaxis_max=11)
bar.add('AA+',value,list(retAA_add.values()),is_stack=True,yaxis_max=11)
bar.add('AAA',value,list(retAAA.values()),is_stack=True,yaxis_max=11)
如果没有安装pyecharts,需要用pip安装即可。
原创文章
转载请注明出处:
http://30daydo.com/article/400
查看全部
即使你有很多数据,可是,你无法直观地看到数据的总体趋势。使用可视化的绘图,可以帮助我们看到数据背后看不到的数据。 比如我已经有每一个可转债的价格,评级。数据如下:
点击查看大图
如果我用下面的图形就可以看出规律:
点击查看大图
横坐标是价格,纵坐标是落在该价格的可转债数量,不同颜色代表不同评级的可转债。
可以看到大部分AA-评级(浅橙色)的可转债价格都在100元以下,而AA(浅蓝色)的可转债价格分布较为平均,从90到110都有。而AA+和AAA的一般都在100以上。
那么如何使用代码实现呢?
from setting import get_mysql_conn,get_engine
import pandas as pd
import pymongo
from pyecharts import Geo,Style,Map
engine = get_engine('db_stock',local='local')
# 堆叠图
from pyecharts import Bar
df = pd.read_sql('tb_bond_jisilu',con=engine)
result ={}
for name,grades in df.groupby('评级'):
# print(name,grades[['可转债名称','可转债价格']])
for each in grades['可转债价格']:
result.setdefault(name,)
result[name].append(each)
# 确定价格的范围
value = [str(i) for i in range(85,140)]
ret = [0]*len(value)
ret1 = dict(zip(value,ret))
ret_A_add = ret1.copy()
for item in result['A+']:
for k in ret1:
if float(k)+0.5>item and float(k)-0.5<=item:
ret_A_add[k]+=1
retAA_ = ret1.copy()
for item in result['']:
for k in ret1:
if float(k)+0.5>item and float(k)-0.5<=item:
retAA_[k]+=1
retAA = ret1.copy()
for item in result['AA']:
for k in ret1:
if float(k)+0.5>item and float(k)-0.5<=item:
retAA[k]+=1
retAA_add = ret1.copy()
for item in result['AA+']:
for k in ret1:
if float(k)+0.5>item and float(k)-0.5<=item:
retAA_add[k]+=1
retAAA = ret1.copy()
for item in result['AAA']:
for k in ret1:
if float(k)+0.5>item and float(k)-0.5<=item:
retAAA[k]+=1
bar = Bar('可转债价格分布')
bar.add('A+',value,list(ret_A_add.values()),is_stack=True,yaxis_max=11)
bar.add('',value,list(retAA_.values()),is_stack=True,yaxis_max=11)
bar.add('AA',value,list(retAA.values()),is_stack=True,yaxis_max=11)
bar.add('AA+',value,list(retAA_add.values()),is_stack=True,yaxis_max=11)
bar.add('AAA',value,list(retAAA.values()),is_stack=True,yaxis_max=11)
如果没有安装pyecharts,需要用pip安装即可。
原创文章
转载请注明出处:
http://30daydo.com/article/400
迅投官网的示例代码真的无眼看。。。
QMT • 李魔佛 发表了文章 • 0 个评论 • 189 次浏览 • 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 | Ptrade 量化策略代写服务
量化交易 • 李魔佛 发表了文章 • 0 个评论 • 297 次浏览 • 2023-11-01 10:43
多年交易经验,量化交易与开发经验。所以很多策略,其实用户大体描述,就知道要注意哪些地方,会提出一些建议,用户要注意,需不需要添加一些判读条件等等。(当然,策略的具体参数都是设置可以调节的,你不需要把实际的参数告诉我,代码给你后,你自己运行策略的时候把你策略的真正参数填上去就好了。)
有偿,收费,价格美丽。根据策略实际的复杂程度与预估的工时,收费。(不根据代码数量,因为我写代码很精简)
我也帮你们咨询过了迅投的客服。 因为他们官网也有提供策略代写服务。他们是不问你策略,直接是5000起步哦。然后根据策略,在5000的基础上不断加。
咨询完,我都感觉我自己以前的报价太低了,呜。
PS: 之前还有迅投的前员工私底下接单写策略,然后到我的星球里面白嫖我的代码,调用我接口数据,被我发现后举报到星球的。后面那个客户发现代码里面藏有我的公众号信息哈,找到我让我修改接口数据哈。
需要的代写策略的盆友,可以关注公众号,在菜单栏那里的“代写量化程序”或者 后台回复:策略代写,获取联系方式哦
扫码关注公众号:
查看全部
迅投的QMT和恒生电子的Ptrade, 还有掘金, 量化策略编程, 实盘和回测都行。只要你的需求明确,白纸黑字描述清楚,都可以做。股票,ETF,可转债都行。
多年交易经验,量化交易与开发经验。所以很多策略,其实用户大体描述,就知道要注意哪些地方,会提出一些建议,用户要注意,需不需要添加一些判读条件等等。(当然,策略的具体参数都是设置可以调节的,你不需要把实际的参数告诉我,代码给你后,你自己运行策略的时候把你策略的真正参数填上去就好了。)
有偿,收费,价格美丽。根据策略实际的复杂程度与预估的工时,收费。(不根据代码数量,因为我写代码很精简)
我也帮你们咨询过了迅投的客服。 因为他们官网也有提供策略代写服务。他们是不问你策略,直接是5000起步哦。然后根据策略,在5000的基础上不断加。
咨询完,我都感觉我自己以前的报价太低了,呜。
PS: 之前还有迅投的前员工私底下接单写策略,然后到我的星球里面白嫖我的代码,调用我接口数据,被我发现后举报到星球的。后面那个客户发现代码里面藏有我的公众号信息哈,找到我让我修改接口数据哈。
需要的代写策略的盆友,可以关注公众号,在菜单栏那里的“代写量化程序”或者 后台回复:策略代写,获取联系方式哦
扫码关注公众号:

QMT获取A股全市场股票代码
QMT • 李魔佛 发表了文章 • 0 个评论 • 261 次浏览 • 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仿真客户端 PTrade仿真客户端 QMT测试版 Ptrade测试版
量化交易 • 李魔佛 发表了文章 • 0 个评论 • 458 次浏览 • 2023-10-22 12:54
国金证券 - QMT测试账号信息: 登录账号:*********** 登录密码:**********
QMT交易测试客户端下载链接 链接:
https://download.gjzq.com.cn/temp/organ/gjzqqmt_ceshi.rar
国金证券 - ptrade测试账号信息: 登录账号:********* 登录密码:********
ptrade交易测试客户端下载链接 链接:
https://download.gjzq.com.cn/temp/organ/gjzqptrade_ceshi.rar
测试时间10:00--17:00 如有什么问题,请和我们联系。谢谢!
下面是国盛证券提供的试用账户:
国盛证券 - 国盛智投软件下载(测试版)Ptrade
https://download.gszq.com/ptrade/PTrade1.0-Client-V201906-00-000.zip
仿真账户:******* / ********
量化回测:支持1分钟、日线回测。
量化交易:支持LEVEL1 tick股票交易。
量化研究:提供云Ipython Notebook研究环境、行情数据2005年至今、可使用全市场金融数据。
国盛证券-迅投QMT软件下载(测试版)
https://download.gszq.com/xt/XtItClient_x64_QMT_test_1.0.0.22650.exe
仿真账户:*******/********
支持VBA、Python开发策略 可以安装第三方库 软件帮助有文档,测试版历史数据不是很准确,以熟悉界面为主。
如果需要测试账号, 需要开通券商账号后找券商经理获取.
可以扫码联系开通
查看全部
下面是国金证券提供的试用账户:
国金证券 - QMT测试账号信息: 登录账号:*********** 登录密码:**********
QMT交易测试客户端下载链接 链接:
https://download.gjzq.com.cn/temp/organ/gjzqqmt_ceshi.rar
国金证券 - ptrade测试账号信息: 登录账号:********* 登录密码:********
ptrade交易测试客户端下载链接 链接:
https://download.gjzq.com.cn/temp/organ/gjzqptrade_ceshi.rar
测试时间10:00--17:00 如有什么问题,请和我们联系。谢谢!
下面是国盛证券提供的试用账户:
国盛证券 - 国盛智投软件下载(测试版)Ptrade
https://download.gszq.com/ptrade/PTrade1.0-Client-V201906-00-000.zip
仿真账户:******* / ********
量化回测:支持1分钟、日线回测。
量化交易:支持LEVEL1 tick股票交易。
量化研究:提供云Ipython Notebook研究环境、行情数据2005年至今、可使用全市场金融数据。
国盛证券-迅投QMT软件下载(测试版)
https://download.gszq.com/xt/XtItClient_x64_QMT_test_1.0.0.22650.exe
仿真账户:*******/********
支持VBA、Python开发策略 可以安装第三方库 软件帮助有文档,测试版历史数据不是很准确,以熟悉界面为主。
如果需要测试账号, 需要开通券商账号后找券商经理获取.
可以扫码联系开通

ptrade/qmt 判断股票是否涨停
Ptrade • 李魔佛 发表了文章 • 0 个评论 • 355 次浏览 • 2023-10-09 11:03
以ptrade为例:
先通过 get_snapshot - 取行情快照
其中里面有2个字段:
up_px:涨停价格(str:float);
down_px:跌停价格(str:float);用当前的最新价格和涨停跌停价格比较:
last_px:最新成交价(str:float);
if last_px>=up_px 就是达到涨停价,
还有判断此时的卖一上是否有挂单. 如果还有卖单, 说明此时的涨停板并没有封住, 被人砸开了.
跌停板的判断也是如此.
2. 使用现有的API函数, 更加简单方便, 这个方法只适用于ptrade, qmt没有类似的函数.
check_limit - 代码涨跌停状态判断
使用场景
该函数仅在交易模块可用。
接口说明
该接口用于标识当日股票的涨跌停情况。
注意事项:
无
参数
security:单只股票代码或者多只股票代码组成的列表,必填字段(list[str]/str);
返回
正常返回一个dict类型数据,包含每只股票代码的涨停状态。多只股票代码查询时其中部分股票代码查询异常则该代码返回既不涨停也不跌停状态0。(dict[str:int])
涨跌停状态说明:
2:触板涨停(已经是涨停价格,但还有卖盘);
1:涨停;
0:既不涨停也不跌停;
-1:跌停;
-2:触板跌停(已经是跌停价格,但还有买盘);
示例代码:
def initialize(context):
g.security = '600570.SS'
set_universe(g.security)
def handle_data(context, data):
# 代码涨跌停状态
stock_flag = check_limit(g.security)
log.info(stock_flag)
公众号: 可转债量化分析
查看全部
以ptrade为例:
先通过 get_snapshot - 取行情快照
其中里面有2个字段:
up_px:涨停价格(str:float);用当前的最新价格和涨停跌停价格比较:
down_px:跌停价格(str:float);
last_px:最新成交价(str:float);
if last_px>=up_px 就是达到涨停价,
还有判断此时的卖一上是否有挂单. 如果还有卖单, 说明此时的涨停板并没有封住, 被人砸开了.
跌停板的判断也是如此.
2. 使用现有的API函数, 更加简单方便, 这个方法只适用于ptrade, qmt没有类似的函数.
check_limit - 代码涨跌停状态判断
使用场景
该函数仅在交易模块可用。
接口说明
该接口用于标识当日股票的涨跌停情况。
注意事项:
无
参数
security:单只股票代码或者多只股票代码组成的列表,必填字段(list[str]/str);
返回
正常返回一个dict类型数据,包含每只股票代码的涨停状态。多只股票代码查询时其中部分股票代码查询异常则该代码返回既不涨停也不跌停状态0。(dict[str:int])
涨跌停状态说明:
2:触板涨停(已经是涨停价格,但还有卖盘);
1:涨停;
0:既不涨停也不跌停;
-1:跌停;
-2:触板跌停(已经是跌停价格,但还有买盘);
示例代码:
def initialize(context):
g.security = '600570.SS'
set_universe(g.security)
def handle_data(context, data):
# 代码涨跌停状态
stock_flag = check_limit(g.security)
log.info(stock_flag)
公众号: 可转债量化分析

一个因为蓝盾退债引起的报错【Ptrade/QMT】
量化交易 • 李魔佛 发表了文章 • 0 个评论 • 238 次浏览 • 2023-09-25 02:49
上去一看。
每一个tick都在报错:
好家伙? 怎么会有个 404001.SS的可转债代码的?
于是顺着代码去调试。 这个代码是从我的接口传过去的。
于是我看了下数据库。
赫然发现了一个蓝盾退债的玩意, 代码正是 404001, 无语中。 怎么这个代码不按常理来的呢。 虽说是三板的股票,可是转债代码改成4字头, 也是奇葩。
刚好也碰巧我的拼接后缀代码:
def modify_code(self, x):
return x + '.SZ' if x.startswith('12') else x + '.SS'
401开头,于是拼接了个.SS 后缀,导致ptrade无法正确识别这个代码行情。
可能用401001.SZ 可以拿到行情呢。
查看全部
上去一看。
每一个tick都在报错:
好家伙? 怎么会有个 404001.SS的可转债代码的?
于是顺着代码去调试。 这个代码是从我的接口传过去的。
于是我看了下数据库。
赫然发现了一个蓝盾退债的玩意, 代码正是 404001, 无语中。 怎么这个代码不按常理来的呢。 虽说是三板的股票,可是转债代码改成4字头, 也是奇葩。
刚好也碰巧我的拼接后缀代码:
def modify_code(self, x):
return x + '.SZ' if x.startswith('12') else x + '.SS'
401开头,于是拼接了个.SS 后缀,导致ptrade无法正确识别这个代码行情。
可能用401001.SZ 可以拿到行情呢。

国金QMT测试版|模拟盘 安装程序 下载
QMT • 李魔佛 发表了文章 • 0 个评论 • 1095 次浏览 • 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就可以了。费率万一,可半年后免五。
开户后可提供技术相关解答。

万0.854 免5 量化开户|QMT|Ptrade|掘金量化|国盛证券
券商万一免五 • 李魔佛 发表了文章 • 0 个评论 • 868 次浏览 • 2023-09-01 22:25
为贯彻落实7月24日中央政治局会议精神和国务院相关会议部署,进一步活跃资本市场,提振投资者信心,形成推动经济持续回升向好的工作合力,证监会指导上海证券交易所、深圳证券交易所、北京证券交易所自8月28日起进一步降低证券交易经手费。沪深交易所此次将A股、B股证券交易经手费从按成交金额的0.00487%双向收取下调为按成交金额的0.00341%双向收取,降幅达30%;北交所在2022年12月调降证券交易经手费50%的基础上,再次将证券交易经手费标准降低50%,由按成交金额的0.025%双边收取下调至按成交金额的0.0125%双边收取。同时,将引导证券公司稳妥做好与客户合同变更及相关交易参数的调整,依法降低经纪业务佣金费率,切实将此次证券交易经手费下降的政策效果传导至广大投资者
在今年8月的时候,交易所下调经手费,经手费是交易所收取的。 所以国盛证券响应国家号召,第一时间下调经手费。
从原来的万1免5,下降到现在的万0.854 免5
对于量化交易Ptrade,QMT,交易费率也是一样,下调到万0.854 免五 !!! 简直良心证券呀,有木有!
目前国盛证券的QMT,miniQMT的开通门槛是入金50W, Ptrade的入金门槛也是50W,而且国盛的Ptrade是可以访问外部数据的。比如你的自己的mysql数据库,还有爬虫获取问财数据等等。 开ptrade的我一般推荐你们开通国盛证券的。 而其他 的湘财证券ptrade,是无法获取外部数据,外部网络的。
需要开通的可以扫码微信开通:
备注: 量化开户
非诚勿扰,欢迎其他券商合作!
查看全部
为贯彻落实7月24日中央政治局会议精神和国务院相关会议部署,进一步活跃资本市场,提振投资者信心,形成推动经济持续回升向好的工作合力,证监会指导上海证券交易所、深圳证券交易所、北京证券交易所自8月28日起进一步降低证券交易经手费。沪深交易所此次将A股、B股证券交易经手费从按成交金额的0.00487%双向收取下调为按成交金额的0.00341%双向收取,降幅达30%;北交所在2022年12月调降证券交易经手费50%的基础上,再次将证券交易经手费标准降低50%,由按成交金额的0.025%双边收取下调至按成交金额的0.0125%双边收取。同时,将引导证券公司稳妥做好与客户合同变更及相关交易参数的调整,依法降低经纪业务佣金费率,切实将此次证券交易经手费下降的政策效果传导至广大投资者
在今年8月的时候,交易所下调经手费,经手费是交易所收取的。 所以国盛证券响应国家号召,第一时间下调经手费。
从原来的万1免5,下降到现在的万0.854 免5
对于量化交易Ptrade,QMT,交易费率也是一样,下调到万0.854 免五 !!! 简直良心证券呀,有木有!
目前国盛证券的QMT,miniQMT的开通门槛是入金50W, Ptrade的入金门槛也是50W,而且国盛的Ptrade是可以访问外部数据的。比如你的自己的mysql数据库,还有爬虫获取问财数据等等。 开ptrade的我一般推荐你们开通国盛证券的。 而其他 的湘财证券ptrade,是无法获取外部数据,外部网络的。
需要开通的可以扫码微信开通:

备注: 量化开户
非诚勿扰,欢迎其他券商合作!
国金QMT实盘版本下载地址
QMT • 李魔佛 发表了文章 • 0 个评论 • 945 次浏览 • 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
QMT iQuant miniQMT它们有什么区别?
量化交易 • 李魔佛 发表了文章 • 0 个评论 • 653 次浏览 • 2023-08-18 15:46
对于第一次接触的朋友来说,经常会问到几个问题,QMT和iQuant,miniQMT有什么区别。
首先,QMT和iQuant都是有迅投开发的。miniQMT是在QMT底下的运行的一个极简模式。
接下来将详细的讲讲。
QMT vs iQuant
一般券商采购了迅投的QMT,接入行情数据服务器和交易服务器,和用户资金账户,就可以让他成为自己的量化交易软件。
而iQuant是有国信定制开发的。iQuant它的大部分券商的QMT的功能基本一样。 不同的地方有:
iQuant移除了VBA模型
下图是国金QMT,在新建策略下面,有VBA模型和python模型
而在国信的iQuant的策略开发模式下,只支持python模型,VBA编写模型的功能被移除了。
对于VBA而言,实际是一门古老的语言,至少在互联网领域,已经没见过几个人在用的了。
不过我在查询了一下它的在QMT里面的实盘交易代码,其实它还是挺适合熟悉通达信公式的朋友使用,很多语法是从通达信的公式演变而来的。
iQuant支持投资研究,使用jupyter notebook逐行运行,为了便于调试。
而其他的QMT均没有这个功能。 不过这个功能我试了下,它只是调用我系统的jupyter notebook,而且它有严重的bug,居然运行不了任何代码。(ptrade也有个类似这样的功能,可以逐行调用内置的获取行情的函数,ptrade的是可以正常运行的)
少数券商的QMT无法在虚拟机运行
QMT可以在虚拟机运行,大部分券商的QMT可以在虚拟机里面运行,这也意味这可以云主机服务器运行,比如阿里云,腾讯云这种,在云服务器上网络和系统稳定性都要比你在家里放的主机要好,因为QMT需要一台正在运行的Windows系统,且网络畅通。
只有少数券商的QMT无法在虚拟机里面运行。
之前笔者粗略地对比了下QMT读取的系统信息,异同点字在于磁盘序列号,想要硬刚的读者朋友在可以尝试修改虚拟机的硬盘序列号。
在python编写策略的代码层面,QMT和iQuant的接口文档也基本一致的,可能在一些功能函数上会有些少出入。二者写的python代码可互相在彼此上运行。
QMT 与 miniQMT
miniQMT属于QMT的一个子功能,一个精简功能下的自动交易框架,只支持实盘交易,不支持回测。在miniQMT模式下,你的策略代码将不在固定在自带的那个QMT软件下编写,而是可以自由地使用pycharm,vscode等编辑器,运行的时候直接使用 python xxxx.py 这样的形式启动。
只是券商很少对它进行宣传,以至于用它的人不多。
进入miniQMT的方法: 点击QMT程序,登录时勾选极简模式
注意:极简模式下,需要一直保持者这个miniQMT的登录程序在运行,意味者miniQMT也只能在windows系统下运行。
XtQuant
miniQMT的核心是XtQuant,XtQuant能提供哪些服务?
XtQuant是基于迅投MiniQMT衍生出来的一套完善的Python策略运行框架,对外以Python库的形式提供策略交易所需要的行情和交易相关的API接口。
XtQuant运行依赖环境
XtQuant目前提供的库包括Python3.6、3.7、3.8版本,不同版本的python导入时会自动切换。根据群友反馈,最新的版本可以支持到python3.11。
在运行使用XtQuant的程序前需要先启动MiniQMT客户端。
然后把你的QMT目录下的\bin.x64\Lib\site-packages\xtquant复制到你系统python目录下的site-packages。
然后就可以在你的代码里面导入QMT的函数,包括获取行情数据,下单函数。
它的帮助文档在bin.x64\Lib\site-packages\xtquant\doc 目录下。
从它的帮助文档来看,它是一套和QMT接口函数完全不一样的交易框架。
所以QMT的代码,无法直接拷贝到miniQMT中使用。虽然名字叫miniQMT,但感觉它提供的很多函数功能,要比QMT更为丰富,用户可以掌控的流程更多,更灵活。
iQuant版虽然也有精简版的miniQMT,但它对个人用户不提供下单功能呢,只有获取行情数据,财务数据等的数据权限。
还有一个与之配套的xtdata库,是专门用来获取行情数据的,而xttrade是专门用来交易下单的。
因为xtdata可以获取很多股票,可转债,ETF等等历史数据,所以即使你不用miniQMT做交易,你也可以白嫖它的数据,这比用积分的tushare简直不要太爽。比如可以获取到股票或可转债的日线,分钟线,甚至tick数据。
比如下面的代码就可以获取 众信转债 的某个时间的历史tick数据,并保存到文件。 只要稍微改造下,就可以获取全市场的转债的tick数据。
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)
dump_single_code_tick()
把上面保存为main.py, 然后执行python main.py , 片刻就可以看到生成的文件数据了。
结语
为了便于读者快速浏览帮助文档,可以在公众号后台回复对应的关键词获取对应的帮助文档:
qmt文档
miniqmt文档
如果想要体验qmt或者miniqmt自动交易的朋友,可以后台回复:开通qmt
即可获取低门槛低费率的开通qmt/iQuant的券商开户方式。
知识星球: 查看全部
对于第一次接触的朋友来说,经常会问到几个问题,QMT和iQuant,miniQMT有什么区别。
首先,QMT和iQuant都是有迅投开发的。miniQMT是在QMT底下的运行的一个极简模式。

接下来将详细的讲讲。
QMT vs iQuant
一般券商采购了迅投的QMT,接入行情数据服务器和交易服务器,和用户资金账户,就可以让他成为自己的量化交易软件。

而iQuant是有国信定制开发的。iQuant它的大部分券商的QMT的功能基本一样。 不同的地方有:
iQuant移除了VBA模型
下图是国金QMT,在新建策略下面,有VBA模型和python模型

而在国信的iQuant的策略开发模式下,只支持python模型,VBA编写模型的功能被移除了。

对于VBA而言,实际是一门古老的语言,至少在互联网领域,已经没见过几个人在用的了。
不过我在查询了一下它的在QMT里面的实盘交易代码,其实它还是挺适合熟悉通达信公式的朋友使用,很多语法是从通达信的公式演变而来的。

iQuant支持投资研究,使用jupyter notebook逐行运行,为了便于调试。
而其他的QMT均没有这个功能。 不过这个功能我试了下,它只是调用我系统的jupyter notebook,而且它有严重的bug,居然运行不了任何代码。(ptrade也有个类似这样的功能,可以逐行调用内置的获取行情的函数,ptrade的是可以正常运行的)

少数券商的QMT无法在虚拟机运行
QMT可以在虚拟机运行,大部分券商的QMT可以在虚拟机里面运行,这也意味这可以云主机服务器运行,比如阿里云,腾讯云这种,在云服务器上网络和系统稳定性都要比你在家里放的主机要好,因为QMT需要一台正在运行的Windows系统,且网络畅通。
只有少数券商的QMT无法在虚拟机里面运行。

之前笔者粗略地对比了下QMT读取的系统信息,异同点字在于磁盘序列号,想要硬刚的读者朋友在可以尝试修改虚拟机的硬盘序列号。

在python编写策略的代码层面,QMT和iQuant的接口文档也基本一致的,可能在一些功能函数上会有些少出入。二者写的python代码可互相在彼此上运行。
QMT 与 miniQMT
miniQMT属于QMT的一个子功能,一个精简功能下的自动交易框架,只支持实盘交易,不支持回测。在miniQMT模式下,你的策略代码将不在固定在自带的那个QMT软件下编写,而是可以自由地使用pycharm,vscode等编辑器,运行的时候直接使用 python xxxx.py 这样的形式启动。
只是券商很少对它进行宣传,以至于用它的人不多。
进入miniQMT的方法: 点击QMT程序,登录时勾选极简模式

注意:极简模式下,需要一直保持者这个miniQMT的登录程序在运行,意味者miniQMT也只能在windows系统下运行。
XtQuant
miniQMT的核心是XtQuant,XtQuant能提供哪些服务?
XtQuant是基于迅投MiniQMT衍生出来的一套完善的Python策略运行框架,对外以Python库的形式提供策略交易所需要的行情和交易相关的API接口。
XtQuant运行依赖环境
XtQuant目前提供的库包括Python3.6、3.7、3.8版本,不同版本的python导入时会自动切换。根据群友反馈,最新的版本可以支持到python3.11。
在运行使用XtQuant的程序前需要先启动MiniQMT客户端。
然后把你的QMT目录下的\bin.x64\Lib\site-packages\xtquant复制到你系统python目录下的site-packages。

然后就可以在你的代码里面导入QMT的函数,包括获取行情数据,下单函数。

它的帮助文档在bin.x64\Lib\site-packages\xtquant\doc 目录下。
从它的帮助文档来看,它是一套和QMT接口函数完全不一样的交易框架。

所以QMT的代码,无法直接拷贝到miniQMT中使用。虽然名字叫miniQMT,但感觉它提供的很多函数功能,要比QMT更为丰富,用户可以掌控的流程更多,更灵活。
iQuant版虽然也有精简版的miniQMT,但它对个人用户不提供下单功能呢,只有获取行情数据,财务数据等的数据权限。
还有一个与之配套的xtdata库,是专门用来获取行情数据的,而xttrade是专门用来交易下单的。

因为xtdata可以获取很多股票,可转债,ETF等等历史数据,所以即使你不用miniQMT做交易,你也可以白嫖它的数据,这比用积分的tushare简直不要太爽。比如可以获取到股票或可转债的日线,分钟线,甚至tick数据。
比如下面的代码就可以获取 众信转债 的某个时间的历史tick数据,并保存到文件。 只要稍微改造下,就可以获取全市场的转债的tick数据。
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)
dump_single_code_tick()
把上面保存为main.py, 然后执行python main.py , 片刻就可以看到生成的文件数据了。
结语
为了便于读者快速浏览帮助文档,可以在公众号后台回复对应的关键词获取对应的帮助文档:
qmt文档
miniqmt文档
如果想要体验qmt或者miniqmt自动交易的朋友,可以后台回复:开通qmt
即可获取低门槛低费率的开通qmt/iQuant的券商开户方式。

知识星球:

哪些券商有miniqmt? 门槛如何
QMT • 李魔佛 发表了文章 • 0 个评论 • 828 次浏览 • 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即可。
所以平时有优惠费率的时候就不要犹犹豫豫,把账户和权限开了再说,因为好事不常有,过了这个桥就没有这个店。
需要开户的盆友可以扫码咨询

ptrade qmt无法登录问题
量化交易 • 李魔佛 发表了文章 • 0 个评论 • 497 次浏览 • 2023-08-08 14:44
实际上这是在周五晚上和周末出现的问题,这是计划内的维护。部分券商没有技术服务支持,用户可能连服务器日常维护服务通知都无法及时得到通知。
PS:其实,大部分券商基本也就那样,ptrade和qmt的技术支持基本等于0,不敢说全部,至少90%的情况是这样的。 以至于我自己维护了一个ptrade,qmt的技术群(审核才可以加),日常有空就在里面解决群友的问题。基本都是些基础问题,部分可能是券商数据问题,大部分是用户的代码问题。 查看全部
QMT vs PTrade资金更新速度|高频中如何处理
Ptrade • 李魔佛 发表了文章 • 0 个评论 • 634 次浏览 • 2023-07-06 17:35
平时在手动交易中,下单委托后,再切换回去持仓页面,可以看到你的可用资金变少了。而在QMT和PTrade里面,却可能会表现得不一样。本文用代码和实盘来作对比。希望本文对量化新手有所帮助,记得收藏哦! 公众号首页链接了视频号,里面也有不少的新手入门教程和进阶教程,欢迎观看。
了解量化交易程序里面的资金更新速度,无论对量化T+0日内交易(可转债,T+0 ETF),还是轮动策略调仓,都是必须的。
Ptrade
以交易逆回购为例,这也便于量化新手也可以实践,可以放心跑,不会亏钱。
代码很简单,每个tick_data行情更新时间(3秒)里打印当前的可用资金。中途买入(借出)逆回购后,看看当面打印的可用资金什么时候发生变化。
import datetime
def initialize(context):
# 初始化策略
g.already_run = False
def handle_data(context, data):
pass
def get_available_cash(context):
# 读取变量protfolio里的可用资金的值
return context.portfolio.cash
def current_time():
return datetime.datetime.now().strftime('%H:%M:%S.%f')
def tick_data(context, data):
log.info('可用资金{}'.format(get_available_cash(context)))
if not g.already_run:
g.already_run = True
# 卖出100手 R-001
ret = order_tick('131810.SZ', -10, priceGear='1', limit_price=None)
def on_order_response(context, trade_list):
# 委托回调函数,有委托出现就调用此函数
log.info('已委托下单 {}'.format(current_time()))
放到Ptrade的实盘里执行,得到下面日志
下单前可用资金为17902,程序启动后下单时间在10:41:08,卖出10张R-001,市值1000元;间隔3s后打印可用资金,在10:41:13的时候,可用资金依然是17902,此时时间已经过去了5秒;
在10:41:18打印的时候资产才发生了变化,此时可用资金为16902,此时距离下单时的10:41:08,已经过去了10秒。所以如果在高频下单时,使用读取内置的context.portfolio.cash 来获取可用资金,那就寄了。那是不是意味着Ptrade无法进行高频率的交易了呢?当然不是的,此时可以使用内置的成交主推函数来更新可用资金,后面下面再介绍。
QMT
而qmt的代码如下,把打印的可用资金的操作放到handlebar里面,它和上面的Ptrade作用一样,每隔3s执行一次。
# encoding:gbk
import datetime
ACCOUNT = '你的账户ID'
start = True
def init(ContextInfo):
ContextInfo.set_account(ACCOUNT)
def current_time():
return datetime.datetime.now().strftime('%H:%M:%S.%f')
def get_available_cash(ContextInfo):
acct_info = get_trade_detail_data(ACCOUNT, 'stock', 'account')
return acct_info[0].m_dAvailable
def deal_callback(ContextInfo, dealInfo):
print('before')
print(dealInfo.m_strProductID)
print(dealInfo.m_nDirection)
print(dealInfo.m_dTradeAmount)
print(dealInfo.m_nVolume)
print(dealInfo.m_dPrice)
print('call back --- ')
print(current_time())
def buy_action(ContextInfo):
opType = 24
orderType = 1101
accountID = ACCOUNT
orderCode = '131810.SZ'
prType = 11
price = 1.8
volume = 10
quickTrade = 2
passorder(opType, orderType, accountID, orderCode, prType, price, volume, quickTrade, ContextInfo)
def handlebar(ContextInfo):
global start
if ContextInfo.is_last_bar():
cash = get_available_cash(ContextInfo)
print('{} 可用资金{}'.format(current_time(),cash))
if start:
print('下单逆回购 131810 ')
buy_action(ContextInfo)
start = False
部署到QMT实盘后,执行。
得到下面的运行日志:
从上面的日志看出,程序在14:35:11启动,马上使用passorder下单,卖出1000元的R-001,此时时间14:35:12,马上成交了。而可用资金在下单后的0.47秒后,14:35:12,显示少了1000元。此时的资金状态已经被更新了。
所以QMT的资金持仓更新速度要比Ptrade快出不少的,如果不是追求毫秒级别的话,这个速度足够满足大部分的轮动和T+0操作了。
虽然QMT的资金持仓更新很快,但如果你的策略是高频或偏高频运行,比如你这一个时刻刚刚买入,下一个tick来到时就要卖出,或者采用驱动成交型的网格交易,你无法知道挂单是在哪一个时刻成交的,此时也亦不能一直循环读取你的可以资金或者持仓来判断是否成交,因为这样会阻塞QMT无法进行下一步的操作(除非你本身就是一直在等待成交,成交后才进行下程序一步)。
委托、成交回调函数
Ptrade和QMT都有对应的委托成交回调函数,用于应对需要即时获取成交状态的情景下。
接口文档介绍如下
Ptrade http://ptradeapi.com/#on_trade_response
QMT:http://qmt.ptradeapi.com/QMT_Python_API_Doc.html#deal-callback
里面就说明了,“该函数会在成交主推回调时响应,比引擎和get_trades()函数更新Order状态的速度更快,适合对速度要求比较高的策略。”
Ptrade的部分代码片段如下:
# 交易回调
def on_trade_response(context, trade_list):
# 成交主推
now = context.blotter.current_dt.strftime("%H:%M:%S")
for trade_info in trade_list:
if trade_info['order_id'] == '':
# 不是本策略跳过
log.info('非本策略订单')
continue
code = trade_info['stock_code']
code = post_fix_convert(code)
business_time = trade_info['business_time']
business_amount = trade_info['business_amount'] # 这个是负数,如果卖出
business_price = trade_info['business_price']
g.total_cash -= business_amount # 马上更新资金状态
g.total_cash -= business_amount # 马上更新资金状态g.total_cash是一个全局的可用资金, 可以提前设定好,亦可以是开盘前读取一次你的账户可用资金。
每次成交的那一刻,on_trade_response这个函数就会被动触发,在这里就可以简单的更新你的资金状态了。上面的例子是最基础的更新资金。
实际可以使用其他的诸如dict或类对象来更新仓位。
上面代码是把仓位更新放到一个全局dict里面,key是股票代码,value也是一个dict,里面包含交易时间,持仓数目,价格等等。
好了,时间有限,今天的教程就到这里了,码字不易,欢迎点赞+收藏哦~
查看全部
平时在手动交易中,下单委托后,再切换回去持仓页面,可以看到你的可用资金变少了。而在QMT和PTrade里面,却可能会表现得不一样。本文用代码和实盘来作对比。希望本文对量化新手有所帮助,记得收藏哦! 公众号首页链接了视频号,里面也有不少的新手入门教程和进阶教程,欢迎观看。
了解量化交易程序里面的资金更新速度,无论对量化T+0日内交易(可转债,T+0 ETF),还是轮动策略调仓,都是必须的。
Ptrade
以交易逆回购为例,这也便于量化新手也可以实践,可以放心跑,不会亏钱。
代码很简单,每个tick_data行情更新时间(3秒)里打印当前的可用资金。中途买入(借出)逆回购后,看看当面打印的可用资金什么时候发生变化。
import datetime
def initialize(context):
# 初始化策略
g.already_run = False
def handle_data(context, data):
pass
def get_available_cash(context):
# 读取变量protfolio里的可用资金的值
return context.portfolio.cash
def current_time():
return datetime.datetime.now().strftime('%H:%M:%S.%f')
def tick_data(context, data):
log.info('可用资金{}'.format(get_available_cash(context)))
if not g.already_run:
g.already_run = True
# 卖出100手 R-001
ret = order_tick('131810.SZ', -10, priceGear='1', limit_price=None)
def on_order_response(context, trade_list):
# 委托回调函数,有委托出现就调用此函数
log.info('已委托下单 {}'.format(current_time()))
放到Ptrade的实盘里执行,得到下面日志
下单前可用资金为17902,程序启动后下单时间在10:41:08,卖出10张R-001,市值1000元;间隔3s后打印可用资金,在10:41:13的时候,可用资金依然是17902,此时时间已经过去了5秒;
在10:41:18打印的时候资产才发生了变化,此时可用资金为16902,此时距离下单时的10:41:08,已经过去了10秒。所以如果在高频下单时,使用读取内置的context.portfolio.cash 来获取可用资金,那就寄了。那是不是意味着Ptrade无法进行高频率的交易了呢?当然不是的,此时可以使用内置的成交主推函数来更新可用资金,后面下面再介绍。
QMT
而qmt的代码如下,把打印的可用资金的操作放到handlebar里面,它和上面的Ptrade作用一样,每隔3s执行一次。
# encoding:gbk
import datetime
ACCOUNT = '你的账户ID'
start = True
def init(ContextInfo):
ContextInfo.set_account(ACCOUNT)
def current_time():
return datetime.datetime.now().strftime('%H:%M:%S.%f')
def get_available_cash(ContextInfo):
acct_info = get_trade_detail_data(ACCOUNT, 'stock', 'account')
return acct_info[0].m_dAvailable
def deal_callback(ContextInfo, dealInfo):
print('before')
print(dealInfo.m_strProductID)
print(dealInfo.m_nDirection)
print(dealInfo.m_dTradeAmount)
print(dealInfo.m_nVolume)
print(dealInfo.m_dPrice)
print('call back --- ')
print(current_time())
def buy_action(ContextInfo):
opType = 24
orderType = 1101
accountID = ACCOUNT
orderCode = '131810.SZ'
prType = 11
price = 1.8
volume = 10
quickTrade = 2
passorder(opType, orderType, accountID, orderCode, prType, price, volume, quickTrade, ContextInfo)
def handlebar(ContextInfo):
global start
if ContextInfo.is_last_bar():
cash = get_available_cash(ContextInfo)
print('{} 可用资金{}'.format(current_time(),cash))
if start:
print('下单逆回购 131810 ')
buy_action(ContextInfo)
start = False
部署到QMT实盘后,执行。
得到下面的运行日志:
从上面的日志看出,程序在14:35:11启动,马上使用passorder下单,卖出1000元的R-001,此时时间14:35:12,马上成交了。而可用资金在下单后的0.47秒后,14:35:12,显示少了1000元。此时的资金状态已经被更新了。
所以QMT的资金持仓更新速度要比Ptrade快出不少的,如果不是追求毫秒级别的话,这个速度足够满足大部分的轮动和T+0操作了。
虽然QMT的资金持仓更新很快,但如果你的策略是高频或偏高频运行,比如你这一个时刻刚刚买入,下一个tick来到时就要卖出,或者采用驱动成交型的网格交易,你无法知道挂单是在哪一个时刻成交的,此时也亦不能一直循环读取你的可以资金或者持仓来判断是否成交,因为这样会阻塞QMT无法进行下一步的操作(除非你本身就是一直在等待成交,成交后才进行下程序一步)。
委托、成交回调函数
Ptrade和QMT都有对应的委托成交回调函数,用于应对需要即时获取成交状态的情景下。
接口文档介绍如下
Ptrade http://ptradeapi.com/#on_trade_response
QMT:http://qmt.ptradeapi.com/QMT_Python_API_Doc.html#deal-callback
里面就说明了,“该函数会在成交主推回调时响应,比引擎和get_trades()函数更新Order状态的速度更快,适合对速度要求比较高的策略。”
Ptrade的部分代码片段如下:
# 交易回调
def on_trade_response(context, trade_list):
# 成交主推
now = context.blotter.current_dt.strftime("%H:%M:%S")
for trade_info in trade_list:
if trade_info['order_id'] == '':
# 不是本策略跳过
log.info('非本策略订单')
continue
code = trade_info['stock_code']
code = post_fix_convert(code)
business_time = trade_info['business_time']
business_amount = trade_info['business_amount'] # 这个是负数,如果卖出
business_price = trade_info['business_price']
g.total_cash -= business_amount # 马上更新资金状态
g.total_cash -= business_amount # 马上更新资金状态g.total_cash是一个全局的可用资金, 可以提前设定好,亦可以是开盘前读取一次你的账户可用资金。
每次成交的那一刻,on_trade_response这个函数就会被动触发,在这里就可以简单的更新你的资金状态了。上面的例子是最基础的更新资金。
实际可以使用其他的诸如dict或类对象来更新仓位。
上面代码是把仓位更新放到一个全局dict里面,key是股票代码,value也是一个dict,里面包含交易时间,持仓数目,价格等等。
好了,时间有限,今天的教程就到这里了,码字不易,欢迎点赞+收藏哦~

目前支持量化接口的万一免五的券商有哪些?
量化交易-Ptrade-QMT • 李魔佛 发表了文章 • 0 个评论 • 1443 次浏览 • 2023-07-04 22:52
其中能够股票免五的有国金证券,国盛证券,国信证券,安信证券。
其中,国金证券,国盛证券支持QMT、MiniQMT、Ptrade。
国信证券,安信证券支持QMT。
东莞证券支持Ptrade
可转债默认免五。
开户后可加入量化技术交流群,可获得编程技术指导。
【提问者需要把问题描述清楚即可,PS: 有些人动不动就说:“Ptrade不行呀”,“QMT垃圾呀”,结果让他贴代码上来瞅瞅,是他本身代码写的拉垮,目前贴出来的已知的问题,90%是个人代码问题。】
扫码添加微信咨询开户:
查看全部
Ptrade/QMT 可转债转股操作 python代码
量化交易 • 李魔佛 发表了文章 • 0 个评论 • 843 次浏览 • 2023-06-19 18:14
而这个转股操作是要在交易时间,也就是盘中时间下一个债转股的命令,然后盘后交易所会更会你盘中下的转股指令,将对应的可转债转为对应的股票,这是,持仓里面的可转债会消失,变成该可转债对应的正股。
(当然这是在全部转股的前提下的情况,也有可能有部分人转债只转一部分,这样持仓里面还仍然会有部分可转债没有被转为股票)
那么在Ptrade和QMT里面,如何调用API接口进行可转债转股呢?
Ptrade:
def initialize(context):
g.security = "600570.SS"
set_universe(g.security)
def before_trading_start(context, data):
g.count = 0
def handle_data(context, data):
if g.count == 0:
# 对持仓内的贝斯进行转股操作
debt_to_stock_order("123075.SZ", -1000)
g.count += 1
# 查看委托状态
log.info(get_orders())
g.count += 1
主要是上面的函数,
debt_to_stock_order 传入可转债代码和转股的数量,注意数量用加一个负号。
QMT可转债转股操作
#coding:gbk
c = True
account = '11111111' # 个人账户
def init(ContextInfo):
pass
def handlebar(ContextInfo):
if not ContextInfo.is_last_bar():
#历史k线不应该发出实盘信号 跳过
return
if c:
passorder(80,1101,account,s,5,0,-100,'1',2,'tzbz',ContextInfo)
c=False
passorder 里面的 80是 普通账户可转债转股
更多Ptrade,qmt知识,可以关注公众号
查看全部
而这个转股操作是要在交易时间,也就是盘中时间下一个债转股的命令,然后盘后交易所会更会你盘中下的转股指令,将对应的可转债转为对应的股票,这是,持仓里面的可转债会消失,变成该可转债对应的正股。
(当然这是在全部转股的前提下的情况,也有可能有部分人转债只转一部分,这样持仓里面还仍然会有部分可转债没有被转为股票)
那么在Ptrade和QMT里面,如何调用API接口进行可转债转股呢?
Ptrade:
def initialize(context):
g.security = "600570.SS"
set_universe(g.security)
def before_trading_start(context, data):
g.count = 0
def handle_data(context, data):
if g.count == 0:
# 对持仓内的贝斯进行转股操作
debt_to_stock_order("123075.SZ", -1000)
g.count += 1
# 查看委托状态
log.info(get_orders())
g.count += 1
主要是上面的函数,
debt_to_stock_order 传入可转债代码和转股的数量,注意数量用加一个负号。
QMT可转债转股操作
#coding:gbk
c = True
account = '11111111' # 个人账户
def init(ContextInfo):
pass
def handlebar(ContextInfo):
if not ContextInfo.is_last_bar():
#历史k线不应该发出实盘信号 跳过
return
if c:
passorder(80,1101,account,s,5,0,-100,'1',2,'tzbz',ContextInfo)
c=False
passorder 里面的 80是 普通账户可转债转股
更多Ptrade,qmt知识,可以关注公众号

国金证券QMT量化新人培训教程
QMT • 李魔佛 发表了文章 • 0 个评论 • 2122 次浏览 • 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获取实时分笔委托数据用哪个函数?
QMT • 李魔佛 发表了文章 • 0 个评论 • 824 次浏览 • 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的属性以及对应的值
QMT • 李魔佛 发表了文章 • 0 个评论 • 862 次浏览 • 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运行后的历史日志保存在哪个位置?
QMT • 李魔佛 发表了文章 • 0 个评论 • 776 次浏览 • 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),背景颜色
QMT • 李魔佛 发表了文章 • 0 个评论 • 857 次浏览 • 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 速度对比 (二)实时行情速度对比
QMT • 李魔佛 发表了文章 • 0 个评论 • 969 次浏览 • 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 速度对比 (一) 历史行情获取速度
QMT • 李魔佛 发表了文章 • 0 个评论 • 1361 次浏览 • 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/
公众号:

Ptrade QMT实盘策略记录 - 不定期更新
量化交易 • 李魔佛 发表了文章 • 0 个评论 • 1261 次浏览 • 2023-04-03 15:27
写出来的是已经实现且实盘稳定运行的;
涨停板;依赖ptrade的高速行情自动配合手动;两融账户的股票日内做T,持有底仓;股票小市值轮动+多因子可转债多因子(有N个版本+不同的排除因子 组合)可转债日内高频股票趋势动量ETF轮动套利脉冲卖出扫描
纯粹自己做的记录,便于自己平时复盘。
有兴趣的朋友可以关注公众号交流。 查看全部
ptrade QMT 动态止盈卖出 python代码实现
Ptrade • 李魔佛 发表了文章 • 0 个评论 • 745 次浏览 • 2023-03-13 23:53
比如设置20%,那么会每天盘中扫描,可以精确到3S 一格,如果你的持仓股的收益率大于20%,它将会帮你自动卖出。
占坑 待续 》》》
比如设置20%,那么会每天盘中扫描,可以精确到3S 一格,如果你的持仓股的收益率大于20%,它将会帮你自动卖出。
占坑 待续 》》》
ptrade qmt的模拟账户能不用尽量不用,无尽的bug让你浪费时间 怀疑人生
Ptrade • 李魔佛 发表了文章 • 0 个评论 • 1342 次浏览 • 2023-03-02 15:57
所以临时登录了模拟账户。 里面也挺悲剧的,初始化的500w资金,之前测试的时候随意买入的转债,很多都强赎了。而ptrade里面依然还在,导致大部分是亏损99%以上, 账上只剩可怜的88w,虚拟基金。
今天用ptrade获取A股市场所有的股票代码,居然调试了半小时,代码如下
def initialize(context):
# 初始化策略
g.security = "600570.SS"
set_universe(g.security)
def handle_data(context, data):
stock=get_Ashares()
log.info(stock)
输出的stock是[],没有任何数据。
上面的xxxxx is expired , close all positions by system. 是因为模拟账户上退市转债还依然挂在上面,清仓也清不掉。每次跑就循环一分钟输出。。
换了个券商的模拟账户,问题依然在,只好倒腾实盘账户。然后问题就解决了。
这个问题,在qmt上就更加严重了。 下次在星球上或者群里慢慢吐槽吧
查看全部
所以临时登录了模拟账户。 里面也挺悲剧的,初始化的500w资金,之前测试的时候随意买入的转债,很多都强赎了。而ptrade里面依然还在,导致大部分是亏损99%以上, 账上只剩可怜的88w,虚拟基金。
今天用ptrade获取A股市场所有的股票代码,居然调试了半小时,代码如下
def initialize(context):
# 初始化策略
g.security = "600570.SS"
set_universe(g.security)
def handle_data(context, data):
stock=get_Ashares()
log.info(stock)
输出的stock是[],没有任何数据。
上面的xxxxx is expired , close all positions by system. 是因为模拟账户上退市转债还依然挂在上面,清仓也清不掉。每次跑就循环一分钟输出。。
换了个券商的模拟账户,问题依然在,只好倒腾实盘账户。然后问题就解决了。
这个问题,在qmt上就更加严重了。 下次在星球上或者群里慢慢吐槽吧

qmt position对象里面有哪些属性?
QMT • 李魔佛 发表了文章 • 0 个评论 • 763 次浏览 • 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 可转债 双低(阈值)轮动 实盘代码
QMT • 李魔佛 发表了文章 • 0 个评论 • 1343 次浏览 • 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软件里面的快速计算是在什么模式下使用的?
QMT • 李魔佛 发表了文章 • 0 个评论 • 769 次浏览 • 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代码实现)实盘代码
QMT • 李魔佛 发表了文章 • 0 个评论 • 1071 次浏览 • 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的文档写的有点稀烂
QMT • 李魔佛 发表了文章 • 0 个评论 • 715 次浏览 • 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:比例(%)
看完不想吐槽了,一群文科生设计的软件。。。