// Least Squares Channel Indicator
// Amibroker AFL code by E.M.Pottasch, Aug 2015
// Indicator updates at end of each bar or when parameters are adjusted
// Else press "Force Calculation" in parameter window
*
Version( 6 ); // need Amibroker version 6
SetBarsRequired( 1000, 0 );
*
order = Param( "n-th Order", 1, 1, 10, 1 );
clevel = Param( "Confidence Level", 2, 1, 3, 0.1 );
extend = Param( "Extend Fit (Bars)", 10, 0, 20, 1 );
trig = ParamTrigger( "Force Calculation", "Press Here" );
minbars = Param( "Minimum", 20, 1, 500, 1 ); // minimum number of bars before new channel starts
showTrack = ParamToggle( "Show Track", "No|Yes", 0 );
showSignals = ParamToggle( "Show Signals", "No|Yes", 0 );
*
s1 = GetChartID() + StrToNum( Name() );
*
regext = regextx1a = regextz1a = Null;
prc = ( H + L ) / 2;
sd = 0;
bi = BarIndex();
lvb = LastVisibleValue( bi );
fvb = 1;
*
function NewBarJustArrived()
{
****vname = "lbe" + s1;
****prev = Nz( StaticVarGet( vname ) );
****curr = Status( "lastbarend" );
*
****StaticVarSet( vname, curr );
*
****return curr != prev;
}
*
StaticVarSet( "DoEntirecalculation" + s1, 0 );
*
if( Nz( StaticVarGet( "svOrder" + s1 ) ) != order OR
********Nz( StaticVarGet( "svClevel" + s1 ) ) != clevel OR
********StaticVarGet( "svInterval" + s1 ) != Interval() OR
********StaticVarGet( "svMinbars" + s1 ) != minbars OR
********StaticVarGet( "svExtend" + s1 ) != extend OR
********StaticVarGetText( "svSymbol" + s1 ) != Name() OR
********NewBarJustArrived() OR
********trig )
{
****StaticVarSet( "DoEntirecalculation" + s1, 1 );
****//Say( " Do Calculation " );
}
*
StaticVarSet( "svOrder" + s1, order );
StaticVarSet( "svClevel" + s1, clevel );
StaticVarSet( "svInterval" + s1, Interval() );
StaticVarSet( "svMinbars" + s1, minbars );
StaticVarSet( "svExtend" + s1, extend );
StaticVarSetText( "svSymbol" + s1, Name() );
*
function CalculateCoefficients( aa, bb )
{
****n = MxGetSize( aa, 0 );
****ll = uu = Matrix( n, n, 0 );
****xx = yy = 0;
*
****for( j = 0; j < n; j++ )
****{
********for( i = 0; i < n; i++ )
********{
************if( i <= j )
************{
****************uu[i][j] = aa[i][j];
*
****************for( k = 0; k <= i - 1; k++ )
********************uu[i][j] -= ll[i][k] * uu[k][j];
*
****************if( i == j )
********************ll[i][j] = 1;
****************else
********************ll[i][j] = 0;
************}
************else
************{
****************ll[i][j] = aa[i][j];
*
****************for( k = 0; k <= j - 1; k++ )
********************ll[i][j] -= ll[i][k] * uu[k][j];
*
****************ll[i][j] /= uu[j][j];
****************uu[i][j] = 0;
************}
********}
****}
*
****for( i = 0; i < n; i++ )
****{
********yy[i] = bb[i];
*
********for( j = 0; j < i; j++ )
********{
************yy[i] -= ll[i][j] * yy[j];
********}
****}
*
****for( i = n - 1; i >= 0; i-- )
****{
********xx[i] = yy[i];
*
********for( j = i + 1; j < n; j++ )
********{
************xx[i] -= uu[i][j] * xx[j];
********}
*
********xx[i] /= uu[i][i];
****}
*
****return xx;
}
*
function CalculateFit( eb, bars )
{
****global reg;
****global x1a;
****global z1a;
****global regext;
****global regextx1a;
****global regextz1a;
*
****reg = x1a = z1a = Null;
****regext = regextx1a = regextz1a = Null;
*
****lb = eb;
****fb = eb - bars;
****nb = lb - fb;
*
****if( eb > bars )
****{
********aa = Matrix( order + 1, order + 1, 0 );
********bb = 0;
*
********// fill matrix A
********for( i = 0; i <= order; i++ )
********{
************for( j = 0; j <= order; j++ )
************{
****************for( k = fb; k <= lb; k++ )
****************{
********************vv = ( k - ( lb + fb ) / 2 );
********************aa[i][j] = aa[i][j] + ( vv ^ ( i + j ) );
****************}
************}
********}
*
********// fill matrix B
********for( i = 0; i <= order; i++ )
********{
************for( j = fb; j <= lb; j++ )
************{
****************vv = ( j - ( lb + fb ) / 2 );
****************bb[i] = bb[i] + prc[j] * ( vv ^ i );
************}
********}
*
********// calculate coefficients
********xx = CalculateCoefficients( aa, bb );
*
********// store the fit in reg
********for( i = fb; i <= lb; i++ )
********{
************reg[i] = xx[0];
*
************for( j = 1; j <= order; j++ )
************{
****************vv = ( i - ( lb + fb ) / 2 );
****************reg[i] = reg[i] + xx[j] * vv ^ j;
************}
********}
*
********// extended fit (only when channel is active at last bar)
********if( lb == BarCount - 1 )
********{
************for( i = lb + 1; i <= lb + extend; i++ )
************{
****************regext[i - extend] = xx[0];
*
****************for( j = 1; j <= order; j++ )
****************{
********************vv = ( i - ( lb + fb ) / 2 );
********************regext[i - extend] = regext[i - extend] + xx[j] * vv ^ j;
****************}
************}
********}
*
********// calculate standard deviation
********sdp = 0;
*
********for( i = fb; i <= lb; i++ )
********{
************sdp = sdp + ( prc[i] - reg[i] ) ^ 2;
********}
*
********sd = sqrt( sdp / ( bars - 2 ) ); // devide by ( bars - 2 ) corresponding to StdErr function
*
********x1a = reg + sd * clevel;
********z1a = reg - sd * clevel;
********regextx1a = regext + sd * clevel;
********regextz1a = regext - sd * clevel;
****}
}
*
if( StaticVarGet( "DoEntirecalculation" + s1 ) == 1 )
{
****regFinal = x1aFinal = z1aFinal = 0;
****regPerm = x1aPerm = z1aPerm = 0;
****buyPerm = sellPerm = 0;
*
****sb = fvb;
*
****for( i = fvb; i <= lvb; i++ )
****{
********eb = i;
********bars = eb - sb;
*
********if( bars > minbars )
********{
************calculateFit( eb, bars );
************regFinal = IIf( !IsEmpty( reg ), reg, regFinal );
************x1aFinal = IIf( !IsEmpty( x1a ), x1a, x1aFinal );
************z1aFinal = IIf( !IsEmpty( z1a ), z1a, z1aFinal );
*
************if( C[ i ] < z1aFinal [ i ] AND z1aFinal [ i ] > z1aFinal [ i - 1 ] )
************{
****************sellPerm[ eb ] = 1;
****************i = i + 2;
****************sb = i;
************}
************else
****************if( C[ i ] > x1aFinal [ i ] AND x1aFinal [ i ] < x1aFinal [ i - 1 ] )
****************{
********************buyPerm[ eb ] = 1;
********************i = i + 2;
********************sb = i;
****************}
*
************regPerm[ eb ] = reg[ eb ];
************x1aPerm[ eb ] = x1a[ eb ];
************z1aPerm[ eb ] = z1a[ eb ];
********}
****}
*
****regFinal = IIf( regFinal, regFinal, Null );
****x1aFinal = IIf( x1aFinal, x1aFinal, Null );
****z1aFinal = IIf( z1aFinal, z1aFinal, Null );
****regPerm = IIf( regPerm, regPerm, Null );
****x1aPerm = IIf( x1aPerm, x1aPerm, Null );
****z1aPerm = IIf( z1aPerm, z1aPerm, Null );
****buyPerm = IIf( buyPerm, buyPerm, Null );
****sellPerm = IIf( sellPerm, sellPerm, Null );
*
****StaticVarSet( "regFinal" + s1, regFinal );
****StaticVarSet( "x1aFinal" + s1, x1aFinal );
****StaticVarSet( "z1aFinal" + s1, z1aFinal );
****StaticVarSet( "regext" + s1, regext );
****StaticVarSet( "regextx1a" + s1, regextx1a );
****StaticVarSet( "regextz1a" + s1, regextz1a );
****StaticVarSet( "regPerm" + s1, regPerm );
****StaticVarSet( "x1aPerm" + s1, x1aPerm );
****StaticVarSet( "z1aPerm" + s1, z1aPerm );
****StaticVarSet( "buyPerm" + s1, buyPerm );
****StaticVarSet( "sellPerm" + s1, sellPerm );
}
*
*
SetChartOptions( 0, chartShowDates );
SetChartBkColor( colorBlack );
SetBarFillColor( IIf( C > O, ColorRGB( 0, 75, 0 ), IIf( C <= O, ColorRGB( 75, 0, 0 ), colorLightGrey ) ) );
Plot( C, "", IIf( C > O, ColorRGB( 0, 255, 0 ), IIf( C <= O, ColorRGB( 255, 0, 0 ), colorLightGrey ) ), 64, Null, Null, 0, 1, 1 );
*
Plot( iif( !IsEmpty( StaticVarGet( "regPerm" + s1 ) ) , StaticVarGet( "regFinal" + s1 ), Null ), "", colorBlue, styleLine | styleNoLabel, Null, Null, 0, 1, 2 );
Plot( StaticVarGet( "regFinal" + s1 ), "", colorBlue, styleDashed, Null, Null, 0, 1, 1 );
Plot( iif( !IsEmpty( StaticVarGet( "regPerm" + s1 ) ) , StaticVarGet( "x1aFinal" + s1 ), Null ), "", colorred, styleLine | styleNoLabel, Null, Null, 0, 1, 2 );
Plot( StaticVarGet( "x1aFinal" + s1 ), "", colorred, styleDashed, Null, Null, 0, 1, 1 );
Plot( iif( !IsEmpty( StaticVarGet( "regPerm" + s1 ) ) , StaticVarGet( "z1aFinal" + s1 ), Null ), "", colorred, styleLine | styleNoLabel, Null, Null, 0, 1, 2 );
Plot( StaticVarGet( "z1aFinal" + s1 ), "", colorred, styleDashed, Null, Null, 0, 1, 1 );
Plot( StaticVarGet( "regext" + s1 ), "", colorlightgrey, styleDashed | styleNoLabel | styleNoRescale, Null, Null, extend, 0, 1 );
Plot( StaticVarGet( "regextx1a" + s1 ), "", colorlightgrey, styleDashed | styleNoLabel | styleNoRescale, Null, Null, extend, 0, 1 );
Plot( StaticVarGet( "regextz1a" + s1 ), "", colorlightgrey, styleDashed | styleNoLabel | styleNoRescale | styleClipMinMax, Null, Null, extend, 0, 1 );
*
hh = StaticVarGet( "x1aFinal" + s1 );
ll = StaticVarGet( "z1aFinal" + s1 );
PlotOHLC( ll, ll, hh, hh, "", ColorRGB( 10, 10, 10 ), styleCloud | styleNoLabel | styleNoRescale, Null, Null, 0, -1, 1 );
*
if( showTrack )
{
****Plot( StaticVarGet( "regPerm" + s1 ), "", colorLightBlue, styleDashed | styleNoLabel | styleNoRescale, Null, Null, 0, 1, 1 );
****Plot( StaticVarGet( "x1aPerm" + s1 ), "", colorOrange, styleDashed | styleNoLabel | styleNoRescale, Null, Null, 0, 1, 1 );
****Plot( StaticVarGet( "z1aPerm" + s1 ), "", colorOrange, styleDashed | styleNoLabel | styleNoRescale, Null, Null, 0, 1, 1 );
}
*
if( showSignals )
{
****PlotShapes( IIf( StaticVarGet( "buyPerm" + s1 ), shapeUpArrow, shapeNone ), colorDarkGreen, 0, L, -15 );
****PlotShapes( IIf( StaticVarGet( "buyPerm" + s1 ), shapeSmallCircle, shapeNone ), colorWhite, 0, C, 0 );
****PlotShapes( IIf( StaticVarGet( "sellPerm" + s1 ), shapeDownArrow, shapeNone ), colorRed, 0, H, -15 );
****PlotShapes( IIf( StaticVarGet( "sellPerm" + s1 ), shapeSmallCircle, shapeNone ), colorWhite, 0, C, 0 );
}
*
SecsToGo = Status( "lastbartimeleft" );
nm = StrMid( Name(), 0, StrLen( Name() ) );
Title = nm +
********" | " + Now( 2 ) +
********" | " + EncodeColor( ColorYellow ) + NumToStr( SecsToGo, 1.0, False ) + EncodeColor( colorWhite ) +
********" | " + NumToStr( order, 1.0, False ) + " | ";