_SAR_Slave
Download scriptThis script functions as a sophisticated technical analysis tool designed to identify price trends and potential reversal points by modifying the behavior of the Parabolic SAR (Stop and Reverse) indicator. Rather than using a static fixed rate, this script employs a dynamic, multi-layered logic to adapt to changing market conditions.
Core Logic Overview
The indicator operates through three primary layers of calculation:
1. The Dynamic Acceleration Engine (Master-Slave System) Unlike standard Parabolic SAR indicators that use a constant acceleration factor, this script utilizes an external "Master" signal to determine its speed. It pulls data from a secondary source (which can be adjusted by the user to be based on volatility, price movement, or other metrics). This "Master" value dictates how aggressively the indicator should react:
- When market activity is high or follows specific patterns, the acceleration factor increases.
- When market activity settles, the factor decreases. This ensures that the indicator remains responsive during trending moves but becomes less erratic during consolidation phases.
2. Trend Detection and Directional Awareness The script continuously monitors price action to establish a primary direction (Long or Short). It keeps track of "Extreme Points"—the highest highs or lowest lows reached during a current trend.
- In an Uptrend: It monitors the lowest prices to set "floor" levels.
- In a Downtrend: It monitors the highest prices to set "ceiling" levels. The logic is designed to distinguish between minor price fluctuations and genuine trend exhaustion by comparing current prices against historical extreme points.
3. The Adaptive Stop-and-Reverse Mechanism The indicator places visual markers (dots) on the chart that act as trailing stop-loss levels. Its movement is governed by two strict rules:
- Movement: As price moves in the direction of the trend, the indicator "trails" behind it, moving further away to allow for market "breathing room."
- The Flip: If the price penetrates the plotted dot (the SAR value), the script interprets this as a potential trend reversal. It immediately flips the direction, recalculates the acceleration based on the new trend, and repositions the dots on the opposite side of the price action.
Summary for the User
In practical terms, this script provides a more "intelligent" version of the Parabolic SAR. By blending a secondary signal (the Master-Slave input) with standard trend-following math, it attempts to filter out market noise. It seeks to stay "behind" a strong trend as long as possible while reacting quickly when price action suggests that the current move has lost its momentum and a reversal is occurring.
#property indicator_chart_window // â îêíå èíñòðóìåíòà
#property indicator_buffers 2
#property indicator_color1 Blue
// âõîäíûå ïàðàìåòðû Parabolic SAR
extern double StepFrom=0.005; // íà÷àëüíîå çíà÷åíèå è øàã ôàêòîðà óñêîðåíèÿ îò
extern double StepTo=0.02; // äî
extern double Maximum=0.2; // êîíå÷íîå çíà÷åíèå ôàêòîðà óñêîðåíèÿ
// Âîõîäíûå ïàðàìåòðû MasterSlave
extern int Source=1; // 0 - îáúåì; 1 - ATR; 2 - ñò.äåâèàöèÿ öåíû;
extern int SourcePeriod=33; // ïåðèîä âõîäíîãî èíäèêàòîðà
extern int Window=88; // äëèíà âûáîðêè íîðìèðîâàíèÿ
extern double Sensitivity=0; // ÷óâñòâèòåëüíîñòü
extern int Signal=33; // ñãëàæèâàíèå íîðìèðîâàííîãî èíäèêàòîðà (ñèãíàëüíàÿ)
//--
int History=0;
// èíäèêàòîðíûå áóôåðû
double SarBuffer[], // ïàðàáîëèê
Step[]; // øàã ôàêòîðà óñêîðåíèÿ
// îáùèå ïåðåìåííûå äëÿ ïàðàáîëèêà
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;
//
bool First=1;
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int init()
{
//---- indicators
SetIndexBuffer(0,SarBuffer);
SetIndexStyle(0,DRAW_ARROW);
SetIndexArrow(0,159);
SetIndexLabel(0,"SAR");
SetIndexBuffer(1,Step);
SetIndexStyle(1,DRAW_NONE,2);
SetIndexEmptyValue(0,0.0);
SetIndexEmptyValue(1,0.0);
//----
return(0);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int start() {
int ic=IndicatorCounted();
if(!First && Bars-ic>2) ic=reinit(); // åñëè åñòü ïðîïóùåííûå áàðû íå íà ïîäêëþ÷åíèè (â ðàáîòå)
First=0; // ñáðîñ ôëàãà ïåðâîãî çàïóñêà
// Ìàñòåð
int limit=Bars-ic-1;
for(int i=limit; i>0; i--) {
// óïðàâëÿþùèé ñèãíàë
double ms=iCustom(NULL,0,"_MasterSlave",Source,SourcePeriod,Window,Sensitivity,Signal, 0,i);
Step[i-1]=StepFrom+ms*(StepTo-StepFrom);
}
//===========ïàðàáîëèê========================
static bool first = true;
bool dirlong;
double start, last_high, last_low;
double ep, sar, price_low, price_high, price;
int counted_bars = IndicatorCounted();
//----
if(Bars < 3)
return(0);
//---- initial settings
i = Bars - 2;
//----
if(counted_bars == 0 || first)
{
first = false;
dirlong = true;
start = Step[i];
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[i];
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[i];
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[i]) <= Maximum)
start += Step[i];
//----
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[i];
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[i]) <= Maximum)
start += Step[i];
//----
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[i];
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);
//----
//----
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;
}
int reinit() { // äîïîëíèòåëüíàÿ èíèöèàëèçàöèÿ
ArrayInitialize(SarBuffer,0.0);
ArrayInitialize(Step,0.0);
return(0);
}
Comments