Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OCO order failing with error "APIError(code=-1102): Mandatory parameter 'aboveType' was not sent, was empty/null, or malformed." #1544

Closed
stucchi opened this issue Jan 9, 2025 · 1 comment · Fixed by #1545
Assignees

Comments

@stucchi
Copy link

stucchi commented Jan 9, 2025

Describe the bug
Trying to use create_oco_order I get an error about aboveType, more precisely:

File "/lib/python3.13/site-packages/binance/client.py", line 84, in _handle_response
raise BinanceAPIException(response, response.status_code, response.text)
binance.exceptions.BinanceAPIException: APIError(code=-1102): Mandatory parameter 'aboveType' was not sent, was empty/null, or malformed.

The strange thing is that the python version does not include the parameter that the error talks about, as we can see from the client.py implementation

def create_oco_order(self, **params):
        """Send in a new OCO order

        https://binance-docs.github.io/apidocs/spot/en/#new-order-list-oco-trade

        :param symbol: required
        :type symbol: str
        :param listClientOrderId: A unique id for the list order. Automatically generated if not sent.
        :type listClientOrderId: str
        :param side: required
        :type side: str
        :param quantity: required
        :type quantity: decimal
        :param limitClientOrderId: A unique id for the limit order. Automatically generated if not sent.
        :type limitClientOrderId: str
        :param price: required
        :type price: str
        :param limitIcebergQty: Used to make the LIMIT_MAKER leg an iceberg order.
        :type limitIcebergQty: decimal
        :param stopClientOrderId: A unique id for the stop order. Automatically generated if not sent.
        :type stopClientOrderId: str
        :param stopPrice: required
        :type stopPrice: str
        :param stopLimitPrice: If provided, stopLimitTimeInForce is required.
        :type stopLimitPrice: str
        :param stopIcebergQty: Used with STOP_LOSS_LIMIT leg to make an iceberg order.
        :type stopIcebergQty: decimal
        :param stopLimitTimeInForce: Valid values are GTC/FOK/IOC.
        :type stopLimitTimeInForce: str
        :param newOrderRespType: Set the response JSON. ACK, RESULT, or FULL; default: RESULT.
        :type newOrderRespType: str
        :param recvWindow: the number of milliseconds the request is valid for
        :type recvWindow: int

Instead, looking for API documentation, the parameter is correctly indicated here

To Reproduce

client = Client(api_key, api_secret)
oco_order = self.client.create_oco_order(
            symbol=self.symbol,
            side=Client.SIDE_SELL,
            quantity=quantity,
            price=str(profit_price),  # Limit price for profit-taking
            stopPrice=str(stop_price),  # Stop price for loss prevention
            stopLimitPrice=str(stop_limit_price),  # Stop-limit sell price
            stopLimitTimeInForce="GTC" # Good Till Cancelled
            )

Expected behavior
The order cannot be placed, it just crashes because of the missing parameter

Environment (please complete the following information):

  • Python version: Python 3.13.1
  • OS: Mac
  • python-binance version: 1.0.26

Logs

here

2025-01-09 23:12:13,963 - asyncio - DEBUG - Using selector: KqueueSelector
2025-01-09 23:12:13,968 - urllib3.connectionpool - DEBUG - Starting new HTTPS connection (1): api.binance.com:443
2025-01-09 23:12:14,225 - urllib3.connectionpool - DEBUG - https://api.binance.com:443 "GET /api/v3/ping HTTP/1.1" 200 2
2025-01-09 23:12:14,460 - urllib3.connectionpool - DEBUG - https://api.binance.com:443 "GET /api/v3/klines?interval=1m&limit=100&symbol=ETHUSDC HTTP/1.1" 200 4723
2025-01-09 23:12:14,709 - urllib3.connectionpool - DEBUG - https://api.binance.com:443 "POST /api/v3/orderList/oco HTTP/1.1" 400 98
Traceback (most recent call last):
  File "/Users/lucastucchi/Projects/thescalper/main_obj.py", line 13, in <module>
    scalper.run()
    ~~~~~~~~~~~^^
  File "/Users/lucastucchi/Projects/thescalper/scalper.py", line 115, in run
    self.set_oco_order(result)
    ~~~~~~~~~~~~~~~~~~^^^^^^^^
  File "/Users/lucastucchi/Projects/thescalper/scalper.py", line 138, in set_oco_order
    oco_order = self.client.create_oco_order(
        symbol=self.symbol,
    ...<5 lines>...
        stopLimitTimeInForce="GTC" # Good Till Cancelled
        )
  File "/Users/lucastucchi/Projects/thescalper/lib/python3.13/site-packages/binance/client.py", line 1566, in create_oco_order
    return self._post("orderList/oco", True, data=params)
           ~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/lucastucchi/Projects/thescalper/lib/python3.13/site-packages/binance/client.py", line 167, in _post
    return self._request_api("post", path, signed, version, **kwargs)
           ~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/lucastucchi/Projects/thescalper/lib/python3.13/site-packages/binance/client.py", line 99, in _request_api
    return self._request(method, uri, signed, **kwargs)
           ~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/lucastucchi/Projects/thescalper/lib/python3.13/site-packages/binance/client.py", line 75, in _request
    return self._handle_response(self.response)
           ~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^
  File "/Users/lucastucchi/Projects/thescalper/lib/python3.13/site-packages/binance/client.py", line 84, in _handle_response
    raise BinanceAPIException(response, response.status_code, response.text)
binance.exceptions.BinanceAPIException: APIError(code=-1102): Mandatory parameter 'aboveType' was not sent, was empty/null, or malformed.
@stucchi
Copy link
Author

stucchi commented Jan 13, 2025

I figured out what was happening... my call was using parameters from a previous version. The comment in the source code wasn't aligned with the latest version of the API from Binance, so I trusted it and I thought there was a problem in the actual call, which is not true, with the proper parameters the OCO works just fine

The working call is (in my case)

oco_order = self.client.create_oco_order(
            symbol=symbol,
            side=Client.SIDE_SELL,
            quantity=quatity,
            abovePrice=str(round(profit_price,2)),  # Limit price for profit-taking
            belowPrice=str(round(stop_price,2)),  # Stop price for loss prevention
            belowStopPrice=str(round(stop_limit_price,2)),  # Stop-limit sell price
            belowTimeInForce="GTC", # Good Till Cancelled
            aboveType="LIMIT_MAKER",
            belowType="STOP_LOSS_LIMIT"
            )

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants