SplashAndShelf_AD

Author: Scriptong
Price Data Components
Series array that contains the lowest prices of each barSeries array that contains the highest prices of each bar
Indicators Used
Fractals
Miscellaneous
It issuies visual alerts to the screen
0 Views
0 Downloads
0 Favorites
SplashAndShelf_AD
#property copyright "Scriptong"
#property link      "http://advancetools.net"
#property description "English: Finding the \"Splash and shelf\" pattern.\nRussian: Ïîèñê ïàòòåðíà \"Âñïëåñê è ïîëêà\"."
#property version "1.30"
#property strict

#property indicator_chart_window
#property indicator_buffers 1
#property indicator_color1  clrDodgerBlue

#define  FRACTALS_AMOUNT                              4                                            // Number of recent accounted fractals
#define  ARRAY_RESERVE_SIZE                           10                                                
#define  SIGN_INCLINE_LINE                            "INCLINE_"
#define  SIGN_HORIZONTAL_LINE                         "HORIZONTAL_"
#define  SIGN_ARROW_BUY                               "ARROW_BUY_"
#define  SIGN_ARROW_SELL                              "ARROW_SELL_"


enum ENUM_YESNO
{
   NO,                                                                                             // No / Íåò
   YES                                                                                             // Yes / Äà
};

enum ENUM_EXTREMUM_TYPE
{
   EXTREMUM_TYPE_NONE,   
   EXTREMUM_TYPE_MIN,
   EXTREMUM_TYPE_MAX
};

enum ENUM_PATTERN_TYPE
{
   PATTERN_TYPE_NONE,
   PATTERN_TYPE_BULL,
   PATTERN_TYPE_BEAR   
};

enum ENUM_FUNCTION_RESULT
{
   FUNCTION_RESULT_OK,                                                                             // The successful ending of function run
   FUNCTION_RESULT_ALRIGHT,                                                                        // The not successful ending of function run but no has critical errors
   FUNCTION_RESULT_FATAL                                                                           // The fatal error ending of function run
};

struct FractalData
{
   ENUM_EXTREMUM_TYPE type;
   datetime           time;
   double             price;  
   
   FractalData()
   {
      Init();
   } 
   
   void Init()
   {
      type = EXTREMUM_TYPE_NONE;
      time = 0;
      price = 0.0;
   }
};

struct Pattern
{
   ENUM_PATTERN_TYPE patternType;
   FractalData       fractals[FRACTALS_AMOUNT];
   int               leftBarIndex;                                                                 // Index of left bar the slope line
   int               rightBarIndex;                                                                // Index of right bar the slope line
   color             patternColor;
   
   Pattern()
   {
      Init();
   }
   
   void Init()
   {
      patternType = PATTERN_TYPE_NONE;
      leftBarIndex = -1;
      rightBarIndex = -1;
      patternColor = clrNONE;
   }
};


// Input parameters of indicator
input uint                     i_minSplashHeight     = 200;                                        // Min. height of splash, pts / Ìèí. âûñîòà âñïëåñêà, ïï.
input uint                     i_maxBarsDuration     = 20;                                         // Max bars before crossing / Ìàêñ. áàðîâ äî ïåðåñå÷åíèÿ
input color                    i_bullPatternRegColor = clrPowderBlue;                              // Color of bull not active pattern / Öâåò áû÷üåãî íåàêòèâíîãî ïàòòåðíà
input color                    i_bearPatternRegColor = clrPink;                                    // Color of bear not active pattern / Öâåò ìåäâåæüåãî íåàêòèâíîãî ïàòòåðíà
input color                    i_bullPatternWorkColor = clrBlue;                                   // Color of bull active pattern / Öâåò áû÷üåãî àêòèâíîãî ïàòòåðíà
input color                    i_bearPatternWorkColor = clrRed;                                    // Color of bear active pattern / Öâåò ìåäâåæüåãî àêòèâíîãî ïàòòåðíà
input color                    i_buyArrowColor       = clrBlue;                                    // Buy signal arrow color / Öâåò ñòðåëêè ñèãíàëà ïîêóïêè
input color                    i_sellArrowColor      = clrRed;                                     // Buy signal arrow color / Öâåò ñòðåëêè ñèãíàëà ïîêóïêè
input ENUM_YESNO               i_isAlert             = YES;                                        // Alert on pattern found? / Ñèãíàë ïðè ïàòòåðíå?
input ENUM_YESNO               i_isPush              = YES;                                        // Notification on pattern found? / Óâåäîìëÿòü î ïàòòåðíå?
input int                      i_indBarsCount        = 10000;                                      // The number of bars to display / Êîëè÷åñòâî áàðîâ îòîáðàæåíèÿ

// Other global variables of indicator
bool              g_activate,                                                                      // Sign of successful initialization of indicator
                  g_isRussianLang;

uint              g_fractalsCnt,                                                                   // Found fractals counter (0 - FRACTALS_AMOUNT)
                  g_patternsCnt;                                                                   // Current amount of patterns which not activated and not trash
                  
datetime          g_lastBuyPatternRegFractalTime,
                  g_lastSellPatternRegFractalTime;
FractalData       g_lastFractals[FRACTALS_AMOUNT];                                                 // Data of last FRACTALS_AMOUNT fractals
Pattern           g_patterns[];                                                                    // Patterns which not activated and not trash
     
       
#define PREFIX                                  "SPLASHEL_"                                        // Prefix the name of the graphic objects which displayed by indicator

//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Custom indicator initialization function                                                                                                                                                          |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
int OnInit()
{
   g_isRussianLang = (TerminalInfoString(TERMINAL_LANGUAGE) == "Russian");
   g_activate = true;                                                                              
   return INIT_SUCCEEDED;
}
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Custom indicator deinitialization function                                                                                                                                                        |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
void OnDeinit(const int reason)
{
   ObjectsDeleteAll(0, PREFIX);
}
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Displaying the trend line                                                                                                                                                                         |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
void ShowTrendLine(string name, datetime time1, double price1, datetime time2, double price2, string toolTip, color clr)
{
   if (ObjectFind(0, name) < 0)
   {
      ObjectCreate(0, name, OBJ_TREND, 0, time1, price1, time2, price2);
      ObjectSetInteger(0, name, OBJPROP_COLOR, clr);
      ObjectSetInteger(0, name, OBJPROP_BACK, false);
      ObjectSetInteger(0, name, OBJPROP_WIDTH, 2);
      ObjectSetInteger(0, name, OBJPROP_RAY, false);
      ObjectSetInteger(0, name, OBJPROP_HIDDEN, true);
      ObjectSetInteger(0, name, OBJPROP_SELECTABLE, false);
      ObjectSetString(0, name, OBJPROP_TOOLTIP, toolTip);
      return;
   }
   
   ObjectMove(0, name, 0, time1, price1);
   ObjectMove(0, name, 1, time2, price2);
   ObjectSetInteger(0, name, OBJPROP_COLOR, clr);
   ObjectSetString(0, name, OBJPROP_TOOLTIP, toolTip);
}
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Show the Wingdings sign                                                                                                                                                                           |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
void ShowArrow(string name, datetime time1, double price1, int code, color clr, ENUM_ARROW_ANCHOR anchor, int width, string toolTip)
{
   if (ObjectFind(0, name) < 0)
   {
      ObjectCreate(0, name, OBJ_ARROW, 0, time1, price1);
      ObjectSetInteger(0, name, OBJPROP_COLOR, clr);
      ObjectSetInteger(0, name, OBJPROP_ARROWCODE, code);
      ObjectSetInteger(0, name, OBJPROP_ANCHOR, anchor);
      ObjectSetInteger(0, name, OBJPROP_WIDTH, width);
      ObjectSetInteger(0, name, OBJPROP_HIDDEN, true);
      ObjectSetString(0, name, OBJPROP_TOOLTIP, toolTip);
      ObjectSetInteger(0, name, OBJPROP_SELECTABLE, false);
      return;
   }
   
   ObjectMove(0, name, 0, time1, price1);
   ObjectSetInteger(0, name, OBJPROP_COLOR, clr);
   ObjectSetString(0, name, OBJPROP_TOOLTIP, toolTip);
}
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Determination of bar index which needed to recalculate                                                                                                                                            |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
int GetRecalcIndex(int& total, const int ratesTotal, const int prevCalculated)
{
   total = ratesTotal - 3;                                                                         
                                                   
   if (i_indBarsCount > 0 && i_indBarsCount < total)
      total = MathMin(i_indBarsCount, total);                      
                                                   
   if (prevCalculated < ratesTotal - 1)                     
   {       
      ObjectsDeleteAll(0, PREFIX);
      for (int i = 0; i < FRACTALS_AMOUNT; i++)
         g_lastFractals[i].Init();
      g_fractalsCnt = 0;
      return (total);
   }
   
   return (MathMin(ratesTotal - prevCalculated, total));                            
}
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Sound and Push-notifications of divergence                                                                                                                                                        |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
void SignalOnPattern(string text)
{
   if (i_isAlert)
      Alert(Symbol(), ", ", EnumToString(ENUM_TIMEFRAMES(Period())), ": ", text);
      
   if (i_isPush)
      SendNotification(Symbol() + ", " + EnumToString(ENUM_TIMEFRAMES(Period())) + ": " + text);
}
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//|                                                                                                                                                                                                   |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
double CalculateBAndKByLine(int x1, double y1, int x2, double y2, double &kKoef)
{
   if (x1 == x2)
      return DBL_MAX;
      
   kKoef = (y2 - y1) / (x2 - x1);
   return y1 - kKoef * x1;
}
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| unique identificator of graphic object                                                                                                                                                            |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
string GetUniqueID(const Pattern & pattern)
{
   return IntegerToString(pattern.fractals[0].time) + "_" + IntegerToString((int)pattern.patternType) + "_";
}
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Show the pattern                                                                                                                                                                                  |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
void ShowPattern(const Pattern & pattern)
{
   double kKoef = 0.0;
   double bKoef = CalculateBAndKByLine(pattern.leftBarIndex, pattern.fractals[2].price, pattern.rightBarIndex, pattern.fractals[0].price, kKoef);
   if (bKoef == DBL_MAX || kKoef == 0.0)
      return;
      
   int crossLinesBarIndex = int(floor((pattern.fractals[1].price - bKoef) / kKoef));
   
   datetime crossLinesTime = (crossLinesBarIndex >= 0)? iTime(NULL, 0, crossLinesBarIndex) : iTime(NULL, 0, 0) - crossLinesBarIndex * PeriodSeconds();

   string uniqID = GetUniqueID(pattern);
   ShowTrendLine(PREFIX + uniqID + SIGN_INCLINE_LINE, pattern.fractals[2].time, pattern.fractals[2].price, crossLinesTime, pattern.fractals[1].price, "", pattern.patternColor);
   ShowTrendLine(PREFIX + uniqID + SIGN_HORIZONTAL_LINE, pattern.fractals[3].time, pattern.fractals[1].price, crossLinesTime, pattern.fractals[1].price, "", pattern.patternColor);
}
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Add specified fractal to g_lastFractals array                                                                                                                                                     |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
void AddFractalToArray(ENUM_EXTREMUM_TYPE fractalType, double fractalPrice, datetime fractalTime)
{
   // if a fractal is already registered, we do not need a new registration
   if (g_lastFractals[0].type == fractalType && g_lastFractals[0].time == fractalTime)
      return;

   // Moving the elemets of array to upside
   for (int i = FRACTALS_AMOUNT - 1; i > 0; i--)
      g_lastFractals[i] = g_lastFractals[i - 1];
      
   // Save the data
   g_lastFractals[0].type = fractalType;
   g_lastFractals[0].price = fractalPrice;
   g_lastFractals[0].time = fractalTime;
   
   if (g_fractalsCnt < FRACTALS_AMOUNT)
      g_fractalsCnt++;
}
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Checking the sell pattern exists                                                                                                                                                                  |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
bool IsLowerPattern()
{
   if (g_fractalsCnt < FRACTALS_AMOUNT)
      return false;
      
   // Down pattern - it is the upper fractal in 0 element, down fractal in 1 element, upper fractal in 2 element and down fractal in 3 element
   if (g_lastFractals[0].type != EXTREMUM_TYPE_MAX || g_lastFractals[1].type != EXTREMUM_TYPE_MIN || g_lastFractals[2].type != EXTREMUM_TYPE_MAX || g_lastFractals[3].type != EXTREMUM_TYPE_MIN)
      return false;
      
   // Height of splash can be i_minSplashHeight points or greater
   if (g_lastFractals[2].price - g_lastFractals[3].price - i_minSplashHeight * Point() < -DBL_EPSILON)
      return false;
      
   // Fractals 0 and 1 must be located between 2 and 3 fractals and fractal 0 must be higher than fractal 1
   return g_lastFractals[0].time > g_lastSellPatternRegFractalTime &&
          g_lastFractals[0].price > g_lastFractals[3].price && g_lastFractals[0].price < g_lastFractals[2].price &&
          g_lastFractals[1].price > g_lastFractals[3].price && g_lastFractals[1].price < g_lastFractals[2].price &&
          g_lastFractals[0].price > g_lastFractals[1].price;
}
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Checking the buy pattern exists                                                                                                                                                                   |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
bool IsUpperPattern()
{
   if (g_fractalsCnt < FRACTALS_AMOUNT)
      return false;
      
   // Down pattern - it is the lower fractal in 0 element, upper fractal in 1 element, lower fractal in 2 element and upper fractal in 3 element
   if (g_lastFractals[0].type != EXTREMUM_TYPE_MIN || g_lastFractals[1].type != EXTREMUM_TYPE_MAX || g_lastFractals[2].type != EXTREMUM_TYPE_MIN || g_lastFractals[3].type != EXTREMUM_TYPE_MAX)
      return false;
      
   // Height of splash can be i_minSplashHeight points or greater
   if (g_lastFractals[3].price - g_lastFractals[2].price - i_minSplashHeight * Point() < -DBL_EPSILON)
      return false;
      
   // Fractals 0 and 1 must be located between 2 and 3 fractals and fractal 0 must be higher than fractal 1
   return g_lastFractals[0].time > g_lastBuyPatternRegFractalTime &&
          g_lastFractals[0].price > g_lastFractals[2].price && g_lastFractals[0].price < g_lastFractals[3].price &&
          g_lastFractals[1].price > g_lastFractals[2].price && g_lastFractals[1].price < g_lastFractals[3].price &&
          g_lastFractals[0].price < g_lastFractals[1].price;
}
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Write the new pattern to database                                                                                                                                                                 |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
ENUM_FUNCTION_RESULT AddPatternToArray()
{
   ENUM_PATTERN_TYPE newPatternType = (g_lastFractals[0].type == EXTREMUM_TYPE_MAX)? PATTERN_TYPE_BEAR : PATTERN_TYPE_BULL;
   int leftBarIndex = iBarShift(NULL, 0, g_lastFractals[2].time);
   int rightBarIndex = iBarShift(NULL, 0, g_lastFractals[0].time);

   // Finding the same pattern in array
   int arraySize = ArraySize(g_patterns);
   for (int i = arraySize - 1; i >= 0; i--)
      if (g_patterns[i].patternType == newPatternType && g_patterns[i].leftBarIndex == leftBarIndex && g_patterns[i].rightBarIndex == rightBarIndex)
         return FUNCTION_RESULT_ALRIGHT;

   // Calculate the K and B coefficients of line equation   
   double kKoef = 0.0;
   double bKoef = CalculateBAndKByLine(leftBarIndex, g_lastFractals[2].price, rightBarIndex, g_lastFractals[0].price, kKoef);
   if (bKoef == DBL_MAX || kKoef == 0.0)
      return FUNCTION_RESULT_ALRIGHT;

   int crossLinesBarIndex = int(floor((g_lastFractals[1].price - bKoef) / kKoef));
   if (rightBarIndex - crossLinesBarIndex - 3 > (int)i_maxBarsDuration)
      return FUNCTION_RESULT_ALRIGHT;


   // Resize the array
   if (ArrayResize(g_patterns, arraySize + 1, ARRAY_RESERVE_SIZE) < 0)
   {
      if (g_isRussianLang)
         Alert(WindowExpertName(), ": íåäîñòàòî÷íî ïàìÿòè äëÿ ïðîäîëæåíèÿ ðàáîòû ïðîãðàììû. Èíäèêàòîð îòêëþ÷åí.");
      else
         Alert(WindowExpertName(), ": not enough memory to continue work the program. Indicator is turned off.");
      return FUNCTION_RESULT_FATAL;      
   }

   // Write the pattern
   g_patterns[arraySize].patternType = newPatternType;
   g_patterns[arraySize].patternColor = (g_lastFractals[0].type == EXTREMUM_TYPE_MAX)? i_bearPatternRegColor : i_bullPatternRegColor;
   g_patterns[arraySize].leftBarIndex = leftBarIndex;
   g_patterns[arraySize].rightBarIndex = rightBarIndex;
   
   for (int i = 0; i < FRACTALS_AMOUNT; i++)
      g_patterns[arraySize].fractals[i] = g_lastFractals[i];
      
   if (newPatternType == PATTERN_TYPE_BEAR)
      g_lastSellPatternRegFractalTime = g_lastFractals[0].time;
   else
      g_lastBuyPatternRegFractalTime = g_lastFractals[0].time;
      
   return FUNCTION_RESULT_OK;
}
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Process the specified pattern                                                                                                                                                                     |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
bool IsNeedToDeletePattern(Pattern &pattern, int barIndex)
{
   // Pattern can be activated through 3 bars from last fractal only
   if (pattern.rightBarIndex - barIndex < 3)
      return false;
   
   // Calculate the K and B coefficients of line equation   
   double kKoef = 0.0;
   double bKoef = CalculateBAndKByLine(pattern.leftBarIndex, pattern.fractals[2].price, pattern.rightBarIndex, pattern.fractals[0].price, kKoef);
   if (bKoef == DBL_MAX || kKoef == 0.0)
      return true;
      
   // Deleting the pattern if pattern is expired
   int crossLinesBarIndex = int(floor((pattern.fractals[1].price - bKoef) / kKoef));
   if (barIndex <= crossLinesBarIndex)
      return true;
      
   // Deleting the pattern if pattern is activated
   if (pattern.patternType == PATTERN_TYPE_BEAR && iLow(NULL, 0, barIndex) < pattern.fractals[1].price)
   {
      pattern.patternColor = i_bearPatternWorkColor;
      ShowPattern(pattern);
      string uniqID = IntegerToString(pattern.fractals[0].time) + "_" + IntegerToString((int)pattern.patternType) + "_";
      ShowArrow(PREFIX + GetUniqueID(pattern) + SIGN_ARROW_SELL, iTime(NULL, 0, barIndex), iHigh(NULL, 0, barIndex), 242, i_bearPatternWorkColor, ANCHOR_BOTTOM, 2, "Sell by pattern");
      if (barIndex == 0)
         SignalOnPattern(g_isRussianLang? "Àêòèâèðîâàí Sell ïàòòåðí" : "Sell pattern activated");
      return true;
   }
   
   if (pattern.patternType == PATTERN_TYPE_BULL && iHigh(NULL, 0, barIndex) > pattern.fractals[1].price)
   {
      pattern.patternColor = i_bullPatternWorkColor;
      ShowPattern(pattern);
      ShowArrow(PREFIX + GetUniqueID(pattern) + SIGN_ARROW_BUY, iTime(NULL, 0, barIndex), iLow(NULL, 0, barIndex), 241, i_bullPatternWorkColor, ANCHOR_TOP, 2, "Buy by pattern");
      if (barIndex == 0)
         SignalOnPattern(g_isRussianLang? "Àêòèâèðîâàí Buy ïàòòåðí" : "Buy pattern activated");
      return true;
   }

   return false;
}
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Deleting the specified element from specified array                                                                                                                                               |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
template<typename T>
void DeleteElementFromArray(T &array[], int elementToDelete)
{
   int arraySize = ArraySize(array);
   if (arraySize == 0)
      return;
      
   array[elementToDelete] = array[arraySize - 1];
   ArrayResize(array, arraySize - 1, ARRAY_RESERVE_SIZE);
}
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Process the not actived patterns                                                                                                                                                                  |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
void ProcessPatterns(int barIndex)
{
   for (int i = ArraySize(g_patterns) - 1; i >= 0; i--)
      if (IsNeedToDeletePattern(g_patterns[i], barIndex))
         DeleteElementFromArray(g_patterns, i);
}
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Process the specified bar                                                                                                                                                                         |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
bool ProcessBar(int barIndex)
{
   int potentialFractalBarIndex = barIndex + 3;

   // Upper fractal
   if (iFractals(NULL, 0, MODE_UPPER, potentialFractalBarIndex) != 0.0)
      AddFractalToArray(EXTREMUM_TYPE_MAX, iHigh(NULL, 0, potentialFractalBarIndex), iTime(NULL, 0, potentialFractalBarIndex));
   
   // Lower fractal
   if (iFractals(NULL, 0, MODE_LOWER, potentialFractalBarIndex) != 0.0)
      AddFractalToArray(EXTREMUM_TYPE_MIN, iLow(NULL, 0, potentialFractalBarIndex), iTime(NULL, 0, potentialFractalBarIndex));
      
   // Pattern found
   bool isLowerPattern = IsLowerPattern();
   bool isUpperPattern = IsUpperPattern();
   if (isLowerPattern || isUpperPattern)
   {
      ENUM_FUNCTION_RESULT result = AddPatternToArray();
      if (result == FUNCTION_RESULT_FATAL)
         return false;
      if (result == FUNCTION_RESULT_ALRIGHT)
         return true;
   
      ShowPattern(g_patterns[ArraySize(g_patterns) - 1]);
         
      string patternType = (g_patterns[ArraySize(g_patterns) - 1].patternType == PATTERN_TYPE_BEAR)? "Sell" : "Buy";
      if (barIndex == 0)
         SignalOnPattern(g_isRussianLang? "Íàéäåí ïàòòåðí " + patternType :
                                          "Found the " + patternType + " pattern");
   }
   
   // Checking the activate or deleting the pattern
   ProcessPatterns(barIndex);
   
   return true;
}
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Displaying of indicators values                                                                                                                                                                   |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
bool ShowIndicatorData(int limit, int total)
{
   if (limit > 1)
   {
      ArrayResize(g_patterns, 0, ARRAY_RESERVE_SIZE);
      g_lastBuyPatternRegFractalTime = 0;
      g_lastSellPatternRegFractalTime = 0;
   }
      
   if (limit == 1)
      for (int i = ArraySize(g_patterns) - 1; i >= 0; i--)
      {
         g_patterns[i].leftBarIndex++;
         g_patterns[i].rightBarIndex++;
      }

   for (int i = limit; i >= 0; i--)
      if (!ProcessBar(i))
         return false;

   return true;
}
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| 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);                                

   if (!ShowIndicatorData(limit, total))
      g_activate = false;
   WindowRedraw();
   
   return rates_total;
}

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 ---