forked from fmzquant/strategies
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpython版 Dual Thrust OKCoin 期货.py
233 lines (206 loc) · 8.61 KB
/
python版 Dual Thrust OKCoin 期货.py
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
'''
策略出处: https://www.botvs.com/strategy/21856
策略名称: python版 Dual Thrust OKCoin 期货
策略作者: 小小梦
策略描述:
Dual Thrust 策略包含完整的图表显示, 图表动态更新,模板引用等功能, 可做学习模板使用.
参数 默认值 描述
--------------- ----- --------------
ContractTypeIdx 0 合约品种: 当周|次周|季度
MarginLevelIdx 0 杠杆大小: 10|20
NPeriod 4 计算周期
Ks 0.5 上轨系数
Kx 0.5 下轨系数
AmountOP true 开仓合约张数
Interval 2000 重试间隔(毫秒)
LoopInterval 3 轮询间隔(秒)
PeriodShow 500 图表最大显示K线柱数
'''
import time
class Error_noSupport(BaseException):
def __init__(self):
Log("只支持OKCoin期货!#FF0000")
class Error_AtBeginHasPosition(BaseException):
def __init__(self):
Log("启动时有期货持仓! #FF0000")
ChartCfg = {
'__isStock': True,
'title': {
'text': 'Dual Thrust 上下轨图'
},
'yAxis': {
'plotLines': [{
'value': 0,
'color': 'red',
'width': 2,
'label': {
'text': '上轨',
'align': 'center'
},
}, {
'value': 0,
'color': 'green',
'width': 2,
'label': {
'text': '下轨',
'align': 'center'
},
}]
},
'series': [{
'type': 'candlestick',
'name': '当前周期',
'id': 'primary',
'data': []
}, {
'type': 'flags',
'onSeries': 'primary',
'data': []
}]
}
STATE_IDLE = 0
STATE_LONG = 1
STATE_SHORT = 2
State = STATE_IDLE
LastBarTime = 0
UpTrack = 0
BottomTrack = 0
chart = None
InitAccount = None
LastAccount = None
Counter = {
'w': 0,
'l': 0
}
def GetPosition(posType): # if the positions has no this posType ,will return [] ,Another case is return a dict of object
positions = exchange.GetPosition()
return [{'Price': position['Price'], 'Amount': position['Amount']} for position in positions if position['Type'] == posType]
def CancelPendingOrders():
while True:
orders = exchange.GetOrders()
[exchange.CancelOrder(order['Id']) for order in orders if not Sleep(500)]
if len(orders) == 0:
break
def Trade(currentState,nextState):
global InitAccount,LastAccount,OpenPrice,ClosePrice
ticker = _C(exchange.GetTicker)
slidePrice = 1
pfn = exchange.Buy if nextState == STATE_LONG else exchange.Sell
if currentState != STATE_IDLE:
Log(_C(exchange.GetPosition)) # ceshi
exchange.SetDirection("closebuy" if currentState == STATE_LONG else "closesell")
while True:
# ID = pfn( (ticker['Last'] - slidePrice) if currentState == STATE_LONG else (ticker['Last'] + slidePrice), AmountOP) # xiugai 限价单
# ID = pfn(-1, AmountOP) # xiugai 市价单
ID = pfn(AmountOP) # xiugai 市价单
Sleep(Interval)
Log(exchange.GetOrder(ID)) # xiugai
ClosePrice = (exchange.GetOrder(ID))['AvgPrice'] #
CancelPendingOrders()
if len(GetPosition(PD_LONG if currentState == STATE_LONG else PD_SHORT)) == 0:
break
account = exchange.GetAccount()
if account['Stocks'] > LastAccount['Stocks']:
Counter['w'] += 1
else:
Counter['l'] += 1
# Log("ceshi account:",account,InitAccount) #ceshi
Log(account) # xiugai
LogProfit((account['Stocks'] - InitAccount['Stocks']),"收益率:", ((account['Stocks'] - InitAccount['Stocks']) * 100 / InitAccount['Stocks']),'%')
Cal(OpenPrice,ClosePrice)
LsatAccount = account
exchange.SetDirection("buy" if nextState == STATE_LONG else "sell")
Log(_C(exchange.GetAccount))
while True:
# pfn( (ticker['Last'] + slidePrice) if nextState == STATE_LONG else (ticker['Last'] - slidePrice), AmountOP) # 限价单
# ID = pfn(-1, AmountOP) # 市价单
ID = pfn(AmountOP) # 市价单
Sleep(Interval)
Log(exchange.GetOrder(ID)) # xiugai
CancelPendingOrders()
pos = GetPosition(PD_LONG if nextState == STATE_LONG else PD_SHORT)
if len(pos) != 0:
Log("持仓均价",pos[0]['Price'],"数量:",pos[0]['Amount'])
OpenPrice = (exchange.GetOrder(ID))['AvgPrice'] # pos[0]['Price']
Log("now account:",exchange.GetAccount())
break
def onTick(exchange):
global LastBarTime,chart,State,UpTrack,DownTrack,LastAccount
records = exchange.GetRecords()
if not records or len(records) <= NPeriod:
return
Bar = records[-1]
if LastBarTime != Bar['Time']:
HH = TA.Highest(records, NPeriod, 'High')
HC = TA.Highest(records, NPeriod, 'Close')
LL = TA.Lowest(records, NPeriod, 'Low')
LC = TA.Lowest(records, NPeriod, 'Close')
Range = max(HH - LC, HC - LL)
UpTrack = _N(Bar['Open'] + (Ks * Range))
DownTrack = _N(Bar['Open'] - (Kx * Range))
if LastBarTime > 0:
PreBar = records[-2]
chart.add(0, [PreBar['Time'], PreBar['Open'], PreBar['High'], PreBar['Low'], PreBar['Close']], -1)
else:
for i in range(len(records) - min(len(records), NPeriod * 3), len(records)):
b = records[i]
chart.add(0,[b['Time'], b['Open'], b['High'], b['Low'], b['Close']])
chart.add(0,[Bar['Time'], Bar['Open'], Bar['High'], Bar['Low'], Bar['Close']])
ChartCfg['yAxis']['plotLines'][0]['value'] = UpTrack
ChartCfg['yAxis']['plotLines'][1]['value'] = DownTrack
ChartCfg['subtitle'] = {
'text': '上轨' + str(UpTrack) + '下轨' + str(DownTrack)
}
chart.update(ChartCfg)
chart.reset(PeriodShow)
LastBarTime = Bar['Time']
else:
chart.add(0,[Bar['Time'], Bar['Open'], Bar['High'], Bar['Low'], Bar['Close']], -1)
LogStatus("Price:", Bar["Close"], "up:", UpTrack, "down:", DownTrack, "wins:", Counter['w'], "losses:", Counter['l'], "Date:", time.time())
msg = ""
if State == STATE_IDLE or State == STATE_SHORT:
if Bar['Close'] >= UpTrack:
msg = "做多,触发价:" + str(Bar['Close']) + "上轨" + str(UpTrack)
Log(msg)
Trade(State, STATE_LONG)
State = STATE_LONG
chart.add(1,{'x': Bar['Time'], 'color': 'red', 'shape': 'flag', 'title': '多', 'text': msg})
if State == STATE_IDLE or State == STATE_LONG:
if Bar['Close'] <= DownTrack:
msg = "做空,触发价:" + str(Bar['Close']) + "下轨" + str(DownTrack)
Log(msg)
Trade(State, STATE_SHORT)
State = STATE_SHORT
chart.add(1,{'x': Bar['Time'], 'color': 'green', 'shape': 'circlepin', 'title': '空', 'text': msg})
OpenPrice = 0
ClosePrice = 0
def Cal(OpenPrice, ClosePrice):
global AmountOP,State
if State == STATE_SHORT:
Log(AmountOP,OpenPrice,ClosePrice,"策略盈亏:", (AmountOP * 100) / ClosePrice - (AmountOP * 100) / OpenPrice, "个币, 手续费:", - (100 * AmountOP * 0.0003), "美元,折合:", _N( - 100 * AmountOP * 0.0003/OpenPrice,8), "个币")
Log(((AmountOP * 100) / ClosePrice - (AmountOP * 100) / OpenPrice) + (- 100 * AmountOP * 0.0003/OpenPrice))
if State == STATE_LONG:
Log(AmountOP,OpenPrice,ClosePrice,"策略盈亏:", (AmountOP * 100) / OpenPrice - (AmountOP * 100) / ClosePrice, "个币, 手续费:", - (100 * AmountOP * 0.0003), "美元,折合:", _N( - 100 * AmountOP * 0.0003/OpenPrice,8), "个币")
Log(((AmountOP * 100) / OpenPrice - (AmountOP * 100) / ClosePrice) + (- 100 * AmountOP * 0.0003/OpenPrice))
def main():
global LoopInterval,chart,LastAccount,InitAccount
if exchange.GetName() != 'Futures_OKCoin':
raise Error_noSupport
exchange.SetRate(1)
exchange.SetContractType(["this_week","next_week","quarter"][ContractTypeIdx])
exchange.SetMarginLevel([10,20][MarginLevelIdx])
Log("Fee:",exchange.GetFee())
if len(exchange.GetPosition()) > 0:
raise Error_AtBeginHasPosition
CancelPendingOrders()
InitAccount = LastAccount = exchange.GetAccount()
LoopInterval = min(1,LoopInterval)
Log("交易平台:",exchange.GetName(), InitAccount)
LogStatus("Ready...")
LogProfitReset()
chart = Chart(ChartCfg)
chart.reset()
LoopInterval = max(LoopInterval, 1)
while True:
onTick(exchange)
Sleep(LoopInterval * 1000)