sParabolic_Sub
Download scriptThis script is designed as a specialized technical analysis tool for the MetaTrader platform. It functions by calculating a dynamic trailing line on a price chart—similar to a Parabolic Stop and Reverse (SAR) indicator—but with specific logic tailored to identify trend reversals and momentum shifts.
Core Logic Overview
The primary goal of the script is to calculate a moving "support" or "resistance" level that follows the price action. It moves automatically based on how fast the market is trending, using two main factors:
- Step: The incremental speed at which the indicator accelerates as the price moves in a consistent direction.
- Maximum: The limit on how fast that acceleration can occur to prevent the indicator from becoming unrealistic or too erratic.
How it Functions
The script operates by analyzing past and current market data to determine whether the trend is currently "Long" (upward) or "Short" (downward).
1. Trend Detection and Acceleration
- When the price moves consistently upward, the indicator stays below the price, acting as a support line. It adjusts its position based on the highest points reached; if the market shows strength, the indicator accelerates its movement upward.
- Conversely, in a downward trend, the indicator stays above the price as a resistance line, adjusting based on the lowest points reached.
2. The Reversal Mechanism The script is constantly looking for a "break" in the current trend:
- Long to Short: If the price drops below the current calculated support level, the script recognizes a potential trend reversal. It then flips its logic, moving the indicator above the price to act as resistance.
- Short to Long: If the price climbs above the current resistance level, the script detects an upward shift and moves the indicator back below the price to act as support.
Whenever such a reversal occurs, the "Step" (acceleration) is reset to its original starting value to begin measuring the new trend from scratch.
Notifications and Alerts
Beyond just drawing lines on the chart, the script includes an automated monitoring system. It observes the relationship between the current closing price and the calculated indicator line:
- Buy Signals: If the closing price moves significantly above the support line (following a period of downward movement), the script triggers an alert.
- Sell Signals: If the closing price drops below the resistance line (following a period of upward movement), the script triggers an alert.
The script is programmed to ensure it only checks for these signals once per candle, preventing multiple alerts from firing on the same price movement.
//+------------------------------------------------------------------+
//| Parabolic Sub.mq4 |
//| Copyright © 2004, MetaQuotes Software Corp. |
//| http://www.metaquotes.net/ |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2004, MetaQuotes Software Corp."
#property link "http://www.metaquotes.net/"
//----
//Added Fix1 September 6, 2006 Advance Index if new bar by Stanley Fiala http://merlin4x.com
#property indicator_chart_window
#property indicator_buffers 1
#property indicator_color1 DodgerBlue
//---- input parameters
extern double Step = 0.02;
extern double Maximum = 0.2;
//---- buffers
double SarBuffer[];
//----
int save_lastreverse;
bool save_dirlong;
double save_start;
double save_last_high;
double save_last_low;
double save_ep;
double save_sar;
int bartime;
//---- Íîìåð áàðà, ïî êîòîðîìó áóäåò èñêàòüñÿ ñèãíàë
#define SIGNAL_BAR 1
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int init()
{
//---- indicators
SetIndexStyle(0, DRAW_ARROW);
SetIndexArrow(0, 159);
SetIndexBuffer(0, SarBuffer);
//----
return(0);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void SaveLastReverse(int last, int dir, double start, double low, double high,
double ep, double sar)
{
save_lastreverse = last;
save_dirlong = dir;
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;
double start, last_high, last_low;
double ep, sar, price_low, price_high, price;
int i, counted_bars = IndicatorCounted();
//----
if(Bars < 3)
return(0);
//---- initial settings
i = Bars - 2;
//----
if(counted_bars == 0 || first)
{
first = false;
dirlong = 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;
Print(" k=", k, " Bars=", Bars);
//----
while(k < Bars)
{
SarBuffer[k] = 0.0;
k++;
}
//---- check further
if(dirlong)
{
SarBuffer[i] = Low[i+1];
ep = High[i];
}
else
{
SarBuffer[i] = High[i+1];
ep = Low[i];
}
i--;
}
else
{
i = save_lastreverse;
start = save_start;
dirlong = save_dirlong;
last_high = save_last_high;
last_low = save_last_low;
ep = save_ep;
sar = save_sar;
// Fix1 start
// If new bar increment index
if(Time[0] != bartime)
{
bartime = Time[0];
i++;
}
//Fix1 end
}
//----
while(i >= 0)
{
price_low = Low[i];
price_high = High[i];
//--- check for reverse from long to short
if(dirlong && price_low < SarBuffer[i+1])
{
SaveLastReverse(i, true, start, price_low, last_high, ep, sar);
start = Step;
dirlong = false;
ep = price_low;
last_low = price_low;
SarBuffer[i] = last_high;
i--;
continue;
}
//--- check for reverse from short to long
if(!dirlong && price_high > SarBuffer[i+1])
{
SaveLastReverse(i, false, start, last_low, price_high, ep, sar);
start = Step;
dirlong = true;
ep = price_high;
last_high = price_high;
SarBuffer[i] = last_low;
i--;
continue;
}
//sar(i) = sar(i+1)+start*(ep-sar(i+1))
price = SarBuffer[i+1];
sar = price + start*(ep - price);
//----
if(dirlong)
{
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, start, price_low, last_high, ep, sar);
start = Step;
dirlong = false;
ep = price_low;
last_low = price_low;
SarBuffer[i] = last_high;
i--;
continue;
}
//----
if(ep < price_high)
{
last_high = price_high;
ep = price_high;
}
} //dir-long
else
{
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, start, last_low, price_high, ep,sar);
start = Step;
dirlong = true;
ep = price_high;
last_high = price_high;
SarBuffer[i] = last_low;
i--;
continue;
}
//----
if(ep > price_low)
{
last_low = price_low;
ep = price_low;
}
} //dir-short
SarBuffer[i] = sar;
i--;
} //while
// 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);
//---- Ñòàòè÷åñêèå ïåðåìåííûå, â êîòîðûõ õðàíÿòñÿ
//---- âðåìÿ ïîñëåäíåãî áàðà è íàïðàâëåíèå ïîñëåäíåãî ñèãíàëà
static int PrevSignal = 0, PrevTime = 0;
//---- Åñëè áàðîì äëÿ àíàëèçà âûáðàí íå 0-é, íàì íåò ñìûñëà ïðîâåðÿòü ñèãíàë
//---- íåñêîëüêî ðàç. Åñëè íå íà÷àëñÿ íîâûé áàð, âûõîäèì.
if(SIGNAL_BAR > 0 && Time[0] <= PrevTime )
return(0);
//---- Îòìå÷àåì, ÷òî ýòîò áàð ïðîâåðåí
PrevTime = Time[0];
//---- Åñëè ïðåäûäóùèé ñèãíàë áûë ÑÅËË èëè ýòî ïåðâûé çàïóñê (PrevSignal=0)
if(PrevSignal <= 0)
{
if(Close[SIGNAL_BAR] - SarBuffer[SIGNAL_BAR] > 0)
{
PrevSignal = 1;
Alert("sParabolic Sub(", Symbol(), ", ", Period(), ") - BUY!!!");
}
}
if(PrevSignal >= 0)
{
if(SarBuffer[SIGNAL_BAR] - Close[SIGNAL_BAR] > 0)
{
PrevSignal = -1;
Alert("sParabolic Sub(", Symbol(), ", ", Period(), ") - SELL!!!");
}
}
//----
return(0);
}
//+------------------------------------------------------------------+
Comments