//by Anderson Wilson
//design to be used with database which has Base time interval set to tick
//set chart interval to 1T and adjust parameters
//TickSize in Symbol Information should be informed correctly
_N(Title = StrFormat("{{NAME}} - {{INTERVAL}} {{VALUES}}"));
cTickSize = TickSize;
if( cTickSize == 0 )
cTickSize = 0.01;
BrickSize = Param( "Brick Size (x TickSize)", 6, 2, 10, 1 ) * cTickSize;
Plot(BrickSize, "\nBrickSize", colorRed, styleNoLine | styleOwnScale | styleNoLabel);
BrickSize -= cTickSize;
dd = DateNum();
tt = TimeNum();
rOpen = Null;
rHigh = Null;
rLow = Null;
rClose = Null;
rDD = Null;
rTT = Null;
QtyTicks = Param( "Ticks (x1.000)", 200, 10, 100000, 10) * 1000;
if( BarCount > QtyTicks )
i = BarCount - QtyTicks;
else
i = 0;
RenkoIndex = i;
LimitInf = BrickSize;
LimitSup = LimitInf + BrickSize;
qtyBricks = (Close[i] - LimitSup) \ BrickSize;
LimitInf = LimitSup + (qtyBricks * BrickSize);
LimitSup = LimitInf + BrickSize;
rClose[RenkoIndex] = Close[i];
rHigh[RenkoIndex] = Close[i];
rOpen[RenkoIndex] = Close[i];
rLow[RenkoIndex] = Close[i];
rDD[RenkoIndex] = dd[i];
rTT[RenkoIndex] = tt[i];
i++;
for(; i < BarCount AND RenkoIndex < BarCount - 3; i++) {
if( Close[i] > LimitSup ) {
qtyBricks = (Close[i] - LimitSup) \ BrickSize;
rClose[RenkoIndex] = LimitSup;
rOpen[RenkoIndex] = LimitSup - BrickSize;
RenkoIndex++;
rDD[RenkoIndex] = dd[i];
rTT[RenkoIndex] = tt[i];
rOpen[RenkoIndex] = LimitSup;
rLow[RenkoIndex] = rOpen[RenkoIndex];
while( qtyBricks > 0 AND RenkoIndex > 3) {
rHigh[RenkoIndex] = rOpen[RenkoIndex] + BrickSize;
rClose[RenkoIndex] = rHigh[RenkoIndex];
nxtOpen = rClose[RenkoIndex];
RenkoIndex++;
rDD[RenkoIndex] = dd[i];
rTT[RenkoIndex] = tt[i];
rOpen[RenkoIndex] = nxtOpen;
rLow[RenkoIndex] = nxtOpen;
qtyBricks--;
}
if( RenkoIndex > 3) {
rHigh[RenkoIndex] = Close[i];
rClose[RenkoIndex] = Close[i];
LimitInf = rOpen[RenkoIndex] - 2 * BrickSize;
LimitSup = rOpen[RenkoIndex] + BrickSize;
}
} else if( Close[i] < LimitInf ) {
qtyBricks = (LimitInf - Close[i]) \ BrickSize;
rClose[RenkoIndex] = LimitInf;
rOpen[RenkoIndex] = LimitInf + BrickSize;
RenkoIndex++;
rDD[RenkoIndex] = dd[i];
rTT[RenkoIndex] = tt[i];
rOpen[RenkoIndex] = LimitInf;
rHigh[RenkoIndex] = rOpen[RenkoIndex];
while( qtyBricks > 0 AND RenkoIndex > 3) {
rLow[RenkoIndex] = rOpen[RenkoIndex] - BrickSize;
rClose[RenkoIndex] = rLow[RenkoIndex];
nxtOpen = rClose[RenkoIndex];
RenkoIndex++;
rDD[RenkoIndex] = dd[i];
rTT[RenkoIndex] = tt[i];
rOpen[RenkoIndex] = nxtOpen;
rHigh[RenkoIndex] = nxtOpen;
qtyBricks--;
}
if( RenkoIndex > 3) {
rLow[RenkoIndex] = Close[i];
rClose[RenkoIndex] = Close[i];
LimitInf = rOpen[RenkoIndex] - BrickSize;
LimitSup = rOpen[RenkoIndex] + 2 * BrickSize;
}
} else {
if( Close[i] > rHigh[RenkoIndex] )
rHigh[RenkoIndex] = Close[i];
if( Close[i] < rLow[RenkoIndex] )
rLow[RenkoIndex] = Close[i];
rClose[RenkoIndex] = Close[i];
}
}
shift = BarCount - RenkoIndex - 1;
rOpen = Ref(rOpen, -shift);
rHigh = Ref(rHigh, -shift);
rLow = Ref(rLow, -shift);
rClose = Ref(rClose, -shift);
rDD = Ref(rDD, -shift);
rTT = Ref(rTT, -shift);
//10000 * (year - 1900) + 100 * month + day,
PlotOHLC(rOpen, rHigh, rLow, rClose, "", colorDefault, styleCandle);
yy = rDD \ 10000 + 1900; mm = rDD % 10000 \ 100; dd = rDD % 100;
hh = rTT \ 10000; mi = rTT % 10000 \ 100; ss = rTT % 100;
_N(Title = Title + StrFormat("\n%02g/%02g/%04g %02g:%02g:%02g", dd, mm, yy, hh, mi, ss));
_N(Title = Title + StrFormat(" Open %g, Hi %g, Lo %g, Close %g", rOpen, rHigh, rLow, rClose));
Correct code below
//by Anderson Wilson v1.1
//design to be used with database which has Base time interval set to tick
//set chart interval to 1T and adjust parameters
//TickSize in Symbol Information should be informed correctly
_N(Title = StrFormat("{{NAME}} - {{INTERVAL}} {{VALUES}}"));
cTickSize = TickSize;
if( cTickSize == 0 )
cTickSize = 0.01;
BrickSize = Param( "Brick Size (x TickSize)", 6, 2, 10, 1 ) * cTickSize;
Plot(BrickSize, "\nBrickSize", colorRed, styleNoLine | styleOwnScale | styleNoLabel);
BrickSize -= cTickSize;
dd = DateNum();
tt = TimeNum();
rOpen = Null;
rHigh = Null;
rLow = Null;
rClose = Null;
rDD = Null;
rTT = Null;
QtyTicks = Param( "Ticks (x1.000)", 200, 10, 100000, 10) * 1000;
if( BarCount > QtyTicks )
i = BarCount - QtyTicks;
else
i = 0;
RenkoIndex = 0;
LimitInf = BrickSize;
LimitSup = LimitInf + BrickSize;
qtyBricks = (Close[i] - LimitSup) \ BrickSize;
LimitInf = LimitSup + (qtyBricks * BrickSize);
LimitSup = LimitInf + BrickSize;
rClose[RenkoIndex] = Close[i];
rHigh[RenkoIndex] = Close[i];
rOpen[RenkoIndex] = Close[i];
rLow[RenkoIndex] = Close[i];
rDD[RenkoIndex] = dd[i];
rTT[RenkoIndex] = tt[i];
i++;
RenkoIndexLimit = BarCount - 3;
for(; i < BarCount AND RenkoIndex < RenkoIndexLimit; i++) {
if( Close[i] > LimitSup ) {
qtyBricks = (Close[i] - LimitSup) \ BrickSize;
rClose[RenkoIndex] = LimitSup;
rOpen[RenkoIndex] = LimitSup - BrickSize;
RenkoIndex++;
rDD[RenkoIndex] = dd[i];
rTT[RenkoIndex] = tt[i];
rOpen[RenkoIndex] = LimitSup;
rLow[RenkoIndex] = rOpen[RenkoIndex];
while( qtyBricks > 0 AND RenkoIndex < RenkoIndexLimit) {
rHigh[RenkoIndex] = rOpen[RenkoIndex] + BrickSize;
rClose[RenkoIndex] = rHigh[RenkoIndex];
nxtOpen = rClose[RenkoIndex];
RenkoIndex++;
rDD[RenkoIndex] = dd[i];
rTT[RenkoIndex] = tt[i];
rOpen[RenkoIndex] = nxtOpen;
rLow[RenkoIndex] = nxtOpen;
qtyBricks--;
}
if( RenkoIndex < RenkoIndexLimit) {
rHigh[RenkoIndex] = Close[i];
rClose[RenkoIndex] = Close[i];
LimitInf = rOpen[RenkoIndex] - 2 * BrickSize;
LimitSup = rOpen[RenkoIndex] + BrickSize;
}
} else if( Close[i] < LimitInf ) {
qtyBricks = (LimitInf - Close[i]) \ BrickSize;
rClose[RenkoIndex] = LimitInf;
rOpen[RenkoIndex] = LimitInf + BrickSize;
RenkoIndex++;
rDD[RenkoIndex] = dd[i];
rTT[RenkoIndex] = tt[i];
rOpen[RenkoIndex] = LimitInf;
rHigh[RenkoIndex] = rOpen[RenkoIndex];
while( qtyBricks > 0 AND RenkoIndex < RenkoIndexLimit) {
rLow[RenkoIndex] = rOpen[RenkoIndex] - BrickSize;
rClose[RenkoIndex] = rLow[RenkoIndex];
nxtOpen = rClose[RenkoIndex];
RenkoIndex++;
rDD[RenkoIndex] = dd[i];
rTT[RenkoIndex] = tt[i];
rOpen[RenkoIndex] = nxtOpen;
rHigh[RenkoIndex] = nxtOpen;
qtyBricks--;
}
if( RenkoIndex < RenkoIndexLimit) {
rLow[RenkoIndex] = Close[i];
rClose[RenkoIndex] = Close[i];
LimitInf = rOpen[RenkoIndex] - BrickSize;
LimitSup = rOpen[RenkoIndex] + 2 * BrickSize;
}
} else {
if( Close[i] > rHigh[RenkoIndex] )
rHigh[RenkoIndex] = Close[i];
if( Close[i] < rLow[RenkoIndex] )
rLow[RenkoIndex] = Close[i];
rClose[RenkoIndex] = Close[i];
}
}
shift = BarCount - RenkoIndex - 1;
rOpen = Ref(rOpen, -shift);
rHigh = Ref(rHigh, -shift);
rLow = Ref(rLow, -shift);
rClose = Ref(rClose, -shift);
rDD = Ref(rDD, -shift);
rTT = Ref(rTT, -shift);
//10000 * (year - 1900) + 100 * month + day,
PlotOHLC(rOpen, rHigh, rLow, rClose, "", colorDefault, styleCandle);
yy = rDD \ 10000 + 1900; mm = rDD % 10000 \ 100; dd = rDD % 100;
hh = rTT \ 10000; mi = rTT % 10000 \ 100; ss = rTT % 100;
_N(Title = Title + StrFormat("\n%02g/%02g/%04g %02g:%02g:%02g", dd, mm, yy, hh, mi, ss));
_N(Title = Title + StrFormat(" Open %g, Hi %g, Lo %g, Close %g", rOpen, rHigh, rLow, rClose));
Special care must be taken to trade this type of chart. Many candles are just "illusion"
Hello sir,
How can we plot RSI for Ranko ?
Use RSIa function and pass rClose like this
RSIa( rClose, periods = 14 );
Thanks for your reply.
but i found solucation as below.
may be i am wrong. i am not a afl writer. but just use some logic.
my AFL is shown below.
function FillRun( dir, num, changedir )
{
global i, j, modified, RKC, RKO, RKD, RKH, RKL;
for ( x = 1; x <= num AND j < BarCount - 1; x++ )
{
j++;
extra = ( changedir AND x == 1 ) * dir;
RKC[ j ] = RKC[ j - 1 ] + dir + extra;
RKO[ j ] = RKC[ j - 1 ] + IIf( modified, 0, extra );
RKH[ j ] = High[ i - 1 ];
RKL[ j ] = Low[ i - 1 ];
}
}
SetBarsRequired( sbrAll, sbrAll );
Brick = Param( "Brick Size",5, 1, 20, 1 );
reverser = Param( "Reverser Size",5, 1, 20, 1 );
modified = ParamToggle( "Modified", "No|Yes", 0 );
// 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[0];
RKO[j] = CF[0] + 1;
RKD = 0;
RKH = 0;
RKL = 0;
RestorePriceArrays();
dir = -1; // 1 is up, -1 is down
// Loop to produce the Renko values in number of bricks
for ( i = 1; i < BarCount - 1; i++ )
{
if ( j >= BarCount ) break; // no more room -> finish
if ( CF[i] <= RKC[j] - 1 AND dir < 0 ) // Continue down
{
num = RKC[j] - CF[i];
FillRun( dir, num, False );
}
else
if ( CR[i] >= RKC[j] + reverser AND dir < 0 ) // Change down to up
{
num = CR[i] - RKC[j];
dir = 1;
FillRun( dir, num, True );
}
else
if ( CR[i] >= RKC[j] + 1 AND dir > 0 ) // Continue Up
{
num = CR[i] - RKC[j];
FillRun( dir, num, False );
}
else
if ( CF[i] <= RKC[j] - reverser AND dir > 0 ) // Change up to down
{
num = RKC[j] - CF[i];
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;
RKC = Ref( RKC, -delta );
RKO = Ref( RKO, -delta );
RKD = Ref( RKD, -delta );
RKH = Ref( RKH, -delta );
RKL = Ref( RKL, -delta );
C = RKC * Brick;
O = RKO * Brick;
H = IIf( modified, RKH, Max( C, O ) );
L = IIf( modified, RKL, Min( C, O ) );
RSIRenko=RSI();
Plot(RSIRenko,"RSIRenko",colorYellow,styleLeftAxisScale);
Vipul,
When you do not know coding, please do not post code of someone else. It confuses others. Most important part is that RSI value shown in your code is complete humbug.....
Now, for the record, the code that you posted is OK-OK as far as Renko brick creation is concerned but it totally ignores the most important part of candle (the Time). Since X Axis Length of each Renko Candle is not constant, display of time is even more important in case of Renko.
Anderson version does make have some code to capture the start of the candle time. IMHO, it needs both start and end time so more code needs to be added to it.
Some refactoring can also be done to reduce the code size...
Hello Tomasz
There was a new thread querying about Renko bar but that was closed before I even saw it.
In that thread, the reply marked as "Solution" said that it needs Tick Data. While I fully agree with "TICK DATA" as input source, it will produce a better renko chart, the reply itself raises lot more questions for me and they are presented below for discussion. Please note that I am not criticizing Amibroker just attempting to have honest and frank discussion that sparks better outcome for the software/
-
Does the "solution reply" imply that Range bar creation logic of Amibroker only use CLOSE prices of a given candle data (ignoring Open High and Low) and thus ignoring 3/4th of price movement recorded in a non-tick database. Is that the reason on why chart appears so different?
-
Although Amibroker permits storage of tick data, its current file format that stores O,H,L,C,V,AUX1,AUX2 causes redundant storage space in case of tick data. Even with 4 bytes for single precision number, On one trading session of 375 mins with only one tick every second, we would end up 48MB (uncompressed) data file. Worst part is that more than half of that data is redundant or plain zero.
-
Next, the Sharekhan software whose screen shot was posted in today's closed thread does in fact create Renko bars from 1 min or 5 min candle. I know this since because I have exported tick, 1 min and renko data from that software. It stores tick only for the most recent trading day and all past days will be saved as 1 minute data. Once the trading session is over, tick data is compressed to 1 min candle. But you are able to see renko of past 30 days without any problem. It does not store renko bars separately AFAIK.
Learn more about Renko and then you will know why tick data are required for proper creation of renko and range bars. Creating multiple Renko/range bars from single time-compressed H-L candle is creating artificial reality, since you don't know what happened inside candle and you are creating illusion based on assumptions and not actual market movement. If you fail to understand that crucial thing, market will give you "actual reality" lesson.
And no, AmiBroker does NOT use close only. It uses H-L if you are not using tick data as input. But if input bar H-L exceeds the range it does not create artificial reality. It leaves actual reality as it is.
If for some reason you want to live in fantasy world where (often false) assumptions are used instead of actual market data, you can use dozens of "Renko" formulas written by various people floating around.
sorry sir if something wrong in my afl.
buy i post as per my best knowledge.
i am not a afl writer or expert.
once again if i heart you.
Have a nice time.
And here we have the (old) problem of different realities again...
The actual renko part is exactly NOT (!) your AFL code! (So there is just a single true reality.)
You copied it from elsewhere... from AmiBroker members area or traders.com website and (because guys like you just do not bother at all) you have impertinently removed reference to original creator(s) from the top of the complete original code (as copy&paste artists always do because guys of such (tiny) caliber seem to think "If I am able to copy code then it is mine as a result". No, it is NOT!).
Respect other people's time & efforts eventually!
Do NOT remove original stuff from code you have not made yourself once and for all!
One original source of the code you posted is this one
http://traders.com/Documentation/FEEDbk_docs/2014/07/TradersTips.html#item4
So what exactly makes you think it would be your code created by yourself since at the top you can clearly see who are actual real creators? I do not see your name there, do you? Do a reality check!
It is not really about the code but about the fact that you don't know what happened INSIDE the candle. Creating multiple renko bars out of single candle that exceeds the range gives FALSE impression (based on unfounded assumptions, not facts) about what happened inside the bar. Prices inside single candle could do circles around and you simply don't know what happened unless you use tick data.
It is not about the code. It is about the idea. The IDEA is flawed.
Imagine the candle like this and try to produce Renko/Range chart out of it with box size = 1
If prices started at 1158 did they
- go up to high first then down to low
OR - go down to low first and then reached high?
OR maybe - they hit lows and highs in zigzaging way
Depending on answer to this question you would paint upward green renko bricks or downward red greens or dozens of red/green runs down and up. The renko chart would be completely different based on your GUESS what happened inside bar.
Place your bets. Which way did it go? And how actual correct renko chart would look like if it was created out of tick data?
The softwares that produce Renko charts out of time compressed input create false image. They would just (wrongly) assume that there was ONE run say from open to low then to high then to close and you will get four renko runs.
Reality is totally different. This is how actual Renko chart produced out of tick data would look for that paricular candle:
Under no circumstances you would be ever able to create this out of single time compressed OHLC candle.
Tomasz
Thank you for responding.
You've hit the hammer on the head!!!
Asking question directly to you was intended for better understanding. There are 1000 example AFL codes of Renko and I have at least dabbled in 50 or 60 of them.
I am both a programmer and a trader. As a programmer, accuracy of coding matters. I used to work in banking software team where 1 cent computation error would result in bug report being raised. Company would pay bunch of developers $$$$ to remove one cent error.
Trader's motivation to use Renko is to reduce the market noise.
As a trader, inaccurate code that provides superior profit-to-loss ratio is better than accurate code that
EITHER takes eons to develop
OR is so damn expensive to acquire
OR it needs very expensive jet-age fuel to drive itself.
As of today, Buying tick data in Indian markets falls in latter category.
Therefore, In your example candle (O=1158, C = 1160, H 1170, L 1150), from the trader's perspective, the most crucial part is neither its high nor its low.
Regardless of whether High was made prior or later to low, the price returned back to where it started before candle closed for good. Whether candle touched high first or low first is precisely the "MARKET NOISE" that I seek to eliminate away.
I will appreciate it If you can help narrow down the RENKO AFL code (that creates artificial reality from non-tick data) without too much compromise on the accuracy aspect.