Здравствуйте уважаемые посетители данной ветки форума. Этот курс предназначен для начинающих знакомство с языком программирования MQL5.
Надеюсь, с азами программирования вы знакомы. Знаете что такое переменная, типы переменных, видимость переменных. Знаете что такое функция, пользовательская функция и прочие минимальные знания программирования вам не чужды.
Для примера напишем советник по избитой теме торговли, основанную на пересечении двух индикаторов Moving Average.
Итак, начинаем:
Также надеюсь, знаете, как создать новый файл будущего советника. Меню «Файл» затем «Создать» отметить, что создаём советник и далее. Либо через контекстное меню «Новый файл»... и так далее. MetaEditor в помощь нам, создаёт такой код.
Теперь начинаем вставлять свой код. Для начала нам надо задать параметры торговли и используемых индикаторов.
Обращение к индикаторам в MQL5 происходит не так как в MQL4, поэтому надо объявить переменные, в которых будем хранить хендлы индикаторов. А поскольку индикаторов у нас два, то и хендлов должно быть два.
Затем в функции int OnInit() получим хендлы необходимых индикаторов.
В итоге наш код будет выглядеть уже вот так.
Теперь надо как-то определить, что произошло пересечение линий индикаторов. Для этого напишем пользовательскую функцию определяющую факт пересечения, назовём её Crossing. Возвращать функция будет 0, 1 или -1 следовательно тип функции будет int.
Но вот незадача… Получается что пересечение действительно на каждом тике пока не закроется текущий бар… Следовательно откроется несколько позиций подряд. Чтобы это предотвратить надо организовать открытие позиций только один раз на баре в момент его первого тика. Для этого напишем ещё одну пользовательскую функцию.
Выглядит она так.
В этой функции объявлена статическая static переменная типа datetime timeLastBar которая хранит время открытия бара на котором было последнее обращение к этой функции. Для определения времени открытия текущего бара будем использовать функцию CopyRates() и помещать результат в массив структур типа MqlRates. Затем полученное время последнего бара сравнивается с временем хранящимся в переменной timeLastBar и если оно изменилось в переменную запишется время последнего бара и функция вернёт true. Если-же время не изменилось, возвращается false.
Поместим его опять-же в самый конец нашего кода и исправим вызов функции Crossing()
Таким образом, вызов функции выглядит так.
Теперь можно запустить код в тестере стратегий и понаблюдать когда в журнале будет печататься наши сообщения.
Надеюсь, с азами программирования вы знакомы. Знаете что такое переменная, типы переменных, видимость переменных. Знаете что такое функция, пользовательская функция и прочие минимальные знания программирования вам не чужды.
Для примера напишем советник по избитой теме торговли, основанную на пересечении двух индикаторов Moving Average.
Замечание: Наш советник предназначен для обучения и не нацелен на извлечение прибыли.
Итак, начинаем:
Также надеюсь, знаете, как создать новый файл будущего советника. Меню «Файл» затем «Создать» отметить, что создаём советник и далее. Либо через контекстное меню «Новый файл»... и так далее. MetaEditor в помощь нам, создаёт такой код.
Код:
//+------------------------------------------------------------------+
//| MyFirstEA.mq5 |
//| Viktorov |
//| [email protected] |
//+------------------------------------------------------------------+
#property copyright "Viktorov"
#property link "[email protected]"
#property version "1.00"
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//---
//---
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//---
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
//---
}
//+------------------------------------------------------------------+
Обращение к индикаторам в MQL5 происходит не так как в MQL4, поэтому надо объявить переменные, в которых будем хранить хендлы индикаторов. А поскольку индикаторов у нас два, то и хендлов должно быть два.
Затем в функции int OnInit() получим хендлы необходимых индикаторов.
В итоге наш код будет выглядеть уже вот так.
Код:
//+------------------------------------------------------------------+
//| MyFirstEA.mq5 |
//| Viktorov |
//| [email protected] |
//+------------------------------------------------------------------+
#property copyright "Viktorov"
#property link "[email protected]"
#property version "1.00"
//---- input parameters
input double lot = 0.1; // Размер лота
input int tacke = 400; // TackeProfit
input int loss = 200; // StopLoss
input int periodFastMa = 8; // Период усреднения быстрой МА
input ENUM_MA_METHOD metodFastMa = 1; // Метод усреднения быстрой МА
input ENUM_APPLIED_PRICE priceFastMA = 1; // Используемая цена быстрой МА
input int periodSlowMa = 13; // Период усреднения медленной МА
input ENUM_MA_METHOD metodSlowMa = 1; // Метод усреднения медленной МА
input ENUM_APPLIED_PRICE priceSlowMA = 1; // Используемая цена медленной МА
int handleFastMA // хендл быстрой МА
, handleSlowMA; // хендл медленной МА
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//---
handleFastMA = iMA(_Symbol, PERIOD_CURRENT, periodFastMa, 0, metodFastMa, priceFastMA);
handleSlowMA = iMA(_Symbol, PERIOD_CURRENT, periodSlowMa, 0, metodSlowMa, priceSlowMA);
if(handleFastMA == INVALID_HANDLE || handleSlowMA == INVALID_HANDLE)
return(INIT_FAILED);
//---
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//---
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
//---
}
//+------------------------------------------------------------------+
Код:
int Crossing()
{
double fastMA[2], slowMA[2];
CopyBuffer(handleFastMA, 0, 1, 2, fastMA);
CopyBuffer(handleSlowMA, 0, 1, 2, slowMA);
if(fastMA[0] < slowMA[0] && fastMA[1] > slowMA[1])
return(0);
if(fastMA[0] > slowMA[0] && fastMA[1] < slowMA[1])
return(1);
return(-1);
}/*******************************************************************/
Выглядит она так.
Код:
bool newBar()
{
static datetime timeLastBar;
MqlRates mqlRates[];
int s = 0;
do
{
s++;
}
while(CopyRates(_Symbol, PERIOD_CURRENT, 0, 1, mqlRates) < 0 && s < 7);
bool ret = timeLastBar != mqlRates[0].time;
if(ret)
timeLastBar = mqlRates[0].time;
return(ret);
}/*******************************************************************/
Поместим его опять-же в самый конец нашего кода и исправим вызов функции Crossing()
Таким образом, вызов функции выглядит так.
Код:
void OnTick()
{
//---
int isCrossed = Crossing();
if(newBar())
{
if(isCrossed == 0)
Print("Откроем позицию Buy");
if(isCrossed == 1)
Print("Откроем позицию Sell");
}
}