Между двумя последними понижающимися максимумами и двумя последними повышающимися минимумами, если таковые имеются, рисуется трендовая линия до текущего бара (последний видимый бар на графике). Если между данными экстремумами имеется противоположный экстремум (мин., макс.) на него проецируется трендовая линия, формируя канал. Дополнительно рисуется центральная линия.
Входные параметры:
PeriodL - количество баров (слева) для поиска экстремумов
PeriodR - количество баров (справа) для поиска экстремумов
Scan - количество баров сканируемой истории
ShowType - отображение в виде: 0 - каналы, 1..x - линии
Примеры работы:
Исходный текст индикатора:
Код: Выделить всё
function Initialize()
{
IndicatorName = "AutoChannels";
PriceStudy = true;
AddInput("Input", Inputs.Candle);
AddSeries("EH", DrawAs.Custom, Color.Green, true, Axes.Parent);
AddSeries("EL", DrawAs.Custom, Color.Red, true, Axes.Parent);
AddSeries("Up1", DrawAs.Custom, Color.Green, true, Axes.Parent);
AddSeries("Up2", DrawAs.Custom, Color.Green, true, Axes.Parent);
AddSeries("UpA", DrawAs.Custom, Color.Gray, true, Axes.Parent); //average line
AddSeries("Down1", DrawAs.Custom, Color.Red, true, Axes.Parent);
AddSeries("Down2", DrawAs.Custom, Color.Red, true, Axes.Parent);
AddSeries("DownA", DrawAs.Custom, Color.Gray, true, Axes.Parent); //average line
AddParameter("PeriodL", 15); // фракталы, баров слева
AddParameter("PeriodR", 15); // фракталы, баров справа
AddParameter("Scan", 300, 1); // сканируемый период
AddParameter("ShowType", 0); // отображение в виде: 0 - каналы, 1..x - линии
}
function Evaluate()
{
// evge 18.02.2016 - 20.02.2016, http://alfadirect4.ru
// Extremums
if ((MaxIndex - CurrentIndex) > Scan) return;
var High = Input.High[PeriodR];
var Low = Input.Low[PeriodR];
var HC = true;
var LC = true;
//PeriodR
for (var x = 0; x < PeriodR; x++) {
if (HC) if (Input.High[x] > High) HC = false;
if (LC) if (Input.Low[x] < Low) LC = false;
if (!LC && !HC) break;
} //x
//PeriodL
for (var x = 0; x < PeriodL; x++) {
if (HC) if (Input.High[PeriodR + PeriodL - x] > High) HC = false;
if (LC) if (Input.Low[PeriodR + PeriodL - x] < Low) LC = false;
if (!LC && !HC) break;
} //x
if (HC) EH[PeriodR] = Input.High[PeriodR];
if (LC) EL[PeriodR] = Input.Low[PeriodR];
EH.DrawCircle();
EL.DrawCircle();
// TrendLines
if (MaxIndex == CurrentIndex) {
// Нисходящий канал / тренд
int x1 = 0, x2 = 0, x3 = 0;
double y1 = 0.0, y2 = 0.0, y3 = 0.0, Shift = 0.0;
for (var x = 0 + PeriodR; x < Scan; x++) {
if (EH[x] > 0 && y2 == 0) { y2 = EH[x]; x2 = x; x++;//x+=Period-1;
}
if (y2 != 0) {
if (EH[x] > 0 && y1 == 0 && y2 > EH[x]) break;
if (EL[x] > 0) { x3 = x; y3 = EL[x]; }
if (EH[x] > 0 && y1 == 0) { y1 = EH[x]; x1 = x; break; }
} //y2
} //x
if (x1 > 0 && x2 > 0) {
Down1[x1] = y1;
Down1[0] = (double)(0 - x1) / (x2 - x1) * (y2 - y1) + y1;
if (x1 > x3 && x3 > x2)
{
Shift = y3 - ((double)(x3 - x1) / (x2 - x1) * (y2 - y1) + y1);
Down2[x1] = Down1[x1] + Shift; //y3
Down2[0] = Down1[0] + Shift;
DownA[x1] = Down1[x1] + Shift / 2; //y3
DownA[0] = Down1[0] + Shift / 2;
}
}
// Восходящий канал / тренд
x1 = 0; x2 = 0; x3 = 0;
y1 = 0.0; y2 = 0.0; y3 = 0.0;
for (var x = 0 + PeriodR; x < Scan; x++) {
if (EL[x] > 0 && y2 == 0) { y2 = EL[x]; x2 = x; x++; //x+=Period-1;
}
if (y2 != 0) {
if (EL[x] > 0 && y1 == 0 && y2 < EL[x]) break;
if (EH[x] > 0) { x3 = x; y3 = EH[x]; }
if (EL[x] > 0 && y1 == 0) { y1 = EL[x]; x1 = x; break; }
} //y2
} //x
if (x1 > 0 && x2 > 0) {
Up1[x1] = y1;
Up1[0] = (double)(0 - x1) / (x2 - x1) * (y2 - y1) + y1;
if (x1 > x3 && x3 > x2)
{
Shift = y3 - ((double)(x3 - x1) / (x2 - x1) * (y2 - y1) + y1);
Up2[x1] = Up1[x1] + Shift; //y3
Up2[0] = Up1[0] + Shift;
UpA[x1] = Up1[x1] + Shift / 2; //y3
UpA[0] = Up1[0] + Shift / 2;
}
}
} //m=c
if (ShowType == 0) {
if (Down2 > 0)
Down1.DrawChannel(Down2);
else
Down1.DrawLine();
if (Up2 > 0)
Up1.DrawChannel(Up2);
else
Up1.DrawLine();
} else
{
Down1.DrawLine();
Up1.DrawLine();
Down2.DrawLine();
Up2.DrawLine();
}
UpA.DrawLine();
DownA.DrawLine();
}
Скачать исходный текст: