Period - количество баров для поиска экстремума
Shift - сдвиг индикатора вперед по оси времени
Пример: PriceChannel с использованием MaxFor, MinFor
Файлы скриптов
MaxFor
Код: Выделить всё
function Initialize()
{
IndicatorName = "MaxFor";
PriceStudy = true;
AddInput("Input", Inputs.Price);
AddSeries("Max", DrawAs.Line, Color.Blue);
AddParameter("Period", 50);
AddParameter("Shift", 0);
// Дополнительные параметры:
AddGlobalVariable("ArrValue", Types.DoubleList);
AddGlobalVariable("ArrIndex", Types.IntList);
AddGlobalVariable("CircIndex", Types.Int);
AddGlobalVariable("PrevIndex", Types.Int);
AddGlobalVariable("CircSize", Types.Int);
AddGlobalVariable("ArrShift", Types.DoubleList);
AddGlobalVariable("ShiftIndex", Types.Int);
AddGlobalVariable("ShiftSize", Types.Int);
}
function Evaluate()
{
if (CurrentIndex == 0 )
{
if(Period < 2)
Period = 2;
CircSize = Period - 1;
for(int i = 0; i < CircSize; i++)
{
ArrValue.Add(-1.0);
ArrIndex.Add(-1);
}
CircIndex = -1;
PrevIndex = 0;
Max = Input[0];
ShiftSize = (int)Math.Abs(Shift) + 1;
ShiftIndex = 0;
for(int i = 0; i < ShiftSize; i++)
{
ArrShift.Add(Max);
}
}
else
{
if (PrevIndex < CurrentIndex)
{
CircIndex++;
if(CircIndex >= CircSize) CircIndex = 0;
ShiftIndex++;
if(ShiftIndex >= ShiftSize) ShiftIndex = 0;
ArrIndex[CircIndex] = 0;
ArrValue[CircIndex] = Input[1];
for(int counter = CircSize - 2; counter >= 0; counter--)
{
int trueIndex = (CircIndex + counter + 1) % CircSize;
int jumpIndex = ArrIndex[trueIndex];
if(jumpIndex < 0)
{
break;
}
if(ArrValue[CircIndex] < ArrValue[trueIndex])
{
ArrIndex[CircIndex] = ArrIndex[CircIndex];
break;
}
else
{
if(jumpIndex > 0)
{
ArrIndex[CircIndex] = ArrIndex[CircIndex] + jumpIndex + 1;
counter = counter - jumpIndex;
}
else
{
++ArrIndex[CircIndex];
}
}
}
PrevIndex = CurrentIndex;
//---
double maxValue = Input[0];
for(int counter = CircSize - 1; counter >= 0; counter--)
{
int trueIndex = (CircIndex + counter + 1) % CircSize;
int jumpIndex = ArrIndex[trueIndex];
if(jumpIndex < 0)
{
break;
}
else
{
counter = counter - jumpIndex;
}
if(maxValue < ArrValue[trueIndex])
{
maxValue = ArrValue[trueIndex];
}
//---
ArrShift[ShiftIndex] = maxValue;
Max = ArrShift[(ShiftIndex + 1) % ShiftSize];
}
}
else
{
if(ArrShift[ShiftIndex] < Input[0] && Shift == 0)
{
ArrShift[ShiftIndex] = Input[0];
}
Max = ArrShift[(ShiftIndex + 1) % ShiftSize];
}
}
}
MinFor
Код: Выделить всё
function Initialize()
{
IndicatorName = "MinFor";
PriceStudy = true;
AddInput("Input", Inputs.Price);
AddSeries("Min", DrawAs.Line, Color.Red);
AddParameter("Period", 50);
AddParameter("Shift", 0);
// Дополнительные параметры:
AddGlobalVariable("ArrValue", Types.DoubleList);
AddGlobalVariable("ArrIndex", Types.IntList);
AddGlobalVariable("CircIndex", Types.Int);
AddGlobalVariable("PrevIndex", Types.Int);
AddGlobalVariable("CircSize", Types.Int);
AddGlobalVariable("ArrShift", Types.DoubleList);
AddGlobalVariable("ShiftIndex", Types.Int);
AddGlobalVariable("ShiftSize", Types.Int);
}
function Evaluate()
{
if (CurrentIndex == 0 )
{
if(Period < 2)
Period = 2;
CircSize = Period - 1;
for(int i = 0; i < CircSize; i++)
{
ArrValue.Add(-1.0);
ArrIndex.Add(-1);
}
CircIndex = -1;
PrevIndex = 0;
Min = Input[0];
ShiftSize = (int)Math.Abs(Shift) + 1;
ShiftIndex = 0;
for(int i = 0; i < ShiftSize; i++)
{
ArrShift.Add(Min);
}
}
else
{
if (PrevIndex < CurrentIndex)
{
CircIndex++;
if(CircIndex >= CircSize) CircIndex = 0;
ShiftIndex++;
if(ShiftIndex >= ShiftSize) ShiftIndex = 0;
ArrIndex[CircIndex] = 0;
ArrValue[CircIndex] = Input[1];
for(int counter = CircSize - 2; counter >= 0; counter--)
{
int trueIndex = (CircIndex + counter + 1) % CircSize;
int jumpIndex = ArrIndex[trueIndex];
if(jumpIndex < 0)
{
break;
}
if(ArrValue[CircIndex] > ArrValue[trueIndex])
{
ArrIndex[CircIndex] = ArrIndex[CircIndex];
break;
}
else
{
if(jumpIndex > 0)
{
ArrIndex[CircIndex] = ArrIndex[CircIndex] + jumpIndex + 1;
counter = counter - jumpIndex;
}
else
{
++ArrIndex[CircIndex];
}
}
}
PrevIndex = CurrentIndex;
//---
double minValue = Input[0];
for(int counter = CircSize - 1; counter >= 0; counter--)
{
int trueIndex = (CircIndex + counter + 1) % CircSize;
int jumpIndex = ArrIndex[trueIndex];
if(jumpIndex < 0)
{
break;
}
else
{
counter = counter - jumpIndex;
}
if(minValue > ArrValue[trueIndex])
{
minValue = ArrValue[trueIndex];
}
}
//---
ArrShift[ShiftIndex] = minValue;
Min = ArrShift[(ShiftIndex + 1) % ShiftSize];
}
else
{
if(ArrShift[ShiftIndex] > Input[0] && Shift == 0)
{
ArrShift[ShiftIndex] = Input[0];
}
//---
Min = ArrShift[(ShiftIndex + 1) % ShiftSize];
}
}
}