CaudateCandle_ByM1_v3

Author: Scriptong
Indicators Used
Indicator of the average true range
Miscellaneous
It issuies visual alerts to the screenImplements a curve of type %1
0 Views
0 Downloads
0 Favorites
CaudateCandle_ByM1_v3
ÿþ#property copyright "Scriptong"

#property link      "http://advancetools.net"

#property version "161.217"

#property strict



#property indicator_chart_window                   

#property indicator_buffers 2                      

#property indicator_color1 Blue                    

#property indicator_color2 Red                     



enum ENUM_PRICE_TYPE

{

   PRICE_TYPE_OPEN,                                // Open

   PRICE_TYPE_CLOSE,                               // Close

   PRICE_TYPE_HIGH,                                // High

   PRICE_TYPE_LOW,                                 // Low

   PRICE_TYPE_MEDIAN,                              // Median

   PRICE_TYPE_TYPICAL,                             // Typical

   PRICE_TYPE_WEIGHTED,                            // Weighted

   PRICE_TYPE_AVERAGE                              // Full Average

};



input  uint                i_uCandlesAmount = 60;       // Candles in synthetic bar

input  double              i_fBodyPercent   = 75;       // Concentration, %

input  ENUM_PRICE_TYPE     i_ePrice         = PRICE_TYPE_AVERAGE;// Applied price

input  uint                i_uIndBarsCount  = 50000;    // Displaying bars amount



uint g_uHistoryOffset,

     g_uWaitingCnt;



double g_prices[];                                 



double g_upCandle[];                               

double g_dnCandle[];                               

double g_upVisualCandle[];                         

double g_dnVisualCandle[];                         

                                                   

#define TYPE_NO_TAIL     0                         

#define TYPE_HIGHER_TAIL 1                         

#define TYPE_LOWER_TAIL  2                         

                                                   

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

//| Custom indicator initialization function                                            |

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

int OnInit()

{

   string name = WindowExpertName();

   

   if (!TuningParameters())                        

      return (-1);                                 

                                                   

                                                   

   if (!BuffersBind())                             

      return INIT_FAILED;                          

   

   return INIT_SUCCEEDED;

}

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

//| @>25@:0 :>@@5:B=>AB8 =0AB@>5G=KE ?0@0<5B@>2                                        |

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

bool TuningParameters()

{

   string name = WindowExpertName();



   if (i_uCandlesAmount < 3)

   {

      Alert(name, ": wrong value of parameter \"Candles in synthetic bar\". Indicator is turning off.");

      return false;

   } 

   

   if (i_fBodyPercent < 0.01 || i_fBodyPercent > 99.99)

   {

      Alert(name, ": wrong value of parameter \"Concentration, %\". Indicator is turning off.");

      return false;

   } 



   g_uWaitingCnt = uint(MathRound((i_uCandlesAmount - 2) * i_fBodyPercent / 100.0));

   g_uHistoryOffset = i_uCandlesAmount;

   ArrayResize(g_prices, i_uCandlesAmount);



   return (true);

}

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

//| !2O7K20=85 1CD5@>2 8=48:0B>@0 A <0AA820<8                                           |

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

bool BuffersBind()

{

   string name = WindowExpertName();

   IndicatorBuffers(4);



   if (

       !SetIndexBuffer(0, g_upVisualCandle)||           

       !SetIndexBuffer(1, g_dnVisualCandle)||

       !SetIndexBuffer(2, g_upCandle)      ||

       !SetIndexBuffer(3, g_dnCandle)

      )

   {

      Alert(name, ": indicators buffers binding error !", GetLastError(), ". Indicator is turning off.");

      return (false);

   }



   for (int i = 0; i < 2; i++)                     // 20 1CD5@0 8=48:0B>@0.. 

      SetIndexStyle(i, DRAW_HISTOGRAM);            // ..>B>1@060NBAO 2 2845 38AB>3@0<<K



   return (true);

}



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

//| Custom indicator deinitialization function                                          |

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

void OnDeinit(const int reason)

{

   

}

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

//| =8F80;870F8O 2A5E 8=48:0B>@=KE 1CD5@>2                                             |

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

void BuffersInitializeAll()

{

   ArrayInitialize(g_upVisualCandle, EMPTY_VALUE);     

   ArrayInitialize(g_dnVisualCandle, EMPTY_VALUE);     

   ArrayInitialize(g_upCandle, EMPTY_VALUE);     

   ArrayInitialize(g_dnCandle, EMPTY_VALUE);

}

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

//| ?@545;5=85 8=45:A0 10@0, A :>B>@>3> =5>1E>48<> ?@>872>48BL ?5@5@0AG5B              |

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

uint GetRecalcIndex(uint& total)

{

   int counted_bars = IndicatorCounted();

   total = Bars - 1 - g_uHistoryOffset;             

   

   if (i_uIndBarsCount > 0 && i_uIndBarsCount < total)

      total = i_uIndBarsCount;                      

                                                   

   if (counted_bars == 0)                          

   {                                               

      BuffersInitializeAll();                      

      return(total);                               

   }

   return Bars - counted_bars - 1;                

}

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

//| >;CG5=85 A@54=59 F5=K A25G8                                                        |

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

double GetPrice(uint index)

{

   switch (i_ePrice)

   {

      case PRICE_TYPE_CLOSE:    return (Close[index]);

      case PRICE_TYPE_OPEN:     return (Open[index]);

      case PRICE_TYPE_HIGH:     return (High[index]);

      case PRICE_TYPE_LOW:      return (Low[index]);

      case PRICE_TYPE_MEDIAN:   return ((High[index] + Low[index]) / 2);

      case PRICE_TYPE_TYPICAL:  return ((High[index] + Low[index] + Close[index]) / 3);

      case PRICE_TYPE_WEIGHTED: return ((High[index] + Low[index] + 2 * Close[index]) / 4);

   }

   

   return ((Close[index] + Open[index] + High[index] + Low[index]) / 4);

}

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

//| $>@<8@>20=85 <0AA820 F5= 480?07>=0                                                  |

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

void PriceArrayFormation(uint index)

{

   uint total = index + i_uCandlesAmount;

   for (uint i = index; i < total; i++)

      g_prices[i - index] = GetPrice(i);

}

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

//|  0AG5B F5=K A5@548=K 480?07>=0                                                      |

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

double GetRangeMiddle()

{

   double high = 0, low = 0;

   for (uint i = 0; i < i_uCandlesAmount; i++)

   {

      if (g_prices[i] > high)

         high = g_prices[i];



      if (g_prices[i] < low || low == 0)

         low = g_prices[i];

   }



   return ((high + low) / 2);

}

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

//| 0E>4OBAO ;8 7=0G5=8O F5= :@09=8E A25G59 480?07>=0 2 >4=>9 ?>;>28=5 480?07>=0?      |

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

bool IsPricesInOneHalf(double middlePrice, double rightPrice, double leftPrice)

{

   if (rightPrice > middlePrice && leftPrice < middlePrice)

      return (false);

      

   if (rightPrice < middlePrice && leftPrice > middlePrice)

      return (false);

      

   return (true);   

}

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

//| >4AG5B :>;8G5AB20 A25G59 2 25@E=59 8 =86=59 ?>;>28=0E 480?07>=0                    |

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

int GetAboveAndBelowCandles(uint index, uint& cntBelow, double rangeMiddle)

{

   int cntAbove = 0;

   for (uint i = 0; i < i_uCandlesAmount; i++)

   {

      if (g_prices[i] - rangeMiddle >= Point)

         cntAbove++;

      if (rangeMiddle - g_prices[i] >= Point)

         cntBelow++;

   }

   

   return (cntAbove);   

}

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

//| ?@545;5=85 B8?0 A25G8                                                              |

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

int GetCandleType(uint index)

{

   PriceArrayFormation(index);



   double rangeMiddle = GetRangeMiddle();

   double priceRightBar = g_prices[0];

   double priceLeftBar = g_prices[i_uCandlesAmount - 1];



   if (!IsPricesInOneHalf(rangeMiddle, priceRightBar, priceLeftBar))

      return (TYPE_NO_TAIL);

   

   uint cntBelow = 0;

   uint cntAbove = GetAboveAndBelowCandles(index, cntBelow, rangeMiddle);

   

   if (priceRightBar > rangeMiddle && cntAbove > g_uWaitingCnt)

      return (TYPE_LOWER_TAIL);                    



   if (priceRightBar < rangeMiddle && cntBelow > g_uWaitingCnt)

      return (TYPE_HIGHER_TAIL);                   



   return (TYPE_NO_TAIL);                          

}

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

//| >8A: E2>AB0BKE A25G59                                                              |

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

void FindCaudateCandles(uint index)

{

   for (uint i = index; i > 0; i--)                 

   {

      int candleType = GetCandleType(i);           

      if (candleType == TYPE_NO_TAIL)              

         continue;

         

      if (candleType == TYPE_LOWER_TAIL)           

      {                                                  

         g_upCandle[i] = Low[i] - iATR(NULL, 0, 14, i);

         continue;

      }

      

      // !25G0 A 25@E=8< E2>AB>< - B>G:0 A25@EC

      g_dnCandle[i] = High[i] + iATR(NULL, 0, 14, i);

   }

}

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

//| >8A: ?>4>1=>3> A83=0;0 2 1;8609H59 8AB>@88                                         |

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

bool IsSignalUnique(uint index, double& buffer[])

{

   for (uint i = index + i_uCandlesAmount / 2 + 1; i > index; i--)

      if (buffer[i] != EMPTY_VALUE)

         return (false);

         

   return (true);

}

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

//| B>1@065=85 >4=>9 A5:F88 E2>AB0B>9 A25G8 A =86=8< E2>AB><                           |

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

void ShowHummer(uint index, uint middleIndex, double high, double low, double middle)

{  

   if (index == middleIndex)

   {

      g_upVisualCandle[index] = high;

      g_dnVisualCandle[index] = low;

      return;

   }

   

   g_upVisualCandle[index] = high;

   g_dnVisualCandle[index] = middle;

}

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

//| B>1@065=85 >4=>9 A5:F88 E2>AB0B>9 A25G8 A 25@E=8< E2>AB><                          |

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

void ShowReverseHummer(uint index, uint middleIndex, double high, double low, double middle)

{

   if (index == middleIndex)

   {

      g_upVisualCandle[index] = low;

      g_dnVisualCandle[index] = high;

      return;

   }

   

   g_upVisualCandle[index] = low;

   g_dnVisualCandle[index] = middle;

}

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

//| B>1@065=85 E2>AB0B>9 A25G8                                                         |

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

void ShowCaudateCandle(uint index, int tailType)

{

   double high = High[iHighest(NULL, 0, MODE_HIGH, i_uCandlesAmount, index)];

   double low = Low[iLowest(NULL, 0, MODE_LOW, i_uCandlesAmount, index)];

   double middle = (high + low) / 2;

   uint middleIndex = index + i_uCandlesAmount / 2;

   

   for (uint i = index + i_uCandlesAmount; i >= index; i--)

      if (tailType == TYPE_LOWER_TAIL)

         ShowHummer(i, middleIndex, high, low, middle);

      else

         ShowReverseHummer(i, middleIndex, high, low, middle);

}

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

//| A:;NG5=85 ?>2B>@ONI8EAO A83=0;>2 E2>AB0BKE A25G59                                  |

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

void ExcludeDuplicateSignals(uint index)

{

   for (uint i = index; i > 0; i--)                 

   {

      if (g_upCandle[i] != EMPTY_VALUE)            // 0945=0 A25G0 A =86=8< E2>AB><

      {

         if (IsSignalUnique(i, g_upCandle))        // !CI5AB2C5B ;8 2 ?@545;0E ?>A;54=59

            ShowCaudateCandle(i, TYPE_LOWER_TAIL); // ..8AB>@88 ?>4>1=K9 A83=0;?

         continue;

      }

      

      if (g_dnCandle[i] == EMPTY_VALUE)            // 5B A25G8 A 25@E=8< E2>AB><

         continue;

         

      if (IsSignalUnique(i, g_dnCandle))           // !CI5AB2C5B ;8 2 ?@545;0E ?>A;54=59

         ShowCaudateCandle(i, TYPE_HIGHER_TAIL);   // ..8AB>@88 ?>4>1=K9 A83=0;?

   }

}

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

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

{

   uint total;

   uint limit = GetRecalcIndex(total);             // ?@545;8< ?5@2K9 @0AG5B=K9 10@

  

   FindCaudateCandles(limit);                      //  0AG5B 40==KE

   ExcludeDuplicateSignals(limit);                 // A:;NG5=85 4C1;8@CNI8E A83=0;>2



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