Overview of the Parabolic Alert System
This script is designed to track price trends and provide real-time notifications when the market momentum shifts. It uses a dynamic "Parabolic" logic—a common method in trading used to identify whether a market is currently trending upward or downward and where the potential turning point might be.
Core Logic and Behavior
1. Trend Tracking (The Parabolic Movement) The system constantly monitors price action to determine the direction of the trend. It calculates a trailing value that follows the price.
- In an upward trend, the indicator looks for new highs to "push" its calculation forward.
- In a downward trend, it looks for new lows.
The script also incorporates a "step" and a "maximum" limit. As the trend continues without a reversal, the gap between the price and the indicator narrows progressively. This simulates an accelerating movement, helping traders see where a trend might be becoming overextended.
2. Identifying Reversals The primary job of this script is to detect "reversals"—the moment when the price breaks through the calculated parabolic line in the opposite direction of the current trend.
- If the market is trending up and the price drops below the indicator's level, the script recognizes a Sell signal.
- If the market is trending down and the price rises above the indicator's level, it recognizes a Buy signal.
3. Automatic State Management The script is "self-aware" regarding its history. Once a reversal is detected, it saves the data from that specific moment (the high/low prices and the exact point of reversal) to use as the new starting point for the next trend calculation. This ensures that the indicator remains smooth and accurate as it transitions from one trend to another.
4. Real-Time Alerts When a reversal is confirmed on the very latest piece of price data (the "live" bar), the script triggers several notifications based on your preferences:
- Audio Alerts: It can play specific sound files (like "thunder" or "crash") to grab your attention immediately.
- Visual Comments: It prints a text notification directly on the trading chart, displaying whether it is a Buy or Sell alert along with the current chart time.
- Email Notifications: If enabled, the script can automatically send an email to your registered account. This email includes vital trade details such as the signal type, the current Ask/Bid prices, the date, time, and the specific currency pair/timeframe being monitored.
Summary for the User
Think of this tool as a sophisticated "tripwire." It follows the trend like a shadow; when the price finally crosses over that shadow in the wrong direction, the "tripwire" snaps, triggering an alarm to let you know that the trend may have officially flipped.
//+------------------------------------------------------------------+
//| Parabolic_Alert.mq4 |
//| Original file name: Parabolic.mq4 |
//| Copyright © 2004, MetaQuotes Software Corp. |
//| http://www.metaquotes.net/ |
//| Modified to give audible alarm on reversal |
//| Modified by Jim Arner, Sr. |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2004, MetaQuotes Software Corp."
#property link "http://www.metaquotes.net/"
#property indicator_chart_window
#property indicator_buffers 1
#property indicator_color1 Aqua
//---- input parameters
extern double Step=0.02;
extern double Maximum=0.2;
extern bool Enable_Alert=false;
//---- buffers
double SarBuffer[];
//----
int save_lastreverse;
bool save_dirlong, save_dirshort;
double save_start;
double save_last_high;
double save_last_low;
double save_ep;
double save_sar;
extern bool mailalert = true;
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int init()
{
//---- indicators
IndicatorDigits(Digits);
SetIndexStyle(0,DRAW_ARROW);
SetIndexArrow(0,158);
SetIndexBuffer(0,SarBuffer);
//----
return(0);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void SaveLastReverse(int last,int dir_l,int dir_s,double start,double low,double high,double ep,double sar)
{
save_lastreverse=last;
save_dirlong=dir_l;
save_dirshort=dir_s;
save_start=start;
save_last_low=low;
save_last_high=high;
save_ep=ep;
save_sar=sar;
}
//+------------------------------------------------------------------+
//| Parabolic Sell And Reverse system |
//+------------------------------------------------------------------+
int start()
{
static bool first=true;
bool dirlong, dirshort;
double start,last_high,last_low;
double ep,sar,price_low,price_high,price;
int i,counted_bars=IndicatorCounted();
string TradeTime;
//----
if(Bars<3) return(0);
//---- initial settings
i=Bars-2;
if(counted_bars==0 || first)
{
first=true;
dirlong=true;
dirshort=true;
start=Step;
last_high=-10000000.0;
last_low=10000000.0;
while(i>0)
{
save_lastreverse=i;
price_low=Low[i];
if(last_low>price_low) last_low=price_low;
price_high=High[i];
if(last_high<price_high) last_high=price_high;
if(price_high>High[i+1] && price_low>Low[i+1]) break;
if(price_high<High[i+1] && price_low<Low[i+1]) { dirlong=false; break; }
i--;
}
//---- initial zero
int k=i;
while(k<Bars)
{
SarBuffer[k]=0.0;
k++;
}
//---- check further
if(dirlong) { SarBuffer[i]=Low[i+1]; ep=High[i]; }
if(dirshort) { SarBuffer[i]=High[i+1]; ep=Low[i]; }
i--;
}
else
{
i=save_lastreverse+1;
start=save_start;
dirlong=save_dirlong;
dirshort=save_dirshort;
last_high=save_last_high;
last_low=save_last_low;
ep=save_ep;
sar=save_sar;
}
//----
while(i>=0)
{
price_low=Low[i];
price_high=High[i];
//--- check for reverse
if(dirlong==true && price_low<SarBuffer[i+1])
{
// Print("Section 1 Code executing"," I= ",i," DirLong= ",dirlong," DirShort= ",dirshort);
SaveLastReverse(i,true,false,start,price_low,last_high,ep,sar);
start=Step; dirlong=false; dirshort=true;
// Comment("I= ",i);
if(Enable_Alert==true)
{
if (i==0)
{
PlaySound("gbpusd crash!.wav");
TradeTime = TimeToStr(CurTime(),TIME_SECONDS);
Comment("\nSell Alert","\nChart Time= ", TradeTime);
if (mailalert) SendMail("Parabolic Alert", "Buy signal at Ask="+Ask+", Bid="+Bid+", Date="+TimeToStr(CurTime(),TIME_DATE)+" "+TimeHour(CurTime())+":"+TimeMinute(CurTime())+" Symbol="+Symbol()+" Period="+Period());
}
}
ep=price_low; last_low=price_low;
SarBuffer[i]=last_high;
i--;
continue;
}
if(dirshort==true && price_high>SarBuffer[i+1])
{
// Print("Section 2 Code executing"," I= ",i," DirLong= ",dirlong," DirShort= ",dirshort);
SaveLastReverse(i,false,true,start,last_low,price_high,ep,sar);
start=Step; dirlong=true; dirshort=false;
// Comment("I= ",i);
if(Enable_Alert==true)
{
if (i==0)
{
PlaySound("thunder_1.wav");
TradeTime = TimeToStr(CurTime(),TIME_SECONDS);
Comment("\nBuy Alert","\nChart Time= ", TradeTime);
if (mailalert) SendMail("Parabolic Alert", "Buy signal at Ask="+Ask+", Bid="+Bid+", Date="+TimeToStr(CurTime(),TIME_DATE)+" "+TimeHour(CurTime())+":"+TimeMinute(CurTime())+" Symbol="+Symbol()+" Period="+Period());
}
}
ep=price_high; last_high=price_high;
SarBuffer[i]=last_low;
i--;
continue;
}
//---
price=SarBuffer[i+1];
sar=price+start*(ep-price);
if(dirlong)
{
/*
Comment("DirLong","\nI= ",i,"\nDirL ",dirlong,"\nDirS ",dirshort,
"\nStart= ",start,"\nLow= ",last_low,"\nHigh= ",last_high,
"\nEP= ",ep,"\nSAR= ",sar,"\nMinute= ",Minute());
*/
// Print("Section 3 Code executing"," I= ",i," DirLong= ",dirlong," DirShort= ",dirshort);
if(ep<price_high && (start+Step)<=Maximum) start+=Step;
if(price_high<High[i+1] && i==Bars-2) sar=SarBuffer[i+1];
price=Low[i+1];
if(sar>price) sar=price;
price=Low[i+2];
if(sar>price) sar=price;
if(sar>price_low)
{
SaveLastReverse(i,true,false,start,price_low,last_high,ep,sar);
start=Step; dirlong=false; dirshort=true; ep=price_low;
last_low=price_low;
SarBuffer[i]=last_high;
i--;
/*
if (i == 0)
{
Print("Section 3a Code executing"," I= ",i," DirLong= ",dirlong," DirShort= ",dirshort);
}
*/
if (dirshort && i == 0)
{
PlaySound("thunder_1.wav");
TradeTime = TimeToStr(CurTime(),TIME_SECONDS);
Comment("\nSell Alert","\nChart Time= ", TradeTime);
}
continue;
}
if(ep<price_high) { last_high=price_high; ep=price_high; }
}
if(dirshort)
{
/*
Comment("DirShort","\nI= ",i,"\nDirL ",dirlong,"\nDirS ",dirshort,
"\nStart= ",start,"\nLow= ",last_low,"\nHigh= ",last_high,
"\nEP= ",ep,"\nSAR= ",sar,"\nMinute= ",Minute());
*/
// Print("Section 4 Code executing"," I= ",i," DirLong= ",dirlong," DirShort= ",dirshort);
if(ep>price_low && (start+Step)<=Maximum) start+=Step;
if(price_low<Low[i+1] && i==Bars-2) sar=SarBuffer[i+1];
price=High[i+1];
if(sar<price) sar=price;
price=High[i+2];
if(sar<price) sar=price;
if(sar<price_high)
{
SaveLastReverse(i,false,true,start,last_low,price_high,ep,sar);
start=Step; dirlong=true; dirshort=false; ep=price_high;
last_high=price_high;
SarBuffer[i]=last_low;
i--;
/*
if (i == 0)
{
Print("Section 4a Code executing"," I= ",i," DirLong= ",dirlong," DirShort= ",dirshort);
}
*/
if (dirlong && i == 0)
{
PlaySound("thunder_1.wav");
TradeTime = TimeToStr(CurTime(),TIME_SECONDS);
Comment("\nBuy Alert","\nChart Time= ", TradeTime);
}
continue;
}
if(ep>price_low) { last_low=price_low; ep=price_low; }
}
SarBuffer[i]=sar;
i--;
}
// sar=SarBuffer[0];
// price=iSAR(NULL,0,Step,Maximum,0);
// if(sar!=price) Print("custom=",sar," SAR=",price," counted=",counted_bars);
// if(sar==price) Print("custom=",sar," SAR=",price," counted=",counted_bars);
//----
return(0);
}
//+------------------------------------------------------------------+
Comments