Files
sure/test
Artem Danilov b57bb938da feat(prices): add Moscow Exchange (MOEX ISS) securities + FX provider (#2394)
* feat(prices): add Moscow Exchange (MOEX ISS) securities + FX provider

Add Provider::MoexPublic, a keyless provider built on the free MOEX ISS API
(https://iss.moex.com/iss), modeled on Provider::BinancePublic.

Securities: shares, funds/ETF/БПИФ (e.g. LQDT), and bonds (OFZ + corporate).
Bonds are priced clean — LAST% × FACEVALUE / 100 in the instrument currency,
with per-row FACEVALUE for amortizing issues; NKD/accrued coupon excluded.

Exchange rates: also implements ExchangeRateConcept for RUB↔{USD,EUR,CNY} via
selt TOM instruments (USD000UTSTOM/EUR_RUB__TOM/CNYRUB_TOM); the selt quote is
X/RUB, inverted for RUB→X, nil for non-RUB-crossed pairs.

Details:
- Board/engine resolution via the ISS primary-board flag with a hardcoded
  priority fallback (TQBR, TQTF, TQOB, TQCB, …).
- Instrument currency from CURRENCYID/FACEUNIT (handles USD/CNY eurobonds &
  FX funds), normalizing legacy SUR/RUR → RUB; default RUB.
- Full history via from/till + start= pagination; current price fallback chain
  LAST → MARKETPRICE → LCURRENTPRICE → LCLOSEPRICE → PREVPRICE → latest history
  close.
- Bare SECID identity, exchange_operating_mic=MISX, country_code=nil (wildcard
  like Binance); search accepts .ME/.MOEX/.MISX/.MCX aliases and ISIN.
- RateLimitable throttling, SslConfigurable, Faraday retry/timeouts; all public
  methods wrapped in with_provider_response.

Wired into Provider::Registry for both :securities and :exchange_rates, the
hosting provider-selection UI, locales, and config/exchanges.yml (MISX).

Docker-tested (devcontainer, Ruby 3.4.9): 29 new tests green, full provider
suite + i18n green, rubocop clean; smoke-tested against live ISS (SBER price,
OFZ clean price, USD/RUB FX).

* fix(moex): address review — FX weekend lookback, dead branch, translated hints

- fetch_exchange_rate now fetches a 10-day lookback window (not just the exact
  day) so a weekend/holiday request resolves to the prior trading day's close,
  matching Yahoo's behavior (Codex P2).
- Remove dead identical if/else branches in history_row_price (CodeRabbit).
- Translate moex_public_hint into ca/fr/hu/vi/zh-CN instead of English copy
  (CodeRabbit).
- Add a test covering the FX prior-trading-day lookback.

* fix(moex): guard ISS date parsing; doc TQTE in board priority

Address maintainer review (jjmata):
- parse_iss_date wraps Date.parse so a malformed ISS TRADEDATE skips just that
  row (with a contextual log warning) instead of failing the whole history/FX
  fetch. Used in history_row_price and fx_history.
- Add TQTE to the BOARD_PRIORITY doc comment (it was in the constant but missing
  from the comment).
- Add a test covering the unparseable-date skip.
2026-06-18 10:36:20 +02:00
..
2024-02-02 09:05:04 -06:00
2025-11-17 21:51:37 +01:00