Общие вопросы по разработке > Cyber Cycle Period для адаптивных индикаторов (Дж. Элерс)

Общие вопросы по разработке в Альфа-Директ 4. Обсуждение разработки пользовательских индикаторов, стратегий.
ChurOlNik
Сообщения: 6
Зарегистрирован: 20 окт 2021, 14:46
Благодарил (а): 6 раз

Cyber Cycle Period для адаптивных индикаторов (Дж. Элерс)

Непрочитанное сообщение ChurOlNik » 14 ноя 2021, 09:26

Мучаюсь не одну неделю с переносом на C# ( на MQL код есть, на Pine тоже). Вроде бы всё просто, и код компилируется успешно, но на графике искомого периода не рисуется. Помогите понять, где у меня в коде ошибки?

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

   IndicatorName = "Cyber_Cycle_Period_OlNi";   
   PriceStudy =false;   
   AddInput("Input", Inputs.Candle);   
   AddParameter("alfa",0.07);
    AddSeries("Period", DrawAs.Line, Color.Green);   // Искомое значение периода для применения в адаптивных индикаторах
    AddSeries("Price", DrawAs.Line, Color.Red,false);
    AddSeries("Cycle", DrawAs.Line, Color.Red);
    AddSeries("Smootch", DrawAs.Line, Color.Gray,false);
    AddSeries("Q1", DrawAs.Line, Color.Blue);
    AddSeries("I1", DrawAs.Line, Color.Gray);
    AddSeries("DeltaPhase", DrawAs.Line, Color.Black);
    AddSeries("DC", DrawAs.Line, Color.Red , true);
    AddSeries("Median", DrawAs.Line, Color.Brown);
    AddSeries("InstPeriod", DrawAs.Line, Color.Violet);
   
    AddGlobalVariable("Buf", Types.DoubleList);     
}

function Evaluate()
         
{
  Price=(Input.High[0]+Input.Low[0])/2;   
  InstPeriod = 0.0;
  Smootch=(Price[0]+2*Price[1]+2*Price[2]+Price[3])/6; // Применение Элерсом фильтра НЧ(КИХ) для устранения шумов
 
  if (CurrentIndex <7)
 
      Cycle=(1-0.5*alfa)*(1-0.5*alfa)*(Smootch[0]-2*Smootch[1]+Smootch[2])+2*(1-alfa)*Cycle[1]-(1-alfa)*(1-alfa)*Cycle[2];
 
  else
 
      Cycle=(Price[0]-2*Price[1]+Price[2])/4;
     
  Q1 = (0.0962*Cycle[0] + 0.5769*Cycle[2] - 0.5769*Cycle[4]-0.0962*Cycle[6])*(0.5+0.08*InstPeriod[1]); //Синус фазового вектора c коррекцией
   
  I1 = Cycle[3]; //Косинус фазового вектоора
 
  if (Q1[0] != 0.0 && Q1[1] != 0.0)  DeltaPhase = (I1/Q1-I1[1]/Q1[1]) / (1 + I1*I1[1]/(Q1*Q1[1]));
  if (DeltaPhase < 0.1)              DeltaPhase = 0.1;
  if (DeltaPhase > 1.1)              DeltaPhase = 1.1;
     
 Buf.Add(DeltaPhase[0]);
 
  if (Buf.Count >5)  Buf.RemoveAt(0);
     
 var tmp = new List<double>(Buf); // Применение Медианного фильтра для сглаживания
 tmp.Sort();
 Median[0] = tmp[tmp.Count/2];
 
  if (Median[0] == 0.0)
     DC = 15;
  else
     DC = 6.28318 / Median[0] + 0.5;
 
 InstPeriod[0] =  0.33*DC + 0.67*InstPeriod[1];
 Period = 0.0;
 Period[0] =0.15*InstPeriod[0] + 0.85*Period[1];   
             
}


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

Re: Cyber Cycle Period для адаптивных индикаторов (Дж. Элерс)

Непрочитанное сообщение BugsDigger » 14 ноя 2021, 12:25

(Я не смотрел код, по крайней мере пока).
Если ничего не рисуется, то м.б. вылетает по исключению.
Попробуйте заключить код в try-catch и вывести в лог сообщение об ошибке.

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

Re: Cyber Cycle Period для адаптивных индикаторов (Дж. Элерс)

Непрочитанное сообщение BugsDigger » 14 ноя 2021, 18:24

Не зная того, чего вы пытаетесь вычислить, пройдемся формально:

Smootch=(Price[0]+2*Price[1]+2*Price[2]+Price[3])/6; // фильтр

В момент разгона (CurrentIndex<3), как вы понимате, не все элементы Price в этом выражении доступны.

if (CurrentIndex <7)
Cycle=(1-0.5*alfa)*(1-0.5*alfa)*(Smootch[0]-2*Smootch[1]+Smootch[2])+2*(1-alfa)*Cycle[1]-(1-alfa)*(1-alfa)*Cycle[2];
else
Cycle=(Price[0]-2*Price[1]+Price[2])/4;

То же самое с элементами Cycle. Что случится в операторах под if(CurrentIndex<7) и else при, скажем, CurrentIndex=0? 1? Ничего хорошего.

Q1 = (0.0962*Cycle[0] + 0.5769*Cycle[2] - 0.5769*Cycle[4]-0.0962*Cycle[6])*(0.5+0.08*InstPeriod[1]); //Синус

То же самое, не все элементы определены в начале счета.

Ну и так далее в том же духе, надо помнить, что в начале работы (на нескольких первых точках) данных еще мало.

А поскольку серий, которые вы формируете для расчета, у вас много, и все они требуют разного минимального количества точек на входе, чтобы начать считаться, вам, видимо, придется изрядно поработать с проверками на этапе разгона счета. Мало того, надо придумать, как считать эти Cycle, Q1 и прочие (что писать туда? нули? или что-то другое? или безразлично?) при недостатке данных.

Upd: нашел какие-то исходники, но не уверен, что это ваш вариант. Киньте ссылку на оригинальный код.

ChurOlNik
Сообщения: 6
Зарегистрирован: 20 окт 2021, 14:46
Благодарил (а): 6 раз

Re: Cyber Cycle Period для адаптивных индикаторов (Дж. Элерс)

Непрочитанное сообщение ChurOlNik » 15 ноя 2021, 13:51

https://www.mql5.com/ru/articles/288
Здесь разъяснение теории Элерса и код на MQL.

https://ru.tradingview.com/v/6dUlw58s/
А здесь вариант кода на языке Pine.

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

Re: Cyber Cycle Period для адаптивных индикаторов (Дж. Элерс)

Непрочитанное сообщение BugsDigger » 15 ноя 2021, 21:01

Много букв, однако.
Довольно забубенная вещь. Особенно мне понравилось суммирование фазы аж по 50 точкам.
Вообще, суммирование фазы - весьма непростая/спорная вещь; необходимо, чтобы каждое следующее значение "не очень" отличалось от предыдущего, иначе получится чепуха. В оригинальной статейке он как-то (не понял еще как) пытается решить эту проблему (не уверен, что корректно). Обычно проще усреднять вектора, а по их сумме уже вычислять финальную фазу.

Программка
https://www.motivewave.com/studies/inst ... urment.htm
Статейка
http://www.technicalanalysis.org.uk/mov ... s/Ehle.pdf

Надо поковырять, народ полон энтузиазма. Хотя, по собственному опыту, чем сложнее обработка, тем она бесполезнее; только самые топорные методы дают что-то стабильное на выходе. :mrgreen:

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

Re: Cyber Cycle Period для адаптивных индикаторов (Дж. Элерс)

Непрочитанное сообщение BugsDigger » 22 ноя 2021, 18:26

Код по первоисточнику.

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

function Initialize()
{
 IndicatorName = "Test";   
 PriceStudy = false;   
 AddInput("Input", Inputs.Candle);   
 AddParameter("MinPeriod", 7);
 AddParameter("MaxPeriod", 50);
   
 AddSeries("v", DrawAs.Line, Color.Black, false, Axes.New);
 AddSeries("RE", DrawAs.Line, Color.Red, false, Axes.New);
 AddSeries("IM", DrawAs.Line, Color.Blue, false, Axes.New);
 AddSeries("phase", DrawAs.Line, Color.Black, false, Axes.New);
 AddSeries("dphase", DrawAs.Line, Color.Black, false, Axes.New);
   
 AddSeries("Period", DrawAs.Line, Color.Green, true, Axes.New);
   
 AddSeries("Mid", DrawAs.Line, Color.Black, false, Axes.Parent);
}

function Evaluate()
{
 //  John Ehlers. Hilbert Indicators Tell You When To Trade. 2000
 // https://silo.tips/download/hilbert-indicators-tell-you-when-to-trade

 // среднее значение бара как исходные данные
 double t=(Input.High[0]+Input.Low[0])/2.0;
 Mid[0]=t;

 int indexm=(int)MinPeriod; if(indexm>CurrentIndex) indexm=0;
 int index1=1;              if(index1>CurrentIndex) index1=0;
 int index2=2;              if(index2>CurrentIndex) index2=0;
 int index3=3;              if(index3>CurrentIndex) index3=0;
 int index4=4;              if(index4>CurrentIndex) index4=0;
 int indexs=(int)MaxPeriod; if(indexs>CurrentIndex) indexs=0;

 // detrend price
 double v0=t-Mid[-indexm];
 v[0]=v0;

 double v2=v[-index2];     
 double v4=v[-index4];     

 double RE3=RE[-index3];     
 double IM2=IM[-index2];     

 // Hilbert transform complex number components, inPhase (real part, RE), quad (imaginary part, IM)
 double re0=1.25*(v4-0.635*(v2+RE3)); RE[0]=re0;
 double im0=v2-0.338*(v0+IM2);        IM[0]=im0;

 double tr=re0+RE[-index1];
 double ti=im0+IM[-index1];
 double rad=Math.Atan2(ti, tr);    // [-pi .. pi]
 if(rad<0) rad=2.0*Math.PI+rad;    // [0 .. 2pi]
 int dg0=(int)(rad/Math.PI*180.0);
 phase[0]=dg0;
     
 // Compute a differential phase, resolve phase wraparound, and limit delta phase errors
 int dg1=(int)(phase[-index1]);
 int dp=dg1-dg0;
   
 if(dg1<90 && dg0>270) dp=360+dp;
 if(dp<1) dp=1; else
 if(dp>60) dp=60;

 dphase[0]=dp;

 int instPeriod=0;
 for(int i=0, dps=0; i<=indexs; i++)
 {
  dps+=(int)dphase[-i];
  if(dps>=360)
  {
   instPeriod=i;
   break;
  }
 }
 if(instPeriod!=0) Period[0]=0.25*instPeriod+0.75*Period[-index1];
 else Period[0]=Period[-index1];
}

Его можно модифицировать, например, сглаживая входной ряд, результаты и т.п.
Не думаю, что он принесет кому-то особое счастье, т.к. подозреваю, что счет не особо корректный.

В тех вариантах, с которыми вы начинали, я вообще ничего не понял: они имеют мало общего с первоисточником Ehlers'а, кроме названия.
Сам код м.б. для вас небесполезен просто как некоторый образец техники (что-то все же получилось на выходе, прогресс!).

ChurOlNik
Сообщения: 6
Зарегистрирован: 20 окт 2021, 14:46
Благодарил (а): 6 раз

Re: Cyber Cycle Period для адаптивных индикаторов (Дж. Элерс)

Непрочитанное сообщение ChurOlNik » 26 ноя 2021, 14:54

Интересное решение. Спасибо за участие. Буду переваривать.


Вернуться в «Общие вопросы по разработке»

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

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