老听说金字塔支持Python了,而且很牛X,一直想了解一下,就边学边玩,写了一个网格交易的策略,经过验证,还不错,金字塔的Python版用于算法交易还是可以,从交易下单,到成交过程订单状态的回报,都很准确。
相对于VBA使用对象的方式来调用,Python更直观,简洁。
需要增强的地方(可能我还没学会):
1、希望增加对INI文件读写的功能,我使用import ConfigParser不支持
2、希望增加对界面方面的支持,Python有支持图形的库
--------------------------------------------------------------
# 本Python代码主要用于策略交易
# 可以自己import我们平台支持的第三方python模块,比如pandas、numpy等。
from PythonApi import *
import time
from decimal import Decimal
# 参数定义区,这里定义的参数可以直接在context对象中获取。--(选择实现)
#def parameter():
# input_par("myvalues1",5,1,20,1)
# input_par("myvalues2",10,1,20,1)
# 在这个方法中编写任何的初始化逻辑。context对象将会在你的算法策略的任何方法之间做传递。--(必须实现)
def init(context):
# 在context中保存全局变量
context.s1 = "ZQZC05" #动力煤
context.lastbuy=0 #末次买入开仓单号
context.lastsell=0 #末次卖出开仓单号
context.lastbuyping=0 #末次平多单单号
context.lastsellping=0 #末次平空单单号
context.jiange=1 #间隔
context.vol=1 #每档手数
context.firstvol=5 #初始手数
context.fx=1 #交易方向 1-多 2-空
context.price=561.2 #初始参考价
context.maxvol=8*context.vol #最大手数
settimer(GridTrade,2000) #2秒执行一次
print(context.s1+"策略启动") #调试打印输出
def setorderid(context):
#检查未成交订单,将单号赋值给全局变量,避免启动策略时变量的值为0
#print("获取未成交订单编号")
Orders=get_orders(context.s1,0) #取未成交单
context.lastbuy=0
context.lastbuyping=0
context.lastsell=0
context.lastsellping=0
if not(Orders == None):
for order in Orders:
orderID=order.order_id #委托单号
sBuySell=order.side #买卖
sKp=order.position_effect #开平
sStatus=order.status #状态
#print(str(orderID)+','+sBuySell+','+sKp+','+sStatus)
if context.lastbuy==0 and sBuySell=="buy" and sKp=="open" and sStatus=="submitted":
context.lastbuy=order.order_id #单号
if context.lastsell==0 and sBuySell=="sell" and sKp=="open" and sStatus=="submitted":
context.lastsell=order.order_id #单号
if context.lastbuyping==0 and sBuySell=="sell" and sKp=="close" and sStatus=="submitted":
context.lastbuyping=order.order_id #单号
if context.lastsellping==0 and sBuySell=="buy" and sKp=="close" and sStatus=="submitted":
context.lastsellping=order.order_id #单号
#print('开多:'+str(context.lastbuy)+',平多:'+str(context.lastbuyping)+',开空:'+str(context.lastsell)+',平空:'+str(context.lastsellping))
#网格交易主程序
def GridTrade(context):
if istradertime(context.s1)==False: #不在交易时间,不进入交易段
return
setorderid(context) #获取未成交订单号,保存到全局变量
nAmount=get_account(19) #可用资金
if nAmount<=10000:
print('账户可用资金低于10000了,退出交易。')
return
portfolio=get_portfolio(context.s1,0) #获取持仓量
if context.fx==1:
iDuoTotal=portfolio.buy_quantity
nCurOrdPrice = round(context.price - ((iDuoTotal -context.firstvol) * context.jiange) / context.vol, 1)
else:
iKongTotal=portfolio.sell_quantity
nCurOrdPrice = round(context.price - ((context.firstvol - iKongTotal) * context.jiange) / context.vol, 1)
#print('档位价:'+str(nCurOrdPrice)+',开多:'+str(context.lastbuy)+',平多:'+str(context.lastbuyping)+',开空:'+str(context.lastsell)+',平空:'+str(context.lastsellping))
nPrice=get_dynainf (context.s1,7) #获取最新价
if context.fx==1: #做多
if (context.lastbuy==0 and iDuoTotal<context.maxvol):
nOrdPrice=nCurOrdPrice-context.jiange
context.lastbuy=buy_open(context.s1,"Limit",nOrdPrice,context.vol)
print('档位价:'+str(nCurOrdPrice)+',委托价:'+str(nOrdPrice)+',开多')
if (context.lastbuyping==0 and iDuoTotal>0):
nOrdPrice=nCurOrdPrice+context.jiange
context.lastbuyping=sell_close(context.s1,"Limit",nOrdPrice,context.vol)
print('档位价:'+str(nCurOrdPrice)+',委托价:'+str(nOrdPrice)+',平多')
if context.fx==2 and iKongTotal<context.maxvol: #做空
if (context.lastsell==0):
nOrdPrice=nCurOrdPrice+context.jiange
context.lastsell=sell_open(context.s1,"Limit",nOrdPrice,context.vol)
print('档位价:'+str(nCurOrdPrice)+',委托价:'+str(nOrdPrice)+',开空')
if (context.lastsellping==0 and iKongTotal>0):
nOrdPrice=nCurOrdPrice-context.jiange
context.lastsellping=buy_close(context.s1,"Limit",nOrdPrice,context.vol)
print('档位价:'+str(nCurOrdPrice)+',委托价:'+str(nOrdPrice)+',平空')
# before_trading此函数会在每天基准合约的策略交易开始前被调用,当天只会被调用一次。--(选择实现)
def before_trading(context):
pass
# 你选择的品种的数据更新将会触发此段逻辑,例如日或分钟历史数据切片或者是实时数据切片更新。--(必须实现)
def handle_bar(context):
# 开始编写你的主要的算法逻辑。
pass
# after_trading函数会在每天交易结束后被调用,当天只会被调用一次。 --(选择实现)
def after_trading(context):
pass
# order_status当委托下单,成交,撤单等与下单有关的动作时,该方法就会被调用。---(选择实现)
def order_status(context,order):
#print('订单成交')
#print(order.order_book_id)
#print(str(order.order_id)+','+order.status+','+order.order_book_id)
#print('开多:'+str(context.lastbuy)+',平多:'+str(context.lastbuyping)+',开空:'+str(context.lastsell)+',平空:'+str(context.lastsellping))
#如果是成交,将对应的委托单撤销
if (order.status=="tradeing" and order.order_book_id==context.s1):
print(str(order.order_id)+'全部成交')
if order.order_id==context.lastbuy: #买入成交
if context.lastbuyping!=0:
cancel_order (context.lastbuyping)
print("买入成交之后撤平仓单,"+str(context.lastbuyping))
context.lastbuyping=0
if order.order_id==context.lastbuyping: #平多成交
if context.lastbuy!=0:
cancel_order (context.lastbuy)
print("平多成交之后撤开仓单,"+str(context.lastbuy))
context.lastbuy=0
if order.order_id==context.lastsell: #卖出成交
if context.lastsellping!=0:
cancel_order (context.lastsellping)
print("卖出成交之后撤平仓单,"+str(context.lastsellping))
context.lastsellping=0
if order.order_id==context.lastsellping: #平空成交
if context.lastsell!=0:
cancel_order (context.lastsell)
print("平空成交之后撤开仓单,"+str(context.lastsell))
context.lastsell=0
#如果是撤单,将对应的变量设置为0
if (order.status=="cancelled" and order.order_book_id==context.s1):
if order.order_id==context.lastbuy: #买入撤单
print("买入开仓撤单,"+str(context.lastbuy))
context.lastbuy=0
if order.order_id==context.lastbuyping: #平多撤单
print("平多单撤单,"+str(context.lastbuyping))
context.lastbuyping=0
if order.order_id==context.lastsell: #卖出撤单
print("卖出开仓撤单,"+str(context.lastsell))
context.lastsell=0
if order.order_id==context.lastsellping: #平空撤单
print("平空单撤单,"+str(context.lastsellping))
context.lastsellping=0
# order_action当查询交易接口信息时返回的通知---(选择实现)
#def order_action(context,type, account, datas)
# pass
# exit函数会在测评结束或者停止策略运行时会被调用。---(选择实现)
def exit(context):
killtimer(GridTrade) #终止计时器 |
|