通知设置 新通知
Ptrade回测模式下获取实时的分钟数据:只能使用handle_data,数据不能用get_snapshot
李魔佛 发表了文章 • 0 个评论 • 220 次浏览 • 2024-09-21 17:32
发现有点蛋疼,记录一下。
因为回测模式下,不能使用run_interval 函数;
而run_daily模式,只能在固定时间运行,无法分钟级别。
所以只能使用 handle_data
而在handle_data 里面获取当前的分钟价格数据,也无法使用 get_snapshot ,get_gear_price,函数。
所以只能使用handle_data(Context,data) 里面的data里。
而handle_data 里面的data数据,使用方法如下:
import datetime
target_list = [
'600000.SS',
'000333.SZ'
]
def execution(context, data):
now = context.current_dt.strftime('%H:%M')
for code in target_list:
tick_info = data[code]
price = tick_info['price']
print('now: {} code : {} price:{}'.format(now,code ,price))
# 标准
def initialize(context):
log.info("公众号:可转债量化分析 ---- start ----")
def handle_data(context, data):
execution(context, data)
获取数据结果:2024-09-20 14:42:00 - INFO - now: 14:42 code : 000333.SZ price:66.22
2024-09-20 14:43:00 - INFO - now: 14:43 code : 000333.SZ price:66.26
2024-09-20 14:44:00 - INFO - now: 14:44 code : 000333.SZ price:66.19
2024-09-20 14:45:00 - INFO - now: 14:45 code : 000333.SZ price:66.2
2024-09-20 14:46:00 - INFO - now: 14:46 code : 000333.SZ price:66.19
2024-09-20 14:47:00 - INFO - now: 14:47 code : 000333.SZ price:66.18
2024-09-20 14:48:00 - INFO - now: 14:48 code : 000333.SZ price:66.14
2024-09-20 14:49:00 - INFO - now: 14:49 code : 000333.SZ price:66.25
2024-09-20 14:50:00 - INFO - now: 14:50 code : 000333.SZ price:66.19
2024-09-20 14:51:00 - INFO - now: 14:51 code : 000333.SZ price:66.18
2024-09-20 14:52:00 - INFO - now: 14:52 code : 000333.SZ price:66.19
2024-09-20 14:53:00 - INFO - now: 14:53 code : 000333.SZ price:66.2
2024-09-20 14:54:00 - INFO - now: 14:54 code : 000333.SZ price:66.19
2024-09-20 14:55:00 - INFO - now: 14:55 code : 000333.SZ price:66.25
2024-09-20 14:56:00 - INFO - now: 14:56 code : 000333.SZ price:66.27
2024-09-20 14:57:00 - INFO - now: 14:57 code : 000333.SZ price:66.28
2024-09-20 14:58:00 - INFO - now: 14:58 code : 000333.SZ price:66.28
2024-09-20 14:59:00 - INFO - now: 14:59 code : 000333.SZ price:66.28
2024-09-20 15:00:00 - INFO - now: 15:00 code : 000333.SZ price:66.06
用同花顺,对了一下结果,是满足的了。
查看全部
发现有点蛋疼,记录一下。
因为回测模式下,不能使用run_interval 函数;
而run_daily模式,只能在固定时间运行,无法分钟级别。
所以只能使用 handle_data
而在handle_data 里面获取当前的分钟价格数据,也无法使用 get_snapshot ,get_gear_price,函数。
所以只能使用handle_data(Context,data) 里面的data里。
而handle_data 里面的data数据,使用方法如下:
import datetime
target_list = [
'600000.SS',
'000333.SZ'
]
def execution(context, data):
now = context.current_dt.strftime('%H:%M')
for code in target_list:
tick_info = data[code]
price = tick_info['price']
print('now: {} code : {} price:{}'.format(now,code ,price))
# 标准
def initialize(context):
log.info("公众号:可转债量化分析 ---- start ----")
def handle_data(context, data):
execution(context, data)
获取数据结果:
2024-09-20 14:42:00 - INFO - now: 14:42 code : 000333.SZ price:66.22
2024-09-20 14:43:00 - INFO - now: 14:43 code : 000333.SZ price:66.26
2024-09-20 14:44:00 - INFO - now: 14:44 code : 000333.SZ price:66.19
2024-09-20 14:45:00 - INFO - now: 14:45 code : 000333.SZ price:66.2
2024-09-20 14:46:00 - INFO - now: 14:46 code : 000333.SZ price:66.19
2024-09-20 14:47:00 - INFO - now: 14:47 code : 000333.SZ price:66.18
2024-09-20 14:48:00 - INFO - now: 14:48 code : 000333.SZ price:66.14
2024-09-20 14:49:00 - INFO - now: 14:49 code : 000333.SZ price:66.25
2024-09-20 14:50:00 - INFO - now: 14:50 code : 000333.SZ price:66.19
2024-09-20 14:51:00 - INFO - now: 14:51 code : 000333.SZ price:66.18
2024-09-20 14:52:00 - INFO - now: 14:52 code : 000333.SZ price:66.19
2024-09-20 14:53:00 - INFO - now: 14:53 code : 000333.SZ price:66.2
2024-09-20 14:54:00 - INFO - now: 14:54 code : 000333.SZ price:66.19
2024-09-20 14:55:00 - INFO - now: 14:55 code : 000333.SZ price:66.25
2024-09-20 14:56:00 - INFO - now: 14:56 code : 000333.SZ price:66.27
2024-09-20 14:57:00 - INFO - now: 14:57 code : 000333.SZ price:66.28
2024-09-20 14:58:00 - INFO - now: 14:58 code : 000333.SZ price:66.28
2024-09-20 14:59:00 - INFO - now: 14:59 code : 000333.SZ price:66.28
2024-09-20 15:00:00 - INFO - now: 15:00 code : 000333.SZ price:66.06
用同花顺,对了一下结果,是满足的了。
python Ptrade获取热门板块,连板股票 python代码
李魔佛 发表了文章 • 0 个评论 • 410 次浏览 • 2024-08-23 16:57
Ptrade API文档:https://ptradeapi.com/#get_sort_msg
get_sort_msg – 获取板块、行业的涨幅排名
get_sort_msg(sort_type_grp=None, sort_field_name=None, sort_type=1, data_count=100)
接口说明
该接口用于获取板块、行业的涨幅排名。
参数 sort_type_grp: 板块或行业的代码(list[str]/str);
(暂时只支持XBHS.DY地域、XBHS.GN概念、XBHS.ZJHHY证监会行业、XBHS.ZS指数、XBHS.HY行业等)
示例代码:按概念板块涨幅倒序排名
import datetime
START_TIME = (datetime.datetime.now() + datetime.timedelta(minutes=1)).strftime('%H:%M')
def execution(context):
#获取XBHS.GN的概念排名信息
sort_data = get_sort_msg(sort_type_grp='XBHS.GN', sort_field_name='px_change_rate', sort_type=1, data_count=100)
for data in sort_data:
log.info('板块: {} '.format(data['prod_name']))
for sub_stock in data['rise_first_grp']:
log.info('{} 涨幅 :{}'.format(sub_stock['prod_name'],sub_stock['px_change_rate']))
log.info('\n')
def initialize(context):
# 初始化策略
run_daily(context, execution, time=START_TIME) # 扫描
log.info("公众号:可转债量化分析\n")
def handle_data(context, data):
pass
上面代码在ptrade启动后一分钟拿到结果。不限制要求开盘时间的。其实Ptrade可以在24小时任意时刻启动。
get_sort_msg 返回的数据结构体如下:
具体字段的含义:
prod_code: 行业代码(str:str);
prod_name: 行业名称(str:str);
hq_type_code: 行业板块代码(str:str);
time_stamp: 时间戳毫秒级(str:int);
trade_mins: 交易分钟数(str:int);
trade_status: 交易状态(str:str);
preclose_px: 昨日收盘价(str:float);
open_px: 今日开盘价(str:float);
last_px: 最新价(str:float);
high_px: 最高价(str:float);
low_px: 最低价(str:float);
wavg_px: 加权平均价(str:float);
business_amount: 总成交量(str:int);
business_balance: 总成交额(str:int);
px_change: 涨跌额(str:float);
amplitude: 振幅(str:int);
px_change_rate: 涨跌幅(str:float);
circulation_amount: 流通股本(str:int);
total_shares: 总股本(str:int);
market_value: 市值(str:int);
circulation_value: 流通市值(str:int);
vol_ratio: 量比(str:float);
shares_per_hand: 每手股数(str:int);
rise_count: 上涨家数(str:int);
fall_count: 下跌家数(str:int);
member_count: 成员个数(str:int);
rise_first_grp: 领涨股票(其包含以下五个字段)(str:list[dict{str:int,str:str,str:str,str:float,str:float},...]);
prod_code: 股票代码(str:str);
prod_name: 证券名称(str:str);
hq_type_code: 类型代码(str:str);
last_px: 最新价(str:float);
px_change_rate: 涨跌幅(str:float);
fall_first_grp: 领跌股票(其包含以下五个字段)(str:list[dict{str:int,str:str,str:str,str:float,str:float},...]);
prod_code: 股票代码(str:str);
prod_name: 证券名称(str:str);
hq_type_code: 类型代码(str:str);
last_px: 最新价(str:float);
px_change_rate: 涨跌幅(str:float);
这个返回数据是实时的,可以用来选股,选择热门股,热门板块,涨停板块,昨日涨停,昨日连板板块。
比如上面运行结果里就有 昨日连板的板块个股,有9个,在rise_first_grp 字段里面:
需要开通Ptrade的读者朋友可以后天联系哦,提供不同券商ptrade,低门槛,低费率,还有技术支持群!
查看全部
Ptrade API文档:https://ptradeapi.com/#get_sort_msg
get_sort_msg – 获取板块、行业的涨幅排名
get_sort_msg(sort_type_grp=None, sort_field_name=None, sort_type=1, data_count=100)
接口说明
该接口用于获取板块、行业的涨幅排名。
参数 sort_type_grp: 板块或行业的代码(list[str]/str);
(暂时只支持XBHS.DY地域、XBHS.GN概念、XBHS.ZJHHY证监会行业、XBHS.ZS指数、XBHS.HY行业等)
示例代码:按概念板块涨幅倒序排名
import datetime
START_TIME = (datetime.datetime.now() + datetime.timedelta(minutes=1)).strftime('%H:%M')
def execution(context):
#获取XBHS.GN的概念排名信息
sort_data = get_sort_msg(sort_type_grp='XBHS.GN', sort_field_name='px_change_rate', sort_type=1, data_count=100)
for data in sort_data:
log.info('板块: {} '.format(data['prod_name']))
for sub_stock in data['rise_first_grp']:
log.info('{} 涨幅 :{}'.format(sub_stock['prod_name'],sub_stock['px_change_rate']))
log.info('\n')
def initialize(context):
# 初始化策略
run_daily(context, execution, time=START_TIME) # 扫描
log.info("公众号:可转债量化分析\n")
def handle_data(context, data):
pass
上面代码在ptrade启动后一分钟拿到结果。不限制要求开盘时间的。其实Ptrade可以在24小时任意时刻启动。
get_sort_msg 返回的数据结构体如下:
具体字段的含义:
prod_code: 行业代码(str:str);
prod_name: 行业名称(str:str);
hq_type_code: 行业板块代码(str:str);
time_stamp: 时间戳毫秒级(str:int);
trade_mins: 交易分钟数(str:int);
trade_status: 交易状态(str:str);
preclose_px: 昨日收盘价(str:float);
open_px: 今日开盘价(str:float);
last_px: 最新价(str:float);
high_px: 最高价(str:float);
low_px: 最低价(str:float);
wavg_px: 加权平均价(str:float);
business_amount: 总成交量(str:int);
business_balance: 总成交额(str:int);
px_change: 涨跌额(str:float);
amplitude: 振幅(str:int);
px_change_rate: 涨跌幅(str:float);
circulation_amount: 流通股本(str:int);
total_shares: 总股本(str:int);
market_value: 市值(str:int);
circulation_value: 流通市值(str:int);
vol_ratio: 量比(str:float);
shares_per_hand: 每手股数(str:int);
rise_count: 上涨家数(str:int);
fall_count: 下跌家数(str:int);
member_count: 成员个数(str:int);
rise_first_grp: 领涨股票(其包含以下五个字段)(str:list[dict{str:int,str:str,str:str,str:float,str:float},...]);
prod_code: 股票代码(str:str);
prod_name: 证券名称(str:str);
hq_type_code: 类型代码(str:str);
last_px: 最新价(str:float);
px_change_rate: 涨跌幅(str:float);
fall_first_grp: 领跌股票(其包含以下五个字段)(str:list[dict{str:int,str:str,str:str,str:float,str:float},...]);
prod_code: 股票代码(str:str);
prod_name: 证券名称(str:str);
hq_type_code: 类型代码(str:str);
last_px: 最新价(str:float);
px_change_rate: 涨跌幅(str:float);
这个返回数据是实时的,可以用来选股,选择热门股,热门板块,涨停板块,昨日涨停,昨日连板板块。
比如上面运行结果里就有 昨日连板的板块个股,有9个,在rise_first_grp 字段里面:
需要开通Ptrade的读者朋友可以后天联系哦,提供不同券商ptrade,低门槛,低费率,还有技术支持群!
【保姆教程】使用ptrade做一个持仓监控提醒软件 (二)
李魔佛 发表了文章 • 0 个评论 • 635 次浏览 • 2024-08-08 14:01
主要框架如下:
盘前我们先去读取数据库的数据:
格式很简单,就记录了代码和名字:
df = pd.read_sql('select * from tb_holding_stock_list', con=engine)
def initialize(context):
# 初始化策略
engine = DBSelector().get_engine()
df = pd.read_sql('select * from tb_holding_stock_list', con=engine)
df['code']=df['code'].astype(str)
result = {}
for index, row in df.iterrows():
code = add_code_postfix(row['code'])
result[code] = {'name': row['name'], 'source': row['source']}
g.holding_stock_dict = result
g.holding_stock_list = list(result.keys())
g.__cache = Cache()
run_interval(context, execution, seconds=INTERVAL) # 扫描
def handle_data(context, data):
pass
def tick_data(context, data):
pass
def before_trading_start(context, data):
'''
盘前
'''
if DEBUG:
log.info('盘前运行开始', str(context.blotter.current_dt))
def after_trading_end(context, data):
'''
盘后
'''
if DEBUG:
log.info('盘后时间 ', str(context.blotter.current_dt))
然后主要部分在 execution 这个监控函数这里。
def execution(context):
tick_info = get_snapshot(g.holding_stock_list)
for code, tick in tick_info.items():
px_change_rate = tick['px_change_rate']
if px_change_rate > abs(HIT_TARGET):
if g.__cache.check(code):
# 通知
name = g.holding_stock_dict.get(code)['name']
source = g.holding_stock_dict.get(code)['source']
msg = '{}-{} 涨幅-{},{}'.format(code,
name, px_change_rate, source)
send_message_via_wechat(msg)
send_message_via_wechat 这个函数是发送微信消息的。
然后基本完成了整体的代码编写,里面一些自定义的函数为了判断 下一次通知要等待多久。
因为不能因为同一个股票满足条件了,然后每隔3秒发一次微信消息。你手机会一直滴滴滴地响的。
而且很容易把其他刚出现的提示给覆盖了。
【保姆教程】使用ptrade做一个持仓监控提醒软件 (一)
查看全部
主要框架如下:
盘前我们先去读取数据库的数据:
格式很简单,就记录了代码和名字:
df = pd.read_sql('select * from tb_holding_stock_list', con=engine)
def initialize(context):
# 初始化策略
engine = DBSelector().get_engine()
df = pd.read_sql('select * from tb_holding_stock_list', con=engine)
df['code']=df['code'].astype(str)
result = {}
for index, row in df.iterrows():
code = add_code_postfix(row['code'])
result[code] = {'name': row['name'], 'source': row['source']}
g.holding_stock_dict = result
g.holding_stock_list = list(result.keys())
g.__cache = Cache()
run_interval(context, execution, seconds=INTERVAL) # 扫描
def handle_data(context, data):
pass
def tick_data(context, data):
pass
def before_trading_start(context, data):
'''
盘前
'''
if DEBUG:
log.info('盘前运行开始', str(context.blotter.current_dt))
def after_trading_end(context, data):
'''
盘后
'''
if DEBUG:
log.info('盘后时间 ', str(context.blotter.current_dt))
然后主要部分在 execution 这个监控函数这里。
def execution(context):
tick_info = get_snapshot(g.holding_stock_list)
for code, tick in tick_info.items():
px_change_rate = tick['px_change_rate']
if px_change_rate > abs(HIT_TARGET):
if g.__cache.check(code):
# 通知
name = g.holding_stock_dict.get(code)['name']
source = g.holding_stock_dict.get(code)['source']
msg = '{}-{} 涨幅-{},{}'.format(code,
name, px_change_rate, source)
send_message_via_wechat(msg)
send_message_via_wechat 这个函数是发送微信消息的。
然后基本完成了整体的代码编写,里面一些自定义的函数为了判断 下一次通知要等待多久。
因为不能因为同一个股票满足条件了,然后每隔3秒发一次微信消息。你手机会一直滴滴滴地响的。
而且很容易把其他刚出现的提示给覆盖了。
【保姆教程】使用ptrade做一个持仓监控提醒软件 (一)
【保姆教程】使用ptrade做一个持仓监控提醒软件 (一)
李魔佛 发表了文章 • 0 个评论 • 642 次浏览 • 2024-08-07 10:23
因为有多个券商,比如银河,华宝,国金,国盛等。 而且也有家人的账户,可能一个银河就有5-6个账户。
所以如果持仓比较多的话,没有时间管得过来。 设置条件单比较繁琐,也不一定能管得过来。
要求:
把所有的持仓股Excel导出,输入的数据库(这里选择mysql),然后Ptrade读取了股票池,每隔3s扫描一次行情,如果遇到大涨或者大跌的个股,转债,ETF,就发送微信消息提醒(涨幅/跌幅大于7%)
这个是某个客户的简单需求。
后面就按照上面的需求做一个客户端,除了可以录入上述资料,还能提供web服务,输入,删除持仓股,做到实时更新。
最后提醒效果如下:
国金QMT的字样,用来区分我这个标的是哪一个券商的持仓。比如 有可能是 家人1-银河,家人2-国盛,这样的哈
下一篇:
【保姆教程】使用ptrade做一个持仓监控提醒软件 (二)
欢迎关注公众号:可转债量化分析 查看全部
因为有多个券商,比如银河,华宝,国金,国盛等。 而且也有家人的账户,可能一个银河就有5-6个账户。
所以如果持仓比较多的话,没有时间管得过来。 设置条件单比较繁琐,也不一定能管得过来。
要求:
把所有的持仓股Excel导出,输入的数据库(这里选择mysql),然后Ptrade读取了股票池,每隔3s扫描一次行情,如果遇到大涨或者大跌的个股,转债,ETF,就发送微信消息提醒(涨幅/跌幅大于7%)
这个是某个客户的简单需求。
后面就按照上面的需求做一个客户端,除了可以录入上述资料,还能提供web服务,输入,删除持仓股,做到实时更新。
最后提醒效果如下:
国金QMT的字样,用来区分我这个标的是哪一个券商的持仓。比如 有可能是 家人1-银河,家人2-国盛,这样的哈
下一篇:
【保姆教程】使用ptrade做一个持仓监控提醒软件 (二)
欢迎关注公众号:可转债量化分析
ptrade获取的历史数据最长到哪一年?ptrade如何获取上证指数
李魔佛 发表了文章 • 0 个评论 • 557 次浏览 • 2024-06-30 13:48
文档里面也有说明:
7、该接口只能获取2005年后的数据。
ptrade官网api接口文档:
https://ptradeapi.com/#
实测也是符合要求的:
ptrade如何获取上证指数, 代码是 000001.SS
test_data = data = get_price(security='000001.SS',start_date='20050201',end_date='20050630',frequency='1d')
ptrade获取上证指数2005年的数据:
需要低佣,低门槛开通ptrade的朋友,可以扫描关注关注号: 查看全部
文档里面也有说明:
7、该接口只能获取2005年后的数据。
ptrade官网api接口文档:
https://ptradeapi.com/#
实测也是符合要求的:
ptrade如何获取上证指数, 代码是 000001.SS
test_data = data = get_price(security='000001.SS',start_date='20050201',end_date='20050630',frequency='1d')
ptrade获取上证指数2005年的数据:
需要低佣,低门槛开通ptrade的朋友,可以扫描关注关注号:
Ptrade成交回调函数无法执行的原因? | ptrade bug
李魔佛 发表了文章 • 0 个评论 • 618 次浏览 • 2024-05-28 00:08
就是回调函数里面有一个字段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 是不会执行的!!!
天坑!
查看全部
就是回调函数里面有一个字段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 个评论 • 839 次浏览 • 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,
在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上运行,均能得到正确的数据。
然后更为搞笑的,这么一个问题,反馈了,没有回应。无语。
ptrade调试经验分享(坑) 委托成交回调函数
李魔佛 发表了文章 • 0 个评论 • 1269 次浏览 • 2023-12-22 10:30
之前的代码里面,由于少了一个if,导致如果code不在
g.start_buy_sell_queue
这个集合里面的话,就会报错。(但正常情况下都会有值,但问题就出现在一些特殊情况下)
不然你试试在
on_trade_response
里面直接raise一个Exception出来,日志里也不会有任何显示。
切近!!
on_trade_response 里面做好安全防护!! 最好是有些业务逻辑完成了在里面print一下,以确保是执行到后面的。 查看全部
ptrade精确参与集合竞价交易 时间设置问题
李魔佛 发表了文章 • 0 个评论 • 1540 次浏览 • 2023-11-16 10:10
查了下日志。run_daily 设置的9:25运行,下单委托的时间在9:25:01 这个时间就被推到9:30开盘去成交了。
所以实际没有参与到9:25的集合竞价。
所以要参与集合竞价,需要设定在9:24分开始,然后不断在一个循环里面,用更小的时间颗粒,比如100ms去监听。
等到9:24:59的时间,才去下单。
import datetime
import time
RUN_TIME = '09:24'
def execution(context):
while 1:
current_second = datetime.datetime.now().strftime('%S')
if current_second >= '58':
break
time.sleep(0.1)
do_something()
def initialize(context):
# 初始化策略
run_daily(context, execution, RUN_TIME)
def handle_data(context, data):
pass
具体代码可以参照我的知识星球
查看全部
查了下日志。run_daily 设置的9:25运行,下单委托的时间在9:25:01 这个时间就被推到9:30开盘去成交了。
所以实际没有参与到9:25的集合竞价。
所以要参与集合竞价,需要设定在9:24分开始,然后不断在一个循环里面,用更小的时间颗粒,比如100ms去监听。
等到9:24:59的时间,才去下单。
import datetime
import time
RUN_TIME = '09:24'
def execution(context):
while 1:
current_second = datetime.datetime.now().strftime('%S')
if current_second >= '58':
break
time.sleep(0.1)
do_something()
def initialize(context):
# 初始化策略
run_daily(context, execution, RUN_TIME)
def handle_data(context, data):
pass
具体代码可以参照我的知识星球
ptrade 全局对象g持久化对象保存失败
李魔佛 发表了文章 • 0 个评论 • 1192 次浏览 • 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 判断股票是否涨停
李魔佛 发表了文章 • 0 个评论 • 1725 次浏览 • 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实盘
李魔佛 发表了文章 • 0 个评论 • 1879 次浏览 • 2023-10-07 14:14
当前策略持有30只。
点击查看大图
点击查看大图
基于股票的策略不敢多买,属于试验阶段,后期仍然会不断根据市场调仓; 主仓依然在可转债。
公众号:可转债量化分析
如果需要策略代写,(ptrade、qmt,其他量化平台)
可以公众号后台回复:
策略代写
查看全部
ptrade最多支持同时运行多少个策略?
李魔佛 发表了文章 • 0 个评论 • 1328 次浏览 • 2023-09-21 17:16
但同时运行的策略只有5个。
如果不需要的策略,可以把它暂停了,记住,不要随意暂停。 因为暂停了,重启后你的日志就会随之被清空。
平时也应该做好日志备份的习惯。 部分券商可以连接mysql,可以把数据导出,也可以顺便把日志也导出。
需要开通Ptrade或者代写的朋友可以咨询:
查看全部
Ptrade跟踪雪球组合自动调仓
李魔佛 发表了文章 • 0 个评论 • 1337 次浏览 • 2023-09-19 20:25
根据指定的雪球组合, 自动跟踪组合的调仓与比例.
图随便截取的,具体跟踪的组合,客户自己可以直接配置.
目前是每10分钟刷新一次 组合数据,如果有更新就马上根据调仓.
盘前和收盘前2分钟, 会定期扫码, 以免到了收盘来不及成交, 留够足够的时间下单与撤单.
PS:图片与策略无关
耗时地方仍然是调试.
查看全部
ptrade量化策略:低位首板启动板-首板+低吸+单阳不破
李魔佛 发表了文章 • 0 个评论 • 1485 次浏览 • 2023-09-05 22:44
Ptrade实现实盘自动交易代码。
(图片截图非本策略,随意贴的)
里面细节比较多。
得慢慢调。
国盛证券Ptrade测试版下载 Ptrade模拟客户端 模拟账号
李魔佛 发表了文章 • 0 个评论 • 1817 次浏览 • 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有测试版本,但是个人还是非常不推荐使用测试版本。 以前在上面写过回测或者模拟盘,发现问题非常多,一个是数据缺了,数据错乱。以前被它坑过,后面基本都就不敢用了。 群里的兄弟大部分也被坑过,进群公告就是告诫他们,远离测试版。。。哈
实盘版本的需要开通才能申请,不同券商的门槛不一样。需要的朋友可以扫码咨询:
20行代码实现Ptrade一键清仓
李魔佛 发表了文章 • 0 个评论 • 1306 次浏览 • 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 个评论 • 1272 次浏览 • 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【一】
李魔佛 发表了文章 • 0 个评论 • 1574 次浏览 • 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的不同
李魔佛 发表了文章 • 0 个评论 • 1345 次浏览 • 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资金更新速度|高频中如何处理
李魔佛 发表了文章 • 0 个评论 • 1556 次浏览 • 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又可以重新开了,需要的小伙伴抓紧开啦
李魔佛 发表了文章 • 0 个评论 • 1665 次浏览 • 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开通
用户问的比较多的关于ptrade基础问题
李魔佛 发表了文章 • 0 个评论 • 2083 次浏览 • 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 个评论 • 1749 次浏览 • 2023-04-29 02:40
部分券商的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可以连通外网,只需要部署一个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. 文件保存了之后,接着就可以下载了。
数据在研究的页面那里。
然后点击某个文件,
如果是非纯文本文件,比如excel文件,会显示:
Error! not UTF-8 encoded
Saving disable
See console for more details
不用理会,直接点击左上角的文件,下载,选择本地的路径,然后文件就可以下载下来了。
【100行python代码实现可转债日内网格-成交驱动】 自定义买卖步长
李魔佛 发表了文章 • 0 个评论 • 1990 次浏览 • 2023-04-19 13:27
## 2023-04-19 更新: 部分成交的需要等待全部成交才触发下一轮挂单
简单的可转债日内网格策略,自定义买卖步长,基准价格,买入与卖出数量,保留底仓张数
开始同时挂买入和卖出委托,如果买入成交后,撤掉委卖(如果是卖出先成交,则撤掉委买),继续挂入下一个步长的委买与委卖,不断循环。
把注释和空格去了100行不到。
代码仅供参考学习具体用法:
用于实盘亏损盈亏自负
后续如果有需要再贴个升级版:多标的网格
或者,额,qmt版本。。。
部分代码截图:
实盘交易日志:点击查看大图
完整代码请参见知识星球.
知识无价,请尊重知识。
查看全部
## 2023-04-19 更新: 部分成交的需要等待全部成交才触发下一轮挂单
简单的可转债日内网格策略,自定义买卖步长,基准价格,买入与卖出数量,保留底仓张数
开始同时挂买入和卖出委托,如果买入成交后,撤掉委卖(如果是卖出先成交,则撤掉委买),继续挂入下一个步长的委买与委卖,不断循环。
把注释和空格去了100行不到。
代码仅供参考学习具体用法:
用于实盘亏损盈亏自负
后续如果有需要再贴个升级版:多标的网格
或者,额,qmt版本。。。
部分代码截图:
实盘交易日志:点击查看大图
完整代码请参见知识星球.
知识无价,请尊重知识。
ptrade担保品买卖,融资买入,融券卖出,卖券还款,买券还券 下单后回调函数里面的结构
李魔佛 发表了文章 • 0 个评论 • 1420 次浏览 • 2023-03-31 21:44
而对于不能安装第三方库的原因,不少菜鸟转而选择了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 个评论 • 1703 次浏览 • 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 个评论 • 1452 次浏览 • 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 个评论 • 1466 次浏览 • 2023-03-13 23:53
比如设置20%,那么会每天盘中扫描,可以精确到3S 一格,如果你的持仓股的收益率大于20%,它将会帮你自动卖出。
占坑 待续 》》》
比如设置20%,那么会每天盘中扫描,可以精确到3S 一格,如果你的持仓股的收益率大于20%,它将会帮你自动卖出。
占坑 待续 》》》
ptrade qmt的模拟账户能不用尽量不用,无尽的bug让你浪费时间 怀疑人生
李魔佛 发表了文章 • 0 个评论 • 2372 次浏览 • 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上就更加严重了。 下次在星球上或者群里慢慢吐槽吧