Go To Date free

by Spotware in category Other at 21/03/2022
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)

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 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)
        {
        }
    }
}
Comments

nancydrewsub - March 24, 2022 @ 09:08

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

ameliajonesphd - April 20, 2022 @ 23:39

Thanks for sharing this is such great information that you are providing and you give it away for free.

Take Your Class

jackkytran204 - April 23, 2022 @ 11:18

If you're searching for something adventurous, exhilarating, but yet soothing and entertaining, go no further. If you're anxious and bored, what should you do? bob the robber is the game you've been searching for. This game provides a truly unique experience. Try it out right now. Note this, don't get addicted.

dorianggg057 - April 29, 2022 @ 18:23

I can't seem to put together an essay despite my best efforts. To get out of this dilemma, I realized that my prior efforts had failed. Academic writers www.collegessaywriter.com/college-paper-help/ can be hired through websites like this one. I embarked on a search for an answer to my question.

coloringpages44 - May 19, 2022 @ 10:59

excellent, congratulations coloring pages

patrickrall - July 12, 2022 @ 20:12

Hey, this page is relevant to the search query! The user has found the information they were looking for! 

hoodm1947 - July 28, 2022 @ 22:23

Thank you for posting. I could not have done this writing assignment without more help. In general, the study of programming is quite interesting. I am educated in this field and now I need help from a letter of recommendation writing service. I need to get a good job and I don't have a letter of recommendation.

nobit2021 - August 29, 2022 @ 10:15

Your writing is excellent, so allow me to share a little of myself. One of the best available limitless running games is wheel spinner. Control your ball as you compete in a fast ramp race to see how far you can climb the leaderboard.

Swenyly - September 12, 2022 @ 10:50

The article with the algorithm is a bit confusing, can anyone help me fleeing the complex?

junealexis001 - September 12, 2022 @ 12:10

Great site i love it keep posting more!   https://fencingyakimawa.com

5