Indicators Used
Miscellaneous
0
Views
0
Downloads
0
Favorites
MAChannel_Close_AD
#property copyright "Scriptong"
#property link "http://advancetools.net"
#property description "English: Horizontal channel, based on extremums between the crossing of the two Moving Averages.\nRussian: Ãîðèçîíòàëüíûé êàíàë, îïèðàþùèéñÿ íà ýêñòðåìóìû ìåæäó ïåðåñå÷åíèÿìè äâóõ Moving Average."
#property version "1.03"
#property strict
#property indicator_chart_window
#property indicator_buffers 5
#property indicator_color1 clrBlue
#property indicator_color2 clrRed
#property indicator_color3 clrBlue
#property indicator_color4 clrRed
#property indicator_color5 clrNONE
#property indicator_width1 2
#property indicator_width2 2
#property indicator_style3 STYLE_DOT
#property indicator_style4 STYLE_DOT
enum ENUM_YESNO
{
NO, // No / Íåò
YES // Yes / Äà
};
input uint i_maFastPeriod = 1; // Period of fast MA / Ïåðèîä ðàñ÷åòà áûñòðîé ÌÀ
input ENUM_MA_METHOD i_maFastMethod = MODE_SMA; // Method of fast MA / Ìåòîä ðàñ÷åòà áûñòðîé ÌÀ
input ENUM_APPLIED_PRICE i_maFastPrice = PRICE_WEIGHTED; // Applied price of fast MA / Öåíà ðàñ÷åòà áûñòðîé ÌÀ
input uint i_maSlowPeriod = 21; // Period of slow MA / Ïåðèîä ðàñ÷åòà ìåäëåííîé ÌÀ
input ENUM_MA_METHOD i_maSlowMethod = MODE_EMA; // Method of slow MA / Ìåòîä ðàñ÷åòà ìåäëåííîé ÌÀ
input ENUM_APPLIED_PRICE i_maSlowPrice = PRICE_WEIGHTED; // Applied price od slow MA / Öåíà ðàñ÷åòà ìåäëåííîé ÌÀ
input ENUM_YESNO i_isAlert = YES; // Alert on trend change? / Ñèãíàë ïðè ñìåíå òðåíäà?
input ENUM_YESNO i_isPush = YES; // Notification on trend change? / Óâåäîìëÿòü ïðè ñìåíå òðåíäà?
input int i_indBarsCount = 10000; // Number of bars to display / Êîë-âî áàðîâ îòîáðàæåíèÿ
bool g_activate;
int g_maxMAPeriod;
double g_point,
g_delta;
enum ENUM_TREND_TYPE
{
TREND_TYPE_NONE,
TREND_TYPE_UPWARD,
TREND_TYPE_DOWNWARD
};
enum ENUM_MESSAGE_CODE
{
MESSAGE_CODE_MA_FAST_LESS_THAN_ZERO,
MESSAGE_CODE_MA_SLOW_LESS_THAN_ZERO,
MESSAGE_CODE_TERMINAL_FATAL_ERROR1,
MESSAGE_CODE_TREND_CHANGE_TO_UPWARD,
MESSAGE_CODE_TREND_CHANGE_TO_DOWNWARD,
MESSAGE_CODE_BIND_ERROR
};
// Ìàññèâû áóôåðîâ íäèêàòîðà
double g_highSolid[];
double g_lowSolid[];
double g_highDot[];
double g_lowDot[];
double g_curTrend[];
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Custom indicator initialization function |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
int OnInit()
{
g_activate = false;
if (!TuningParameters())
return INIT_FAILED;
if (!BuffersBind())
return INIT_FAILED;
g_activate = true;
return INIT_SUCCEEDED;
}
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Checking the correctness of values of tuning parameters |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
bool TuningParameters()
{
string name = WindowExpertName();
if (i_maFastPeriod < 1)
{
Alert(name, GetStringByMessageCode(MESSAGE_CODE_MA_FAST_LESS_THAN_ZERO));
return false;
}
if (i_maSlowPeriod < 1)
{
Alert(name, GetStringByMessageCode(MESSAGE_CODE_MA_SLOW_LESS_THAN_ZERO));
return false;
}
g_point = Point;
g_delta = -g_point / 10;
if (g_point == 0)
{
Alert(name, GetStringByMessageCode(MESSAGE_CODE_TERMINAL_FATAL_ERROR1));
return false;
}
g_maxMAPeriod = (int)MathMax(i_maFastPeriod, i_maSlowPeriod);
return true;
}
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Custom indicator deinitialization function |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
void OnDeinit(const int reason)
{
}
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Binding of array and the indicator buffers |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
bool BuffersBind()
{
string name = WindowExpertName();
// IndicatorBuffers(5);
// Ñâÿçûâàíèå áóôåðîâ èíäèêàòîðà ñ ìàññèâàìè
if (!SetIndexBuffer(0, g_highSolid) ||
!SetIndexBuffer(1, g_lowSolid) ||
!SetIndexBuffer(2, g_highDot) ||
!SetIndexBuffer(3, g_lowDot) ||
!SetIndexBuffer(4, g_curTrend))
{
Alert(name, GetStringByMessageCode(MESSAGE_CODE_BIND_ERROR), GetLastError());
return false;
}
// Çàäàíèå ãðàôè÷åñêîãî òèïà áóôåðîâ
for (int i = 0; i < 4; i++)
SetIndexStyle(i, DRAW_LINE);
SetIndexStyle(4, DRAW_NONE);
SetIndexLabel(0, "Resistance of downward trend");
SetIndexLabel(1, "Support of upward trend");
SetIndexLabel(2, "Breaking resistance");
SetIndexLabel(3, "Breaking support");
SetIndexLabel(4, "Trend Direction");
return true;
}
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Initialize of all indicator buffers |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
void BuffersInitializeAll()
{
ArrayInitialize(g_highSolid, EMPTY_VALUE);
ArrayInitialize(g_lowSolid, EMPTY_VALUE);
ArrayInitialize(g_highDot, EMPTY_VALUE);
ArrayInitialize(g_lowDot, EMPTY_VALUE);
ArrayInitialize(g_curTrend, TREND_TYPE_NONE);
}
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Determination of bar index which needed to recalculate |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
int GetRecalcIndex(int &total, const int ratesTotal, const int prevCalculated)
{
total = ratesTotal - g_maxMAPeriod - 2;
if (i_indBarsCount > 0 && i_indBarsCount < total)
total = MathMin(i_indBarsCount, total);
if (prevCalculated < ratesTotal - 1)
{
BuffersInitializeAll();
return total;
}
return (MathMin(ratesTotal - prevCalculated, total));
}
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| The minimal price at the downtrend interval |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
double GetLowPrice(int barIndex)
{
double lowPrice = Low[barIndex];
for (int i = barIndex + 1; i < Bars; i++)
{
double maFast = iMA(NULL, 0, i_maFastPeriod, 0, i_maFastMethod, i_maFastPrice, i);
double maSlow = iMA(NULL, 0, i_maSlowPeriod, 0, i_maSlowMethod, i_maSlowPrice, i);
if (maFast > maSlow)
return lowPrice;
lowPrice = MathMin(lowPrice, Low[i]);
}
return lowPrice;
}
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| The maximal price at the downtrend interval |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
double GetHighPrice(int barIndex)
{
double highPrice = High[barIndex];
for (int i = barIndex + 1; i < Bars; i++)
{
double maFast = iMA(NULL, 0, i_maFastPeriod, 0, i_maFastMethod, i_maFastPrice, i);
double maSlow = iMA(NULL, 0, i_maSlowPeriod, 0, i_maSlowMethod, i_maSlowPrice, i);
if (maFast < maSlow)
return highPrice;
highPrice = MathMax(highPrice, High[i]);
}
return highPrice;
}
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| The continuity of the indicator buffers values |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
void ContinuityBuffers(int barIndex)
{
if (g_curTrend[barIndex + 1] == TREND_TYPE_UPWARD)
{
g_lowDot[barIndex + 1] = EMPTY_VALUE;
g_highSolid[barIndex + 1] = EMPTY_VALUE;
}
if (g_curTrend[barIndex + 1] == TREND_TYPE_DOWNWARD)
{
g_highDot[barIndex + 1] = EMPTY_VALUE;
g_lowSolid[barIndex + 1] = EMPTY_VALUE;
}
g_highSolid[barIndex] = g_highSolid[barIndex + 1];
g_lowSolid[barIndex] = g_lowSolid[barIndex + 1];
g_highDot[barIndex] = g_highDot[barIndex + 1];
g_lowDot[barIndex] = g_lowDot[barIndex + 1];
g_curTrend[barIndex] = g_curTrend[barIndex + 1];
}
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| To process the upward MA cross |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
void ProcessUpwardMACross(int barIndex)
{
if (g_curTrend[barIndex + 1] == TREND_TYPE_DOWNWARD)
{
g_lowDot[barIndex] = GetLowPrice(barIndex);
g_lowSolid[barIndex] = EMPTY_VALUE;
if (g_lowDot[barIndex + 1] == EMPTY_VALUE)
g_lowDot[barIndex + 1] = g_lowDot[barIndex];
return;
}
g_lowSolid[barIndex] = GetLowPrice(barIndex);
g_lowDot[barIndex] = EMPTY_VALUE;
if (g_lowSolid[barIndex + 1] == EMPTY_VALUE)
g_lowSolid[barIndex + 1] = g_lowSolid[barIndex];
}
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| To process the downward MA cross |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
void ProcessDownwardMACross(int barIndex)
{
if (g_curTrend[barIndex + 1] == TREND_TYPE_UPWARD)
{
g_highDot[barIndex] = GetHighPrice(barIndex);
g_highSolid[barIndex] = EMPTY_VALUE;
if (g_highDot[barIndex + 1] == EMPTY_VALUE)
g_highDot[barIndex + 1] = g_highDot[barIndex];
return;
}
g_highSolid[barIndex] = GetHighPrice(barIndex);
g_highDot[barIndex] = EMPTY_VALUE;
if (g_highSolid[barIndex + 1] == EMPTY_VALUE)
g_highSolid[barIndex + 1] = g_highSolid[barIndex];
}
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Cast the timeframe to string value |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
string CastTFToString(ENUM_TIMEFRAMES tf)
{
switch(tf)
{
case PERIOD_H1: return "H1";
case PERIOD_H4: return "H4";
case PERIOD_D1: return "D1";
case PERIOD_W1: return "W1";
case PERIOD_MN1: return "MN1";
}
return "M" + IntegerToString((int)tf);
}
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| To process of breakout of resistance level |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
void ProcessResistanceBreak(int barIndex)
{
g_curTrend[barIndex] = TREND_TYPE_UPWARD;
g_highDot[barIndex + 1] = g_highSolid[barIndex + 1];
g_highDot[barIndex] = (g_highSolid[barIndex] == EMPTY_VALUE)? g_highSolid[barIndex + 1] : g_highSolid[barIndex];
g_highSolid[barIndex] = EMPTY_VALUE;
if (g_lowDot[barIndex + 1] == EMPTY_VALUE)
return;
g_lowSolid[barIndex + 1] = g_lowDot[barIndex + 1];
g_lowSolid[barIndex] = (g_lowDot[barIndex] == EMPTY_VALUE)? g_lowDot[barIndex + 1] : g_lowDot[barIndex];
g_lowDot[barIndex] = EMPTY_VALUE;
}
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| To process of breakout of the support level |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
void ProcessSupportBreak(int barIndex)
{
g_curTrend[barIndex] = TREND_TYPE_DOWNWARD;
g_lowDot[barIndex + 1] = g_lowSolid[barIndex + 1];
g_lowDot[barIndex] = (g_lowSolid[barIndex] == EMPTY_VALUE)? g_lowSolid[barIndex + 1] : g_lowSolid[barIndex];
g_lowSolid[barIndex] = EMPTY_VALUE;
if (g_highDot[barIndex + 1] == EMPTY_VALUE)
return;
g_highSolid[barIndex + 1] = g_highDot[barIndex + 1];
g_highSolid[barIndex] = (g_highDot[barIndex] == EMPTY_VALUE)? g_highDot[barIndex + 1] : g_highDot[barIndex];
g_highDot[barIndex] = EMPTY_VALUE;
}
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Calculation of the indicators values at the specified bar |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
void CalculateOneBarMA(int barIndex)
{
double maFast = iMA(NULL, 0, i_maFastPeriod, 0, i_maFastMethod, i_maFastPrice, barIndex);
double maSlow = iMA(NULL, 0, i_maSlowPeriod, 0, i_maSlowMethod, i_maSlowPrice, barIndex);
double maFast2 = iMA(NULL, 0, i_maFastPeriod, 0, i_maFastMethod, i_maFastPrice, barIndex + 1);
double maSlow2 = iMA(NULL, 0, i_maSlowPeriod, 0, i_maSlowMethod, i_maSlowPrice, barIndex + 1);
ContinuityBuffers(barIndex);
if (maFast > maSlow && maFast2 < maSlow2)
ProcessUpwardMACross(barIndex);
if (maFast < maSlow && maFast2 > maSlow2)
ProcessDownwardMACross(barIndex);
if (g_curTrend[barIndex] != TREND_TYPE_UPWARD && Close[barIndex] > g_highSolid[barIndex])
{
ProcessResistanceBreak(barIndex);
return;
}
if (g_curTrend[barIndex] != TREND_TYPE_DOWNWARD && Close[barIndex] < g_lowSolid[barIndex] && g_lowSolid[barIndex] != EMPTY_VALUE)
ProcessSupportBreak(barIndex);
}
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Alert and notification on trend change |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
void SignalOnTrendChange(string text)
{
static datetime lastSignal = 0;
if (lastSignal >= Time[0])
return;
lastSignal = Time[0];
if (i_isAlert)
Alert(_Symbol, ", ", CastTFToString((ENUM_TIMEFRAMES)_Period), ": ", text);
if (i_isPush)
SendNotification(_Symbol + ", " + CastTFToString((ENUM_TIMEFRAMES)_Period) + ": " + text);
}
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Calculation of indicators values |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
void CalcIndicatorData(int limit, int total)
{
for (int i = limit; i >= 0; i--)
CalculateOneBarMA(i);
if (g_curTrend[1] == TREND_TYPE_UPWARD && g_curTrend[2] != TREND_TYPE_UPWARD)
SignalOnTrendChange(GetStringByMessageCode(MESSAGE_CODE_TREND_CHANGE_TO_UPWARD));
if (g_curTrend[1] == TREND_TYPE_DOWNWARD && g_curTrend[2] != TREND_TYPE_DOWNWARD)
SignalOnTrendChange(GetStringByMessageCode(MESSAGE_CODE_TREND_CHANGE_TO_DOWNWARD));
}
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Custom indicator iteration function |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
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 (!g_activate)
return rates_total;
int total;
int limit = GetRecalcIndex(total, rates_total, prev_calculated);
CalcIndicatorData(limit, total);
return rates_total;
}
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Getting string by code of message and terminal language |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
string GetStringByMessageCode(ENUM_MESSAGE_CODE messageCode)
{
string language = TerminalInfoString(TERMINAL_LANGUAGE);
if (language == "Russian")
return GetRussianMessage(messageCode);
return GetEnglishMessage(messageCode);
}
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Getting string by code of message for russian language |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
string GetRussianMessage(ENUM_MESSAGE_CODE messageCode)
{
switch (messageCode)
{
case MESSAGE_CODE_MA_FAST_LESS_THAN_ZERO: return ": ïåðèîä ðàñ÷åòà áûñòðîãî ñðåäíåãî äîëæåí áûòü áîëüøå íóëÿ. Èíäèêàòîð îòêëþ÷åí.";
case MESSAGE_CODE_MA_SLOW_LESS_THAN_ZERO: return ": ïåðèîä ðàñ÷åòà ìåäëåííîãî ñðåäíåãî äîëæåí áûòü áîëüøå íóëÿ. Èíäèêàòîð îòêëþ÷åí.";
case MESSAGE_CODE_TERMINAL_FATAL_ERROR1: return ": ôàòàëüíàÿ îøèáêà òåðìèíàëà - ïóíêò ðàâåí íóëþ. Èíäèêàòîð îòêëþ÷åí.";
case MESSAGE_CODE_BIND_ERROR: return ": îøèáêà ñâÿçûâàíèÿ ìàññèâîâ ñ áóôåðàìè èíäèêàòîðà. Îøèáêà ¹";
case MESSAGE_CODE_TREND_CHANGE_TO_UPWARD: return ": ñìåíà òðåíäà. Íîâûé òðåíä - âîñõîäÿùèé.";
case MESSAGE_CODE_TREND_CHANGE_TO_DOWNWARD: return ": ñìåíà òðåíäà. Íîâûé òðåíä - íèñõîäÿùèé.";
}
return "";
}
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Getting string by code of message for english language |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
string GetEnglishMessage(ENUM_MESSAGE_CODE messageCode)
{
switch (messageCode)
{
case MESSAGE_CODE_MA_FAST_LESS_THAN_ZERO: return ": calculation period of fast MA must be more than zero. The indicator is turned off.";
case MESSAGE_CODE_MA_SLOW_LESS_THAN_ZERO: return ": calculation period of slow MA must be more than zero. The indicator is turned off.";
case MESSAGE_CODE_TERMINAL_FATAL_ERROR1: return ": terminal fatal error - point equals to zero. The indicator is turned off.";
case MESSAGE_CODE_BIND_ERROR: return ": error of binding of the arrays and the indicator buffers. Error N";
case MESSAGE_CODE_TREND_CHANGE_TO_UPWARD: return ": change of trend. The new trend - upward.";
case MESSAGE_CODE_TREND_CHANGE_TO_DOWNWARD: return ": change of trend. The new trend - downward.";
}
return "";
}
Comments
Markdown Formatting Guide
# H1
## H2
### H3
**bold text**
*italicized text*
[title](https://www.example.com)

`code`
```
code block
```
> blockquote
- Item 1
- Item 2
1. First item
2. Second item
---