Category Volatility  Published on 10/06/2020

Major Currency Strength Comparison

Description

Last update:
Added: correlation pairs & editable some interfaces 

This indicator is used for checking all major currencies strength after comparing them with each other

How it works:
I. Sum of [(high - low) + Abs(open - close)] in the last [input peroids]
II. Average them with one of these (Simple Moving Average, Weighted Moving Average, Exponential Moving Average or use Average True Range instead)
III. Compare each of them with each other, then convert it to the percentage

Let me know if there's any bug or feedback

Cheers

 

 


using System;
using cAlgo.API;
using System.Linq;
using cAlgo.API.Indicators;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Security;

namespace cAlgo
{
    [Indicator(IsOverlay = true, TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class MajorCurrencyStrengthComparison : Indicator
    {
        [Parameter("Periods", Group = "User Defines", DefaultValue = 24, MinValue = 1)]
        public int Periods { get; set; }

        [Parameter("Show Best", Group = "User Defines", DefaultValue = 5, MinValue = 1)]
        public int ShowBest { get; set; }

        [Parameter("Major Pairs", Group = "User Defines", DefaultValue = true)]
        public bool IncludeMajor { get; set; }

        [Parameter("Correlation", Group = "User Defines", DefaultValue = false)]
        public bool IncludeCross { get; set; }

        [Parameter("Sort By", Group = "User Defines", DefaultValue = SortType.Strength)]
        public SortType SortBy { get; set; }

        [Parameter("TimeFrame", Group = "User Defines")]
        public TimeFrame TF { get; set; }

        [Parameter("Title", Group = "Interface", DefaultValue = true)]
        public bool Title { get; set; }

        [Parameter("Percentage", Group = "Interface", DefaultValue = 100, MinValue = 100)]
        public int Percentage { get; set; }

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

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

        [Parameter("Type", Group = "High-Low + [Abs(Open-Close)]", DefaultValue = Type.Weighted)]
        public Type TYPE { get; set; }

        [Parameter("ATR", Group = "Alternative", DefaultValue = false)]
        public bool ATR { get; set; }

        [Parameter("ATR MA", Group = "Alternative", DefaultValue = MovingAverageType.Exponential)]
        public MovingAverageType ATRType { get; set; }

        readonly List<string> MajorCurrencies = new List<string> 
        {
            "USD",
            "EUR",
            "GBP",
            "JPY",
            "CHF",
            "CAD",
            "AUD",
            "NZD"
        };

        public enum SortType
        {
            Strength,
            Momentum
        }

        public enum Type
        {
            Simple,
            Weighted,
            Exponential
        }

        public enum MAType
        {
            Simple,
            Exponential,
            Time_Series,
            Triangular,
            VIDYA,
            Weighted,
            Wilder_Smoothing
        }

        public class PreviousValue
        {
            public int Index { get; set; }
            public List<double> LastPeriods = new List<double>();
        }

        readonly List<double> CSIs = new List<double>();
        readonly List<double> CChs = new List<double>();
        readonly List<string> Currencies = new List<string>();
        readonly List<PreviousValue> LastValues = new List<PreviousValue>();

        readonly List<Bars> BarSeries = new List<Bars>();
        readonly List<AverageTrueRange> ATRs = new List<AverageTrueRange>();

        readonly List<SimpleMovingAverage> SMA_Low = new List<SimpleMovingAverage>();
        readonly List<SimpleMovingAverage> SMA_Open = new List<SimpleMovingAverage>();
        readonly List<SimpleMovingAverage> SMA_High = new List<SimpleMovingAverage>();
        readonly List<SimpleMovingAverage> SMA_Close = new List<SimpleMovingAverage>();

        readonly List<WeightedMovingAverage> WMA_Low = new List<WeightedMovingAverage>();
        readonly List<WeightedMovingAverage> WMA_Open = new List<WeightedMovingAverage>();
        readonly List<WeightedMovingAverage> WMA_High = new List<WeightedMovingAverage>();
        readonly List<WeightedMovingAverage> WMA_Close = new List<WeightedMovingAverage>();

        readonly List<ExponentialMovingAverage> EMA_Low = new List<ExponentialMovingAverage>();
        readonly List<ExponentialMovingAverage> EMA_Open = new List<ExponentialMovingAverage>();
        readonly List<ExponentialMovingAverage> EMA_High = new List<ExponentialMovingAverage>();
        readonly List<ExponentialMovingAverage> EMA_Close = new List<ExponentialMovingAverage>();

        protected override void Initialize()
        {
            var currencies = string.Join(" ", MajorCurrencies.ToArray());
            var symbols = Symbols.Where(S => currencies.Contains(S.Substring(0, 3)) && currencies.Contains(S.Substring(3)) && ((IncludeMajor && !IncludeCross && S.Contains("USD")) || (!IncludeMajor && IncludeCross && !S.Contains("USD")) || IncludeMajor && IncludeCross)).ToArray();

            foreach (var s in symbols)
            {
                var MarketData = base.MarketData.GetBars(TF, s);

                CChs.Add(0.0);
                CSIs.Add(0.0);
                Currencies.Add(s);
                BarSeries.Add(MarketData);
                LastValues.Add(new PreviousValue 
                {
                    Index = -1
                });

                if (ATR)
                {
                    //var ma = ATRType == MAType.Simple ? MovingAverageType.Simple : ATRType == MAType.Exponential ? MovingAverageType.Exponential : ATRType == MAType.Time_Series ? MovingAverageType.TimeSeries : ATRType == MAType.Triangular ? MovingAverageType.Triangular : ATRType == MAType.VIDYA ? MovingAverageType.VIDYA : ATRType == MAType.Weighted ? MovingAverageType.Weighted : MovingAverageType.WilderSmoothing;
                    ATRs.Add(Indicators.AverageTrueRange(MarketData, Periods, ATRType));
                }
                else if (TYPE == Type.Simple)
                {
                    SMA_Low.Add(Indicators.SimpleMovingAverage(MarketData.LowPrices, Periods));
                    SMA_Open.Add(Indicators.SimpleMovingAverage(MarketData.OpenPrices, Periods));
                    SMA_High.Add(Indicators.SimpleMovingAverage(MarketData.HighPrices, Periods));
                    SMA_Close.Add(Indicators.SimpleMovingAverage(MarketData.ClosePrices, Periods));
                }
                else if (TYPE == Type.Weighted)
                {
                    WMA_Low.Add(Indicators.WeightedMovingAverage(MarketData.LowPrices, Periods));
                    WMA_Open.Add(Indicators.WeightedMovingAverage(MarketData.OpenPrices, Periods));
                    WMA_High.Add(Indicators.WeightedMovingAverage(MarketData.HighPrices, Periods));
                    WMA_Close.Add(Indicators.WeightedMovingAverage(MarketData.ClosePrices, Periods));
                }
                else if (TYPE == Type.Exponential)
                {
                    EMA_Low.Add(Indicators.ExponentialMovingAverage(MarketData.LowPrices, Periods));
                    EMA_Open.Add(Indicators.ExponentialMovingAverage(MarketData.OpenPrices, Periods));
                    EMA_High.Add(Indicators.ExponentialMovingAverage(MarketData.HighPrices, Periods));
                    EMA_Close.Add(Indicators.ExponentialMovingAverage(MarketData.ClosePrices, Periods));
                }
            }
        }

        public override void Calculate(int index)
        {
            for (int i = 0; i < BarSeries.Count; i++)
            {
                var index2 = GetIndexByTF(BarSeries[i], this.Bars, index);

                if (index2 == -1)
                {
                    continue;
                }

                var PS = BarSeries[i].SymbolName.Contains("JPY") ? 100 : 1;

                var value = 0.0;

                if (ATR)
                {
                    value = ATRs[i].Result[index2] / PS;
                }
                else if (TYPE == Type.Simple)
                {
                    value = ((SMA_High[i].Result[index2] - SMA_Low[i].Result[index2]) + Math.Abs(SMA_Open[i].Result[index2] - SMA_Close[i].Result[index2])) / PS;
                }
                else if (TYPE == Type.Weighted)
                {
                    value = ((WMA_High[i].Result[index2] - WMA_Low[i].Result[index2]) + Math.Abs(WMA_Open[i].Result[index2] - WMA_Close[i].Result[index2])) / PS;
                }
                else if (TYPE == Type.Exponential)
                {
                    value = ((EMA_High[i].Result[index2] - EMA_Low[i].Result[index2]) + Math.Abs(EMA_Open[i].Result[index2] - EMA_Close[i].Result[index2])) / PS;
                }

                CSIs[i] = value;
            }

            var sum = CSIs.Select(x => x).Sum();
            for (int i = 0; i < BarSeries.Count; i++)
            {
                var index2 = GetIndexByTF(BarSeries[i], this.Bars, index);

                if (index2 == -1)
                {
                    continue;
                }

                CSIs[i] = (CSIs[i] / sum) * Percentage;

                var lastvalues = LastValues[i];
                var lastperiods = lastvalues.LastPeriods;

                if (!lastperiods.Any() || lastperiods.Count <= Periods && LastValues[i].Index != index2)
                {
                    lastperiods.Add(CSIs[i]);
                }
                else
                {
                    lastperiods[lastperiods.Count - 1] = CSIs[i];
                }
                if (lastperiods.Count > Periods)
                {
                    lastperiods.RemoveAt(0);
                }

                CChs[i] = lastperiods[lastperiods.Count - 1] - lastperiods[0];

                LastValues[i].Index = index2;
            }

            DrawTexts();
        }

        void DrawTexts()
        {
            double[] values = CSIs.ToArray();
            double[] momentums = CChs.ToArray();
            string[] currencies = Currencies.ToArray();

            for (int i = 1; i < values.Length; i++)
            {
                for (int k = i; k >= 1; k--)
                {
                    var value2 = SortBy == SortType.Strength ? values[k] : momentums[k];
                    var value1 = SortBy == SortType.Strength ? values[k - 1] : momentums[k - 1];

                    if (value2 > value1)
                    {
                        var temp1 = values[k];
                        values[k] = values[k - 1];
                        values[k - 1] = temp1;

                        var temp2 = momentums[k];
                        momentums[k] = momentums[k - 1];
                        momentums[k - 1] = temp2;

                        var temp3 = currencies[k];
                        currencies[k] = currencies[k - 1];
                        currencies[k - 1] = temp3;
                    }
                }
            }

            var Text = string.Empty;
            var sot = ShowBest > BarSeries.Count ? BarSeries.Count : ShowBest;

            for (int i = 0; i < sot; i++)
            {
                var value = Math.Round(values[i], 7).ToString();
                if (value.Length > 5)
                {
                    value = value.Remove(5);
                }

                var momentum = Math.Round(momentums[i], 10).ToString();
                if (momentum.Contains("-"))
                {
                    momentum = momentum.Replace("-", "");
                    momentum = "-  " + momentum;

                    if (momentum.Length > 5)
                    {
                        momentum = momentum.Remove(7);
                    }
                }
                else
                {
                    momentum = "+ " + momentum;

                    if (momentum.Length > 6)
                    {
                        momentum = momentum.Remove(6);
                    }
                }

                var currency = currencies[i].Contains("JPY") ? currencies[i] + " " : currencies[i];

                if (Horizontal != HorizontalAlignment.Right)
                {
                    if (i == 0 && Title)
                        Text = "          Best " + sot + " Major Pairs         \n";

                    Text += "- " + currency.Substring(0, 3) + "/" + currency.Substring(3) + ":  " + value + " %  :  " + momentum + " %\n";
                }
                else
                {
                    if (i == 0 && Title)
                        Text = "-------- Best " + sot + " Major Pairs --------\n";

                    Text += momentum + " %  :  " + value + " %  :" + currency.Substring(0, 3) + "/" + currency.Substring(3) + " -\n";
                }
            }

            Chart.DrawStaticText("Symbols", Text, Vertical, Horizontal, Color.White);
        }

        int GetIndexByTF(Bars B1, Bars B2, int index)
        {
            var index2 = B1.OpenTimes.GetIndexByTime(B2.OpenTimes[index]);
            return index2;
        }
    }
}


Kbee's avatar
Kbee

Joined on 28.03.2020

  • Distribution: Free
  • Language: C#
  • Trading platform: cTrader Automate
  • File name: Major Currency Strength Comparison (MCSC) v0.1.algo
  • Rating: 5
  • Installs: 2700
  • Modified: 13/10/2021 09:55
Comments
Log in to add a comment.
MA
Maxim_Quad · 3 years ago

Hi 

 

Is there anyway to change to font colour to Black please? Plus can you explain what data is it showing ? Like for instance in the picture above, EURNZD, what is it showing ?

 

Many Thanks

D.
d.stavenau · 3 years ago

Great Indicator, very useful..  Just a quick question.

in your parameter declarations, you have:-

public MovingAverageType ATRType { get; set; ]

..but the corresponding enum listing doesn't appear to match:-

public enum MAType       (i.e.  ATRType is not MAType).

I just wondered if this was a typo?

Many thanks.

SG
SGordon1985 · 4 years ago

Hi, what are the benefit of this indicator?....Is it just showing the strenght of the pair or is it showing the strenght of both currency?

Kbee's avatar
Kbee · 4 years ago

I get what you mean. It should be work on both major pairs and cross pairs now after this update

JI
jivkoivanoff2 · 4 years ago

Just to calculate all 28 major pairs,doesont matter what a  format to be used

Kbee's avatar
Kbee · 4 years ago

Thank you! Anyways, by 28 major pairs correlation, do you mean to be able to calculate like AUD/JYP, EUR/AUD pairs, and so on using the current format, or you mean to be able to calculate the correlations between currency pairs (-1 to +1) format?

JI
jivkoivanoff2 · 4 years ago

Nice work,but is there are possible to make this one to calculate all major 28 pairs correlation?