-
Notifications
You must be signed in to change notification settings - Fork 218
/
豆粕期权长期做空虚值期权策略 Soymeal Options Short OTM Long Term
177 lines (149 loc) · 6.13 KB
/
豆粕期权长期做空虚值期权策略 Soymeal Options Short OTM Long Term
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
# coding:utf-8
#!/usr/bin/env python
from PoboAPI import *
import datetime
import time
import numpy as np
#用poboquant python实现,在poboquant上运行,如果有问题 可加群 726895887 咨询
#开始时间,用于初始化一些参数
def OnStart(context) :
print "I\'m starting..."
#设定一个全局变量品种
#g.code = GetMainContract('DCE','m',20)
#print '豆粕主力:' + str(g.code)
#订阅实时数据,用于驱动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 OnMarketQuotationInitialEx(context, exchange,daynight):
if exchange <> "DCE" and daynight<>'night':
return
g.code = GetMainContract('DCE','m',20)
SubscribeBar(g.code, BarType.Day)
print "g.code "+str(g.code)
def Getop(code):
print "code is " +str(code)
#g.code = GetMainContract('DCE','m',20)
#print '豆粕主力:' + str(g.code)
dyndata = GetQuote(code)
now1 = dyndata.now
now50 = round(now1/100,0)*100 + 200 #取虚值四档
print "strike price "+str(now50)
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(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 = cutim#int(cutim)
# n = kill - cu
# return n
#实时行情事件,当有新行情出现时调用该事件
#def OnQuote(context, code) :
def OnBar(context,code,bartype):
g.code = GetMainContract('DCE','m',20)
print '豆粕主力:' + str(g.code)
#过滤掉不需要的行情通知
if code != g.code :
print "code checking ..."+str(code)+" "+str(g.code)
#return
code=g.code #处理主力合约切换的问题,也许有更好的写法
#获取最新行情
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 "持仓数量: " +str(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.17:
opc,opp = Getop(g.code)
print "目标call" + str(opc) + " 目标put " + str(opp)
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, 100)
context.myacc.InsertOrder(opp, BSType.SellOpen, dynp.now, 100)
if len(posi)==1:#出现瘸腿
print "需要平仓瘸腿 "
context.myacc.InsertOrder(posi[0].contract, BSType.BuyClose, GetQuote(posi[0].contract).now+20, posi[0].volume)
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 = GetTradingDayLeft(opcode1)
print str(pr1) + '行权价格'
print str(pr2) + '行权价格2'
print sy
if sy<2: #平仓的时间条件
context.myacc.InsertOrder(opcode1, BSType.BuyClose, dyn1.now+10, 100)
context.myacc.InsertOrder(opcode2, BSType.BuyClose, dyn2.now+10, 100)
elif now1 >= pr1+300 or now1 <= (pr1-300): #平仓价格条件
context.myacc.InsertOrder(opcode1, BSType.BuyClose, dyn1.now+10, 100)
context.myacc.InsertOrder(opcode2, BSType.BuyClose, dyn2.now+10, 100)
UnsubscribeAllBar() #退订所有k线,避免重复订阅
#委托回报事件,当有委托回报时调用
def OnOrderChange(context, AccountName, order) :
#打印委托信息,id是编号,volume是数量,详细见API文档
print "委托编号: " + order.id + " 账号名称: " + AccountName
print "Vol: " + str(order.volume) + " Price: " + str(order.price)
def GetTradingDayLeft(code):
import re
m=re.match(r'[a-z]+[0-9]+\.+[A-Z]',code)
if m:
info=GetContractInfo(code)
T=info['最后交易日']
exchange=GetExchangeByCode(code)
t=GetCurrentTradingDate(exchange)
return (T-t).days
else:
info=GetContractInfo(code)
T=info['行权到期日']
exchange=GetExchangeByCode(code)
t=GetCurrentTradingDate(exchange)
return (T-t).days