Единый мультитаймфреймовый Ренко: Синтез временных измерений рынка
Введение: когда одного взгляда недостаточно
Представьте рынок через четыре окна: M5 — нервные подёргивания спекулянтов, M15 — дыхание внутридневных трейдеров, H1 — намерения позиционных игроков, H4 — глобальные тренды. Эти реальности параллельны, но не общаются. Трейдер переключается между графиками, ища согласие, как оркестр без дирижёра.
Обычный Ренко не отвечает на вопрос о старших таймфреймах. Рынок многослойный: M5 шепчет об импульсе, H1 — о среднесрочном дыхании, H4 — о большой волне. Идея: единый Ренко, дышащий всеми частотами. Это мост между шумом и структурой, фильтрующий колебания и выделяющий направление капитала.
Рынки фрактальны: хаос на минутах обретает смысл на часах, тренды состоят из микросделок. Классический анализ — последовательный: глобальный тренд на D1, вход на H1, тайминг на M5. Требует субъективности.
Мультитаймфреймовый Ренко — параллельный синтез: сигналы взвешиваются в единое решение, как нейронная сеть. EMA — датчик направления, с весом на недавние данные. Четыре мнения сводятся в консенсус, создавая синтетический символ в MetaTrader 5. Он получает тики в реальном времени, рисует бары, появляется в списке символов. Подход для тестирования стратегий, индикаторов, автоторговли по очищенному отражению рынка.
Архитектура системы: от концепции к коду
Компоненты: захват тиков, четыре анализатора EMA и направлений, синтезатор сигналов.
struct TimeframeData { ENUM_TIMEFRAMES timeframe; double emaValue; double lastRenkoPrice; double weight; int renkoDirection; // 1 = вверх, -1 = вниз, 0 = боковик datetime lastUpdateTime; double signalStrength; };
Эта структура — сердце системы. Она хранит полное состояние каждого таймфрейма: текущее значение EMA, последнюю цену Ренко-кирпича, вес таймфрейма в общем решении, направление последнего движения, время последнего обновления и силу текущего сигнала. Модульность архитектуры позволяет легко добавлять новые таймфреймы или изменять веса существующих без переписывания логики.
Веса таймфреймов — критический параметр системы. По умолчанию используется прогрессия {1.0, 2.0, 3.0, 4.0} для M5, M15, H1 и H4 соответственно. Это означает, что H4 имеет в четыре раза больше влияния на итоговое решение, чем M5. Логика проста: чем старше таймфрейм, тем меньше в нём шума и тем надёжнее его сигналы. Но эти веса можно и нужно настраивать под конкретные торговые стратегии и особенности активов.
Система работает в двух режимах: исторический и реал-тайм. В историческом режиме она загружает данные за указанный период, обрабатывает их последовательно и создаёт массив Ренко-баров. В реал-тайм режиме она подключается к потоку тиков через таймер и обновляет виртуальный символ по мере поступления новых данных. Это позволяет использовать систему как для бэктестинга, так и для живой торговли.
Создание виртуального символа: магия Custom Symbols
MetaTrader 5 предоставляет уникальную возможность создавать пользовательские символы — это одна из самых мощных, но недооценённых функций платформы. Custom Symbol — это не просто набор данных, это полноценный торговый инструмент со всеми атрибутами реального символа: точностью котировок, размером контракта, валютой прибыли, торговыми сессиями.
bool CreateUnifiedSymbol() { if(SymbolSelect(UnifiedSymbol, true)) { CustomRatesDelete(UnifiedSymbol, 0, 0); Print("Символ ", UnifiedSymbol, " существует. История удалена."); return true; } if(!CustomSymbolCreate(UnifiedSymbol)) { Print("Ошибка создания символа: ", GetLastError()); return false; } double point = SymbolInfoDouble(SourceSymbol, SYMBOL_POINT); int digits = (int)SymbolInfoInteger(SourceSymbol, SYMBOL_DIGITS); CustomSymbolSetInteger(UnifiedSymbol, SYMBOL_DIGITS, digits); CustomSymbolSetDouble(UnifiedSymbol, SYMBOL_POINT, point); CustomSymbolSetString(UnifiedSymbol, SYMBOL_DESCRIPTION, "Unified Multi-TF Renko for " + SourceSymbol); return true; }
Этот код выполняет несколько критически важных операций. Сначала проверяется, не существует ли уже символ с таким именем — если да, его история очищается, чтобы избежать конфликтов. Затем создаётся новый символ через CustomSymbolCreate(). После этого устанавливаются основные свойства: количество знаков после запятой, размер пункта, описание.
Важный момент: виртуальный символ наследует большинство свойств от исходного. Это гарантирует, что расчёты прибыли и убытка будут корректными, а сам символ будет выглядеть естественно в терминале. Можно даже настроить торговые сессии, хотя для Ренко-графиков это обычно не критично, поскольку они строятся на изменении цены, а не времени.
Теперь у нас есть «живой» символ в терминале, который можно открыть на графике, запустить в тестере стратегий, прикрепить к нему индикаторы и даже строить на нём советники. Всё, что остаётся — наполнять его барами. И здесь начинается настоящая магия.
Размер кирпича: адаптация к волатильности
Ренко-кирпич можно делать фиксированным или адаптивным. Фиксированный размер прост и понятен: каждый кирпич всегда имеет одну и ту же высоту в пунктах. Это работает хорошо на стабильных рынках, но создаёт проблемы на волатильных активах. Когда ATR (Average True Range) резко растёт, фиксированные кирпичи начинают рисоваться слишком часто, заполняя график шумом. Когда волатильность падает, кирпичи формируются слишком редко, и график теряет информативность.
Адаптивный размер решает эту проблему элегантно: система вычисляет дневной ATR и умножает его на коэффициент — обычно от 0.3 до 0.7. Это даёт размер кирпича, который автоматически масштабируется под текущую рыночную активность.
double CalculateBrickSizeFromATR() { double atr[]; int handle = iATR(SourceSymbol, PERIOD_D1, ATRPeriod); if(handle == INVALID_HANDLE) return -1; int copied = CopyBuffer(handle, 0, 0, 1, atr); IndicatorRelease(handle); if(copied != 1) return -1; return NormalizeDouble(atr[0] * ATRMultiplier, _Digits); }
Функция предельно проста, но эффективна. Она создаёт хендл индикатора ATR на дневном таймфрейме, копирует последнее значение, освобождает ресурсы и возвращает нормализованный размер кирпича. Использование дневного периода критично — он даёт стабильную оценку волатильности, не подверженную внутридневным всплескам.
Множитель ATR — это искусство, а не наука. Значение 0.5 даёт сбалансированный результат для большинства валютных пар. Меньшие значения (0.3-0.4) делают график более чувствительным, больше кирпичей, больше деталей. Большие значения (0.6-0.8) создают более гладкую картину, фильтруя мелкие колебания. Выбор зависит от торгового стиля: скальперам нужны мелкие кирпичи, свинг-трейдерам — крупные.
Такой подход делает график «саморегулируемым»: при росте волатильности кирпичи становятся крупнее, при затухании рынка — меньше. Это избавляет от необходимости постоянно подгонять настройки вручную при переходе от спокойных периодов к новостным релизам или экономическим шокам.
Композитный сигнал: три метода объединения
Самое интересное и нетривиальное в системе — механизм объединения сигналов с разных таймфреймов. Здесь реализовано три подхода, каждый со своими преимуществами и областями применения.
Метод 1: простое среднее
Самый наивный, но удивительно эффективный подход. Берём значения EMA со всех четырёх таймфреймов и вычисляем арифметическое среднее.
double CalculateAverageSignal()
{
double sum = 0;
for(int i = 0; i < 4; i++)
{
sum += timeframes[i].emaValue;
}
return sum / 4.0;
}Этот метод даёт всем таймфреймам равные права. M5 и H4 вносят одинаковый вклад в итоговый сигнал. Казалось бы, это плохо — ведь старшие таймфреймы надёжнее. Но на практике простое среднее создаёт удивительно сбалансированный график, который улавливает и краткосрочные импульсы, и долгосрочные тренды.
Применение: подходит для скальпинга и внутридневной торговли, где важна чувствительность к быстрым движениям. Хорошо работает на высоколиквидных парах типа EURUSD, где шум относительно невелик.
Метод 2: взвешенное среднее
Более изощрённый подход — каждому таймфрейму присваивается вес, отражающий его важность.
double CalculateWeightedSignal() { double weightedSum = 0; double totalWeight = 0; for(int i = 0; i < 4; i++) { weightedSum += timeframes[i].emaValue * timeframes[i].weight; totalWeight += timeframes[i].weight; } return totalWeight > 0 ? weightedSum / totalWeight : 0; }
При весах {1.0, 2.0, 3.0, 4.0} сигнал H4 имеет в 10 раз больше влияния, чем все остальные вместе взятые (4/(1+2+3+4) = 40%). Это создаёт график, который следует за старшими таймфреймами, но при этом не игнорирует младшие полностью.
Применение: идеален для позиционной торговли и свинг-стратегий. График получается более гладким, меньше ложных сигналов, но и меньше чувствительности к краткосрочным возможностям. Отлично работает на волатильных кроссах вроде GBPJPY.
Метод 3: консенсус
Самый консервативный и надёжный подход. Кирпич рисуется только тогда, когда минимум три из четырёх таймфреймов согласны относительно направления.
double CalculateConsensusSignal()
{
int upCount = 0, downCount = 0;
double avgUp = 0, avgDown = 0;
for(int i = 0; i < 4; i++)
{
if(timeframes[i].renkoDirection > 0)
{
upCount++;
avgUp += timeframes[i].emaValue * timeframes[i].weight;
}
else if(timeframes[i].renkoDirection < 0)
{
downCount++;
avgDown += timeframes[i].emaValue * timeframes[i].weight;
}
}
if(upCount >= 3) return avgUp / upCount;
if(downCount >= 3) return avgDown / downCount;
return CalculateWeightedSignal();
}Этот метод моделирует «демократическое голосование» между таймфреймами. Если три или четыре EMA показывают рост, строится кирпич вверх. Если три показывают падение — вниз. При отсутствии консенсуса (например, 2 вверх, 2 вниз), система возвращается к взвешенному среднему как к компромиссному решению.
Применение: прекрасно работает на парах с частыми микроколебаниями — EURUSD, USDCAD. Количество кирпичей существенно меньше, зато каждый из них имеет высокую вероятность продолжения. Это снижает количество ложных сигналов и делает структуру движения устойчивее.
Построение исторических данных: путешествие в прошлое
Генерация истории — один из самых технически сложных аспектов системы. Нужно не просто скопировать существующие бары, а пересчитать их через призму мультитаймфреймового анализа. Процесс начинается с загрузки данных с самого младшего таймфрейма (M5), поскольку он обеспечивает максимальную детализацию.
bool GenerateUnifiedHistory() { datetime endTime = TimeCurrent(); datetime startTime = endTime - HistoryDays * 24 * 60 * 60; MqlRates sourceRates[]; int copied = CopyRates(SourceSymbol, PERIOD_M5, startTime, endTime, sourceRates); if(copied <= 0) { Print("Ошибка копирования баров: ", GetLastError()); return false; } Print("Обработка ", copied, " M5 баров для создания единого Ренко"); ArrayResize(unifiedRates, copied * 2); unifiedRatesCount = 0; double basePrice = sourceRates[0].close; for(int i = 0; i < 4; i++) { timeframes[i].emaValue = basePrice; timeframes[i].lastRenkoPrice = basePrice; } unifiedLastPrice = basePrice; CreateInitialBars(basePrice, sourceRates[0].time); for(int i = 0; i < copied; i++) { ProcessHistoricalBar(sourceRates[i]); } ArrayResize(unifiedRates, unifiedRatesCount); if(!CustomRatesUpdate(UnifiedSymbol, unifiedRates)) { Print("Ошибка обновления единого символа: ", GetLastError()); return false; } Print("Создано ", unifiedRatesCount, " единых Ренко-баров"); return true; }
Функция выполняет несколько ключевых шагов. Сначала определяется временной диапазон — от текущего момента на заданное количество дней назад. Затем загружаются M5-бары через CopyRates(). Массив для хранения Ренко-баров предварительно увеличивается до двукратного размера исходных данных — это эвристическая оценка, обычно Ренко-баров получается меньше.
Критический момент — инициализация. Все EMA начинаются с одного и того же значения (первая цена закрытия), иначе в начале истории будут огромные артефакты из-за резких скачков неинициализированных средних. Создаются два начальных бара, чтобы алгоритм мог корректно определить направление движения.
Затем каждый исторический M5-бар пропускается через ProcessHistoricalBar(), которая обновляет EMA всех таймфреймов и формирует композитный сигнал. Если сигнал достаточно сильный, создаётся новый Ренко-кирпич. В конце массив обрезается до реального размера и передаётся в CustomRatesUpdate(), которая записывает всю историю в виртуальный символ одной операцией.
Обработка каждого исторического бара: детали имеют значение
Каждый M5-бар обрабатывается через специальную функцию, которая координирует обновление всех компонентов системы.
void ProcessHistoricalBar(const MqlRates &bar) { UpdateTimeframeEMAs(bar.close, bar.time); double compositePrice = CalculateCompositeSignal(); if(compositePrice > 0) { unifiedRatesCount = LoadUnifiedPrice(compositePrice, bar.time); unifiedLastBarTime = bar.time; } }
Функция выглядит обманчиво просто, но за её лаконичностью скрывается сложная логика. UpdateTimeframeEMAs() проверяет, нужно ли обновлять каждый таймфрейм в данный момент времени. Например, если текущий бар относится к тому же H1-периоду, что и предыдущий, H1-EMA не пересчитывается, экономя вычислительные ресурсы и обеспечивая корректность расчётов.
CalculateCompositeSignal() применяет выбранный метод объединения (среднее, взвешенное или консенсус) и возвращает синтетическую цену, которая представляет собой коллективное мнение всех таймфреймов. Если эта цена положительна (что всегда так для валютных пар, но может быть не так для синтетических индексов), она передаётся в LoadUnifiedPrice() .
LoadUnifiedPrice() — самая сложная функция в системе. Она решает, нужно ли создавать новый кирпич, и если да — то сколько. При сильном импульсе за один вызов может создаться несколько кирпичей подряд. Функция также отслеживает фитили (wicks), если они включены, и корректно обрабатывает развороты движения.
Определение направления: логика Ренко-движения
Для каждого таймфрейма система отслеживает виртуальный Ренко-график, который существует независимо от единого синтетического символа.
void UpdateTimeframeRenkoDirection(int tfIndex) { double emaPrice = timeframes[tfIndex].emaValue; double lastRenko = timeframes[tfIndex].lastRenkoPrice; if(emaPrice >= lastRenko + currentBrickSize) { timeframes[tfIndex].renkoDirection = 1; timeframes[tfIndex].lastRenkoPrice = lastRenko + currentBrickSize; timeframes[tfIndex].signalStrength = (emaPrice - lastRenko) / currentBrickSize; } else if(emaPrice <= lastRenko - currentBrickSize) { timeframes[tfIndex].renkoDirection = -1; timeframes[tfIndex].lastRenkoPrice = lastRenko - currentBrickSize; timeframes[tfIndex].signalStrength = (lastRenko - emaPrice) / currentBrickSize; } else { timeframes[tfIndex].renkoDirection = 0; timeframes[tfIndex].signalStrength = 0; } }
Логика классическая для Ренко: если EMA прошла выше предыдущей цены Ренко плюс размер кирпича, фиксируется движение вверх. Если упала ниже минус размер кирпича — движение вниз. Если осталась в коридоре — боковик.
Поле signalStrength содержит дополнительную информацию — насколько сильно цена ушла от последнего кирпича. Значение 1.5 означает, что движение достаточно для полутора кирпичей. Это можно использовать для приоритизации таймфреймов с более сильными импульсами.
Интересный момент: каждый таймфрейм имеет собственную Ренко-цену, которая не обязательно совпадает с ценами других таймфреймов. M5 может показывать 1.0850, а H4 — 1.0840. Это нормально и отражает различные временные масштабы. Синтез происходит через EMA-значения и направления, а не через прямое усреднение цен.
Визуализация: когда график оживает
Чтобы наблюдать за работой системы в реальном времени, создаётся отдельное окно с виртуальным символом.
void OpenUnifiedChart() { unifiedChartId = ChartOpen(UnifiedSymbol, PERIOD_M1); if(unifiedChartId != 0) { ChartSetInteger(unifiedChartId, CHART_MODE, CHART_CANDLES); ChartSetInteger(unifiedChartId, CHART_AUTOSCROLL, true); ChartSetInteger(unifiedChartId, CHART_SCALE, 3); string comment = "Unified Multi-TF Renko - Brick: " + DoubleToString(currentBrickSize, _Digits) + " - Method: " + GetSignalMethodName() + " - EMA: " + IntegerToString(EMAPeriod); ChartSetString(unifiedChartId, CHART_COMMENT, comment); Print("Единый график открыт. ID: ", unifiedChartId); } }
График открывается в режиме свечей, хотя сами «свечи» на самом деле — Ренко-кирпичи с одинаковыми телами. Автопрокрутка включена, чтобы график всегда показывал последние данные. Масштаб установлен в 3 — средний размер, подходящий для большинства экранов.
Комментарий в верхней части графика содержит ключевые параметры: размер кирпича, метод объединения сигналов, период EMA. Это позволяет быстро понять, с какой конфигурацией работает система, не копаясь в настройках.
Видеть такой график — отдельное удовольствие. Он выглядит как гибрид между классическим Renko и агрегированным баровым потоком. Каждое движение становится логичным, а фальшивые импульсы исчезают. На EURUSD, где обычный M5-график трясётся, как будто у евро и доллара эпилепсия, единый Ренко показывает чёткую структуру: три кирпича вверх, откат, пять вниз, консолидация.

Можно развить визуализацию дальше — добавить цветовую кодировку кирпичей в зависимости от того, какой таймфрейм доминирует. Например, если консенсус достигнут благодаря H4, кирпич окрашивается в тёмно-красный или тёмно-синий. Если решение принято на основе M5 и M15, используются светлые оттенки. Тогда структура рынка буквально оживает: H4 окрашивает глобальный тренд, M5 добавляет «дыхание», а M15 и H1 формируют «ритм».
Практическое применение: от теории к торговле
Как использовать единый мультитаймфреймовый Ренко в реальной торговле? Вот несколько стратегий:
Стратегия 1. Торговля по тренду. Ждём формирования линии последовательных кирпичей в одном направлении — это сигнал о начале импульса. Входим в направлении движения на четвёртом кирпиче. Стоп-лосс на два кирпича назад. Тейк-профит на расстоянии 5-7 кирпичей или при появлении кирпича в обратном направлении.
Стратегия 2. Пробой консолидации. Когда график входит в боковик (кирпичи чередуются вверх-вниз-вверх-вниз), отмечаем диапазон. При пробое — серии из 2-3 кирпичей в одну сторону — входим по направлению пробоя. Это момент, когда все таймфреймы наконец-то приходят к согласию.
Стратегия 3. Корреляционный арбитраж. Создаём два единых Ренко: для EURUSD и AUDUSD. Эти пары обычно коррелируют. Если EURUSD показывает сильный восходящий тренд (5+ кирпичей вверх), а AUDUSD ещё в боковике, высока вероятность, что GBPUSD догонит. Открываем лонг по AUDUSD с коротким стопом.
Торговля эксперта
Представьте: ваш мультитаймфреймовый Ренко готов, кирпичи строятся в реальном времени. Теперь заставим его торговать. Эксперт RenkoEA_MA_Cross.mq5 — простой, но рабочий. Он берёт пересечение двух MA на Ренко-символе и открывает позицию на реальном инструменте. Никакого шума, только подтверждённые сигналы от четырёх таймфреймов.
Архитектура простая. Два символа: RenkoSymbol для анализа (например, EURUSD_UNIFIED_RENKO), TradeSymbol для торговли (EURUSD). MA считаются по закрытиям кирпичей, PERIOD_CURRENT — это Ренко-бары.
input string RenkoSymbol = "EURUSD_UNIFIED_RENKO"; // Ренко-символ (анализ) input string TradeSymbol = "EURUSD"; // Торговый символ
В OnInit добавляем символы в рынок, создаём хэндлы iMA на Ренко. Таймер ждёт тики с обоих, чтобы синхронизировать.
// Добавляем символы if(!AddSymbolToMarket(RenkoSymbol)) { Print("Ошибка: Не удалось добавить ", RenkoSymbol); return(INIT_FAILED); } if(!AddSymbolToMarket(TradeSymbol)) { Print("Ошибка: Не удалось добавить ", TradeSymbol); return(INIT_FAILED); } // Создаём индикаторы на Renko-символе fast_ma_handle = iMA(RenkoSymbol, PERIOD_CURRENT, FastMAPeriod, 0, MAMethod, MAPrice); slow_ma_handle = iMA(RenkoSymbol, PERIOD_CURRENT, SlowMAPeriod, 0, MAMethod, MAPrice); if(fast_ma_handle == INVALID_HANDLE || slow_ma_handle == INVALID_HANDLE) { Print("Ошибка создания индикаторов MA"); return(INIT_FAILED); } EventSetTimer(1); Print("Ожидание тиков для ", RenkoSymbol, " и ", TradeSymbol, "..."); return(INIT_SUCCEEDED);
В OnTick проверяем новый кирпич: if(rates[0].time > lastBarTime). Копируем 3-4 бара, буферы MA. Сигнал на пересечении предыдущего и текущего закрытого бара (BarShift=1 по умолчанию, чтобы не ловить незавершённый кирпич).
void OnTick() { if(!symbols_ready) return; if(Symbol() != TradeSymbol) return; // Получаем бары и MA MqlRates rates[]; int copied = CopyRates(RenkoSymbol, PERIOD_CURRENT, 0, 4, rates); if(copied < 3) { Print("Ошибка: CopyRates вернул ", copied, " баров"); return; } // Новый бар? if(rates[0].time <= lastBarTime) return; if(BarShift + 1 >= copied) return; // Копируем значения MA double fast_ma[], slow_ma[]; if(CopyBuffer(fast_ma_handle, 0, 0, 3, fast_ma) <= 0 || CopyBuffer(slow_ma_handle, 0, 0, 3, slow_ma) <= 0) { Print("Ошибка копирования буфера MA"); return; } int shift = BarShift; // Проверяем пересечение на предыдущем закрытом баре (shift) bool prev_fast_above = fast_ma[shift + 1] > slow_ma[shift + 1]; bool prev_fast_below = fast_ma[shift + 1] < slow_ma[shift + 1]; bool curr_fast_above = fast_ma[shift] > slow_ma[shift]; bool curr_fast_below = fast_ma[shift] < slow_ma[shift]; bool buySignal = prev_fast_below && curr_fast_above; // Пересечение вверх bool sellSignal = prev_fast_above && curr_fast_below; // Пересечение вниз // Логирование Print("=== MA CHECK ==="); Print("Bar[", shift, "]: FastMA=", DoubleToString(fast_ma[shift], _Digits), " SlowMA=", DoubleToString(slow_ma[shift], _Digits)); Print("Prev: Fast", (prev_fast_above ? ">":"<"), "Slow → Curr: Fast", (curr_fast_above ? ">":"<"), "Slow"); Print("BUY=", buySignal, " SELL=", sellSignal); // --- ЗАКРЫТИЕ ПО СИГНАЛУ --- if(OnePosition && PositionsTotalByMagic() > 0 && CloseOnSignal) { if(buySignal) ClosePositions(POSITION_TYPE_SELL); if(sellSignal) ClosePositions(POSITION_TYPE_BUY); } // --- ОТКРЫТИЕ НОВОЙ ПОЗИЦИИ --- if(OnePosition && PositionsTotalByMagic() > 0) return; double price, sl = 0, tp = 0; int digits = (int)SymbolInfoInteger(TradeSymbol, SYMBOL_DIGITS); double point = SymbolInfoDouble(TradeSymbol, SYMBOL_POINT); if(buySignal) { price = SymbolInfoDouble(TradeSymbol, SYMBOL_ASK); if(StopLoss > 0) sl = NormalizeDouble(price - StopLoss * point, digits); if(TakeProfit > 0) tp = NormalizeDouble(price + TakeProfit * point, digits); OpenPosition(POSITION_TYPE_BUY, price, sl, tp); } if(sellSignal) { price = SymbolInfoDouble(TradeSymbol, SYMBOL_BID); if(StopLoss > 0) sl = NormalizeDouble(price + StopLoss * point, digits); if(TakeProfit > 0) tp = NormalizeDouble(price - TakeProfit * point, digits); OpenPosition(POSITION_TYPE_SELL, price, sl, tp); } // Обновляем время последнего бара if(rates[0].time > lastBarTime) lastBarTime = rates[0].time; }
Купить: быстрая MA пересекла медленную вверх. Продать — вниз. Если CloseOnSignal, то обратный сигнал закрывает позицию. OnePosition — только одна открытая.
Функции: AddSymbolToMarket — селектит символ. OpenPosition — формирует запрос. ClosePositions — пробегает по тикам, закрывает по типу. CalculateLot — учитывает мин/макс/шаг.
Вот мой бэктест. Параметры использовались такие, тест шел на EURUSD, на сочетании EURUSD M15 и синтетического EURUSDRENKO M1:
RenkoSymbol=EURUSD_UNIFIED_RENKO TradeSymbol=EURUSD FastMAPeriod=300 SlowMAPeriod=400 MAMethod=3 MAPrice=5 Lots=0.1 RiskPercent=7 StopLoss=700 TakeProfit=100 Slippage=30 CloseOnSignal=true BarShift=1 MagicNumber=123456 OnePosition=true Comm=RenkoEA
Результаты меня вполне радуют. Коэффициент Шарпа — свыше 15, это отлично:

График бэктеста также красив, и практически нет просадки по эквити:

Код готов к тесту. Запустите на истории Ренко, попробуйте оптимизировать и запускать. На демо — проверьте исполнение. Меняется EMA в Ренко или метод консенсуса — сигналы чище.
Это базовый EA, но уже видно, что на синтетическом Ренко он даёт меньше ложных сигналов, чем на обычных барах. Экспериментируйте с периодами, добавляйте свои фильтры. Рынок в одном графике — и робот по нему торгует.
Заключение: новый язык анализа рынков
Этот проект — не просто очередной индикатор или торговый робот. Это концепция нового типа анализа, где временные масштабы перестают быть изолированными слоями реальности и сливаются в единое целое. Создавая мультитаймфреймовый Ренко, мы фактически создаём «синтетический рынок» — пространство, где все временные шкалы сходятся в одном графике.
Ренко изначально был инструментом абстракции, способом убрать время из уравнения и сосредоточиться на чистом движении цены. Мультитаймфреймовый подход добавляет ещё один уровень абстракции — он убирает не только время, но и произвольность выбора таймфрейма. Больше не нужно решать, торговать ли по M15 или по H1. Система принимает решение за вас, взвешивая мнения всех периодов.
Это философия, близкая к квантовой механике: наблюдение на одном таймфрейме коллапсирует волновую функцию рынка в конкретное состояние. Но истинная реальность существует во всех таймфреймах одновременно, в суперпозиции. Единый Ренко — это способ наблюдать эту суперпозицию без коллапса, видеть рынок таким, какой он есть, а не таким, каким его показывает произвольно выбранный период.
Можно развивать идею дальше: подключать коррелирующие инструменты (золото для AUDUSD, нефть для CADJPY), включать фундаментальные индикаторы (календарь новостей, процентные ставки), использовать нейросети для динамической настройки весов или даже создавать ансамбли из нескольких единых Ренко с разными параметрами, где финальное решение принимается голосованием.
Ренко в таком контексте перестаёт быть фильтром — он становится интерфейсом между рыночным шумом и структурой тренда. Это не визуализация, а язык, на котором можно описывать поведение цены. Язык, где каждое слово — кирпич, каждое предложение — последовательность движений, а весь текст — история рынка, рассказанная без лишних деталей, но с полным сохранением смысла.
Код открыт для экспериментов. Меняйте веса, добавляйте таймфреймы, интегрируйте новые индикаторы. Может быть, именно ваша модификация откроет паттерн, который до сих пор был скрыт в многомерном пространстве временных масштабов. Удачи в исследовании рынков!
Предупреждение: все права на данные материалы принадлежат MetaQuotes Ltd. Полная или частичная перепечатка запрещена.
Данная статья написана пользователем сайта и отражает его личную точку зрения. Компания MetaQuotes Ltd не несет ответственности за достоверность представленной информации, а также за возможные последствия использования описанных решений, стратегий или рекомендаций.
Возможности Мастера MQL5, которые вам нужно знать (Часть 55): SAC с приоритетным воспроизведением опыта
Введение в MQL5 (Часть 12): Руководство для начинающих по созданию пользовательских индикаторов
Нейросети в трейдинге: Спайковая архитектура пространственно-временного анализа рынка (SDformerFlow)
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Вы принимаете политику сайта и условия использования
НЕУЖЕЛИ появилась новая идея в этом теме. Сам я пользуюсь Ренко уже более 10 лет. Считаю их самым перспективным направлением в торговле. Нашел для себя самое удачное сочетание стратегий (с моей точки зрения) Ренко + Объём. И вот решил, что на этом жизнь «кончилась». Свои идеи закончились т.к. текущий результат более чем эффективный, а новых не подкидывают ни в том не в другом направлении. Все как будто помешались на ИИ. Так мало нового. Пытаются создать гоночный авто на паровом моторе. Рынок это не математика, а люди. Все снова беремся за творческий процесс. Спасибо огромное.
количество — зашкаливает.
Как понял, кирпичи рисуются в основном за счет изменения ЕМА на М5.
Остальные вносят коррекцию суммарной цены раз в 15, 60 и 240 минут.
На Н4 цена Close может и на 0,01000 измениться. С учетом ЕМА 20 скачек будет меньше, например 0,00100. Тогда на вашем графике с кирпичами по 0,00010 нарисуется 10 кирпичей в одну сторону в момент наступления Н4 - только из за того, что 4 часа ждали и наконец пересчитали.
Оптимизация может именно на эти перерасчетные кирпичи настроиться, ведь они возникают закономерно каждые 4 часа. Но реальная цена не будет проходить в долю секунды 0,00100 со срабатыванием ТП. Будет рандомный итог за вычетом маркапа.
Аналогично на Н1 и М15, но кирпичей возникших из за их перерасчета будет меньше.
Думаю они только вносят искажения. Перспективнее представляется торговля только на ЕМА М5.
Если неправильно понимаю - поясните.
Мне показались странными настройки (FastMAPeriod=300, SlowMAPeriod=400) - здесь чудовищная задержка сигналов по времени от реального движения цены.
Кроме того, StopLoss=700 и TakeProfit=100 - похоже на пересиживание убытков.