Auto Drawings

by Bart A in category Other at 29/10/2019
Description

How to use:
1) Select bars using Ctrl + Mouse 
2) Choose desired drawing in selected area: fibonacci, min/max price level, or support/resistance trend line.

 

Algorhitm to place trend lines is pretty dumb. It simply draw a line between left and right extremums (when high or low exceed its neigbours).
If you know better ideas, please advice.

Please share your ideas, what to add to this indicator.

Download
252 downloads
How to install
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 cAlgo.API;
using cAlgo.API.Internals;
using cAlgo.API.Indicators;
using cAlgo.Indicators;
using System.Collections.Generic;
using System.Linq;

namespace cAlgo
{
    [Indicator(IsOverlay = true, TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class AutoDrawings : Indicator
    {
        [Parameter("Drawings Color", DefaultValue = "99DFF9")]
        public string DrawingsColor { get; set; }

        [Parameter("Selection Color", DefaultValue = "2F68D0F7")]
        public string SelectionleColor { get; set; }

        ChartRectangle SelectRectangle;
        int SelectedStartBarIndex;
        int SelectedEndBarIndex;
        decimal[] DefaultFiboLevels = new[] 
        {
            0.0m,
            23.6m,
            38.2m,
            50.0m,
            61.8m,
            100.0m
        };

        ControlBase DrawingDialog;

        protected override void Initialize()
        {
            Chart.MouseDown += Chart_MouseDown;
            Chart.MouseUp += Chart_MouseUp;
            Chart.MouseMove += Chart_MouseMove;

            CreateDrawingDialog();
        }

        private void CreateDrawingDialog()
        {
            var stackPanel = new StackPanel 
            {
                VerticalAlignment = VerticalAlignment.Top,
                HorizontalAlignment = HorizontalAlignment.Left,
                Orientation = Orientation.Vertical,
                IsVisible = false,
                Width = 160,
                BackgroundColor = "#707070"
            };

            var fibonacciRetracementButton = new Button 
            {
                Text = "Fibonacci Retracement",
                HorizontalContentAlignment = HorizontalAlignment.Left
            };

            var supportTrendLineButton = new Button 
            {
                Text = "Support Trend Line",
                HorizontalContentAlignment = HorizontalAlignment.Left
            };

            var resistanceTrendLineButton = new Button 
            {
                Text = "Resistance Trend Line",
                HorizontalContentAlignment = HorizontalAlignment.Left
            };

            var supportLevelButton = new Button 
            {
                Text = "Support Level",
                HorizontalContentAlignment = HorizontalAlignment.Left
            };

            var resistanceLevelButton = new Button 
            {
                Text = "Resistance Level",
                HorizontalContentAlignment = HorizontalAlignment.Left
            };

            fibonacciRetracementButton.Click += FibonacciRetracementButton_Click;
            supportTrendLineButton.Click += SupportTrendLineButton_Click;
            resistanceTrendLineButton.Click += ResistanceTrendLineButton_Click;
            supportLevelButton.Click += SupportLevelButton_Click;
            resistanceLevelButton.Click += ResistanceLevelButton_Click;

            stackPanel.AddChild(fibonacciRetracementButton);
            stackPanel.AddChild(supportTrendLineButton);
            stackPanel.AddChild(resistanceTrendLineButton);
            stackPanel.AddChild(supportLevelButton);
            stackPanel.AddChild(resistanceLevelButton);

            DrawingDialog = stackPanel;
            Chart.AddControl(DrawingDialog);
        }

        private void FibonacciRetracementButton_Click(ButtonClickEventArgs obj)
        {
            var extremums = GetHighLowInSelection();
            var name = string.Format("Fibonacci Retracement [Auto Drawing] {0}", DateTime.Now.ToString("dd.MM.yy HH:mm:ss.zzz"));
            var point1 = extremums.Point1.BarIndex < extremums.Point2.BarIndex ? extremums.Point1 : extremums.Point2;
            var point2 = extremums.Point1.BarIndex < extremums.Point2.BarIndex ? extremums.Point2 : extremums.Point1;
            var fibo = Chart.DrawFibonacciRetracement(name, point1.BarIndex, point1.Price, point2.BarIndex, point2.Price, DrawingsColor);
            fibo.IsInteractive = true;
            fibo.DisplayPrices = false;
            SetDefaultFiboLevels(fibo.FibonacciLevels);
            CloseDrawingDialog();
        }

        private void SetDefaultFiboLevels(IEnumerable<FibonacciLevel> levels)
        {
            foreach (var level in levels)
            {
                level.IsVisible = Array.IndexOf(DefaultFiboLevels, (decimal)level.PercentLevel) > -1;
            }
        }

        private void ResistanceTrendLineButton_Click(ButtonClickEventArgs obj)
        {
            var extremums = GetFirstLastHighExtremumsInSelection();
            var point1 = extremums.Point1.BarIndex < extremums.Point2.BarIndex ? extremums.Point1 : extremums.Point2;
            var point2 = extremums.Point1.BarIndex < extremums.Point2.BarIndex ? extremums.Point2 : extremums.Point1;
            var name = string.Format("Resistance Trend Line [Auto Drawing] {0}", DateTime.Now.ToString("dd.MM.yy HH:mm:ss.zzz"));
            var line = Chart.DrawTrendLine(name, point1.BarIndex, point1.Price, point2.BarIndex, point2.Price, DrawingsColor);
            line.IsInteractive = true;
            line.ExtendToInfinity = true;
            CloseDrawingDialog();
        }

        private void SupportTrendLineButton_Click(ButtonClickEventArgs obj)
        {
            var extremums = GetFirstLastLowExtremumsInSelection();
            var point1 = extremums.Point1.BarIndex < extremums.Point2.BarIndex ? extremums.Point1 : extremums.Point2;
            var point2 = extremums.Point1.BarIndex < extremums.Point2.BarIndex ? extremums.Point2 : extremums.Point1;
            var name = string.Format("Support Trend Line [Auto Drawing] {0}", DateTime.Now.ToString("dd.MM.yy HH:mm:ss.zzz"));
            var line = Chart.DrawTrendLine(name, point1.BarIndex, point1.Price, point2.BarIndex, point2.Price, DrawingsColor);
            line.IsInteractive = true;
            line.ExtendToInfinity = true;
            CloseDrawingDialog();
        }

        private void ResistanceLevelButton_Click(ButtonClickEventArgs obj)
        {
            var maximum = GetMaximumInSelection();
            var name = string.Format("Resistance Level [Auto Drawing] {0}", DateTime.Now.ToString("dd.MM.yy HH:mm:ss.zzz"));
            var line = Chart.DrawHorizontalLine(name, maximum.Price, DrawingsColor);
            line.IsInteractive = true;
            CloseDrawingDialog();
        }

        private void SupportLevelButton_Click(ButtonClickEventArgs obj)
        {
            var minimum = GetMinimumInSelection();
            var name = string.Format("Support Level [Auto Drawing] {0}", DateTime.Now.ToString("dd.MM.yy HH:mm:ss.zzz"));
            var line = Chart.DrawHorizontalLine(name, minimum.Price, DrawingsColor);
            line.IsInteractive = true;
            CloseDrawingDialog();
        }

        private ChartPoint GetMaximumInSelection()
        {
            var priceMax = double.MinValue;
            int barIndexMax = -1;
            for (int i = SelectedStartBarIndex; i <= SelectedEndBarIndex; i++)
            {
                var high = MarketSeries.High[i];
                if (high > priceMax)
                {
                    priceMax = high;
                    barIndexMax = i;
                }
            }
            return new ChartPoint(barIndexMax, priceMax);
        }

        private ChartPoint GetMinimumInSelection()
        {
            var priceMin = double.MaxValue;
            int barIndexMin = -1;
            for (int i = SelectedStartBarIndex; i <= SelectedEndBarIndex; i++)
            {
                var low = MarketSeries.Low[i];
                if (low < priceMin)
                {
                    priceMin = low;
                    barIndexMin = i;
                }
            }
            return new ChartPoint(barIndexMin, priceMin);
        }

        private ChartPoints GetHighLowInSelection()
        {
            var priceMax = double.MinValue;
            var priceMin = double.MaxValue;
            int barIndexMin = -1;
            int barIndexMax = -1;
            for (int i = SelectedStartBarIndex; i <= SelectedEndBarIndex; i++)
            {
                var high = MarketSeries.High[i];
                var low = MarketSeries.Low[i];
                if (high > priceMax)
                {
                    priceMax = high;
                    barIndexMax = i;
                }
                if (low < priceMin)
                {
                    priceMin = low;
                    barIndexMin = i;
                }
            }

            var maximum = new ChartPoint(barIndexMax, priceMax);
            var minimum = new ChartPoint(barIndexMin, priceMin);
            return new ChartPoints(minimum, maximum);
        }

        private ChartPoints GetFirstLastHighExtremumsInSelection()
        {
            var highExtremums = new List<ChartPoint>();
            for (int i = SelectedStartBarIndex; i <= SelectedEndBarIndex; i++)
            {
                bool isExtremum = false;
                var currHigh = MarketSeries.High[i];

                if (i == 0 || i == MarketSeries.Close.Count - 1)
                {
                    isExtremum = true;
                }
                else
                {
                    var nextHigh = MarketSeries.High[i + 1];
                    var prevHigh = MarketSeries.High[i - 1];
                    isExtremum = currHigh > nextHigh && currHigh > prevHigh;
                }

                if (isExtremum)
                    highExtremums.Add(new ChartPoint(i, currHigh));
            }
            if (highExtremums.Count < 2)
                return null;

            return new ChartPoints(highExtremums.First(), highExtremums.Last());
        }

        private ChartPoints GetFirstLastLowExtremumsInSelection()
        {
            var lowExtremums = new List<ChartPoint>();
            for (int i = SelectedStartBarIndex; i <= SelectedEndBarIndex; i++)
            {
                bool isExtremum = false;
                var currLow = MarketSeries.Low[i];

                if (i == 0 || i == MarketSeries.Close.Count - 1)
                {
                    isExtremum = true;
                }
                else
                {
                    var nextLow = MarketSeries.Low[i + 1];
                    var prevLow = MarketSeries.Low[i - 1];
                    isExtremum = currLow < nextLow && currLow < prevLow;
                }

                if (isExtremum)
                    lowExtremums.Add(new ChartPoint(i, currLow));
            }
            if (lowExtremums.Count < 2)
                return null;

            return new ChartPoints(lowExtremums.First(), lowExtremums.Last());

        }

        private void Chart_MouseMove(ChartMouseEventArgs obj)
        {
            if (SelectRectangle == null)
                return;

            SelectRectangle.Time2 = obj.TimeValue;
        }

        private void Chart_MouseDown(ChartMouseEventArgs obj)
        {
            if (DrawingDialog.IsVisible)
            {
                CloseDrawingDialog();
            }

            if (obj.CtrlKey == false)
                return;

            Chart.IsScrollingEnabled = false;
            SelectRectangle = CreateDragRectangle(obj.TimeValue);
        }

        private void Chart_MouseUp(ChartMouseEventArgs obj)
        {
            Chart.IsScrollingEnabled = true;

            if (SelectRectangle != null)
            {
                SetSelectedStartEndIndex(SelectRectangle);
                Chart.RemoveObject(SelectRectangle.Name);
                SelectRectangle = null;

                if (SelectedStartBarIndex >= 0 && SelectedEndBarIndex >= 0)
                {
                    OpenDrawingDialog(obj.MouseX, obj.MouseY);
                }
            }
        }

        private void SetSelectedStartEndIndex(ChartRectangle rectangle)
        {
            var index1 = MarketSeries.OpenTime.GetIndexByTime(rectangle.Time1);
            var index2 = MarketSeries.OpenTime.GetIndexByTime(rectangle.Time2);
            SelectedStartBarIndex = Math.Min(index1, index2);
            SelectedEndBarIndex = Math.Max(index1, index2);
        }

        private void OpenDrawingDialog(double mouseX, double mouseY)
        {
            DrawingDialog.IsVisible = true;
            var left = Chart.Width - mouseX > 160 ? mouseX : mouseX - 160;
            var right = Chart.Height - mouseY > 100 ? mouseY : mouseY - 100;
            DrawingDialog.Margin = new Thickness(left, right, 0, 0);

        }

        private void CloseDrawingDialog()
        {
            DrawingDialog.IsVisible = false;
        }

        private ChartRectangle CreateDragRectangle(DateTime time)
        {
            var rect = Chart.DrawRectangle("DragRectangle", time, Chart.TopY, time, Chart.BottomY, SelectionleColor);
            rect.IsFilled = true;
            return rect;
        }

        public override void Calculate(int index)
        {
        }
    }

    class ChartPoint
    {
        public ChartPoint(int barIndex, double price)
        {
            BarIndex = barIndex;
            Price = price;
        }

        public int BarIndex { get; private set; }
        public double Price { get; private set; }
    }

    class ChartPoints
    {
        public ChartPoints(ChartPoint point1, ChartPoint point2)
        {
            Point1 = point1;
            Point2 = point2;
        }

        public ChartPoint Point1 { get; private set; }
        public ChartPoint Point2 { get; private set; }
    }
}
Comments

cysecsbin.01 - October 30, 2019 @ 00:32

You're a genius, thanks

massimiliano.quarti - October 30, 2019 @ 16:53

Not working for me, ctrl mouse is scrolling.

Which libraries are referenced?

Bart A - October 31, 2019 @ 09:24

Probably your broker has cTrader version 3.5. This indicator use custom UI from  the new version 3.6.

You can try it with Spotware cTrader
https://spotware.com/beta/

Yuri - November 15, 2019 @ 13:05

This is super cool!

5