期权的策略回测系统来了,当前聚宽平台没有期权的模拟交易模块,我们在此只能通过获取历史行情,通过遍历日期的方式进行模拟测试。 1、策略构建时间:每个月的第一个交易日 2、合约选择:选择当月虚值8%左右的看跌期权和下个季度的相同点位的看跌期权的季度期权,构建领口交易策略。 3、交易数量,远期看跌期权1份,当前月看涨期权数量=远期看跌期权价格/当月看涨期权价格 4、开仓方式:双向同时开盘价下单, 5、平仓条件,条件一,当月看涨期权最高价格较买入价格涨幅超过10倍,条件二,当月看涨期权价格收盘价上涨超过5倍,条件三,交割日前2天平仓。 6、平仓方式:条件满足,双向同时平仓 这个策略主要在一些大事情要发生,但又不知道方向的时候采用,说白了就是市场行情波动率大的时候运用,效果比较好,每月定投,可以达到为自己的持仓买保险的效果,大家可以自动调试参数。 本次完成了期权合约的选择,期权行情数据的获取,以及回测模块,一个完整的期权回测体系基本完成了90%。后期做期权的策略的相关回测就简单了,当然还得加一个交易费用的模块,今天就介绍到这里。
from __future__ import print_function, division
import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt
%matplotlib inline
from jqdata import *
import datetime
import matplotlib.pyplot as plt
import tushare as ts
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
#参数设置
shortcode=None
opentrade_s=[]
opentrade_l=[]
closetrade_s=[]
closetrade_l=[]
这里我们主要通过tushare金融数据库获得交易日信息,如果回测失败,没有数据,可能就是token过期,大家需要自己去申请新的token.
#获取每个月的第n个交易日的日期
def tradedate(start,end,n=1):
'start,end均为str类型,如“20190102”,n为当月的第几个交易日'
#如果回测失败,可能token如果过期,需要自己在Tushare上重新申请,不然没数据,建议注册自己注册一个。
ts.set_token('384e878fadc6ad14225108d7a471360ffab5913e30378be6a7871c35')
tradedate=[]
b=[]
pro = ts.pro_api()
#获取
a=pro.trade_cal(exchange='', start_date=start, end_date=end)
x=0
for i in a.index:
if len(tradedate)==0:
if a.is_open[i]==1:
x+=1
if x==n:
tradedate.append(a.cal_date[i])
x=0
else:
if a.is_open[i]==1 and tradedate[-1][4:6]!=a.cal_date[i][4:6]:
x+=1
if x==n:
tradedate.append(a.cal_date[i])
x=0
if len(tradedate)>0:
for c in tradedate:
d=datetime.datetime(int(c[:4]),int(c[4:6]),int(c[6:]))
b.append(d)
print('获取每个月的第n个交易日的日期')
return b
这里主要是进行远期季度合约的时间选择。
#获取远期合约时间
def time_change(current):
dt=current.month
if dt in [2,3,4]:
longdata=[0,9]
elif dt in [5,6,7]:
longdata=[0,12]
elif dt in [8,9,10]:
longdata=[1,3]
elif dt in [11,12]:
longdata=[1,6]
elif dt ==1:
longdata=[0,6]
return longdata
这里我们通过当前上证50ETF价格,选择目标合约,但由于期权合约代码变化的无规律性,我们只能先拼接目标合约的trading_code,通过trading_code,来找到对应合约的code,从而获取合约的行情数据。
#获取交易的合约的trading_code
def check_seed(current):
dt=str(current.month)
it=time_change(current)
x=it[0]+current.year
x=str(x)[2:]
y=str(it[1])
if len(y)==1:
y='0'+y
security='510050.XSHG'
current_price=get_bars(security,1, unit='1d',
fields=['open', 'close', 'high', 'low', 'volume', 'money'],
include_now=False, end_dt=current, fq_ref_date=None)[0][3]
#print('上证50当前价格:%s:%s'%(current,current_price))
a=current_price*1000
b=a*1.08
c=round(b/50)*50
c=int(c)
d=str(c)
if len(dt)==1:
dt='0'+dt
shortcode='510050C'+str(current.year)[2:]+dt+'M0'+d
longcode='510050P'+x+y+'M0'+d
return shortcode,longcode
#选择交易合约代码,交割日
def contract(current,code):
date=current.strftime('%Y-%m-%d')
q=query(opt.OPT_DAILY_PREOPEN.code,
opt.OPT_DAILY_PREOPEN.expire_date,
opt.OPT_DAILY_PREOPEN.trading_code,
opt.OPT_DAILY_PREOPEN.date,
).filter(opt.OPT_DAILY_PREOPEN.trading_code==code,
opt.OPT_DAILY_PREOPEN.date==date,
)
df=opt.run_query(q)
return df
#获取合约的日行情数据
def quotation(current,code,expire_date):
df_price=get_bars(code,count=50,unit='1d',
fields=['date','open','high','low','close'],
include_now=False, end_dt=expire_date)
#把numpy数据类型,转化为pd类型
df_price=pd.DataFrame(df_price,columns=['date','open','high','low','close'])
#注意datetime.datetime和datetime.date不能比较,需要用方法date()转化。
#选取当前时间之后的数据
df_price=df_price[df_price.date>(current-datetime.timedelta(1)).date()]
#重置索引,丢掉原来的索引
df_price = df_price.reset_index(drop = True)
#返回行情数据
return df_price
#获取交易数据结果
def trede():
monthdate=tradedate(start='20180101',end='20190630',n=7)
for current in monthdate:
shortdata,longdata=check_seed(current)
df1=contract(current,shortdata)
df2=contract(current,longdata)
#因为有的月份数据没有,我被聚宽坑惨了,
if df1.shape[0]!=0 and df2.shape[0]!=0:
#获取合约交割日期
expire_date=df1['expire_date'][0]
#获取合约代码
shortcode=df1['code'][0]
longcode=df2['code'][0]
#获取日行情数据
df_price1=quotation(current,shortcode,expire_date)
df_price2=quotation(current,longcode,expire_date)
#因为有的月份数据缺失,所有需要判断
if df_price1.shape[0]!=0 and df_price2.shape[0]!=0:
a=df_price1.close[0]
b=df_price2.close[0]
num=int(b/a)
c=a*10000*num
c=round(c,2)
d=b*10000
d=round(d,2)
ct=current.strftime('%Y-%m-%d')#时间格式转换
opentrade_s.append({'date':ct,'so':c})
opentrade_l.append({'date':ct,'lo':d})
#卖出条件,盘中最高价涨10倍,收盘涨5倍,到期前两天
for i in range(len(df_price1)-2):
if df_price1.high[i]>10*a:
x=round(df_price1.high[i]*10000*num)
y=round(df_price2.high[i]*10000)
closetrade_s.append({'date':ct,'sc':x})
closetrade_l.append({'date':ct,'lc':y})
break
elif df_price1.close[i]>5*a or i==len(df_price1)-3:
x=round(df_price1.close[i]*10000*num)
y=round(df_price2.close[i]*10000)
closetrade_s.append({'date':ct,'sc':x})
closetrade_l.append({'date':ct,'lc':y})
break
s_1=pd.DataFrame(opentrade_s)
s_2=pd.DataFrame(closetrade_s)
l_1=pd.DataFrame(opentrade_l)
l_2=pd.DataFrame(closetrade_l)
#合并数据表
#fally=pd.concat([s_1,s_2,l_1,l_2],axis=1,ignore_index=True)
fally=s_1.merge(s_2,on='date')
fally=fally.merge(l_1,on='date')
fally=fally.merge(l_2,on='date')
return fally
if __name__=='__main__':
fally=trede()
fally['share']=fally['sc']+fally['lc']-fally['so']-fally['lo']
fally['profit']=fally.share.cumsum()
print(fally)
plt.figure()
plt.plot(fally.date,fally.profit,label='profit')
plt.plot(fally.date,fally.share,color='red',linewidth=1.0,linestyle='--',label='share')
plt.legend(loc='best')#打印图例
plt.xlabel('日期')
plt.ylabel('元')
plt.show()
获取每个月的第n个交易日的日期 date so sc lo lc share profit 0 2018-01-10 2178.0 24926.0 2180.0 1777.0 22345.0 22345.0 1 2018-03-09 2590.0 175.0 2615.0 4211.0 -819.0 21526.0 2 2018-04-12 3135.0 495.0 3149.0 3871.0 -1918.0 19608.0 3 2018-05-10 2552.0 290.0 2560.0 2144.0 -2678.0 16930.0 4 2018-06-11 2241.0 249.0 2267.0 2819.0 -1440.0 15490.0 5 2018-07-10 2262.0 858.0 2270.0 1814.0 -1860.0 13630.0 6 2018-08-09 2407.0 87.0 2434.0 3319.0 -1435.0 12195.0 7 2018-09-11 2646.0 540.0 2692.0 1915.0 -2883.0 9312.0 8 2018-10-16 2379.0 1464.0 2390.0 2319.0 -986.0 8326.0 9 2018-11-09 3404.0 230.0 3432.0 3355.0 -3251.0 5075.0 10 2018-12-11 2133.0 395.0 2142.0 3046.0 -834.0 4241.0 11 2019-01-10 1974.0 1128.0 1984.0 1539.0 -1291.0 2950.0 12 2019-02-18 1960.0 1862.0 1989.0 1821.0 -266.0 2684.0 13 2019-03-11 2717.0 780.0 2776.0 2515.0 -2198.0 486.0 14 2019-05-14 3072.0 1152.0 3084.0 2918.0 -2086.0 -1600.0 15 2019-06-12 2415.0 11865.0 2444.0 1792.0 8798.0 7198.0
本社区仅针对特定人员开放
查看需注册登录并通过风险意识测评
5秒后跳转登录页面...
移动端课程