Category Other  Published on 21/03/2022

Go To Date

Description

This indicator allows you to easily and quickly scroll your chart to a specific time, you just have to pass the time and it will scroll back your chart to your passed time value.

Features

  • It doesn't occupy any space on your chart, you can show/hide it with an hotkey
  • It doesn't consume any system resource while it's attached on your chart
  • Automatically adjusts itself with your cTrader time zone
  • Uses cTrader chart controls and works like a built-in feature
  • You can change the hotkey to any of your keyboard keys
  • You can change the location of it's input box

When you are setting the hotkey be sure that your selected keys aren't used by any other cTrader hotkeys, otherwise it will not work.

You can disable the hotkey mode in case if you want to always have access to that indicator input box, when hotkey is active it only appears if you press the hotkey.

This indicator is open source, if you want to improve it create a PR on it's Github repository: spotware/Go-To-Date: A cTrader desktop indicator that allows you to easily scroll back the chart to a specific date (github.com)


using System;
using cAlgo.API;
using System.Collections.Concurrent;
using System.Globalization;

namespace cAlgo
{
    [Indicator(IsOverlay = true, TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class GoToDate : Indicator
    {
        private const string _timeFormat = "yyyy/MM/dd HH:mm:ss";

        private static ConcurrentDictionary<string, string> _timeCache = new ConcurrentDictionary<string, string>();

        private TextBox _textBox;

        private string _chartKey;

        private StackPanel _mainPanel;

        private TextBlock _errorMessageTextBlock;

        [Parameter("Horizontal Alignment", DefaultValue = HorizontalAlignment.Left, Group = "Panel")]
        public HorizontalAlignment HorizontalAlignment { get; set; }

        [Parameter("Vertical Alignment", DefaultValue = VerticalAlignment.Top, Group = "Panel")]
        public VerticalAlignment VerticalAlignment { get; set; }

        [Parameter("Opacity", DefaultValue = 1, MinValue = 0, MaxValue = 1, Group = "Panel")]
        public double Opacity { get; set; }

        [Parameter("Active", DefaultValue = true, Group = "Hotkey")]
        public bool IsHotkeyActive { get; set; }

        [Parameter("Key", DefaultValue = Key.G, Group = "Hotkey")]
        public Key Hotkey { get; set; }

        [Parameter("Modifier Key", DefaultValue = ModifierKeys.Shift, Group = "Hotkey")]
        public ModifierKeys HotkeyModifierKey { get; set; }

        protected override void Initialize()
        {
            _chartKey = string.Format("{0}_{1}_{2}", SymbolName, TimeFrame, Chart.ChartType);

            _textBox = new TextBox 
            {
                Margin = 2,
                MinWidth = 130
            };

            var button = new Button 
            {
                Text = "Go To",
                Margin = 2
            };

            button.Click += Button_Click;

            var panel = new StackPanel 
            {
                Orientation = Orientation.Horizontal
            };

            panel.AddChild(_textBox);
            panel.AddChild(button);

            _mainPanel = new StackPanel 
            {
                Orientation = Orientation.Vertical,
                HorizontalAlignment = HorizontalAlignment,
                VerticalAlignment = VerticalAlignment,
                Margin = 2,
                Opacity = Opacity
            };

            _errorMessageTextBlock = new TextBlock 
            {
                FontWeight = FontWeight.Bold
            };

            _mainPanel.AddChild(panel);
            _mainPanel.AddChild(_errorMessageTextBlock);

            Chart.AddControl(_mainPanel);

            string timeString;

            if (_timeCache.TryGetValue(_chartKey, out timeString))
            {
                DateTime time;

                var timeStringSplit = timeString.Split('|');

                if (timeStringSplit.Length != 2 || DateTime.TryParseExact(timeStringSplit[0], _timeFormat, CultureInfo.InvariantCulture, DateTimeStyles.AllowWhiteSpaces, out time) == false)
                {
                    _textBox.Text = GetCurrentTime();

                    _timeCache.TryRemove(_chartKey, out timeString);
                }
                else
                {
                    var utcTime = GetUtcTime(time, timeStringSplit[1]);

                    _textBox.Text = timeStringSplit[0];

                    if (Bars[0].OpenTime > utcTime)
                    {
                        LoadMoreBars();
                    }
                    else if (utcTime.HasValue)
                    {
                        GoTo(utcTime.Value);
                    }
                }
            }
            else
            {
                _textBox.Text = GetCurrentTime();
            }

            if (IsHotkeyActive)
            {
                Chart.AddHotkey(OnHotkey, Hotkey, HotkeyModifierKey);

                _mainPanel.IsVisible = false;
            }
        }

        private void OnHotkey()
        {
            _mainPanel.IsVisible = !_mainPanel.IsVisible;
        }

        private void Button_Click(ButtonClickEventArgs obj)
        {
            DateTime time;

            if (DateTime.TryParseExact(_textBox.Text, _timeFormat, CultureInfo.InvariantCulture, DateTimeStyles.AllowWhiteSpaces, out time) == false)
            {
                _errorMessageTextBlock.Text = string.Format("Invalid date: {0}, please use this exact format: {1}", _textBox.Text, _timeFormat);

                return;
            }

            var timeString = string.Format("{0}|{1}", time.ToString(_timeFormat, CultureInfo.InvariantCulture), Application.UserTimeOffset);

            _timeCache.AddOrUpdate(_chartKey, timeString, (key, value) => timeString);

            var utcTime = GetUtcTime(time, Application.UserTimeOffset.ToString());

            if (Bars[0].OpenTime > utcTime)
            {
                LoadMoreBars();
            }
            else if (utcTime.HasValue)
            {
                GoTo(utcTime.Value);
            }
        }

        private void LoadMoreBars()
        {
            var loadedBarsNumber = Bars.LoadMoreHistory();

            if (loadedBarsNumber == 0)
            {
                _errorMessageTextBlock.Text = string.Format("Data not available for: {0}", _textBox.Text);
            }
        }

        private void GoTo(DateTime utcTime)
        {
            if (utcTime > Server.TimeInUtc)
            {
                _errorMessageTextBlock.Text = string.Format("Invalid date (Future): {0}", _textBox.Text);
            }
            else
            {
                _timeCache.AddOrUpdate(_chartKey, _timeFormat, (key, value) => string.Format("{0}|1", value));

                Chart.ScrollXTo(utcTime);

                if (IsHotkeyActive)
                {
                    _mainPanel.IsVisible = false;
                }
            }
        }

        private DateTime? GetUtcTime(DateTime dateTime, string offsetString)
        {
            TimeSpan offset;

            if (TimeSpan.TryParse(offsetString, out offset) == false)
            {
                return null;
            }

            var dateTimeOffset = new DateTimeOffset(dateTime.Year, dateTime.Month, dateTime.Day, dateTime.Hour, dateTime.Minute, dateTime.Second, offset);

            return dateTimeOffset.UtcDateTime;
        }

        private string GetCurrentTime()
        {
            var currentUtc = new DateTimeOffset(Server.TimeInUtc.Year, Server.TimeInUtc.Month, Server.TimeInUtc.Day, Server.TimeInUtc.Hour, Server.TimeInUtc.Minute, Server.TimeInUtc.Second, TimeSpan.FromSeconds(0));

            return currentUtc.ToOffset(Application.UserTimeOffset).DateTime.ToString(_timeFormat, CultureInfo.InvariantCulture);
        }

        public override void Calculate(int index)
        {
        }
    }
}


Spotware's avatar
Spotware

Joined on 23.09.2013

  • Distribution: Free
  • Language: C#
  • Trading platform: cTrader Automate
  • File name: Go To Date.algo
  • Rating: 5
  • Installs: 2452
Comments
Log in to add a comment.
OC
ochsendorf.p · 1 year ago

Thank you and its working.

Press the Modifier Key + Key and it will popup. Write in the date and press go to.

Thanks, it helps alot.

TV
tvan07 · 1 year ago

Hey, this is very useful to analyze specific time, but it doesn't work on version 4.2.22.10221. is there any update for this?

CO
coloringpages44 · 2 years ago

excellent, congratulations coloring pages

NA
nancydrewsub · 2 years ago

 I am just amazed. I hope that you continue to do your work like this in the future also subway surfers