Category Other  Published on 20/05/2022

Chart Analysis Saver

Description

This indicator saves your chart objects including indicator area objects and load it automatically when you re open the chart or manually if you press the hotkeys for loading the saved chart objects.

Saving

It works in both auto and manual, the auto save has two different modes:

  • OnChange: When an object is added/removed/changed it saves the chart
  • Interval: Keeps saving the chart based on a time interval you set

To manually save your chart objects you just have to press the hotkey you set for manual save, the default hotkey for manual save is Shift+S.

You can also save the chart objects on a file that you select, the save as function allows you to save the chart objects on any file you want to, it has an hotkey like manual save, the default hotkey for save as is Shift+A.

Loading

Indicator saves the chart objects on your system cAlgo folder, the path to saved chart files is: documents/calgo/charts

Each saved chart has it own ".cchart" file, the file name is in this format: AccountNumber-SymbolName-TimeFrame-ChartType.cchart

By using the above naming format indicator keeps each of your charts separate on their own files.

To load a saved chart you can use either auto load, manual load, or open as functions.

If you enable auto load indicator will load the chart objects from its saved file whenever the indicator initializes.

The manual load function allows you to load the chart whenever you want to, you just have to press the manual load hotkey, the default hotkey for manual load is Shift+L.

You can also open a saved chart file by using Open as option like Save as option, just press the Open As hotkey and select the chart file you want to load.

It has an hotkey for opening the charts folder on your file explorer, to open the folder press the "Charts Folder Hotkey", it will automatically select the current chart file if there was any.

When setting hotkeys be sure it will not interfere with cTrader hotkeys, otherwise the hotkey will not work.

This indicator is open source, feel free to fork and improve it: spotware/Chart-Analysis-Saver: This indicator saves / loads cTrader chart objects (github.com)


using System;
using cAlgo.API;
using System.Globalization;
using cAlgo.ChartObjectModels;
using System.IO;
using System.Linq;
using cAlgo.Helpers;
using System.Threading;
using System.Diagnostics;
using System.Windows.Forms;

namespace cAlgo
{
    [Indicator(IsOverlay = true, TimeZone = TimeZones.UTC, AccessRights = AccessRights.FullAccess)]
    public class ChartAnalysisSaver : Indicator
    {
        private TimeSpan _autoSaveInterval;

        private string _chartsDirectoryPath;

        [Parameter("Enable", DefaultValue = false, Group = "Auto Save")]
        public bool IsAutoSaveEnabled { get; set; }

        [Parameter("Mode", DefaultValue = AutoSaveMode.OnChange, Group = "Auto Save")]
        public AutoSaveMode AutoSaveMode { get; set; }

        [Parameter("Interval", DefaultValue = "00:01:00", Group = "Auto Save")]
        public string AutoSaveInterval { get; set; }

        [Parameter("Enable", DefaultValue = false, Group = "Auto Load On Start")]
        public bool IsAutoLoadEnabled { get; set; }

        [Parameter("Only Interactive", DefaultValue = true, Group = "Save")]
        public bool SaveOnlyInteractive { get; set; }

        [Parameter("Remove All Before Load", DefaultValue = false, Group = "Load")]
        public bool RemoveAllBeforeLoad { get; set; }

        [Parameter("Only Interactive", DefaultValue = true, Group = "Load")]
        public bool LoadOnlyInteractive { get; set; }

        [Parameter("Key", DefaultValue = Key.S, Group = "Manual Save Hotkey")]
        public Key ManualSaveKey { get; set; }

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

        [Parameter("Key", DefaultValue = Key.A, Group = "Save As Hotkey")]
        public Key SaveAsKey { get; set; }

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

        [Parameter("Key", DefaultValue = Key.L, Group = "Manual Load Hotkey")]
        public Key ManualLoadKey { get; set; }

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

        [Parameter("Key", DefaultValue = Key.O, Group = "Open As Hotkey")]
        public Key OpenAsKey { get; set; }

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

        [Parameter("Key", DefaultValue = Key.D, Group = "Remove All Hotkey")]
        public Key RemoveAllKey { get; set; }

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

        [Parameter("Only Interactive", DefaultValue = true, Group = "Remove All Hotkey")]
        public bool RemoveAllOnlyInteractive { get; set; }

        [Parameter("Key", DefaultValue = Key.F, Group = "Charts Folder Hotkey")]
        public Key ChartsFolderKey { get; set; }

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

        protected override void Initialize()
        {
            SetupChartsDirectory();

            Chart.AddHotkey(args => SaveChart(), ManualSaveKey, ManualSaveModifierKeys);
            Chart.AddHotkey(args => SaveChart(true), SaveAsKey, SaveAsModifierKeys);
            Chart.AddHotkey(args => LoadChart(), ManualLoadKey, ManualLoadModifierKeys);
            Chart.AddHotkey(args => LoadChart(true), OpenAsKey, OpenAsModifierKeys);
            Chart.AddHotkey(args => Chart.RemoveAllObjects(RemoveAllOnlyInteractive == false), RemoveAllKey, RemoveAllModifierKeys);
            Chart.AddHotkey(args => OpenChartsFolder(), ChartsFolderKey, ChartsFolderModifierKeys);

            if (IsAutoLoadEnabled)
            {
                LoadChart();
            }

            if (IsAutoSaveEnabled)
            {
                if (AutoSaveMode == AutoSaveMode.Time)
                {
                    if (TimeSpan.TryParse(AutoSaveInterval, CultureInfo.InvariantCulture, out _autoSaveInterval) == false)
                    {
                        Print("Invalid auto save interval: ", AutoSaveInterval);
                    }

                    Timer.Start(_autoSaveInterval);
                }
                else
                {
                    Chart.ObjectsAdded += args => SaveChart();
                    Chart.ObjectsRemoved += args => SaveChart();
                    Chart.ObjectsUpdated += args => SaveChart();
                }
            }
        }

        private void OpenChartsFolder()
        {
            var filePath = GetChartFilePath();

            if (File.Exists(filePath))
            {
                Process.Start("explorer.exe", string.Format("/select, {0}", filePath));
            }
            else
            {
                Process.Start("explorer.exe", string.Format("/open, {0}", _chartsDirectoryPath));
            }
        }

        public override void Calculate(int index)
        {
        }

        protected override void OnTimer()
        {
            SaveChart();
        }

        private void SaveChart(bool saveAs = false)
        {
            var objectModels = Chart.GetObjectModels();

            if (SaveOnlyInteractive)
            {
                objectModels = objectModels.Where(chartObject => chartObject.IsInteractive).ToArray();
            }

            var chartFilePath = GetChartFilePath(userSelectedFile: saveAs, isSaving: true);

            if (string.IsNullOrWhiteSpace(chartFilePath)) return;

            try
            {
                ChartObjectsSerializer.Serialize(objectModels, chartFilePath);
            }
            catch (IOException)
            {
                Thread.Sleep(3000);

                RefreshData();

                ChartObjectsSerializer.Serialize(objectModels, chartFilePath);
            }
        }

        private void LoadChart(bool openAs = false)
        {
            if (RemoveAllBeforeLoad)
            {
                Chart.RemoveAllObjects(LoadOnlyInteractive == false);
            }

            var chartFilePath = GetChartFilePath(userSelectedFile: openAs, isSaving: false);

            if (File.Exists(chartFilePath) == false || string.IsNullOrWhiteSpace(chartFilePath))
                return;

            var models = ChartObjectsSerializer.Deserialize(chartFilePath);

            if (LoadOnlyInteractive)
            {
                models = models.Where(model => model.IsInteractive).ToArray();
            }

            Chart.DrawModels(models);
        }

        private void SetupChartsDirectory()
        {
            var documentsPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);

            _chartsDirectoryPath = Path.Combine(documentsPath, "cAlgo", "Charts");

            if (Directory.Exists(_chartsDirectoryPath) == false)
            {
                Directory.CreateDirectory(_chartsDirectoryPath);
            }
        }

        private string GetChartFilePath(bool userSelectedFile = false, bool isSaving = true)
        {
            if (userSelectedFile == false)
            {
                return Path.Combine(_chartsDirectoryPath, string.Format("Chart-{0}-{1}-{2}-{3}.cchart", Account.Number, SymbolName, TimeFrame, Chart.ChartType));
            }
            else
            {
                var result = string.Empty;

                var thread = new Thread(() =>
                {
                    if (isSaving)
                    {
                        var saveFileDialog = new SaveFileDialog
                        {
                            Title = "Save As",
                            Filter = "cchart Files (*.cchart)|*.cchart",
                            InitialDirectory = _chartsDirectoryPath,
                            RestoreDirectory = true
                        };

                        if (saveFileDialog.ShowDialog() == DialogResult.OK)
                        {
                            result = saveFileDialog.FileName;
                        }
                    }
                    else
                    {
                        var openFileDialog = new OpenFileDialog
                        {
                            Title = "Open As",
                            Filter = "cchart Files (*.cchart)|*.cchart",
                            InitialDirectory = _chartsDirectoryPath,
                            RestoreDirectory = true
                        };

                        if (openFileDialog.ShowDialog() == DialogResult.OK)
                        {
                            result = openFileDialog.FileName;
                        }
                    }
                });

                thread.SetApartmentState(ApartmentState.STA);

                thread.Start();

                thread.Join();

                RefreshData();

                return result;
            }
        }
    }

    public enum AutoSaveMode
    {
        Time,
        OnChange
    }
}

Spotware's avatar
Spotware

Joined on 23.09.2013

  • Distribution: Free
  • Language: C#
  • Trading platform: cTrader Automate
  • File name: Chart Analysis Saver.algo
  • Rating: 5
  • Installs: 1366
Comments
Log in to add a comment.
NA
nancydrewsub · 2 years ago

The information and facts mentioned in the post are some of the most effective that can be achieved subway surfers