Пользовательские индикаторы > FractalsMTF - отображение фракталов старшего таймфрейма на младшем

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

FractalsMTF - отображение фракталов старшего таймфрейма на младшем

Непрочитанное сообщение Alexey » 07 ноя 2017, 13:19

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

TypeOfPeriod - тип периода : 0 - секунды, 1 - минуты, 2 - часы, 3 - день, 4 - неделя, 5 - месяц
PeriodLength - протяженность периода, соответствует интервалам периодов терминала АД4
VerticalShift - смещение по вертикали в пунктах относительно high \ low

Если текущий период графика больше периода заданного в настройках индикатора, или текущий период не кратен периоду заданному в настройках индикатора, то индикатор не отрисовывается.

Пример: 30-ти минутные фракталы на получасовом и минутном фреймах
FractalsMTF.png


Файл скрипта:
FractalsMTF.rar
(1.51 КБ) 510 скачиваний


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

function Initialize()
{
   IndicatorName = "FractalsMTF";
   PriceStudy = true;
   AddInput("Input", Inputs.Candle);
   AddSeries("UpFractal", DrawAs.Custom, Color.DarkGray);
   AddSeries("DownFractal", DrawAs.Custom, Color.DarkGray);
   
   //
   AddParameter("TypeOfPeriod", 1);    // 0 - Seconds, 1 - Minutes, 2 - Hours, 3 - Day, 4 - Week, 5 - Month
   AddParameter("PeriodLength", 5);    // Period length for period types 0, 1, 2
   AddParameter("VerticalShift", 0.0); // Vertical shift of the arrows
   
   //
   AddGlobalVariable("Init", Types.Boolean, false);
   AddGlobalVariable("Check", Types.Boolean, true);
   AddGlobalVariable("PrevInd", Types.Int, 0);
   AddGlobalVariable("GlVar", Types.Int, -1);
   
   //
   AddGlobalVariable("HighSeries", Types.DoubleList);
   AddGlobalVariable("HighIndSeries", Types.IntList);
   AddGlobalVariable("LowSeries", Types.DoubleList);
   AddGlobalVariable("LowIndSeries", Types.IntList);
   AddGlobalVariable("CircleInd", Types.Int, 0);
}

function Evaluate()
{
   if(!Init)
   {
      if(CurrentIndex < 15 || Check == false) return;
      
      if(!(TypeOfPeriod == 0 || TypeOfPeriod == 1 || TypeOfPeriod == 2 || TypeOfPeriod == 3 || TypeOfPeriod == 4 || TypeOfPeriod == 5))
      {
         ShowMessage("FractalsMTF: Wrong period type value! Do the correction and proceed...");
         Check = false;
         return;
      }
      
      if(TypeOfPeriod == 0 || TypeOfPeriod == 1)
      {
         if(!(PeriodLength == 1 || PeriodLength == 2 || PeriodLength == 3 || PeriodLength == 4 || PeriodLength == 5 || PeriodLength == 6 ||
                PeriodLength == 10 || PeriodLength == 12 || PeriodLength == 15 || PeriodLength == 20 || PeriodLength == 30))
         {
            ShowMessage("FractalsMTF: Wrong period length value! Do the correction and proceed...");
            Check = false;
            return;
         }
      }
      else if(TypeOfPeriod == 2)
      {
         if(!(PeriodLength == 1 || PeriodLength == 2 || PeriodLength == 3 || PeriodLength == 4 || PeriodLength == 6 || PeriodLength == 8 || PeriodLength == 12))
         {
            ShowMessage("FractalsMTF: Wrong period length value! Do the correction and proceed...");
            Check = false;
            return;
         }
      }
      
      int interval = Int32.MaxValue;
      
      for(int i = 0; i > -15; i--)
      {
         int checkingInterval = (int)((BarDate(i) + BarTime(i)) - (BarDate(i-1) + BarTime(i-1))).TotalSeconds;
         if(interval > checkingInterval) interval = checkingInterval;
      }
      
      if(TypeOfPeriod == 0)
      {
         if((PeriodLength % interval != 0 && PeriodLength >= interval) || PeriodLength < interval)
         {
            Check = false;
            return;
         }
      }
      else if(TypeOfPeriod == 1 && interval > 30)
      {
         interval = interval / 60;
         if((PeriodLength % interval != 0 && PeriodLength >= interval) || PeriodLength < interval)
         {
            Check = false;
            return;
         }
      }
      else if(TypeOfPeriod == 2 && interval > 1800)
      {
         interval = interval / 3600;
         if((PeriodLength % interval != 0 && PeriodLength >= interval) || PeriodLength < interval)
         {
            Check = false;
            return;
         }
      }
      else if(TypeOfPeriod == 3 && interval > 86400)
      {
         Check = false;
         return;
      }
      else if(TypeOfPeriod == 4 && interval > 604800)
      {
         Check = false;
         return;
      }

      for(int i = 0; i < 5; i++)
      {
         HighSeries.Add(Double.MaxValue);
         HighIndSeries.Add(0);
         LowSeries.Add(Double.MinValue);
         LowIndSeries.Add(0);
      }
      
      VerticalShift = Math.Abs(VerticalShift);            
      Init = true;
   }
   else if(PrevInd != CurrentIndex)
   {   
      if(HighSeries[CircleInd] <= Input.High[1] + VerticalShift)
      {
         HighSeries[CircleInd] = Input.High[1] + VerticalShift;
         HighIndSeries[CircleInd] = PrevInd;
      }
      
      if(LowSeries[CircleInd] >= Input.Low[1] - VerticalShift)
      {
         LowSeries[CircleInd] = Input.Low[1] - VerticalShift;
         LowIndSeries[CircleInd] = PrevInd;
      }
      
      DateTime BarDateTime = BarDate() + BarTime();
      bool isNewBar = false;
            
      switch ((int)TypeOfPeriod)
      {
          case 0:
                if(GlVar != (BarDateTime.Second / PeriodLength))
                {
                   isNewBar = true;
                   GlVar = (BarDateTime.Second / PeriodLength);
                }
              break;
          case 1:
                if(GlVar != (BarDateTime.Minute / PeriodLength))
                {
                   isNewBar = true;
                   GlVar = (BarDateTime.Minute / PeriodLength);
                }
              break;
          case 2:
                if(GlVar != (BarDateTime.Hour / PeriodLength))
                {
                   isNewBar = true;
                   GlVar = (BarDateTime.Hour / PeriodLength);
                }
              break;
          case 3:
                if(GlVar != BarDateTime.DayOfYear)
                {
                   isNewBar = true;
                   GlVar = BarDateTime.DayOfYear;
                }
              break;
          case 4:   
            int weekNum = System.Globalization.CultureInfo.CurrentCulture.Calendar.GetWeekOfYear(BarDateTime, 0, DayOfWeek.Monday);
                   if(GlVar != weekNum)
                {
                   isNewBar = true;
                   GlVar = weekNum;
                }
              break;
          case 5:
                if(GlVar != BarDateTime.Month)
                {
                   isNewBar = true;
                   GlVar = BarDateTime.Month;
                }
              break;
      }
   
      if(isNewBar)
      {         
         int ind = (CircleInd + 8) % 5;
         
         if(HighSeries[ind] >= HighSeries[(CircleInd + 6) % 5] && HighSeries[ind] >= HighSeries[(CircleInd + 7) % 5] &&
            HighSeries[ind] > HighSeries[(CircleInd + 9) % 5] && HighSeries[ind] > HighSeries[(CircleInd + 5) % 5])
            {
               UpFractal[HighIndSeries[ind] - CurrentIndex] = HighSeries[ind];
            }   
            
         if(LowSeries[ind] <= LowSeries[(CircleInd + 6) % 5] && LowSeries[ind] <= LowSeries[(CircleInd + 7) % 5] &&
            LowSeries[ind] < LowSeries[(CircleInd + 9) % 5] && LowSeries[ind] < LowSeries[(CircleInd + 5) % 5])
            {
               DownFractal[LowIndSeries[ind] - CurrentIndex] = LowSeries[ind];
            }   
         
         if(++CircleInd > 4) CircleInd = 0;
         
         HighSeries[CircleInd] = Input.High + VerticalShift;
         HighIndSeries[CircleInd] = CurrentIndex;
         
         LowSeries[CircleInd] = Input.Low - VerticalShift;
         LowIndSeries[CircleInd] = CurrentIndex;         
      }
      
      UpFractal.DrawArrowUp();
      DownFractal.DrawArrowDown();      
      PrevInd = CurrentIndex;   
   }   
}
Последний раз редактировалось Alexey 09 ноя 2017, 22:47, всего редактировалось 2 раза.

Аватара пользователя
Den
Сообщения: 345
Зарегистрирован: 09 фев 2016, 15:52
Благодарил (а): 14 раз
Поблагодарили: 4 раза

Re: FractalsMTF - отображение фракталов старшего таймфрейма на младшем

Непрочитанное сообщение Den » 09 ноя 2017, 02:54

Добрый день,

а вызов индикатора в нем возможен ? Чтобы его сигналы на вышестоящем ТФ отображались на нижестоящем?

небольшое уточнение

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

function Initialize()
{
IndicatorName = "FractalsMTF";
PriceStudy = true;
AddInput("Input", Inputs.Candle);
AddSeries("UpFractal", DrawAs.Custom, Color.Red);
AddSeries("DownFractal", DrawAs.Custom, Color.Green);

//
AddParameter("TypeOfPeriod", 1); // 0 - Seconds, 1 - Minutes, 2 - Hours, 3 - Day, 4 - Week, 5 - Month
AddParameter("PeriodLength", 5); // Period length for period types 0, 1, 2
AddParameter("VerticalShift", 0.0); // Vertical shift of the arrows

//
AddGlobalVariable("Init", Types.Boolean, false);
AddGlobalVariable("Check", Types.Boolean, true);
AddGlobalVariable("PrevInd", Types.Int, 0);
AddGlobalVariable("IsNewBar", Types.Boolean, false);
AddGlobalVariable("GlVar", Types.Int, -1);

//
AddGlobalVariable("HighSeries", Types.DoubleList);
AddGlobalVariable("HighIndSeries", Types.IntList);
AddGlobalVariable("LowSeries", Types.DoubleList);
AddGlobalVariable("LowIndSeries", Types.IntList);
AddGlobalVariable("CircleInd", Types.Int, 0);
}

function Evaluate()
{
if(!Init)
{
if(CurrentIndex < 15 || Check == false) return;

if(!(TypeOfPeriod == 0 || TypeOfPeriod == 1 || TypeOfPeriod == 2 || TypeOfPeriod == 3 || TypeOfPeriod == 4 || TypeOfPeriod == 5))
{
ShowMessage("FractalsMTF: Wrong period type value! Do the correction and proceed...");
Check = false;
return;
}

if(TypeOfPeriod == 0 || TypeOfPeriod == 1)
{
if(!(PeriodLength == 1 || PeriodLength == 2 || PeriodLength == 3 || PeriodLength == 4 || PeriodLength == 5 || PeriodLength == 6 ||
PeriodLength == 10 || PeriodLength == 12 || PeriodLength == 15 || PeriodLength == 20 || PeriodLength == 30))
{
ShowMessage("FractalsMTF: Wrong period length value! Do the correction and proceed...");
Check = false;
return;
}
}
else if(TypeOfPeriod == 2)
{
if(!(PeriodLength == 1 || PeriodLength == 2 || PeriodLength == 3 || PeriodLength == 4 || PeriodLength == 6 || PeriodLength == 8 || PeriodLength == 12))
{
ShowMessage("FractalsMTF: Wrong period length value! Do the correction and proceed...");
Check = false;
return;
}
}

int interval = Int32.MaxValue;

for(int i = 0; i > -15; i--)
{
int checkingInterval = (int)((BarDate(i) + BarTime(i)) - (BarDate(i-1) + BarTime(i-1))).TotalSeconds;
if(interval > checkingInterval) interval = checkingInterval;
}

if(TypeOfPeriod == 0)
{
if((PeriodLength % interval != 0 && PeriodLength >= interval) || PeriodLength < interval)
{
Check = false;
return;
}
}
else if(TypeOfPeriod == 1 && interval > 30)
{
interval = interval / 60;
if((PeriodLength % interval != 0 && PeriodLength >= interval) || PeriodLength < interval)
{
Check = false;
return;
}
}
else if(TypeOfPeriod == 2 && interval > 1800)
{
interval = interval / 3600;
if((PeriodLength % interval != 0 && PeriodLength >= interval) || PeriodLength < interval)
{
Check = false;
return;
}
}
else if(TypeOfPeriod == 3 && interval > 86400)
{
Check = false;
return;
}
else if(TypeOfPeriod == 4 && interval > 604800)
{
Check = false;
return;
}

for(int i = 0; i < 5; i++)
{
HighSeries.Add(Double.MaxValue);
HighIndSeries.Add(0);
LowSeries.Add(Double.MinValue);
LowIndSeries.Add(0);
}

VerticalShift = Math.Abs(VerticalShift);
Init = true;
}
else if(PrevInd != CurrentIndex)
{
if(HighSeries[CircleInd] <= Input.High[1] + VerticalShift)
{
HighSeries[CircleInd] = Input.High[1] + VerticalShift;
HighIndSeries[CircleInd] = PrevInd;
}

if(LowSeries[CircleInd] >= Input.Low[1] - VerticalShift)
{
LowSeries[CircleInd] = Input.Low[1] - VerticalShift;
LowIndSeries[CircleInd] = PrevInd;
}

DateTime BarDateTime = BarDate() + BarTime();

switch ((int)TypeOfPeriod)
{
case 0:
if(GlVar != (BarDateTime.Second / PeriodLength))
{
IsNewBar = true;
GlVar = (BarDateTime.Second / PeriodLength);
}
else
IsNewBar = false;
break;
case 1:
if(GlVar != (BarDateTime.Minute / PeriodLength))
{
IsNewBar = true;
GlVar = (BarDateTime.Minute / PeriodLength);
}
else
IsNewBar = false;
break;
case 2:
if(GlVar != (BarDateTime.Hour / PeriodLength))
{
IsNewBar = true;
GlVar = (BarDateTime.Hour / PeriodLength);
}
else
IsNewBar = false;
break;
case 3:
if(GlVar != BarDateTime.DayOfYear)
{
IsNewBar = true;
GlVar = BarDateTime.DayOfYear;
}
else
IsNewBar = false;
break;
case 4:
int weekNum = System.Globalization.CultureInfo.CurrentCulture.Calendar.GetWeekOfYear(BarDateTime, 0, DayOfWeek.Monday);
if(GlVar != weekNum)
{
IsNewBar = true;
GlVar = weekNum;
}
else
IsNewBar = false;
break;
case 5:
if(GlVar != BarDateTime.Month)
{
IsNewBar = true;
GlVar = BarDateTime.Month;
}
else
IsNewBar = false;
break;
}

if(IsNewBar)
{
int ind = (CircleInd + 8) % 5;

if(HighSeries[ind] >= HighSeries[(CircleInd + 6) % 5] && HighSeries[ind] >= HighSeries[(CircleInd + 7) % 5] &&
HighSeries[ind] > HighSeries[(CircleInd + 9) % 5] && HighSeries[ind] > HighSeries[(CircleInd + 5) % 5])
{
UpFractal[HighIndSeries[ind] - CurrentIndex] = HighSeries[ind];
}

if(LowSeries[ind] <= LowSeries[(CircleInd + 6) % 5] && LowSeries[ind] <= LowSeries[(CircleInd + 7) % 5] &&
LowSeries[ind] < LowSeries[(CircleInd + 9) % 5] && LowSeries[ind] < LowSeries[(CircleInd + 5) % 5])
{
DownFractal[LowIndSeries[ind] - CurrentIndex] = LowSeries[ind];
}

if(++CircleInd > 4) CircleInd = 0;

HighSeries[CircleInd] = Input.High + VerticalShift;
HighIndSeries[CircleInd] = CurrentIndex;

LowSeries[CircleInd] = Input.Low - VerticalShift;
LowIndSeries[CircleInd] = CurrentIndex;
}

UpFractal.DrawArrowDown(Color.Red, LineStyles.Solid, 5, Color.Red, 10);

DownFractal.DrawArrowUp(Color.Green, LineStyles.Solid, 5, Color.Green, 10);

PrevInd = CurrentIndex;
}
}

 

Alexey
Сообщения: 19
Зарегистрирован: 16 апр 2017, 16:02
Благодарил (а): 1 раз
Поблагодарили: 6 раз

Re: FractalsMTF - отображение фракталов старшего таймфрейма на младшем

Непрочитанное сообщение Alexey » 09 ноя 2017, 11:03

Den писал(а):а вызов индикатора в нем возможен ? Чтобы его сигналы на вышестоящем ТФ отображались на нижестоящем?

Den, здравствуйте. Не совсем понял вопрос - вызов какого индикатора и в ком?

Аватара пользователя
Den
Сообщения: 345
Зарегистрирован: 09 фев 2016, 15:52
Благодарил (а): 14 раз
Поблагодарили: 4 раза

Re: FractalsMTF - отображение фракталов старшего таймфрейма на младшем

Непрочитанное сообщение Den » 09 ноя 2017, 11:07

Вызвать пользовательский MY.индикатор в вашем индикаторе. Чтобы его отражать его сигналы из вышестоящего ТФ в нижестоящем

Alexey
Сообщения: 19
Зарегистрирован: 16 апр 2017, 16:02
Благодарил (а): 1 раз
Поблагодарили: 6 раз

Re: FractalsMTF - отображение фракталов старшего таймфрейма на младшем

Непрочитанное сообщение Alexey » 09 ноя 2017, 11:17

Den писал(а):Вызвать пользовательский MY.индикатор в вашем индикаторе. Чтобы его отражать его сигналы из вышестоящего ТФ в нижестоящем

Думаю, что нет. Индикатор FractalsMTF можно использовать как идею. Надо данные текущего фрейма преобразовать в данные (серии) вышестоящего фрейма, а уже на основании их рассчитывать необходимые данные.

Аватара пользователя
Den
Сообщения: 345
Зарегистрирован: 09 фев 2016, 15:52
Благодарил (а): 14 раз
Поблагодарили: 4 раза

Re: FractalsMTF - отображение фракталов старшего таймфрейма на младшем

Непрочитанное сообщение Den » 09 ноя 2017, 11:21

я это и имел ввиду - только преобразовать сигналы вышестоящего в нижестоящий. Как-бы сделать подстановку, вызов индикатора внутри

Alexey
Сообщения: 19
Зарегистрирован: 16 апр 2017, 16:02
Благодарил (а): 1 раз
Поблагодарили: 6 раз

Re: FractalsMTF - отображение фракталов старшего таймфрейма на младшем

Непрочитанное сообщение Alexey » 09 ноя 2017, 11:28

Den писал(а):я это и имел ввиду - только преобразовать сигналы вышестоящего в нижестоящий. Как-бы сделать подстановку, вызов индикатора внутри

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

Аватара пользователя
Den
Сообщения: 345
Зарегистрирован: 09 фев 2016, 15:52
Благодарил (а): 14 раз
Поблагодарили: 4 раза

Re: FractalsMTF - отображение фракталов старшего таймфрейма на младшем

Непрочитанное сообщение Den » 09 ноя 2017, 11:37

так я же говорю - отображать сигналы пользовательского индикатора из минут на нижестоящем ТФ - в секундах, например.

Аватара пользователя
Den
Сообщения: 345
Зарегистрирован: 09 фев 2016, 15:52
Благодарил (а): 14 раз
Поблагодарили: 4 раза

Re: FractalsMTF - отображение фракталов старшего таймфрейма на младшем

Непрочитанное сообщение Den » 09 ноя 2017, 15:16

Евгений, повторю вопрос уже вам.

Вы не сможете его оптимизировать для подстановки MY.индикатора?

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

Re: FractalsMTF - отображение фракталов старшего таймфрейма на младшем

Непрочитанное сообщение evge » 09 ноя 2017, 15:34

Den писал(а):Евгений, повторю вопрос уже вам.

Вы не сможете его оптимизировать для подстановки MY.индикатора?


Уже ответ был. Это идея, такие тут уже были индикаторы с отображением в других ТФ данных от выше \ нижестоящих ТФ.

А вообще реализовать вывод сигналов (серий) любого индикатора можно, прочитав тему:

Несколько источников данных для стратегии

Там описывается методика и есть нужные скрипты :)

Есть там даже видео, где я показываю как передать из GAZP в SBER данные на одном ТФ, в т.ч. передать (как пример) SMA.

Передавать данные, в т.ч. и значения серий индикаторов, между ТФ можно с помощью WriteData, ReadData.

Просто в коде чтения нужно подправить код, например:

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

var FileName = String.Format("{0}-{1}-{2}-{3}-{4}-{5}",
BarDate().Year, BarDate().Month, BarDate().Day, BarTime().Hours, BarTime().Minutes, BarTime().Seconds);


заменить на

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

var FileName = String.Format("{0}-{1}-{2}-{3}-{4}-{5}",
BarDate().Year, BarDate().Month, BarDate().Day, BarTime().Hours, 0, 0);


в итоге при таком изменении ReadData, чтение из слота данных будет производится только часового ТФ, хотя ТФ рабочий может быть, например, минутный.

Как писать в данные значения индикаторов можно подсмотреть на видео (см. выше ссылку)

Запишу как-нибудь видио-инструкцию как это делать. Но считаю, что там материала достаточно уже чтобы догадаться как это сделать, тем более, что идеи уже даны и описано как сделать :)
никогда такого не было и вот опять


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

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

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