-
Notifications
You must be signed in to change notification settings - Fork 5
/
trader.py
192 lines (139 loc) · 7.13 KB
/
trader.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
import math
from BinanceAPI import BinanceAPI
class trader():
commission = 0.002
def __init__(self):
self.API = BinanceAPI()
def filters(self, symbol):
# Get symbol exchange info
symbol_info = self.API.get_exchange_info(symbol)
if not symbol_info:
print('Invalid symbol, please try again...')
exit(1)
symbol_info['filters'] = {item['filterType']: item for item in symbol_info['filters']}
return symbol_info
def format_step(self, quantity, stepSize):
return float(stepSize * math.floor(float(quantity)/stepSize))
def validate(self, symbol, quantity):
valid = True
filters = self.filters(symbol)['filters']
lastBid, lastAsk = self.get_market_price(symbol)
lastPrice = self.API.get_ticker(symbol)
minQty = float(filters['LOT_SIZE']['minQty'])
minPrice = float(filters['PRICE_FILTER']['minPrice'])
minNotional = float(filters['MIN_NOTIONAL']['minNotional'])
quantity_temp = float(quantity)
# stepSize defines the intervals that a quantity/icebergQty can be increased/decreased by.
stepSize = float(filters['LOT_SIZE']['stepSize'])
# tickSize defines the intervals that a price/stopPrice can be increased/decreased by
tickSize = float(filters['PRICE_FILTER']['tickSize'])
# Just for validation
lastBid = lastBid + tickSize
# Set static
# If quantity or amount is zero, minNotional increase 10%
if quantity_temp == 0:
quantity_temp = (minNotional / lastBid)
quantity_temp = quantity_temp + (quantity_temp * 10 / 100)
notional = minNotional
quantity_temp = self.format_step(quantity_temp, stepSize)
notional = lastBid * float(quantity_temp)
# minQty = minimum order quantity
if quantity_temp < minQty:
print('Invalid quantity, minQty: %.8f (u: %.8f)' % (minQty, quantity_temp))
valid = False
if lastPrice < minPrice:
print('Invalid price, minPrice: %.8f (u: %.8f)' % (minPrice, lastPrice))
valid = False
# minNotional = minimum order value (price * quantity)
if notional < minNotional:
print('Invalid notional, minNotional: %.8f (u: %.8f)' % (minNotional, notional))
valid = False
if not valid:
return 0, 0
return quantity_temp, tickSize
def get_open_trades(self, market):
order = self.API.get_open_trades(market)
return order
def cancel_order(self, market, orderID):
order = self.API.cancel_order(market, orderID)
return order
def get_balance(self, market="BTC"):
balance = self.API.get_balance(market)
return balance
def get_market_price(self, market):
lastBid, lastAsk = self.API.get_market_price(market)
return lastBid, lastAsk
def buy_market(self, market, quantity):
quantity_validated, tickSize = self.validate(market, quantity)
if quantity_validated==0 and tickSize==0:
return "You encountered a problem! Please try again."
order = self.API.buy_market(market, quantity_validated)
return order
def sell_market(self, market, quantity):
quantity_validated, tickSize = self.validate(market, quantity)
if quantity_validated==0 and tickSize==0:
return "You encountered a problem! Please try again."
order = self.API.sell_market(market, quantity_validated)
return order
def buy_limit(self, market, quantity, rate):
quantity_validated, tickSize = self.validate(market, quantity)
if quantity_validated==0 and tickSize==0:
return "You encountered a problem! Please try again."
order = self.API.buy_limit(market, quantity_validated, rate)
return order
def sell_limit(self, market, quantity, rate):
quantity_validated, tickSize = self.validate(market, quantity)
if quantity_validated==0 and tickSize==0:
return "You encountered a problem! Please try again."
order = self.API.sell_limit(market, quantity_validated, rate)
return order
def sell_OCO_order(self, market, quantity, takeProfitPrice, stopLimit, stopLossPrice):
quantity_validated, tickSize = self.validate(market, quantity)
if quantity_validated==0 and tickSize==0:
return "You encountered a problem! Please try again."
order = self.API.sell_OCO_order(market, quantity_validated, takeProfitPrice, stopLimit, stopLossPrice)
return order
def calc_decimal_places(self, num):
count = 0
temp_num = num
while temp_num < 1:
temp_num *= 10
count += 1
return count
def calc_sell_prices(self, lastBid, profitPct, stopLossPct, tickSize):
takeProfitPrice = lastBid + (lastBid * profitPct / 100) + (lastBid * self.commission)
stopLossPrice = lastBid - (lastBid * (stopLossPct-self.commission) / 100)
decimal_places = self.calc_decimal_places(tickSize)
return round(takeProfitPrice,decimal_places), round(stopLossPrice,decimal_places)
def trade(self, market, quantity, takeProfitPrice, stopLossPrice):
quantity_validated, tickSize = self.validate(market, quantity)
if quantity_validated==0 and tickSize==0:
return "You encountered a problem! Please try again."
order1 = self.buy_market(market, quantity_validated)
stopLimit = float(stopLossPrice) + tickSize
precision = self.calc_decimal_places(tickSize)
stopLimit = "{:0.0{}f}".format(stopLimit, precision)
if(isinstance(takeProfitPrice, list)):
quantity_validated, tickSize = self.validate(market, quantity_validated/len(takeProfitPrice))
for i in range(len(takeProfitPrice)):
order2 = self.sell_OCO_order(market, quantity_validated, takeProfitPrice[i], stopLimit, stopLossPrice)
else:
order2 = self.sell_OCO_order(market, quantity_validated, takeProfitPrice, stopLimit, stopLossPrice)
return order1, order2
def trade_pct(self, market, quantity, takeProfitPct, stopLossPct):
quantity_validated, tickSize = self.validate(market, quantity)
if quantity_validated==0 and tickSize==0:
return "You encountered a problem! Please try again."
order1 = self.buy_market(market, quantity_validated)
lastBid, lastAsk = self.get_market_price(market)
takeProfitPrice, stopLossPrice = self.calc_sell_prices(lastBid, float(takeProfitPct), float(stopLossPct), tickSize)
stopLimit = float(stopLossPrice) + tickSize
precision = self.calc_decimal_places(tickSize)
stopLimit = "{:0.0{}f}".format(stopLimit, precision)
takeProfitPrice = "{:0.0{}f}".format(takeProfitPrice, precision)
stopLossPrice = "{:0.0{}f}".format(stopLossPrice, precision)
order2 = self.sell_OCO_order(market, quantity_validated, takeProfitPrice, stopLimit, stopLossPrice)
return order1, order2
def transfer_dust(self, symbol):
trasnfer = self.API.transfer_dust(symbol)
return trasnfer