· 6 years ago · Feb 04, 2020, 03:44 AM
1#!/usr/bin/env python
2# coding: utf-8
3
4# In[ ]:
5
6
7from sympy import symbols, Eq, solve
8import numpy as np
9from bitmex import bitmex
10import operator
11import json
12import pprint
13import sys
14
15if not sys.warnoptions:
16 import warnings
17 warnings.simplefilter("ignore")
18
19bitmex_api_key = '' #Input your API Key here
20bitmex_api_secret = '' #Input your API Secret here
21bitmex_client = bitmex(test=False, api_key=bitmex_api_key, api_secret=bitmex_api_secret)
22
23
24# In[ ]:
25
26
27while True:
28 try:
29 current_contracts = bitmex_client.Instrument.Instrument_getActive().result()[0]
30 current_contracts = [sub['symbol'] for sub in current_contracts]
31 contractsDict = {k: v for k, v in enumerate(current_contracts)}
32 print('Choose contract index to trade based on the following list' + '\n')
33 for k, v in contractsDict.items():
34 print(k, ': ', v)
35 contract = input()
36 contract = contractsDict[int(contract)]
37 print('Contract selected: ' + str(contract) + '\n')
38 except (IndexError, ValueError):
39 print('Contract selection must be a number. Try again')
40 continue
41 else:
42 break
43while True:
44 try:
45 order_types = {0:'Market', 1:'Limit'}
46 order_type = int(input('Choose order_type index for entry' + '\n' + str(order_types) + '\n'))
47 order_type = order_types[order_type]
48 print('Entry Order Type: ' + str(order_type))
49 except (IndexError, ValueError):
50 print('Entry Order Type selection must be a number 0-1. Try Again')
51 continue
52 else:
53 break
54while True:
55 try:
56 stop = float(input('Stop Market Price: '))
57 except ValueError:
58 print('Stop must be a number. Try Again')
59 continue
60 else:
61 break
62while True:
63 try:
64 target = float(input('Target Close Price: '))
65 except ValueError:
66 print('Target must be a number. Try Again')
67 continue
68 else:
69 break
70while True:
71 try:
72 active_contracts = list(range(0, len(contractsDict)))
73 for x in active_contracts:
74 if contract == contractsDict[x]:
75 contract_data = bitmex_client.Instrument.Instrument_getActive().result()[0]
76 contract_data = next(item for item in contract_data if item["symbol"] == str(contractsDict[x]))
77 tick_size = float(contract_data["tickSize"])
78 bidPrice = float(contract_data['bidPrice'])
79 askPrice = float(contract_data['askPrice'])
80 makerFee = float(contract_data['makerFee'])
81 takerFee = float(contract_data['takerFee'])
82 if contract == 'XRPUSD':
83 multiplier = float((contract_data['quoteToSettleMultiplier'])/100000000)
84 elif contract == 'ETHUSD':
85 multiplier = float((contract_data['quoteToSettleMultiplier'])/10000000000)
86 if order_type == 'Limit':
87 entry = float(input('Limit Entry Price: '))
88 else:
89 if stop > target:
90 entry = bidPrice
91 else:
92 entry = askPrice
93 except ValueError:
94 print('Entry must be a number. Try Again')
95 continue
96 else:
97 break
98while True:
99 try:
100 risk = float(input('BTC Risk Percentage. Or 0 for 1x Short: '))/100
101 if risk == 0:
102 risk = (stop - entry) / entry
103 else:
104 None
105 except ValueError:
106 print('Risk must be expressed as integer or float. I.e. 3% is 3. 0.5% is 0.5. Or choose 0 for 1x Short')
107 continue
108 else:
109 break
110balance = bitmex_client.User.User_getWalletHistory().result()[0][0]['walletBalance']/100000000
111
112
113# In[ ]:
114
115
116multiplier
117
118
119# In[ ]:
120
121
122def position_size(entry, stop, balance, risk):
123 x = symbols('x')
124 if contract[:3]=='XBT':
125 if target > entry:
126 target_value = (1/target)+((1/target)*takerFee)
127 stop_value = (1/stop)+((1/stop)*takerFee)
128 if order_type == 'Limit':
129 entry_value = (1/entry)-((1/entry)*makerFee)
130 eq1 = Eq((x*(entry_value - stop_value)) + (balance*risk))
131 else:
132 entry_value = (1/entry)-((1/entry)*takerFee)
133 eq1 = Eq((x*(entry_value - stop_value)) + (balance*risk))
134 elif target < entry:
135 target_value = (1/target)-((1/target)*takerFee)
136 stop_value = (1/stop)-((1/stop)*takerFee)
137 if order_type == 'Limit':
138 entry_value = (1/entry)+((1/entry)*makerFee)
139 eq1 = Eq((x*(stop_value - entry_value)) - (balance*risk))
140 else:
141 entry_value = (1/entry)+((1/entry)*takerFee)
142 eq1 = Eq((x*(stop_value - entry_value)) - (balance*risk))
143 size = solve(eq1)
144 size = [ '%.0f' % elem for elem in size ]
145 size = size[0]
146 return size, entry_value, stop_value, target_value
147
148 elif contract == 'XRPUSD' or contract == 'ETHUSD':
149 if target > entry:
150 target_value = (target*multiplier)-((target*multiplier)*takerFee)
151 stop_value = (stop*multiplier)-((stop*multiplier)*takerFee)
152 if order_type == 'Limit':
153 entry_value = (entry*multiplier)+((entry*multiplier)*makerFee)
154 eq1 = Eq(((entry_value - stop_value)*x) - (balance*risk))
155 else:
156 entry_value = (entry*multiplier)+((entry*multiplier)*takerFee)
157 eq1 = Eq(((entry_value - stop_value)*x) - (balance*risk))
158 elif target < entry:
159 target_value = (target*multiplier)+((target*multiplier)*takerFee)
160 stop_value = (stop*multiplier)+((stop*multiplier)*takerFee)
161 if order_type == 'Limit':
162 entry_value = (entry*multiplier)-((entry*multiplier)*makerFee)
163 eq1 = Eq(((stop_value - entry_value)*x) + (balance*risk))
164 else:
165 entry_value = (entry*multiplier)-((entry*multiplier)*takerFee)
166 eq1 = Eq(((stop_value - entry_value)*x) + (balance*risk))
167 size = solve(eq1)
168 size = [ '%.0f' % elem for elem in size ]
169 size = size[0]
170 return size, entry_value, stop_value, target_value
171
172 elif contract[:3]!='XBT' and contract[3:]!='USD':
173 if target > entry:
174 if order_type == 'Limit':
175 eq1 = Eq(((entry*x)+((entry*x)*makerFee)) - ((stop*x)-((stop*x)*takerFee)) - (balance*risk))
176 else:
177 eq1 = Eq(((entry*x)+((entry*x)*takerFee)) - ((stop*x)-((stop*x)*takerFee)) - (balance*risk))
178 else:
179 if order_type == 'Limit':
180 eq1 = Eq(((entry*x)-((entry*x)*makerFee)) - ((stop*x)+((stop*x)*takerFee)) - (balance*risk))
181 else:
182 eq1 = Eq(((entry*x)-((entry*x)*takerFee)) - ((stop*x)+((stop*x)*takerFee)) - (balance*risk))
183
184 size = solve(eq1)
185 size = [ '%.0f' % elem for elem in size ]
186 return size
187
188
189# In[ ]:
190
191
192position_size = position_size(entry, stop, balance, risk)
193size = int(position_size[0])
194if contract[:3]=='XBT' or contract[3:]=='USD':
195 entry_value = float(position_size[1])
196 stop_value = float(position_size[2])
197 target_value = float(position_size[3])
198
199
200# In[ ]:
201
202
203size
204
205
206# In[ ]:
207
208
209def risk_amount_XBT(entry_value, stop_value, size):
210 risk_amount = (size*(entry_value - stop_value))
211 risk_amount = float(round(risk_amount, 8))
212 return risk_amount
213
214def risk_amount_ETH_XRP(entry, stop, multiplier, size):
215 risk_amount = (entry - stop) * multiplier * size
216 risk_amount = float(round(risk_amount, 8))
217 return risk_amount
218
219def risk_amount_alt(entry, stop, size):
220 if target > entry: #Calculate long alt risk_amount
221 if order_type == 'Limit':
222 risk_amount = ((entry*size)+((entry*size)*makerFee)) - ((stop*size)-((stop*size)*takerFee))
223 else:
224 risk_amount = ((entry*size)+((entry*size)*takerFee)) - ((stop*size)-((stop*size)*takerFee))
225 risk_amount = float(round(risk_amount, 8))
226 return risk_amount
227
228 else: #Calculate short alt risk_amount
229 if order_type == 'Limit':
230 risk_amount = ((stop*size)+((stop*size)*takerFee)) - ((entry*size)-((entry*size)*makerFee))
231 else:
232 risk_amount = ((stop*size)+((stop*size)*takerFee)) - ((entry*size)-((entry*size)*takerFee))
233 risk_amount = float(round(risk_amount, 8))
234 return risk_amount
235
236
237# In[ ]:
238
239
240if contract[:3]!='XBT' and contract[3:]!='USD':
241 risk_amount = risk_amount_alt(entry, stop, size)*-1
242 if target > entry:
243 risk_amount = risk_amount*-1
244
245elif contract[:3]=='XBT':
246 risk_amount = risk_amount_XBT(entry_value, stop_value, size)*-1
247
248elif contract == 'ETHUSD' or contract == 'XRPUSD':
249 risk_amount = risk_amount_ETH_XRP(entry, stop, multiplier, size)
250
251
252# In[ ]:
253
254
255def reward_amount_XBT(entry_value, target_value, size):
256 reward_amount = (size*(target_value - entry_value))
257 reward_amount = float(round(reward_amount, 8))
258 return reward_amount
259
260def reward_amount_ETH_XRP(entry, target, multiplier, size):
261 reward_amount = (entry - target) * multiplier * size
262 reward_amount = float(round(reward_amount, 8))
263 return reward_amount
264
265def reward_amount_alt(entry, target, size):
266 if target < entry: #Calculate short alt reward_amount
267 if order_type == 'Limit':
268 reward_amount = ((size*target-((size*target)*makerFee)) - ((size*entry)+((size*entry)*makerFee)))
269 else:
270 reward_amount = ((size*target-((size*target)*makerFee)) - ((size*entry)-((size*entry)*takerFee)))
271 reward_amount = float(round(reward_amount, 8))
272 return reward_amount
273
274 else: #Calculate long alt reward_amount
275 if order_type == 'Limit':
276 reward_amount = ((size*entry-((size*entry)*makerFee)) - ((size*target)+((size*target)*makerFee)))
277 else:
278 reward_amount = ((size*entry+((size*entry)*takerFee)) - ((size*target)+((size*target)*makerFee)))
279 reward_amount = float(round(reward_amount, 8))
280 return reward_amount
281
282
283# In[ ]:
284
285
286if contract[:3]!='XBT' and contract[3:]!='USD':
287 reward_amount = reward_amount_alt(entry, target, size)
288 if target > entry:
289 reward_amount = reward_amount*-1
290
291elif contract[:3]=='XBT':
292 reward_amount = reward_amount_XBT(entry_value, target_value, size)*-1
293
294elif contract == 'ETHUSD' or contract == 'XRPUSD':
295 reward_amount = reward_amount_ETH_XRP(entry, target, multiplier, size)*-1
296
297
298# In[ ]:
299
300
301def r(reward_amount, risk_amount):
302 r_r = reward_amount/risk_amount
303 return r_r
304
305
306# In[ ]:
307
308
309r_r = r(reward_amount, risk_amount)
310r_r = format(r_r, '.2f')
311
312
313# In[ ]:
314
315
316def breakeven_XBT(entry_value, takerFee):
317 y = symbols('y')
318 eq2 = Eq(((1/y)+((1/y)*takerFee)) - entry_value)
319 if target < entry:
320 eq2 = Eq(((1/y)-((1/y)*takerFee)) - entry_value)
321 breakeven = solve(eq2)
322 breakeven = [ '%.2f' % elem for elem in breakeven ]
323 return breakeven
324
325def breakeven_ETH_XRP(entry_value, takerFee, multiplier, size):
326 y = symbols('y')
327 eq2 = Eq((entry_value-((y*multiplier)-((y*multiplier)*takerFee)))*size)
328 if target < entry:
329 eq2 = Eq((entry_value-((y*multiplier)+((y*multiplier)*takerFee)))*size)
330 breakeven = solve(eq2)
331 if contract == 'ETHUSD':
332 breakeven = [ '%.2f' % elem for elem in breakeven ]
333 else:
334 breakeven = [ '%.4f' % elem for elem in breakeven ]
335 return breakeven
336
337def breakeven_alt(entry, takerFee, makerFee, size):
338 y = symbols('y')
339 if order_type == 'Limit':
340 eq2 = Eq((size*entry-((size*entry)*makerFee)) - ((size*y)-((size*y)*takerFee)))
341 else:
342 eq2 = Eq((size*entry+((size*entry)*takerFee)) - ((size*y)-((size*y)*takerFee)))
343 breakeven = solve(eq2)
344 breakeven = [ '%.8f' % elem for elem in breakeven ]
345 return breakeven
346
347
348# In[ ]:
349
350
351if contract[:3]!='XBT' and contract[3:]!='USD':
352 breakeven = breakeven_alt(entry, takerFee, makerFee, size)[0]
353
354elif contract[:3]=='XBT':
355 breakeven = breakeven_XBT(entry_value, takerFee)[0]
356
357elif contract == 'ETHUSD' or contract == 'XRPUSD':
358 breakeven = breakeven_ETH_XRP(entry_value, takerFee, multiplier, size)[0]
359
360
361# In[ ]:
362
363
364loss_final_balance = balance - risk_amount
365loss_final_balance = round(loss_final_balance, 8)
366win_final_balance = balance + reward_amount
367win_final_balance = round(win_final_balance, 8)
368starting_usd = balance*entry
369starting_usd = round(starting_usd, 2)
370winning_usd = win_final_balance*target
371winning_usd = round(winning_usd, 2)
372losing_usd = loss_final_balance*stop
373losing_usd = round(losing_usd, 2)
374risk_amount = format(risk_amount, '.8f')
375reward_amount = format(reward_amount, '.8f')
376
377if target < entry:
378 direction = 'Short'
379else:
380 direction = 'Long'
381
382risk_percentage = str((risk*100))+'%'
383
384if contract[:3]!='XBT' and contract[3:]!='USD':
385 entry_print = format(entry, '.8f')
386 stop_print = format(stop, '.8f')
387 target_print = format(target, '.8f')
388 breakeven_print = breakeven
389
390
391message = f"""
392Contract: {contract}
393Direction: {direction}
394BTC Percent Risk: {risk_percentage}
395Size: {size}
396"""
397if contract[:3]=='XBT' or contract[3:]=='USD':
398 message_1 = f"""Entry: {entry}
399Stop: {stop}
400Target: {target}
401Risk: {risk_amount} BTC
402Reward: {reward_amount} BTC
403R: {r_r}
404Breakeven: {breakeven}
405"""
406else:
407 message_1 = f"""Entry: {entry_print}
408Stop: {stop_print}
409Target: {target_print}
410Risk: {risk_amount} BTC
411Reward: {reward_amount} BTC
412R: {r_r}
413Breakeven: {breakeven}
414"""
415if contract.find('XBT')==0:
416 message_2 = f"""Starting Balance: {balance} / ${starting_usd}
417Winning Balance: {win_final_balance} / ${winning_usd}
418Losing Balance: {loss_final_balance} / ${losing_usd}
419"""
420else:
421 message_2 = f"""Starting Balance: {balance}
422Winning Balance: {win_final_balance}
423Losing Balance: {loss_final_balance}
424"""
425print(message+message_1+message_2)
426
427
428# In[ ]:
429
430
431def initiate_trade(contract, size, entry, target, stop):
432 if order_type == order_types[0]:
433 entry_placement = bitmex_client.Order.Order_new(symbol=contract, orderQty=size, ordType='Market').result()
434 else:
435 entry_placement = bitmex_client.Order.Order_new(symbol=contract, orderQty=size, price=entry).result()
436
437 exit_placement = bitmex_client.Order.Order_new(symbol=contract, stopPx=target, execInst='LastPrice', orderQty=(size*-1), ordType='MarketIfTouched').result()
438 stop_placement = bitmex_client.Order.Order_new(symbol=contract, stopPx=stop, execInst='LastPrice', orderQty=(size*-1), ordType='Stop').result()
439
440
441# In[ ]:
442
443
444while True:
445 try:
446 trade_execution = int(input('Do you wish to take this trade? 0:Yes, 1:No' + '\n'))
447 if trade_execution == 0:
448 initiate_trade(contract, size, entry, target, stop)
449 print('TRADE EXECUTED')
450 else:
451 print('TRADE NOT EXECUTED')
452 except ValueError:
453 print('Selection must be a number 0-1. Try Again')
454 continue
455 else:
456 break