Renko free

by Jiri in category Trend at 24/01/2016
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.

 

 

Notification Publishing copyrighted material is strictly prohibited. If you believe there is copyrighted material in this section you may use the Copyright Infringement Notification form to submit a claim.
Formula / Source Code
Language: C#
Trading Platform: cAlgocTrader
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;
        }
    }
}
Comments

Jiri - February 02, 2016 @ 14:16

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

  •    ⍁
  • ⍁   ⍂

fouadmail - December 21, 2016 @ 00:48

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

        }



    }
}
















 

ceakuk - March 28, 2018 @ 23:05

@didpenny

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

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

mapseam - November 21, 2018 @ 10:10

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