× В данной ветке можно публиковать разные коды на языке LCRYP.

compress Код бота "Storm-Regr"

1 год 5 дн. назад #868 от Administrator
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
double g_spread()
  {
   /*
     Получает разницу между ценой продажи и покупки
   */
   return ask()-bid();
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
double g_price(int real,int dir,int index)
  {
   /*
     Получает актуальную цену

     real - из какого вектора данных считать информацию (1 - тестовая, 0 - реальная) выборки
     dir - направление сигнала 0 - нет сигнала, 1 - на бай, -1 - на селл; используется для реального вектора
     index - индекс обрабатываемого сигнала (элемента в массиве)
   */
   if(real==1) // Для виртуальных (тестовых) данных
     {
      /*
       Для работы тестера используем цену открытия
       сигнал формируется на цене открытия и соответственно логично использовать данную цену для работы
       А не цену закрытия, так как для нулевого бара цена закрытия будет неизвестной.
       Более того, даже цену открытия некоторые биржи после формирования бара корректируют
      */
      return open(index);
     }
   if(real==0) // Для реальных данных
     {
      // Для работы с реальным вектором данных желательно использовать текущие цены bid и ask
      if(dir==1)
        {
         return ask();
        }
      if(dir==-1)
        {
         return bid();
        }
     }
   return 0;
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
double g_position(int real,int ind_pos_buff,int index,int spi)
  {
   /*
   Отображает информацию по текущей сформированной позиции

   real - из какого вектора данных считать информацию (1 - тестовая, 0 - реальная) выборки
   ind_pos_buff - индекс буфера (вектора данных) массива тестовой стратегии
   index - индекс обрабатываемого сигнала (элемента в массиве)
   spi - информация по коду от 1 до 22
   */
   if(real==1)
     {
      return gv_position(ind_pos_buff,index,spi); // Из массива виртуальных данных (для тестовой выборки) (0 - самая свежая позиция)
     }
   if(real==0)
     {
      // Работа проводится с самой актуальной информацией позиции (открытой) - индекс всегда = 0
      return gr_position(0,spi); // Из массива реальных данных (0 - самая свежая позиция)
     }
   return 0;
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int ShowInfo(int ind_pos_buff,int index,int spi)
  {
   /*
    Отобразит информацию над каждым сигналом (для тестовой выборки)

    ind_pos_buff - индекс буфера (вектора данных) массива с сигналами
    spi - информация для отображения по коду от 1 до 22
   */
   double value;
   if(ShowPositionInfo>0)
     {
      value=g_position(1,ind_pos_buff,index,spi); // Информация для отображения по коду от 1 до 22
      m_sdd(ind_pos_buff,index,value); // Отображаемое значение
      m_ssd(ind_pos_buff,index,"0.########"); // Маска, если надо отобразить меньше цифр, то можно так "0.####" или "0.##"
     }
   return 0;
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int SetOrder(int real,int ind_pos_buff,int index,double price,double volum,int signal)
  {
   /*
     Устанавливает ордер

     real - из какого вектора данных считать информацию (1 - тестовая, 0 - реальная) выборки
     ind_pos_buff - индекс буфера (вектора данных) массива тестовой стратегии
     index - индекс обрабатываемого сигнала (элемента в массиве)
     price - цена
     volum - объем
     signal - сигнал
   */

   if(signal==0) {return -1;} // Нет сигнала - тогда выход

   // Проверка на ограничение по объему
   int dir;
   flagVolumeError=0;s_reg(5,flagVolumeError);


   if(volum<VolumeMinMM)
     {
      volum=0;//VolumeMinMM;
      flagVolumeError=1;s_reg(5,flagVolumeError); // Код для сообщения о слишком малом объеме
      return 0;
     }
   if(volum>VolumeMaxMM)
     {
      volum=VolumeMaxMM; // Если объем больше допустимого, то урезать его
      flagVolumeError=2;s_reg(5,flagVolumeError); // Код для сообщения об урезании объема
     }
   flagDir=signal; s_reg(8,flagDir);  // Код для сообщения о выставленном сигнале
   if(real==1) // В случае виртуального массива данных
     {
      s_dbuff(ind_pos_buff,index,price,volum,0,"",signal); // В случае работы тестового вектора установить соответствующий сигнал в буфере
      if(is_opt()==0)
        {
         c_ind(ind_pos_buff,index); // пересчитать данные по позиции
         ShowInfo(ind_pos_buff,index,ShowPositionInfo); // Отобразить информацию, заданную в настройках над сигналом
        }
     }
   if(real==0) // В случае реального массива данных
     {
      /*
        В случае реального сигнала необходимо установить в регистры нужные значения,
        после чего функция обработки тиков должна обработать соответствующий запрос
        и после обработки обнулить регистры
        В реальной работе нет буфера данных, информация о позиции формируется исходя из
        исторических данных по торговле, соответственно необходимо сделать реальное действие
        и подождать до его иcполнения биржей, после чего изменится реальный вектор данных
      */
      dir=g_reg(1); //проверяем - возможно работа уже в процессе (по завершению должно быть = 0)
      if(dir==0) && (signal!=0)
        {
         s_reg(1,signal); // направление храним в регистре с номерм 1
         s_reg(2,volum); // объем храним  в регистре с номерм 2
         s_reg(3,price); // цену храним  в регистре с номерм 3
        }
     }
   return 0;
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int PrintStat(int real,int ind_pos_buff,int index)
  {
   /*
     Функция отображает на чарте статистику по торговле

     real - из какого вектора данных считать информацию (1 - тестовая, 0 - реальная) выборки
     ind_pos_buff - индекс буфера (вектора данных) массива тестовой стратегии

     в линейке №2 общая статистика по результатам работы стратегии
     в линейке #3 информация о позиции на данный момент

     BalanceStrategy - баланс от торовли
     VolumeStrategy - общий суммарный объем по всем позициям, использованный в торговле за все время работы стратегии
     MaxStepStrategy - Сколько шагов догонки зафиксировано в позиции с максимумом шагов догонки.
   */
   double MaxStepStrategy,BalanceStrategy,VolumeStrategy,testerprofitability,volum,NormalBalance,BalanceX;
   BalanceStrategy=g_position(real,ind_pos_buff,index,20);
   VolumeStrategy=g_position(real,ind_pos_buff,index,21);
   MaxStepStrategy=g_position(real,ind_pos_buff,index,22);
   if(real==1)
     {
      prt(2,"TESTER ");
     }
   if(real==0)
     {
      prt(2,"REAL ");
     }
   prt_a(2,"BalanceStrategy [");
   prt_a(2,BalanceStrategy);
   prt_a(2,"] ");
   prt_a(2,"VolumeStrategy [");
   prt_a(2,VolumeStrategy);
   prt_a(2,"] ");
   prt_a(2,"MaxStepStrategy [");
   prt_a(2,MaxStepStrategy);
   prt_a(2,"] ");
   if(real==1)
     {
      testerprofitability=profitability(VolumeStrategy,BalanceStrategy,MaxStepStrategy,LimitBars);
      prt_a(2,"Profitability AVG Month [");
      prt_a(2,testerprofitability);
      prt_a(2,"%] ");
     }

   double ProfitPosition0,VolumePosition0,StepPosition;
   ProfitPosition0=g_position(real,ind_pos_buff,index,17);
   VolumePosition0=g_position(real,ind_pos_buff,index,18);
   StepPosition=g_position(real,ind_pos_buff,index,10);
   if(real==1)
     {
      prt(3,"TESTER ");
     }
   if(real==0)
     {
      prt(3,"REAL ");
     }
   if(VolumePosition0!=0)
     {
      if(VolumePosition0<0)
        {
         prt_a(3,"Sell Volume [");
         prt_a(3,abs(VolumePosition0));
         prt_a(3,"] ");
        }
      if(VolumePosition0>0)
        {
         prt_a(3,"Buy Volume [");
         prt_a(3,VolumePosition0);
         prt_a(3,"] ");
        }
      prt_a(3,"Profit [");
      prt_a(3,ProfitPosition0);
      prt_a(3,"] ");
      prt_a(3,"Step [");
      prt_a(3,StepPosition);
      prt_a(3,"] ");
     }
   else
     {
      prt_a(3,"No position"); // Если нет открытой позиции
     }
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int OpenSell(int ind_pos_buff, double price, double volum)
  {
   int o_count,time_0;
   double Spread,vol_limit;
   Spread=SpreadControl();
   if(Spread>0)
     {
      flagBigSpread=1; // Флаг о превышении спреда
      return -1;
     }
   else
     {
      flagBigSpread=0;
     }
   if(volum>0)
     {
      o_count=c_trad(-1);
      if(o_count>0)
        {
         time_0=d_trad(0,-1);
         if(this_now(time_0)==1)
           {
            return -2;
           }
        }
      o_count=c_ord(-1);
      if(o_count>0)
        {
         time_0=d_ord(0,-1);
         if(this_now(time_0)==1)
           {
            return -3;
           }
        }
      /*
        Несмотря на то, что цена задана, мы все же получим свежую цену?
        так как могли быть задержки или повторные попытки отправить
        ордер, а цена могла измениться уже
      */
      price=g_price(0,-1,0); // получаем свежую цену
      double first,second;
      first=g_b_free("",1);
      second=g_b_free("",2);
      PrintNameBot();
      p_info_a("signal: ");
      InfoSignal(0,0);
      p_info_a("balance first: ");
      p_info_a(first);
      p_info_a(", balance second: ");
      p_info_a(second);
      p_info_a(" SELL: time=");
      p_info_a(gTickCount());
      p_info_a(" price=");
      p_info_a(price);
      vol_limit=check_volume(-1,0.01,volum);
      if(vol_limit<volum)
        {
         p_info_a(", bot_volume=");
         p_info_a(volum);
         volum=vol_limit;
         p_info_a(", limit_volume=");
         p_info_a(volum);
        }
      else
        {
         p_info_a(", volume=");
         p_info_a(volum);
        }
      p_info_a(", LSP=");
      p_info_a(LevelShiftPrice);
      p_info_a(", TCV=");
      p_info_a(TypeCalculateValute);
      p_info("!");
      if(EnabledAlert>0)
        {
         SendAlert(ind_pos_buff,-1,volum);
        }
      if(EnabledRealOrder==1)
        {
         send(price+LevelShiftPrice,volum,TypeCalculateValute,-1,0);
        }
      flagOrderExecuted=1;s_reg(9,flagOrderExecuted);
      s_reg(4,gTickCount());
      s_reg(1,0);
      s_reg(2,0);
      s_reg(3,0);
     }
   return 1;
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int OpenBuy(int ind_pos_buff, double price,double volum)
  {
   int o_count,time_0;
   double Spread,vol_limit;
   Spread=SpreadControl();
   if(Spread>0)
     {
      flagBigSpread=1; // Код о превышении спреда
      return -1;
     }
   else
     {
      flagBigSpread=0;
     }
   if(volum>0)
     {
      o_count=c_trad(1);
      if(o_count>0)
        {
         time_0=d_trad(0,1);
         if(this_now(time_0)==1)
           {
            return -2;
           }
        }
      o_count=c_ord(1);
      if(o_count>0)
        {
         time_0=d_ord(0,1);
         if(this_now(time_0)==1)
           {
            return -3;
           }
        }
      /*
        Несмотря на то, что цена задана, мы все же получим свежую цену,
        так как могли быть задержки или повторные попытки отправить
        ордер, а цена могла измениться уже
      */
      price=g_price(0,1,0); // получаем свежую цену
      double first,second;
      first=g_b_free("",1);
      second=g_b_free("",2);
      PrintNameBot();
      p_info_a("signal: ");
      InfoSignal(0,0);
      p_info_a(", balance first: ");
      p_info_a(first);
      p_info_a(", balance second: ");
      p_info_a(second);
      p_info_a(" BUY: time=");
      p_info_a(gTickCount());
      p_info_a(" price=");
      p_info_a(price);
      vol_limit=check_volume(1,0.01,volum);
      if(vol_limit<volum)
        {
         p_info_a(", bot_volume=");
         p_info_a(volum);
         volum=vol_limit;
         p_info_a(", limit_volume=");
         p_info_a(volum);
        }
      else
        {
         p_info_a(", volume=");
         p_info_a(volum);
        }
      p_info_a(", LSP=");
      p_info_a(LevelShiftPrice);
      p_info_a(", TCV=");
      p_info_a(TypeCalculateValute);
      p_info("!");
      if(EnabledAlert>0)
        {
         SendAlert(ind_pos_buff,1,volum);
        }
      if(EnabledRealOrder==1)
        {
         send(price-LevelShiftPrice,volum,TypeCalculateValute,1,0);
        }
      flagOrderExecuted=1;s_reg(9,flagOrderExecuted);
      s_reg(4,gTickCount());
      s_reg(1,0);
      s_reg(2,0);
      s_reg(3,0);
     }
   return 1;
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int GetTimeLastOrder()
  {
   /*
     Проверяет, есть ли открытый ордер на контролируемом промежутке
   */
   int o_count,time_0,time_server,delta;
   o_count=c_ord(0);
   if(o_count>0)
     {
      time_0=d_ord(0,0);
      time_server=t_server();
      delta=(time_0+PauseExecuteOrder)-time_server;
      if(delta>0)
        {
         return delta;
        }
     }
   return 0;
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int SpreadControl()
  {
   /*
     Проверяет, допустимый ли спред
   */
   flagSpreadDetal=g_spread();
   if(flagSpreadDetal>LimitSpread)
     {
      return flagSpreadDetal;
     }
   return 0;
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int OnTick()
  {
   /*
     Обработка тика

     Функция отвечает за реальное выставление ордеров
     также отображает свежую информацию для пользователя
   */
   int ind_pos_buff;
   ind_pos_buff=7;
   int New,Fix,Tim,TimeLastOrder;
   GetParam();
   flagTickStatus= 0;
   flagBigSpread = 0;
   SpreadControl();
   if(e_abot()==1)
     {
      c_real();
      New=gTickCount();
      Fix=g_reg(4);
      Tim=New-Fix;
      if((Tim<TimPause) && (Fix!=0))
        {
         flagTickStatus=3; // Код для сообщения о паузе в работе бота после отправки ордера на биржу
         flagTimeDetal=Tim;
        }
      else
        {
         TimeLastOrder=GetTimeLastOrder();
         if(TimeLastOrder>0)
           {
            flagTickStatus=4; // Код для сообщения об ожидании исполнения неисполенных ордеров на контролируемом промежутке
            flagTimeDetal=TimeLastOrder;
           }
         else
           {
            int dir;
            double volum;
            double price;
            dir=g_reg(1);
            volum=g_reg(2);
            price=g_reg(3);
            if(dir==-1)
              {
               OpenSell(ind_pos_buff,price,volum);
              }
            if(dir==1)
              {
               OpenBuy(ind_pos_buff,price,volum);
              }
            flagTickStatus=1; // Код для сообщения об ожидании сигнала
           }
        }
     }
   else
     {
      s_reg(4,0);
      flagTickStatus=2; // Код для сообщения об отключенной торговле
     }

   PrintStat(TesterStrategy,ind_pos_buff,0); // Отображение данных по стратегии

   prt(4,"Signal Info: ");
   InfoSignal(1,4);

   prt(5,"Status Info: ");
   InfoStatus(5);

   return 0;
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int SendAlert(int ind_pos_buff, int dir, double volume)
  {
   double MaxStepStrategy,VolumeStrategy;
   double idate,iprice;
   int id;
   iprice=g_price(0,dir,0); // получаем новую цену
   idate = date(0);
   if((iprice==0) || (idate==0))
     {
      return -1;
     }
   id=idonnameprim(idate);
   if(id==-1)
     {
      id=newarrow(16,idate,iprice,"pref_",idate);
      if (EnabledAlert==2)
      {
        setuparrow(id,18,1,"");
      } else
      {
        setuparrow(id,18,0,"");
      }
      setuparrow(id,15,0,"Bot: 'Storm-Regr'");
      setuparrow(id,15,1,"[enter]");
      if(dir==1)
        {
         setuparrow(id,15,1,"Order: 'BUY'");
         setuparrow(id,8,0,"Blue");
        }
      if(dir==-1)
        {
         setuparrow(id,15,1,"Order: 'SELL'");
         setuparrow(id,8,0,"Red");
        }
      setuparrow(id,15,1,"[enter]");
      setuparrow(id,15,1,"Pair: ");
      setuparrow(id,15,1,"[pair_name]");
      setuparrow(id,15,1,"[enter]");
      setuparrow(id,15,1,"Volume: ");
      setuparrow(id,15,1,volume);
      setuparrow(id,15,1,"[enter]");
      InfoSignal(2,id);
      setuparrow(id,15,1,"[enter]");
      setuparrow(id,17,1,"");
      setuparrow(id,11,2,""); // Изменим свойство 11 - задав форм-фактор сообщения из справки форм (тип 1)
      setuparrow(id,12,2,""); // Изменим свойство 12 - задав тип размер сообщения из справки размеров (тип 2)
      int alert;
      alert=0;
      setuparrow(id,9,alert,""); // Изменим свойство 9 - задав команду сигнала
     }
   return 0;
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int InfoSignal(int on_print,int linechart)
  {
   /*
    Коротко информирует в сообщении в журнале о сигнале, который создал ордер, если print = 1
    И отобраает информацию в чарте, если print = 0

    linechart - индекс строки на чарте

    Флаг flagIndSignal
     1 - сигнал от индикатора
     2 - сигнал закрытия по профиту
     3 - сигнал дополнительного закрытия
     4 - сигнал дополнительной догонки
     5 - сигнал дополнительного (против тренда)

    Флаг flagPositionSignal
     1 - сигнал начала позиции
     2 - сигнал догонки позиции
     3 - сигнал закрытия позиции по сигналу в любом случае
     4 - сигнал закрытия позиции по сигналу в профите
     5 - сигнал докупки позиции (по тренду)

    Флаг flagDir
      Отображает направление сигнала для исполнения: 0 - нет сигнала, 1 - на бай, -1 - на селл
   */
   flagIndSignal=g_reg(6);
   flagPositionSignal=g_reg(7);
   flagDir=g_reg(8);

   if(on_print==2)
     {
      if(flagIndSignal==1)
        {
         setuparrow(linechart,15,1,"IN & ");
        }
      if(flagIndSignal==2)
        {
         setuparrow(linechart,15,1,"PROFIT & ");
        }
      if(flagIndSignal==3)
        {
         setuparrow(linechart,15,1,"CLOSE_X & ");
        }
      if(flagIndSignal==4)
        {
         setuparrow(linechart,15,1,"DOG_X & ");
        }
      if(flagIndSignal==5)
        {
         setuparrow(linechart,15,1,"TREND_X & ");
        }

      if(flagPositionSignal==1)
        {
         setuparrow(linechart,15,1,"START & ");
        }
      if(flagPositionSignal==2)
        {
         setuparrow(linechart,15,1,"DOG & ");
        }
      if(flagPositionSignal==3)
        {
         setuparrow(linechart,15,1,"CLOSE_FULL & ");
        }
      if(flagPositionSignal==4)
        {
         setuparrow(linechart,15,1,"CLOSE_PROFIT & ");
        }
      if(flagPositionSignal==5)
        {
         setuparrow(linechart,15,1,"TREND & ");
        }
      setuparrow(linechart,15,1,"DIR=");
      setuparrow(linechart,15,1,flagDir);
    }

   if(on_print==1)
     {
      if(flagIndSignal==1)
        {
         prt_a(linechart,"IN & ");
        }
      if(flagIndSignal==2)
        {
         prt_a(linechart,"PROFIT & ");
        }
      if(flagIndSignal==3)
        {
         prt_a(linechart,"CLOSE_X & ");
        }
      if(flagIndSignal==4)
        {
         prt_a(linechart,"DOG_X & ");
        }
      if(flagIndSignal==5)
        {
         prt_a(linechart,"TREND_X & ");
        }

      if(flagPositionSignal==1)
        {
         prt_a(linechart,"START & ");
        }
      if(flagPositionSignal==2)
        {
         prt_a(linechart,"DOG & ");
        }
      if(flagPositionSignal==3)
        {
         prt_a(linechart,"CLOSE_FULL & ");
        }
      if(flagPositionSignal==4)
        {
         prt_a(linechart,"CLOSE_PROFIT & ");
        }
      if(flagPositionSignal==5)
        {
         prt_a(linechart,"TREND & ");
        }
      prt_a(linechart,"DIR=");
      prt_a(linechart,flagDir);
     }
   if(on_print==0)
     {
      if(flagIndSignal==1)
        {
         p_info_a("IN & ");
        }
      if(flagIndSignal==2)
        {
         p_info_a("PROFIT & ");
        }
      if(flagIndSignal==3)
        {
         p_info_a("CLOSE_X & ");
        }
      if(flagIndSignal==4)
        {
         p_info_a("DOG_X & ");
        }
      if(flagIndSignal==5)
        {
         p_info_a("TREND_X & ");
        }

      if(flagPositionSignal==1)
        {
         p_info_a("START & ");
        }
      if(flagPositionSignal==2)
        {
         p_info_a("DOG & ");
        }
      if(flagPositionSignal==3)
        {
         p_info_a("CLOSE_FULL & ");
        }
      if(flagPositionSignal==4)
        {
         p_info_a("CLOSE_PROFIT & ");
        }
      if(flagPositionSignal==5)
        {
         p_info_a("TREND & ");
        }
      p_info_a("DIR=");
      p_info_a(flagDir);
      p_info_a(" ");
     }
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int InfoStatus(int index)
  {
   /*
    Информирует о состоянии бота

    flagBigSpread - Флаг превышенного спреда

    flagOrderExecuted - Флаг исполненного ордера

    Флаг flagVolumeError
     1 - сообщение о слишком малом объеме
     2 - сообщение об урезании объема

    Флаг flagTickStatus
     1 - сообщение об отключенной торговле
     2 - сообщение о паузе в работе бота после отправки ордера на биржу
     3 - сообщение об ожидании сигнала
     4 - сообщение об ожидании исполнения неисполенных ордеров на контролируемом промежутке

    flagTimeDetal - Маркер времени
    flagSpreadDetal - Маркер спреда
   */
   double vol_limit_buy,vol_limit_sell;
   flagVolumeError=g_reg(5);
   flagOrderExecuted=g_reg(9);
   if(flagTickStatus==1)
     {
      prt_a(index,"Bot Enabled");
     }
   if(flagTickStatus==2)
     {
      prt_a(index,"Bot Disabled");
     }
   if(flagTickStatus==3)
     {
      prt_a(index,"Bot Paused (send order) ");
      prt_a(index,flagTimeDetal);
      prt_a(index," msec.");
     }
   if(flagTickStatus==4)
     {
      prt_a(index,"Bot Paused (last order not traid) ");
      prt_a(index,flagTimeDetal);
      prt_a(index," sec.");
     }
   if(flagOrderExecuted==1)
     {
      prt_a(index,", order executed");
     }
   if(flagVolumeError==1)
     {
      prt_a(index,", low volume");
     }
   if(flagVolumeError==2)
     {
      prt_a(index,", volume reduction");
     }

   prt_a(index,", spread: ");
   prt_a(index,flagSpreadDetal);
   prt_a(index,", normal ( ");
   prt_a(index,LimitSpread);
   prt_a(index," )");
   if(flagBigSpread==1)
     {
      prt_a(index,", spread too big!");
     }
   vol_limit_buy=check_volume(1,0.01,1000000);
   vol_limit_sell=check_volume(-1,0.01,1000000);
   prt(index+1,"Volume Limits: SELL=");
   prt_a(index+1,vol_limit_sell);
   prt_a(index+1,", BUY=");
   prt_a(index+1,vol_limit_buy);
  }
//+------------------------------------------------------------------+

Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.

1 год 5 дн. назад #867 от Administrator
//+------------------------------------------------------------------+
//|                                                 Storm-Regr.lcryp |
//|                                     Copyright 2018, TerminalCoin |
//|                                                      Version-1.0 |
//|                                             www.terminalcoin.com |
//+------------------------------------------------------------------+
double ValueMM,VolumeMinMM,VolumeMaxMM,IterMM,StartDepoMM;
double flagSpreadDetal,flagTimeDetal,big_kstd,small_kstd,StepTrend;
double PipsProfit,LevelShiftPrice,LimitSpread,FastShift,SlowLength;
int TypeMM,Dir,OnMartin,LimitBars,TypeCalculateValute,SlowShift;
int LimitBars,CloseLoss,ProfitIsSignal,StepMartin,FastLength,OnTrend;
int ShowPositionInfo,EnabledRealOrder,TesterStrategy,VisibleAllSignals;
int TimPause,PauseExecuteOrder,flagIndSignal,flagPositionSignal,flagDir;
int flagTickStatus,flagVolumeError,flagBigSpread,flagOrderExecuted;
int TipTarget,EnabledAlert,big_degree,big_bars,small_degree,small_bars;
int CloseIsX,DogonkaIsX;
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
/*
     Дополнительно используем константы

     Набор данных: 0 - реальный, 1 - тестовый

     Направление сигнала: 0 - нет сигнала, 1 - на бай, -1 - на селл
*/
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int OnInit()
  {
   // Regression
   s_buff(0,1,1,0,"Olive","Olive","Olive"); // первый буфер данных регрессии
   s_buff(1,1,1,0,"Green","Green","Green"); // второй буфер данных регрессии
   s_buff(2,1,1,0,"Olive","Olive","Olive"); // третий буфер данных регрессии

   // Regression
   s_buff(3,1,1,0,"Olive","Olive","Olive"); //  первый буфер данных регрессии
   s_buff(4,1,1,0,"Green","Green","Green"); //  второй буфер данных регрессии
   s_buff(5,1,1,0,"Olive","Olive","Olive"); //  третий буфер данных регрессии


   // Bot Buffers - буферы для работы бота, один - для сохранения общих сигналов,
   s_buff(6,4,1,0,"Green","Green","Green"); // буфер (вектор данных) массив со всеми сигналами

   // другой - для сохранения фильтрованных в соотретствии с обстановкой (текущей позицией) сигналов
   s_buff(7,2,1,0,"None","Blue","Red"); // буфер (вектор данных) массив с фильтрованными в соответствии с позицией сигналами

   // ===
   int id;
   id=type_add("TTargetOptimization");
   if (id>-1)
   {
     type_shift(id,0);
     type_add_item(id,"Balance");
     type_add_item(id,"Profitability");
     type_add_item(id,"BalanceV");
     type_add_item(id,"ProfitabilityS");
     type_add_item(id,"BalanceVS");
   }
   // ===

   s_par(0,"int","LimitBars",2000,0,0,0);
   lang_par(0,"Russian",0,"Ограничение баров");
   lang_par(1,"Ukrainian",0,"Обмеження барів");
   lang_par(2,"English",0,"Limitation bars");

   // ===

   s_par(1,"TRisk","TypeMM",3,0,0,0);
   lang_par(0,"Russian",1,"Тип мани-менеджмента");
   lang_par(1,"Ukrainian",1,"Тип мані-менеджменту");
   lang_par(2,"English",1,"Type of money management");
   link_par(1,"https://terminalcoin.com/help/lcryp-lang-commands#Type_money_management");

   s_par(2,"double","ValueMM",0.1,0,0,0);
   lang_par(0,"Russian",2,"Объем или риск");
   lang_par(1,"Ukrainian",2,"Об'єм чи ризик");
   lang_par(2,"English",2,"ValueMM");
   link_par(2,"https://terminalcoin.com/help/lcryp-lang-commands#ValueMM");

   s_par(3,"double","VolumeMinMM",0.035,0,0,0);
   lang_par(0,"Russian",3,"Минимально допустимый объем");
   lang_par(1,"Ukrainian",3,"Мінімально допустимий об'єм");
   lang_par(2,"English",3,"VolumeMinMM");
   link_par(3,"https://terminalcoin.com/help/lcryp-lang-commands#VolumeMinMM");

   s_par(4,"double","VolumeMaxMM",1000,0,0,0);
   lang_par(0,"Russian",4,"Максимально допустимый объем");
   lang_par(1,"Ukrainian",4,"Максимально допустимий об'єм");
   lang_par(2,"English",4,"Maximum allowable volume");
   link_par(4,"https://terminalcoin.com/help/lcryp-lang-commands#VolumeMaxMM");

   s_par(5,"double","IterMM",1.3,1.0,0.01,3.0);
   lang_par(0,"Russian",5,"Способ коррекции объема");
   lang_par(1,"Ukrainian",5,"Спосіб корекції об'єму");
   lang_par(2,"English",5,"IterMM");
   link_par(5,"https://terminalcoin.com/help/lcryp-lang-commands#IterMM");

   s_par(6,"double","StartDepoMM",2,0,0,0);
   lang_par(0,"Russian",6,"Депозит для расчета риска (сумма)");
   lang_par(1,"Ukrainian",6,"Депозит для розрахунку ризику (сума)");
   lang_par(2,"English",6,"Deposit for risk calculation (sum)");
   link_par(6,"https://terminalcoin.com/help/lcryp-lang-commands#StartDepoMM");

   s_par(7,"TTypeCalculateValute","TypeCalculateValute",0,0,0,0);
   lang_par(0,"Russian",7,"Перерасчет объема");
   lang_par(1,"Ukrainian",7,"Перерахунок об'єму");
   lang_par(2,"English",7,"Volume recalculation");
   link_par(7,"https://terminalcoin.com/help/lcryp-lang-commands#Recalculation_volume");

   // ===

   s_par(8,"boolean","OnMartin",1,0,0,0);
   lang_par(0,"Russian",8,"Сеточный догонки");
   lang_par(1,"Ukrainian",8,"Режим догонки");
   lang_par(2,"English",8,"Grid mode");
   link_par(8,"https://terminalcoin.com/help/lcryp-lang-commands#OnMartin");

   s_par(9,"double","StepMartin",0.002,0.0002,0.0001,0.002);
   lang_par(0,"Russian",9,"Шаг сетки");
   lang_par(1,"Ukrainian",9,"Крок сітки");
   lang_par(2,"English",9,"StepMartin");
   link_par(9,"https://terminalcoin.com/help/lcryp-lang-commands#StepMartin");

   s_par(10,"boolean","ProfitIsSignal",1,0,0,0);
   lang_par(0,"Russian",10,"Закрытие по профиту как по сигналу");
   lang_par(1,"Ukrainian",10,"Закриття по профіту як по сигналу");
   lang_par(2,"English",10,"ProfitIsSignal");
   link_par(10,"https://terminalcoin.com/help/lcryp-lang-commands#ProfitIsSignal");

   // ===

   s_par(11,"TDir","Dir",0,0,0,0);
   lang_par(0,"Russian",11,"Направление работы");
   lang_par(1,"Ukrainian",11,"Напрямок роботи");
   lang_par(2,"English",11,"Direction of work");
   link_par(11,"https://terminalcoin.com/help/lcryp-lang-commands#Dir");

   s_par(12,"double","PipsProfit",0.002,0.0002,0.0001,0.002);
   lang_par(0,"Russian",12,"Профит (от линии безубытка)");
   lang_par(1,"Ukrainian",12,"Профіт (від лінії безубитку)");
   lang_par(2,"English",12,"Profit (from the breakeven line)");
   link_par(12,"https://terminalcoin.com/help/lcryp-lang-commands#PipsProfit");

   s_par(13,"boolean","CloseLoss",0,0,0,0);
   lang_par(0,"Russian",13,"Закрытие в минусе по сигналу");
   lang_par(1,"Ukrainian",13,"Закриття в мінусі по сигналу");
   lang_par(2,"English",13,"Close in minus");
   link_par(13,"https://terminalcoin.com/help/lcryp-lang-commands#CloseLoss");

   s_par(14,"double","LevelShiftPrice",0,0,0,0);
   lang_par(0,"Russian",14,"Отступ от сигнала");
   lang_par(1,"Ukrainian",14,"Відступ від сигналу");
   lang_par(2,"English",14,"Distance from signal");
   link_par(14,"https://terminalcoin.com/help/lcryp-lang-commands#LevelShiftPrice");

   s_par(15,"double","LimitSpread",0.0001,0,0,0);
   lang_par(0,"Russian",15,"Ограничения по спреду 0-нет");
   lang_par(1,"Ukrainian",15,"Обмеження по спреду 0-ні");
   lang_par(2,"English",15,"Limitation Spread 0-off");
   link_par(15,"https://terminalcoin.com/help/lcryp-lang-commands#LimitSpread");

   s_par(16,"int","TimPause",60000,0,0,0);
   lang_par(0,"Russian",16,"Пауза после открытия ордера, мсек.");
   lang_par(1,"Ukrainian",16,"Пауза після відкриття ордеру, мсек.");
   lang_par(2,"English",16,"Pause after opening order, msec.");
   link_par(16,"https://terminalcoin.com/help/lcryp-lang-commands#TimPause");

   s_par(17,"int","PauseExecuteOrder",3600,0,0,0);
   lang_par(0,"Russian",17,"Пауза для выполнения ордера, сек.");
   lang_par(1,"Ukrainian",17,"Пауза для виконання ордеру, сек.");
   lang_par(2,"English",17,"Pause for order execution, sec.");
   link_par(17,"https://terminalcoin.com/help/lcryp-lang-commands#PauseExecuteOrder");

   // ===

   s_par(18,"TShowPositionInfo","ShowPositionInfo",2,0,0,0);
   lang_par(0,"Russian",18,"Показывать заметки");
   lang_par(1,"Ukrainian",18,"Показувати замітки");
   lang_par(2,"English",18,"Show notes");
   link_par(18,"https://terminalcoin.com/help/lcryp-lang-commands#ShowPositionInfo");

   s_par(19,"boolean","TesterStrategy",1,0,0,0);
   lang_par(0,"Russian",19,"Cтратегия тестера");
   lang_par(1,"Ukrainian",19,"Стратегія тестера");
   lang_par(2,"English",19,"Tester strategy");
   link_par(19,"https://terminalcoin.com/help/lcryp-lang-commands#TesterStrategy");

   s_par(20,"boolean","VisibleAllSignals",0,0,0,0);
   lang_par(0,"Russian",20,"Показывать все сигналы");
   lang_par(1,"Ukrainian",20,"Показувати всі сигнали");
   lang_par(2,"English",20,"Show all signals");
   link_par(20,"https://terminalcoin.com/help/lcryp-lang-commands#VisibleAllSignals");

   s_par(21,"boolean","EnabledRealOrder",0,0,0,0);
   lang_par(0,"Russian",21,"Разрешить реальные ордера");
   lang_par(1,"Ukrainian",21,"Дозволити реальні ордера");
   lang_par(2,"English",21,"Allow real orders");
   link_par(21,"https://terminalcoin.com/help/lcryp-lang-commands#EnabledRealOrder");

   // ===

   s_par(22,"int","#1 Degree",5,1,1,8);
   lang_par(0,"Russian",22,"#1 Степень регрессии");
   lang_par(1,"Ukrainian",22,"#1 Степінь регресії");
   lang_par(2,"English",22,"#1 Degree");

   s_par(23,"double","#1 Kstd",2.0,0,0,0);
   lang_par(0,"Russian",23,"#1 Ширина регрессии");
   lang_par(1,"Ukrainian",23,"#1 Ширина регресії");
   lang_par(2,"English",23,"#1 Kstd");

   s_par(24,"int","#1 Bars",800,1,1,800);
   lang_par(0,"Russian",24,"#1 Количество баров регрессии");
   lang_par(1,"Ukrainian",24,"#1 Кількість барів регресії");
   lang_par(2,"English",24,"#1 Bars");

   // ===

   s_par(25,"int","#2 Degree",7,1,1,8);
   lang_par(0,"Russian",25,"#2 Степень регрессии");
   lang_par(1,"Ukrainian",25,"#2 Степінь регресії");
   lang_par(2,"English",25,"#2 Degree");

   s_par(26,"double","#2 Kstd",2.0,0,0,0);
   lang_par(0,"Russian",26,"#2 Ширина регрессии");
   lang_par(1,"Ukrainian",26,"#2 Ширина регресії");
   lang_par(2,"English",26,"#2 Kstd");

   s_par(27,"int","#2 Bars",800,1,1,800);
   lang_par(0,"Russian",27,"#2 Количество баров регрессии");
   lang_par(1,"Ukrainian",27,"#2 Кількість барів регресії");
   lang_par(2,"English",27,"#2 Bars");

   // ===

   s_par(28,"boolean","CloseIsX",1,0,1,1);
   lang_par(0,"Russian",28,"Закрыть по сигалу #2");
   lang_par(1,"Ukrainian",28,"Закрити по сигалу #2");
   lang_par(2,"English",28,"Close #2");

   s_par(29,"boolean","DogonkaIsX",1,0,1,1);
   lang_par(0,"Russian",29,"Догонка по сигалу #2");
   lang_par(1,"Ukrainian",29,"Догонка по сигалу #2");
   lang_par(2,"English",29,"Dogonka #2");

   s_par(30,"boolean","OnTrend",1,0,0,0);
   lang_par(0,"Russian",30,"Добирать по тренду");
   lang_par(1,"Ukrainian",30,"Добирати по тренду");
   lang_par(2,"English",30,"OnTrend");

   s_par(31,"double","StepTrend",0.0012,0.0002,0.0001,0.002);
   lang_par(0,"Russian",31,"Шаг добора по тренду");
   lang_par(1,"Ukrainian",31,"Крок добору по тренду");
   lang_par(2,"English",31,"StepTrend");

   // ===

   s_par(32,"boolean","EnabledAlert",1,0,0,0);
   lang_par(0,"Russian",32,"Включить уведомления");
   lang_par(1,"Ukrainian",32,"Включити повідомлення");
   lang_par(2,"English",32,"Enabled Alert");

   s_par(33,"TTargetOptimization","TipTarget",1,0,0,0);
   lang_par(0,"Russian",33,"Цель оптимизации");
   lang_par(1,"Ukrainian",33,"Ціль оптимізації");
   lang_par(2,"English",33,"Target Optimization");

   return 0;
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int ShowName()
  {
   // Отобразим в нулевой строке чарта название бота
   prt(0,"Storm-Regr");
   return 0;
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int PrintNameBot()
  {
   // ... в нужный момент в консоль будет выдана информация о названии бота
   p_info_a("Storm-Regr -> ");
   return 0;
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int GetParam()
  {
   /*
     Считывание входных параметров в соответствии с допустимыми ограничениями
   */

   LimitBars=g_par(0);

   TypeMM=g_par(1);
   ValueMM=g_par(2);
   VolumeMinMM=g_par(3);
   VolumeMaxMM=g_par(4);
   IterMM=g_par(5);
   StartDepoMM=g_par(6);
   TypeCalculateValute=g_par(7);

   OnMartin=g_par(8);
   StepMartin=g_par(9);
   ProfitIsSignal=g_par(10);

   Dir=g_par(11);
   PipsProfit=g_par(12);
   CloseLoss=g_par(13);
   LevelShiftPrice=g_par(14);
   LimitSpread=g_par(15);

   TimPause=g_par(16);
   PauseExecuteOrder=g_par(17);

   ShowPositionInfo=g_par(18);
   TesterStrategy=g_par(19);
   VisibleAllSignals=g_par(20);
   EnabledRealOrder=g_par(21);

   big_degree=g_par(22);
   big_kstd=g_par(23);
   big_bars=g_par(24);

   small_degree=g_par(25);
   small_kstd=g_par(26);
   small_bars=g_par(27);


   CloseIsX=g_par(28);
   DogonkaIsX=g_par(29);
   OnTrend=g_par(30);
   StepTrend=g_par(31);

   EnabledAlert=g_par(32);

   TipTarget=g_par(33);

   /*
     Коррекция входных параметров в соответствии с допустимыми ограничениями
   */

   if(StepTrend<0){StepTrend=0;}

   if(EnabledAlert<0){EnabledAlert=0;}
   if(EnabledAlert>2){EnabledAlert=2;}

   if(CloseIsX<0){CloseIsX=0;}
   if(CloseIsX>1){CloseIsX=1;}

   if(DogonkaIsX<0){DogonkaIsX=0;}
   if(DogonkaIsX>1){DogonkaIsX=1;}

   if(OnTrend<0){OnTrend=0;}
   if(OnTrend>1){OnTrend=1;}

   if(TipTarget<0){TipTarget=0;}
   if(TipTarget>4){TipTarget=4;}

   if(LimitBars<100){LimitBars=100;}
   if(LimitBars>10000){LimitBars=10000;}

   if(TypeMM<0){TypeMM=0;}
   if(TypeMM>8){TypeMM=8;}

   if(ValueMM<0){ValueMM=0;}

   if(VolumeMinMM<0){VolumeMinMM=0;}

   if(VolumeMaxMM<0){VolumeMaxMM=0;}

   if(IterMM<0){IterMM=0;}
   if(IterMM>2){IterMM=2;}

   if(StartDepoMM<0){StartDepoMM=0;}

   if(TypeCalculateValute<0){TypeCalculateValute=0;}
   if(TypeCalculateValute>4){TypeCalculateValute=4;}

   if(OnMartin<0){OnMartin=0;}
   if(OnMartin>1){OnMartin=1;}

   if(ProfitIsSignal<0){ProfitIsSignal=0;}
   if(ProfitIsSignal>1){ProfitIsSignal=1;}

   if(Dir<-1){Dir=-1;}
   if(Dir>1){Dir=1;}

   if(PipsProfit<0){PipsProfit=0;}

   if(CloseLoss<0){CloseLoss=0;}
   if(CloseLoss>1){CloseLoss=1;}


   if(TesterStrategy<0){TesterStrategy=0;}
   if(TesterStrategy>1){TesterStrategy=1;}

   if(VisibleAllSignals<0){VisibleAllSignals=0;}
   if(VisibleAllSignals>1){VisibleAllSignals=1;}

   if(EnabledRealOrder<0){EnabledRealOrder=0;}
   if(EnabledRealOrder>1){EnabledRealOrder=1;}

   if(big_degree<1){big_degree=1;}
   if(big_degree>9){big_degree=9;}

   if(big_kstd<0.1){big_kstd=0.1;}
   if(big_kstd>10){big_kstd=10;}

   if(big_bars<10){big_bars=10;}
   if(big_bars>800){big_bars=1200;}

   if(small_degree<1){small_degree=1;}
   if(small_degree>9){small_degree=9;}

   if(small_kstd<0.1){small_kstd=0.1;}
   if(small_kstd>10){small_kstd=10;}

   if(small_bars<10){small_bars=10;}
   if(small_bars>800){small_bars=1200;}

   if(LimitSpread<0){LimitSpread=0;}

   if(TimPause<30000){TimPause=30000;}

   if(PauseExecuteOrder<60){PauseExecuteOrder=60;}

   return 0;
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int OnBar()
  {
   /*
     Прочитать все входные параметры, заданные пользователем и
     установить в глобальные переменные их значения, после чего
     значения можно будет испольовать во всех функциях, вызванных из данной,
     то есть только в подпространстве функции OnBar.

     Глобально существующие значения во всех пространствах прогаммы

     Count - количество баров на чарте
     ReCount - количество новых баров на чарте
   */

   GetParam(); // Коррекция входных параметров по заданным ограничениям
   ShowName(); // Отображение имени бота на чарте

   int ind_sig_buff; // индекс буфера (вектора данных) массива со всеми сигналами
   ind_sig_buff=6;

   int ind_pos_buff; // индекс буфера (вектора данных) массива с фильтрованными в соответствии с позицией сигналами
   ind_pos_buff=7;

   // Переназначение параметров буферов данных ботов, в соответствии с настройками пользователя
   // Включить или выключить отображения всех сигналов сигнальной системы
   if(VisibleAllSignals==0)
     {
      s_buff(ind_sig_buff,4,1,0,"None","None","None");
     }
   else
     {
      s_buff(ind_sig_buff,4,1,0,"Green","Blue","Red");
     }

   // Включить или выключить отображение тестовой стратегии
   // Также данный флаг переключает комментарии с тестовой стратегии на комментарии реальной стратегии
   if(TesterStrategy==0)
     {
      s_buff(ind_pos_buff,2,1,0,"None","None","None");
     }
   else
     {
      s_buff(ind_pos_buff,2,1,0,"None","Blue","Red");
     }

   // Коррекция значения LimitBars и ReCount в соответствии с реальными данными
   if(LimitBars>0)
     {
      if(LimitBars>Count) // Если LimitBars больше реально существующего количества баров
        {
         LimitBars=Count; // Привести LimitBars к Count
        }
      if(ReCount>LimitBars) // Если реальный запрос на калькуляцию количества истории больше LimitBars
        {
         ReCount=LimitBars; // Привести ReCount к LimitBars
        }
     }
   if(ReCount<=0){return -1;}  // Если запрос на калькуляцию нулевой - то выход из функции

   double big_p_regr,big_p_regr_1;
   double small_p_regr,small_p_regr_1;
   double sq,sql,sqh;
   // Обнулим регистры, которые будем использовать
   /*
   ! Данные, записанные в регистрах, сохраняются во всех пространствах всех функций !
   */
   // Для передачи информации между разными подпространствами
   s_reg(1,0); // Хранит направление
   s_reg(2,0); // Хранит объем
   s_reg(3,0); // Хранит цену
   s_reg(4,0); // Дополнительно для работы с паузой
   s_reg(5,0); // Для хранения информации о статусе объема
   s_reg(6,0);
   s_reg(7,0);
   s_reg(8,0);
   s_reg(9,0);
   int i; // Індекс обрабатываемого бара
   /*
     На старте обрабатываются все бары, в последствии - только новые,
     количество для калькуляции задается значением ReCount
     Движения от самого старого бара (ReCount) к самому новому (нулевому)
   */
   for(i=ReCount;i>=0;i=i-1)
     {
      // Обработка сигнального индикатора
      big_p_regr=regr(i+1,big_degree,big_kstd,big_bars); // Калькуляция регрессии
      sq=g_reg(0); // Рассчитанное значение границы регрессии
      sqh=big_p_regr+sq;
      sql=big_p_regr-sq;
      s_dbuff(0,i,sqh,0,0,"",0); // Отображение верхней границы регрессии
      s_dbuff(1,i,big_p_regr,0,0,"",0); // Отображение регрессии
      s_dbuff(2,i,sql,0,0,"",0); // Отображение нижней границы регрессии

      small_p_regr=regr(i+1,small_degree,small_kstd,small_bars); // Калькуляция регрессии
      sq=g_reg(0); // Рассчитанное значение границы регрессии
      sqh=small_p_regr+sq;
      sql=small_p_regr-sq;
      s_dbuff(3,i,sqh,0,0,"",0); // Отображение верхней границы регрессии
      s_dbuff(4,i,small_p_regr,0,0,"",0); // Отображение регрессии
      s_dbuff(5,i,sql,0,0,"",0); // Отображение нижней границы регрессии
                                 // Обнуление ячеек буферов сигналов
      s_dbuff(ind_sig_buff,i,0,0,0,"",0);
      s_dbuff(ind_pos_buff,i,0,0,0,"",0);
      /*
        Для генерации сигнала надо знать предыдущиие значения сигнального индикатора
        Самый новй бар - с индексом 0, бар перед ним - с индексом 1, то есть
        индекс каждого предыдущего бара больше на +1
      */
      big_p_regr_1=g_dbuff(1,i+1);
      small_p_regr_1=g_dbuff(4,i+1);
      if(TesterStrategy==1)
        {
         // Вызов функции генерации сигнала и передача параметров о состоянии индикатора на данный момент
         gener_signal(TesterStrategy,ind_sig_buff,ind_pos_buff,i,big_p_regr,big_p_regr_1,small_p_regr,small_p_regr_1); // для тестового вектора данных
        }
      if(TesterStrategy==0) // Если пользователь задал отображение данных по реальному вектору данных
        {
         if(i==0) // Если калькуляция достигла нулевого бара (самого нового)
           {
            // Вызов функции генерации сигнала и передача параметров о состоянии индикатора на данный момент
            // Вызов функции генерации сигнала для реального вектора данных
            flagIndSignal=0;s_reg(6,flagIndSignal);
            flagPositionSignal=0;s_reg(7,flagPositionSignal);
            flagDir=0;s_reg(8,flagDir);
            flagVolumeError=0;s_reg(5,flagVolumeError);
            flagOrderExecuted=0;s_reg(9,flagOrderExecuted);
            gener_signal(TesterStrategy,ind_sig_buff,ind_pos_buff,i,big_p_regr,big_p_regr_1,small_p_regr,small_p_regr_1);
           }
         else
           {
            gener_signal(1,ind_sig_buff,ind_pos_buff,i,big_p_regr,big_p_regr_1,small_p_regr,small_p_regr_1); // для тестового вектора данных
           }
        }
     }
   if(TesterStrategy==1)
     {
      OnTick();
      OnTester(ind_pos_buff);
     }
   return 0;
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int OnTester(int ind_pos_buff)
  {
   double BalanceStrategy,MaxStep,Target,VolumeStrategy;
   BalanceStrategy=g_position(1,ind_pos_buff,0,20);
   VolumeStrategy=g_position(1,ind_pos_buff,0,21);
   MaxStep=g_position(1,ind_pos_buff,0,22);
   if((MaxStep>0) && (VolumeStrategy>0))
     {
      if(TipTarget==0)
        {
         Target=BalanceStrategy;
        }
      if(TipTarget==1)
        {
         Target=profitability(VolumeStrategy,BalanceStrategy,MaxStep,LimitBars);
        }
      if(TipTarget==2)
        {
         Target=BalanceStrategy/VolumeStrategy;
        }
      if(TipTarget==3)
        {
         Target=profitability(VolumeStrategy, BalanceStrategy, MaxStep, LimitBars);
         Target=Target/MaxStep;
        }
      if(TipTarget==4)
        {
         if(IterMM>0)
           {
            Target=BalanceStrategy/(VolumeStrategy*IterMM*MaxStep);
           }
         else
           {
            Target=BalanceStrategy/(VolumeStrategy*MaxStep);
           }
        }
     }
   else
     {
      Target=BalanceStrategy;
     }
   s_reg(0,Target);
   s_reg(1,BalanceStrategy);
   s_reg(2,VolumeStrategy);
   s_reg(3,MaxStep);
   s_reg(4,LimitBars);
   return 0;
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int gener_signal(int real,int ind_sig_buff,int ind_pos_buff,int index,double big_p_regr,double big_p_regr_1,double small_p_regr,double small_p_regr_1)
  {
   /*
     Генерация сигнала по заданным значениям индикатора

     real - из какого вектора данных считать информацию (1 - тестовая, 0 - реальная) выборки
     ind_sig_buff - индекс буфера (вектора данных) массива всех сигналов сигнальной системы
     ind_pos_buff - индекс буфера (вектора данных) массива тестовой стратегии
     index - индекс обрабатываемого сигнала (элемента в массиве)
     p_Fast_1, p_Slow_1, p_Fast, p_Slow - значения индикатора
   */
   int price; // актуальная на данный момент цена
   int signal; // Направление сигнала 0 - нет сигнала, 1 - на бай, -1 - на селл
   signal=0; // Начальная установка сигнала - 0
   price=0; // Начальная цена - 0
   flagIndSignal=0;s_reg(6,flagIndSignal);

   if(real==1)
     {
      c_ind(ind_pos_buff,index); // в случае виртуального потока обновим значения позиции по существующему вектору данных
     }
   if(real==0)
     {
      c_real(); // в случае реального потока обновим значения позиции по реальным данным
     }
   // Проверка дополнительного сигнала, который генерируется при заданном в натройках профите по позиции
   if((ProfitIsSignal==1) && (signal==0)) // Если установлена данная опция (ProfitIsSignal==1) в настройках и если нет никакого сигнала (signal==0)
     {
      signal=SignalProfit(real,ind_pos_buff,index); // Используем функцию SignalProfit для определения сигнала по профиту
      if(signal!=0)
        {
         flagIndSignal=2;s_reg(6,flagIndSignal); // Фиксируем для отображения пользователю состояния (сигнал закрытия по профиту)
        }
     }
   // Проверяем, есть ли какие-то значения  от индикатора
   if((((big_p_regr!=0) && (big_p_regr_1!=0)) && ((small_p_regr!=0) && (small_p_regr_1!=0))) && (signal==0))
     {
      // Проверка дополнительного сигнала на закрытие
      if(CloseIsX==1) && (signal==0) // Если установлена данная опция (CloseIsShift==1) в настройках и если нет никакого сигнала (signal==0)
        {
         signal=SignalCloseX(real,ind_pos_buff,index,small_p_regr,small_p_regr_1); // Используем функцию SignalCloseShift для определения сигнала по профиту
         if(signal!=0)
           {
            flagIndSignal=3;s_reg(6,flagIndSignal); // Фиксируем для отображения пользователю состояния
           }
        }
      // Проверка дополнительного сигнала на догонку по SHiftX
      if(DogonkaIsX==1) && (signal==0) // Если установлена данная опция (DogonkaIsShift==1) в настройках и если нет никакого сигнала (signal==0)
        {
         signal=SignalDogonkaX(real,ind_pos_buff,index,small_p_regr,small_p_regr_1); // Используем функцию SignalDogonkaShift для определения сигнала по профиту
         if(signal!=0)
           {
            flagIndSignal=4;s_reg(6,flagIndSignal); // Фиксируем для отображения пользователю состояния
           }
        }
      // Генерация сигнала
      // Если значение регресии p_regr_1 (предыдущий бар) меньше p_regr (поточный бар). Направлена вверх.
      // Значит зафиксировано направление, которое интерпретируем как сигнал на бай
      if((big_p_regr_1<big_p_regr) && (small_p_regr_1>small_p_regr))
        {
         signal=1; // Установим сигнал на бай (1)
         price=g_price(1,signal,index); // Получаем актуальную цену
         s_dbuff(ind_sig_buff,index,price,0,0,"",signal); // Массив всех сигналов сигнальной системы
         flagIndSignal=1;s_reg(6,flagIndSignal); // Фиксируем для отображения пользователю состояния (есть сигнал от индикатора)
        }
      // Если значение регресии p_regr_1 (предыдущий бар) больше p_regr (поточный бар). Направлена вниз.
      // Значит зафиксировано направление, которое интерпретируем как сигнал на бай
      if((big_p_regr_1>big_p_regr) && (small_p_regr_1<small_p_regr))
        {
         signal=-1; // установим сигнал на бай (-1)
         price=g_price(1,signal,index); // получаем актуальную  цену
         s_dbuff(ind_sig_buff,index,price,0,0,"",signal); // Массив всех сигналов сигнальной системы
         flagIndSignal=1;s_reg(6,flagIndSignal); // Фиксируем для отображения пользователю состояния (есть сигнал от индикатора)
        }
     }
   if(signal!=0) // В случее, если сигнал сформирован
     {
      // Используем функцию для обработки сигнала от индикатора
      // и форморования в последствии сигналов в тестовом потоке данных
      CoreBot(real,ind_sig_buff,ind_pos_buff,index,signal);
     }
   return signal;
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int SignalDogonkaX(int real,int ind_pos_buff,int index,double small_p_regr,double small_p_regr_1)
  {
   /*
   Создает дополнительный сигнал, для догонки только по ShiftX игнорируя ценовой канал

   real - с каким вектором данных работать (1 - тестовая, 0 - реальная) выборки
   ind_pos_buff - индекс буфера тестера (вектора данных)
   index - индекс обрабатываемого сигнала (элемента в массиве)
   */
   int sig;
   double VolumePosition0;
   double price,nline;
   sig=0;
   nline=g_position(real,ind_pos_buff,index,8); // узнаем уровень безубыка позиции (код 8) (комиссия задается в настройках терминала)
   if(nline!=0) // проверим, есть ли линия безубытка
     {

      VolumePosition0=g_position(real,ind_pos_buff,index,18); // узнаем объем позиции (код 18); если меньше нуля - то объем на селл и наоборот
      if((VolumePosition0<0))// && (small_p_regr_1>small_p_regr))
        {
         price=g_price(real,-1,index); // получим свежую цену на рынке
         if(((price!=0) && (price>nline)) && (small_p_regr_1<small_p_regr))
           {
            sig=-1;
           }
        }
      if((VolumePosition0>0))//  && (small_p_regr_1<small_p_regr))
        {
         price=g_price(real,1,index); // получим свежую цену на рынке
         if(((price!=0) && (price<nline)) && (small_p_regr_1>small_p_regr))
           {
            sig=1;
           }
        }
     }
   return sig; // результат функции - сигнал или 0 - если сигнала нет
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int SignalCloseX(int real,int ind_pos_buff,int index,double small_p_regr,double small_p_regr_1)
  {
   /*
   Создает дополнительный сигнал, для закрытися только по ShiftX игнорируя ценовой канал

   real - с каким вектором данных работать (1 - тестовая, 0 - реальная) выборки
   ind_pos_buff - индекс буфера тестера (вектора данных)
   index - индекс обрабатываемого сигнала (элемента в массиве)
   */
   int sig;
   double VolumePosition0;
   double price,nline;
   sig=0;
   nline=g_position(real,ind_pos_buff,index,8); // узнаем уровень безубыка позиции (код 8) (комиссия задается в настройках терминала)
   if(nline!=0) // проверим, есть ли линия безубытка
     {
      VolumePosition0=g_position(real,ind_pos_buff,index,18); // узнаем объем позиции (код 18); если меньше нуля - то объем на селл и наоборот
      if(VolumePosition0>0)
        {
         price=g_price(real,-1,index); // получим свежую цену на рынке
         if(((price!=0) && (price>nline)) && (small_p_regr_1>small_p_regr))
           {
            sig=-1;
           }
        }
      if(VolumePosition0<0)
        {
         price=g_price(real,1,index); // получим свежую цену на рынке
         if(((price!=0) && (price<nline)) && (small_p_regr_1<small_p_regr))
           {
            sig=1;
           }
        }
     }
   return sig; // результат функции - сигнал или 0 - если сигнала нет
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int SignalProfit(int real,int ind_pos_buff,int index)
  {
   /*
   Создает дополнительный сигнал, если позиция в профите в соответствии с настройкой профита заданой пользоветелем

   real - с каким вектором данных работать (1 - тестовая, 0 - реальная) выборки
   ind_pos_buff - индекс буфера тестера (вектора данных)
   index - индекс обрабатываемого сигнала (элемента в массиве)
   */
   int sig;
   double VolumePosition0;
   double price,nline;
   sig=0;
   nline=g_position(real,ind_pos_buff,index,8); // узнаем уровень безубыка позиции (код 8) (комиссия задается в настройках терминала)
   if(nline!=0) // проверим, есть ли линия безубытка
     {
      VolumePosition0=g_position(real,ind_pos_buff,index,18); // узнаем объем позиции (код 18); если меньше нуля - то объем на селл и наоборот
      if(VolumePosition0>0) // объем больше нуля, значит существует позиция на бай
        {
         price=g_price(real,1,index); // получим свежую цену на рынке
         if(price!=0) && (price>=(nline+PipsProfit))
           {
            // Если уровень безубытка откорректированного заданным пользователем значением PipsProfit
            // то есть цена выше уровня безубытка на PipsProfit, тогда генерируем сигнал на закрытие по профиту
            // Позиция открыта на бай, значит ее надо закрыть сигналом на селл.
            sig=-1;
           }
        }
      if(VolumePosition0<0) // объем меньше нуля значит существует позиция на сел
        {
         price=g_price(real,-1,index); // получим свежую цену на рынке
         if(price!=0) && (price<=(nline-PipsProfit))
           {
            // Если уровень безубытка откорректированного заданным пользователем значением PipsProfit
            // то есть цена ниже уровня безубытка на PipsProfit, тогда генерируем сигнал на закрытие по профиту
            // Позиция открыта на селл, значит ее надо закрыть сигналом на бай.
            sig=1;
           }
        }
     }
   return sig; // результат функции - сигнал или 0 - если сигнала нет
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int CoreBot(int real,double ind_sig_buff,double ind_pos_buff,int index,int signal)
  {
   /*
     Генерация сигнала по заданным значениям индикатора

     real - из какого вектора данных считать информацию (1 - тестовая, 0 - реальная) выборки
     ind_sig_buff - индекс буфера (вектора данных) массива всех сигналов сигнальной системы
     ind_pos_buff - индекс буфера (вектора данных) массива тестовой стратегии
     index - индекс обрабатываемого сигнала (элемента в массиве)
     p_Fast_1, p_Slow_1, p_Fast, p_Slow - значения индикатора
   */
   double price,volum;
   double max_price,min_price;
   double VolumePosition0,nline,prof;
   flagOrderExecuted=0; s_reg(9,flagOrderExecuted);
   flagDir=0; s_reg(8,flagDir);  // Код для сообщения о выставленном сигнале
   flagPositionSignal=0;s_reg(7,flagPositionSignal);
   VolumePosition0=g_position(real,ind_pos_buff,index,18); // узнаем объем позиции (код 18); если меньше нуля - то объем на селл и наоборот
   if(signal==1) // Индикатор генерировал сигнал на селл
     {
      price=g_price(real,1,index); // получаем свежую цену
      if((Dir==1) || (Dir==0)) // Если настройки пользователя разрешают торговать на бай (1) или в обе стороны (0)
        {
         if(VolumePosition0==0) // Если объем равен нулю, нет открытых позиций
           {
            flagPositionSignal=1;s_reg(7,flagPositionSignal); //  Информационный сигнал начала позиции
                                                              // Расчет объема в соответствии с настройками мани менеджмента
            set_dr(ind_pos_buff,index,real);
            volum=c_risk(TypeMM,ValueMM,IterMM,VolumeMinMM,VolumeMaxMM,StartDepoMM,TypeCalculateValute);
            SetOrder(real,ind_pos_buff,index,price,volum,signal); // Устанавливаем сигнал
           }
         else
           {
            // Если позиция открыта, тогда сигнал можно разрешить только исходя из правил догонки
            if(VolumePosition0>0) && (OnMartin==1) // Догонка разрешена пользователем и реальная позиция на бай
              {
               // Узнаем минимальную цену, зафиксированную в позиции на бай
               // и скорректируем ее заданным пользователем минимальным шагом отступа
               min_price=g_position(real,ind_pos_buff,index,12)-StepMartin;
               if(price<min_price) // если актуальная цена меньше минимального рубежа, тогда разрешена реализация сигнала
                 {
                  // Догоняемся только когда цена идет в противоположную сторону
                  flagPositionSignal=2;s_reg(7,flagPositionSignal); // Информационный сигнал догонки позиции
                  // Расчет объема в соответствии с настройками мани менеджмента
                  set_dr(ind_pos_buff,index,real);
                  //c_real();
                  volum=c_risk(TypeMM,ValueMM,IterMM,VolumeMinMM,VolumeMaxMM,StartDepoMM,TypeCalculateValute);
                  SetOrder(real,ind_pos_buff,index,price,volum,signal); // Устанавливаем сигнал
                 }
              }

            if(VolumePosition0>0) && (OnTrend==1)
              {
               max_price=g_position(real,ind_pos_buff,index,11)+StepTrend;
               if(price>max_price)
                 {
                  flagPositionSignal=5;s_reg(7,flagPositionSignal);
                  // Расчет объема в соответствии с настройками мани менеджмента
                  set_dr(ind_pos_buff,index,real);
                  volum=c_risk(TypeMM,ValueMM,1,VolumeMinMM,VolumeMaxMM,StartDepoMM,TypeCalculateValute);
                  SetOrder(real,ind_pos_buff,index,price,volum,signal); // Устанавливаем сигнал
                 }
              }

           }
        }
      // Дальше вариант, когда открыта позиция на селл и есть сигнал на бай,
      // тогда надо проанализировать возможноть закрытия позиции
      nline=g_position(real,ind_pos_buff,index,8); // Узнаем уровень безубыка позиции (код 8) (комиссия задается в настройках терминала)
      if((VolumePosition0<0) && (nline>0)) // Проверяем реальное направление позиции (должна быть на селл) и есть ли уровень безубытка
        {
         // VolumePosition0 меньше нуля, значит позиция на селл
         if((price<=(nline-PipsProfit)) || (CloseLoss==1)) // Два варианта закрыться
           {
            // (price<=(nline-PipsProfit)) - ... первый - если позиция в профите
            // (CloseLoss==1) - ... второй - если есть настройка пользователя закрывать позицию не смотря на профит
            if(CloseLoss==1)
              {
               flagPositionSignal=3;s_reg(7,flagPositionSignal); // Информационный сигнал закрытия позиции по сигналу в любом случае
              }
            if(price<=(nline-PipsProfit))
              {
               flagPositionSignal=4;s_reg(7,flagPositionSignal); // Информационный сигнал закрытия позиции по сигналу в профите
              }
            volum=abs(VolumePosition0); // Объем установим равным объему всей позиции, для ее полного закрытия
            SetOrder(real,ind_pos_buff,index,price,volum,signal); // Устанавливаем сигнал
           }
        }

     }

   if(signal==-1) // Индикатор генерировал сигнал на бай
     {
      price=g_price(real,-1,index); // получаем свежую цену
      if((Dir==-1) || (Dir==0)) // Если настройки пользователя разрешают торговать на селл (-1) или в обе стороны (0)
        {
         if(VolumePosition0==0) // Если объем равен нулю, нет открытых позиций
           {
            flagPositionSignal=1;s_reg(7,flagPositionSignal); // Информационный сигнал начала позициим
                                                              // Расчет объема в соответствии с настройками мани менеджмента
            set_dr(ind_pos_buff,index,real);
            volum=c_risk(TypeMM,ValueMM,IterMM,VolumeMinMM,VolumeMaxMM,StartDepoMM,TypeCalculateValute);
            SetOrder(real,ind_pos_buff,index,price,volum,signal); // Устанавливаем сигнал
           }
         else
           {
            // Если позиция открыта, то сигнал можно разрешить только исходя из правил догонки
            if(VolumePosition0<0) && (OnMartin==1) // Догонка разрешена пользователем и реальная позиция на селл
              {
               // Узнаем максимальную цену, зафиксированную в позиции на селл
               // и скорректируем ее заданным пользователем минимальным шагом отступа
               max_price=g_position(real,ind_pos_buff,index,11)+StepMartin;
               if(price>max_price) // если актуальная цена больше минимального рубежа, то разрешена реализация сигнала
                 {
                  // Догоняемся только когда цена идет в противоположную сторону
                  flagPositionSignal=2;s_reg(7,flagPositionSignal); // Информационный сигнал догонки позиции
                  // Расчет объема в соответствии с настройками мани менеджмента
                  set_dr(ind_pos_buff,index,real);
                  //c_real();
                  volum=c_risk(TypeMM,ValueMM,IterMM,VolumeMinMM,VolumeMaxMM,StartDepoMM,TypeCalculateValute);
                  SetOrder(real,ind_pos_buff,index,price,volum,signal); // Устанавливаем сигнал
                 }
              }

            if(VolumePosition0<0) && (OnTrend==1)
              {
               min_price=g_position(real,ind_pos_buff,index,12)-StepTrend;
               if(price<min_price)
                 {
                  flagPositionSignal=5;s_reg(7,flagPositionSignal); // Информационный сигнал догонки позиции
                                                                    // Расчет объема в соответствии с настройками мани менеджмента
                  set_dr(ind_pos_buff,index,real);
                  volum=c_risk(TypeMM,ValueMM,1,VolumeMinMM,VolumeMaxMM,StartDepoMM,TypeCalculateValute);
                  SetOrder(real,ind_pos_buff,index,price,volum,signal); // Устанавливаем сигнал
                 }
              }

           }
        }
      // Дальше вариант, когда открыта позиция на бай, и есть сигнал на селл
      // тогда надо проанализировать возможноть закрытия позиции
      nline=g_position(real,ind_pos_buff,index,8); // Узнаем уровень безубыка позиции (код 8) (комиссия задается в настройках терминала)
      if((VolumePosition0>0) && (nline>0)) // Проверяем реальное направление позиции (должна быть на бай) и есть ли уровень безубытка
        {
         if((price>=(nline+PipsProfit)) || (CloseLoss==1))
           {
            // (price>=(nline+PipsProfit)) - ... первый - если позиция в профите
            // (CloseLoss==1) - ... второй - если есть настройка пользователя закрывать позицию не смотря на профит
            if(CloseLoss==1)
              {
               flagPositionSignal=3;s_reg(7,flagPositionSignal); // Информационный сигнал закрытия позиции по сигналу в любом случае
              }
            if(price>=(nline+PipsProfit))
              {
               flagPositionSignal=4;s_reg(7,flagPositionSignal); // Информационный сигнал закрытия позиции по сигналу в профите
              }
            volum=abs(VolumePosition0); // Объем установим равным объему всей позиции, для ее полного закрытия
            SetOrder(real,ind_pos_buff,index,price,volum,signal); // Устанавливаем сигнал
           }
        }

     }
   return 0;
  }

Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.