home

Наиболее простым способом для новичка изучить процесс написания экспертов будет подробный разбор специально написанных мной для этой цели экспертов. На данный момент (да и далее в своих статьях) я не буду ставить перед собой цель написать супер гениального эксперта, который способен будет зарабатывать десятки процентов в месяц и делать это стабильно. Основная цель — показать все аспекты программирования экспертов, а не написать «грааль».

Итак, внимательно изучите код эксперта ниже, но не волнуйтесь, что на данный момент Вам пока еще ничего не понятно. В следующих выпусках будет подробно разобрана каждая строчка этого эксперта.

//+------------------------------------------------------------------+
//| My First Expert.mq4 |
//| Copyright © 2006, Andrey Vedikhin |
//| http://www.vedikhin.ru |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2006, Andrey Vedikhin"
#property link "http://www.vedikhin.ru"

#define STATE_SQUARE 0
#define STATE_LONG 1
#define STATE_SHORT 2

//---- input parameters
extern int MAPeriod=13;
extern double LotsNumber=1.0;


//---- глобальные переменные
int CurrentState;
int MyOrderTicket;


//+------------------------------------------------------------------+
//| expert initialization function |
//+------------------------------------------------------------------+
int init()
{
//----
if (iMA(NULL, 0, MAPeriod, 0, MODE_EMA, PRICE_CLOSE, 0) > Close[0])
CurrentState = STATE_SHORT;
else CurrentState = STATE_LONG;

MyOrderTicket = 0;
//----
return(0);
}
//+------------------------------------------------------------------+
//| expert deinitialization function |
//+------------------------------------------------------------------+
int deinit()
{
//----

//----
return(0);
}
//+------------------------------------------------------------------+
//| expert start function |
//+------------------------------------------------------------------+
int start()
{
//----
int err;

double MA;
MA = iMA(NULL, 0, MAPeriod, 0, MODE_EMA, PRICE_CLOSE, 0);

if ( CurrentState == STATE_LONG)
{
if (MA > Close[1]) //скользящая средняя выше цены закрытия
{
CurrentState = STATE_SHORT;

//переворачиваемся в продажу

//---закрыть позицию, если была открыта
if ( MyOrderTicket != 0)
{
if (!OrderClose(MyOrderTicket, LotsNumber, Bid, 3, CLR_NONE))
{
err = GetLastError();
Print("Ошибка при закрытии позиции: ", err);
return(0);
}
MyOrderTicket = 0;
}
RefreshRates();

//--- длинная позиция была закрыта успешно

//--- теперь откроем позицию в продажу

//--- проверим на наличие свободных средств
if (!CheckForEnoughMargin()) return(0);

MyOrderTicket = OrderSend(Symbol(), OP_SELL, LotsNumber, Bid, 3, 0, 0,
NULL, 0, 0, CLR_NONE);
if (MyOrderTicket<0)
{
err = GetLastError();
Print("Ошибка при открытии позиции: ", err);
MyOrderTicket = 0;
}
}
}
else
{
if (MA < Close[1]) //скользящая средняя ниже цены закрытия
{
CurrentState = STATE_LONG;

//переворачиваемся в покупку

//---закрыть позицию, если была открыта
if ( MyOrderTicket != 0)
{
if (!OrderClose(MyOrderTicket, LotsNumber, Ask, 3, CLR_NONE))
{
err = GetLastError();
Print("Ошибка при закрытии позиции: ", err);
return(0);
}
MyOrderTicket = 0;
}
RefreshRates();

//--- короткая позиция была закрыта успешно

//--- теперь откроем позицию в покупку

//--- проверим на наличие свободных средств
if (!CheckForEnoughMargin()) return(0);

MyOrderTicket = OrderSend(Symbol(), OP_BUY, LotsNumber, Ask, 3, 0, 0,
NULL, 0, 0, CLR_NONE);
if (MyOrderTicket<0)
{
err = GetLastError();
Print("Ошибка при открытии позиции: ", err);
MyOrderTicket = 0;
}
}
}
//----
return(0);
}
//+------------------------------------------------------------------+
//| Проверка наличия свободной маржи |
//+------------------------------------------------------------------+
bool CheckForEnoughMargin()
{
if (GetOneLotMargin(Symbol())*LotsNumber

Вначале разберем, что означают следующие строчки:

 

 #define STATE_SQUARE 0
#define STATE_LONG 1
#define STATE_SHORT 2


 

Эти строчки дают возможность вместо написания малоинформтивных чисел 0, 1 или 2 использовать более понятные имена STATE_SQUARE, STATE_LONG или STATE_SHORT. Результат будет абсолютно таким же — если программа встретит в тексте STATE_SQUARE, STATE_LONG или STATE_SHORT, она заменит их на 0, 1 и 2 соответственно. Такая программа будет более читаемой.

Также константы используются в тех случаях, когда какое-то значение использует в нескольких местах программы и существует вероятность, что трейдеру может понадобиться изменить это значение в будущем. Если использовать константу, достаточно будет это сделать только в одном месте — в директиве #define.

Для объявления константы используйте следующую конструкцию:

 

 #define имя значение


 

Примеры констант:

 

 #define AUTHOR "Vedikhin Andrey"
#define Lots 1.1
#define ItemsNumber 77


 

Следующие две строчки абсолютно идентичны, но первая — более читаема:

 

 for(x=1;x<=ItemsNumber;x++) Print(Lots*x);
for(x=1;x<=77;x++) Print(1.1*x);


 

Константа может быть любого типа: int, bool, datetime, double, color, string