AM2
Андрей

 
Уровень 35

  Торгую в компаниях:


Группа "Программирование на MQL"

Рейтинг 280



Напишем свои функции для реальной торговли

Некоторое время назад вышел топик «Как переписать советник для реальной торговли», где рассматривалось создание эксперта на основе заимствованных функций. В этом же топике зададимся целью создать собственные функции и используем их для создания советника.

Чем же функция для тестера будет отличаться от версии онлайн?

1. Проверкой определенных параметров.
2. Заданным количеством попыток установить/закрыть/модифицировать/удалить ордер.
3. Обработкой ошибок по определенному алгоритму.

Для написания функций кроме приведенных в прошлом топике:

forum.mql4.com/ru/38949
www.opentraders.ru/downloads/1095/
www.opentraders.ru/downloads/1096/

я также использовал коды экспертов, созданных опытными разработчиками:

www.mql5.com/ru/code/15163
www.mql5.com/ru/code/14072

Для начала перепишем удаление отложек и закрытие ордеров. Начнем с удаления т.к. она самая простая и по ее примеру перепишем остальные.


//+------------------------------------------------------------------+
//| Удаление отложенных ордеров                                      |
//+------------------------------------------------------------------+
void DelOrder()
  {
   bool del;
   for(int i=OrdersTotal()-1;i>=0;i--)
     {
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
        {
         if(OrderSymbol()==Symbol() && OrderMagicNumber()==Magic)
           {
            if(OrderType()>1) del=OrderDelete(OrderTicket());
           }
        }
     }
  }



//+------------------------------------------------------------------+
//| Закрытие позиции по типу ордера                                  |
//+------------------------------------------------------------------+
void CloseAll(int ot=-1)
  {
   bool cl;
   for(int i=OrdersTotal()-1;i>=0;i--)
     {
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
        {
         if(OrderSymbol()==Symbol() && OrderMagicNumber()==Magic)
           {
            if(OrderType()==0 && (ot==0 || ot==-1))
              {
               RefreshRates();
               cl=OrderClose(OrderTicket(),OrderLots(),NormalizeDouble(Bid,Digits),Slip,White);
              }
            if(OrderType()==1 && (ot==1 || ot==-1))
              {
               RefreshRates();
               cl=OrderClose(OrderTicket(),OrderLots(),NormalizeDouble(Ask,Digits),Slip,White);
              }
           }
        }
     }
  }


Начинаем с попыток:


            for(int k=1;k<=MaxEntry;k++)
              {
                .....
              }


Далее проверим состояние кнопок и галочек в терминале:


               if(!IsTesting() && (!IsExpertEnabled() || IsStopped())) break;
               while(!IsTradeAllowed()) Sleep(5000);


Также можно проверить тип и время закрытия ордера:


   if(OrderCloseTime()>0)
     {
      Print("Ордер был закрыт или удален ");
      .....
     }

   if(Type<2)
     {
      Print(" Ордер удалить нельзя, он уже исполнен ");
      .....
     }


Теперь займемся обработкой ошибок.

Для расшифровки кодов ошибок можно пользоваться функцией ErrorDescription из библиотеки stdlib.mq4, но лучше расположить ее в теле эксперта, это может пригодиться для маркета.


//+------------------------------------------------------------------+
// Пример использования    Print("Ошибка : ",Error(GetLastError())); |
//+------------------------------------------------------------------+

string ErrorDescription(int error_code)
  {
   string error_string;
//----
   switch(error_code)
     {
      //---- Коды ошибок, возвращаемые торговым сервером:
      case 0:   error_string="Нет ошибок";                                                     break;
      case 1:   error_string="Нет ошибки, но результат неизвестен";                            break;
      case 2:   error_string="Общая ошибка";                                                   break;
      case 3:   error_string="Неправильные параметры";                                         break;
      case 4:   error_string="Торговый сервер занят";                                          break;
      case 5:   error_string="Старая версия клиентского терминала";                            break;
      case 6:   error_string="Нет связи с торговым сервером";                                  break;
      case 7:   error_string="Недостаточно прав";                                              break;
      case 8:   error_string="Слишком частые запросы";                                         break;
      case 9:   error_string="Недопустимая операция нарушающая функционирование сервера";      break;
      case 64:  error_string="Счет заблокирован";                                              break;
      case 65:  error_string="Неправильный номер счета";                                       break;
      case 128: error_string="Истек срок ожидания совершения сделки";                          break;
      case 129: error_string="Неправильная цена";                                              break;
      case 130: error_string="Неправильные стопы";                                             break;
      case 131: error_string="Неправильный объем";                                             break;
      case 132: error_string="Рынок закрыт";                                                   break;
      case 133: error_string="Торговля запрещена";                                             break;
      case 134: error_string="Недостаточно денег для совершения операции";                     break;
      case 135: error_string="Цена изменилась";                                                break;
      case 136: error_string="Нет цен";                                                        break;
      case 137: error_string="Брокер занят";                                                   break;
      case 138: error_string="Новые цены";                                                     break;
      case 139: error_string="Ордер заблокирован и уже обрабатывается";                        break;
      case 140: error_string="Разрешена только покупка";                                       break;
      case 141: error_string="Слишком много запросов";                                         break;
      case 145: error_string="Модификация запрещена, так как ордер слишком близок к рынку";    break;
      case 146: error_string="Подсистема торговли занята";                                     break;
      case 147: error_string="Использование даты истечения ордера запрещено брокером";         break;
      case 148: error_string="Количество открытых и отложенных ордеров достигло предела, установленного брокером.";break;


      //---- Коды ошибок выполнения MQL4-программы:

      case 4000: error_string="Нет ошибки";                                                      break;
      case 4001: error_string="Неправильный указатель функции";                                  break;
      case 4002: error_string="Индекс массива - вне диапазона";                                  break;
      case 4003: error_string="Нет памяти для стека функций";                                    break;
      case 4004: error_string="Переполнение стека после рекурсивного вызова";                    break;
      case 4005: error_string="На стеке нет памяти для передачи параметров";                     break;
      case 4006: error_string="Нет памяти для строкового параметра";                             break;
      case 4007: error_string="Нет памяти для временной строки";                                 break;
      case 4008: error_string="Неинициализированная строка";                                     break;
      case 4009: error_string="Неинициализированная строка в массиве";                           break;
      case 4010: error_string="Нет памяти для строкового массива";                               break;
      case 4011: error_string="Слишком длинная строка";                                          break;
      case 4012: error_string="Остаток от деления на ноль";                                      break;
      case 4013: error_string="Деление на ноль";                                                 break;
      case 4014: error_string="Неизвестная команда";                                             break;
      case 4015: error_string="Неправильный переход";                                            break;
      case 4016: error_string="Неинициализированный массив";                                     break;
      case 4017: error_string="Вызовы DLL не разрешены";                                         break;
      case 4018: error_string="Невозможно загрузить библиотеку";                                 break;
      case 4019: error_string="Невозможно вызвать функцию";                                      break;
      case 4020: error_string="Вызовы внешних библиотечных функций не разрешены";                break;
      case 4021: error_string="Недостаточно памяти для строки, возвращаемой из функции";         break;
      case 4022: error_string="Система занята";                                                  break;
      case 4050: error_string="Неправильное количество параметров функции";                      break;
      case 4051: error_string="Недопустимое значение параметра функции";                         break;
      case 4052: error_string="Внутренняя ошибка строковой функции";                             break;
      case 4053: error_string="Ошибка массива";                                                  break;
      case 4054: error_string="Неправильное использование массива-таймсерии";                    break;
      case 4055: error_string="Ошибка пользовательского индикатора";                             break;
      case 4056: error_string="Массивы несовместимы";                                            break;
      case 4057: error_string="Ошибка обработки глобальныех переменных";                         break;
      case 4058: error_string="Глобальная переменная не обнаружена";                             break;
      case 4059: error_string="Функция не разрешена в тестовом режиме";                          break;
      case 4060: error_string="Функция не разрешена";                                            break;
      case 4061: error_string="Ошибка отправки почты";                                           break;
      case 4062: error_string="Ожидается параметр типа string";                                  break;
      case 4063: error_string="Ожидается параметр типа integer";                                 break;
      case 4064: error_string="Ожидается параметр типа double";                                  break;
      case 4065: error_string="В качестве параметра ожидается массив";                           break;
      case 4066: error_string="Запрошенные исторические данные в состоянии обновления";          break;
/*м*/ case 4067: error_string="Ошибка при выполнении торговой операции";                         break;
      case 4099: error_string="Конец файла";                                                     break;
      case 4100: error_string="Ошибка при работе с файлом";                                      break;
      case 4101: error_string="Неправильное имя файла";                                          break;
      case 4102: error_string="Слишком много открытых файлов";                                   break;
      case 4103: error_string="Невозможно открыть файл";                                         break;
      case 4104: error_string="Несовместимый режим доступа к файлу";                             break;
      case 4105: error_string="Ни один ордер не выбран";                                         break;
      case 4106: error_string="Неизвестный символ";                                              break;
      case 4107: error_string="Неправильный параметр цены для торговой функции";                 break;
      case 4108: error_string="Неверный номер тикета";                                           break;
      case 4109: error_string="Торговля не разрешена. Необходимо включить опцию Разрешить советнику торговать в свойствах эксперта.";            break;
      case 4110: error_string="Длинные позиции не разрешены. Необходимо проверить свойства эксперта.";           break;
      case 4111: error_string="Короткие позиции не разрешены. Необходимо проверить свойства эксперта.";          break;
      case 4200: error_string="Объект уже существует";                                           break;
      case 4201: error_string="Запрошено неизвестное свойство объекта";                          break;
      case 4202: error_string="Объект не существует";                                            break;
      case 4203: error_string="Неизвестный тип объекта";                                         break;
      case 4204: error_string="Нет имени объекта";                                               break;
      case 4205: error_string="Ошибка координат объекта";                                        break;
      case 4206: error_string="Не найдено указанное подокно";                                    break;
      default:   error_string="Ошибка при работе с объектом";
     }
//----
   return(error_string);
  }



string ErrorDescription(int error_code)
  {
   string error_string;
//----
   switch(error_code)
     {
      // ---- Error codes returned from trade server:
      case 0: error_string="No error"; break;
      case 1: error_string="No error, but the result is unknown"; break;
      case 2: error_string="Common error"; break;
      case 3: error_string="Wrong parameters"; break;
      case 4: error_string="Trade server is busy"; break;
      case 5: error_string="Old version of client terminal"; break;
      case 6: error_string="No connection with trade server"; break;
      case 7: error_string="not Enough rights"; break;
      case 8: error_string="Too frequent requests"; break;
      case 9: error_string="invalid operation in violation of the functioning of the server"; break;
      case 64: error_string="Account is locked"; break;
      case 65: error_string="Invalid account number"; break;
      case 128: error_string="Expired expectations of the transaction"; break;
      case 129: error_string="Invalid price"; break;
      case 130: error_string="invalid stops"; break;
      case 131: error_string="Wrong volume"; break;
      case 132: error_string="Market is closed"; break;
      case 133: error_string="Trade is disabled"; break;
      case 134: error_string="not Enough money for the transaction"; break;
      case 135: error_string="Price changed"; break;
      case 136: error_string="off quotes"; break;
      case 137: error_string="Broker is busy"; break;
      case 138: error_string="New prices"; break;
      case 139: error_string="Order is locked."; break;
      case 140: error_string="long positions only Allowed."; break;
      case 141: error_string="Too many requests"; break;
      case 145: error_string="Modification denied because order too close to market"; break;
      case 146: error_string="trade context is busy."; break;
      case 147: error_string="Using the expiration date of the warrant is prohibited broker"; break;
      case 148: error_string="Amount of open and pending orders has reached the limit set by the broker";break;
      case 149: error_string="An attempt to open an order opposite to the existing one when hedging is disabled"; break;
      case 150: error_string="An attempt to close an order contravening the FIFO rule";break;

      // ---- Error codes run MQL4 programs:

      case 4000: error_string="No error"; break;
      case 4001: error_string="Wrong function pointer"; break;
      case 4002: error_string="array Index is out of range"; break;
      case 4003: error_string="No memory to stack functions"; break;
      case 4004: error_string="stack Overflow after recursive call"; break;
      case 4005: error_string="not enough stack for parameter passing"; break;
      case 4006: error_string="No memory for parameter string"; break;
      case 4007: error_string="No memory for temp string"; break;
      case 4008: error_string="not initialized string"; break;
      case 4009: error_string="not initialized string in array"; break;
      case 4010: error_string="No memory for string array"; break;
      case 4011: error_string="Too long string"; break;
      case 4012: error_string="Remainder from division by zero"; break;
      case 4013: error_string="zero Divide"; break;
      case 4014: error_string="Unknown command"; break;
      case 4015: error_string="Wrong jump"; break;
      case 4016: error_string="not initialized array"; break;
      case 4017: error_string="DLL Calls are not allowed"; break;
      case 4018: error_string="Cannot load library"; break;
      case 4019: error_string="Cannot call function"; break;
      case 4020: error_string="Calls external library functions are not allowed"; break;
      case 4021: error_string="not Enough memory for the string returned from function"; break;
      case 4022: error_string="System is busy"; break;
      case 4050: error_string="Wrong number of function parameters"; break;
      case 4051: error_string="Invalid function parameter value."; break;
      case 4052: error_string="Internal error string functions"; break;
      case 4053: error_string="some array Error."; break;
      case 4054: error_string="invalid use of array-timeseries"; break;
      case 4055: error_string="custom indicator Error"; break;
      case 4056: error_string="Arrays are incompatible"; break;
      case 4057: error_string="Error processing globalnej variables"; break;
      case 4058: error_string="global variable not found"; break;
      case 4059: error_string="Function is not allowed in testing mode"; break;
      case 4060: error_string="Function is not allowed"; break;
      case 4061: error_string="Error sending mail"; break;
      case 4062: error_string="Expected parameter type string"; break;
      case 4063: error_string="Expected parameter type integer"; break;
      case 4064: error_string="Expected parameter type double"; break;
      case 4065: error_string="as expected array parameter"; break;
      case 4066: error_string="Requested history data in update state"; break;
/*m*/ case 4067: error_string="Error executing trading operations"; break;
      case 4099: error_string="End of file"; break;
      case 4100: error_string="Error when working with file"; break;
      case 4101: error_string="Wrong file name"; break;
      case 4102: error_string="Too many open files"; break;
      case 4103: error_string="Cannot open file"; break;
      case 4104: error_string="Incompatible access to a file"; break;
      case 4105: error_string="No warrant is not selected"; break;
      case 4106: error_string="Unknown symbol"; break;
      case 4107: error_string="Invalid price parameter for trade function"; break;
      case 4108: error_string="Invalid ticket number"; break;
      case 4109: error_string="Trade is not allowed. You must enable the option to Allow the EA to trade in the expert properties."; break;
      case 4110: error_string="Long positions are not allowed. You need to check the expert properties."; break;
      case 4111: error_string="shorts are not allowed.. You need to check the expert properties."; break;
      case 4200: error_string="Object already exists"; break;
      case 4201: error_string="Requested an unknown object property"; break;
      case 4202: error_string="Object is not exist"; break;
      case 4203: error_string="Unknown object type"; break;
      case 4204: error_string="No object name"; break;
      case 4205: error_string="Error coordinates object"; break;
      case 4206: error_string="Not found specified subwindow"; break;
      default: error_string="Error when working with object";
     }
//----
   return(error_string);
  }


За действия эксперта после получения ошибки отвечает функция ErrorsAction().


int ErrorsAction(int error_code)
  {
   int act=0;
//----
   switch(error_code)
     {
      // ---- Error codes returned from trade server:
      case 0: Print("No error"); break;
      case 1: Print("No error, but the result is unknown"); return(0);
      case 2: Print("Common error"); return(2);
      case 3: Print("Wrong parameters"); return(0);
      case 4: Print("Trade server is busy"); return(1);
      case 5: Print("Old version of client terminal"); return(2);
      case 6: Print("No connection with trade server"); return(0);
      case 7: Print("not Enough rights"); return(2);
      case 8: Print("Too frequent requests"); return(1);
      case 9: Print("invalid operation in violation of the functioning of the server"); return(2);
      case 64: Print("Account is locked"); return(2);
      case 65: Print("Invalid account number"); return(2);
      case 128: Print("Expired expectations of the transaction"); return(0);
      case 129: Print("Invalid price"); return(1);
      case 130: Print("invalid stops"); return(0);
      case 131: Print("Wrong volume"); return(0);
      case 132: Print("Market is closed"); return(0);
      case 133: Print("Trade is disabled"); return(2);
      case 134: Print("not Enough money for the transaction"); return(2);
      case 135: Print("Price changed"); return(1);
      case 136: Print("off quotes"); return(1);
      case 137: Print("Broker is busy"); return(1);
      case 138: Print("New prices"); return(1);
      case 139: Print("Order is locked."); return(0);
      case 140: Print("long positions only Allowed."); return(2);
      case 141: Print("Too many requests"); return(1);
      case 145: Print("Modification denied because order too close to market"); return(0);
      case 146: Print("trade context is busy."); return(1);
      case 147: Print("Using the expiration date of the warrant is prohibited broker"); return(2);
      case 148: Print("Amount of open and pending orders has reached the limit set by the broker"); return(0);
      case 149: Print("An attempt to open an order opposite to the existing one when hedging is disabled"); return(2);
      case 150: Print("An attempt to close an order contravening the FIFO rule"); return(2);

      // ---- Error codes run MQL4 programs:

      case 4000: Print("No error"); return(1);
      case 4001: Print("Wrong function pointer"); return(0);
      case 4002: Print("array Index is out of range"); return(0);
      case 4003: Print("No memory to stack functions"); return(0);
      case 4004: Print("stack Overflow after recursive call"); return(0);
      case 4005: Print("not enough stack for parameter passing"); return(0);
      case 4006: Print("No memory for parameter string"); return(0);
      case 4007: Print("No memory for temp string"); return(1);
      case 4008: Print("not initialized string"); return(1);
      case 4009: Print("not initialized string in array"); return(0);
      case 4010: Print("No memory for string array"); return(0);
      case 4011: Print("Too long string"); return(0);
      case 4012: Print("Remainder from division by zero"); return(0);
      case 4013: Print("zero Divide"); return(0);
      case 4014: Print("Unknown command"); return(0);
      case 4015: Print("Wrong jump"); return(0);
      case 4016: Print("not initialized array"); return(0);
      case 4017: Print("DLL Calls are not allowed"); return(0);
      case 4018: Print("Cannot load library"); return(0);
      case 4019: Print("Cannot call function"); return(0);
      case 4020: Print("Calls external library functions are not allowed"); return(0);
      case 4021: Print("not Enough memory for the string returned from function"); return(0);
      case 4022: Print("System is busy"); return(0);
      case 4050: Print("Wrong number of function parameters"); return(0);
      case 4051: Print("Invalid function parameter value."); return(0);
      case 4052: Print("Internal error string functions"); return(0);
      case 4053: Print("some array Error."); return(0);
      case 4054: Print("invalid use of array-timeseries"); return(0);
      case 4055: Print("custom indicator Error"); return(0);
      case 4056: Print("Arrays are incompatible"); return(0);
      case 4057: Print("Error processing globalnej variables"); return(0);
      case 4058: Print("global variable not found"); return(0);
      case 4059: Print("Function is not allowed in testing mode"); return(0);
      case 4060: Print("Function is not allowed"); return(0);
      case 4061: Print("Error sending mail"); return(0);
      case 4062: Print("Expected parameter type string"); return(0);
      case 4063: Print("Expected parameter type integer"); return(0);
      case 4064: Print("Expected parameter type double"); return(0);
      case 4065: Print("as expected array parameter"); return(0);
      case 4066: Print("Requested history data in update state"); return(0);
      case 4067: Print("Error executing trading operations"); return(0);
      case 4099: Print("End of file"); return(0);
      case 4100: Print("Error when working with file"); return(0);
      case 4101: Print("Wrong file name"); return(0);
      case 4102: Print("Too many open files"); return(0);
      case 4103: Print("Cannot open file"); return(0);
      case 4104: Print("Incompatible access to a file"); return(0);
      case 4105: Print("No warrant is not selected"); return(0);
      case 4106: Print("Unknown symbol"); return(0);
      case 4107: Print("Invalid price parameter for trade function"); return(0);
      case 4108: Print("Invalid ticket number"); return(0);
      case 4109: Print("Trade is not allowed. You must enable the option to Allow the EA to trade in the expert properties."); return(2);
      case 4110: Print("Long positions are not allowed. You need to check the expert properties."); return(2);
      case 4111: Print("shorts are not allowed.. You need to check the expert properties."); return(2);
      case 4200: Print("Object already exists"); return(0);
      case 4201: Print("Requested an unknown object property"); return(0);
      case 4202: Print("Object is not exist"); return(0);
      case 4203: Print("Unknown object type"); return(0);
      case 4204: Print("No object name"); return(0);
      case 4205: Print("Error coordinates object"); return(0);
      case 4206: Print("Not found specified subwindow"); return(0);
      default: Print("Error when working with object");
     }
//----
   return(0);
  }


Результатом получения определенной ошибки будет небольшая или длительная пауза, а в исключительных случаях остановка работы эксперта.


               if(del)
                 {
                  Print("Order: "+(string)OrderTicket()+" is removed successfully");
                  break;
                 }
               if(!del)
                 {
                  err=GetLastError();
                  Print("Error(",err,") Order delete error: ",ErrorDescription(err));

                  // Блокировка работы советника
                  if(ErrorsAction(err)==2)
                    {
                     trade=false;
                     Print("Stop the Advisor!");
                     return;
                    }
                  // Длительная пауза
                  if(ErrorsAction(err)==1)
                    {
                     Sleep(1000*LongPause);
                    }
                  //  Небольшая пауза
                  if(ErrorsAction(err)==0)
                    {
                     Sleep(1000*ShortPause);
                    }
                 }


Целиком функция удаления ордеров будет выглядеть так:


//+------------------------------------------------------------------+
//| Удаление отложенных ордеров                                      |
//+------------------------------------------------------------------+
void DelOrderReal()
  {
   bool del=true;
   int err=0;

   for(int i=OrdersTotal()-1;i>=0;i--)
     {
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
        {
         if(OrderSymbol()==Symbol() && OrderMagicNumber()==Magic)
           {
            for(int k=1;k<=MaxEntry;k++)
              {
               if(!IsTesting() && (!IsExpertEnabled() || IsStopped())) break;
               while(!IsTradeAllowed()) Sleep(5000);
               if(OrderType()>1) del=OrderDelete(OrderTicket());
               if(del)
                 {
                  Print("Order: "+(string)OrderTicket()+" is removed successfully");
                  break;
                 }
               if(!del)
                 {
                  err=GetLastError();
                  Print("Error(",err,") Order delete error: ",ErrorDescription(err));

                  // Блокировка работы советника
                  if(ErrorsAction(err)==2)
                    {
                     trade=false;
                     Print("Stop the Advisor!");
                     return;
                    }
                  // Длительная пауза
                  if(ErrorsAction(err)==1)
                    {
                     Sleep(1000*LongPause);
                    }
                  //  Небольшая пауза
                  if(ErrorsAction(err)==0)
                    {
                     Sleep(1000*ShortPause);
                    }
                 }
              }
           }
        }
     }
  }


Точно таким же образом перепишем закрытие позиций: проверки, попытки, обработка ошибок:


//+------------------------------------------------------------------+
//| Закрытие позиции по типу ордера                                  |
//+------------------------------------------------------------------+
void CloseAllReal(int ot=-1)
  {
   bool cl;
   int err=0;

   for(int i=OrdersTotal()-1;i>=0;i--)
     {
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
        {
         if(OrderSymbol()==Symbol() && OrderMagicNumber()==Magic)
           {
            if(OrderType()==0 && (ot==0 || ot==-1))
              {
               for(int k=1;k<=MaxEntry;k++)
                 {
                  if(!IsTesting() && (!IsExpertEnabled() || IsStopped())) break;
                  while(!IsTradeAllowed()) Sleep(5000);

                  RefreshRates();
                  cl=OrderClose(OrderTicket(),OrderLots(),NormalizeDouble(Bid,Digits),Slip,White);
                  if(cl)
                    {
                     Print("Order: "+(string)OrderTicket()+" has been closed successfully");
                     break;
                    }
                  if(!cl)
                    {
                     err=GetLastError();
                     Print("Error(",err,") Order close error: ",ErrorDescription(err));

                     // Блокировка работы советника
                     if(ErrorsAction(err)==2)
                       {
                        trade=false;
                        Print("Stop the Advisor!");
                        return;
                       }
                     // Длительная пауза
                     if(ErrorsAction(err)==1)
                       {
                        Sleep(1000*LongPause);
                       }
                     //  Небольшая пауза
                     if(ErrorsAction(err)==0)
                       {
                        Sleep(1000*ShortPause);
                       }
                    }
                 }
              }

            if(OrderType()==1 && (ot==1 || ot==-1))
              {
               for(int k=1;k<=MaxEntry;k++)
                 {
                  if(!IsTesting() && (!IsExpertEnabled() || IsStopped())) break;
                  while(!IsTradeAllowed()) Sleep(5000);

                  RefreshRates();
                  cl=OrderClose(OrderTicket(),OrderLots(),NormalizeDouble(Ask,Digits),Slip,White);
                  if(cl)
                    {
                     Print("Order: "+(string)OrderTicket()+" has been closed successfully");
                     break;
                    }
                  if(!cl)
                    {
                     err=GetLastError();
                     Print("Error(",err,") Order close error: ",ErrorDescription(err));

                     // Блокировка работы советника
                     if(ErrorsAction(err)==2)
                       {
                        trade=false;
                        Print("Stop the Advisor!");
                        return;
                       }
                     // Длительная пауза
                     if(ErrorsAction(err)==1)
                       {
                        Sleep(1000*LongPause);
                       }
                     //  Небольшая пауза
                     if(ErrorsAction(err)==0)
                       {
                        Sleep(1000*ShortPause);
                       }
                    }
                 }
              }
           }
        }
     }
  }


В функции открытия ордера:


//+------------------------------------------------------------------+
//| Установка ордера                                                 |
//+------------------------------------------------------------------+
void PutOrder(int type,double price)
  {
   int r=0;
   color clr=Green;
   double sl=0,tp=0;

   if(type==1 || type==3 || type==5)
     {
      clr=Red;
      if(StopLoss>0)   sl=NormalizeDouble(price+StopLoss*Point,Digits);
      if(TakeProfit>0) tp=NormalizeDouble(price-TakeProfit*Point,Digits);
     }

   if(type==0 || type==2 || type==4)
     {
      clr=Blue;
      if(StopLoss>0)   sl=NormalizeDouble(price-StopLoss*Point,Digits);
      if(TakeProfit>0) tp=NormalizeDouble(price+TakeProfit*Point,Digits);
     }

   r=OrderSend(NULL,type,Lots,NormalizeDouble(price,Digits),Slip,sl,tp,"",Magic,TimeCurrent()+Expiration*3600,clr);
   return;
  }


Добавим ко всему вышеперечисленному только проверку на наличие средств, а остальном все делается также:


   if(AccountFreeMarginCheck(Symbol(),type,Lot(type))<=0)
     {
      Print("No enough money!");
      trade=false;
      return;
     }


Если не хватает средств для открытия позиции, останавливаем работу советника.


//+------------------------------------------------------------------+
//| Установка ордера                                                 |
//+------------------------------------------------------------------+
void PutOrderReal(int type,double price)
  {
   int r=0,err=0;
   color clr=Green;
   double sl=0,tp=0;

   if(type==1 || type==3 || type==5)
     {
      clr=Red;
      if(StopLoss>0)   sl=NormalizeDouble(price+StopLoss*Point,Digits);
      if(TakeProfit>0) tp=NormalizeDouble(price-TakeProfit*Point,Digits);
     }

   if(type==0 || type==2 || type==4)
     {
      clr=Blue;
      if(StopLoss>0)   sl=NormalizeDouble(price-StopLoss*Point,Digits);
      if(TakeProfit>0) tp=NormalizeDouble(price+TakeProfit*Point,Digits);
     }

   if(AccountFreeMarginCheck(Symbol(),type,Lot(type))<=0)
     {
      Print("No enough money!");
      trade=false;
      return;
     }

   for(int k=1;k<=MaxEntry;k++)
     {
      if(!IsTesting() && (!IsExpertEnabled() || IsStopped())) break;
      while(!IsTradeAllowed()) Sleep(5000);
      RefreshRates();

      r=OrderSend(NULL,type,Lots,NormalizeDouble(price,Digits),Slip,sl,tp,"",Magic,0,clr);
      if(r>0)
        {
         Print("Order is placed successfully: "+" OOP: ",price," SL: ",sl,+" TP: ",tp);
         break;
        }
      else
        {
         err=GetLastError();
         Print("Error(",err,") Order delete error: ",ErrorDescription(err));

         // Блокировка работы советника
         if(ErrorsAction(err)==2)
           {
            trade=false;
            Print("Stop the Advisor!");
            return;
           }
         // Длительная пауза
         if(ErrorsAction(err)==1)
           {
            Sleep(1000*LongPause);
           }
         //  Небольшая пауза
         if(ErrorsAction(err)==0)
           {
            Sleep(1000*ShortPause);
           }
        }
     }
   return;
  }


Проверку на стоплевел будем делать уже при установке ордера.

Модификация одного предварительно выбранного ордера будет написана по такому же алгоритму: проверяем входные параметры, кнопки, обновляем данные и т.д.:


//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void ModifyReal(double oop,double sl=0,double tp=0)
  {
   bool mod;
   double op=0,os=0,ot=0;
   int err=0;

   if(oop<=0) oop=OrderOpenPrice();
   if(sl<0 ) sl=OrderStopLoss();
   if(tp<0 ) tp=OrderTakeProfit();

   oop=NormalizeDouble(oop,Digits);
   sl=NormalizeDouble(sl,Digits);
   tp=NormalizeDouble(tp,Digits);
   op=NormalizeDouble(OrderOpenPrice() , Digits);
   os=NormalizeDouble(OrderStopLoss()  , Digits);
   ot=NormalizeDouble(OrderTakeProfit(), Digits);

   if(oop!=op || sl!=os || tp!=ot)
     {
      for(int i=1; i<=MaxEntry;i++)
        {
         if(!IsTesting() && (!IsExpertEnabled() || IsStopped())) break;
         while(!IsTradeAllowed()) Sleep(5000);
         RefreshRates();

         mod=OrderModify(OrderTicket(),oop,sl,tp,0,Yellow);
         if(mod)
           {
            Print("Modify Order: "," OOP: ",oop," SL: ",sl," TP: ",tp);
            break;
           }
         if(!mod)
           {
            err=GetLastError();
            Print("Error(",err,") modifying order: ",ErrorDescription(err));
            Print("Modify Error: "," OOP: ",OrderOpenPrice()," SL: ",sl," TP: ",tp);

            // Блокировка работы советника
            if(ErrorsAction(err)==2)
              {
               trade=false;
               Print("Stop the Advisor!");
               return;
              }
            // Длительная пауза
            if(ErrorsAction(err)==1)
              {
               Sleep(1000*300);
              }
            //  Небольшая пауза
            if(ErrorsAction(err)==0)
              {
               Sleep(1000*10);
              }
           }
        }
     }
  }


И на последок когда самые наиболее часто употребляемые функции у нас готовы, напишем советник на двух МА где будут использованы все эти функции.

При пересечении машек будет установлен отложенник на расстоянии от цены и при смене сигнала позиция будет закрыта, а если ордер не сработал он удалится и установится новый. Сопровождение позиции будет осуществляться простым тралом.

Код советника для тестера у нас будет таким:


//+------------------------------------------------------------------+
//|                                                          2MA.mq4 |
//|                                              Copyright 2016, AM2 |
//|                                      http://www.forexsystems.biz |
//+------------------------------------------------------------------+
#property copyright "Copyright 2016, AM2"
#property link      "http://www.forexsystems.biz"
#property version   "1.00"
#property strict

//--- Inputs
extern double Lots       = 0.1;      // лот
extern int StopLoss      = 2000;     // лось
extern int TakeProfit    = 2000;     // язь
extern int TrailingStop  = 250;      // трал
extern int MA1Period     = 12;       // период МА1
extern int MA2Period     = 40;       // период МА2
extern int Slip          = 30;       // реквот
extern int Shift         = 1;        // на каком баре сигнал индикатора
extern int Delta         = 100;      // расстояние от цены
extern int Magic         = 123;      // магик

datetime t=0;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
   Comment("");
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void PutOrder(int type,double price)
  {
   int r=0;
   color clr=Green;
   double sl=0,tp=0;

   if(type==1 || type==3 || type==5)
     {
      clr=Red;
      if(StopLoss>0) sl=NormalizeDouble(price+StopLoss*Point,Digits);
      if(TakeProfit>0) tp=NormalizeDouble(price-TakeProfit*Point,Digits);
     }

   if(type==0 || type==2 || type==4)
     {
      clr=Blue;
      if(StopLoss>0) sl=NormalizeDouble(price-StopLoss*Point,Digits);
      if(TakeProfit>0) tp=NormalizeDouble(price+TakeProfit*Point,Digits);
     }

   r=OrderSend(NULL,type,Lots,NormalizeDouble(price,Digits),Slip,sl,tp,"",Magic,0,clr);
   return;
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OpenOrd()
  {
   double MA11=iMA(NULL,0,MA1Period,0,0,0,Shift);
   double MA12=iMA(NULL,0,MA1Period,0,0,0,Shift+1);
   double MA21=iMA(NULL,0,MA2Period,0,0,0,Shift);
   double MA22=iMA(NULL,0,MA2Period,0,0,0,Shift+1);

   if(MA11<MA21 && MA12>MA22)
     {
      DelOrder();
      CloseAll();
      PutOrder(5,Bid-Delta*Point);
     }

   if(MA11>MA21 && MA12<MA22)
     {
      DelOrder();
      CloseAll();
      PutOrder(4,Bid+Delta*Point);
     }
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void CloseOrd()
  {
   double MA11=iMA(NULL,0,MA1Period,0,0,0,Shift);
   double MA12=iMA(NULL,0,MA1Period,0,0,0,Shift+1);
   double MA21=iMA(NULL,0,MA2Period,0,0,0,Shift);
   double MA22=iMA(NULL,0,MA2Period,0,0,0,Shift+1);

   if(MA11<MA21 && MA12>MA22)
     {
      DelOrder();
      CloseAll();
     }

   if(MA11>MA21 && MA12<MA22)
     {
      DelOrder();
      CloseAll();
     }
  }
//+------------------------------------------------------------------+
//| Удаление отложенных ордеров                                      |
//+------------------------------------------------------------------+
void DelOrder()
  {
   bool del;
   for(int i=OrdersTotal()-1;i>=0;i--)
     {
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
        {
         if(OrderSymbol()==Symbol() && OrderMagicNumber()==Magic)
           {
            if(OrderType()>1) del=OrderDelete(OrderTicket());
           }
        }
     }
  }
//+------------------------------------------------------------------+
//| Закрытие позиции по типу ордера                                  |
//+------------------------------------------------------------------+
void CloseAll(int ot=-1)
  {
   bool cl;
   for(int i=OrdersTotal()-1;i>=0;i--)
     {
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
        {
         if(OrderSymbol()==Symbol() && OrderMagicNumber()==Magic)
           {
            if(OrderType()==0 && (ot==0 || ot==-1))
              {
               RefreshRates();
               cl=OrderClose(OrderTicket(),OrderLots(),NormalizeDouble(Bid,Digits),Slip,White);
              }
            if(OrderType()==1 && (ot==1 || ot==-1))
              {
               RefreshRates();
               cl=OrderClose(OrderTicket(),OrderLots(),NormalizeDouble(Ask,Digits),Slip,White);
              }
           }
        }
     }
  }
//+------------------------------------------------------------------+
//| Простой трал                                                     |
//+------------------------------------------------------------------+
void Trailing()
  {
   bool mod;
   for(int i=OrdersTotal()-1;i>=0;i--)
     {
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
        {
         if(OrderSymbol()==Symbol() || OrderMagicNumber()==Magic)
           {
            if(OrderType()==OP_BUY)
              {
               if(Bid-OrderOpenPrice()>TrailingStop*Point)
                 {
                  if(OrderStopLoss()<Bid-TrailingStop*Point)
                    {
                     mod=OrderModify(OrderTicket(),OrderOpenPrice(),Bid-TrailingStop*Point,OrderTakeProfit(),0,Yellow);
                     return;
                    }
                 }
              }

            if(OrderType()==OP_SELL)
              {
               if((OrderOpenPrice()-Ask)>TrailingStop*Point)
                 {
                  if((OrderStopLoss()>(Ask+TrailingStop*Point)) || (OrderStopLoss()==0))
                    {
                     mod=OrderModify(OrderTicket(),OrderOpenPrice(),Ask+TrailingStop*Point,OrderTakeProfit(),0,Yellow);
                     return;
                    }
                 }
              }
           }
        }
     }
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
   if(t!=Time[0])
     {
      if(TrailingStop>0) Trailing();
      if(OrdersTotal()>0)CloseOrd();
      if(OrdersTotal()<1)OpenOrd();
      t=Time[0];
     }
  }
//+------------------------------------------------------------------+



Он будет у нас работать по ценам открытия и после оптимизации показывает неплохую кривую доходности:



Начнем потихоньку делать реальную версию с проверок всего что только можно в онините. Здесь я предпочитаю не возвращать:


return(INIT_FAILED);
return(INIT_PARAMETERS_INCORRECT);


т.к. неопытный пользователь может не понять почему не запускается советник.


//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   StopLevel=SPREAD*3;
   if(StopLoss!=0 && StopLoss<StopLevel) Alert("Incorrect Stop Loss! Should not be less than: ",StopLevel);
   if(TakeProfit!=0 && TakeProfit<StopLevel) Alert("Incorrect Take Profit! Should not be less than: ",StopLevel);
   if(TrailingStop!=0 && TrailingStop<StopLevel) Alert("Incorrect TrailingStop! Should not be less than: ",StopLevel);

   if(!IsTradeAllowed()) Alert("Allow the EA to trade!");
   if(!IsLibrariesAllowed()) Alert("Allow DLL import!");
   if(!IsExpertEnabled()) Alert("Allow startup advisors!");

   if(Lots<=0) Alert("A wrong Lot has to be greater than zero!");

   if(Slip<=0) Alert("A wrong Slip has to be greater than zero!");
   if(MA1Period<=0) Alert("A wrong MA1Period has to be greater than zero!");
   if(MA2Period<=0) Alert("A wrong MA2Period has to be greater than zero!");
   if(Delta<=0) Alert("A wrong Delta has to be greater than zero!");
   if(Shift<=0) Alert("A wrong MA1Period has to be greater than zero!");
   if(Magic<0) Alert("A wrong Shift may not be less than zero!");

   if(Lots<MarketInfo(NULL,MODE_MINLOT) || Lots>MarketInfo(NULL,MODE_MAXLOT)) Alert("Incorrect lot!");
//---
   return(INIT_SUCCEEDED);
  }


Добавим во входные переменные попытки и паузы:


extern int MaxEntry     = 10;       // количество попыток
extern int LongPause    = 300;      // длительная пауза
extern int ShortPause   = 10;       // короткая пауза


Заменим функции для тестера на реальные и добавим функции обработки ошибок. В трале и при выставлении ордера сделаем проверки на стоплевел.


if(Delta<StopLevel) Delta=(int)StopLevel;
if(TrailingStop<StopLevel) TrailingStop=(int)StopLevel;


И вот наконец то мы получили желаемое. Советник около семисот строк, где все по самому минимуму.

Код советника и еще 2 примера от других разработчиков можно скачать по ссылке: www.opentraders.ru/downloads/1256/
  • +6
  • Просмотров: 18369
  • 16 июля 2016, 19:24
  • AM2
Понравилcя материал? Не забудьте поставить плюс и поделиться в социальной сети!

Вступите в группу "Программирование на MQL", чтобы следить за обновлениями
ПРИСОЕДИНИТЬСЯ К ГРУППЕ
присоединиться
  Предыдущая запись в группе
Индикатор опционных уровней для MT4 и МТ5
Следующая запись в группе  
Делаем простейший копировщик сделок
12 июля 2016
18 июля 2016

Брокер для ваших роботов, 15 лет на рынке

Комментарии (14)

+
0
Для расшифровки кодов ошибок можно пользоваться функцией ErrorDescription из библиотеки stdlib.mq4, но лучше расположить ее в теле эксперта, это может пригодиться для маркета.
А что мешает воспользоваться импортом?
P.S. как-то так: #include <stdlib.mqh>
Редактирован: 17 июля 2016, 21:25
avatar

  27  Oxy Сообщений: 3430 - ..ιllιlι.lι.ιllι.ιlι..

  • 17 июля 2016, 21:22
+
0
В маркете так забраковали.
avatar

  35  AM2 Автор Сообщений: 16247 - Андрей

  • 17 июля 2016, 21:37
+
0
Удивлена. Индикаторы же импортируются.
avatar

  27  Oxy Сообщений: 3430 - ..ιllιlι.lι.ιllι.ιlι..

  • 17 июля 2016, 21:40
+
0
У меня вопрос: Обьясните великали разница между строчками for (index = 0; index < OrdersTotal(); index++) и
for (index = OrdersTotal() — 1; index >= 0; index--)?
Одно и тоже правильно!?
avatar

  8  Kudryashov Сообщений: 129

  • 8 октября 2016, 10:44
+
0
Объясните велика ли разница между строчками

В первом случае ордера перебираются с начала во втором с конца.
avatar

  35  AM2 Автор Сообщений: 16247 - Андрей

  • 8 октября 2016, 12:46
+
0
И второй вопрос: Как избавиться от OrderSend error 131?
avatar

  8  Kudryashov Сообщений: 129

  • 8 октября 2016, 10:46
+
0
Как избавиться от OrderSend error 131?

Задать правильный лот.
avatar

  35  AM2 Автор Сообщений: 16247 - Андрей

  • 8 октября 2016, 12:48
+
0
В том то и дело что не могу понять какой лот правильный.
Лот определяется функцией:
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
double LotsOptimized()
{
//--- Инициализация переменых ----------------------------------------
double   volume     = 0;
double   lot        = 0.01;
double   exponent   = 2;
double   count      = CountOpenOrders();
int      digits     = (int)2; //MarketInfo(Symbol(),MODE_DIGITS);
//--------------------------------------------------------------------
volume = NormalizeDouble(lot * MathPow(exponent, count),digits);
//--------------------------------------------------------------------
return(volume);
}
//+------------------------------------------------------------------+/code>
avatar

  8  Kudryashov Сообщений: 129

  • 8 октября 2016, 15:40
+
0
Вот рабочий вариант:


double Lot()
  {
   double lot=Lots;
   if(CountTrades()>0) lot=NormalizeDouble(Lots*MathPow(KLot,CountTrades()),2);
   if(lot>MaxLot)lot=Lots;
   return(lot);
  }
avatar

  35  AM2 Автор Сообщений: 16247 - Андрей

  • 8 октября 2016, 18:11
+
0
Благодарствую!
avatar

  8  Kudryashov Сообщений: 129

  • 8 октября 2016, 19:47
+
0
«Он будет у нас работать по ценам открытия»- любопытно как Вы собираетесь торговать по ценам открытия на реальном рынке? У Вас часовой график и только два раза в час роботу поступает торговый сигнал. А так вообще на Метатрейдере около 60 тиков в минуту и 3600 тиков в час
. И если среди этих 3600 будут такие что выбъют стоп-лос или тейк Профит то картина торговли будет совсем инная. Это мягко говоря. Как Вы собираетесь оградить выставленный ордер от сигналов и ихзменений на рынке в течении часа?

Я Вам скажу что торговля роботов по каждому тику говорит что это сливатор, которых в интернете тысячи.

Вы что не можете выложить ни одного прибыльного робота? Тогда зачем и кому нужны функции которые Вы описываете если они не приносят прибыль?
avatar

  0  user999 Сообщений: 1

  • 8 октября 2016, 16:00
+
0
Работа по ценам открытия (советник должен под эту работу писаться специально, а не просто ставится на тест по ценам открытия) — это как раз оптимальный способ для проверки идей.

Как Вы собираетесь оградить выставленный ордер от сигналов и ихзменений на рынке в течении часа?

Происходит только обработка сигналов на открытие и закрытие сделок по ценам открытия, но учитываются все изменения внутри бара, которые повлияют на судьбу сделки. Если был всплеск внутри бара против позиции на 150 пунктов, а стоп стоит 50, то сделка будет корректно закрыта по стопу. Никаких проблем с этим нет.
avatar

  45  Bishop Сообщений: 5802 - АЛЬФАХАМЕЦ-Машковод

  • 8 октября 2016, 16:18
+
0
Ошибка OrderSend error 131 все равно выскакивает при оптимизации ( 
Нашел на MQL4 вот такую функцию:
//+------------------------------------------------------------------+
//|  Проверяет объем ордера на корректность                          |
//+------------------------------------------------------------------+
bool CheckVolumeValue(double volume,string &description)
  {
//--- минимально допустимый объем для торговых операций
   double min_volume=SymbolInfoDouble(Symbol(),SYMBOL_VOLUME_MIN);
   if(volume<min_volume)
     {
      description=StringFormat("Объем меньше минимально допустимого SYMBOL_VOLUME_MIN=%.2f",min_volume);
      return(false);
     }

//--- максимально допустимый объем для торговых операций
   double max_volume=SymbolInfoDouble(Symbol(),SYMBOL_VOLUME_MAX);
   if(volume>max_volume)
     {
      description=StringFormat("Объем больше максимально допустимого SYMBOL_VOLUME_MAX=%.2f",max_volume);
      return(false);
     }

//--- получим минимальную градацию объема
   double volume_step=SymbolInfoDouble(Symbol(),SYMBOL_VOLUME_STEP);

   int ratio=(int)MathRound(volume/volume_step);
   if(MathAbs(ratio*volume_step-volume)>0.0000001)
     {
      description=StringFormat("Объем не является кратным минимальной градации SYMBOL_VOLUME_STEP=%.2f, ближайший корректный объем %.2f",
                               volume_step,ratio*volume_step);
      return(false);
     }
   description="Корректное значение объема";
   return(true);
  }

Вставил ее перед OrderSend в следующем виде:
if (CheckVolumeValue(iLots)==TRUE) ticket = OrderSend...

но при компиляции выскакивает ошибка: 'CheckVolumeValue' — wrong parameters count
Однако изменив функцию на:
bool CheckVolumeValue(double volume)
{
string description;
double min_volume=SymbolInfoDouble(Symbol(),SYMBOL_VOLUME_MIN);   //Минимально допустимый объем для торговых операций
if(volume<min_volume)
   {
   description=StringFormat("Объем меньше минимально допустимого SYMBOL_VOLUME_MIN=%.2f",min_volume);
   return(FALSE);
   }
double max_volume=SymbolInfoDouble(Symbol(),SYMBOL_VOLUME_MAX);   //Максимально допустимый объем для торговых операций
if(volume>max_volume)
   {
   description=StringFormat("Объем больше максимально допустимого SYMBOL_VOLUME_MAX=%.2f",max_volume);
   return(FALSE);
   }
double volume_step=SymbolInfoDouble(Symbol(),SYMBOL_VOLUME_STEP); //Получим минимальную градацию объема
int ratio=(int)MathRound(volume/volume_step);
if(MathAbs(ratio*volume_step-volume)>0.0000001)
   {
   description=StringFormat("Объем не является кратным минимальной градации SYMBOL_VOLUME_STEP=%.2f, ближайший корректный объем %.2f",
                               volume_step,ratio*volume_step);
   return(FALSE);
   }
description="Корректное значение объема";
return(TRUE);
}

компиляция прошла успешно.
В связи с вышеперечисленым шаманством… вопрос:
1. Что не так сделал в первый раз когда функция выглядела так
bool CheckVolumeValue(double volume,string &description)
?
2.Насколько критичны внесенные мной изменения?
avatar

  8  Kudryashov Сообщений: 129

  • 13 октября 2016, 20:20
+
0
Добрейшего времени суток!
Тут функцию открытия ордеров надыбал…
На сколько она правильная *tipatogo* 
В советник вставил разницы невижу
//+------------------------------------------------------------------+
//|   Функция открытия ордера                                        |
//|------------------------------------------------------------------|
//|   Параметры запроса:                                             |
//|   OpenOrder("BUY")  - Открытие ордера на покупку (BUY)           |
//|   OpenOrder("SELL") - Открытие ордера на продажу (SELL)          |
//+------------------------------------------------------------------+
void OpenOrder(string type)
{
double StopLoss = 0;
double TakeProfit = 0;
//--- Инициализация переменых ----------------------------------------
int               ticket      = 0;
string            symbol      /* Cимвол */                  = Symbol();
ENUM_ORDER_TYPE   cmd         /* Торговая операция */       = ORDER_TYPE_BUY; 
double            volume      /* Количество лотов */        = LotsOptimized();
double            price       /* Цена */                    = 0.0;
int               slippage    /* Проскальзывание */         = 3; 
double            stoploss    /* stop loss */               = 0;
double            takeprofit  /* take profit */             = 0;
string            comment     /* Комментарий */             = NULL;
int               magic       /* Идентификатор */           = MAGICMA;
datetime          expiration  /* Cрок истечения ордера */   = 0;
color             arrow_color /* Цвет */                    = clrNONE;
//--- Получим информацию по символу ----------------------------------
double bid     = MarketInfo(symbol,MODE_BID);    // Запрос значения Bid
double ask     = MarketInfo(symbol,MODE_ASK);    // Запрос значения Ask
double point   = MarketInfo(symbol,MODE_POINT);  // Запрос Point
double digits  = MarketInfo(symbol,MODE_DIGITS);  // Запрос Digits
//--------------------------------------------------------------------
//--- Подставим значения под соответствующий тип ордера --------------
if (type == "BUY")
   {
   cmd = ORDER_TYPE_BUY;
   price = NormalizeDouble(Ask,digits);
   if (StopLoss > 0) stoploss = NormalizeDouble(Bid - StopLoss * point,digits);
   if (TakeProfit > 0) takeprofit = NormalizeDouble(Ask + TakeProfit * point,digits);
   arrow_color = Green;
   }
if (type == "SELL")
   {
   cmd = ORDER_TYPE_SELL;
   price = NormalizeDouble(Bid,digits);
   if (StopLoss > 0) stoploss = NormalizeDouble(Ask + StopLoss * point,digits); 
   if (TakeProfit > 0) takeprofit = NormalizeDouble(Bid - TakeProfit * point,digits);
   arrow_color = Red;
   }
//--- Проверим достаточно ли средств для открытия ордера -------------
double free_margin=AccountFreeMarginCheck(symbol,cmd,volume);
if(free_margin<0) //Если на счету не хватает средств
   {
   string oper=(cmd==OP_BUY)? "Buy":"Sell";
   Print("Not enough money for ", oper," ",volume, " ", symbol, " Error code=",GetLastError());
   return;
   }
//--------------------------------------------------------------------
//--------------------------------------------------------------------
if(free_margin>0)
   {ticket = OrderSend(symbol,cmd,volume,price,slippage,stoploss,takeprofit,comment,magic,expiration,arrow_color);}
//--------------------------------------------------------------------
}
//+------------------------------------------------------------------+
avatar

  8  Kudryashov Сообщений: 129

  • 15 октября 2016, 18:43

Зарегистрируйтесь или авторизуйтесь, чтобы оставить комментарий