Пользовательские индикаторы > MaxFor (Максимум за) и MinFor (Минимум за) - на базе кольцевого буфера для быстрых вычислений на больших периодах

Дополнительные индикаторы от пользователей Альфа-Директ 4. Готовые решения от пользователей.
Alexey
Сообщения: 19
Зарегистрирован: 16 апр 2017, 16:02
Благодарил (а): 1 раз
Поблагодарили: 6 раз

MaxFor (Максимум за) и MinFor (Минимум за) - на базе кольцевого буфера для быстрых вычислений на больших периодах

Непрочитанное сообщение Alexey » 31 май 2017, 15:16

Входящие параметры

Period - количество баров для поиска экстремума
Shift - сдвиг индикатора вперед по оси времени

Пример: PriceChannel с использованием MaxFor, MinFor
PC.png


Файлы скриптов
MaxMin.rar
(1.82 КБ) 1166 скачиваний


MaxFor

Код: Выделить всё

function Initialize()
{
   IndicatorName = "MaxFor";
   PriceStudy = true;
   AddInput("Input", Inputs.Price);
   AddSeries("Max", DrawAs.Line, Color.Blue);
   AddParameter("Period", 50);
   AddParameter("Shift", 0);
       
   // Дополнительные параметры:
   AddGlobalVariable("ArrValue", Types.DoubleList);
   AddGlobalVariable("ArrIndex", Types.IntList);
   AddGlobalVariable("CircIndex", Types.Int);
   AddGlobalVariable("PrevIndex", Types.Int);
   AddGlobalVariable("CircSize", Types.Int);
   AddGlobalVariable("ArrShift", Types.DoubleList);
   AddGlobalVariable("ShiftIndex", Types.Int);
   AddGlobalVariable("ShiftSize", Types.Int);   
}

function Evaluate()
{
    if (CurrentIndex == 0 )
    {         
          if(Period < 2)
             Period = 2;   
          CircSize = Period - 1;
          
          for(int i = 0; i < CircSize; i++)
          {
             ArrValue.Add(-1.0);
             ArrIndex.Add(-1);
          }
          
      CircIndex = -1;
      PrevIndex = 0;
              
      Max = Input[0];
        
          ShiftSize = (int)Math.Abs(Shift) + 1;
          ShiftIndex = 0;
          for(int i = 0; i < ShiftSize; i++)
          {
             ArrShift.Add(Max);
          }   
     }
   else
   {
      if (PrevIndex < CurrentIndex)
      {
         CircIndex++;
         if(CircIndex >= CircSize) CircIndex = 0;
         
         ShiftIndex++;
         if(ShiftIndex >= ShiftSize) ShiftIndex = 0;
         
         ArrIndex[CircIndex] = 0;
         ArrValue[CircIndex] = Input[1];
         
         for(int counter = CircSize - 2; counter >= 0; counter--)
         {
            int trueIndex = (CircIndex + counter + 1) % CircSize;
            int  jumpIndex = ArrIndex[trueIndex];
         
            if(jumpIndex < 0)
            {
               break;
            }
         
            if(ArrValue[CircIndex] < ArrValue[trueIndex])
            {
               ArrIndex[CircIndex] = ArrIndex[CircIndex];
               break;
            }
            else
            {
               if(jumpIndex > 0)
               {
                  ArrIndex[CircIndex] = ArrIndex[CircIndex] + jumpIndex + 1;
                  counter = counter - jumpIndex;
               }
               else
               {
                  ++ArrIndex[CircIndex];
               }
            }
         }   
                
         PrevIndex = CurrentIndex;
         
         //---
         double maxValue = Input[0];
         
         for(int counter = CircSize - 1; counter >= 0; counter--)
         {
            int trueIndex = (CircIndex + counter + 1) % CircSize;
            int jumpIndex = ArrIndex[trueIndex];
         
            if(jumpIndex < 0)
            {
               break;
            }
            else
            {
               counter = counter - jumpIndex;
            }
         
            if(maxValue < ArrValue[trueIndex])
            {
               maxValue = ArrValue[trueIndex];
            }
         
            //---
            ArrShift[ShiftIndex] = maxValue;
            Max = ArrShift[(ShiftIndex + 1) % ShiftSize];         
         }
      }
      else
      {
        if(ArrShift[ShiftIndex] < Input[0] && Shift == 0)
        {
           ArrShift[ShiftIndex] = Input[0];
        }
       
        Max = ArrShift[(ShiftIndex + 1) % ShiftSize];
      }
   }
}


MinFor

Код: Выделить всё

function Initialize()
{
   IndicatorName = "MinFor";
   PriceStudy = true;
   AddInput("Input", Inputs.Price);
   AddSeries("Min", DrawAs.Line, Color.Red);
       AddParameter("Period", 50);
   AddParameter("Shift", 0);
       
   // Дополнительные параметры:
   AddGlobalVariable("ArrValue", Types.DoubleList);
   AddGlobalVariable("ArrIndex", Types.IntList);
   AddGlobalVariable("CircIndex", Types.Int);
   AddGlobalVariable("PrevIndex", Types.Int);
   AddGlobalVariable("CircSize", Types.Int);
   AddGlobalVariable("ArrShift", Types.DoubleList);
   AddGlobalVariable("ShiftIndex", Types.Int);
   AddGlobalVariable("ShiftSize", Types.Int);
}

function Evaluate()
{
    if (CurrentIndex == 0 )
    {
          if(Period < 2)
             Period = 2;   
          CircSize = Period - 1;
          
          for(int i = 0; i < CircSize; i++)
          {
             ArrValue.Add(-1.0);
             ArrIndex.Add(-1);
          }
          
      CircIndex = -1;
      PrevIndex = 0;
              
      Min = Input[0];
        
          ShiftSize = (int)Math.Abs(Shift) + 1;
          ShiftIndex = 0;
          for(int i = 0; i < ShiftSize; i++)
          {
             ArrShift.Add(Min);
          }   
      }
   else
   {
      if (PrevIndex < CurrentIndex)
      {
         CircIndex++;
         if(CircIndex >= CircSize) CircIndex = 0;
         
         ShiftIndex++;
         if(ShiftIndex >= ShiftSize) ShiftIndex = 0;
         
         ArrIndex[CircIndex] = 0;
         ArrValue[CircIndex] = Input[1];
         
         for(int counter = CircSize - 2; counter >= 0; counter--)
         {
            int trueIndex = (CircIndex + counter + 1) % CircSize;
            int  jumpIndex = ArrIndex[trueIndex];
         
            if(jumpIndex < 0)
            {
               break;
            }
         
            if(ArrValue[CircIndex] > ArrValue[trueIndex])
            {
               ArrIndex[CircIndex] = ArrIndex[CircIndex];
               break;
            }
            else
            {
               if(jumpIndex > 0)
               {
                  ArrIndex[CircIndex] = ArrIndex[CircIndex] + jumpIndex + 1;
                  counter = counter - jumpIndex;
               }
               else
               {
                  ++ArrIndex[CircIndex];
               }
            }
         }   
                
         PrevIndex = CurrentIndex;   
      
         //---
         double minValue = Input[0];
         
         for(int counter = CircSize - 1; counter >= 0; counter--)
         {
            int trueIndex = (CircIndex + counter + 1) % CircSize;
            int jumpIndex = ArrIndex[trueIndex];
         
            if(jumpIndex < 0)
            {
               break;
            }
            else
            {
               counter = counter - jumpIndex;
            }
         
            if(minValue > ArrValue[trueIndex])
            {
               minValue = ArrValue[trueIndex];
            }
         }
         
         //---
         ArrShift[ShiftIndex] = minValue;
         Min = ArrShift[(ShiftIndex + 1) % ShiftSize];
      }
      else
      {
         if(ArrShift[ShiftIndex] > Input[0] && Shift == 0)
         {
            ArrShift[ShiftIndex] = Input[0];
         }
         
         //---
         Min = ArrShift[(ShiftIndex + 1) % ShiftSize];
      }   
   }
}

Вернуться в «Пользовательские индикаторы»

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 2 гостя