FVG - SIBI BISI free

by eyeballpaul in category Other at 04/04/2021
Description

The indicator identifies gaps between the open and close of candles and highlights where price has been offered on one side only.

 The gap setting is best set at the overnight spread - ie on GBPUSD set to 11 pips min. 

The Zone is best set to your particular brokers spread on that pair.

HOW TO USE

All based on the belief that price is being delivered by IPDA ( Interbank Price Delivery Algorithm).

The algorithm is designed to offer price on both sides, this indicator is just a visual way of highlighting where price has only been delivered on one side.

Tips:

Leaving history on you will see that areas have an efficacy at the previous swing and if you are quick enough on the trigger can even play in the 1minTF.

Best to use in traditional top down analysis TF, Weekly / Daily  / 1 hr.

Credit for programming to Jiri @ Poshtrader. 

 

Example settings for 1 min TF (GBPUSD )

 

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 System;
using System.Collections.Generic;
using cAlgo.API;
using cAlgo.API.Internals;

namespace cAlgo
{
    public static class License
    {
        private static readonly DateTime Expiration = new DateTime(2021, 12, 31);

        public static bool IsValid(Algo algo)
        {
            return algo.Server.TimeInUtc.Date <= Expiration;
        }
    }

    [Indicator(IsOverlay = true, TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class SideImbalance : Indicator
    {
        [Parameter("Min Size (Pips)", Group = "Overnight Spread", DefaultValue = 0, MinValue = 0, Step = 0.1)]
        public double GapMinSizePips { get; set; }

        [Parameter("Color", Group = "Overnight Spread", DefaultValue = "Lime")]
        public string GapColor { get; set; }

        [Parameter("Opacity", Group = "Overnight Spread", DefaultValue = 50, MinValue = 0, MaxValue = 100, Step = 1)]
        public double GapOpacity { get; set; }

        [Parameter("Remove History?", Group = "Overnight Spread")]
        public bool GapRemoveHistory { get; set; }

        [Parameter("Min Size (Pips)", Group = "Zone", DefaultValue = 0, MinValue = 0, Step = 0.1)]
        public double ZoneMinSizePips { get; set; }

        [Parameter("Break by wicks?", Group = "Zone")]
        public bool ZoneBreakByWicks { get; set; }

        [Parameter("Up Color", Group = "Zone", DefaultValue = "DodgerBlue")]
        public string ZoneUpColor { get; set; }

        [Parameter("Down Color", Group = "Zone", DefaultValue = "Magenta")]
        public string ZoneDownColor { get; set; }

        [Parameter("Opacity", Group = "Zone", DefaultValue = 30, MinValue = 0, MaxValue = 100, Step = 1)]
        public double ZoneOpacity { get; set; }

        [Parameter("Remove History?", Group = "Zone")]
        public bool ZoneRemoveHistory { get; set; }

        [Parameter("Thickness", Group = "Zone Line", DefaultValue = 1, MinValue = 1)]
        public int ZoneLineThickness { get; set; }

        [Parameter("Style", Group = "Zone Line", DefaultValue = LineStyle.Solid)]
        public LineStyle ZoneLineStyle { get; set; }

        [Parameter("Opacity", Group = "Zone Line", DefaultValue = 100, MinValue = 0, MaxValue = 255, Step = 1)]
        public double LineOpacity { get; set; }

        private class Colors
        {
            public Color GapZone { get; set; }
            public Color GapLine { get; set; }
            public Color UpZone { get; set; }
            public Color UpLine { get; set; }
            public Color DownZone { get; set; }
            public Color DownLine { get; set; }

            public static Color Get(string color, double opacity)
            {
                var baseColor = color[0] == '#' ? Color.FromHex(color) : Color.FromName(color);
                return Color.FromArgb((int)(opacity * 2.55), baseColor.R, baseColor.G, baseColor.B);
            }
        }

        public class Zone
        {
            public bool IsGap { get; set; }
            public ChartTrendLine Line { get; set; }
            public ChartRectangle Rectangle { get; set; }
            public List<ChartRectangle> Rectangles { get; set; }
        }

        public List<Zone> UpZones, DownZones;

        private int _index;
        private double _gapMinSize, _zoneMinSize;
        private Colors _colors;

        protected override void Initialize()
        {
            if (!License.IsValid(this))
                return;

            UpZones = new List<Zone>();
            DownZones = new List<Zone>();

            _gapMinSize = GapMinSizePips * Symbol.PipSize;
            _zoneMinSize = ZoneMinSizePips * Symbol.PipSize;
            _colors = new Colors 
            {
                GapZone = Colors.Get(GapColor, GapOpacity),
                GapLine = Colors.Get(GapColor, LineOpacity),
                UpZone = Colors.Get(ZoneUpColor, ZoneOpacity),
                UpLine = Colors.Get(ZoneUpColor, LineOpacity),
                DownZone = Colors.Get(ZoneDownColor, ZoneOpacity),
                DownLine = Colors.Get(ZoneDownColor, LineOpacity)
            };
        }

        public override void Calculate(int index)
        {
            if (!License.IsValid(this))
                return;

            if (index < 3)
                return;

            if (ZoneBreakByWicks)
                BreakZonesByBar(Bars[index]);

            if (_index < index)
            {
                _index = index;

                if (!ZoneBreakByWicks)
                    BreakZonesByBar(Bars[index - 1]);

                OnBarClosed(index - 1);
                BreakZonesByBar(Bars[index]);
            }
        }

        private void OnBarClosed(int index)
        {
            var bars = new[] 
            {
                Bars[index],
                Bars[index - 1],
                Bars[index - 2]
            };

            if (Math.Abs(bars[0].Open - bars[1].Close) >= _gapMinSize)
            {
                var max = Math.Max(bars[0].Open, bars[1].Close);
                var min = Math.Min(bars[0].Open, bars[1].Close);

                DrawGap("gap", index, min, max, bars[0].Close > (min + max) / 2);
            }

            if (bars[1].Low - bars[0].High >= _zoneMinSize)
            {
                DrawGap("a-down-zone", index, bars[0].High, bars[1].Low, false);
            }

            if (bars[2].Low - bars[0].High >= _zoneMinSize)
            {
                DrawGap("b-down-zone", index, bars[0].High, bars[2].Low, false);
            }

            if (bars[0].Low - bars[1].High >= _zoneMinSize)
            {
                DrawGap("a-up-zone", index, bars[1].High, bars[0].Low, true);
            }

            if (bars[0].Low - bars[2].High >= _zoneMinSize)
            {
                DrawGap("b-up-zone", index, bars[2].High, bars[0].Low, true);
            }
        }

        private void DrawGap(string tag, int index, double y1, double y2, bool isUpZone)
        {
            var isGap = tag.Contains("gap");

            var time1 = Bars[index].OpenTime;
            var time2 = Time.AddYears(100);

            Color zoneColor, lineColor;

            if (isGap)
            {
                zoneColor = _colors.GapZone;
                lineColor = _colors.GapLine;
            }
            else if (isUpZone)
            {
                zoneColor = _colors.UpZone;
                lineColor = _colors.UpLine;
            }
            else
            {
                zoneColor = _colors.DownZone;
                lineColor = _colors.DownLine;
            }

            tag = index + "_" + tag;

            var median = (y1 + y2) / 2;
            var line = Chart.DrawTrendLine("line_" + tag, time1, median, time2, median, lineColor, ZoneLineThickness, ZoneLineStyle);
            line.ExtendToInfinity = true;

            var zone = Chart.DrawRectangle("zone_" + tag, time1, y1, time2, y2, zoneColor, 0);
            zone.IsFilled = true;
            zone.ZIndex = -100;

            var rect = Chart.DrawRectangle(tag, time1, y1, time2, y2, zoneColor, 0);
            rect.IsFilled = true;
            rect.ZIndex = -1;

            if (isUpZone)
            {
                UpZones.Add(new Zone 
                {
                    IsGap = isGap,
                    Line = line,
                    Rectangle = rect,
                    Rectangles = new List<ChartRectangle> 
                    {
                        zone
                    }
                });
            }
            else
            {
                DownZones.Add(new Zone 
                {
                    IsGap = isGap,
                    Line = line,
                    Rectangle = rect,
                    Rectangles = new List<ChartRectangle> 
                    {
                        zone
                    }
                });
            }
        }

        private void BreakZonesByBar(Bar bar)
        {
            var time = bar.OpenTime;
            var upBreakPrice = Math.Min(bar.Open, bar.Close);
            var downBreakPrice = Math.Max(bar.Open, bar.Close);

            foreach (var zone in UpZones.ToArray())
            {
                var breaker = !zone.IsGap && ZoneBreakByWicks ? bar.Low : upBreakPrice;
                var removeHistory = zone.IsGap ? GapRemoveHistory : ZoneRemoveHistory;

                if (zone.Rectangles[0].Y2 <= breaker)
                    continue;

                var rect = zone.Rectangles[0];
                rect.Time2 = time;

                if (rect.Y1 < breaker - _zoneMinSize + Symbol.TickSize)
                {
                    var newRect = Chart.DrawRectangle(rect.Name + "X", time, rect.Y1, time.AddYears(100), breaker, rect.Color, 0);
                    newRect.IsFilled = true;
                    newRect.ZIndex = -1;

                    zone.Rectangles.Insert(0, newRect);
                }
                else
                {
                    if (removeHistory)
                    {
                        zone.Rectangles.ForEach(x => Chart.RemoveObject(x.Name));
                        Chart.RemoveObject(zone.Line.Name);
                        Chart.RemoveObject(zone.Rectangle.Name);
                    }
                    else
                    {
                        zone.Line.Time2 = time;
                        zone.Line.ExtendToInfinity = false;

                        zone.Rectangles.Clear();
                        zone.Rectangle.Time2 = time;
                    }

                    UpZones.Remove(zone);
                }
            }

            foreach (var zone in DownZones.ToArray())
            {
                var breakPrice = !zone.IsGap && ZoneBreakByWicks ? bar.High : downBreakPrice;
                var removeHistory = zone.IsGap ? GapRemoveHistory : ZoneRemoveHistory;

                if (zone.Rectangles[0].Y1 >= breakPrice)
                    continue;

                var rect = zone.Rectangles[0];
                rect.Time2 = time;

                if (rect.Y2 > breakPrice + _zoneMinSize - Symbol.TickSize)
                {
                    var newRect = Chart.DrawRectangle(rect.Name + "X", time, breakPrice, time.AddYears(10), rect.Y2, rect.Color, 0);
                    newRect.IsFilled = true;
                    newRect.ZIndex = -1;

                    zone.Rectangles.Insert(0, newRect);
                }
                else
                {
                    if (removeHistory)
                    {
                        zone.Rectangles.ForEach(x => Chart.RemoveObject(x.Name));
                        Chart.RemoveObject(zone.Line.Name);
                        Chart.RemoveObject(zone.Rectangle.Name);
                    }
                    else
                    {
                        zone.Line.Time2 = time;
                        zone.Line.ExtendToInfinity = false;

                        zone.Rectangles.Clear();
                        zone.Rectangle.Time2 = time;
                    }

                    DownZones.Remove(zone);
                }
            }
        }
    }
}
Comments
0