koala73 / koala73/worldmonitor

feat(markets): add Russian equities + IMOEX via MOEX ISS API

Open
#6,153 0 comments 0 reactions 0 assignees View on GitHub
feature P2
Dominant language
TypeScript
Stars
86.6k
Forks
13.1k
Avg merge
8h 4m
Merged PRs (30d)
825

Description

Split out of #6146 (1 of 3 on the Russia/China market-data thread).

## Gap

We have **zero** Russian market data. MOEX exists in the codebase only as static chrome:

- `src/config/finance-geo.ts:87` — a pin on the exchange map
- `src/components/WorldClockPanel.ts:22` — a market-hours clock

No quotes, no index, no instruments. `IMOEX` and Russian equities are absent from `scripts/shared/stocks.json`.

## Source: MOEX ISS

`https://iss.moex.com/iss` — free, **no key, no registration**, 15-minute delayed. Probed live on 2026-08-04, both 200:

```
GET /iss/engines/stock/markets/index/securities/IMOEX.json?iss.meta=off
→ 200, 1297B, application/json; charset=utf-8
→ ["IMOEX","SNDX","Индекс МосБиржи",2,"Индекс МосБиржи",3014.21,1898.51,"RUB","PR"]
(SECID, BOARDID, NAME, DECIMALS, SHORTNAME, ANNUALHIGH, ANNUALLOW, CURRENCYID, CALCMODE)

GET /iss/engines/stock/markets/shares/boards/TQBR/securities.json?iss.meta=off&iss.only=marketdata
→ 200, 203359B
→ columns: SECID, BOARDID, BID, BIDDEPTH, OFFER, OFFERDEPTH, SPREAD, ..., OPEN, LOW, HIGH, LAST, LASTCHANGE, LASTCHANGEPRCNT, QTY
```

This is the cleanest of the three sources in #6146: **UTF-8 JSON**, no encoding or number-format traps (contrast the CBR issue, which has both).

## Scope

- Add `IMOEX` to the market-quotes surface. The board endpoint also gives the full Russian equity market if we want per-name coverage.
- ISS returns a columnar `{columns: [...], data: [[...]]}` shape — zip by column name, never by positional index, so a column insertion upstream can't silently shift every field.

## Landmine: payload size

The `TQBR` board response is **203KB** raw. Cap it — and per the established seam in this repo, cap in `publishTransform`, **not** in the fetcher, so `extraKeys` consumers still see the full fetched set. Same pattern as the existing bounded-payload seeders.

## Not in scope

Per-user Russian access routing. These are server-side seeders — a user in Russia reads `worldmonitor.app`, not MOEX directly. This issue is about **coverage** (we publish no Russian market data at all), which is a different problem from the one #6146's title describes.

Contributor guide

Open the contributing guide

Research direction

Locate the existing market-data seeders and their bounded-payload publishTransform pattern, then inspect the MOEX ISS IMOEX and TQBR board responses described here. Preserve column-name mapping and keep the fetcher's full result available to extraKeys consumers. Done means Russian market data is published, with the payload cap applied at publishTransform.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
backend, data
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
52/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.