English 中文 Español Deutsch 日本語 Português
Эксперты на основе популярных торговых систем и алхимия оптимизации торгового робота (Часть 7)

Эксперты на основе популярных торговых систем и алхимия оптимизации торгового робота (Часть 7)

MetaTrader 4Торговые системы | 11 июля 2008, 08:13
3 497 16
Nikolay Kositsin
Nikolay Kositsin

Введение

Итак, с 1 июля 2008 года компания MetaQuotes Software Corp. открывает регистрацию на участие в Automated Trading Championship 2008! С моей стороны было бы несколько нелогичным упустить такую возможность и не воспользоваться случаем, продолжить цикл своих статей с изложения логики построения эксперта, который бы по всем формальным признакам вписался в условия проведения Automated Trading Championship 2008 и за весь период этого мероприятия не сделал бы ни одной грубой ошибки, за которую он бы мог быть дисквалифицирован!

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


Общая идея написания эксперта

На мой взгляд, наиболее наглядным в нашем случае будет нарисовать эскиз такого эксперта с подробным объяснением деталей его строения, которые обеспечивают корректное поведение эксперта при его взаимодействии с торговым сервером. Условиями чемпионата количество одновременно открытых позиций и выставленных отложенных ордеров равно трём. Так что достаточно разумным будет использование трёх стратегий в одном эксперте, по одной стратегии на позицию.

Для открывания лонгов и шортов в пределах одной стратегии будем использовать одинаковые алгоритмы но с разными параметрами, а для того, чтобы эти алгоритмы использовали всего одну позицию, присвоим им одинаковые магик-номера. Таким образом у нас получится шесть алгоритмов для входа в рынок, а магик-номеров всего три! В качестве алгоритма для входа я использую торговую систему, основанную на изменении направления мувинга из моей первой статьи. А для того, чтобы алгоритмы отличались друг от друга, я использую в них разные мувинги!


Код эксперта

Вот получившийся вариант кода эксперта:

//+==================================================================+
//|                                                 Exp_16_Champ.mq4 |
//|                             Copyright © 2008,   Nikolay Kositsin | 
//|                              Khabarovsk,   farria@mail.redcom.ru | 
//+==================================================================+
#property copyright "Copyright © 2008, Nikolay Kositsin"
#property link "farria@mail.redcom.ru"
//----+ +-----------------------------------------------------------------------+
//---- ВХОДНЫЕ ПАРАМЕТРЫ ЭКСПЕРТА ДЛЯ BUY СДЕЛОК 
extern bool   Test_Up1 = true;//фильтр направления расчётов сделок
extern int    Timeframe_Up1 = 60;
extern double Money_Management_Up1 = 0.1;
extern int    Length_Up1 = 4;  // глубина сглаживания 
extern int    Phase_Up1 = 100; // параметр, изменяющийся в пределах 
          //-100 ... +100, влияет на качество переходного процесса; 
extern int    IPC_Up1 = 0;/* Выбор цен, по которым производится расчёт 
индикатора (0-CLOSE, 1-OPEN, 2-HIGH, 3-LOW, 4-MEDIAN, 5-TYPICAL, 
6-WEIGHTED, 7-Heiken Ashi Close, 8-SIMPL, 9-TRENDFOLLOW, 10-0.5*TRENDFOLLOW, 
11-Heiken Ashi Low, 12-Heiken Ashi High, 13-Heiken Ashi Open, 
14-Heiken Ashi Close.) */
extern int    STOPLOSS_Up1 = 50;  // стоплосс
extern int    TAKEPROFIT_Up1 = 100; // тейкпрофит
extern bool   ClosePos_Up1 = true; // разрешение принудительного закрывания позиции
//----+ +-----------------------------------------------------------------------+
//---- ВХОДНЫЕ ПАРАМЕТРЫ ЭКСПЕРТА ДЛЯ SELL СДЕЛОК 
extern bool   Test_Dn1 = true;//фильтр направления расчётов сделок
extern int    Timeframe_Dn1 = 60;
extern double Money_Management_Dn1 = 0.1;
extern int    Length_Dn1 = 4;  // глубина сглаживания 
extern int    Phase_Dn1 = 100; // параметр, изменяющийся в пределах
         // -100 ... +100, влияет на качество переходного процесса; 
extern int    IPC_Dn1 = 0;/* Выбор цен, по которым производится расчёт 
индикатора (0-CLOSE, 1-OPEN, 2-HIGH, 3-LOW, 4-MEDIAN, 5-TYPICAL, 
6-WEIGHTED, 7-Heiken Ashi Close, 8-SIMPL, 9-TRENDFOLLOW, 10-0.5*TRENDFOLLOW, 
11-Heiken Ashi Low, 12-Heiken Ashi High, 13-Heiken Ashi Open, 
14-Heiken Ashi Close.) */
extern int   STOPLOSS_Dn1 = 50;  // стоплосс
extern int   TAKEPROFIT_Dn1 = 100; // тейкпрофит
extern bool   ClosePos_Dn1 = true; // разрешение принудительного закрывания позиции
//----+ +-----------------------------------------------------------------------+
//---- ВХОДНЫЕ ПАРАМЕТРЫ ЭКСПЕРТА ДЛЯ BUY СДЕЛОК 
extern bool   Test_Up2 = true;//фильтр направления расчётов сделок
extern int    Timeframe_Up2 = 60;
extern double Money_Management_Up2 = 0.1;
extern int    Length1_Up2 = 4;  // глубина первого сглаживания 
extern int    Phase1_Up2 = 100; // параметр первого сглаживания, 
       //изменяющийся в пределах -100 ... +100, влияет на качество 
       //переходного процесса усреднения;  
extern int    Length2_Up2 = 4;  // глубина второго сглаживания 
extern int    Phase2_Up2 = 100; // параметр второго сглаживания, 
       //изменяющийся в пределах -100 ... +100, влияет на качество 
       //переходного процесса усреднения;  
extern int    IPC_Up2 = 0;/* Выбор цен, по которым производится расчёт 
индикатора (0-CLOSE, 1-OPEN, 2-HIGH, 3-LOW, 4-MEDIAN, 5-TYPICAL, 
6-WEIGHTED, 7-Heiken Ashi Close, 8-SIMPL, 9-TRENDFOLLOW, 10-0.5*TRENDFOLLOW, 
11-Heiken Ashi Low, 12-Heiken Ashi High, 13-Heiken Ashi Open, 
14-Heiken Ashi Close.) */
extern int    STOPLOSS_Up2 = 50;  // стоплосс
extern int    TAKEPROFIT_Up2 = 100; // тейкпрофит
extern bool   ClosePos_Up2 = true; // разрешение принудительного закрывания позиции
//----+ +-----------------------------------------------------------------------+
//---- ВХОДНЫЕ ПАРАМЕТРЫ ЭКСПЕРТА ДЛЯ SELL СДЕЛОК 
extern bool   Test_Dn2 = true;//фильтр направления расчётов сделок
extern int    Timeframe_Dn2 = 60;
extern double Money_Management_Dn2 = 0.1;
extern int    Length1_Dn2 = 4;  // глубина сглаживания 
extern int    Phase1_Dn2 = 100;  // параметр первого сглаживания, 
       //изменяющийся в пределах -100 ... +100, влияет на качество 
       //переходного процесса усреднения;  
extern int    Length2_Dn2 = 4;  // глубина сглаживания 
extern int    Phase2_Dn2 = 100; // параметр второго сглаживания, 
       //изменяющийся в пределах -100 ... +100, влияет на качество 
       //переходного процесса усреднения;  
extern int    IPC_Dn2 = 0;/* Выбор цен, по которым производится расчёт 
индикатора (0-CLOSE, 1-OPEN, 2-HIGH, 3-LOW, 4-MEDIAN, 5-TYPICAL, 
6-WEIGHTED, 7-Heiken Ashi Close, 8-SIMPL, 9-TRENDFOLLOW, 10-0.5*TRENDFOLLOW, 
11-Heiken Ashi Low, 12-Heiken Ashi High, 13-Heiken Ashi Open, 
14-Heiken Ashi Close.) */
extern int   STOPLOSS_Dn2 = 50;  // стоплосс
extern int   TAKEPROFIT_Dn2 = 100; // тейкпрофит
extern bool   ClosePos_Dn2 = true; // разрешение принудительного закрывания позиции
//----+ +-----------------------------------------------------------------------+
//---- ВХОДНЫЕ ПАРАМЕТРЫ ЭКСПЕРТА ДЛЯ BUY СДЕЛОК 
extern bool   Test_Up3 = true;//фильтр направления расчётов сделок
extern int    Timeframe_Up3 = 60;
extern double Money_Management_Up3 = 0.1;
extern int    Period_Up3 = 10;  // период LSMA
extern int    Length_Up3 = 4;  // глубина сглаживания 
extern int    Phase_Up3 = 100; // параметр сглаживания, 
       //изменяющийся в пределах -100 ... +100, влияет на качество 
       //переходного процесса усреднения;  
extern int    IPC_Up3 = 0;/* Выбор цен, по которым производится расчёт 
индикатора (0-CLOSE, 1-OPEN, 2-HIGH, 3-LOW, 4-MEDIAN, 5-TYPICAL, 
6-WEIGHTED, 7-Heiken Ashi Close, 8-SIMPL, 9-TRENDFOLLOW, 10-0.5*TRENDFOLLOW, 
11-Heiken Ashi Low, 12-Heiken Ashi High, 13-Heiken Ashi Open, 
14-Heiken Ashi Close.) */
extern int    STOPLOSS_Up3 = 50;  // стоплосс
extern int    TAKEPROFIT_Up3 = 100; // тейкпрофит
extern bool   ClosePos_Up3 = true; // разрешение принудительного закрывания позиции
//----+ +-----------------------------------------------------------------------+
//---- ВХОДНЫЕ ПАРАМЕТРЫ ЭКСПЕРТА ДЛЯ SELL СДЕЛОК 
extern bool   Test_Dn3 = true;//фильтр направления расчётов сделок
extern int    Timeframe_Dn3 = 60;
extern double Money_Management_Dn3 = 0.1;
extern int    Period_Dn3 = 10;  // период LSMA
extern int    Length_Dn3 = 4;  // глубина сглаживания 
extern int    Phase_Dn3 = 100;  // параметр сглаживания, 
       //изменяющийся в пределах -100 ... +100, влияет на качество 
       //переходного процесса усреднения;  
extern int    IPC_Dn3 = 0;/* Выбор цен, по которым производится расчёт 
индикатора (0-CLOSE, 1-OPEN, 2-HIGH, 3-LOW, 4-MEDIAN, 5-TYPICAL, 
6-WEIGHTED, 7-Heiken Ashi Close, 8-SIMPL, 9-TRENDFOLLOW, 10-0.5*TRENDFOLLOW, 
11-Heiken Ashi Low, 12-Heiken Ashi High, 13-Heiken Ashi Open, 
14-Heiken Ashi Close.) */
extern int   STOPLOSS_Dn3 = 50;  // стоплосс
extern int   TAKEPROFIT_Dn3 = 100; // тейкпрофит
extern bool   ClosePos_Dn3 = true; // разрешение принудительного закрывания позиции
//----+ +-----------------------------------------------------------------------+

//---- Целые переменные для минимума расчётных баров
int MinBar_Up1, MinBar_Up2, MinBar_Up3;
int MinBar_Dn1, MinBar_Dn2, MinBar_Dn3;
//+==================================================================+
//| Custom Expert functions                                          |
//+==================================================================+
#include <Lite_EXPERT_Champ.mqh>
//+==================================================================+
//| TimeframeCheck() functions                                       |
//+==================================================================+
void TimeframeCheck(string Name, int Timeframe)
  {
//----+
   //---- Проверка значения переменной Timeframe на корректность
   if (Timeframe != 1)
    if (Timeframe != 5)
     if (Timeframe != 15)
      if (Timeframe != 30)
       if (Timeframe != 60)
        if (Timeframe != 240)
         if (Timeframe != 1440)
           Print(StringConcatenate("Параметр ",Name,
                     " не может ", "быть равным ", Timeframe, "!!!"));    
//----+ 
  }
//+==================================================================+
//| Custom Expert initialization function                            |
//+==================================================================+
int init()
  {
//---- Проверка значений переменных лонговых таймфреймов на корректность
   TimeframeCheck("Timeframe_Up1", Timeframe_Up1);
   TimeframeCheck("Timeframe_Up2", Timeframe_Up2);
   TimeframeCheck("Timeframe_Up3", Timeframe_Up3);

//---- Проверка значений переменных шортовых таймфреймов на корректность 
   TimeframeCheck("Timeframe_Dn1", Timeframe_Dn1); 
   TimeframeCheck("Timeframe_Dn2", Timeframe_Dn2); 
   TimeframeCheck("Timeframe_Dn3", Timeframe_Dn3);
   
//---- Инициализация переменных             
   MinBar_Up1 = 4 + 39 + 30;
   MinBar_Up2 = 4 + 30;
   MinBar_Up3 = 4 + Period_Up3 + 30;
   
   MinBar_Dn1 = 4 + 39 + 30;
   MinBar_Dn2 = 4 + 30;  
   MinBar_Dn3 = 4 + Period_Dn3 + 30;                                          
//---- завершение инициализации
   return(0);
  }
//+==================================================================+
//| expert deinitialization function                                 |
//+==================================================================+  
int deinit()
  {
//----+
   
    //---- Завершение деинициализации эксперта
    return(0);
//----+ 
  }
//+==================================================================+
//| Custom Expert iteration function                                 |
//+==================================================================+
int start()
  {
   //----+ Объявление локальных переменных
   int    bar;
   double Mov[3], dMov12, dMov23;
   //----+ Объявление статических переменных
   static int LastBars_Up1, LastBars_Dn1;
   static int LastBars_Up2, LastBars_Dn2;
   static int LastBars_Up3, LastBars_Dn3;
   
   static bool BUY_Sign1, BUY_Stop1, SELL_Sign1, SELL_Stop1;
   static bool BUY_Sign2, BUY_Stop2, SELL_Sign2, SELL_Stop2;
   static bool BUY_Sign3, BUY_Stop3, SELL_Sign3, SELL_Stop3;
   
   //+------------------------------------------------------------------------+
   
   //----++ КОД ДЛЯ ДЛИННЫХ ПОЗИЦИЙ
   if (Test_Up1) 
    {
      int IBARS_Up1 = iBars(NULL, Timeframe_Up1);
      
      if (IBARS_Up1 >= MinBar_Up1)
       {
         if (LastBars_Up1 != IBARS_Up1)
          {
           //----+ Иницмализация переменных 
           BUY_Sign1 = false;
           BUY_Stop1 = false;
           LastBars_Up1 = IBARS_Up1; 
           
           //----+ ВЫЧИСЛЕНИЕ ИНДИКАТОРНЫХ ЗНАЧЕНИЙ И ЗАГРУЗКА ИХ В БУФЕРЫ        
           for(bar = 1; bar <= 3; bar++)
                     Mov[bar - 1]=                  
                         iCustom(NULL, Timeframe_Up1, 
                                "JFatl", Length_Up1, Phase_Up1, 
                                                   0, IPC_Up1, 0, bar);
           
           //----+ ОПРЕДЕЛЕНИЕ СИГНАЛОВ ДЛЯ СДЕЛОК 
           dMov12 = Mov[0] - Mov[1];
           dMov23 = Mov[1] - Mov[2]; 
                                          
           if (dMov23 < 0)
              if (dMov12 > 0)
                        BUY_Sign1 = true;
                          
           if (dMov12 < 0)
                        BUY_Stop1 = true;                                           
          }
          //----+ СОВЕРШЕНИЕ СДЕЛОК
          if (!OpenBuyOrder_Ch(BUY_Sign1, 1, Money_Management_Up1, 
                                          STOPLOSS_Up1, TAKEPROFIT_Up1))
                                                                 return(-1);
          if (ClosePos_Up1)
                if (!CloseOrder_Ch(BUY_Stop1, 1))
                                        return(-1);
        }
     }
     
   //----++ КОД ДЛЯ КОРОТКИХ ПОЗИЦИЙ
   if (Test_Dn1) 
    {
      int IBARS_Dn1 = iBars(NULL, Timeframe_Dn1);
      
      if (IBARS_Dn1 >= MinBar_Dn1)
       {
         if (LastBars_Dn1 != IBARS_Dn1)
          {
           //----+ Иницмализация переменных 
           SELL_Sign1 = false;
           SELL_Stop1 = false;
           LastBars_Dn1 = IBARS_Dn1; 
           
           //----+ ВЫЧИСЛЕНИЕ ИНДИКАТОРНЫХ ЗНАЧЕНИЙ И ЗАГРУЗКА ИХ В БУФЕРЫ        
           for(bar = 1; bar <= 3; bar++)
                     Mov[bar - 1]=                  
                         iCustom(NULL, Timeframe_Dn1, 
                                "JFatl", Length_Dn1, Phase_Dn1, 
                                                   0, IPC_Dn1, 0, bar);
           
           //----+ ОПРЕДЕЛЕНИЕ СИГНАЛОВ ДЛЯ СДЕЛОК
           dMov12 = Mov[0] - Mov[1];
           dMov23 = Mov[1] - Mov[2]; 
                                           
           if (dMov23 > 0)
              if (dMov12 < 0)
                       SELL_Sign1 = true;
                          
           if (dMov12 > 0)
                       SELL_Stop1 = true;                                           
          }
          //----+ СОВЕРШЕНИЕ СДЕЛОК
          if (!OpenSellOrder_Ch(SELL_Sign1, 1, Money_Management_Dn1, 
                                            STOPLOSS_Dn1, TAKEPROFIT_Dn1))
                                                                   return(-1);
          if (ClosePos_Dn1)
                if (!CloseOrder_Ch(SELL_Stop1, 1))
                                          return(-1);
        }
     }
    //+------------------------------------------------------------------------+
    //----++ КОД ДЛЯ ДЛИННЫХ ПОЗИЦИЙ
   if (Test_Up2) 
    {
      int IBARS_Up2 = iBars(NULL, Timeframe_Up2);
      
      if (IBARS_Up2 >= MinBar_Up2)
       {
         if (LastBars_Up2 != IBARS_Up2)
          {
           //----+ Иницмализация переменных 
           BUY_Sign2 = false;
           BUY_Stop2 = false;
           LastBars_Up2 = IBARS_Up2; 
           
           //----+ ВЫЧИСЛЕНИЕ ИНДИКАТОРНЫХ ЗНАЧЕНИЙ И ЗАГРУЗКА ИХ В БУФЕРЫ        
           for(bar = 1; bar <= 3; bar++)
                     Mov[bar - 1]=                  
                         iCustom(NULL, Timeframe_Up2, 
                                "J2JMA", Length1_Up2, Length2_Up2,
                                             Phase1_Up2, Phase2_Up2,  
                                                  0, IPC_Up2, 0, bar);
           
           //----+ ОПРЕДЕЛЕНИЕ СИГНАЛОВ ДЛЯ СДЕЛОК 
           dMov12 = Mov[0] - Mov[1];
           dMov23 = Mov[1] - Mov[2]; 
                                          
           if (dMov23 < 0)
              if (dMov12 > 0)
                        BUY_Sign2 = true;
                          
           if (dMov12 < 0)
                        BUY_Stop2 = true;                                           
          }
          //----+ СОВЕРШЕНИЕ СДЕЛОК
          if (!OpenBuyOrder_Ch(BUY_Sign2, 2, Money_Management_Up2, 
                                          STOPLOSS_Up2, TAKEPROFIT_Up2))
                                                                 return(-1);
          if (ClosePos_Up2)
                if (!CloseOrder_Ch(BUY_Stop2, 2))
                                          return(-1);
        }
     }
     
   //----++ КОД ДЛЯ КОРОТКИХ ПОЗИЦИЙ
   if (Test_Dn2) 
    {
      int IBARS_Dn2 = iBars(NULL, Timeframe_Dn2);
      
      if (IBARS_Dn2 >= MinBar_Dn2)
       {
         if (LastBars_Dn2 != IBARS_Dn2)
          {
           //----+ Иницмализация переменных 
           SELL_Sign2 = false;
           SELL_Stop2 = false;
           LastBars_Dn2 = IBARS_Dn2; 
           
           //----+ ВЫЧИСЛЕНИЕ ИНДИКАТОРНЫХ ЗНАЧЕНИЙ И ЗАГРУЗКА ИХ В БУФЕРЫ        
           for(bar = 1; bar <= 3; bar++)
                     Mov[bar - 1]=                  
                         iCustom(NULL, Timeframe_Dn2, 
                                "J2JMA", Length1_Dn2, Length2_Dn2,
                                               Phase1_Dn2, Phase2_Dn2,  
                                                   0, IPC_Dn2, 0, bar);
           
           //----+ ОПРЕДЕЛЕНИЕ СИГНАЛОВ ДЛЯ СДЕЛОК
           dMov12 = Mov[0] - Mov[1];
           dMov23 = Mov[1] - Mov[2]; 
                                           
           if (dMov23 > 0)
              if (dMov12 < 0)
                       SELL_Sign2 = true;
                          
           if (dMov12 > 0)
                       SELL_Stop2 = true;                                           
          }
          //----+ СОВЕРШЕНИЕ СДЕЛОК
          if (!OpenSellOrder_Ch(SELL_Sign2, 2, Money_Management_Dn2, 
                                            STOPLOSS_Dn2, TAKEPROFIT_Dn2))
                                                                   return(-1);
          if (ClosePos_Dn2)
                if (!CloseOrder_Ch(SELL_Stop2, 2))
                                           return(-1);
        }
     }
    //+------------------------------------------------------------------------+
    //----++ КОД ДЛЯ ДЛИННЫХ ПОЗИЦИЙ
   if (Test_Up3) 
    {
      int IBARS_Up3 = iBars(NULL, Timeframe_Up3);
      
      if (IBARS_Up3 >= MinBar_Up3)
       {
         if (LastBars_Up3 != IBARS_Up3)
          {
           //----+ Иницмализация переменных 
           BUY_Sign3 = false;
           BUY_Stop3 = false;
           LastBars_Up3 = IBARS_Up3; 
           
           //----+ ВЫЧИСЛЕНИЕ ИНДИКАТОРНЫХ ЗНАЧЕНИЙ И ЗАГРУЗКА ИХ В БУФЕРЫ        
           for(bar = 1; bar <= 3; bar++)
                     Mov[bar - 1]=                  
                         iCustom(NULL, Timeframe_Up3, 
                              "JLSMA", Period_Up3, Length_Up3, Phase_Up3,  
                                                         0, IPC_Up3, 0, bar);
           
           //----+ ОПРЕДЕЛЕНИЕ СИГНАЛОВ ДЛЯ СДЕЛОК 
           dMov12 = Mov[0] - Mov[1];
           dMov23 = Mov[1] - Mov[2]; 
                                          
           if (dMov23 < 0)
              if (dMov12 > 0)
                        BUY_Sign3 = true;
                          
           if (dMov12 < 0)
                        BUY_Stop3 = true;                                           
          }
          //----+ СОВЕРШЕНИЕ СДЕЛОК
          if (!OpenBuyOrder_Ch(BUY_Sign3, 3, Money_Management_Up3, 
                                          STOPLOSS_Up3, TAKEPROFIT_Up3))
                                                                 return(-1);
          if (ClosePos_Up3)
                if (!CloseOrder_Ch(BUY_Stop3, 3))
                                          return(-1);
        }
     }
     
   //----++ КОД ДЛЯ КОРОТКИХ ПОЗИЦИЙ
   if (Test_Dn3) 
    {
      int IBARS_Dn3 = iBars(NULL, Timeframe_Dn3);
      
      if (IBARS_Dn3 >= MinBar_Dn3)
       {
         if (LastBars_Dn3 != IBARS_Dn3)
          {
           //----+ Иницмализация переменных 
           SELL_Sign3 = false;
           SELL_Stop3 = false;
           LastBars_Dn3 = IBARS_Dn3; 
           
           //----+ ВЫЧИСЛЕНИЕ ИНДИКАТОРНЫХ ЗНАЧЕНИЙ И ЗАГРУЗКА ИХ В БУФЕРЫ        
           for(bar = 1; bar <= 3; bar++)
                     Mov[bar - 1]=                  
                         iCustom(NULL, Timeframe_Dn3, 
                              "JLSMA", Period_Dn3, Length_Dn3, Phase_Dn3,  
                                                         0, IPC_Dn3, 0, bar);
                                                         
           //----+ ОПРЕДЕЛЕНИЕ СИГНАЛОВ ДЛЯ СДЕЛОК
           dMov12 = Mov[0] - Mov[1];
           dMov23 = Mov[1] - Mov[2]; 
                                           
           if (dMov23 > 0)
              if (dMov12 < 0)
                       SELL_Sign3 = true;
                          
           if (dMov12 > 0)
                       SELL_Stop3 = true;                                           
          }
          //----+ СОВЕРШЕНИЕ СДЕЛОК
          if (!OpenSellOrder_Ch(SELL_Sign3, 3, Money_Management_Dn3, 
                                            STOPLOSS_Dn3, TAKEPROFIT_Dn3))
                                                                   return(-1);
          if (ClosePos_Dn3)
                if (!CloseOrder_Ch(SELL_Stop3, 3))
                                          return(-1);
        }
     }
    //+------------------------------------------------------------------------+
//----+ 
    
    return(0);
  }
//+------------------------------------------------------------------+

Для тех, кому нужен эксперт с отсутствием чемпионатных ограничений, могут заняться экспертом Exp_16.mq4. Фактически налицо диверсификация торговых стратегий между тремя, определённым образом различающимися алгоритмами. По большому счёту мы имеем три абсолютно независимых МТС в одном эксперте. При написании кода я немного изменил названия переменных в каждой из МТС для исключения совпадений и накладок.

Для совершения торговых операций я использовал аналоги функций из файла Lite_EXPERT1.mqh, которые представлены файлом Lite_EXPERT_Champ.mqh. Для выполнения условий чемпионата эти функции потребовали минимального количества исправлений и дополнений кода. Само использование кода подобных функций в составе кода экспертов других участников чемпионата не имеет под собой никакого криминала, потому как они являются всего лишь исполнительными элементами эксперта, не имеющими никакого отношения к его интелектуальной начинке, управляющей этими элементами!

Так что особой необходимости, досконально разбираться во внутреннем устройстве этих функций и самому создавать нечто подобное, но своё, нет никакой. Вполне достаточно для их использования почитать мои предыдущие статьи. А вооще-то, по большому счёту, использование таких функций при написании экспертов даёт тот же эффект, что использование микросхем при разработке и производстве электронной техники.


Теперь я вкратце перечислю всё, что было учтено в устройстве этих функций.
1. Все функции для открывания позиций и отложенных ордеров определяют количество уже имеющихся, открытых позиций и выставленных, отложенных ордеров и, если количество таковых больше двух, то никаких действий не предпринимают.


2. Минимальное расстояние, на котором функции OpenBuyOrder_Ch(), OpenSellOrder_Ch(), OpenBuyLimitOrder_Ch(), OpenBuyStopOrder_Ch(), OpenSellLimitOrder_Ch() и OpenSellStopOrder_Ch() располагают тейкпрофит от цены открывания ордера всегда больше того, которое определяется правилами чемпионата, как пипсовочное. Минимальное расстояние для стоплосса определяется свойствами торгуемого инструмента и запрашивается с сервера. То же самое касается и минимальных расстояний до остальных, отложенных ордеров. Но тут следует учесть тот факт, что подчас отложенные ордера срабатывают по ценам, которые оказываются хуже выставленных и тейкпрофиты в таком случае тоже могут оказаться в пределах пипсовочной стратегии! Так что лучше изначально держаться от пипсовочных стратегий на весьма почтительном расстоянии, в противном случае при достаточном количестве гэпов, что для конца года очень даже и может иметь место, можно обнаружить, что эксперт лихо вписался в пипсовочную стратегию!
Но тут будет уместно будет напомнить, что ежели тейкпрофиты будут непомерно велики, то эксперт может совершить совсем мало сделок, за что его тоже могут дисквалифицировать!

3. Минимальный и максимальный размер лота для открываемой позиции, а так же минимальный шаг изменения лота, определяемые правилами чемпионата, прописаны во все эти функции значениями инициализируемых переменных. Так что в этих вещах ошибки исключены изначально!

4. Функции OpenBuyOrder_Ch() и OpenSellOrder_Ch() прежде чем открывать позицию, делают проверку величины лота этой позиции на наличие для неё достаточного количества средств на счёте и, в случае необходимости, уменьшают лот до приемлимых значений. Так что при работе с этими функциями эксперту не грозят ошибки типа "invalid trade volume" ни в какой ситуации. К сожалению, для отложенных ордеров такую коррекцию величины лота изначально выполнить невозможно по причине того, что нельзя сказать заранее, сколько будет свободных средств на счёте на момент срабатывания отложенного ордера. Так что экспертописателю следует быть достаточно внимательным при при инициализации внешних переменных Money_Management функций OpenBuyLimitOrder_Ch(), OpenBuyStopOrder_Ch(), OpenSellLimitOrder_Ch() и OpenSellStopOrder_Ch(), особенно при больших значениях стоплоссов.

5. Все функции для управления позициями выдерживают корректные паузы между торговыми операциями в зависимости от кодов возникающих при этом ошибок.

6. Функции CloseOrder_Ch(), CloseOrder_Ch() и Make_TreilingStop_Ch(), прежде чем закрывать позиции, или удалять отложенные ордера, или двигать стоплоссы, проверяют эти позиции на заморозку, и в случае наличия таковой никаких действий не предпринимают.

7. Функция CloseOrder_Ch() до закрывания позиции проверяет её профицит на условия пипсовки, и если он находится в пределах пипсовочного диапозона, то никаких действий не производит.

8. Функция Make_TreilingStop_Ch() не передвигает стоплосс в ценовой диапозон, внутри которого профит закрытой по стоплоссу позиции окажется в пределах пипсовочной зоны.

Заключение

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

Прикрепленные файлы |
EXPERTS.zip (7.88 KB)
INCLUDE.zip (21.93 KB)
indicators.zip (8.77 KB)
TESTER.zip (4.49 KB)
Последние комментарии | Перейти к обсуждению на форуме трейдеров (16)
[Удален] | 21 июл. 2008 в 10:48

Николай, добрый день !



Ещё вопрос: у вас в коде нет никаких ограничений, чтобы на реале или на демо не торговал советник ?

У меня советник на демо стоит 3 дня и ни одной сделки.

А в тестере за этот же период есть сделки.

С Уважением !

Nikolay Kositsin
Nikolay Kositsin | 21 июл. 2008 в 13:34
Stells:

Николай, добрый день !


Ещё вопрос: у вас в коде нет никаких ограничений, чтобы на реале или на демо не торговал советник ?

У меня советник на демо стоит 3 дня и ни одной сделки.

А в тестере за этот же период есть сделки.

С Уважением !

Никаких ограничений в эксперте для демо или реала нет! Код довольно простой и ошибки в нём отсутствуют, так что разбирайтесь сами, что вы могли намудрить! Может быть просто в опциях Метатрейдера забыли запрет на работу экспертов снять!
[Удален] | 5 авг. 2008 в 13:19
Не будет ли нарушением правил чемпионата использование кодов из Ваших статей для написания эксперта. На прошлом чемпионате были дисквалификации по принципу "знакомое перо".
Nikolay Kositsin
Nikolay Kositsin | 5 авг. 2008 в 17:11
FION:
Не будет ли нарушением правил чемпионата использование кодов из Ваших статей для написания эксперта. На прошлом чемпионате были дисквалификации по принципу "знакомое перо".
Ну тут, надо полагать, всё-таки вопрос не ко мне, я тут абсолютно ничегошеньки не решаю, так что едва ли могу дать какой-либо вразумительный ответ по этому поводу! Пожалуй, гораздо проще будет уточнить эти детали у устроителей Чемпионата!
[Удален] | 26 янв. 2009 в 22:43

приветствую всех!

Попробовал протестировать эксперта, ошибку 130 дает

на 10 стоплосы умножил, все равно..

Групповые файловые операции Групповые файловые операции
Иногда требуется проделать одинаковые операции для некоторой группы файлов. Если у вас есть список файлов, входящих в эту группу, то это не проблема. Но если этот список нужно получить самостоятельно, то возникает вопрос: "Каким образом?" В статье предлагается сделать это с помощью функций FindFirstFile() и FindNextFile(), входящих в библиотеку kernel32.dll.
Изменение внешних параметров MQL4-программ без перезагрузки Изменение внешних параметров MQL4-программ без перезагрузки
Статья описывает метод изменения внешних параметров MQL4-программ на лету без перезагрузки.
Построение горизонтальных уровней пробития при помощи фракталов Построение горизонтальных уровней пробития при помощи фракталов
В статье описывается создание индикатора, который отображает уровни поддержки/сопротивления на основе фракталов вверх и вниз.
Файловые операции через WinAPI Файловые операции через WinAPI
Исполнительная среда MQL4 основана на концепции безопасной "песочницы": чтение и запись средствами языка разрешены только в определенных папках. Это защищает пользователя MetaTrader 4 от потенциальной опасности испортить важные данные на жестком диске компьютера. Но иногда все же бывает необходимость покинуть безопасную зону. Как это сделать легко и правильно - об этом статья.