Советник по обьемам

  • Автор темы Автор темы mironrzg
  • Дата начала Дата начала

JacksonZP

Новичок форума
Всем привет, возможно ли сделать тп и сл задаваемые в ручную( без кф и умножений) и вынести настройки во входные параметры?
 

mironrzg

Элитный участник
Поставил версию 1.1 настройки те же. Бешена версия думаю денег хватит:rolleyes:3.PNG
 

lsv107

Почетный гражданин
можно, проверяйте.
Коллега, я тут проходил мимо, скачал вашего робота, потестировать предложенную систему, но уж больно медленно он тестируется из-за обращения к индикатору через iCustom. Потом вспомнил, что делал расчёт значений индикатора BetterVolume в самом советнике в виде обычной функции. Я для себя изменил код вашего советника, скорость тестирования выросла в 5-6 раз. Счёл нужным поделиться с вами кодом.
Better Volume x.x:
Expand Collapse Copy
//+------------------------------------------------------------------+
//| Функция принимает переменные red,yellow,green,white,magenta      |
//| и записывает в них значения столбцов соответствующего цвета      |
//| индикатора BeterVolume                                           |
//| look_back - расчётный период индикатора                          |
//| bar - номер свечи, для которой рассчитывается значение индикатора|
//+------------------------------------------------------------------+
void GetBetterVolume(int look_back,int bar,double &red,double &yellow,double &green,double &white,double &magenta)
  {
   double Range,Value2=0,Value3=0,HiValue2=0,HiValue3=0,LoValue3=FLT_MAX,tempv2=0,tempv3=0;

   red=0;
   yellow=0;
   green=0;
   white=0;
   magenta=0;

   MqlRates rates[];
   ArraySetAsSeries(rates,true);

   if(CopyRates(_Symbol,_Period,bar,look_back,rates)<=0)
      return;

   Range=rates[0].high-rates[0].low;
   Value2=rates[0].tick_volume*Range;

   long min_volume=LONG_MAX;

   for(int j=0; j<look_back; j++)
     {
      
      if(rates[j].tick_volume<min_volume)
         min_volume=rates[j].tick_volume;

      tempv2=rates[j].tick_volume*(rates[j].high-rates[j].low);

      if(NormalizeDouble(tempv2,_Digits)>=NormalizeDouble(HiValue2,_Digits))
         HiValue2=tempv2;

      if(NormalizeDouble(rates[j].tick_volume*(rates[j].high-rates[j].low),_Digits)!=0)
        {
         double hl=rates[j].high-rates[j].low;
         if(NormalizeDouble(hl,_Digits)!=0)
            tempv3=rates[j].tick_volume/hl;
         if(tempv3>HiValue3)
            HiValue3=tempv3;
         if(tempv3<LoValue3)
            LoValue3=tempv3;
        }
     }

   if(rates[0].tick_volume==min_volume)
      yellow=double(min_volume);
   if(NormalizeDouble(Value2,_Digits)==NormalizeDouble(HiValue2,_Digits) &&
      rates[0].close>(rates[0].high+rates[0].low)/2.0)
      red=double(rates[0].tick_volume); // Climax High
   if(NormalizeDouble(Value3,_Digits)==NormalizeDouble(HiValue3,_Digits))
      green=double(rates[0].tick_volume);
   if(NormalizeDouble(Value2,_Digits)==NormalizeDouble(HiValue2,_Digits)
      && NormalizeDouble(Value3,_Digits)==NormalizeDouble(HiValue3,_Digits))
      magenta=double(rates[0].tick_volume);
   if(NormalizeDouble(Value2,_Digits)==NormalizeDouble(HiValue2,_Digits) &&
      rates[0].close<=NormalizeDouble((rates[0].high+rates[0].low)/2.0,_Digits))
      white=double(rates[0].tick_volume); // Climax Low
  }

Использование
C-подобный:
Expand Collapse Copy
double red[2],white[2];
//red[0]   = iCustom(NULL,0,"bettervolume1.4",0,"",ind_MAPeriod,ind_LookBack,0, i);
//red[1]   = iCustom(NULL,0,"bettervolume1.4",0,"",ind_MAPeriod,ind_LookBack,0, i+1);
//white[0] = iCustom(NULL,0,"bettervolume1.4",0,"",ind_MAPeriod,ind_LookBack,4, i);
//white[1] = iCustom(NULL,0,"bettervolume1.4",0,"",ind_MAPeriod,ind_LookBack,4, i+1);
      
GetBetterVolume(ind_LookBack,i,red[0],yl,gr,white[0],mg);
GetBetterVolume(ind_LookBack,i+1,red[1],yl,gr,white[1],mg);
 

MrGreen86

Гуру форума
Коллега, я тут проходил мимо, скачал вашего робота, потестировать предложенную систему, но уж больно медленно он тестируется из-за обращения к индикатору через iCustom. Потом вспомнил, что делал расчёт значений индикатора BetterVolume в самом советнике в виде обычной функции. Я для себя изменил код вашего советника, скорость тестирования выросла в 5-6 раз. Счёл нужным поделиться с вами кодом.
Better Volume x.x:
Expand Collapse Copy
//+------------------------------------------------------------------+
//| Функция принимает переменные red,yellow,green,white,magenta      |
//| и записывает в них значения столбцов соответствующего цвета      |
//| индикатора BeterVolume                                           |
//| look_back - расчётный период индикатора                          |
//| bar - номер свечи, для которой рассчитывается значение индикатора|
//+------------------------------------------------------------------+
void GetBetterVolume(int look_back,int bar,double &red,double &yellow,double &green,double &white,double &magenta)
  {
   double Range,Value2=0,Value3=0,HiValue2=0,HiValue3=0,LoValue3=FLT_MAX,tempv2=0,tempv3=0;

   red=0;
   yellow=0;
   green=0;
   white=0;
   magenta=0;

   MqlRates rates[];
   ArraySetAsSeries(rates,true);

   if(CopyRates(_Symbol,_Period,bar,look_back,rates)<=0)
      return;

   Range=rates[0].high-rates[0].low;
   Value2=rates[0].tick_volume*Range;

   long min_volume=LONG_MAX;

   for(int j=0; j<look_back; j++)
     {
     
      if(rates[j].tick_volume<min_volume)
         min_volume=rates[j].tick_volume;

      tempv2=rates[j].tick_volume*(rates[j].high-rates[j].low);

      if(NormalizeDouble(tempv2,_Digits)>=NormalizeDouble(HiValue2,_Digits))
         HiValue2=tempv2;

      if(NormalizeDouble(rates[j].tick_volume*(rates[j].high-rates[j].low),_Digits)!=0)
        {
         double hl=rates[j].high-rates[j].low;
         if(NormalizeDouble(hl,_Digits)!=0)
            tempv3=rates[j].tick_volume/hl;
         if(tempv3>HiValue3)
            HiValue3=tempv3;
         if(tempv3<LoValue3)
            LoValue3=tempv3;
        }
     }

   if(rates[0].tick_volume==min_volume)
      yellow=double(min_volume);
   if(NormalizeDouble(Value2,_Digits)==NormalizeDouble(HiValue2,_Digits) &&
      rates[0].close>(rates[0].high+rates[0].low)/2.0)
      red=double(rates[0].tick_volume); // Climax High
   if(NormalizeDouble(Value3,_Digits)==NormalizeDouble(HiValue3,_Digits))
      green=double(rates[0].tick_volume);
   if(NormalizeDouble(Value2,_Digits)==NormalizeDouble(HiValue2,_Digits)
      && NormalizeDouble(Value3,_Digits)==NormalizeDouble(HiValue3,_Digits))
      magenta=double(rates[0].tick_volume);
   if(NormalizeDouble(Value2,_Digits)==NormalizeDouble(HiValue2,_Digits) &&
      rates[0].close<=NormalizeDouble((rates[0].high+rates[0].low)/2.0,_Digits))
      white=double(rates[0].tick_volume); // Climax Low
  }

Использование
C-подобный:
Expand Collapse Copy
double red[2],white[2];
//red[0]   = iCustom(NULL,0,"bettervolume1.4",0,"",ind_MAPeriod,ind_LookBack,0, i);
//red[1]   = iCustom(NULL,0,"bettervolume1.4",0,"",ind_MAPeriod,ind_LookBack,0, i+1);
//white[0] = iCustom(NULL,0,"bettervolume1.4",0,"",ind_MAPeriod,ind_LookBack,4, i);
//white[1] = iCustom(NULL,0,"bettervolume1.4",0,"",ind_MAPeriod,ind_LookBack,4, i+1);
     
GetBetterVolume(ind_LookBack,i,red[0],yl,gr,white[0],mg);
GetBetterVolume(ind_LookBack,i+1,red[1],yl,gr,white[1],mg);
да это хороший вариант, спасибо.
еще один момент как можно ускоритьего работу, запоминать последние "wait_for_signal_bars" свечей, а не обсчитывать их каждый раз. тоже должен ускорить тестирование в несколько раз.
займусь на днях.
 

lsv107

Почетный гражданин
да это хороший вариант, спасибо.
еще один момент как можно ускоритьего работу, запоминать последние "wait_for_signal_bars" свечей, а не обсчитывать их каждый раз. тоже должен ускорить тестирование в несколько раз.
займусь на днях.
Правильно мыслите. Я вот только сомневаюсь в необходимости самого этого параметра - "wait_for_signal_bars". Насколько я понимаю, это вы его добавили в систему, чтобы отсекать слишком долгие участки ожидания сигнала. Хотя, я не очень вникал в тему.
Та функция, что я дал, избыточна, конечно, нам нужны только красные и белые "столбики", а она рассчитывает все. Для себя я вообще предельно упростил расчёт объёмов. Вот так:
Какого цвета последние bars_amount столбика индикатора BetterVolume:
Expand Collapse Copy
//+------------------------------------------------------------------+
//| OP_BUY  - bars_amount подряд красных столбика диаграммы          |
//| OP_SELL - bars_amount подряд белых столбика диаграммы            |
//| EMPTY   - все другие цвета                                       |
//+------------------------------------------------------------------+
int GetBarsState(int look_back, int index, int bars_amount=2)
  {
   int red=0,white=0;
   double Value2=0,HiValue2=0,tempv2=0;

   for(int n=index+bars_amount-1; n>=index; n--)
     {
      Value2=iVolume(_Symbol,_Period,n)*(iHigh(_Symbol,_Period,n)-iLow(_Symbol,_Period,n));

      for(int j=n; j<look_back+n; j++)
        {
         double tempv=iVolume(_Symbol,_Period,j)*(iHigh(_Symbol,_Period,j)-iLow(_Symbol,_Period,j));
         if(NormalizeDouble(tempv,_Digits)>=NormalizeDouble(HiValue2,_Digits))
            HiValue2=tempv;
        }

      if(NormalizeDouble(Value2,_Digits)==NormalizeDouble(HiValue2,_Digits))
        {
         if(iClose(_Symbol,_Period,n)>(iHigh(_Symbol,_Period,n)+iLow(_Symbol,_Period,n))/2.0)
            red++; // Climax High
         else
            if(iClose(_Symbol,_Period,n)<=(iHigh(_Symbol,_Period,n)+iLow(_Symbol,_Period,n))/2.0)
               white++; // Climax Low
        }
     }

   if(red==bars_amount)
      return(OP_BUY);
   if(white==bars_amount)
      return(OP_SELL);

   return(EMPTY);
  }
Использование:
Expand Collapse Copy
   if(time_bar!=Time[0])
     {
      time_bar = Time[0];
      for(i = signal_bars+1; i<wait_for_signal_bars+signal_bars; i++)
        {
         int bars=GetSignalBars(ind_LookBack,i);

         double range_max=0,range_min=0;
         double signal_range_max=0,signal_range_min=0;
         if(bars==OP_BUY)
           {
            range_max = MathMax(High[i],High[i+1]);
            range_min = MathMin(Low[i],Low[i+1]);
            for(r=i-signal_bars; r>0; r--)
              {
               if(!check_only_body)
                  signal_range_min = Low[ iLowest(NULL,0,MODE_LOW,signal_bars,r) ];
               else
                  signal_range_min = MathMin(Open[ iLowest(NULL,0,MODE_OPEN,signal_bars,r) ],Close[ iLowest(NULL,0,MODE_CLOSE,signal_bars,r) ]);
               if(NormalizeDouble(signal_range_min - range_max,_Digits)>0.0)
                 {
                  if(r==1)
                    {
                     signal = 0;
                     signal_stop_loss = range_min;
                     create_rectangle("svbuy_"+(string)Time[1],range_max,Time[i],range_min,Time[i+1],STYLE_SOLID,1,clrDeepSkyBlue,true);
                     create_rectangle("svbuy2_"+(string)Time[1],range_max,Time[i],range_min,Time[1],STYLE_SOLID,1,clrDeepSkyBlue,false);
                    }
                  break;
                 }
              }
            break;
           }
         if(bars==OP_SELL)
           {
            range_max = MathMax(High[i],High[i+1]);
            range_min = MathMin(Low[i],Low[i+1]);
            for(r=i-signal_bars; r>0; r--)
              {
               if(!check_only_body)
                  signal_range_max = High[ iHighest(NULL,0,MODE_HIGH,signal_bars,r) ];
               else
                  signal_range_max = MathMax(Open[ iHighest(NULL,0,MODE_OPEN,signal_bars,r) ],Close[ iHighest(NULL,0,MODE_CLOSE,signal_bars,r) ]);
               if(NormalizeDouble(range_min - signal_range_max,_Digits)>0.0)
                 {
                  if(r==1)
                    {
                     signal = 1;
                     signal_stop_loss = range_max;
                     create_rectangle("svsell_"+(string)Time[1],range_max,Time[i],range_min,Time[i+1],STYLE_SOLID,1,clrTomato,true);
                     create_rectangle("svsell2_"+(string)Time[1],range_max,Time[i],range_min,Time[1],STYLE_SOLID,1,clrTomato,false);
                    }
                  break;
                 }
              }
            break;
           }
         if(signal!=-1)
            break;
        }
     }
 

MrGreen86

Гуру форума
Спасибо lsv107 за предложенные функции. Дошли руки, внедрил в советника и его стало возможно тестировать с адекватной скоростью )

Стратегия слабовата, на стандартных настройках сливает вообще везде.
лучшие результаты получились по AUDCAD, EURUSD, USDJPY.
Отчеты и файлы настроек прикрепил.
 

Вложения

pulio5g

Местный житель
Спасибо lsv107 за предложенные функции. Дошли руки, внедрил в советника и его стало возможно тестировать с адекватной скоростью )

Стратегия слабовата, на стандартных настройках сливает вообще везде.
лучшие результаты получились по AUDCAD, EURUSD, USDJPY.
Отчеты и файлы настроек прикрепил.
Идея норм. Нужно просто доработать советник. И тестировать на нормальных котировках в Метатрейдер 5
 

fzeter

Активный участник
Погуглите советник GridMachine из маркета. Это сетка. Советник распространяется бесплатно. Есть и МТ4, МТ5 версии, тесты, сеты... Как утверждает автор, сова ищет объемы и входит по ним, понятное дело, что всё на тиковых объемах, реальных естественно брать не откуда, но под описание этой темы вполне попадает. Сам немного торговал им на центовых реалах, вполне нормально торгует, не строчит ордера, перед выборами в штатах отложил, сейчас мб опять поставлю, посмотрю.
 

Milord

Местный знаток
Спасибо lsv107 за предложенные функции. Дошли руки, внедрил в советника и его стало возможно тестировать с адекватной скоростью )

Стратегия слабовата, на стандартных настройках сливает вообще везде.
лучшие результаты получились по AUDCAD, EURUSD, USDJPY.
Отчеты и файлы настроек прикрепил.
спасибо за советник,а можно ли в него добавить трейлинг стоп?
 

pulio5g

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