I tried to make that hxxps://www.tradingview.com/script/d3Ia (replace xx to tt)Fa7c-Trend-Impulse-Channels-Zeiierman/ for MT5, yes it draws those channels and arrows and gives alerts too. It's just surprising when even such close TFs as M5 and M6 draw different channels.
But the source code is available to everyone. This is made with Grok4. Do you get it/like it? continue to refine
Code: Select all
// This work is licensed under a Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0) https://creativecommons.org/licenses/by-nc-sa/4.0/
// © Zeiierman
#property copyright "Zeiierman"
#property link ""
#property version "1.00"
#property strict
#property indicator_chart_window
#property indicator_buffers 10
#property indicator_plots 7
// Inputs
input double flipMult = 2.86; // Trigger Threshold
input double maxStepAtr = -0.034; // Max Step Size
input double bandMult = 2.02; // Band Multiplier
input int holdBars = 0; // Trend Hold
input color colorUp = clrLime;
input color colorDown = clrRed;
input bool showFill = true; // Channel Fill
input bool ChannelRetestSignal = true; // Retest Signals
input bool TrendFilter = true; // Filter by Trend
input color colorUp2 = clrLime;
input color colorDown2 = clrRed;
input bool TrendStepSignal = false; // Trend Step Signals
input color colorUp3 = clrLime;
input color colorDown3 = clrRed;
// Buffers
double TrendBuffer[];
double TrendColors[];
double UpperBuffer[];
double UpperColors[];
double LowerBuffer[];
double LowerColors[];
double LowerRetestBuf[];
double UpperRetestBuf[];
double BullStepBuf[];
double BearStepBuf[];
// Calculation arrays
double dirArray[];
double barsInTrendArray[];
double extensionArray[];
// ATR handle
int atrHandle;
// OnInit
int OnInit()
{
IndicatorSetString(INDICATOR_SHORTNAME, "Trend Impulse Channels (Zeiierman)");
SetIndexBuffer(0, TrendBuffer, INDICATOR_DATA);
PlotIndexSetString(0, PLOT_LABEL, "Trend Line");
PlotIndexSetInteger(0, PLOT_DRAW_TYPE, DRAW_COLOR_LINE);
PlotIndexSetInteger(0, PLOT_LINE_WIDTH, 2);
SetIndexBuffer(1, TrendColors, INDICATOR_COLOR_INDEX);
PlotIndexSetInteger(0, PLOT_COLOR_INDEXES, 3);
PlotIndexSetInteger(0, PLOT_LINE_COLOR, 0, colorUp);
PlotIndexSetInteger(0, PLOT_LINE_COLOR, 1, colorDown);
PlotIndexSetInteger(0, PLOT_LINE_COLOR, 2, clrGray);
SetIndexBuffer(2, UpperBuffer, INDICATOR_DATA);
PlotIndexSetString(1, PLOT_LABEL, "Upper Band");
PlotIndexSetInteger(1, PLOT_DRAW_TYPE, DRAW_COLOR_LINE);
PlotIndexSetInteger(1, PLOT_COLOR_INDEXES, 3);
PlotIndexSetInteger(1, PLOT_LINE_COLOR, 0, colorUp);
PlotIndexSetInteger(1, PLOT_LINE_COLOR, 1, colorDown);
PlotIndexSetInteger(1, PLOT_LINE_COLOR, 2, clrGray);
SetIndexBuffer(3, UpperColors, INDICATOR_COLOR_INDEX);
SetIndexBuffer(4, LowerBuffer, INDICATOR_DATA);
PlotIndexSetString(2, PLOT_LABEL, "Lower Band");
PlotIndexSetInteger(2, PLOT_DRAW_TYPE, DRAW_COLOR_LINE);
PlotIndexSetInteger(2, PLOT_COLOR_INDEXES, 3);
PlotIndexSetInteger(2, PLOT_LINE_COLOR, 0, colorUp);
PlotIndexSetInteger(2, PLOT_LINE_COLOR, 1, colorDown);
PlotIndexSetInteger(2, PLOT_LINE_COLOR, 2, clrGray);
SetIndexBuffer(5, LowerColors, INDICATOR_COLOR_INDEX);
SetIndexBuffer(6, LowerRetestBuf, INDICATOR_DATA);
PlotIndexSetString(3, PLOT_LABEL, "Lower Retest");
PlotIndexSetInteger(3, PLOT_DRAW_TYPE, DRAW_ARROW);
PlotIndexSetInteger(3, PLOT_LINE_COLOR, colorUp2);
PlotIndexSetInteger(3, PLOT_ARROW, 225); // Triangle up
SetIndexBuffer(7, UpperRetestBuf, INDICATOR_DATA);
PlotIndexSetString(4, PLOT_LABEL, "Upper Retest");
PlotIndexSetInteger(4, PLOT_DRAW_TYPE, DRAW_ARROW);
PlotIndexSetInteger(4, PLOT_LINE_COLOR, colorDown2);
PlotIndexSetInteger(4, PLOT_ARROW, 226); // Triangle down
SetIndexBuffer(8, BullStepBuf, INDICATOR_DATA);
PlotIndexSetString(5, PLOT_LABEL, "Bullish Step");
PlotIndexSetInteger(5, PLOT_DRAW_TYPE, DRAW_ARROW);
PlotIndexSetInteger(5, PLOT_LINE_COLOR, colorUp3);
PlotIndexSetInteger(5, PLOT_ARROW, 159); // Circle
SetIndexBuffer(9, BearStepBuf, INDICATOR_DATA);
PlotIndexSetString(6, PLOT_LABEL, "Bearish Step");
PlotIndexSetInteger(6, PLOT_DRAW_TYPE, DRAW_ARROW);
PlotIndexSetInteger(6, PLOT_LINE_COLOR, colorDown3);
PlotIndexSetInteger(6, PLOT_ARROW, 159); // Circle
atrHandle = iATR(NULL, 0, 200);
if (atrHandle == INVALID_HANDLE)
{
Print("Failed to create ATR handle");
return(INIT_FAILED);
}
return(INIT_SUCCEEDED);
}
// OnDeinit
void OnDeinit(const int reason)
{
IndicatorRelease(atrHandle);
}
// OnCalculate
int OnCalculate(const int rates_total,
const int prev_calculated,
const datetime &time[],
const double &open[],
const double &high[],
const double &low[],
const double &close[],
const long &tick_volume[],
const long &volume[],
const int &spread[])
{
if (rates_total < 1) return(0);
ArraySetAsSeries(TrendBuffer, false);
ArraySetAsSeries(TrendColors, false);
ArraySetAsSeries(UpperBuffer, false);
ArraySetAsSeries(UpperColors, false);
ArraySetAsSeries(LowerBuffer, false);
ArraySetAsSeries(LowerColors, false);
ArraySetAsSeries(LowerRetestBuf, false);
ArraySetAsSeries(UpperRetestBuf, false);
ArraySetAsSeries(BullStepBuf, false);
ArraySetAsSeries(BearStepBuf, false);
ArraySetAsSeries(high, false);
ArraySetAsSeries(low, false);
ArraySetAsSeries(close, false);
ArraySetAsSeries(time, false);
ArrayResize(dirArray, rates_total);
ArrayResize(barsInTrendArray, rates_total);
ArrayResize(extensionArray, rates_total);
double atrBuffer[];
ArraySetAsSeries(atrBuffer, false);
if (CopyBuffer(atrHandle, 0, 0, rates_total, atrBuffer) != rates_total) return(0);
int limit = (prev_calculated == 0) ? 0 : prev_calculated - 1;
static datetime currentBarTime = 0;
static bool alertedLowerRetest = false;
static bool alertedUpperRetest = false;
static bool alertedBullStep = false;
static bool alertedBearStep = false;
if (time[ rates_total - 1 ] != currentBarTime)
{
currentBarTime = time[ rates_total - 1 ];
alertedLowerRetest = false;
alertedUpperRetest = false;
alertedBullStep = false;
alertedBearStep = false;
}
for (int i = limit; i < rates_total; i++)
{
double atr = atrBuffer[i];
double stepBase = atr * 2.52;
double maxStep = atr * maxStepAtr;
double trigger = atr * flipMult;
double offset = atr * 0.1; // Offset for positioning shapes
if (atr == 0)
{
stepBase = 0;
maxStep = 0;
trigger = 0; // But will force no flip
}
if (i == 0)
{
TrendBuffer[i] = close[i];
dirArray[i] = 0;
barsInTrendArray[i] = 0;
extensionArray[i] = 0;
}
else
{
double prevTrend = TrendBuffer[i-1];
int prevDir = (int)dirArray[i-1];
int prevBarsInTrend = (int)barsInTrendArray[i-1];
int prevExtension = (int)extensionArray[i-1];
bool startLong = close[i] > prevTrend + trigger;
bool startShort = close[i] < prevTrend - trigger;
if (atr == 0)
{
startLong = false;
startShort = false;
}
bool flip = (startLong || startShort) && prevBarsInTrend >= 0;
double stepSize = MathMin(stepBase + 0.0093 * prevBarsInTrend * atr, maxStep);
if (flip && prevExtension <= 0)
{
TrendBuffer[i] = close[i];
dirArray[i] = startLong ? 1 : -1;
barsInTrendArray[i] = 1;
extensionArray[i] = holdBars;
}
else
{
double add = (prevDir == 1 ? stepSize : (prevDir == -1 ? -stepSize : 0));
TrendBuffer[i] = prevTrend + add;
dirArray[i] = prevDir;
barsInTrendArray[i] = prevBarsInTrend + 1;
extensionArray[i] = MathMax(prevExtension - 1, 0);
}
}
int trendDirection = (int)dirArray[i] == 1 ? 1 : ((int)dirArray[i] == -1 ? -1 : 0);
if (atr == 0 && showFill)
{
UpperBuffer[i] = EMPTY_VALUE;
LowerBuffer[i] = EMPTY_VALUE;
}
else
{
UpperBuffer[i] = showFill ? TrendBuffer[i] + atr * bandMult : EMPTY_VALUE;
LowerBuffer[i] = showFill ? TrendBuffer[i] - atr * bandMult : EMPTY_VALUE;
}
if ((int)dirArray[i] == 1) TrendColors[i] = 0;
else if ((int)dirArray[i] == -1) TrendColors[i] = 1;
else TrendColors[i] = 2;
UpperColors[i] = TrendColors[i];
LowerColors[i] = TrendColors[i];
bool crossUnder = false;
bool crossOver = false;
if (i > 0)
{
bool cu = (low[i-1] >= LowerBuffer[i-1] && low[i] < LowerBuffer[i]);
bool co = (high[i-1] <= UpperBuffer[i-1] && high[i] > UpperBuffer[i]);
if (TrendFilter)
{
crossUnder = cu && trendDirection == 1;
crossOver = co && trendDirection == -1;
}
else
{
crossUnder = cu;
crossOver = co;
}
}
LowerRetestBuf[i] = (crossUnder && ChannelRetestSignal) ? low[i] - offset : EMPTY_VALUE;
UpperRetestBuf[i] = (crossOver && ChannelRetestSignal) ? high[i] + offset : EMPTY_VALUE;
bool trendStep = false;
if (i > 0)
{
trendStep = ((int)dirArray[i] != 0) && (TrendBuffer[i] != TrendBuffer[i-1]) &&
((TrendBuffer[i] > TrendBuffer[i-1] && (int)dirArray[i] == 1) ||
(TrendBuffer[i] < TrendBuffer[i-1] && (int)dirArray[i] == -1));
}
BullStepBuf[i] = (trendStep && (int)dirArray[i] == 1 && TrendStepSignal) ? high[i] : EMPTY_VALUE;
BearStepBuf[i] = (trendStep && (int)dirArray[i] == -1 && TrendStepSignal) ? low[i] : EMPTY_VALUE;
// Alerts
if (i == rates_total - 1)
{
if (crossUnder && !alertedLowerRetest)
{
Alert("Lower Retest");
alertedLowerRetest = true;
}
if (crossOver && !alertedUpperRetest)
{
Alert("Upper Retest");
alertedUpperRetest = true;
}
if (trendStep && (int)dirArray[i] == 1 && !alertedBullStep)
{
Alert("Bullish Step");
alertedBullStep = true;
}
if (trendStep && (int)dirArray[i] == -1 && !alertedBearStep)
{
Alert("Bearish Step");
alertedBearStep = true;
}
}
}
return(rates_total);
}