fix(backtest): Hong Kong RMB and USD counters stay out of the HKD pool, decided by the code

The BYMA / TSX fix could not close Hong Kong. The hk_equity chain starts with
Tencent and Eastmoney, which declare no currency, so a guard on Yahoo's
declared currency only moved a counter to the next source. The venue gives a
better handle. HKEX's Stock Code Allocation Plan (updated 2026-03-12) assigns
80000-89999 to "Products traded in Renminbi", and 09000-09199, 09200-09399,
09400-09499, 09500-09599, 09700-09799, 09800-09849, 10900-10999 and
41500-41599 to products traded in USD. Every other .HK code trades in HKD, and
that includes 09600-09699 and 09850-09999 (9988.HK, 9618.HK). Checked against
the currency Yahoo declared for 24 codes on 2026-09-24: 6 CNY, 10 USD and
8 HKD, all matching.

Before: 80700.HK (Tencent's RMB counter, 375.40 CNY) or 9834.HK (a USD ETF)
ran in the HK engine's HKD pool next to 00700.HK with no check at all, because
Composite's mixed-currency guard only runs across markets. The grounding gate
also required the answer to call their prices HKD.

- _market_hooks.hk_counter_currency(): the one table. code_currency() uses it,
  so Composite's guard sees CNY / USD counters.
- runner._create_market_engine refuses a Hong Kong code traded in another
  currency, for single-market and cross-market runs alike, before any engine
  prices it.
- grounding identity._infer_currency reads the same table (lazy import, as
  context.py already imports from backtest), so 80700.HK is quoted in CNY
  whichever source served it.

Tests cover the 24 live codes, both sides of every range boundary, the refusal
(mixed, pure RMB, USD, cross-market) and an HKD-only run that still builds.
Mutants each fail: no RMB range (12), a USD range one code too wide (1),
code_currency ignoring the counter (1), the runner guard off (4), grounding
ignoring the counter (1). Related suites: 2769 passed.
This commit is contained in:
Haozhe Wu committed 2026-09-24 20:08:03 +08:00
1 parent 198f73856d
commit 1f6e05d3ba
12 files changed
+167 -20

No files matched your search

+1 -1
View File
@@ -52,7 +52,7 @@
> ⚠️ **보안 경고:** X 계정 `VibeTrading_HKU`, Virtuals 프로젝트 `101845`, 토큰 컨트랙트 `0x640BDBF77b6447E8b7DB7894cED84BD1c40571f4`는 모두 Vibe-Trading 공식과 무관합니다. Vibe-Trading은 어떠한 토큰이나 밈코인도 발행하거나 공식적으로 지지한 적이 없습니다. 해당 토큰을 구매하거나 지갑을 연결하거나 어떠한 서명도 하지 마세요. [자세히 보기](SECURITY.md#official-channels--impersonation).
- **2026-09-24** 💱 **페소로 계산되던 달러 종목, Web UI에 들어온 Email과 WebSocket, 그리고 SDK 업데이트로 깨진 CI**: BYMA와 토론토 증권거래소에는 자국 통화 종목 옆에 미국 달러 종목(GGALD.BA, DLR-U.TO)도 상장되어 있는데, 아르헨티나·캐나다 백테스트는 이를 하나뿐인 페소·캐나다 달러 풀에서 평가했습니다. 이제 로더는 해당 시장 통화로 호가되는 종목만 받아들이고(LSE 종목과 같은 규칙), 그 밖에 소스가 선언한 호가 통화는 데이터와 함께 전달되어 답변에 올바른 통화가 적힙니다([#1576](https://github.com/HKUDS/Vibe-Trading/pull/1576)). 종목 프로필은 발행사 펀더멘털과 별도로 해당 상장 종목의 거래소와 통화를 담고([#1577](https://github.com/HKUDS/Vibe-Trading/pull/1577)), 그라운딩과 종목 검색은 데이터 계층이 다루는 모든 시장을 인식하며([#1575](https://github.com/HKUDS/Vibe-Trading/pull/1575)), `technical_indicators`는 거래량을 소스가 선언한 단위(매매 단위 lot 또는 주, 100배 차이)와 함께 반환합니다([#1571](https://github.com/HKUDS/Vibe-Trading/pull/1571)). Email과 WebSocket이 가이드형 채널 설정에 합류했고, 메일 서버 인증서를 검증하며 크로스사이트 페이지의 설정 쓰기를 막습니다([#1544](https://github.com/HKUDS/Vibe-Trading/pull/1544)). **수정:** openai 3.19.2에서 명시한 provider 헤더가 환경 변수의 같은 이름 헤더에 밀려 모든 PR의 CI가 빨갛게 되던 문제([#1568](https://github.com/HKUDS/Vibe-Trading/pull/1568)), 마이크로초 해상도 소스의 백테스트가 1970년으로 찍히던 문제([#1560](https://github.com/HKUDS/Vibe-Trading/pull/1560)), 명백한 주문인 리서치 목표를 다시 거부([#1562](https://github.com/HKUDS/Vibe-Trading/pull/1562)), strict bench의 OOS 분할이 한쪽을 비울 수 있던 문제([#1559](https://github.com/HKUDS/Vibe-Trading/pull/1559)), HRP 라벨 정렬·교차검증 라벨 순서·유한하지 않은 퀀트 입력([#1555](https://github.com/HKUDS/Vibe-Trading/pull/1555), [#1556](https://github.com/HKUDS/Vibe-Trading/pull/1556), [#1557](https://github.com/HKUDS/Vibe-Trading/pull/1557), [#1558](https://github.com/HKUDS/Vibe-Trading/pull/1558)), 섀도 계정의 과잉 매매 기간([#1563](https://github.com/HKUDS/Vibe-Trading/pull/1563)), 일 단위로 계산되던 자산 성장률([#1564](https://github.com/HKUDS/Vibe-Trading/pull/1564)). [@Shizoqua](https://github.com/Shizoqua), [@zeus229](https://github.com/zeus229), [@shadowinlife](https://github.com/shadowinlife) 님 감사합니다!
- **2026-09-24** 💱 **페소로 계산되던 달러 종목, Web UI에 들어온 Email과 WebSocket, 그리고 SDK 업데이트로 깨진 CI**: BYMA와 토론토 증권거래소에는 자국 통화 종목 옆에 미국 달러 종목(GGALD.BA, DLR-U.TO)도 상장되어 있는데, 아르헨티나·캐나다 백테스트는 이를 하나뿐인 페소·캐나다 달러 풀에서 평가했습니다. 이제 로더는 해당 시장 통화로 호가되는 종목만 받아들이고(LSE 종목과 같은 규칙), 그 밖에 소스가 선언한 호가 통화는 데이터와 함께 전달되어 답변에 올바른 통화가 적힙니다([#1576](https://github.com/HKUDS/Vibe-Trading/pull/1576)). 홍콩거래소가 별도 코드 구간으로 번호를 매기는 위안화·달러 카운터(80700.HK, 9834.HK)도 같은 이유로 홍콩 백테스트에서 거부되고 각자의 통화로 표시됩니다. 종목 프로필은 발행사 펀더멘털과 별도로 해당 상장 종목의 거래소와 통화를 담고([#1577](https://github.com/HKUDS/Vibe-Trading/pull/1577)), 그라운딩과 종목 검색은 데이터 계층이 다루는 모든 시장을 인식하며([#1575](https://github.com/HKUDS/Vibe-Trading/pull/1575)), `technical_indicators`는 거래량을 소스가 선언한 단위(매매 단위 lot 또는 주, 100배 차이)와 함께 반환합니다([#1571](https://github.com/HKUDS/Vibe-Trading/pull/1571)). Email과 WebSocket이 가이드형 채널 설정에 합류했고, 메일 서버 인증서를 검증하며 크로스사이트 페이지의 설정 쓰기를 막으며, SSL 없는 IMAP 로그인도 비밀번호를 보내기 전에 STARTTLS로 암호화합니다([#1544](https://github.com/HKUDS/Vibe-Trading/pull/1544)). **수정:** openai 3.19.2에서 명시한 provider 헤더가 환경 변수의 같은 이름 헤더에 밀려 모든 PR의 CI가 빨갛게 되던 문제([#1568](https://github.com/HKUDS/Vibe-Trading/pull/1568)), 마이크로초 해상도 소스의 백테스트가 1970년으로 찍히던 문제([#1560](https://github.com/HKUDS/Vibe-Trading/pull/1560)), 명백한 주문인 리서치 목표를 다시 거부([#1562](https://github.com/HKUDS/Vibe-Trading/pull/1562)), strict bench의 OOS 분할이 한쪽을 비울 수 있던 문제([#1559](https://github.com/HKUDS/Vibe-Trading/pull/1559)), HRP 라벨 정렬·교차검증 라벨 순서·유한하지 않은 퀀트 입력([#1555](https://github.com/HKUDS/Vibe-Trading/pull/1555), [#1556](https://github.com/HKUDS/Vibe-Trading/pull/1556), [#1557](https://github.com/HKUDS/Vibe-Trading/pull/1557), [#1558](https://github.com/HKUDS/Vibe-Trading/pull/1558)), 섀도 계정의 과잉 매매 기간([#1563](https://github.com/HKUDS/Vibe-Trading/pull/1563)), 일 단위로 계산되던 자산 성장률([#1564](https://github.com/HKUDS/Vibe-Trading/pull/1564)). [@Shizoqua](https://github.com/Shizoqua), [@zeus229](https://github.com/zeus229), [@shadowinlife](https://github.com/shadowinlife) 님 감사합니다!
- **2026-09-23** 🇦🇷 **아르헨티나 종목, 거꾸로 사이징되던 숏 북, 그리고 테일리스크 게이트의 마지막 절반**: `.BA`(BYMA 주식과 CEDEAR)는 자체 ARS 시장으로 Yahoo에 연결되고 웹 UI도 다른 시장과 같이 묶어 표시합니다. BYMA 체결 규칙을 모델링하기 전까지 아르헨티나 백테스트는 다른 시장의 가정을 빌리지 않고 명시적으로 실패합니다([#1543](https://github.com/HKUDS/Vibe-Trading/pull/1543)). 평균-분산 및 회전율 고려 옵티마이저가 모든 포지션을 롱으로 평가해 가장 좋은 숏에 자본이 가장 적게 배분됐습니다. 이제 둘 다 포지션 수익으로 사이징하므로, 상관된 두 종목의 롱과 숏은 상관이 아니라 헤지로 읽힙니다(상관 +0.92인 쌍에서 기존 목적함수는 전액을 롱에, 새 방식은 0.51 / -0.49로 배분)([#1548](https://github.com/HKUDS/Vibe-Trading/pull/1548)). 또한 한 세션이 두 개 이상의 테일리스크 측정치(VaR와 ES, 95%와 99%)를 보유하면 테일리스크 수치는 자신의 필드를 지정해야 하며, ES 95%가 VaR 95% 값을 빌려 쓸 수 없습니다([#1425](https://github.com/HKUDS/Vibe-Trading/issues/1425)). **수정:** 몬테카를로 검증이 하드코딩된 252가 아니라 거래소의 연간 바 수로 연율화해 같은 리포트의 샤프와 어긋나지 않습니다([#1546](https://github.com/HKUDS/Vibe-Trading/pull/1546)). 음수 가격 바에서 선물 주문이 전부 거부되지 않습니다([#1547](https://github.com/HKUDS/Vibe-Trading/pull/1547)). 베이스라인 IC가 음수면 팩터의 IC ratio를 비워 두어 실제 감쇠를 건강한 개선으로 읽지 않습니다([#1549](https://github.com/HKUDS/Vibe-Trading/pull/1549)). 제목이 같고 타입이 다른 두 메모리는 각자의 색인 행과 링크 대상을 유지합니다([#1545](https://github.com/HKUDS/Vibe-Trading/pull/1545)). [@zeus229](https://github.com/zeus229), [@Shizoqua](https://github.com/Shizoqua), [@he-yufeng](https://github.com/he-yufeng) 님 감사합니다!