fix(backtest): classify separated USDC/BUSD pairs (BTC-USDC, ETH/USDC) as crypto
Only the USDT spellings were separator-aware in the market classifier, so BTC-USDC, ETH/USDC and BTC-BUSD matched no pattern and fell through to the a_share default (T+1, no shorting, CNY), while the unseparated BTCUSDC and correlation.infer_market already treated them as crypto. Signed-off-by: Rudy Celekli <rudy@gradiahq.com>
This commit is contained in:
1 parent
d7f1b9e22b
commit
5cf858be9c
2 files changed
+53
No files matched your search
@@ -130,6 +130,10 @@ _MARKET_PATTERNS = [
|
||||
# perpetual. Bare metals/FX (XAUUSD) end in USD, not USDT/USDC/BUSD, so
|
||||
# they still reach the forex whitelist below.
|
||||
(re.compile(r"^[A-Z]{2,}(?:USDT|USDC|BUSD)$", re.I), "crypto"),
|
||||
# Separated USDC/BUSD-quoted pairs (BTC-USDC, ETH/USDC). Only the USDT
|
||||
# spellings above were separator-aware, so these fell through to the
|
||||
# a_share default even though the unseparated BTCUSDC is crypto.
|
||||
(re.compile(r"^(?=[A-Z0-9]*[A-Z])[A-Z0-9]+[-/](?:USDC|BUSD)$", re.I), "crypto"),
|
||||
# China futures: product+delivery.exchange (e.g. IF2406.CFFEX, rb2410.SHFE)
|
||||
# Tushare suffix spellings (SHF/CZC/CFX/GFE) classify here too.
|
||||
(
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
"""Separator-spelled USDC/BUSD crypto pairs must classify as crypto.
|
||||
|
||||
``BTCUSDC`` was already crypto, but ``BTC-USDC`` / ``ETH/USDC`` matched no
|
||||
pattern and fell through to the ``a_share`` default (T+1, no shorting, CNY,
|
||||
tushare) even though ``correlation.infer_market`` already called them crypto.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import pytest
|
||||
|
||||
from backtest.correlation import infer_market
|
||||
from backtest.engines._market_hooks import _detect_market, code_currency
|
||||
from src.market_data import detect_source
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"code",
|
||||
["BTC-USDC", "ETH/USDC", "SOL-USDC", "BTC-BUSD", "ETH/BUSD", "btc-usdc", "BTCUSDC"],
|
||||
)
|
||||
def test_separated_usdc_busd_pairs_are_crypto(code: str) -> None:
|
||||
assert _detect_market(code.upper()) == "crypto"
|
||||
assert code_currency(code.upper()) == "USD"
|
||||
assert infer_market(code) == "crypto"
|
||||
|
||||
|
||||
@pytest.mark.parametrize("code", ["BTC-USDC", "ETH/USDC", "BTC-BUSD"])
|
||||
def test_separated_usdc_busd_pairs_use_the_crypto_source_chain(code: str) -> None:
|
||||
assert detect_source(code) == "okx"
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("code", "market"),
|
||||
[
|
||||
("USDCAD", "forex"),
|
||||
("USDCHF", "forex"),
|
||||
("EUR/USD", "forex"),
|
||||
("600000", "a_share"),
|
||||
("000001.SZ", "a_share"),
|
||||
("AAPL", "us_equity"),
|
||||
],
|
||||
)
|
||||
def test_non_crypto_symbols_keep_their_market(code: str, market: str) -> None:
|
||||
assert infer_market(code) == market
|
||||
|
||||
|
||||
@pytest.mark.parametrize("code", ["000001-USDC", "000001/BUSD"])
|
||||
def test_digit_only_base_is_not_crypto(code: str) -> None:
|
||||
assert _detect_market(code) != "crypto"
|
||||
Reference in new issue
Block a user