VeighNa量化社区
你的开源社区量化交易平台
Member
avatar
加入于:
帖子: 7
声望: 5

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
Administrator
avatar
加入于:
帖子: 4502
声望: 321

不可以,他们是自己设计的一套框架,而且也不是开源的

© 2015-2022 上海韦纳软件科技有限公司
备案服务号:沪ICP备18006526号

沪公网安备 31011502017034号

【用户协议】
【隐私政策】
【免责条款】