TypeOfPeriod - тип периода : 0 - секунды, 1 - минуты, 2 - часы, 3 - день, 4 - неделя, 5 - месяц
PeriodLength - протяженность периода, соответствует интервалам периодов терминала АД4
VerticalShift - смещение по вертикали в пунктах относительно high \ low
Если текущий период графика больше периода заданного в настройках индикатора, или текущий период не кратен периоду заданному в настройках индикатора, то индикатор не отрисовывается.
Пример: 30-ти минутные фракталы на получасовом и минутном фреймах
Файл скрипта:
Код: Выделить всё
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;
}
}