Разработка инструментария для анализа Price Action (Часть 29): Советник "Boom and Crash Interceptor"
Содержание
- Введение
- Знакомство со стратегией
- Разбор кода
- Тестирование на исторических данных и результаты
- Заключение
Введение
В современных системах противовоздушной обороны многослойная сеть датчиков с предельной точностью анализирует каждый радиолокационный отклик и каждый инфракрасный след. Каждый обнаруженный объект оценивается по скорости, траектории и сигнатуре, а затем сверяется с обширной базой угроз. Только когда несколько независимых фильтров подтверждают один и тот же вывод, система санкционирует запуск перехватчика, сохраняя ресурсы и гарантируя, что реальные угрозы будут нейтрализованы без задержки.
Советник Boom & Crash Interceptor использует столь же дисциплинированный подход к рыночным данным. Скользящее окно скорости определяет, превосходит ли текущий ценовой импульс недавнее поведение рынка; множитель всплеска на основе ATR подтверждает, что волатильность действительно существенно выросла; а фильтры тренда на основе скользящих средних подтверждают направленность движения. Дополнительные фильтры по пивот-зоне и времени сессии еще сильнее отсекают сигналы, которые иначе возникали бы в периоды низкой ликвидности.
Когда все уровни подтверждают сигнал, советник рисует на графике стрелку "BOOM" или "CRASH" с заданными пользователем цветами, смещениями и записью в CSV-лог. Это гарантирует, что внимание будет сосредоточено только на наиболее вероятных возможностях. Далее мы разберем, как можно откалибровать каждый уровень обнаружения и как использовать этот инструмент на MQL5 в качестве надежного сигнального компонента в рамках более широкой торговой системы.
Знакомство со стратегией
Черпая вдохновение в противоракетной обороне, советник Boom & Crash Interceptor рассматривает рыночные всплески как надвигающиеся угрозы. Под missile в широком смысле понимается любой поражающий снаряд, управляемый или неуправляемый, запускаемый с целью поразить цель. Современные варианты представляют собой ракеты с собственным двигателем, оснащенные боеголовками и системами инерциального, радиолокационного, спутникового или оптического наведения; к ним относятся как межконтинентальные баллистические ракеты (МБР), так и крылатые ракеты и зенитные перехватчики. Исторически даже брошенное копье или выпущенная стрела подпадают под это определение, поскольку их траектория намеренно направлена к цели.
В торговле столь же опасным может быть резкий ценовой всплеск: он возникает быстро, часто неожиданно и способен нанести серьезный ущерб неподготовленному счету. Здесь аналогия с системой перехвата ракет оказывается особенно полезной. Система перехвата ракет – это оборонительный комплекс, который обнаруживает, сопровождает и нейтрализует входящую боеголовку до удара. Ее работа строится вокруг четырех тесно связанных этапов:
Обнаружение и сопровождение
- Наземные, корабельные или космические датчики фиксируют запуск вражеского снаряда.
- Система управления огнем вычисляет траекторию, скорость и предполагаемую точку удара.
Запуск и наведение
- После подтверждения перехватчик стартует из шахты, с мобильной установки, корабля или самолета.
- Коррекция курса обеспечивается инерциальным наведением, каналами передачи данных на среднем участке траектории и радиолокационным или инфракрасным самонаведением на финальной фазе.
- Кинетический перехват: перехватчик напрямую сталкивается с боеголовкой на скорости сближения с числом Маха свыше 10, полагаясь на кинетическую энергию для ее уничтожения.
- Подрыв на близкой дистанции: контролируемая детонация рядом с целью разрушает или отклоняет ее осколками либо направленной ударной волной.
- Системы малой дальности, например Patriot PAC-3, перехватывают угрозы на финальной фазе.
- Системы перехвата на среднем участке траектории, например SM-3 и Ground-based Midcourse Defense, действуют в космосе.
- Перехватчики на фазе разгона пока еще экспериментальны. Они нацеливаются на ракеты в первые моменты после их запуска.
Эти уровни нужны для того, чтобы обеспечить максимальную защиту при минимуме ложных пусков; такой баланс достигается за счет быстрого объединения данных и строгой логики подтверждения.
Советник Boom & Crash Interceptor воспроизводит ту же архитектуру. Непрерывный мониторинг рынка играет роль радиолокационной сети; пороги скорости, фильтры всплеска ATR и согласованность со скользящей средней выступают как независимые уровни подтверждения; дополнительные фильтры по пивот-зоне и времени сессии имитируют распознавание и отсечение ложных целей; и лишь когда все критерии совпадают, советник "производит пуск" – рисует стрелку BOOM или CRASH и заносит событие в лог. Тем самым он сохраняет внимание трейдера и торговый капитал для тех угроз, которые действительно требуют реакции, подобно тому как батарея ПРО бережет свои перехватчики для боеголовок, представляющих реальную опасность.

Рис. 1. Стратегия
Радар скорости
Измеряет изменение цены за VelocityHistoryBars и сравнивает его с порогом исторического процентиля – проходят только "необычно большие" движения.
// Record current vs. old price double priceNow = SymbolInfoDouble(_Symbol, SYMBOL_ASK); double priceOld = velHistory[VelocityHistoryBars - 1]; double delta = priceNow - priceOld; // Build and sort past deltas double d[]; ArrayResize(d, VelocityHistoryBars - 1); for(int i = 1; i < VelocityHistoryBars; i++) d[i - 1] = velHistory[0] - velHistory[i]; ArraySort(d); // Pick the (100–VelocityPctile)% threshold int idx = (int)MathRound((VelocityPctile / 100.0) * (ArraySize(d) - 1)); double velTh = d[ArraySize(d) - 1 - idx]; // Pass if current move exceeds threshold bool okVel = (delta > velTh || delta < -velTh);
Детектор всплеска ATR
Проверяет наличие резкого скачка волатильности, сравнивая последнее значение ATR со значением ATR предыдущего бара, умноженным на ATRMultiplier.
// Fetch two most recent ATR values double atrArr[2]; CopyBuffer(atrHandle, 0, 0, 2, atrArr); // Pass if ATR_now > ATR_prev × ATRMultiplier bool okATR = (atrArr[0] > atrArr[1] * ATRMultiplier);
Проверка согласованности с трендом
Проверяет, соответствует ли движение цены тренду: при восходящем движении SMA тоже должна расти, а при нисходящем – падать.// Fetch two most recent SMA values double maArr[2]; CopyBuffer(maHandle, 0, 0, 2, maArr); // If delta>0 require SMA_now>SMA_prev; if delta<0 require SMA_now<SMA_prev bool okTrend = (delta > 0 ? maArr[0] > maArr[1] : maArr[0] < maArr[1]);
Фильтр пивот-зоны (опционально)
Блокирует сигналы, возникающие слишком близко к пивоту предыдущего бара, задавая буфер ZoneBufferPoints.
// Compute prior bar’s pivot double h1 = iHigh(_Symbol, MainTF, 1), l1 = iLow (_Symbol, MainTF, 1), c1 = iClose(_Symbol, MainTF, 1); double pivot = (h1 + l1 + c1) / 3.0; // Pass if priceNow is beyond pivot ± buffer bool okZone = (delta > 0 ? priceNow < pivot - ZoneBufferPoints * _Point : priceNow > pivot + ZoneBufferPoints * _Point);
Финальная логика "запуска ракеты"
Стрелка Boom (вверх) или Crash (вниз) появляется только тогда, когда пройдены все фильтры.
// Determine direction bool isBoom = (delta > velTh); bool isCrash = (delta < -velTh); // Fire only if velocity, ATR, trend, and zone all passed bool fire = ((isBoom || isCrash) && okVel && okATR && okTrend && okZone); if(fire) GenerateSignal(isBoom, priceNow, delta, atrArr[0], MainTF);
Разбор кода
Ниже приведен последовательный разбор всех основных разделов советника "Boom & Crash Interceptor".
Заголовок и директивы компиляции
Начальный блок комментариев и следующие за ним строки #property служат визитной карточкой советника. В них задаются сведения об авторском праве, ссылка на поддержку, текущая версия и флаг строгой компиляции. При компиляции в строгом режиме MetaTrader 5 применяет наиболее жесткие проверки типов и диапазонов, что помогает выявлять скрытые ошибки еще на ранних этапах сборки. Эти данные также позволяют MetaQuotes Market отслеживать историю продукта и обеспечивать для конечных пользователей плавные обновления между версиями.
//+------------------------------------------------------------------+ //| Boom and Crash Interceptor EA| //| Copyright 2025, MetaQuotes Ltd.| //+------------------------------------------------------------------+ #property copyright "Copyright 2025, MetaQuotes Ltd." #property link "https://www.mql5.com/ru/users/lynnchris" #property version "1.0" #property strict
Подключение библиотеки и торговый объект
Подключив <Trade\Trade.mqh> и создав глобальный объект CTrade, код получает доступ к объектно-ориентированной обертке над торговым API MetaTrader. Хотя текущая версия пока только выводит оповещения и графические элементы, наличие этого объекта заранее подготавливает кодовую базу к плавному переходу на реальное исполнение ордеров, когда это понадобится.
#include <Trade\Trade.mqh> CTrade trade; // object-oriented trading wrapper
Внешние параметры – панель управления советника
Все рабочие параметры объявлены с помощью ключевого слова input, что позволяет оптимизировать их в тестере стратегий или быстро менять на вкладке "Inputs" окна графика. Они делятся на четыре логические группы:
• Настройки формирования сигналов: таймфреймы, глубина анализа скорости, параметры ATR, параметры скользящей средней.
• Опциональные фильтры: логика пивот-зон и время сессии.
• Настройки отображения: расположение панели, цвета, толщина линий, смещения стрелок.
• Логирование данных: имя CSV-файла.
input ENUM_TIMEFRAMES MainTF = PERIOD_CURRENT; // Signal TF input int VelocityHistoryBars = 96; input double VelocityPctile = 120.0; // >100 ⇒ extreme input int ATRPeriod = 14; input double ATRMultiplier = 1.5; input bool UseZoneFilter = true; input int SessionStartHour = 7; input int SessionEndHour = 17; input string LogFilename = "BoCrashLog.csv";
Интересный нюанс – значение VelocityPctile по умолчанию равно 120%. Поскольку алгоритм процентилей упирается в верхний край распределения, значение выше 100% фактически требует, чтобы цена превзошла самое резкое движение, наблюдавшееся в окне анализа, тем самым намеренно повышая избирательность триггера.
Глобальные переменные и соглашения об именовании
Массив velHistory[] хранит скользящее окно, необходимое для анализа скорости, а несколько строковых констант централизованно задают имена GUI-объектов. Хранение имен в массивах (dashNames, hVelUp и т.д.) гарантирует детерминированное создание и удаление объектов, предотвращает появление осиротевших элементов и упрощает будущий рефакторинг.
double velHistory[]; string dashBG = "DashBG"; string dashNames[] = {"Delta","VelThr","ATR","ATRm","Trend", "Pivot","Zone","Signal"}; string hVelUp = "VelUp"; string hVelDown = "VelDown";
OnInit(): получение ресурсов и построение интерфейса
Во время инициализации мы изменяем размер массива скорости, получаем хэндлы индикаторов ATR и скользящей средней и завершаем работу с INIT_FAILED, если какой-либо хэндл недоступен – здесь лучше завершить работу раньше, чем столкнуться с нестабильностью во время выполнения. Затем советник открывает или создает CSV-лог, записывает заголовок, если файл новый, и переходит в конец файла для добавления последующих записей. Наконец, процедура создает полупрозрачный прямоугольник панели, заполняет его текстовыми метками и заранее строит горизонтальные и вертикальные опорные линии. Все графические элементы присутствуют на графике еще до прихода первого рыночного тика.
int OnInit() { ArrayResize(velHistory,VelocityHistoryBars); atrHandle = iATR(_Symbol, ATRTF, ATRPeriod); maHandle = iMA (_Symbol, TrendTF, TrendMAPeriod, 0, MODE_SMA, PRICE_CLOSE); if(atrHandle==INVALID_HANDLE || maHandle==INVALID_HANDLE) return INIT_FAILED; logHandle = FileOpen(LogFilename, FILE_READ|FILE_WRITE|FILE_CSV|FILE_ANSI); if(logHandle>=0 && FileSize(logHandle)==0) FileWrite(logHandle,"DateTime,Type,Velocity,ATR,Price"); // dashboard background ObjectCreate(0,dashBG,OBJ_RECTANGLE_LABEL,0,0,0); ObjectSetInteger(0,dashBG,OBJPROP_XSIZE,200); ObjectSetInteger(0,dashBG,OBJPROP_YSIZE,140); // dashboard labels for(int i=0;i<ArraySize(dashNames);i++) { string name="Dash_"+dashNames[i]; ObjectCreate(0,name,OBJ_LABEL,0,0,0); ObjectSetString(0,name,OBJPROP_TEXT,dashNames[i]+": ?"); } // reference lines ObjectCreate(0,hVelUp ,OBJ_HLINE,0,0,0); ObjectCreate(0,hVelDown,OBJ_HLINE,0,0,0); return INIT_SUCCEEDED; }
OnDeinit(): корректное завершение работы
При удалении советник освобождает хэндлы индикаторов, закрывает хэндл файла и удаляет все графические объекты, перечисленные в массивах имен. Такая симметрия между созданием и удалением крайне важна: она помогает поддерживать список объектов терминала в чистоте и экономить ресурсы операционной системы.
void OnDeinit(const int reason) { if(atrHandle!=INVALID_HANDLE) IndicatorRelease(atrHandle); if(maHandle !=INVALID_HANDLE) IndicatorRelease(maHandle); if(logHandle>=0) FileClose(logHandle); string objs[]={dashBG,hVelUp,hVelDown}; for(int i=0;i<ArraySize(objs);i++) ObjectDelete(0,objs[i]); for(int i=0;i<ArraySize(dashNames);i++) ObjectDelete(0,"Dash_"+dashNames[i]); }
OnTick(): движок принятия решений в реальном времени
Сначала функция проверяет, закрылся ли новый бар на MainTF. Если нет, функция немедленно завершается, избегая ненужных вычислений. Если обнаружен переход к новому бару, код применяет опциональный фильтр сессии, чтобы операции выполнялись только в пределах окна, заданного трейдером.
void OnTick() { // process only on completed bar int cur=iBars(_Symbol,MainTF)-1; if(cur==lastBar) return; lastBar=cur; // optional session filter MqlDateTime now; TimeToStruct(TimeCurrent(),now); if(UseSessionFilter && (now.hour<SessionStartHour || now.hour>SessionEndHour)) return; // velocity calculation double priceNow = SymbolInfoDouble(_Symbol,SYMBOL_ASK); ArrayMove(velHistory,1,0,VelocityHistoryBars-1); // shift right velHistory[0]=priceNow; double delta = priceNow-velHistory[VelocityHistoryBars-1]; double velTh = ComputeVelocityPercentile(velHistory,VelocityPctile); bool okVel = (delta>velTh || delta<-velTh); // ATR, MA, pivot-zone checks ... /* …remaining signal logic… */ if(fire) GenerateSignal(isBoom,priceNow,delta,atrArr[0],MainTF); }
Затем последняя цена Ask вставляется в начало velHistory, сдвигая более старые значения на одну позицию вниз. Затем мы вычисляем delta – расстояние между самой новой и самой старой ценой в окне - и получаем порог процентиля с помощью ComputeVelocityPercentile(). Условие по скорости считается выполненным, когда delta превышает верхний или нижний порог.
Фильтры ATR и скользящей средней оцениваются, при необходимости, на других, более низких таймфреймах, чтобы уловить краткосрочное расширение волатильности и подтвердить направленность движения. При включении фильтр пивот-зоны вычисляет классический пивот H+L+C по предыдущей свече и ограничивает сигналы теми движениями, которые все еще находятся по "неправильную" сторону этого пивота с учетом настраиваемого буфера, тем самым отбирая ситуации с потенциалом возврата к среднему.
Панель обновляется текущими диагностическими значениями, а цвета сразу показывают, выполнен ли каждый критерий. В то же время горизонтальные линии скорости и пивота, а также вертикальная временная линия перемещаются так, чтобы визуальный контекст графика оставался синхронизирован с новым баром. Сигнал считается действительным только в том случае, если все четыре условия – всплеск скорости, всплеск ATR, согласованность с трендом и прохождение зонного фильтра – дают true.
Вспомогательная функция UpdateLabel()
Эта небольшая функция централизует обновление текста и цвета на панели. Сосредоточив форматирование в одном месте, мы обеспечиваем единый стиль и упрощаем глобальные визуальные правки.
void UpdateLabel(int idx,string txt,bool pass) { string name="Dash_"+dashNames[idx]; ObjectSetString (0,name,OBJPROP_TEXT ,txt); ObjectSetInteger(0,name,OBJPROP_COLOR, pass ? clrLime : clrRed); }
Вспомогательная функция ComputeVelocityPercentile()
Алгоритм преобразует сохраненный ценовой ряд в список знаковых разностей delta, сортирует этот список и выбирает нужный индекс в соответствии с процентилем, заданным пользователем. Выбор с крайнего конца упорядоченного массива позволяет методу учитывать знак движения (boom или crash) без дополнительной логики. Значения процентиля выше 100% сводятся к максимальному элементу, тем самым задавая порог на уровне "абсолютного экстремума в пределах окна".
double ComputeVelocityPercentile(double &hist[],double pct) { int n=ArraySize(hist); if(n<2) return 0; double d[]; ArrayResize(d,n-1); for(int i=1;i<n;i++) d[i-1]=hist[0]-hist[i]; ArraySort(d); // ascending int idx=(int)MathRound((pct/100.0)*(ArraySize(d)-1)); return d[ArraySize(d)-1-idx]; // mirror to get extreme with sign }
Вспомогательная функция SetHLine()
Изменяя свойства уже существующих объектов вместо пересоздания линий, этот метод позволяет избежать мерцания и графических задержек, сохраняя плавную работу даже на менее производительном оборудовании.
void SetHLine(string name,double price,color clr) { ObjectSetDouble (0,name,OBJPROP_PRICE, price); ObjectSetInteger(0,name,OBJPROP_COLOR, clr); ObjectSetInteger(0,name,OBJPROP_WIDTH, 1); }
Вспомогательная функция GenerateSignal()
Когда все фильтры сходятся, эта функция рисует цветную стрелку Wingdings со смещением от минимума бара (boom) или максимума бара (crash), записывает подробную строку в CSV-лог (временная метка, тип, delta, ATR, цена) и подает звуковой сигнал. Поскольку CTrade уже находится в области видимости, преобразовать эти визуальные маркеры в реальные ордера можно будет простым вызовом trade.Buy() или trade.Sell() в этом месте.
void GenerateSignal(bool isBoom,double price,double delta, double atr,ENUM_TIMEFRAMES tf) { int code = isBoom ? 233 : 234; double y = isBoom ? iLow(_Symbol,tf,0)-ArrowOffsetPips*_Point : iHigh(_Symbol,tf,0)+ArrowOffsetPips*_Point; color clr = isBoom ? BoomArrowColor : CrashArrowColor; string tag = (isBoom?"BOOM":"CRASH")+"_"+ TimeToString(TimeCurrent(),TIME_SECONDS); datetime t0 = iTime(_Symbol,tf,0); ObjectCreate(0,tag,OBJ_ARROW,0,t0,y); ObjectSetInteger(0,tag,OBJPROP_ARROWCODE,code); ObjectSetInteger(0,tag,OBJPROP_COLOR,clr); if(logHandle>=0) FileWrite(logHandle,TimeToString(TimeCurrent(),TIME_DATE|TIME_SECONDS), isBoom?"BOOM":"CRASH",DoubleToString(delta,2), DoubleToString(atr,_Digits),DoubleToString(price,_Digits)); Alert((isBoom?"BOOM":"CRASH")+" signal @"+ DoubleToString(price,_Digits)); }
Стратегический замысел и возможности расширения.
// Inside GenerateSignal(), after drawing the arrow: double lot = 0.02; // example risk sizing double sl = isBoom ? price - atr*2 : price + atr*2; double tp = pivot; // mean-reversion target if(AutoTrade) // user-controlled switch { if(isBoom) trade.Buy(lot,_Symbol,price,sl,tp,"Boom-auto"); else trade.Sell(lot,_Symbol,price,sl,tp,"Crash-auto"); }
В концептуальном плане советник ищет взрывные однобарные ускорения, возникающие на фоне свежего расширения волатильности, но при этом сохраняют потенциал возврата к предыдущему пивоту. Такое поведение характерно для индексов Boom/Crash, где резкие всплески часто быстро откатываются. В настоящее время код генерирует информационные оповещения; для интеграции автоматического исполнения потребуется добавить расчет размера позиции, стоп-лосс (например, по противоположной линии скорости) и логику тейк-профита (например, по пивоту или половине буфера). Наконец, линейный сдвиг массива внутри velHistory приемлем для стандартного окна в 96 баров, но при гораздо большей глубине истории его можно заменить кольцевым буфером.
Тестирование на исторических данных и результаты
Прежде чем запускать наш перехватчик в реальной торговле, давайте проведем комплексное тестирование на демо-счете, чтобы точно настроить его параметры:
1. Скомпилируйте и загрузите
После того как советник успешно скомпилируется в MetaEditor, переключитесь в MetaTrader.
2. Откройте тестер стратегий
На панели инструментов MetaTrader нажмите значок "Тестер стратегий". Выберите советник Boom & Crash Interceptor из списка экспертов.
3. Настройте тест
- Символ и таймфрейм: Выберите тот же инструмент и тот же MainTF, с которыми вы планируете работать в реальной торговле.
- Период: Выберите период, охватывающий разные рыночные условия (спокойный рынок, тренд и высокую волатильность).
- Входные параметры: Настройте VelocityHistoryBars, VelocityPctile, ATRMultiplier, TrendMAPeriod, ZoneBufferPoints и т.д., чтобы увидеть, как эти параметры влияют на частоту и точность сигналов.
- Исполнение: Используйте режим "Every Tick" для получения максимально точных результатов.
4. Запустите тест и оцените результаты
Нажмите "Старт". После завершения тестирования проанализируйте кривую капитала, список сигналов, а также все неудачные или запоздалые перехваты. Обратите внимание, где сигналы сгруппировались слишком плотно и где были пропущены реальные всплески.
5. Уточните настройки и повторите тест
Меняйте по одному-два параметра за раз: например, ужесточите процентиль скорости или увеличьте буфер пивота, а затем снова проведите тест. Повторяйте этот цикл до тех пор, пока результаты на демо не покажут чистые, повторяемые сигналы Boom/Crash при приемлемой просадке.
Когда вы убедитесь в эффективности советника по итогам нескольких прогонов на демо, можно будет запускать его на реальном счете при контролируемом риске.
Ниже я привожу результаты тестирования на исторических данных советника Boom & Crash Interceptor, и они показались мне особенно показательными.

Рис. 2. Тестирование на исторических данных Boom 900
В тесте Boom 900 наш советник зафиксировал в журнале все сигналы Boom и Crash, как и ожидалось. Линия пивота отображается синим цветом, а порог скорости – оранжевым, что дает наглядный визуальный ориентир. Вы также увидите зеленые стрелки вверх, отмечающие каждый BOOM, и красные стрелки вниз, отмечающие каждый CRASH. Ниже я также привожу статичное изображение, чтобы наглядно показать то, что вы видели в GIF.

Рис. 3. Результаты тестирования на исторических данных
Заключение
Мы разработали советник Boom & Crash Interceptor и тщательно протестировали его на исторических данных – результаты говорят сами за себя. Он точно выявляет экстремальные ценовые движения, отслеживая скорость, всплески ATR, согласованность с трендом и пробои пивот-зоны, а затем выводит только наиболее четкие сигналы – стрелки Boom (зеленые) и Crash (красные). В нашем демо-прогоне Boom 900 были зафиксированы все сигналы, линии пивота и скорости отображались синим и оранжевым цветами, а статический кадр полностью совпал с GIF.
Тем не менее, некоторым сигналам все еще может пойти на пользу дополнительная фильтрация. Воспринимайте этот советник как тактический радар, а не как автономного исполнителя ордеров, и всегда дополняйте его собственными проверками по времени суток, паттернам и фундаментальным факторам, прежде чем открывать сделку. А если вы хотите еще сильнее сократить число ложных срабатываний, переходите на более крупные таймфреймы (H1, H4 или Daily), чтобы сгладить рыночный шум.
При дисциплинированном тестировании, грамотной фильтрации и контролируемом запуске на реальном счете советник Boom & Crash Interceptor становится настоящим перехватчиком рыночных всплесков, позволяя реагировать раньше рынка, а не метаться вслед за каждым движением.
Перевод с английского произведен MetaQuotes Ltd.
Оригинальная статья: https://www.mql5.com/en/articles/18616
Предупреждение: все права на данные материалы принадлежат MetaQuotes Ltd. Полная или частичная перепечатка запрещена.
Данная статья написана пользователем сайта и отражает его личную точку зрения. Компания MetaQuotes Ltd не несет ответственности за достоверность представленной информации, а также за возможные последствия использования описанных решений, стратегий или рекомендаций.
Создание самооптимизирующихся советников на MQL5 (Часть 14): Преобразования данных как параметры настройки регулятора с обратной связью
Нейронные сети на практике: Практика ведет к совершенству
Разработка инструментария для анализа Price Action (Часть 30): Советник CCI Zero Line
Python + MetaTrader 5: быстрый исследовательский контур для данных, признаков и прототипов
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Вы принимаете политику сайта и условия использования
Привет,
Могу ли я скачать это, пожалуйста, не могу найти никаких ссылок?
С уважением,
Гарри
Имеется проблема с детектором скорости.
ArraySort(d);Работает в направлении покупки хорошо,
но для отрицательного движения сортировка плохая.
Вам нужно сделать это отдельно или изменить формулу индекса (при продаже отрицательные значения сортируются!!!).
if(delta>0) { for(int i = 1; i < VelocityHistoryBars; i++) d[i - 1] = velHistory[0] - velHistory[i]; ArraySort(d); } if(delta<0) { for(int i = 1; i < VelocityHistoryBars; i++) d[i - 1] = velHistory[i] - velHistory[0]; ArraySort(d); }
int idx= (int)MathRound((VelocityPctile / 100.0) * (ArraySize(d) - 1)); double velTh = d[ArraySize(d) - 1 - idx]; bool okVel = MathAbs(delta) > velTh;
У меня есть несколько вариантов выравнивания пивотов.
Не знаю, что лучше.
(от цены, которая является пивотом вверх, мы ожидаем движения вверх .... )
bool okZone = false; if((delta > 0 ) && (priceNow > pivot)) okZone = true; if((delta < 0 ) && (priceNow < pivot)) okZone = true;bool okZone = false; if((delta > 0 ) && (priceNow > pivot) && (priceNow < ( pivot + ZONE_Points * _Point))) okZone = true; if((delta < 0 ) && (priceNow < pivot) && (priceNow > ( pivot - ZONE_Points * _Point))) okZone = true;Хорошая оценка баров по направлению для детектора скорости:
Мы можем отфильтровать парцентрически зеленые/красные бары.
(Отрицательное направление было переведено в положительное значение)
0.8 = 80% баров было на правильном пути.
double goodBars = 1; for(int i=ArraySize(d) - 1; i>=0; i--) if(d[i] < 0) goodBars=1 - (i+1.0)/ArraySize(d);