Price Data Components
Indicators Used
Miscellaneous
0
Views
0
Downloads
0
Favorites
MAChannel_Close_MultiTF_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. Multi timeframes version.\nRussian: Ãîðèçîíòàëüíûé êàíàë, îïèðàþùèéñÿ íà ýêñòðåìóìû ìåæäó ïåðåñå÷åíèÿìè äâóõ Moving Average. Ìóëüòèïåðèîäíàÿ âåðñèÿ."
#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
#define TF_AMOUNT 9
#define START_Y_OFFSET 12
#define STEP_Y 15
#define START_X_OFFSET 12
#define STEP_X 23
#define FONT_SIZE_TEXT 8
#define FONT_SIZE_ARROW 10
#define FONT_NAME_TEXT "Constantia"
#define FONT_NAME_ARROW "Wingdings"
#define PREFIX "MACCMTF_"
#define LABEL_TF_NAME "TF_NAME_"
#define LABEL_TREND "TREND_"
#define LABEL_PRICE_LOC "PRICE_LOC_"
#define VERT_LINE "VERT_LINE"
#define VERT_LINE_COLOR clrDodgerBlue
#define VERT_LINE_STYLE 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_BASE_CORNER i_corner = CORNER_RIGHT_UPPER; // Corner for the summary / Óãîë äëÿ îòîáðàæåíèÿ ñàììàðè
input ENUM_YESNO i_useM1 = YES; // Show the data of M1 TF / Îòîáðàæàòü äàííûå ÒÔ Ì1
input ENUM_YESNO i_useM5 = YES; // Show the data of M5 TF / Îòîáðàæàòü äàííûå ÒÔ Ì5
input ENUM_YESNO i_useM15 = YES; // Show the data of M15 TF / Îòîáðàæàòü äàííûå ÒÔ Ì15
input ENUM_YESNO i_useM30 = YES; // Show the data of M30 TF / Îòîáðàæàòü äàííûå ÒÔ Ì30
input ENUM_YESNO i_useH1 = YES; // Show the data of H1 TF / Îòîáðàæàòü äàííûå ÒÔ H1
input ENUM_YESNO i_useH4 = YES; // Show the data of H4 TF / Îòîáðàæàòü äàííûå ÒÔ H4
input ENUM_YESNO i_useD1 = YES; // Show the data of D1 TF / Îòîáðàæàòü äàííûå ÒÔ D1
input ENUM_YESNO i_useW1 = YES; // Show the data of W1 TF / Îòîáðàæàòü äàííûå ÒÔ W1
input ENUM_YESNO i_useMN1 = YES; // Show the data of MN1 TF / Îòîáðàæàòü äàííûå ÒÔ ÌN1
input color i_upwardTrendColor = clrBlue; // Color of arrow up / Öâåò ñòðåëêè ââåðõ
input color i_downwardTrendColor = clrRed; // Color of arrow down / Öâåò ñòðåëêè âíèç
input color i_undefinedTrendColor = clrLime; // Color of arrow right / Öâåò ñòðåëêè âïðàâî
input color i_textColor = clrGreen; // Color of table header / Öâåò øàïêè òàáëèöû
input ENUM_YESNO i_showFocusBar = YES; // Show the selected bar? / Îòîáðàæàòü ëè âûáðàííûé áàð?
input int i_indBarsCount = 10000; // Number of bars to display / Êîë-âî áàðîâ îòîáðàæåíèÿ
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_BIND_ERROR
};
struct TFInfo
{
bool isShow;
ENUM_TIMEFRAMES tf;
string tfName;
double highLimit;
double lowLimit;
ENUM_TREND_TYPE curTrend;
};
// Global variables
bool g_activate;
int g_maxMAPeriod;
datetime g_focusBarTime;
double g_point,
g_delta;
ENUM_ANCHOR_POINT g_anchor;
TFInfo g_tfInfo[TF_AMOUNT];
// Arrays for buffers of the indicators
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;
FormTheTFArray();
if (!BuffersBind())
return INIT_FAILED;
g_anchor = (i_corner == CORNER_RIGHT_UPPER || i_corner == CORNER_LEFT_UPPER)? ANCHOR_UPPER : ANCHOR_LOWER;
g_focusBarTime = 0;
if (i_showFocusBar == YES)
ShowVLine(Time[0]);
ShowSummaryTitle();
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;
}
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Formation the data of the TFs array |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
void FormTheTFArray()
{
SaveTheTF(0, i_useM1 == YES, PERIOD_M1, "M1");
SaveTheTF(1, i_useM5 == YES, PERIOD_M5, "M5");
SaveTheTF(2, i_useM15 == YES, PERIOD_M15, "M15");
SaveTheTF(3, i_useM30 == YES, PERIOD_M30, "M30");
SaveTheTF(4, i_useH1 == YES, PERIOD_H1, "H1");
SaveTheTF(5, i_useH4 == YES, PERIOD_H4, "H4");
SaveTheTF(6, i_useD1 == YES, PERIOD_D1, "D1");
SaveTheTF(7, i_useW1 == YES, PERIOD_W1, "W1");
SaveTheTF(8, i_useMN1 == YES, PERIOD_MN1, "MN1");
}
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Save the data of one TF |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
void SaveTheTF(const int index, const bool isShow, const ENUM_TIMEFRAMES tf, const string tfName)
{
g_tfInfo[index].isShow = isShow;
g_tfInfo[index].tf = tf;
g_tfInfo[index].tfName = tfName;
}
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Show one TF name |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
void ShowOneTFName(const int tfIndex, const int yCoord, int& xCoord)
{
if (!g_tfInfo[tfIndex].isShow)
return;
ShowLabel(LABEL_TF_NAME + (string)tfIndex, xCoord, yCoord, g_tfInfo[tfIndex].tfName, i_textColor, FONT_NAME_TEXT, FONT_SIZE_TEXT);
xCoord += STEP_X;
}
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Show the title for summary |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
void ShowSummaryTitle()
{
int y = START_Y_OFFSET;
if (i_corner == CORNER_RIGHT_LOWER || i_corner == CORNER_LEFT_LOWER)
y += 2 * STEP_Y;
int x = START_X_OFFSET;
if (i_corner == CORNER_RIGHT_LOWER || i_corner == CORNER_RIGHT_UPPER)
{
for (int i = TF_AMOUNT - 1; i >= 0; i--)
ShowOneTFName(i, y, x);
}
else
for (int i = 0; i < TF_AMOUNT; i++)
ShowOneTFName(i, y, x);
}
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Custom indicator deinitialization function |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
void OnDeinit(const int reason)
{
DeleteObjectsAll();
}
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Deleting the objects created by program |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
void DeleteObjectsAll()
{
for (int i = ObjectsTotal() - 1; i >= 0; i--)
if (StringSubstr(ObjectName(i), 0, StringLen(PREFIX)) == PREFIX)
ObjectDelete(ObjectName(i));
}
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Binding of array and the indicator buffers |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
bool BuffersBind()
{
string name = WindowExpertName();
// Ñâÿçûâàíèå áóôåðîâ èíäèêàòîðà ñ ìàññèâàìè
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(const int barIndex, const ENUM_TIMEFRAMES tf)
{
double lowPrice = iLow(NULL, tf, barIndex);
int total = iBars(NULL, tf);
for (int i = barIndex + 1; i < total; i++)
{
double maFast = iMA(NULL, tf, i_maFastPeriod, 0, i_maFastMethod, i_maFastPrice, i);
double maSlow = iMA(NULL, tf, i_maSlowPeriod, 0, i_maSlowMethod, i_maSlowPrice, i);
if (maFast > maSlow)
return lowPrice;
lowPrice = MathMin(lowPrice, iLow(NULL, tf, i));
}
return lowPrice;
}
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| The maximal price at the downtrend interval |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
double GetHighPrice(const int barIndex, const ENUM_TIMEFRAMES tf)
{
double highPrice = iHigh(NULL, tf, barIndex);
int total = iBars(NULL, tf);
for (int i = barIndex + 1; i < total; i++)
{
double maFast = iMA(NULL, tf, i_maFastPeriod, 0, i_maFastMethod, i_maFastPrice, i);
double maSlow = iMA(NULL, tf, i_maSlowPeriod, 0, i_maSlowMethod, i_maSlowPrice, i);
if (maFast < maSlow)
return highPrice;
highPrice = MathMax(highPrice, iHigh(NULL, tf, 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, (ENUM_TIMEFRAMES)_Period);
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, (ENUM_TIMEFRAMES)_Period);
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, (ENUM_TIMEFRAMES)_Period);
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, (ENUM_TIMEFRAMES)_Period);
g_highDot[barIndex] = EMPTY_VALUE;
if (g_highSolid[barIndex + 1] == EMPTY_VALUE)
g_highSolid[barIndex + 1] = g_highSolid[barIndex];
}
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| 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);
}
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Data at all TFs need to recalculate on all history interval |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
void RecalculateTFsData(const int total)
{
for (uint i = 0; i < TF_AMOUNT; i++)
{
if (!g_tfInfo[i].isShow)
continue;
g_tfInfo[i].lowLimit = EMPTY_VALUE;
g_tfInfo[i].highLimit = EMPTY_VALUE;
g_tfInfo[i].curTrend = TREND_TYPE_NONE;
int toBarIndex = 0;
if (g_focusBarTime != 0)
toBarIndex = (int)MathMax(iBarShift(NULL, g_tfInfo[i].tf, g_focusBarTime), 0);
for (int j = total; j > toBarIndex; j--)
CalculateTFData(j, i);
}
}
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Calculation data for all used TFs |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
void CalculateTFData(const int tfBarIndex, const int tfIndex)
{
// Do not calculate data for unformed candle
if (tfBarIndex <= 0 || tfBarIndex >= iBars(NULL, g_tfInfo[tfIndex].tf))
return;
// Calculate MAs values
double maFast = iMA(NULL, g_tfInfo[tfIndex].tf, i_maFastPeriod, 0, i_maFastMethod, i_maFastPrice, tfBarIndex);
double maSlow = iMA(NULL, g_tfInfo[tfIndex].tf, i_maSlowPeriod, 0, i_maSlowMethod, i_maSlowPrice, tfBarIndex);
double maFast2 = iMA(NULL, g_tfInfo[tfIndex].tf, i_maFastPeriod, 0, i_maFastMethod, i_maFastPrice, tfBarIndex + 1);
double maSlow2 = iMA(NULL, g_tfInfo[tfIndex].tf, i_maSlowPeriod, 0, i_maSlowMethod, i_maSlowPrice, tfBarIndex + 1);
// Upward MA cross
if (maFast > maSlow && maFast2 < maSlow2)
g_tfInfo[tfIndex].lowLimit = GetLowPrice(tfBarIndex, g_tfInfo[tfIndex].tf);
// Downward MA cross
if (maFast < maSlow && maFast2 > maSlow2)
g_tfInfo[tfIndex].highLimit = GetHighPrice(tfBarIndex, g_tfInfo[tfIndex].tf);
// Breaking the resistance level
if (g_tfInfo[tfIndex].curTrend != TREND_TYPE_UPWARD && iClose(NULL, g_tfInfo[tfIndex].tf, tfBarIndex) > g_tfInfo[tfIndex].highLimit)
{
g_tfInfo[tfIndex].curTrend = TREND_TYPE_UPWARD;
return;
}
// Breaking the support level
if (g_tfInfo[tfIndex].curTrend != TREND_TYPE_DOWNWARD && iClose(NULL, g_tfInfo[tfIndex].tf, tfBarIndex) < g_tfInfo[tfIndex].lowLimit && g_tfInfo[tfIndex].lowLimit != EMPTY_VALUE)
g_tfInfo[tfIndex].curTrend = TREND_TYPE_DOWNWARD;
}
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Convert the trend type to arrow |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
string GetStringTrend(const ENUM_TREND_TYPE trendType)
{
switch (trendType)
{
case TREND_TYPE_DOWNWARD: return CharToString(226);
case TREND_TYPE_UPWARD: return CharToString(225);
}
return CharToString(251);
}
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Convert the trend type to color |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
color GetColorTrend(const ENUM_TREND_TYPE trendType)
{
switch (trendType)
{
case TREND_TYPE_DOWNWARD: return i_downwardTrendColor;
case TREND_TYPE_UPWARD: return i_upwardTrendColor;
}
return i_undefinedTrendColor;
}
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Show the text label |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
void ShowLabel(string labelID, int x, int y, string text, color clr, string fontName, int fontSize)
{
string name = PREFIX + labelID;
if (ObjectFind(0, name) < 0)
{
ObjectCreate(0, name, OBJ_LABEL, 0, 0, 0);
ObjectSetInteger(0, name, OBJPROP_CORNER, i_corner);
ObjectSetInteger(0, name, OBJPROP_XDISTANCE, x);
ObjectSetInteger(0, name, OBJPROP_YDISTANCE, y);
ObjectSetInteger(0, name, OBJPROP_FONTSIZE, fontSize);
ObjectSetInteger(0, name, OBJPROP_COLOR, clr);
ObjectSetString(0, name, OBJPROP_TEXT, text);
ObjectSetInteger(0, name, OBJPROP_ANCHOR, g_anchor);
ObjectSetString(0, name, OBJPROP_FONT, fontName);
ObjectSetInteger(0, name, OBJPROP_SELECTABLE, false);
ObjectSetInteger(0, name, OBJPROP_HIDDEN, true);
return;
}
ObjectSetInteger(0, name, OBJPROP_XDISTANCE, x);
ObjectSetInteger(0, name, OBJPROP_YDISTANCE, y);
ObjectSetInteger(0, name, OBJPROP_COLOR, clr);
ObjectSetString(0, name, OBJPROP_TEXT, text);
}
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Show the vertical line |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
void ShowVLine(datetime time)
{
string name = PREFIX + VERT_LINE;
if (ObjectFind(0, name) < 0)
{
ObjectCreate(0, name, OBJ_VLINE, 0, time, 1);
ObjectSetInteger(0, name, OBJPROP_COLOR, VERT_LINE_COLOR);
ObjectSetInteger(0, name, OBJPROP_STYLE, VERT_LINE_STYLE);
ObjectSetInteger(0, name, OBJPROP_SELECTABLE, false);
ObjectSetInteger(0, name, OBJPROP_HIDDEN, true);
return;
}
ObjectSetInteger(0, name, OBJPROP_TIME1, time);
}
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Show one character |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
void ShowOneChar(const int tfIndex, const int yCoord, int& xCoord)
{
if (!g_tfInfo[tfIndex].isShow)
return;
ShowLabel(LABEL_TREND + (string)tfIndex, xCoord, yCoord, GetStringTrend(g_tfInfo[tfIndex].curTrend), GetColorTrend(g_tfInfo[tfIndex].curTrend), FONT_NAME_ARROW, FONT_SIZE_ARROW);
xCoord += STEP_X;
}
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Define the arrow that correspond to the relative location of price and channel |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
string GetStringPriceLocation(const TFInfo& tfInfo, const double price, color& clr)
{
clr = i_undefinedTrendColor;
// Undefined trend direction
if (tfInfo.curTrend == TREND_TYPE_NONE)
return CharToString(251);
// Price is located higher than channel
if (tfInfo.highLimit < price)
{
clr = i_upwardTrendColor;
return CharToString(217);
}
// Price is located lower than channel
if (tfInfo.lowLimit > price)
{
clr = i_downwardTrendColor;
return CharToString(218);
}
// Price is located in a channel
return CharToString(216);
}
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Show line of the summary that displaying the direction of trend |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
void ShowTrendDirectionLine(const int y)
{
int x = START_X_OFFSET;
if (i_corner == CORNER_RIGHT_LOWER || i_corner == CORNER_RIGHT_UPPER)
{
for (int i = TF_AMOUNT - 1; i >= 0; i--)
ShowOneChar(i, y, x);
}
else
for (int i = 0; i < TF_AMOUNT; i++)
ShowOneChar(i, y, x);
}
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Show price location one character |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
void ShowOneCharPriceLocation(const int tfIndex, const int yCoord, int& xCoord, const double price)
{
if (!g_tfInfo[tfIndex].isShow)
return;
color arrowColor = clrNONE;
string arrow = GetStringPriceLocation(g_tfInfo[tfIndex], price, arrowColor);
ShowLabel(LABEL_PRICE_LOC + (string)tfIndex, xCoord, yCoord, arrow, arrowColor, FONT_NAME_ARROW, FONT_SIZE_ARROW);
xCoord += STEP_X;
}
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Show line of summary that displaying price location relative to the channel |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
void ShowPriceLocation(const int y, const double price)
{
int x = START_X_OFFSET;
if (i_corner == CORNER_RIGHT_LOWER || i_corner == CORNER_RIGHT_UPPER)
{
for (int i = TF_AMOUNT - 1; i >= 0; i--)
ShowOneCharPriceLocation(i, y, x, price);
}
else
for (int i = 0; i < TF_AMOUNT; i++)
ShowOneCharPriceLocation(i, y, x, price);
}
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Show the data from timeframes |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
void ShowSummary(const double price)
{
if (i_corner == CORNER_LEFT_UPPER || i_corner == CORNER_RIGHT_UPPER)
{
int y = START_Y_OFFSET + STEP_Y;
ShowTrendDirectionLine(y);
y += STEP_Y;
ShowPriceLocation(y, price);
}
else
{
int y = START_Y_OFFSET;
ShowPriceLocation(y, price);
y += STEP_Y;
ShowTrendDirectionLine(y);
}
}
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Calculation of indicators values |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
void CalcIndicatorData(int limit, int total)
{
// Initialize the start data
if (limit > 1)
RecalculateTFsData(total);
// Calculate all data of indicator
for (int i = limit; i >= 0; i--)
{
CalculateOneBarMA(i);
if (g_focusBarTime != 0)
continue;
for (int j = 0; j < TF_AMOUNT; j++)
{
if (!g_tfInfo[j].isShow)
continue;
int tfBarIndex = iBarShift(NULL, g_tfInfo[j].tf, Time[i]);
if (tfBarIndex == 1)
CalculateTFData(1, j);
}
}
// Show the data from timeframes
if (g_focusBarTime == 0)
ShowSummary(Bid);
// Show the focus bar
if (limit == 1 && i_showFocusBar == YES)
ShowVLine((g_focusBarTime == 0)? Time[0] : g_focusBarTime);
}
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| 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;
}
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Process the events on a chart |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
void OnChartEvent(const int id,const long& lparam,const double& dparam,const string& sparam)
{
// Processing only one event - click of left mouse button
if (id != CHARTEVENT_CLICK)
return;
// Convert the decart coordinates to the coordinates of time and price
double price = 0.0;
datetime time = 0;
int subWindow = 0;
if (!ChartXYToTimePrice(0, (int)lparam, (int)dparam, subWindow, time, price))
return;
// Find the bar index by place where mouse click has occurred
int barIndex = iBarShift(NULL, 0, time);
if (barIndex < 0 || barIndex >= Bars)
return;
// Processing the click if mouse coordinates are inside the bar
if (price > High[barIndex] || price < Low[barIndex])
return;
// Show new position of vertical line
g_focusBarTime = (barIndex == 0)? 0 : Time[barIndex];
if (i_showFocusBar == YES)
ShowVLine((g_focusBarTime == 0)? Time[0] : g_focusBarTime);
// Recalculate TFs data
int total = i_indBarsCount;
if (total == 0 || total > Bars - g_maxMAPeriod - 2)
total = Bars - g_maxMAPeriod - 2;
RecalculateTFsData(total);
// Show calculated data
ShowSummary(Open[barIndex]);
}
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| 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 ": îøèáêà ñâÿçûâàíèÿ ìàññèâîâ ñ áóôåðàìè èíäèêàòîðà. Îøèáêà ¹";
}
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";
}
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
---