Скользящие средние — один из самых понятных способов превратить «шумный» ценовой график в рабочий сигнал. В Python такие стратегии легко собрать, протестировать на исторических данных и быстро понять, где у них есть смысл, а где они начинают приносить ложные входы и завышенные ожидания.
Ниже — практическое руководство: что такое скользящие средние, как работают пересечения, как написать базовую стратегию в Python, как проверить ее на данных и какие ошибки чаще всего допускают начинающие.
Что такое скользящая средняя и зачем она нужна
Скользящая средняя показывает усредненную цену за выбранный период. Проще говоря, она сглаживает резкие колебания и помогает увидеть направление движения. Если цена растет, средняя обычно тоже идет вверх. Если рынок падает — средняя разворачивается вниз. Именно поэтому ее используют как фильтр тренда и как основу для простых торговых правил.
На практике это первый инструмент, с которого стоит начинать знакомство с количественным анализом временных рядов. Когда вы смотрите на минутный или дневной график, ваш глаз невольно пытается уловить общее направление, отфильтровав случайные всплески. Скользящая средняя делает ровно это — формализует интуитивное восприятие тренда в виде четкого математического индикатора. Без такого сглаживания ценовой ряд — это просто последовательность чисел, в которой сложно отделить сигнал от шума.
Основные виды
- SMA (Simple Moving Average) — простая скользящая средняя. Все значения в окне имеют одинаковый вес.
- EMA (Exponential Moving Average) — экспоненциальная скользящая средняя. Недавние цены влияют сильнее, чем старые.
Для первых экспериментов чаще берут SMA: она проще, прозрачнее и лучше подходит для понимания логики стратегии. Когда вы только начинаете разбираться с бэктестингом, SMA дает предсказуемое поведение — вы всегда знаете, какие именно бары попали в расчет и с каким весом. EMA, в свою очередь, удобна, когда важна скорость реакции на свежие движения, но ее рекурсивная природа иногда создает иллюзию «опережающего» сигнала, которого в реальности нет.
Как работает стратегия на пересечении средних
Самая известная идея — взять две средние:
- быструю с коротким периодом;
- медленную с длинным периодом.
Когда быстрая средняя пересекает медленную снизу вверх, это воспринимается как сигнал на покупку. Когда пересекает сверху вниз — как сигнал на выход или продажу.
Простой смысл сигнала
- Короткая средняя быстрее реагирует на изменения цены.
- Длинная средняя реагирует медленнее и показывает более устойчивый фон.
- Пересечение означает, что краткосрочное движение стало сильнее долгосрочного.
Это не прогноз и не гарантия. Это всего лишь формализованная реакция на изменение структуры рынка. По сути, пересечение средних фиксирует момент, когда краткосрочный импульс преодолевает инерцию долгосрочного фона. В трендовом движении это работает как раннее подтверждение разворота или ускорения, но в боковике тот же механизм генерирует ложные срабатывания одно за другим.
Где такие стратегии работают лучше
Пересечения средних чаще всего дают смысл:
- на трендовых рынках;
- на ликвидных инструментах;
- на таймфреймах, где шум не слишком доминирует;
- когда нужен простой и воспроизводимый алгоритм.
Они хуже работают:
- во флэте;
- в периоды резких новостных всплесков;
- на очень коротких интервалах, где комиссия и проскальзывание «съедают» преимущество;
- на неликвидных инструментах.
Из опыта: на дневных графиках ликвидных фьючерсов или ETF стратегия на SMA 50/200 способна десятилетиями показывать осмысленные результаты, если дисциплинированно следовать сигналам. Но как только вы спускаетесь на пятиминутный таймфрейм, те же самые правила начинают генерировать десятки ложных входов в день, и без дополнительных фильтров модель быстро уходит в минус.
Какие данные нужны для теста
Для бэктеста обычно достаточно таблицы с колонками:
- дата;
- open;
- high;
- low;
- close;
- volume.
Чаще всего для простой стратегии используют именно close, потому что сигналы строятся по закрытию свечи. Это принципиальный момент: цена закрытия — единственное значение, которое окончательно фиксируется по завершении бара. Все остальные цены внутри бара (high, low) могут быть переписаны следующим тиком, и строить на них торговые правила — значит закладывать в модель информацию, которая в реальной торговле еще не определена.
Что важно проверить заранее
- Нет ли пропусков по датам.
- Нет ли дубликатов.
- Учитывается ли режим торгов инструмента.
- Корректна ли временная зона.
- Не задним ли числом загружены данные с учетом будущих значений.
Последний пункт особенно важен: если в расчет случайно попали будущие цены, стратегия покажет нереалистично хорошие результаты. Это называется look-ahead bias, и на практике я не раз видел, как начинающие аналитики непреднамеренно загружали данные, где сплиты и дивиденды были скорректированы задним числом, или использовали скользящее окно, которое «заглядывало» на один бар вперед. Модель выглядела великолепно ровно до момента первого реального прогона.
Базовая логика стратегии
Ниже — самая простая схема:
- Загружаем цены.
- Считаем короткую и длинную средние.
- Находим моменты пересечения.
- Генерируем сигналы: buy или sell.
- Проверяем результат на исторических данных.
Пример параметров
| Параметр | Значение | Что означает |
|---|---|---|
| Short window | 20 | Быстрая средняя |
| Long window | 50 | Медленная средняя |
| Таймфрейм | daily | Дневные данные |
| Цена | close | Цена закрытия |
Эти числа не являются универсальными. Они служат стартовой точкой для теста. Комбинация 20/50 — это классика для дневных графиков, которая примерно соответствует одному месяцу против квартала торговых дней. Но если вы работаете с часовыми барами, те же 20 и 50 периодов охватят всего несколько дней, и сигнал станет значительно более шумным.
Пример реализации в Python
Ниже — рабочий минимальный пример на pandas.
import pandas as pd
import numpy as np
# Загрузка данных
df = pd.read_csv('data.csv', index_col='date', parse_dates=True)
# Расчет скользящих средних
df['SMA20'] = df['close'].rolling(window=20).mean()
df['SMA50'] = df['close'].rolling(window=50).mean()
# Сигнал: 1 когда быстрая выше медленной, 0 когда ниже
df['signal'] = np.where(df['SMA20'] > df['SMA50'], 1, 0)
# Момент пересечения: разница между текущим и предыдущим значением сигнала
df['position'] = df['signal'].diff()
# position == 1 — пересечение снизу вверх (покупка)
# position == -1 — пересечение сверху вниз (продажа)
Что делает этот код
rolling(window).mean()считает среднее за заданное окно.signal = 1означает, что быстрая средняя выше медленной.diff()помогает найти момент, когда состояние поменялось.position == 1— вход в лонг.position == -1— выход из лонга или продажа.
Обратите внимание на diff() — это простейший способ зафиксировать именно момент смены режима, а не само состояние. Если бы мы торговали напрямую по столбцу signal, то получали бы сигнал каждый день, пока быстрая средняя выше медленной, что привело бы к бесконечному циклу входов и выходов. diff() выделяет только точки переключения — именно то, что нам нужно для дискретных сделок.
Как не ошибиться в логике сигналов
Самая частая ошибка — строить сигнал на текущей свече и тут же исполнять сделку по этой же цене. В реальности решение принимается после закрытия свечи, а исполнение обычно происходит уже на следующем баре.
Правильнее учитывать лаг
Если сигнал сформировался на закрытии дня, то вход в сделку должен быть смещен хотя бы на следующую свечу. Иначе бэктест будет слишком оптимистичным. На быстрых таймфреймах эта разница может показаться незначительной, но на дневных данных один день задержки способен полностью изменить экономику стратегии. Я неоднократно видел модели, которые превращались из «прибыльных» в убыточные только после добавления корректного лага в один бар.
Как посчитать доходность стратегии
Одна из базовых схем:
- если стратегия в позиции, доходность равна дневной доходности инструмента;
- если вне позиции, доходность равна нулю;
- затем накапливаем результат.
Пример кода для расчета
# Дневная доходность инструмента
df['returns'] = df['close'].pct_change()
# Смещаем сигнал на один бар вперед
df['strategy_returns'] = df['position'].shift(1) * df['returns']
# Кривая капитала
df['equity_curve'] = (1 + df['strategy_returns']).cumprod()
Что здесь важно
pct_change()считает простую доходность между свечами.shift(1)переносит сигнал на следующий бар.cumprod()строит кривую капитала.
Кривая капитала — это ваш главный визуальный инструмент для первичной оценки стратегии. Если график плавно растет вверх и вправо, это хороший знак. Но если рост обеспечивается двумя-тремя удачными сделками за десять лет, а все остальное время кривая лежит в просадке, такая стратегия вряд ли будет психологически комфортной для реальной торговли.
Почему стратегия может выглядеть хорошо на графике, но плохо в жизни
Пересечение средних — это удобная учебная модель, но в реальности на результат влияют дополнительные факторы:
- комиссия;
- проскальзывание;
- задержка исполнения;
- качество котировок;
- изменение волатильности;
- режим рынка.
Если не учесть эти моменты, стратегия может выглядеть прибыльной только на бумаге. Особенно коварно проскальзывание на новостях: модель видит сигнал на закрытии бара, но реальная сделка исполняется по цене, которая уже ушла на процент-другой в невыгодную сторону. За год таких микро-потерь набирается достаточно, чтобы свести на нет все преимущество стратегии.
Типовые ошибки новичков
- Использование слишком коротких окон, из-за чего сигналов слишком много.
- Игнорирование комиссии.
- Отсутствие теста на разных периодах.
- Подбор параметров под один участок истории.
- Использование только роста кривой капитала без оценки просадки.
- Смешивание логики сигнала и логики исполнения.
Последний пункт заслуживает отдельного внимания. Логика сигнала отвечает на вопрос «когда открывать позицию?», а логика исполнения — «по какой цене и с какими издержками?». Если вы смешиваете их в одном блоке кода, модель становится негибкой и сложной для отладки. Разделяйте генерацию сигналов и симуляцию сделок с самого начала — это сэкономит вам часы при переходе к более сложным системам.
Как выбирать периоды для средних
Здесь нет магической формулы. Периоды подбирают под таймфрейм, характер инструмента и цель стратегии.
Практическая логика подбора
- Для дневных данных часто начинают с пар вроде 10/30, 20/50, 50/200.
- Для часовых данных окна обычно короче.
- Для высокочастотных данных простые средние часто становятся слишком шумными.
Хорошая практика
- Сначала проверить 3–5 комбинаций.
- Затем сравнить их на нескольких отрезках истории.
- Не выбирать параметры только по максимальной прибыли.
- Смотреть не только доходность, но и просадку, число сделок, стабильность.
Разумный подход — разбить историю на три части: тренировочный период для подбора параметров, валидационный для сравнения комбинаций и тестовый для финальной оценки. Если стратегия хорошо работает на тренировочном отрезке, но проваливается на валидации, значит, вы подогнали параметры под шум, а не под закономерность.
Что нужно смотреть кроме прибыли
Одна прибыль сама по себе мало о чем говорит. Важно понимать, какой ценой она получена.
| Метрика | Зачем нужна | Что показывает |
|---|---|---|
| Доходность | Оценка результата | Сколько заработала стратегия |
| Просадка | Риск падения капитала | Насколько сильно стратегия теряла в плохие периоды |
| Sharpe ratio | Соотношение доходности и риска | Насколько результат устойчив относительно волатильности |
| Profit factor | Баланс прибыли и убытков | Сколько прибыли приходится на 1 рубль убытка |
| Количество сделок | Частота торговли | Насколько стратегия активна |
| Win rate | Доля прибыльных сделок | Как часто сигнал оказывается верным |
Для простых стратегий на пересечении средних важнее не только доходность, но и устойчивость на разных участках рынка. Например, profit factor ниже 1.2 при большом количестве сделок — это тревожный сигнал: даже небольшое ухудшение рыночных условий или рост комиссии может сделать стратегию убыточной. А просадка более 30% от пика капитала часто означает, что вы просто не пересидите такой период психологически, даже если математически модель потом восстанавливается.
Мини-чек-лист перед запуском теста
- Данные очищены от пропусков и дубликатов.
- Используется только информация, доступная на момент сигнала.
- Сигнал смещен на следующий бар.
- Учтены комиссии и проскальзывание.
- Проверены несколько периодов истории.
- Стратегия протестирована на out-of-sample участке.
- Оценены просадка и число сделок, а не только прибыль.
Out-of-sample тестирование — это не опция, а обязательный этап. Если вы оптимизировали параметры на всей доступной истории, у вас нет способа понять, работает ли модель на новых данных или просто запомнила прошлое. Оставьте хотя бы 20% самых свежих данных нетронутыми до финальной проверки.
Как улучшить простую стратегию
Если базовая версия уже собрана, можно постепенно усложнять модель.
1. Добавить фильтр тренда
Например, входить только тогда, когда цена находится выше старшей средней. Это снижает количество ложных входов во флэте. Идея в том, что долгосрочная средняя выступает якорем: если цена ниже нее, рынок, скорее всего, медвежий, и длинные позиции имеют пониженную вероятность успеха.
2. Использовать EMA вместо SMA
EMA быстрее реагирует на новые изменения. Это полезно, если нужен более чувствительный сигнал. Но помните: повышенная чувствительность работает в обе стороны — вы раньше входите в тренд, но и чаще получаете ложные срабатывания на откатах. Компромисс между скоростью и стабильностью всегда индивидуален для каждого инструмента.
3. Ввести фильтр волатильности
Если рынок слишком спокойный, пересечения часто становятся случайным шумом. Если волатильность слишком высокая, сигналов может быть слишком много. Фильтр помогает отсеять некачественные периоды. Простой вариант — считать ATR (Average True Range) и разрешать вход только когда волатильность находится в определенном диапазоне относительно своей исторической нормы.
4. Ограничить сделки по времени
Для части инструментов полезно закрывать позиции к концу сессии или не держать их через выходные и важные события. Гэпы на открытии понедельника способны свести на нет прибыль, накопленную за неделю, особенно если вы торгуете отдельные акции, а не диверсифицированный портфель.
5. Добавить риск-менеджмент
Без управления риском даже хорошая идея может быть убыточной.
Полезные элементы:
- стоп-лосс;
- тейк-профит;
- трейлинг-стоп;
- ограничение максимального объема позиции;
- ограничение потерь на день или неделю.
Стоп-лосс, рассчитанный на основе волатильности (например, 2 ATR от точки входа), гораздо эффективнее фиксированного стопа в пунктах. Рынок не знает, где вы поставили стоп, но он «уважает» свою собственную волатильность — выход за пределы двух-трех ATR обычно уже означает смену режима, а не случайный шум.
Когда простые средние не подходят
Есть ситуации, где лучше не пытаться «дожать» стратегию:
- рынок долго ходит в узком диапазоне;
- инструмент слишком резкий и новостной;
- ликвидность низкая;
- комиссия велика относительно движения цены;
- нужен не учебный пример, а промышленная торговая система.
В таких случаях пересечения средних можно оставить как базовый ориентир, но не как полноценный торговый двигатель. Например, на криптовалютном рынке с его экстремальной волатильностью и частыми ложными пробоями стратегия на чистых пересечениях без дополнительных фильтров обычно сливает депозит за несколько месяцев. Здесь скользящие средние лучше использовать как один из элементов составной модели, а не как самостоятельное торговое правило.
Пошаговый план для самостоятельной работы
Шаг 1. Подготовьте данные
Загрузите исторические котировки и проверьте качество таблицы. Убедитесь, что временная зона едина для всех записей, а пропуски в данных — это действительно неторговые дни, а не ошибки выгрузки.
Шаг 2. Посчитайте средние
Начните с SMA 20 и SMA 50. Не усложняйте на этом этапе — сначала добейтесь корректной работы базовой механики.
Шаг 3. Постройте сигналы
Определите моменты пересечения вверх и вниз. Визуализируйте их на графике: наложите средние на цену и отметьте точки входа и выхода. Глаз быстрее кода находит очевидные ошибки в логике.
Шаг 4. Смоделируйте сделки
Смещение сигнала на следующий бар обязательно. Проверьте, что первая сделка не может произойти раньше, чем накоплено достаточно данных для расчета обеих средних.
Шаг 5. Посчитайте метрики
Сравните доходность, просадку и число сделок. Если стратегия совершает меньше 30 сделок за весь период тестирования, статистических выводов сделать нельзя — результат может быть случайным.
Шаг 6. Проверьте устойчивость
Протестируйте стратегию на разных периодах. Разбейте историю на несколько непересекающихся отрезков и убедитесь, что метрики не разваливаются на каком-то из них.
Шаг 7. Добавьте фильтры
Только после этого стоит усложнять логику. Каждый новый фильтр тестируйте изолированно, чтобы понимать его реальный вклад в результат.
FAQ
Чем SMA отличается от EMA?
SMA считает среднее с одинаковым весом всех значений окна. EMA сильнее реагирует на последние цены и обычно быстрее меняется. Математически EMA — это бесконечный импульсный отклик, где вес каждого предыдущего значения экспоненциально затухает, но никогда не становится равным нулю. SMA же «забывает» старые значения полностью, как только они выходят за пределы окна.
Можно ли использовать пересечение средних как готовую торговую систему?
Да, но только после учета комиссий, проскальзывания и проверки на разных периодах. В сыром виде это скорее учебная модель, чем готовый алгоритм. Реальная торговля добавляет к математике сигналов целый слой операционных рисков, и без их учета вы торгуете не ту стратегию, которую протестировали.
Какие окна средних выбрать для старта?
Для дневных данных часто начинают с 20/50 или 50/200. Для других таймфреймов параметры нужно подбирать отдельно. Комбинация 50/200 — это классика, популяризированная еще в середине прошлого века, и она до сих пор работает как долгосрочный трендовый фильтр на широких рыночных индексах.
Почему стратегия часто проигрывает во флэте?
Потому что пересечения в боковике дают много ложных входов без устойчивого направления движения. Средние многократно переплетаются, генерируя сигналы, каждый из которых по отдельности выглядит осмысленно, но в сумме дает череду мелких убытков, постепенно съедающих капитал.
Нужен ли для такой стратегии машинный интеллект?
Нет. Для базовой модели достаточно статистики, корректного бэктеста и дисциплины в проверке гипотез. ML можно подключать позже, когда появится четкая исследовательская задача — например, классификация рыночных режимов или прогнозирование вероятности ложного пробоя.
Вывод
Стратегия на скользящих средних — это хороший старт для изучения алготрейдинга в Python. Она проста в реализации, помогает понять логику сигналов, учит работать с историческими данными и быстро показывает, почему в торговле важны не только идеи, но и проверка на реальных условиях.
Если собрать такую модель аккуратно — с лагом, комиссиями, фильтрами и нормальным бэктестом — она станет отличной базой для более сложных систем: фильтрации тренда, оценки риска, анализа волатильности и построения полноценных торговых алгоритмов. Главное, что вы вынесете из этого упражнения — не конкретные параметры SMA, а дисциплину работы с данными и понимание того, что любая, даже самая простая модель требует тщательной проверки перед тем, как доверить ей реальные деньги.
