Ptrade成交回调函数无法执行的原因? | ptrade bug

李魔佛 发表了文章 • 0 个评论 • 132 次浏览 • 2024-05-28 00:08 • 来自相关话题

目前的ptrade有一个隐藏很深的bug。
 
就是回调函数里面有一个字段entrust_no.
 
这个字段是什么意思呢? 是营业部的下单编号。比如你挂了一个委托单,就会有一个entrust_no, 比如 100001
 
这个编号对于一天的数据来说,是唯一不重复的,也就是一天内再不会出现100001。
 
而ptrade的成交回调依赖的是这个entrust_no, 如果系统里面已经触发过了一个entrust_no 为 100001的成交委托,那么如果又有一个重复的订单entrust_no 100001成交,那么,此时的ptrade的 成交回调函数是不会触发的!
 
那么上面说的一天内这个entrust_no是不会重复的。
 
可是,这个entrust_no挂单编号,在同一个营业部单元里,第二天会重复的,比如你第二天挂单也是entrust_no 100001,并且你的ptrade策略没有重启,也就是一直运行的话,那么如果碰巧你的下单entrust_no上昨天或者之前某一天(ptrade策略没有重启开始算起),entrust_no重复了的情况下。 
 
此时的ptrade 成交回调函数 on_trade_repsonse 是不会执行的!!!
 
天坑!
  查看全部
目前的ptrade有一个隐藏很深的bug。
 
就是回调函数里面有一个字段entrust_no.
 
这个字段是什么意思呢? 是营业部的下单编号。比如你挂了一个委托单,就会有一个entrust_no, 比如 100001
 
这个编号对于一天的数据来说,是唯一不重复的,也就是一天内再不会出现100001。
 
而ptrade的成交回调依赖的是这个entrust_no, 如果系统里面已经触发过了一个entrust_no 为 100001的成交委托,那么如果又有一个重复的订单entrust_no 100001成交,那么,此时的ptrade的 成交回调函数是不会触发的!
 
那么上面说的一天内这个entrust_no是不会重复的。
 
可是,这个entrust_no挂单编号,在同一个营业部单元里,第二天会重复的,比如你第二天挂单也是entrust_no 100001,并且你的ptrade策略没有重启,也就是一直运行的话,那么如果碰巧你的下单entrust_no上昨天或者之前某一天(ptrade策略没有重启开始算起),entrust_no重复了的情况下。 
 
此时的ptrade 成交回调函数 on_trade_repsonse 是不会执行的!!!
 
天坑!
 

国盛证券的Ptrade数据无论是回测还是实盘很有问题,前复权不正确,数据断崖

李魔佛 发表了文章 • 0 个评论 • 341 次浏览 • 2024-04-18 00:19 • 来自相关话题

连基本的历史数据都无法保证数据正确。
 
举个例子,比如 煤炭ETF 515220,





 
在4月12日进行的除权,1股变2股,因此,所以4月12日之后的价格会是原来的1/2,如果做前复权,那么前面的价格也都是要根据当前的价格做复权处理。
 
结果国盛的ptrade的历史数据,取的是前复权数据,前复权数据,(重点强调),在4月12日的的时候就出现了断崖。也就是没有做复权的处理。





 
测试代码很简单:
def initialize(context):
run_daily(context, event, '09:38')


def handle_data(context, data):
pass


def event(context):
his60 = get_history(60, '1d', ['close'], ['515220.SS'], fq='pre', include=False)
print(his60)运行时间改成任意的就行。
 
获取历史数据用
get_history,取过去60天的前复权的数据。 然后就是断崖的数据。 已经确定是国盛的ptrade数据问题。因为我用上面的代码,在东莞证券,国金证券,湘财证券的ptrade上运行,均能得到正确的数据。
 
然后更为搞笑的,这么一个问题,反馈了,没有回应。无语。
 
 
  查看全部
连基本的历史数据都无法保证数据正确。
 
举个例子,比如 煤炭ETF 515220,

20240418001102.png

 
在4月12日进行的除权,1股变2股,因此,所以4月12日之后的价格会是原来的1/2,如果做前复权,那么前面的价格也都是要根据当前的价格做复权处理。
 
结果国盛的ptrade的历史数据,取的是前复权数据,前复权数据,(重点强调),在4月12日的的时候就出现了断崖。也就是没有做复权的处理。

微信图片_20240418001026.png

 
测试代码很简单:
def initialize(context):
run_daily(context, event, '09:38')


def handle_data(context, data):
pass


def event(context):
his60 = get_history(60, '1d', ['close'], ['515220.SS'], fq='pre', include=False)
print(his60)
运行时间改成任意的就行。
 
获取历史数据用
get_history,取过去60天的前复权的数据。 然后就是断崖的数据。 已经确定是国盛的ptrade数据问题。因为我用上面的代码,在东莞证券,国金证券,湘财证券的ptrade上运行,均能得到正确的数据。
 
然后更为搞笑的,这么一个问题,反馈了,没有回应。无语。
 
 
 

ptrade调试经验分享(坑) 委托成交回调函数

李魔佛 发表了文章 • 0 个评论 • 778 次浏览 • 2023-12-22 10:30 • 来自相关话题

特么的在里面的报错了是不会有任何显示!!!!!!
 





 
之前的代码里面,由于少了一个if,导致如果code不在
g.start_buy_sell_queue 
这个集合里面的话,就会报错。(但正常情况下都会有值,但问题就出现在一些特殊情况下)
 
不然你试试在 
on_trade_response
里面直接raise一个Exception出来,日志里也不会有任何显示。
 
切近!! 
on_trade_response 里面做好安全防护!! 最好是有些业务逻辑完成了在里面print一下,以确保是执行到后面的。 查看全部
特么的在里面的报错了是不会有任何显示!!!!!!
 

20231222102356.png

 
之前的代码里面,由于少了一个if,导致如果code不在
g.start_buy_sell_queue 
这个集合里面的话,就会报错。(但正常情况下都会有值,但问题就出现在一些特殊情况下)
 
不然你试试在 
on_trade_response
里面直接raise一个Exception出来,日志里也不会有任何显示。
 
切近!! 
on_trade_response 里面做好安全防护!! 最好是有些业务逻辑完成了在里面print一下,以确保是执行到后面的。

ptrade精确参与集合竞价交易 时间设置问题

李魔佛 发表了文章 • 0 个评论 • 1097 次浏览 • 2023-11-16 10:10 • 来自相关话题

最近几次的集合竞价都没有卖出成功。
 
查了下日志。run_daily 设置的9:25运行,下单委托的时间在9:25:01 这个时间就被推到9:30开盘去成交了。
所以实际没有参与到9:25的集合竞价。
 
所以要参与集合竞价,需要设定在9:24分开始,然后不断在一个循环里面,用更小的时间颗粒,比如100ms去监听。
 
等到9:24:59的时间,才去下单。





 





 
具体代码可以参照我的知识星球

 
 
  查看全部
最近几次的集合竞价都没有卖出成功。
 
查了下日志。run_daily 设置的9:25运行,下单委托的时间在9:25:01 这个时间就被推到9:30开盘去成交了。
所以实际没有参与到9:25的集合竞价。
 
所以要参与集合竞价,需要设定在9:24分开始,然后不断在一个循环里面,用更小的时间颗粒,比如100ms去监听。
 
等到9:24:59的时间,才去下单。

20231116100349-v1.png

 

20231116100758-v1.png

 
具体代码可以参照我的知识星球

 
 
 

ptrade 全局对象g持久化对象保存失败

李魔佛 发表了文章 • 0 个评论 • 756 次浏览 • 2023-10-18 09:36 • 来自相关话题

 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 查看全部


 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中以'__'开头的变量为私有变量,持久化时将不会被保存;
 

20231018095102.png


 
具体可以参加 API文档:
https://ptradeapi.com

ptrade/qmt 判断股票是否涨停

李魔佛 发表了文章 • 0 个评论 • 1199 次浏览 • 2023-10-09 11:03 • 来自相关话题

 1. 可以直接用代码实现:
以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)
公众号: 可转债量化分析

 
  查看全部
 1. 可以直接用代码实现:
以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实盘

李魔佛 发表了文章 • 0 个评论 • 1400 次浏览 • 2023-10-07 14:14 • 来自相关话题

运行了一段时间的实盘策略。中途不断加条件,避免买入暴雷的品种;遇到一字板涨停的不要急于轮动卖出。等破板再卖出。
 
当前策略持有30只。




点击查看大图




点击查看大图

基于股票的策略不敢多买,属于试验阶段,后期仍然会不断根据市场调仓; 主仓依然在可转债。
 
公众号:可转债量化分析

如果需要策略代写,(ptrade、qmt,其他量化平台)
可以公众号后台回复:
策略代写

  查看全部
运行了一段时间的实盘策略。中途不断加条件,避免买入暴雷的品种;遇到一字板涨停的不要急于轮动卖出。等破板再卖出。
 
当前策略持有30只。

20231007002.jpg
点击查看大图

20231007003.jpg
点击查看大图

基于股票的策略不敢多买,属于试验阶段,后期仍然会不断根据市场调仓; 主仓依然在可转债。
 
公众号:可转债量化分析

如果需要策略代写,(ptrade、qmt,其他量化平台)
可以公众号后台回复:
策略代写

 

ptrade最多支持同时运行多少个策略?

李魔佛 发表了文章 • 0 个评论 • 929 次浏览 • 2023-09-21 17:16 • 来自相关话题

Ptrade上支持写无限个策略。





 
但同时运行的策略只有5个。





 
如果不需要的策略,可以把它暂停了,记住,不要随意暂停。 因为暂停了,重启后你的日志就会随之被清空。
平时也应该做好日志备份的习惯。 部分券商可以连接mysql,可以把数据导出,也可以顺便把日志也导出。





 
需要开通Ptrade或者代写的朋友可以咨询:

  查看全部
Ptrade上支持写无限个策略。

20230921170144-v1.png

 
但同时运行的策略只有5个。

20230921170529-v2.png

 
如果不需要的策略,可以把它暂停了,记住,不要随意暂停。 因为暂停了,重启后你的日志就会随之被清空。
平时也应该做好日志备份的习惯。 部分券商可以连接mysql,可以把数据导出,也可以顺便把日志也导出。

20230921171333-v1.png

 
需要开通Ptrade或者代写的朋友可以咨询:

 

Ptrade跟踪雪球组合自动调仓

李魔佛 发表了文章 • 0 个评论 • 989 次浏览 • 2023-09-19 20:25 • 来自相关话题

Task: 
根据指定的雪球组合, 自动跟踪组合的调仓与比例.





 
图随便截取的,具体跟踪的组合,客户自己可以直接配置.
 
目前是每10分钟刷新一次 组合数据,如果有更新就马上根据调仓.
 
盘前和收盘前2分钟, 会定期扫码, 以免到了收盘来不及成交,  留够足够的时间下单与撤单.
 

PS:图片与策略无关
 
耗时地方仍然是调试. 
  查看全部
Task: 
根据指定的雪球组合, 自动跟踪组合的调仓与比例.

20230919201907.png

 
图随便截取的,具体跟踪的组合,客户自己可以直接配置.
 
目前是每10分钟刷新一次 组合数据,如果有更新就马上根据调仓.
 
盘前和收盘前2分钟, 会定期扫码, 以免到了收盘来不及成交,  留够足够的时间下单与撤单.
 

PS:图片与策略无关
 
耗时地方仍然是调试. 
 

ptrade量化策略:低位首板启动板-首板+低吸+单阳不破

李魔佛 发表了文章 • 0 个评论 • 1113 次浏览 • 2023-09-05 22:44 • 来自相关话题

低位的首板通常是启动板,首板+低吸+单阳不破,胜率还过得去。毛估估大于55%
 
Ptrade实现实盘自动交易代码。
 
(图片截图非本策略,随意贴的)

 
里面细节比较多。
 
得慢慢调。 查看全部
低位的首板通常是启动板,首板+低吸+单阳不破,胜率还过得去。毛估估大于55%
 
Ptrade实现实盘自动交易代码。
 
(图片截图非本策略,随意贴的)

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

国盛证券Ptrade测试版下载 Ptrade模拟客户端 模拟账号

李魔佛 发表了文章 • 0 个评论 • 1391 次浏览 • 2023-09-01 22:53 • 来自相关话题

国盛证券Ptrade有实盘正式版 和 测试版, 测试版提供的是模拟账户,里面的资金是模拟的,默认有500万,随意你操作,亏完拉倒重新设置就好了。
国盛证券Ptrade测试版下载 Ptrade模拟客户端 模拟账号
仿真客户端








国盛Ptrade测试版 模拟账户下载:
https://download.gszq.com/ptrade/PTrade1.0-Client-V201906-00-000.zip
仿真账户: ***** / ****** 量化回测:支持1分钟、日线回测。 量化交易:支持LEVEL1 tick股票交易。 量化研究:提供云Ipython Notebook研究环境、行情数据2005年至今、可使用全市场金融数据。





虽然ptrade有测试版本,但是个人还是非常不推荐使用测试版本。 以前在上面写过回测或者模拟盘,发现问题非常多,一个是数据缺了,数据错乱。以前被它坑过,后面基本都就不敢用了。 群里的兄弟大部分也被坑过,进群公告就是告诫他们,远离测试版。。。哈
 
实盘版本的需要开通才能申请,不同券商的门槛不一样。需要的朋友可以扫码咨询:
 

  查看全部
国盛证券Ptrade有实盘正式版 和 测试版, 测试版提供的是模拟账户,里面的资金是模拟的,默认有500万,随意你操作,亏完拉倒重新设置就好了。
国盛证券Ptrade测试版下载 Ptrade模拟客户端 模拟账号
仿真客户端
20230901004.jpg

20231022124203-v1.png

国盛Ptrade测试版 模拟账户下载:
https://download.gszq.com/ptrade/PTrade1.0-Client-V201906-00-000.zip
 
仿真账户: ***** / ****** 量化回测:支持1分钟、日线回测。 量化交易:支持LEVEL1 tick股票交易。 量化研究:提供云Ipython Notebook研究环境、行情数据2005年至今、可使用全市场金融数据。

20230901006.jpg


虽然ptrade有测试版本,但是个人还是非常不推荐使用测试版本。 以前在上面写过回测或者模拟盘,发现问题非常多,一个是数据缺了,数据错乱。以前被它坑过,后面基本都就不敢用了。 群里的兄弟大部分也被坑过,进群公告就是告诫他们,远离测试版。。。哈
 
实盘版本的需要开通才能申请,不同券商的门槛不一样。需要的朋友可以扫码咨询:
 

 

20行代码实现Ptrade一键清仓

李魔佛 发表了文章 • 0 个评论 • 955 次浏览 • 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重启策略后日志被清空,正常的操作方式

李魔佛 发表了文章 • 0 个评论 • 896 次浏览 • 2023-07-25 04:36 • 来自相关话题

坑爹的设计。 一个不留神,改了个参数,然后就点了一下重启策略。。。。





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





 
更多ptrade、qmt,掘金的量化交易技巧,请查看星球。

  查看全部
坑爹的设计。 一个不留神,改了个参数,然后就点了一下重启策略。。。。

20230725001.jpg

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

20230725002.jpg

 
更多ptrade、qmt,掘金的量化交易技巧,请查看星球。

 

ptrade批量获取股票的昨天的收盘价,转为字典json【一】

李魔佛 发表了文章 • 0 个评论 • 1082 次浏览 • 2023-07-17 19:50 • 来自相关话题

有些指标的计算,需要拿个股的昨日收盘价。而ptrade提供了多个API函数可以获取股票的昨天的收盘价。
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提供了多个API函数可以获取股票的昨天的收盘价。
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

20230717004.jpg

 
 
输出:
zz_df_price.iloc[0].to_json()

20230717003.jpg

 
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的不同

李魔佛 发表了文章 • 0 个评论 • 988 次浏览 • 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
 

20230710002.jpg

 
注意:大部分函数自适用于交易模块,回测模式不支持部分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资金更新速度|高频中如何处理

李魔佛 发表了文章 • 0 个评论 • 1145 次浏览 • 2023-07-06 17:35 • 来自相关话题

QMT vs PTrade资金更新速度|高频中如何处理

平时在手动交易中,下单委托后,再切换回去持仓页面,可以看到你的可用资金变少了。而在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 vs PTrade资金更新速度|高频中如何处理

平时在手动交易中,下单委托后,再切换回去持仓页面,可以看到你的可用资金变少了。而在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的实盘里执行,得到下面日志


20230706001.jpg



下单前可用资金为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实盘后,执行。

得到下面的运行日志:


20230705001.jpg



从上面的日志看出,程序在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


20230706002.jpg



里面就说明了,“该函数会在成交主推回调时响应,比引擎和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或类对象来更新仓位。


20230706003.jpg



上面代码是把仓位更新放到一个全局dict里面,key是股票代码,value也是一个dict,里面包含交易时间,持仓数目,价格等等。

好了,时间有限,今天的教程就到这里了,码字不易,欢迎点赞+收藏哦~
 

国盛Ptrade又可以重新开了,需要的小伙伴抓紧开啦

李魔佛 发表了文章 • 0 个评论 • 1287 次浏览 • 2023-06-14 11:34 • 来自相关话题

作为目前为止,唯一一个可以和外部通讯的Ptrade券商,之前因为账户号码耗尽的原因,暂停了开通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开通
 
 
  查看全部
作为目前为止,唯一一个可以和外部通讯的Ptrade券商,之前因为账户号码耗尽的原因,暂停了开通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开通
 
 
 

用户问的比较多的关于ptrade基础问题

李魔佛 发表了文章 • 0 个评论 • 1624 次浏览 • 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上的数据?

李魔佛 发表了文章 • 0 个评论 • 1368 次浏览 • 2023-04-29 02:40 • 来自相关话题

很多菜鸟会觉得不能下载或者上传数据到Ptrade的。

部分券商的Ptrade可以连通外网,只需要部署一个mysql服务器,或者rabbitMQ,就可以快捷的接受数据了。为啥是这两个,而不是mongodb?

因为ptrade内置的pip装好的库就有pymysql和pyzmq,可以配置下就可以直接开箱使用。如果需要开通有外网功能的Ptrade券商,可以关注公众号:可转债量化分析,后台留言:ptrade外网,即可咨询开通。


1. 首先,我们把数据保存到ptrade的服务端,保存方法多样,比如csv,excel,sql文件等,比如df.to_csv, df.to_excel等等。这里要注意一下,保存的路径。需要指定,/home/fly/notebookimport pickle
from collections import defaultdict
NOTEBOOK_PATH = '/home/fly/notebook/'
'''
持仓N日后卖出,仓龄变量每日pickle进行保存,重启策略后可以保证逻辑连贯
'''
def initialize(context):
#尝试启动pickle文件
try:
with open(NOTEBOOK_PATH+'hold_days.pkl','rb') as f:
g.hold_days = pickle.load(f)

2. 文件保存了之后,接着就可以下载了。

   数据在研究的页面那里。







然后点击某个文件,

如果是非纯文本文件,比如excel文件,会显示:Error! not UTF-8 encoded

Saving disable

See console for more details
不用理会,直接点击左上角的文件,下载,选择本地的路径,然后文件就可以下载下来了。 查看全部
很多菜鸟会觉得不能下载或者上传数据到Ptrade的。

部分券商的Ptrade可以连通外网,只需要部署一个mysql服务器,或者rabbitMQ,就可以快捷的接受数据了。为啥是这两个,而不是mongodb?

因为ptrade内置的pip装好的库就有pymysql和pyzmq,可以配置下就可以直接开箱使用。如果需要开通有外网功能的Ptrade券商,可以关注公众号:可转债量化分析,后台留言:ptrade外网,即可咨询开通。


1. 首先,我们把数据保存到ptrade的服务端,保存方法多样,比如csv,excel,sql文件等,比如df.to_csv, df.to_excel等等。这里要注意一下,保存的路径。需要指定,/home/fly/notebook
import pickle
from collections import defaultdict
NOTEBOOK_PATH = '/home/fly/notebook/'
'''
持仓N日后卖出,仓龄变量每日pickle进行保存,重启策略后可以保证逻辑连贯
'''
def initialize(context):
#尝试启动pickle文件
try:
with open(NOTEBOOK_PATH+'hold_days.pkl','rb') as f:
g.hold_days = pickle.load(f)


2. 文件保存了之后,接着就可以下载了。

   数据在研究的页面那里。


20230429001.jpg


然后点击某个文件,

如果是非纯文本文件,比如excel文件,会显示:
Error! not UTF-8 encoded

Saving disable

See console for more details

不用理会,直接点击左上角的文件,下载,选择本地的路径,然后文件就可以下载下来了。

20230429002.jpg

【100行python代码实现可转债日内网格-成交驱动】 自定义买卖步长

李魔佛 发表了文章 • 0 个评论 • 1537 次浏览 • 2023-04-19 13:27 • 来自相关话题

基于ptrade的可转债日内网格实盘,基于成交驱动,成交后马上挂入下一轮的网格委托。
 
 ## 2023-04-19 更新: 部分成交的需要等待全部成交才触发下一轮挂单

简单的可转债日内网格策略,自定义买卖步长,基准价格,买入与卖出数量,保留底仓张数

开始同时挂买入和卖出委托,如果买入成交后,撤掉委卖(如果是卖出先成交,则撤掉委买),继续挂入下一个步长的委买与委卖,不断循环。


把注释和空格去了100行不到。

代码仅供参考学习具体用法:

用于实盘亏损盈亏自负

后续如果有需要再贴个升级版:多标的网格

或者,额,qmt版本。。。

部分代码截图:




 
 
实盘交易日志:点击查看大图





 






完整代码请参见知识星球.
知识无价,请尊重知识。
  查看全部
基于ptrade的可转债日内网格实盘,基于成交驱动,成交后马上挂入下一轮的网格委托。
 
 ## 2023-04-19 更新: 部分成交的需要等待全部成交才触发下一轮挂单

简单的可转债日内网格策略,自定义买卖步长,基准价格,买入与卖出数量,保留底仓张数

开始同时挂买入和卖出委托,如果买入成交后,撤掉委卖(如果是卖出先成交,则撤掉委买),继续挂入下一个步长的委买与委卖,不断循环。


把注释和空格去了100行不到。

代码仅供参考学习具体用法:

用于实盘亏损盈亏自负

后续如果有需要再贴个升级版:多标的网格

或者,额,qmt版本。。。

部分代码截图:
20230419001.jpg

 
 
实盘交易日志:点击查看大图

20230419003.jpg

 

20230419004.jpg


完整代码请参见知识星球.
知识无价,请尊重知识。
 

ptrade担保品买卖,融资买入,融券卖出,卖券还款,买券还券 下单后回调函数里面的结构

李魔佛 发表了文章 • 0 个评论 • 1079 次浏览 • 2023-03-31 21:44 • 来自相关话题

【ptrade的稳定性,获取行情速度,实盘交易,回测速度无意不秒杀QMT的。
而对于不能安装第三方库的原因,不少菜鸟转而选择了QMT。有点可惜了ptrade。ptrade其实也可以联通外部数据。
ptrade软件设计层面和体验是企业级的,而QMT就呵呵哒,0售后技术支持,软件bug层出不穷。里面的某个别的工程师(袁姓)素质也是底下,我星球上的代码他也抄过去,抄过去后呢 放到他自己付费星球,而且还不止一篇。】
而ptrade相对而言,恒生电子的工程师服务就很到位,发送日志给他们,会在一天内分析结果告知你哪些出现问题了。
 
题外话说多了。
 
ptrade支持两融账户的量化操作。
如:担保品买卖,融资买入,融券卖出,卖券还款,买券还券margin_trade - 担保品买卖

margincash_open - 融资买入

margincash_close - 卖券还款

margincash_direct_refund - 直接还款

marginsec_open - 融券卖出

marginsec_close - 买券还券




它们之间的参数都比较相近:

margin_xxxx(security, amount, limit_price=None)

security:股票代码(str);

amount:交易数量,输入正数(int);

limit_price:买卖限价(float);
 
而用它们进行买卖操作后,在on_trade_response回调函数里面的机构提如下:
 
担保品买入:2023-03-31 14:41:02 - INFO - 生成订单,订单号:cd25d27f39854721aac99db13c9e9b73股票代码:601328.SS 数量:信用买入1000
2023-03-31 14:41:02 - INFO - {'error_info': '', 'stock_code': '601328.SS', 'order_id': 'cd25d27f39854721aac99db13c9e9b73', 'status': '2', 'price': 5.1, 'entrust_type': '9', 'amount': 1000, 'business_amount': 0.0, 'entrust_prop': '0', 'entrust_no': '1', 'order_time': '2023-03-31 14:35:53.776'}
2023-03-31 14:41:02 - INFO - {'business_amount': 1000, 'order_id': 'cd25d27f39854721aac99db13c9e9b73', 'stock_code': '601328.SS', 'entrust_bs': '1', 'entrust_no': '1', 'status': '8', 'business_balance': 5100.0, 'business_price': 5.1, 'business_id': '2', 'business_time': '2023-03-31 14:39:17'} 
 
 
  
 融资买入:2023-03-31 14:52:00 - INFO - 生成订单,订单号:01b7851d37014709bde3ec6ebe9e89c3股票代码:601328.SS 数量:融资买入100
2023-03-31 14:52:00 - INFO - {'price': 5.1, 'entrust_prop': '0', 'status': '2', 'entrust_type': '6', 'stock_code': '601328.SS', 'business_amount': 0.0, 'entrust_no': '3', 'order_time': '2023-03-31 14:46:51.620', 'error_info': '', 'amount': 100, 'order_id': '01b7851d37014709bde3ec6ebe9e89c3'}
2023-03-31 14:52:00 - INFO - {'business_id': '4', 'business_balance': 509.99999999999994, 'business_price': 5.1, 'order_id': '01b7851d37014709bde3ec6ebe9e89c3', 'business_time': '2023-03-31 14:50:14', 'status': '8', 'entrust_bs': '1', 'business_amount': 100, 'entrust_no': '3', 'stock_code': '601328.SS'} 
 
卖券还款2023-03-31 14:58:20 - INFO - start
2023-03-31 14:59:00 - INFO - 生成订单,订单号:20cef28ec52c4d41b09c80fc49167497股票代码:600269.SS 数量:卖券还款-200
2023-03-31 14:59:00 - INFO - {'business_amount': 0.0, 'amount': -200, 'stock_code': '600269.SS', 'error_info': '', 'order_time': '2023-03-31 14:53:51.375', 'price': 3.38, 'entrust_type': '6', 'status': '2', 'order_id': '20cef28ec52c4d41b09c80fc49167497', 'entrust_prop': '0', 'entrust_no': '5'}
2023-03-31 14:59:00 - INFO - {'status': '8', 'business_time': '2023-03-31 14:57:14', 'stock_code': '600269.SS', 'entrust_bs': '2', 'business_id': '6', 'business_balance': -676.0, 'business_amount': -200, 'order_id': '20cef28ec52c4d41b09c80fc49167497', 'business_price': 3.38, 'entrust_no': '5'}
返回的结构体和那个普通账户交易的回调函数基本一致的。
 
  查看全部

【ptrade的稳定性,获取行情速度,实盘交易,回测速度无意不秒杀QMT的。
而对于不能安装第三方库的原因,不少菜鸟转而选择了QMT。有点可惜了ptrade。ptrade其实也可以联通外部数据。
ptrade软件设计层面和体验是企业级的,而QMT就呵呵哒,0售后技术支持,软件bug层出不穷。里面的某个别的工程师(袁姓)素质也是底下,我星球上的代码他也抄过去,抄过去后呢 放到他自己付费星球,而且还不止一篇。】
而ptrade相对而言,恒生电子的工程师服务就很到位,发送日志给他们,会在一天内分析结果告知你哪些出现问题了。
 
题外话说多了。
 
ptrade支持两融账户的量化操作。
如:担保品买卖,融资买入,融券卖出,卖券还款,买券还券
margin_trade - 担保品买卖

margincash_open - 融资买入

margincash_close - 卖券还款

margincash_direct_refund - 直接还款

marginsec_open - 融券卖出

marginsec_close - 买券还券




它们之间的参数都比较相近:

margin_xxxx(security, amount, limit_price=None)

security:股票代码(str);

amount:交易数量,输入正数(int);

limit_price:买卖限价(float);
 
而用它们进行买卖操作后,在on_trade_response回调函数里面的机构提如下:
 
担保品买入:
2023-03-31 14:41:02 - INFO - 生成订单,订单号:cd25d27f39854721aac99db13c9e9b73股票代码:601328.SS 数量:信用买入1000
2023-03-31 14:41:02 - INFO - {'error_info': '', 'stock_code': '601328.SS', 'order_id': 'cd25d27f39854721aac99db13c9e9b73', 'status': '2', 'price': 5.1, 'entrust_type': '9', 'amount': 1000, 'business_amount': 0.0, 'entrust_prop': '0', 'entrust_no': '1', 'order_time': '2023-03-31 14:35:53.776'}
2023-03-31 14:41:02 - INFO - {'business_amount': 1000, 'order_id': 'cd25d27f39854721aac99db13c9e9b73', 'stock_code': '601328.SS', 'entrust_bs': '1', 'entrust_no': '1', 'status': '8', 'business_balance': 5100.0, 'business_price': 5.1, 'business_id': '2', 'business_time': '2023-03-31 14:39:17'}
 
 
 
  
 融资买入:
2023-03-31 14:52:00 - INFO - 生成订单,订单号:01b7851d37014709bde3ec6ebe9e89c3股票代码:601328.SS 数量:融资买入100
2023-03-31 14:52:00 - INFO - {'price': 5.1, 'entrust_prop': '0', 'status': '2', 'entrust_type': '6', 'stock_code': '601328.SS', 'business_amount': 0.0, 'entrust_no': '3', 'order_time': '2023-03-31 14:46:51.620', 'error_info': '', 'amount': 100, 'order_id': '01b7851d37014709bde3ec6ebe9e89c3'}
2023-03-31 14:52:00 - INFO - {'business_id': '4', 'business_balance': 509.99999999999994, 'business_price': 5.1, 'order_id': '01b7851d37014709bde3ec6ebe9e89c3', 'business_time': '2023-03-31 14:50:14', 'status': '8', 'entrust_bs': '1', 'business_amount': 100, 'entrust_no': '3', 'stock_code': '601328.SS'}
 
 
卖券还款
2023-03-31 14:58:20 - INFO - start
2023-03-31 14:59:00 - INFO - 生成订单,订单号:20cef28ec52c4d41b09c80fc49167497股票代码:600269.SS 数量:卖券还款-200
2023-03-31 14:59:00 - INFO - {'business_amount': 0.0, 'amount': -200, 'stock_code': '600269.SS', 'error_info': '', 'order_time': '2023-03-31 14:53:51.375', 'price': 3.38, 'entrust_type': '6', 'status': '2', 'order_id': '20cef28ec52c4d41b09c80fc49167497', 'entrust_prop': '0', 'entrust_no': '5'}
2023-03-31 14:59:00 - INFO - {'status': '8', 'business_time': '2023-03-31 14:57:14', 'stock_code': '600269.SS', 'entrust_bs': '2', 'business_id': '6', 'business_balance': -676.0, 'business_amount': -200, 'order_id': '20cef28ec52c4d41b09c80fc49167497', 'business_price': 3.38, 'entrust_no': '5'}

返回的结构体和那个普通账户交易的回调函数基本一致的。
 
 

Ptrade融资融券双均线 代码 讲解

李魔佛 发表了文章 • 0 个评论 • 1303 次浏览 • 2023-03-31 02:08 • 来自相关话题

因为一些融资融券的函数只能在交易模块使用,所以如果需要模拟的话,可以使用模拟端进行交易。
 
def initialize(context):
# 初始化策略
# 设置我们要操作的股票池, 这里我们只操作一支股票
g.security = "600300.SS"
set_universe(g.security)

def before_trading_start(context, data):
# 买入标识
g.order_buy_flag = False
# 卖出标识
g.order_sell_flag = False

#当五日均线高于十日均线时买入,当五日均线低于十日均线时卖出
def handle_data(context, data):
# 得到十日历史价格
df = get_history(10, "1d", "close", g.security, fq=None, include=False)
# 得到五日均线价格
ma5 = round(df["close"][-5:].mean(), 3)
# 得到十日均线价格
ma10 = round(df["close"][-10:].mean(), 3)
# 取得昨天收盘价
price = data[g.security]["close"]
# 如果五日均线大于十日均线
if ma5 > ma10:
if not g.order_buy_flag:
# 获取最大可融资数量
amount = get_margincash_open_amount(g.security).get(g.security)
# 进行融资买入操作
margincash_open(g.security, amount)
# 记录这次操作
log.info("Buying %s Amount %s" % (g.security, amount))
# 当日已融资买入
g.order_buy_flag = True

# 如果五日均线小于十日均线,并且目前有头寸
elif ma5 < ma10 and get_position(g.security).amount > 0:
if not g.order_sell_flag:
# 获取标的卖券还款最大可卖数量
amount = get_margincash_close_amount(g.security).get(g.security)
# 进行卖券还款操作
margincash_close(g.security, -amount)
# 记录这次操作
log.info("Selling %s Amount %s" % (g.security, amount))
# 当日已卖券还款
g.order_sell_flag = True  查看全部
因为一些融资融券的函数只能在交易模块使用,所以如果需要模拟的话,可以使用模拟端进行交易。
 
def initialize(context):
# 初始化策略
# 设置我们要操作的股票池, 这里我们只操作一支股票
g.security = "600300.SS"
set_universe(g.security)

def before_trading_start(context, data):
# 买入标识
g.order_buy_flag = False
# 卖出标识
g.order_sell_flag = False

#当五日均线高于十日均线时买入,当五日均线低于十日均线时卖出
def handle_data(context, data):
# 得到十日历史价格
df = get_history(10, "1d", "close", g.security, fq=None, include=False)
# 得到五日均线价格
ma5 = round(df["close"][-5:].mean(), 3)
# 得到十日均线价格
ma10 = round(df["close"][-10:].mean(), 3)
# 取得昨天收盘价
price = data[g.security]["close"]
# 如果五日均线大于十日均线
if ma5 > ma10:
if not g.order_buy_flag:
# 获取最大可融资数量
amount = get_margincash_open_amount(g.security).get(g.security)
# 进行融资买入操作
margincash_open(g.security, amount)
# 记录这次操作
log.info("Buying %s Amount %s" % (g.security, amount))
# 当日已融资买入
g.order_buy_flag = True

# 如果五日均线小于十日均线,并且目前有头寸
elif ma5 < ma10 and get_position(g.security).amount > 0:
if not g.order_sell_flag:
# 获取标的卖券还款最大可卖数量
amount = get_margincash_close_amount(g.security).get(g.security)
# 进行卖券还款操作
margincash_close(g.security, -amount)
# 记录这次操作
log.info("Selling %s Amount %s" % (g.security, amount))
# 当日已卖券还款
g.order_sell_flag = True
 

Ptrade担保品买入卖出

李魔佛 发表了文章 • 0 个评论 • 1068 次浏览 • 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:全额成交或撤单;

ptrade QMT 动态止盈卖出 python代码实现

李魔佛 发表了文章 • 0 个评论 • 1146 次浏览 • 2023-03-13 23:53 • 来自相关话题

帮你轻松实现自动止盈。
比如设置20%,那么会每天盘中扫描,可以精确到3S 一格,如果你的持仓股的收益率大于20%,它将会帮你自动卖出。
 
占坑 待续 》》》
帮你轻松实现自动止盈。
比如设置20%,那么会每天盘中扫描,可以精确到3S 一格,如果你的持仓股的收益率大于20%,它将会帮你自动卖出。
 
占坑 待续 》》》

ptrade qmt的模拟账户能不用尽量不用,无尽的bug让你浪费时间 怀疑人生

李魔佛 发表了文章 • 0 个评论 • 1928 次浏览 • 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是[],没有任何数据。

20230302012.jpg

上面的xxxxx is expired , close all positions by system. 是因为模拟账户上退市转债还依然挂在上面,清仓也清不掉。每次跑就循环一分钟输出。。
 
换了个券商的模拟账户,问题依然在,只好倒腾实盘账户。然后问题就解决了。
这个问题,在qmt上就更加严重了。 下次在星球上或者群里慢慢吐槽吧
 
 

Ptrade基本期货策略

李魔佛 发表了文章 • 0 个评论 • 1227 次浏览 • 2023-02-04 14:17 • 来自相关话题

ptrade本身支持期货交易,开通账户绑定就可以了。
新建策略的时候选择:期货即可。





 
 
 1. 买入开仓
 
不同期货品种每一跳的价格变动都不一样,limit_price入参的时候要参考对应品种的价格变动规则,如limit_price不做入参则会以交易的行情快照最新价或者回测的分钟最新价进行报单;

根据交易所规则,每天结束时会取消所有未完成交易;
 
 
def initialize(context):
g.security = ['IF1712.CCFX', 'CU1806.XSGE']
set_universe(g.security)

def handle_data(context, data):
#买入开仓
buy_open('IF1712.CCFX', 1)

#买入开仓(限定点数为52220)
buy_open('CU1806.XSGE', 1, limit_price=52220)
2. 卖出平仓
def initialize(context):
g.security = ['IF1712.CCFX', 'CU1806.XSGE']
set_universe(g.security)

def handle_data(context, data):
#卖出平仓
sell_close('IF1712.CCFX', 1)
#卖出平今仓(限定点数为52220)
sell_close ('CU1806.XSGE', 1, limit_price=52220, close_today=True)
#卖出平仓(限定点数为52220)
sell_close ('CU1806.XSGE', 1, limit_price=52220)
3. 获取合约信息
get_instruments- 获取合约信息
 
get_instruments(contract)


返回

FutureParams对象,主要返回的字段为:

contract_code -- 合约代码,str类型;
contract_name -- 合约名称,str类型;
exchange -- 交易所:大商所、郑商所、上期所、中金所,str类型;
trade_unit -- 交易单位,int类型;
contract_multiplier -- 合约乘数,float类型;
delivery_date -- 交割日期,str类型;
listing_date -- 上市日期,str类型;
trade_code -- 交易代码,str类型;
margin_rate -- 保证金比例,float类型;

 
代码示例:
def initialize(context):
g.security = ["CU2112.XSGE", "IF2112.CCFX"]
set_universe(g.security)

def before_trading_start(context, data):
# 获取股票池代码合约信息
for security in g.security:
info = get_instruments(security)
log.info(info)

def handle_data(context, data):
pass 查看全部
ptrade本身支持期货交易,开通账户绑定就可以了。
新建策略的时候选择:期货即可。

20230204005.jpg

 
 
 1. 买入开仓
 
不同期货品种每一跳的价格变动都不一样,limit_price入参的时候要参考对应品种的价格变动规则,如limit_price不做入参则会以交易的行情快照最新价或者回测的分钟最新价进行报单;

根据交易所规则,每天结束时会取消所有未完成交易;
 
 
def initialize(context):
g.security = ['IF1712.CCFX', 'CU1806.XSGE']
set_universe(g.security)

def handle_data(context, data):
#买入开仓
buy_open('IF1712.CCFX', 1)

#买入开仓(限定点数为52220)
buy_open('CU1806.XSGE', 1, limit_price=52220)

2. 卖出平仓
def initialize(context):
g.security = ['IF1712.CCFX', 'CU1806.XSGE']
set_universe(g.security)

def handle_data(context, data):
#卖出平仓
sell_close('IF1712.CCFX', 1)
#卖出平今仓(限定点数为52220)
sell_close ('CU1806.XSGE', 1, limit_price=52220, close_today=True)
#卖出平仓(限定点数为52220)
sell_close ('CU1806.XSGE', 1, limit_price=52220)

3. 获取合约信息
get_instruments- 获取合约信息
 
get_instruments(contract)


返回

FutureParams对象,主要返回的字段为:

contract_code -- 合约代码,str类型;
contract_name -- 合约名称,str类型;
exchange -- 交易所:大商所、郑商所、上期所、中金所,str类型;
trade_unit -- 交易单位,int类型;
contract_multiplier -- 合约乘数,float类型;
delivery_date -- 交割日期,str类型;
listing_date -- 上市日期,str类型;
trade_code -- 交易代码,str类型;
margin_rate -- 保证金比例,float类型;


 
代码示例:
def initialize(context):
g.security = ["CU2112.XSGE", "IF2112.CCFX"]
set_universe(g.security)

def before_trading_start(context, data):
# 获取股票池代码合约信息
for security in g.security:
info = get_instruments(security)
log.info(info)

def handle_data(context, data):
pass

ptrade获取分时成交数据-LEVEL2数据逐笔数据

李魔佛 发表了文章 • 0 个评论 • 2030 次浏览 • 2023-02-04 12:27 • 来自相关话题

在接口文档 http://ptradeapi.com/#get_tick_direction
中提供了获取分时成交的数据。
 
使用场景
该函数在交易模块可用

接口说明
该接口用于获取当日分时成交行情数据。

注意事项:

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量化交易接口的券商吗?
 

 
  查看全部
在接口文档 http://ptradeapi.com/#get_tick_direction
中提供了获取分时成交的数据。
 
使用场景
该函数在交易模块可用

接口说明
该接口用于获取当日分时成交行情数据。

注意事项:

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量化交易接口的券商吗?
 

 
 

ptrade移除当前ST股

李魔佛 发表了文章 • 0 个评论 • 952 次浏览 • 2023-02-04 12:14 • 来自相关话题

 
下面代码移除创业板,科创板还有当前被ST的股票。也可以任意组合,移除。
可以参考上一篇:http://30daydo.com/article/44569
 
def remove_st_stock(all_stock_list):
st_dict = get_stock_status(all_stock_list, query_type='ST', query_date=None)
st_list = []
for k, v in st_dict.items():
if v:
st_list.append(k)
return st_list

MARKET_DICT = {0: '科创板', 1: '创业板', }
IGNORE_MARKET = [0, 1]

def all_codes_in_market():
all_stock_set = set(get_Ashares(date=None))
for ignore_code in IGNORE_MARKET:
market = MARKET_DICT.get(ignore_code)
if market == '科创板':
all_stock_set = all_stock_set - set(filter(lambda x: x.startswith('68'), all_stock_set))
if market == '创业板':
all_stock_set = all_stock_set - set(filter(lambda x: x.startswith('3'), all_stock_set))

return all_stock_set


def create_target(context):
all_stock_set = all_codes_in_market()
st_list = remove_st_stock(list(all_stock_set))
all_stock_set = all_stock_set - set(st_list)
return all_stock_set
调用方式:

stock_target = create_target(None)
 
这样返回的股票就被排除了科创板,创业板,ST股票。
 

 
  查看全部
 
下面代码移除创业板,科创板还有当前被ST的股票。也可以任意组合,移除。
可以参考上一篇:http://30daydo.com/article/44569
 
def remove_st_stock(all_stock_list):
st_dict = get_stock_status(all_stock_list, query_type='ST', query_date=None)
st_list = []
for k, v in st_dict.items():
if v:
st_list.append(k)
return st_list

MARKET_DICT = {0: '科创板', 1: '创业板', }
IGNORE_MARKET = [0, 1]

def all_codes_in_market():
all_stock_set = set(get_Ashares(date=None))
for ignore_code in IGNORE_MARKET:
market = MARKET_DICT.get(ignore_code)
if market == '科创板':
all_stock_set = all_stock_set - set(filter(lambda x: x.startswith('68'), all_stock_set))
if market == '创业板':
all_stock_set = all_stock_set - set(filter(lambda x: x.startswith('3'), all_stock_set))

return all_stock_set


def create_target(context):
all_stock_set = all_codes_in_market()
st_list = remove_st_stock(list(all_stock_set))
all_stock_set = all_stock_set - set(st_list)
return all_stock_set

调用方式:

stock_target = create_target(None)
 
这样返回的股票就被排除了科创板,创业板,ST股票。
 

 
 

ptrade排除A股创业板,科创板的股票

李魔佛 发表了文章 • 0 个评论 • 1127 次浏览 • 2023-02-04 10:48 • 来自相关话题

由于创业板和科创板的股票波动会比沪深主板的要大,所以如果想要按照某些策略,排除这两个板块的股票,可以使用下面的方法:
 
MARKET_DICT = {0: '科创板', 1: '创业板', }
IGNORE_MARKET = [0, 1]

def create_target(context):

all_stock_set = set(get_Ashares(date=None))
for ignore_code in IGNORE_MARKET:
market = MARKET_DICT.get(ignore_code)
if market == '科创板':
all_stock_set = all_stock_set - set(filter(lambda x:x.startswith('68'),all_stock_set))
if market == '创业板':
all_stock_set = all_stock_set - set(filter(lambda x:x.startswith('3'),all_stock_set))

return all_stock_set
返回的all_stock_set就是排除了创业板,科创板的股票列表。
 
ptrade接口文档:http://ptradeapi.com
  查看全部
由于创业板和科创板的股票波动会比沪深主板的要大,所以如果想要按照某些策略,排除这两个板块的股票,可以使用下面的方法:
 
MARKET_DICT = {0: '科创板', 1: '创业板', }
IGNORE_MARKET = [0, 1]

def create_target(context):

all_stock_set = set(get_Ashares(date=None))
for ignore_code in IGNORE_MARKET:
market = MARKET_DICT.get(ignore_code)
if market == '科创板':
all_stock_set = all_stock_set - set(filter(lambda x:x.startswith('68'),all_stock_set))
if market == '创业板':
all_stock_set = all_stock_set - set(filter(lambda x:x.startswith('3'),all_stock_set))

return all_stock_set

返回的all_stock_set就是排除了创业板,科创板的股票列表。
 
ptrade接口文档:http://ptradeapi.com
 

ptrade如何获取某天的全市场股票代码?

李魔佛 发表了文章 • 0 个评论 • 1374 次浏览 • 2023-02-04 03:19 • 来自相关话题

ptrade如何获取全市场股票代码?
 
在ptrade的接口文档http://ptradeapi.com 里面可以查到,
 
get_Ashares – 获取指定日期A股代码列表
 
get_Ashares(date=None)

 
如果不指定日期,则获取单天的A股所有股票的股票代码。
 
如果在回测的时候,获取的是回测单天额所有股票代码; 如果指定日期,则获取的是指定日期的所有A股股票代码。

get_Ashares – 获取指定日期A股代码列表get_Ashares(date=None)使用场景

该函数在研究、回测、交易模块可用

接口说明

该接口用于获取指定日期沪深市场的所有A股代码列表

注意事项:

1、在回测中,date不入参默认取回测日期,默认值会随着回测日期变化而变化,等于context.current_dt

2、在研究中,date不入参默认取当天日期

3、在交易中,date不入参默认取当天日期

参数

date:格式为YYYYmmdd

返回

股票代码列表,list类型(list[str,...])

 
让我们来测试一下:





 
拿到的股票个数是4912个。
 
然后我对着通达信的所有A股数据比较了一下,get_Ashares 获取的数据不包括北交所,新三板创新创业的股票,也就是不包括4和8开头的股票数据,但包含沪深主板,创业板,科创板的股票数据。
 

  查看全部
ptrade如何获取全市场股票代码?
 
在ptrade的接口文档http://ptradeapi.com 里面可以查到,
 
get_Ashares – 获取指定日期A股代码列表
 
get_Ashares(date=None)

 
如果不指定日期,则获取单天的A股所有股票的股票代码。
 
如果在回测的时候,获取的是回测单天额所有股票代码; 如果指定日期,则获取的是指定日期的所有A股股票代码。


get_Ashares – 获取指定日期A股代码列表get_Ashares(date=None)使用场景

该函数在研究、回测、交易模块可用

接口说明

该接口用于获取指定日期沪深市场的所有A股代码列表

注意事项:

1、在回测中,date不入参默认取回测日期,默认值会随着回测日期变化而变化,等于context.current_dt

2、在研究中,date不入参默认取当天日期

3、在交易中,date不入参默认取当天日期

参数

date:格式为YYYYmmdd

返回

股票代码列表,list类型(list[str,...])


 
让我们来测试一下:

20230204002.jpg

 
拿到的股票个数是4912个。
 
然后我对着通达信的所有A股数据比较了一下,get_Ashares 获取的数据不包括北交所,新三板创新创业的股票,也就是不包括4和8开头的股票数据,但包含沪深主板,创业板,科创板的股票数据。