欢迎光临
专业期货策略平台

50ETF与期权对冲策略 50ETF and Options Hedging

管理员阅读(656)

# coding:utf-8
#!/usr/bin/env python
from PoboAPI import *
import datetime
import numpy as np
#用poboquant python实现,在poboquant上运行,如果有问题 可加群 726895887 咨询
#50ETF 和 50ETF期权的对冲交易,当ETF隐含波动率较高时就买50ETF并做空50ETF看涨期权.
#日线级别策略 Strategy on Day Range
#Hedge 50ETF with 50ETF call options, open positions when IV's high
#开始时间,用于初始化一些参数
def OnStart(context) :
    print "system starting..."
    #设定一个全局变量品种
    #g.code1 = "10001315.SHSE" # 50ETF购12月2600
    g.code0 = "510050.SHSE" #其中g表示code0是一个类全局变量

    #订阅实时数据,用于驱动OnQuote事件
    SubscribeQuote(g.code0)
    #订阅K线数据,用于驱动OnBar事件
    SubscribeBar(g.code0, BarType.Day)

    #登录交易账号,需在主页用户管理中设置账号,并把证券测试替换成您的账户名称
    context.myaccOPT = None #初始化期权账户
    if context.accounts.has_key("回测期权") :
        print "登录交易账号[回测期权]"
        if context.accounts["回测期权"].Login() :
            context.myaccOPT = context.accounts["回测期权"]
    
    context.myaccSTC = None #初始化股票账户
    if context.accounts.has_key("回测证券") :
        print "登录交易账号[回测证券]"
        if context.accounts["回测证券"].Login() :
            context.myaccSTC = context.accounts["回测证券"]        
  
def Getop(code):#获取期权合约,包括call和put合约
    dyndata = GetQuote(code)
    now1 = dyndata.now
    now50 = round(now1,1) + 0.05
    cutime = GetCurrentTime()
    if cutime.day >15 and cutime.month<12:
        tim = cutime.month + 1
        month_time = datetime.datetime(month=tim, year=cutime.year,day = 20)
    elif cutime.day >15 and cutime.month==12:
        tim = 1
        yea = cutime.year + 1
        month_time = datetime.datetime(month=tim, year=yea,day = 20) 
    else:
        month_time = cutime
    atmopc = GetAtmOptionContract(code,month_time,now50,0)
    atmopp = GetAtmOptionContract(code,month_time,now50,1)
    return atmopc,atmopp

def GetDaystoExpire(op):#计算期权到期日
    info1 = GetContractInfo(op)
    kill = info1['行权到期日']

    cutime = GetCurrentTime()
    c = cutime.date()
    n = (kill - c).days
    print n
#实时行情事件,当有新行情出现时调用该事件
def OnQuote(context, code) :
    #过滤掉不需要的行情通知
   # if code != g.code1 :
   #     return
   # if code != g.code2 :
   #     return 
    #获取最新行情
    #dyndata1 = GetQuote(g.code1)
    dyndata0 = GetQuote(g.code0)
    tradingtime=GetQuote(g.code0).time
    tradingdate=GetCurrentTime().date()
    
    print "tradingtime ",tradingtime
    print "tradingdate ",tradingdate
    if  dyndata0 :
        #.now指最新价,详细属性见API文档
        #now1 = dyndata1.now
        now0 = dyndata0.now
        #打印最新价
        #log.info("50ETF购12月2600: " + str(dyndata1.now))
        log.info("510050最新价: " + str(now0))
    opc,opp = Getop(g.code0)#获取期权合约代码    
    #获取K线数据
    #klinedata1 = GetHisData(g.code1, BarType.Day)
    dyndata1 = GetQuote(opc)
    klinedata0 = GetHisData(g.code0, BarType.Day)
    #打印K线数据,如最新一根K线的收盘价
    CalObj = CreateCalcObj()
    option = PBObj()
    option.EndDate = GetCurrentTime()
    option.Count = 30
    #计算30日历史波动率
    klist = GetHisDataByField(g.code0, BarType.Day, "close", option)
    if len(klist)>0:
        Kl = np.array(klist, dtype=np.double)
        HisVola=CalObj.GetVolatility(Kl)        
        print HisVola    
    OptDirection=0 # 0 for call, 1 for put
    
    AssetType=0 # 0 for stock opt,1 for etf opt, 2 for futures opt
    
    AssetPrice=now0 # here is the 510050 price
    print "AssetPrice ",AssetPrice
    StrikePrice=round(now0,1) + 0.05 # 计算期权行权价
    
    InterestRate=4.35*0.01 # the risk free interest rate 
    #print "g.code ",g.code0
    #dates=GetOptionsLastDates("m1901.DCE")# not working
    #dates=GetOptionsLastDates("SR901C6000.CZCE") # not working 
    #dates=GetOptionsLastDates("510050.SHSE")#  working
    #dates=GetOptionsLastDates("m1805-C-3300.DCE")
    #dates=datetime.datetime(2018,12,26) # expire date for 50ETF购12月2600 options 
    OptInfo = GetContractInfo(opc)#查询期权信息
    ExpDates=OptInfo['行权到期日']
    print "dates of expire ",str(ExpDates)
    
    #ExpireinYear=(GetOptionsLastDates(g.code1) - tradingtime).days / 365.0 # years to expire
    ExpireinYear=(ExpDates - tradingdate).days / 365.0 # years to expire
    print "ExpireinYear ",ExpireinYear
    OptionPrice=dyndata1.now # get option price
    
    
    #calculate the implied volatility
    #format (direction,asset type,asset price,strikeprice,HisVola,interest rate,expire year,option price)
    print "opt para:"+str(OptDirection)+","+str(AssetType)+","+str(AssetPrice)+","+str(StrikePrice)+","+str(HisVola)+","+str(InterestRate)+","+str(ExpireinYear)+","+str(OptionPrice)
    ImpliedVola=CalObj.GetImpliedVolatility(OptDirection,AssetType,AssetPrice,StrikePrice,HisVola,InterestRate,ExpireinYear,OptionPrice)
    print "Implied Volatility is " + str(ImpliedVola)
    
    balOPT = context.myaccOPT.AccountBalance #获取账户资金状况
    posmarginOPT=balOPT.MarketValue
    
    balSTC = context.myaccSTC.AccountBalance #获取账户资金状况
    posmarginSTC=balSTC.MarketValue
    
    posmargin=posmarginOPT + posmarginSTC
    
    pos = context.myaccOPT.GetPositions()    
    
    poslength=len(pos)
    

        
      
    print "持仓合约数: "+str(poslength)
    #如果配置好交易账号了,可以根据条件下单,需把下面中的证券测试账号换成您设置的账号名称
    if  ImpliedVola>0.23 and poslength==0 and context.myaccOPT and context.myaccSTC  and posmargin<=500000 :
        # 50ETF隐含波动率大于23%就卖出50ETF购12月2600,买入50ETF
        print "open positions with IV at "+str(ImpliedVola)
        print "trading day "+str(tradingtime)
        print "期权持仓市值 "+str(posmargin)
        context.myaccOPT.InsertOrder(opc, BSType.SellOpen, dyndata1.now, 10)#sell options
        context.myaccSTC.InsertOrder(g.code0, BSType.BuyOpen, dyndata0.now, 100000)#buy ETF
        
        
    if  ImpliedVola<0.18 and poslength>0 and context.myaccOPT and context.myaccSTC  :
        # 50ETF隐含波动率小于18%就买平50ETF购12月2600,卖出50ETF,获利平仓
        print "Close positions,take profit with IV"+str(ImpliedVola)
        print "trading day "+str(tradingtime)
        context.myaccOPT.InsertOrder(opc, BSType.BuyClose, dyndata1.now, 10)
        context.myaccSTC.InsertOrder(g.code0, BSType.SellClose, dyndata0.now, 100000)
    
    if  ImpliedVola>0.30 and poslength>0 and context.myaccOPT and context.myaccSTC  :
        # 50ETF隐含波动率大于30%就买平50ETF购12月2600,卖出50ETF,止损平仓
        print "sell close the spread,cut loss with IV "+str(ImpliedVola)
        print "trading day "+str(tradingtime)
        context.myaccOPT.InsertOrder(opc, BSType.BuyClose, dyndata1.now, 10)
        context.myaccSTC.InsertOrder(g.code0, BSType.SellClose, dyndata0.now, 100000)    
    if poslength>0:
      #平仓快要到期的期权头寸和相应50ETF头寸
      for i in pos:
        if GetDaystoExpire(i.contract)<=3:
          OptClosePrice=GetQuote(i.contract)
          OptCloseVolume=i.availvolume
          print "平仓快到期头寸"
          context.myaccOPT.InsertOrder(i.contract, BSType.BuyClose, OptClosePrice, OptCloseVolume)
          context.myaccSTC.InsertOrder(g.code0, BSType.SellClose, dyndata0.now, 10000*OptCloseVolume)
      
#委托回报事件,当有委托回报时调用
def OnOrderChange(context, AccountName, order) :
    #打印委托信息,id是编号,volume是数量,详细见API文档
    print "委托编号: " + order.id + "   账号名称: " + AccountName
    print "Vol: " + str(order.volume) + " Price: " + str(order.price)

经典国债期货套利量化源代码学习

管理员阅读(725)

经典国债期货套利量化源代码学习,适用于博易真格量化平台,大家可以下载学习。

如果有什么问题,可以直接在贴子底部回复。

# coding:utf-8
#!/usr/bin/env python

from PoboAPI import *
import datetime
import numpy as np
#债券期货价差策略,10年期国债与5年期国债价差 spread trade on 10y and 5y bond futures
def OnStart(context) :
    print "I\'m starting..."
    
    context.myacc = None
    if context.accounts.has_key("回测期货"):
        print "登录交易账号[回测期货]"
        if context.accounts["回测期货"].Login() :
            context.myacc = context.accounts["回测期货"]    
    SubscribeQuote(["T1812.CFFEX","TF1812.CFFEX"]) 
    g.code1="T1812.CFFEX"
    g.code2="TF1812.CFFEX"

    
def OnOrderChange(context, AccountName, order) :
    Test = context.accounts["回测期货"].GetOrder(order.id)
    print str(Test.volume)
    

def OnQuote(context,code) :
    option=PBObj()
    #option.buysellflag='0'
    pos = context.accounts["回测期货"].GetPositions()
    #print "positions ",pos
    #print "len(pos) ",len(pos)
    

    leg1 = GetQuote(g.code1)
    leg2 = GetQuote(g.code2)
    
    leg1now=leg1.now
    leg2now=leg2.now
    spreadnow=leg1now-leg2now
    print "spread "+str(spreadnow) # 最新价差
    
    if spreadnow<=0.5 and len(pos)==0 : #10债和5债价差小于0.5就买10债卖5债
        print "to buy Spread....要开仓" 
        context.myacc.InsertOrder(g.code1, BSType.BuyOpen, leg1now, 10)
        context.myacc.InsertOrder(g.code2, BSType.SellOpen,  leg2now, 10)
        print "positions bought"
        bal=context.accounts["回测期货"].AccountBalance.AssetsBalance #返回成交后账户权益
        
        print "账户金额 :"+str(bal)
        #orders = context.accounts["回测期货"].GetOrder(order.id)
        #print str(orders.volume)
        #OnOrderChange(context, "回测期货", order)
        TradeDetails = context.accounts["回测期货"].GetTradeDetails()
        print TradeDetails
        #print "len(pos) in trade ",len(pos)
        pos = context.accounts["回测期货"].GetPositions()
        print "len(pos) str in trade "+str(len(pos))
    
    if spreadnow>1 and len(pos)>0: #有持仓且最新价差大于1就卖出止盈
        print "to sell Spread..." 
        context.myacc.InsertOrder(g.code1, BSType.SellClose, leg1now, 10)
        context.myacc.InsertOrder(g.code2, BSType.BuyClose, leg2now, 10)
        print "positions sold,已经获利平仓"
        bal=context.accounts["回测期货"].AccountBalance.AssetsBalance #返回成交后账户权益
        print "账户金额 :"+str(bal)
        pos = context.accounts["回测期货"].GetPositions()
        print "len(pos) str in trade "+str(len(pos))
    
    if spreadnow<=0.3 and len(pos)>0: #有持仓且最新价差小于0.3就卖出止损
        print "to sell Spread..." 
        context.myacc.InsertOrder(g.code1, BSType.SellClose, leg1now, 10)
        context.myacc.InsertOrder(g.code2, BSType.BuyClose, leg2now, 10)
        print "positions sold 已经止损"
        bal=context.accounts["回测期货"].AccountBalance.AssetsBalance #返回成交后账户权益
        print "账户金额 :"+str(bal)
        pos = context.accounts["回测期货"].GetPositions()
        print "len(pos) str in trade "+str(len(pos))

PVC价格量化交易源代码学习下载

管理员阅读(327)

LLDPE-PVC价差真格量化交易学习,源代码下载。

# coding:utf-8
#!/usr/bin/env python

from PoboAPI import *
import datetime

#开始时间,用于初始化一些参数
def OnStart(context) :
  print "I\'m starting..."
  #设定一个全局变量品种
  g.code1 = "l1905.DCE"
  g.code2="v1905.DCE"
  #订阅实时数据,用于驱动OnQuote事件
  SubscribeQuote([g.code1,g.code2])
  #订阅K线数据,用于驱动OnBar事件
  #SubscribeBar(g.code, BarType.Min)
  #登录交易账号,需在主页用户管理中设置账号,并把证券测试替换成您的账户名称
  context.myacc = None
  if context.accounts.has_key("回测期货") :
    print "登录交易账号[回测期货]"
    if context.accounts["回测期货"].Login() :
      context.myacc = context.accounts["回测期货"]
  
#实时行情事件,当有新行情出现时调用该事件
def OnQuote(context, code) :
  #过滤掉不需要的行情通知
  
  #if code != g.code1 or code!=g.code2 :
  #  return 
  
  #获取最新行情
  dyndatal = GetQuote(g.code1)
  dyndatav = GetQuote(g.code2)
  
  #if dyndata :
    #.now指最新价,详细属性见API文档
  #  now1 = dyndata.now
    #打印最新价
  #  log.info("最新价: " + str(dyndata.now))

  #获取K线数据
  g.code1 = "l1905.DCE"
  g.code2="v1905.DCE"
  klinedata3l = GetHisData(g.code1, BarType.Min3)
  klinedata1l = GetHisData(g.code1, BarType.Min)
  
  klinedata3v = GetHisData(g.code2, BarType.Min3)
  klinedata1v = GetHisData(g.code2, BarType.Min)
  
  spread3=klinedata3l[-2].low-klinedata3v[-2].low
  print "spread3 is " +str(spread3)
  
  spread1=klinedata1l[-1].low-klinedata1v[-1].low
  print "spread1 is " +str(spread1)
  
  #打印K线数据,如最新一根K线的最高价
  #if len(klinedata3) > 0 and len(klinedata1)> 0:
  #  lasthigh3 = klinedata3[-1].high
  #  lasthigh1 = klinedata1[-1].high
  #  log.info("最新3分钟K线的最高价: "  + str(lasthigh3))
  #  log.info("最新1分钟K线的最高价: "  + str(lasthigh1))
  #如果配置好交易账号了,可以根据条件下单,需把下面中的证券测试账号换成您设置的账号名称
  if spread3-50>=spread1 and context.myacc :
      # 当日收盘价小于昨收则买入
      print "满足价差开仓条件......."
      context.myacc.InsertOrder(g.code1, BSType.BuyOpen, dyndatal.now, 50)
      context.myacc.InsertOrder(g.code2, BSType.SellOpen, dyndatav.now, 50)
  elif spread3+10<=spread1 and context.myacc :
      # 当日收盘价大于昨收则卖出
      print "满足价差平仓条件......."
      context.myacc.InsertOrder(g.code1, BSType.SellClose, dyndatal.now, 50)
      context.myacc.InsertOrder(g.code2, BSType.BuyClose, dyndatav.now, 50)

#委托回报事件,当有委托回报时调用
def OnOrderChange(context, AccountName, order) :
  #打印委托信息,id是编号,volume是数量,详细见API文档
  print "委托编号: " + order.id + "   账号名称: " + AccountName
  print "Vol: " + str(order.volume) + " Price: " + str(order.price)

中金所IH与50ETF对冲-改进历史波动率计算代码研究学习

管理员阅读(415)

中金所IH与50ETF对冲-改进历史波动率计算代码研究学习,程序适用与博易量化交易平台-真格量化系统。

# coding:utf-8
#!/usr/bin/env python
from PoboAPI import *
import datetime
import numpy as np
#上证50指数期货 和 50ETF期权的对冲交易,当ETF隐含波动率较高时就买IH期货并做空ETF看涨期权
#Hedge IH Index Futures with 50ETF call options, open positions when IV's high
#开始时间,用于初始化一些参数
def OnStart(context) :
    print "system starting..."
    #设定一个全局变量品种
    
    g.code0 = "510050.SHSE"
    g.code1 = "10001315.SHSE" # 50ETF购12月2600
    g.code2="IH1812.CFFEX"

    #订阅实时数据,用于驱动OnQuote事件
    SubscribeQuote([g.code1,g.code0,g.code2]) #批量订阅行情
    #订阅K线数据,用于驱动OnBar事件
    #SubscribeBar(g.code1, BarType.Day)

    #登录交易账号,需在主页用户管理中设置账号,并把证券测试替换成您的账户名称
    context.myaccOPT = None
    if context.accounts.has_key("回测期权") :
        print "登录交易账号[回测期权]"
        if context.accounts["回测期权"].Login() :
            context.myaccOPT = context.accounts["回测期权"]
    
    context.myaccFUT = None
    if context.accounts.has_key("回测期货") :
        print "登录交易账号[回测期货]"
        if context.accounts["回测期货"].Login() :
            context.myaccFUT = context.accounts["回测期货"]        
  
#实时行情事件,当有新行情出现时调用该事件
def OnQuote(context, code) :
    #获取最新行情
    dyndata1 = GetQuote(g.code1).now#.now指最新价,详细属性见API文档
    dyndata0 = GetQuote(g.code0).now
    dyndata2 = GetQuote(g.code2).now
    tradingtime=GetQuote(g.code0).time#获取50ETF交易时间,用于计算波动率
    print "tradingtime ",tradingtime
    if dyndata1 and dyndata0 and dyndata2 :        
        now1 = dyndata1
        now0 = dyndata0
        now2 = dyndata2
        #打印最新价
        log.info("50ETF购12月2600: " + str(dyndata1))
        log.info("510050最新价: " + str(dyndata0))
        log.info("IH1812最新价:" + str(dyndata2))        
               
        #klinedata0 = GetHisData(g.code0, BarType.Day)#获取K线数据         
        CalOBJ = CreateCalcObj() #创建一个计算对象
        option = PBObj()
        #option.StartDate = datetime.datetime(int(tradingtime.year), int(tradingtime.month), int(tradingtime.day))
        yearstring=int(tradingtime.year)
        #print "yearstring=int(tradingtime.year)",int(tradingtime.year)
        monthstring=int(tradingtime.month)
        daystring=int(tradingtime.day)
        #准备计算50ETF的历史波动率

        option.EndDate=datetime.datetime(yearstring,monthstring,daystring)
        option.Count = 31 #计算50ETF 30天历史波动率 
        klinedata0 = GetHisData(g.code0, BarType.Day, option)
        #print "len(klinedata) ",len(klinedata)
        klist = []
        i=0
        while i<len(klinedata0)-1:
            #print "previous trading day" +str(klinedata0[i].tradedate)
            #print "previous prices "+str(klinedata0[i].close)
            klist.append(klinedata0[i].close) #  
            i+=1
        if len(klist)>0:
            Kl = np.array(klist, dtype=np.double)
            HisVola=CalOBJ.GetVolatility(Kl) #得到历史波动率
        print "30D HisVola "+str(HisVola)
        
        OptDirection=0 # 0 for call, 1 for put
        
        AssetType=0 # 0 for stock opt,1 for etf opt, 2 for futures opt
        
        AssetPrice=now0 # here is the 510050 price
        print "AssetPrice ",AssetPrice
        StrikePrice=2.6 # for 50ETF购12月2600 strike price
        
        InterestRate=4.5*0.01 # the risk free interest rate 
        print "g.code ",g.code0
        #dates=GetOptionsLastDates("m1901.DCE")# not working
        #dates=GetOptionsLastDates("SR901C6000.CZCE") # not working 
        #dates=GetOptionsLastDates("510050.SHSE")#  working
        #dates=GetOptionsLastDates("m1805-C-3300.DCE")
        dates=datetime.datetime(2018,12,26) # expire date for 50ETF购12月2600 options 
        
        print "dates of expire ",str(dates)
        
        #ExpireinYear=(GetOptionsLastDates(g.code1) - tradingtime).days / 365.0 # years to expire
        ExpireinYear=(dates - tradingtime).days / 365.0 # years to expire
        print "ExpireinYear ",ExpireinYear
        OptionPrice=now1 # for option price
        
        
        #calculate the implied volatility
        #format (direction,asset type,asset price,strikeprice,HisVola,interest rate,expire year,option price)
        print "opt para:"+str(OptDirection)+","+str(AssetType)+","+str(AssetPrice)+","+str(StrikePrice)+","+str(HisVola)+","+str(InterestRate)+","+str(ExpireinYear)+","+str(OptionPrice)
        ImpliedVola=CalOBJ.GetImpliedVolatility(OptDirection,AssetType,AssetPrice,StrikePrice,HisVola,InterestRate,ExpireinYear,OptionPrice)
        print "Implied Volatility is " + str(ImpliedVola)
        
        balOPT = context.myaccOPT.AccountBalance #获取账户资金状况
        posmarginOPT=balOPT.MarketValue
        
        balFUT = context.myaccFUT.AccountBalance #获取账户资金状况
        posmarginFUT=balFUT.MarketValue
        
        posmargin=posmarginOPT + posmarginFUT
        
        pos = context.myaccOPT.GetPositions()    
        
        poslength=len(pos)
        print "持仓合约数: "+str(poslength)
        #如果配置好交易账号了,可以根据条件下单,需把下面中的证券测试账号换成您设置的账号名称
        #if len(klinedata1) > 1  and ImpliedVola>0.23 and context.myaccOPT and context.myaccFUT  and posmargin<600000 :
        if  ImpliedVola>0.23   and posmargin<600000 :
            # 
            print "open positions with IV at "+str(ImpliedVola)
            print "trading day "+str(tradingtime)
            print "期权持仓市值 "+str(posmargin)
            context.myaccOPT.InsertOrder(g.code1, BSType.SellOpen, dyndata1, 30)#sell options
            context.myaccFUT.InsertOrder(g.code2, BSType.BuyOpen, dyndata2, 1)#buy ETF
            
            
        if  ImpliedVola<0.18 and poslength>0 :
            # 
            print "Close positions,take profit with IV"+str(ImpliedVola)
            print "trading day "+str(tradingtime)
            context.myaccOPT.InsertOrder(g.code1, BSType.BuyClose, dyndata1, 30)
            context.myaccFUT.InsertOrder(g.code2, BSType.SellClose, dyndata2, 1)
        
        if  ImpliedVola>0.30 and poslength>0 :
            # 
            print "sell close the spread,cut loss with IV "+str(ImpliedVola)
            print "trading day "+str(tradingtime)
            context.myaccOPT.InsertOrder(g.code1, BSType.BuyClose, dyndata1, 30)
            context.myaccFUT.InsertOrder(g.code2, BSType.SellClose, dyndata2, 1)    

#委托回报事件,当有委托回报时调用
def OnOrderChange(context, AccountName, order) :
    #打印委托信息,id是编号,volume是数量,详细见API文档
    print "委托编号: " + order.id + "   账号名称: " + AccountName
    print "Vol: " + str(order.volume) + " Price: " + str(order.price)

豆粕期权价差套利代码范例详解

管理员阅读(569)

# coding:utf-8
#!/usr/bin/env python

from PoboAPI import *
import datetime
#用poboquant python实现,在poboquant上运行,请关注A期客网,下载更多量化代码 www.a-qike.com
#回测的时候最好自己选好期权还在交易的日期段,否则回测会不能进行 pick the date range the options in trading or back test will hault
#这是豆粕1901 看涨3000和看涨3050的价差套利,在豆粕牛市中,看涨期权价差也会拉大
#A spread trade strategy of DCE soybean meal 1901 call 3000 and 3050
#开始时间,用于初始化一些参数
def OnStart(context) :
    print "system starting..."
    #设定一个全局变量品种
    g.code1 = "m1901-C-3000.DCE"
    g.code2= "m1901-C-3050.DCE"
    #订阅实时数据,用于驱动OnQuote事件
    SubscribeQuote([g.code1,g.code2])
    #订阅K线数据,用于驱动OnBar事件
    SubscribeBar(g.code1, BarType.Day)
    SubscribeBar(g.code2, BarType.Day)
    #登录交易账号,需在主页用户管理中设置账号,并把证券测试替换成您的账户名称
    context.myacc = None
    if context.accounts.has_key("回测期货") :
        print "登录交易账号[回测期货]"
        if context.accounts["回测期货"].Login() :
            context.myacc = context.accounts["回测期货"]
  
#实时行情事件,当有新行情出现时调用该事件
def OnQuote(context, code) :
    #过滤掉不需要的行情通知
   # if code != g.code1 :
   #     return
   # if code != g.code2 :
   #     return 
    #获取最新行情
    dyndata1 = GetQuote(g.code1)
    dyndata2 = GetQuote(g.code2)
    if dyndata1 and dyndata2 :
        #.now指最新价,详细属性见API文档
        now1 = dyndata1.now
        now2 = dyndata2.now
        #打印最新价
        log.info("m1901-C-3000最新价1: " + str(dyndata1.now))
        log.info("m1901-C-3050最新价2: " + str(dyndata2.now))
    #获取K线数据
    klinedata1 = GetHisData(g.code1, BarType.Day)
    klinedata2 = GetHisData(g.code2, BarType.Day)
    #打印K线数据,如最新一根K线的收盘价
    if len(klinedata1) > 0 and len(klinedata2) > 0 :
        lastspread = klinedata1[-1].close - klinedata2[-1].close #期权价差
        log.info("最新价差: "  + str(lastspread))
    bal = context.myacc.AccountBalance
    posmargin=bal.FrozenMargin
    
    pos = context.myacc.GetPositions()    
    
    poslength=len(pos)
    print "持仓合约数: "+str(poslength)
    #如果配置好交易账号了,可以根据条件下单,需把下面中的证券测试账号换成您设置的账号名称
    if len(klinedata1) > 1 and len(klinedata2) > 1 and lastspread<5 and context.myacc and posmargin<100000 :
        # 两个期权价差小于50就买入价差,开仓策略,open position
        print "buy open the spread "+str(lastspread)
        context.myacc.InsertOrder(g.code1, BSType.BuyOpen, dyndata1.now, 10)
        context.myacc.InsertOrder(g.code2, BSType.SellOpen, dyndata2.now, 10)
        
        
    if len(klinedata1) > 1 and len(klinedata2) > 1 and lastspread>60 and poslength>0 and context.myacc  :
        # 两个期权价差大于60就卖平价差,平仓,close positions
        print "sell close the spread,take profit "+str(lastspread)
        context.myacc.InsertOrder(g.code1, BSType.SellClose, dyndata1.now, 10)
        context.myacc.InsertOrder(g.code2, BSType.BuyClose, dyndata2.now, 10)
    
    if len(klinedata1) > 1 and len(klinedata2) > 1 and lastspread<2 and poslength>0 and context.myacc  :
        # 两个期权价差小于2就卖平价差,止损,cut loss
        print "sell close the spread,cut loss "+str(lastspread)
        context.myacc.InsertOrder(g.code1, BSType.SellClose, dyndata1.now, 10)
        context.myacc.InsertOrder(g.code2, BSType.BuyClose, dyndata2.now, 10)    

#委托回报事件,当有委托回报时调用
def OnOrderChange(context, AccountName, order) :
    #打印委托信息,id是编号,volume是数量,详细见API文档
    print "委托编号: " + order.id + "   账号名称: " + AccountName
    print "Vol: " + str(order.volume) + " Price: " + str(order.price)

做空白糖波动率策略范例Short Sugar Vola

管理员阅读(351)

做空白糖波动率策略范例Short Sugar Vola ,博易量化

# coding:utf-8
#!/usr/bin/env python
from PoboAPI import *
import datetime
#用poboquant python实现,在poboquant上运行,请关注A期客网www.a-qike.com ,更多程序化源码代下载。
#做空白糖期权波动率策略,卖宽跨式,比如你认为白糖价格在较长时间里会在5000~6000区间运行,而不会向上或向下突破
#short sugar price volatility, like you believe that sugar will range move in 5000 to 6000,no break out in either way
#开始时间,用于初始化一些参数
def OnStart(context) :
    print "system starting..."
    #设定一个全局变量品种
    g.code1 = "SR901C6000.CZCE"
    g.code2 = "SR901P5000.CZCE"
    #订阅实时数据,用于驱动OnQuote事件
    SubscribeQuote([g.code1,g.code2])
    #订阅K线数据,用于驱动OnBar事件
    SubscribeBar(g.code1, BarType.Day)
    SubscribeBar(g.code2, BarType.Day)
    #登录交易账号,需在主页用户管理中设置账号,并把证券测试替换成您的账户名称
    context.myacc = None
    if context.accounts.has_key("回测期货") :
        print "登录交易账号[回测期货]"
        if context.accounts["回测期货"].Login() :
            context.myacc = context.accounts["回测期货"]
  
#实时行情事件,当有新行情出现时调用该事件
def OnQuote(context, code) :
    #过滤掉不需要的行情通知
   # if code != g.code1 :
   #     return
   # if code != g.code2 :
   #     return 
    #获取最新行情
    dyndata1 = GetQuote(g.code1)
    dyndata2 = GetQuote(g.code2)
    if dyndata1 and dyndata2 :
        #.now指最新价,详细属性见API文档
        now1 = dyndata1.now
        now2 = dyndata2.now
        #打印最新价
        log.info("SR901C6000最新价1: " + str(dyndata1.now))
        log.info("SR901P5000最新价2: " + str(dyndata2.now))
    #获取K线数据
    klinedata1 = GetHisData(g.code1, BarType.Day)
    klinedata2 = GetHisData(g.code2, BarType.Day)
    #打印K线数据,如最新一根K线的收盘价
    if len(klinedata1) > 0 and len(klinedata2) > 0 :
        lastsum = klinedata1[-1].close + klinedata2[-1].close #期权价格之和
        log.info("最新价格和: "  + str(lastsum))
    bal = context.myacc.AccountBalance
    posmargin=bal.FrozenMargin
    
    pos = context.myacc.GetPositions()    
    
    poslength=len(pos)
    print "持仓合约数: "+str(poslength)
    #如果配置好交易账号了,可以根据条件下单,需把下面中的证券测试账号换成您设置的账号名称
    if len(klinedata1) > 1 and len(klinedata2) > 1 and lastsum>200 and context.myacc and posmargin<100000 :
        # 两个期权价格之和大于200就同时卖出
        print "buy open the spread "+str(lastsum)
        context.myacc.InsertOrder(g.code1, BSType.SellOpen, dyndata1.now, 10)
        context.myacc.InsertOrder(g.code2, BSType.SellOpen, dyndata2.now, 10)
        
        
    if len(klinedata1) > 1 and len(klinedata2) > 1 and lastsum<50 and poslength>0 and context.myacc  :
        # 两个期权价格之和小于50就同时买平
        print "sell close the spread,take profit "+str(lastsum)
        context.myacc.InsertOrder(g.code1, BSType.BuyClose, dyndata1.now, 10)
        context.myacc.InsertOrder(g.code2, BSType.BuyClose, dyndata2.now, 10)
    
    if len(klinedata1) > 1 and len(klinedata2) > 1 and lastsum>250 and poslength>0 and context.myacc  :
        # 两个期权价格之和大于250就同时买平,止损
        print "sell close the spread,cut loss "+str(lastsum)
        context.myacc.InsertOrder(g.code1, BSType.BuyClose, dyndata1.now, 10)
        context.myacc.InsertOrder(g.code2, BSType.BuyClose, dyndata2.now, 10)    

#委托回报事件,当有委托回报时调用
def OnOrderChange(context, AccountName, order) :
    #打印委托信息,id是编号,volume是数量,详细见API文档
    print "委托编号: " + order.id + "   账号名称: " + AccountName
    print "Vol: " + str(order.volume) + " Price: " + str(order.price)

期权盒式套利-日线级别量化源代码下载

管理员阅读(422)

真格量化系统-期权盒式套利-日线级别量化源代码下载

#!/usr/bin/env python
# coding:utf-8
from PoboAPI import *
import datetime
import math
from copy import *

#开始时间,用于初始化一些参数
def OnStart(context) :
  print "I\'m starting..."
  #设置全局变量,作为是否已经平仓的标志
  g.close=True
  #设置开仓阈值
  g.threshold=1.5
  #获取当前期权的到期日列表
  last= GetOptionsLastDates('510050.SHSE')
  #获取特定到期日的期权列表
  call_oplist = GetOptionContracts('510050.SHSE',last[-1],0)
  put_oplist=GetOptionContracts('510050.SHSE',last[-1],1)
  g.code=[call_oplist[0],call_oplist[1],put_oplist[0],put_oplist[1]]
  print "当前套利期权组合初始化为"+str(g.code)
  SubscribeQuote(g.code[0])
  #登录期权账号
  if context.accounts.has_key("回测期权") :
    print "登录交易账号 回测期权"
    if context.accounts["回测期权"].Login() :
      context.myacc = context.accounts["回测期权"]
      
#实时行情事件
def OnQuote(context,code) :
  #print "调用到OnQuote事件"
  #如果当前持仓已平仓,寻找当前可进行套利的一组期权
  if g.close==True:
    #获取当前期权的到期日列表
    last= GetOptionsLastDates('510050.SHSE')
    #获取特定到期日的期权列表
    call_oplist = GetOptionContracts('510050.SHSE',last[-1],0)
    put_oplist= GetOptionContracts('510050.SHSE',last[-1],1)
    #获取期权的基本信息列表
    info=[]
    for op in call_oplist:
      info.append(GetContractInfo(op))
    #获取期权的行权价列表
    K=[]
    for i in info:
      K.append(i['行权价格'])
    #获取看涨期权当前最新价列表
    C=[]
    for op in call_oplist:
      C.append(GetQuote(op).now)
    #获取看跌期权当前最新价列表
    P=[]
    for op in put_oplist:
      P.append(GetQuote(op).now)
    #获取期权行权日
    T=last[-1]
    #获取当前交易日
    t=GetCurrentTradingDate('SHFE')
    #计算当前日距离到期日的时间,并换算成以年为单位
    time=float((T-t).days)/365.0
    #无风险利率设为0.04
    r=0.04
    code_list=[]
    spreads=[]
    #将列表可进行套利的期权加入code_list中,并将套利差加入spreads中
    for i in range(len(K)):
      for j in range(i+1,len(K)):
        K_all=(K[j]-K[i])*math.exp(-r*time)
        C_all=C[i]-C[j]
        P_all=P[j]-P[i]
        if C_all+P_all>= g.threshold*K_all or C_all+P_all<=-g.threshold*K_all:
          code_list.append([call_oplist[i],call_oplist[j],put_oplist[i],put_oplist[j]])
          spreads.append(abs(C_all+P_all))
    #如果code_list不为空,将套利差绝对值最大的期权组合保存到g.code中
    if code_list:
      UnsubscribeQuote(g.code[0])
      index=spreads.index(max(spreads))
      g.code=code_list[index]
      #print "套利期权组合更改为"+str(g.code)
      SubscribeQuote(g.code[0])
  #print "当前套利期权组合为"+str(g.code)
  #获取套利期权组合的基本信息
  info1=GetContractInfo(g.code[0])
  info2=GetContractInfo(g.code[1])
  #获取套利期权组合的行权价
  K1=info1['行权价格']
  K2=info2['行权价格']
  #获取套利期权组合的最新价
  dyndata1=GetQuote(g.code[0])
  dyndata2=GetQuote(g.code[1])
  C1=dyndata1.now
  C2=dyndata2.now
  dyndata3=GetQuote(g.code[2])
  dyndata4=GetQuote(g.code[3])
  P1=dyndata3.now
  P2=dyndata4.now
  #获取期权组合的到期日并转换为date格式
  T_int=info1['行权到期日']
  T_str=str(T_int)
  year=int(T_str[0:4])
  month=int(T_str[5:7])
  day=int(T_str[8:])
  T=datetime.date(year,month,day)
  #获取当前交易日
  t=GetCurrentTradingDate('SHFE')
  #计算当前日距离到期日的时间,并换算成以年为单位
  time=float((T-t).days)/365.0
  #无风险利率设为0.04
  r=0.04
  #计算K
  K=(K2-K1)*math.exp(-r*time)
  #计算C
  C=C1-C2
  #计算P
  P=P2-P1
  #获取期权组合的当前涨停价
  dyndata1=GetQuote(g.code[0])
  riselimit1=dyndata1.riselimit
  dyndata2=GetQuote(g.code[1])
  riselimit2=dyndata2.riselimit
  dyndata3=GetQuote(g.code[2])
  riselimit3=dyndata3.riselimit
  dyndata4=GetQuote(g.code[3])
  riselimit4=dyndata4.riselimit
  #获取期权组合的当前成交量
  trade1=dyndata1.volume
  trade2=dyndata2.volume
  trade3=dyndata3.volume
  trade4=dyndata4.volume
  price_type= PriceType(PbPriceType.Limit,limit_price_type=2,limit_price_offset=10)
  #若当前期权组合均可交易
  if trade1!=0 and trade2!=0 and trade3!=0 and trade4!=0:
    value = 0.8
    context.myacc.SetRiskDegreeMaxThreshold(value)
    isOver = context.myacc.IsRiskDegreeOverMax()
    if C+P>= g.threshold*K:
      if g.close==True:
        if isOver==False:
        #计算最佳下单量
          v1=context.myacc.GetValidVolume(g.code[0],BSType.SellOpen,riselimit1)
          v2=context.myacc.GetValidVolume(g.code[1],BSType.BuyOpen,riselimit2)
          v3=context.myacc.GetValidVolume(g.code[2],BSType.BuyOpen,riselimit3)
          v4=context.myacc.GetValidVolume(g.code[3],BSType.SellOpen,riselimit4)
          v=int(min(v1,v2,v3,v4))
        #卖出低执行价看涨期权
          QuickInsertOrder(context.myacc,g.code[0],'sell','open',price_type,v/4)
        #买入高执行价看涨期权
          QuickInsertOrder(context.myacc,g.code[1],'buy','open',price_type,v/4)
        #买入低执行价看跌期权
          QuickInsertOrder(context.myacc,g.code[2],'buy','open',price_type,v/4)
        #卖出高执行价看跌期权
          QuickInsertOrder(context.myacc,g.code[3],'sell','open',price_type,v/4)
          print "开仓成功"
          g.close=False
    elif C+P<=-g.threshold*K:
      if g.close==True:
        if isOver==False:
        #计算最佳下单量
          v1=context.myacc.GetValidVolume(g.code[0],BSType.BuyOpen,riselimit1)
          v2=context.myacc.GetValidVolume(g.code[1],BSType.SellOpen,riselimit2)
          v3=context.myacc.GetValidVolume(g.code[2],BSType.SellOpen,riselimit3)
          v4=context.myacc.GetValidVolume(g.code[3],BSType.BuyOpen,riselimit4)
          v=int(min(v1,v2,v3,v4))
        #买入低执行价看涨期权
          QuickInsertOrder(context.myacc,g.code[0],'buy','open',price_type,v/4)
        #卖出高执行价看涨期权
          QuickInsertOrder(context.myacc,g.code[1],'sell','open',price_type,v/4)  
        #卖出低执行价看跌期权
          QuickInsertOrder(context.myacc,g.code[2],'sell','open',price_type,v/4)  
        #买入高执行价看跌期权
          QuickInsertOrder(context.myacc,g.code[3],'buy','open',price_type,v/4)  
          print "开仓成功"
          g.close=False
      #当C+P的值在g.threshold*K和-g.threshold*K之间,平掉所有持仓
    else:
      for c in g.code:
        option = PBObj()
        option.contract = c
        pos = context.myacc.GetPositions(option)
        for p in pos:
          if p.bstype.BuySellFlag=="0":
            QuickInsertOrder(context.myacc,c,'sell','close',price_type,p.volume)
          if p.bstype.BuySellFlag=="1":
            QuickInsertOrder(context.myacc,c,'buy','close',price_type,p.volume)
      g.close=True
  #若g.code中期权已到期
  if T==t:
    #平仓掉g.code中的持仓
    for c in g.code:
      option = PBObj()
      option.contract = c
      pos = context.myacc.GetPositions(option)
      for p in pos:
        if p.bstype.BuySellFlag=="0":
          QuickInsertOrder(context.myacc,c,'sell','close',price_type,p.volume)
        if p.bstype.BuySellFlag=="1":
          QuickInsertOrder(context.myacc,c,'buy','close',price_type,p.volume)
        print "到期强制平仓"
    #重新初始化g.code中的交易资产
    last= GetOptionsLastDates('510050.SHSE')
    call_oplist = GetOptionContracts('510050.SHSE',last[-1],0)
    put_oplist=GetOptionContracts('510050.SHSE',last[-1],1)
    UnsubscribeQuote(g.code[0])
    g.code=[call_oplist[0],call_oplist[1],put_oplist[0],put_oplist[1]]
    #print "当前套利期权已到期,重新初始化为"+str(g.code)
    SubscribeQuote(g.code[0])
    g.close=True
    

量化交易日线单品种跨期套利代码下载(真格量化)

管理员阅读(424)

量化交易日线单品种跨期套利源代码下载(真格量化)

# coding:utf-8
#!/usr/bin/env python
from PoboAPI import *
import datetime
import statsmodels.formula.api as sm
from statsmodels.tsa import stattools
import numpy as np
import pandas as pd
from copy import *

#开始时间,用于初始化一些参数    
def OnStart(context) :
  print "I\'m starting..."
  #获取ag当前可交易合约,并按月份进行排序
  vac=sorted(GetFuturesContracts('SHFE','rb'))
  #获取当前主力合约
  MainContract=GetMainContract('SHFE', 'rb',20)
  #获取当前主力合约下一月合约
  for i in range(len(vac)):
    if vac[i]==MainContract:
      s=i+1
      break
  g.code=[MainContract,vac[s]]
  #订阅g.code[0]
  SubscribeQuote(g.code[0])
  #登录交易账号
  if context.accounts.has_key("回测期货") :
    print "登录交易账号 回测期货"
    if context.accounts["回测期货"].Login() :
      context.myacc = context.accounts["回测期货"]

#实时行情事件,当有新行情出现时调用该事件            
def OnQuote(context,code) :
  #print "调用到OnQuote事件"
  vac=sorted(GetFuturesContracts('SHFE','rb'))
  #获取当前主力合约
  MainContract=GetMainContract('SHFE', 'rb',20)
  #获取当前主力合约下一月合约
  price_type=PriceType(PbPriceType.LimitFOK,limit_price_type=2)
  for i in range(len(vac)):
    if vac[i]==MainContract:
      s=i+1
      break
  if g.code[0]!=MainContract:
    #进行平仓
    for c in g.code:
      option = PBObj()
      option.contract = c
      pos = context.myacc.GetPositions(option)
      for p in pos:
        if p.bstype.BuySellFlag=="0":
          QuickInsertOrder(context.myacc,c,'sell','close',price_type,p.volume)
        if p.bstype.BuySellFlag=="1":
          QuickInsertOrder(context.myacc,c,'buy','close',price_type,p.volume)
    #取消订阅原主力合约
    UnsubscribeQuote(g.code[0])
    g.code_old=g.code
    g.code=[MainContract,vac[s]]
    print "当前主力合约由"+str(g.code_old[0])+"更换为"+str(g.code[1])
    print "平仓掉原主力合约"
    #订阅当前主力合约信息
    SubscribeQuote(g.code[0])
  print "当前套利组合为"+str(g.code)
  #获取当前日期
  current_date=GetCurrentTradingDate('SHFE')
  #获取两个品种的近60个交易日的收盘价构造收盘价序列
  close_01= GetHisDataByFieldAsDF(g.code[0],'close', BarType.Day, start_date=None, end_date=current_date, count=60,weight_type=0)
  close_02= GetHisDataByFieldAsDF(g.code[1],'close', BarType.Day, start_date=None, end_date=current_date, count=60,weight_type=0)
  #对价格序列取对数
  x=np.log(close_01)
  y=np.log(close_02)
  #做回归,取残差序列
  x=pd.Series(x)
  y=pd.Series(y)
  df = pd.concat([x,y],axis = 1)
  df.columns = ['x','y']
  model = sm.ols(formula = 'y~x',data = df).fit()
  resid=model.resid
  #对残差进行单位根检验,求p值
  p=stattools.adfuller(resid)[1]
  #设定残差序列的2倍标准差为开仓阈值
  open_ththreshold_positive =2*resid.std()
  #设定残差序列的0.01倍标准差为平仓阈值
  close_ththreshold_positive =0.05*resid.std()
  close_ththreshold_negative =-0.05*resid.std()
  resid=np.array(resid)
  #获取资产的当前涨停价,成交量,最新价
  dyndata1 = GetQuote(g.code[0])
  dyndata2 = GetQuote(g.code[1])
  riselimit1=dyndata1.riselimit
  riselimit2=dyndata2.riselimit
  value = 0.8
  context.myacc.SetRiskDegreeMaxThreshold(value)
  isOver=context.myacc.IsRiskDegreeOverMax()
  if isOver==False:
    #若通过协整检验
    if p<0.05:
      value = PBObj()
#       value.Rate = 0.12
#       context.myacc.SetMargin(g.code[0], value)
#       context.myacc.SetMargin(g.code[1], value)
      #下单
      if resid[-1]>= open_ththreshold_positive:
        v1=context.myacc.GetValidVolume(g.code[0],BSType.BuyOpen,riselimit1)
        v2=context.myacc.GetValidVolume(g.code[1],BSType.SellOpen,riselimit2)
        v=int(min(v1,v2))
        QuickInsertOrder(context.myacc,g.code[0],'buy','open',price_type,v/2)
        QuickInsertOrder(context.myacc,g.code[1],'sell','open',price_type,v/2)
        print "买入"+str(g.code[0])+","+"卖出"+str(g.code[1])
      #平仓
      if resid[-1]<close_ththreshold_positive:
        for c in g.code:
          option = PBObj()
          option.contract = c
          pos = context.myacc.GetPositions(option)
          dyndata=GetQuote(c)
          now=dyndata.now
          for p in pos:
            if p.bstype.BuySellFlag=="0":
              QuickInsertOrder(context.myacc,c,'sell','close',price_type,p.volume)
            print "卖平"+str(c)
            if p.bstype.BuySellFlag=="1":
              QuickInsertOrder(context.myacc,c,'buy','close',price_type,p.volume)
            print "买平"+str(c)

博易真格量化策略-波动收敛突变分钟级

管理员阅读(638)

博易真格量化策略,波动收敛突变分钟级运行环境python2

#!/usr/bin/env python
# coding:utf-8
from PoboAPI import *
import datetime
import numpy as np
import math
import pandas as pd
#开始时间,用于初始化一些参数
def OnStart(context) :
    print "I\'m starting..."
    #设置全局交易品种
    g.code = GetMainContract('CFFEX','IF',20)
    #设置全局变量
    g.count=0
    g.N1=26
    g.N2=7
    g.Alpha=5
    g.AF=0.02
    g.SAR=0
    g.derection='close'
    g.j0=GetCurrentTime()
    #订阅行情
    SubscribeQuote(g.code)
    #设置闹钟
    context.MyAlarm = SetAlarm(datetime.time(14, 59), RepeatType.Daily)
    #登录期货账号
    if context.accounts.has_key("回测期货") :
        print "登录交易账号 回测期货"
        if context.accounts["回测期货"].Login() :
            context.myacc = context.accounts["回测期货"]

#开盘事件            
def OnExchangeOpen(context, accountname, exchangecode, productcode):
    if exchangecode == 'CFFEX':
      cutime = GetCurrentTime()
      if str(cutime)[12:]=='9:30:00':
        #在每日开盘时将g.count初始化为0
        g.count=0

#闹钟事件
def OnAlarm(context, alarmid):
    print "每日收盘前平仓"
    #每日收盘前平仓
    option = PBObj()
    option.contract = g.code
    pos = context.myacc.GetPositions(option)
    price_type=PriceType(PbPriceType.Limit,limit_price_type=2)
    for p in pos:
      if p.bstype.BuySellFlag=="0":
        QuickInsertOrder(context.myacc,g.code,'sell','close',price_type,p.volume)
      if p.bstype.BuySellFlag=="1":
        QuickInsertOrder(context.myacc,g.code,'buy','close',price_type,p.volume)
    g.derection='close'
    
def OnQuote(context,code) :
    #每5分钟执行一次
    if g.count%5==0:
      print "调用到OnQuote事件"
      #获取当前主力合约
      Maincontract=GetMainContract('CFFEX','IF',20)
      #若主力合约发生更换,将交易品种换成新的主力合约
      if g.code != Maincontract:
        UnsubscribeQuote(g.code)
        g.code=Maincontract
        SubscribeQuote(g.code)
      print "当前交易品种为"+str(g.code)
      #获取当前时间
      cutime = GetCurrentTime()
      dfd=GetHisDataByFieldAsDF(g.code, ['high', 'low'], bar_type=BarType.Min5, end_date=cutime,count=g.N1)
      #计算vH,vL
      vH=max(dfd['high'])
      vL=min(dfd['low'])
      #计算近N2期的波动率的最小值
      d=list(GetHisDataByFieldAsDF(g.code, ['close'], bar_type=BarType.Min,end_date=cutime,count=g.N2)['close'])
      dlist=[]
      for i in range(0,len(d)-5,5):
        dlist.append(d[i:i+5])
      vlist=[]
      for l in dlist:
        vlist.append(pd.Series(l).std())
      vol=min(vlist)
      #下单类型
      price_type=PriceType(PbPriceType.Limit,limit_price_type=2)
      #设置风险度
      value = 0.6
      context.myacc.SetRiskDegreeMaxThreshold(value)
      isOver=context.myacc.IsRiskDegreeOverMax()
      #获取最新价
      dyndata = GetQuote(g.code)
      now=dyndata.now
      if now>=vH: 
      #市场每突破一次,g.AF增加0.02
        if g.AF<0.2:
          g.AF=g.AF+0.02   
        v=int(math.ceil(0.6*context.myacc.GetValidVolume(g.code, BSType.BuyOpen,now)))
        if vol<g.Alpha:
          #若没超过风险度
          if isOver==False:
              #开多仓
              QuickInsertOrder(context.myacc,g.code,'buy','open',price_type,v)
              g.j0=cutime
              g.SAR=np.array(dfd['low'])[-1]
              g.AF=0.02
              g.derection='buy'
              print "买入"+str(v)+str(g.code)
      if now<=vL:
        if g.AF<0.2:
          g.AF=g.AF+0.02  
        v=int(math.ceil(0.6*context.myacc.GetValidVolume(g.code, BSType.SellOpen,now)))
        if vol<g.Alpha:
            #若没超过风险度
            if isOver==False:
              #开空仓
              QuickInsertOrder(context.myacc,g.code,'sell','open',price_type,v)
              g.j0=cutime
              g.vc=np.array(dfd['high'])[-1]
              g.AF=0.02
              g.derection='sell'
              print "卖出"+str(v)+str(g.code)
      #获取持仓状况
      option = PBObj()
      option.contract = g.code
      pos = context.myacc.GetPositions(option)
      #多仓止损
      if now<=g.SAR and g.derection=='buy':
        for p in pos:
          QuickInsertOrder(context.myacc,g.code,'sell','close',price_type,p.volume)
          g.derection='close'
      #空仓止损
      if now>=g.SAR and g.derection=='sell':
        for p in pos:
          QuickInsertOrder(context.myacc,g.code,'buy','close',price_type,p.volume)
          g.derection='close'
      #获取开仓时间到现在的最高价最低价数据
      h=GetHisDataByFieldAsDF(g.code, ['high', 'low'], bar_type=BarType.Min5, start_date=g.j0, end_date=cutime)
      highlist=list(h['high'])
      lowlist=list(h['low'])
      h_two=highlist[-2:]
      l_two=lowlist[-2:]
      #更新g.SAR
      if g.derection=='buy':
        if highlist:
          g.SAR=min(min(l_two),g.SAR+(max(highlist)-g.SAR)*g.AF)
      if g.derection=='sell':
        if lowlist:
          g.SAR=max(max(h_two),g.SAR-(g.SAR-min(lowlist))*g.AF)
    g.count=g.count+1

50ETF期权波动率策略(真格量化)

管理员阅读(553)

50ETF期权波动率策略,博易真格量化策略下载

#!/usr/bin/env python
# coding:utf-8
from PoboAPI import *
import datetime
import time
import numpy as np
#日线级别
#开始时间,用于初始化一些参数
def OnStart(context) :
    print "I\'m starting..."
    #设定一个全局变量品种
    g.code = "510050.SHSE"
    #订阅实时数据,用于驱动OnQuote事件
    SubscribeQuote(g.code)
    #订阅K线数据,用于驱动OnBar事件
    SubscribeBar(g.code, BarType.Day)
    #登录交易账号,需在主页用户管理中设置账号,并把证券测试替换成您的账户名称
    context.myacc = None
    if context.accounts.has_key("回测期权") :
        print "登录交易账号[回测期权]"
        if context.accounts["回测期权"].Login() :
            context.myacc = context.accounts["回测期权"]
def Getop(code):
    dyndata = GetQuote(code)
    now1 = dyndata.now
    now50 = round(now1,1) + 0.05 #虚值一档
    cutime = GetCurrentTime()
    if cutime.day >15 and cutime.month<12:
        tim = cutime.month + 1
        month_time = datetime.datetime(month=tim, year=cutime.year,day = 20)
    elif cutime.day >15 and cutime.month==12:
        tim = 1
        yea = cutime.year + 1
        month_time = datetime.datetime(month=tim, year=yea,day = 20) 
    else:
        month_time = cutime
    atmopc = GetAtmOptionContract(code,month_time,now50,0)
    atmopp = GetAtmOptionContract(code,month_time,now50,1)
    return atmopc,atmopp
  
def stime(op):
#     info1 = GetContractInfo(op)
#     kill = info1['行权到期日']
#     print "行权到期日"+str(kill)
#     print str(type(kill))
#     cutime = GetCurrentTime()
#     if cutime.day <10:
#         cutim = str(cutime.year) + str(cutime.month) + '0' +str(cutime.day)
#     elif cutime.month <10:
#         cutim = str(cutime.year) + '0' + str(cutime.month) +str(cutime.day)
#     else:
#         cutim = str(cutime.year) + str(cutime.month) +str(cutime.day)
#     cu = int(cutim)
#     n = kill - cu
#     return n
      info1 = GetContractInfo(op)
      kill = info1['行权到期日']

      cutime = GetCurrentTime()
      c = cutime.date()
      n = (kill - c).days
      print n
      return n
    
#实时行情事件,当有新行情出现时调用该事件
def OnQuote(context, code) :
    #过滤掉不需要的行情通知
    if code != g.code :
        return

    #获取最新行情
    dyndata = GetQuote(g.code)
    if dyndata :
        #.now指最新价,详细属性见API文档i
        now1 = dyndata.now
        #打印最新价
        log.info("最新价: " + str(dyndata.now) + str(dyndata.time))
    posi = context.myacc.GetPositions()
    print len(posi)
    
    b = CreateCalcObj()
    option = PBObj()
    option.EndDate = GetCurrentTime()
    option.Count = 60
    #获取最近10天的最高价列表
    klist = GetHisDataByField(g.code, BarType.Day, "close", option)
    if len(klist)>0:
        Kl = np.array(klist, dtype=np.double)
        c=b.GetVolatility(Kl)
        print "历史波动率"
        print c

    if len(posi) == 0 and c<0.35:
        opc,opp = Getop(g.code)
        print str(opc)
        dync = GetQuote(opc)
        dynp = GetQuote(opp)
        if dync != None:
            log.info("最新价2: " + str(dync.now))
            log.info("最新价3: " + str(dynp.now))
            context.myacc.InsertOrder(opc, BSType.SellOpen, dync.now, 50)
            context.myacc.InsertOrder(opp, BSType.SellOpen, dynp.now, 50)
    elif len(posi) >1:
        print len(posi)
        opcode1 = posi[0].contract
        opcode2 = posi[1].contract
        dyn1 = GetQuote(opcode1)
        dyn2 = GetQuote(opcode2)
        info1 = GetContractInfo(opcode1)
        pr1 = info1['行权价格']
        ki1 = info1['行权到期日']
        info2 = GetContractInfo(opcode2)
        pr2 = info2['行权价格']
        sy = stime(opcode1)
        print str(pr1) + '行权价格'
        print str(pr2) + '行权价格2'
        print sy
        if sy<3:
            context.myacc.InsertOrder(opcode1, BSType.BuyClose, dyn1.now, 50)
            context.myacc.InsertOrder(opcode2, BSType.BuyClose, dyn2.now, 50)
        elif now1 >= pr1 or now1 <= (pr1-0.15):
            context.myacc.InsertOrder(opcode1, BSType.BuyClose, dyn1.now, 50)
            context.myacc.InsertOrder(opcode2, BSType.BuyClose, dyn2.now, 50)
#委托回报事件,当有委托回报时调用
def OnOrderChange(context, AccountName, order) :
    #打印委托信息,id是编号,volume是数量,详细见API文档
    print "委托编号: " + order.id + "   账号名称: " + AccountName
    print "Vol: " + str(order.volume) + " Price: " + str(order.price)