zipFinam
Бэктест и алготорговля на Мосбирже через Финам.
zipFinam — открытая Python-библиотека для бэктеста и алготорговли на Московской бирже:
котировки Финама, торговые календари MOEX и исполнение заявок через Finam Trade API.
Стратегия, проверенная на истории, без переписывания запускается на вашем счёте в Финаме.
Зачем это нужно · Котировки Финама · MOEX AlgoPack · Торговля на своём счёте · Начало работы · Лицензия
акции и фонды MOEX из Финам Trade API · календари MOEX и FORTS · заявки целыми лотами · капитал стратегии, а не весь счёт · данные MOEX AlgoPack по желанию · движок ziplime
Зачем это нужно
Большинство инструментов для бэктеста сделаны для американского рынка. На Мосбирже с ними начинаются проблемы:
- Нет данных. Популярные бесплатные источники вроде
yfinanceроссийские бумаги толком не покрывают. - Свечей мало. OHLCV показывает, куда сходила цена, но не кто её двигал: агрессивный покупатель или пустой стакан, толпа или один крупный игрок.
- Тестер заглядывает в будущее. Биржевая статистика публикуется с задержкой, иногда пересчитывается задним числом, и наивный бэктест незаметно читает то, чего в тот момент ещё не было.
- От теста до торговли — вторая разработка. Стратегию, проверенную в одном инструменте, приходится переписывать под API брокера.
zipFinam закрывает все четыре проблемы.
📈 Котировки Финама — вся Мосбиржа одной командой
Бары и справочник инструментов приходят напрямую из Финам Trade API: акции и фонды MOEX, таймфреймы от минуты до квартала. Нужен только токен из личного кабинета Финама.
cd examples
python ingest_finam.py # справочник инструментов и дневные бары
python run_backtest.py # бэктест на голубых фишках
Финам подключается к движку как штатный провайдер данных: get_market_data_source("finam")
работает так же, как встроенный Yahoo для американского рынка.
🔬 MOEX AlgoPack — то, чего не видно в свечах
AlgoPack — аналитика, которую Мосбиржа считает по собственной ленте сделок и стакану. Их не восстановить по свечам или ленте: биржа видит каждую заявку, включая снятые. В zipFinam таблицы AlgoPack читаются той же строкой, что и цены:
# zipFinam достаточно установить: ziplime сам находит адреса algopack://
flow = await data.history(assets=[sber], fields=["disb", "val"], bar_count=5,
data_source="algopack://eq/tradestats")
| Таблица | Что видит стратегия | Рынки |
|---|---|---|
tradestats |
Кто пересекал спред: объём агрессивных покупок против продаж (disb) |
акции, фьючерсы, валюта |
orderstats |
Какие заявки выставили и какие сняли: настоящий спрос против декорации | акции, фьючерсы, валюта |
obstats |
Спред в б.п., глубина и дисбаланс стакана каждые 5 минут | акции, фьючерсы, валюта |
hi2 |
Концентрация потока: покупает толпа или один игрок | акции, фьючерсы |
futoi |
Открытый интерес физлиц против юрлиц | фьючерсы |
alerts |
Сигналы биржи об аномальной активности | акции, фьючерсы, валюта |
Без заглядывания в будущее
Это главное отличие от самодельного парсера. Каждая строка AlgoPack становится видна стратегии в момент, когда биржа её опубликовала, а не в момент, к которому она относится:
- дневной итог виден на следующей сессии, а не в течение своей;
hi2биржа публикует примерно через шесть минут после своей метки времени, и раньше этого стратегия его не увидит;- строки, которые биржа пересчитала задним числом (бывает, спустя месяцы), не пропадают из бэктеста до даты пересчёта, а остаются на своём месте.
Сводка за сессию собрана по правилу для каждой колонки: объёмы суммируются, VWAP взвешиваются,
снимки стакана усредняются, дисбаланс пересчитывается по итогам дня. Агрегация сверена вручную
с реальными данными SBER. Нужны пятиминутки — algopack://eq/tradestats/5min.
Загруженная история кэшируется на диске: инструмент-год tradestats занимает около 3 МБ, и
повторный бэктест по тем же годам не скачивает их заново.
Пять готовых стратегий
В examples/algorithms/algopack/ по стратегии на каждую таблицу:
| Стратегия | Идея |
|---|---|
flow_tilt |
Держать голубые фишки, которые покупают агрессивные деньги |
orderstats_conviction |
Покупать там, где выставленные биды не снимают |
obstats_liquidity |
Держать то, что поддерживает стакан, а не случайный принт ленты |
hi2_crowding |
Идти за бумагами, где покупает кто-то один против рассеянного рынка |
futoi_crowd |
Стоять против толпы физлиц во фьючерсе на доллар/рубль |
python run_backtest.py algorithms/algopack/flow_tilt.py
💼 От бэктеста к вашему счёту
Та же стратегия, без изменений, торгует на вашем брокерском счёте в Финаме через Trade API. Укажите данные счёта и запустите пример:
export FINAM_TRADE_TOKEN=... # токен счёта, на котором исполняются заявки
export FINAM_ACCOUNT_ID=... # номер этого счёта
export FINAM_TRADE_URL=https://api.finam.ru # заявки уходят на ваш счёт
cd examples && python run_live_finam.py
Исполнение рассчитано на реальные деньги:
- Стратегии выделяется капитал, а не весь счёт.
order_target_percent(0.5)— это половина её бюджета, а не половина брокерского счёта. - Лоты. Объём округляется до целых лотов (GAZP — по 10 штук). Если размер лота неизвестен, заявка не отправляется вовсе: наугад ничего не торгуется.
- Принятая заявка ≠ исполненная. После каждого тика статус заявок запрашивается у брокера, и отклонённая заявка отмечается как ошибка, а не как успех.
Начало работы
pip install "zipfinam[all]"
Создайте .env в рабочей папке:
GRPC_TOKEN=... # токен Финам Trade API: котировки, справочник, лоты
ALGOPACK_API=... # ключ MOEX AlgoPack, подписка на https://data.moex.com
Для бэктестов на свечах хватит GRPC_TOKEN. Можно поставить не всё:
| Extra | Что добавляет |
|---|---|
| — | Данные Финама, календари, адреса algopack:// |
algopack |
Клиент MOEX AlgoPack |
live |
Исполнение заявок через Финам |
Стратегия — обычный Python:
from ziplime.finance.execution import MarketOrder
async def initialize(context):
context.stocks = [await context.symbol(s) for s in ("SBER@MISX", "GAZP@MISX")]
async def handle_data(context, data):
for stock in context.stocks:
bars = await data.history(assets=[stock], fields=["close"], bar_count=50)
if len(bars) < 50:
continue
closes = bars["close"].to_numpy()
target = 0.5 if closes[-20:].mean() > closes.mean() else 0.0
await context.order_target_percent(asset=stock, target=target, style=MarketOrder())
Тикеры пишутся с кодом площадки (SBER@MISX). Имя context.assets занято движком, своим
переменным давайте другие имена.
Календарь срочного рынка
Стандартный календарь XMOS заканчивается в 18:45, и фьючерсная стратегия теряет на нём вечернюю
сессию. zipFinam добавляет календарь FORTS (09:00–23:50, клиринг 18:50–19:05) и регистрирует в
ziplime площадки Мосбиржи: акции MISX живут по XMOS, срочный рынок RTSX — по FORTS. Каждая
бумага торгуется в часы своей площадки, а для портфеля из бумаг нескольких бирж ziplime подбирает
общий календарь: clock_calendar_name(["MISX", "XNYS"]) → 24/5.
Под капотом
zipFinam — надстройка над ziplime, открытым движком бэктестинга и живой торговли от Limex. Движок, метрики и модели исполнения берутся из ziplime, а zipFinam добавляет российский рынок: данные, календари и брокера.
zipfinam/
├── finam/ # Финам: бары, справочник, исполнение (REST и gRPC)
├── algopack/ # MOEX AlgoPack: каталог таблиц, клиент, источник данных
└── venue_calendars.py # календарь FORTS и площадки Мосбиржи для ziplime
examples/ # загрузка, бэктест, живая торговля, стратегии
Тесты работают без сети: pip install -e ".[dev]" && pytest.
Переход с версии 0.x и ограничения
- Нужен ziplime 2.11 или новее. Импорты:
from zipfinam import FinamDataSource, FinamAssetDataSource; старый модульziplime_grpc_data_sourceоставлен на время перехода. - Готовый
assets.sqliteбольше не поставляется: справочник загружается из Финама скриптомexamples/ingest_finam.py. - В стратегиях
data.historyиdata.currentвызываются сawait, у заявок обязателенstyle=MarketOrder(). - Из справочника Финама импортируются акции и фонды; фьючерсы и опционы пропускаются.
- Торговый день AlgoPack (07:00–23:50) длиннее основной сессии акций (10:00–18:45), поэтому
volиpr_closeвключают утро и вечер. - С версии 1.26.10.1 zipFinam подключается к ziplime через точки расширения (entry points
ziplime.venue_calendarsиziplime.address_schemes): площадки Мосбиржи, календарь FORTS и адресаalgopack://работают, как только пакет установлен,import zipfinamдля этого не нужен. Прежняя подменаTradingAlgorithm._resolve_named_data_sourceубрана.
Лицензия
GNU GPL v3, как у ziplime.
Metadata
Release files for zipfinam 1.26.10.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| zipfinam-1.26.10.1.tar.gz | 143.5 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| zipfinam-1.26.10.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 290.1 kB
Release files / zipfinam-1.26.10.1.tar.gz
| Download URL | zipfinam-1.26.10.1.tar.gz |
|---|---|
| Size | 143.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
5476d40cdff70d779399a5701382c550c08b3972a627bef08def1bc4bdd2615f
|
|
BLAKE2b-256 checksum How to use checksums |
6763336beb25ad31979c6cc7d8d649f1f4b8528d53b0536fd84f26844d67e6b7
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 14, 2026.
Transparency logRelease files / zipfinam-1.26.10.1-py3-none-any.whl
| Download URL | zipfinam-1.26.10.1-py3-none-any.whl |
|---|---|
| Size | 146.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
547ee95b7791399517bbe5ac084b7b32f5026e198afa45a31d867ab54e8150fe
|
|
BLAKE2b-256 checksum How to use checksums |
d29fc289d0a4104f286610dedafccc10ab20a36f91abffdba84118c2d56c869a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 14, 2026.
Transparency log