//Version: 9
//Updated: December 22, 2006
//+------------------------------------------------------------------+
//|                       XP Moving Average                          | 
//|                                                         xpMA.mq4 |
//|                                         Developed by Coders Guru |
//|                                            http://www.xpworx.com |
//+------------------------------------------------------------------+

#property link      "http://www.xpworx.com"


#property indicator_chart_window
#property indicator_buffers 4
#property indicator_color1 Yellow
#property indicator_color2 FireBrick
#property indicator_color3 Green










extern   bool     Arrows_On               = false;

extern int MAlength = 60;
extern int ePeriod1=-1;

int      UpArrowCode             = 159;
int      DownArrowCode           = 159;
color    UpArrowColor            = Lime;
color    DownArrowColor          = Red;
int      UpArrowSize             = 1;
int      DownArrowSize           = 1;

string   pro  = "";
string   ver  = "";

int Period_1;
double UpBuffer[];
double DownBuffer[];
double Buffer3[];
double buffer[];
double tempbuffer[];
double matriple[];
double signal[];

int    nShift;   

int init()
{
   //DeleteStamp();
   //ver = GenVer();
   DeleteAllObjects();
   IndicatorBuffers(7); 

   SetIndexStyle(2,DRAW_LINE,STYLE_SOLID);
   SetIndexBuffer(2,UpBuffer);
   SetIndexStyle(1,DRAW_LINE,STYLE_SOLID);
   SetIndexBuffer(1,DownBuffer);
   SetIndexStyle(0,DRAW_LINE,STYLE_SOLID);
   SetIndexBuffer(0,Buffer3);
   
   SetIndexBuffer(3,signal);
   SetIndexBuffer(4,buffer);
   SetIndexBuffer(5,tempbuffer);
   SetIndexBuffer(6,matriple);
   
   SetIndexLabel(0,"XP Moving Average");
   SetIndexLabel(1,"DownBuffer");
   SetIndexLabel(2,"UpBuffer");
   SetIndexLabel(3,"Signal");
   
    switch(Period())
      {
        case     1: nShift = 5;   break;    
        case     5: nShift = 7;   break; 
        case    15: nShift = 10;   break; 
        case    30: nShift = 15;  break; 
        case    60: nShift = 20;  break; 
        case   240: nShift = 30;  break; 
        case  1440: nShift = 80;  break; 
        case 10080: nShift = 150; break; 
        case 43200: nShift = 250; break;               
      }
 
  getPeriod();
   return(0);
}

int deinit()
{
   //DeleteStamp();
   DeleteAllObjects();
   return(0);
}



void start()
{
   
 //  StampVersion(pro,ver,5,20);
   
   int limit;
   int i = 0;
   
   int counted_bars=IndicatorCounted();
   if(counted_bars<0) return(-1);
   if(counted_bars>0) counted_bars--;
   limit=Bars-counted_bars;
   
     
                  for(i=0; i<limit; i++)
                  {
                     buffer[i] = iCustom(NULL,0,"THV3 T3",MAlength*Period_1/Period(),0.4,0,i);
                  }
   //   Comment(Period_1,Period_1/Period());
   
   for(int shift=0; shift<limit; shift++)
   {
       UpBuffer[shift] = buffer[shift];
       DownBuffer[shift] = buffer[shift];
       Buffer3[shift] = buffer[shift];
   }                   
   
  
   
   for(shift=0; shift<limit; shift++)
   {
      double dMA = 0;
      for(int k = shift+1; k <= shift+4; k++){
         dMA += buffer[k];
      }
      dMA = dMA / 4;

      if (buffer[shift] < dMA)
      {
         UpBuffer[shift] = EMPTY_VALUE;
      }
      else if (buffer[shift]>dMA)
      {
         DownBuffer[shift] = EMPTY_VALUE;
      } 
      else
      {
         UpBuffer[shift] = EMPTY_VALUE;
         DownBuffer[shift] = EMPTY_VALUE;
      }
   }
   for(shift=0; shift<limit; shift++)
   {
         signal[shift]=0;
         if(UpBuffer[shift+1] == EMPTY_VALUE &&  UpBuffer[shift] != EMPTY_VALUE && Buffer3[shift+1] != UpBuffer[shift] )
            {
               if(Arrows_On && shift !=0) DrawObject(1,shift, buffer[shift] - nShift*Point);
               if(Arrows_On && shift ==0) DrawOnce(1,shift, buffer[shift] - nShift*Point,1);
               signal[shift] = 1;
            }
            
         if(DownBuffer[shift+1] == EMPTY_VALUE &&  DownBuffer[shift] != EMPTY_VALUE && Buffer3[shift+1] != DownBuffer[shift])
           {
               if(Arrows_On && shift !=0) DrawObject(2,shift, buffer[shift] + nShift*Point);
               if(Arrows_On && shift ==0) DrawOnce(2,shift, buffer[shift] + nShift*Point,2);
               signal[shift] = -1;
           }
   } 
   
   
   

   
   

   return(0);
}

bool DrawOnce(int direction, int bar , double price, int ref)
{  
   static int LastDraw_1 = 0;
   static int LastDraw_2 = 0;
   static int LastDraw_3 = 0;
   static int LastDraw_4 = 0;
   
   switch(ref)
   {
      case 1:
         if( LastDraw_1 == 0 || LastDraw_1 < Bars )
         {
            DrawObject(direction, bar , price);
            LastDraw_1 = Bars;
            return (1);
         }
      break;
      case 2:
         if( LastDraw_2 == 0 || LastDraw_2 < Bars )
         {
            DrawObject(direction, bar , price);
            LastDraw_2 = Bars;
            return (1);
         }
      break;
      case 3:
         if( LastDraw_3 == 0 || LastDraw_3 < Bars )
         {
            DrawObject(direction, bar , price);
            LastDraw_3 = Bars;
            return (1);
         }
      break;
      case 4:
         if( LastDraw_4 == 0 || LastDraw_4 < Bars )
         {
            DrawObject(direction, bar , price);
            LastDraw_4 = Bars;
            return (1);
         }
      break;
   }
}

void DrawObject(int direction, int bar , double price)
{

   static int count = 0;
   count++;
   string Obj = "";
   if (direction==1) //up arrow
   {
      Obj = "Buy Option" + DoubleToStr(count,0);
      ObjectCreate(Obj,OBJ_ARROW,0,Time[bar],price);
      ObjectSet(Obj,OBJPROP_COLOR,UpArrowColor);
      ObjectSet(Obj,OBJPROP_ARROWCODE,UpArrowCode);
      ObjectSet(Obj,OBJPROP_WIDTH,DownArrowSize);
   }
   if (direction==2) //down arrow
   {
      Obj = "Sell Option" + DoubleToStr(count,0);
      ObjectCreate(Obj,OBJ_ARROW,0,Time[bar],price);
      ObjectSet(Obj,OBJPROP_COLOR,DownArrowColor);
      ObjectSet(Obj,OBJPROP_ARROWCODE,DownArrowCode);
      ObjectSet(Obj,OBJPROP_WIDTH,DownArrowSize);
   }
   ObjectsRedraw();
}

void DeleteAllObjects()
{
   int objs = ObjectsTotal();
   string name;
   for(int cnt=ObjectsTotal()-1;cnt>=0;cnt--)
   {
      name=ObjectName(cnt);
      if (StringFind(name,"Option",0)>-1) ObjectDelete(name);
      ObjectsRedraw();
   }
}



int getPeriod1()

{
int thePeriod;
      switch(Period())
        {
        
        
        
         case 1:
            thePeriod=5; 
            break;
         case 5:
           thePeriod=15;
            break;
         case 15:
            thePeriod=30;
            break;
         case 30:
          thePeriod=60;
            break;
         case 60:
           thePeriod=240;
            break;
         case 240:
            thePeriod=1440; 
            break;
         case 1440:
            thePeriod=10080; 
            break;
         case 10080:
            thePeriod=43200; 
            break;
         case 43200:
            thePeriod=43200;
            break;
        }
     
        return(thePeriod);
 } 
 
 int getPeriod2()

{
   int thePeriod;
      switch(Period())
        {
     
        
         
         case 1:
            thePeriod=15; 
            break;
         case 5:
           thePeriod=30;
            break;
         case 15:
            thePeriod=60;
            break;
         case 30:
          thePeriod=240;
            break;
         case 60:
           thePeriod=1440;
            break;
         case 240:
            thePeriod=10080; 
            break;
         case 1440:
            thePeriod=43200; 
            break;
         case 10080:
            thePeriod=43200; 
            break;
         case 43200:
            thePeriod=43200;
            break;
        }
     
        return(thePeriod);
 }             
int getPeriod3()

{
int thePeriod;
      switch(Period())
        {
        
         
         case 1:
            thePeriod=30; 
            break;
         case 5:
           thePeriod=60;
            break;
         case 15:
            thePeriod=240;
            break;
         case 30:
          thePeriod=1440;
            break;
         case 60:
           thePeriod=10080;
            break;
         case 240:
            thePeriod=43200; 
            break;
         case 1440:
            thePeriod=43200; 
            break;
         case 10080:
            thePeriod=43200; 
            break;
         case 43200:
            thePeriod=43200;
            break;
        }
     
        return(thePeriod);
 }  
 
 int getPeriod4()

{
  int thePeriod;
      switch(Period())
        {
      
        
        
         
         case 1:
            thePeriod=60; 
            break;
         case 5:
           thePeriod=240;
            break;
         case 15:
            thePeriod=1440;
            break;
         case 30:
          thePeriod=10080;
            break;
         case 60:
           thePeriod=43200;
            break;
         case 240:
            thePeriod=43200; 
            break;
         case 1440:
            thePeriod=43200; 
            break;
         case 10080:
            thePeriod=43200; 
            break;
         case 43200:
            thePeriod=43200;
            break;
        }
     
        return(thePeriod);
 }                        

void getPeriod()
  {
    
 
   string msgText="Invalid timeframe. Please enter a valid timeframe";
   
       if (validateInput(ePeriod1)==false)
       {
       Alert(msgText);
       }
       else Period_1= ePeriod1;
       
       if (ePeriod1==0)
       
       {
       Period_1 = Period();
       }
       if (ePeriod1==-1)
       
       {
       Period_1 = getPeriod1();
       }
       
       if (ePeriod1==-2)
       
       {
       Period_1 = getPeriod2();
       }
       
       if (ePeriod1==-3)
       
       {
       Period_1 = getPeriod3();
       }
       
       if (ePeriod1==-4)
       
       {
       Period_1 = getPeriod4();
       }
       
       
       
     
  }
  
  
bool validateInput(int theval)
 {
 bool theanswer=false;
      switch(theval)
        {
         
            case -1:
            theanswer=true;
           ;
            break;
            
            case -2:
            theanswer=true;
           
            break;
           
            case -3:
            theanswer=true;
            break;  
            
            case -4:
            theanswer=true;
            break;  
            
            
           case 0:
            theanswer=true;
            break; 
            
           
         case 1:
            theanswer=true;
            break;
         case 5:
           theanswer=true;
           break;
         case 15:
            theanswer=true;
            break;
         case 30:
           theanswer=true;
           break;
         
         case 60:
           theanswer=true;
           break;
         case 240:
            theanswer=true;
            break;
         case 1440:
           theanswer=true;
           break;
        
           case 10080:
            theanswer=true;
            break;
         case 43200:
           theanswer=true;
           break;
         
           
          }
          
          return (theanswer);
 }
 
 












