_SECTION_BEGIN( "renko" );
// Modified Renko Chart with custom date axis
// and high/low winks
// Loosely based on Renko chart formula by G. Kavanagh
// from AmiBroker on-line formula library (id=521)
// Modifications & fixes TJ 2014
// Enhanced by Mark Huang June 2015
function FillRun( dir, num, changedir )
{
global i, j, modified, dt, RKC, RKO, RKD, RKH, RKL, RKC2, RKO2, RKD2, RKH2, RKL2, rounds;
for ( x = 1; x <= num; x++ )
{
if ( j == BarCount-1 )
{
rounds++;
j = 0;
if ( rounds % 2 == 0 )
{
RKC[j] = RKC2[barcount - 1];
RKO[j] = RKO2[barcount - 1];
RKD[j] = RKD2[barcount - 1];
RKH[j] = RKH2[barcount - 1];
RKL[j] = RKL2[barcount - 1];
}
else
{
RKC2[j] = RKC[barcount - 1];
RKO2[j] = RKO[barcount - 1];
RKD2[j] = RKD[barcount - 1];
RKH2[j] = RKH[barcount - 1];
RKL2[j] = RKL[barcount - 1];
}
}
j++;
extra = ( changedir AND x == 1 ) * dir;
if ( rounds % 2 == 1 )
{
RKC2[ j ] = RKC2[ j - 1 ] + dir + extra;
RKO2[ j ] = RKC2[ j - 1 ] + IIf( modified, 0, extra );
RKD2[ j ] = dt[ i ];
RKH2[ j ] = High[ i - 1 ];
RKL2[ j ] = Low[ i - 1 ];
}
else
{
RKC[ j ] = RKC[ j - 1 ] + dir + extra;
RKO[ j ] = RKC[ j - 1 ] + IIf( modified, 0, extra );
RKD[ j ] = dt[ i ];
RKH[ j ] = High[ i - 1 ];
RKL[ j ] = Low[ i - 1 ];
}
}
}
SetBarsRequired( sbrAll, sbrAll );
Brick = Param( "Brick Size", 1, 0.0001, 100, 0.001 );
reverse = 2;
intra = 0; //ParamToggle( "Intraday", "No|Yes", 0 );
if(interval() < inDaily) intra = 1;
modified = ParamToggle( "Modified", "No|Yes", 0 );
startBar = 0; //Param( "Start Bar", 0, 0, BarCount - 1, 1 );
// Convert the closing price to rising and falling rounded bricks
CF = ceil( C / Brick );
CR = floor( C / Brick );
// initialize first element
j = 0;
RKC[j] = CF[startBar];
RKO[j] = CF[startBar] + 1;
//RKD = 0;
//RKH = 0;
//RKL = 0;
dt = IIf( intra, floor( TimeNum() / 100 ), DateNum() );
dir = -1; // 1 is up, -1 is down
//RKC2 = RKO2 = RKD2 = RKH2 = RKL2 = 0;
// Loop to produce the Renko values in number of bricks
rounds = 0;
for ( i = startBar + 1; i <= BarCount - 1; i++ )
{
/*
if ( j >= BarCount )
{
if ( rounds == 0 )
rounds = 1;
else
rounds = 0;
//break; // no more room -> finish
j = 0;
if ( ! rounds )
{
RKC[j] = RKC2[barcount - 1];
RKO[j] = RKO2[barcount - 1];
RKD = 0;
RKH = 0;
RKL = 0;
}
else
{
RKC2[j] = RKC[barcount - 1];
RKO2[j] = RKO[barcount - 1];
RKD2 = 0;
RKH2 = 0;
RKL2 = 0;
}
}
*/
if ( rounds % 2 == 1 )
{
if ( CF <= RKC2[j] - 1 AND dir < 0 ) // Continue down
{
num = RKC2[j] - CF;
FillRun( dir, num, False );
}
else
if ( CR >= RKC2[j] + Reverse AND dir < 0 ) // Change down to up
{
num = CR - RKC2[j];
dir = 1;
FillRun( dir, num, True );
}
else
if ( CR >= RKC2[j] + 1 AND dir > 0 ) // Continue Up
{
num = CR - RKC2[j];
FillRun( dir, num, False );
}
else
if ( CF <= RKC2[j] - Reverse AND dir > 0 ) // Change up to down
{
num = RKC2[j] - CF;
dir = -1;
FillRun( dir, num, True );
}
}
else // rounds %2 == 0
{
if ( CF <= RKC[j] - 1 AND dir < 0 ) // Continue down
{
num = RKC[j] - CF;
FillRun( dir, num, False );
}
else
if ( CR >= RKC[j] + Reverse AND dir < 0 ) // Change down to up
{
num = CR - RKC[j];
dir = 1;
FillRun( dir, num, True );
}
else
if ( CR >= RKC[j] + 1 AND dir > 0 ) // Continue Up
{
num = CR - RKC[j];
FillRun( dir, num, False );
}
else
if ( CF <= RKC[j] - Reverse AND dir > 0 ) // Change up to down
{
num = RKC[j] - CF;
dir = -1;
FillRun( dir, num, True );
}
}
}
// move the chart to right end of chart space, ie last brick on last bar position
delta = BarCount - 1 - j;
if ( rounds % 2 == 0 )
{
RKCx = Ref( RKC, -delta );
RKOx = Ref( RKO, -delta );
RKDx = Ref( RKD, -delta );
RKHx = Ref( RKH, -delta );
RKLx = Ref( RKL, -delta );
if ( rounds > 0 )
{
for ( k = 0; k < delta; k ++ )
{
// remember: RKC2[0] == RKC[barcount -1]
RKCx[k] = RKC2[barcount - 1 - delta + k];
RKOx[k] = RKO2[barcount - 1 - delta + k];
RKDx[k] = RKD2[barcount - 1 - delta + k];
RKHx[k] = RKH2[barcount - 1 - delta + k];
RKLx[k] = RKL2[barcount - 1 - delta + k];
}
}
}
else
{
RKCx = Ref( RKC2, -delta );
RKOx = Ref( RKO2, -delta );
RKDx = Ref( RKD2, -delta );
RKHx = Ref( RKH2, -delta );
RKLx = Ref( RKL2, -delta );
if ( rounds > 0 )
{
for ( k = 0; k < delta; k ++ )
{
RKCx[k] = RKC[barcount - 1 - delta + k];
RKOx[k] = RKO[barcount - 1 - delta + k];
RKDx[k] = RKD[barcount - 1 - delta + k];
RKHx[k] = RKH[barcount - 1 - delta + k];
RKLx[k] = RKL[barcount - 1 - delta + k];
}
}
}
C = RKCx * Brick;
O = RKOx * Brick;
H = IIf( modified, RKHx, Max( C, O ) );
L = IIf( modified, RKLx, Min( C, O ) );
Plot( C, "", IIf( C > O, colorGreen, colorRed ), styleCandle );
m1 = MA( ( C + H + L ) / 3, 8 );
m2 = MA( C, 8 );
Plot( m1, "SMA Typ", colorBlue );
Plot( m2, "SMA Renko", colorOrange );
Cover = Cross( m2, m1 );
Sell = Cross( m1, m2 );
Short = Sell AND C < O;
Buy = Cover AND C > O;
PlotShapes( shapeUpArrow * Buy, colorGreen, 0, m1 );
PlotShapes( shapeDownArrow * Sell, colorRed, 0, m1 );
PlotShapes( shapeHollowUpArrow * Cover, colorGreen, 0, m1, -25 );
PlotShapes( shapeHollowDownArrow * Short, colorRed, 0, m1, -25 );
color = IIf( Flip( Buy, Sell ), ColorRGB( 220, 255, 220 ),
IIf( Flip( Short, Cover ), ColorRGB( 255, 220, 220 ), colorWhite ) );
Plot( 1, "", color, styleArea | styleOwnScale, 0, 1, 0, -1 );
xnum = floor( RKDx / 1000 );
XChange = IIf( xnum != Ref( xnum, -1 ), 1, Null );
Plot( XChange, "", colorGrey50, styleHistogram | styleOwnScale, 0, 1 );
// Draw renko-date axis
MonthNames = "Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec";
fvb = FirstVisibleValue( BarIndex() );
lvb = LastVisibleValue( BarIndex() );
for ( i = fvb; i < lvb; i++ )
{
if ( XChange[ i ] )
{
if ( intra )
datetext = StrFormat( "%02gh", floor ( RKDx[ i ] / 100 ) );
else
if ( ( xnum[ i ] % 100 ) == 1 )
datetext = StrFormat( "%04.0f", 1900 + ( xnum[ i ] / 100 ) );
else
datetext = StrExtract( MonthNames, ( xnum[ i ] % 100 ) - 1 );
PlotText( datetext , i, LowestVisibleValue( Low ), colorGrey50, colorWhite );
}
}
Title = Name() + StrFormat( " - 20%06.0f", RKDx % 1000000 ) + " - Renko Chart : Last Value = " + RKC * Brick + " H: " + RKH + " L: " + RKL + ", Brick Size = " + Brick;
GraphXSpace = 5;
_SECTION_END();