Search code examples
pythontradingbinancecryptocurrency

Python Binance Futures - problem creating Take Profit Limit order -> (APIError(code=-2021): Order would immediately trigger.)


Trying to write a basic Binance trading bot in python. Keep getting "APIError(code=-2021): Order would immediately trigger" even though it makes no sense when placing a limit order.

At the time of writing this the ETH/BUSD exchange is rate is at about 1210.

I printed out my current price (1210.00) and target price (1215.44) when take profit is supposed to trigger. I can do this without any problems whatsoever via the Binance GUI and the order is accepted and triggered.

But via the API even if I set my price to over (or under) the current market price and target price to like 2000 (far above the market price) the order is not accepted and I get the same error. I think there is something wrong with my futures_create_order parameters but I cannout figure it out from the documentation. Any help would be greatly appreciated.

Here is my code

from binance.client import Client

test_key = "xxx"
test_secret_key = "xxx"
client = Client(test_key, test_secret_key, testnet = True)

symbol = 'ETHBUSD'
tar_profit = 0.09 #take profit when ROE hits 9%
lev = 20 #leverage

ticker_data = client.futures_symbol_ticker(symbol = symbol)
current_price = float(ticker_data["price"])
cp_adder = 1 + float(tar_profit / lev)
tp_price = round(current_price * cp_adder, 2)
qty = 0.2

client.futures_create_order(
    symbol=symbol,
    side='BUY', #'SELL' or 'BUY'
    type ='TAKE_PROFIT',
    timeInForce='GTC', #good until cancelled
    price = current_price,
    quantity = qty,
    #isolated=True,
    stopPrice = tp_price, #take_profit price
    workingType='CONTRACT_PRICE' #or MARK PRICE
)

Solution

  • Answering my own question because I figured it out.

    Ashamed to admit it but I realized the take profit / stop loss orders are additional separate orders you can send AFTER your first limit/market... order. This means you have to send 2 separate orders to Bianance. If we take a look at my example:

    First I send a limit order to open a long/short position. Right after that I can send an equivalent but opposite take profit order (with reduceOnly parameter set to True; improtant!) which will close my position once the criteria are met.

    So only after the first order is executed and a position is opened can the second order become "active" and close my position.

        client.futures_create_order(
            symbol=symbol,
            side='BUY', #'SELL' or 'BUY'
            type ='LIMIT',
            timeInForce='GTC',
            price = price,
            quantity = qty,
            #isolated=True,
            #stopPrice=stop_price,
            workingType='CONTRACT_PRICE' #or MARK PRICE
            )
    
        client.futures_create_order(
            symbol=symbol,
            side='SELL', #'SELL' or 'BUY'
            type ='TAKE_PROFIT',
            timeInForce='GTC',
            price = price,
            reduceOnly= True,
            quantity = qty,
            #isolated=True,
            stopPrice=stop_price,
            workingType='CONTRACT_PRICE' #or MARK PRICE
            )