Skip to content

bybit/bitget perpetual accounts report HEDGE regardless of the exchange; position-mode switch reports success it can't deliver #210

Closed

Description

@fengtality

Summary

UnifiedConnectorService._create_and_initialize_trading_connector() forces HEDGE on every perpetual connector at init, while the connector has trading_pairs=[]:

if PositionMode.HEDGE in connector.supported_position_modes():
    connector.set_position_mode(PositionMode.HEDGE)

What that does depends on the connector, and for most of them it's harmless. The base PerpetualDerivativePyBase._execute_set_position_mode reads the exchange's mode first: if the account is already HEDGE it sets local HEDGE; if not, it logs "No trading pairs configured" and leaves local at the ONEWAY default. Either way local matches the exchange on binance, okx and gate_io — the call never switches anything, but nothing depends on it doing so.

The bug is in the connectors that override that path, and in the switch endpoint.

1. bybit and bitget report HEDGE regardless of the account

  • bybit overrides _execute_set_position_mode to loop over self.trading_pairs with no exchange read. With an empty list the loop succeeds vacuously and local becomes HEDGE. (supported_position_modes() also returns both modes vacuously on an empty list, so the guard passes.)
  • bitget reads the exchange first, but _fetch_account_position_mode returns None without a pair to query with, then loops over the empty list → local HEDGE.

On a one-way account, orders then carry hedge-mode position fields (bybit positionIdx 1/2, bitget tradeSide) and the exchange rejects them, far from the cause.

hummingbot already has the right init path, _initialize_position_mode() (read the exchange, adopt it), but it runs from start_network(), which the API never calls for CEX connectors (_start_connector_network starts the polling tasks itself).

2. The switch endpoint reports success it can't deliver

POST /trading/{account}/{connector}/position-mode calls connector.set_position_mode(), which fires _execute_set_position_mode in the background and returns immediately. So it returns success when:

  • no pair is registered (the switch no-ops, or on bybit/bitget flips only the local mode), or
  • the exchange rejects the switch (e.g. open positions, Binance -4068).

Not covered

bitmart supports HEDGE but can't read the account's mode; local stays ONEWAY. Same for bybit after the fix: an account in HEDGE must be switched explicitly through the endpoint.

Activity

  1. added a commit that references this issue on Aug 7, 2026
    ed2eec3
  2. added a commit that references this issue on Sep 29, 2026
    ccddb71
  3. changed the title [-]Init-time HEDGE default has never reached the exchange (set_position_mode no-ops with trading_pairs=[])[/-] [+]bybit/bitget perpetual accounts report HEDGE regardless of the exchange; position-mode switch reports success it can't deliver[/+] on Sep 29, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions