Category Trend  Published on 06/08/2024

JK CT

Description

Jk ct bot trading 


using System.Collections.Generic;
using System.Linq;
using cAlgo.API;

namespace cAlgo.Plugins
{
    [Plugin(AccessRights = AccessRights.None)]
    public class CurrencyStrengthBoard : Plugin
    {
        #region Fields

        private const double ScaleMin = 1;
        private const double ScaleMax = 500;

        private readonly List<string> _symbolNames = new();
        private readonly List<Bars> _symbolBars = new();
        private readonly Dictionary<string, double> _currencyStrength = new();
        private readonly List<HorizontalBar> _orderedStrengthBars = new();
        private readonly List<string> _bestLongSymbols = new();
        private readonly List<string> _bestShortSymbols = new();
        
        private readonly HashSet<string> _currencies = new()
        {
            "EUR",
            "USD",
            "GBP",
            "AUD",
            "CAD",
            "NZD",
            "JPY",
            "CHF",
            "TRY",
            "SGD",
            "BTC",
            "MXN"
        };

        private StackPanel _strengthBoardPanel;
        private ComboBox _timeFramesComboBox;
        private TextBlock _loadingTextBlock;
        private CustomFrame _frame;
        private TextBox _periodsTextBox;
        private StackPanel _bestLongSymbolsPanel;
        private StackPanel _bestShortSymbolsPanel;
        private Grid _mainPanel;
        
        #endregion Fields

        #region Parameters
        
        public int Periods        
        {
            get => int.Parse(LocalStorage.GetString(nameof(Periods)) ?? 20.ToString());
            set => LocalStorage.SetString(nameof(Periods), value.ToString());
        }
        
        public TimeFrame BarsTimeFrame
        {
            get => TimeFrame.Parse(LocalStorage.GetString(nameof(BarsTimeFrame)) ?? TimeFrame.Daily.ToString());
            set => LocalStorage.SetString(nameof(BarsTimeFrame), value.ToString());
        }

        #endregion Parameters

        #region Overridden methods

        protected override void OnStart()
        {
            ChartManager.FramesRemoved += OnChartManagerFramesRemoved;

            Start();
        }

        private void OnChartManagerFramesRemoved(FramesRemovedEventArgs obj)
        {
            if (_frame is null)
                return;
            
            if (!obj.RemovedFrames.Contains(_frame))
                return;

            Start();
        }

        private void Start()
        {
            CreateFrame();
            
            Loading();
            
            BeginInvokeOnMainThread(() =>
            {
                AddSymbolsNames();

                AddCurrenciesStrength();
                
                RefreshBoard();
            });
        }
        
        private void CreateBestShortSymbolsPanel()
        {
            _bestShortSymbolsPanel = new StackPanel();

            _bestShortSymbolsPanel.AddChild(new TextBlock
            {
                Text = "Best Symbols To Short",
                FontWeight = FontWeight.Bold,
                HorizontalAlignment = HorizontalAlignment.Center,
                Margin = new Thickness(5, 10, 5, 5),
                FontSize = 14
            });
            
            var count = _bestShortSymbols.Count > 10 ? 10 : _bestShortSymbols.Count;
            
            for (var i = 0; i < count; i++)
            {
                _bestShortSymbolsPanel.AddChild(new TextBlock
                {
                    Margin = 5,
                    Text = $"#{i + 1}: {_bestShortSymbols[i]}",
                    FontWeight = FontWeight.Bold,
                });
            }
        }

        private void CreateBestLongSymbolsPanel()
        {
            _bestLongSymbolsPanel = new StackPanel();

            _bestLongSymbolsPanel.AddChild(new TextBlock
            {
                Text = "Best Symbols To Long",
                FontWeight = FontWeight.Bold,
                HorizontalAlignment = HorizontalAlignment.Center,
                Margin = new Thickness(5, 5, 5, 10),
                FontSize = 14
            });
            
            var count = _bestLongSymbols.Count > 10 ? 10 : _bestLongSymbols.Count;
            
            for (var i = 0; i < count; i++)
            {
                _bestLongSymbolsPanel.AddChild(new TextBlock
                {
                    Margin = 5,
                    Text = $"#{i + 1}: {_bestLongSymbols[i]}",
                    FontWeight = FontWeight.Bold,
                });
            }
        }

        private void Loading()
        {
            CreateLoadingTextBlock();
            
            _frame.Child = new ScrollViewer {Content = _loadingTextBlock};
        }

        private void Show()
        {
            _mainPanel = new Grid(1, 2);
            
            _mainPanel.AddChild(_strengthBoardPanel, 0, 0);

            _mainPanel.Columns[0].SetWidthInStars(1);
            _mainPanel.Columns[1].SetWidthToAuto();
            
            var bestSymbolsPanel = new StackPanel() {Orientation = Orientation.Vertical, Margin = 20};
            
            bestSymbolsPanel.AddChild(_bestLongSymbolsPanel);
            bestSymbolsPanel.AddChild(_bestShortSymbolsPanel);
            
            _mainPanel.AddChild(bestSymbolsPanel, 0, 1);

            _frame.Child = new ScrollViewer {Content = _mainPanel};
        }

        private void CreateFrame()
        {
            _frame = ChartManager.AddCustomFrame("Currency Strength Board");
        }

        private void CreateLoadingTextBlock()
        {
            _loadingTextBlock = new TextBlock
            {
                Text = "Loading...",
                FontWeight = FontWeight.ExtraBold,
                FontSize = 16,
                HorizontalAlignment = HorizontalAlignment.Center,
                VerticalAlignment = VerticalAlignment.Center,
                Margin = 10
            };
        }

        private void UpdateAllCurrenciesStrength()
        {
            foreach (var currency in _currencies) UpdateCurrencyStrength(currency);
        }

        private void CreateStrengthBoard()
        {
            _strengthBoardPanel = new StackPanel {Orientation = Orientation.Vertical};

            var titleTextBlock = new TextBlock
            {
                Text = $"Currency Strength Board ({ScaleMin} - {ScaleMax})",
                Margin = 20,
                FontWeight = FontWeight.Bold,
                FontSize = 14,
                HorizontalAlignment = HorizontalAlignment.Center
            };
            
            _strengthBoardPanel.AddChild(titleTextBlock);

            var timeFramesTextBox = new TextBlock
            {
                Margin = 20,
                Text = "Timeframe",
                FontWeight = FontWeight.Bold
            };
            
            _timeFramesComboBox = new ComboBox
            {
                Margin = 20,
                HorizontalAlignment = HorizontalAlignment.Left,
                MinWidth = 80,
                FontWeight = FontWeight.Bold,
            };

            PopulateTimeFrames();

            _timeFramesComboBox.SelectedItemChanged += OnTimeFramesComboBoxSelectedItemChanged;

            var periodsTextBlock = new TextBlock
            {
                Margin = 20,
                Text = "Periods",
                FontWeight = FontWeight.Bold
            };

            _periodsTextBox = new TextBox
            {
                Text = Periods.ToString(),
                Margin = 20,
                FontWeight = FontWeight.Bold,
                MinWidth = 80
            };
            
            _periodsTextBox.TextChanged += OnPeriodsTextBoxTextChanged;
            
            var settingsPanel = new StackPanel {Orientation = Orientation.Horizontal};
            
            settingsPanel.AddChild(timeFramesTextBox);
            settingsPanel.AddChild(_timeFramesComboBox);
            
            settingsPanel.AddChild(periodsTextBlock);
            settingsPanel.AddChild(_periodsTextBox);

            _strengthBoardPanel.AddChild(settingsPanel);
            
            _orderedStrengthBars.Clear();
            
            for (var i = 0; i < _currencies.Count; i++)
            {
                var bar = new HorizontalBar {Margin = 20};

                _strengthBoardPanel.AddChild(bar);
                
                _orderedStrengthBars.Add(bar);
            }
        }

        private void OnPeriodsTextBoxTextChanged(TextChangedEventArgs obj)
        {
            Periods = int.Parse(obj.TextBox.Text);
            
            RefreshBoard();
        }

        private void OnTimeFramesComboBoxSelectedItemChanged(ComboBoxSelectedItemChangedEventArgs args)
        {
            BarsTimeFrame = TimeFrame.Parse(args.SelectedItem);

            RefreshBoard();
        }

        private void RefreshBoard()
        {
            Loading();
            
            BeginInvokeOnMainThread(() =>
            {
                UnsubscribeFromBars();
            
                AddBars();
                
                UpdateAllCurrenciesStrength();

                CreateStrengthBoard();

                UpdateStrengthBoard(); 
                
                UpdateBestLongShortSymbols();
                
                CreateBestLongSymbolsPanel();

                CreateBestShortSymbolsPanel();
                
                Show();
            });
        }

        private void PopulateTimeFrames()
        {
            foreach (var fieldInfo in typeof(TimeFrame).GetFields())
            {
                _timeFramesComboBox.AddItem(fieldInfo.Name);
            }

            _timeFramesComboBox.SelectedItem = BarsTimeFrame.ToString();
        }

        private void AddBars()
        {
            _symbolBars.Clear();
            
            foreach (var symbolName in _symbolNames)
            {
                var bars = MarketData.GetBars(BarsTimeFrame, symbolName);

                _symbolBars.Add(bars);

                bars.BarOpened += OnBarOpened;
            }
        }

        private void UnsubscribeFromBars()
        {
            if (_symbolBars is null)
                return;
            
            foreach (var bars in _symbolBars)
            {
                bars.BarOpened -= OnBarOpened;
            }
        }
        
        private void OnBarOpened(BarOpenedEventArgs args)
        {
            var symbol = Symbols.GetSymbol(args.Bars.SymbolName);

            if (_currencies.TryGetValue(symbol.BaseAsset.Name.ToUpperInvariant(), out var baseCurrency))
                UpdateCurrencyStrength(baseCurrency);

            if (_currencies.TryGetValue(symbol.QuoteAsset.Name.ToUpperInvariant(), out var quoteCurrency))
                UpdateCurrencyStrength(quoteCurrency);

            UpdateStrengthBoard();

            UpdateBestLongShortSymbols();
        }

        private void UpdateStrengthBoard()
        {
            var valueMax = _currencyStrength.Values.Max();
            var valueMin = _currencyStrength.Values.Min();

            var barIndex = 0;

            foreach (var (currency, strength) in _currencyStrength.OrderByDescending(i => i.Value))
            {
                var bar = _orderedStrengthBars[barIndex];

                bar.Label = currency;
                bar.Value = MinMax(strength, valueMin, valueMax, ScaleMin, ScaleMax);

                barIndex++;
            }
        }

        private static double MinMax(double number, double min, double max, double minAllowedNumber,
            double maxAllowedNumber)
        {
            var b = max - min != 0 ? max - min : 1 / max;
            var uninterpolate = (number - min) / b;
            var result = minAllowedNumber * (1 - uninterpolate) + maxAllowedNumber * uninterpolate;

            return result;
        }

        private void AddCurrenciesStrength()
        {
            _currencyStrength.Clear();
            
            foreach (var currency in _currencies) _currencyStrength.Add(currency, 0);
        }

        #endregion Overridden methods

        #region Other methods

        private void UpdateCurrencyStrength(string currency)
        {
            double symbolPercentage = 0;

            var seriesCounter = 0;

            foreach (var bars in _symbolBars)
            {
                var symbol = Symbols.GetSymbol(bars.SymbolName);

                var impact = 0;

                if (symbol.BaseAsset.Name == currency)
                    impact = 1;
                else if ((symbol.QuoteAsset.Name == currency))
                    impact = -1;

                if (impact == 0)
                    continue;

                var index = bars.Count - 1;

                seriesCounter++;

                double seriesResult = 0;

                for (var i = index - Periods; i <= index; i++) seriesResult += GetPercentageChange(bars, i);

                symbolPercentage += seriesResult * impact;
            }

            _currencyStrength[currency] = symbolPercentage / seriesCounter;
        }

        private void UpdateBestLongShortSymbols()
        {
            _bestLongSymbols.Clear();
            _bestShortSymbols.Clear();
            
            var orderedCurrenciesStrength = _currencyStrength
                .OrderByDescending(kv => kv.Value)
                .ToArray();

            for (var i = 0; i < orderedCurrenciesStrength.Length; i++)
            {
                var strongCurrency = orderedCurrenciesStrength[i].Key;

                for (var j = orderedCurrenciesStrength.Length - 1; j > i; j--)
                {
                    var weakCurrency = orderedCurrenciesStrength[j].Key;

                    foreach (var symbolName in Symbols)
                    {
                        var symbol = Symbols.GetSymbol(symbolName);

                        if (symbol.BaseAsset.Name == strongCurrency && symbol.QuoteAsset.Name == weakCurrency)
                        {
                            _bestLongSymbols.Add(symbolName);
                        }
                        else if (symbol.BaseAsset.Name == weakCurrency && symbol.QuoteAsset.Name == strongCurrency)
                        {
                            _bestShortSymbols.Add(symbolName);
                        }
                    }
                }
            }
        }

        private void AddSymbolsNames()
        {
            _symbolNames.Clear();
            
            foreach (var symbolName in Symbols)
            {
                var symbol = Symbols.GetSymbol(symbolName);

                var baseAssetName = symbol.BaseAsset.Name;
                var quoteAssetName = symbol.QuoteAsset.Name;

                if (!IsInCurrencies(baseAssetName) || !IsInCurrencies(quoteAssetName) ||
                    baseAssetName == quoteAssetName)
                    continue;

                _symbolNames.Add(symbolName);
            }
        }

        private bool IsInCurrencies(string currency) => _currencies.Contains(currency.ToUpperInvariant());

        private static double GetPercentageChange(Bars bars, int index)
        {
            return -((bars.OpenPrices[index] - bars.ClosePrices[index]) / bars.OpenPrices[index]) * 100;
        }

        #endregion Other methods
    }
}

HA
hajovi5474

Joined on 06.08.2024

  • Distribution: Free
  • Language: C#
  • Trading platform: cTrader Automate
  • File name: Currency Strength Board_withSourceCode.algo.txt
  • Rating: 0
  • Installs: 171
  • Modified: 06/08/2024 20:11
Comments
Log in to add a comment.
JI
jim.tollan · 1 month ago

excellent work - some would say it's a close copy of the plugin called Currency Strength Board

well done for thinking this one out and making it available as a bot, never mind a plugin!!