-2

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
)

1 Answers1

0

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
        )
  • ADDITION: To apply tp to the entire position instead of a certain quantity: add 'closePosition':True in TAKE_PROFIT => applies tp to the entire position by default. If 'closePosition':True is used, price, quantity and reduceOnly are not needed. reduceOnly is automatically accepted as True. – Pranav Joshi Feb 17 '23 at 11:14