Stoch Crossing
Download scriptThis script is designed as a technical analysis tool for the MetaTrader 4 platform. It automates the identification of specific momentum shifts by monitoring the relationship between two different lines on a Stochastic Oscillator.
Core Logic and Functionality
The primary purpose of this tool is to detect "crosses" between two components of the Stochastic indicator: the %K line (which represents current price momentum) and the %D line (which acts as a smoothed moving average of the %K line).
When these two lines intersect, it suggests a potential change in market direction. The script monitors these movements and provides visual and audible feedback to the trader.
How the Script Works
1. Momentum Monitoring The tool constantly calculates the values for both the %K and %D lines based on user-defined settings (such as periods and moving average types). It looks at three specific points in time: the current bar, the previous bar, and the "after" bar to confirm that a definitive crossover has actually occurred rather than just a momentary touch.
2. Signal Detection
- Buy Signals: When the %K line crosses from below to above the %D line, the script identifies an upward momentum shift.
- Sell Signals: When the %K line crosses from above to below the %D line, the script identifies a downward momentum shift.
3. Visual Execution To help traders see these signals clearly on their charts, the script places distinct visual markers (arrows) at the exact moment a crossover is confirmed:
- Buy Arrows are placed below the current price candle.
- Sell Arrows are placed above the current price candle. The script also calculates the "Range" of the recent price action to ensure these arrows are placed at a consistent distance from the candles, keeping the chart clean and readable.
4. Notifications and Alerts The script is equipped with a multi-layered notification system to ensure traders don't miss important movements:
- On-Screen Alerts: If enabled, the script will trigger a pop-up alert window on the trading platform showing the signal type (Buy/Sell), the current price, and the specific time of the cross.
- Email Notifications: The script can be configured to send an automated email with these same details directly to the user’s connected email account.
- Timeframe Identification: Every alert automatically includes a prefix identifying which timeframe (e.g., M15, H1, D1) the signal occurred on, allowing for easier multi-chart monitoring.
Customization Options
The tool is highly configurable, allowing users to adjust:
- Stochastic Parameters: Modify the sensitivity and smoothing of the momentum lines.
- Visual Style: Choose between various arrow shapes (thin, thick, hollow, round, etc.) to suit different chart aesthetics.
- Alert Preferences: Toggle on/off the types of notifications desired (Screen Alerts vs. Emails).
//+------------------------------------------------------------------+
//| 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 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