
Прогнозируем Ренко — бары при помощи ИИ CatBoost
Введение
В тишине моего кабинета светится лишь экран монитора. Терминал MetaTrader 5 выдает очередные тиковые данные, а разработанный мной алгоритм методично превращает хаос рынка в упорядоченную систему Ренко-баров. Три часа ночи — время, когда рождаются настоящие торговые стратегии. Я провожу рукой по небритому подбородку и отпиваю уже остывший кофе, мой любимый "Карт Нуар". Точность модели 59.27% — это победа. Настоящая победа для тех, кто понимает непредсказуемую природу финансовых рынков.
Когда традиционный анализ стал бессилен
Почти 10 лет назад я пришел на рынок с убеждением, что технический анализ — это священное писание трейдера. Я рисовал линии поддержки и сопротивления, следил за пересечениями скользящих средних, искал дивергенции на RSI и MACD, но год за годом наблюдал, как эффективность этих методов снижается. Рынок менялся, алгоритмы высокочастотной торговли трансформировали его природу, а классические методики уже не давали прежнего преимущества.
Как-то раз, после особенно неудачной торговой недели, я задал себе вопрос: что, если все книги по техническому анализу, написанные в прошлом веке, сегодня стали просто увлекательной художественной литературой? Этот вопрос привел меня к радикальному пересмотру подхода к трейдингу и, в конечном итоге, к созданию системы прогнозирования Ренко-баров на основе машинного обучения.
Ренко-бары — цифровой дзен трейдера
Впервые я столкнулся с Ренко-графиками на конференции в Сингапуре. Японский трейдер, чье имя я обещал никогда не разглашать, показал мне свой терминал с необычными прямоугольными блоками вместо привычных свечей. "Это Ренко, — сказал он, — графики, которые показывают только то, что имеет значение — движение цены".
В мире, перенасыщенном информацией, Ренко-графики предлагают цифровой дзен — очищение от шума, от фактора времени, от всего, что отвлекает от истинного движения рынка. Каждый новый блок формируется только тогда, когда цена проходит определенное расстояние вверх или вниз. В этой простоте скрыта невероятная сила.
Я начал экспериментировать с Ренко-графиками на различных инструментах. EURUSD, GBPUSD, DAX, S&P 500 — везде они позволяли увидеть структуру рынка яснее и чище. Но ручной анализ требовал времени, которого всегда не хватает. И тогда я обратился к машинному обучению.
CatBoost — алгоритм, покоривший мировые рынки
Выбор алгоритма был не менее важен, чем выбор торговой стратегии. Перебрав десятки различных моделей машинного обучения, я остановился на CatBoost — алгоритме градиентного бустинга, разработанном компанией Яндекс. Это была любовь с первого запуска модели.
# Инициализация модели CatBoost params = { 'iterations': 300, 'learning_rate': 0.05, 'depth': 5, 'loss_function': 'Logloss', 'random_seed': 42, 'verbose': False } model = CatBoostClassifier(**params) model.fit(X_train, y_train, eval_set=(X_test, y_test), early_stopping_rounds=30, verbose=False)
CatBoost не просто хорошо работает с категориальными признаками, что критично для анализа паттернов Ренко-баров. Он устойчив к переобучению, а это редкость для алгоритмов такой мощности, и работает достаточно быстро, чтобы модель можно было переобучать на свежих данных хоть каждый день.
Мой эксперимент начался с загрузки данных EURUSD за 60 дней — более 12000 пятиминутных баров. Эти данные трансформировались в 11578 Ренко-баров с рассчитанным алгоритмически оптимальным размером блока в 0.00028 единицы цены. Подготовка признаков дала 11572 образца для обучения модели.
И вот наступил момент истины — запуск обучения модели CatBoost на подготовленных данных.
Откровение в цифрах: что показал эксперимент
Когда алгоритм завершил обучение, и я увидел результаты, это было подобно озарению. Точность модели на тестовой выборке составила 59.27%. Для неискушенного в трейдинге человека эта цифра может показаться скромной. Но для тех, кто знаком с беспощадной статистикой торговли на финансовых рынках, это выдающийся результат.
Стоит вспомнить знаменитое исследование Мичиганского университета, показавшее, что большинство активно управляемых фондов не способны превзойти простую стратегию "купи и держи". А ведь в этих фондах работают блестящие аналитики с докторскими степенями и доступом к инсайдерской информации. На этом фоне точность в 59.27% выглядит уже не просто хорошо, а феноменально.
Но еще более удивительным оказался анализ важности признаков. Вопреки всем канонам технического анализа, объемные показатели оказались значительно важнее ценовых паттернов. "Last_volume" с важностью 18.36, "avg_volume" с 14.23 и "volume_ratio" с 12.81 заняли первые три строчки. И только потом шли показатели последовательных движений цены.
Кстати, сейчас вспомнил и дописал: я пару раз видел в одной из известных социальных сетей успешного трейдера, который говорил о том, что Грааль — в делении объема по блокам Ренко и кластерам объема. Возможно, эти результаты вообще не случайны и имеют смысл?
Искусство создания Ренко-баров
Работа с Ренко-графиками начинается с определения оптимального размера блока. Это как настройка микроскопа — слишком маленькое увеличение не позволит разглядеть детали, слишком большое — исказит общую картину. Размер блока Ренко — это своего рода разрешение, с которым мы смотрим на рынок.
# Создание Ренко-баров с адаптивным размером блока def create_renko_bars(df, brick_size=None): if brick_size is None: # Расчет ATR для определения размера блока df['tr'] = np.maximum( df['high'] - df['low'], np.maximum( np.abs(df['high'] - df['close'].shift(1)), np.abs(df['low'] - df['close'].shift(1)) ) ) df['atr'] = df['tr'].rolling(window=14).mean() brick_size = df['atr'].mean() * 0.5 print(f"Размер блока Ренко: {brick_size:.5f}") # Создание Ренко-баров renko_bars = [] current_price = df.iloc[0]['close'] # ... остальной код
После многочисленных экспериментов, я пришел к выводу, что лучший способ определения размера блока — через показатель ATR (Average True Range, Средний Истинный Диапазон). Этот подход делает размер блока адаптивным к текущей волатильности инструмента.
В случае с EURUSD, алгоритм определил оптимальный размер блока как 0.00028 единицы цены, что соответствует примерно 2.8 пункта. На первый взгляд, это кажется незначительным, но именно такая гранулярность позволяет улавливать значимые движения и отфильтровывать рыночный шум.
Создание Ренко-баров — это не просто механическое преобразование ценовых данных. Это искусство извлечения сигнала из шума, выделения значимого движения из океана колебаний. И когда я увидел преобразованные данные, отображенные на графике, перед глазами предстала кристально чистая картина рынка — лестница из красных и зеленых блоков, отражающая истинное движение цены без искажений, вызванных фактором времени.
Формирование признаков: что действительно важно для прогноза
Успех любой модели машинного обучения в значительной степени зависит от качества и релевантности признаков. Для прогнозирования направления следующего Ренко-бара я разработал многоуровневую систему признаков, учитывающую как историю движений, так и объемные характеристики.
# Подготовка признаков для модели def prepare_features(renko_df, lookback=5): features = [] targets = [] for i in range(lookback, len(renko_df) - 1): window = renko_df.iloc[i-lookback:i] feature_dict = { # Направления последних n баров **{f'dir_{j}': window['direction'].iloc[-(j+1)] for j in range(lookback)}, # Статистика по движениям 'up_ratio': (window['direction'] > 0).mean(), 'max_up_streak': window['consec_up_streak'].max(), 'max_down_streak': window['consec_down_streak'].max(), 'last_up_streak': window['consec_up_streak'].iloc[-1], 'last_down_streak': window['consec_down_streak'].iloc[-1], # Объем 'last_volume': window['volume'].iloc[-1], 'avg_volume': window['volume'].mean(), 'volume_ratio': window['volume'].iloc[-1] / window['volume'].mean() if window['volume'].mean() > 0 else 1 } features.append(feature_dict) # Направление следующего бара (1 - вверх, 0 - вниз) next_direction = 1 if renko_df.iloc[i+1]['direction'] > 0 else 0 targets.append(next_direction) return pd.DataFrame(features), np.array(targets)
Сначала я включил очевидные признаки — направления последних нескольких баров. Затем, добавил статистические метрики — соотношение восходящих и нисходящих баров, длину последовательных движений в одном направлении, максимальные серии. И наконец, включил объемные показатели — объем последнего бара, средний объем за период, отношение текущего объема к среднему.
Именно объемные показатели, к моему удивлению, оказались наиболее значимыми для прогноза. Это перевернуло мое представление о ценовом анализе. Годами я, как и большинство трейдеров, фокусировался на формах свечей, паттернах, линиях тренда. А ответ все это время был в объемах — показателе, который на Форексе часто игнорируют из-за децентрализованной природы рынка.
Финальный набор признаков включил 14 параметров, что оказалось оптимальным с точки зрения баланса между сложностью модели и ее прогностической силой. Больше признаков приводило к переобучению, меньше — к недостаточной точности.
Прогноз в действии: от теории к практике
Построенная модель выдает не просто бинарный прогноз направления следующего бара, но и вероятность этого движения. В последнем примере модель предсказала снижение с вероятностью 69.35%, что является достаточно уверенным прогнозом, но недостаточным для генерации торгового сигнала (для которого я установил порог в 75%).
# Прогнозирование следующего бара def predict_next_bar(model, renko_df, lookback=5, feature_names=None): if len(renko_df) < lookback: return {"error": "Недостаточно данных"} window = renko_df.iloc[-lookback:] feature_dict = { **{f'dir_{j}': window['direction'].iloc[-(j+1)] for j in range(lookback)}, 'up_ratio': (window['direction'] > 0).mean(), 'max_up_streak': window['consec_up_streak'].max(), 'max_down_streak': window['consec_down_streak'].max(), 'last_up_streak': window['consec_up_streak'].iloc[-1], 'last_down_streak': window['consec_down_streak'].iloc[-1], 'last_volume': window['volume'].iloc[-1], 'avg_volume': window['volume'].mean(), 'volume_ratio': window['volume'].iloc[-1] / window['volume'].mean() if window['volume'].mean() > 0 else 1 } X_pred = pd.DataFrame([feature_dict]) # Проверяем, что все признаки присутствуют if feature_names: for feature in feature_names: if feature not in X_pred.columns: X_pred[feature] = 0 X_pred = X_pred[feature_names] prob = model.predict_proba(X_pred)[0] prediction = model.predict(X_pred)[0] return { 'prediction': 'UP' if prediction == 1 else 'DOWN', 'probability': prob[prediction], 'prob_up': prob[1], 'prob_down': prob[0], 'signal': 'BUY' if prob[1] > 0.75 else 'SELL' if prob[0] > 0.75 else 'NEUTRAL' }
Однако, настоящую ценность представляет не единичный прогноз, а комплексная торговая система. Последние пять Ренко-баров демонстрируют интересную динамику: три последовательных снижения, а затем два повышения. Этот микротренд вверх, в сочетании с прогнозом вниз, с высокой, но недостаточной для сигнала, вероятностью, говорит о возможной консолидации и неопределенности на рынке.
Именно такие моменты являются наиболее опасными для торговли, и система корректно определила это состояние, не сгенерировав торговый сигнал, несмотря на относительно высокую вероятность снижения.
Заглядывая под капот: архитектура системы
Разработанная система представляет собой многослойный механизм, в котором каждый компонент выполняет свою роль в общем оркестре прогнозирования. Рассмотрим ключевые элементы этой архитектуры.
python# Основная функция def main(): # Получение данных EURUSD print("Загрузка данных EURUSD из MetaTrader5...") df = get_mt5_data(symbol='EURUSD', days=60) if df is None or len(df) == 0: print("Не удалось получить данные") return print(f"Загружено {len(df)} баров") # Создание Ренко-баров print("Создание Ренко-баров...") renko_df, brick_size = create_renko_bars(df) print(f"Создано {len(renko_df)} Ренко-баров") # Подготовка признаков print("Подготовка признаков...") X, y = prepare_features(renko_df) print(f"Подготовлено {len(X)} образцов") # Обучение модели print("Обучение модели...") model, X_test, y_test = train_model(X, y) # Прогноз следующего бара feature_names = X.columns.tolist() prediction = predict_next_bar(model, renko_df, feature_names=feature_names) print("\nПРОГНОЗ СЛЕДУЮЩЕГО РЕНКО-БАРА:") for k, v in prediction.items(): print(f"{k}: {v}") # Информация о последних барах print("\nПоследние 5 Ренко-баров:") print(renko_df.tail(5)[['time', 'open', 'close', 'direction']])
Основой системы является модуль загрузки данных из MetaTrader 5. Интеграция с MetaTrader 5 позволяет получать актуальные рыночные данные в режиме, близком к реальному времени. Этот модуль использует официальное API MetaTrader 5, что обеспечивает надежность и стабильность работы.
Следующий слой — преобразование стандартных временных баров в Ренко. Алгоритм вычисляет оптимальный размер блока на основе ATR и выполняет трансформацию с учетом объемов и времени. Особенность реализации — подсчет последовательных движений и их характеристик непосредственно в процессе формирования Ренко-баров, что повышает эффективность работы всей системы.
Ядро системы — модуль формирования признаков и обучения модели. Здесь каждый Ренко-бар превращается в набор числовых характеристик, которые затем подаются на вход алгоритма CatBoost. Выбор оптимальных параметров модели осуществляется через кросс-валидацию, с учетом специфики финансовых временных рядов.
Наконец, модуль прогнозирования принимает обученную модель и актуальные данные, формирует прогноз и, при достижении заданного порога уверенности, генерирует торговый сигнал.
Вся система написана на Python с использованием библиотек numpy, pandas, MetaTrader 5 и catboost. Выбор Python обусловлен не только удобством разработки, но и широкими возможностями для анализа данных и визуализации результатов.
Выводы и перспективы: будущее алгоритмической торговли
После разработки и тестирования системы прогнозирования Ренко-баров, я пришел к нескольким важным выводам, которые могут изменить ваш взгляд на алгоритмическую торговлю.
Во-первых, классические методы технического анализа уступают в эффективности современным алгоритмам машинного обучения. Точность в 59.27% может показаться не такой впечатляющей, но она стабильно превосходит результаты большинства технических индикаторов на длительных промежутках времени.
Во-вторых, объемные показатели оказались значительно важнее ценовых паттернов для прогнозирования движения рынка. Это противоречит многим классическим учебникам по трейдингу, но подтверждается результатами моделирования на реальных данных.
В-третьих, Ренко-графики действительно очищают ценовые данные от шума, что позволяет алгоритмам машинного обучения выявлять более стабильные закономерности в движении рынка.
Но самое главное — это только начало. Я вижу огромный потенциал для дальнейшего развития системы. Возможно включение фундаментальных данных, новостных событий, анализа настроений рынка через социальные сети. Возможно расширение на другие инструменты и таймфреймы. Возможно создание ансамбля моделей для повышения точности прогнозирования.
Заключение
Мир алгоритмической торговли стоит на пороге новой революции, и комбинация Ренко-графиков с современными алгоритмами машинного обучения может стать одним из ее драйверов. Я приглашаю всех, кто интересуется этой темой, погрузиться в мир данных, алгоритмов и прогнозирования. Будущее торговли уже здесь — и оно алгоритмическое.





- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Вы принимаете политику сайта и условия использования
Больше процентов 63 получить не удается. Какие бы признаки не добавлять. 63 для форекса это фиаско
У меня получалось выше 75% на Мидасе (многомодульном, где множество модулей совмещают свои сигналы в единый сигнал). Но тогда возникает другая проблема - сигналы раз в месяц-полтора))))Чем надежнее сигнал, тем реже он возникает...Поэтому в последних роботах вообще забивать стал на высокий винрейт, пытаюсь прогнозировать глубину движений чтобы брать риск к прибыли в 1:3, 1:4 и т.п. Настраиваю метки таким образом, чтобы они давали премии моделям через DQN за правильную разметку глубоких движений....Вылилось это в итоге в робота LSTM Europe.
У меня получалось выше 75% на Мидасе (многомодульном, где множество модулей совмещают свои сигналы в единый сигнал). Но тогда возникает другая проблема - сигналы раз в месяц-полтора))))Чем надежнее сигнал, тем реже он возникает...Поэтому в последних роботах вообще забивать стал на высокий винрейт, пытаюсь прогнозировать глубину движений чтобы брать риск к прибыли в 1:3, 1:4 и т.п. Настраиваю метки таким образом, чтобы они давали премии моделям через DQN за правильную разметку глубоких движений....Вылилось это в итоге в робота LSTM Europe.
75 на LTSM при lookback = 5 bars_ahead = 1 но это для бинарки норм, а не для форекса
Так а где ИИ? Или Вы катбуст возвели в этот ранг?
Ну тест бы какой нибудь сделали что ли. 58% это окей? Этот показатель–Accuracy- чисто ориентир. Основной показатель - баланс на тесте по полученным сигналам.
Не интересно.