//+------------------------------------------------------------------+
//|                                      sm3BarFractalBreak vX
//+------------------------------------------------------------------+
#property copyright "Copyright 15.03.2020, SwingMan"
#property strict

#property description "Thread autor: dazjw2311"
#property description "https://www.forexfactory.com/showthread.php?t=985306"

/*--------------------------------------------------------------------
Source: smSmashBar Indicator_v2.0
14.03.2020  - v1.0   -  first version

--------------------------------------------------------------------*/

#property indicator_chart_window

#property indicator_buffers 4

#property indicator_color1 clrDodgerBlue
#property indicator_color2 clrRed
#property indicator_color3 clrDodgerBlue
#property indicator_color4 clrRed

#property indicator_width1 0
#property indicator_width2 0

#property indicator_width3 1
#property indicator_width4 1

//------- external parameters ---------------------------------------+
input bool Draw_Fractal_Arrows = true;
input int Line_Length = 2;
input int Line_Width = 3;
input bool Show_Comment = true;
//+------------------------------------------------------------------+

//---- constants
string CR = "\n";
string sObj = "3Bar_";

//---- buffers
double arrowUP[], arrowDN[];
double arrowFractalUP[], arrowFractalDN[];

//---- variables
datetime thisTime, oldTime;
bool newBar;

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
{
   IndicatorDigits(Digits);
   int iArrowSignal = 164;
   int iArrowFractal = 159;

   int iBuff = -1;
   //--- indicator buffers mapping
   iBuff++; //0
   SetIndexBuffer(iBuff, arrowUP);
   SetIndexStyle(iBuff, DRAW_ARROW);
   SetIndexArrow(iBuff, iArrowSignal);
   SetIndexLabel(iBuff, "high UP");

   iBuff++; //1
   SetIndexBuffer(iBuff, arrowDN);
   SetIndexStyle(iBuff, DRAW_ARROW);
   SetIndexArrow(iBuff, iArrowSignal);
   SetIndexLabel(iBuff, "low DOWN");

   iBuff++; //2
   SetIndexBuffer(iBuff, arrowFractalUP);
   SetIndexStyle(iBuff, DRAW_ARROW);
   SetIndexArrow(iBuff, iArrowFractal);
   SetIndexLabel(iBuff, "fractal UP");

   iBuff++; //3
   SetIndexBuffer(iBuff, arrowFractalDN);
   SetIndexStyle(iBuff, DRAW_ARROW);
   SetIndexArrow(iBuff, iArrowFractal);
   SetIndexLabel(iBuff, "fractal DOWN");

   //---
   ChartSetInteger(0, CHART_SHOW_OBJECT_DESCR, false);
   ChartSetInteger(0, CHART_SHOW_GRID, false);

   ObjectsDeleteAll(0, sObj);
   //---
   if (Show_Comment == true)
      Comment(WindowExpertName(), CR,
              "==================");
   //---
   return (INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
   if (Show_Comment == true)
      Comment("");
   ObjectsDeleteAll(0, sObj);
}
//+------------------------------------------------------------------+
//| 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[])
{
   //---
   int limit = rates_total - prev_calculated;
   //---
   if (rates_total <= 10)
      return (0);
   if (prev_calculated == 0)
      limit = limit - 20;

   if (prev_calculated > 0)
      limit++;
   if (limit < 5)
      limit = 5;

   //=========================================================
   int period = Period();

   double low1, low2, low3;
   double high1, high2, high3;
   bool buyCondition, sellCondition;

   for (int i = limit; i >= 0; i--)
   {
      //---- new bar    -----------------------------------------
      thisTime = Time[i];
      if (thisTime != oldTime)
      {
         oldTime = thisTime;
         newBar = true;
      }
      else
         newBar = false;

      //--- prices ----------------------------------------
      low1 = NormalizeDouble(iLow(Symbol(), period, i + 1), Digits);
      low2 = NormalizeDouble(iLow(Symbol(), period, i + 2), Digits);
      low3 = NormalizeDouble(iLow(Symbol(), period, i + 3), Digits);
   

      high1 = NormalizeDouble(iHigh(Symbol(), period, i + 1), Digits);
      high2 = NormalizeDouble(iHigh(Symbol(), period, i + 2), Digits);
      high3 = NormalizeDouble(iHigh(Symbol(), period, i + 3), Digits);
  

      //===================================================
      //--- fractals 1-1 ----------------------------------
      if (Draw_Fractal_Arrows == true)
      {
         if (high3 < high2 )
            arrowFractalUP[i + 2] = High[i + 2];
         if (low3 > low2 )
            arrowFractalDN[i + 2] = Low[i + 2];
      }

      //===================================================
      //--- signal bars -----------------------------------
      //-- condition 1 - stronger
      buyCondition = ( low3 < low2 && low1 > low2 && high1 > high2);
      sellCondition = ( high3 > high2 && high1 < high2 && low1 < low2);



      if (buyCondition == true)
      {
         arrowUP[i + 1] = High[i + 1];
         Draw_ShortTrendLine(i, high1, indicator_color1, Line_Width);
      }
      else if (sellCondition == true)
      {
         arrowDN[i + 1] = Low[i + 1];
         Draw_ShortTrendLine(i, low1, indicator_color2, Line_Width);
      }
   }
   //--- return value of prev_calculated for next call
   return (rates_total);
}


void Draw_ShortTrendLine(int iBar, double value, color dColor, int iWidth)
{
   string objName = sObj + TimeToString(Time[iBar + 1]);
   ObjectDelete(objName);

   datetime time1 = Time[iBar + 1];
   datetime time2 = time1 + Line_Length * Period() * 60;

   ObjectCreate(0, objName, OBJ_TREND, 0, time1, value, time2, value);
   //ObjectCreate(0,objName,OBJ_TREND,0,Time[iBar+1],value,Time[iBar-1],value);
   ObjectSetInteger(0, objName, OBJPROP_COLOR, dColor);
   ObjectSetInteger(0, objName, OBJPROP_WIDTH, iWidth);
   ObjectSetInteger(0, objName, OBJPROP_RAY, false);
   ObjectSetInteger(0, objName, OBJPROP_HIDDEN, true);
}
//+------------------------------------------------------------------+
