Алгоритм действий: ловим транзакцию'TRADE_TRANSACTION_DEAL_ADD' (добавление сделки в историю). Далее проверяем свойство сделки из перечисления ENUM_DEAL_REASON (Причина или источник исполнения сделки) - если это 'DEAL_REASON_SL' или 'DEAL_REASON_TP', то отправляем сигнал.
Пример: простой советник на пересечении двух индикаторов iMA (Moving Average, MA).
Код: Simple Two iMA Crossing.mq5
ВНИМАНИЕ: Чтобы получить данные индикатора в MQL5-эксперте, необходимо придерживаться следующих правил:
Хендл индикатора создается в OnInit
Затем (как правило, в OnTick) данные индикатора получаются с помощью CopyBuffer
Создание хэндлов индикаторов в OnInit
//+------------------------------------------------------------------+//| Expert initialization function |//+------------------------------------------------------------------+intOnInit()
{
//---ResetLastError();
if(!m_symbol.Name(Symbol())) // sets symbol name
{
Print(__FILE__," ",__FUNCTION__,", ERROR: CSymbolInfo.Name");
return(INIT_FAILED);
}
RefreshRates();
//---
m_trade.SetExpertMagicNumber(InpMagic);
m_trade.SetMarginMode();
m_trade.SetTypeFillingBySymbol(m_symbol.Name());
m_trade.SetDeviationInPoints(InpDeviation);
//--- create handle of the indicator iMA
handle_iMA_Fast=iMA(m_symbol.Name(),Period(),Inp_MA_Fast_ma_period,Inp_MA_Fast_ma_shift,
Inp_MA_Fast_ma_method,Inp_MA_Fast_applied_price);
//--- if the handle is not createdif(handle_iMA_Fast==INVALID_HANDLE)
{
//--- tell about the failure and output the error codePrintFormat("Failed to create handle of the iMA ('Fast') indicator for the symbol %s/%s, error code %d",
m_symbol.Name(),
EnumToString(Period()),
GetLastError());
//--- the indicator is stopped earlyreturn(INIT_FAILED);
}
//--- create handle of the indicator iMA
handle_iMA_Slow=iMA(m_symbol.Name(),Period(),Inp_MA_Slow_ma_period,Inp_MA_Slow_ma_shift,
Inp_MA_Slow_ma_method,Inp_MA_Slow_applied_price);
//--- if the handle is not createdif(handle_iMA_Slow==INVALID_HANDLE)
{
//--- tell about the failure and output the error codePrintFormat("Failed to create handle of the iMA ('Slow') indicator for the symbol %s/%s, error code %d",
m_symbol.Name(),
EnumToString(Period()),
GetLastError());
//--- the indicator is stopped earlyreturn(INIT_FAILED);
}//---return(INIT_SUCCEEDED);
}
Таким образом, советник будет искать сигнал только в момент рождения нового бара. Код, отвечающий за поиск нового бара:
//+------------------------------------------------------------------+//| Expert tick function |//+------------------------------------------------------------------+voidOnTick()
{
***
//--- we work only at the time of the birth of new bardatetime time_0=iTime(m_symbol.Name(),Period(),0);
if(time_0==m_prev_bars)
return;
m_prev_bars=time_0;
***
}
Если новый бар найден, ищем сигнал: сравниваем значения двух индикаторов iMA ('Fast' и 'Slow') на баре № 2 и на баре № 1. Обратите внимание, что текущий бар - бар № 0 - не используется. Когда поступает сигнал на открытие позиции BUY, мы выставляем ордер на закрытие позиций SELL, и наоборот: когда поступает сигнал на открытие позиции SELL, мы выставляем ордер на закрытие BUY.
//+------------------------------------------------------------------+//| Expert tick function |//+------------------------------------------------------------------+voidOnTick()
{
***
//---double fast[],slow[];
ArraySetAsSeries(fast,true);
ArraySetAsSeries(slow,true);
int start_pos=0,count=6;
if(!iGetArray(handle_iMA_Fast,0,start_pos,count,fast) || !iGetArray(handle_iMA_Slow,0,start_pos,count,slow))
{
m_prev_bars=0;
return;
}
//--- check signal close SELL and open BUYif(fast[1]>slow[1]&&fast[2]<slow[2])
{
m_need_close_sells=true;
m_need_open_buy=true;
return;
}
//--- check signal close BUY and open SELLif(fast[1]<slow[1]&&fast[2]>slow[2])
{
m_need_close_buys=true;
m_need_open_sell=true;
return;
}
}
Counting of elements of copied data (indicator buffer with the index buffer_num) from the starting position is performed from the present to the past, i.e., starting position of 0 means the current bar (indicator value for the current bar). When copying the yet unknown amount of data, it is recommended to use a dynamic array as a buffer[]...
Пример: если индикатор Moving Average опустился ниже цены закрытия, закройте позиции BUY, если индикатор Moving Average поднялся выше цены закрытия, закройте позиции SELL.
Код: Simple iMA Above Below Close.mq5
Пример создания индикатора подробно описан выше(#112), а здесь я более подробно остановлюсь на получении сигнала, а не на его реализации.
Итак, в момент рождения нового бара
//--- we work only at the time of the birth of new bardatetime time_0=iTime(m_symbol.Name(),Period(),0);
if(time_0==m_prev_bars)
return;
m_prev_bars=time_0;
//---
проверяем необходимость закрытия позиций (сравниваем значение индикатора Moving Average на баре №1 и цену закрытия бара №1)
//--- check signal close BUY if(ma[1]<rates[1].close)
{
m_need_close_buys=true;
return;
}
//--- check signal close SELLif(ma[1]>rates[1].close)
{
m_need_close_sells=true;
return;
}
В OnTick (то есть на каждом тике) проверяем флаги ' m_need_close_buys ' и ' m_need_close_sells ' - и, если необходимо, закрываем позиции выбранного направления.
//+------------------------------------------------------------------+//| Expert tick function |//+------------------------------------------------------------------+voidOnTick()
{
//--- need close BUY positions OR SELL positionsif(m_need_close_buys || m_need_close_sells)
{
int count_buys = 0;
int count_sells = 0;
CalculateAllPositions(count_buys,count_sells);
//---if(m_need_close_buys)
{
if(count_buys>0)
{
ClosePositions(POSITION_TYPE_BUY);
return;
}
else
m_need_close_buys=false;
}
//---if(m_need_close_sells)
{
if(count_sells>0)
{
ClosePositions(POSITION_TYPE_SELL);
return;
}
else
m_need_close_sells=false;
}
}
Это заготовка - пример того, как управлять торговым сигналом. Этот код позволяет избежать ситуации: открытия нескольких позиций. Как это работает: после генерации торгового ордера мы увеличиваем структуру 'SPosition'. В OnTick, если 'SPosition' больше нуля, переходим к блоку открытия позиций. В OnTradeTransaction отслеживаем ситуацию, когда позиция появляется точно по нашему сигналу.
//+------------------------------------------------------------------+//| Expert initialization function |//+------------------------------------------------------------------+intOnInit()
{
//--- create handle of the indicator iMAhandle_iMA=iMA(Symbol(),Period(),Inp_MA_ma_period,Inp_MA_ma_shift,
Inp_MA_ma_method,Inp_MA_applied_price);//--- if the handle is not createdif(handle_iMA==INVALID_HANDLE)
{
//--- tell about the failure and output the error codePrintFormat("Failed to create handle of the iMA indicator for the symbol %s/%s, error code %d",
Symbol(),
EnumToString(Period()),
GetLastError());
//--- the indicator is stopped earlyreturn(INIT_FAILED);
}
//---return(INIT_SUCCEEDED);
}
Получение значений (я использую общую функцию iGetArray). Обратите внимание: для массива"array_ma" я использую"ArraySetAsSeries" - в этом случае в массиве "array_ma" элемент с индексом "0" соответствует самому правому бару на графике (bar # 0)
Patrine Peniston : Привет, я здесь новичок. Не знаю, упоминалось ли это раньше, но я пытаюсь понять, как открыть позицию по цене открытия НОВОЙ свечи. возможно ли это?
Нет, это невозможно: так как свеча уже открылась и это событие В ПРОШЛОМ :)
Но проблему можно сформулировать иначе: как поймать момент рождения нового бара и открыть позицию в этот момент. Устроит ли вас такая постановка вопроса?
Пример: отслеживание срабатывания стоп-лосса или тейк-профита
Код: SL TP Triggered.mq5
Алгоритм действий: ловим транзакцию'TRADE_TRANSACTION_DEAL_ADD' (добавление сделки в историю). Далее проверяем свойство сделки из перечисления ENUM_DEAL_REASON (Причина или источник исполнения сделки) - если это 'DEAL_REASON_SL' или 'DEAL_REASON_TP', то отправляем сигнал.
Пример: простой советник на пересечении двух индикаторов iMA (Moving Average, MA).
Код: Simple Two iMA Crossing.mq5
ВНИМАНИЕ: Чтобы получить данные индикатора в MQL5-эксперте, необходимо придерживаться следующих правил:
Создание хэндлов индикаторов в OnInit
Таким образом, советник будет искать сигнал только в момент рождения нового бара. Код, отвечающий за поиск нового бара:
Если новый бар найден, ищем сигнал: сравниваем значения двух индикаторов iMA ('Fast' и 'Slow') на баре № 2 и на баре № 1. Обратите внимание, что текущий бар - бар № 0 - не используется. Когда поступает сигнал на открытие позиции BUY, мы выставляем ордер на закрытие позиций SELL, и наоборот: когда поступает сигнал на открытие позиции SELL, мы выставляем ордер на закрытие BUY.
Пример: если индикатор Moving Average опустился ниже цены закрытия, закройте позиции BUY, если индикатор Moving Average поднялся выше цены закрытия, закройте позиции SELL.
Код: Simple iMA Above Below Close.mq5
Пример создания индикатора подробно описан выше(#112), а здесь я более подробно остановлюсь на получении сигнала, а не на его реализации.
Итак, в момент рождения нового бара
проверяем необходимость закрытия позиций (сравниваем значение индикатора Moving Average на баре №1 и цену закрытия бара №1)
В OnTick (то есть на каждом тике) проверяем флаги ' m_need_close_buys ' и ' m_need_close_sells ' - и, если необходимо, закрываем позиции выбранного направления.
Мы ловим транзакцию
Код: Мы ловим сделку.mq5
Это заготовка - пример того, как управлять торговым сигналом. Этот код позволяет избежать ситуации: открытия нескольких позиций. Как это работает: после генерации торгового ордера мы увеличиваем структуру 'SPosition'. В OnTick, если 'SPosition' больше нуля, переходим к блоку открытия позиций. В OnTradeTransaction отслеживаем ситуацию, когда позиция появляется точно по нашему сигналу.
Пример: найти самую убыточную позицию и самую прибыльную позицию
Код: Поиск максимального убытка и максимальной прибыли.mq5
Пример: ловля триггера тейк-профита
Код: Last Deal Take Profit activation.mq5
Пример работы в режиме онлайн (через OnTradeTransaction).
Получение данных от индикатора в MQL5.
Схема:
Пример для индикатора iMA:
функции OnInit).
Входные параметры и переменная, в которой хранится хэндл индикатора:
Создание хэндла(проверка результата)
Получение значений (я использую общую функцию iGetArray). Обратите внимание: для массива"array_ma" я использую"ArraySetAsSeries" - в этом случае в массиве "array_ma" элемент с индексом "0" соответствует самому правому бару на графике (bar # 0)
Результат работы:
Рис. 1. Получение значений на барах #0, #1, #2
Привет, я здесь новичок. Не знаю, упоминалось ли это раньше, но я пытаюсь понять, как открыть позицию по цене открытия НОВОЙ свечи. возможно ли это?
Нет, это невозможно: так как свеча уже открылась и это событие В ПРОШЛОМ :)
Но проблему можно сформулировать иначе: как поймать момент рождения нового бара и открыть позицию в этот момент. Устроит ли вас такая постановка вопроса?
Пример: в момент рождения нового бара открывается позиция размером 1,0 лот
Код: Открыть позицию на новом баре.mq5