// Time frame --->daily (4H maybe ok.dont use other tfs)
// indicator1------>EMA 365 (above bulls and below bears as you know).
// indicator2----->zigzag to find stop loss (default settings)
// indicator3----->Forex_King-STS with arrow alert(designed by LukeB)
//
// simple rules---->(1)if price action is above the ema only consider the green buy arrows.
// (2)if price action is below the ema only consider the red sell arrows.
// (3)stop loss-->recent high/low of zigzag.(some 
// times use the same ema)
// (4)take profit-->it is up to you.(half of sl,same as sl or1.5x of sl etc.)
// (5)use your own money management rules.

//
#define CHARTTF      0
#define CHARTSYMBOL  NULL
#define NOCHARTSHIFT 0
#define ACTIVEBAR    0
#define ZEROWINDOW   0
#define WHOLEBUFFER  0
#define UPPRICE      1
#define DOWNPRICE    -1
#define VAGUEPRICE   0
#define ONEHIGH      1
#define TWOHIGH      2
#define REDOVERGREEN 1
#define GREENOVERRED 2
#define BARZERO      0
#define BARONE       1
//
#property indicator_separate_window
#property indicator_buffers 6
#property indicator_color1 OrangeRed  //  Going Down
#property indicator_color2 Lime       //  Going Up
#property indicator_color3 Green      //  Starting Trend
#property indicator_color4 Blue       //  Trend Continuing
#property indicator_color5 Turquoise  //  Trend Fading
#property indicator_color6 Salmon     //  No Trend - Ranging
//
extern string TimeFrame = "current time frame";
extern string signalMethod = " 0 - Bar Zero (flickers), 1 - Bar 1 ";
extern  int   SignalMethod = 0;
extern bool ArrowDrawOn     = true;
extern bool TradeLineOn     = true;
extern bool AlertWindowOn   = false;
extern bool AlertSoundOn    = false;
extern bool AlertSMSOn      = false;
extern bool RulesOnlyDraw   = false;
extern bool SignalWithTrend = false;
extern int AveragingPeriod = 1;
extern string arrowColors    = " Arrow Colors, for Rules qualified and Rules Unqualified Arrows";
extern color  UpQualColor    = Green;
extern color  DnQualColor    = Red;
extern color  UpUnQualColor  = MediumSeaGreen;
extern color  DnUnQualColor  = Coral;
extern int ArrowSize         = 2;
//
double MovingAverageOne[];
double MovingAverageTwo[];
double TrendStart[];                  // indicator_color3 Green      //  Starting Trend
double TrendContinue[];               // indicator_color4 Blue       //  Trend Continuing
double TrendFade[];                   // indicator_color5 Turquoise  //  Trend Fading
double TrendRanges[];                  // indicator_color6 Salmon     //  No Trend - Ranging
double StdDevLine[];                  //  non-displaying values for trend calc.
// Signal Strenght Parameters.
// Standard Deviation for Signal Strength
extern int StdDevPeriod   = 12;
// Average True Range for Signal Strenth
extern int ATRPeriod      = 20;  
// Moving Average for Standard Deviation and Signal Strength
int maFastPeriod   = 3;
//
extern int LongPeriod = 365;
double LongMA;
int MinBarCount = 4;
extern int MaxBarsToProcess = 2000;
int ChartTF;
string ChartSymbol;
double   TextPrice[2];
datetime TextTime[2];
#define LASTSIGNAL  0
#define CURRENTSIGNAL 1
//
string ObjName[] = {"KingArrow","DirBox","ActionSpot","ConnectLine"};
#define KINGARROW   0
#define DIRBOX      1
#define ACTIONSPOT  2
#define CONNECTLINE 3
//
string debugOne;
string debugTwo;
string debugThree;
string debugFour;

int    timeFrame;
string indicatorFileName;
bool   calculateValue;

int init()
{
   IndicatorBuffers(6);
   IndicatorDigits(Digits+1);
   ArrayResize(StdDevLine,MaxBarsToProcess+1);
   ArrayInitialize(StdDevLine,EMPTY_VALUE);
   ArraySetAsSeries( StdDevLine, true);
   //
   SetIndexBuffer(0, MovingAverageOne);
   SetIndexBuffer(1, MovingAverageTwo);
   SetIndexBuffer(2, TrendStart);
   SetIndexBuffer(3, TrendContinue);
   SetIndexBuffer(4, TrendFade);
   SetIndexBuffer(5, TrendRanges);
   // SetIndexBuffer(6, StdDevLine);
   //
   SetIndexStyle(0, DRAW_LINE, STYLE_SOLID, 1);
   SetIndexStyle(1, DRAW_LINE, STYLE_SOLID, 1);
   SetIndexStyle(2, DRAW_LINE, STYLE_SOLID, 1);
   SetIndexStyle(3, DRAW_LINE, STYLE_SOLID, 1);
   SetIndexStyle(4, DRAW_LINE, STYLE_SOLID, 1);
   SetIndexStyle(5, DRAW_LINE, STYLE_SOLID, 1);
   // SetIndexStyle(6, DRAW_NONE, EMPTY, EMPTY, CLR_NONE);
   //
   SetIndexLabel(0,"Signal MA One");
   SetIndexLabel(1,"Sginal MA Two");
   SetIndexLabel(2, "Trend Starting");
   SetIndexLabel(3, "Trend Continues");
   SetIndexLabel(4, "Trend Fadeing");
   SetIndexLabel(5, "Trend Ranging");
   //  SetIndexLabel(6, "Std Dev");
   //
   SetIndexShift(0,0);   //  use shift to separate the lines if they are too close to see.
   SetIndexShift(1,0);
   SetIndexShift(2,0);
   SetIndexShift(3,0);
   SetIndexShift(4,0);
   SetIndexShift(5,0);
   // SetIndexShift(6,0);
   //
   SetIndexDrawBegin(0,0);
   SetIndexDrawBegin(1,0);
   SetIndexDrawBegin(2,0);
   SetIndexDrawBegin(3,0);
   SetIndexDrawBegin(4,0);
   SetIndexDrawBegin(5,0);
   // SetIndexDrawBegin(6,0);
   //
   SetIndexEmptyValue(0, EMPTY_VALUE);
   SetIndexEmptyValue(1, EMPTY_VALUE);
   SetIndexEmptyValue(2, EMPTY_VALUE);
   SetIndexEmptyValue(3, EMPTY_VALUE);
   SetIndexEmptyValue(4, EMPTY_VALUE);
   SetIndexEmptyValue(5, EMPTY_VALUE);
   // SetIndexEmptyValue(6, EMPTY_VALUE);
   //
   
   indicatorFileName = WindowExpertName();
   calculateValue    = (TimeFrame=="calculateValue"); if (calculateValue) return(0); 
   
   timeFrame = stringToTimeFrame(TimeFrame);
   string shortName = timeFrameToString(timeFrame)+" Forex King STS 2";
   IndicatorShortName(shortName);
   ChartTF = Period();
   ChartSymbol = Symbol();
   if ( !( (SignalMethod != BARZERO) || (SignalMethod != BARONE) ) )
   {
      SignalMethod = BARONE;
   }
   return (0);
}
int deinit()
{
   RemoveObjects();
   return (0);
}
int start()
{
   if (calculateValue || timeFrame==Period())
   {
      static datetime lastZeroBarTime = 0;
      static int tickCount = 0;
      static double lastMA = 0;
      tickCount ++;
      if ( Time[0] != lastZeroBarTime ) // A new Bar Zero has been made.
      {  //  the system makes the new zero element for index buffers, but this has been made independant to make the display better.
         for (int i = ArraySize(StdDevLine)-1; i >=0; i-- )
         {
            StdDevLine[i] = StdDevLine[i-1];
         }
         lastZeroBarTime = Time[0];
      }
      int barToProcess;
      int maSide;
      int oldestUnprocessedBar = GetOldestBarToProcess(tickCount);   //  Get the oldest bar to process.
      for (barToProcess = oldestUnprocessedBar; barToProcess>=0; barToProcess--)
      {
         LongMA = iMA(CHARTSYMBOL,CHARTTF,LongPeriod,NOCHARTSHIFT,MODE_EMA,PRICE_CLOSE,barToProcess);
         maSide = PlotTheCrossingMAs(barToProcess);
         StdDevLine[barToProcess] = iStdDev(CHARTSYMBOL,0,StdDevPeriod,NOCHARTSHIFT,MODE_SMA,PRICE_CLOSE,barToProcess);
         AlertsAndBoxes(barToProcess);
      }
      for (barToProcess = oldestUnprocessedBar; barToProcess>=0; barToProcess--)
      {
         LongMA = iMA(CHARTSYMBOL,CHARTTF,LongPeriod,NOCHARTSHIFT,MODE_EMA,PRICE_CLOSE,barToProcess);
         PlotLongMATrend(barToProcess);
      }
      barToProcess ++;
      debugOne = StringConcatenate("Long MA: ",DoubleToStr(LongMA,Digits+1)," TrendStart: ",DoubleToStr(TrendStart[barToProcess],Digits+1),
              " TrendContinue: ",DoubleToStr(TrendContinue[barToProcess],Digits+1)," TrendFade: ", DoubleToStr(TrendFade[barToProcess],Digits+1),
              " TrendRanges: ",DoubleToStr(TrendRanges[barToProcess],Digits+1)," StdDevLine: ",DoubleToStr(StdDevLine[barToProcess],Digits+1) );
      debugTwo = StringConcatenate("Last MA: ",DoubleToStr(lastMA,Digits+1)," TrendStart: ",DoubleToStr(TrendStart[barToProcess+1],Digits+1),
              " TrendContinue: ",DoubleToStr(TrendContinue[barToProcess+1],Digits+1)," TrendFade: ", DoubleToStr(TrendFade[barToProcess+1],Digits+1),
              " TrendRanges: ",DoubleToStr(TrendRanges[barToProcess+1],Digits+1)," StdDevLine: ",DoubleToStr(StdDevLine[barToProcess+1],Digits+1) );
      return (0);
   }      

   //
   //
   //
   //
   //
   
   int limit = MathMin((MaxBarsToProcess+1)*timeFrame/Period(),Bars-1);
      for (i = limit; i >=0; i-- )
      {
         int y = iBarShift(NULL,timeFrame,Time[i]);
            MovingAverageOne[i] = iCustom(NULL,timeFrame,indicatorFileName,"calculateValue","",SignalMethod,ArrowDrawOn,TradeLineOn,AlertWindowOn,AlertSoundOn,AlertSMSOn,RulesOnlyDraw,SignalWithTrend,AveragingPeriod,"",UpQualColor,DnQualColor,UpUnQualColor,DnUnQualColor,ArrowSize,StdDevPeriod,ATRPeriod,maFastPeriod,LongPeriod,MaxBarsToProcess,0,y);
            MovingAverageTwo[i] = iCustom(NULL,timeFrame,indicatorFileName,"calculateValue","",SignalMethod,ArrowDrawOn,TradeLineOn,AlertWindowOn,AlertSoundOn,AlertSMSOn,RulesOnlyDraw,SignalWithTrend,AveragingPeriod,"",UpQualColor,DnQualColor,UpUnQualColor,DnUnQualColor,ArrowSize,StdDevPeriod,ATRPeriod,maFastPeriod,LongPeriod,MaxBarsToProcess,1,y);
            TrendStart[i]       = iCustom(NULL,timeFrame,indicatorFileName,"calculateValue","",SignalMethod,ArrowDrawOn,TradeLineOn,AlertWindowOn,AlertSoundOn,AlertSMSOn,RulesOnlyDraw,SignalWithTrend,AveragingPeriod,"",UpQualColor,DnQualColor,UpUnQualColor,DnUnQualColor,ArrowSize,StdDevPeriod,ATRPeriod,maFastPeriod,LongPeriod,MaxBarsToProcess,2,y);
            TrendContinue[i]    = iCustom(NULL,timeFrame,indicatorFileName,"calculateValue","",SignalMethod,ArrowDrawOn,TradeLineOn,AlertWindowOn,AlertSoundOn,AlertSMSOn,RulesOnlyDraw,SignalWithTrend,AveragingPeriod,"",UpQualColor,DnQualColor,UpUnQualColor,DnUnQualColor,ArrowSize,StdDevPeriod,ATRPeriod,maFastPeriod,LongPeriod,MaxBarsToProcess,3,y);
            TrendFade[i]        = iCustom(NULL,timeFrame,indicatorFileName,"calculateValue","",SignalMethod,ArrowDrawOn,TradeLineOn,AlertWindowOn,AlertSoundOn,AlertSMSOn,RulesOnlyDraw,SignalWithTrend,AveragingPeriod,"",UpQualColor,DnQualColor,UpUnQualColor,DnUnQualColor,ArrowSize,StdDevPeriod,ATRPeriod,maFastPeriod,LongPeriod,MaxBarsToProcess,4,y);
            TrendRanges[i]      = iCustom(NULL,timeFrame,indicatorFileName,"calculateValue","",SignalMethod,ArrowDrawOn,TradeLineOn,AlertWindowOn,AlertSoundOn,AlertSMSOn,RulesOnlyDraw,SignalWithTrend,AveragingPeriod,"",UpQualColor,DnQualColor,UpUnQualColor,DnUnQualColor,ArrowSize,StdDevPeriod,ATRPeriod,maFastPeriod,LongPeriod,MaxBarsToProcess,5,y);
      }
   return(0);
}



int GetOldestBarToProcess(int tickCount) 
{
   int countedBars=IndicatorCounted();
   int maxTimeFrameBarCount = iBars(Symbol(),PERIOD_MN1);
   int firstBarToProcess = Bars-countedBars-1;
   if ( firstBarToProcess > 1)  // only do all the calculations for startup
     {
      if (firstBarToProcess > MaxBarsToProcess)
     {
        firstBarToProcess = MaxBarsToProcess;
     }
     if ( maxTimeFrameBarCount < MinBarCount )  //  not enough history
     {
        string commentString;
        if ( (MathMod(tickCount, 100) == 1) )  // No need to blast the system with Prints, or elimiate all other comments all the time.
        {
           commentString = StringConcatenate("There are only ",maxTimeFrameBarCount," Bars, and Forex King specifies ",MinBarCount," for the iMA function.  ",tickCount);
           Comment(commentString);
        }
        firstBarToProcess = maxTimeFrameBarCount-1;  //  Do as well as can be done.
        LongPeriod = firstBarToProcess;
     }
   }
   return(firstBarToProcess);
}
int PlotTheCrossingMAs(int barToProcess)
{
   static int indicatorSide;
   int maSide;
   int upDownEven;
   if ((Close[barToProcess] > iMA(CHARTSYMBOL, CHARTTF, AveragingPeriod, NOCHARTSHIFT, MODE_SMA, PRICE_HIGH, barToProcess+3)) )
   {  // The current Bar Close is higher than the MA of the bar three periods ago.
      upDownEven = UPPRICE;
   } else if ((Close[barToProcess] < iMA(CHARTSYMBOL, CHARTTF, AveragingPeriod, NOCHARTSHIFT, MODE_SMA, PRICE_LOW, barToProcess+3)) )
   {  // The current Bar Close is lower than the MA of the bar three periods ago.
         upDownEven = DOWNPRICE;
   } else
   { // The current Bar Close is between the High and Low MA of the bar three periods ago.
         upDownEven = VAGUEPRICE;
   }
   if (upDownEven != VAGUEPRICE)   // Don't change the side when the price is vague
   {
      indicatorSide = upDownEven;  // Leave the indicator on one or the other side until there is a signal.
   }
   if (indicatorSide == DOWNPRICE)  // Give the indicator buffers their values.
   {
      MovingAverageOne[barToProcess] = iMA(CHARTSYMBOL, CHARTTF, AveragingPeriod, 0, MODE_EMA, PRICE_HIGH, barToProcess);
      MovingAverageTwo[barToProcess] = iMA(CHARTSYMBOL, CHARTTF, AveragingPeriod, 0, MODE_EMA, PRICE_LOW, barToProcess);
      maSide = ONEHIGH;
   }else  // Indicator side is UPPRICE
   {
      MovingAverageOne[barToProcess] = iMA(CHARTSYMBOL, CHARTTF, AveragingPeriod, 0, MODE_EMA, PRICE_LOW, barToProcess);
      MovingAverageTwo[barToProcess] = iMA(CHARTSYMBOL, CHARTTF, AveragingPeriod, 0, MODE_EMA, PRICE_HIGH, barToProcess);
      maSide = TWOHIGH;
   }
   return(maSide);
}
void PlotLongMATrend(int barToProcess)
{
   double atrValue;
   double stdValue;
   double maValue;
   atrValue = iATR(CHARTSYMBOL,0,ATRPeriod,barToProcess);
   stdValue = StdDevLine[barToProcess];
   maValue  = iMAOnArray(StdDevLine,WHOLEBUFFER,maFastPeriod,NOCHARTSHIFT, MODE_SMMA, barToProcess);
   if ( (maValue < stdValue) && (maValue < atrValue) )
   {
      TrendStart[barToProcess]    = LongMA;
      if (TrendStart[barToProcess+1] == EMPTY_VALUE ) // Starting a new line segment
      {
         AdvanceLineSegment(LongMA,barToProcess);  // Fill the blank space between two bar start times.
      }
   } else if ( (maValue < stdValue) && (maValue > atrValue) )
   {
      TrendContinue[barToProcess]    = LongMA;
      if (TrendContinue[barToProcess+1] == EMPTY_VALUE ) // Starting a new line segment
      {
         AdvanceLineSegment(LongMA,barToProcess);  // Fill the blank space between two bar start times.
      }
   } else if ( (maValue > stdValue) && (maValue > atrValue) )
   {
      TrendFade[barToProcess]     = LongMA;
      if (TrendFade[barToProcess+1] == EMPTY_VALUE ) // Starting a new line segment
      {
         AdvanceLineSegment(LongMA,barToProcess);  // Fill the blank space between two bar start times.
      }
   } else    // (maValue > stdValue) && (maValue < atrValue)
   {
      TrendRanges[barToProcess]   = LongMA;    // rangeing
      if (TrendRanges[barToProcess+1] == EMPTY_VALUE ) // Starting a new line segment
      {
         AdvanceLineSegment(LongMA,barToProcess);  // Fill the blank space between two bar start times.
      }
   }
   // SetGraphPoint(barToProcess,LongMA);
   debugThree = StringConcatenate("TrendStart: ",DoubleToStr(TrendStart[barToProcess],Digits+1)," TrendContinue: ",DoubleToStr(TrendContinue[barToProcess],Digits+1),
                " TrendFade: ",DoubleToStr(TrendFade[barToProcess],Digits+1)," TrendRanges: ",DoubleToStr(TrendRanges[barToProcess],Digits+1),
                " EMPTY_VALUE: ",DoubleToStr(EMPTY_VALUE,Digits+1)," LongMA: ",DoubleToStr(LongMA,Digits+1)  );
   debugFour = StringConcatenate("ATRValue: ",DoubleToStr(atrValue,Digits+1)," stdValue: ",DoubleToStr(stdValue,8),
               " maValue: ",DoubleToStr(maValue,8) );
}
void AdvanceLineSegment(double longMA, int barToProcess)
{
   if ( TrendStart[barToProcess+1] != EMPTY_VALUE )
      TrendStart[barToProcess] = longMA;
   if ( TrendContinue[barToProcess+1] != EMPTY_VALUE )
      TrendContinue[barToProcess] = longMA;
   if ( TrendFade[barToProcess+1] != EMPTY_VALUE )
      TrendFade[barToProcess] = longMA;
   if ( TrendRanges[barToProcess+1] != EMPTY_VALUE )
      TrendRanges[barToProcess] = longMA;
}
void AlertsAndBoxes(int barToProcess)
{  // #define PROBUP (20)  PROBDN (-20)  INVALIDDIR (-1)
   bool lineCrossed;
   static int crossCount   = 0;          // static to preserve value between calls, incremeted with diretion changes.
   static int lineRelation;
   string crossText;
   lineCrossed = TheLinesCrossed(barToProcess,crossCount,crossText,lineRelation); // changeCount and crossText passed by reference, will be changed.
   if ( (ArrowDrawOn) && (lineCrossed == true)) // Provide Direction Change Alerts
   {
      if ( ArrowDrawingIsTrue(barToProcess,lineRelation) )
      {
         MakeArrow(crossCount,lineRelation,barToProcess,crossText);
         if ( TradeLineOn )
         {
            // DrawBullsEye(TextPrice[CURRENTSIGNAL],TextTime[CURRENTSIGNAL],barToProcess,crossText);
            DrawTargetLines(TextPrice,TextTime,crossCount);
         }
         if ( AlertWindowOn && (barToProcess < 5) )
            Alert(crossText);
         if ( AlertSoundOn && (barToProcess < 5) )
            PlaySound("stops.wav");
         if ( AlertSMSOn && (barToProcess < 5) )
            SendMail("ForexKing-STS",crossText);
      }
   } else if ( ArrowDrawOn )
   {
      DeleteArrow(barToProcess);  //  Purely to remove arrows if SignalMethod === BARZERO and the singnal turns around intra bar zero.
   }
}
bool ArrowDrawingIsTrue(int barToProcess, int lineRelation)
{
   bool returnValue = false;
   if ( ArrowDrawOn && (!RulesOnlyDraw) )
   {
      returnValue = true;
   } else if ( (ArrowDrawOn && RulesOnlyDraw) )
   { 
      if ( (lineRelation == GREENOVERRED) && (Close[barToProcess]>LongMA)
            &&  ( (!SignalWithTrend) || (TrendStart[barToProcess] != EMPTY_VALUE) || (TrendContinue[barToProcess]!=EMPTY_VALUE) ) )
      {
         returnValue = true;
      }
      if ( (lineRelation == REDOVERGREEN) && (Close[barToProcess]<LongMA)
            && ( (!SignalWithTrend) || (TrendStart[barToProcess] != EMPTY_VALUE) || (TrendContinue[barToProcess]!=EMPTY_VALUE) ) )
      {
         returnValue = true;
      }
   }
   return(returnValue);
}
bool TheLinesCrossed(int barToProcess,int &crossCount,string &crossText,int &lineRelation)
{
   static int lastRelation = 0;
   bool linesCrossed = false;
   double orderPrice;
   int oldBar = barToProcess + SignalMethod + 1;
   int newBar = barToProcess + SignalMethod;
   if ( (MovingAverageOne[oldBar] < MovingAverageTwo[oldBar])  && // Old Green Line below old Red Line
        (MovingAverageOne[newBar] > MovingAverageTwo[newBar])     // New Green Line above new Red Line
      )  // Red Line has switched positions to be above the Green Line
   {
      linesCrossed = true;
      crossCount ++;
      orderPrice = GetThePrice(barToProcess,REDOVERGREEN);
      crossText = StringConcatenate(Symbol()," SELL Signal at: ",DoubleToStr(orderPrice,Digits),", on: ",TimeToStr(Time[barToProcess],TIME_DATE|TIME_MINUTES));
      lineRelation = REDOVERGREEN;
   } else if ( (MovingAverageOne[oldBar] > MovingAverageTwo[oldBar])  && // Old Green Line above old red line
               (MovingAverageOne[newBar] < MovingAverageTwo[newBar])     // New Green Line below new red line.
             ) 
   {
      linesCrossed = true;
      crossCount ++;
      orderPrice = GetThePrice(barToProcess,GREENOVERRED);
      crossText = StringConcatenate(Symbol()," BUY Signal at: ",DoubleToStr(orderPrice,Digits),", on: ",TimeToStr(Time[barToProcess],TIME_DATE|TIME_MINUTES));
      lineRelation = GREENOVERRED;
   } else //  no cross detected.  Not sure if there is an equal condition that over two bars could result in a miss of a crossover.
   {
      linesCrossed = false;
      lineRelation = lastRelation;
   }
   lastRelation = lineRelation;
   return(linesCrossed);
}
void MakeArrow(int count,int direction,int barToProcess,string displayText)
{
   string arrowName = MakeArrowName(barToProcess);
   int    arrowCode;
   color  objColor;
   string objFont = "Wingdings";
   int    fontSize = 9;
   double price;
   datetime barTime = Time[barToProcess];
   double longMA   = iMA(CHARTSYMBOL,CHARTTF,LongPeriod,NOCHARTSHIFT,MODE_EMA,PRICE_CLOSE,barToProcess);
   if (direction == GREENOVERRED)
   {
      arrowCode   = 233;  // SYMBOL_ARROWUP
      if ( (MovingAverageTwo[barToProcess] > LongMA) &&  // (Close[barToProcess]>LongMA[barToProcess]) )
           ((!SignalWithTrend) || (TrendStart[barToProcess]!=EMPTY_VALUE) || (TrendContinue[barToProcess]!=EMPTY_VALUE)) )
      {
         objColor    = UpQualColor;
      } else
      {
         objColor    = UpUnQualColor;
      }
      price       = Low[barToProcess] - iATR(CHARTSYMBOL, ChartTF, 60, barToProcess) / 1.5;
   }  else if (direction == REDOVERGREEN)
   {
      arrowCode   = 234;  // SYMBOL_ARROWDOWN;
      if ( (MovingAverageOne[barToProcess] < LongMA) &&  // (Close[barToProcess]<LongMA[barToProcess]) )
           ((!SignalWithTrend) || (TrendStart[barToProcess]!=EMPTY_VALUE) || (TrendContinue[barToProcess]!=EMPTY_VALUE)) )
      {
         objColor    = DnQualColor;
      } else
      {
         objColor    = DnUnQualColor;
      }
      price       = High[barToProcess]+ (MarketInfo(ChartSymbol,MODE_SPREAD)*Point) + iATR(CHARTSYMBOL, ChartTF, 60, barToProcess) / 1.5;
   }
   if ( ObjectFind(arrowName) < 0 ) //  Arrow not drawn yet
   {
      ObjectCreate(arrowName, OBJ_ARROW, ZEROWINDOW, barTime, price, 0, 0, 0, 0);
      ObjectSetText(arrowName, displayText, fontSize, objFont, objColor);
      SetPriceAndTime(barToProcess,displayText,direction);
   }
   ObjectSet(arrowName,OBJPROP_ARROWCODE,arrowCode);
   ObjectSet(arrowName,OBJPROP_WIDTH, ArrowSize);   //OBJPROP_FONTSIZE
   ObjectSet(arrowName,OBJPROP_XDISTANCE,barTime);
   ObjectSet(arrowName,OBJPROP_YDISTANCE,price);
   ObjectSet(arrowName,OBJPROP_COLOR,objColor);
}
void DeleteArrow(int barToProcess)
{
   string arrowName = MakeArrowName(barToProcess);
   if ( ObjectFind(arrowName) >= 0 )
      ObjectDelete(arrowName);
}
string MakeArrowName(int barToProcess)
{
   return(StringConcatenate(ObjName[KINGARROW],TimeToStr(Time[barToProcess],TIME_DATE|TIME_MINUTES)));
}
void SetPriceAndTime(int barToProcess, string displayText,int direction)
{
   TextPrice[LASTSIGNAL] = TextPrice[CURRENTSIGNAL];   // element 0 gets elemenmt one.
   TextTime[LASTSIGNAL]  = TextTime[CURRENTSIGNAL];    //  Will use the old if we add cocde to draw line segements.
   TextPrice[CURRENTSIGNAL] = GetThePrice(barToProcess,direction);
   TextTime[CURRENTSIGNAL]  = Time[barToProcess];
}
void DrawBullsEye( double price, datetime time, int barToProcess,string displayText )
{  // OBJ_TEXT
   string bullsEyeName = StringConcatenate(ObjName[ACTIONSPOT],TimeToStr(Time[barToProcess],TIME_DATE|TIME_MINUTES));
   if ( ObjectFind(bullsEyeName) < 0 )  // Object does not exist
   {
      ObjectCreate(bullsEyeName, OBJ_ARROW, ZEROWINDOW, time, price, 0, 0, 0, 0);
      ObjectSetText(bullsEyeName, displayText, 10, "Wingdings", Blue);
      ObjectSet(bullsEyeName,OBJPROP_ARROWCODE,164);
      ObjectSet(bullsEyeName,OBJPROP_COLOR,Blue);
      ObjectSet(bullsEyeName,OBJPROP_BACK,false);
   }
}
void DrawTargetLines(double &tTextPrice[],datetime &tTextTime[],int count)
{
   string lineName = StringConcatenate(ObjName[CONNECTLINE],count);
   if ( (ObjectFind(lineName) < 0) && (tTextTime[CURRENTSIGNAL] >tTextTime[LASTSIGNAL]) ) // does not exist, and time appears valid
   { 
      ObjectCreate(lineName,OBJ_TREND,ZEROWINDOW,tTextTime[LASTSIGNAL],tTextPrice[LASTSIGNAL],tTextTime[CURRENTSIGNAL],tTextPrice[CURRENTSIGNAL],0,0);
      ObjectSet(lineName,   OBJPROP_RAY, false);
      ObjectSet(lineName,   OBJPROP_WIDTH, 1);
      ObjectSet(lineName,   OBJPROP_STYLE,STYLE_SOLID);
      ObjectSet(lineName,   OBJPROP_COLOR,Ivory);
   }
}
double GetThePrice(int barToProcess, int direction)  // What price could the user realize based on info at hand?
{
   double priceForOrder;
   double spread;
   if (direction == GREENOVERRED)  // Buying, get the order filled at the higher price
   { 
      if ( barToProcess == BARZERO ) // doing live quotes not historical bars
      {
         priceForOrder = Ask;
      } else  // buying at the close + spread  Historical Bars, we know the close price, data as of the MA value.
      {  
         spread = MarketInfo( ChartSymbol, MODE_SPREAD)*Point;
         priceForOrder = iClose(CHARTSYMBOL,ChartTF,barToProcess) + spread;
      }
   } else  // (direction == REDOVERGREEN)   - selling at the lower price
   { 
      if ( barToProcess == BARZERO )  // doing live quotes not historical bars
      {
         priceForOrder = Bid;
      } else  // buing at the close + spread
      {  
         priceForOrder = iClose(CHARTSYMBOL,ChartTF,barToProcess);
      }
   }
   return(priceForOrder);
}
void RemoveObjects()
{
   for (int objIdx = ObjectsTotal(EMPTY)-1; objIdx >= 0 ; objIdx--)  // end to start so the index #'s don't change during the loop through
   {
      // If the Found Object's name matches any of this indicator objects names, delete it.
      for ( int indIdx = 0; indIdx < ArraySize(ObjName); indIdx++)
      {
         string objString = ObjectName(objIdx);
         string indIdxName  = ObjName[indIdx];
         string matchString = StringSubstr(objString,0,StringLen(indIdxName));
         if ( matchString == indIdxName )  // See if name matches name in control array
         {
            ObjectDelete(objString);  // Delete Name Matched Object
            break;  // Object is gone, no need to try and delete it again, go get the next object.
         }
      }
   }
}

//+-------------------------------------------------------------------
//|                                                                  
//+-------------------------------------------------------------------
//
//
//
//
//

string sTfTable[] = {"M1","M5","M15","M30","H1","H4","D1","W1","MN"};
int    iTfTable[] = {1,5,15,30,60,240,1440,10080,43200};

//
//
//
//
//

int stringToTimeFrame(string tfs)
{
   tfs = stringUpperCase(tfs);
   for (int i=ArraySize(iTfTable)-1; i>=0; i--)
         if (tfs==sTfTable[i] || tfs==""+iTfTable[i]) return(MathMax(iTfTable[i],Period()));
                                                      return(Period());
}
string timeFrameToString(int tf)
{
   for (int i=ArraySize(iTfTable)-1; i>=0; i--) 
         if (tf==iTfTable[i]) return(sTfTable[i]);
                              return("");
}

//
//
//
//
//

string stringUpperCase(string str)
{
   string   s = str;

   for (int length=StringLen(str)-1; length>=0; length--)
   {
      int tchar = StringGetChar(s, length);
         if((tchar > 96 && tchar < 123) || (tchar > 223 && tchar < 256))
                     s = StringSetChar(s, length, tchar - 32);
         else if(tchar > -33 && tchar < 0)
                     s = StringSetChar(s, length, tchar + 224);
   }
   return(s);
}