CaudateCandle_Synthetic

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_Synthetic
ÿþ#property copyright "Scriptong"

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

#property version "491.217"

#property strict



#property indicator_chart_window                   

#property indicator_buffers 2                      

#property indicator_color1 clrBlue                 

#property indicator_color2 clrRed                  



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

};



#define PRICE_AVERAGE   7



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

input  double              i_fBodyPercent   = 75;       // Concentration, %

input  ENUM_PRICE_TYPE     i_ePrice         = PRICE_AVERAGE;// Applied price

input  uint                i_uIndBarsCount  = 50000;    // Displaying bars amount



uint g_historyOffset,

     g_waitingCnt;



double g_prices[];                                 



double g_upCandle[];                               

double g_dnCandle[];                               

double g_upDerCandle[];                            

double g_dnDerCandle[];                            

                                                   

                                                   

#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 INIT_FAILED;                          

                                                   

                                                   

   if (!BuffersBind())                             

      return INIT_FAILED;                          

   

   return INIT_SUCCEEDED;

}

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

//| Checking the correctness of input parameters                                        |

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

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_waitingCnt = int(MathRound((i_uCandlesAmount - 2) * i_fBodyPercent / 100.0));

   g_historyOffset = i_uCandlesAmount;

   ArrayResize(g_prices, i_uCandlesAmount);



   return (true);

}

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

//| Binding the indicator buffers with arrays                                           |

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

bool BuffersBind()

{

   string name = WindowExpertName();



   IndicatorBuffers(4);



   if (

       !SetIndexBuffer(0, g_upDerCandle)   ||           

       !SetIndexBuffer(1, g_dnDerCandle)   ||

       !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++)                     

   {

      SetIndexStyle(i, DRAW_ARROW);                

      SetIndexArrow(i, 108);

   }



   

   return (true);

}



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

//| Custom indicator deinitialization function                                          |

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

void OnDeinit(const int reason)

{

   

}

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

//| Initialize of all indicator buffers                                                 |

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

void BuffersInitializeAll()

{

   ArrayInitialize(g_upDerCandle, EMPTY_VALUE);     

   ArrayInitialize(g_dnDerCandle, EMPTY_VALUE);     

   ArrayInitialize(g_upCandle, EMPTY_VALUE);     

   ArrayInitialize(g_dnCandle, EMPTY_VALUE);

}

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

//| Determination of bar index which needed to recalculate                              |

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

uint GetRecalcIndex(uint& total)

{

   int counted_bars = IndicatorCounted();

   total = Bars - 1 - g_historyOffset;             

   

   if (i_uIndBarsCount > 0 && i_uIndBarsCount < total)

      total = i_uIndBarsCount;                     

                                                   

   if (counted_bars == 0)                          

   {                                               

      BuffersInitializeAll();                      

      return(total);                               

   }

   return Bars - counted_bars - 1;                

}

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

//| Calculate the average candle price                                                  |

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

double GetPrice(int 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);

}

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

//| Formation the array of price interval                                               |

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

void PriceArrayFormation(int index)

{

   uint total = index + i_uCandlesAmount;

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

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

}

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

//| Calculate the average price of candles interval                                     |

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

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

}

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

//| Is candle body located in one half?                                                 |

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

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

{

   if (rightPrice > middlePrice && leftPrice < middlePrice)

      return (false);

      

   if (rightPrice < middlePrice && leftPrice > middlePrice)

      return (false);

      

   return (true);   

}

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

//| Calculates the candles amount in either half of interval                            |

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

uint GetAboveAndBelowCandles(int index, int& 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);   

}

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

//| Define a candle type                                                                |

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

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

      return (TYPE_LOWER_TAIL);                    



   if (priceRightBar < rangeMiddle && cntBelow > g_waitingCnt)

      return (TYPE_HIGHER_TAIL);                   



   return (TYPE_NO_TAIL);                          

}

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

//| Finding the caudate candles                                                         |

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

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;

      }

      

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

   }

}

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

//| Excludes the duplicate signals of caudate candles                                   |

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

void ExcludeDuplicateSignals(uint index)

{

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

   {

      if (g_upCandle[i] != EMPTY_VALUE)

      {

         if (g_upCandle[i + 1] == EMPTY_VALUE)

            g_upDerCandle[i] = g_upCandle[i];

         continue;

      }

      

      if (g_dnCandle[i] == EMPTY_VALUE)

         continue;

         

      if (g_dnCandle[i + 1] == EMPTY_VALUE)

         g_dnDerCandle[i] = g_dnCandle[i];

   }

}

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

//| 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);             

  

   FindCaudateCandles(limit);                      

   ExcludeDuplicateSignals(limit);                 



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