cAlgo doesn't support Multithreading

Created at 17 Nov 2017, 13:59
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

cAlgo doesn't support Multithreading
17 Nov 2017, 13:59


Hi Spotware,

Please can you tell us what this error means?  Multithreading doesn't seem to be supported.

using System;
using System.Linq;
using cAlgo.API;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;
using cAlgo.Indicators;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Collections.Concurrent;
 
namespace cAlgo
{
    [Indicator(IsOverlay = false, TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class NewIndicator : Indicator
    {
        [Parameter(DefaultValue = 0.0)]
        public double Parameter { get; set; }
 
        [Output("Main")]
        public IndicatorDataSeries Result { get; set; }
 
        ///////////////////////////////////////////////////////////////////////////////////////////////////
        //                       Illustration Purposes
        //   Goal is to get the lows of multiple symbols in a specified timeframe at the same time
        //   
        ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 
        protected override void Initialize()
        {
            ///////////////////////////////////////////////////////////////////////////////////////////////////
            //                       Attempt 1
            //   Calling MarketData.GetSeries & MarketSeries works fine together, 
            //   however 2 x MarketData.GetSeries calls Kicking off at the same time seems to be a problem.
            //   Uncomment below to run.
            ///////////////////////////////////////////////////////////////////////////////////////////////////
 
            // Attempt1_GetSymbolCodeLowAsyncWithTasks();
 
            ///////////////////////////////////////////////////////////////////////////////////////////////////
            //                       Attempt 2
            //   Parallel Foreach loop work fine with doing dummy calculation
            //   If same logic is applied but trying to get lows of multiple symbols, we run into a problem.
            //   Uncomment below to run.
            ///////////////////////////////////////////////////////////////////////////////////////////////////        
 
            Attempt_2_ParallelGetLows(AllSymbolCodes());
        }
 
        public override void Calculate(int index)
        {
            // Calculate value at specified index
            // Result[index] = ...
        }
        public void Attempt1_GetSymbolCodeLowAsyncWithTasks()
        {
            var t1 = Task.Factory.StartNew(() => EURUSD());
            var t2 = Task.Factory.StartNew(() => GBPUSD());
            var t3 = Task.Factory.StartNew(() => USDCHF());
            var t4 = Task.Factory.StartNew(() => USDJPY());
        }
 
        public double EURUSD()
        {
            Print("API Call 1 Kicking Off");
            double result = (MarketData.GetSeries(MarketData.GetSymbol("EURUSD"), TimeFrame.Daily).Low.Last(0));
            Print("API Call 1 EURUSD Low Result: ", result);
            return result;
        }
        public string GBPUSD()
        {
            Print("API Call 2 Kicking Off (Different API) ");
            string result = (MarketSeries.SymbolCode);
            Print("API Call 2 Get Symbol Code Result: ", result);
            return result;
        }
        public double USDCHF()
        {
            Print("Kicking off API Call 3");
            double result = (MarketData.GetSeries(MarketData.GetSymbol("USDCHF"), TimeFrame.Daily).Open.Last(0));
            Print("API Call 3 Get USDCHF Open Result: ", result);
            return result;
        }
        public double USDJPY()
        {
            Print("Kicking off API Call 4");
            double result = (MarketData.GetSeries(MarketData.GetSymbol("USDJPY"), TimeFrame.Daily).Close.Last(0));
            Print("API Call 4 Get USDJPY Close Result: ", result);
            return result;
        }
 
 
        public List<Symbol> AllSymbolCodes()
        {
            List<Symbol> allSymbolCodes = new List<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")
            };
            return allSymbolCodes;
        }
        public ConcurrentBag<double> Attempt_2_ParallelGetLows(List<Symbol> allSymbolCodes)
        {
            var StartTime = Server.Time;
            ConcurrentBag<double> allSymbolCodesDaily = new ConcurrentBag<double>();
 
            Print("Starting Parallel Loop Testing ...");
            ConcurrentBag<double> TestParallel = new ConcurrentBag<double> 
            {
                1.1,
                2.2,
                3.3,
                4.4,
                5.5,
                6.6,
                7.7,
                8.8
            };
            ConcurrentBag<double> TestParallel2 = new ConcurrentBag<double>();
 
            //Testing Parallel For Loop with dummy data, seems to work fine.
 
            Parallel.ForEach(TestParallel, (double t) =>
            {
                double result = 5 * t;
                TestParallel2.Add(result);
            });
            Print("Ending Parralel Loop Test...");
            Print("Test Loop Results: ", string.Join(",", TestParallel2));
 
            //Get lows of multiple symbols using Parallel For Loop, doesn't seem to work.
 
            Print("Starting Parralel Loop Get Lows...");
            Parallel.ForEach(allSymbolCodes, (Symbol i) =>
            {
                double result = (MarketData.GetSeries(i, TimeFrame.Daily).Low.Last(0));
                allSymbolCodesDaily.Add(result);
            });
            Print("Ending Parralel Loop Get Lows...");
            Print(string.Join(",", allSymbolCodesDaily));
 
            return (allSymbolCodesDaily);
        }
    }
}

What does the errors mean?


@myinvestmentsfx
Replies

PanagiotisCharalampous
20 Nov 2017, 14:35

Hi myinvestmentsfx,

Please see my reply here.

Best Regards,

Panagiotis


@PanagiotisCharalampous