{"record":{"id":"ebda6d3acfc017cb","repo":"nautechsystems/nautilus_trader","slug":"invalid-ticker-format-ticker-expected-base-q","errorCode":null,"errorMessage":"Invalid ticker format '{ticker}', expected 'BASE-QUOTE' (e.g., 'BTC-USD')","messagePattern":"Invalid ticker format '(.+?)', expected 'BASE-QUOTE' \\(e\\.g\\., 'BTC-USD'\\)","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/adapters/dydx/src/http/parse.rs","lineNumber":154,"sourceCode":"    let close = Price::from_decimal_dp(candle.close, price_precision)\n        .context(\"failed to parse candle close price\")?;\n    let volume = Quantity::from_decimal_dp(candle.base_token_volume, size_precision)\n        .context(\"failed to parse candle base_token_volume\")?;\n\n    Ok(Bar::new(\n        bar_type, open, high, low, close, volume, ts_event, ts_init,\n    ))\n}\n\n/// Validates that a ticker has the correct format (BASE-QUOTE).\n///\n/// # Errors\n///\n/// Returns an error if the ticker is not in the format \"BASE-QUOTE\".\npub fn validate_ticker_format(ticker: &str) -> anyhow::Result<()> {\n    let parts: Vec<&str> = ticker.split('-').collect();\n    if parts.len() != 2 {\n        anyhow::bail!(\"Invalid ticker format '{ticker}', expected 'BASE-QUOTE' (e.g., 'BTC-USD')\");\n    }\n\n    if parts[0].is_empty() || parts[1].is_empty() {\n        anyhow::bail!(\"Invalid ticker format '{ticker}', base and quote cannot be empty\");\n    }\n    Ok(())\n}\n\n/// Parses base and quote currency codes from a ticker.\n///\n/// # Errors\n///\n/// Returns an error if the ticker format is invalid.\npub fn parse_ticker_currencies(ticker: &str) -> anyhow::Result<(&str, &str)> {\n    validate_ticker_format(ticker)?;\n    let parts: Vec<&str> = ticker.split('-').collect();\n    Ok((parts[0], parts[1]))\n}","sourceCodeStart":136,"sourceCodeEnd":172,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/dydx/src/http/parse.rs#L136-L172","documentation":"dYdX market tickers must be exactly two non-empty segments joined by a hyphen (`BASE-QUOTE`). `validate_ticker_format` splits on `-` and throws this error when the split does not yield exactly two parts.","triggerScenarios":"Calling `parse_ticker_currencies` (or any code path that validates tickers) with strings like `\"BTCUSD\"`, `\"BTC/USD\"`, `\"BTC-USD-PERP\"`, or an empty string.","commonSituations":"Using Binance-style (`BTCUSDT`) or slash-separated symbols; passing an internal instrument ID instead of the venue ticker; config symbols copied from another exchange adapter.","solutions":["Format the ticker as `BASE-QUOTE`, e.g. `BTC-USD`","Convert exchange-native symbol formats to hyphen-separated form before calling dYdX APIs","Verify the exact ticker with `instruments()` or the dYdX markets endpoint"],"exampleFix":"// before\nparse_ticker_currencies(\"BTCUSD\")?;\n// after\nparse_ticker_currencies(\"BTC-USD\")?;","handlingStrategy":"validation","validationCode":"fn is_valid_ticker(t: &str) -> bool {\n    let parts: Vec<&str> = t.split('-').collect();\n    parts.len() == 2 && !parts[0].is_empty() && !parts[1].is_empty()\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Normalize exchange symbols to BASE-QUOTE before using dYdX adapters","Keep a canonical ticker list fetched from the venue's markets endpoint"],"tags":["rust","dydx","ticker","validation"],"backgroundTag":"invalid-identifier-format","analyzedSha":"18893faf8b356be3320add8de2f861b0b647cf06","analyzedAt":"2026-09-08T20:49:34.690Z","contentChangedAt":"2026-09-08T20:49:34.690Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}