Skip to content

fix(rest): send the order identifier params that were declared but dropped - #29

Open
pucedoteth wants to merge 1 commit into
asterdex:masterfrom
pucedoteth:fix-order-identifier-params
Open

fix(rest): send the order identifier params that were declared but dropped#29
pucedoteth wants to merge 1 commit into
asterdex:masterfrom
pucedoteth:fix-order-identifier-params

Conversation

@pucedoteth

Copy link
Copy Markdown

Fixes #1, and the same bug in three more endpoints.

The bug

Four functions in aster/rest_api/account.py accept the parameters that identify which order to act on, and then build the request without them:

def cancel_order (self, symbol: str, orderId: int = None, origClientOrderId: str = None, **kwargs):
    check_required_parameter (symbol, "symbol")
    params = {"symbol": symbol, **kwargs}          # orderId / origClientOrderId dropped

Because the names are bound to the signature, they cannot arrive through **kwargs either — the caller's value is simply discarded.

function endpoint actually sent
query_order GET /fapi/v1/order symbol
cancel_order DELETE /fapi/v1/order symbol
get_open_orders GET /fapi/v1/openOrder symbol
cancel_batch_order DELETE /fapi/v1/batchOrders symbol

The API docs require "Either orderId or origClientOrderId must be sent" on the first three and "Either orderIdList or origClientOrderIdList must be sent" on the fourth, so all four calls fail server-side. There is currently no way to query, cancel or inspect a specific order through the connector.

Captured from the connector with the transport stubbed, no network — the full query string minus timestamp/signature:

before
  query_order          GET    symbol=BTCUSDT
  cancel_order         DELETE symbol=BTCUSDT
  get_open_orders      GET    symbol=BTCUSDT
  cancel_batch_order   DELETE symbol=BTCUSDT

cancel_batch_order has a second problem: both lists are declared as required positionals, so the documented either/or call raises before a request is even built:

TypeError: cancel_batch_order() missing 1 required positional argument: 'origClientOrderIdList'

The fix

Put the parameters into params. cleanNoneValue() in _prepare_params already drops whichever one is None, so only the identifier the caller supplied is sent, and the signature covers it because it is added before sign_request encodes.

For cancel_batch_order the lists also have to go out as JSON arrays with no spaces, per the docs:

orderIdList … e.g. [1234567,2345678]
origClientOrderIdList … e.g. ["my_id_1","my_id_2"], encode the double quotes. No space after comma.

convert_list_to_json_array() in aster/lib/utils.py already produces exactly that string, and was not referenced anywhere in the package — it is wired up here rather than adding anything new. Passing the raw Python lists would instead produce repeated keys (orderIdList=1234567&orderIdList=2345678), which is not the documented format.

Both lists also become optional, matching the docstring that already says "Either orderIdList or origClientOrderIdList must be sent." Existing positional callers are unaffected.

after
  query_order          GET    symbol=BTCUSDT&orderId=12345
  query_order (cid)    GET    symbol=BTCUSDT&origClientOrderId=my_id
  cancel_order         DELETE symbol=BTCUSDT&orderId=12345
  get_open_orders      GET    symbol=BTCUSDT&origClientOrderId=my_id
  cancel_batch (ids)   DELETE symbol=BTCUSDT&orderIdList=[1234567,2345678]
  cancel_batch (cids)  DELETE symbol=BTCUSDT&origClientOrderIdList=["my_id_1","my_id_2"]

(shown URL-decoded; on the wire the brackets and quotes are percent-encoded, which is what the docs ask for)

Notes

@threewave-hun reported this for cancel_order in #1 with essentially this fix. This PR uses cleanNoneValue's existing None handling rather than truthiness checks, and covers the other three endpoints with the same defect.

The repo has no test suite, so there is nothing to add tests to — the before/after above is from driving the real Client with _dispatch_request stubbed out. Happy to add a small tests/ harness if you'd like one.


🤖 Written with Claude Code. All output above is from running the connector locally.

…opped

query_order (), cancel_order (), get_open_orders () and cancel_batch_order ()
all accept the parameters that say *which* order to act on, and then build the
request without them:

    def cancel_order (self, symbol, orderId=None, origClientOrderId=None, **kwargs):
        check_required_parameter (symbol, "symbol")
        params = {"symbol": symbol, **kwargs}

orderId and origClientOrderId are bound to the named parameters, so they can
never arrive through **kwargs either - the value is simply discarded. Every one
of these calls goes out carrying nothing but symbol, and the API requires
"either orderId or origClientOrderId" (either orderIdList or
origClientOrderIdList for the batch), so all four fail server-side. There is no
way to query, cancel or inspect a specific order through the connector.

cancel_batch_order additionally declares both lists as required positionals, so
the documented "either ... or ..." call raises TypeError before any request is
built, and the lists need to be JSON arrays with no spaces per the API docs:

    orderIdList=[1234567,2345678]
    origClientOrderIdList=["my_id_1","my_id_2"]

convert_list_to_json_array () in aster/lib/utils.py already produces exactly
that and was not referenced anywhere in the package - it is wired up here.

Reported for cancel_order in asterdex#1.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
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 this pull request may close these issues.

cancel order bug

1 participant