Пользовательские индикаторы > Индикатор iVar

Дополнительные индикаторы от пользователей Альфа-Директ 4. Готовые решения от пользователей.
wowa
Сообщения: 5
Зарегистрирован: 06 июн 2019, 11:57
Поблагодарили: 3 раза

Индикатор iVar

Непрочитанное сообщение wowa » 06 июн 2019, 12:06

Не знаю был или нет, но вот попробовал что то сделать.

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

function Initialize()
{
// Область определения параметров индикатора

// Обязательные параметры:
 IndicatorName = "iVar";   // Задайте название индикатора и сохраните с данным именем
 PriceStudy = false;   // Рисовать в области цены (true – да, false – нет)
 AddInput("Input", Inputs.Candle);   // Input - входной ряд (Inputs.Price) или свечи (Inputs.Candle)
 AddSeries("A", DrawAs.Line, Color.Red);   // Задаем вид линии индикатора A
 AddSeries("B", DrawAs.Line, Color.Black);   // Задаем вид линии индикатора B

// Дополнительные параметры:
 AddParameter("Period", 5);   // Задаем имя изменяемого параметра и его значение
}

function Evaluate()
{
   int i, j, k, l;
   int ihigh, ilow, nInterval, nint, mpow;
   double Delta, Xс, Yс, Sx, Sy, Sxx, Sxy, fndl, fndh;
   
      Sx = 0; Sy = 0; Sxx = 0; Sxy = 0; j = 0; ihigh = 0; ilow = 0;
      for(i=0; i<=Period; i++)
      {
         nInterval = (int) Math.Pow(2,Period-i);
         mpow = (int) Math.Pow(2,i);
      //---- суммируем разницы максимальной и минимальной цен на интервале
         for(Delta=0, k=0; k < mpow; k++)
         {
         
//            ihigh = MaxValue(Input.High,  nInterval, nInterval*k+j);
            fndl = 0;
            fndh = 0;
            for(l=0; l<nInterval; l++)
            {
            nint = l + nInterval*k+j;
               if (fndl == 0)
               {
                   fndh = Input.High[nint];
                  fndl = Input.Low[nint];
                  ihigh = nint;
                  ilow = nint;
                  continue;
               }

               if (fndh < Input.High[nint]) {
                  fndh = Input.High[nint];
                  ihigh = nint;
               }

               if (fndl > Input.Low[nint]) {
                  fndl = Input.Low[nint];
                  ilow = nint;
               }

           
            }
            Delta += Input.High[ihigh]-Input.Low[ilow];
//              WriteData("c:\\temp\\"+ IndicatorName + "_log.txt", DateTime.Today, BarDate(ihigh), BarTime(ihigh), BarDate(ilow), BarTime(ilow), k, fndh, fndl);
         }
      //---- вычисляем координаты вариации в двойном логарифмическом масштабе
         Xс = (Period-i)*Math.Log(2.0);
         Yс = Math.Log(Delta);
      //---- накапливаем данные для нахождения коэффициентов линии регрессии с помощью МНК
         Sx += Xс;
         Sy += Yс;
         Sxx += Xс*Xс;
         Sxy += Xс*Yс;
      }
   //---- вычисляем индекс вариации (коэффициент наклона линии регрессии)
      A = -(Sx*Sy-(Period+1)*Sxy)/(Sx*Sx-(Period+1)*Sxx);
     B = 0.5;
}


Переносил с исходника который для mt4 по моему был. Как то он притормаживает у меня. Но вроде и работает и приверает иногда.

исходник из чего делал

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

//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
#property link "http://forexbig.ru"
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
//+------------------------------------------------------------------+
//|                                                         iVAR.mq4 |
//|                                        (C)opyright © 2008, Ilnur |
//|                                        http://www.metaquotes.net |
//+------------------------------------------------------------------+

//   Индикатор отображает индекс вариации ценового ряда, вычисленного
// на минимальном предшествующем интервале длины 2^n. Индекс вариации
// показывает, что преобладает во временном ряду – трендовая или флетовая
// составляющая, или же ряд ведет себя случайно.

// М.М. Дубовиков и др. - Размерность минимального покрытия и локальный
// анализ фрактальных временных рядов.

#property copyright "(C)opyright © 2008, Ilnur"
#property link      "http://www.metaquotes.net"
//---- настройки индикатора
#property indicator_separate_window
#property indicator_buffers 1
#property indicator_color1 Red
#property indicator_level1 0.5
//---- входные параметры
extern int n = 5;
extern int nBars = 1000;
//---- буфер индикатора
double ibuffer[];
//+------------------------------------------------------------------+
//| Функция инициализации индикатора                                 |
//+------------------------------------------------------------------+
int init()
{
//---- настройка параметров отрисовки
   SetIndexBuffer(0,ibuffer);
   SetIndexStyle(0,DRAW_LINE);
   SetIndexDrawBegin(0,Bars-nBars);
   SetIndexLabel(0,"iVAR");
//---- "короткое имя" отображаемое в окне индикатора
   IndicatorShortName("iVAR("+n+")");
   return(0);
}
//+------------------------------------------------------------------+
//| Основная функция индикатора                                      |
//+------------------------------------------------------------------+
int start()
{
   int i, j, k, nTotal, nCountedBars = IndicatorCounted();
   int ihigh, ilow, nInterval;
   double Delta, Xс, Yс, Sx, Sy, Sxx, Sxy;
//---- последний посчитанный бар будет пересчитан
   if(nCountedBars==0) nTotal = nBars;
   if(nCountedBars>0) nTotal = Bars-nCountedBars-1;
//---- основной цикл индикатора
   for(j=nTotal; j>=0; j--)
   {
      Sx = 0; Sy = 0; Sxx = 0; Sxy = 0;
      for(i=0; i<=n; i++)
      {
         nInterval = MathPow(2,n-i);
      //---- суммируем разницы максимальной и минимальной цен на интервале
         for(Delta=0, k=0; k<MathPow(2,i); k++)
         {
            ihigh = iHighest(Symbol(),0,MODE_HIGH,nInterval,nInterval*k+j);
            ilow = iLowest(Symbol(),0,MODE_LOW,nInterval,nInterval*k+j);
            Delta += High[ihigh]-Low[ilow];
         }
      //---- вычисляем координаты вариации в двойном логарифмическом масштабе
         Xс = (n-i)*MathLog(2.0);
         Yс = MathLog(Delta);
      //---- накапливаем данные для нахождения коэффициентов линии регрессии с помощью МНК
         Sx += Xс;
         Sy += Yс;
         Sxx += Xс*Xс;
         Sxy += Xс*Yс;
      }
   //---- вычисляем индекс вариации (коэффициент наклона линии регрессии)
      ibuffer[j] = -(Sx*Sy-(n+1)*Sxy)/(Sx*Sx-(n+1)*Sxx);
   }
   return(0);
}


может более знающие получше перенесут и меньше врать будет )

Аватара пользователя
evge
Администратор
Сообщения: 1811
Зарегистрирован: 04 фев 2016, 09:46
Откуда: Млечный путь, планета Земля
Благодарил (а): 83 раза
Поблагодарили: 366 раз
Контактная информация:

Re: Индикатор iVar

Непрочитанное сообщение evge » 21 мар 2021, 12:51

По запросу из этой темы

1. Для ускорения добавлен период расчета индикатора для N последних баров
2. Добавлена защита от зависания при больших значениях Period. Если nInterval (2 в степени Period) превышает MaxIndex - ничего не вычисляется и завершается работа индикатора. Индикатор ничего не отобразит.


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

function Initialize()
{
 IndicatorName = "iVar";
 PriceStudy = false;   
 AddInput("Input", Inputs.Candle);   
 AddSeries("A", DrawAs.Line, Color.Red);   
 AddSeries("B", DrawAs.Line, Color.Black);   

 AddParameter("Period", 5);
 AddParameter("N", 100, 50);   //считать только для последних N баров графика

}

function Evaluate()
{

   if (CurrentIndex < MaxIndex - N) return; //evge 21.03.2021, считать только для последних N баров графика
   if ((int) Math.Pow(2, Period) > MaxIndex) return; //evge 21.03.2021, интервал за пределами доступных данных, ничего не вычисляем и завершаем выполнение
   
   int i, j, k, l;
   int ihigh, ilow, nInterval, nint, mpow;
   double Delta, Xс, Yс, Sx, Sy, Sxx, Sxy, fndl, fndh;
   
      Sx = 0; Sy = 0; Sxx = 0; Sxy = 0; j = 0; ihigh = 0; ilow = 0;
      for(i=0; i<=Period; i++)
      {
         nInterval = (int) Math.Pow(2,Period-i);
                 
         mpow = (int) Math.Pow(2,i);
      //---- суммируем разницы максимальной и минимальной цен на интервале
         for(Delta=0, k=0; k < mpow; k++)
         {
         
//            ihigh = MaxValue(Input.High,  nInterval, nInterval*k+j);
            fndl = 0;
            fndh = 0;
            for(l=0; l<nInterval; l++)
            {
            nint = l + nInterval*k+j;
               if (fndl == 0)
               {
                   fndh = Input.High[nint];
                  fndl = Input.Low[nint];
                  ihigh = nint;
                  ilow = nint;
                  continue;
               }

               if (fndh < Input.High[nint]) {
                  fndh = Input.High[nint];
                  ihigh = nint;
               }

               if (fndl > Input.Low[nint]) {
                  fndl = Input.Low[nint];
                  ilow = nint;
               }

           
            }
            Delta += Input.High[ihigh]-Input.Low[ilow];
//              WriteData("c:\\temp\\"+ IndicatorName + "_log.txt", DateTime.Today, BarDate(ihigh), BarTime(ihigh), BarDate(ilow), BarTime(ilow), k, fndh, fndl);
         }
      //---- вычисляем координаты вариации в двойном логарифмическом масштабе
         Xс = (Period-i)*Math.Log(2.0);
         Yс = Math.Log(Delta);
      //---- накапливаем данные для нахождения коэффициентов линии регрессии с помощью МНК
         Sx += Xс;
         Sy += Yс;
         Sxx += Xс*Xс;
         Sxy += Xс*Yс;
      }
   //---- вычисляем индекс вариации (коэффициент наклона линии регрессии)
      A = -(Sx*Sy-(Period+1)*Sxy)/(Sx*Sx-(Period+1)*Sxx);
     B = 0.5;
}
никогда такого не было и вот опять

ReskatorVVV
Сообщения: 7
Зарегистрирован: 20 мар 2021, 07:32
Благодарил (а): 1 раз

Re: Индикатор iVar

Непрочитанное сообщение ReskatorVVV » 21 мар 2021, 13:40

Спасибо огромное Евгений!

BugsDigger
Сообщения: 535
Зарегистрирован: 11 ноя 2018, 17:11
Благодарил (а): 21 раз
Поблагодарили: 92 раза

Re: Индикатор iVar

Непрочитанное сообщение BugsDigger » 21 мар 2021, 18:53

> Для ускорения

Двойку в степень через Pow излишне возводить, лучше просто через сдвиг

int r=1<<n;
n=0 r=1
n=1 2
n=2 4
и т.д.

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

Если "B" - просто уровень 0.5, то его логичнее рисовать через AddLevel.

ReskatorVVV
Сообщения: 7
Зарегистрирован: 20 мар 2021, 07:32
Благодарил (а): 1 раз

Re: Индикатор iVar

Непрочитанное сообщение ReskatorVVV » 23 мар 2021, 09:00

BugsDigger писал(а):> Для ускорения

Двойку в степень через Pow излишне возводить, лучше просто через сдвиг

int r=1<<n;
n=0 r=1
n=1 2
n=2 4
и т.д.

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

Если "B" - просто уровень 0.5, то его логичнее рисовать через AddLevel.



Если не сложно, скиньте пжлст полную версию кода )

ReskatorVVV
Сообщения: 7
Зарегистрирован: 20 мар 2021, 07:32
Благодарил (а): 1 раз

Re: Индикатор iVar

Непрочитанное сообщение ReskatorVVV » 24 мар 2021, 12:13

Оптимизация действительно не работает, ни на старом ни на новом коде


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

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

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