└── main1.py /main1.py: -------------------------------------------------------------------------------- 1 | from keys import api, secret 2 | from binance.um_futures import UMFutures 3 | import ta 4 | import pandas as pd 5 | from time import sleep 6 | from binance.error import ClientError 7 | 8 | client = UMFutures(key = api, secret=secret) 9 | 10 | # 0.012 means +1.2%, 0.009 is -0.9% 11 | tp = 0.012 12 | sl = 0.009 13 | volume = 10 # volume for one order (if its 10 and leverage is 10, then you put 1 usdt to one position) 14 | leverage = 10 15 | type = 'ISOLATED' # type is 'ISOLATED' or 'CROSS' 16 | qty = 100 # Amount of concurrent opened positions 17 | 18 | # getting your futures balance in USDT 19 | def get_balance_usdt(): 20 | try: 21 | response = client.balance(recvWindow=6000) 22 | for elem in response: 23 | if elem['asset'] == 'USDT': 24 | return float(elem['balance']) 25 | 26 | except ClientError as error: 27 | print( 28 | "Found error. status: {}, error code: {}, error message: {}".format( 29 | error.status_code, error.error_code, error.error_message 30 | ) 31 | ) 32 | 33 | 34 | # Getting all available symbols on the Futures ('BTCUSDT', 'ETHUSDT', ....) 35 | def get_tickers_usdt(): 36 | tickers = [] 37 | resp = client.ticker_price() 38 | for elem in resp: 39 | if 'USDT' in elem['symbol']: 40 | tickers.append(elem['symbol']) 41 | return tickers 42 | 43 | 44 | # Getting candles for the needed symbol, its a dataframe with 'Time', 'Open', 'High', 'Low', 'Close', 'Volume' 45 | def klines(symbol): 46 | try: 47 | resp = pd.DataFrame(client.klines(symbol, '15m')) 48 | resp = resp.iloc[:,:6] 49 | resp.columns = ['Time', 'Open', 'High', 'Low', 'Close', 'Volume'] 50 | resp = resp.set_index('Time') 51 | resp.index = pd.to_datetime(resp.index, unit = 'ms') 52 | resp = resp.astype(float) 53 | return resp 54 | except ClientError as error: 55 | print( 56 | "Found error. status: {}, error code: {}, error message: {}".format( 57 | error.status_code, error.error_code, error.error_message 58 | ) 59 | ) 60 | 61 | 62 | # Set leverage for the needed symbol. You need this bcz different symbols can have different leverage 63 | def set_leverage(symbol, level): 64 | try: 65 | response = client.change_leverage( 66 | symbol=symbol, leverage=level, recvWindow=6000 67 | ) 68 | print(response) 69 | except ClientError as error: 70 | print( 71 | "Found error. status: {}, error code: {}, error message: {}".format( 72 | error.status_code, error.error_code, error.error_message 73 | ) 74 | ) 75 | 76 | 77 | # The same for the margin type 78 | def set_mode(symbol, type): 79 | try: 80 | response = client.change_margin_type( 81 | symbol=symbol, marginType=type, recvWindow=6000 82 | ) 83 | print(response) 84 | except ClientError as error: 85 | print( 86 | "Found error. status: {}, error code: {}, error message: {}".format( 87 | error.status_code, error.error_code, error.error_message 88 | ) 89 | ) 90 | 91 | 92 | # Price precision. BTC has 1, XRP has 4 93 | def get_price_precision(symbol): 94 | resp = client.exchange_info()['symbols'] 95 | for elem in resp: 96 | if elem['symbol'] == symbol: 97 | return elem['pricePrecision'] 98 | 99 | 100 | # Amount precision. BTC has 3, XRP has 1 101 | def get_qty_precision(symbol): 102 | resp = client.exchange_info()['symbols'] 103 | for elem in resp: 104 | if elem['symbol'] == symbol: 105 | return elem['quantityPrecision'] 106 | 107 | 108 | # Open new order with the last price, and set TP and SL: 109 | def open_order(symbol, side): 110 | price = float(client.ticker_price(symbol)['price']) 111 | qty_precision = get_qty_precision(symbol) 112 | price_precision = get_price_precision(symbol) 113 | qty = round(volume/price, qty_precision) 114 | if side == 'buy': 115 | try: 116 | resp1 = client.new_order(symbol=symbol, side='BUY', type='LIMIT', quantity=qty, timeInForce='GTC', price=price) 117 | print(symbol, side, "placing order") 118 | print(resp1) 119 | sleep(2) 120 | sl_price = round(price - price*sl, price_precision) 121 | resp2 = client.new_order(symbol=symbol, side='SELL', type='STOP_MARKET', quantity=qty, timeInForce='GTC', stopPrice=sl_price) 122 | print(resp2) 123 | sleep(2) 124 | tp_price = round(price + price * tp, price_precision) 125 | resp3 = client.new_order(symbol=symbol, side='SELL', type='TAKE_PROFIT_MARKET', quantity=qty, timeInForce='GTC', 126 | stopPrice=tp_price) 127 | print(resp3) 128 | except ClientError as error: 129 | print( 130 | "Found error. status: {}, error code: {}, error message: {}".format( 131 | error.status_code, error.error_code, error.error_message 132 | ) 133 | ) 134 | if side == 'sell': 135 | try: 136 | resp1 = client.new_order(symbol=symbol, side='SELL', type='LIMIT', quantity=qty, timeInForce='GTC', price=price) 137 | print(symbol, side, "placing order") 138 | print(resp1) 139 | sleep(2) 140 | sl_price = round(price + price*sl, price_precision) 141 | resp2 = client.new_order(symbol=symbol, side='BUY', type='STOP_MARKET', quantity=qty, timeInForce='GTC', stopPrice=sl_price) 142 | print(resp2) 143 | sleep(2) 144 | tp_price = round(price - price * tp, price_precision) 145 | resp3 = client.new_order(symbol=symbol, side='BUY', type='TAKE_PROFIT_MARKET', quantity=qty, timeInForce='GTC', 146 | stopPrice=tp_price) 147 | print(resp3) 148 | except ClientError as error: 149 | print( 150 | "Found error. status: {}, error code: {}, error message: {}".format( 151 | error.status_code, error.error_code, error.error_message 152 | ) 153 | ) 154 | 155 | 156 | # Your current positions (returns the symbols list): 157 | def get_pos(): 158 | try: 159 | resp = client.get_position_risk() 160 | pos = [] 161 | for elem in resp: 162 | if float(elem['positionAmt']) != 0: 163 | pos.append(elem['symbol']) 164 | return pos 165 | except ClientError as error: 166 | print( 167 | "Found error. status: {}, error code: {}, error message: {}".format( 168 | error.status_code, error.error_code, error.error_message 169 | ) 170 | ) 171 | 172 | def check_orders(): 173 | try: 174 | response = client.get_orders(recvWindow=6000) 175 | sym = [] 176 | for elem in response: 177 | sym.append(elem['symbol']) 178 | return sym 179 | except ClientError as error: 180 | print( 181 | "Found error. status: {}, error code: {}, error message: {}".format( 182 | error.status_code, error.error_code, error.error_message 183 | ) 184 | ) 185 | 186 | # Close open orders for the needed symbol. If one stop order is executed and another one is still there 187 | def close_open_orders(symbol): 188 | try: 189 | response = client.cancel_open_orders(symbol=symbol, recvWindow=6000) 190 | print(response) 191 | except ClientError as error: 192 | print( 193 | "Found error. status: {}, error code: {}, error message: {}".format( 194 | error.status_code, error.error_code, error.error_message 195 | ) 196 | ) 197 | 198 | 199 | # Strategy. Can use any other: 200 | def str_signal(symbol): 201 | kl = klines(symbol) 202 | rsi = ta.momentum.RSIIndicator(kl.Close).rsi() 203 | rsi_k = ta.momentum.StochRSIIndicator(kl.Close).stochrsi_k() 204 | rsi_d = ta.momentum.StochRSIIndicator(kl.Close).stochrsi_d() 205 | ema = ta.trend.ema_indicator(kl.Close, window=200) 206 | if rsi.iloc[-1] < 40 and ema.iloc[-1] < kl.Close.iloc[-1] and rsi_k.iloc[-1] < 20 and rsi_k.iloc[-3] < rsi_d.iloc[-3] and rsi_k.iloc[-2] < rsi_d.iloc[-2] and rsi_k.iloc[-1] > rsi_d.iloc[-1]: 207 | return 'up' 208 | if rsi.iloc[-1] > 60 and ema.iloc[-1] > kl.Close.iloc[-1] and rsi_k.iloc[-1] > 80 and rsi_k.iloc[-3] > rsi_d.iloc[-3] and rsi_k.iloc[-2] > rsi_d.iloc[-2] and rsi_k.iloc[-1] < rsi_d.iloc[-1]: 209 | return 'down' 210 | 211 | else: 212 | return 'none' 213 | 214 | 215 | def rsi_signal(symbol): 216 | kl = klines(symbol) 217 | rsi = ta.momentum.RSIIndicator(kl.Close).rsi() 218 | ema = ta.trend.ema_indicator(kl.Close, window=200) 219 | if rsi.iloc[-2] < 30 and rsi.iloc[-1] > 30: 220 | return 'up' 221 | if rsi.iloc[-2] > 70 and rsi.iloc[-1] < 70: 222 | return 'down' 223 | 224 | else: 225 | return 'none' 226 | 227 | 228 | def macd_ema(symbol): 229 | kl = klines(symbol) 230 | macd = ta.trend.macd_diff(kl.Close) 231 | ema = ta.trend.ema_indicator(kl.Close, window=200) 232 | if macd.iloc[-3] < 0 and macd.iloc[-2] < 0 and macd.iloc[-1] > 0 and ema.iloc[-1] < kl.Close.iloc[-1]: 233 | return 'up' 234 | if macd.iloc[-3] > 0 and macd.iloc[-2] > 0 and macd.iloc[-1] < 0 and ema.iloc[-1] > kl.Close.iloc[-1]: 235 | return 'down' 236 | else: 237 | return 'none' 238 | 239 | 240 | def ema200_50(symbol): 241 | kl = klines(symbol) 242 | ema200 = ta.trend.ema_indicator(kl.Close, window=100) 243 | ema50 = ta.trend.ema_indicator(kl.Close, window=50) 244 | if ema50.iloc[-3] < ema200.iloc[-3] and ema50.iloc[-2] < ema200.iloc[-2] and ema50.iloc[-1] > ema200.iloc[-1]: 245 | return 'up' 246 | if ema50.iloc[-3] > ema200.iloc[-3] and ema50.iloc[-2] > ema200.iloc[-2] and ema50.iloc[-1] < ema200.iloc[-1]: 247 | return 'down' 248 | else: 249 | return 'none' 250 | 251 | 252 | orders = 0 253 | symbol = '' 254 | # getting all symbols from Binace Futures list: 255 | symbols = get_tickers_usdt() 256 | 257 | while True: 258 | # we need to get balance to check if the connection is good, or you have all the needed permissions 259 | balance = get_balance_usdt() 260 | sleep(1) 261 | if balance == None: 262 | print('Cant connect to API. Check IP, restrictions or wait some time') 263 | if balance != None: 264 | print("My balance is: ", balance, " USDT") 265 | # getting position list: 266 | pos = [] 267 | pos = get_pos() 268 | print(f'You have {len(pos)} opened positions:\n{pos}') 269 | # Getting order list 270 | ord = [] 271 | ord = check_orders() 272 | # removing stop orders for closed positions 273 | for elem in ord: 274 | if not elem in pos: 275 | close_open_orders(elem) 276 | 277 | if len(pos) < qty: 278 | for elem in symbols: 279 | # Strategies (you can make your own with the TA library): 280 | 281 | # signal = str_signal(elem) 282 | signal = rsi_signal(elem) 283 | # signal = macd_ema(elem) 284 | 285 | # 'up' or 'down' signal, we place orders for symbols that arent in the opened positions and orders 286 | # we also dont need USDTUSDC because its 1:1 (dont need to spend money for the commission) 287 | if signal == 'up' and elem != 'USDCUSDT' and not elem in pos and not elem in ord and elem != symbol: 288 | print('Found BUY signal for ', elem) 289 | set_mode(elem, type) 290 | sleep(1) 291 | set_leverage(elem, leverage) 292 | sleep(1) 293 | print('Placing order for ', elem) 294 | open_order(elem, 'buy') 295 | symbol = elem 296 | order = True 297 | pos = get_pos() 298 | sleep(1) 299 | ord = check_orders() 300 | sleep(1) 301 | sleep(10) 302 | # break 303 | if signal == 'down' and elem != 'USDCUSDT' and not elem in pos and not elem in ord and elem != symbol: 304 | print('Found SELL signal for ', elem) 305 | set_mode(elem, type) 306 | sleep(1) 307 | set_leverage(elem, leverage) 308 | sleep(1) 309 | print('Placing order for ', elem) 310 | open_order(elem, 'sell') 311 | symbol = elem 312 | order = True 313 | pos = get_pos() 314 | sleep(1) 315 | ord = check_orders() 316 | sleep(1) 317 | sleep(10) 318 | # break 319 | print('Waiting 3 min') 320 | sleep(180) 321 | 322 | 323 | 324 | --------------------------------------------------------------------------------