Stoch Crossing_001

Author: Copyright � 2005-07, Jason Robinson (jnrtrading)
Stoch Crossing_001

This script is a specialized trading tool designed for the MetaTrader platform to help traders identify specific momentum shifts in the market. It focuses on interpreting "Stochastic" oscillator data—a technical indicator used to determine if an asset is overbought or oversold—and translates those movements into visual signals and real-time notifications.

Core Functionality

The primary purpose of this script is to detect crossovers. In trading, a crossover occurs when two moving lines intersect each other. This script specifically monitors the relationship between the main "%K" line and the "%D" line of the Stochastic oscillator.

  • Buy Signals (Upward Momentum): When the %K line moves from below the %D line to above it, the script identifies a potential upward trend. It marks this on your chart with a specific arrow pointing upwards, placed just below the price candles.
  • Sell Signals (Downward Momentum): Conversely, when the %K line moves from above the %D line to below it, the script identifies a potential downward trend. It marks this with an arrow pointing downwards, placed just above the price candles.

Smart Visual Positioning

To ensure the signals are easy to read, the script does not simply place arrows in a static location. Instead, it calculates the "average range" of recent price movements (measuring the distance between highs and lows over the last 10 candles). It then uses this calculation to offset the arrows perfectly, ensuring they stay clear of the actual price bars while remaining close enough to provide context.

Customization Options

The script is highly flexible, allowing you to tailor its behavior to your specific trading style through several configurable settings:

  • Stochastic Parameters: You can adjust the core math of the indicator (the periods and smoothing methods) to match different timeframes or asset types.
  • Visual Variety: There are several different arrow styles available (such as thick, thin, hollow, round, or diagonal), allowing you to choose the visual representation that best fits your chart layout.
  • Notification System: The script is designed to keep you informed even when you aren't looking at the screen. It includes a robust alert system that can:
    • Trigger an immediate audible sound/pop-up alert on your trading platform.
    • Send a detailed email notification containing the specific price (Ask and Bid), the time of the signal, and the timeframe it occurred on.

How it Works in Real-Time

The script constantly scans every new candle that forms. It verifies three points of data to confirm a crossover: the current position of both lines, the position they were in on the previous candle, and a confirmation point to ensure the "cross" is valid and not just a momentary touch. Once confirmed, it executes the visual signal and, if enabled, broadcasts the alert to your device or inbox.

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
9 Views
0 Downloads
0 Favorites
Stoch Crossing_001
//+------------------------------------------------------------------+
//|                Stoch Crossing.mq4 modified from                  |
//+------------------------------------------------------------------+
//|                                         EMA-Crossover_Signal.mq4 |
//|         Copyright © 2005-07, Jason Robinson (jnrtrading)         |
//|                   http://www.jnrtading.co.uk                     |
//+------------------------------------------------------------------+

/*
  +------------------------------------------------------------------+
  | 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 DodgerBlue
#property indicator_width1 1
#property indicator_color2 Red
#property indicator_width2 1

extern string note1 = "Stochastic settings";
extern string note2 = "default = Stoch(14,3,3)";
extern int       KPeriod1     =  14;
extern int       DPeriod1     =  3;
extern int       Slowing1     =  3;
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=true;
extern string note15 = "---------------------------------- Try";
extern string note16 = "GBPJPY M15 chart Stoch(14,3,3)";

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, 159);
      SetIndexStyle(1,DRAW_ARROW);
      SetIndexArrow(1, 159);
   }

   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