MAFilling_Trend_WithShift

Author: Scriptong
Indicators Used
Moving average indicator
Miscellaneous
It issuies visual alerts to the screen
0 Views
0 Downloads
0 Favorites
MAFilling_Trend_WithShift
ÿþ#property copyright "Scriptong"

#property link      "scriptong@gmail.com"

#define VERSION "210.722"

#property version VERSION



#property indicator_chart_window

#property indicator_buffers 0

#property strict

#include <iCanvas.mqh>





input color                i_clrFillingUpward               = clrDodgerBlue;                       // Upward trend filling color

input color                i_clrFillingDownward             = clrRed;                              // Downward trend filling color

input uchar                i_uchAlpha                       = 100;                                 // Transparent (0 - 255)

input uint                 i_uMAFastPeriod                  = 13;                                  // MA fast period

input color                i_clrMAFastColor                 = clrBlue;                             // MA fast color

input uint                 i_uMASlowPeriod                  = 55;                                  // MA slow period

input color                i_clrMASlowColor                 = clrRed;                              // MA slow color

input ENUM_APPLIED_PRICE   i_eMAPrice                       = PRICE_CLOSE;                         // MA applied price

input ENUM_MA_METHOD       i_eMAMethod                      = MODE_EMA;                            // MA method

input uint                 i_uMAWidth                       = 1;                                   // MA line width

input int                  i_nMAShift                       = 1;                                   // MA shift



bool              g_bIsCreate;

int               g_nMaxPeriod;



#define PRINT(A) Print(#A + " = " + (string)(A))



//+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+

//| Indicator attaching                                                                                                                                                                      |

//+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+

int OnInit()

{

   Print("Version: ", VERSION);



   g_bIsCreate = true;

   g_nMaxPeriod = int(fmax(i_uMAFastPeriod, i_uMASlowPeriod));

   

   

   if (i_uMAFastPeriod == 0)

   {

      Alert(MQLInfoString(MQL_PROGRAM_NAME), ": MA fast period must be greater than zero. Indicator is turned off.");

      return INIT_PARAMETERS_INCORRECT;

   }

   

   if (i_uMASlowPeriod == 0)

   {

      Alert(MQLInfoString(MQL_PROGRAM_NAME), ": MA slow period must be greater than zero. Indicator is turned off.");

      return INIT_PARAMETERS_INCORRECT;

   }



   if (i_uMASlowPeriod < i_uMAFastPeriod)

   {

      Alert(MQLInfoString(MQL_PROGRAM_NAME), ": MA slow period must be greater than MA fast period. Indicator is turned off.");

      return INIT_PARAMETERS_INCORRECT;

   }

   

   return INIT_SUCCEEDED;

}

//+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+

//| Indicator detaching                                                                                                                                                                      |

//+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+

void OnDeinit(const int reason) 

{

}

//+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+

//| Processing the chart events                                                                                                                                                              |

//+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+

void OnChartEvent(const int id,const long& lparam,const double& dparam,const string& sparam)

{

   if (id != CHARTEVENT_CHART_CHANGE && !g_bIsCreate)

      return;



   g_bIsCreate = false;



   Canvas.Erase(0);



   double fMAFastPrev = iMA(NULL, PERIOD_CURRENT, i_uMAFastPeriod, i_nMAShift, i_eMAMethod, i_eMAPrice, W.Left_bar);

   double fMASlowPrev = iMA(NULL, PERIOD_CURRENT, i_uMASlowPeriod, i_nMAShift, i_eMAMethod, i_eMAPrice, W.Left_bar);

   int nBarsPerWindow = int(ChartGetInteger(0, CHART_WIDTH_IN_BARS));

   int nRightBar = int(W.Right_bar);

   if (nBarsPerWindow > W.Left_bar)

   {

      if (i_nMAShift > 0)

         nRightBar = int(fmax(W.Left_bar - nBarsPerWindow, 0 - i_nMAShift));

      if (i_nMAShift < 0)

         nRightBar = 0 - i_nMAShift;

   }

      

   for (int i = W.Left_bar - 1; i >= nRightBar; --i)

   {

      double fMAFast = iMA(NULL, PERIOD_CURRENT, i_uMAFastPeriod, i_nMAShift, i_eMAMethod, i_eMAPrice, i);

      double fMASlow = iMA(NULL, PERIOD_CURRENT, i_uMASlowPeriod, i_nMAShift, i_eMAMethod, i_eMAPrice, i);

      if ((fMAFast > fMASlow && fMAFastPrev < fMASlowPrev) || (fMAFast < fMASlow && fMAFastPrev > fMASlowPrev)) // If MA's intersections, then two filling areas between bars required

         FillAreasBetweenBars(i, fMAFastPrev, fMASlowPrev, fMAFast, fMASlow, i_clrFillingUpward, i_clrFillingDownward);

      else

         FillArea(i, fMAFastPrev, fMASlowPrev, fMAFast, fMASlow, (fMAFast > fMASlow)? i_clrFillingUpward : i_clrFillingDownward);

      

      DrawLine(i, fMAFastPrev, fMAFast, i_clrMAFastColor, i_uMAWidth);

      DrawLine(i, fMASlowPrev, fMASlow, i_clrMASlowColor, i_uMAWidth);

      

      

      fMAFastPrev = fMAFast;

      fMASlowPrev = fMASlow;

   }



   Canvas.Update();         

}

//+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+

//| Indicators calculating                                                                                                                                                                   |

//+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+

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[])

{

   return rates_total;

}

//+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+

//| Filling two arreas between two bars                                                                                                                                                      |

//+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+

void FillAreasBetweenBars(const int nBarIndex, const double fPrevBarPrice1, const double fPrevBarPrice2, const double fCurBarPrice1, const double fCurBarPrice2, const color clrFillingUpward, 

                          const color clrFillingDownward)

{

   datetime dtLeftBar = GetBarTime(NULL, PERIOD_CURRENT, nBarIndex + 1);

   datetime dtRightBar = GetBarTime(NULL, PERIOD_CURRENT, nBarIndex);



   int nXLeft, nXRight, nYFastLineLeft, nYFastLineRight, nYSlowLineLeft, nYSlowLineRight;

   ChartTimePriceToXY(0, 0, dtLeftBar, fPrevBarPrice1, nXLeft, nYFastLineLeft);

   ChartTimePriceToXY(0, 0, dtRightBar, fCurBarPrice1, nXRight, nYFastLineRight);

   ChartTimePriceToXY(0, 0, dtRightBar, fCurBarPrice2, nXRight, nYSlowLineRight);

   ChartTimePriceToXY(0, 0, dtLeftBar, fPrevBarPrice2, nXLeft, nYSlowLineLeft);



   double fKFastLine, fKSlowLine;

   double fBFastLine = CalculateBAndKKoefs(nXLeft, nYFastLineLeft - 3, nXRight, nYFastLineRight - 3, fKFastLine);

   double fBSlowLine = CalculateBAndKKoefs(nXLeft, nYSlowLineLeft - 3, nXRight, nYSlowLineRight - 3, fKSlowLine);

   double fDenominator = fKFastLine - fKSlowLine;

   if (fDenominator == 0.0)

      return;

   

   int nXIntersection = Round((fBSlowLine - fBFastLine) / fDenominator);

   color clrFilling = (fPrevBarPrice1 > fPrevBarPrice2)? clrFillingUpward : clrFillingDownward;

   

   for (int nByX = nXLeft; nByX <= nXRight; ++nByX)

   {

      if (nByX == nXIntersection)

         clrFilling = (fPrevBarPrice1 > fPrevBarPrice2)? clrFillingDownward : clrFillingUpward;

   

      int nYFastLine = Round(fKFastLine * nByX + fBFastLine);

      int nYSlowLine = Round(fKSlowLine * nByX + fBSlowLine);

      int nMinY = fmin(nYFastLine, nYSlowLine);

      int nMaxY = fmax(nYFastLine, nYSlowLine);

      

      for (int nByY = nMinY; nByY <= nMaxY; ++nByY)

         Canvas.PixelSet(nByX, nByY, ColorToARGB(clrFilling, i_uchAlpha));

   }

}

//+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+

//| Filling the arrea between two bars and two lines                                                                                                                                         |

//+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+

void FillArea(const int nBarIndex, const double fPrevBarPrice1, const double fPrevBarPrice2, const double fCurBarPrice1, const double fCurBarPrice2, const color clrFilling)

{

   datetime dtLeftBar = GetBarTime(NULL, PERIOD_CURRENT, nBarIndex + 1);

   datetime dtRightBar = GetBarTime(NULL, PERIOD_CURRENT, nBarIndex);



   int nXLeft, nXRight, nYFastLineLeft, nYFastLineRight, nYSlowLineLeft, nYSlowLineRight;

   ChartTimePriceToXY(0, 0, dtLeftBar, fPrevBarPrice1, nXLeft, nYFastLineLeft);

   ChartTimePriceToXY(0, 0, dtRightBar, fCurBarPrice1, nXRight, nYFastLineRight);

   ChartTimePriceToXY(0, 0, dtRightBar, fCurBarPrice2, nXRight, nYSlowLineRight);

   ChartTimePriceToXY(0, 0, dtLeftBar, fPrevBarPrice2, nXLeft, nYSlowLineLeft);

   

   double fKFastLine, fKSlowLine;

   double fBFastLine = CalculateBAndKKoefs(nXLeft, nYFastLineLeft - 3, nXRight, nYFastLineRight - 3, fKFastLine);

   double fBSlowLine = CalculateBAndKKoefs(nXLeft, nYSlowLineLeft - 3, nXRight, nYSlowLineRight - 3, fKSlowLine);

   

   for (int nByX = nXLeft; nByX <= nXRight; ++nByX)

   {

      int nYFastLine = Round(fKFastLine * nByX + fBFastLine);

      int nYSlowLine = Round(fKSlowLine * nByX + fBSlowLine);

      int nMinY = fmin(nYFastLine, nYSlowLine);

      int nMaxY = fmax(nYFastLine, nYSlowLine);

      

      for (int nByY = nMinY; nByY <= nMaxY; ++nByY)

         Canvas.PixelSet(nByX, nByY, ColorToARGB(clrFilling, i_uchAlpha));

   }

}

//+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+

//| K and B Aoefficients calculating by equation of a straight line                                                                                                                          |

//+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+

double CalculateBAndKKoefs(const int nX1, const int nY1, const int nX2, const int nY2, double &fKKoef)

{

   if (nX1 == nX2)

      return DBL_MAX;

      

   fKKoef = (nY2 - nY1) / 1.0 / (nX2 - nX1);

   return nY1 - fKKoef * nX1;   

}

//+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+

//| Draw the line between two points                                                                                                                                                         |

//+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+

void DrawLine(const int nBarIndex, const double fPrevBarPrice, const double fCurBarPrice, const color clrLine, const uint uWidth, const uchar uchAlpha = 255)

{

   if (clrLine == clrNONE)

      return;



   datetime dtLeftBar = GetBarTime(NULL, PERIOD_CURRENT, nBarIndex + 1);

   datetime dtRightBar = GetBarTime(NULL, PERIOD_CURRENT, nBarIndex);



   int nXLeft, nXRight, nYLeft, nYRight;

   ChartTimePriceToXY(0, 0, dtLeftBar, fPrevBarPrice, nXLeft, nYLeft);

   ChartTimePriceToXY(0, 0, dtRightBar, fCurBarPrice, nXRight, nYRight);



   double fKLine;

   double fBLine = CalculateBAndKKoefs(nXLeft, nYLeft - 3, nXRight, nYRight - 3, fKLine);

   

   int nYPrev = INT_MAX, nStartPixels = Round((uWidth - 1) / 2.0);

   for (int nByX = nXLeft; nByX <= nXRight; ++nByX)

   {

      int nYLine = Round(fKLine * nByX + fBLine);

      int nTotal = nYLine + int(uWidth - 1 - nStartPixels) + 1;

      for (int nByY = nYLine - nStartPixels; nByY < nTotal; ++nByY)

      {

         int nTotalX = nByX + int(uWidth - 1 - nStartPixels) + 1;

         for (int nX = nByX - nStartPixels; nX < nTotalX; ++nX)

            Canvas.PixelSet(nX, nByY, ColorToARGB(clrLine, uchAlpha));

      }

         

      if (nYPrev != INT_MAX && fabs(nYPrev - nYLine) > 1)

      {

         int nYMax = fmax(nYPrev, nYLine);

         for (int nByY = fmin(nYPrev, nYLine) + 1; nByY < nYMax; ++nByY)

         {

            nTotal = nByX + int(uWidth - 1 - nStartPixels) + 1;

            for (int nX = nByX - nStartPixels; nX < nTotal; ++nX)

               Canvas.PixelSet(nX, nByY, ColorToARGB(clrLine, uchAlpha));

         }

      }

         

      nYPrev = nYLine;

   }

}

//+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+

//| Gets the time for negative bars index even                                                                                                                                               |

//+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+

datetime GetBarTime(const string sSymbol, const ENUM_TIMEFRAMES eTF, const int nBarIndex)

{

   if (nBarIndex >= 0)

      return iTime(sSymbol, eTF, nBarIndex);

      

   return iTime(sSymbol, eTF, 0) + PeriodSeconds() * fabs(nBarIndex);

}

Comments

Markdown supported. Formatting help

Markdown Formatting Guide

Element Markdown Syntax
Heading # H1
## H2
### H3
Bold **bold text**
Italic *italicized text*
Link [title](https://www.example.com)
Image ![alt text](image.jpg)
Code `code`
Code Block ```
code block
```
Quote > blockquote
Unordered List - Item 1
- Item 2
Ordered List 1. First item
2. Second item
Horizontal Rule ---