ISS MOEX API: как получать свечи, стакан и сделки без авторизации
ISS MOEX API — публичный REST-интерфейс Московской биржи: можно бесплатно и без регистрации получать спецификации инструментов, исторические свечи, текущие котировки, стакан и ленту сделок. Подходит для бэктестинга, аналитики и pet-проектов, где не нужна реальная торговля. Разбираем структуру URL, ключевые endpoint, парсинг ответа в pandas, ограничения и где это решение заканчивается.
Что такое ISS MOEX API
ISS — Information Statistical Server — это публичный REST API Московской биржи, доступный по адресу https://iss.moex.com/iss/. Он отдаёт данные обо всём, что торгуется на MOEX: акции, облигации, фьючерсы, опционы, валюты, индексы, ETF, БПИФ. Авторизация не требуется для большинства endpoint — данные публичны.
Что можно получать:
- Спецификации инструментов: тикер, ISIN, лот, шаг цены, режим торгов, экспирация для деривативов.
- Исторические свечи (1 минута, 10 минут, час, день, неделя, месяц, квартал).
- Текущие котировки (с задержкой 15 минут — это реальное ограничение, а не баг).
- Стакан (биды/аски) — упрощённый, без полной глубины.
- Лента сделок (тиковые трейды) с задержкой.
- Корпоративные действия: дивиденды, сплиты, размещения.
- Индексы (
IMOEX,RTSI, отраслевые) — состав и веса бумаг.
Что нельзя:
- Торговать. ISS — read-only.
- Получать данные real-time без задержки. Для этого — Plaza-2 или брокерский API (Tinkoff, БКС).
- Стримить через WebSocket. ISS — чистый REST с polling-моделью.
Для бэктестинга, обзорной аналитики, дашбордов и пет-проектов ISS — оптимальный выбор: бесплатно, не требует регистрации, не блокирует по IP при разумных нагрузках.
Структура URL
Базовая модель URL: iss/<engine>/<market>/<resource>. Engine — это рынок, market — секция этого рынка.
https://iss.moex.com/iss/engines/stock/markets/shares/securities/SBER.json
Разбор:
engines/stock— фондовый рынок.markets/shares— акции.securities/SBER— конкретная бумага по тикеру..json— формат ответа (доступны также.xml,.csv,.html).
Engines, доступные на MOEX:
stock— акции, облигации, ETF, БПИФ, ПИФы.futures— фьючерсы и опционы (FORTS).currency— валютный рынок.commodity— товарный рынок (металлы).agro— АГРО-площадка.interventions— валютные интервенции.
Markets внутри stock: shares (акции), bonds (облигации), index (индексы), eq_bob (T-Bond OFZ), etf_bob, foreignshares и др.
Markets внутри futures: forts (срочный рынок), fortsoptions (опционы).
Полный список — https://iss.moex.com/iss/engines/<engine>/markets.json.
Ответ ISS: формат
Ответ ISS — не плоский массив объектов, а табличная структура:
{
"securities": {
"metadata": { ... },
"columns": ["SECID", "BOARDID", "SHORTNAME", "PREVPRICE", "LOTSIZE", ...],
"data": [
["SBER", "TQBR", "Сбербанк", 280.50, 10, ...],
...
]
}
}
Это проектная особенность ISS: данные оптимизированы под минимальный размер ответа, поэтому каждая «таблица» отдельно содержит схему (columns) и данные (data). При парсинге надо собирать словари.
Хелпер на Python:
import requests
def iss_get(url, params=None):
r = requests.get(url, params=params, timeout=15)
r.raise_for_status()
raw = r.json()
out = {}
for table_name, table in raw.items():
if isinstance(table, dict) and "columns" in table and "data" in table:
out[table_name] = [dict(zip(table["columns"], row))
for row in table["data"]]
else:
out[table_name] = table
return out
data = iss_get("https://iss.moex.com/iss/engines/stock/markets/shares/securities/SBER.json")
print(data["securities"][:3])
Получение списка инструментов
# Все акции на MOEX в режиме T+1 (TQBR)
url = "https://iss.moex.com/iss/engines/stock/markets/shares/securities.json"
data = iss_get(url)
shares = [s for s in data["securities"] if s["BOARDID"] == "TQBR"]
print(f"акций в TQBR: {len(shares)}")
print(shares[0])
Ответ содержит ~280 акций с тикером, наименованием, лотом, текущей котировкой. Для конкретной бумаги — добавить тикер в URL: securities/SBER.json.
Для фьючерсов:
url = "https://iss.moex.com/iss/engines/futures/markets/forts/securities.json"
data = iss_get(url)
si_futures = [s for s in data["securities"] if s["SECID"].startswith("Si")]
Получение исторических свечей
Свечи живут на отдельном endpoint candles:
GET https://iss.moex.com/iss/engines/stock/markets/shares/securities/SBER/candles.json
?from=2026-01-01&till=2026-05-01&interval=60
Где interval — длительность свечи в минутах:
1— 1 минута10— 10 минут60— час24— день7— неделя31— месяц4— квартал
Полный пример загрузки в pandas:
import pandas as pd
import requests
def get_candles(secid, market="shares", engine="stock",
from_date="2026-01-01", till_date=None, interval=60):
if till_date is None:
till_date = pd.Timestamp.now().strftime("%Y-%m-%d")
url = (f"https://iss.moex.com/iss/engines/{engine}"
f"/markets/{market}/securities/{secid}/candles.json")
candles = []
start = 0
while True:
r = requests.get(url, params={
"from": from_date,
"till": till_date,
"interval": interval,
"start": start,
}, timeout=15)
r.raise_for_status()
page = r.json()["candles"]
cols = page["columns"]
rows = page["data"]
if not rows:
break
candles.extend([dict(zip(cols, row)) for row in rows])
start += len(rows)
if len(rows) < 500: # ISS отдаёт страницами по 500
break
df = pd.DataFrame(candles)
df["begin"] = pd.to_datetime(df["begin"])
df["end"] = pd.to_datetime(df["end"])
return df.set_index("begin")[["open", "close", "high", "low", "value", "volume"]]
df = get_candles("SBER", interval=60, from_date="2026-04-01")
print(df.tail())
Важный момент: ISS возвращает данные страницами по 500 свечей. Чтобы получить всю историю, нужно пагинировать через параметр start. Без пагинации вы получите только первые 500 свечей и решите, что данных мало.
Время свечей в ISS — московское (UTC+3), без явного указания TZ в формате. Если бэктест на UTC — нужно конвертировать.
Стакан и сделки
Стакан (только лучшие 20 уровней):
url = "https://iss.moex.com/iss/engines/stock/markets/shares/boards/TQBR/securities/SBER/orderbook.json"
data = iss_get(url)
ob = data["orderbook"]
bids = sorted([b for b in ob if b["BUYSELL"] == "B"],
key=lambda x: -x["PRICE"])
asks = sorted([b for b in ob if b["BUYSELL"] == "S"],
key=lambda x: x["PRICE"])
print(f"bid {bids[0]['PRICE']} x {bids[0]['QUANTITY']}")
print(f"ask {asks[0]['PRICE']} x {asks[0]['QUANTITY']}")
Лента сделок (последние 100):
url = "https://iss.moex.com/iss/engines/stock/markets/shares/boards/TQBR/securities/SBER/trades.json"
data = iss_get(url)
trades = data["trades"]
print(f"трейдов в окне: {len(trades)}")
print(trades[-1])
Все эти данные — с задержкой 15 минут относительно реального времени биржи. Для боевого алготрейдинга не подходит, для аналитики и индикаторов на закрытых барах — нормально.
Корпоративные действия и дивиденды
# Дивиденды по бумаге
url = "https://iss.moex.com/iss/securities/SBER/dividends.json"
data = iss_get(url)
divs = data["dividends"]
for d in divs[-5:]:
print(f"{d['registryclosedate']}: {d['value']} ₽ ({d['currencyid']})")
Этот endpoint — главный источник для любого «календаря дивидендов». Не нужно ходить на Smart-lab или disclosure — данные у биржи в первоисточнике.
Состав индексов
# Состав индекса IMOEX
url = "https://iss.moex.com/iss/statistics/engines/stock/markets/index/analytics/IMOEX.json"
data = iss_get(url)
weights = data["analytics"]
for s in sorted(weights, key=lambda x: -x["weight"])[:10]:
print(f"{s['ticker']}: {s['weight']:.2f}%")
Аналогично — RTSI, MOEXBC (голубые фишки), MOEXBMI (бенчмарк), отраслевые индексы.
Подводные камни
- Пагинация. Каждая «большая» выборка отдаётся страницами по 500–1000 строк. Параметр
startдля смещения. Без пагинации — обрезанный ответ. - Поля meta vs data. Иногда нужная информация лежит не в
data, а вmetadataили дополнительной таблице. Структураcandlesотличается отsecurities, и каждое API имеет свои поля. - Тайм-зона. ISS возвращает время в московском часовом поясе как «naive datetime» — без указания TZ. Для конверсии в UTC:
pd.to_datetime(df['begin']) - pd.Timedelta(hours=3). - Праздники и выходные. ISS не выдаёт «нулевых свечей» в нерабочие часы — пропуски в индексе нужно обрабатывать в коде самостоятельно.
- Переименования бумаг. При смене тикера старый тикер в ISS какое-то время остаётся доступным, потом исчезает. Историю надо подгружать с актуальным тикером.
- Rate limiting. Биржа официально не публикует лимиты, но при потоке > 10 запросов/секунду с одного IP начинаются 429. Делайте
time.sleep(0.1–0.2)между запросами в массовом сборе. - Неполные данные за свежие сессии. Свечи за «сегодня» могут содержать только закрытые бары. Активный 5-минутный бар в текущий момент в ответе не появится — для real-time нужен другой источник.
Альтернативы для real-time
ISS — для исторических данных и аналитики. Для боевого алготрейдинга:
- Tinkoff Invest API (gRPC stream) — real-time свечи без задержки, при наличии счёта.
- Plaza-2 — прямой биржевой канал для срочного рынка, требует соглашения.
- TQS / SmartCom (Финам, Алор) — брокерские API, реалтайм есть только при наличии счёта.
- WebSocket-обёртки третьих сторон — ALOR Open API, Тинькофф WebSocket — но всё через брокерский счёт.
Что запомнить
- ISS MOEX API — публичный REST биржи, без авторизации, идеально для бэктеста и аналитики.
- Базовая модель URL:
iss/engines/<engine>/markets/<market>/securities/<secid>/<resource>.json. - Свечи — на endpoint
candles, параметрintervalв минутах, пагинация по 500. - Котировки и стакан — с задержкой 15 минут. Для боевой торговли использовать брокерский API.
- Готовый код парсинга — около 30 строк Python с
requestsиpandas. - Дивиденды и состав индексов — там же, в первоисточнике.