Category Trend  Published on 12/05/2018

Renko

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's avatar
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
Log in to add a comment.
HA
hamid.dnd92 · 5 months ago

hello 

can u Update this indicator to show “shadow” of renko chart or "Renko Wicks"  chart please 

like renko chart in gocharting 


 

HA
hamid.dnd92 · 5 months ago

like renko chart in gocharting 

 

HA
hamid.dnd92 · 5 months ago

hello 

can u Update this indicator to show shadow of renko chart or weak of renko chart please 

DA
davidtrinh555@hotmail.com · 3 years ago

how can I add parabolic indicator to the renko bricks itself and not the candles?

 

AU
augrust · 5 years ago

hi problem download renko chart 

 

DelFonseca's avatar
DelFonseca · 5 years ago

Why changing timeframes, this renko indicator changes the bricks? It's not supposed, right?

SY
sylwester.guzek · 5 years ago

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

RO
robert.dms83@gmail.com · 5 years ago

its appear as indicator, not a chart type so price dont follow...

MA
mapseam · 5 years ago

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;
        // ...
    }
    }
}

MA
mapseam · 6 years ago

Thanx for you renko indi!

renko = Indicators.GetIndicator<Renko>(RenkoPips, BricksToShow, 3, "SeaGreen", "Tomato");
Buy renko.Bricks.Count() = 0.

Tell me please, why?

Jiri's avatar
Jiri · 6 years ago

Thanks for pointing this out, didn't notice it. :)

CE
ceakuk · 6 years ago

@didpenny

The right approach is below. its something @tmc. needs to correct

renko = Indicators.GetIndicator<Renko>(RenkoPips, BricksToShow, 3, "SeaGreen", "Tomato");

DI
didpenny · 6 years ago

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];

        }

 

Jiri's avatar
Jiri · 6 years ago

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.

TH
thierry · 6 years ago

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

CH
chiripacha · 7 years ago

MACD asks for the source. Just take Renko as the source.

JA
jadfakhoury@gmail.com · 7 years ago

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

LA
larsonsteffensen · 7 years ago

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

Jiri's avatar
Jiri · 7 years ago

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.

LA
larsonsteffensen · 7 years ago

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

 

 

 

LS
lsheytanov · 7 years ago

tmc - great job!
How can I create rule to trade on the creations of new brick?

FO
fouadmail · 7 years ago

It Repaints ?

FO
fouadmail · 7 years ago

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");
            }

        }



    }
}
















 

FO
fouadmail · 7 years ago

A very valuable job, thank you!

Jiri's avatar
Jiri · 8 years ago

I don't see any problem.

MA
majesamade · 8 years ago
Jiri's avatar
Jiri · 8 years ago

@majesamade What problem exactly?

MA
majesamade · 8 years ago

i have problem http://octafx.ctrader.com/images/screens/Lzwbn.png

MA
marciogarcia · 8 years ago

@tmc: Hi tmc, I did not see the accuracy notes, my fault :) Nice job, thank you!

Jiri's avatar
Jiri · 8 years ago

@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.

MA
marciogarcia · 8 years ago

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?

gainer's avatar
gainer · 8 years ago

A very valuable job, thank you!

TR
trend_meanreversion · 8 years ago

@tmc : Thanks mate. I suppose i would have preferred the first way rather than second one.

Jiri's avatar
Jiri · 8 years ago

@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.

  •    ⍁
  • ⍁   ⍂
TR
trend_meanreversion · 8 years ago

@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 )

TR
trend_meanreversion · 8 years ago

@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.

Jiri's avatar
Jiri · 8 years ago

@trend_meanreversion I guess you were talking about another issue I came across today and fixed. Please download updated version. ;)

Jiri's avatar
Jiri · 8 years ago

@trend_meanreversion Thank you for reporting that issue. Outputs are fixed now and Open/Close.LastValue should return value now.

TR
trend_meanreversion · 8 years ago

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.

Jiri's avatar
Jiri · 8 years ago

Please, download latest version for better performance. ;)

ClickAlgo's avatar
ClickAlgo · 8 years ago

Nice job Jiri, thanks.