
PTrade
Ptrade下单接口 order,order_target, order_value,order_target_value的区别
量化交易 • 李魔佛 发表了文章 • 0 个评论 • 54 次浏览 • 2022-08-11 23:57
接口
order_value 接口通过 金额/限价 或者 金额/默认最新价 两种方式转换成需要交易的数量,
传入 order 接口
order_target_value 接口通过持仓金额比较得到需要交易的金额, 金额/限价 或者 金额/默
认最新价 两种方式转换成需要交易的数量,传入 order 接口
所以其他几个接口都是对order的封装。
order接口的逻辑:
order 接口:
一、
先判断 limit_price 是否传入,传入则用传入价格限价,不传入则最新价代替,都是
限价方式报单。
二、
判断隔夜单和交易时间,交易时间(9:10(系统可配)~15:00)范围的订单会马上
加入未处理订单队列,其他订单先放到一个队列,等时间到交易时间就放到未处理订单
队列
三、
未处理订单队列的订单会进行限价判断,如果没有传入限价就按当前最新价处理,
然后报柜台
查看全部
order_target 接口通过持仓数量比较将入参的目标数量转换成需要交易的成交,传入 order
接口
order_value 接口通过 金额/限价 或者 金额/默认最新价 两种方式转换成需要交易的数量,
传入 order 接口
order_target_value 接口通过持仓金额比较得到需要交易的金额, 金额/限价 或者 金额/默
认最新价 两种方式转换成需要交易的数量,传入 order 接口
所以其他几个接口都是对order的封装。
order接口的逻辑:
order 接口:
一、
先判断 limit_price 是否传入,传入则用传入价格限价,不传入则最新价代替,都是
限价方式报单。
二、
判断隔夜单和交易时间,交易时间(9:10(系统可配)~15:00)范围的订单会马上
加入未处理订单队列,其他订单先放到一个队列,等时间到交易时间就放到未处理订单
队列
三、
未处理订单队列的订单会进行限价判断,如果没有传入限价就按当前最新价处理,
然后报柜台
Ptrade抢新上市的可转债
量化交易 • 李魔佛 发表了文章 • 0 个评论 • 61 次浏览 • 2022-08-11 10:20
PS: 也不是每一只都是去抢,还是需要提前判断下。规模小的优先。
自己写的包在 PTrade 里如何使用的方法有吗?
量化交易 • 李魔佛 发表了文章 • 0 个评论 • 68 次浏览 • 2022-08-08 03:28
A:和常规 Python 函数调用时一样的,只是需要和你的其它函数放在同一个脚本
中,暂时不支持跨越脚本文件的调用。
所以你写的包,都要放着ptrade的策略里面,不能另外保存到一个地方,然后通过 from xxxx import xxxx 这种方式导入。
所以有时候你的ptrade文件会臃肿无比。经常复制粘贴。也是无奈之举。 查看全部
A:和常规 Python 函数调用时一样的,只是需要和你的其它函数放在同一个脚本
中,暂时不支持跨越脚本文件的调用。
所以你写的包,都要放着ptrade的策略里面,不能另外保存到一个地方,然后通过 from xxxx import xxxx 这种方式导入。
所以有时候你的ptrade文件会臃肿无比。经常复制粘贴。也是无奈之举。
ptrade支持文件的读写吗,Excel 文件可以读写吗
量化交易 • 李魔佛 发表了文章 • 0 个评论 • 55 次浏览 • 2022-08-08 00:01
当前支持 csv,xlsx,txt,pkl 等文件的读取,需要手动将对应文件上传到研究环境中,
然后在回测中使用 get_research_path()+”文件名”获取文件路径后进行读取(见下图),
回写文件类似,可使用 pd.to_csv()等函数存储在研究环境指定目录下。
值得注意的是,当前支持单个文件最大为 50M
模型每天都会更新的,权重文件,能上传吗?
可以,注意文件大小的限制。
查看全部
ptrade策略代码:集合竞价追涨停策略
量化交易 • 李魔佛 发表了文章 • 0 个评论 • 103 次浏览 • 2022-08-04 15:24
# 初始化此策略
# 设置我们要操作的股票池, 这里我们只操作一支股票
g.security = '600570.SS'
set_universe(g.security)
#每天9:23分运行集合竞价处理函数
run_daily(context, aggregate_auction_func, time='9:23')
def aggregate_auction_func(context):
stock = g.security
#最新价
snapshot = get_snapshot(stock)
price = snapshot[stock]['last_px']
#涨停价
up_limit = snapshot[stock]['up_px']
#如果最新价不小于涨停价,买入
if float(price) >= float(up_limit):
order(g.security, 100, limit_price=up_limit)
def handle_data(context, data):
pass
分解讲解:def initialize(context):
# 初始化此策略
# 设置我们要操作的股票池, 这里我们只操作一支股票
g.security = '600570.SS'
set_universe(g.security)
#每天9:23分运行集合竞价处理函数
run_daily(context, aggregate_auction_func, time='9:23')
initialize是初始化函数,一定要有的函数。在策略运行时首先运行的,而且只会运行一次。
set_universe(g.security) 在把标的代码放进去。这里是 '600570.SS' 记得要有后缀,上证股票用 .SS ,深圳股票用.SZ。
run_daily(context, aggregate_auction_func, time='9:23')
这一行是设定每天运行一次。这个策略是日线级别的,所以每天只要运行一次就可以了。 分别传入3个参数。
第一个参数固定是context,第二个要执行的函数名,记住只能传函数名,不能把括号也加进去,第三个参数,是运行的时间,现在设定在 9:23
那么接下来就是要实现上面那个函数名了: aggregate_auction_func,这个名字可以随意定义
def aggregate_auction_func(context):
stock = g.security
#最新价
snapshot = get_snapshot(stock)
price = snapshot[stock]['last_px']
#涨停价
up_limit = snapshot[stock]['up_px']
#如果最新价不小于涨停价,买入
if float(price) >= float(up_limit):
order(g.security, 100, limit_price=up_limit)
stock = g.security , g是全局变量,用来在上下文中传递数据。这里就是上面的'600570.SS'
snapshot = get_snapshot(stock)
这个就是获取行情数据,当前的价格
up_limit = snapshot[stock]['up_px']
拿到这个标的的涨停价
if float(price) >= float(up_limit):
这个是当前价格大于涨停板价格(主要考虑了四舍五入,用于大号比较安全)
order(g.security, 100, limit_price=up_limit)
这个就是下单函数。
买入100股,不限价,市价成交。
然后就可以点击运行交易。
程序每天都会自动交易。
查看全部
def initialize(context):
# 初始化此策略
# 设置我们要操作的股票池, 这里我们只操作一支股票
g.security = '600570.SS'
set_universe(g.security)
#每天9:23分运行集合竞价处理函数
run_daily(context, aggregate_auction_func, time='9:23')
def aggregate_auction_func(context):
stock = g.security
#最新价
snapshot = get_snapshot(stock)
price = snapshot[stock]['last_px']
#涨停价
up_limit = snapshot[stock]['up_px']
#如果最新价不小于涨停价,买入
if float(price) >= float(up_limit):
order(g.security, 100, limit_price=up_limit)
def handle_data(context, data):
pass
分解讲解:
def initialize(context):
# 初始化此策略
# 设置我们要操作的股票池, 这里我们只操作一支股票
g.security = '600570.SS'
set_universe(g.security)
#每天9:23分运行集合竞价处理函数
run_daily(context, aggregate_auction_func, time='9:23')
initialize是初始化函数,一定要有的函数。在策略运行时首先运行的,而且只会运行一次。
set_universe(g.security) 在把标的代码放进去。这里是 '600570.SS' 记得要有后缀,上证股票用 .SS ,深圳股票用.SZ。
run_daily(context, aggregate_auction_func, time='9:23')
这一行是设定每天运行一次。这个策略是日线级别的,所以每天只要运行一次就可以了。 分别传入3个参数。
第一个参数固定是context,第二个要执行的函数名,记住只能传函数名,不能把括号也加进去,第三个参数,是运行的时间,现在设定在 9:23
那么接下来就是要实现上面那个函数名了: aggregate_auction_func,这个名字可以随意定义
def aggregate_auction_func(context):
stock = g.security
#最新价
snapshot = get_snapshot(stock)
price = snapshot[stock]['last_px']
#涨停价
up_limit = snapshot[stock]['up_px']
#如果最新价不小于涨停价,买入
if float(price) >= float(up_limit):
order(g.security, 100, limit_price=up_limit)
stock = g.security , g是全局变量,用来在上下文中传递数据。这里就是上面的'600570.SS'
snapshot = get_snapshot(stock)
这个就是获取行情数据,当前的价格
up_limit = snapshot[stock]['up_px']
拿到这个标的的涨停价
if float(price) >= float(up_limit):
这个是当前价格大于涨停板价格(主要考虑了四舍五入,用于大号比较安全)
order(g.security, 100, limit_price=up_limit)
这个就是下单函数。
买入100股,不限价,市价成交。
然后就可以点击运行交易。
程序每天都会自动交易。
ptrade可以同时执行多少个实盘策略?
量化交易 • 李魔佛 发表了文章 • 0 个评论 • 104 次浏览 • 2022-08-02 20:41
而在代码里面,如果多个策略同时运行,需要在代码层面区分不同策略下的单子,不然会造成冲突。比如你第一个策略下的单子,被第二个策略清仓了。
那么要如何区分不同策略下单呢?
1. 如果是日内策略,只需要用一个字典dict,记录每次买入记录,每次的卖出标的都要在dict里面。
2. 持久化。虽然大部分券商的ptrade都不支持联网,但是,可以使用本地持久化,pickle或者sqlite。保存在云本地。 查看全部
ptrade如何以指定价格下单?
量化交易 • 李魔佛 发表了文章 • 0 个评论 • 108 次浏览 • 2022-07-30 19:27
order函数:order-按数量买卖
order(security, amount, limit_price=None)
买卖标的。
注意:
由于下述原因,回测中实际买入或者卖出的股票数量有时候可能与委托设置的不一样,针对上述内容调整,系统会在日志中增加警告信息:
根据委托买入数量与价格经计算后的资金数量,大于当前可用资金;
委托卖出数量大于当前可用持仓数量;
每次交易数量只能是100的整数倍,但是卖出所有股票时不受此限制;
股票停牌、股票未上市或者退市、股票不存在;
回测中每天结束时会取消所有未完成交易;
order_target - 函数order_target(security, amount, limit_price=None)
买卖股票,直到股票最终数量达到指定的amount。
注意:该函数在委托股票时取整100股,委托可转债时取整100张。
参数
security: 股票代码(str);
amount: 期望的最终数量(int);
limit_price:买卖限价(float);
返回
Order对象中的id或者None。如果创建订单成功,则返回Order对象的id,失败则返回None(str)。
order_value 函数order_value - 指定目标价值买卖
order_value(security, value, limit_price=None)
买卖指定价值为value的股票。
注意:该函数在委托股票时取整100股,委托可转债时取整100张。
order_target_value - 函数order_target_value - 指定持仓市值买卖
order_target_value(security, value, limit_price=None)
调整股票仓位到value价值
注意:该函数在委托股票时取整100股,委托可转债时取整100张。
order_market 函数order_market - 按市价进行委托
order_market(security, amount, market_type=None, limit_price=None)
可以使用多种市价类型进行委托。
注意:该函数仅在股票交易模块可用。
上面几个在handle_data中使用的下单函数,都是无法指定价格的,limit_price 只是用于限价,比如你要卖1000股,limit_price的作用是不要把价格卖出你的目标,至于多少卖,是无法控制的。
但是有一个tick_data函数,专门用于行情交易的,里面可调用的函数也很少。tick_data(可选)
tick_data(context, data)
该函数会每隔3秒执行一次。
注意 :
该函数仅在交易模块可用。
该函数在9:30之后才能执行。
该函数中只能使用order_tick进行对应的下单操作。里面下单,用的下单函数是
order_tick - tick行情触发买卖
order_tick(sid, amount, priceGear='1', limit_price=None)
买卖股票下单,可设定价格档位进行委托
注意:该函数仅在交易模块可用。
参数
sid:股票代码(str);
amount:交易数量,正数表示买入,负数表示卖出(int)
priceGear:盘口档位,level1:1~5买档/-1~-5卖档,level2:1~10买档/-1~-10卖档(str)
limit_price:买卖限价,当输入参数中也包含priceGear时,下单价格以limit_price为主(float);
注意到里面:
limit_price:买卖限价,当输入参数中也包含priceGear时,下单价格以limit_price为主
发现这里面居然可以定义价格下单,所以如果一定要指定价格,就需要使用tick_data 触发。
使用代码:
def initialize(context):
g.security = "600570.SS"
set_universe(g.security)
def tick_data(context,data):
security = g.security
current_price = eval(data[security]['tick']['bid_grp'][0])[1][0]
if current_price > 56 and current_price < 57:
# 以买一档下单
order_tick(g.security, -100, "1")
# 以卖二档下单
order_tick(g.security, 100, "-2")
# 以指定价格下单
order_tick(g.security, 100, limit_price=56.5)
def handle_data(context, data):
pass 查看全部
order函数:
order-按数量买卖
order(security, amount, limit_price=None)
买卖标的。
注意:
由于下述原因,回测中实际买入或者卖出的股票数量有时候可能与委托设置的不一样,针对上述内容调整,系统会在日志中增加警告信息:
根据委托买入数量与价格经计算后的资金数量,大于当前可用资金;
委托卖出数量大于当前可用持仓数量;
每次交易数量只能是100的整数倍,但是卖出所有股票时不受此限制;
股票停牌、股票未上市或者退市、股票不存在;
回测中每天结束时会取消所有未完成交易;
order_target - 函数
order_target(security, amount, limit_price=None)
买卖股票,直到股票最终数量达到指定的amount。
注意:该函数在委托股票时取整100股,委托可转债时取整100张。
参数
security: 股票代码(str);
amount: 期望的最终数量(int);
limit_price:买卖限价(float);
返回
Order对象中的id或者None。如果创建订单成功,则返回Order对象的id,失败则返回None(str)。
order_value 函数
order_value - 指定目标价值买卖
order_value(security, value, limit_price=None)
买卖指定价值为value的股票。
注意:该函数在委托股票时取整100股,委托可转债时取整100张。
order_target_value - 函数
order_target_value - 指定持仓市值买卖
order_target_value(security, value, limit_price=None)
调整股票仓位到value价值
注意:该函数在委托股票时取整100股,委托可转债时取整100张。
order_market 函数
order_market - 按市价进行委托
order_market(security, amount, market_type=None, limit_price=None)
可以使用多种市价类型进行委托。
注意:该函数仅在股票交易模块可用。
上面几个在handle_data中使用的下单函数,都是无法指定价格的,limit_price 只是用于限价,比如你要卖1000股,limit_price的作用是不要把价格卖出你的目标,至于多少卖,是无法控制的。
但是有一个tick_data函数,专门用于行情交易的,里面可调用的函数也很少。
tick_data(可选)里面下单,用的下单函数是
tick_data(context, data)
该函数会每隔3秒执行一次。
注意 :
该函数仅在交易模块可用。
该函数在9:30之后才能执行。
该函数中只能使用order_tick进行对应的下单操作。
order_tick - tick行情触发买卖
order_tick(sid, amount, priceGear='1', limit_price=None)
买卖股票下单,可设定价格档位进行委托
注意:该函数仅在交易模块可用。
参数
sid:股票代码(str);
amount:交易数量,正数表示买入,负数表示卖出(int)
priceGear:盘口档位,level1:1~5买档/-1~-5卖档,level2:1~10买档/-1~-10卖档(str)
limit_price:买卖限价,当输入参数中也包含priceGear时,下单价格以limit_price为主(float);
注意到里面:
limit_price:买卖限价,当输入参数中也包含priceGear时,下单价格以limit_price为主
发现这里面居然可以定义价格下单,所以如果一定要指定价格,就需要使用tick_data 触发。
使用代码:
def initialize(context):
g.security = "600570.SS"
set_universe(g.security)
def tick_data(context,data):
security = g.security
current_price = eval(data[security]['tick']['bid_grp'][0])[1][0]
if current_price > 56 and current_price < 57:
# 以买一档下单
order_tick(g.security, -100, "1")
# 以卖二档下单
order_tick(g.security, 100, "-2")
# 以指定价格下单
order_tick(g.security, 100, limit_price=56.5)
def handle_data(context, data):
pass
ptrade每天自动打新 (新股和可转债)附python代码
量化交易 • 李魔佛 发表了文章 • 0 个评论 • 187 次浏览 • 2022-07-28 11:10
def initialize(context):
g.flag = False
log.info("initialize g.flag=" + str(g.flag) )
def before_trading_start(context, data):
g.flag = False
log.info("before_trading_start g.flag=" + str(g.flag) )
def handle_data(context, data):
if not g.flag and time.strftime("%H:%M:%S", time.localtime()) > '09:35:00':
# 自动打新
log.info("自动打新")
ipo_stocks_order()
g.flag = True
def on_order_response(context, order_list):
# 该函数会在委托回报返回时响应
log.info(order_list)
交易页面
程序运行返回代码:
点击查看大图
【如果没有打新额度或者没有开通对应的权限,会显示可收购为0】
底下的成功的是可转债申购成功。
然后可以到券商app上看看是否已经有自动申购成功的记录。 查看全部
import time
def initialize(context):
g.flag = False
log.info("initialize g.flag=" + str(g.flag) )
def before_trading_start(context, data):
g.flag = False
log.info("before_trading_start g.flag=" + str(g.flag) )
def handle_data(context, data):
if not g.flag and time.strftime("%H:%M:%S", time.localtime()) > '09:35:00':
# 自动打新
log.info("自动打新")
ipo_stocks_order()
g.flag = True
def on_order_response(context, order_list):
# 该函数会在委托回报返回时响应
log.info(order_list)
交易页面
程序运行返回代码:
点击查看大图
【如果没有打新额度或者没有开通对应的权限,会显示可收购为0】
底下的成功的是可转债申购成功。
然后可以到券商app上看看是否已经有自动申购成功的记录。
ptrade回测和实盘支持可转债日内tick/分时吗?
可转债 • 李魔佛 发表了文章 • 0 个评论 • 175 次浏览 • 2022-07-25 07:19
比如下面的部分代码片段,是用于导出可转债的日内分时数据的。最低颗粒,按照一分钟k线获取。 ptrade里面能够获取到的最小频率单位。
def initialize(context):
# 初始化策略
g.code_mapper = date_code_mapper()
log.info(g.code_mapper)
g.error_set=set()
def last_n_day(date,n,origin_fmt,target_fmt):
return (datetime.datetime.strptime(date, origin_fmt) - datetime.timedelta(days=n)).strftime(target_fmt)
def post_fix(code):
return code + '.SZ' if code.startswith('12') else code + '.SS'
def handle_data(context, data):
date=context.blotter.current_dt.strftime('%Y%m%d')
if date not in g.code_mapper:
return
security_list=g.code_mapper.get(date)
for code in security_list:
code=post_fix(code)
try:
df = get_history(1, frequency='1m', field=['open' ,'high','low','close'], security_list=code, fq='pre',include=False)
except Exception as e:
if code not in g.error_set:
log.info(e)
log.info('代码获取数据 出错{}'.format(code))
g.error_set.add(code)
continue
df['ticker']=code
g.result.append(df)
def after_trading_end(context, data):
#engine = DBS
db = DBSelector()
conn = db.get_engine()
date=context.blotter.current_dt.strftime('%Y%m%d%H%M')
if len(g.result)==0:
return
df = pd.concat(g.result)
try:
df.to_sql('minute_info',con=conn,if_exists='append')
except Exception as e:
log.info(e)
g.result=
def before_trading_start(context, data):
g.result=
然后在handle_data里面加入相关的order就可以交易了。(上面的代码主要是保存tick/分时数据到mysql,实际并没有进行交易。) 查看全部
比如下面的部分代码片段,是用于导出可转债的日内分时数据的。最低颗粒,按照一分钟k线获取。 ptrade里面能够获取到的最小频率单位。
def initialize(context):
# 初始化策略
g.code_mapper = date_code_mapper()
log.info(g.code_mapper)
g.error_set=set()
def last_n_day(date,n,origin_fmt,target_fmt):
return (datetime.datetime.strptime(date, origin_fmt) - datetime.timedelta(days=n)).strftime(target_fmt)
def post_fix(code):
return code + '.SZ' if code.startswith('12') else code + '.SS'
def handle_data(context, data):
date=context.blotter.current_dt.strftime('%Y%m%d')
if date not in g.code_mapper:
return
security_list=g.code_mapper.get(date)
for code in security_list:
code=post_fix(code)
try:
df = get_history(1, frequency='1m', field=['open' ,'high','low','close'], security_list=code, fq='pre',include=False)
except Exception as e:
if code not in g.error_set:
log.info(e)
log.info('代码获取数据 出错{}'.format(code))
g.error_set.add(code)
continue
df['ticker']=code
g.result.append(df)
def after_trading_end(context, data):
#engine = DBS
db = DBSelector()
conn = db.get_engine()
date=context.blotter.current_dt.strftime('%Y%m%d%H%M')
if len(g.result)==0:
return
df = pd.concat(g.result)
try:
df.to_sql('minute_info',con=conn,if_exists='append')
except Exception as e:
log.info(e)
g.result=
def before_trading_start(context, data):
g.result=
然后在handle_data里面加入相关的order就可以交易了。(上面的代码主要是保存tick/分时数据到mysql,实际并没有进行交易。)
ptrade的run_interval定时执行或者handle_data周期运行
量化交易 • 李魔佛 发表了文章 • 0 个评论 • 190 次浏览 • 2022-07-11 11:04
可以知道,他们是通过多线程触发的。 每一次运行的线程名字都不一样。
所以在里面操作一些共享变量的时候,最好加锁操作。
比如:
def query_offset(self,start,count):
sqlite_str = 'select code,open,current from {} limit {},{}'.format(self.table_name,start,count)
cursor = self.db.cursor()
with lock:
try:
cursor.execute(sqlite_str)
except Exception as e:
log.info(e)
self.db.rollback()
else:
return cursor.fetchall() 查看全部
可以知道,他们是通过多线程触发的。 每一次运行的线程名字都不一样。
所以在里面操作一些共享变量的时候,最好加锁操作。
比如:
def query_offset(self,start,count):
sqlite_str = 'select code,open,current from {} limit {},{}'.format(self.table_name,start,count)
cursor = self.db.cursor()
with lock:
try:
cursor.execute(sqlite_str)
except Exception as e:
log.info(e)
self.db.rollback()
else:
return cursor.fetchall()
低门槛开通量化交易接口Ptrade QMT (入金1万即可,AA级大券商)
券商万一免五 • 海螺复盘 发表了文章 • 0 个评论 • 676 次浏览 • 2022-07-06 00:24
该券商为AA级券商,GJ证券,腾讯入股的A股券商
该券商营业部最近对量化交易软件推广期,对开通门槛做了大幅降低, 目前只需要入金1W,既可以开通量化交易接口与软件,有Ptrade和QMT两个。 二者支持python语言编写策略,支持tick,分钟线,日线,等级别的实盘交易。
Ptrade为云端部署,QMT为本地部署(你的策略只会放着本地,使用本地python运行)
该QMT支持虚拟机内运行,也就是可以在云主机(腾讯云,阿里云这些服务器上)运行。
目前开通门槛低,时间有限,需要的朋友抓紧时间开通,过了这个时间就没有下次机会了。
交易费率: 量化没有流量费。(针对该营业部开户用户)
股票万一
可转债(新规) 沪:十万分之四点四,深:十万分之四
基金:万0.5
没有流量费
需要的朋友可以加微信咨询开通:备注开户
查看全部
该券商为AA级券商,GJ证券,腾讯入股的A股券商
该券商营业部最近对量化交易软件推广期,对开通门槛做了大幅降低, 目前只需要入金1W,既可以开通量化交易接口与软件,有Ptrade和QMT两个。 二者支持python语言编写策略,支持tick,分钟线,日线,等级别的实盘交易。

Ptrade为云端部署,QMT为本地部署(你的策略只会放着本地,使用本地python运行)
该QMT支持虚拟机内运行,也就是可以在云主机(腾讯云,阿里云这些服务器上)运行。
目前开通门槛低,时间有限,需要的朋友抓紧时间开通,过了这个时间就没有下次机会了。
交易费率: 量化没有流量费。(针对该营业部开户用户)
股票万一
可转债(新规) 沪:十万分之四点四,深:十万分之四
基金:万0.5
没有流量费
需要的朋友可以加微信咨询开通:备注开户

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

开通券商账户后可以 可以先试用,再考虑是否开通量化接口权限
Ptrade下单接口 order,order_target, order_value,order_target_value的区别
量化交易 • 李魔佛 发表了文章 • 0 个评论 • 54 次浏览 • 2022-08-11 23:57
接口
order_value 接口通过 金额/限价 或者 金额/默认最新价 两种方式转换成需要交易的数量,
传入 order 接口
order_target_value 接口通过持仓金额比较得到需要交易的金额, 金额/限价 或者 金额/默
认最新价 两种方式转换成需要交易的数量,传入 order 接口
所以其他几个接口都是对order的封装。
order接口的逻辑:
order 接口:
一、
先判断 limit_price 是否传入,传入则用传入价格限价,不传入则最新价代替,都是
限价方式报单。
二、
判断隔夜单和交易时间,交易时间(9:10(系统可配)~15:00)范围的订单会马上
加入未处理订单队列,其他订单先放到一个队列,等时间到交易时间就放到未处理订单
队列
三、
未处理订单队列的订单会进行限价判断,如果没有传入限价就按当前最新价处理,
然后报柜台
查看全部
order_target 接口通过持仓数量比较将入参的目标数量转换成需要交易的成交,传入 order
接口
order_value 接口通过 金额/限价 或者 金额/默认最新价 两种方式转换成需要交易的数量,
传入 order 接口
order_target_value 接口通过持仓金额比较得到需要交易的金额, 金额/限价 或者 金额/默
认最新价 两种方式转换成需要交易的数量,传入 order 接口
所以其他几个接口都是对order的封装。
order接口的逻辑:
order 接口:
一、
先判断 limit_price 是否传入,传入则用传入价格限价,不传入则最新价代替,都是
限价方式报单。
二、
判断隔夜单和交易时间,交易时间(9:10(系统可配)~15:00)范围的订单会马上
加入未处理订单队列,其他订单先放到一个队列,等时间到交易时间就放到未处理订单
队列
三、
未处理订单队列的订单会进行限价判断,如果没有传入限价就按当前最新价处理,
然后报柜台
Ptrade抢新上市的可转债
量化交易 • 李魔佛 发表了文章 • 0 个评论 • 61 次浏览 • 2022-08-11 10:20
PS: 也不是每一只都是去抢,还是需要提前判断下。规模小的优先。
自己写的包在 PTrade 里如何使用的方法有吗?
量化交易 • 李魔佛 发表了文章 • 0 个评论 • 68 次浏览 • 2022-08-08 03:28
A:和常规 Python 函数调用时一样的,只是需要和你的其它函数放在同一个脚本
中,暂时不支持跨越脚本文件的调用。
所以你写的包,都要放着ptrade的策略里面,不能另外保存到一个地方,然后通过 from xxxx import xxxx 这种方式导入。
所以有时候你的ptrade文件会臃肿无比。经常复制粘贴。也是无奈之举。 查看全部
A:和常规 Python 函数调用时一样的,只是需要和你的其它函数放在同一个脚本
中,暂时不支持跨越脚本文件的调用。
所以你写的包,都要放着ptrade的策略里面,不能另外保存到一个地方,然后通过 from xxxx import xxxx 这种方式导入。
所以有时候你的ptrade文件会臃肿无比。经常复制粘贴。也是无奈之举。
ptrade支持文件的读写吗,Excel 文件可以读写吗
量化交易 • 李魔佛 发表了文章 • 0 个评论 • 55 次浏览 • 2022-08-08 00:01
当前支持 csv,xlsx,txt,pkl 等文件的读取,需要手动将对应文件上传到研究环境中,
然后在回测中使用 get_research_path()+”文件名”获取文件路径后进行读取(见下图),
回写文件类似,可使用 pd.to_csv()等函数存储在研究环境指定目录下。
值得注意的是,当前支持单个文件最大为 50M
模型每天都会更新的,权重文件,能上传吗?
可以,注意文件大小的限制。
查看全部
ptrade策略代码:集合竞价追涨停策略
量化交易 • 李魔佛 发表了文章 • 0 个评论 • 103 次浏览 • 2022-08-04 15:24
# 初始化此策略
# 设置我们要操作的股票池, 这里我们只操作一支股票
g.security = '600570.SS'
set_universe(g.security)
#每天9:23分运行集合竞价处理函数
run_daily(context, aggregate_auction_func, time='9:23')
def aggregate_auction_func(context):
stock = g.security
#最新价
snapshot = get_snapshot(stock)
price = snapshot[stock]['last_px']
#涨停价
up_limit = snapshot[stock]['up_px']
#如果最新价不小于涨停价,买入
if float(price) >= float(up_limit):
order(g.security, 100, limit_price=up_limit)
def handle_data(context, data):
pass
分解讲解:def initialize(context):
# 初始化此策略
# 设置我们要操作的股票池, 这里我们只操作一支股票
g.security = '600570.SS'
set_universe(g.security)
#每天9:23分运行集合竞价处理函数
run_daily(context, aggregate_auction_func, time='9:23')
initialize是初始化函数,一定要有的函数。在策略运行时首先运行的,而且只会运行一次。
set_universe(g.security) 在把标的代码放进去。这里是 '600570.SS' 记得要有后缀,上证股票用 .SS ,深圳股票用.SZ。
run_daily(context, aggregate_auction_func, time='9:23')
这一行是设定每天运行一次。这个策略是日线级别的,所以每天只要运行一次就可以了。 分别传入3个参数。
第一个参数固定是context,第二个要执行的函数名,记住只能传函数名,不能把括号也加进去,第三个参数,是运行的时间,现在设定在 9:23
那么接下来就是要实现上面那个函数名了: aggregate_auction_func,这个名字可以随意定义
def aggregate_auction_func(context):
stock = g.security
#最新价
snapshot = get_snapshot(stock)
price = snapshot[stock]['last_px']
#涨停价
up_limit = snapshot[stock]['up_px']
#如果最新价不小于涨停价,买入
if float(price) >= float(up_limit):
order(g.security, 100, limit_price=up_limit)
stock = g.security , g是全局变量,用来在上下文中传递数据。这里就是上面的'600570.SS'
snapshot = get_snapshot(stock)
这个就是获取行情数据,当前的价格
up_limit = snapshot[stock]['up_px']
拿到这个标的的涨停价
if float(price) >= float(up_limit):
这个是当前价格大于涨停板价格(主要考虑了四舍五入,用于大号比较安全)
order(g.security, 100, limit_price=up_limit)
这个就是下单函数。
买入100股,不限价,市价成交。
然后就可以点击运行交易。
程序每天都会自动交易。
查看全部
def initialize(context):
# 初始化此策略
# 设置我们要操作的股票池, 这里我们只操作一支股票
g.security = '600570.SS'
set_universe(g.security)
#每天9:23分运行集合竞价处理函数
run_daily(context, aggregate_auction_func, time='9:23')
def aggregate_auction_func(context):
stock = g.security
#最新价
snapshot = get_snapshot(stock)
price = snapshot[stock]['last_px']
#涨停价
up_limit = snapshot[stock]['up_px']
#如果最新价不小于涨停价,买入
if float(price) >= float(up_limit):
order(g.security, 100, limit_price=up_limit)
def handle_data(context, data):
pass
分解讲解:
def initialize(context):
# 初始化此策略
# 设置我们要操作的股票池, 这里我们只操作一支股票
g.security = '600570.SS'
set_universe(g.security)
#每天9:23分运行集合竞价处理函数
run_daily(context, aggregate_auction_func, time='9:23')
initialize是初始化函数,一定要有的函数。在策略运行时首先运行的,而且只会运行一次。
set_universe(g.security) 在把标的代码放进去。这里是 '600570.SS' 记得要有后缀,上证股票用 .SS ,深圳股票用.SZ。
run_daily(context, aggregate_auction_func, time='9:23')
这一行是设定每天运行一次。这个策略是日线级别的,所以每天只要运行一次就可以了。 分别传入3个参数。
第一个参数固定是context,第二个要执行的函数名,记住只能传函数名,不能把括号也加进去,第三个参数,是运行的时间,现在设定在 9:23
那么接下来就是要实现上面那个函数名了: aggregate_auction_func,这个名字可以随意定义
def aggregate_auction_func(context):
stock = g.security
#最新价
snapshot = get_snapshot(stock)
price = snapshot[stock]['last_px']
#涨停价
up_limit = snapshot[stock]['up_px']
#如果最新价不小于涨停价,买入
if float(price) >= float(up_limit):
order(g.security, 100, limit_price=up_limit)
stock = g.security , g是全局变量,用来在上下文中传递数据。这里就是上面的'600570.SS'
snapshot = get_snapshot(stock)
这个就是获取行情数据,当前的价格
up_limit = snapshot[stock]['up_px']
拿到这个标的的涨停价
if float(price) >= float(up_limit):
这个是当前价格大于涨停板价格(主要考虑了四舍五入,用于大号比较安全)
order(g.security, 100, limit_price=up_limit)
这个就是下单函数。
买入100股,不限价,市价成交。
然后就可以点击运行交易。
程序每天都会自动交易。
ptrade可以同时执行多少个实盘策略?
量化交易 • 李魔佛 发表了文章 • 0 个评论 • 104 次浏览 • 2022-08-02 20:41
而在代码里面,如果多个策略同时运行,需要在代码层面区分不同策略下的单子,不然会造成冲突。比如你第一个策略下的单子,被第二个策略清仓了。
那么要如何区分不同策略下单呢?
1. 如果是日内策略,只需要用一个字典dict,记录每次买入记录,每次的卖出标的都要在dict里面。
2. 持久化。虽然大部分券商的ptrade都不支持联网,但是,可以使用本地持久化,pickle或者sqlite。保存在云本地。 查看全部
ptrade如何以指定价格下单?
量化交易 • 李魔佛 发表了文章 • 0 个评论 • 108 次浏览 • 2022-07-30 19:27
order函数:order-按数量买卖
order(security, amount, limit_price=None)
买卖标的。
注意:
由于下述原因,回测中实际买入或者卖出的股票数量有时候可能与委托设置的不一样,针对上述内容调整,系统会在日志中增加警告信息:
根据委托买入数量与价格经计算后的资金数量,大于当前可用资金;
委托卖出数量大于当前可用持仓数量;
每次交易数量只能是100的整数倍,但是卖出所有股票时不受此限制;
股票停牌、股票未上市或者退市、股票不存在;
回测中每天结束时会取消所有未完成交易;
order_target - 函数order_target(security, amount, limit_price=None)
买卖股票,直到股票最终数量达到指定的amount。
注意:该函数在委托股票时取整100股,委托可转债时取整100张。
参数
security: 股票代码(str);
amount: 期望的最终数量(int);
limit_price:买卖限价(float);
返回
Order对象中的id或者None。如果创建订单成功,则返回Order对象的id,失败则返回None(str)。
order_value 函数order_value - 指定目标价值买卖
order_value(security, value, limit_price=None)
买卖指定价值为value的股票。
注意:该函数在委托股票时取整100股,委托可转债时取整100张。
order_target_value - 函数order_target_value - 指定持仓市值买卖
order_target_value(security, value, limit_price=None)
调整股票仓位到value价值
注意:该函数在委托股票时取整100股,委托可转债时取整100张。
order_market 函数order_market - 按市价进行委托
order_market(security, amount, market_type=None, limit_price=None)
可以使用多种市价类型进行委托。
注意:该函数仅在股票交易模块可用。
上面几个在handle_data中使用的下单函数,都是无法指定价格的,limit_price 只是用于限价,比如你要卖1000股,limit_price的作用是不要把价格卖出你的目标,至于多少卖,是无法控制的。
但是有一个tick_data函数,专门用于行情交易的,里面可调用的函数也很少。tick_data(可选)
tick_data(context, data)
该函数会每隔3秒执行一次。
注意 :
该函数仅在交易模块可用。
该函数在9:30之后才能执行。
该函数中只能使用order_tick进行对应的下单操作。里面下单,用的下单函数是
order_tick - tick行情触发买卖
order_tick(sid, amount, priceGear='1', limit_price=None)
买卖股票下单,可设定价格档位进行委托
注意:该函数仅在交易模块可用。
参数
sid:股票代码(str);
amount:交易数量,正数表示买入,负数表示卖出(int)
priceGear:盘口档位,level1:1~5买档/-1~-5卖档,level2:1~10买档/-1~-10卖档(str)
limit_price:买卖限价,当输入参数中也包含priceGear时,下单价格以limit_price为主(float);
注意到里面:
limit_price:买卖限价,当输入参数中也包含priceGear时,下单价格以limit_price为主
发现这里面居然可以定义价格下单,所以如果一定要指定价格,就需要使用tick_data 触发。
使用代码:
def initialize(context):
g.security = "600570.SS"
set_universe(g.security)
def tick_data(context,data):
security = g.security
current_price = eval(data[security]['tick']['bid_grp'][0])[1][0]
if current_price > 56 and current_price < 57:
# 以买一档下单
order_tick(g.security, -100, "1")
# 以卖二档下单
order_tick(g.security, 100, "-2")
# 以指定价格下单
order_tick(g.security, 100, limit_price=56.5)
def handle_data(context, data):
pass 查看全部
order函数:
order-按数量买卖
order(security, amount, limit_price=None)
买卖标的。
注意:
由于下述原因,回测中实际买入或者卖出的股票数量有时候可能与委托设置的不一样,针对上述内容调整,系统会在日志中增加警告信息:
根据委托买入数量与价格经计算后的资金数量,大于当前可用资金;
委托卖出数量大于当前可用持仓数量;
每次交易数量只能是100的整数倍,但是卖出所有股票时不受此限制;
股票停牌、股票未上市或者退市、股票不存在;
回测中每天结束时会取消所有未完成交易;
order_target - 函数
order_target(security, amount, limit_price=None)
买卖股票,直到股票最终数量达到指定的amount。
注意:该函数在委托股票时取整100股,委托可转债时取整100张。
参数
security: 股票代码(str);
amount: 期望的最终数量(int);
limit_price:买卖限价(float);
返回
Order对象中的id或者None。如果创建订单成功,则返回Order对象的id,失败则返回None(str)。
order_value 函数
order_value - 指定目标价值买卖
order_value(security, value, limit_price=None)
买卖指定价值为value的股票。
注意:该函数在委托股票时取整100股,委托可转债时取整100张。
order_target_value - 函数
order_target_value - 指定持仓市值买卖
order_target_value(security, value, limit_price=None)
调整股票仓位到value价值
注意:该函数在委托股票时取整100股,委托可转债时取整100张。
order_market 函数
order_market - 按市价进行委托
order_market(security, amount, market_type=None, limit_price=None)
可以使用多种市价类型进行委托。
注意:该函数仅在股票交易模块可用。
上面几个在handle_data中使用的下单函数,都是无法指定价格的,limit_price 只是用于限价,比如你要卖1000股,limit_price的作用是不要把价格卖出你的目标,至于多少卖,是无法控制的。
但是有一个tick_data函数,专门用于行情交易的,里面可调用的函数也很少。
tick_data(可选)里面下单,用的下单函数是
tick_data(context, data)
该函数会每隔3秒执行一次。
注意 :
该函数仅在交易模块可用。
该函数在9:30之后才能执行。
该函数中只能使用order_tick进行对应的下单操作。
order_tick - tick行情触发买卖
order_tick(sid, amount, priceGear='1', limit_price=None)
买卖股票下单,可设定价格档位进行委托
注意:该函数仅在交易模块可用。
参数
sid:股票代码(str);
amount:交易数量,正数表示买入,负数表示卖出(int)
priceGear:盘口档位,level1:1~5买档/-1~-5卖档,level2:1~10买档/-1~-10卖档(str)
limit_price:买卖限价,当输入参数中也包含priceGear时,下单价格以limit_price为主(float);
注意到里面:
limit_price:买卖限价,当输入参数中也包含priceGear时,下单价格以limit_price为主
发现这里面居然可以定义价格下单,所以如果一定要指定价格,就需要使用tick_data 触发。
使用代码:
def initialize(context):
g.security = "600570.SS"
set_universe(g.security)
def tick_data(context,data):
security = g.security
current_price = eval(data[security]['tick']['bid_grp'][0])[1][0]
if current_price > 56 and current_price < 57:
# 以买一档下单
order_tick(g.security, -100, "1")
# 以卖二档下单
order_tick(g.security, 100, "-2")
# 以指定价格下单
order_tick(g.security, 100, limit_price=56.5)
def handle_data(context, data):
pass
ptrade每天自动打新 (新股和可转债)附python代码
量化交易 • 李魔佛 发表了文章 • 0 个评论 • 187 次浏览 • 2022-07-28 11:10
def initialize(context):
g.flag = False
log.info("initialize g.flag=" + str(g.flag) )
def before_trading_start(context, data):
g.flag = False
log.info("before_trading_start g.flag=" + str(g.flag) )
def handle_data(context, data):
if not g.flag and time.strftime("%H:%M:%S", time.localtime()) > '09:35:00':
# 自动打新
log.info("自动打新")
ipo_stocks_order()
g.flag = True
def on_order_response(context, order_list):
# 该函数会在委托回报返回时响应
log.info(order_list)
交易页面
程序运行返回代码:
点击查看大图
【如果没有打新额度或者没有开通对应的权限,会显示可收购为0】
底下的成功的是可转债申购成功。
然后可以到券商app上看看是否已经有自动申购成功的记录。 查看全部
import time
def initialize(context):
g.flag = False
log.info("initialize g.flag=" + str(g.flag) )
def before_trading_start(context, data):
g.flag = False
log.info("before_trading_start g.flag=" + str(g.flag) )
def handle_data(context, data):
if not g.flag and time.strftime("%H:%M:%S", time.localtime()) > '09:35:00':
# 自动打新
log.info("自动打新")
ipo_stocks_order()
g.flag = True
def on_order_response(context, order_list):
# 该函数会在委托回报返回时响应
log.info(order_list)
交易页面
程序运行返回代码:
点击查看大图
【如果没有打新额度或者没有开通对应的权限,会显示可收购为0】
底下的成功的是可转债申购成功。
然后可以到券商app上看看是否已经有自动申购成功的记录。
ptrade回测和实盘支持可转债日内tick/分时吗?
可转债 • 李魔佛 发表了文章 • 0 个评论 • 175 次浏览 • 2022-07-25 07:19
比如下面的部分代码片段,是用于导出可转债的日内分时数据的。最低颗粒,按照一分钟k线获取。 ptrade里面能够获取到的最小频率单位。
def initialize(context):
# 初始化策略
g.code_mapper = date_code_mapper()
log.info(g.code_mapper)
g.error_set=set()
def last_n_day(date,n,origin_fmt,target_fmt):
return (datetime.datetime.strptime(date, origin_fmt) - datetime.timedelta(days=n)).strftime(target_fmt)
def post_fix(code):
return code + '.SZ' if code.startswith('12') else code + '.SS'
def handle_data(context, data):
date=context.blotter.current_dt.strftime('%Y%m%d')
if date not in g.code_mapper:
return
security_list=g.code_mapper.get(date)
for code in security_list:
code=post_fix(code)
try:
df = get_history(1, frequency='1m', field=['open' ,'high','low','close'], security_list=code, fq='pre',include=False)
except Exception as e:
if code not in g.error_set:
log.info(e)
log.info('代码获取数据 出错{}'.format(code))
g.error_set.add(code)
continue
df['ticker']=code
g.result.append(df)
def after_trading_end(context, data):
#engine = DBS
db = DBSelector()
conn = db.get_engine()
date=context.blotter.current_dt.strftime('%Y%m%d%H%M')
if len(g.result)==0:
return
df = pd.concat(g.result)
try:
df.to_sql('minute_info',con=conn,if_exists='append')
except Exception as e:
log.info(e)
g.result=
def before_trading_start(context, data):
g.result=
然后在handle_data里面加入相关的order就可以交易了。(上面的代码主要是保存tick/分时数据到mysql,实际并没有进行交易。) 查看全部
比如下面的部分代码片段,是用于导出可转债的日内分时数据的。最低颗粒,按照一分钟k线获取。 ptrade里面能够获取到的最小频率单位。
def initialize(context):
# 初始化策略
g.code_mapper = date_code_mapper()
log.info(g.code_mapper)
g.error_set=set()
def last_n_day(date,n,origin_fmt,target_fmt):
return (datetime.datetime.strptime(date, origin_fmt) - datetime.timedelta(days=n)).strftime(target_fmt)
def post_fix(code):
return code + '.SZ' if code.startswith('12') else code + '.SS'
def handle_data(context, data):
date=context.blotter.current_dt.strftime('%Y%m%d')
if date not in g.code_mapper:
return
security_list=g.code_mapper.get(date)
for code in security_list:
code=post_fix(code)
try:
df = get_history(1, frequency='1m', field=['open' ,'high','low','close'], security_list=code, fq='pre',include=False)
except Exception as e:
if code not in g.error_set:
log.info(e)
log.info('代码获取数据 出错{}'.format(code))
g.error_set.add(code)
continue
df['ticker']=code
g.result.append(df)
def after_trading_end(context, data):
#engine = DBS
db = DBSelector()
conn = db.get_engine()
date=context.blotter.current_dt.strftime('%Y%m%d%H%M')
if len(g.result)==0:
return
df = pd.concat(g.result)
try:
df.to_sql('minute_info',con=conn,if_exists='append')
except Exception as e:
log.info(e)
g.result=
def before_trading_start(context, data):
g.result=
然后在handle_data里面加入相关的order就可以交易了。(上面的代码主要是保存tick/分时数据到mysql,实际并没有进行交易。)
ptrade的run_interval定时执行或者handle_data周期运行
量化交易 • 李魔佛 发表了文章 • 0 个评论 • 190 次浏览 • 2022-07-11 11:04
可以知道,他们是通过多线程触发的。 每一次运行的线程名字都不一样。
所以在里面操作一些共享变量的时候,最好加锁操作。
比如:
def query_offset(self,start,count):
sqlite_str = 'select code,open,current from {} limit {},{}'.format(self.table_name,start,count)
cursor = self.db.cursor()
with lock:
try:
cursor.execute(sqlite_str)
except Exception as e:
log.info(e)
self.db.rollback()
else:
return cursor.fetchall() 查看全部
可以知道,他们是通过多线程触发的。 每一次运行的线程名字都不一样。
所以在里面操作一些共享变量的时候,最好加锁操作。
比如:
def query_offset(self,start,count):
sqlite_str = 'select code,open,current from {} limit {},{}'.format(self.table_name,start,count)
cursor = self.db.cursor()
with lock:
try:
cursor.execute(sqlite_str)
except Exception as e:
log.info(e)
self.db.rollback()
else:
return cursor.fetchall()
低门槛开通量化交易接口Ptrade QMT (入金1万即可,AA级大券商)
券商万一免五 • 海螺复盘 发表了文章 • 0 个评论 • 676 次浏览 • 2022-07-06 00:24
该券商为AA级券商,GJ证券,腾讯入股的A股券商
该券商营业部最近对量化交易软件推广期,对开通门槛做了大幅降低, 目前只需要入金1W,既可以开通量化交易接口与软件,有Ptrade和QMT两个。 二者支持python语言编写策略,支持tick,分钟线,日线,等级别的实盘交易。
Ptrade为云端部署,QMT为本地部署(你的策略只会放着本地,使用本地python运行)
该QMT支持虚拟机内运行,也就是可以在云主机(腾讯云,阿里云这些服务器上)运行。
目前开通门槛低,时间有限,需要的朋友抓紧时间开通,过了这个时间就没有下次机会了。
交易费率: 量化没有流量费。(针对该营业部开户用户)
股票万一
可转债(新规) 沪:十万分之四点四,深:十万分之四
基金:万0.5
没有流量费
需要的朋友可以加微信咨询开通:备注开户
查看全部
该券商为AA级券商,GJ证券,腾讯入股的A股券商
该券商营业部最近对量化交易软件推广期,对开通门槛做了大幅降低, 目前只需要入金1W,既可以开通量化交易接口与软件,有Ptrade和QMT两个。 二者支持python语言编写策略,支持tick,分钟线,日线,等级别的实盘交易。

Ptrade为云端部署,QMT为本地部署(你的策略只会放着本地,使用本地python运行)
该QMT支持虚拟机内运行,也就是可以在云主机(腾讯云,阿里云这些服务器上)运行。
目前开通门槛低,时间有限,需要的朋友抓紧时间开通,过了这个时间就没有下次机会了。
交易费率: 量化没有流量费。(针对该营业部开户用户)
股票万一
可转债(新规) 沪:十万分之四点四,深:十万分之四
基金:万0.5
没有流量费
需要的朋友可以加微信咨询开通:备注开户

重启ptrade策略会重新载入修改的代码吗?
量化交易 • 李魔佛 发表了文章 • 0 个评论 • 199 次浏览 • 2022-07-05 11:06
这个是方便你修改了代码,不用重新新建策略,重启一下,原来旧代码就会被覆盖的。
ptrade用的python版本?
量化交易 • 李魔佛 发表了文章 • 0 个评论 • 260 次浏览 • 2022-06-25 17:58
而print的f-string也是无法导入的,导入报错,而f-string是从python3.6引入的。
所以ptrade内置的 python版本是低于3.6的,所以一些关键字async 也是无法使用的,
查看全部
获取可转债历史分时tick数据 【python】
可转债 • 李魔佛 发表了文章 • 0 个评论 • 382 次浏览 • 2022-06-25 12:29
对于想做日内回测的朋友,是一件很痛苦的事情。
那么,接下来,本文结束一种通过第三方平台的数据,来把可转债的分时tick数据获取下来,并保存到本地数据库。
2022-07-05 更新:
如果直接拿历史数据,可以拿到1分钟级别的数据,如上图所示。
如果要拿秒级别的,需要实时采集。
笔者使用sqlite做为内存缓存,盘后统一入到mysql中。
如果盘中每隔3秒使用mysql储存,显然会造成不必要的io阻塞(开个线程存数据也是一个方案)。
使用sqlite的时候,设置为memeory模式,速度比存文件要快很多倍。
待续 查看全部
对于想做日内回测的朋友,是一件很痛苦的事情。
那么,接下来,本文结束一种通过第三方平台的数据,来把可转债的分时tick数据获取下来,并保存到本地数据库。
2022-07-05 更新:
如果直接拿历史数据,可以拿到1分钟级别的数据,如上图所示。
如果要拿秒级别的,需要实时采集。
笔者使用sqlite做为内存缓存,盘后统一入到mysql中。
如果盘中每隔3秒使用mysql储存,显然会造成不必要的io阻塞(开个线程存数据也是一个方案)。
使用sqlite的时候,设置为memeory模式,速度比存文件要快很多倍。
待续
不同券商的ptrade的异同
量化交易 • 李魔佛 发表了文章 • 0 个评论 • 482 次浏览 • 2022-06-17 16:36
1. 湘财无法访问外网,国盛的可以
2.
get_cb_list 获取可转债列表 的 国盛没有
get_history 获取历史数据函数
get_history(5, frequency='1d', field='close', security_list=['123084.SZ'], fq=None, include=False, fill='nan')国盛是没有fill参数的。
持续更新。。。待续
Ptrade开户联系:
查看全部