//+------------------------------------------------------------------+
//|                                       smAndrewSys Signals_v1.mq4 |
//|                                                                  |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2010.01.17, SwingMan"
#property link      ""

#property indicator_chart_window

#property indicator_buffers 2
#property indicator_color1 LimeGreen  // long
#property indicator_color2 DodgerBlue // short

#property indicator_width1 1
#property indicator_width2 1

//---- extern inputs
//+------------------------------------------------------------------+
extern int maxBars = 500;
extern int Entry_Offset = 3;
extern string Parameters_NonLagDot = "_______________";
extern int     Price          = 0;
extern int     Length         = 20;
extern int     Displace       = 0;
extern int     Filter         = 0;
extern int     Color          = 1;
extern int     ColorBarBack   = 0;
extern double  Deviation      = 0;
double Cycle =  4;
//+------------------------------------------------------------------+

//---- constants

//---- buffers
double UPsignal[], DNsignal[];
double Dot_Trend[], ST_Trend[];

//---- variables
double entryOffset;
bool bLongSignal, bShortSignal;
int nDigits;

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
{
//---- arrays   
   ArraySetAsSeries(Dot_Trend, true);
   ArraySetAsSeries(ST_Trend, true);

//---- indicators
   SetIndexBuffer(0,UPsignal); SetIndexStyle(0,DRAW_ARROW); SetIndexArrow(0,241); SetIndexLabel(0,"UP signal");
   SetIndexBuffer(1,DNsignal); SetIndexStyle(1,DRAW_ARROW); SetIndexArrow(1,242); SetIndexLabel(1,"DOWN signal");
   
   SetIndexEmptyValue(0,EMPTY_VALUE);
   SetIndexEmptyValue(1,EMPTY_VALUE);
//###############
//----   
   nDigits = MarketInfo(Symbol(),MODE_DIGITS);
   if (nDigits == 5 || nDigits == 3)
      nDigits--;
//----
   IndicatorDigits(nDigits);      
//----
   entryOffset = Entry_Offset * (1.0 / MathPow(10,nDigits));      
//----      
   Delete_NameObjects("price_");   
//----
   return(0);
}
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
int deinit()
{
//----
   Delete_NameObjects("price_");
//----
   return(0);
}

//####################################################################
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int start()
{
int limit;
   //---- arrays   
   ArrayResize(Dot_Trend, Bars);
   ArrayResize(ST_Trend, Bars);

   int counted_bars=IndicatorCounted();
   if(counted_bars<0) return(-1);
   if(counted_bars>0) counted_bars--;
   if (counted_bars == 0)
        limit = maxBars;
   else limit = Bars-counted_bars;      
   if (limit <= 2) limit = 0;  
    
//----
   for(int i=limit; i>=0; i--)   
   {
      Get_Indicators(i);
   }
//----
   return(0);
}
//+------------------------------------------------------------------+

//___________________________________________________________________
void Get_Indicators(int i)
{
int dotTrend, superTrend, OpenClosePosition;
double dPrice;

   //---- non lag dots indicator
   //----------------------------------------------------------------
   double UpDotBuffer = iCustom(Symbol(),Period(),"smNonlagDot",
      Price,Length,Displace,Filter,Color,ColorBarBack,Deviation, 1,i);
   double DnDotBuffer = iCustom(Symbol(),Period(),"smNonlagDot",
      Price,Length,Displace,Filter,Color,ColorBarBack,Deviation, 2,i);
      
   //-- long dot trend
   Dot_Trend[i] = 0;
   if (UpDotBuffer != EMPTY_VALUE && DnDotBuffer == EMPTY_VALUE)   
   {  
      Dot_Trend[i] = 1;
   }
   else
   //-- short dot trend
   if (UpDotBuffer == EMPTY_VALUE && DnDotBuffer != EMPTY_VALUE)   
   {      
      Dot_Trend[i] = -1;
   }
   
   //---- super trend indicator
   //----------------------------------------------------------------
   double UpSuperTBuffer = iCustom(Symbol(),Period(),"smSupertrend1", 0, 0,i);
   double DnSuperTBuffer = iCustom(Symbol(),Period(),"smSupertrend1", 0, 1,i);

   //-- long super trend
   ST_Trend[i] = 0;   
   if (UpSuperTBuffer != EMPTY_VALUE && DnSuperTBuffer == EMPTY_VALUE)   
   {  
      ST_Trend[i] = 1;
   }
   else
   //-- short super trend
   if (UpSuperTBuffer == EMPTY_VALUE && DnSuperTBuffer != EMPTY_VALUE)   
   {      
      ST_Trend[i] = -1;
   }
   //-- both values available
   if (UpSuperTBuffer != EMPTY_VALUE && DnSuperTBuffer != EMPTY_VALUE)   
   {      
      ST_Trend[i] = ST_Trend[i+1];
   }
      
   //---- Open/Close position
   //----------------------------------------------------------------   
   double dOpen  = iOpen(Symbol(),Period(),i);
   double dClose = iClose(Symbol(),Period(),i);
   OpenClosePosition = 0;
   if (dClose > dOpen) OpenClosePosition = 1; else
   if (dClose < dOpen) OpenClosePosition = -1;
   
   //---- offset arrows
   //----------------------------------------------------------------
   double dATR_Offset = iATR(Symbol(),Period(),10,i) * 0.50;
   
   //---- signals
   //----------------------------------------------------------------
   //-- long trend, rebounce bar short
   if (ST_Trend[i] == 1)
   {
      if (bLongSignal == false)
      {      
         if (Dot_Trend[i] == 1)
         {
            if (UpDotBuffer > UpSuperTBuffer)
            {
               if (OpenClosePosition == -1)
               {
                  UPsignal[i] = Low[i] - dATR_Offset;
                  DNsignal[i] = EMPTY_VALUE;
                  bLongSignal  = true;
                  bShortSignal = false;
                  dPrice = High[i] + entryOffset;
                  Draw_PriceValue(i, dPrice, indicator_color1);      
               }
               else
               if (OpenClosePosition == 1)
               {
                  UPsignal[i] = EMPTY_VALUE;
                  bLongSignal = false;
                  ObjectDelete("price_" + TimeToStr(Time[i]));
               }
            }
            else
            if (UpDotBuffer < UpSuperTBuffer)
            {
               UPsignal[i] = EMPTY_VALUE;
               bLongSignal = false;
               ObjectDelete("price_" + TimeToStr(Time[i]));
            }
         }
      }
      else
      if (bLongSignal == true)
      {
         if (Dot_Trend[i] == -1 && DnDotBuffer < UpSuperTBuffer)
            bLongSignal  = false;
         if (UPsignal[i] != EMPTY_VALUE)
            UPsignal[i] = Low[i] - dATR_Offset;   
      }   
   }
   else
   
   //-- short trend, rebounce bar long
   if (ST_Trend[i] == -1)
   { 
      if (bShortSignal == false)
      {
         if (Dot_Trend[i] == -1)
         {  
            if (DnDotBuffer < DnSuperTBuffer)
            {
               if (OpenClosePosition == 1)
               {
                  UPsignal[i] = EMPTY_VALUE;
                  DNsignal[i] = High[i] + dATR_Offset;
                  bLongSignal  = false;
                  bShortSignal = true;
                  dPrice = Low[i] - entryOffset;
                  Draw_PriceValue(i, dPrice, indicator_color2);
               }
               else
               if (OpenClosePosition == -1)
               {
                  DNsignal[i] = EMPTY_VALUE;
                  bShortSignal = false;
                  ObjectDelete("price_" + TimeToStr(Time[i]));
               }
            }
            else
            if (DnDotBuffer > DnSuperTBuffer)
            {
               DNsignal[i] = EMPTY_VALUE;
               bShortSignal = false;
               ObjectDelete("price_" + TimeToStr(Time[i]));
            }
         }
      }
      else
      if (bShortSignal == true)
      {
         if (Dot_Trend[i] == 1 && UpDotBuffer > DnSuperTBuffer)      
            bShortSignal = false;
         if (DNsignal[i] != EMPTY_VALUE)   
            DNsignal[i] = High[i] + dATR_Offset;   
      }
   }
   return; 
}

//___________________________________________________________________
void Draw_PriceValue(int i, double dPrice, color dColor)
{
string sName = "price_" + TimeToStr(Time[i]);
int iBoxWidth = 2;   

   dPrice = NormalizeDouble(dPrice,nDigits);

   ObjectCreate(sName,OBJ_ARROW,0,Time[i],dPrice);
      ObjectSet(sName,OBJPROP_ARROWCODE,SYMBOL_LEFTPRICE);
      ObjectSet(sName,OBJPROP_WIDTH,iBoxWidth);  
      ObjectSet(sName,OBJPROP_COLOR,dColor);
      ObjectSet(sName,OBJPROP_BACK,false);
   return;   
}

//___________________________________________________________________
void Delete_NameObjects(string sName)
{
   ObjectsDeleteAll();
   return;

   /*
   //-------------------------------------------
   for (int b=0; b<Bars; b++)
   {
      string sNameDel = "price_" + TimeToStr(Time[b]);
      if (ObjectFind(sNameDel))
         ObjectDelete(sNameDel);
   }
   return;
   */  
  
   /*
   //-------------------------------------------
   for (int j=0; j<5; j++)
   {
      int obj_total = ObjectsTotal();
      for (int i=0; i<obj_total; i++)
      {
         string sObject = ObjectName(i);
         int iFind = StringFind(sName, sObject, 0);
         if (iFind != -1)
            ObjectDelete(sObject);
      }
   }
   return;*/
}