#8351·hummingbot

gate_io_perpetual candles feed: TypeError due to uninitialized quanto_multiplier

Author: NenengRCreated Jul 10, 2026Updated Aug 31, 2026

Describe the bug

The gate_io_perpetual candles feed crashes with TypeError: unsupported operand type(s) for *: 'int' and 'NoneType' when fetch_candles() or WebSocket candle streaming is called before initialize_exchange_data() has completed.

Root Cause

In hummingbot/data_feed/candles_feed/gate_io_perpetual_candles/gate_io_perpetual_candles.py:

  • self.quanto_multiplier is initialized as None in __init__
  • It only gets set when initialize_exchange_data() is called, which fetches the quanto multiplier from the Gate.io API via get_exchange_trading_pair_quanto_multiplier()
  • Both _parse_rest_candles and _parse_websocket_message multiply volume by self.quanto_multiplier:
    python
    volume = i.get("v") * self.quanto_multiplier  # TypeError if quanto_multiplier is None
  • If fetch_candles() is called before initialize_exchange_data() completes (e.g. during validation or when a consumer calls the candle feed immediately after creation), the multiplication fails

Error Message

Trading pair 'BTC-USDT' appears to be invalid on 'gate_io_perpetual': 
unsupported operand type(s) for *: 'int' and 'NoneType'

This error is misleading — the trading pair is valid, but the feed hasn't initialized its exchange data yet.

Impact

  • Candle charts: No chart data is rendered for any gate_io_perpetual trading pair in downstream consumers (e.g. Condor web dashboard, hummingbot-api)
  • WebSocket streams: Candle WS subscriptions fail permanently because hummingbot-api's validate_trading_pair() creates a fresh feed via CandlesFactory.get_candle() and immediately calls fetch_candles() without awaiting initialize_exchange_data()
  • Spot works fine: gate_io (spot) candles feed does not have a quanto_multiplier and is unaffected

Suggested Fix

Option A (in the candles feed itself — preferred):

Default quanto_multiplier to 1 instead of None, and/or call initialize_exchange_data() inside fetch_candles() if not yet initialized:

python
# In __init__:
self.quanto_multiplier = 1  # Safe default until exchange data is fetched

# Or guard in _parse_rest_candles / _parse_websocket_message:
multiplier = self.quanto_multiplier if self.quanto_multiplier is not None else 1
volume = i.get("v") * multiplier

Option B (in consumers like hummingbot-api):

Call await feed.initialize_exchange_data() before fetch_candles():

python
feed = CandlesFactory.get_candle(config)
if hasattr(feed, 'initialize_exchange_data'):
    await feed.initialize_exchange_data()
candles = await feed.fetch_candles(end_time=end_time, limit=1)

Option A is preferred because the candles feed should be resilient to its own initialization order.

Steps to reproduce

  1. Start hummingbot-api with Gate.io perpetual credentials configured
  2. Make a REST API call to fetch candles for gate_io_perpetual with any valid pair:
    POST /market-data/candles
    {"connector_name": "gate_io_perpetual", "trading_pair": "BTC-USDT", "interval": "1m", "max_records": 10}
  3. Or subscribe via WebSocket:
    json
    {"action": "subscribe", "type": "candles", "connector": "gate_io_perpetual", "trading_pair": "BTC-USDT", "interval": "1m"}
  4. The request fails with: Trading pair 'BTC-USDT' appears to be invalid on 'gate_io_perpetual': unsupported operand type(s) for *: 'int' and 'NoneType'
  5. Compare with gate_io (spot) — works correctly

Release version

Latest (pip install hummingbot, tested July 2026)

Type of installation

Source (via pip in conda environment, used with hummingbot-api)

Additional context

  • The same bug pattern likely affects other perpetual connectors that use quanto_multiplier (e.g. binance_perpetual if it has the same field)
  • Workaround applied in hummingbot-api fork by calling initialize_exchange_data() before fetch_candles() in validate_trading_pair()
  • File: hummingbot/data_feed/candles_feed/gate_io_perpetual_candles/gate_io_perpetual_candles.py