// Downloaded From https://www.WiseStockTrader.com // 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 ) + " | ";