//+------------------------------------------------------------------+
//| #PH#StochCrossOverSpecial[5].mq4                                 |
//+------------------------------------------------------------------+
//| Code by fewhills with help from other code                       |
//| With this indicator you can choose cross overs of main and signal|
//|      lines, or overbought and oversold areas                     |
//| changes Special[4]: choose highest TF as reference for trend     |
//|                     on smaller TF's                              |
//|                     if so, only show trend or also opposite      |
//| changes Special[5]: show arrows per timeframe if true            |
//|                     if so, you can choose different arrow per TF |
//+------------------------------------------------------------------+



#property indicator_chart_window

#define PH_OP_NONE -1
#define PH_OP_BUY   1
#define PH_OP_SELL  2

#define MAX_PH_PS 9

extern int    ShiftLine             =    0;      // Move line per # of bars 
back or forward  (negative = forward)
extern int    MaxNumberOfBars       =  100;      // Within how many bars to 
show cross overs
extern int    MAMode                = MODE_SMA;  // Stochastic MA method, 
default 0   0=SMA 1=EMA 2=SMMA 3=LWMA
extern int    PriceField            =    0;      // Stochastic Price method: 
   0 = H/L   1 = Close/Close
extern int    AlertNrOfTFs          =    2;      // at least how many the 
same Colors with different TF's together give the Alert, 1 = as system was
extern bool   AlertOn               = true;      // general alert on or off 
(does not influence sendmail)
extern bool   SendMailOn            = false;     // send alert if live 
account
extern bool   UseHighestTFforTrend  =  true;     // use highest timeframe to 
show direction trend
extern int    HighestTFforTrend     =   240;     // which timeframe will be 
used as highest
extern bool   OnlyShowTrend         =  true;     // show stochastic lines 
for only trend or also opposite of trend
extern bool   showArrows            = false;     // show arrows instead of 
lines
//--------------------------------------

extern string Period1               = "-(1)--First Time Frame in minutes 
(smallest)----";
extern bool   usePeriod1            =false;      // false = don't use this 
time frame
extern int    period1               =    1;      // 1 = 1 Minute Time Frame. 
Must always have a positive number in minutes
extern bool   useSignalCrossOver1   = true;      // Signal Crossover Main 
line (if signal true, then OBOSCrossover will be false)
extern bool   useOBOSCrossOver1     = true;      // Overbought Oversold 
cross over (if signal true, then this will be false)
extern double OverboughtNumber1     =   80;      // if overbought, Sell if 
price goes below this number
extern double OversoldNumber1       =   20;      // if oversold, Buy if 
price goes above this number
extern int    KPeriod1              =    5;      // Stochastic KPeriod
extern int    DPeriod1              =    3;      // Stochastic DPeriod
extern int    Slowing1              =    3;      // Stochastic Slowing
extern int    MaxNumberOfLinesP1    =   50;      // How many period1 
vertical lines will be shown - show this one always
extern color  UpColor1              = Blue;      // Up line color
extern color  DownColor1            = Red;       // Down line color
extern color  NoneCloseUpColor1     = Aqua;      // None closed bar color
extern color  NoneCloseDownColor1   = Gold;      // None closed bar color
extern int    LineWidth1            =    1;      // Line width
extern int    LineStyle1            =    0;      // Line style  
0=solid,1=dash,2=dot,3=dashdot,4=dashdotdot
extern int    ArrowUp1              =  217;      // if showArrows is true, 
then no lines but arrows. Up Arrow code
extern int    ArrowDown1            =  218;      // if showArrows is true, 
then no lines but arrows. Down Arrow code
extern bool   AlertPeriod1          = false;      // need an alert if 
period1 is triggered?

extern string Period2               = "-(2)--Second Time Frame in minutes 
(higher or equal to #1)----";
extern bool   usePeriod2            =false;      // false = don't use this 
time frame
extern int    period2               =    5;      // 5 = 5 Minute Time Frame. 
Must always have a positive number in minutes
extern bool   useSignalCrossOver2   = true;      // Signal Crossover Main 
line (if signal true, then OBOSCrossover will be false)
extern bool   useOBOSCrossOver2     = true;      // Overbought Oversold 
cross over (if signal true, then this will be false)
extern double OverboughtNumber2     =   80;      // if overbought, Sell if 
price goes below this number
extern double OversoldNumber2       =   20;      // if oversold, Buy if 
price goes above this number
extern int    KPeriod2              =   14;      // Stochastic KPeriod
extern int    DPeriod2              =    3;      // Stochastic DPeriod
extern int    Slowing2              =    3;      // Stochastic Slowing
extern int    MaxNumberOfLinesP2    =   50;      // How many period2 
vertical lines will be shown - 0 means don't show this period
extern color  UpColor2              = Blue;      // Up line color
extern color  DownColor2            = Red;       // Down line color
extern color  NoneCloseUpColor2     = Aqua;      // None closed bar color
extern color  NoneCloseDownColor2   = Gold;      // None closed bar color
extern int    LineWidth2            =    1;      // Line width
extern int    LineStyle2            =    3;      // Line style  
0=solid,1=dash,2=dot,3=dashdot,4=dashdotdot
extern int    ArrowUp2              =  200;      // if showArrows is true, 
then no lines but arrows. Up Arrow code
extern int    ArrowDown2            =  202;      // if showArrows is true, 
then no lines but arrows. Down Arrow code
extern bool   AlertPeriod2          = false;      // need an alert if 
period2 is triggered?

extern string Period3               = "-(3)--Third Time Frame in minutes 
(higher or equal to #2)----";
extern bool   usePeriod3            =true;      // false = don't use this 
time frame
extern int    period3               =   15;      // Must always have a 
positive number in minutes
extern bool   useSignalCrossOver3   = true;      // Signal Crossover Main 
line (if signal true, then OBOSCrossover will be false)
extern bool   useOBOSCrossOver3     =true;      // Overbought Oversold cross 
over (if signal true, then this will be false)
extern double OverboughtNumber3     =   80;      // if overbought, Sell if 
price goes below this number
extern double OversoldNumber3       =   20;      // if oversold, Buy if 
price goes above this number
extern int    KPeriod3              =   14;      // Stochastic KPeriod
extern int    DPeriod3              =    3;      // Stochastic DPeriod
extern int    Slowing3              =    3;      // Stochastic Slowing
extern int    MaxNumberOfLinesP3    =   51;      // How many period3 
vertical lines will be shown - 1 means just show one line of this period
extern color  UpColor3              = Blue;      // Up line color
extern color  DownColor3            = Red;       // Down line color
extern color  NoneCloseUpColor3     = Aqua;      // None closed bar color
extern color  NoneCloseDownColor3   = Gold;      // None closed bar color
extern int    LineWidth3            =    1;      // Line width
extern int    LineStyle3            =    2;      // Line style  
0=solid,1=dash,2=dot,3=dashdot,4=dashdotdot
extern int    ArrowUp3              =  241;      // if showArrows is true, 
then no lines but arrows. Up Arrow code
extern int    ArrowDown3            =  242;      // if showArrows is true, 
then no lines but arrows. Down Arrow code
extern bool   AlertPeriod3          = false;      // need an alert if 
period3 is triggered?

extern string Period4               = "-(4)--Fourth Time Frame in minutes 
(higher or equal to #3)----";
extern bool   usePeriod4            = true;      // false = don't use this 
time frame
extern int    period4               =   30;      // Must always have a 
positive number in minutes
extern bool   useSignalCrossOver4   = true;      // Signal Crossover Main 
line (if signal true, then OBOSCrossover will be false)
extern bool   useOBOSCrossOver4     =true;      // Overbought Oversold cross 
over (if signal true, then this will be false)
extern double OverboughtNumber4     =   80;      // if overbought, Sell if 
price goes below this number
extern double OversoldNumber4       =   20;      // if oversold, Buy if 
price goes above this number
extern int    KPeriod4              =    14;      // Stochastic KPeriod
extern int    DPeriod4              =    3;      // Stochastic DPeriod
extern int    Slowing4              =    3;      // Stochastic Slowing
extern int    MaxNumberOfLinesP4    =   25 ;      // How many period4 
vertical lines will be shown - 1 or more = # of lines per period
extern color  UpColor4              = Blue;      // Up line color
extern color  DownColor4            = Red;       // Down line color
extern color  NoneCloseUpColor4     = Aqua;      // None closed bar color
extern color  NoneCloseDownColor4   = Gold;      // None closed bar color
extern int    LineWidth4            =    1;      // Line width
extern int    LineStyle4            =    1;      // Line style  
0=solid,1=dash,2=dot,3=dashdot,4=dashdotdot
extern int    ArrowUp4              =  221;      // if showArrows is true, 
then no lines but arrows. Up Arrow code
extern int    ArrowDown4            =  222;      // if showArrows is true, 
then no lines but arrows. Down Arrow code
extern bool   AlertPeriod4          = true;      // need an alert if period4 
is triggered?

extern string Period5               = "-(5)--Fifth Time Frame in minutes 
(higher or equal to #4)----";
extern bool   usePeriod5            = true;      // false = don't use this 
time frame
extern int    period5               =   60;      // Must always have a 
positive number in minutes
extern bool   useSignalCrossOver5   = true;      // Signal Crossover Main 
line (if signal true, then OBOSCrossover will be false)
extern bool   useOBOSCrossOver5     =true;      // Overbought Oversold cross 
over (if signal true, then this will be false)
extern double OverboughtNumber5     =   80;      // if overbought, Sell if 
price goes below this number
extern double OversoldNumber5       =   20;      // if oversold, Buy if 
price goes above this number
extern int    KPeriod5              =   14;      // Stochastic KPeriod
extern int    DPeriod5              =    3;      // Stochastic DPeriod
extern int    Slowing5              =    3;      // Stochastic Slowing
extern int    MaxNumberOfLinesP5    =   13;      // How many period5 
vertical lines will be shown - 1 or more = # of lines per period
extern color  UpColor5              = Blue;      // Up line color
extern color  DownColor5            = Red;       // Down line color
extern color  NoneCloseUpColor5     = Aqua;      // None closed bar color
extern color  NoneCloseDownColor5   = Gold;      // None closed bar color
extern int    LineWidth5            =    1;      // Line width
extern int    LineStyle5            =    0;      // Line style  
0=solid,1=dash,2=dot,3=dashdot,4=dashdotdot
extern int    ArrowUp5              =  225;      // if showArrows is true, 
then no lines but arrows. Up Arrow code
extern int    ArrowDown5            =  226;      // if showArrows is true, 
then no lines but arrows. Down Arrow code
extern bool   AlertPeriod5          = true;      // need an alert if period4 
is triggered?

extern string Period6               = "-(6)--Sixth Time Frame in minutes 
(higher or equal to #5)----";
extern bool   usePeriod6            = true;      // false = don't use this 
time frame
extern int    period6               =  240;      // Must always have a 
positive number in minutes
extern bool   useSignalCrossOver6   = true;      // Signal Crossover Main 
line (if signal true, then OBOSCrossover will be false)
extern bool   useOBOSCrossOver6     =true;      // Overbought Oversold cross 
over (if signal true, then this will be false)
extern double OverboughtNumber6     =   80;      // if overbought, Sell if 
price goes below this number
extern double OversoldNumber6       =   20;      // if oversold, Buy if 
price goes above this number
extern int    KPeriod6              =   14;      // Stochastic KPeriod
extern int    DPeriod6              =    3;      // Stochastic DPeriod
extern int    Slowing6              =    3;      // Stochastic Slowing
extern int    MaxNumberOfLinesP6    =    2;      // How many period6 
vertical lines will be shown - 1 or more = # of lines per period
extern color  UpColor6              = Blue;      // Up line color
extern color  DownColor6            = Red;       // Down line color
extern color  NoneCloseUpColor6     = Aqua;      // None closed bar color
extern color  NoneCloseDownColor6   = Gold;      // None closed bar color
extern int    LineWidth6            =    3;      // Line width
extern int    LineStyle6            =    0;      // Line style  
0=solid,1=dash,2=dot,3=dashdot,4=dashdotdot
extern int    ArrowUp6              =  233;      // if showArrows is true, 
then no lines but arrows. Up Arrow code
extern int    ArrowDown6            =  234;      // if showArrows is true, 
then no lines but arrows. Down Arrow code
extern bool   AlertPeriod6          = true;      // need an alert if period4 
is triggered?

extern string Period7               = "-(7)--Seventh Time Frame in minutes 
(higher or equal to #6)----";
extern bool   usePeriod7            =false;      // false = don't use this 
time frame
extern int    period7               = 1440;      // Must always have a 
positive number in minutes
extern bool   useSignalCrossOver7   = true;      // Signal Crossover Main 
line (if signal true, then OBOSCrossover will be false)
extern bool   useOBOSCrossOver7     = true;      // Overbought Oversold 
cross over (if signal true, then this will be false)
extern double OverboughtNumber7     =   80;      // if overbought, Sell if 
price goes below this number
extern double OversoldNumber7       =   20;      // if oversold, Buy if 
price goes above this number
extern int    KPeriod7              =   14;      // Stochastic KPeriod
extern int    DPeriod7              =    3;      // Stochastic DPeriod
extern int    Slowing7              =    3;      // Stochastic Slowing
extern int    MaxNumberOfLinesP7    =    1;      // How many period7 
vertical lines will be shown - 1 or more = # of lines per period
extern color  UpColor7              = Blue;      // Up line color
extern color  DownColor7            = Red;       // Down line color
extern color  NoneCloseUpColor7     = Aqua;      // None closed bar color
extern color  NoneCloseDownColor7   = Gold;      // None closed bar color
extern int    LineWidth7            =    3;      // Line width
extern int    LineStyle7            =    0;      // Line style  
0=solid,1=dash,2=dot,3=dashdot,4=dashdotdot
extern int    ArrowUp7              =  233;      // if showArrows is true, 
then no lines but arrows. Up Arrow code
extern int    ArrowDown7            =  234;      // if showArrows is true, 
then no lines but arrows. Down Arrow code
extern bool   AlertPeriod7          = true;      // need an alert if period4 
is triggered?

extern string Period8               = "-(7)--Eighth Time Frame in minutes 
(higher or equal to #7)----";
extern bool   usePeriod8            =false;      // false = don't use this 
time frame
extern int    period8               =10080;      // Must always have a 
positive number in minutes
extern bool   useSignalCrossOver8   = true;      // Signal Crossover Main 
line (if signal true, then OBOSCrossover will be false)
extern bool   useOBOSCrossOver8     = true;      // Overbought Oversold 
cross over (if signal true, then this will be false)
extern double OverboughtNumber8     =   80;      // if overbought, Sell if 
price goes below this number
extern double OversoldNumber8       =   20;      // if oversold, Buy if 
price goes above this number
extern int    KPeriod8              =   14;      // Stochastic KPeriod
extern int    DPeriod8              =    3;      // Stochastic DPeriod
extern int    Slowing8              =    3;      // Stochastic Slowing
extern int    MaxNumberOfLinesP8    =    2;      // How many period8 
vertical lines will be shown - 1 or more = # of lines per period
extern color  UpColor8              = Blue;      // Up line color
extern color  DownColor8            = Red;       // Down line color
extern color  NoneCloseUpColor8     = Aqua;      // None closed bar color
extern color  NoneCloseDownColor8   = Gold;      // None closed bar color
extern int    LineWidth8            =    1;      // Line width
extern int    LineStyle8            =    0;      // Line style  
0=solid,1=dash,2=dot,3=dashdot,4=dashdotdot
extern int    ArrowUp8              =  233;      // if showArrows is true, 
then no lines but arrows. Up Arrow code
extern int    ArrowDown8            =  234;      // if showArrows is true, 
then no lines but arrows. Down Arrow code
extern bool   AlertPeriod8          = true;      // need an alert if period4 
is triggered?

extern string Period9               = "-(9)--Ninth Time Frame in minutes 
(higher or equal to #8)----";
extern bool   usePeriod9            =false;      // false = don't use this 
time frame
extern int    period9               =43200;      // Must always have a 
positive number in minutes
extern bool   useSignalCrossOver9   = true;      // Signal Crossover Main 
line (if signal true, then OBOSCrossover will be false)
extern bool   useOBOSCrossOver9     =false;      // Overbought Oversold 
cross over (if signal true, then this will be false)
extern double OverboughtNumber9     =   80;      // if overbought, Sell if 
price goes below this number
extern double OversoldNumber9       =   20;      // if oversold, Buy if 
price goes above this number
extern int    KPeriod9              =   14;      // Stochastic KPeriod
extern int    DPeriod9              =    3;      // Stochastic DPeriod
extern int    Slowing9              =    3;      // Stochastic Slowing
extern int    MaxNumberOfLinesP9    =    2;      // How many period9 
vertical lines will be shown - 1 or more = # of lines per period
extern color  UpColor9              = Blue;      // Up line color
extern color  DownColor9            = Red;       // Down line color
extern color  NoneCloseUpColor9     = Aqua;      // None closed bar color
extern color  NoneCloseDownColor9   = Gold;      // None closed bar color
extern int    LineWidth9            =    1;      // Line width
extern int    LineStyle9            =    0;      // Line style  
0=solid,1=dash,2=dot,3=dashdot,4=dashdotdot
extern int    ArrowUp9              =  233;      // if showArrows is true, 
then no lines but arrows. Up Arrow code
extern int    ArrowDown9            =  234;      // if showArrows is true, 
then no lines but arrows. Down Arrow code
extern bool   AlertPeriod9          = true;      // need an alert if period4 
is triggered?

#define NEGATIVE_RESULT -1
#define NONE_RESULT     -2

#define PH_MAX_PERIODS 9
#define PH_MAX_TL      2
static int    periodTF[PH_MAX_PERIODS];
static bool   periodUse[PH_MAX_PERIODS];
static color  periodColorUp[PH_MAX_PERIODS][PH_MAX_TL];
static color  periodColorDn[PH_MAX_PERIODS][PH_MAX_TL];
static int    periodStyle[PH_MAX_PERIODS][PH_MAX_TL];
static int    periodWidth[PH_MAX_PERIODS][PH_MAX_TL];
static bool   periodUseSignal[PH_MAX_PERIODS];
static bool   periodUseOBOS[PH_MAX_PERIODS];
static double periodOBOSSell[PH_MAX_PERIODS];
static double periodOBOSBuy[PH_MAX_PERIODS];
static int    periodK[PH_MAX_PERIODS];
static int    periodD[PH_MAX_PERIODS];
static int    periodSlowing[PH_MAX_PERIODS];
static int    periodMaxLines[PH_MAX_PERIODS];
static bool   periodUseAlert[PH_MAX_PERIODS];
static int    periodArrowUp[PH_MAX_PERIODS];
static int    periodArrowDn[PH_MAX_PERIODS];

//+------------------------------------------------------------------+
//| Make strings from periods                                        |
//+------------------------------------------------------------------+
string givePerStr(int period)
{
   string retPerStr = "";
   switch (period)
   {
      case PERIOD_M1  : retPerStr = retPerStr + " 1 Min"; break;
      case PERIOD_M5  : retPerStr = retPerStr + " 5 Min"; break;
      case PERIOD_M15 : retPerStr = retPerStr + "15 Min"; break;
      case PERIOD_M30 : retPerStr = retPerStr + "30 Min"; break;
      case PERIOD_H1  : retPerStr = retPerStr + " 1 Hour"; break;
      case PERIOD_H4  : retPerStr = retPerStr + " 4 Hour"; break;
      case PERIOD_D1  : retPerStr = retPerStr + " 1 Day"; break;
      case PERIOD_W1  : retPerStr = retPerStr + " 1 Week"; break;
      case PERIOD_MN1 : retPerStr = retPerStr + " 1 Month"; break;
      default:          retPerStr = "wrong period"; break;
   }
   return (retPerStr);
}
string givePeriodStr(int period,int K,int D, int S)
{
   string retPerStr = "Stoch(";
   retPerStr = retPerStr + K;
   retPerStr = retPerStr + ",";
   retPerStr = retPerStr + D;
   retPerStr = retPerStr + ",";
   retPerStr = retPerStr + S;
   retPerStr = retPerStr + ") ";
   retPerStr = retPerStr + givePerStr(period) + " ";
   return (retPerStr);
}

void init()
{
   int period = Period();
   DeleteObjects();
   for (int i=0; i<MaxNumberOfBars; i++)
   {
      for (int j=PH_MAX_PERIODS;j>=0;j--)
      {
         if (periodUse[j]==true && periodMaxLines[j] > 0 && period <= 
periodTF[j])
         {
            
CreateObjects(givePeriodStr(periodTF[j],periodK[j],periodD[j],periodSlowing[j])+"["+i+"]",periodWidth[j][0],periodStyle[j][0]);
         }
      }
   }
   initPeriods();
}

void deinit()
{
  DeleteObjects();
}

void CreateObjects(string vL, int width, int style)
{
   if (showArrows)
   {
      ObjectCreate(vL,OBJ_ARROW,0,0,NULL);
   }
   else
   {
      ObjectCreate(vL,OBJ_VLINE,0,0,NULL);
      ObjectSet(vL,OBJPROP_WIDTH,width);
      ObjectSet(vL,OBJPROP_STYLE,style);
   }
}


void DeleteObjects()
{
   int period = Period();
   for (int i=0; i<MaxNumberOfBars; i++)
   {
      for (int j=PH_MAX_PERIODS;j>=0;j--)
      {
         if (periodUse[j]==true && periodMaxLines[j] > 0 && period <= 
periodTF[j])
         {
            
ObjectDelete(givePeriodStr(periodTF[j],periodK[j],periodD[j],periodSlowing[j])+"["+i+"]");
         }
      }
   }
}

//+------------------------------------------------------------------+
//| Has 4 functions                                                  |
//| 1) show cross overs main and signal                              |
//| OR                                                               |
//| 2) show cross overs oversold and overbought                      |
//| OR                                                               |
//| 3) combination 1 and 2                                           |
//| OR                                                               |
//| 4) show stoch direction including cross overs                    |
//+------------------------------------------------------------------+
int showStochasticRoute(int timeFrame,int i,bool giveTrend,int KPeriod,int 
DPeriod,int Slowing,
                                   bool useSignalCrossOver,bool 
useOBOSCrossOver,double OverboughtNumber,double OversoldNumber)
{
   int sSR = NEGATIVE_RESULT;

   double 
StochM1=iStochastic(NULL,timeFrame,KPeriod,DPeriod,Slowing,MAMode,PriceField,MODE_MAIN,i);
   double 
StochS1=iStochastic(NULL,timeFrame,KPeriod,DPeriod,Slowing,MAMode,PriceField,MODE_SIGNAL,i);
   double 
StochM2=iStochastic(NULL,timeFrame,KPeriod,DPeriod,Slowing,MAMode,PriceField,MODE_MAIN,i+1);
   double 
StochS2=iStochastic(NULL,timeFrame,KPeriod,DPeriod,Slowing,MAMode,PriceField,MODE_SIGNAL,i+1);

   StochM1 = MathRound(StochM1);
   StochM2 = MathRound(StochM2);
   StochS1 = MathRound(StochS1);
   StochS2 = MathRound(StochS2);
   if (useSignalCrossOver == true && useOBOSCrossOver == true)
   {
      if                              // Signal Crosses Main line up
         (   StochM1 > StochS1
          && StochM2 < StochS2
   //      && StochM1 > OversoldNumber     // 20
          && StochM1 < OverboughtNumber)  // 80
          sSR = PH_OP_BUY;

      else if                         // Signal Crosses Main line down
         (   StochM1 < StochS1
          && StochM2 > StochS2
          && StochM1 > OversoldNumber
        //  && StochM1 > OverboughtNumber
         ) sSR = PH_OP_SELL;
   }
   else if (useSignalCrossOver == true)
   {
      if                              // Signal Crosses Main line up
         (   StochM1 > StochS1
          && StochM2 < StochS2)
          sSR = PH_OP_BUY;

      else if                         // Signal Crosses Main line down
         (   StochM1 < StochS1
          && StochM2 > StochS2)
          sSR = PH_OP_SELL;
   }
   else if (useOBOSCrossOver == true)
   {
      if                              // Main line crosses oversold level
         (   StochM2 <= OversoldNumber
          && StochM1 >  OversoldNumber)
          sSR = PH_OP_BUY;

      else if                         // Main line crosses overbought level
         (   StochM2 >= OverboughtNumber
          && StochM1 <  OverboughtNumber)
          sSR = PH_OP_SELL;
   }

   if (giveTrend == true)
   {
      if (
         (sSR==PH_OP_BUY)      ||     // CROSSING OR CONTINUATION
         (StochM1 > StochM2 &&
          StochS1 > StochS2 &&
          StochM1 > StochS1 &&
          StochM2 > StochS2)) sSR=PH_OP_BUY;
      else if (
         (sSR==PH_OP_SELL)     ||
         (StochM1 < StochM2 &&
          StochS1 < StochS2 &&
          StochM1 < StochS1 &&
          StochM2 < StochS2)) sSR=PH_OP_SELL;
   }
   return (sSR);
}

static datetime CheckTimeAlertPeriod[MAX_PH_PS];

bool AlertP[MAX_PH_PS];

void start()
{
   int sSR          = NONE_RESULT;
   int highestTrend = PH_OP_NONE;
   int MaxNoOfLines = 0;
   color colr;
   string trend   = Symbol()+", Stochastic cross over period: ";
   int period = Period();
   int  i;
   int ups=0;
   int downs=0;
   int p[MAX_PH_PS][MAX_PH_PS];
   int maxP[MAX_PH_PS];
   bool AlertP[MAX_PH_PS];

   datetime OldestTime=0;
   bool doContinue = false;

   if      (MaxNumberOfBars<1)      { Alert("MaxNumberOfBars must have 
positive number."); return(0); }
   else if (AlertNrOfTFs<1)         { Alert("AlertNrOfTFs must have positive 
number.");    return(0); }
   else if (AlertNrOfTFs>MAX_PH_PS) { Alert("AlertNrOfTFs number is too 
high.");           return(0); }

   DeleteObjects();
   initPeriods();

   bool AlertDone = false;

   for (i=0;i<MAX_PH_PS;i++)
   {
     for (int k=0;k<MAX_PH_PS;k++)
     {
        p[k][i] = PH_OP_NONE;
     }
     maxP[i]=0;
     AlertP[i]=false;
     if (CheckTimeAlertPeriod[i]==0) CheckTimeAlertPeriod[i] = 
iTime(NULL,periodTF[i],0);

   }

   bool barNow = false;

   Comment("\n");

   for (i=0; i<MaxNumberOfBars; i++)
   {
      for (int j=PH_MAX_PERIODS;j>=0;j--)  // start at highest tf
      {
         if (periodUse[j]==true && maxP[j] < periodMaxLines[j] && period <= 
periodTF[j])
         {
            doContinue = false;
            sSR = 
showStochasticRoute(periodTF[j],i,false,periodK[j],periodD[j],periodSlowing[j],periodUseSignal[j],periodUseOBOS[j],periodOBOSSell[j],periodOBOSBuy[j]);
            if (UseHighestTFforTrend==true)
            {
               // first time: determine right highest TF as identifier of 
trend
               if (maxP[j] < 1 && periodTF[j] == HighestTFforTrend && 
highestTrend == PH_OP_NONE && sSR!=NEGATIVE_RESULT)
               {
                  OldestTime   = iTime(NULL,periodTF[j],i);
                  highestTrend = sSR;
               }
               // if tf is equal or higher, then just go on
               if (periodTF[j] >= HighestTFforTrend)
               {
                  if (sSR!=NEGATIVE_RESULT) doContinue = true;
               }
               else if (periodTF[j] < HighestTFforTrend)
               {
                  if (highestTrend != PH_OP_NONE && sSR == highestTrend && 
OnlyShowTrend==true && iTime(NULL,periodTF[j],i) >= OldestTime)
                  {
                     doContinue = true;
                  }
                  if (highestTrend != PH_OP_NONE && sSR != highestTrend && 
OnlyShowTrend==false && iTime(NULL,periodTF[j],i) >= OldestTime)
                  {
                     doContinue = true;
                  }
               }
            }
            else if (UseHighestTFforTrend==false && sSR!=NEGATIVE_RESULT)
            {
               doContinue = true;
            }
            if (doContinue)
            {
               
CreateObjects(givePeriodStr(periodTF[j],periodK[j],periodD[j],periodSlowing[j])+"["+i+"]",periodWidth[j][0],periodStyle[j][0]);
               if (periodTF[j] == HighestTFforTrend && highestTrend == 
PH_OP_NONE) highestTrend = sSR;
               if (maxP[j] < 1 && 
0==iBarShift(NULL,periodTF[j],iTime(NULL,periodTF[j],i),true))
               {
                  if      (sSR==PH_OP_BUY)  { colr = periodColorUp[j][1]; }
                  else if (sSR==PH_OP_SELL) { colr = periodColorDn[j][1]; }
               }
               else
               {
                  if      (sSR==PH_OP_BUY)  { colr = periodColorUp[j][0]; }
                  else if (sSR==PH_OP_SELL) { colr = periodColorDn[j][0]; }
               }
               if (maxP[j] < 1 && 
CheckTimeAlertPeriod[j]!=iTime(NULL,periodTF[j],0))  // only most recent
               {
                  if 
(0==iBarShift(NULL,periodTF[j],iTime(NULL,periodTF[j],i),true)) barNow = 
true;
                  if      (sSR==PH_OP_BUY)  { colr = periodColorUp[j][0]; }
                  else if (sSR==PH_OP_SELL) { colr = periodColorDn[j][0]; }
                  CheckTimeAlertPeriod[j] = iTime(NULL,periodTF[j],0);
                  if (periodUseAlert[j]) AlertP[j] = true;

               }
               if (showArrows)
               {
                  
ObjectSet(givePeriodStr(periodTF[j],periodK[j],periodD[j],periodSlowing[j])+"["+i+"]",OBJPROP_COLOR,colr);
                  
ObjectSet(givePeriodStr(periodTF[j],periodK[j],periodD[j],periodSlowing[j])+"["+i+"]",OBJPROP_TIME1,iTime(NULL,periodTF[j],i+ShiftLine));
                  if (sSR==PH_OP_BUY)
                  {
                     
ObjectSet(givePeriodStr(periodTF[j],periodK[j],periodD[j],periodSlowing[j])+"["+i+"]",OBJPROP_PRICE1,iLow(NULL,periodTF[j],i+ShiftLine)-1-(j+1)*Point);
                     
ObjectSet(givePeriodStr(periodTF[j],periodK[j],periodD[j],periodSlowing[j])+"["+i+"]",OBJPROP_ARROWCODE,periodArrowUp[j]);
                  }
                  else
                  {
                     
ObjectSet(givePeriodStr(periodTF[j],periodK[j],periodD[j],periodSlowing[j])+"["+i+"]",OBJPROP_PRICE1,iHigh(NULL,periodTF[j],i+ShiftLine)+1+(j+1)*Point);
                     
ObjectSet(givePeriodStr(periodTF[j],periodK[j],periodD[j],periodSlowing[j])+"["+i+"]",OBJPROP_ARROWCODE,periodArrowDn[j]);
                  }
               }
               else
               {
                  
ObjectSet(givePeriodStr(periodTF[j],periodK[j],periodD[j],periodSlowing[j])+"["+i+"]",OBJPROP_COLOR,colr);
                  
ObjectSet(givePeriodStr(periodTF[j],periodK[j],periodD[j],periodSlowing[j])+"["+i+"]",OBJPROP_TIME1,iTime(NULL,periodTF[j],i+ShiftLine));
               }

               if (maxP[j] < MAX_PH_PS) p[j][maxP[j]] = sSR;
               maxP[j]++;
            }
         }
      }
   }

   if (!AlertDone)
   {
      bool isAlert = false;
      for (int g=0;g<MAX_PH_PS;g++)  // determine the sets of TF's and 
trends/cross over to give an Alert
      {
         if (AlertP[g] && barNow) { isAlert=true; break; }
      }
      if (isAlert)
      {
         for (g=0;g<MAX_PH_PS;g++)  // determine the sets of TF's and 
trends/cross over to give an Alert
         {
            AlertDone = 
giveAlert(p[0][g],p[1][g],p[2][g],p[3][g],p[4][g],p[5][g],p[6][g],p[7][g],p[8][g]);
            if (AlertDone) return (0);
         }
      }
   }
}
bool giveAlert(int p1,int p2,int p3,int p4,int p5,int p6,int p7,int p8,int 
p9)
{
   string AlertStringBuy  = "";
   string AlertStringSell = "";
   int totalBuys  = 0;
   int totalSells = 0;
   bool   gaveAlert = false;

   if (p1!=PH_OP_NONE && AlertPeriod1)
   {
      if (p1 == PH_OP_BUY) { AlertStringBuy  = AlertStringBuy  + "-(UP: "   
+ givePerStr(period1) + ")-"; totalBuys++;  }
      else                 { AlertStringSell = AlertStringSell + "-(DOWN: " 
+ givePerStr(period1) + ")-"; totalSells++; }
   }
   if (p2!=PH_OP_NONE && AlertPeriod2)
   {
      if (p2 == PH_OP_BUY) { AlertStringBuy  = AlertStringBuy  + "-(UP: "   
+ givePerStr(period2) + ")-"; totalBuys++;  }
      else                 { AlertStringSell = AlertStringSell + "-(DOWN: " 
+ givePerStr(period2) + ")-"; totalSells++; }
   }
   if (p3!=PH_OP_NONE && AlertPeriod3)
   {
      if (p3 == PH_OP_BUY) { AlertStringBuy  = AlertStringBuy  + "-(UP: "   
+ givePerStr(period3) + ")-"; totalBuys++;  }
      else                 { AlertStringSell = AlertStringSell + "-(DOWN: " 
+ givePerStr(period3) + ")-"; totalSells++; }
   }
   if (p4!=PH_OP_NONE && AlertPeriod4)
   {
      if (p4 == PH_OP_BUY) { AlertStringBuy  = AlertStringBuy  + "-(UP: "   
+ givePerStr(period4) + ")-"; totalBuys++;  }
      else                 { AlertStringSell = AlertStringSell + "-(DOWN: " 
+ givePerStr(period4) + ")-"; totalSells++; }
   }
   if (p5!=PH_OP_NONE && AlertPeriod5)
   {
      if (p5 == PH_OP_BUY) { AlertStringBuy  = AlertStringBuy  + "-(UP: "   
+ givePerStr(period5) + ")-"; totalBuys++;  }
      else                 { AlertStringSell = AlertStringSell + "-(DOWN: " 
+ givePerStr(period5) + ")-"; totalSells++; }
   }
   if (p6!=PH_OP_NONE && AlertPeriod6)
   {
      if (p6 == PH_OP_BUY) { AlertStringBuy  = AlertStringBuy  + "-(UP: "   
+ givePerStr(period6) + ")-"; totalBuys++;  }
      else                 { AlertStringSell = AlertStringSell + "-(DOWN: " 
+ givePerStr(period6) + ")-"; totalSells++; }
   }
   if (p7!=PH_OP_NONE && AlertPeriod7)
   {
      if (p7 == PH_OP_BUY) { AlertStringBuy  = AlertStringBuy  + "-(UP: "   
+ givePerStr(period7) + ")-"; totalBuys++;  }
      else                 { AlertStringSell = AlertStringSell + "-(DOWN: " 
+ givePerStr(period7) + ")-"; totalSells++; }
   }
   if (p8!=PH_OP_NONE && AlertPeriod8)
   {
      if (p8 == PH_OP_BUY) { AlertStringBuy  = AlertStringBuy  + "-(UP: "   
+ givePerStr(period8) + ")-"; totalBuys++;  }
      else                 { AlertStringSell = AlertStringSell + "-(DOWN: " 
+ givePerStr(period8) + ")-"; totalSells++; }
   }
   if (p9!=PH_OP_NONE && AlertPeriod9)
   {
      if (p9 == PH_OP_BUY) { AlertStringBuy  = AlertStringBuy  + "-(UP: "   
+ givePerStr(period9) + ")-"; totalBuys++;  }
      else                 { AlertStringSell = AlertStringSell + "-(DOWN: " 
+ givePerStr(period9) + ")-"; totalSells++; }
   }

   if (totalBuys==AlertNrOfTFs || totalSells==AlertNrOfTFs)
   {
      string tfs = " Timeframe";
      if (AlertNrOfTFs > 1) tfs = tfs + "s";
      string AlertString = Symbol();
      if (totalBuys==AlertNrOfTFs && totalSells==AlertNrOfTFs)
      {
         AlertString = AlertString + "- Possible BUY: " + AlertNrOfTFs + tfs 
+ ": " + AlertStringBuy;
         if (AlertOn)  Alert(AlertString);
         if (SendMailOn) sendMail(AlertString);
         AlertString = Symbol();
         AlertString = AlertString + "- Possible SELL: " + AlertNrOfTFs + 
tfs + ": " + AlertStringSell;
         if (AlertOn)  Alert(AlertString);
         if (SendMailOn) sendMail(AlertString);
         gaveAlert = true;
      }
      else if (totalBuys==AlertNrOfTFs)
      {
         AlertString = AlertString + "- Possible BUY: " + AlertNrOfTFs + tfs 
+ ": " + AlertStringBuy;
         if (AlertOn)  Alert(AlertString);
         if (SendMailOn) sendMail(AlertString);
         gaveAlert = true;
      }
      else if (totalSells==AlertNrOfTFs)
      {
         AlertString = AlertString + "- Possible SELL: " + AlertNrOfTFs + 
tfs + ": " + AlertStringSell;
         if (AlertOn)  Alert(AlertString);
         if (SendMailOn) sendMail(AlertString);
         gaveAlert = true;
      }
   }
   return (gaveAlert);
}


void sendMail(string PeriodDirection)
{
   SendMail("StochCrossOver",PeriodDirection);
}


int initPeriods()
{
   periodTF[0]           = period1;
   periodUse[0]          = usePeriod1;
   periodColorUp[0][0]   = UpColor1;
   periodColorDn[0][0]   = DownColor1;
   periodColorUp[0][1]   = NoneCloseUpColor1;
   periodColorDn[0][1]   = NoneCloseDownColor1;
   periodStyle[0][0]     = LineStyle1;
   periodWidth[0][0]     = LineWidth1;
   periodStyle[0][1]     = 1;
   periodWidth[0][1]     = 1;
   periodUseSignal[0]    = useSignalCrossOver1;
   periodUseOBOS[0]      = useOBOSCrossOver1;
   periodOBOSSell[0]     = OverboughtNumber1;
   periodOBOSBuy[0]      = OversoldNumber1;
   periodK[0]            = KPeriod1;
   periodD[0]            = DPeriod1;
   periodSlowing[0]      = Slowing1;
   periodMaxLines[0]     = MaxNumberOfLinesP1;
   periodArrowUp[0]      = ArrowUp1;
   periodArrowDn[0]      = ArrowDown1;
   periodUseAlert[0]     = AlertPeriod1;

   periodTF[1]           = period2;
   periodUse[1]          = usePeriod2;
   periodColorUp[1][0]   = UpColor2;
   periodColorDn[1][0]   = DownColor2;
   periodColorUp[1][1]   = NoneCloseUpColor2;
   periodColorDn[1][1]   = NoneCloseDownColor2;
   periodStyle[1][0]     = LineStyle2;
   periodWidth[1][0]     = LineWidth2;
   periodStyle[1][1]     = 1;
   periodWidth[1][1]     = 1;
   periodUseSignal[1]    = useSignalCrossOver2;
   periodUseOBOS[1]      = useOBOSCrossOver2;
   periodOBOSSell[1]     = OverboughtNumber2;
   periodOBOSBuy[1]      = OversoldNumber2;
   periodK[1]            = KPeriod2;
   periodD[1]            = DPeriod2;
   periodSlowing[1]      = Slowing2;
   periodMaxLines[1]     = MaxNumberOfLinesP2;
   periodArrowUp[1]      = ArrowUp2;
   periodArrowDn[1]      = ArrowDown2;
   periodUseAlert[1]     = AlertPeriod2;

   periodTF[2]           = period3;
   periodUse[2]          = usePeriod3;
   periodColorUp[2][0]   = UpColor3;
   periodColorDn[2][0]   = DownColor3;
   periodColorUp[2][1]   = NoneCloseUpColor3;
   periodColorDn[2][1]   = NoneCloseDownColor3;
   periodStyle[2][0]     = LineStyle3;
   periodWidth[2][0]     = LineWidth3;
   periodStyle[2][1]     = 1;
   periodWidth[2][1]     = 1;
   periodUseSignal[2]    = useSignalCrossOver3;
   periodUseOBOS[2]      = useOBOSCrossOver3;
   periodOBOSSell[2]     = OverboughtNumber3;
   periodOBOSBuy[2]      = OversoldNumber3;
   periodK[2]            = KPeriod3;
   periodD[2]            = DPeriod3;
   periodSlowing[2]      = Slowing3;
   periodMaxLines[2]     = MaxNumberOfLinesP3;
   periodArrowUp[2]      = ArrowUp3;
   periodArrowDn[2]      = ArrowDown3;
   periodUseAlert[2]     = AlertPeriod3;

   periodTF[3]           = period4;
   periodUse[3]          = usePeriod4;
   periodColorUp[3][0]   = UpColor4;
   periodColorDn[3][0]   = DownColor4;
   periodColorUp[3][1]   = NoneCloseUpColor4;
   periodColorDn[3][1]   = NoneCloseDownColor4;
   periodStyle[3][0]     = LineStyle4;
   periodWidth[3][0]     = LineWidth4;
   periodStyle[3][1]     = 1;
   periodWidth[3][1]     = 1;
   periodUseSignal[3]    = useSignalCrossOver4;
   periodUseOBOS[3]      = useOBOSCrossOver4;
   periodOBOSSell[3]     = OverboughtNumber4;
   periodOBOSBuy[3]      = OversoldNumber4;
   periodK[3]            = KPeriod4;
   periodD[3]            = DPeriod4;
   periodSlowing[3]      = Slowing4;
   periodMaxLines[3]     = MaxNumberOfLinesP4;
   periodArrowUp[3]      = ArrowUp4;
   periodArrowDn[3]      = ArrowDown4;
   periodUseAlert[3]     = AlertPeriod4;

   periodTF[4]           = period5;
   periodUse[4]          = usePeriod5;
   periodColorUp[4][0]   = UpColor5;
   periodColorDn[4][0]   = DownColor5;
   periodColorUp[4][1]   = NoneCloseUpColor5;
   periodColorDn[4][1]   = NoneCloseDownColor5;
   periodStyle[4][0]     = LineStyle5;
   periodWidth[4][0]     = LineWidth5;
   periodStyle[4][1]     = 1;
   periodWidth[4][1]     = 1;
   periodUseSignal[4]    = useSignalCrossOver5;
   periodUseOBOS[4]      = useOBOSCrossOver5;
   periodOBOSSell[4]     = OverboughtNumber5;
   periodOBOSBuy[4]      = OversoldNumber5;
   periodK[4]            = KPeriod5;
   periodD[4]            = DPeriod5;
   periodSlowing[4]      = Slowing5;
   periodMaxLines[4]     = MaxNumberOfLinesP5;
   periodArrowUp[4]      = ArrowUp5;
   periodArrowDn[4]      = ArrowDown5;
   periodUseAlert[4]     = AlertPeriod5;

   periodTF[5]           = period6;
   periodUse[5]          = usePeriod6;
   periodColorUp[5][0]   = UpColor6;
   periodColorDn[5][0]   = DownColor6;
   periodColorUp[5][1]   = NoneCloseUpColor6;
   periodColorDn[5][1]   = NoneCloseDownColor6;
   periodStyle[5][0]     = LineStyle6;
   periodWidth[5][0]     = LineWidth6;
   periodStyle[5][1]     = 1;
   periodWidth[5][1]     = 1;
   periodUseSignal[5]    = useSignalCrossOver6;
   periodUseOBOS[5]      = useOBOSCrossOver6;
   periodOBOSSell[5]     = OverboughtNumber6;
   periodOBOSBuy[5]      = OversoldNumber6;
   periodK[5]            = KPeriod6;
   periodD[5]            = DPeriod6;
   periodSlowing[5]      = Slowing6;
   periodMaxLines[5]     = MaxNumberOfLinesP6;
   periodArrowUp[5]      = ArrowUp6;
   periodArrowDn[5]      = ArrowDown6;
   periodUseAlert[5]     = AlertPeriod6;

   periodTF[6]           = period7;
   periodUse[6]          = usePeriod7;
   periodColorUp[6][0]   = UpColor7;
   periodColorDn[6][0]   = DownColor7;
   periodColorUp[6][1]   = NoneCloseUpColor7;
   periodColorDn[6][1]   = NoneCloseDownColor7;
   periodStyle[6][0]     = LineStyle7;
   periodWidth[6][0]     = LineWidth7;
   periodStyle[6][1]     = 1;
   periodWidth[6][1]     = 1;
   periodUseSignal[6]    = useSignalCrossOver7;
   periodUseOBOS[6]      = useOBOSCrossOver7;
   periodOBOSSell[6]     = OverboughtNumber7;
   periodOBOSBuy[6]      = OversoldNumber7;
   periodK[6]            = KPeriod7;
   periodD[6]            = DPeriod7;
   periodSlowing[6]      = Slowing7;
   periodMaxLines[6]     = MaxNumberOfLinesP7;
   periodArrowUp[6]      = ArrowUp7;
   periodArrowDn[6]      = ArrowDown7;
   periodUseAlert[6]     = AlertPeriod7;

   periodTF[7]           = period8;
   periodUse[7]          = usePeriod8;
   periodColorUp[7][0]   = UpColor8;
   periodColorDn[7][0]   = DownColor8;
   periodColorUp[7][1]   = NoneCloseUpColor8;
   periodColorDn[7][1]   = NoneCloseDownColor8;
   periodStyle[7][0]     = LineStyle8;
   periodWidth[7][0]     = LineWidth8;
   periodStyle[7][1]     = 1;
   periodWidth[7][1]     = 1;
   periodUseSignal[7]    = useSignalCrossOver8;
   periodUseOBOS[7]      = useOBOSCrossOver8;
   periodOBOSSell[7]     = OverboughtNumber8;
   periodOBOSBuy[7]      = OversoldNumber8;
   periodK[7]            = KPeriod8;
   periodD[7]            = DPeriod8;
   periodSlowing[7]      = Slowing8;
   periodMaxLines[7]     = MaxNumberOfLinesP8;
   periodArrowUp[7]      = ArrowUp8;
   periodArrowDn[7]      = ArrowDown8;
   periodUseAlert[7]     = AlertPeriod8;

   periodTF[8]           = period9;
   periodUse[8]          = usePeriod9;
   periodColorUp[8][0]   = UpColor9;
   periodColorDn[8][0]   = DownColor9;
   periodColorUp[8][1]   = NoneCloseUpColor9;
   periodColorDn[8][1]   = NoneCloseDownColor9;
   periodStyle[8][0]     = LineStyle9;
   periodWidth[8][0]     = LineWidth9;
   periodStyle[8][1]     = 1;
   periodWidth[8][1]     = 1;
   periodUseSignal[8]    = useSignalCrossOver9;
   periodUseOBOS[8]      = useOBOSCrossOver9;
   periodOBOSSell[8]     = OverboughtNumber9;
   periodOBOSBuy[8]      = OversoldNumber9;
   periodK[8]            = KPeriod9;
   periodD[8]            = DPeriod9;
   periodSlowing[8]      = Slowing9;
   periodMaxLines[8]     = MaxNumberOfLinesP9;
   periodArrowUp[8]      = ArrowUp9;
   periodArrowDn[8]      = ArrowDown9;
   periodUseAlert[8]     = AlertPeriod9;
}


//+------------------------------------------------------------------+


