nautechsystems/nautilus_trader · error · anyhow::Error

Hyperliquid does not support {a:?} aggregation

Error message

Hyperliquid does not support {a:?} aggregation

What it means

bar_type_to_interval's final match arm rejects aggregation schemes Hyperliquid has no interval concept for. Only Minute, Hour, Day, Week (step 1) and Month (step 1) are supported; aggregations such as Tick, Volume, Value, or Dollar are rejected since they are not exchange-native candle types.

Source

Thrown at crates/adapters/hyperliquid/src/common/parse.rs:470

            30 => ThirtyMinutes,
            _ => anyhow::bail!("Unsupported minute step: {step}"),
        },
        BarAggregation::Hour => match step {
            1 => OneHour,
            2 => TwoHours,
            4 => FourHours,
            8 => EightHours,
            12 => TwelveHours,
            _ => anyhow::bail!("Unsupported hour step: {step}"),
        },
        BarAggregation::Day => match step {
            1 => OneDay,
            3 => ThreeDays,
            _ => anyhow::bail!("Unsupported day step: {step}"),
        },
        BarAggregation::Week if step == 1 => OneWeek,
        BarAggregation::Month if step == 1 => OneMonth,
        a => anyhow::bail!("Hyperliquid does not support {a:?} aggregation"),
    };

    Ok(interval)
}

/// Converts a Nautilus order to Hyperliquid request using a pre-resolved asset index.
///
/// This variant is used when the caller has already resolved the asset index
/// from the instrument cache (e.g., for SPOT instruments where the index
/// cannot be derived from the symbol alone). `slippage_bps` controls the
/// buffer applied when deriving a limit from a stop trigger price.
pub fn order_to_hyperliquid_request_with_asset(
    order: &OrderAny,
    asset: u32,
    price_decimals: u8,
    should_normalize_prices: bool,
    slippage_bps: u32,
) -> anyhow::Result<HyperliquidExchangePlaceOrderRequest> {

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Switch to a time-based aggregation (Minute/Hour/Day/Week/Month) with a supported step.
  2. Compute tick/volume bars locally by subscribing to trades and aggregating in the strategy.
  3. If the aggregation was accidental, correct the BarType construction to the intended time aggregation.
  4. Validate bar specs against supported aggregations before subscribing.

Example fix

// before
let bar_type = BarType::new(instrument_id, 1000, BarAggregation::Volume, PriceType::Last);
// after
let bar_type = BarType::new(instrument_id, 5, BarAggregation::Minute, PriceType::Last);
Defensive patterns

Strategy: validation

Validate before calling

fn hyperliquid_native_aggregation(a: BarAggregation) -> bool {
    matches!(a, BarAggregation::Minute | BarAggregation::Hour
        | BarAggregation::Day | BarAggregation::Week | BarAggregation::Month)
}
if !hyperliquid_native_aggregation(spec.aggregation()) { /* aggregate locally or reject */ }

Prevention

When it happens

Trigger: Passing a BarType with a non-time aggregation (Tick/Volume/Value/Dollar etc.) to request_bars, request_bars_from_http, subscribe_bars, or unsubscribe_bars for the Hyperliquid adapter.

Common situations: Strategies using volume- or tick-bars shared across venues, generic bar configs that assume the adapter resamples locally, or misconfigured BarType builders where the aggregation enum was set by mistake.

Related errors


AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08). Data as JSON: /api/errors/af757ed7b7bc4415. Report an issue: GitHub.