log("Calculate price to sell at and round.") # find price to sell coins at priceToSell = coinPriceBought * profitMargin # rounding sell price to correct dp roundedPriceToSell = float_to_string(priceToSell, int(-math.log10(minPrice))) # get stop price stopPrice = float_to_string(stopLoss * coinPriceBought, int(-math.log10(minPrice))) log("Attempting to create sell order.") try: # oco order (with stop loss) order = client.create_oco_order(symbol=tradingPair, quantity=coinOrderQty, side=SIDE_SELL, price=roundedPriceToSell, stopPrice=stopPrice, stopLimitPrice=stopPrice, stopLimitTimeInForce=TIME_IN_FORCE_GTC) except BinanceAPIException as e: print("A BinanceAPI error has occurred. Code = " + str(e.code)) print( e.message + " Please use https://github.com/binance/binance-spot-api-docs/blob/master/errors.md to find " "greater details " "on error codes before raising an issue.") log(e) log("Binance API error has occured on sell order.") marketSell(coinOrderQty) quit() except Exception as d:
class BinanceAPI: def __init__(self): self.client = Client(config.api_key, config.api_secret) def get_open_trades(self, market): order = self.client.get_open_orders(symbol=market) return order def cancel_order(self, market, orderID): order = self.client.cancel_order(symbol=market, orderId=orderID) return order def get_balance(self, market="BTC"): balance = self.client.get_asset_balance(asset=market) balance = balance['free'] return balance def get_market_price(self, market): depth = self.client.get_order_book(symbol=market, limit=5) lastBid = float(depth['bids'][0][0]) #last buy price (bid) lastAsk = float(depth['asks'][0][0]) #last sell price (ask) return lastBid, lastAsk def buy_market(self, market, quantity): order = self.client.order_market_buy(symbol=market, quantity=quantity) return order def sell_market(self, market, quantity): order = self.client.order_market_sell(symbol=market, quantity=quantity) return order def buy_limit(self, market, quantity, rate): order = self.client.order_limit_buy(symbol=market, quantity=quantity, price=rate) return order def sell_limit(self, market, quantity, rate): order = self.client.order_limit_sell(symbol=market, quantity=quantity, price=rate) return order def sell_OCO_order(self, market, quantity, takeProfitPrice, stopLimit, stopLossPrice): order = self.client.create_oco_order( symbol=market, side=SIDE_SELL, quantity=quantity, stopLimitTimeInForce=TIME_IN_FORCE_GTC, price=takeProfitPrice, stopPrice=stopLimit, stopLimitPrice=stopLossPrice) return order def get_exchange_info(self, symbol): info = self.client.get_exchange_info() if symbol != "": return [ market for market in info['symbols'] if market['symbol'] == symbol ][0] return info def get_ticker(self, market): ticker = self.client.get_ticker(symbol=market) return float(ticker['lastPrice']) def transfer_dust(self, symbol): transfer = self.client.transfer_dust(asset=symbol) return transfer
class BnOrder(): def __init__(self) -> None: self.chat_id = BN_CHAT_ID_GROUP # self.chat_id = BN_CHAT_ID self.client = Client(BN_API_KEY, BN_API_SECRET) # self.client = Client(BN_TEST_API_KEY, BN_TEST_API_SECRET) # self.client.API_URL = 'https://testnet.binance.vision/api' self.client.PUBLIC_API_VERSION = "v3" self.bm = bn_UserSocket(self.client) self.tso = None def process_message(self, msg): try: self.send_chat_message("Account Update:\n" + json.dumps(msg)) except Exception as e: logging.error("Process Account Update Error:" + str(e)) self.send_chat_message("Process Account Update Error: " + str(e)) def create_test_order(self, chat_id, symbol, buy_price, amount): try: if self.is_authorized(chat_id): symbol = symbol.strip().upper() + "BTC" logging.error("SYMBOL: " + symbol) order = self.client.create_test_order( symbol=symbol, side=SIDE_BUY, type=ORDER_TYPE_LIMIT, timeInForce=TIME_IN_FORCE_GTC, quantity=amount, price=buy_price) text = "TEST ORDER CREATED: " + json.dumps(order) self.send_chat_message(text) except Exception as e: logging.error("Test Order Failed error:" + str(e)) self.send_chat_message("CREATE TEST ORDER FAILED: " + str(e)) def create_market_buy(self, chat_id, symbol, amount, to_currency="BTC"): try: if self.is_authorized(chat_id): symbol = symbol.strip().upper() + to_currency.strip().upper() amount = round(amount, 8) order = self.client.order_market_buy(symbol=symbol, quantity=amount) text = "REAL BUY CREATED: " + json.dumps(order) self.send_chat_message(text) except Exception as e: logging.error("Test Order Failed error:" + str(e)) self.send_chat_message("CREATE ORDER FAILED: " + str(e)) raise e def get_exchange_symbol(self, sell_coin, buy_coin): try: symbol = buy_coin.strip().upper() + sell_coin.strip().upper() info = self.client.get_symbol_info(symbol) if info is not None: result = self.client.get_symbol_ticker(symbol=symbol) s, t = self.get_step_size(info) return symbol, "BUY", result["price"], info, s, t except Exception as e: logging.error("Symbol fail:" + str(e)) try: symbol = sell_coin.strip().upper() + buy_coin.strip().upper() info = self.client.get_symbol_info(symbol) if info is not None: result = self.client.get_symbol_ticker(symbol=symbol) s, t = self.get_step_size(info) return symbol, "SELL", result["price"], info, s, t except Exception as e: logging.error("Symbol fail:" + str(e)) raise e def get_step_size(self, info): step_size = 0.0 tick_size = 0.0 logging.error("INFO:" + json.dumps(info)) for f in info['filters']: if f['filterType'] == 'LOT_SIZE': step_size = float(f['stepSize']) if f['filterType'] == 'PRICE_FILTER': tick_size = float(f['tickSize']) return step_size, tick_size def create_market_conversion(self, chat_id, sell_coin, total_spend, buy_coin): try: if self.is_authorized(chat_id): symbol, sale_type, price, _, step_size, _ = self.get_exchange_symbol( sell_coin, buy_coin) precision = int(round(-math.log(step_size, 10), 0)) logging.error("AMOUNT:" + str(total_spend)) logging.error("step_size:" + str(step_size)) logging.error("precision:" + str(precision)) logging.error("SALE TYPE:" + str(sale_type)) if sale_type == "SELL": amt_str = "{:0.0{}f}".format(total_spend, precision) logging.error("QUANTITY:" + str(amt_str)) order = self.client.order_market_sell(symbol=symbol, quantity=amt_str) text = "SELL " + str( amt_str) + " of " + symbol + "\nOrderId:" + str( order["orderId"]) + " STATUS:" + str( order["status"]) + "\nFILLS:\n" + json.dumps( order["fills"]) else: amount = total_spend / float(price) amt_str = "{:0.0{}f}".format(amount, precision) logging.error("QUANTITY:" + str(amt_str)) order = self.client.order_market_buy(symbol=symbol, quantity=amt_str) text = "BUY " + str( amt_str) + " of " + symbol + "\nOrderId:" + str( order["orderId"]) + " STATUS:" + str( order["status"]) + "\nFILLS:\n" + json.dumps( order["fills"]) self.send_chat_message(text) return amt_str, sale_type, symbol, buy_coin, sell_coin except Exception as e: logging.error("Order Failed error:" + str(e)) self.send_chat_message("CREATE ORDER FAILED: " + str(e)) raise e def create_trailing_stop_limit(self, market, buy_coin, sell_coin, type, stop_percentage, interval): try: if self.tso is not None and self.tso.running is True: self.send_chat_message( "OPEN Trailing Stop Limit, Cancel First. ") else: self.tso = TrailingStopLimit(chat_id=self.chat_id, client=self.client, market=market, buy_coin=buy_coin, sell_coin=sell_coin, type=type, stop_percentage=stop_percentage, interval=interval) run(self.tso) except Exception as e: logging.error("Order Failed error:" + str(e)) self.send_chat_message("CREATE ORDER FAILED: " + str(e)) raise e def create_oco_conversion(self, chat_id, sell_coin, amount, buy_coin): try: if self.is_authorized(chat_id): symbol, sale_type, price, info, step_size, price_tick_size = self.get_exchange_symbol( sell_coin, buy_coin) precision = int(round(-math.log(step_size, 10), 0)) amt_str = "{:0.0{}f}".format(float(amount), precision) price_precision = int(round(-math.log(price_tick_size, 10), 0)) logging.error("QUANTITY:" + str(amt_str)) if sale_type == "SELL": # BUY Orders: Limit Price < Last Price < Stop Price sell_price = "{:0.0{}f}".format( float(price) * 0.97, price_precision) stop_price = "{:0.0{}f}".format( float(price) * 1.01, price_precision) stop_limit_price = "{:0.0{}f}".format( float(price) * 1.01, price_precision) order_oco = self.client.create_oco_order( symbol=symbol, side='BUY', quantity=amt_str, price=sell_price, stopPrice=stop_price, stopLimitPrice=stop_limit_price, stopLimitTimeInForce='GTC') else: # TODO check filters # quantity >= minQty # quantity <= maxQty # (quantity-minQty) % stepSize == 0 # SELL Orders: Limit Price > Last Price > Stop Price sell_price = "{:0.0{}f}".format( float(price) * 1.03, price_precision) stop_price = "{:0.0{}f}".format( float(price) * 0.99, price_precision) stop_limit_price = "{:0.0{}f}".format( float(price) * 0.989, price_precision) logging.error("CURRENT PRICE: " + str(price) + " SELL PRICE: " + str(sell_price) + " STOP PRICE:" + str(stop_price) + " STOP LIMIT PRICE:" + str(stop_limit_price)) order_oco = self.client.create_oco_order( symbol=symbol, side='SELL', quantity=amt_str, price=sell_price, stopPrice=stop_price, stopLimitPrice=stop_limit_price, stopLimitTimeInForce='GTC') oco_text = order_oco[ "listOrderStatus"] + " " + self.format_orders( order_oco["orderReports"]) self.send_chat_message(oco_text) except Exception as e: logging.error("OCO Failed error:" + str(e)) self.send_chat_message("CREATE OCO FAILED: " + str(e)) raise e def format_orders(self, orders): oco_text = "OPEN ORDERS:\n" for o in orders: if o["type"] == "STOP_LOSS_LIMIT": oco_text = oco_text + "\nSTOP LOSS:\n" + o["side"] + " " + o[ "symbol"] + "- Stop Limit: " + o[ "stopPrice"] + " Price: " + o["price"] + " Qty:" + o[ "origQty"] + "\n" elif o["type"] == "LIMIT_MAKER": oco_text = oco_text + "\nPROFIT:\n" + o["side"] + " " + o[ "symbol"] + "- Price: " + o["price"] + " Qty:" + o[ "origQty"] + "\n" else: oco_text = oco_text + "\n" + json.dumps(o) + "\n" oco_text = oco_text + "\nCheck Order Status with: /checkorders\n" oco_text = oco_text + "\nCancel All Orders with: /cancelorders\n" return oco_text def create_order(self, chat_id, selling_coin, buying_coin, price, amount): try: if self.is_authorized(chat_id): symbol, sale_type, price, info, step_size = self.get_exchange_symbol( selling_coin, buying_coin) precision = int(round(-math.log(step_size, 10), 0)) if sale_type == "SELL": amt_str = "{:0.0{}f}".format(float(amount), precision) order = self.client.order_limit_sell(symbol=symbol, quantity=amt_str, price=round( float(price), 5)) else: amt_str = "{:0.0{}f}".format(float(amount), precision) order = self.client.order_limit_buy(symbol=symbol, quantity=amt_str, price=round( float(price), 5)) text = "LIMIT ORDER CREATED:\n" + json.dumps(order) self.send_chat_message(text) # self.last_order_id = order['orderId'] # saved_orders = r.get(LIVE_ORDER_KEY.format(self.chat_id)) # if saved_orders is None: # r.set(LIVE_ORDER_KEY.format(self.chat_id), json.dumps({"orders": [order]})) # else: # ar = json.loads(saved_orders.decode("utf-8")) # ar["orders"].append(order) # r.set(LIVE_ORDER_KEY.format(self.chat_id), json.dumps(ar)) self.check_orders(chat_id=chat_id) except Exception as e: logging.error("Test Order Failed error:" + str(e)) self.send_chat_message("CREATE ORDER FAILED: " + str(e)) def check_orders(self, chat_id): try: if self.is_authorized(chat_id): orders = self.client.get_open_orders() self.send_chat_message(self.format_orders(orders)) # saved_orders = r.get(LIVE_ORDER_KEY.format(self.chat_id)) # if saved_orders is not None: # ar = json.loads(saved_orders.decode("utf-8")) # self.send_chat_message("SAVED ORDERS: " + json.dumps(ar)) except Exception as e: logging.error("Check Order Failed error:" + str(e)) self.send_chat_message("CHECK ORDERS FAILED: " + str(e)) def cancel_open_orders(self, chat_id): try: if self.is_authorized(chat_id): if self.tso is not None: self.tso.running = False FORCE_STOP = True orders = self.client.get_open_orders() for order in orders: result = self.client.cancel_order(symbol=order['symbol'], orderId=order["orderId"]) text = "CANCEL RESULT:\n" + json.dumps(result) self.send_chat_message(text) except Exception as e: logging.error("Cancel Order Failed error:" + str(e)) orders = self.client.get_open_orders() if len(orders) > 0: self.send_chat_message("FAILED TO CANCEL ORDER: " + str(e)) def get_usd_price(self, symbol): usd_price = 0 try: usd_price = self.client.get_symbol_ticker(symbol=symbol.upper() + "USDT") return usd_price["price"] except Exception as e: logging.error("USD Price Failed error:" + symbol + " -- " + str(e)) return usd_price def get_btc_price(self, symbol): btc_price = 0 try: btc_price = self.client.get_symbol_ticker(symbol=symbol.upper() + "BTC") return btc_price["price"] except Exception as e: logging.error("BTC Price Failed error:" + symbol + " -- " + str(e)) return btc_price def round_sense(self, price): price = float(price) if price is None or price == 0: return 0 if price > 1000: return int(price) if price > 100: return round(price, 1) if price > 10: return round(price, 2) if price > 0.01: return round(price, 4) if price > 0.001: return round(price, 5) return round(price, 8) def get_user_balance(self, symbol): try: balance = self.client.get_asset_balance(asset=symbol) logging.error("CHeck" + json.dumps(balance)) return float(balance["free"]) except Exception as e: logging.error("Account settings error:" + str(e)) self.send_chat_message("FAILED TO GET BALANCE: " + str(e)) return 0 def get_wallet(self, chat_id): try: if self.is_authorized(chat_id): info = self.client.get_account() balances = info["balances"] # "balances": [{"asset": "BNB", "free": "1014.21000000", "locked": "0.00000000"}, {"asset": "BTC", "free": "0.92797152", "locked": "0.00000000"}, {"asset": "BUSD", "free": "10000.00000000", "locked": "0.00000000"}, {"asset": "ETH", "free": "100.00000000", "locked": "0.00000000"}, {"asset": "LTC", "free": "500.00000000", "locked": "0.00000000"}, {"asset": "TRX", "free": "500000.00000000", "locked": "0.00000000"}, {"asset": "USDT", "free": "10000.00000000", "locked": "0.00000000"}, {"asset": "XRP", "free": "50000.00000000", "locked": "0.00000000"}] out = "<pre>FREE LOCKED BTC USD\n" val = 0 btc_val = 0 for b in balances: quantity = float(b["free"]) + float(b["locked"]) if quantity > 0: if b["asset"].upper() != "BETH": usd_price = float(self.get_usd_price(b["asset"])) btc_price = float(self.get_btc_price(b["asset"])) if b["asset"].upper() in ["BUSD", "USDT"]: usd_value = float(b["free"]) + float( b["locked"]) if btc_price > 0: btc_value = usd_value / btc_price else: btc_value = 0 else: usd_value = usd_price * quantity if b["asset"].upper() == "BTC": btc_price = 1 btc_value = float(b["free"]) + float( b["locked"]) else: btc_value = btc_price * quantity val = val + usd_value btc_val = btc_val + btc_value out = out + "\n" + b["asset"] + " @ $" + str( round(usd_price, 2)) + " BTC" + str(btc_price) + "\n" out = out + str(self.round_sense(b["free"])).ljust( 10, ' ') + " " + str( self.round_sense(b["locked"])).ljust( 8, ' ') + " " + str( self.round_sense(btc_value) ).ljust(8, ' ') + " " + str( self.round_sense(usd_value)) + "\n" out = out + "</pre>\n$" + str(round(val, 2)) + "\n₿" + str( round(btc_val, 6)) self.send_chat_message(out) except Exception as e: logging.error("Account settings error:" + str(e)) self.send_chat_message("FAILED TO GET WALLET: " + str(e)) def send_chat_message(self, text): try: bot_key = TELEGRAM_BOT send_message_url = f'https://api.telegram.org/bot{bot_key}/sendMessage?chat_id={self.chat_id}&text={text}&parse_mode=HTML' resp = requests.post(send_message_url) except Exception as e: logging.error("Failed to send chat message:" + str(e)) def is_authorized(self, chat_id): if self.chat_id is None or int(self.chat_id) != int(chat_id): raise Exception("Unauthorized Chat, use only correct chat.") starter = self.bm.start_user_socket(self.process_message) logging.error("Stream resp:" + str(starter)) return True def get_symbol_trades(self, chat_id, symbol): try: if self.is_authorized(chat_id): trades = self.client.get_my_trades(symbol=symbol.upper() + 'BTC') if len(trades) > 0: sorted_trades = sorted(trades, key=lambda k: k['time'], reverse=True) out = "<pre>DATE TIME SYMBOL SIDE PRICE QUANTITY\n" for t in sorted_trades: if t["isBuyer"] == True: action = "BUY" else: action = "SELL" time_str = datetime.datetime.fromtimestamp( int(t["time"]) / 1000).strftime('%d-%m %H:%M') out = out + time_str + " " + t[ "symbol"] + " " + action + " " + t[ "price"] + " " + t["qty"] + "\n" out = "TRADES vs BTC:\n" + out + "</pre>" self.send_chat_message(out) trades = self.client.get_my_trades(symbol=symbol.upper() + 'USDT') if len(trades) > 0: sorted_trades = sorted(trades, key=lambda k: k['time'], reverse=True) out = "<pre>DATE TIME SYMBOL SIDE PRICE QUANTITY\n" for t in sorted_trades: if t["isBuyer"] == True: action = "BUY" else: action = "SELL" time_str = datetime.datetime.fromtimestamp( int(t["time"]) / 1000).strftime('%d-%m %H:%M') out = out + time_str + " " + t[ "symbol"] + " " + action + " " + t[ "price"] + " " + t["qty"] + "\n" out = "TRADES vs USDT:\n" + out + "</pre>" self.send_chat_message(out) except Exception as e: logging.error("Failed to get trades for symbol chat message:" + str(e)) self.send_chat_message("Failed to get trades for " + symbol + " -- " + str(e))
class Client: def __init__( self, api_key: str, api_secret: str, ) -> None: """ Initialize the Binance client Args: api_key (str): api key for binance api client api_secret (str): api secret for binance api client Return: None """ self.binance_client = BinanceClient( api_key=api_key, api_secret=api_secret ) server_time_utc_iso8601 = datetime_to_iso8601( self.get_binance_api_server_time() ) print(f"Binance API Time: {server_time_utc_iso8601}") if not self.is_binance_api_live(): sys.exit("Binance API is down") print("Binance API is up") def get_binance_api_server_time(self) -> datetime: """Retrieve Binance API UTC server time as a datetime.""" server_time_unix_epoch = self.binance_client.get_server_time() server_time_utc_datetime = datetime.utcfromtimestamp( server_time_unix_epoch["serverTime"]/MULT_MILLISECONDS_TO_SECONDS ) return server_time_utc_datetime def is_binance_api_live(self) -> bool: """Get binance api status.""" return not bool(self.binance_client.get_system_status()["status"]) def get_symbol(self, symbol_name: str) -> Symbol: """ Set the information about a symbol. Args: symbol_name (str): name of the symbol to retrieve Return: Symbol """ symbol_info = self.binance_client.get_symbol_info(symbol_name) if not symbol_info: sys.exit(f"No info found for the symbol {symbol_name}") filters = self._get_filters(symbol_info["filters"]) avg_price = self.get_avg_symbol_price(symbol_name) price_round = decimal_precision_from_scientific_notation( filters.price_filter.min_price ) qty_round = decimal_precision_from_scientific_notation( filters.lot_size_filter.min_qty ) symbol = Symbol( symbol=symbol_info['symbol'], status=symbol_info['status'], baseAsset=symbol_info['baseAsset'], quoteAsset=symbol_info['quoteAsset'], isSpotTradingAllowed=symbol_info['isSpotTradingAllowed'], ocoAllowed=symbol_info['isSpotTradingAllowed'], price_decimal_precision=price_round, qty_decimal_precision=qty_round, average_price=avg_price, filters=filters ) if ( symbol.status != "TRADING" or not symbol.isSpotTradingAllowed ): sys.exit("Spot trading is not allowed on this pair") print("Trading allowed") if not symbol.ocoAllowed: sys.exit("OCO order is not allowed on this pair") print("OCO orders allowed") return symbol def get_avg_symbol_price(self, symbol_name: str) -> Decimal: return Decimal( self.binance_client.get_avg_price(symbol=symbol_name)['price'] ) def _get_filters( self, symbol_filters: List[Dict] ) -> Filters: """ Get the filters. Args: symbol_filters (List of Dict): list of filters as dicts for a given symbol Return: Filters """ price_filter = PriceFilter( min_price=symbol_filters[0]["minPrice"], max_price=symbol_filters[0]["maxPrice"], tick_size=symbol_filters[0]["tickSize"], ) percent_price_filter = PercentPriceFilter( mul_up=symbol_filters[1]["multiplierUp"], mul_down=symbol_filters[1]["multiplierDown"], avg_price_mins=symbol_filters[1]["avgPriceMins"] ) lot_size_filter = LotSizeFilter( min_qty=symbol_filters[2]["minQty"], max_qty=symbol_filters[2]["maxQty"], step_size=symbol_filters[2]["stepSize"] ) market_lot_size_filter = MarketLotSizeFilter( min_qty=symbol_filters[5]["minQty"], max_qty=symbol_filters[5]["maxQty"], step_size=symbol_filters[5]["stepSize"] ) return Filters( price_filter=price_filter, percent_price_filter=percent_price_filter, lot_size_filter=lot_size_filter, market_lot_size_filter=market_lot_size_filter, ) def create_market_buy_order( self, order: MarketOrder ) -> Optional[OrderInProgress]: """ Place a market buy order. Args: order (MarketOrder): Market order to be executed by Binance Return OrderInProgress """ try: buy_order = self.binance_client.order_market_buy( symbol=order.symbol.symbol, quoteOrderQty=order.total, ) order_in_progress = OrderInProgress( id=buy_order["orderId"], order=order ) print("The market order has been sent") except BinanceAPIException as e: print(f"(Code {e.status_code}) {e.message}") return None else: return order_in_progress def create_limit_buy_order( self, order: LimitOrder, ) -> Optional[OrderInProgress]: """ Place a limit buy order. Args: order (LimitOrder): Limit order to be executed by Binance Return OrderInProgress """ try: buy_order = self.binance_client.order_limit_buy( symbol=order.symbol.symbol, quantity=order.quantity, price=order.price, ) order_in_progress = OrderInProgress( id=buy_order["orderId"], order=order ) print("-> The limit buy order has been sent") except BinanceAPIException as e: print(f"(Code {e.status_code}) {e.message}") return None else: return order_in_progress def create_sell_oco_order( self, order: OCOOrder, ) -> Dict: """ Place a Sell OCO order. Args: order: OCOOrder Return: Dict """ try: sell_order = self.binance_client.create_oco_order( symbol=order.symbol.symbol, side=order.side, quantity=order.quantity, price=order.price, stopPrice=order.stop_price, stopLimitPrice=order.stop_limit_price, stopLimitTimeInForce=order.time_in_force ) print("-> The sell oco order has been sent") except BinanceAPIException as e: print(f"(Code {e.status_code}) {e.message}") return {} else: return sell_order def cancel_open_order( self, order_in_progress: OrderInProgress, ) -> Dict: """ Cancel an open order. Args: order_in_progress (OrderInProgress): Order executed by Binance Return Dict """ try: cancel_result = self.binance_client.cancel_order( symbol=order_in_progress.order.symbol.symbol, orderId=order_in_progress.id ) except BinanceAPIException as e: print(f"(Code {e.status_code}) {e.message}") return {} else: return cancel_result def execute_buy_strategy( self, order: Order, ) -> OrderInProgress: """ Execute the buy strategy. Args: order (Order): Order to be executed by Binance Return: OrderInProgress """ print("=> Step 1 - Buy order execution") if isinstance(order, LimitOrder): if not (buy_order_in_progress := self.create_limit_buy_order(order)): sys.exit("Limit buy order has not been created") elif isinstance(order, MarketOrder): if not (buy_order_in_progress := self.create_market_buy_order(order)): sys.exit("Market buy order has not been created")
# once bought we can get info of order coinOrderInfo = order["fills"][0] coinPriceBought = float(coinOrderInfo['price']) coinOrderQty = float(coinOrderInfo['qty']) # rounding sell price to correct dp priceToSell = coinPriceBought * profitMargin roundedPriceToSell = float_to_string(priceToSell, int(- math.log10(minPrice))) try: # oco order (with stop loss) order = client.create_oco_order( symbol=tradingPair, quantity=coinOrderQty, side=SIDE_SELL, price=roundedPriceToSell, stopPrice=float_to_string(stopLoss * coinPriceBought, int(- math.log10(minPrice))), stopLimitPrice=float_to_string(stopLoss * coinPriceBought, int(- math.log10(minPrice))), stopLimitTimeInForce=TIME_IN_FORCE_GTC ) except BinanceAPIException as e: print("A BinanceAPI error has occurred. Code = " + str(e.code)) print( e.message + "Please use https://github.com/binance/binance-spot-api-docs/blob/master/errors.md to find " "greater details " "on error codes before raising an issue.") log("Binance API error has occured on sell order") quit() except Exception as d: print(d) print("An unknown error has occurred.")
from binance.enums import * from binance.exceptions import BinanceAPIException, BinanceOrderException # init api_key = os.environ.get('binance_api') api_secret = os.environ.get('binance_secret') client = Client(api_key, api_secret) ## main try: order = client.create_oco_order(symbol='ETHUSDT', side='SELL', quantity=100, price=250, stopPrice=150, stopLimitPrice=150, stopLimitTimeInForce='GTC') except BinanceAPIException as e: # error handling goes here print(e) except BinanceOrderException as e: # error handling goes here print(e) # use exchange info to confirm order types info = client.get_symbol_info('ETHUSDT') print(info['orderTypes'])
class crypto_currency: def __init__(self, symbol, usdt): #setting API self.client = Client(api_key, api_secret) self.symbol_taapi = (symbol + "/USDT").upper() self.symbol = self.symbol_taapi.replace('/', '') #user info self.balance = 0 #user input defined. self.usdt = usdt #define results self.No_of_Trade = 0 self.Win = 0 self.Lose = 0 #define bband value self.valueUpperBand = 0 self.valueMiddleBand = 0 self.valueLowerBand = 0 #profit_count self.total_profit = 0 #pre-defined risk self.entry_price = 0 self.stop_loss = 0 self.net_profit = 0 self.net_loss = 0 self.set_profit = 0 self.set_loss = 0 #pre-defined risk 2 self.buy_price = 0 self.profit_price = 0 self.med_price = 0 self.loss_price = 0 self.trade_unit = 0 #previous_candle_settings self.candle1_open = 0 self.candle1_close = 0 self.candle1_high = 0 self.candle1_low = 0 #robots testing buy & sell self.robots_is_buy_price_enable = False self.colored_buy_price = False #bot setting self.Trading = [] def pull_user_data(self): self.usdt_asset() self.get_prev_candle() self.current_price = self.symbol_price() self.percentage_risk() self.unit = self.unit_check() def overall_results(self): print('%sWin : %s%s' % (fg(10), attr(0), self.Win)) print('%sLose : %s%s' % (fg(9), attr(0), self.Lose)) print('%sTrade : %s%s' % (fg(117), attr(0), self.No_of_Trade)) print('%sProfit : %s%s' % (fg(165), attr(0), self.total_profit)) print('%sPer-Trade : %s%s' % (fg(43), attr(0), len(self.Trading))) #make the buy colored if success execute. if (self.colored_buy_price == True): print('%sBuy price : %s%s%s%s' % (fg(117), attr(0), fg(43), self.buy_price, attr(0))) else: print('%sBuy price : %s%s' % (fg(117), attr(0), self.buy_price)) print('%sprofit price: %s%s' % (fg(10), attr(0), self.profit_price)) print('%smed price : %s%s' % (fg(11), attr(0), self.med_price)) print('%sloss price : %s%s' % (fg(9), attr(0), self.loss_price)) print('%strade unit : %s%s' % (fg(43), attr(0), self.trade_unit)) def define_buy(self): #indicators self.hammer = self.pattern_hammer() self.invertedhammer = self.pattern_invertedhammer() self.engulfing = self.pattern_engulfing() self.morningstar = self.pattern_morningstar() self.ema20_buy = self.get_ema20_check_buy() self.sma50_buy = self.get_sma50_check_buy() self.sma100_buy = self.get_sma100_check_buy() self.rsi_buy_uptrend = self.get_rsi_check_buy_uptrend() self.rsi_buy_downtrend = self.get_rsi_check_buy_downtrend() self.bbands_buy = self.get_bbands_check_buy() self.macd_buy = self.get_macd_check_buy() self.macd_p4 = self.get_macd_check_buy_past4() self.qstick = self.pattern_qstick() self.qstick25 = self.pattern_qstick25() #special case indicator self._3whitesoldiers = self.pattern_3whitesoldiers() #--------------------------------------------------------------- important part ------------------------------------------------------- #buy bot completed!. def bot_buy_check(self): ''' ''' if (((self.hammer == True or self.invertedhammer == True or self.engulfing == True or self.morningstar == True or self._3whitesoldiers) and ((( # entry price must greater than ema20 and 3% below ema20. (self.current_price >= self.ema20_buy and self.current_price >= (self.ema20_buy - (self.ema20_buy * 0.03))) or # entry price must either 3% greater and lower sma50. ((self.sma50_buy + (self.sma50_buy * 0.03)) >= self.current_price and self.current_price >= (self.sma50_buy - (self.sma50_buy * 0.03))) or # entry price must either 3% greater and lower sma100. ((self.sma100_buy + (self.sma100_buy * 0.03)) >= self.current_price and self.current_price >= (self.sma100_buy - (self.sma100_buy * 0.03))) or #lower bband greater than entry price. (self.bbands_buy == True))) or #downtrend buy 10% below 20 ema.(where incase the candle drop to much. ((self.ema20_buy - (self.ema20_buy * 0.1)) >= self.current_price and self.qstick == False)) and #either rsi,macd. #rsi uptrend set to 35 #((self.rsi_buy_uptrend == True and self.qstick25==True) or ((self.rsi_buy_uptrend == True) or #rsi downtrend set to 25 #(self.rsi_buy_downtrend == True and self.qstick25==False) or (self.rsi_buy_downtrend == True) or #(self.macd_buy == True and self.macd_p4 == True) (self.macd_buy == True))) or #special case indicator here. #Three with soldiers should be with downtrend. (self._3whitesoldiers == True) or #morningstar (self.morningstar == True)): if (float(self.balance) > self.usdt or robots_testing == True): #defined 1 trade per coin. if (len(self.Trading) < No_trading_per_coin): Trading_Dict = { "Id": self.No_of_Trade, "buy_price": self.entry_price, "high_price": self.set_profit, "med_price": self.valueMiddleBand, "low_price": self.set_loss, "unit_amount": self.unit, } #define the price. self.buy_price = self.entry_price self.profit_price = self.set_profit self.med_price = self.valueMiddleBand self.loss_price = self.set_loss self.trade_unit = self.unit #add buy to list. self.Trading.append(Trading_Dict) self.No_of_Trade += 1 def bot_sell_check(self): if (self.current_price == 0): return 0 for sell_check in self.Trading: #just to immitate if robots successfully buy,and price is not zero. # self.robots_is_buy_price_enable is to check if the bot already buy once. if (self.current_price > sell_check['buy_price'] and (self.robots_is_buy_price_enable == False)): self.colored_buy_price = True self.robots_is_buy_price_enable = True ''' #execute buy order. for decimal in range(6,-1,-1): if(decimal == 0): valid_unit_amount = int(sell_check['unit_amount']) else: valid_unit_amount = round(sell_check['unit_amount'],decimal) if(self.order_buy_price(valid_unit_amount,self.current_price) != False): break else: print('%sAttempt to buy.%s' %(fg(43),attr(0))) #execute sell order. # minus unit_amount * 0.002 is trading fee need by binance. valid_unit_amount = sell_check["unit_amount"] - (sell_check["unit_amount"] * 0.002) for decimal in range(6,-1,-1): if(decimal == 0): valid_unit_amount = int(valid_unit_amount) else: valid_unit_amount = round(valid_unit_amount,decimal) if(self.order_oco_sell_price(valid_unit_amount,sell_check["high_price"],sell_check["low_price"]) != False): break else: print('%sAttempt to set sell execution. :( .%s' %(fg(200),attr(0))) ''' if ((self.current_price > sell_check['high_price']) and self.robots_is_buy_price_enable): self.colored_buy_price = False self.robots_is_buy_price_enable = False self.Win += 1 self.total_profit += ( (self.current_price - sell_check['buy_price']) * sell_check["unit_amount"]) self.Trading.remove(sell_check) break if ((self.current_price < sell_check['low_price']) and self.robots_is_buy_price_enable): self.colored_buy_price = False self.robots_is_buy_price_enable = False self.Lose += 1 self.total_profit -= ( (sell_check['buy_price'] - self.current_price) * sell_check["unit_amount"]) self.Trading.remove(sell_check) break if (self.current_price < sell_check['low_price']): self.colored_buy_price = False self.robots_is_buy_price_enable = False self.Trading.remove(sell_check) #--------------------------------------------------------------- important part ------------------------------------------------------- #--------------------------------------------------------------- default function ----------------------------------------------------- ''' !DO NOT TOUCH, CODE ALREADY COMPLETE. ''' #unit is check on the entry price, not on current Price. def unit_check(self): #unit error handling. #check if usdt is larger than current price and 0.1 if (self.usdt > self.entry_price and self.entry_price > 0.1): unit = round(self.usdt / self.entry_price, 1) #check if current price less than 0.1 elif (self.entry_price < 0.1): unit = round(self.usdt / self.entry_price, 0) #check if current price larger than usdt. else: unit = round(self.usdt / self.entry_price, 4) print("current unit: " + str(unit)) return unit ''' !DO NOT TOUCH, CODE ALREADY COMPLETE. ''' def usdt_asset(self): try: balance = self.client.get_asset_balance(asset='USDT') self.balance = balance["free"] print("USDT balance: %s$%s%s" % (fg(220), balance["free"], attr(0))) except: print("USDT balance: Server reset.") ''' !DO NOT TOUCH, CODE ALREADY COMPLETE. ''' def order_buy_price(self, unit_quantity, unit_price): try: self.client.order_limit_buy(symbol=self.symbol, quantity=unit_quantity, price=unit_price) print('%sSuccessful buy!.%s' % (fg(43), attr(0))) return True except BinanceAPIException as e: #print(e.message) #print(e.code) #return e.code return False ''' !DO NOT TOUCH, CODE ALREADY COMPLETE. ''' def order_sell_price(self, unit_quantity, unit_price): try: self.client.order_limit_sell(symbol=self.symbol, quantity=unit_quantity, price=unit_price) return True except BinanceAPIException as e: #print(e.message) #print(e.code) #return e.code return False def order_oco_sell_price(self, unit_quantity, upper_price, lower_price): try: self.client.create_oco_order( symbol=self.symbol, side='sell', stopLimitTimeInForce=TIME_IN_FORCE_GTC, quantity=unit_quantity, price=upper_price, stopPrice=(lower_price + (lower_price * 0.001)), stopLimitPrice=lower_price) print('%sSell execution succeed. :) .%s' % (fg(200), attr(0))) return True except BinanceAPIException as e: #print(e.message) #print(e.code) #return e.code return False #getting price function def symbol_price(self): try: r = requests.get( 'https://api.binance.com/api/v3/ticker/price?symbol=' + self.symbol) value = json.loads(r.text) current_price = round(float(value["price"]), 5) print("symbol : " + value["symbol"]) print("curr price : %s%s%s" % (fg(220), str(current_price), attr(0))) return current_price except: print("curr price : %s%s%s" % (fg(11), "Not Available.", attr(0))) return 0 ''' DO NOT TOUCH,COMPLETE ALREADY. ''' def get_prev_candle(self): endpoint = "https://api.taapi.io/candle" parameters = { 'secret': api_taapi, 'exchange': exchange, 'symbol': self.symbol_taapi, 'interval': interval, 'backtrack': 1 } try: response = requests.get(url=endpoint, params=parameters) result = json.loads(response.text) self.candle1_open = result["open"] self.candle1_close = result["close"] self.candle1_high = result["high"] self.candle1_low = result["low"] except: print("price : %s%s%s" % (fg(11), "Not Available.", attr(0))) return 0 ''' DO NOT TOUCH, COMPLETE ALREADY. ''' #risk calculation #0.0013 is gap on high and lower previous candle. def percentage_risk(self): self.entry_price = round( self.candle1_high + (self.candle1_high * 0.0013), 5) self.stop_loss = round(self.candle1_low - (self.candle1_low * 0.0013), 5) self.net_profit = round(((self.entry_price - self.stop_loss) * 2), 5) self.net_loss = round((self.entry_price - self.stop_loss), 5) self.set_profit = round( self.entry_price + ((self.entry_price - self.stop_loss) * 2), 5) self.set_loss = self.stop_loss print("entry price : %s" % (str(self.entry_price))) #disable,it may duplicate when successful buy. #print('profit set : %s%s%s' % (fg(10),str(self.set_profit),attr(0))) #print('loss set : %s%s%s' % (fg(9),str(self.set_loss),attr(0))) print('profit (2R) : $%s' % (round(self.net_profit * self.trade_unit, 4))) print('loss (1R) : $%s' % (round(self.net_loss * self.trade_unit, 4))) #--------------------------------------------------------------- default function ----------------------------------------------------- #--------------------------------------------------------------- default Api ------------------------------------------------------- ''' !DO NOT TOUCH QSTICK PATTERN, ALREADY COMPLETE. period is set 10 for per minutes. period 25 is to validate with sell price. ''' def pattern_qstick(self): endpoint = "https://api.taapi.io/qstick" parameters = { 'secret': api_taapi, 'exchange': exchange, 'symbol': self.symbol_taapi, 'interval': interval, 'period': 10 } try: response = requests.get(url=endpoint, params=parameters) result = json.loads(response.text) except: return False if (result["value"] > 0): print('%s[+]qstick10 : Uptrend%s ' % (fg(10), attr(0))) return True else: print('%s[-]qstick10 : Downtrend%s ' % (fg(9), attr(0))) return False def pattern_qstick25(self): endpoint = "https://api.taapi.io/qstick" parameters = { 'secret': api_taapi, 'exchange': exchange, 'symbol': self.symbol_taapi, 'interval': interval, 'period': 25 } try: response = requests.get(url=endpoint, params=parameters) result = json.loads(response.text) except: return False if (result["value"] > 0): print('%s[+]qstick25 : Uptrend%s ' % (fg(10), attr(0))) return True else: print('%s[-]qstick25 : Downtrend%s ' % (fg(9), attr(0))) return False #--------------------------------------------------------------- default Api ------------------------------------------------------- #--------------------------------------------------------------- buying mechanism -------------------------------------------------- ''' DO NOT TOUCH THE ALL SPECIAL INDICATOR, ALREADY COMPLETE. all pattern mechanism is set to previous 3 candle stick (backtracks 3) to match with MACD and RSI. ''' def pattern_hammer(self): endpoint = "https://api.taapi.io/hammer" parameters = { 'secret': api_taapi, 'exchange': exchange, 'symbol': self.symbol_taapi, 'interval': interval, 'backtracks': 3 } try: response = requests.get(url=endpoint, params=parameters) results = json.loads(response.text) except: return False for result in results: if (result["value"] == 100): print('%s[+]hammer : Success%s ' % (fg(10), attr(0))) return True print('%s[-]hammer : Failed%s ' % (fg(9), attr(0))) return False def pattern_invertedhammer(self): endpoint = "https://api.taapi.io/invertedhammer" parameters = { 'secret': api_taapi, 'exchange': exchange, 'symbol': self.symbol_taapi, 'interval': interval, 'backtracks': 3 } try: response = requests.get(url=endpoint, params=parameters) results = json.loads(response.text) except: return False for result in results: if (result["value"] == 100): print('%s[+]Ihammer : Success%s ' % (fg(10), attr(0))) return True print('%s[-]Ihammer : Failed%s ' % (fg(9), attr(0))) return False def pattern_engulfing(self): endpoint = "https://api.taapi.io/engulfing" parameters = { 'secret': api_taapi, 'exchange': exchange, 'symbol': self.symbol_taapi, 'interval': interval, 'backtracks': 3 } try: response = requests.get(url=endpoint, params=parameters) results = json.loads(response.text) except: return False for result in results: if (result["value"] == 100): print('%s[+]engulf : Success%s ' % (fg(10), attr(0))) return True print('%s[-]engulf : Failed%s ' % (fg(9), attr(0))) return False def pattern_morningstar(self): endpoint = "https://api.taapi.io/morningstar" parameters = { 'secret': api_taapi, 'exchange': exchange, 'symbol': self.symbol_taapi, 'interval': interval, 'backtracks': 3 } try: response = requests.get(url=endpoint, params=parameters) results = json.loads(response.text) except: return False for result in results: if (result["value"] == 100): print('%s[+]ms : Success%s ' % (fg(10), attr(0))) return True print('%s[-]ms : Failed%s ' % (fg(9), attr(0))) return False def pattern_3whitesoldiers(self): endpoint = "https://api.taapi.io/3whitesoldiers" parameters = { 'secret': api_taapi, 'exchange': exchange, 'symbol': self.symbol_taapi, 'interval': interval, 'backtracks': 3 } try: response = requests.get(url=endpoint, params=parameters) results = json.loads(response.text) except: return False for result in results: if (result["value"] == 100): print('%s[+]3ws : Success%s ' % (fg(10), attr(0))) return True print('%s[-]3ws : Failed%s ' % (fg(9), attr(0))) return False ''' ! DO NOT TOUCH THE CODE, ALREADY COMPLETE. MACD is succeed when histogram is positive, MACD > signalMACD, and it still lower than 0 -remove the comment to enable value display. macd past 3 is to make sure we not buy on high false positive value, as value MACD is set 0.1 higher then signal value. ''' def get_macd_check_buy(self): endpoint = "https://api.taapi.io/macd" parameters = { 'secret': api_taapi, 'exchange': exchange, 'symbol': self.symbol_taapi, 'interval': interval } try: response = requests.get(url=endpoint, params=parameters) result = json.loads(response.text) except: return False if (result["valueMACDHist"] < 0 and ((result["valueMACD"] + abs(result["valueMACD"] * 0.1)) > result["valueMACDSignal"])): #print('%s[+]MACD %s : Success%s ' %(fg(10),round(result["valueMACDHist"],6),attr(0))) print('%s[+]MACD : Success%s ' % (fg(10), attr(0))) return True else: #print('%s[-]MACD %s : Failed%s ' %(fg(9),round(result["valueMACDHist"],6),attr(0))) print('%s[-]MACD : Failed%s ' % (fg(9), attr(0))) return False def get_macd_check_buy_past4(self): endpoint = "https://api.taapi.io/macd" parameters = { 'secret': api_taapi, 'exchange': exchange, 'symbol': self.symbol_taapi, 'interval': interval, 'backtrack': 4 } try: response = requests.get(url=endpoint, params=parameters) result = json.loads(response.text) except: return False if (result["valueMACDHist"] < 0): #print('%s[+]MACD_p4 %s : Success%s ' %(fg(10),round(result["valueMACDHist"],6),attr(0))) print('%s[+]MACD_p4 : Success%s ' % (fg(10), attr(0))) return True else: #print('%s[-]MACD_p4 %s : Failed%s ' %(fg(9),round(result["valueMACDHist"],6),attr(0))) print('%s[-]MACD_p4 : Failed%s ' % (fg(9), attr(0))) return False ''' !DO NOT TOUCH THE CODE, ALREADY COMPLETE. Bollinger band defined. -disable the comment to show the value. ''' def get_bbands_check_buy(self): endpoint = "https://api.taapi.io/bbands" parameters = { 'secret': api_taapi, 'exchange': exchange, 'symbol': self.symbol_taapi, 'interval': interval } try: response = requests.get(url=endpoint, params=parameters) result = json.loads(response.text) except: return False self.valueUpperBand = round(result["valueUpperBand"], 5) self.valueMiddleBand = round(result["valueMiddleBand"], 5) self.valueLowerBand = round(result["valueLowerBand"], 5) if (result["valueLowerBand"] >= self.current_price): #print('%s[+]bbands %s : Success%s' %(fg(10),self.valueLowerBand,attr(0))) print('%s[+]bbands : Success%s' % (fg(10), attr(0))) return True elif (result["valueMiddleBand"] > self.current_price): print('%s[=]bbands : Normal%s ' % (fg(142), attr(0))) return False else: print('%s[-]bbands : Failed%s ' % (fg(9), attr(0))) return False ''' !DO NOT TOUCH THE MA CODE, ALREADY COMPLETE. ''' # Need to check the trend if its up or down for ema20,50,100. # v2 i using ema 20. def get_ema20_check_buy(self): endpoint = "https://api.taapi.io/ema" parameters = { 'secret': api_taapi, 'exchange': exchange, 'symbol': self.symbol_taapi, 'interval': interval, 'optInTimePeriod': 20 } try: response = requests.get(url=endpoint, params=parameters) result = json.loads(response.text) except: return 0 return result["value"] def get_sma50_check_buy(self): endpoint = "https://api.taapi.io/sma" parameters = { 'secret': api_taapi, 'exchange': exchange, 'symbol': self.symbol_taapi, 'interval': interval, 'optInTimePeriod': 50 } try: response = requests.get(url=endpoint, params=parameters) result = json.loads(response.text) except: return 0 return result["value"] def get_sma100_check_buy(self): endpoint = "https://api.taapi.io/sma" parameters = { 'secret': api_taapi, 'exchange': exchange, 'symbol': self.symbol_taapi, 'interval': interval, 'optInTimePeriod': 100 } try: response = requests.get(url=endpoint, params=parameters) result = json.loads(response.text) except: return 0 return result["value"] ''' !DO NOT TOUCH THE CODE, ALREADY COMPLETE. rsi is set to previous 3 candle (backtrack) to get optimise with candle pattern. - remove the comment to enable value display. ''' def get_rsi_check_buy_uptrend(self): endpoint = "https://api.taapi.io/rsi" parameters = { 'secret': api_taapi, 'exchange': exchange, 'symbol': self.symbol_taapi, 'interval': interval, 'backtrack': 3 } try: response = requests.get(url=endpoint, params=parameters) result = json.loads(response.text) except: return False if (result["value"] > 80): #print('%s[-]RSI %s:Failed%s ' %(fg(9),round(result["value"],6),attr(0))) print('%s[-]RSI up : Failed%s ' % (fg(9), attr(0))) return False elif (result["value"] <= 35): #print('%s[+]RSI %s:Success%s' %(fg(10),round(result["value"],6),attr(0))) print('%s[+]RSI up : Success%s' % (fg(10), attr(0))) return True else: #print('%s[=]RSI %s:Normal%s ' %(fg(142),round(result["value"],6),attr(0))) print('%s[=]RSI up : Normal%s ' % (fg(142), attr(0))) return False ''' ! DO NOT TOUCH THE CODE, ALREADY COMPLETE. ''' def get_rsi_check_buy_downtrend(self): endpoint = "https://api.taapi.io/rsi" parameters = { 'secret': api_taapi, 'exchange': exchange, 'symbol': self.symbol_taapi, 'interval': interval, 'backtrack': 3 } try: response = requests.get(url=endpoint, params=parameters) result = json.loads(response.text) except: return False if (result["value"] > 80): #print('%s[-]RSI %s:Failed%s ' %(fg(9),round(result["value"],6),attr(0))) print('%s[-]RSI down : Failed%s ' % (fg(9), attr(0))) return False elif (result["value"] <= 25): #print('%s[+]RSI %s:Success%s' %(fg(10),round(result["value"],6),attr(0))) print('%s[+]RSI down : Success%s' % (fg(10), attr(0))) return True else: #print('%s[=]RSI %s:Normal%s ' %(fg(142),round(result["value"],6),attr(0))) print('%s[=]RSI down : Normal%s ' % (fg(142), attr(0))) return False
sell_limit_price = "{:.8}".format(sell_limit_price) print(sell_limit_price) print("sell limit price after round:" + sell_limit_price) sell_stop_loss = float(current_price) * stop_loss sell_stop_loss = "{:.8f}".format(sell_stop_loss) print(type(sell_stop_loss)) sell_stop_loss_limit = float(sell_stop_loss) * 0.90 sell_stop_loss_limit = "{:.8f}".format(sell_stop_loss_limit) try: order = client.create_oco_order(symbol=market, side='SELL', quantity=number, price=sell_limit_price, stopPrice=sell_stop_loss, stopLimitPrice=sell_stop_loss_limit, stopLimitTimeInForce='GTC') print("OCO order---------------------------------------------\n") print(order) except BinanceAPIException as e: # error handling goes here print(e) except BinanceOrderException as e: # error handling goes here print(e) input("Press enter to exit ;")