Description
Description
A type of chart, developed by the Japanese, that is only concerned with price movement - time and volume are not included. A renko chart is constructed by placing a brick in the next column once the price surpasses the top or bottom of the previous brick by a predefined amount. Green bricks are used when the direction of the trend is up, while red bricks are used when the trend is down.
Updates
- 24/01/2016
- Released.
- 25/01/2016
- Added live forming brick.
- Added option to plot defined number of bricks.
- Added option to choose colors for bricks.
- Updated reference mode for better performance.
- 27/01/2016
- Changed charting method.
- Overlay set to true by default.
- Deleted reference mode. (Check reference sample to update your cBot / Indicator!)
- 29/01/2016
- Added LastValue (live forming brick) into outputs.
- 31/01/2016
- Added High and Low values into outputs.
- 01/02/2016
- Fixed live brick not drawing when BricksToShow was set too high.
- Improved performance.
Inputs
- Renko (Pips) - Defines height of one brick in pips.
- Bricks To Show - Defines how many bricks will be plotted.
- Zoom Level - Adjusts width of bricks for defined zoom level.
- Bullish Color - Sets color of bullish bricks.
- Bearish Color - Sets color of bearish bricks.
Screenshot
Notes
- Overlay - Indicator can be set not to overlay at line 11.
[Indicator("Renko", IsOverlay = false, ...)]
- Referencing - Indicator can be used in other indicators or cBots. Sample below.
public double RenkoPips = 10; public int BricksToShow = 10; private Renko renko; protected override void OnStart() { renko = Indicators.GetIndicator<Renko>(RenkoPips, BricksToShow, 3, "SeaGreen", "Tomato"); } protected override void OnTick() { bool isLastBrickBullish = renko.Open.Last(1) < renko.Close.Last(1); if (isLastBrickBullish) { ExecuteMarketOrder(TradeType.Buy, Symbol, 1000); } }
- Accuracy
- When the indicator is loaded it can access only OHLC values of historical data. For better accuracy of historical chart I highly recommend using lower timeframe and scroll back for more data.
- When the indicator is running it's fed by live data (each tick) so it's 100% accurate no matter what timeframe it's loaded up on.
Make a Donation
- If you like my work and effort then please consider to make a kind donation thru PayPal or any Credit Card at this link.
using cAlgo.API;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;
using cAlgo.Indicators;
using System;
using System.Collections.Generic;
using System.Linq;
namespace cAlgo
{
[Indicator("Renko", IsOverlay = true, AutoRescale = true, TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
public class Renko : Indicator
{
[Parameter("Renko (Pips)", DefaultValue = 10, MinValue = 0.1, Step = 1)]
public double RenkoPips { get; set; }
[Parameter("Bricks To Show", DefaultValue = 100, MinValue = 1)]
public int BricksToShow { get; set; }
[Parameter("Zoom Level", DefaultValue = 3, MinValue = 0, MaxValue = 5, Step = 1)]
public double ZoomLevel { get; set; }
[Parameter("Bullish Color", DefaultValue = "SeaGreen")]
public string ColorBull { get; set; }
[Parameter("Bearish Color", DefaultValue = "Tomato")]
public string ColorBear { get; set; }
[Output("Open", Color = Colors.DimGray, Thickness = 1, PlotType = PlotType.Points)]
public IndicatorDataSeries Open { get; set; }
[Output("High", Color = Colors.DimGray, Thickness = 1, PlotType = PlotType.Points)]
public IndicatorDataSeries High { get; set; }
[Output("Low", Color = Colors.DimGray, Thickness = 1, PlotType = PlotType.Points)]
public IndicatorDataSeries Low { get; set; }
[Output("Close", Color = Colors.DimGray, Thickness = 1, PlotType = PlotType.Points)]
public IndicatorDataSeries Close { get; set; }
public class Brick
{
public double Open { get; set; }
public double Close { get; set; }
}
public List<Brick> Bricks = new List<Brick>();
private double closeLastValue, thickness, renkoPips, renkoLastValue;
private Colors colorBull, colorBear;
private bool colorError;
private int lastCount;
protected override void Initialize()
{
if (!Enum.TryParse<Colors>(ColorBull, out colorBull) || !Enum.TryParse<Colors>(ColorBear, out colorBear))
colorError = true;
renkoPips = RenkoPips * Symbol.PipSize;
thickness = Math.Pow(2, ZoomLevel) - (ZoomLevel > 0 ? 1 : 0);
renkoLastValue = 0;
}
public override void Calculate(int index)
{
if (colorError)
{
ChartObjects.DrawText("Error0", "{o,o}\n/)_)\n \" \"\nOops! Incorrect colors.", StaticPosition.TopCenter, Colors.Gray);
return;
}
if (renkoLastValue == 0)
{
var open = MarketSeries.Open.LastValue;
renkoLastValue = open - (open % renkoPips) + renkoPips / 2;
}
closeLastValue = MarketSeries.Close.LastValue;
while (closeLastValue >= renkoLastValue + renkoPips * 1.5)
{
renkoLastValue += renkoPips;
Bricks.Insert(0, new Brick
{
Open = renkoLastValue - renkoPips / 2,
Close = renkoLastValue + renkoPips / 2
});
if (Bricks.Count() > BricksToShow)
Bricks.RemoveRange(BricksToShow, Bricks.Count() - BricksToShow);
if (IsLastBar)
UpdateHistory(index);
}
while (closeLastValue <= renkoLastValue - renkoPips * 1.5)
{
renkoLastValue -= renkoPips;
Bricks.Insert(0, new Brick
{
Open = renkoLastValue + renkoPips / 2,
Close = renkoLastValue - renkoPips / 2
});
if (Bricks.Count() > BricksToShow)
Bricks.RemoveRange(BricksToShow, Bricks.Count() - BricksToShow);
if (IsLastBar)
UpdateHistory(index);
}
bool isNewBar = MarketSeries.Close.Count > lastCount;
if (IsLastBar && isNewBar)
{
UpdateHistory(index);
Open[index - BricksToShow] = double.NaN;
High[index - BricksToShow] = double.NaN;
Low[index - BricksToShow] = double.NaN;
Close[index - BricksToShow] = double.NaN;
lastCount = MarketSeries.Close.Count;
}
if (IsRealTime)
UpdateLive(index);
}
private void UpdateHistory(int index)
{
for (int i = 0; i < BricksToShow - 1 && i < Bricks.Count() - 1; i++)
{
var color = Bricks[i].Open < Bricks[i].Close ? colorBull : colorBear;
ChartObjects.DrawLine(string.Format("renko.Last({0})", i + 1), index - i - 1, Bricks[i].Open, index - i - 1, Bricks[i].Close, color, thickness, LineStyle.Solid);
Open[index - i - 1] = Bricks[i].Open;
High[index - i - 1] = Math.Max(Bricks[i].Open, Bricks[i].Close);
Low[index - i - 1] = Math.Min(Bricks[i].Open, Bricks[i].Close);
Close[index - i - 1] = Bricks[i].Close;
}
}
private void UpdateLive(int index)
{
double y1, y2;
var top = Math.Max(Bricks[0].Open, Bricks[0].Close);
var bottom = Math.Min(Bricks[0].Open, Bricks[0].Close);
if (closeLastValue > top)
y1 = top;
else if (closeLastValue < bottom)
y1 = bottom;
else
y1 = closeLastValue;
y2 = closeLastValue;
var colorLive = y1 < y2 ? colorBull : colorBear;
ChartObjects.DrawLine("renko.Live", index, y1, index, y2, colorLive, thickness, LineStyle.Solid);
Open[index] = y1;
High[index] = y1 > y2 ? y1 : y2;
Low[index] = y1 < y2 ? y1 : y2;
Close[index] = y2;
}
}
}
Jiri
Joined on 31.08.2015
- Distribution: Free
- Language: C#
- Trading platform: cTrader Automate
- File name: Renko.algo
- Rating: 4.5
- Installs: 11705
- Modified: 13/10/2021 09:55
Comments
like renko chart in gocharting
hello
can u Update this indicator to show shadow of renko chart or weak of renko chart please
how can I add parabolic indicator to the renko bricks itself and not the candles?
hi problem download renko chart
Why changing timeframes, this renko indicator changes the bricks? It's not supposed, right?
Dear Jiri,
I have opened a thread related to your indicator, https://ctrader.com/forum/cbot-support/14881
Would you be able to give me any advise on that question?
Thanks
its appear as indicator, not a chart type so price dont follow...
Can I do the calculation of Renko bars inside the bot?
using System;
using System.Linq;
using cAlgo.API;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;
using cAlgo.Indicators;
namespace cAlgo.Robots
{
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
public class My_RenkoRobot : Robot
{
[Parameter("Renko (Pips)", DefaultValue = 10.0, MinValue = 0.1, Step = 1)]
public double RenkoPips { get; set; }
protected class Brick
{
public double Open { get; set; }
public double Close { get; set; }
}
protected List<Brick> Bricks = new List<Brick>();
private double closeLastValue, renkoPips, renkoLastValue;
private MarketSeries M1;
protected override void OnStart()
{
// ...
renkoPips = RenkoPips * Symbol.PipSize;
M1 = MarketData.GetSeries(TimeFrame.Minute);
var open = M1.Open.LastValue;
renkoLastValue = open - (open % renkoPips) + renkoPips / 2;
int totalBars = Math.Min(LookupBars + 1, M1.Close.Count);
for (int i = 0; i < totalBars; i++)
{
closeLastValue = M1.Close[i];
while (closeLastValue >= renkoLastValue + renkoPips * 1.5)
{
renkoLastValue += renkoPips;
Bricks.Insert(0, new Brick
{
Open = renkoLastValue - renkoPips / 2,
Low = Open,
Close = renkoLastValue + renkoPips / 2,
High = Close
});
}
while (closeLastValue <= renkoLastValue - renkoPips * 1.5)
{
renkoLastValue -= renkoPips;
Bricks.Insert(0, new Brick
{
Open = renkoLastValue + renkoPips / 2,
High = Open,
Close = renkoLastValue - renkoPips / 2,
Low = Close
});
}
}
// ...
}
protected override void OnTick()
{
// ...
double y1, y2;
var top = Math.Max(Bricks[0].Open, Bricks[0].Close);
var bottom = Math.Min(Bricks[0].Open, Bricks[0].Close);
closeLastValue = M1.Close[0];
if (closeLastValue > top)
y1 = top;
else if (closeLastValue < bottom)
y1 = bottom;
else
y1 = closeLastValue;
y2 = closeLastValue;
Bricks[0].Open = y1;
Bricks[0].High = y1 > y2 ? y1 : y2;
Bricks[0].Low = y1 < y2 ? y1 : y2;
Bricks[0].Close = y2;
// ...
}
}
}
Thanx for you renko indi!
renko = Indicators.GetIndicator<Renko>(RenkoPips, BricksToShow, 3, "SeaGreen", "Tomato");
Buy renko.Bricks.Count() = 0.
Tell me please, why?
Thanks for pointing this out, didn't notice it. :)
Hi tmc,
Great job.
Quick question for you, I am trying to calculate a moving average based on your renko chart. Sounds simple but it does not seem to work (nothing appears on the chart), even if this compiles - do you see anything wrong in this section of my code:
private Renko renko;
private IndicatorDataSeries renko_data;
private MovingAverage renko_MA;
protected override void Initialize()
{
renko = Indicators.GetIndicator(RenkoPips, BricksToShow, 3, "SeaGreen", "Tomato");
renko_data = CreateDataSeries();
renko_MA = Indicators.MovingAverage(renko_data, 10, MovingAverageType.Simple);
}
public override void Calculate(int index)
{
renko_data[index] = renko.Close[index];
Indic[index] = renko_MA.Result[index];
}
The Renko is overlaying your chart, it's just an indicator. Since the chart is time-based while Renko is price-change based there is applied a logic that shifts Renko to align with the latest bar. You will need to integrate same logic to the indicator if you want to feed it with Renko as a source.
Does not work well at last. It seems that it has some result default when the current Renko bar returns to the last Renko bar close. This seems to lead visually by a horizontal jump backwards on the last Renko bar. Moreover if you use it in a bot, there are very quick positions (buy & sell or the contrary) likely due to this jump.
At last if you used it with a custom indicator as the following: https://ctrader.com/algos/indicators/show/1608, there will be a failure, again probabaly due to th backwards.
Thanks
MACD asks for the source. Just take Renko as the source.
Hey guys i'm a programmer but i'm new to calgo, could anyone show me the way to create a MACD indicator to work on the candles created by this renko indicator? or if it already exist just link me.
Thanks
I would like to say sorry.
Let me be celar. IT IS NOT A BUG, and this is a VERY GOOD indicator.
But what i say is still true. there is boxes missing, and you should KNOW this before trading. i have traded with renko for a long time, and i did not know they build them in many different ways.
The problem is not with tmc or his indicator. It was with my knowledge.
However. It is VERY IMPORTANT, to understand how this indicator work before using it, because if you dont udnerstand it 100% it can cheat you with the illussion of how many pips the market has moved. I found out this can happen easy, because even tho there are many different renko indicators. they all look the same. So educate yourself first.
I HIGHLY recomend this indicator, and tmc as a developer. He does very good work, and you can trust him. He dot work for me personally.
best regards
It's not a bug, that's how classic/standard renko is supposed to work as explained in previous comments. If you want to protect your position just set SL to same size as a renko brick and trail it.
I am planning to release an universal renko which can be optimized to your needs - brick size, open offset and reversal size, as soon as we publish our website.
This renko can not be used. It has a dangerous bug.
All the renko boxes are not the same size. The problem happen when the color change from red to green, or from green to red.
Example:
i set the renko to 5 pip. And all the boxes are 5 pip. But on color change they are 10 pip becuase the open price is used.
red = 5 pip
red = 5 pip
red = 5 pip
green = 10 pip
green = 5 pip
green = 5 pip
red = 10 pip
This is a MAJOR problem. I can see i am not the first to mention this, and that the developer dont think its a problem. But if you set a renko chart to be 5 pips, then ALL the boxes needs to be 5 pip.
The truth is everytime the color change, 1 box is missing, and this makes a trading problem. Especially if you use it with high pip setting like 20 or 50. Then you have 50 pips missing and it creates the potensial for double loss.
I will be happy to pay anyone to fix this bug. Until its fixed, all should be warned about using this indicator.
If you are a developer who can fix this, please contact me:
larsonsteffensen (a) gmail.com
tmc - great job!
How can I create rule to trade on the creations of new brick?
It Repaints ?
Great Indicator ! Thank you
However, cannot get it to work in the tester using my cBot ...
Code:
using System;
using System.Linq;
using cAlgo.API;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;
using cAlgo.Indicators;
namespace cAlgo
{
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
public class RenkoBot : Robot
{
[Parameter("RenkoPips", DefaultValue = 10, MinValue = 2, Step = 2)]
public double RenkoPips { get; set; }
[Parameter("Quantity (Lots)", DefaultValue = 1, MinValue = 0.01, Step = 0.01)]
public double Quantity { get; set; }
private Renko mr_indi;
protected override void OnStart()
{
mr_indi = Indicators.GetIndicator<Renko>(RenkoPips, 100, 3, "SeaGreen", "Tomato");
}
protected override void OnTick()
{
var longPosition = Positions.Find("Renko", Symbol, TradeType.Buy);
var shortPosition = Positions.Find("Renko", Symbol, TradeType.Sell);
bool lastTwoBarsBullish = mr_indi.Open.Last(1) < mr_indi.Close.Last(1);
bool lastTwoBarsBearish = mr_indi.Open.Last(1) > mr_indi.Close.Last(1);
if (lastTwoBarsBullish && longPosition == null)
{
if (shortPosition != null)
ClosePosition(shortPosition);
ExecuteMarketOrder(TradeType.Buy, Symbol, 10000, "Renko");
}
else if (lastTwoBarsBearish && shortPosition == null)
{
if (longPosition != null)
ClosePosition(longPosition);
ExecuteMarketOrder(TradeType.Sell, Symbol, 10000, "Renko");
}
}
}
}
A very valuable job, thank you!
I don't see any problem.
http://octafx.ctrader.com/images/screens/Lzwbn.png
look at image problem
@majesamade What problem exactly?
i have problem http://octafx.ctrader.com/images/screens/Lzwbn.png
@tmc: Hi tmc, I did not see the accuracy notes, my fault :) Nice job, thank you!
@marciogarcia : As I stated in "Accuracy" above, when the indicator is loaded it can access only OHLC values of historical data. So if you left indicator running a while, it got fed by tick data and might plot some candles that you can't read from OHLC values only. When you refreshed the chart those candles may disappeared due to lack of data.
If I change the time frame from M5 to M15 and then change again to M5 the renko bricks appears different. Is that normal?
IE: M5 => In a up trend, we have a formation with 1 brick up and 1 brick down and then some bricks up... If I change the time frame from M5 to M15 and then return to M5, it will appear only up bricks. Is it supposed to be like that?
A very valuable job, thank you!
@tmc : Thanks mate. I suppose i would have preferred the first way rather than second one.
@trend_meanreversion: Not really. I was studying renko on multiple platforms and they all work just like that. The price needs to surpass the top or bottom of the previous brick by a predefined amount in order to make new brick.
Otherwise, the chart would like something like that.
- ⍁⍂
- ⍁ ⍂
Instead of.
- ⍁
- ⍁ ⍂
@tmc : I am not an expert but i think once you have a sell brick followed by buy brick then that buy brick should also be displayed. Currently a sell brick is followed by buy brick only when you have a move of 2*RenkoPips ie..price of 100 -> 95 -> 100 -> 105 => we should have sell , buy and buy brick but currently indicator draws sell(100->95) and buy(100->105) brick only ( misses the 95->100 move )
@tmc : let me do some testing this week and i will get back to you if i still find the initial issue. I am thinking of trying RSI on this Renko, to come up with some strategy. Let's see how it goes.
@trend_meanreversion I guess you were talking about another issue I came across today and fixed. Please download updated version. ;)
@trend_meanreversion Thank you for reporting that issue. Outputs are fixed now and Open/Close.LastValue should return value now.
Thanks TMC for the indicator but it is not generating renko real time. It seems there is 1 brick delay. I have sent you an email , please respond when you get time.
Please, download latest version for better performance. ;)
Nice job Jiri, thanks.
hello
can u Update this indicator to show “shadow” of renko chart or "Renko Wicks" chart please
like renko chart in gocharting