Run an indicator for multi symbols and get text outputs

Created at 24 Mar 2021, 02:46
How’s your experience with the cTrader Platform?
Your feedback is crucial to cTrader's development. Please take a few seconds to share your opinion and help us improve your trading experience. Thanks!
itmfar's avatar

itmfar

Joined 08.11.2017

Run an indicator for multi symbols and get text outputs
24 Mar 2021, 02:46


Hi
I have made an indicator with 1200 lines of code that returns a text. to simplify the situation. I have made a sample indicator that returns index and SymbolName.
Now I need to run this indicator on multi symbols and analysis those outputs.

for example
            Symbol[] MySymbols = Symbols.GetSymbols("EURUSD", "GBPUSD", "USDJPY", "USDCHF", "AUDCAD", "AUDCHF", "AUDJPY", "AUDNZD", "AUDUSD", "CADCHF",
            "CADJPY");

            foreach (var symbol in MySymbols)
            {
                // run or call indicator for each symbol
            }
I wonder how I can run or call an indicator for a list of currencies or symbols?
 

------------------------------------------------------------------------------------

using System;
using cAlgo.API;
using cAlgo.API.Internals;
using cAlgo.API.Indicators;
using cAlgo.Indicators;
using System.Collections.Generic;

namespace cAlgo
{
    [Indicator(IsOverlay = true, TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class Callindicator : Indicator
    {

        [Parameter("Bigger Timeframe", DefaultValue = "Daily")]
        public TimeFrame TimeframeBigger { get; set; }

        public int IndexMinDaily = 0;
        public int MinIndexB = 0;
        public double MinLineB = 0;

        public int IndexMaxDaily = 0;
        public int MaxIndexB = 0;
        public double MaxLineB = 0;

        public bool is_minB = false;
        public bool is_maxB = false;

        public List<Extremum> extremums = new List<Extremum>();

        public int lastHighindexB;
        public int LastLowindexB;

        public bool isBuy_allowedB = true;
        public bool isSell_allowedB = true;

        public bool signal_BuyB = false;
        public bool signal_SellB = false;


        public double high_insideB;
        public double low_insideB;

        public int lastbuy_exIndexB;
        public int lastsell_exIndexB;


        private MarketSeries Biggermarketseries;

        private int lastIndex = 0;


        protected override void Initialize()
        {
            // Initialize and create nested indicators

            while (Bars.Count < 1000)
            {
                var loadedCount = Bars.LoadMoreHistory();
                Print("Loaded {0} bars", loadedCount);
                if (loadedCount == 0)
                    break;
            }

            Biggermarketseries = MarketData.GetSeries(TimeframeBigger);

            int index = Bars.Count - 2;

            int idx1 = Biggermarketseries.OpenTime.GetIndexByTime(MarketSeries.OpenTime[index]);
            int indaxstart = idx1 - 10;
            MinIndexB = indaxstart;
            MinLineB = double.MaxValue;
            MaxIndexB = indaxstart;
            MaxLineB = double.MinValue;

        }

        public override void Calculate(int index)
        {

            Symbol[] MySymbols = Symbols.GetSymbols("EURUSD", "GBPUSD", "USDJPY", "USDCHF", "AUDCAD", "AUDCHF", "AUDJPY", "AUDNZD", "AUDUSD", "CADCHF",
            "CADJPY");
            foreach (var symbol in MySymbols)
            {
                // run indicator for each symbol
            }

            int idx1 = Biggermarketseries.OpenTime.GetIndexByTime(MarketSeries.OpenTime[index]);
            // index daily
            int idx2 = MarketSeries.OpenTime.GetIndexByTime(Biggermarketseries.OpenTime[idx1]);


            Bars barsD1 = MarketData.GetBars(TimeFrame.Daily);
            Bars barsH1 = MarketData.GetBars(TimeFrame.Hour);
            if (is_maxB && Biggermarketseries.High[idx1 - 1] > MaxLineB)
            {

                MaxLineB = Biggermarketseries.High[idx1 - 1];
                MaxIndexB = findindexmax(idx2, MaxLineB);

            }

            Chart.DrawStaticText("text", index + SymbolName, VerticalAlignment.Bottom, HorizontalAlignment.Left, Color.Red);
            returnfun(MaxIndexB);
        }

        public string returnfun(int index)
        {

            return index + SymbolName;

        }

        public int findindexmax(int index, double high)
        {
            for (int i = index - 24; i <= index + 24; i++)
            {
                if (high == Bars.HighPrices[i])
                    return i;
            }
            return index;
        }
    }
}

 


@itmfar
Replies

amusleh
24 Mar 2021, 09:17

Try this:

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

namespace cAlgo
{
    [Indicator(IsOverlay = true, TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class Callindicator : Indicator
    {
        private Symbol[] _symbols;
        private Bars[] _bars;

        [Parameter("Symbols", DefaultValue = "EURUSD,GBPUSD,USDJPY,USDCHF,AUDCAD,AUDCHF,AUDJPY,AUDNZD,AUDUSD,CADCHF,CADJPY")]
        public string SymbolNames { get; set; }

        [Parameter("Bigger Timeframe", DefaultValue = "Daily")]
        public TimeFrame TimeframeBigger { get; set; }

        public int IndexMinDaily = 0;
        public int MinIndexB = 0;
        public double MinLineB = 0;

        public int IndexMaxDaily = 0;
        public int MaxIndexB = 0;
        public double MaxLineB = 0;

        public bool is_minB = false;
        public bool is_maxB = false;

        public List<Extremum> extremums = new List<Extremum>();

        public int lastHighindexB;
        public int LastLowindexB;

        public bool isBuy_allowedB = true;
        public bool isSell_allowedB = true;

        public bool signal_BuyB = false;
        public bool signal_SellB = false;

        public double high_insideB;
        public double low_insideB;

        public int lastbuy_exIndexB;
        public int lastsell_exIndexB;

        private MarketSeries Biggermarketseries;

        private int lastIndex = 0;

        protected override void Initialize()
        {
            _symbols = Symbols.GetSymbols(SymbolNames.Replace(" ", string.Empty).Split(',').ToArray());
            _bars = _symbols.Select(iSymbol => MarketData.GetBars(TimeframeBigger, iSymbol.Name)).ToArray();

            foreach (var bars in _bars)
            {
                while (bars.Count < 1000)
                {
                    var loadedCount = bars.LoadMoreHistory();
                    Print("Loaded {0} bars of {1}", loadedCount, bars.SymbolName);
                    if (loadedCount == 0)
                        break;
                }

                bars.Tick += Bars_Tick;
                bars.BarOpened += Bars_BarOpened;
            }

            Biggermarketseries = MarketData.GetSeries(TimeframeBigger);

            int index = Bars.Count - 2;

            int idx1 = Biggermarketseries.OpenTime.GetIndexByTime(MarketSeries.OpenTime[index]);
            int indaxstart = idx1 - 10;
            MinIndexB = indaxstart;
            MinLineB = double.MaxValue;
            MaxIndexB = indaxstart;
            MaxLineB = double.MinValue;
        }

        private void Bars_BarOpened(BarOpenedEventArgs obj)
        {
            // each symbol will call this method on new bar open
        }

        private void Bars_Tick(BarsTickEventArgs obj)
        {
            // each symbol will call this method on tick change
        }

        public override void Calculate(int index)
        {
            foreach (var symbol in _symbols)
            {
                // run indicator for each symbol
            }

            int idx1 = Biggermarketseries.OpenTime.GetIndexByTime(MarketSeries.OpenTime[index]);
            // index daily
            int idx2 = MarketSeries.OpenTime.GetIndexByTime(Biggermarketseries.OpenTime[idx1]);

            Bars barsD1 = MarketData.GetBars(TimeFrame.Daily);
            Bars barsH1 = MarketData.GetBars(TimeFrame.Hour);
            if (is_maxB && Biggermarketseries.High[idx1 - 1] > MaxLineB)
            {
                MaxLineB = Biggermarketseries.High[idx1 - 1];
                MaxIndexB = findindexmax(idx2, MaxLineB);
            }

            Chart.DrawStaticText("text", index + SymbolName, VerticalAlignment.Bottom, HorizontalAlignment.Left, Color.Red);
            returnfun(MaxIndexB);
        }

        public string returnfun(int index)
        {
            return index + SymbolName;
        }

        public int findindexmax(int index, double high)
        {
            for (int i = index - 24; i <= index + 24; i++)
            {
                if (high == Bars.HighPrices[i])
                    return i;
            }
            return index;
        }
    }
}

You can put any code you want to inside "Bars_BarOpened" and "Bars_Tick" methods, you can use the Calculate method to calculate the indicator for historical data, its called only for current chart symbol ticks not your other symbols, so instead use "Bars_Tick" method.

Now you have all you need, the symbols and their bars, and you can pass the symbols via a parameter instead of hard coding the symbol names inside your indicator.


@amusleh

itmfar
25 Mar 2021, 19:10

RE:

Wow, interesting, you made my day.

amusleh said:

Try this:

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

namespace cAlgo
{
    [Indicator(IsOverlay = true, TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class Callindicator : Indicator
    {
        private Symbol[] _symbols;
        private Bars[] _bars;

        [Parameter("Symbols", DefaultValue = "EURUSD,GBPUSD,USDJPY,USDCHF,AUDCAD,AUDCHF,AUDJPY,AUDNZD,AUDUSD,CADCHF,CADJPY")]
        public string SymbolNames { get; set; }

        [Parameter("Bigger Timeframe", DefaultValue = "Daily")]
        public TimeFrame TimeframeBigger { get; set; }

        public int IndexMinDaily = 0;
        public int MinIndexB = 0;
        public double MinLineB = 0;

        public int IndexMaxDaily = 0;
        public int MaxIndexB = 0;
        public double MaxLineB = 0;

        public bool is_minB = false;
        public bool is_maxB = false;

        public List<Extremum> extremums = new List<Extremum>();

        public int lastHighindexB;
        public int LastLowindexB;

        public bool isBuy_allowedB = true;
        public bool isSell_allowedB = true;

        public bool signal_BuyB = false;
        public bool signal_SellB = false;

        public double high_insideB;
        public double low_insideB;

        public int lastbuy_exIndexB;
        public int lastsell_exIndexB;

        private MarketSeries Biggermarketseries;

        private int lastIndex = 0;

        protected override void Initialize()
        {
            _symbols = Symbols.GetSymbols(SymbolNames.Replace(" ", string.Empty).Split(',').ToArray());
            _bars = _symbols.Select(iSymbol => MarketData.GetBars(TimeframeBigger, iSymbol.Name)).ToArray();

            foreach (var bars in _bars)
            {
                while (bars.Count < 1000)
                {
                    var loadedCount = bars.LoadMoreHistory();
                    Print("Loaded {0} bars of {1}", loadedCount, bars.SymbolName);
                    if (loadedCount == 0)
                        break;
                }

                bars.Tick += Bars_Tick;
                bars.BarOpened += Bars_BarOpened;
            }

            Biggermarketseries = MarketData.GetSeries(TimeframeBigger);

            int index = Bars.Count - 2;

            int idx1 = Biggermarketseries.OpenTime.GetIndexByTime(MarketSeries.OpenTime[index]);
            int indaxstart = idx1 - 10;
            MinIndexB = indaxstart;
            MinLineB = double.MaxValue;
            MaxIndexB = indaxstart;
            MaxLineB = double.MinValue;
        }

        private void Bars_BarOpened(BarOpenedEventArgs obj)
        {
            // each symbol will call this method on new bar open
        }

        private void Bars_Tick(BarsTickEventArgs obj)
        {
            // each symbol will call this method on tick change
        }

        public override void Calculate(int index)
        {
            foreach (var symbol in _symbols)
            {
                // run indicator for each symbol
            }

            int idx1 = Biggermarketseries.OpenTime.GetIndexByTime(MarketSeries.OpenTime[index]);
            // index daily
            int idx2 = MarketSeries.OpenTime.GetIndexByTime(Biggermarketseries.OpenTime[idx1]);

            Bars barsD1 = MarketData.GetBars(TimeFrame.Daily);
            Bars barsH1 = MarketData.GetBars(TimeFrame.Hour);
            if (is_maxB && Biggermarketseries.High[idx1 - 1] > MaxLineB)
            {
                MaxLineB = Biggermarketseries.High[idx1 - 1];
                MaxIndexB = findindexmax(idx2, MaxLineB);
            }

            Chart.DrawStaticText("text", index + SymbolName, VerticalAlignment.Bottom, HorizontalAlignment.Left, Color.Red);
            returnfun(MaxIndexB);
        }

        public string returnfun(int index)
        {
            return index + SymbolName;
        }

        public int findindexmax(int index, double high)
        {
            for (int i = index - 24; i <= index + 24; i++)
            {
                if (high == Bars.HighPrices[i])
                    return i;
            }
            return index;
        }
    }
}

You can put any code you want to inside "Bars_BarOpened" and "Bars_Tick" methods, you can use the Calculate method to calculate the indicator for historical data, its called only for current chart symbol ticks not your other symbols, so instead use "Bars_Tick" method.

Now you have all you need, the symbols and their bars, and you can pass the symbols via a parameter instead of hard coding the symbol names inside your indicator.

 

 
 
 
 

@itmfar