//+------------------------------------------------------------------+
//| Die Stärke des Corrected Average (CA) besteht darin,             |
//| dass der aktuelle Wert der Zeitreihe einen von der momentanen    |
//| Volatilität abhängigen Schwellenwert überschreiten muss,         |
//| damit der Filter steigt bzw. fällt, wodurch Fehlsignale          |
//| in trendschwachen Phasen vermieden werden.                       |
//| -A.Uhl-                                                          |
//+------------------------------------------------------------------+
//|Germany, 23.03.2007
#property copyright "A.Uhl, © RickD 2006, Alexander Piechotta"
#property link      "http://onix-trade.net/forum/"
//----
#define major   1
#define minor   0
//----
#property indicator_chart_window
#property indicator_buffers 1
#property indicator_color1  Gold
//----
extern int MA.Period=35;
extern int MA.method=MODE_SMA;
extern int MA.applied_price=PRICE_CLOSE;
extern string note1 = "-----Alert Options----";
extern bool Std_MT4_Alert = true;
extern bool Use_Email = false;
//----
double MABuf[];
double CABuf[];

int Arrow_ID = 0;

color Arrow_Color = Yellow;
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void init()
  {
   IndicatorBuffers(2);
   SetIndexStyle(2, DRAW_LINE, STYLE_SOLID,1);
   SetIndexDrawBegin(0, MA.Period);
   //
   SetIndexBuffer(0, CABuf);
   SetIndexBuffer(1, MABuf);
   IndicatorShortName("Corrected Average (CA) ("+MA.Period+")");
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
  void deinit()
  {ObjectsDeleteAll();}
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void start()
  {
   if(New_Bar()){
      if(Close[1] > CABuf[1] && Open[1] < CABuf[1]) Alert_User("UP");
      if(Close[1] < CABuf[1] && Open[1] > CABuf[1]) Alert_User("DOWN");
   }
   int counted=IndicatorCounted();
   if (counted < 0) return(-1);
   if (counted > 0) counted--;
   int limit=Bars-counted;
   double v1, v2, k;
//----
   for(int i=limit-1; i>=0; i--)
     {
      MABuf[i]=iMA(NULL, 0, MA.Period, 0, MA.method, MA.applied_price, i);
        if (i==Bars-1) 
        {
         CABuf[i]=MABuf[i];
         continue;
        }
      v1=MathPow(iStdDev(NULL, 0, MA.Period, 0, MA.method, MA.applied_price, i), 2);
      v2=MathPow(CABuf[i+1] - MABuf[i], 2);
//----
      k=0;
      if (v2 < v1 || v2==0) k=0; else k=1 - v1/v2;

      CABuf[i]=CABuf[i+1] + k*(MABuf[i]-CABuf[i+1]);
     }

  }
  
//+------------------------------------------------------------------+
void Alert_User(string Up_or_Down)
{
string 
   Text = StringConcatenate(Symbol(), " price has closed ", Up_or_Down, " i-CAi");
   if (Std_MT4_Alert) Alert(Text);
   if (Use_Email) SendMail("MT4 Indicator Alert", Text);
   if(Up_or_Down == "UP")Display_Marker(High[1] + 0.0005, SYMBOL_ARROWUP);
   else Display_Marker(Low[1] - 0.0001, SYMBOL_ARROWDOWN);
}
//+------------------------------------------------------------------+
bool New_Bar()
{
   static datetime New_Time=0;
   if(New_Time!=Time[0]){
      New_Time=Time[0];
      return(true);
   }
   return(false);
}
//+------------------------------------------------------------------+
void Display_Marker(double Marker_Price, int Arrow)
{
   string Marker_Name = StringConcatenate("Arrow",Arrow_ID);
   ObjectCreate(Marker_Name, OBJ_ARROW ,0,Time[1],Marker_Price);
   ObjectSet(Marker_Name, OBJPROP_ARROWCODE, Arrow);
   ObjectSet(Marker_Name, OBJPROP_COLOR,Arrow_Color);
   Arrow_ID++;
}