https://quant.pobo.net.cn/forum-portal/
现在是免费注册的,!/usr/bin/env python
coding:utf-8
from PoboAPI import *
import datetime
import numpy as np'''
g.buy_flag的含义(g.sell_flag同理)
g.buy_flag = 0 #当前没有多头持仓
g.buy_flag = 1 #执行开多仓指令
g.buy_flag = 2 #买开订单已经提交
g.buy_flag = 3 #买开订单已经成交
g.buy_flag = 4 #执行平多仓指令
g.buy_flag = 5 #卖平订单已经提交
g.buy_flag = 6 #卖平订单已经成交
g.buy_flag = 8 #撤回平多仓并强制平仓
'''
'''
利用一个全局的字典进行多品种的转换
注意要把代码中大部分的g.code换成g.position_now
'''
variety_list = ['rb','ag','cu']用于检测交易合约是否变更
def contract_change(code = None):
if code == None: #进行初始化
code = []
for i in variety_list:
code.append(GetMainContract('SHFE',i,20))
return code
else:
for i in range(len(variety_list)):
if code[i] != GetMainContract('SHFE',variety_list[i],20):
return True #主力合约发生了变化
return False开始时间,用于初始化一些参数
def OnStart(context) :
print("I\'m starting...")#固定交易合约列表 g.code = contract_change() g.code_position = [] for i in g.code: g.code_position.append(i) g.position_now = None #用来记录当日交易的合约
context.myacc = None
if "回测期货" in context.accounts :
print("登录交易账号[回测期货]")
if context.accounts["回测期货"].Login() :
context.myacc = context.accounts["回测期货"]#订阅K线数据,用于驱动OnBar事件 SubscribeBar(g.code, BarType.Min3)
g.change_flag = 0
g.has_contract = 0
g.initial_flag = 0
g.cancel_time = 10 #10分钟未成交则撤单#设置闹铃,用于调用Onalarm事件 g.alarmid_openmarket = SetAlarm(datetime.time(10, 30),RepeatType.Daily)#开盘闹铃 g.alarmid_closemarket = SetAlarm(datetime.time(14, 59),RepeatType.Daily) #收盘闹铃
#设置价格最小变动单位 info = GetVarietyInfo('SHFE','rb') g.step_unit = info['最小变动价位']
def OnAlarm(context, alarmid):
if alarmid == g.alarmid_openmarket:
print("开盘闹铃")#设置部分交易参数 g.initial_flag = 1 #当前处于可交易状态 g.buy_flag = 0 #当前没有多头持仓或挂单 g.sell_flag = 0 #当前没有空头持仓或挂单 g.position_now = None elif alarmid == g.alarmid_closemarket: print("收盘闹铃") if g.initial_flag == 0: return g.initial_flag = 0 #14:59收盘后不再下单 if g.buy_flag == 3: #当前仍然有未平仓多头合约 print("当前仍有未平仓多头") data_now = GetQuote(g.position_now) g.buy_flag = 4 #变为多头平仓状态 #以现价减一个变动单位强制平多仓 position = context.myacc.GetPositions() volume = 0 for pos in position: volume += pos.volume QuickInsertOrder(context.myacc,g.position_now,'sell','close', data_now.bidprice(0) - 1*g.step_unit, volume) #平仓 if g.sell_flag == 3: #当前仍然有未平仓空头合约 print("当前仍有未平仓空头") data_now = GetQuote(g.position_now) g.sell_flag = 4 #变为空头平仓状态 #以现价加一个变动单位强制平空仓 position = context.myacc.GetPositions() volume = 0 for pos in position: volume += pos.volume QuickInsertOrder(context.myacc,g.position_now,'buy','close', data_now.askprice(0) + 1*g.step_unit, volume) #平仓 if g.buy_flag == 2: #当前仍有挂单中的多头合约 print("取消买开") context.myacc.CancelOrder(g.buy_open_id) g.buy_flag = 0 if g.sell_flag == 2: #当然仍有挂单中的空头合约 print("取消卖开") context.myacc.CancelOrder(g.sell_open_id) g.sell_flag = 0 if g.buy_flag == 5: #当前正在卖平但未成功交易 print("取消卖平并强平") g.buy_flag = 8 context.myacc.CancelOrder(g.sell_offset_id) if g.sell_flag == 5: #当前正在买平但未成功交易 print("取消买平并强平") g.sell_flag = 8 context.myacc.CancelOrder(g.buy_offset_id) g.position_now = None #当日所有交易完成,将当日交易合约重置为None
def OnMarketQuotationInitialEx(context, exchange,daynight):
if exchange != 'SHFE':
return#codel = GetMainContract('SHFE','rb',20)
Flag = contract_change(g.code) #检测当前的主力合约是否变动
if Flag:
g.change_flag = 1
UnsubscribeBar(g.code,BarType.Min3) #取消订阅原K线数据
g.code = contract_change() #变更合约
SubscribeBar(g.code, BarType.Min3) #订阅K线数据,用于驱动OnBar事件
print("当前交易合约为"+str(g.code))
else :
SubscribeBar(g.code, BarType.Min3)辅助函数,过滤掉datetime中的日期
def CutHour(time=datetime.datetime.now()):
new_time = str(time)
hour = new_time[11:19]
return "".join(hour)辅助函数,设置每天的开始日期
def start_time():
cutime = str(GetCurrentTime())
return datetime.datetime(int(cutime[0:4]),int(cutime[5:7]),int(cutime[8:10]),9,30,0)def Start_time():
cutime = str(GetCurrentTime())
return datetime.datetime(int(cutime[0:4]),int(cutime[5:7]),int(cutime[8:10]),10,15,0)实时行情事件,当有新行情出现时调用该事件Ex
def OnBar(context,code,bartype) :
#过滤掉不需要的行情通知 if code != g.code[0] and code != g.code[1] and code != g.code[2]: return #当已经买入某合约后,当天只能买卖该种合约 if g.position_now != None and code != g.position_now: return
#开盘前、收盘后不再进行交易 if g.initial_flag == 0: return if g.change_flag == 1: #换期时平掉之前的仓位 for i in g.code_position: QuickClosePosition(context.myacc,i,'buy', max_volume=-1, today_first=True) QuickClosePosition(context.myacc,i,'sell', max_volume=-1, today_first=True) g.change_flag = 0 g.code_position = [] for i in g.code: g.code_position.append(i) #获得当前时间,如果当前时间早于10点45,则不交易 time_now = CutHour(GetCurrentTime()) if time_now < "10:45:00" or time_now > "18:00:00": return #获取当天相关数据 dyndata = GetQuote(code) #if time_now <="11:00:00": df = GetHisDataAsDF(code,bar_type = BarType.Min3,start_date = start_time(), end_date = GetCurrentTime()) close_price = np.array(df["open"]) #多项式拟合 Y = close_price - np.mean(close_price) #去中心化处理,作为拟合用的因变量
X = np.linspace(1,len(Y),len(Y)) #拟合用的自变量
poly_1 = np.polyfit(X,Y,deg=1) #一阶拟合
poly_2 = np.polyfit(X,Y,deg=2) #二阶拟合if (time_now >= "10:57:00" and time_now <= "10:57:03") or (time_now >= "11:00:00" and time_now <= "11:00:03"): print(str(code)+"拟合结果:") print(poly_1,poly_2) #在可交易时间段中,且当天没有进行过交易 if (time_now >= "10:57:00" and time_now <= "10:57:03") or (time_now >= "11:00:00" and time_now <= "11:00:03") and g.has_contract == 0: #螺纹钢 if code == g.code[0] and poly_1[0]>0.5 and poly_2[0]>0.06: #加快增长趋势 g.buy_flag = 1 QuickInsertOrder(context.myacc,code,'buy','open', dyndata.now,200) #开多头 g.has_contract = 1 g.position_now = code #当前持仓为code print(str(code)+"多头加速,入场") elif code == g.code[0] and poly_1[0]<-0.5 and poly_2[0]<-0.06: #加快下跌趋势 g.sell_flag = 1 QuickInsertOrder(context.myacc,code,'sell','open', dyndata.now,200) #开空头 g.has_contract = 2 g.position_now = code #当前持仓为code print(str(code)+"空头加速,入场") #铜 elif code == g.code[2] and poly_1[0]>3 and poly_2[0]>0.04: #加快增长趋势 g.buy_flag = 1 QuickInsertOrder(context.myacc,code,'buy','open', dyndata.now,20) #开多头 g.has_contract = 1 g.position_now = code #当前持仓为code print(str(code)+"多头加速,入场") elif code == g.code[2] and poly_1[0]<-3 and poly_2[0]<-0.04: #加快下跌趋势 g.sell_flag = 1 QuickInsertOrder(context.myacc,code,'sell','open', dyndata.now,20) #开空头 g.has_contract = 2 g.position_now = code #当前持仓为code print(str(code)+"空头加速,入场")
#判断买单是否长时间未成交 if g.buy_flag == 2 and g.cancel_time > 0: cur_time = GetCurrentTime() if cur_time - g.buy_open_time >= datetime.timedelta(minutes = g.cancel_time): print(("买开超过 %d 分钟未成交,撤单" %g.cancel_time)) context.myacc.CancelOrder(g.buy_open_id) g.buy_flag = 0 g.has_contract = 0 #当前没有持多仓
#判断卖单是否长时间未成交 if g.sell_flag == 2 and g.cancel_time > 0: cur_time = GetCurrentTime() if cur_time - g.sell_open_time >= datetime.timedelta(minutes = g.cancel_time): print(("卖开超过 %d 分钟未成交,撤单" %g.cancel_time)) context.myacc.CancelOrder(g.sell_open_id) g.sell_flag = 0 g.has_contract = 0 #当前没有持空仓 if time_now == "14:45:00" and g.has_contract == 1: g.buy_flag = 4 #平多仓标志 position = context.myacc.GetPositions() volume = 0 for pos in position: volume += pos.volume QuickInsertOrder(context.myacc,g.position_now,'sell','close', dyndata.now,volume) #平仓 print("收盘平仓") g.has_contract = 0
if time_now == "14:45:00" and g.has_contract == 2:
g.sell_flag = 4 #平空仓标志
position = context.myacc.GetPositions()
volume = 0
for pos in position:
volume += pos.volume
QuickInsertOrder(context.myacc,g.position_now,'buy','close',
dyndata.now,volume) #平仓
print("收盘平仓")
g.has_contract = 0#当天进行过交易之后,寻找合适的出场信号 if g.has_contract == 1: if poly_2[0]<=0 or poly_1[0]<=0.2: #增长速率减缓 g.buy_flag = 4 #平多仓标志 position = context.myacc.GetPositions() volume = 0 for pos in position: volume += pos.volume QuickInsertOrder(context.myacc,g.position_now,'sell','close', dyndata.now,volume) #平仓 g.has_contract = 0 print("多头减速,出场")
if g.has_contract == 2:
if poly_2[0]>=0 or poly_1[0]>=-0.2: #下跌趋势减缓
g.sell_flag = 4 #平空仓标志
position = context.myacc.GetPositions()
volume = 0
for pos in position:
volume += pos.volume
QuickInsertOrder(context.myacc,g.position_now,'buy','close',
dyndata.now,volume) #平仓g.has_contract = 0 g.sell_flag = 4 #平空仓标志 print("空头减速,出场")
委托回报事件,当有委托回报时调用
def OnOrderChange(context, AccountName, order) :
#打印委托信息,id是编号,volume是数量,详细见API文档 print((g.buy_flag,g.sell_flag,order.bstype.BuySellFlag,order.bstype.OffsetFlag))
#处理提交的买开订单 if g.buy_flag == 1 and order.bstype.BuySellFlag == '0' and order.bstype.OffsetFlag == '0': g.buy_flag = 2 g.buy_open_id = order.id g.buy_open_time = GetCurrentTime() #print("买开订单已提交 编号: %s Price: %f" %(order.id,order.price)) #处理提交的平多仓订单 if g.buy_flag == 4 and order.bstype.BuySellFlag == '1' and order.bstype.OffsetFlag == '1': g.buy_flag = 5 g.sell_offset_id = order.id #print("卖平订单已提交 编号: %s Price: %f" %(order.id,order.price))
#处理提交的卖开订单 if g.sell_flag == 1 and order.bstype.BuySellFlag == '1' and order.bstype.OffsetFlag == '0': g.sell_flag = 2 g.sell_open_id = order.id g.sell_open_time = GetCurrentTime() #print("卖开订单已提交: %s Price: %f" %(order.id,order.price)) #处理提交的平空仓订单 if g.sell_flag == 4 and order.bstype.BuySellFlag == '0' and order.bstype.OffsetFlag == '1': g.sell_flag = 5 g.buy_offset_id = order.id #print("买平订单已提交: %s Price: %f" %(order.id,order.price))
#强制卖平 if g.buy_flag == 8 and order.bstype.BuySellFlag == '1' and order.bstype.OffsetFlag == '1' and order.IsOrderCancelled(): #print("卖平订单已撤单: %s" %(order.id)) print(g.position_now) dyndata = GetQuote(g.position_now) g.buy_flag = 4 position = context.myacc.GetPositions() volume = 0 for pos in position: volume += pos.volume id2 = QuickInsertOrder(context.myacc,g.position_now,'sell','close', dyndata.now.bidprice(0) - 1*g.step_unit,volume)
#强制买平 if g.sell_flag == 8 and order.bstype.BuySellFlag == '0' and order.bstype.OffsetFlag == '1' and order.IsOrderCancelled(): #print("买平订单已撤单: %s" %(order.id)) dyndata = GetQuote(g.position_now) g.sell_flag = 4 position = context.myacc.GetPositions() volume = 0 for pos in position: volume += pos.volume id2 = QuickInsertOrder(context.myacc,g.position_now,'buy','close', dyndata.now,volume)
def OnTradeDeal(context, AccountName, trade) :
#print "TradeDealed on " + trade.orderid + " on " + AccountName
#买开订单成交 if g.buy_flag ==2 and trade.orderid == g.buy_open_id : #print("买开订单已成交 编号:"+ trade.orderid) g.buy_flag = 3
#卖开订单成交 if g.sell_flag ==2 and trade.orderid == g.sell_open_id : #print("卖开订单已成交 编号:"+ trade.orderid) g.sell_flag = 3 #平多仓成交 if g.buy_flag ==5 and trade.orderid == g.sell_offset_id : #print("卖平订单已成交 编号:"+ trade.orderid) g.buy_flag = 6
#平空仓成交 if g.sell_flag ==5 and trade.orderid == g.buy_offset_id : # print("买平订单已成交 编号:"+ trade.orderid) g.sell_flag = 6