-
Notifications
You must be signed in to change notification settings - Fork 218
/
铜期权波动率策略CopperOptVolaTrade
293 lines (226 loc) · 10.9 KB
/
铜期权波动率策略CopperOptVolaTrade
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
#!/usr/bin/env python
# coding:utf-8
from PoboAPI import *
import datetime
import time
import numpy as np
# SetTradeLogLevel(53,255)
# SetTradeLogLevel(54,255)
# SetTradeLogLevel(55,255)
#日线级别
#开始时间,用于初始化一些参数
def OnStart(context) :
# Emucounter2
print "I\'m starting..."
#设定一个全局变量品种
#g.code = GetMainContract("shfe","cu",20)#取铜主力合约
#订阅实时数据,用于驱动OnQuote事件
# print"underlying "+str(g.code)
# SubscribeQuote(g.code)
#订阅K线数据,用于驱动OnBar事件
#SubscribeBar(g.code, BarType.Day)
#登录交易账号,需在主页用户管理中设置账号,并把证券测试替换成您的账户名称
g.targetpos=20 #目标开仓手数
g.oppos1,g.oppos2=0,0 #初始化持仓数量
g.openflag=0 #允许补仓开仓状态变量,为0不开仓,为1开仓
context.myacc = None
if context.accounts.has_key("回测期货") :
print "登录交易账号[回测期货]"
if context.accounts["回测期货"].Login() :
context.myacc = context.accounts["回测期货"]
def OnMarketQuotationInitialEx(context, exchange,daynight):
if exchange == 'SHFE':# and daynight == 'night':
print '上期所 开盘时重登交易账号'
context.myacc.Logout()
context.myacc.Login()
g.code=GetFutwithOPT(context,"cu","SHFE")#根据成交量获取带有期权的期货合约,用于订阅行情
print "in market ini "+str(g.code)
#SubscribeBar(g.code, BarType.Day)
SubscribeBar(g.code, BarType.Day)
def GetFutwithOPT(context,productcode,exchangecode):
#返回一个带有期权的期货合约
futlist=RankingContract(context,exchangecode,productcode,2) #RankingContract(context,exchangecode,productcode,RankingCriteria)
#[contract, oi,volume]
found=0
for i in futlist:
print"in func i[0] "+str(i[0])
option = PBObj()
option.EndDate = GetCurrentTime()
option.Count = 60
klinedata = GetHisData(i[0], BarType.Day, option)
if GetOptionContracts(i[0],None,2) and len(klinedata)==60:
print "target contract "+str(i[0])
return i[0]
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)
#获取某档位期权合约GetAtmOptionContractByPos ( object_stock_code, pricetype,position, option_type, excute_date = None )
atmopc=GetAtmOptionContractByPos( g.code, "now", -2, 0, None )
atmopp=GetAtmOptionContractByPos( g.code, "now", -2, 1, None )
print "for test "+str(atmopc)+" and "+str(atmopp)
return atmopc,atmopp
# def OnExchangeOpen(context, accountname, exchangecode, productcode):
# context.accounts["回测期货"].Logout()
# context.accounts["回测期货"].Login()
# #context.accounts["回测期权"].SetAutoRelogin(datetime.time(8, 50))
# print "账户重登录"
# # if context.accounts.has_key("回测期权") :
# # print "登录交易账号[回测期权]"
# # if context.accounts["回测期权"].Login() :
# # context.myacc = context.accounts["回测期权"]
# print "in function-------------"
# print "exchangecode "+str(exchangecode)
# if exchangecode=='SHFE':
# cuttime=GetCurrentTime()
# print "检验时间"
# if str(cuttime)[12:]=="9:00:00":
# print "上期所开盘"
def stime(op):
info1 = GetContractInfo(op)
kill = info1['行权到期日']
cutime = GetCurrentTime()
c = cutime.date()
n = (kill - c).days
print n
return n
#实时行情事件,当有新行情出现时调用该事件
#def OnQuote(context, code) :
def OnBar(context,code,bartype):
#过滤掉不需要的行情通知
if code != g.code :
return
print "in onbar "+str(g.code)
#获取最新行情
# cuttime=GetCurrentTime()
# print "检验时间"
# if str(cuttime)[12:]=="9:30:00":
# print "中金所开盘"
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)
print "to cal hv"
b = CreateCalcObj()
option = PBObj()
option.EndDate = GetCurrentTime()
option.Count = 60
#获取60天
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
opc,opp = Getop(g.code)
print "for test "+str(opc)+" and "+str(opp)
if len(posi) == 0 and c<0.35:
g.openflag=1
opc,opp = Getop(g.code)
g.opcode1,g.opcode2=opc,opp #用全局变量进行ontradedeal持仓检查
print str(opc)
dync = GetQuote(opc)
dynp = GetQuote(opp)
if dync != None and dync.now>0 and dynp.now>0:
log.info("最新价2: " + str(dync.now))
log.info("最新价3: " + str(dynp.now))
context.myacc.InsertOrder(opc, BSType.SellOpen, dync.now, 20)
context.myacc.InsertOrder(opp, BSType.SellOpen, dynp.now, 20)
elif len(posi) >0:
print "有持仓 "+str(len(posi))
if len(posi)<2 :#出现单腿
opcode1 = posi[0].contract
dyn1 = GetQuote(opcode1)
if dyn1.now>0:
context.myacc.InsertOrder(opcode1, BSType.BuyClose, dyn1.now, posi[0].volume)
if len(posi)==2:
opcode1 = posi[0].contract
opcode2 = posi[1].contract
g.opcode1,g.opcode2=opcode1,opcode2 #用全局变量进行ontradedeal持仓检查
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
print "距离到期日-----"+str(sy)
if sy<5 and dyn1.now>0 and dyn2.now>0 : #到期平仓
print "合约接近到期平仓-----------------------------------"
g.openflag=0 #需要平仓时不可补仓
print str(opcode1)+"期权第一腿 高:"+str(dyn1.high)+" 低价 "+str(dyn1.low)+" 成交量 "+str(dyn1.volume)
print str(opcode2)+"期权第二腿 高:"+str(dyn2.high)+" 低价 "+str(dyn2.low)+" 成交量 "+str(dyn2.volume)
print "第一腿委托价格 "+str(dyn1.now)+" 第二腿委托价格 "+str(dyn2.now)
context.myacc.InsertOrder(opcode1, BSType.BuyClose, dyn1.now, posi[0].volume)
context.myacc.InsertOrder(opcode2, BSType.BuyClose, dyn2.now, posi[1].volume)
elif now1 >= pr1 or now1 <= (pr1-500*5) and dyn1.now>0 and dyn2.now>0:
print "合约止盈止损平仓-----------------------------------"
g.openflag=0 #需要平仓时不可补仓
context.myacc.InsertOrder(opcode1, BSType.BuyClose, dyn1.now, posi[0].volume)
context.myacc.InsertOrder(opcode2, BSType.BuyClose, dyn2.now, posi[1].volume)
print "g.openflag "+str(g.openflag)
if g.openflag==1 and (posi[0].volume<g.targetpos or posi[1].volume<g.targetpos): #未达到开仓目标量、两腿没配齐时进行补仓
print "需要补仓 -------- "+str(posi[0].volume)+" "+str(posi[1].volume)
if g.targetpos-posi[0].volume>0 and dyn1.now>0:
context.myacc.InsertOrder(opcode1, BSType.SellOpen, dyn1.now,g.targetpos-posi[0].volume)
if g.targetpos-posi[1].volume>0 and dyn2.now>0:
context.myacc.InsertOrder(opcode2, BSType.SellOpen, dyn2.now,g.targetpos-posi[1].volume)
bal=context.accounts["回测期货"].AccountBalance
print "账户权益检查-------------- "+str(bal.DynamicNetAssets)
print "账户风险度 ---------------"+str(bal.RiskDegree)
#委托回报事件,当有委托回报时调用
def OnOrderChange(context, AccountName, order) :
#打印委托信息,id是编号,volume是数量,详细见API文档
print "委托编号: " + order.id + " 账号名称: " + AccountName
print "Vol: " + str(order.volume) + " Price: " + str(order.price)
def RankingContract(context,exchangecode,productcode,RankingCriteria):#exchangecode like "SHFE",productcode like "rb",RankingCriteria:1 for ranked by open interests,2 for ranking by trading volume
contractlist=GetFuturesContracts(exchangecode,productcode) #获取主力合约排名
contractlist={}.fromkeys(contractlist).keys()
Rankedcontractlist=[]
n=0
if RankingCriteria==1: # to rank by open interests
n=1
if RankingCriteria==2: # to rank by volume
n=2
for i in contractlist:
#print str(i)
dyndatacontract=GetQuote(i)
volume=dyndatacontract.volume
openinterest=dyndatacontract.amount
datatime=dyndatacontract.time
#print "volume"+str(volume)
#print "openinterest"+str(openinterest)
#print "data time "+str(datatime)
Rankedcontractlist.append([i,openinterest,volume])
ResultList=sorted(Rankedcontractlist, key=lambda Rankedcontractlist:(Rankedcontractlist[n]),reverse=True)
return ResultList
def OnTradeDeal(context,AccountName,trade):
posi = context.myacc.GetPositions()
if len(posi)>0:
for i in posi:
if i.contract==g.opcode1 and i.volume>0:
g.oppos1=i.volume
if i.contract==g.opcode2 and i.volume>0:
g.oppos2=i.volume
if g.oppos1==g.targetpos and g.oppos2==g.targetpos:
g.openflag=0