Рыночные секреты Ларри Уильямса (Часть 10): Автоматизация паттернов разворота Smash Day
Введение
Рынки движутся не только по логике — самые резкие движения вызывают эмоции. Страх ускоряет продажи, жадность заставляет входить в покупку на поздней стадии движения. Ларри Уильямс десятилетиями изучал эти эмоциональные экстремумы и показал, что краткосрочные возможности часто появляются сразу после чрезмерной реакции толпы.
Наглядный пример — разворот Smash Day: цена выглядит так, будто уверенно совершает пробой, но затем этот пробой быстро оказывается ложным. Этот провал запирает покупателей или продавцов, вошедших слишком поздно, а их вынужденные выходы часто подпитывают разворот.
Уильямс также предупреждает, что это не сигнал «нажми кнопку» — контекст имеет значение. Проблема в том, что большинство трейдеров видят паттерн, но не знают, как он на самом деле работает на разных рынках, таймфреймах и настройках риска.
Эта статья призвана восполнить этот пробел. Мы создадим советник, который максимально точно реализует правила Ларри Уильямса и исполняет их без эмоций. Цель — не слепая автоматизация, а проверяемость идеи, чтобы можно было измерить, что работает, что не работает и при каких условиях.
Понимание разворотных паттернов Smash Day
Прежде чем писать хотя бы одну строку кода, нужно ясно понять, что на самом деле представляет собой Smash Day. Этот паттерн не про изящные рисунки на графике и не про интерпретацию задним числом. Он про выявление моментов, когда рынок резко движется в одном направлении, а затем не получает продолжения, выявляя эмоциональный дисбаланс. Ларри Уильямс построил эту идею вокруг наблюдаемого ценового поведения, а не мнений.
Что такое Smash Day?
В системе Ларри Уильямса Smash Day — это торговая сессия, в которой цена будто бы решительно пробивает недавнюю ценовую структуру, вызывая сильную эмоциональную вовлеченность публики. Такой пробой убеждает участников рынка в том, что начался новый тренд. Срабатывают стопы, исполняются пробойные ордера, а уверенность достигает пика или рушится за один день.
Smash day определяется тем, как цена закрывается относительно предыдущих баров. При движении вниз она закрывается ниже прежних минимумов. При движении вверх — выше прежних максимумов. Особенным этот день делает не направление движения, а эмоциональная реакция, которую он вызывает. Трейдеры действуют так, будто рынок раскрыл свое истинное намерение.
Такие дни отражают эмоциональные экстремумы, потому что заставляют людей принимать решения. Страх вынуждает продавцов выходить или агрессивно открывать короткие позиции. Жадность втягивает покупателей во входы на поздней стадии пробоя. Рынок создает иллюзию определенности, и именно эта иллюзия создает возможность.
Именно в этом паттерны Smash Day отличаются от классических пробойных моделей. Традиционные пробои предполагают продолжение движения. Smash day ставит его под вопрос. Ларри Уильямс заметил, что многие пробои, выглядящие сильными, быстро проваливаются. Когда такой провал происходит сразу, эмоциональные трейдеры, действовавшие на пробое, внезапно оказываются в ловушке. Эта ловушка и становится основой разворота.
Логика разворота Smash Day для покупки
Разворотный паттерн Smash Day для покупки начинается с шока вниз.

Цена закрывается ниже минимумов одного или нескольких предыдущих баров, показывая, что давление продавцов наконец-то подавило рынок. Для большинства трейдеров это выглядит убедительно по-медвежьи. Срабатывают стопы, а короткие позиции добавляются на поздней стадии движения.
Психология проста. Трейдеры ждут продолжения. Когда цены пробивают недавние минимумы, они считают дальнейшее снижение неизбежным. Но они редко ожидают немедленного провала этого движения.
Логика разворота проявляется тогда, когда рынок отказывается продолжать движение. Если цена возвращается выше максимума Smash Day, это сигнализирует, что продавцы потеряли контроль. Те, кто вошел в шорт слишком поздно, теперь оказываются под давлением. Начинается закрытие коротких позиций, а новые покупатели входят увереннее. Результатом часто становится резкое движение в противоположном направлении.
В этом советнике паттерн определяется объективно. Свеча Smash Day должна закрыться ниже минимумов заданного пользователем числа предыдущих баров. Свеча не должна быть внешним баром, поскольку это сделало бы движение скорее направленным, чем хаотичным. После обнаружения паттерна максимум Smash Day становится критическим опорным уровнем. Длинная позиция открывается только в том случае, если цена пробивает этот уровень на следующем баре — сразу или после подтверждения, в зависимости от выбранного режима входа.
Логика разворота Smash Day для продажи
Разворот для продажи следует той же логике, но в противоположном эмоциональном направлении.

Цена закрывается выше недавних максимумов баров, вызывая у покупателей воодушевление и уверенность. Трейдеры, торгующие пробои, входят агрессивно, убежденные, что импульс продолжится.
Такой восходящий Smash Day наглядно показывает действие жадности. Трейдеры боятся упустить движение и входят в покупку на поздней стадии движения, предполагая, что сила сохранится. Однако сильные на вид восходящие движения часто наиболее уязвимы к провалу.
Разворот подтверждается, когда цена не может удержать пробой. Если рынок опускается ниже минимума Smash Day, это сигнализирует, что покупатели оказались в ловушке. Длинные позиции, открытые на поздней стадии движения, уже находятся в убытке. По мере их закрытия давление продавцов растет, часто ускоряя движение вниз.
Советник определяет этот паттерн с той же объективностью. Свеча Smash Day должна закрыться выше максимумов заданного числа предыдущих баров и не должна быть внешним баром. Минимум этой свечи становится ключевым уровнем. Короткая позиция открывается только в том случае, если цена пробивает этот уровень вниз на следующем баре, подтверждая, что провал реален, а не предполагаем.
Построив развороты для покупки и продажи на одних и тех же принципах, система остается симметричной, измеримой и верной исходному замыслу Ларри Уильямса.
Как устроен советник Smash Day и почему
Прежде чем перейти к результатам или эффективности, важно понять, как устроен этот советник и почему в нем закреплены определенные правила. Цель здесь не в том, чтобы создать сложную торговую машину, а в том, чтобы перевести идеи Ларри Уильямса о Smash Day в чистую, проверяемую архитектуру, учитывающую и поведение рынка, и практические ограничения автоматизации.
Этот советник прежде всего задуман как инструмент для исследования и проверки. Каждое правило существует для того, чтобы убрать неоднозначность, снизить риск подгонки и гарантировать, что мы тестируем именно то, что описывает паттерн, — ничего больше и ничего меньше.
Одно семейство паттернов, одна система за раз
Мы сосредоточимся на двух тесно связанных паттернах: разворотах Smash Day для покупки и разворотах Smash Day для продажи. Хотя они являются зеркальными отражениями друг друга, они оцениваются независимо и могут включаться или отключаться через входные параметры.
В любой момент советник можно настроить на торговлю только разворотами для покупки, только разворотами для продажи или обоими типами. Независимо от выбранного режима система всегда допускает только одну активную позицию. Это решение намеренное. Развороты Smash Day — это отдельные события, а не непрерывные сигналы. Разрешение нескольких позиций размыло бы причинно-следственную связь и усложнило бы интерпретацию результатов. При одной позиции за раз каждую сделку можно напрямую связать с конкретным событием Smash Day.
Четкие и объективные правила паттерна
Развороты Smash Day для покупки и продажи определяются строгими, измеримыми правилами. Для разворота Smash Day на покупку последний закрытый бар должен закрыться ниже минимумов заданного пользователем числа предыдущих баров. Это число настраивается, чтобы можно было изучать, как глубина пробоя вниз влияет на результаты. Smash-бар также не должен быть внешним баром. Это исключает свечи, расширяющиеся в обе стороны и часто отражающие шум, а не направленное намерение. После обнаружения корректного Smash Day рынок должен доказать провал. Длинная сделка рассматривается только в том случае, если цена возвращается выше максимума Smash Day. Это подтверждает, что продавцы потеряли контроль и разворот уже начался.
Та же логика применяется к разворотам Smash Day для продажи, но в противоположном направлении. Smash-бар должен закрыться выше максимумов предыдущих баров, не должен быть внешним баром, а затем цена должна опуститься ниже минимума этого Smash Day, чтобы подтвердить провал. Эти правила намеренно строгие. Если паттерн нельзя описать четко, его нельзя надежно протестировать.
Подтверждение входа и контроль исполнения
Не все трейдеры согласны в том, какой объем подтверждения достаточен. Одни предпочитают немедленное исполнение, другие хотят дождаться закрытия полного бара для подтверждения пробоя. Чтобы учесть это различие, советник поддерживает два режима входа.
Первый режим входит сразу, когда цена пересекает уровень Smash Day. Второй ждет, пока текущий бар закроется за этим уровнем. Оба подхода допустимы, а такая гибкость позволяет изучать, как момент подтверждения влияет на результаты, не меняя базовую логику паттерна.
Управление риском, соответствующее паттерну
Контроль риска остается простым и согласуется с исходным замыслом Ларри Уильямса. Для разворотов на покупку стоп-лосс размещается на минимуме Smash Day. Для разворотов на продажу — на максимуме Smash Day. Эти уровни отмечают точку, в которой паттерн явно становится недействительным.
Тейк-профит рассчитывается по соотношению риска к прибыли, которое задает пользователь. Это делает выходы объективными и масштабируемыми для разных рынков и таймфреймов.
Размер позиции также гибко настраивается. Для простоты можно использовать фиксированный лот или рассчитывать размер позиции автоматически как процент от баланса счета. При автоматическом расчете каждая сделка рискует постоянной долей капитала, что позволяет результатам отражать эффективность стратегии, а не влияние размера позиции.
Такая структура позволяет изучать развороты Smash Day такими, какие они есть, а не такими, какими нам хотелось бы их видеть. Она также создает чистую основу для будущих вариаций, фильтров и дискреционных надстроек без нарушения целостности исходного паттерна.
Создание советника для разворотов Smash Day
Этот раздел отмечает переход от идей и правил к реальной реализации. Мы больше не обсуждаем, что такое развороты Smash Day и почему они работают. Теперь мы переводим эту логику в советник, который может исполнять, тестировать и проверять эти идеи контролируемым и воспроизводимым образом.
Прежде чем начинать писать логику, важно правильно задать ожидания. Это практическая пошаговая реализация. Концепции лучше всего понимаются тогда, когда их реализуют, наблюдают и ставят под вопрос. Поэтому мы рекомендуем писать код параллельно с этим руководством, а не просто читать его пассивно.
Для поддержки этого процесса к статье приложен полный рабочий исходный файл lwSmashDayReversalExpert.mq5. Если держать его открытым в отдельной вкладке во время работы с материалом, можно сверять идеи, проверять предположения и понимать, как каждый элемент вписывается в более крупную систему.
Предварительные требования для работы по ходу руководства
Чтобы получить от этого раздела максимум пользы, предполагается несколько базовых навыков. Во-первых, требуется знакомство с языком MQL5. Основные понятия, такие как переменные, функции, циклы, условная логика, перечисления, структуры и стандартные библиотеки, уже должны быть понятны. Если эта база еще формируется, официальный справочник MQL5 станет отличной отправной точкой.
Во-вторых, необходим предыдущий опыт работы с платформой MetaTrader 5. Сюда входят навигация по графикам, подключение советников, открытие тестера стратегий и работа с базовыми окнами платформы, такими как Навигатор.
В-третьих, ожидается уверенная работа с MetaEditor. Мы будем создавать исходные файлы, компилировать код и изучать ошибки при их появлении. Это необходимые навыки для любой серьезной разработки на MQL5. Когда эти предварительные условия выполнены, можно начинать строить советник с нуля.
Закладка основы с помощью шаблонного кода
Каждый надежный советник начинается с чистой, хорошо структурированной основы.
//+------------------------------------------------------------------+ //| lwSmashDayReversalExpert.mq5 | //| Copyright 2026, MetaQuotes Ltd. Developer is Chacha Ian | //| https://www.mql5.com/en/users/chachaian | //+------------------------------------------------------------------+ #property copyright "Copyright 2026, MetaQuotes Ltd. Developer is Chacha Ian" #property link "https://www.mql5.com/en/users/chachaian" #property version "1.00" //+------------------------------------------------------------------+ //| Standard Libraries | //+------------------------------------------------------------------+ #include <Trade\Trade.mqh> //+------------------------------------------------------------------+ //| Custom Enumerations | //+------------------------------------------------------------------+ enum ENUM_SMASH_ENTRY_MODE{ ENTRY_ON_LEVEL_CROSS, ENTRY_ON_BAR_CLOSE }; enum ENUM_SMASH_TRADE_MODE{ SMASH_TRADE_BUY_ONLY, SMASH_TRADE_SELL_ONLY, SMASH_TRADE_BOTH }; enum ENUM_LOT_SIZE_INPUT_MODE { MODE_MANUAL, MODE_AUTO }; //+------------------------------------------------------------------+ //| User input variables | //+------------------------------------------------------------------+ input group "Information" input ulong magicNumber = 254700680002; input ENUM_TIMEFRAMES timeframe = PERIOD_CURRENT; input group "Smash Day Pattern Rules" input int smashBuyLookbackBars = 1; input int smashSellLookbackBars = 1; input group "Smash Day Entry Settings" input ENUM_SMASH_ENTRY_MODE smashEntryMode = ENTRY_ON_LEVEL_CROSS; input ENUM_SMASH_TRADE_MODE smashTradeMode = SMASH_TRADE_BOTH; input group "Trade and Risk Management" input ENUM_LOT_SIZE_INPUT_MODE lotSizeMode = MODE_AUTO; input double riskPerTradePercent = 1.0; input double positionSize = 0.1; input double riskRewardRatio = 3.0; //+------------------------------------------------------------------+ //| Global Variables | //+------------------------------------------------------------------+ //--- Create a CTrade object to handle trading operations CTrade Trade; //--- To hep track current market prices for Buying (Ask) and Selling (Bid) double askPrice; double bidPrice; //--- To store current time datetime currentTime; struct MqlSmashDayPatternState{ //--- Pattern detection flags bool hasBuySmashSetup; bool hasSellSmashSetup; //--- Reference breakout levels from smash bar double buyBreakoutLevel; double sellBreakoutLevel; //--- Pattern bar reference data datetime smashBarTime; //--- Entry status tracking bool entryPending; //--- Stop-Loss levels double buyStopLoss; double sellStopLoss; }; MqlSmashDayPatternState smashState; //--- To store minutes data double closePriceMinutesData []; //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit(){ //--- Assign a unique magic number to identify trades opened by this EA Trade.SetExpertMagicNumber(magicNumber); //--- Reset ZeroMemory(smashState); //--- Treat the following arrays as timeseries (index 0 becomes the most recent bar) ArraySetAsSeries(closePriceMinutesData, true); return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Expert deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason){ //--- Notify why the program stopped running Print("Program terminated! Reason code: ", reason); } //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick(){ //--- Retrieve current market prices for trade execution askPrice = SymbolInfoDouble (_Symbol, SYMBOL_ASK); bidPrice = SymbolInfoDouble (_Symbol, SYMBOL_BID); currentTime = TimeCurrent(); //--- Get some minutes data if(CopyClose(_Symbol, PERIOD_M1, 0, 7, closePriceMinutesData) == -1){ Print("Error while copying minutes datas ", GetLastError()); return; } } //--- UTILITY FUNCTIONS //+------------------------------------------------------------------+
Приведенный ниже код закладывает эту основу. На этом этапе торговой логики еще нет. Вместо этого мы определяем идентификацию, конфигурацию, структуры данных и среду, в которой позднее будет работать логика. Такой подход удерживает сложность под контролем и гарантирует, что каждый слой логики имеет ясную цель.
Заголовок файла и свойства
//+------------------------------------------------------------------+ //| lwSmashDayReversalExpert.mq5 | //| Copyright 2026, MetaQuotes Ltd. Developer is Chacha Ian | //| https://www.mql5.com/en/users/chachaian | //+------------------------------------------------------------------+ #property copyright "Copyright 2026, MetaQuotes Ltd. Developer is Chacha Ian" #property link "https://www.mql5.com/en/users/chachaian" #property version "1.00"
Начальный раздел определяет идентификатор исходного файла и предоставляет метаданные, отображаемые в MetaTrader. Сюда входят имя файла, сведения об авторе, номер версии и справочная ссылка. Хотя эта информация не влияет на исполнение, она важна для долгосрочного сопровождения, отслеживания версий и распространения.
Подключение стандартных библиотек
//+------------------------------------------------------------------+ //| Standard Libraries | //+------------------------------------------------------------------+ #include <Trade\Trade.mqh>
Мы подключаем библиотеку Trade, чтобы получить доступ к классу CTrade. Этот класс предоставляет чистый и надежный интерфейс для открытия, управления и закрытия позиций. Опираясь на стандартную библиотеку, а не на собственный код обработки ордеров, мы снижаем риск ошибок и улучшаем читаемость.
Определение пользовательских перечислений
//+------------------------------------------------------------------+ //| Custom Enumerations | //+------------------------------------------------------------------+ enum ENUM_SMASH_ENTRY_MODE{ ENTRY_ON_LEVEL_CROSS, ENTRY_ON_BAR_CLOSE }; enum ENUM_SMASH_TRADE_MODE{ SMASH_TRADE_BUY_ONLY, SMASH_TRADE_SELL_ONLY, SMASH_TRADE_BOTH }; enum ENUM_LOT_SIZE_INPUT_MODE { MODE_MANUAL, MODE_AUTO };
Перечисления используются для преобразования абстрактных решений в явные и контролируемые варианты выбора. Мы определяем три ключевых перечисления.
Первое управляет тем, как срабатывают входы. Сделка может открываться сразу, когда цена пересекает уровень пробоя, или только после того, как бар полностью закроется и подтвердит движение.
Второе определяет, какие паттерны Smash Day разрешены для торговли: только покупки, только продажи или оба варианта. Это важно для исследования и тестирования, потому что позволяет отдельно анализировать поведение стратегии в лонг и в шорт.
Третье управляет способом расчета размера позиции. Лот может быть фиксированным или рассчитываться автоматически на основе риска. Эти перечисления формируют основу гибкости советника, не добавляя сложности в логику исполнения.
Входные параметры пользователя
//+------------------------------------------------------------------+ //| User input variables | //+------------------------------------------------------------------+ input group "Information" input ulong magicNumber = 254700680002; input ENUM_TIMEFRAMES timeframe = PERIOD_CURRENT; input group "Smash Day Pattern Rules" input int smashBuyLookbackBars = 1; input int smashSellLookbackBars = 1; input group "Smash Day Entry Settings" input ENUM_SMASH_ENTRY_MODE smashEntryMode = ENTRY_ON_LEVEL_CROSS; input ENUM_SMASH_TRADE_MODE smashTradeMode = SMASH_TRADE_BOTH; input group "Trade and Risk Management" input ENUM_LOT_SIZE_INPUT_MODE lotSizeMode = MODE_AUTO; input double riskPerTradePercent = 1.0; input double positionSize = 0.1; input double riskRewardRatio = 3.0;
Входные параметры логически сгруппированы, чтобы конфигурация была интуитивно понятной. Группа Information определяет magic number и таймфрейм. Magic number гарантирует, что этот советник управляет только собственными позициями, а таймфрейм определяет, где оцениваются паттерны Smash Day.
Группа Smash Day Pattern Rules определяет, насколько строгой должна быть квалификация паттерна. Параметры lookback управляют тем, сколько предыдущих баров должно быть пробито, чтобы Smash Day считался действительным. Это напрямую влияет на частоту и избирательность паттерна.
Группа Smash Day Entry Settings определяет поведение исполнения и направление торговли. Эти входные параметры задают, насколько агрессивной или консервативной должна быть логика входа и разрешены ли длинные, короткие или оба типа сделок.
Группа Trade and Risk Management определяет размер позиции и ожидания по прибыли. Риск может быть фиксированным или динамическим, а уровни тейк-профита рассчитываются из настраиваемого соотношения риска к прибыли.
Глобальные торговые объекты и состояние рынка
//+------------------------------------------------------------------+ //| Global Variables | //+------------------------------------------------------------------+ //--- Create a CTrade object to handle trading operations CTrade Trade; //--- To hep track current market prices for Buying (Ask) and Selling (Bid) double askPrice; double bidPrice; //--- To store current time datetime currentTime;
Мы создаем один экземпляр объекта CTrade. Позднее этот объект будет отвечать за все торговое исполнение. Также мы определяем переменные для отслеживания текущих цен Bid и Ask, а также серверного времени. Эти значения обновляются на каждом тике и служат потоком актуальных данных для логики исполнения.
Структурирование состояния паттерна Smash Day
Одно из важнейших проектных решений в этом советнике — использование отдельной структуры для отслеживания состояния паттерна Smash Day.
Структура MqlSmashDayPatternState выполняет роль памяти.
struct MqlSmashDayPatternState{ //--- Pattern detection flags bool hasBuySmashSetup; bool hasSellSmashSetup; //--- Reference breakout levels from smash bar double buyBreakoutLevel; double sellBreakoutLevel; //--- Pattern bar reference data datetime smashBarTime; //--- Entry status tracking bool entryPending; //--- Stop-Loss levels double buyStopLoss; double sellStopLoss; }; MqlSmashDayPatternState smashState;
Она позволяет один раз обнаружить паттерн, а затем отслеживать поведение цены без повторной переоценки исторических баров.
Внутри этой структуры мы отслеживаем, существует ли корректный сетап Smash Day для покупки или продажи, уровни пробоя, полученные из бара Smash Day, время бара Smash Day и наличие ожидающего входа.
Мы также храним уровни стоп-лосса, напрямую полученные из бара Smash Day. Это удерживает всю связанную с паттерном информацию в одном месте и предотвращает разрастание глобальных переменных. Позднее эта структура станет мостом между обнаружением паттерна и торговым исполнением.
Обработка ценовых данных для внутрибарового обнаружения
Чтобы надежно обнаруживать пересечения уровней, нужен доступ к недавним минутным ценам закрытия.
//--- To store minutes data double closePriceMinutesData [];
Мы выделяем массив для хранения минутных данных и явно задаем его как временной ряд. Это гарантирует, что индекс ноль всегда относится к самому свежему значению.
Позднее эти данные будут использоваться для обнаружения движения цены через уровни пробоя в реальном времени, когда режим входа настроен на немедленное исполнение.
Инициализация и очистка
//+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit(){ //--- Assign a unique magic number to identify trades opened by this EA Trade.SetExpertMagicNumber(magicNumber); //--- Reset ZeroMemory(smashState); //--- Treat the following arrays as timeseries (index 0 becomes the most recent bar) ArraySetAsSeries(closePriceMinutesData, true); return(INIT_SUCCEEDED); }
Функция OnInit назначает magic number торговому объекту, очищает структуру состояния Smash Day и подготавливает массив минутных данных. Это гарантирует, что при каждом подключении советника он стартует из чистого, предсказуемого состояния.
Функция OnDeinit сообщает причину завершения работы. Это полезно при тестировании и отладке.
//+------------------------------------------------------------------+ //| Expert deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason){ //--- Notify why the program stopped running Print("Program terminated! Reason code: ", reason); }
Создание каркаса OnTick
Функция OnTick пока выполняет только базовые задачи.
//+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick(){ //--- Retrieve current market prices for trade execution askPrice = SymbolInfoDouble (_Symbol, SYMBOL_ASK); bidPrice = SymbolInfoDouble (_Symbol, SYMBOL_BID); currentTime = TimeCurrent(); //--- Get some minutes data if(CopyClose(_Symbol, PERIOD_M1, 0, 7, closePriceMinutesData) == -1){ Print("Error while copying minutes datas ", GetLastError()); return; } }
Он обновляет цены Bid и Ask, фиксирует текущее время и обновляет минутные цены закрытия. Торговые решения пока не принимаются. Это сделано намеренно. На этом этапе мы строим каркас советника. Обнаружение паттернов, управление состоянием и торговое исполнение будут добавлены поверх этой основы в следующих разделах. Сейчас у нас есть стабильная и расширяемая база. Советник знает, что он собой представляет, как должен вести себя и как хранить информацию об обнаруженных паттернах Smash Day.
Когда эта основа готова, можно переходить к реализации логики, которая обнаруживает развороты Smash Day и превращает их в торговые сетапы, пригодные к исполнению.
Обнаружение новых торговых дней и отслеживание состояния паттерна
Логика Smash Day оценивается один раз на каждом завершенном дневном баре. Поэтому первый строительный блок, который мы добавляем, — способ определить открытие нового бара на выбранном таймфрейме. Это делается с помощью небольшой вспомогательной функции. Добавьте следующую функцию в раздел utility-функций исходного файла.
//--- UTILITY FUNCTIONS //+------------------------------------------------------------------+ //| Function to check if there's a new bar on a given chart timeframe| //+------------------------------------------------------------------+ bool IsNewBar(string symbol, ENUM_TIMEFRAMES tf, datetime &lastTm){ datetime currentTm = iTime(symbol, tf, 0); if(currentTm != lastTm){ lastTm = currentTm; return true; } return false; }
Эта функция сравнивает время открытия текущего бара с временем последнего записанного бара. Если время изменилось, сформировался новый бар.
Третий параметр передается по ссылке. Это позволяет функции обновить сохраненное время сразу после обнаружения нового бара. Другими словами, функция не только проверяет наличие нового бара, но и запоминает, что уже отреагировала на него. Для поддержки этого поведения добавьте глобальную переменную в раздел глобальных переменных.
//--- To help track new bar open datetime lastBarOpenTime;
Эта переменная хранит метку времени самого последнего бара, который уже был обработан. Внутри функции инициализации установите ее значение равным нулю, чтобы самый первый тик после подключения советника воспринимался как событие нового бара.
//+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit(){ //--- Initialize global variables lastBarOpenTime = 0; return(INIT_SUCCEEDED); }
С этого момента все ежедневные решения будут приниматься только один раз на новом баре. Это предотвращает повторные сигналы и сохраняет логику чистой и предсказуемой.
Отбрасывание внешних баров
Одно из проектных правил разворотов Smash Day состоит в том, что бар Smash Day не должен поглощать весь предыдущий бар. Такой тип бара отражает другое поведение рынка и должен фильтроваться. Добавьте следующую вспомогательную функцию в раздел utility.
//+-----------------------------------------------------------------------------+ //| Checks whether the bar at the given index fully engulfs the prior bar range | //+-----------------------------------------------------------------------------+ bool IsOutsideBar(string symbol, ENUM_TIMEFRAMES tf, int index){ double high0 = iHigh(symbol, tf, index); double low0 = iLow (symbol, tf, index); double high1 = iHigh(symbol, tf, index + 1); double low1 = iLow (symbol, tf, index + 1); return (high0 > high1 && low0 < low1); }
Эта функция сравнивает диапазон текущего бара с диапазоном предыдущего. Если максимум выше, а минимум ниже соответственно, бар является внешним и отклоняется при проверке паттерна. Такой простой фильтр защищает стратегию от реакции на экстремально волатильные бары, которые не соответствуют чистой структуре Smash Day, которую мы ищем.
Обнаружение разворотов Smash Day для покупки
Теперь мы определяем первый настоящий детектор паттерна. Разместите следующую функцию ниже функции внешнего бара.
//+-----------------------------------------------------------------------------------+ //| Detects a Smash Day Buy Reversal where the close breaks below multiple prior lows | //+-----------------------------------------------------------------------------------+ bool IsSmashDayBuyReversal(string symbol, ENUM_TIMEFRAMES tf, int index, int lookbackBars) { // Bar must not be an outside bar if(IsOutsideBar(symbol, tf, index)) return false; double close1 = iClose(symbol, tf, index); // Validate close breaks below N prior lows for(int i = 2; i <= lookbackBars + 1; i++) { double priorLow = iLow(symbol, tf, index + i); if(close1 >= priorLow) return false; } return true; }
Эта логика проверяет три вещи. Во-первых, бар не должен быть внешним. Во-вторых, мы берем закрытие бара Smash Day. В-третьих, сравниваем это закрытие с минимумами нескольких более ранних баров. Если закрытие ниже всех этих предыдущих минимумов, рынок сильно продавили вниз, и он закрылся ниже недавней поддержки. Именно такую эмоциональную распродажу мы хотим обнаружить. Входной параметр управляет числом проверяемых предыдущих баров. Благодаря этому паттерн становится более или менее строгим в зависимости от предпочтений пользователя.
Обнаружение разворотов Smash Day для продажи
Сторона продаж является зеркальным отражением логики покупки. Добавьте следующую функцию сразу после детектора покупки.
//+-------------------------------------------------------------------------------------+ //| Detects a Smash Day Sell Reversal where the close breaks above multiple prior highs | //+-------------------------------------------------------------------------------------+ bool IsSmashDaySellReversal(string symbol, ENUM_TIMEFRAMES tf, int index, int lookbackBars) { // Bar must not be an outside bar if(IsOutsideBar(symbol, tf, index)) return false; double close1 = iClose(symbol, tf, index); // Validate close breaks above N prior highs for(int i = 2; i <= lookbackBars + 1; i++) { double priorHigh = iHigh(symbol, tf, index + i); if(close1 <= priorHigh) return false; } return true; }
Здесь мы проверяем, закрывается ли бар Smash Day выше максимумов нескольких предыдущих баров. Это отражает эмоциональный всплеск покупок, который часто запирает покупателей, вошедших слишком поздно, когда движение не получает продолжения. Вместе эти две функции дают объективное обнаружение паники вниз и эйфории вверх.
Сброс состояния паттерна на каждом новом дне
Каждый новый дневной бар должен начинаться с чистого внутреннего состояния. Старые уровни пробоя не должны переходить на следующий день. Добавьте эту функцию в раздел utility.
//+--------------------------------------------------------------------+ //| Resets all Smash Day detection flags and breakout reference levels | //+--------------------------------------------------------------------+ void ResetSmashDaySetupState(){ smashState.hasBuySmashSetup = false; smashState.hasSellSmashSetup = false; smashState.buyBreakoutLevel = iHigh(_Symbol, timeframe, 1); smashState.sellBreakoutLevel = iLow(_Symbol, timeframe, 1); smashState.smashBarTime = iTime(_Symbol, timeframe, 1); }
Эта функция очищает флаги обнаружения и обновляет опорные уровни, используя только что завершенный бар. С этого момента каждый новый день начинается заново, и обнаружение паттерна выполняется снова. Это важно, потому что сетапы Smash Day действительны только в течение одного дня.
Обнаружение пробоев в реальном времени
Советник поддерживает два варианта входа. В первом вход выполняется сразу, когда цена пробивает уровень. Во втором советник ждет закрытия бара за этим уровнем. Для немедленного входа нужно обнаруживать пересечения уровней с помощью минутных данных. Добавьте следующие вспомогательные функции.
//+------------------------------------------------------------------+ //| To detect a crossover at a given price level | //+------------------------------------------------------------------+ bool IsCrossOver(const double price, const double &closePriceMinsData[]){ if(closePriceMinsData[1] <= price && closePriceMinsData[0] > price){ return true; } return false; } //+------------------------------------------------------------------+ //| To detect a crossunder at a given price level | //+------------------------------------------------------------------+ bool IsCrossUnder(const double price, const double &closePriceMinsData[]){ if(closePriceMinsData[1] >= price && closePriceMinsData[0] < price){ return true; } return false; }
Они сравнивают две последние минутные цены закрытия. Если цена была ниже уровня и теперь выше него, у нас есть пробой вверх. Если цена была выше уровня и теперь ниже него, у нас есть пробой вниз. Это дает быстрое и точное внутридневное подтверждение.
Правило одной позиции за раз
Перед открытием любой сделки нужно подтвердить, что активной позиции от этого советника еще нет. Добавьте эти две функции.
//+------------------------------------------------------------------+ //| To verify whether this EA currently has an active buy position. | | //+------------------------------------------------------------------+ bool IsThereAnActiveBuyPosition(ulong magic){ for(int i = PositionsTotal() - 1; i >= 0; i--){ ulong ticket = PositionGetTicket(i); if(ticket == 0){ Print("Error while fetching position ticket ", _LastError); continue; }else{ if(PositionGetInteger(POSITION_MAGIC) == magic && PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY){ return true; } } } return false; } //+------------------------------------------------------------------+ //| To verify whether this EA currently has an active sell position. | | //+------------------------------------------------------------------+ bool IsThereAnActiveSellPosition(ulong magic){ for(int i = PositionsTotal() - 1; i >= 0; i--){ ulong ticket = PositionGetTicket(i); if(ticket == 0){ Print("Error while fetching position ticket ", _LastError); continue; }else{ if(PositionGetInteger(POSITION_MAGIC) == magic && PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL){ return true; } } } return false; }
Эти функции просматривают все открытые позиции и возвращают true, если находят соответствующую сделку. Позднее каждое решение о входе вызывает эти проверки, чтобы обеспечить правило одной сделки.
Автоматический расчет размера позиции на основе риска счета
Когда включен автоматический расчет лота, торговый объем рассчитывается так, чтобы в каждой сделке под риском находился только фиксированный процент баланса счета. Добавьте следующую вспомогательную функцию в раздел utility:
//+------------------------------------------------------------------+ //| Calculates position size based on a fixed percentage risk of the account balance | //+------------------------------------------------------------------+ double CalculatePositionSizeByRisk(double stopDistance){ double amountAtRisk = (riskPerTradePercent / 100.0) * AccountInfoDouble(ACCOUNT_BALANCE); double contractSize = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_CONTRACT_SIZE); double volume = amountAtRisk / (contractSize * stopDistance); return NormalizeDouble(volume, 2); }
Эта функция преобразует выбранный процент риска в размер лота на основе расстояния до стоп-лосса. Более широкие стопы дают меньший размер лота, а более тесные — больший, сохраняя постоянной сумму денег под риском в каждой сделке.
Проекция уровней тейк-профита
Тейк-профит основан на соотношении риска к прибыли. Добавьте эти две функции.
//+------------------------------------------------------------------+ //| Computes the bullish take profit level based on entry price, stop loss, and risk to reward ratio | //+------------------------------------------------------------------+ double GetBuyTakeProfit(double entryPrice, double stopLoss){ double riskDistance = entryPrice - stopLoss; double rewardDistance = riskDistance * riskRewardRatio; rewardDistance = MathAbs(rewardDistance); return NormalizeDouble((entryPrice + rewardDistance), Digits()); } //+------------------------------------------------------------------+ //| Computes the bearish take profit level based on entry price, stop loss, and risk to reward ratio | //+------------------------------------------------------------------+ double GetSellTakeProfit(double entryPrice, double stopLoss){ double riskDistance = stopLoss - entryPrice; double rewardDistance = riskDistance * riskRewardRatio; rewardDistance = MathAbs(rewardDistance); return NormalizeDouble((entryPrice - rewardDistance), Digits()); }
Они измеряют расстояние между входом и стоп-лоссом, умножают его на выбранное соотношение и проецируют целевую цену. Это постоянно сохраняет прибыль пропорциональной риску.
Открытие сделок
Теперь мы оборачиваем исполнение в две простые функции.
//+------------------------------------------------------------------+ //| Function to open a market buy position | //+------------------------------------------------------------------+ bool OpenBuy(double entryPrice, double stopLoss, double takeProfit, double lotSize){ if(lotSizeMode == MODE_AUTO){ lotSize = CalculatePositionSizeByRisk(entryPrice - stopLoss); } if(!Trade.Buy(lotSize, _Symbol, entryPrice, stopLoss, takeProfit)){ Print("Error while executing a market buy order: ", GetLastError()); Print(Trade.ResultRetcode()); Print(Trade.ResultComment()); return false; } return true; } //+------------------------------------------------------------------+ //| Function to open a market sell position | //+------------------------------------------------------------------+ bool OpenSel(double entryPrice, double stopLoss, double takeProfit, double lotSize){ if(lotSizeMode == MODE_AUTO){ lotSize = CalculatePositionSizeByRisk(stopLoss - entryPrice); } if(!Trade.Sell(lotSize, _Symbol, entryPrice, stopLoss, takeProfit)){ Print("Error while executing a market sell order: ", GetLastError()); Print(Trade.ResultRetcode()); Print(Trade.ResultComment()); return false; } return true; }
Они обрабатывают автоматический расчет размера позиции, а затем отправляют ордер через торговый объект. Логика исполнения теперь полностью отделена от логики обнаружения.
Объединение всего внутри OnTick
//+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick(){ //--- Retrieve current market prices for trade execution askPrice = SymbolInfoDouble (_Symbol, SYMBOL_ASK); bidPrice = SymbolInfoDouble (_Symbol, SYMBOL_BID); currentTime = TimeCurrent(); //--- Get some minutes data if(CopyClose(_Symbol, PERIOD_M1, 0, 7, closePriceMinutesData) == -1){ Print("Error while copying minutes datas ", GetLastError()); return; } //--- Execute this block on new bar formation if(IsNewBar(_Symbol, timeframe, lastBarOpenTime)){ //--- if(smashEntryMode == ENTRY_ON_BAR_CLOSE){ //--- if(smashState.hasBuySmashSetup && smashState.entryPending){ if(!IsThereAnActiveBuyPosition(magicNumber) && !IsThereAnActiveSellPosition(magicNumber)){ if(smashTradeMode == SMASH_TRADE_BUY_ONLY || smashTradeMode == SMASH_TRADE_BOTH){ OpenBuy(askPrice, smashState.buyStopLoss, GetBuyTakeProfit(askPrice, smashState.buyStopLoss), positionSize); smashState.entryPending = false; } } } //--- if(smashState.hasSellSmashSetup && smashState.entryPending){ if(!IsThereAnActiveBuyPosition(magicNumber) && !IsThereAnActiveSellPosition(magicNumber)){ if(smashTradeMode == SMASH_TRADE_SELL_ONLY || smashTradeMode == SMASH_TRADE_BOTH){ OpenSel(bidPrice, smashState.sellStopLoss, GetSellTakeProfit(bidPrice, smashState.sellStopLoss), positionSize); smashState.entryPending = false; } } } } //--- ResetSmashDaySetupState(); //--- if(IsSmashDayBuyReversal(_Symbol, timeframe, 1, smashBuyLookbackBars)){ smashState.hasBuySmashSetup = true; smashState.entryPending = true; smashState.buyStopLoss = iLow(_Symbol, timeframe, 1); } //--- if(IsSmashDaySellReversal(_Symbol, timeframe, 1, smashSellLookbackBars)){ smashState.hasSellSmashSetup = true; smashState.entryPending = true; smashState.sellStopLoss = iHigh(_Symbol, timeframe, 1); } } //--- if(smashEntryMode == ENTRY_ON_LEVEL_CROSS){ //--- if(smashState.hasBuySmashSetup && smashState.entryPending){ // --- if(IsCrossOver(smashState.buyBreakoutLevel, closePriceMinutesData)){ if(!IsThereAnActiveBuyPosition(magicNumber) && !IsThereAnActiveSellPosition(magicNumber)){ if(smashTradeMode == SMASH_TRADE_BUY_ONLY || smashTradeMode == SMASH_TRADE_BOTH){ OpenBuy(askPrice, smashState.buyStopLoss, GetBuyTakeProfit(askPrice, smashState.buyStopLoss), positionSize); } smashState.hasBuySmashSetup = false; smashState.entryPending = false; } } } //--- if(smashState.hasSellSmashSetup && smashState.entryPending){ // --- if(IsCrossUnder(smashState.sellBreakoutLevel, closePriceMinutesData)){ if(!IsThereAnActiveBuyPosition(magicNumber) && !IsThereAnActiveSellPosition(magicNumber)){ if(smashTradeMode == SMASH_TRADE_SELL_ONLY || smashTradeMode == SMASH_TRADE_BOTH){ OpenSel(bidPrice, smashState.sellStopLoss, GetSellTakeProfit(bidPrice, smashState.sellStopLoss), positionSize); } smashState.hasSellSmashSetup = false; smashState.entryPending = false; } } } } }
Внутри функции OnTick мы сначала обновляем цены и минутные данные. Затем реагируем на новый дневной бар. На новом баре мы выполняем три действия по порядку.
1. Обрабатываем отложенные входы, когда режим входа ждет закрытия бара
2. Сбрасываем внутреннее состояние Smash Day
3. Обнаруживаем свежие паттерны Smash Day на завершенном баре
После этого, вне блока нового бара, мы обрабатываем входы по пробою в реальном времени, когда активен режим немедленного входа. Такая структура гарантирует следующее.
- Обнаружение паттерна происходит один раз в день
- Мониторинг пробоя идет непрерывно
- Входы не повторяются
- Одновременно может существовать только одна сделка
Флаги состояния Smash Day направляют поток от обнаружения к входу, а затем автоматически отключаются после исполнения. Такое чистое разделение обнаружения и исполнения делает поведение предсказуемым и понятным для анализа.
Повышение визуальной наглядности при тестировании
Перед тестированием мы настраиваем график для удобного просмотра.
//+------------------------------------------------------------------+ //| This function configures the chart's appearance. | //+------------------------------------------------------------------+ bool ConfigureChartAppearance() { if(!ChartSetInteger(0, CHART_COLOR_BACKGROUND, clrWhite)){ Print("Error while setting chart background, ", GetLastError()); return false; } if(!ChartSetInteger(0, CHART_SHOW_GRID, false)){ Print("Error while setting chart grid, ", GetLastError()); return false; } if(!ChartSetInteger(0, CHART_MODE, CHART_CANDLES)){ Print("Error while setting chart mode, ", GetLastError()); return false; } if(!ChartSetInteger(0, CHART_COLOR_FOREGROUND, clrBlack)){ Print("Error while setting chart foreground, ", GetLastError()); return false; } if(!ChartSetInteger(0, CHART_COLOR_CANDLE_BULL, clrSeaGreen)){ Print("Error while setting bullish candles color, ", GetLastError()); return false; } if(!ChartSetInteger(0, CHART_COLOR_CANDLE_BEAR, clrBlack)){ Print("Error while setting bearish candles color, ", GetLastError()); return false; } if(!ChartSetInteger(0, CHART_COLOR_CHART_UP, clrSeaGreen)){ Print("Error while setting bearish candles color, ", GetLastError()); return false; } if(!ChartSetInteger(0, CHART_COLOR_CHART_DOWN, clrBlack)){ Print("Error while setting bearish candles color, ", GetLastError()); return false; } return true; }
Добавьте функцию ConfigureChartAppearance в раздел utility и вызовите ее из OnInit.
//+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit(){ ... //--- To configure the chart's appearance if(!ConfigureChartAppearance()){ Print("Error while configuring chart appearance", GetLastError()); return INIT_FAILED; } return(INIT_SUCCEEDED); }
Она задает четкие цвета свечей и фона, чтобы сделки и ценовое движение было легко отслеживать во время визуальных бэктестов. На этом этапе советник завершен. Все ключевые элементы на месте: обнаружение нового дня, распознавание паттернов Smash Day, мониторинг пробоя, расчет размера позиции на основе риска, правило одной сделки и автоматический сброс состояния.
Полный исходный файл предоставлен как lwSmashDayReversalExpert.mq5. Теперь у нас есть полностью функциональный инструмент для исследования и проверки, который превращает развороты Smash Day Ларри Уильямса в точные, проверяемые и воспроизводимые торговые правила.
Тестирование разворота Smash Day для покупки на золоте
Чтобы оценить, как эта идея работает на практике, был проведен контролируемый бэктест по золоту на дневном таймфрейме. Тест охватывал полный год рыночных данных — с первого дня января 2025 года до последнего дня декабря 2025 года.
Был включен только режим Smash Day Buy, поэтому система могла открывать только длинные сделки. Размер позиции был настроен на автоматический режим риска: каждая сделка рисковала 1% текущего баланса счета. Это означает, что размер позиции растет и уменьшается вместе со счетом и сохраняет риск постоянным от сделки к сделке.
Тест начался с первоначального баланса $10 000. За год система получила общую чистую прибыль в размере $2307,25.

Это выше двадцати процентов доходности инвестиций. Доля прибыльных сделок составила шестьдесят четыре процента.
Хотя доля прибыльных сделок не чрезвычайно высока, общая кривая капитала рассказывает более важную историю. Рост счета устойчивый и плавный, без резких провалов.

Нет драматических обвалов капитала или длинных периодов застоя. Вместо этого кривая постепенно и контролируемо растет, что говорит о хорошо ограниченных убытках и возможности прибыли накапливаться со временем. Такое поведение напрямую связано с двумя проектными решениями: во-первых, каждая сделка рискует лишь небольшой фиксированной долей счета; во-вторых, сделки открываются только при появлении четкого объективного паттерна, а не ради постоянного присутствия на рынке.
Чтобы сделать этот тест полностью воспроизводимым, вместе со статьей предоставлены два файла. Файл конфигурации содержит настройки среды тестера. Файл параметров содержит точные входные значения, использованные советником. Загрузив эти файлы в тестер стратегий, можно воспроизвести те же результаты на том же символе и диапазоне дат.
Этот одиночный тест не доказывает, что паттерн всегда будет работать на каждом рынке или в каждом году. Он показывает, что при одной четкой, хорошо определенной конфигурации идея дала стабильный рост с контролируемым риском на золоте в этот период. Настоящая сила проекта — в его гибкости. Все основные элементы поведения, такие как глубина lookback, режим входа и уровень риска, можно менять через входные параметры. Это позволяет исследовать бесконечное число вариантов.
Дальнейшее тестирование на других символах, в другие годы и с альтернативными значениями параметров может выявить новые сильные или слабые стороны. Разные сочетания могут раскрыть еще более качественное преимущество. Самостоятельные эксперименты настоятельно приветствуются. Наблюдениями, идеями и улучшениями можно делиться в разделе комментариев, чтобы исследование продолжало развиваться коллективными усилиями.
Заключение
В этой работе дискреционная торговая идея Ларри Уильямса была преобразована в полностью объективную и проверяемую торговую систему. Разворотный паттерн Smash Day, основанный на эмоциональных пробоях, которые быстро оказываются ложными, был сведен к четким правилам, которые система может распознавать и отрабатывать без колебаний.
Был создан советник, который обнаруживает такие условия в реальном времени, автоматически управляет риском и исполняет сделки с жесткой дисциплиной. Система допускает только одну позицию за раз, использует четко определенные стоп-лоссы и целевые уровни прибыли, а также адаптирует размер позиции к фиксированному проценту риска счета. Это превращает рыночное поведение, ранее описанное лишь в общих чертах, в структурированный исследовательский инструмент.
Годовой тест на золоте показал устойчивый рост счета, контролируемые просадки и последовательное накопление прибыли. Это показывает, что паттерн не просто привлекателен на графике, но может быть количественно описан, измерен и оценен в реальных рыночных условиях.
Что важнее, программа была разработана прежде всего для тестирования и изучения, а не для слепой автоматизации. Каждое ключевое правило можно настроить через входные параметры. Это позволяет дальше тестировать разные глубины lookback, стили входа и уровни риска на любом символе или таймфрейме. Читатель не ограничен единственным примером, приведенным здесь.
Достигнутый результат — это мост между торговой психологией и программируемой логикой. Эмоциональные ловушки, которые раньше интерпретировались на глаз, теперь можно просканировать за секунды по многим годам исторических данных. Это открывает путь к более глубокому исследованию, более быстрой проверке идей и более уверенным решениям.
Разворот Smash Day — лишь один паттерн. Тот же процесс можно повторить для многих других концепций из классической торговой литературы. Сочетая четкие правила, строгий контроль риска и систематическое тестирование, можно отделять интуицию от доказательств.
Следующий шаг — самостоятельное экспериментирование. Новые тесты, изменение параметров и сравнение результатов на разных рынках могут выявить еще более сильные варианты этой идеи. Обмен такими находками помогает продвигать исследование дальше и превращает одну статью в растущий массив практических знаний.
Приложенные файлы и как ими пользоваться
Чтобы упростить воспроизведение и дальнейшее исследование, к статье приложены все важные ресурсы, использованные в этом проекте. Эти файлы позволяют загрузить ту же торговую логику, настройки среды и тестовые параметры без ручной перенастройки.
Такая настройка позволяет воспроизвести показанные результаты, изучить полный исходный код и менять входные параметры для поиска новых идей. Таким образом советник становится не просто готовым инструментом, а отправной точкой для более глубоких экспериментов.
В таблице ниже кратко описан каждый приложенный файл и его назначение.
| Имя файла | Описание |
|---|---|
| lwSmashDayReversalExpert.mq5 | Полный исходный код советника MQL5, реализующего развороты Smash Day |
| configurations.ini | Конфигурация среды тестера стратегий для согласованной настройки бэктеста |
| parameters.set | Набор входных параметров, использованный для получения показанных результатов бэктеста |
Исходный файл можно открыть напрямую в MetaEditor для изучения, изменения и компиляции. Файл конфигурации можно загрузить в тестер стратегий, чтобы повторить точную среду тестирования. Файл параметров можно применить на вкладке входных параметров тестера, чтобы мгновенно загрузить те же торговые настройки, которые использовались в представленных результатах.
Вместе эти файлы образуют готовый исследовательский пакет. Они позволяют проверить стратегию, провести стресс-тестирование в разных рыночных условиях и расширить ее дополнительными фильтрами или идеями.
Перевод с английского произведен MetaQuotes Ltd.
Оригинальная статья: https://www.mql5.com/en/articles/21127
Предупреждение: все права на данные материалы принадлежат MetaQuotes Ltd. Полная или частичная перепечатка запрещена.
Данная статья написана пользователем сайта и отражает его личную точку зрения. Компания MetaQuotes Ltd не несет ответственности за достоверность представленной информации, а также за возможные последствия использования описанных решений, стратегий или рекомендаций.
От начального до среднего уровня: Произвольный доступ (I)
Нейросети в трейдинге: Когнитивная инерция в анализе финансовых рынков (модуль временной согласованности)
Разработка динамического мультивалютного советника (Часть 8): Ротация капитала в зависимости от времени суток
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Вы принимаете политику сайта и условия использования