Multi Symbol, Multi Timeframe API's very slow

Created at 06 Nov 2017, 10:38
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!
MY

myinvestmentsfx

Joined 06.11.2017

Multi Symbol, Multi Timeframe API's very slow
06 Nov 2017, 10:38


Hi Guys,

I just want to establish whether or not its normal to wait 10 seconds+ to collect Mutli Symbol, Multi Timeframe information from the MarketData.GetSeries API.

See code below used as an example (Apologies code still a bit messy), once I enter the loop, to get past the first task in the loop can take up to 10 seconds.

I understand that latency, bandwidth and computing power all play a roll in the overall speed the code will execute.  But from my testing it points to Multi Symbol, Multi Timeframe API's that's a little slow.  If spotware can have a look it will be greatly appriciated.

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

namespace cAlgo
{
    [Indicator(IsOverlay = false, TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class NewIndicator : Indicator
    {
        ////////////////////////////////////////////////////////////////////////////////
        ///                        USER PARAMETERS                                   ///
        ////////////////////////////////////////////////////////////////////////////////
        protected override void Initialize()
        {
            PAIR_ANALYSIS();
        }

        public override void Calculate(int index)
        {
        }

        private void PAIR_ANALYSIS()
        {
            ////////////////////////////////////////////////////////////////////////////////
            ///             CHECK PAIR UP FOR TODAY & CHECK ATR REACHED                  ///
            ////////////////////////////////////////////////////////////////////////////////

            var start_time = Server.Time;
            double hposition = 1;

            List<Symbol> _all_symbol_codes = new List<Symbol>();
            List<MarketSeries> _all_symbol_daily = new List<MarketSeries>();
            List<MarketSeries> _all_symbol_5min = new List<MarketSeries>();
            List<AverageTrueRange> _all_symbol_atr_daily_indicator = new List<AverageTrueRange>();
            List<double> _all_atr_daily_results = new List<double>();
            List<double> _all_daily_last_opens = new List<double>();
            List<double> _all_5min_last_opens = new List<double>();
            List<double> _all_daily_last_highs = new List<double>();
            List<double> _all_daily_last_lows = new List<double>();
            List<double> _all_daily_high_minus_daily_atr = new List<double>();
            List<double> _all_daily_low_add_daily_atr = new List<double>();
            List<string> _all_price_up_down = new List<string>();
            List<string> _atr_reached_not_reached = new List<string>();
            List<string> _all_symbol_names = new List<string>();

            _all_symbol_codes.InsertRange(_all_symbol_codes.Count, new Symbol[] 
            {
                MarketData.GetSymbol("EURUSD"),
                MarketData.GetSymbol("GBPUSD"),
                MarketData.GetSymbol("USDCHF"),
                MarketData.GetSymbol("USDJPY"),
                MarketData.GetSymbol("USDCAD"),
                MarketData.GetSymbol("AUDUSD"),
                MarketData.GetSymbol("GBPJPY"),
                MarketData.GetSymbol("EURJPY"),
                MarketData.GetSymbol("NZDUSD"),
                MarketData.GetSymbol("AUDJPY")

            });
            for (int index = 0; index < _all_symbol_codes.Count; index++)
            {
                var Step_1 = Server.Time;
                Print("The Server Time Start Loop: {0}", Step_1 - start_time);
                _all_symbol_daily.Add(MarketData.GetSeries(_all_symbol_codes[index], TimeFrame.Daily));
                var Step_2 = Server.Time;
                Print("The Server Get MarketData For Daily Timeframe Step 1: {0}", Step_2 - start_time);

                _all_symbol_5min.Add(MarketData.GetSeries(_all_symbol_codes[index], TimeFrame.Minute5));
                _all_symbol_atr_daily_indicator.Add(Indicators.AverageTrueRange(_all_symbol_daily[index], 5, MovingAverageType.Exponential));
                _all_atr_daily_results.Add(_all_symbol_atr_daily_indicator[index].Result.LastValue);
                _all_daily_last_opens.Add(_all_symbol_daily[index].Open.Last(0));
                _all_daily_last_highs.Add(_all_symbol_daily[index].High.Last(0));
                _all_daily_last_lows.Add(_all_symbol_daily[index].Low.Last(0));
                _all_daily_high_minus_daily_atr.Add(_all_daily_last_highs[index] - _all_atr_daily_results[index]);
                _all_daily_low_add_daily_atr.Add(_all_daily_last_lows[index] + _all_atr_daily_results[index]);
                _all_5min_last_opens.Add(_all_symbol_5min[index].Open.Last(0));
                hposition -= 0.1;

                if (_all_daily_last_opens[index] > _all_5min_last_opens[index])
                {
                    _all_price_up_down.Add(_all_symbol_codes[index] + " | " + "Down");

                }
                else
                {
                    _all_price_up_down.Add(_all_symbol_codes[index] + " | " + "Up");
                }

                if ((_all_daily_last_highs[index] > _all_daily_low_add_daily_atr[index]) || (_all_daily_last_lows[index] < _all_daily_high_minus_daily_atr[index]))
                {
                    _atr_reached_not_reached.Add("ATR Reached");
                }
                else
                {
                    _atr_reached_not_reached.Add("ATR --NOT-- Reached");
                }
            }
            string _all_price_up_down_results = string.Join("\n", _all_price_up_down);
            string _all_atr_reached_not_reached = string.Join("\n", _atr_reached_not_reached);

            ChartObjects.DrawText("UP or Down", _all_price_up_down_results, StaticPosition.TopLeft, Colors.Blue);
            ChartObjects.DrawText("ATR", _all_atr_reached_not_reached, StaticPosition.TopCenter, Colors.Green);

            _all_symbol_daily.Clear();
            _all_symbol_5min.Clear();
            _all_symbol_atr_daily_indicator.Clear();
            _all_atr_daily_results.Clear();
            _all_daily_last_opens.Clear();
            _all_daily_last_highs.Clear();
            _all_daily_last_lows.Clear();
            _all_daily_high_minus_daily_atr.Clear();
            _all_daily_low_add_daily_atr.Clear();
            _all_5min_last_opens.Clear();
            _all_price_up_down.Clear();
            _atr_reached_not_reached.Clear();
        }
    }
}

Kind Regards,

 


@myinvestmentsfx
Replies

firemyst
04 Sep 2020, 09:39

RE:

myinvestmentsfx said:

Hi Guys,

I just want to establish whether or not its normal to wait 10 seconds+ to collect Mutli Symbol, Multi Timeframe information from the MarketData.GetSeries API.

See code below used as an example (Apologies code still a bit messy), once I enter the loop, to get past the first task in the loop can take up to 10 seconds.

I understand that latency, bandwidth and computing power all play a roll in the overall speed the code will execute.  But from my testing it points to Multi Symbol, Multi Timeframe API's that's a little slow.  If spotware can have a look it will be greatly appriciated.

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

namespace cAlgo
{
    [Indicator(IsOverlay = false, TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class NewIndicator : Indicator
    {
        ////////////////////////////////////////////////////////////////////////////////
        ///                        USER PARAMETERS                                   ///
        ////////////////////////////////////////////////////////////////////////////////
        protected override void Initialize()
        {
            PAIR_ANALYSIS();
        }

        public override void Calculate(int index)
        {
        }

        private void PAIR_ANALYSIS()
        {
            ////////////////////////////////////////////////////////////////////////////////
            ///             CHECK PAIR UP FOR TODAY & CHECK ATR REACHED                  ///
            ////////////////////////////////////////////////////////////////////////////////

            var start_time = Server.Time;
            double hposition = 1;

            List<Symbol> _all_symbol_codes = new List<Symbol>();
            List<MarketSeries> _all_symbol_daily = new List<MarketSeries>();
            List<MarketSeries> _all_symbol_5min = new List<MarketSeries>();
            List<AverageTrueRange> _all_symbol_atr_daily_indicator = new List<AverageTrueRange>();
            List<double> _all_atr_daily_results = new List<double>();
            List<double> _all_daily_last_opens = new List<double>();
            List<double> _all_5min_last_opens = new List<double>();
            List<double> _all_daily_last_highs = new List<double>();
            List<double> _all_daily_last_lows = new List<double>();
            List<double> _all_daily_high_minus_daily_atr = new List<double>();
            List<double> _all_daily_low_add_daily_atr = new List<double>();
            List<string> _all_price_up_down = new List<string>();
            List<string> _atr_reached_not_reached = new List<string>();
            List<string> _all_symbol_names = new List<string>();

            _all_symbol_codes.InsertRange(_all_symbol_codes.Count, new Symbol[] 
            {
                MarketData.GetSymbol("EURUSD"),
                MarketData.GetSymbol("GBPUSD"),
                MarketData.GetSymbol("USDCHF"),
                MarketData.GetSymbol("USDJPY"),
                MarketData.GetSymbol("USDCAD"),
                MarketData.GetSymbol("AUDUSD"),
                MarketData.GetSymbol("GBPJPY"),
                MarketData.GetSymbol("EURJPY"),
                MarketData.GetSymbol("NZDUSD"),
                MarketData.GetSymbol("AUDJPY")

            });
            for (int index = 0; index < _all_symbol_codes.Count; index++)
            {
                var Step_1 = Server.Time;
                Print("The Server Time Start Loop: {0}", Step_1 - start_time);
                _all_symbol_daily.Add(MarketData.GetSeries(_all_symbol_codes[index], TimeFrame.Daily));
                var Step_2 = Server.Time;
                Print("The Server Get MarketData For Daily Timeframe Step 1: {0}", Step_2 - start_time);

                _all_symbol_5min.Add(MarketData.GetSeries(_all_symbol_codes[index], TimeFrame.Minute5));
                _all_symbol_atr_daily_indicator.Add(Indicators.AverageTrueRange(_all_symbol_daily[index], 5, MovingAverageType.Exponential));
                _all_atr_daily_results.Add(_all_symbol_atr_daily_indicator[index].Result.LastValue);
                _all_daily_last_opens.Add(_all_symbol_daily[index].Open.Last(0));
                _all_daily_last_highs.Add(_all_symbol_daily[index].High.Last(0));
                _all_daily_last_lows.Add(_all_symbol_daily[index].Low.Last(0));
                _all_daily_high_minus_daily_atr.Add(_all_daily_last_highs[index] - _all_atr_daily_results[index]);
                _all_daily_low_add_daily_atr.Add(_all_daily_last_lows[index] + _all_atr_daily_results[index]);
                _all_5min_last_opens.Add(_all_symbol_5min[index].Open.Last(0));
                hposition -= 0.1;

                if (_all_daily_last_opens[index] > _all_5min_last_opens[index])
                {
                    _all_price_up_down.Add(_all_symbol_codes[index] + " | " + "Down");

                }
                else
                {
                    _all_price_up_down.Add(_all_symbol_codes[index] + " | " + "Up");
                }

                if ((_all_daily_last_highs[index] > _all_daily_low_add_daily_atr[index]) || (_all_daily_last_lows[index] < _all_daily_high_minus_daily_atr[index]))
                {
                    _atr_reached_not_reached.Add("ATR Reached");
                }
                else
                {
                    _atr_reached_not_reached.Add("ATR --NOT-- Reached");
                }
            }
            string _all_price_up_down_results = string.Join("\n", _all_price_up_down);
            string _all_atr_reached_not_reached = string.Join("\n", _atr_reached_not_reached);

            ChartObjects.DrawText("UP or Down", _all_price_up_down_results, StaticPosition.TopLeft, Colors.Blue);
            ChartObjects.DrawText("ATR", _all_atr_reached_not_reached, StaticPosition.TopCenter, Colors.Green);

            _all_symbol_daily.Clear();
            _all_symbol_5min.Clear();
            _all_symbol_atr_daily_indicator.Clear();
            _all_atr_daily_results.Clear();
            _all_daily_last_opens.Clear();
            _all_daily_last_highs.Clear();
            _all_daily_last_lows.Clear();
            _all_daily_high_minus_daily_atr.Clear();
            _all_daily_low_add_daily_atr.Clear();
            _all_5min_last_opens.Clear();
            _all_price_up_down.Clear();
            _atr_reached_not_reached.Clear();
        }
    }
}

Kind Regards,

 

It could depending on your connection and the response time of the cTrader servers.

What you might consider doing is using "MarketData.GetBarsAsync" instead. So then you can process each atr and show it as its data comes in. Otherwise, you have to wait until everything is received before data is shown.


@firemyst