欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

真格量化学习处理——几个功能小函数

程序员文章站 2022-04-26 21:13:43
真格这周是学习使用了不少,功能算是很不错,但在做的时候也发现了一个问题:数据缺失:我在做回测,要求获取每天的delta值,并从中筛选条件值时,报错,显示无数据。不得不使用pass,影响我的回测连贯性。现在开始讲下,我做的几个功能函数:算起来,挺烦的,就是各种细节处理:获取最接近指定delta值的期权合约。用于风险偏好选择def min_delta_c(df,n=1): #print('atm>0',df) df=df.sort_values(by='delta',...

真格这周是学习使用了不少,功能算是很不错,但在做的时候也发现了一个问题:
数据缺失:我在做回测,要求获取每天的delta值,并从中筛选条件值时,报错,显示无数据。不得不使用pass,影响我的回测连贯性。
现在开始讲下,我做的几个功能函数:
算起来,挺烦的,就是各种细节处理:

获取最接近指定delta值的期权合约。

用于风险偏好选择

def min_delta_c(df,n=1):
    
    #print('atm>0',df)
    df=df.sort_values(by='delta',ascending=True) 
    #print(df)
    if n ==0:
        dfn =df.head(n)
    elif n == 1:
        dfn=df.head(n)
    elif n ==2 :
        df1 = df[0:1]
        df2 = df[1:2]
        dfn=pd.merge(df1,df2,on='date')

    return dfn

def min_delta_p(df,n=1):
    
    #print('atm>0',df)
    df=df.sort_values(by='delta',ascending=True) 
    #print(df)
    if n ==0:
        dfn =df.head(n)
    elif n == 1:
        dfn=df.head(n)
    elif n ==2 :
        df1 = df[0:1]
        df2 = df[1:2]
        dfn=pd.merge(df1,df2,on='date')

    return dfn
#获取期权标的
g.biaodi = '510050.SHSE'
cutime = GetCurrentTime()#获取当前时间
b = CreateCalcObj()
    
#查询期权C合约列表
c_oplist = GetOptionContracts('510050.SHSE',cutime,0,'')
p_oplist = GetOptionContracts('510050.SHSE',cutime,1,'')
klinedata = GetHisData2(g.biaodi,BarType.Day)
lastclose = klinedata[-1].close 
#标的物价格
c_df = pd.DataFrame(columns = ['code','delta'])
for i in c_oplist:
    dela = GetOptionDeltaByCode(i,60,pricetype="now")
    df_insert = pd.DataFrame({'code':[i],
                             'delta':[dela]})
    c_df=c_df.append(df_insert,ignore_index=True)
c_df['s'] =  0.3
c_df['delta'] = abs(c_df['delta']-c_df['s'])

atmoc = min_delta_c(c_df)

p_df = pd.DataFrame(columns = ['code','delta'])
for i in p_oplist:
    dela = GetOptionDeltaByCode(i,60,pricetype="now")
    df_insert = pd.DataFrame({'code':[i],
                             'delta':[dela]})
    p_df=p_df.append(df_insert,ignore_index=True)
p_df['s'] = 0.3     
p_df['delta'] = abs(abs(p_df['delta'])-p_df['s'])   
atmop = min_delta_p(p_df)

print('c',atmoc,c_df['delta'])
print("p",atmop,p_df['delta'])
  

当前期权持仓delta(标的价)归零的函数

用于中性策略,也可以改为gamma(delta),vega(波动率),theta(时间),rho(利率)。
操作对象为期权合约

#令delta归0的动态对冲函数
def del_0():
    positions_buy = GetPositionsAsDF(context.accounts["回测期权"],buysellflag = '0')

    positions_sell = GetPositionsAsDF(context.accounts["回测期权"],buysellflag = '1')
    del_buy = 0 
    for i in range(len(positions_buy)):
        num = position_buy.iloc[i,2]
        optionDelta = GetOptionDeltaByCode(position_buy.iloc[i,1],60,'now')
        
        del_buy+=optionDelta*num
    del_sell = 0
    for i in range(len(positions_sell)):
        num = position_sell.iloc[i,2]
        optionDelta = GetOptionDeltaByCode(position_sell.iloc[i,1],60,'now')
      
        del_sell+=optionDelta*num    
    share = 0
    if del_buy+del_sell>0:
        share = int((del_buy+del_sell)/cal_del(g.atmop))
        QuickInsertOrder(context.myacc,g.atmop,'buy','open',PriceType(PbPriceType.Limit,2),share)
    elif del_buy+del_sell<0:
        share = int(abs(del_buy+del_sell)/cal_del(g.atmoc))
        QuickInsertOrder(context.myacc,g.atmoc,'buy','open',PriceType(PbPriceType.Limit,2),share)

当前期权持仓delta(标的价)归零的函数

操作对象为期货

#标的买卖对冲
def del_0(context,atmoc,atmop):
    atmop = atmop
    atmoc = atmoc
    positions_buy = GetPositionsAsDF(context.accounts["回测期权"],buysellflag = '0')

    positions_sell = GetPositionsAsDF(context.accounts["回测期权"],buysellflag = '1')
    del_buy = 0 
    for i in range(len(positions_buy)):
        num = positions_buy.iloc[i,2]
        optionDelta = GetOptionDeltaByCode(positions_buy.iloc[i,1],60,'now')
        
        del_buy+=optionDelta*num
    del_sell = 0
    for i in range(len(positions_sell)):
        num = positions_sell.iloc[i,2]
        optionDelta = GetOptionDeltaByCode(positions_sell.iloc[i,1],60,'now')
      
        del_sell+=optionDelta*num    
    share = 0
    if del_buy+del_sell>0:
        #做空头
        share = int(del_buy+del_sell)
        df = GetPositionsAsDF(context.accounts["回测期货"]) 
        if len(df)==2:
            df_buy = GetPositionsAsDF(context.accounts["回测期货"],buysellflag ='buy')
            QuickInsertOrder(context.myacc1,g.biaodi2,'sell','close',PriceType(PbPriceType.Limit,2),df_buy.iloc[0,2])
            df_sell = GetPositionsAsDF( context.accounts["回测期货"],buysellflag = 'sell')
            if df_sell.iloc[0,2]>share:
                QuickInsertOrder(context.myacc1,g.biaodi2,'sell','close',PriceType(PbPriceType.Limit,2),df_sell.iloc[0,2]-share)
            else:
                QuickInsertOrder(context.myacc1,g.biaodi2,'sell','open',PriceType(PbPriceType.Limit,2),share-df_sell.iloc[0,2])  
        elif len(df)==1:
            if len(GetPositionsAsDF( context.accounts["回测期货"],buysellflag = 'buy'))==1:
                df_buy = GetPositionsAsDF(context.accounts["回测期货"],buysellflag ='buy')    
                QuickInsertOrder(context.myacc1,g.biaodi2,'sell','close',PriceType(PbPriceType.Limit,2),df_buy.iloc[0,2])
                QuickInsertOrder(context.myacc1,g.biaodi2,'sell','open',PriceType(PbPriceType.Limit,2),share)
            else:
                df_sell = GetPositionsAsDF( context.accounts["回测期货"],buysellflag = 'sell')
                if df_sell.iloc[0,2]>share:
                    QuickInsertOrder(context.myacc1,g.biaodi2,'buy','close',PriceType(PbPriceType.Limit,2),df_sell.iloc[0,2]-share)
                else:
                    QuickInsertOrder(context.myacc1,g.biaodi2,'sell','open',PriceType(PbPriceType.Limit,2),share-df_sell.iloc[0,2])    
        elif len(df)==0:
            QuickInsertOrder(context.myacc1,g.biaodi2,'sell','open',PriceType(PbPriceType.Limit,2),share) 
    elif del_buy+del_sell<0:
        #做多头
        share = int(abs(del_buy+del_sell))
        df = GetPositionsAsDF(context.accounts["回测期货"]) 
        if len(df)==2:
            df_buy = GetPositionsAsDF( context.accounts["回测期货"],buysellflag = 'buy')
            
            df_sell = GetPositionsAsDF( context.accounts["回测期货"],buysellflag = 'sell')
            QuickInsertOrder(context.myacc1,g.biaodi2,'buy','close',PriceType(PbPriceType.Limit,2),df_sell.iloc[0,2])        
            if df_buy.iloc[0,2]>share:
                QuickInsertOrder(context.myacc1,g.biaodi2,'sell','close',PriceType(PbPriceType.Limit,2),df_buy.iloc[0,2]-share)
            else:
                QuickInsertOrder(context.myacc1,g.biaodi2,'buy','open',PriceType(PbPriceType.Limit,2),share-df_buy.iloc[0,2])  
        elif len(df)==1:
            if len(GetPositionsAsDF( context.accounts["回测期货"],buysellflag = 'sell'))==1:
                QuickInsertOrder(context.myacc1,g.biaodi2,'buy','close',PriceType(PbPriceType.Limit,2),df_sell.iloc[0,2])
                QuickInsertOrder(context.myacc1,g.biaodi2,'buy','open',PriceType(PbPriceType.Limit,2),share)
            else:
                df_sell = GetPositionsAsDF( context.accounts["回测期货"],buysellflag = 'buy')
                if df_sell.iloc[0,2]>share:
                    QuickInsertOrder(context.myacc1,g.biaodi2,'sell','close',PriceType(PbPriceType.Limit,2),df_sell.iloc[0,2]-share)
                else:
                    QuickInsertOrder(context.myacc1,g.biaodi2,'buy','open',PriceType(PbPriceType.Limit,2),share-df_sell.iloc[0,2])    
        elif len(df)==0:
            QuickInsertOrder(context.myacc1,g.biaodi2,'buy','open',PriceType(PbPriceType.Limit,2),share) 
#K线事件

计算剩余时间

引用真格函数,在此感谢,用处很大

#自定义函数,用于计算合约截至到期剩余天数
def stime(op):
    #获取合约信息  
    info1 = GetContractInfo(op)
    #获取该合约的行权到期日
    kill = info1['行权到期日']
    #获取当前时间
    cutime = GetCurrentTime()
    #获取当前时间的日期
    c = cutime.date()
    #计算当前日期与行权到期日相差天数
    n = (kill - c).days
    #print(n)
    #返回合约截至到期剩余天数
    return n

获取主力或次主力合约函数
同样为引用真格函数,多谢。

#自定义函数, 用于获取当前所有主力或者次主力合约        
def Getop(code):
    #获取实时行情
    dyndata = GetQuote(g.code)
    #获取最新价
    now1 = dyndata.now
    
    #获取当前时间
    cutime = GetCurrentTime()
    #获取当月期权到期时间
    #该段功能时换月,如果不足10天,换下个月合约。
    #若当前时间处于当月15号之后,则到期月份向后推一个月
    if cutime.day >15 and cutime.month<12:
        tim = cutime.month + 1
        month_time = datetime.datetime(month=tim, year=cutime.year,day = 20)
    #若当前时间处于12.15之后,则取下一年的1.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
    
    clist = GetOptionContracts(g.code,month_time,0,'M')
    plist = GetOptionContracts(g.code,month_time,1,'M')
            
    return clist,plist

根据成交量获取合约

此函数源于博主的一个脑洞,主力跟随,选择成交量适当的合约,进行买卖。对不起,我错了,输的一塌糊涂。欢迎交流。

#自定义函数,获取第n档成交量合约
def get_volume_opt(context,clist,plist):
    df = pd.DataFrame(columns = ['opt','volume'])
    
    for i in clist:
        df.loc[len(df),'opt'] = i
        df.loc[len(df)-1,'volume']=GetQuote(i).amount
    df=df.sort_values(by='volume')
    c1 = df.loc[context.param['n'],'opt']
    c2 = df.loc[context.param['n']+1,'opt']
    df1 = pd.DataFrame(columns = ['opt','volume'])
    
    for i in plist:
        df1.loc[len(df1),'opt'] = i
        df1.loc[len(df1)-1,'volume']=GetQuote(i).amount
    df1=df1.sort_values(by='volume')
    p1 = df1.loc[context.param['n'],'opt']
    p2 = df1.loc[context.param['n']+1,'opt']
    return c1,c2,p1,p2

检测合约是否依旧为符合条件的合约

#检查是否还是成交量前n+1档
def stoploss(context,list1,op):
    df = pd.DataFrame(columns = ['opt','volume'])
    
    for i in list1:
        df.loc[len(df),'opt'] = i
        df.loc[len(df)-1,'volume']=GetQuote(i).amount
    df=df.sort_values(by='volume').head(context.param['n']+1)
    if op in df['opt']:
        return True
    else:
        return False

本博主现在在使用真格进行量化回测,研究学习,欢迎大家交流讨论。博主真格id:中性策略研究

本文地址:https://blog.csdn.net/qq_26742269/article/details/109902330