i-Regr_trace_tail
Download scriptThis script is a sophisticated technical analysis tool designed to project price trends and volatility boundaries on a trading chart. Rather than using simple moving averages, it employs advanced mathematical modeling to "forecast" the path of the market based on historical data.
Core Logic Overview
The primary objective of this script is to calculate a dynamic trend line (the "fit") and then establish an upper and lower boundary around that trend. It achieves this through three distinct phases:
1. Data Modeling (Curve Fitting) The script looks at a specific number of past candles (defined by the user) to analyze price movement. Instead of just connecting dots, it uses a mathematical process called "Least Squares Regression." By applying a degree of complexity to this calculation, the script determines the most accurate mathematical curve that represents the recent price action. This helps smooth out market "noise" to reveal the underlying direction.
2. Volatility Analysis (Standard Deviation) Once the primary trend line is established, the script measures how much the actual price fluctuates around that line. It calculates a "Standard Deviation"—a statistical measure of spread. By multiplying this deviation by a user-defined factor, the script determines how wide or narrow the "safe zone" of the market should be at any given moment.
3. Visual Projection and Boundaries The final output is rendered on your chart in three main ways:
- Trend Paths: It calculates and plots the primary projected trend line.
- Upper and Lower Envelopes: Based on the volatility analysis, it creates two outer boundaries (Highs and Lows). These act like a "channel" or "tunnel"; when prices stay within these lines, the trend is considered stable, and when they break out, it signals significant momentum or exhaustion.
- Trend Rays: The script automatically draws visual "rays" or segments on the chart. These provide a clear look at where the current price trend is heading in the immediate future based on the mathematical curve it has constructed.
Key Functionalities for the User
- Dynamic Adjustment: Because it uses standard deviation, the boundaries aren't static; they expand during high-volatility markets and contract during calm periods.
- Look-Back Period: The user can define how many bars of historical data the script should consider when calculating the trend, allowing for customization between "fast" (responsive) and "slow" (stable) analysis.
- Visual Cues: By using different colors and line styles for the upper boundaries, lower boundaries, and the central trend, it allows traders to quickly identify the "equilibrium" of the market at a glance.
//http://www.forex-tsd.com/suggestions-trading-systems/20012-didgeridoo-trading-system.html
//mod trail 2009fxtsd
//----
#property indicator_chart_window
#property indicator_buffers 6
#property indicator_color4 LimeGreen
#property indicator_color5 Gold
#property indicator_color6 Gold
#property indicator_color1 Blue
#property indicator_color2 Brown
#property indicator_color3 Maroon
#property indicator_style1 4
#property indicator_style2 4
#property indicator_style3 4
extern int degree = 3;
extern double kstd = 2.0;
extern int bars = 250;
extern int shift = 0;
//-----
double fx[],sqh[],sql[];
double fx1[],sqh1[],sql1[];
double ai[10,10],b[10],x[10],sx[20];
double sum;
int ip,p,n,f;
double qq,mm,tt;
int ii,jj,kk,ll,nn;
double sq;
int i0 = 0;
/*
void clear()
{
int total = ObjectsTotal();
for (int i=total-1; i >= 0; i--)
{
string name = ObjectName(i);
if (StringFind(name, prefix) == 0) ObjectDelete(name);
}
}
*/
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int init()
{
SetIndexBuffer(3, fx); // Áóôåðû ìàññèâîâ èíäèêàòîðà
SetIndexBuffer(4, sqh);
SetIndexBuffer(5, sql);
SetIndexStyle(3, DRAW_LINE);
SetIndexStyle(4, DRAW_LINE);
SetIndexStyle(5, DRAW_LINE);
SetIndexEmptyValue(3, 0.0);
SetIndexEmptyValue(4, 0.0);
SetIndexEmptyValue(5, 0.0);
SetIndexShift(3, shift);
SetIndexShift(4, shift);
SetIndexShift(5, shift);
SetIndexBuffer(0, fx1);
SetIndexBuffer(1, sqh1);
SetIndexBuffer(2, sql1);
return(0);
}
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function |
//+------------------------------------------------------------------+
int deinit()
{ for (int i=0;i<Bars;i++)
{
ObjectDelete("Ray1"+Time[i]);
ObjectDelete("Ray2"+Time[i]);
ObjectDelete("Ray3"+Time[i]);
ObjectDelete("Ray11"+Time[i]);
ObjectDelete("Ray21"+Time[i]);
ObjectDelete("Ray31"+Time[i]);
}
//clear();
return(0);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int start()
{
if (Bars < bars) return;
//----
int mi; // ïåðåìåííàÿ èñïîëüçóþùàÿñÿ òîëüêî â start
ip = bars;
p=ip; // òèïà ïðèñâàèâàíèå
sx[1]=p+1; // ïðèìå÷àíèå - [] - îçíà÷àåò ìàññèâ
nn = degree+1;
SetIndexDrawBegin(0, Bars-p-1);
SetIndexDrawBegin(1, Bars-p-1);
SetIndexDrawBegin(2, Bars-p-1);
//----------------------sx-------------------------------------------------------------------
for(mi=1;mi<=nn*2-2;mi++) // ìàòåìàòè÷åñêîå âûðàæåíèå - äëÿ âñåõ mi îò 1 äî nn*2-2
{
sum=0;
for(n=i0;n<=i0+p;n++)
{
sum+=MathPow(n,mi);
}
sx[mi+1]=sum;
}
//----------------------syx-----------
for(mi=1;mi<=nn;mi++)
{
sum=0.00000;
for(n=i0;n<=i0+p;n++)
{
if(mi==1) sum+=Close[n];
else sum+=Close[n]*MathPow(n,mi-1);
}
b[mi]=sum;
}
//===============Matrix=======================================================================================================
for(jj=1;jj<=nn;jj++)
{
for(ii=1; ii<=nn; ii++)
{
kk=ii+jj-1;
ai[ii,jj]=sx[kk];
}
}
//===============Gauss========================================================================================================
for(kk=1; kk<=nn-1; kk++)
{
ll=0;
mm=0;
for(ii=kk; ii<=nn; ii++)
{
if(MathAbs(ai[ii,kk])>mm)
{
mm=MathAbs(ai[ii,kk]);
ll=ii;
}
}
if(ll==0) return(0);
if (ll!=kk)
{
for(jj=1; jj<=nn; jj++)
{
tt=ai[kk,jj];
ai[kk,jj]=ai[ll,jj];
ai[ll,jj]=tt;
}
tt=b[kk];
b[kk]=b[ll];
b[ll]=tt;
}
for(ii=kk+1;ii<=nn;ii++)
{
qq=ai[ii,kk]/ai[kk,kk];
for(jj=1;jj<=nn;jj++)
{
if(jj==kk) ai[ii,jj]=0;
else ai[ii,jj]=ai[ii,jj]-qq*ai[kk,jj];
}
b[ii]=b[ii]-qq*b[kk];
}
}
x[nn]=b[nn]/ai[nn,nn];
for(ii=nn-1;ii>=1;ii--)
{
tt=0;
for(jj=1;jj<=nn-ii;jj++)
{
tt=tt+ai[ii,ii+jj]*x[ii+jj];
x[ii]=(1/ai[ii,ii])*(b[ii]-tt);
}
}
//===========================================================================================================================
for(n=i0;n<=i0+p;n++)
{
sum=0;
for(kk=1;kk<=degree;kk++)
{
sum+=x[kk+1]*MathPow(n,kk);
}
fx[n]=x[1]+sum;
}
//-----------------------------------Std-----------------------------------------------------------------------------------
sq=0.0;
for(n=i0;n<=i0+p;n++)
{
sq+=MathPow(Close[n]-fx[n],2);
}
sq=MathSqrt(sq/(p+1))*kstd;
for(n=i0;n<=i0+p;n++)
{
sqh[n]=fx[n]+sq;
sql[n]=fx[n]-sq;
}
for(n=0;n<Bars-IndicatorCounted();n++)
{
fx1[n]=fx[n];
sqh1[n]=sqh[n];
sql1[n]=sql[n];
}
if ( ObjectFind ("Ray1"+Time[0])== -1 )
ObjectCreate("Ray1"+Time[0],OBJ_TREND,0,Time[3],sqh[3],Time[0],sqh[0]);
ObjectSet ("Ray1"+Time[0],OBJPROP_COLOR,Red);
ObjectSet ("Ray1"+Time[0],OBJPROP_RAY,false);
if ( ObjectFind ("Ray11"+Time[0])== -1 )
ObjectCreate("Ray11"+Time[0],OBJ_TREND,0,Time[7],sqh[7],Time[5],sqh[5]);
ObjectSet ("Ray11"+Time[0],OBJPROP_COLOR,Maroon);
ObjectSet ("Ray11"+Time[0],OBJPROP_RAY,false);
if ( ObjectFind ("Ray2"+Time[0])== -1 )
ObjectCreate("Ray2"+Time[0],OBJ_TREND,0,Time[7],fx[7],Time[5],fx[5]);
ObjectSet ("Ray2"+Time[0],OBJPROP_COLOR,Blue);
ObjectSet ("Ray2"+Time[0],OBJPROP_RAY,false);
if ( ObjectFind ("Ray21"+Time[0])== -1 )
ObjectCreate("Ray21"+Time[0],OBJ_TREND,0,Time[3],fx[3],Time[0],fx[0]);
ObjectSet ("Ray21"+Time[0],OBJPROP_COLOR,RoyalBlue);
ObjectSet ("Ray21"+Time[0],OBJPROP_RAY,false);
if ( ObjectFind ("Ray31"+Time[0])== -1 )
ObjectCreate("Ray31"+Time[0],OBJ_TREND,0,Time[7],sql[7],Time[5],sql[5]);
ObjectSet ("Ray31"+Time[0],OBJPROP_COLOR,Maroon);
ObjectSet ("Ray31"+Time[0],OBJPROP_RAY,false);
if ( ObjectFind ("Ray3"+Time[0])== -1 )
ObjectCreate("Ray3"+Time[0],OBJ_TREND,0,Time[3],sql[3],Time[0],sql[0]);
ObjectSet ("Ray3"+Time[0],OBJPROP_COLOR,Red);
ObjectSet ("Ray3"+Time[0],OBJPROP_RAY,false);
return(0);
}
//+------------------------------------------------------------------+
Comments