Buy/Sell iteration

Hi Team,

Python 3.8. API.

Really appreciate any feedback you can provide; Here’s my scenario. Its actaully driving me nuts.

Here’s the sequence of events I am trying to achieve, its classic stuff

  1. Place BUY Limit order to buy 10 tokens say at 1 USD each.
    1A) Wait for confirmation (execution) that I actually own 10 tokens at 1 USD each
  2. Issue SELL Limit order to sell 10 tokens at 1.05 each.

The issue is this. I am getting a confirmation (“FILLED”) after a wait/while loop from 1/1a). So now I KNOW i own 10 tokens.

Time to sell;

When I attempt to sell , I am getting “INSUFFICIENT ASSETS” . The BUY limit order has executed (I can see it in Binance APP). NOW I am in a position to sell the same asset at buy price +1.5%, say. Fails eveytime with insufficient FUNDS. I can SEE it in my wallet though. I can also see it in trade/order history. But BINANCE API won’t let me sell it. Do I need to invert the symbol pairs? I mean, buy FTM/BUSD, then sell BUSD/FTM

Confused.com! :slight_smile:\
Code looks like this;

// buy/sell code

def place_buy_limit_order(client, symbol_pair: str, qty: int, prc: float):
order = client.order_limit_buy(
symbol = symbol_pair,
quantity = qty,
price = prc)

 print("PLACING BUY TRADE: Pair:", symbol_pair , "BUYING qty: ", qty, ", ExecutedQty: ",  order["executedQty"], ", BUY Price: ", prc, ", Quantity Ordered: ", qty)
 print(order["executedQty"])
 print(order["status"])
 print(order)
 executed_qty = float(order["executedQty"])
 status = order["status"]
 orderId = order['orderId']
 return executed_qty, status, orderId

def place_sell_limit_order(client, symbol_pair: str, qty: int, prc: float):
order = client.order_limit_sell(
symbol = symbol_pair,
quantity = qty,
price = prc)

 print("PLACING SELL TRADE: Pair:", symbol_pair , "SELLING qty: ", qty, ", ExecutedQty: ",  order["executedQty"], ", SELL Price: ", prc, ", Quantity Ordered: ", qty)
 print(order["status"])
 print(order)
 executed_qty = float(order["executedQty"])
 status = order["status"]
 orderId = order['orderId']
 return executed_qty, status, orderId

----------------------- THIS IS BUY/SELL LOOP that fails consistently with LIMIT SELL ORDER (Insufficient funds)

    while True:

        trade_listener.merge_latest_trades_to_historical()
        trade = ma_mgr.calculate()
        if trade:


            buy_price = ma_mgr.get_latest_price()
            buy_sell_quantity = 4
            executed_qty, status, orderId, = place_buy_limit_order(client, str(symbol1 + symbol2), buy_sell_quantity, buy_price)
            print("PLACED ORDER: qty:", buy_sell_quantity, "executed quantity" , executed_qty, "STATUS:", status)

            while status != "FILLED":
                venue_response = client.get_order(
                    symbol=str(symbol1 + symbol2),
                    orderId=orderId)
                status = venue_response["status"]

                response = client.get_asset_balance("FTM")
                print("Here's your FTM Balance:", response)
                sleep(1)

            print("FILLED, executed qty: ", executed_qty, ", ordered Qty: ", buy_sell_quantity, ", OrderStatus: ", status)

            print("We are LONG!!!")

            ###################### WE NOW OWN
            sleep(1)

            sell_price = round((buy_price * 1.015), 2)
            print("Sell Price: ",  sell_price)

            sleep(5)

            executed_qty = 0.0
            status = ""
            print("BUY PRICE: " , buy_price, ", SELLLLLLLLLLLLLLLLLLLLLLLLLLING for: ",  sell_price)
            executed_qty, status , orderId = place_sell_limit_order(client, str(symbol1 + symbol2), buy_sell_quantity, sell_price)

            while status != "FILLED":
                venue_response = client.get_order(
                    symbol=str(symbol1 + symbol2),
                    orderId=orderId)
                status = venue_response["status"]
                balance = client.get_asset_balance(symbol1)
                free_amt = balance["free"]
                if free_amt != buy_sell_quantity:
                    sleep(1)

                sleep(5)


            print("FILLED, executed qty: ", executed_qty, ", ordered Qty: ",buy_sell_quantity)


        else:
            sleep(1)

Your logic looks fine to me but the library you are using does not look like the official binance package. Try using the official one and see if the problem persists.

One more thing to consider is instead of querying the get_order endpoint periodically, you can consider listening to the User Data Stream (https://binance-docs.github.io/apidocs/spot/en/#payload-order-update) for the order update event. This not only improves the speed of receiving an order filled notice but also ensures that you do not break the rate limit rules.