Python bot places a market buy order but fails to create an OCO order

Hello everyone,

I have a trading bot written in Python using the Binance API. The bot successfully places a market buy order, but it fails to create an OCO (One Cancels the Other) order afterward. The error message I receive is:

APIError(code=-1102): Mandatory parameter ‘aboveType’ was not sent, was empty/null, or malformed.

Here is the part of my code responsible for creating the OCO order:

def create_oco_order(symbol):
global order_created, purchase_made

try:
    logger.info(f"🔄 Starting OCO order creation for {symbol}...")

    if purchase_made:
        logger.info(f"⚠ Purchase already made for {symbol}. Skipping.")
        return

    # Get current price
    ticker = client.get_symbol_ticker(symbol=symbol)
    current_price = float(ticker['price'])
    logger.info(f"💰 Current price for {symbol}: {current_price}")

    # Get filters for trading pair
    filters = get_symbol_filters(symbol)
    if not filters:
        logger.error(f"❌ Failed to get filters for {symbol}.")
        return

    min_qty = filters.get('minQty')
    step_size = filters.get('stepSize')
    min_notional = filters.get('minNotional')

    # Calculate quantity
    quantity = 5 / current_price
    quantity = adjust_quantity(quantity, min_qty, step_size, min_notional, current_price)
    logger.info(f"✔ Adjusted quantity: {quantity}")

    # Execute market buy order
    logger.info(f"🛒 Buying {quantity} {symbol} at market price...")
    buy_order = client.order_market_buy(symbol=symbol, quantity=quantity)

    if not buy_order.get('fills'):
        logger.error(f"❌ Purchase failed for {symbol}. 'fills' missing.")
        return

    buy_price = float(buy_order['fills'][0]['price'])
    logger.info(f"✔ Bought {quantity} {symbol} at {buy_price}")

    # Set flag to prevent multiple buys
    purchase_made = True

    # Calculate OCO order prices
    take_profit_price = round(buy_price * 1.05, 8)
    stop_loss_price = round(buy_price * 0.98, 8)
    logger.info(f"🎯 Take Profit: {take_profit_price}, Stop Loss: {stop_loss_price}")

    # Create OCO order
    logger.info(f"⚙ Creating OCO order for {symbol}...")
    oco_order = client.create_oco_order(
        symbol=symbol,
        side=Client.SIDE_SELL,
        quantity=quantity,
        price=take_profit_price,
        stopPrice=stop_loss_price,
        stopLimitPrice=stop_loss_price,
        stopLimitTimeInForce='GTC'
    )

    order_created = True
    logger.info(f"✅ OCO order created for {symbol}!")

except Exception as e:
    logger.error(f"❌ Error creating OCO order for {symbol}: {e}")

I’ve seen similar issues related to aboveType or belowType, but I haven’t found a clear solution.

Could someone provide an updated, working example of placing an OCO order with the latest Binance API requirements?

Thanks in advance!

Hi @Shuriken89,

The Binance error you get indicates that belowType and aboveType parameters, which are mandatory for listing an OCO order, are missing from your request.

You can have a look on the documentation on the mandatory parameters for the OCO trades and how to use them.

Here’s an example of how to structure your OCO order request:

oco_order = client.create_oco_order(
    symbol=symbol,
    side=Client.SIDE_SELL,
    quantity=quantity,
    price=take_profit_price,
    stopPrice=stop_loss_price,
    stopLimitPrice=stop_limit_price,
    stopLimitTimeInForce='GTC',
    aboveType='LIMIT_MAKER',  # Specify the type for the above order
    belowType='STOP_LOSS_LIMIT'  # Specify the type for the below order
)

In this example, aboveType is set to LIMIT_MAKER, and belowType is set to STOP_LOSS_LIMIT. Ensure that these types align with your trading strategy and the specific requirements of your OCO order.

An error occurs after adding aboveType and belowType APIError(code=-1104): Not all sent parameters were read; read ‘9’ parameter(s) but was sent ‘13’.

Having a closer look to the documentation, you need to adjust your parameters based on your trading requirements. A working example for a LIMIT_MAKER and a STOP_LOSS_LIMIT pair of orders would be:

oco_order = client.create_oco_order(
    symbol=symbol,
    side=Client.SIDE_SELL,
    quantity=quantity,
    aboveType="LIMIT_MAKER",
    abovePrice=take_profit_price, # Limit price for sell order
    belowType="STOP_LOSS_LIMIT",
    belowPrice=stop_loss_price, # Stop trigger price
    belowStopPrice=stop_loss_price, # Stop-limit price
    belowTimeInForce="GTC",
)

Keep in mind that you may need to adjust the parameters based on the above and below type order strategies that you need.

Let me know if that works for you!

1 Like

It works, thank you.

Also, could you please provide an example of creating an OCO order with a market stop-loss?

Hey @Shuriken89, you can set belowType to STOP_LOSS which will trigger a market order instead of a limit one.