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

Дополнительные индикаторы от пользователей Альфа-Директ 4. Готовые решения от пользователей.
BugsDigger
Сообщения: 332
Зарегистрирован: 11 ноя 2018, 17:11
Благодарил (а): 21 раз
Поблагодарили: 41 раз

Capital

Непрочитанное сообщение BugsDigger » 16 июн 2019, 19:12

Сумма (нарастающий итог) величины (Close[0]-Close[-1])*Volume[0].
Родственно OBV (балансовый объем), где суммируется просто объем со знаком Math.Sign(Close[0]-Close[-1]), но в отличие от него домножаем еще на само изменение цены.

Ничего особо гениального, конечно, но есть приятности:
- после интенсивного фронта дальнейшие колебания цен (релаксация) проходят уже при существенно более низких объемах, и выходной график практически постоянен;
- видны вступления сильных игроков (чем короче ТФ, тем заметнее). Иногда виден и их выход (если ступенька входа в обозримом будущем скакнет практически на такую же амплитуду обратно);
- на достаточно коротких ТФ есть шанс увидеть "размазанную" во времени ступеньку, и вскочить в уходящий поезд;
- интересны малые изменения цен на больших обьемах (тоже будет заметная ступенька на графике), хотя и редко это бывает: обычно это сигнал к последующему движению в том же направлении.

К графику можно применить индикатор вроде NATR (мои pNVLT/pNVLTD, например). Он даст сигнал на вход, выход же, наверное, лучше непосредственно по ценам, т.к. дрейф на малых объемах на графике практически не сказывается, а сдрейфовать может довольно сильно.

Два варианта: просто нарастающий итог и со сбросом в начале каждого дня (параметр "Daily" 0 или 1).
В первом случае абсолютный насчитанный результат зависит от точки старта (практически случайной, как уж терминалу захочется), но сам ход графика в +/- , конечно, правильный. Как это сказывается на тестировании, не проверял.
Во втором случае надо быть осторожным с индикаторами, напускаемыми на этот график, т.к. в начале дня будет бросок из-за обнуления перед первым баром дня, а индикаторы обычно на это не рассчитаны.

Еще два варианта: счет по Close'ам или по соседним средним (High+Low)/2, кому как нравится.

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

function Initialize()
{
 IndicatorName = "Capital";
 AddInput("Input", Inputs.Candle);
 PriceStudy = false;
 AddSeries("Capital", DrawAs.Line, Color.Blue); 
 AddLevel(0, Color.Black, "Capital");
 AddParameter("UseAvgCandle", 0, "Считать по средней цене свечи");               
 AddParameter("Daily", 0, "Считать от начала дня");               
}

function Evaluate()
{
 if(CurrentIndex==0) // неизвестно где
  Capital[0]=(Input.Close-Input.Open)*Input.Volume;
 else
 {
  if(Daily!=0 && BarDate()>BarDate(-1)) // первый бар дня
   Capital[0]=(Input.Close-Input.Open)*Input.Volume;
  else // очередной бар
  {
   double p0, p1;
   if(UseAvgCandle!=0)
   {
    p1=(Input.High[-1]+Input.Low[-1])/2.0;
    p0=(Input.High[ 0]+Input.Low[ 0])/2.0;
   }
   else
   {
    p1=Input.Close[-1];
    p0=Input.Close[ 0];
   }
   Capital[0]=Capital[-1]+(p0-p1)*Input.Volume[0];
  }
 }
}

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


AS IS WITHOUT WARRANTY :mrgreen:

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

Re: Capital

Непрочитанное сообщение BugsDigger » 04 май 2020, 10:46

Добавлена опция счета объема как разницы Ask-Bid.

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

function Initialize()
{
 IndicatorName = "Capital";
 AddInput("Input", Inputs.Candle);
 PriceStudy = false;
 AddSeries("Capital", DrawAs.Line, Color.Blue); 
 AddLevel(0, Color.Black, "Capital");
 AddParameter("UseAvgCandle", 0, "Считать по средней цене свечи");               
 AddParameter("UseBidAsk", 0, "Считать объем по разнице Ask-Bid");               
 AddParameter("Daily", 0, "Считать от начала дня");               
}

function Evaluate()
{
 double V=(UseBidAsk==0 ? Input.Volume : Input.VolumeAsk-Input.VolumeBid);
 if(CurrentIndex==0) // неизвестно где
 {
  Capital[0]=V* (UseBidAsk==0 ? Input.Close-Input.Open : Math.Abs(Input.Close-Input.Open));
 }
 else
 {
  if(Daily!=0 && BarDate()>BarDate(-1)) // первый бар дня
   Capital[0]=V* (UseBidAsk==0 ? Input.Close-Input.Open : Math.Abs(Input.Close-Input.Open));
  else // очередной бар
  {
   double p0, p1;
   if(UseAvgCandle!=0)
   {
    p1=(Input.High[-1]+Input.Low[-1])/2.0;
    p0=(Input.High[ 0]+Input.Low[ 0])/2.0;
   }
   else
   {
    p1=Input.Close[-1];
    p0=Input.Close[ 0];
   }
   Capital[0]=Capital[-1]+V* (UseBidAsk==0 ? p0-p1 : Math.Abs(p0-p1));
  }
 }
}

Orange2000
Сообщения: 43
Зарегистрирован: 13 мар 2019, 00:45
Благодарил (а): 31 раз
Поблагодарили: 1 раз

Re: Capital

Непрочитанное сообщение Orange2000 » 05 май 2020, 20:36

Подскажите, а как нанести natr на этот индикатор?)

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

Re: Capital

Непрочитанное сообщение BugsDigger » 06 май 2020, 09:30

Можно использовать

NVLT/NVLTD (по мотивам NATR)
viewtopic.php?t=724#p4517

либо переписать NATR для "точечных" данных, например, так:

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

function Initialize()
{
 // для работы с точечными индикаторами (не свечками) в области цен
 IndicatorName = "pNATRps";
 PriceStudy = true;               // в области цен
 
 AddInput("Input", Inputs.Price); // точки         
 AddSeries("pNATRps", DrawAs.Custom, Color.Blue);

 AddParameter("Period", 30, "Период расчета", 1); // период расчета ATR             
 AddParameter("N", 4.0, "Порог волатильности");   // гистерезис в амплитудах ATR (фактически текущей волатильности)
 AddParameter("Daily", 0, "От начала дня");
 // AddParameter("LogLevel", 0, "Уровень лога");               
   
 AddGlobalVariable("gDirection", Types.Int, 1);
 AddGlobalVariable("gHigh", Types.Double, 0.0);
 AddGlobalVariable("gLow", Types.Double, 100000000000.0);
 AddGlobalVariable("Samples", Types.Int, 0);
 AddGlobalVariable("cATR", Types.Double, 0.0);
 AddGlobalVariable("Result", Types.Double, 0.0);
}

function Evaluate()
{
 double I0=Input[0];
 double I1=(CurrentIndex==0 ? I0 : Input[-1]);

 double InputLo, InputHi; // имитация свечки
 if(CurrentIndex==0 || (Daily!=0 && BarDate()>BarDate(-1)))
 { // неизвестно где или первый бар дня в режиме "Daily"
  InputLo=I0; InputHi=I0;
  gHigh=0.0; gLow=100000000000.0;
  Samples=1;
 }
 else
 {
  if(I0<I1) { InputLo=I0; InputHi=I1; }
  else      { InputLo=I1; InputHi=I0; }
 }

 if(CurrentIndex==0 || (Daily!=0 && BarDate()>BarDate(-1)))
 {
  Result=I0; cATR=0;
 }
 else
 { // очередной бар
  // Вызов индикатора ATR
  // cATR = ATR(Input, Period)[0]; // не работает для точек
 
  // считаем "ручками"
  Samples++;
  double p=Math.Min(Period, Samples);        // текущий период         
  cATR=((p-1.0)*cATR + InputHi-InputLo)/p;   // средняя волатильность по периоду

  double vlt=N;                              // коридор волатильности
  if(p<Period/3.0) vlt=vlt*3.0*p/(double)Period; // берем только долю N при разгоне фильтра, чтобы быстрее встать на нужную сторону тренда
  vlt=vlt*cATR;                           
         
  if(gDirection > 0)
  { // был рост
   if(InputLo < gHigh-vlt)
   {
    gDirection=-1;
    gLow=InputLo;
    Result=gLow+vlt;
   }
   else Result=Math.Max(/*pNATRps[-1]*/ Result, gHigh-vlt); // gHigh-vlt;
  }
  else
  // if(gDirection < 0)
  { // было снижение
   if(InputHi> gLow+vlt)
   {
    gDirection=1;
    gHigh=InputHi;
    Result=gHigh-vlt;
   }
   else Result=Math.Min(/*pNATRps[-1]*/ Result, gLow+vlt); // gLow+vlt;
  }
 }

 if(InputHi > gHigh) gHigh=InputHi;
 if(InputLo < gLow)  gLow =InputLo;

 pNATRps=Result;
 int LW=2; // pNATRps.LineWidth;                      // не работает для CustomDraw (читается всегда 1)
 if(gDirection>0) pNATRps.DrawLine(Color.Green, Line.Solid, LW);
 else             pNATRps.DrawLine(Color.Red,   Line.Solid, LW);
 
/*
 if(LogLevel>0)
 {   
  var Log="D:\\ADdebug\\"+IndicatorName+".txt";
  WriteLine(Log, String.Format("{0} I1:{1:F2} I0:{2:F2} Res:{3:F2} Dir:{4}",
                        GetTime(0), I1,       I0,       pNATRps,   gDirection));
 }
*/
}


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

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

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