Исторические данные — это не просто архив котировок, а рабочий материал для тестирования стратегий, расчета волатильности, поиска закономерностей и построения торговых или аналитических моделей. В Python их можно получить несколькими путями: через готовые библиотеки, через API биржи и через внешние источники с курсами валют и котировками акций. Дальше разберем, как выстроить этот процесс без хаоса и с пониманием, какие данные пригодны для реального анализа.
Зачем вообще тянуть исторические данные в Python
Без истории невозможно нормально проверить гипотезу. На живом рынке почти любая идея кажется рабочей, пока ее не прогнали через реальные котировки за разные периоды, кризисы, боковики и тренды. Именно исторические ряды позволяют понять, где в логике стратегии дыра, а где — действительно повторяющаяся закономерность.
На практике исторические данные нужны для:
- расчета доходности и риска;
- бэктестинга торговых стратегий;
- анализа сезонности и циклов;
- оценки волатильности;
- построения ML-моделей;
- подготовки отчетов и дашбордов;
- автоматизации анализа рынка.
Для российского контекста особенно важно уметь работать с акциями Московской биржи и валютными парами, включая курс рубля к доллару, евро и другим валютам. Если вы планируете строить модели на локальном рынке, без надежного доступа к этим рядам не обойтись.
Какие есть источники данных
На практике чаще всего используют четыре подхода. Выбор зависит от того, какой рынок интересует и насколько критичны стабильность и глубина истории.
| Источник | Что подходит | Плюсы | Минусы |
|---|---|---|---|
yfinance |
американские акции, ETF, часть мировых инструментов | очень простой старт, DataFrame сразу в Python | возможны ограничения по доступности и стабильности данных |
| MOEX ISS | акции, индексы, валюты Московской биржи | хорошо подходит для российского рынка, много официальных данных | нужно разбираться в запросах и структуре ответа |
pandas_datareader |
часть биржевых и валютных данных | удобный интерфейс для типовых задач | покрытие зависит от источника |
| сторонние библиотеки и сервисы | если нужен быстрый импорт в DataFrame | могут экономить время | качество и поддержка отличаются |
Если задача — российские акции и валюты, обычно начинают с MOEX. Там данные официальные, и они покрывают именно ту специфику торгов, которая нужна для локальных моделей. Если нужны зарубежные бумаги — часто проще стартовать с yfinance, поскольку он экономит массу времени на подготовительном этапе.
Подготовка окружения
Для базовой работы достаточно установить несколько пакетов:
pip install yfinance pandas_datareader requests pandas
Если планируете работать с визуализацией и анализом, пригодятся также:
pip install matplotlib seaborn numpy
В большинстве случаев этого набора хватает, чтобы загрузить данные, проверить их структуру, построить простой график и посчитать базовые метрики. Для более тяжелых сценариев — например, тиков или внутридневной истории — позже можно добавить parquet для хранения сжатых колоночных файлов или requests-cache для экономии запросов.
Как загрузить данные по акциям через yfinance
yfinance — один из самых удобных способов быстро получить исторические котировки в Python. Он возвращает таблицу с OHLCV-данными: Open, High, Low, Close, Volume. Для первичного анализа этого обычно достаточно.
Пример загрузки котировок Apple
import yfinance as yf
df = yf.download('AAPL', start='2020-01-01', end='2024-12-31')
print(df.head())
Что важно знать
- Тикер для американской акции указывается как есть:
AAPL,MSFT,TSLA. - Для ряда рынков используются суффиксы, например для японских бумаг часто добавляют
.T. startиendзадают диапазон дат.- Результат уже удобно работать как с обычным
pandas.DataFrame.
Загрузка одной бумаги через объект тикера
ticker = yf.Ticker('AAPL')
hist = ticker.history(period='5y')
print(hist.tail())
Такой вариант полезен, когда нужно дополнительно вытащить фундаментальные метрики, дивиденды или информацию о дроблениях бумаги. В исследовательских задачах это экономит несколько лишних запросов.
Когда yfinance подходит лучше всего
- для быстрого прототипирования;
- для учебных задач;
- для анализа американских акций и ETF;
- для небольших исследовательских проектов.
Ограничения
Не стоит строить на нем критически важную промышленную систему без проверки. Возможны пропуски, сдвиги и разница в настройках округления. Для глубокой работы с российским рынком лучше использовать данные Московской биржи, потому что там вы имеете дело с первоисточником, а не с агрегатором.
Как загрузить исторические данные по акциям Мосбиржи
Для российских акций наиболее практичный вариант — работать с MOEX ISS API. Это официальный интерфейс Московской биржи, который позволяет получать исторические данные по акциям, индексам, валютам и другим инструментам. Стоит один раз разобраться с форматом запросов, и дальше можно автоматизировать выгрузки без привязки к сторонним библиотекам.
Прямой запрос через requests
import requests
import pandas as pd
url = 'https://iss.moex.com/iss/history/engines/stock/markets/shares/boards/TQBR/securities/SBER.json'
params = {
'from': '2022-01-01',
'till': '2023-12-31',
'iss.only': 'history',
'iss.meta': 'off'
}
resp = requests.get(url, params=params)
data = resp.json()
df = pd.DataFrame(data['history']['data'], columns=data['history']['columns'])
df['TRADEDATE'] = pd.to_datetime(df['TRADEDATE'])
df = df.set_index('TRADEDATE').sort_index()
print(df[['OPEN', 'HIGH', 'LOW', 'CLOSE', 'VOLUME']].head())
Что здесь происходит
SBER— тикер Сбербанка.fromиtillзадают период.- Ответ приходит в JSON.
- Затем данные преобразуются в
DataFrame.
Как понять структуру ответа
У MOEX часто ответ состоит не из одной таблицы, а из нескольких блоков. Для истории котировок обычно нужна секция с историческими данными. Если получать не тот блок, можно увидеть пустой результат или метаданные вместо цен. Я рекомендую сначала открыть URL в браузере и посмотреть, какие ключи верхнего уровня приходят, а затем уже выбирать нужный список колонок.
Полезные поля
Чаще всего интересуют:
- дата сделки;
- open;
- high;
- low;
- close;
- volume;
- turnover;
- number of trades.
Названия полей могут отличаться в зависимости от инструмента и эндпоинта, поэтому всегда полезно посмотреть список колонок перед анализом. Для российских акций поля обычно называются OPEN, HIGH, LOW, CLOSE, VOLUME, NUMTRADES и VALTODAY, но полагаться на это без проверки не стоит.
Как загрузить данные по валютам
С валютами есть два распространенных сценария:
- курс рубля к иностранной валюте на Московской бирже;
- международные валютные пары через внешние источники.
Вариант 1. Валюты через MOEX
Если нужны биржевые валютные данные, логика та же: используете MOEX ISS и запрашиваете нужный инструмент. Например, для пары USD/RUB на валютном рынке биржи задействуется свой endpoint.
url = 'https://iss.moex.com/iss/history/engines/currency/markets/selt/boards/CETS/securities/USD000UTSTOM.json'
params = {'from': '2022-01-01', 'till': '2023-12-31', 'iss.only': 'history', 'iss.meta': 'off'}
resp = requests.get(url, params=params)
data = resp.json()
fx_df = pd.DataFrame(data['history']['data'], columns=data['history']['columns'])
fx_df['TRADEDATE'] = pd.to_datetime(fx_df['TRADEDATE'])
fx_df = fx_df.set_index('TRADEDATE').sort_index()
У валютных инструментов MOEX свои тикеры и режимы торгов, поэтому перед выгрузкой стоит уточнить конкретный код инструмента. Это уберегает от ситуации, когда таблица загрузилась, но в ней оказались не те сделки.
Вариант 2. Курсы валют через pandas_datareader
Для задач, где нужен именно валютный курс, удобно использовать интерфейсы, которые возвращают данные в табличном виде. В pandas_datareader есть поддержка исторических валютных рядов через внешние источники.
import pandas_datareader.data as web
from datetime import datetime
start = datetime(2020, 1, 1)
end = datetime(2024, 12, 31)
currency = web.DataReader('USDRUB=X', 'yahoo', start, end)
print(currency.tail())
Для многих аналитических задач этого достаточно: получить ряд, посчитать доходности, построить график, проверить корреляцию с акциями. Важно помнить, что источник данных может менять доступность или формат, поэтому в рабочем пайплайне лучше делать запасной вариант выгрузки или кэшировать последний успешный ответ.
Сравнение способов загрузки данных
| Способ | Для чего лучше | Уровень сложности | Идеален для |
|---|---|---|---|
yfinance |
зарубежные акции и ETF | низкий | быстрый старт, обучение |
MOEX ISS через requests |
российские акции и валюты | средний | практический анализ рынка РФ |
pandas_datareader |
типовые рыночные ряды | низкий–средний | простые аналитические задачи |
| сторонние обертки | ускорение работы с MOEX | низкий–средний | ускоренная разработка |
Пошаговый алгоритм: как загрузить исторические данные правильно
Сам процесс загрузки — это лишь первый шаг. Дальше начинается та часть, где данные превращаются в рабочий датасет. Порядок действий ниже поможет избежать типовых граблей.
1. Определите источник
Сначала решите, откуда брать данные: MOEX, Yahoo Finance или другой сервис. Критерий простой: какой рынок вам нужен и насколько критична официальность данных.
2. Уточните тикер и рынок
Ошибка в тикере — одна из самых частых причин пустой таблицы. Перед запросом проверьте, как инструмент называется именно в выбранном источнике, а не в новостях или у брокера.
3. Проверьте период
Слишком короткий диапазон дает мало статистики, слишком длинный — может упереться в ограничения источника. Для бэктеста среднесрочной стратегии обычно берут несколько лет, для анализа волатильности — как минимум полный рыночный цикл.
4. Посмотрите структуру ответа
Не начинайте сразу считать доходности. Сначала убедитесь, что колонки действительно содержат нужные поля. Иногда под знакомым названием скрывается скорректированная цена, а не реальная цена закрытия.
5. Приведите даты к нужному формату
Дату лучше сразу перевести в индекс и отсортировать по возрастанию. Это убирает лишние проблемы при склейке рядов и расчете дневной доходности.
6. Очистите пропуски
Пропуски, дубликаты и неработающие торговые дни встречаются регулярно. Для дневных данных обычно достаточно удалить строки без цен закрытия, но для внутридневных нужно разбираться с торговыми сессиями отдельно.
7. Нормализуйте данные под задачу
Для бэктеста может понадобиться Close, для риск-анализа — доходности, для внутридневных задач — более частые таймфреймы. Не тащите в модель лишние поля, но и не выбрасывайте волатильность, если она нужна для сигналов.
Практический пример: подготовка данных к анализу
Ниже базовый шаблон, который я чаще всего применяю к любому финансовому ряду перед тем, как начать исследование.
import pandas as pd
# Предполагаем, что df уже получен из любого источника
df.index = pd.to_datetime(df.index)
df = df.sort_index()
df = df.dropna(subset=['Close'])
df['returns'] = df['Close'].pct_change()
print(df[['Close', 'returns']].tail())
Такой шаблон подходит почти для любого финансового ряда:
- загрузили;
- привели дату;
- отсортировали;
- удалили пропуски;
- рассчитали доходность.
Типовые ошибки новичков
1. Путают торговый символ и название компании
Сервису нужен тикер, а не полное название. Например, не Сбербанк, а SBER. Часто пользователи вводят название компании так, как оно отображается в новостях, и удивляются пустому результату.
2. Сразу используют Close, не проверив корректность данных
Иногда в ряду есть корпоративные события, разрывы, неполные дни и технические пропуски. Прежде чем строить стратегию на ценах закрытия, стоит посмотреть на график и проверить аномальные скачки.
3. Смешивают разные источники без синхронизации
У разных поставщиков могут отличаться часовые пояса, методика корректировки и состав торговых дней. Если склеивать ряды из разных мест, легко получить ложные доходности на стыке.
4. Игнорируют разделение price series и total return series
Для оценки стратегии на дивидендных бумагах обычного Close может быть недостаточно. Полная доходность должна учитывать дивиденды, иначе модель будет систематически занижать результат по бумагам с высокой дивидендной доходностью.
5. Используют слишком частые данные без учета ограничений
Минутные и тиковые ряды тяжелее, а у некоторых источников на них есть лимиты по глубине истории. Перед загрузкой внутридневных данных уточните, сколько свечей вы реально можете получить и сколько памяти это займет.
Как проверить, что данные загружены правильно
Используйте короткий чек-лист:
- в таблице есть строки, а не пустой DataFrame;
- даты идут по порядку;
- нет явных дублей;
- столбцы
Open,High,Low,Close,Volumeвыглядят разумно; - нет странных скачков из-за ошибок импорта;
- данные соответствуют ожидаемому рынку и периоду.
Если строите рабочий пайплайн, добавьте автоматическую проверку:
assert not df.empty, 'Данные не загрузились'
assert df.index.is_monotonic_increasing, 'Даты не отсортированы'
assert df['Close'].notna().sum() / len(df) > 0.95, 'Слишком много пропусков'
print('Базовые проверки пройдены')
Когда лучше брать данные с MOEX, а когда с yfinance
| Сценарий | Что выбрать |
|---|---|
| Анализ российских акций | MOEX ISS |
| Курсы валют для российского рынка | MOEX ISS |
| Учебный проект по Python | yfinance |
| Быстрый прототип для зарубежных бумаг | yfinance |
| Стабильный ETL-процесс под РФ-рынок | MOEX ISS |
| Исследование международных активов | yfinance или другой внешний источник |
Мини-шпаргалка по рабочему процессу
- Выберите источник данных.
- Найдите тикер.
- Загрузите историю.
- Проверьте структуру таблицы.
- Очистите пропуски.
- Посчитайте доходности.
- Сохраните данные в CSV или Parquet.
- Используйте их в анализе, бэктесте или модели.
Вывод
Загружать исторические данные по акциям и валютам в Python проще всего через yfinance для зарубежных активов и через MOEX ISS для российского рынка. Если задача учебная или исследовательская, начните с готовых библиотек; если нужен анализ российских бумаг и валют, лучше сразу выстраивать работу вокруг официальных данных Мосбиржи.
Главный принцип простой: не ограничивайтесь фактом загрузки. Всегда проверяйте структуру, даты, пропуски и корректность ряда. Именно это отличает рабочий финансовый датасет от случайной выгрузки.
FAQ
Какой способ самый простой для новичка?
Самый простой старт — yfinance, потому что он дает готовый DataFrame и требует минимум кода.
Можно ли загрузить данные по Сбербанку в Python?
Да, для российских акций удобно использовать MOEX ISS и тикер SBER.
Где брать исторические курсы валют?
Для валютных рядов можно использовать MOEX, а для международных пар — внешние источники через Python-библиотеки.
Что делать, если данные не загружаются?
Проверьте тикер, период, структуру ответа и доступность источника. Часто проблема в неправильном символе или в том, что запрошен не тот endpoint.
Можно ли сразу использовать данные в бэктесте?
Да, но только после очистки, сортировки по дате и проверки на пропуски и дубли.
