class Binance(Exchange): SOCKET = "wss://stream.binance.com:9443/ws/reefusdt@kline_1m" client = None async def connect(self, api_key: str, api_secret: str): self.client = Client(api_key, api_secret) async def buy(self, quantity: str, symbol: str, price: float): self.client.create_order(symbol=symbol, side=SIDE_BUY, type=ORDER_TYPE_MARKET, quantity=quantity) async def sell(self, quantity: str, symbol: str, price: float): self.client.create_order(symbol=symbol, side=SIDE_SELL, type=ORDER_TYPE_MARKET, quantity=quantity) async def start_socket(self): ws = websocket.WebSocketApp(self.SOCKET, on_message=self.on_message) ws.run_forever() async def on_message(self, ws, message) -> ExchangeMessage: json_message = json.loads(message) print(json_message) candle = json_message['k'] is_candle_closed = candle['x'] close = candle['c'] return ExchangeMessage(symbol='REEFUSDT', is_candle_closed=is_candle_closed, close=close)
def handle(self, *args, **options): c = Client(settings.BINANCE_API_KEY, settings.BINANCE_SECRET) assets = c.get_all_tickers() for asset in assets: coin, crt = Coin.objects.get_or_create(symbol=asset['symbol']) coin.btc_price = asset['price'] coin.save() trading_orders = TradingCondition.objects.filter(closed=False, coin=coin) for tc in trading_orders: # Calculate price change in percentage. IF AutoSell or StopLoss # is triggered - sell coins. change = round((tc.coin.btc_price - tc.btc_buy_price) / tc.btc_buy_price * 100, 2) tc.change = change if change >= tc.auto_sell: # Send market SELL order print("AUTO SELL!", coin.symbol, tc.btc_buy_price, tc.coin.btc_price, change) c = Client(tc.trader.api_key, tc.trader.secret) order_result = c.create_order(symbol=coin.symbol, side='SELL', type='MARKET', quantity=tc.quantity) print(order_result) tc.closed = True elif change <= -tc.stop_loss: # Send market SELL order print("STOP LOSS!", coin.symbol, tc.btc_buy_price, tc.coin.btc_price, change) c = Client(tc.trader.api_key, tc.trader.secret) order_result = c.create_order(symbol=coin.symbol, side='SELL', type='MARKET', quantity=tc.quantity) print(order_result) tc.closed = True tc.save() print("Prices updated!")
def order(side,symble,quantity,order_type): try: print("sending order") order = Client.create_order(symble=symble,side=side,type=order_type,quantity=quantity) print(order) except Exception as e: return False return True
def Order(side, quantity, symbol, order_type=ORDER_TYPE_MARKET): global asset_qauntity client = Client(config.binance_api_key, config.binance_secret_key) try: last_message = "sending order" order_with_info = client.create_order(symbol=symbol, side=side, type=order_type, quantity=asset_qauntity) #print(order_with_info) except Exception as e: #print("an exception occured - {}".format(e)) return False return True
def order(side, quantity, symbol, order_type=ORDER_TYPE_MARKET): client = Client(ApiSettings.query.filter_by(id=1).first().API_KEY, ApiSettings.query.filter_by(id=1).first().SECRET_KEY) try: print(f"sending order {order_type} - {side} {quantity} {symbol}") order = client.create_order(symbol=symbol, side=side, type=order_type, quantity=quantity) except Exception as e: print(f"an exception occured - {e}") result = e logs_to_file(side, quantity, ticker, tv_price, result) return False return order
def binance_create_order(chat_id, **params): full_api = getbinanceapi(chat_id)['binance_api'] api_key = full_api.split(':')[0].strip() api_secret = full_api.split(':')[1].strip() client = Client(api_key, api_secret) binance_timesync(client) try: js_info = client.create_order(**params) return js_info except Exception as e: print(e) return str(e)
def order(side, quantity, symbol, order_type=ORDER_TYPE_MARKET): try: client = Client(config.API_KEY, config.API_SECRET) order = client.create_order(symbol=symbol, side=side, type=order_type, quantity=quantity) print(order) return True except Exception as e: print(e) print("ERROR ORDERING") return False return True
def make_multiplier_sell(client: Client, symbol: str, amount: float, multiplier: float): print(f"selling {symbol} at {amount} * {multiplier}") order = client.create_order( symbol=symbol, side=SIDE_SELL, type=ORDER_TYPE_TAKE_PROFIT, stopPrice=amount * multiplier) # order = client.create_test_order( # symbol=symbol, # side=SIDE_SELL, # type=ORDER_TYPE_TAKE_PROFIT, # stopPrice=amount * multiplier) return order
def market_buy_order(self, _amount, _symbol): client = Client(keys['api_key'], keys['api_secret'], tld="us") try: buy_order = client.create_order(symbol=_symbol, side=Client.SIDE_BUY, type=Client.ORDER_TYPE_MARKET, quantity=_amount) except Exception as e: print(e) with open('order_message_log.txt', 'a') as message_entry: message_entry.write( f'{_index} SELL {_symbol} \n\n ERROR OCCURED {e} \n\n') return buy_order
class BinanceTrade: #定义基本属性 def __init__(self): self.binance = Client(ACCESS_KEY, SECRET_KEY) def place_order(self, order): try: data = self.binance.create_order( symbol = order.contract_id, side = order.side, type = order.order_type, timeInForce = order.time_in_force, quantity = order.quantity, price = order.price) order.order_id = str(data['orderId']) order.client_order_id = data['clientOrderId'] except (BinanceAPIException, BinanceRequestException) as e: order.err_code = 1 order.err_msg = str(e) except: order.err_code = 2 order.err_msg = str(sys.exc_info()) if order.err_code != 0: logger.debug(order.err_msg) def cancel_order(self, order): pass def get_order(self, order): data = self.binance.get_order( symbol = order.security, orderId = order.order_id) if float(data['executedQty']) != order.executed_amount: pass if data['status'] == 'CANCELED': pass if data['status'] == 'FILLED' or data['status'] == 'CANCELED': self.is_complete = True def get_account(self): data_dic = self.binance.get_account() print(data_dic)
class BinanceAPI(API): def __init__(self): api_key = "rOsVSRe409vOsHGnwpErHivGTsAqCHNxZoNnocvYnuhBCX1iAbBnTsiKSh5hBmyV" api_secret = "d7zvWZBktLsFJVp8T5g6Q8koLQUPPr8GEwBu41Dfgame25r8L8zbtpuTuzE2gRAh" self.client = Client(api_key, api_secret) self.allowedTickers = ["BTCUSDT", "ETHUSDT", "BTCETH"] def check_allowed_ticker(self, ticker): return ticker in self.allowedTickers def create_order(self, ticker, quantity, side, orderType, price=0): sideAPI = Client.SIDE_SELL if side == "SELL" else Client.SIDE_BUY if side == "BUY" else None typeAPI = Client.ORDER_TYPE_MARKET if orderType == "MARKET" else Client.ORDER_TYPE_LIMIT if orderType == "LIMIT" else None if sideAPI == None: raise Exception("Side not allowed") if typeAPI == None: raise Exception("Type not allowed") order = self.client.create_order(symbol=ticker, side=sideAPI, type=typeAPI, quantity=quantity) return True def get_all_tickers_prices(self): return self.client.get_all_tickers() def get_order_book(self, symbol): # get market depth return self.client.get_order_book(symbol=symbol) def get_historical_data(self, symbol, interval, startDate, endDate): startDate = startDate.strftime("%d %b, %Y") endDate = endDate.strftime("%d %b, %Y") if interval == '15': APIInterval = Client.KLINE_INTERVAL_15MINUTE return self.client.get_historical_klines(symbol, APIInterval, startDate, endDate)
def place_order(coin, amount): client = Client("BINANCE HASH", "SECRET HASH") order = client.create_order( symbol=coin + 'BTC', side=Client.SIDE_BUY, type=Client.ORDER_TYPE_MARKET, quantity=int( float(amount) / float( json.loads( requests.get( "https://api.binance.com/api/v3/ticker/price?symbol=" + coin + "BTC").text)["price"]))) price = float( json.loads( requests.get( "https://api.binance.com/api/v3/ticker/price?symbol=" + coin + "BTC").text)["price"]) balance = json.loads(client.get_asset_balance(asset=coin)["free"]) order = client.order_limit_sell(symbol=coin + 'BTC', quantity=int(balance), price=f"{2*price:.8f}")
coinA_balance = int(float(client.get_asset_balance("coinA").get("free"))) coinB_balance = float(client.get_asset_balance("coinB").get("free")) Side = "sell" # depending on the situation, change this with "sell" or "buy" while True: while Side == "sell": coinA_last_price = float(client.get_symbol_ticker(symbol="coinA symbol").get("price")) coinB_last_price = float(client.get_symbol_ticker(symbol="coinB symbol").get("price")) if coinA_last_price > you decide and coinB_last_price > you decide: # change you decide with a float client.create_order(symbol="coinA symbol", side="SELL", type="MARKET", quantity=coinA_balance) # sell all coinA coinA_balance = int(float(client.get_asset_balance("coinA").get("free"))) coinB_balance = float(client.get_asset_balance("coinB").get("free")) email_conn = smtplib.SMTP(host, port) email_conn.ehlo() email_conn.starttls() email_conn.login(username, password) email_conn.sendmail(from_email, to_mail, "you sold") email_conn.quit() Side = "buy" sleep(30) # seconds while Side == "buy":
class BinanceExchange(Exchange): exchange_name = "Binance" isMargin = False def __init__(self, apiKey, apiSecret, pairs, name): super().__init__(apiKey, apiSecret, pairs, name) self.connection = Client(self.api['key'], self.api['secret']) symbol_info_arr = self.connection.get_exchange_info() dict_symbols_info = { item['symbol']: item for item in symbol_info_arr["symbols"] } actual_symbols_info = { symbol: dict_symbols_info[symbol] for symbol in self.pairs } self.symbols_info = actual_symbols_info self.update_balance() self.socket = BinanceSocketManager(self.connection) self.socket.start_user_socket(self.on_balance_update) self.socket.start() self.is_last_order_event_completed = True self.step_sizes = {} self.balance_updated = True for symbol_info in symbol_info_arr['symbols']: if symbol_info['symbol'] in self.pairs: self.step_sizes[symbol_info['symbol']] = \ [f['stepSize'] for f in symbol_info['filters'] if f['filterType'] == 'LOT_SIZE'][0] def start(self, caller_callback): self.socket.start_user_socket(caller_callback) def update_balance(self): account_information = self.connection.get_account() self.set_balance(account_information['balances']) def get_trading_symbols(self): symbols = set() if not self.symbols_info: raise RuntimeError("Cant get exchange info") for key, value in self.symbols_info.items(): symbols.add(value["quoteAsset"]) symbols.add(value["baseAsset"]) return symbols def set_balance(self, balances): symbols = self.get_trading_symbols() dict_balances = {item['asset']: item for item in balances} actual_balance = {symbol: dict_balances[symbol] for symbol in symbols} self.balance = actual_balance def on_balance_update(self, upd_balance_ev): if upd_balance_ev['e'] == 'outboundAccountPosition': balance = [] for ev in upd_balance_ev['B']: balance.append({ 'asset': ev['a'], 'free': ev['f'], 'locked': ev['l'] }) self.balance.update({item['asset']: item for item in balance}) def get_open_orders(self): orders = self.connection.get_open_orders() general_orders = [] for o in orders: quantityPart = self.get_part(o['symbol'], o["origQty"], o['price'], o['side']) general_orders.append( Order(o['price'], o["origQty"], quantityPart, o['orderId'], o['symbol'], o['side'], o['type'], self.exchange_name)) return general_orders def _cancel_order(self, order_id, symbol): self.connection.cancel_order(symbol=symbol, orderId=order_id) self.logger.info(f'{self.name}: Order canceled') async def on_cancel_handler(self, event: Actions.ActionCancel): try: slave_order_id = self._cancel_order_detector(event.price) self._cancel_order(slave_order_id, event.symbol) except BinanceAPIException as error: self.logger.error(f'{self.name}: error {error.message}') except: self.logger.error( f"{self.name}: error in action: {event.name} in slave {self.name}" ) def stop(self): self.socket.close() def _cancel_order_detector(self, price): # detect order id which need to be canceled slave_open_orders = self.connection.get_open_orders() for ordr_open in slave_open_orders: if float(ordr_open['price']) == float(price): return ordr_open['orderId'] def process_event(self, event): # return event in generic type from websocket # if this event in general type it was send from start function and need call firs_copy if 'exchange' in event: return event if event['e'] == 'outboundAccountPosition': self.on_balance_update(event) elif event['e'] == 'executionReport': if event['X'] == 'FILLED': return elif event['x'] == 'CANCELED': return Actions.ActionCancel(event['s'], event['p'], event['i'], self.exchange_name, event) elif event['X'] == 'NEW': order_event = event if order_event['s'] not in self.pairs: return if order_event[ 'o'] == 'MARKET': # if market order, we haven't price and cant calculate quantity order_event['p'] = self.connection.get_ticker( symbol=order_event['s'])['lastPrice'] # part = self.get_part(order_event['s'], order_event['q'], order_event['p'], order_event['S']) # shortcut mean https://github.com/binance-exchange/binance-official-api-docs/blob/master/user-data-stream.md#order-update order = Order( order_event['p'], order_event['q'], self.get_part(order_event['s'], order_event['q'], order_event['p'], order_event['S']), order_event['i'], order_event['s'], order_event['S'], order_event['o'], self.exchange_name, order_event['P']) return Actions.ActionNewOrder(order, self.exchange_name, event) return async def on_order_handler(self, event: Actions.ActionNewOrder): self.create_order(event.order) def create_order(self, order): """ :param order: """ quantity = self.calc_quantity_from_part(order.symbol, order.quantityPart, order.price, order.side) self.logger.info('Slave ' + self.name + ' ' + str(self._get_quote_balance(order.symbol)) + ' ' + str(self._get_base_balance(order.symbol)) + ', Create Order:' + ' amount: ' + str(quantity) + ', price: ' + str(order.price)) try: if order.type == 'STOP_LOSS_LIMIT' or order.type == "TAKE_PROFIT_LIMIT": self.connection.create_order(symbol=order.symbol, side=order.side, type=order.type, price=order.price, quantity=quantity, timeInForce='GTC', stopPrice=order.stop) if order.type == 'MARKET': self.connection.create_order(symbol=order.symbol, side=order.side, type=order.type, quantity=quantity) else: self.connection.create_order(symbol=order.symbol, side=order.side, type=order.type, quantity=quantity, price=order.price, timeInForce='GTC') self.logger.info(f"{self.name}: order created") except Exception as e: self.logger.error(str(e)) def _get_quote_balance(self, symbol): return self.balance[self.symbols_info[symbol]['quoteAsset']] def _get_base_balance(self, symbol): return self.balance[self.symbols_info[symbol]['baseAsset']] def get_part(self, symbol: str, quantity: float, price: float, side: str): # get part of the total balance of this coin # if order[side] == sell: need obtain coin balance if side == 'BUY': get_context_balance = self._get_quote_balance market_value = float(quantity) * float(price) else: get_context_balance = self._get_base_balance market_value = float(quantity) balance = float(get_context_balance(symbol)['free']) # if first_copy the balance was update before if self.balance_updated: balance += float(get_context_balance(symbol)['locked']) # else: # balance += market_value part = market_value / balance part = part * 0.99 # decrease part for 1% for avoid rounding errors in calculation return part def calc_quantity_from_part(self, symbol, quantityPart, price, side): # calculate quantity from quantityPart # if order[side] == sell: need obtain coin balance if side == 'BUY': get_context_balance = self._get_quote_balance buy_koef = float(price) else: get_context_balance = self._get_base_balance buy_koef = 1 cur_bal = float(get_context_balance(symbol)['free']) if self.balance_updated: cur_bal += float(get_context_balance(symbol)['locked']) quantity = quantityPart * cur_bal / buy_koef stepSize = float(self.step_sizes[symbol]) precision = int(round(-math.log(stepSize, 10), 0)) quantity = round(quantity, precision) return quantity
from binance.client import Client from lamda import * client = Client(AK, AS) # get market depth depth = client.get_order_book(symbol='BNBBTC') # place market buy order from binance.enums import * order = client.create_order(symbol='BNBBTC', side=SIDE_BUY, type=ORDER_TYPE_MARKET, quantity=100) # get all symbol prices prices = client.get_all_tickers() # withdraw 100 ETH # check docs for assumptions around withdrawals from binance.exceptions import BinanceApiException, BinanceWithdrawException try: result = client.withdraw(asset='ETH', address='<eth_address>', amount=100) except BinanceApiException as e: print(e) except BinanceWithdrawException as e: print(e) else: print("Success") # fetch list of withdrawals
watched = db.watched binance_client = Client(settings.BINANCE_API_KEY, settings.BINANCE_SECRET) while True: payload = {} for coin_watched in watched.find(): current_price = prices.find_one({"s": coin_watched['s']})['c'] buy_price = Decimal(coin_watched['buy']) change = round((Decimal(current_price) - buy_price) / buy_price \ * 100, 2) if change >= int(coin_watched['sell']) or \ change <= -int(coin_watched['stop']): watched.delete_one({"tc": coin_watched['tc']}) payload[int(coin_watched['tc'])] = ["SOLD", str(change)] try: o_r = binance_client.create_order(symbol=coin_watched['s'], side='SELL', type='MARKET', quantity=coin_watched['q']) print(o_r) except BinanceAPIException as e: print(binance_client.get_account()) print(e, coin_watched) else: payload[int(coin_watched['tc'])] = [current_price, str(change)] channel_layer.send("prices", {"text": json.dumps(payload)}) time.sleep(0.5)
"o": open_order_count, "t": trade_count }) if open_order_count < 1 and trade_count < 5: print('PASSED') all_rules_passed = True if all_rules_passed: print('buy...............................') order_number = 999999999 buy_price = round(Decimal(price), 8) try: print('AMOUNT: %(a)s' % {"a": amount}) print('PRICE: %(a)s' % {"a": buy_price}) print('SYMBOL: %(a)s' % {"a": symbol}) buy = client.create_order(symbol=symbol, side=Client.SIDE_BUY, type=Client.ORDER_TYPE_MARKET, quantity=amount) print(buy) time.sleep(1) order_number = buy["orderId"] opened = False final_price = buy_price if buy["status"] == 'filled': opened = True final_price = buy['fills'][0]['price'] insert_cmd = """ INSERT INTO set_trades_binance ( currencypair, rate, amount, btc_value,
class BinanceClient(AbstractClient): def __init__(self, listener): self.exchange = 'binance' self.trade_fee = Decimal(0.0005) self.client = Client(api_keys.binance[0], api_keys.binance[1]) super(BinanceClient, self).__init__(listener) self._get_exchange_info() self.get_all_balances() def _buy(self, symbol, price, amount): result = self.client.create_order(symbol=symbol, quantity=amount, price=price, side=SIDE_BUY, type=ORDER_TYPE_LIMIT, timeInForce=TIME_IN_FORCE_GTC) self.open_orders[symbol] = result['orderId'] def _sell(self, symbol, price, amount): result = self.client.create_order(symbol=symbol, quantity=amount, price=price, side=SIDE_SELL, type=ORDER_TYPE_LIMIT, timeInForce=TIME_IN_FORCE_GTC) self.open_orders[symbol] = result['orderId'] def _cancel(self, symbol): orderId = self.open_orders.pop(symbol) try: self.client.cancel_order(symbol=symbol, orderId=orderId) # Binance throws API exception if the order is not open so we'll have to check if it's fulfilled here. except BinanceAPIException as e: time.sleep(1) if not self.is_order_fulfilled(symbol, orderId): # Order was not fulfilled, re-throw exception raise e except BinanceRequestException as e: self.errors += 1 raise e def is_order_fulfilled(self, symbol, orderId): try: for data in self.client.get_my_trades(symbol=symbol): if data['orderId'] == int(orderId): return True except (BinanceRequestException, BinanceAPIException) as e: print datetime.now(), "[Binance] is order fulfilled error", e self.errors += 1 return False def get_all_balances(self): try: result = self.client.get_account() for balance in result['balances']: self.coin_balances[str(balance['asset'])] = Decimal( str(balance['free'])) # + Decimal(balance['locked']) return self.coin_balances except (BinanceRequestException, BinanceAPIException) as e: print datetime.now(), "[Binance] get all balances error:", str( e).replace('\r\n', '') self.errors += 1 def _market_poll(self): result = {'success': False} result['client'] = self result['timestamp'] = int(time.time() * 1000) result['coinpairs'] = {} try: coins = self.client.get_orderbook_tickers() for coin in coins: symbol = str(coin['symbol']) if symbol in self.exchange_symbols: result['coinpairs'][self._get_arbitrager_coinpair( symbol)] = { 'buy': Decimal(str(coin['bidPrice'])), 'buyAmount': Decimal(str(coin['bidQty'])), 'sell': Decimal(str(coin['askPrice'])), 'sellAmount': Decimal(str(coin['askQty'])) } except (BinanceRequestException, BinanceAPIException) as e: print datetime.now(), "[Binance] market poll error", str( e).replace('\r\n', '') self.errors += 1 if len(result['coinpairs']) > 0: result['success'] = True return result def _get_exchange_info(self): result = self.client.get_exchange_info() for symbol in result['symbols']: sym = str(symbol['symbol']) self.trade_rules[sym] = {} trade_rule = self.trade_rules[sym] for filter in symbol['filters']: if filter['filterType'] == 'PRICE_FILTER': trade_rule['minPrice'] = Decimal(filter['minPrice']) trade_rule['maxPrice'] = Decimal(filter['maxPrice']) trade_rule['stepPrice'] = Decimal(filter['tickSize']) elif filter['filterType'] == 'LOT_SIZE': if sym == 'NEOETH': trade_rule['minAmount'] = Decimal(0.1) elif sym == 'LTCETH': trade_rule['minAmount'] = Decimal(0.05) else: trade_rule['minAmount'] = Decimal(filter['minQty']) trade_rule['maxAmount'] = Decimal(filter['maxQty']) trade_rule['stepAmount'] = Decimal(filter['stepSize']) elif filter['filterType'] == 'MIN_NOTIONAL': trade_rule['minNotional'] = Decimal(filter['minNotional'])
class BinanceApi(object): def __init__(self, api_key, api_secret, order_currency, payment_currency): self.api_key = api_key self.api_secret = api_secret self.client = Client(self.api_key, self.api_secret) self.bsm = BinanceSocketManager(client=self.client) self.orders = {} self.asset_balance = {} self.order_currency = order_currency self.payment_currency = payment_currency self.symbol = self.order_currency + self.payment_currency self.current_price = {} self.current_depth = {} self.bsm.start_symbol_ticker_socket(self.symbol, self._process_ticker_message) self.bsm.start_depth_socket(self.symbol, self._process_depth_message, BinanceSocketManager.WEBSOCKET_DEPTH_5) self.bsm.start_user_socket(self._process_user_info_message) self.bsm.start() self._set_asset_balance() def _process_ticker_message(self, msg): self.current_price = { "price": float(msg['c']), "timestamp": time.time() * 1000 } #print self.current_price def _process_depth_message(self, msg): asks_depth = [] bids_depth = [] for ask in msg['asks']: asks_depth.append({ "price": float(ask[0]), "quantity": float(ask[1]) }) for bid in msg['bids']: bids_depth.append({ "price": float(bid[0]), "quantity": float(bid[1]) }) self.current_depth = { "asks": asks_depth, "bids": bids_depth, "timestamp": time.time() * 1000 } #print self.current_depth def _process_user_info_message(self, msg): #print msg if msg['e'].encode('utf-8') == "outboundAccountInfo": '''TODO: 用户数据入库''' found = 0 for balance in msg['B']: if balance['a'].encode('utf-8') == self.order_currency: self.asset_balance[self.order_currency] = { "free": float(balance['f']), "locked": float(balance['l']) } found += 1 elif balance['a'].encode('utf-8') == self.payment_currency: self.asset_balance[self.payment_currency] = { "free": float(balance['f']), "locked": float(balance['l']) } found += 1 elif found >= 2: break else: continue conn.execute('INSERT INTO asset_info VALUES (?,?,?,?,?,?)', [ str(uuid.uuid1()), self.asset_balance[self.order_currency]['free'] + self.asset_balance[self.order_currency]['locked'], 0.0, self.asset_balance[self.payment_currency]['free'] + self.asset_balance[self.payment_currency]['locked'], 'binance', time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()) ]) conn.commit() elif msg['e'].encode('utf-8') == "executionReport": if not self.orders.has_key(msg['i']): time.sleep(1) self.orders[msg['i']]['status'] = msg['X'].encode('utf-8') if msg['X'].encode('utf-8') in ["FILLED", "PARTIALLY_FILLED"]: trade = { 'trade_id': msg['t'], 'commission': float(msg['n']), 'commissionAsset': msg['N'].encode('utf-8'), 'price': float(msg['L']), 'quantity': float(msg['l']), 'order_id': msg['i'], 'date_time': time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(msg['T'] / 1000)) } self.orders[msg['i']]['trades'][trade['trade_id']] = trade self.orders[msg['i']]['deal_quantity'] += trade['quantity'] self.orders[msg['i']][ 'deal_amount'] += trade['quantity'] * trade['price'] self.orders[msg['i']]['deal_fee'] += trade['commission'] '''手续费记录方式可能会存在问题,多币种咋办''' if self.orders[ msg['i']]['fee_asset'] != trade['commissionAsset']: self.orders[msg['i']][ 'fee_asset'] += trade['commissionAsset'] + ' ' self.orders[msg['i']]['deal_price'] = self.orders[msg['i']][ 'deal_amount'] / self.orders[msg['i']]['deal_quantity'] def _set_asset_balance(self): tries = 0 '''sleep?''' while tries < 5: try: asset = self.client.get_asset_balance(self.payment_currency) except BinanceAPIException as e: print e.code, e.message tries += 1 continue if asset is not None: self.asset_balance[asset['asset']] = { "free": float(asset['free']), 'locked': float(asset['locked']) } break time.sleep(0.5) if tries == 5: print "get asset balance failed! " return tries = 0 while tries < 5: try: asset = self.client.get_asset_balance(self.order_currency) except BinanceAPIException as e: print e.code, e.message tries += 1 continue if asset is not None: self.asset_balance[asset['asset']] = { "free": float(asset['free']), 'locked': float(asset['locked']) } break time.sleep(0.5) if tries == 5: print "get asset balance failed! " return def get_current_price(self): return self.current_price def get_current_depth(self): return self.current_depth def create_order(self, side, price, quantity): try: order_info = self.client.create_order( symbol=self.symbol, side=side, type=ORDER_TYPE_LIMIT, price=str(price), quantity=quantity, timeInForce=TIME_IN_FORCE_GTC) except BinanceAPIException as e: return -1, {"code": e.code, "message": e.message} self.orders[order_info['orderId']] = { "side": side, "order_quantity": float(order_info['origQty']), "symbol": self.symbol, "order_price": float(order_info['price']), "status": order_info['status'].encode('utf-8'), 'date_time': time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(order_info['transactTime'] / 1000)), 'deal_quantity': 0, 'order_amount': float(order_info['price']) * float(order_info['origQty']), 'deal_amount': 0, 'deal_fee': 0, 'fee_asset': '', 'deal_price': 0, 'trades': {} } return order_info['orderId'], self.orders[order_info['orderId']] '''def order_buy(self, price, quantity, order_type=ORDER_TYPE_LIMIT): if order_type is ORDER_TYPE_LIMIT: try: order = self.client.order_limit_buy(symbol=self.symbol, quantity=quantity, price=str(price)) except BinanceAPIException as e: return -1, {"code": e.code, "message": e.message} else: try: order = self.client.order_market_buy(symbol=self.symbol, quantity=quantity, price=str(price)) except BinanceAPIException as e: return -1, {"code": e.code, "message": e.message} self.orders[order['orderId']] = {"side": "bid", "executedQty": [], "origQty": float(order['origQty']), "currency": self.symbol, "price": float(order['price']), "status": order['status'].encode('utf-8')} return order['orderId'], self.orders[order['orderId']] def order_sell(self, price, quantity, order_type=ORDER_TYPE_LIMIT): if order_type is ORDER_TYPE_LIMIT: try: order = self.client.order_limit_sell(symbol=self.symbol, quantity=quantity, price=str(price)) except BinanceAPIException as e: return -1, {"code": e.code, "message": e.message} else: try: order = self.client.order_market_sell(symbol=self.symbol, quantity=quantity, price=str(price)) except BinanceAPIException as e: return -1, {"code": e.code, "message": e.message} #self.orders[order_id] = "NEW" self.orders[order['orderId']] = {"side": "ask", "executedQty": [], "origQty": float(order['origQty']),"symbol": self.symbol, "price": float(order['price']), "status": order['status'].encode('utf-8')} return order['orderId'], self.orders[order['orderId']]''' def order_cancel(self, order_id): try: result = self.client.cancel_order(symbol=self.symbol, orderId=order_id) except BinanceAPIException as e: return -1, {"code": e.code, "message": e.message} #self.orders[result['orderId']]["status"] = "CANCELED" return result['orderId'], self.orders[result['orderId']] def get_order_info(self, order_id): if self.orders.has_key(order_id): if abs(self.orders[order_id]['order_quantity'] - self.orders[order_id]['deal_quantity']) < 0.0001: self.orders[order_id]['status'] = 'FILLED' elif self.orders[order_id]['deal_quantity'] == 0: self.orders[order_id]['status'] = 'PARTIALLY_FILLED' return self.orders[order_id] return None def check_balance(self, currency): return self.asset_balance[currency] def get_asset_balance(self): return self.asset_balance def get_all_trade(self, order_id): return self.client.get_my_trades(symbol=self.symbol) def get_symbol_info(self, symbol): return self.client.get_symbol_info(symbol=symbol)
class Binance(object): def __init__(self): print("-- Connecting to binance ...") self.client = Client(os.environ['BINANCE_API_KEY'], os.environ['BINANCE_API_SECRET']) def get_balance(self, coin): print("-- Getting balance for " + coin) assetJSON = self.client.get_asset_balance(coin) return float(assetJSON['free']) def get_price(self, coin, coinfrom): priceJSON = self.client.get_symbol_ticker(symbol=coin + coinfrom) return float(priceJSON['price']) def buy_market(self, coin, coinfrom, ignored, quantity, testmode): print("-- Buying market " + str(quantity) + " " + coin + " from " + coinfrom) self.symbol = coin + coinfrom if testmode: print("[TEST] " + str(quantity) + " " + coin + " buy at : " + str(ignored) + " " + coinfrom + " (price is ignored on Binance)") else: orderBuy = self.client.create_order( symbol=coin + coinfrom, side=self.client.SIDE_BUY, type=self.client.ORDER_TYPE_MARKET, # timeInForce=clientBinance.TIME_IN_FORCE_GTC, quantity=quantity, # price=repr(originalPrice) ) completed = False while not completed: time.sleep(0.2) self.orderID = orderBuy['clientOrderId'] orderBuySt = self.client.get_order(symbol=coin + coinfrom, orderId=self.orderID) print("+ Order buy status : " + orderBuySt['status'] + " at : " + orderBuySt['price']) if not orderBuySt == self.client.ORDER_STATUS_NEW: completed = True def sell_market(self, coin, coinTo, ignored, quantity, testmode): print("-- Selling market " + str(quantity) + " " + coin + " to " + coinTo) if testmode: print("[TEST] " + str(quantity) + " " + coin + " sell at : " + str(ignored) + " " + coinTo + " (price is ignored on Binance)") else: orderSell = self.client.create_test_order( symbol=coin + coinTo, side=self.client.SIDE_SELL, type=self.client.ORDER_TYPE_MARKET, # timeInForce=clientBinance.TIME_IN_FORCE_GTC, quantity=quantity, # price=repr(newPrice) ) completed = False while not completed: time.sleep(0.2) orderSellId = orderSell['clientOrderId'] orderSellSt = self.client.get_order(symbol=coin + coinTo, orderId=orderSellId) print("+ Order sell status : " + orderSellSt['status'] + " at : " + orderSellSt['price']) if not orderSellSt == self.client.ORDER_STATUS_NEW: completed = True def cancel_order(self): print("-- Canceling order") self.client.cancel_order(symbol=self.symbol, orderId=self.orderID) self.symbol = None self.orderID = None
class BinanceAPIManager: def __init__(self, config: Config, db: Database, logger: Logger): # initializing the client class calls `ping` API endpoint, verifying the connection self.binance_client = Client( config.BINANCE_API_KEY, config.BINANCE_API_SECRET_KEY, tld=config.BINANCE_TLD, ) self.db = db self.logger = logger self.config = config self.cache = BinanceCache() self.stream_manager: Optional[BinanceStreamManager] = None self.setup_websockets() def setup_websockets(self): self.stream_manager = BinanceStreamManager( self.cache, self.config, self.binance_client, self.logger, ) @cached(cache=TTLCache(maxsize=1, ttl=43200)) def get_trade_fees(self) -> Dict[str, float]: return { ticker["symbol"]: float(ticker["takerCommission"]) for ticker in self.binance_client.get_trade_fee() } @cached(cache=TTLCache(maxsize=1, ttl=60)) def get_using_bnb_for_fees(self): return self.binance_client.get_bnb_burn_spot_margin()["spotBNBBurn"] def get_fee(self, origin_coin: Coin, target_coin: Coin, selling: bool): base_fee = self.get_trade_fees()[origin_coin + target_coin] if not self.get_using_bnb_for_fees(): return base_fee # The discount is only applied if we have enough BNB to cover the fee amount_trading = (self._sell_quantity(origin_coin.symbol, target_coin.symbol) if selling else self._buy_quantity( origin_coin.symbol, target_coin.symbol)) fee_amount = amount_trading * base_fee * 0.75 if origin_coin.symbol == "BNB": fee_amount_bnb = fee_amount else: origin_price = self.get_ticker_price(origin_coin + Coin("BNB")) if origin_price is None: return base_fee fee_amount_bnb = fee_amount * origin_price bnb_balance = self.get_currency_balance("BNB") if bnb_balance >= fee_amount_bnb: return base_fee * 0.75 return base_fee def get_account(self): """ Get account information """ return self.binance_client.get_account() def get_ticker_price(self, ticker_symbol: str): """ Get ticker price of a specific coin """ price = self.cache.ticker_values.get(ticker_symbol, None) if price is None and ticker_symbol not in self.cache.non_existent_tickers: self.cache.ticker_values = { ticker["symbol"]: float(ticker["price"]) for ticker in self.binance_client.get_symbol_ticker() } self.logger.debug( f"Fetched all ticker prices: {self.cache.ticker_values}") price = self.cache.ticker_values.get(ticker_symbol, None) if price is None: self.logger.info( f"Ticker does not exist: {ticker_symbol} - will not be fetched from now on" ) self.cache.non_existent_tickers.add(ticker_symbol) return price def get_currency_balance(self, currency_symbol: str, force=False) -> float: """ Get balance of a specific coin """ with self.cache.open_balances() as cache_balances: balance = cache_balances.get(currency_symbol, None) if force or balance is None: cache_balances.clear() cache_balances.update({ currency_balance["asset"]: float(currency_balance["free"]) for currency_balance in self.binance_client.get_account() ["balances"] }) self.logger.debug(f"Fetched all balances: {cache_balances}") if currency_symbol not in cache_balances: cache_balances[currency_symbol] = 0.0 return 0.0 return cache_balances.get(currency_symbol, 0.0) return balance def retry(self, func, *args, **kwargs): time.sleep(1) attempts = 0 while attempts < 20: try: return func(*args, **kwargs) except Exception: # pylint: disable=broad-except self.logger.warning( f"Failed to Buy/Sell. Trying Again (attempt {attempts}/20)" ) if attempts == 0: self.logger.warning(traceback.format_exc()) attempts += 1 return None def get_symbol_filter(self, origin_symbol: str, target_symbol: str, filter_type: str): return next(_filter for _filter in self.binance_client.get_symbol_info( origin_symbol + target_symbol)["filters"] if _filter["filterType"] == filter_type) @cached(cache=TTLCache(maxsize=2000, ttl=43200)) def get_alt_tick(self, origin_symbol: str, target_symbol: str): step_size = self.get_symbol_filter(origin_symbol, target_symbol, "LOT_SIZE")["stepSize"] if step_size.find("1") == 0: return 1 - step_size.find(".") return step_size.find("1") - 1 @cached(cache=TTLCache(maxsize=2000, ttl=43200)) def get_min_notional(self, origin_symbol: str, target_symbol: str): return float( self.get_symbol_filter(origin_symbol, target_symbol, "MIN_NOTIONAL")["minNotional"]) def _wait_for_order( self, order_id, origin_symbol: str, target_symbol: str ) -> Optional[BinanceOrder]: # pylint: disable=unsubscriptable-object while True: order_status: BinanceOrder = self.cache.orders.get(order_id, None) if order_status is not None: break self.logger.debug(f"Waiting for order {order_id} to be created") time.sleep(1) self.logger.debug(f"Order created: {order_status}") while order_status.status != "FILLED": try: order_status = self.cache.orders.get(order_id, None) self.logger.debug(f"Waiting for order {order_id} to be filled") if self._should_cancel_order(order_status): cancel_order = None while cancel_order is None: cancel_order = self.binance_client.cancel_order( symbol=origin_symbol + target_symbol, orderId=order_id) self.logger.info("Order timeout, canceled...") # sell partially if order_status.status == "PARTIALLY_FILLED" and order_status.side == "BUY": self.logger.info("Sell partially filled amount") order_quantity = self._sell_quantity( origin_symbol, target_symbol) partially_order = None while partially_order is None: partially_order = self.binance_client.order_market_sell( symbol=origin_symbol + target_symbol, quantity=order_quantity) self.logger.info("Going back to scouting mode...") return None if order_status.status == "CANCELED": self.logger.info( "Order is canceled, going back to scouting mode...") return None time.sleep(1) except BinanceAPIException as e: self.logger.info(e) time.sleep(1) except Exception as e: # pylint: disable=broad-except self.logger.info(f"Unexpected Error: {e}") time.sleep(1) self.logger.debug(f"Order filled: {order_status}") return order_status def wait_for_order( self, order_id, origin_symbol: str, target_symbol: str, order_guard: OrderGuard ) -> Optional[BinanceOrder]: # pylint: disable=unsubscriptable-object with order_guard: return self._wait_for_order(order_id, origin_symbol, target_symbol) def _should_cancel_order(self, order_status): minutes = (time.time() - order_status.time / 1000) / 60 timeout = 0 if order_status.side == "SELL": timeout = float(self.config.SELL_TIMEOUT) else: timeout = float(self.config.BUY_TIMEOUT) if timeout and minutes > timeout and order_status.status == "NEW": return True if timeout and minutes > timeout and order_status.status == "PARTIALLY_FILLED": if order_status.side == "SELL": return True if order_status.side == "BUY": current_price = self.get_ticker_price(order_status.symbol) if float(current_price) * (1 - 0.001) > float( order_status.price): return True return False def buy_alt(self, origin_coin: Coin, target_coin: Coin) -> BinanceOrder: return self.retry(self._buy_alt, origin_coin, target_coin) def _buy_quantity(self, origin_symbol: str, target_symbol: str, target_balance: float = None, from_coin_price: float = None): target_balance = target_balance or self.get_currency_balance( target_symbol) from_coin_price = from_coin_price or self.get_ticker_price( origin_symbol + target_symbol) origin_tick = self.get_alt_tick(origin_symbol, target_symbol) return math.floor(target_balance * 10**origin_tick / from_coin_price) / float(10**origin_tick) @staticmethod def float_as_decimal_str(num: float): return f"{num:0.08f}".rstrip("0").rstrip( ".") # remove trailing zeroes too def _make_order( self, side: str, symbol: str, quantity: float, price: float, quote_quantity: float, ): params = { "symbol": symbol, "side": side, "quantity": self.float_as_decimal_str(quantity), "type": self.config.BUY_ORDER_TYPE if side == Client.SIDE_BUY else self.config.SELL_ORDER_TYPE, } if params["type"] == Client.ORDER_TYPE_LIMIT: params["timeInForce"] = self.binance_client.TIME_IN_FORCE_GTC params["price"] = self.float_as_decimal_str(price) elif side == Client.SIDE_BUY: del params["quantity"] params["quoteOrderQty"] = self.float_as_decimal_str(quote_quantity) return self.binance_client.create_order(**params) def _buy_alt(self, origin_coin: Coin, target_coin: Coin): """ Buy altcoin """ trade_log = self.db.start_trade_log(origin_coin, target_coin, False) origin_symbol = origin_coin.symbol target_symbol = target_coin.symbol with self.cache.open_balances() as balances: balances.clear() origin_balance = self.get_currency_balance(origin_symbol) target_balance = self.get_currency_balance(target_symbol) from_coin_price = self.get_ticker_price(origin_symbol + target_symbol) order_quantity = self._buy_quantity(origin_symbol, target_symbol, target_balance, from_coin_price) self.logger.info(f"BUY QTY {order_quantity} of <{origin_symbol}>") # Try to buy until successful order = None order_guard = self.stream_manager.acquire_order_guard() while order is None: try: order = self._make_order( side=Client.SIDE_BUY, symbol=origin_symbol + target_symbol, quantity=order_quantity, quote_quantity=target_balance, price=from_coin_price, ) self.logger.info(order) except BinanceAPIException as e: self.logger.info(e) time.sleep(1) except Exception as e: # pylint: disable=broad-except self.logger.warning(f"Unexpected Error: {e}") executed_qty = float(order.get("executedQty", 0)) if executed_qty > 0 and order["status"] == "FILLED": order_quantity = executed_qty # Market buys provide QTY of actually bought asset trade_log.set_ordered(origin_balance, target_balance, order_quantity) order_guard.set_order(origin_symbol, target_symbol, int(order["orderId"])) order = self.wait_for_order(order["orderId"], origin_symbol, target_symbol, order_guard) if order is None: return None self.logger.info(f"Bought {origin_symbol}") trade_log.set_complete(order.cumulative_quote_qty) return order def sell_alt(self, origin_coin: Coin, target_coin: Coin) -> BinanceOrder: return self.retry(self._sell_alt, origin_coin, target_coin) def _sell_quantity(self, origin_symbol: str, target_symbol: str, origin_balance: float = None): origin_balance = origin_balance or self.get_currency_balance( origin_symbol) origin_tick = self.get_alt_tick(origin_symbol, target_symbol) return math.floor(origin_balance * 10**origin_tick) / float( 10**origin_tick) def _sell_alt(self, origin_coin: Coin, target_coin: Coin): """ Sell altcoin """ trade_log = self.db.start_trade_log(origin_coin, target_coin, True) origin_symbol = origin_coin.symbol target_symbol = target_coin.symbol with self.cache.open_balances() as balances: balances.clear() origin_balance = self.get_currency_balance(origin_symbol) target_balance = self.get_currency_balance(target_symbol) from_coin_price = self.get_ticker_price(origin_symbol + target_symbol) order_quantity = self._sell_quantity(origin_symbol, target_symbol, origin_balance) self.logger.info(f"Selling {order_quantity} of {origin_symbol}") self.logger.info(f"Balance is {origin_balance}") order = None order_guard = self.stream_manager.acquire_order_guard() while order is None: try: order = self._make_order( side=Client.SIDE_SELL, symbol=origin_symbol + target_symbol, quantity=order_quantity, quote_quantity=target_balance, price=from_coin_price, ) self.logger.info(order) except BinanceAPIException as e: self.logger.info(e) time.sleep(1) except Exception as e: # pylint: disable=broad-except self.logger.warning(f"Unexpected Error: {e}") self.logger.info("order") self.logger.info(order) trade_log.set_ordered(origin_balance, target_balance, order_quantity) order_guard.set_order(origin_symbol, target_symbol, int(order["orderId"])) order = self.wait_for_order(order["orderId"], origin_symbol, target_symbol, order_guard) if order is None: return None new_balance = self.get_currency_balance(origin_symbol) while new_balance >= origin_balance: new_balance = self.get_currency_balance(origin_symbol, True) self.logger.info(f"Sold {origin_symbol}") trade_log.set_complete(order.cumulative_quote_qty) return order
continue #sell if (sell_price < float(bids3[2][0])): if ((order_ask_quantity > 0) and (order_ask_quantity < (float(bids3[0][1]) + float(bids3[1][1]) + float(bids3[2][1])))): notify_str = 'SELL EOS price: ' + bids3[2][ 0] + ' quantity: ' + str(order_ask_quantity) logging.warn(notify_str) last_price = float(bids3[2][0]) store_price(last_price) sell_count += 1 store_sell_count(sell_count) response = client.create_order(symbol=trade_pairs, side='SELL', type='LIMIT', quantity=order_ask_quantity, price=float(bids3[2][0]), timeInForce='GTC') logging.warn(response) notify("Notify", notify_str) #mqttc.publish(PUB_TOPIC,payload=notify_str,qos=0) else: if (order_ask_quantity > 0): sleep_time = 5 #buy if (buy_price > float(asks3[2][0])): if ((order_bid_quantity > 0) and (order_bid_quantity < (float(asks3[0][1]) + float(asks3[1][1]) + float(asks3[2][1])))): notify_str = 'BUY EOS price: ' + asks3[2][0] + ' quantity: ' + str( order_bid_quantity)
print("Decreasing") time.sleep(20) continue else: print("Creasing") if (symbolPrice < ma50 * 0.995): print("DINAMIC_BUY") try: buyOrder = client.create_order(symbol=symbolTicker, side='BUY', type='STOP_LOSS_LIMIT', quantity=1.5, price=round(symbolPrice * 1.0055, 7), stopPrice=round( symbolPrice * 1.005, 7), timeInForce='GTC') auxPrice = symbolPrice time.sleep(3) while orderStatus(buyOrder) == 'NEW': # BEGIN GET PRICE try: list_of_tickers = client.get_all_tickers() except Exception as e: with open("BNBBTC_scalper.txt", "a") as myfile: myfile.write(
class BinanceStore(with_metaclass(MetaSingleton, object)): _GRANULARITIES = { (TimeFrame.Minutes, 1): '1m', (TimeFrame.Minutes, 3): '3m', (TimeFrame.Minutes, 5): '5m', (TimeFrame.Minutes, 15): '15m', (TimeFrame.Minutes, 30): '30m', (TimeFrame.Minutes, 60): '1h', (TimeFrame.Minutes, 120): '2h', (TimeFrame.Minutes, 240): '4h', (TimeFrame.Minutes, 360): '6h', (TimeFrame.Minutes, 480): '8h', (TimeFrame.Minutes, 720): '12h', (TimeFrame.Days, 1): '1d', (TimeFrame.Days, 3): '3d', (TimeFrame.Weeks, 1): '1w', (TimeFrame.Months, 1): '1M', } BrokerCls = None # Broker class will autoregister DataCls = None # Data class will auto register @classmethod def getdata(cls, *args, **kwargs): """Returns ``DataCls`` with args, kwargs""" return cls.DataCls(*args, **kwargs) @classmethod def getbroker(cls, *args, **kwargs): """Returns broker with *args, **kwargs from registered ``BrokerCls``""" return cls.BrokerCls(*args, **kwargs) def __init__(self, api_key, api_secret, coin_refer, coin_target, retries=5): self.binance = Client(api_key, api_secret) self.binance_socket = BinanceSocketManager(self.binance) self.coin_refer = coin_refer self.coin_target = coin_target self.retries = retries self._precision = None self._step_size = None self._cash = 0 self._value = 0 self.get_balance() def retry(method): @wraps(method) def retry_method(self, *args, **kwargs): for i in range(self.retries): time.sleep(500 / 1000) # Rate limit try: return method(self, *args, **kwargs) except BinanceAPIException: if i == self.retries - 1: raise return retry_method @retry def cancel_order(self, order_id): try: self.binance.cancel_order(symbol=self.symbol, orderId=order_id) except BinanceAPIException as api_err: if api_err.code == -2011: # Order filled return else: raise api_err except Exception as err: raise err @retry def create_order(self, side, type, size, price): return self.binance.create_order(symbol=self.symbol, side=side, type=type, timeInForce=TIME_IN_FORCE_GTC, quantity=self.format_quantity(size), price=self.strprecision(price)) @retry def close_open_orders(self): orders = self.binance.get_open_orders(symbol=self.symbol) for o in orders: self.cancel_order(o['orderId']) def format_quantity(self, size): precision = self.step_size.find('1') - 1 if precision > 0: return '{:0.0{}f}'.format(size, precision) return floor(int(size)) @retry def get_asset_balance(self, asset): balance = self.binance.get_asset_balance(asset) return float(balance['free']), float(balance['locked']) def get_balance(self): free, locked = self.get_asset_balance(self.coin_target) self._cash = free self._value = free + locked def get_interval(self, timeframe, compression): return self._GRANULARITIES.get((timeframe, compression)) def get_precision(self): symbol_info = self.get_symbol_info(self.symbol) self._precision = symbol_info['baseAssetPrecision'] def get_step_size(self): symbol_info = self.get_symbol_info(self.symbol) for f in symbol_info['filters']: if f['filterType'] == 'LOT_SIZE': self._step_size = f['stepSize'] @retry def get_symbol_info(self, symbol): return self.binance.get_symbol_info(symbol) @property def precision(self): if not self._precision: self.get_precision() return self._precision def start_socket(self): if self.binance_socket.is_alive(): return self.binance_socket.daemon = True self.binance_socket.start() @property def step_size(self): if not self._step_size: self.get_step_size() return self._step_size def stop_socket(self): self.binance_socket.close() reactor.stop() self.binance_socket.join() def strprecision(self, value): return '{:.{}f}'.format(value, self.precision) @property def symbol(self): return '{}{}'.format(self.coin_refer, self.coin_target)
def trades(self): client = Client(api_key, api_secret) asset = "BNB" balance= (client.get_asset_balance('BTC')) balance = float(balance['free']) startBalance=(client.get_asset_balance('BTC')) startBalance= float(startBalance['free']) #lastPrice = float(Orders.get_ticker(symbol)['lastPrice']) currentPrice = client.get_ticker(symbol='BNBBTC') currentPrice=float(currentPrice['lastPrice']) firstBuyPrice = .00118 numberOfBuys =0 balances = client.get_account() lowCertainty = firstBuyPrice * 0.95 highCertainty = firstBuyPrice * 1.0 sellCertainty = firstBuyPrice * 1.1 buylowCertainty= float(round((balance* 0.05)/currentPrice)) buyhighCertainty= float(round((balance * 0.10)/currentPrice)) sellhighCertainty= float(round(balance * 0.95)) lowCounter= 0 highCounter= 0 sellcounter = 0 cycle = 0 actions = [] print colored('Auto Trading with binance', "cyan") while balance>= (startBalance/2): if lowCounter < 1: if currentPrice >= lowCertainty and currentPrice< highCertainty: order = client.create_order( symbol='BNBBTC', side= Client.SIDE_BUY, type=Client.ORDER_TYPE_MARKET, quantity=buylowCertainty ) firstBuyPrice = currentPrice print colored('bought at low certainty', "blue") balance= (client.get_asset_balance('BTC')) balance = float(balance['free']) lowCounter= lowCounter +1 elif highCounter < 1: elif currentPrice >= highCertainty: order = client.create_order( symbol='BNBBTC', side= Client.SIDE_BUY, type=Client.ORDER_TYPE_MARKET, quantity=buyhighCertainty ) firstBuyPrice = currentPrice print colored('bought at high certainty', "blue") highCounter = highCounter + 1 balance= (client.get_asset_balance('BTC')) balance = float(balance['free']) elif currentPrice >= sellCertainty: order = client.order_market_sell( symbol='BNBBTC', quantity=sellhighCertainty) print colored('sold at high certainty', "blue") sellcounter= sellcounter + 1 balance= (client.get_asset_balance('BTC')) balance = float(balance['free'])
class Market: def __init__(self): self.client = Client(api_key=apiKey, api_secret=apiSecret, tld='us') def buy_coin_possible(self, symbol, percentOfEquity): # Get equity amount of our USD, BTC, ETH accountValue = float(self.client.get_asset_balance("USD")["free"]) accountValue += float( self.client.get_asset_balance("BTC")["free"]) * float( self.client.get_symbol_ticker(symbol="BTCUSD")["price"]) accountValue += float( self.client.get_asset_balance("ETH")["free"]) * float( self.client.get_symbol_ticker(symbol="ETHUSD")["price"]) # calculate how much of the symbol that is moneyToSpend = percentOfEquity * accountValue / 100.0 symbolQuantity = moneyToSpend / float( self.client.get_symbol_ticker(symbol=symbol)["price"]) # get recent trades to see current volatility recentTrades = self.client.get_recent_trades(symbol=symbol) lastTrade = {} totalSum = 0 weightedSum = 0 for trade in recentTrades: if lastTrade == {} or int(trade["time"]) > int(lastTrade["time"]): lastTrade = trade totalSum += float(trade["qty"]) weightedSum += float(trade["price"]) * float(trade["qty"]) weightedAvg = weightedSum / totalSum # calculate the price we should strive for with current volatility symbolQtyAdjustedBefore = symbolQuantity * (1.0 - takerFee) symbolQtyAdjustedAfter = symbolQtyAdjustedBefore * (1.0 - takerFee) endProfitPrice = 0 if weightedAvg > float(lastTrade["price"]): endProfitPrice = weightedAvg + (weightedAvg - float(lastTrade["price"])) * .5 else: endProfitPrice = float( lastTrade["price"]) + abs(weightedAvg - float(lastTrade["price"])) * .5 # calculate stop loss at 3 : 1 risk ratio using expected profit expectedProfit = (endProfitPrice * symbolQtyAdjustedAfter) - ( float(lastTrade["price"]) * symbolQtyAdjustedAfter) if expectedProfit <= 0: return stopLossPrice = float(lastTrade["price"]) - expectedProfit * (1 / 3) # possibleLoss = (stopLossPrice * symbolQtyAdjusted) - (float(lastTrade["price"]) * symbolQtyAdjusted) # for reference # set the limit buy so we get it at the price we want hopefully order = None try: order = self.client.order_limit_buy( symbol=symbol, quantity="{:0.0{}f}".format(symbolQuantity, 3), price="{:0.0{}f}".format( float(lastTrade["price"]) + float(lastTrade["price"]) * .001, 2), ) except exceptions.BinanceAPIException as e: print(e) return # wait 3 seconds. usually small orders will go through immediately but if this scales it wouldn't time.sleep(5) # see if it went through at our price, otherwise cancel it if order is not None: for openOrder in self.client.get_open_orders(): if order["orderId"] == openOrder["orderId"]: self.client.cancel_order(symbol=symbol, orderId=order["orderId"]) return try: # set our end/expected price for this trade self.client.order_limit_sell( symbol=symbol, quantity="{:0.0{}f}".format(symbolQtyAdjustedBefore, 3), price="{:0.0{}f}".format(endProfitPrice, 2)) self.client.create_order( symbol=symbol, side=Client.SIDE_SELL, type=Client.ORDER_TYPE_STOP_LOSS_LIMIT, quantity="{:0.0{}f}".format(symbolQtyAdjustedBefore, 3), price="{:0.0{}f}".format(stopLossPrice, 2), stopPrice="{:0.0{}f}".format(stopLossPrice + .01, 2), timeInForce=Client.TIME_IN_FORCE_GTC) except exceptions.BinanceAPIException as e: print(e) return def get_symbol_price(self, symbol): recentTrades = self.client.get_recent_trades(symbol=symbol) lastTrade = {} for trade in recentTrades: if lastTrade == {} or int(trade["time"]) > int(lastTrade["time"]): lastTrade = trade return float(lastTrade["price"]) def get_account_value(self): valueInUSD = 0.0 usdBalance = self.client.get_asset_balance("USD") valueInUSD = valueInUSD + float(usdBalance["free"]) + float( usdBalance["locked"]) time.sleep(.1) ethBalance = self.client.get_asset_balance("ETH") ethPrice = self.get_symbol_price("ETHUSD") valueInUSD = valueInUSD + float(ethBalance["free"]) * ethPrice + float( ethBalance["locked"]) * ethPrice time.sleep(.1) btcBalance = self.client.get_asset_balance("BTC") btcPrice = self.get_symbol_price("BTCUSD") valueInUSD = valueInUSD + float(btcBalance["free"]) * btcPrice + float( btcBalance["locked"]) * btcPrice time.sleep(.1) return valueInUSD
from binance.client import Client from binance.websockets import BinanceSocketManager from twisted.internet import reactor api_key = "WK8dITaZRDlJ2DRSjxZdrHbuvMRhSafCls8WdhGrmNArF3FoSxUmjlto3iTOvWDU" api_secret = "acEjoqKOJ0TNlVYoZgDYrKVIYvStBfxAmCJG90rj3GYi7jlOJzwqqcAeLcLZN4BK" client = Client(api_key, api_secret) client.API_URL = 'https://testnet.binance.vision/api' #print(client.get_asset_balance(asset='ETH')) print(client.get_account()) try: order = client.create_order( symbol='ETHUSDT', side=Client.SIDE_BUY, type=Client.ORDER_TYPE_MARKET, quantity=1, ) except BinanceAPIException as e: # error handling goes here print(e) except BinanceOrderException as e: # error handling goes here print(e) print(order) print(client.get_asset_balance(asset='ETH'))
class PriceTunnelTrader: def __init__(self, tunnels): self.bot = BotSettings.objects.all()[0] self.telegram_bot = telegram.Bot(token=self.bot.telegram_bot.token) self.tech_chat = self.bot.telegram_bot.chat.get( name='Binance_Tech_Vice_Trader_chat') self.info_chat = self.bot.telegram_bot.chat.get( name='Binance_Vice_Trader_chat') self.tunnels = tunnels self.client = Client(self.bot.binance_api.api_key, self.bot.binance_api.api_secret) self.profit_threshold = self.bot.profit_threshold def init_trade(self, tunnel): new_trade = Deals.objects.create( base_pair=tunnel.symbol_tuple[0], middle_pair=tunnel.symbol_tuple[1], end_pair=tunnel.symbol_tuple[2], init_qty=tunnel.qty_final, expected_base_price=tunnel.price_info[0], expected_middle_price=tunnel.price_info[1], expected_end_price=tunnel.price_info[2], reverse=tunnel.reverse, expected_invest_amount=tunnel.invest_amount, expected_profit=tunnel.profit_abs, expected_return=tunnel.return_amount, expected_roi=tunnel.roi) self.place_base_order(new_trade) def place_base_order(self, trade): order = self.client.create_order(symbol=trade.base_pair, side='BUY', type='LIMIT', timeInForce='IOC', quantity=1, price=1) if order['status'] == 'FILLED': trade.base_order_id = order['clientOrderId'] trade.invest = order['cummulativeQuoteQty'] trade.datetime_base_pair = datetime.datetime.utcfromtimestamp( int(order['transactTime']) / 1000).replace(tzinfo=timezone.get_current_timezone()) trade.save() def place_middle_order(self): pass def place_end_order(self): pass def _is_repeated_deal(self, symbol_tuple, price_tuple, init_qty): now = timezone.now() deals = Deals.objects.filter( date_open__range=(now - timezone.timedelta(minutes=1), now)) init_hash = hash(( symbol_tuple[0], symbol_tuple[1], symbol_tuple[2], price_tuple[0], price_tuple[1], price_tuple[2], init_qty, )) if deals: for deal in deals: check_hash = hash(( deal.base_pair, deal.middle_pair, deal.end_pair, deal.base_price, deal.middle_price, deal.end_price, deal.init_qty, )) if check_hash == init_hash: return True return False def check_profit_trade(self): for tunnel in self.tunnels[::-1]: repeated_trade = self._is_repeated_deal(tunnel.symbol_tuple, tunnel.price_info, tunnel.qty_final) if tunnel.profit_abs > self.profit_threshold and tunnel.invest_amount > 10 and not repeated_trade: self.inform_telegram(tunnel) #self.init_trade(tunnel) #Result already sorted, if no profit, break elif tunnel.profit_abs > self.profit_threshold: continue else: break def inform_telegram(self, tunnel): deal = Deals.objects.create( base_pair=tunnel.symbol_tuple[0], middle_pair=tunnel.symbol_tuple[1], end_pair=tunnel.symbol_tuple[2], init_qty=tunnel.qty_final, expected_base_price=tunnel.price_info[0], expected_middle_price=tunnel.price_info[1], expected_end_price=tunnel.price_info[2], reverse=tunnel.reverse, expected_invest=tunnel.invest_amount, expected_return=tunnel.return_amount, expected_roi=tunnel.roi, expected_profit=tunnel.profit_abs, hypothetical_invest=tunnel.should_info[0], hypothetical_return=tunnel.should_info[1], hypothetical_profit=tunnel.should_info[2], ) message = '''Есть сделка в плюс ROI = {0} % Ожидаемый профит = {1} $ Схема = {2} Инвест = {3} $ Возврат = {4} $ '''.format(round(tunnel.roi, 2), round(tunnel.profit_abs, 8), tunnel.symbol_tuple, round(tunnel.invest_amount, 8), round(tunnel.return_amount, 8)) while True: try: #print(tunnel) self.telegram_bot.send_message(self.tech_chat.chat_id, message) except: continue break
class TriangularArbitrageModel: def __init__(self, base_asset, quote_asset, tertiary_asset): # Construct the Binance API client self.client = Client(os.environ.get('STELLA_API_KEY'), os.environ.get('STELLA_SECRET_KEY')) self.base_asset = base_asset self.quote_asset = quote_asset self.tertiary_asset = tertiary_asset self.pair_a = (base_asset, quote_asset) self.pair_b = (quote_asset, tertiary_asset) self.pair_c = (tertiary_asset, base_asset) # get the valid exchange names for each pair self.pair_a_valid_name = valid_pair_name[self.pair_a] self.pair_b_valid_name = valid_pair_name[self.pair_b] self.pair_c_valid_name = valid_pair_name[self.pair_c] # determine if the valid pair needs to be inverted for our model self.pair_a_inversion = self.pair_a_valid_name.startswith( quote_asset) #usdt/eth false self.pair_b_inversion = self.pair_b_valid_name.startswith( tertiary_asset) #eth/btc false self.pair_c_inversion = self.pair_c_valid_name.startswith( base_asset) # btc/usdt false # call get_market_data to update the data self.market_data = {} # call get_order_books to update the data self.order_book_limit = 100 self.pair_a_order_book = {} self.pair_b_order_book = {} self.pair_c_order_book = {} self.base_asset_amount = 0 self.pair_a_quote_fill = 0 self.pair_b_quote_fill = 0 self.implicit_profit = 0 self.debounce = timedelta( 0, 10, 0) # 10 seconds -- decrease this when we get more advanced # initialize last_trade_time so we can trade immediately self.last_trade_time = datetime.now() - self.debounce # holds the last n values for implicit profit self.live_pair_a_fill = [] self.live_pair_b_fill = [] self.live_implicit_profit = [] self.live_implicit_profit_len = 0 self.implicit_rolling_window = 10 # smaller window to calculate for trading strategy self.live_window = 60 self.trade_fee = 0.0005 self.base_asset_account = 0 self.quote_asset_account = 0 self.tertiary_asset_account = 0 # TODO: add filters for min_notional self.pair_a_minQty = 0 self.pair_a_maxQty = 0 self.pair_a_stepSize = 0 self.pair_b_minQty = 0 self.pair_b_maxQty = 0 self.pair_b_stepSize = 0 self.pair_c_minQty = 0 self.pair_c_maxQty = 0 self.pair_c_stepSize = 0 self.exchangeInfo = self.update_exchange_info( ) # update filter information def async_update(self, total_base_asset, profit_conditional): # This method should be called periodically for executing live trading # TODO: get order book data from web socket streams instead of REST API self.update_order_books() self.base_asset_amount = total_base_asset self.pair_a_quote_fill = self._get_order_book_quote_value( self.pair_a_order_book, total_base_asset, self.pair_a_inversion) self.pair_b_quote_fill = self._get_order_book_quote_value( self.pair_b_order_book, self.pair_a_quote_fill, self.pair_b_inversion) self.implicit_profit = self._get_order_book_quote_value( self.pair_c_order_book, self.pair_b_quote_fill, self.pair_c_inversion) # update the time series for last n implicit profits self.live_implicit_profit_len = len(self.live_implicit_profit) if self.live_implicit_profit_len >= self.live_window: self.live_pair_a_fill.pop(0) self.live_pair_b_fill.pop(0) self.live_implicit_profit.pop(0) self.live_pair_a_fill.append(self.pair_a_quote_fill) self.live_pair_b_fill.append(self.pair_b_quote_fill) self.live_implicit_profit.append(self.implicit_profit) # CONDITIONAL FOR PLACING TRADES debounce_conditional = (datetime.now() - self.last_trade_time >= self.debounce) implicit_rolling_average = self.implicit_profit if self.live_implicit_profit_len > self.implicit_rolling_window: implicit_rolling_average = sum( self.live_implicit_profit[-self.implicit_rolling_window:] ) / float(self.implicit_rolling_window) if debounce_conditional and (self.implicit_profit > implicit_rolling_average > profit_conditional): print() print('Implicit profit is: ', self.implicit_profit) print('implicit_rolling_average: ', implicit_rolling_average) pre_trade = datetime.now() print('Placing arbitrage trades', str(pre_trade)) # self.place_arbitrage_trade(total_base_asset) # self.place_arbitrage_trade() post_trade = datetime.now() print('Arbitrage trades complete: ', str(post_trade)) print('Time to complete trades: ', str(post_trade - pre_trade)) print() self.last_trade_time = post_trade else: print('Trade conditional not met. Implicit profit: ', self.implicit_profit) def update_exchange_info(self): exchange_info = self.client.get_exchange_info() for symbol in exchange_info['symbols']: print(symbol['symbol']) print(symbol['filters']) if symbol['symbol'] == self.pair_a_valid_name: self.pair_a_minQty = symbol['filters'][1]['minQty'] self.pair_a_maxQty = symbol['filters'][1]['maxQty'] self.pair_a_stepSize = symbol['filters'][1]['stepSize'] print(self.pair_a_minQty) print(self.pair_a_maxQty) print(self.pair_a_stepSize) for symbol in exchange_info['symbols']: print(symbol['filters']) if symbol['symbol'] == self.pair_b_valid_name: self.pair_b_minQty = symbol['filters'][1]['minQty'] self.pair_b_maxQty = symbol['filters'][1]['maxQty'] self.pair_b_stepSize = symbol['filters'][1]['stepSize'] print(self.pair_b_minQty) print(self.pair_b_maxQty) print(self.pair_b_stepSize) for symbol in exchange_info['symbols']: print(symbol['filters']) if symbol['symbol'] == self.pair_c_valid_name: self.pair_c_minQty = symbol['filters'][1]['minQty'] self.pair_c_maxQty = symbol['filters'][1]['maxQty'] self.pair_c_stepSize = symbol['filters'][1]['stepSize'] print(self.pair_c_minQty) print(self.pair_c_maxQty) print(self.pair_c_stepSize) return exchange_info def test_binance_client(self): depth = self.client.get_order_book(symbol='ETHBTC') print(depth) def place_arbitrage_trade(self): # place the arbitrage based on the model's most recent calculations # we save time by not updating the values # place trade a a_side = SIDE_BUY if self.pair_a_inversion: a_side = SIDE_SELL trade_qty = str( float(self.pair_a_quote_fill) - (float(self.pair_a_quote_fill) % float(self.pair_a_stepSize)))[:7] print('placing order for %s %s' % (trade_qty, self.pair_a_valid_name)) order = self.client.create_order(symbol=self.pair_a_valid_name, side=a_side, type=ORDER_TYPE_MARKET, quantity=trade_qty, recvWindow=10000) print('ORDER: ', order) # TODO: receive trade a fill amount # place trade b b_side = SIDE_BUY if self.pair_b_inversion: b_side = SIDE_SELL trade_qty = str( float(self.pair_b_quote_fill) - (float(self.pair_b_quote_fill) % float(self.pair_b_stepSize)))[:7] print('placing order for %s %s' % (trade_qty, self.pair_b_valid_name)) order = self.client.create_order(symbol=self.pair_b_valid_name, side=b_side, type=ORDER_TYPE_MARKET, quantity=trade_qty, recvWindow=10000) print('ORDER: ', order) # TODO: receive trade b fill amount # place trade c c_side = SIDE_BUY if self.pair_c_inversion: c_side = SIDE_SELL trade_qty = str( float(self.implicit_profit) - (float(self.implicit_profit) % float(self.pair_c_stepSize)))[:7] print('placing order for %s %s' % (trade_qty, self.pair_c_valid_name)) order = self.client.create_order(symbol=self.pair_c_valid_name, side=c_side, type=ORDER_TYPE_MARKET, quantity=trade_qty, recvWindow=10000) print('ORDER: ', order) # TODO: calculate total trade profit from fill amount # print account info after trade self.print_account_info() return def print_account_info(self): self.pair_a_valid_name = valid_pair_name[self.pair_a] self.pair_b_valid_name = valid_pair_name[self.pair_b] self.pair_c_valid_name = valid_pair_name[self.pair_c] info = self.client.get_account(recvWindow=10000) for balance in info['balances']: if balance['asset'] == self.base_asset: print(balance['asset'], balance) print(balance['free']) print('Change %s: %s' % (balance['asset'], float(balance['free']) - float(self.base_asset_account))) self.base_asset_account = float(balance['free']) elif balance['asset'] == self.quote_asset: print(balance['asset'], balance) print(balance['free']) print('Change %s: %s' % (balance['asset'], float(balance['free']) - float(self.quote_asset_account))) self.quote_asset_account = float(balance['free']) elif balance['asset'] == self.tertiary_asset: print(balance['asset'], balance) print('Change %s: %s' % (balance['asset'], float(balance['free']) - float(self.tertiary_asset_account))) self.tertiary_asset_account = float(balance['free']) def testing_ping(self, total_base_asset): # place trades in parallel ep = 'https://api.binance.com/api/v1/ping' get_request_list = [grequests.get(ep)] * 3 responses = grequests.map(get_request_list, exception_handler=self._request_exception, size=3) pair_a_response = responses[0] pair_b_response = responses[1] pair_c_response = responses[2] return def update_market_data(self): # call this once per second response_list = api_lib.get_book_ticker(symbol='all').json() # assign the prices to variables self.market_data['pair_a_ask'] = self._get_ask_from_json( response_list, self.pair_a_valid_name, self.pair_a_inversion) self.market_data['pair_b_ask'] = self._get_ask_from_json( response_list, self.pair_b_valid_name, self.pair_b_inversion) self.market_data['pair_c_ask'] = self._get_ask_from_json( response_list, self.pair_c_valid_name, self.pair_c_inversion) self.market_data['pair_a_bid'] = self._get_bid_from_json( response_list, self.pair_a_valid_name, self.pair_a_inversion) self.market_data['pair_b_bid'] = self._get_bid_from_json( response_list, self.pair_b_valid_name, self.pair_b_inversion) self.market_data['pair_c_bid'] = self._get_bid_from_json( response_list, self.pair_c_valid_name, self.pair_c_inversion) profit1 = float(self.market_data['pair_a_ask']) * float( self.market_data['pair_b_bid']) profit2 = float(self.market_data['pair_b_ask']) * float( self.market_data['pair_c_bid']) profit3 = float(self.market_data['pair_c_ask']) * float( self.market_data['pair_a_bid']) # arbitrage profit is total after making three trades self.market_data[ 'market_arbitrage_profit'] = profit1 * profit2 * profit3 return self.market_data def get_implicit_profit(self, total_base_asset): # get the implied profit from executing a triangular arbitrage trade with the specified base asset amount # this calculates trades against the most recent order book # TODO: implement implicit profit calculation for trading the other direction self.update_order_books() pair_a_quote_bought = self._get_order_book_quote_value( self.pair_a_order_book, total_base_asset, self.pair_a_inversion) pair_b_quote_bought = self._get_order_book_quote_value( self.pair_b_order_book, pair_a_quote_bought, self.pair_b_inversion) base_asset_bought = self._get_order_book_quote_value( self.pair_c_order_book, pair_b_quote_bought, self.pair_c_inversion) self.implicit_profit = base_asset_bought return self.implicit_profit def update_order_books(self): # update order books in parallel # call this sparsely -- when arbitrage_profit is within a specified range ep = 'https://api.binance.com/api/v1/depth' symbols = [ self.pair_a_valid_name, self.pair_b_valid_name, self.pair_c_valid_name ] headers = {'X-MBX-APIKEY': os.environ.get('STELLA_API_KEY')} get_request_list = [] for symbol in symbols: get_request_list.append( grequests.get(ep, params={ 'symbol': symbol, 'limit': self.order_book_limit }, headers=headers)) responses = grequests.map(get_request_list, exception_handler=self._request_exception, size=3) pair_a_response = responses[0] pair_b_response = responses[1] pair_c_response = responses[2] if 429 in [ pair_a_response.status_code, pair_b_response.status_code, pair_c_response.status_code ]: print('Received a status code 429... exiting') exit(1) self.pair_a_order_book = pair_a_response.json() self.pair_b_order_book = pair_b_response.json() self.pair_c_order_book = pair_c_response.json() return [ self.pair_a_order_book, self.pair_b_order_book, self.pair_c_order_book ] @staticmethod def _request_exception(request, exception): print('Error executing HTTP GET request') print("Problem: {}: {}".format(request.url, exception)) exit(1) def _get_order_book_quote_value(self, order_book, total_base_asset, inversion=False): # choose the trading direction dependent on inversion factor # fees are calculated here if inversion: profit = self._get_base_amount_from_sell_quote( order_book, total_base_asset) return profit * (1.0 - self.trade_fee) profit = self._get_quote_amount_from_sell_base(order_book, total_base_asset) return profit * (1.0 - self.trade_fee) @staticmethod def _get_quote_amount_from_sell_base(order_book, total_base_asset): # amount = total_base * price base_to_sell = total_base_asset quote_bought = 0.0 for ask in order_book['asks']: price = float(ask[0]) qty = float(ask[1]) ask_total = price * qty if ask_total >= base_to_sell: # we can buy all we need within this ask's total quote_bought += base_to_sell * price base_to_sell -= base_to_sell break elif base_to_sell > ask_total: # we are trying to buy more than this ask total, move on to next ask quote_bought += ask_total * price base_to_sell -= ask_total if base_to_sell > 0.0: print( 'Not enough order book info to calculate trade quantity. Consider increasing the limit parameter.' ) return quote_bought @staticmethod def _get_base_amount_from_sell_quote(order_book, total_quote_asset): # amount = total_base / price quote_to_sell = total_quote_asset base_bought = 0.0 for bid in order_book['bids']: price = float(bid[0]) qty = float(bid[1]) bid_total = price * qty if bid_total >= quote_to_sell: # we can sell all we need within this bid's total base_bought += quote_to_sell * (1.0 / price) quote_to_sell -= quote_to_sell break elif quote_to_sell > bid_total: # we are trying to sell more than this bid total, move on to next bid base_bought += bid_total * (1.0 / price) quote_to_sell -= bid_total if quote_to_sell > 0.0: print( 'Not enough order book info to calculate trade quantity. Consider increasing the limit parameter.' ) return base_bought @staticmethod def _get_ask_from_json(response_list, pair_valid_name, inversion=False): for symbol_dict in response_list: if symbol_dict['symbol'] == pair_valid_name: if inversion: return 1.0 / float(symbol_dict['askPrice']) return symbol_dict['askPrice'] @staticmethod def _get_bid_from_json(response_list, pair_valid_name, inversion=False): for symbol_dict in response_list: if symbol_dict['symbol'] == pair_valid_name: if inversion: return 1.0 / float(symbol_dict['bidPrice']) return symbol_dict['bidPrice']
client = Client(access_key, secret_key) def write_log(logline): timestamp = datetime.now().strftime("%d/%m %H:%M:%S") with open(LOG_FILE_PATH, 'a+') as f: f.write(timestamp + ' ' + logline + '\n') with open('../coins_bought.json', 'r') as f: coins = json.load(f) for coin in list(coins): sell_coin = client.create_order(symbol=coin, side='SELL', type='MARKET', quantity=coins[coin]['volume']) BuyPrice = float(coins[coin]['bought_at']) LastPrice = float(sell_coin['fills'][0]['price']) profit = (LastPrice - BuyPrice) * coins[coin]['volume'] PriceChange = float((LastPrice - BuyPrice) / BuyPrice * 100) if LOG_TRADES: timestamp = datetime.now().strftime("%d/%m %H:%M:%S") write_log( f"Sell: {coins[coin]['volume']} {coin} - {BuyPrice} - {LastPrice} Profit: {profit:.2f} {PriceChange:.2f}%" ) os.remove('../coins_bought.json')