Stoch Crossing_v2

Download script
Author: Copyright � 2005-07, Jason Robinson (jnrtrading)
Stoch Crossing_v2

This script is designed for traders using the MetaTrader 4 platform to simplify and highlight specific momentum shifts in market data. It focuses on a technical indicator known as the Stochastic Oscillator, which helps identify whether an asset is overbought or oversold and where price momentum might be shifting.

Core Functionality

The primary purpose of this tool is to detect "crosses" between two different lines of the Stochastic Oscillator (typically referred to as the %K and %D lines). When these two lines intersect, it often signals a potential change in market direction. Instead of forcing you to squint at small line movements on a busy chart, the script identifies these exact moments and marks them clearly with visual icons.

How the Logic Works

The script monitors the price action in real-time and performs the following steps:

  • Momentum Calculation: It calculates the Stochastic values based on user-defined periods (speed, slowing, and moving average methods).
  • Crossover Detection: The logic specifically looks for three conditions to confirm a "cross." It checks the current position of the lines, their previous positions, and their predicted next positions. This ensures that a signal is only generated when a definitive crossover occurs, rather than just a momentary touch.
  • Dynamic Visual Marking: When a crossover is detected:
    • Buy Signals: If the main line crosses upward over the signal line, the script places a visual arrow below the price candle.
    • Sell Signals: If the main line crosses downward under the signal line, it places a visual arrow above the price candle.
  • Smart Positioning: To ensure the icons are easy to see, the script calculates the "Range" (the average height of recent candles). It then places the arrows at a distance proportional to this range so that they do not overlap with the actual price bars.

User Alerts and Customization

Beyond just providing visual marks, the script includes several automated notification features:

  • Visual Variety: You can choose from various arrow styles (such as thick, thin, hollow, or different shapes) to suit your preferred chart aesthetics.
  • Real-Time Alerts: The script can trigger an immediate pop-up alert on your trading platform whenever a cross occurs.
  • Email Notifications: If enabled, the script can send an automated email containing the specific price (Bid/Ask), the time of the signal, and the asset name directly to your inbox.
  • Timeframe Awareness: The alerts are "smart"—they include the current timeframe (e.g., M15, H1, D1) in the message prefix, allowing you to manage multiple charts without getting confused about which signal belongs to which time period.

Summary for the User

In short, this script acts as an automated scout. It watches the complex mathematical crossovers of the Stochastic Oscillator for you and "pokes" you with a visual arrow and/or an alert the moment the momentum shifts, helping you identify potential entry or exit points more efficiently.

Price Data Components
Series array that contains open time of each bar
Indicators Used
Stochastic oscillator
Miscellaneous
Implements a curve of type %1It issuies visual alerts to the screenIt sends emails
19 Views
0 Downloads
0 Favorites
Stoch Crossing_v2
//+------------------------------------------------------------------+
//|            Stoch Crossing.mq4 modified from EMA-Crossover_Signal |
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| Allows you to enter two ema periods and it will then show you at |
//| Which point they crossed over. It is more usful on the shorter   |
//| periods that get obscured by the bars / candlesticks and when    |
//| the zoom level is out. Also allows you then to remove the emas   |
//| from the chart. (emas are initially set at 5 and 6)              |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2005-07, Jason Robinson (jnrtrading)"
#property link      "http://www.jnrtrading.co.uk/"
//----
#property indicator_chart_window
#property indicator_buffers 2
//----
#property indicator_color1 DarkGreen
#property indicator_width1 3
#property indicator_color2 Red
#property indicator_width2 3
//----
extern string note1="Stochastic settings";
extern string note2="default = Stoch(30,10,10)";
extern int       KPeriod1   =30;
extern int       DPeriod1   =10;
extern int       Slowing1   =10;
extern string note3="0=sma, 1=ema, 2=smma, 3=lwma";
extern int       MAMethod1 =0;
extern string note4="0=high/low, 1=close/close";
extern int       PriceField1= 1;
//----
extern string note5="--------------------------------------------";
extern string note6="Arrow Type";
extern string note7="0=Thick, 1=Thin, 2=Hollow, 3=Round";
extern string note8="4=Fractal, 5=Diagonal Thin";
extern string note9="6=Diagonal Thick, 7=Diagonal Hollow";
extern string note10="8=Thumb, 9=Finger";
extern int ArrowType=3;
extern string note11="--------------------------------------------";
extern string note12="turn on Alert = true; turn off = false";
extern bool AlertOn=true;
extern string note13="--------------------------------------------";
extern string note14="send Email Alert = true; turn off = false";
extern bool SendAnEmail=false;
extern string note15="---------------------------------- Try";
extern string note16="GBPJPY M15 chart Stoch(30,10,10)";
//----
double CrossUp[];
double CrossDown[];
//----
string AlertPrefix;
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
  string GetTimeFrameStr() 
  {
   switch(Period())
     {
      case 1 : string TimeFrameStr="M1"; break;
      case 5 : TimeFrameStr="M5"; break;
      case 15 : TimeFrameStr="M15"; break;
      case 30 : TimeFrameStr="M30"; break;
      case 60 : TimeFrameStr="H1"; break;
      case 240 : TimeFrameStr="H4"; break;
      case 1440 : TimeFrameStr="D1"; break;
      case 10080 : TimeFrameStr="W1"; break;
      case 43200 : TimeFrameStr="MN1"; break;
      default : TimeFrameStr=Period();
     }
   return(TimeFrameStr);
  }
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
//---- indicators
     if (ArrowType==0) 
     {
      SetIndexStyle(0,DRAW_ARROW);
      SetIndexArrow(0, 233);
      SetIndexStyle(1,DRAW_ARROW);
      SetIndexArrow(1, 234);
     }
     else if (ArrowType==1) 
     {
         SetIndexStyle(0,DRAW_ARROW);
         SetIndexArrow(0, 225);
         SetIndexStyle(1,DRAW_ARROW);
         SetIndexArrow(1, 226);
        }
        else if (ArrowType==2) 
        {
            SetIndexStyle(0,DRAW_ARROW);
            SetIndexArrow(0, 241);
            SetIndexStyle(1,DRAW_ARROW);
            SetIndexArrow(1, 242);
           }
           else if (ArrowType==3) 
           {
               SetIndexStyle(0,DRAW_ARROW);
               SetIndexArrow(0, 221);
               SetIndexStyle(1,DRAW_ARROW);
               SetIndexArrow(1, 222);
              }
              else if (ArrowType==4) 
              {
                  SetIndexStyle(0,DRAW_ARROW);
                  SetIndexArrow(0, 217);
                  SetIndexStyle(1,DRAW_ARROW);
                  SetIndexArrow(1, 218);
                 }
                 else if (ArrowType==5) 
                 {
                     SetIndexStyle(0,DRAW_ARROW);
                     SetIndexArrow(0, 228);
                     SetIndexStyle(1,DRAW_ARROW);
                     SetIndexArrow(1, 230);
                    }
                    else if (ArrowType==6) 
                    {
                        SetIndexStyle(0,DRAW_ARROW);
                        SetIndexArrow(0, 236);
                        SetIndexStyle(1,DRAW_ARROW);
                        SetIndexArrow(1, 238);
                       }
                       else if (ArrowType==7) 
                       {
                           SetIndexStyle(0,DRAW_ARROW);
                           SetIndexArrow(0, 246);
                           SetIndexStyle(1,DRAW_ARROW);
                           SetIndexArrow(1, 248);
                          }
                          else if (ArrowType==8) 
                          {
                              SetIndexStyle(0,DRAW_ARROW);
                              SetIndexArrow(0, 67);
                              SetIndexStyle(1,DRAW_ARROW);
                              SetIndexArrow(1, 68);
                             }
                             else if (ArrowType==9) 
                             {
                                 SetIndexStyle(0,DRAW_ARROW);
                                 SetIndexArrow(0, 71);
                                 SetIndexStyle(1,DRAW_ARROW);
                                 SetIndexArrow(1, 72);
                                }
   SetIndexBuffer(0, CrossUp);
   SetIndexBuffer(1, CrossDown);
   AlertPrefix=Symbol()+" ("+GetTimeFrameStr()+"):  ";
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
int deinit()
  {
//---- 
//----
   return(0);
  }
//+------------------------------------------------------------------+
bool NewBar()
  {
   static datetime lastbar;
   datetime curbar=Time[0];
   if(lastbar!=curbar)
     {
      lastbar=curbar;
      return(true);
     }
   else
     {
      return(false);
     }
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
  int start() 
  {
   int limit, i, counter;
   double stochastic1now, stochastic2now, stochastic1previous, stochastic2previous, stochastic1after, stochastic2after;
   double Range, AvgRange;
   int counted_bars=IndicatorCounted();
//---- check for possible errors
   if(counted_bars<0) return(-1);
//---- last counted bar will be recounted
   if(counted_bars>0) counted_bars--;
   limit=Bars-counted_bars;
     for(i=0; i<=limit; i++) 
     {
      counter=i;
      Range=0;
      AvgRange=0;
      for(counter=i ;counter<=i+9;counter++)
        {
         AvgRange=AvgRange+MathAbs(High[counter]-Low[counter]);
        }
      Range=AvgRange/10;
      stochastic1now=iStochastic(NULL,0,KPeriod1,DPeriod1,Slowing1,MAMethod1,PriceField1,0,i);
      stochastic1previous=iStochastic(NULL,0,KPeriod1,DPeriod1,Slowing1,MAMethod1,PriceField1,0,i+1);
      stochastic1after=iStochastic(NULL,0,KPeriod1,DPeriod1,Slowing1,MAMethod1,PriceField1,0,i-1);
      stochastic2now=iStochastic(NULL,0,KPeriod1,DPeriod1,Slowing1,MAMethod1,PriceField1,1,i);
      stochastic2previous=iStochastic(NULL,0,KPeriod1,DPeriod1,Slowing1,MAMethod1,PriceField1,1,i+1);
      stochastic2after=iStochastic(NULL,0,KPeriod1,DPeriod1,Slowing1,MAMethod1,PriceField1,1,i-1);
//----
        if ((stochastic1now > stochastic2now) && (stochastic1previous < stochastic2previous) && (stochastic1after > stochastic2after)) 
        {
         CrossUp[i]=Low[i] - Range*1.5;
           if (AlertOn && NewBar()) 
           {
            Alert(AlertPrefix+"Stoch ("+KPeriod1+","+DPeriod1+","+Slowing1+") %K crosses UP %D\nBUY signal @ Ask = ",Ask,"; Bid = ",Bid,"\nDate & Time = ",TimeToStr(CurTime(),TIME_DATE)," ",TimeHour(CurTime()),":",TimeMinute(CurTime()));
           }
           if (SendAnEmail && NewBar()) 
           {
            SendMail(AlertPrefix,"Stoch ("+KPeriod1+","+DPeriod1+","+Slowing1+") %K crosses UP %D\nBUY signal @ Ask = "+DoubleToStr(Ask,4)+", Bid = "+DoubleToStr(Bid,4)+", Date & Time = "+TimeToStr(CurTime(),TIME_DATE)+" "+TimeHour(CurTime())+":"+TimeMinute(CurTime()));
           }
        }
        if ((stochastic1now < stochastic2now) && (stochastic1previous > stochastic2previous) && (stochastic1after < stochastic2after)) 
        {
         CrossDown[i]=High[i] + Range*1.5;
           if (AlertOn && NewBar())
           {
            Alert(AlertPrefix+"Stoch ("+KPeriod1+","+DPeriod1+","+Slowing1+") %K crosses DOWN %D\nSELL signal @ Ask = ",Ask,"; Bid = ",Bid,"\nDate & Time = ",TimeToStr(CurTime(),TIME_DATE)," ",TimeHour(CurTime()),":",TimeMinute(CurTime()));
           }
           if (SendAnEmail && NewBar()) 
           {
            SendMail(AlertPrefix,"Stoch ("+KPeriod1+","+DPeriod1+","+Slowing1+") %K crosses DOWN %D\nSELL signal @ Ask = "+DoubleToStr(Ask,4)+", Bid = "+DoubleToStr(Bid,4)+", Date & Time = "+TimeToStr(CurTime(),TIME_DATE)+" "+TimeHour(CurTime())+":"+TimeMinute(CurTime()));
           }
        }
     }
   return(0);
  }
//+------------------------------------------------------------------+

Comments