Automate Cancel TP/SL order

Hello there! I am trying to create a function to cancel automatically the TP & SL orders.

Now I only have this, you are free to help:

OPTION 1:

def check_delete():
    symbol = "BTTUSDT"
    position = client.futures_position_information(symbol = symbol)
    orders = client.futures_get_open_orders(symbol= symbol)
    for value in position:
        if (float(value['entryPrice']) > 0.00001):
            if (len(orders) % 2) == 0:
                pass
            else:
                first = orders[0]
                orderId = int(first["orderId"])
                exchange.cancel_order(str(orderId), 'BTT/USDT')
        else:
            if len(orders) > 0: 
                for order in orders:
                    orderId = int(order["orderId"])
                    exchange.cancel_order(str(orderId), 'BTT/USDT')

What do you think about? This function should be implemented before to create another position.
Like if you have a while and if “condition” you will open an order, this should be good for it.

OPTION 2:

def save_order():
    time.sleep(15)

    # Save last two orders after a position and order have been done
    orders = client.futures_get_open_orders(symbol="BTTUSDT")

    if len(orders) > 1:

        order1 = orders[-1]
        order1_id =  order1["orderId"]
        order2 = orders[-2]
        order2_id = order2["orderId"]
        

        myData = [order1_id, order2_id]

        myFile = open('orders.csv', 'a+')
        writer = csv.writer(myFile)
        writer.writerow(myData)
        myFile.close()
    
    else:
        print("No DATA to save")



def check_delete():
    orders_oppened = []
    orders = client.futures_get_open_orders(symbol="BTTUSDT")
    # Check orders
    if not orders:
        df = pd.read_csv('orders.csv')
        if df.empty == True:
            pass
        else:
            df = pd.read_csv('orders.csv')

            for index, row in df.iterrows():
                order1 = int(row["order1_id"])
                order2 = int(row["order2_id"])
                # Delete the column that has that value
                df = df[df.order2_id != order2]
                df = df.head()

                df.to_csv('orders.csv', index=False, encoding='utf-8') 
                
    else:
        # add orders into a list
        df = pd.read_csv('orders.csv')
        if df.empty == True:
            for order in orders:
                orderId = int(order["orderId"])
                exchange.cancel_order(str(orderId), 'BTT/USDT')

        else:        
            for order in orders:
                orderId = int(order["orderId"])
                orders_oppened.append(orderId)

            df = pd.read_csv('orders.csv')

            for index ,row in df.iterrows():
                order1 = int(row["order1_id"])
                # print(order1)
                order2 = int(row["order2_id"])
                # print(order2)

                if (order1 in orders_oppened) and (order2 in orders_oppened):
                    #print("Están")
                    pass
                if (order1 not in orders_oppened) and (order2 in orders_oppened):
                    # Cancel orders
                    for order in orders:
                        if int(order["orderId"]) == order2:
                            exchange.cancel_order(str(order2), 'BTT/USDT')

                    #Delete orders based in a value
                    df = df[df.order2_id != order2]
                    df = df.head()

                    df.to_csv('orders.csv', index=False, encoding='utf-8') 

                if (order2 not in orders_oppened) and (order1 in orders_oppened):
                    #Cancel order
                    for order in orders:
                        if int(order["orderId"]) == order1:
                            exchange.cancel_order(str(order1), 'BTT/USDT')

                    # Delete column 
                    df = df[df.order1_id != order1]
                    df = df.head()

                    df.to_csv('orders.csv', index=False, encoding='utf-8') 

With that option you should add the function save_order() after a position and order have been created. And then, during your code you will be free to execute check_delete().

What do you think is better or what can you change of it?

Hi,

I reviewed the code above and theoretically it should work, however it could be improved by replacing the the REST API call in the check_delete() function with opening a connection to the User Data Websocket and listening to order updates.

Here is the pseudo code for the above suggestion:

  1. Open connection to User Data websocket stream and listen for order updates (https://binance-docs.github.io/apidocs/futures/en/#event-order-update).
  2. Place TP and SL orders via the Place Multiple Orders endpoint (https://binance-docs.github.io/apidocs/futures/en/#place-multiple-orders-trade)
  3. Store the orderIds of both orders.
  4. When order update is received from the websocket
    4a. If orderStatus = Filled and orderId matches one of the orders stored previously, call Cancel Order endpoint to cancel the remaining order. (https://binance-docs.github.io/apidocs/futures/en/#cancel-order-trade)

This approach is more efficient as it does not rely on polling the API to see if the order is filled, but rather the API pushes the event to me.

The method of storing the orderId’s is up to you, however I would suggest keeping them close by as they will need to be retrieved whenever an order is filled.

Let me know if you have any questions on the above.