nautechsystems/nautilus_trader · error
historical open interest request requires `period` metadata
Error message
historical open interest request requires `period` metadata
What it means
Historical open interest custom data requests (BinanceFuturesOpenInterestHist) additionally require a `period` metadata string (the Binance OI stats period such as '5m', '1h'). `required_period_metadata` bails when it is missing or blank.
Solutions
- Add `period` to the request metadata with a Binance-supported period (e.g. "5m","15m","30m","1h","2h","4h","6h","12h","1d")
- Verify the value is serialized as a string, not a number or null
- Trim whitespace in configuration
- Check Binance futures API docs for currently accepted periods if the request is rejected after adding one
Example fix
// before
IndexMap::from([("instrument_id".to_string(), json!("BTCUSDT-PERP.BINANCE"))])
// after
IndexMap::from([
("instrument_id".to_string(), json!("BTCUSDT-PERP.BINANCE")),
("period".to_string(), json!("5m")),
]) Defensive patterns
Strategy: validation
Validate before calling
const OI_PERIODS: [&str; 9] = ["5m","15m","30m","1h","2h","4h","6h","12h","1d"];
let period = data_type.metadata().and_then(|m| m.get("period")).and_then(|v| v.as_str());
assert!(period.map_or(false, |p| OI_PERIODS.contains(&p.trim())), "period metadata required"); Type guard
fn has_period(meta: &Option<IndexMap<String, serde_json::Value>>) -> bool {
meta.as_ref().and_then(|m| m.get("period")).and_then(|v| v.as_str()).map(str::trim).map_or(false, |s| !s.is_empty())
} Try / catch
match client.request_data(data_type).await {
Err(e) if e.to_string().contains("requires `period` metadata") => return Err(anyhow::anyhow!("add period metadata e.g. '5m'")),
other => other,
} Prevention
- Include period metadata for OpenInterestHist requests
- Use a builder that pairs instrument_id and period together
- Validate period against Binance's accepted set
When it happens
Trigger: request_data on data type BinanceFuturesOpenInterestHist where metadata lacks a `period` key, has a non-string value, or an empty/whitespace value.
Common situations: Constructing the OpenInterestHist DataCmd without period metadata, or copying a snippet for spot open interest (which has no period) and reusing it for futures hist.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- custom data request requires `instrument_id` metadata
- period required for historical open interest
- Binance Futures custom data requires BINANCE venue…
- Binance Futures does not support
- Binance Futures does not support second-level kline…
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/01c5f95ed869ed71.
Report an issue: GitHub.
Appendix: source
Thrown at crates/adapters/binance/src/futures/data.rs:492
.filter(|value| !value.is_empty())
else {
anyhow::bail!("custom data request requires `instrument_id` metadata");
};
InstrumentId::from_str(raw_instrument_id)
.with_context(|| format!("invalid instrument_id metadata `{raw_instrument_id}`"))
}
fn required_period_metadata(data_type: &DataType) -> anyhow::Result<String> {
let Some(period) = data_type
.metadata()
.as_ref()
.and_then(|m| m.get("period"))
.and_then(|v| v.as_str())
.map(str::trim)
.filter(|value| !value.is_empty())
else {
anyhow::bail!("historical open interest request requires `period` metadata");
};
Ok(period.to_string())
}
fn coinm_open_interest_hist_params(
http: &BinanceFuturesHttpClient,
instrument_id: &InstrumentId,
) -> anyhow::Result<(String, String)> {
let symbol = format_binance_symbol(instrument_id);
if let Some(pair) = symbol.strip_suffix("_PERP") {
return Ok((pair.to_string(), "PERPETUAL".to_string()));
}
let definition = http
.instrument_metadata(*instrument_id)
.with_context(|| format!("missing COIN-M definition for {instrument_id}"))?;
let BinanceFuturesInstrument::CoinM(definition) = definition else {View on GitHub (pinned to 18893faf8b)