Исходный код нашего первого советника.
Наиболее простым способом для новичка изучить процесс написания экспертов будет подробный разбор специально написанных мной для этой цели экспертов. На данный момент (да и далее в своих статьях) я не буду ставить перед собой цель написать супер гениального эксперта, который способен будет зарабатывать десятки процентов в месяц и делать это стабильно. Основная цель — показать все аспекты программирования экспертов, а не написать «грааль».
Итак, внимательно изучите код эксперта ниже, но не волнуйтесь, что на данный момент Вам пока еще ничего не понятно. В следующих выпусках будет подробно разберана каждая строчку этого эксперта.
//+------------------------------------------------------------------+ //| 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