Каталог файлов форума

Список вложений в сообщениях, оставленных на этой конференции.

Все файлы форума: 1233

Добавлено: BugsDigger » 23 июн 2019, 18:49

Тема: Re: NVLT/NVLTD (по мотивам NATR)

Текст сообщения:

"Свечной" вариант.

Формула счета порогов по волатильности баров сделана универсальной:
VLT=Nv*VLTm + Nd*VLTd,
где VLTm - средняя волатильность за период, VLTd - среднеквадратичное отклонение, Nv и Nd - их веса в конечном значении (можно и 0 задать при желании).
Знак изменения на очередном баре отсчитывается либо от цены закрытия предыдущего бара, либо от средней цены предыдущего бара (задается параметром UseAvgCandle= 0 или 1 соответственно).

Процентные значения VLTup_pc и VLTdn_pc рассчитываются относительно средней цены бара.
Серия VLTdiff добавлена "для красоты"; даже не знаю, несет ли она какой-то смысл. :)

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

function Initialize()
{
 IndicatorName = "cNVLTD";
 PriceStudy = true;                                            // в области цен
 
 AddInput("Input", Inputs.Candle);
 AddParameter("Period", 30, "Период расчета", 1);              // период расчета VLT             
 AddParameter("UseAvgCandle", 0, "Считать по средней цене свечи");               
 AddParameter("Nv", 1.0, "Порог волатильности");               // зазор в амплитудах текущей волатильности
 AddParameter("Nd", 4.0, "Добавка по СКО");                    // зазор в амплитудах текущей дисперсии волатильности

 AddSeries("cNVLTD", DrawAs.Custom, Color.Blue);               // выходная серия
 AddSeries("VLTup", DrawAs.Custom, Color.Green, false);        // уровень волатильности в + (невидимая серия)
 AddSeries("VLTdn", DrawAs.Custom, Color.Red, false);          // уровень волатильности в - (невидимая серия)
 AddSeries("VLTup_pc", DrawAs.Custom, Color.Green, AxisType.ZeroBased, true, Axes.New);  // уровень волатильности в +, %
 AddSeries("VLTdn_pc", DrawAs.Custom, Color.Red, AxisType.ZeroBased, true, Axes.New);    // уровень волатильности в -, %
 AddSeries("VLTdiff", DrawAs.Line, Color.Black, AxisType.ZeroBased, true, Axes.New);     // разность % уровеней волатильности в + и -
 AddSeries("zDirection", DrawAs.Custom, Color.Black, false);   // собственно сигнал (невидимая серия)
       
 AddGlobalVariable("gHigh", Types.Double, 0.0);
 AddGlobalVariable("gLow", Types.Double, 1e+8);
 
 AddGlobalVariable("bufU", Types.DoubleList);
 AddGlobalVariable("bufD", Types.DoubleList);
}

function Evaluate()
{
 //------------------------------------------------------------------------------------------------------
 Action<double, int> AddVal = (double V, int MaxCnt) =>
 {
  if(V>0) { bufU.Add( V); if(bufU.Count>Period) bufU.RemoveAt(0); } else
  if(V<0) { bufD.Add(-V); if(bufD.Count>Period) bufD.RemoveAt(0); }
  else
  {
   bufU.Add(0.0); if(bufU.Count>Period) bufU.RemoveAt(0);
   bufD.Add(0.0); if(bufD.Count>Period) bufD.RemoveAt(0);
  }
 };
 //------------------------------------------------------------------------------------------------------
 // среднее и СКО по ~40% центральных значений
 Func< List<double>, Tuple<double, double> > Median1 = (List<double> L) =>
 {
  List<double> tmp=new List<double>(L);
  tmp.Sort();
 
  int n=tmp.Count;                         
  int n1=n/2-n/5;              // [n1..n2] - 40% центральных значений
  int n2=n/2+n/5;
 
  double m, d=0.0;
  if(n1==n2) m=tmp[n1];       // всего одно значение
  else                        // несколько значений
  {
   m=0.0;
   for(int i=n1; i<=n2; i++) m+=tmp[i];
   m/=(n2-n1+1);
   for(int i=n1; i<=n2; i++) { double v=m-tmp[i]; d+=v*v; }
   d=Math.Sqrt(d/(n2-n1));
  }
  return new Tuple<double, double>(m, d);
 };
 //------------------------------------------------------------------------------------------------------
 int Period_=(int)Period;
 double Nv_=(double)Nv;
 double Nd_=(double)Nd;
 double gHigh_=gHigh;
 double gLow_=gLow;
 
 int gDirection;
 double NVLTD1;                      // нужно только для случая, если для уровня запрещен ход назад
 double Ref, O0, L0, H0, C0, M0;
 
 O0=Input.Open[0];
 L0=Input.Low[0];
 H0=Input.High[0];
 C0=Input.Close[0];
 M0=(L0+H0)/2.0;
 
 if(CurrentIndex==0)
 {
  Ref=(UseAvgCandle==0 ? O0 : M0);
  gDirection=(C0>=Ref ? 1 : -1);
  NVLTD1=0.0;
 }
 else
 {
  Ref=(UseAvgCandle==0 ? Input.Close[-1] : (Input.High[-1]+Input.Low[-1])/2.0);
  gDirection=(int)zDirection[-1];
  NVLTD1=cNVLTD[-1];                 
 }
 
 AddVal(H0-Ref, Period_);             // волатильность в + относительно предыдущего закрытия/среднего значения
 AddVal(L0-Ref, Period_);             // волатильность в - относительно предыдущего закрытия/среднего значения
 
 Tuple<double, double> md;
 md=Median1(bufU);                   
 double vU=Nv_*md.Item1+Nd_*md.Item2; // уровень волатильности в +
 md=Median1(bufD);                   
 double vD=Nv_*md.Item1+Nd_*md.Item2; // уровень волатильности в -
 
 double Result;
 if(gDirection>0)
 { // был рост
  // if(L0<gHigh_-vD)  // по Low кажется грубовато
  if(C0<gHigh_-vD &&   // по цене закрытия и
     C0<O0)            // бар отрицательный
  { // переворот
   gDirection=-1;
   gLow_=L0;
   Result=gLow_+vU;
  }
  else
  { // продолжение
   Result=Math.Max(NVLTD1, gHigh_-vD);         // для уровня нет хода назад
   //Result=gHigh_-vD;                         // ход назад возможен
  }
 }
 else
 { // было снижение
  // if(H0>gLow_+vU)
  if(C0>gLow_+vU &&
     C0>O0)
  { // переворот
   gDirection=1;
   gHigh_=H0;
   Result=gHigh_-vD;
  }
  else
  { // продолжение                               
   Result=Math.Min(NVLTD1, gLow_+vU);
   // Result=gLow_+vU;
  }
 }

 if(H0>gHigh_) gHigh_=H0;
 if(L0<gLow_)  gLow_ =L0;

 cNVLTD[0]=Result;
 VLTup[0]=vU; vU=vU/M0*100.0; VLTup_pc[0]= vU;
 VLTdn[0]=vD; vD=vD/M0*100.0; VLTdn_pc[0]=-vD;
 VLTdiff[0]=vU-vD;
 zDirection[0]=gDirection;

// cNVLT.DrawLine((gDirection>0 ? Color.Green : Color.Red), Line.Solid, 2);
 if(gDirection>0) cNVLTD.DrawFigure(Figure.Up,   Color.Green, Line.Solid, 3, Color.Green, 50);
 else             cNVLTD.DrawFigure(Figure.Down, Color.Red,   Line.Solid, 3, Color.Red,   50);
 
 VLTup_pc.DrawHistogram(Color.Green);
 VLTdn_pc.DrawHistogram(Color.Red);
 
 gHigh=gHigh_;
 gLow=gLow_;
}


Безымянный.png


AS IS WITHOUT WARRANTY :mrgreen: