Speeding up this code - 192 trillion for () loops

I have a small program that I use for algorithmic stock trading. The code should take about 192 trillion times on my 8-core desktop. I was thinking of renting a 64-core machine to run this, but it was inefficient.

This is just this bit of code. But for for loops, it is necessary to execute a loop on each bar, which will be calculated (about 1.8 million), and then the list that he skipped to check the correspondence is about 800 thousand elements.

The only way I could speed it up now is to remove the matching element, as this only happens once (DateTime).

Does anyone else have a way to speed up this code? It takes my desktop about 45 hours to complete one iteration of the program.

Basically what I do is computed on each bar, looking for the current DateTime byte to match the DateTime that I have in the CSV file I created manually. Then, from the Object list, I grabbed the direction of the trade and set bool for the position.

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using PowerLanguage.Function;
using ATCenterProxy.interop;
using System.IO;
using System.IO.Compression;

namespace PowerLanguage.Strategy
{
    public class Ecal_v1 : SignalObject
    {
        public List<Trades> tradeList = new List<Trades>();
        public List<string> csvList = new List<string>();
        public bool exitOn24 = false;
        public string ecalPath = @"C:\Users\Skynet\OneDrive\Trading\Economic Calendars\backtest1.csv";
        PowerLanguage.Indicator.Bollinger_Bands bb;

        public Ecal_v1(object _ctx):base(_ctx){}

        //[Input]
        //public bool exitOn24 { get; set; }

        [Input]
        public double bbTopOffset { get; set; }
        775
        [Input]
        public double bbBotOffset { get; set; }

        [Input]
        public double longTPMod { get; set; }

        [Input]
        public double shortTPMod { get; set; }

        [Input]
        public double longSLMod { get; set; }

        [Input]
        public double shortSLMod { get; set; }

        //[Input]
        //public double buyTrail { get; set; }

        //[Input]
        //public double sellTrail { get; set; }

        double bbUpperDiff;
        double bbLowerDiff;
        double bbBasis;
        double longTP;
        double shortTP;
        double longSL;
        double shortSL;
        double ptValue;
        public DateTime tradeTime;

        private IOrderMarket longEntry, shortEntry, longExit, shortExit;

        protected override void Create()
        {
            // create variable objects, function objects, order objects etc.
            bb = ((PowerLanguage.Indicator.Bollinger_Bands)AddIndicator("Bollinger_Bands"));

            longEntry = OrderCreator.MarketNextBar(new SOrderParameters(Contracts.Default, EOrderAction.Buy));
            shortEntry = OrderCreator.MarketNextBar(new SOrderParameters(Contracts.Default, EOrderAction.SellShort));
            longExit = OrderCreator.MarketNextBar(new SOrderParameters(Contracts.Default, EOrderAction.Sell));
            shortExit = OrderCreator.MarketNextBar(new SOrderParameters(Contracts.Default, EOrderAction.BuyToCover));
        }

        protected override void StartCalc()
        {
            // assign inputs 
            GetEcal();
            ptValue = Bars.Point;

            longTP = longTPMod;
            longSL = longSLMod;
            shortTP = shortTPMod;
            shortSL = shortSLMod;

        }

        protected override void CalcBar()
        {
            bool LE = false;
            bool SE = false;
            bool LX = false;
            bool SX = false;

            for(int i=0; i<tradeList.Count; i++)
            {
                if(Bars.Time[0] == tradeList.ElementAt(i).time)
                {
                    if (tradeList.ElementAt(i).direction == "Up")
                    {
                        LE = true;
                        tradeList.RemoveAt(i);
                    }
                    else if (tradeList.ElementAt(i).direction == "Down")
                    {
                        SE = true;
                        tradeList.RemoveAt(i);
                    }
                    else
                    {

                    }
                }
            }

            if(exitOn24 == true)
            {
                if (Bars.Time[0] > tradeTime.AddHours(24))
                {
                    LX = true;
                    SX = true;
                }
            }

            if (StrategyInfo.MarketPosition == 0)
            {
                if (LE)
                {
                    longEntry.Send();
                    tradeTime = Bars.Time[0];
                    setLongStops();     
                }
                else if (SE)
                {
                    shortEntry.Send();
                    tradeTime = Bars.Time[0];
                    setShortStops();        
                }
            }

            else if (StrategyInfo.MarketPosition > 0)
            {
                if (LX)
                {
                    longExit.Send();
                }
                else if (LE)
                {
                    longEntry.Send();
                    tradeTime = Bars.Time[0];
                    setLongStops();
                }
                else
                {
                    CurSpecOrdersMode = ESpecOrdersMode.PerPosition;
                    GenerateStopLossPt(longSL);
                    GenerateProfitTargetPt(longTP);
                    //GenerateTrailingStopPt(buyTrail);
                }
            }

            else if (StrategyInfo.MarketPosition < 0)
            {
                if (SX)
                {
                    shortExit.Send();
                }
                else if (SE)
                {
                    shortEntry.Send();
                    tradeTime = Bars.Time[0];
                    setShortStops();
                }
                else
                {
                    CurSpecOrdersMode = ESpecOrdersMode.PerPosition;
                    GenerateStopLossPt(shortSL);
                    GenerateProfitTargetPt(shortTP);
                    //GenerateTrailingStopPt(sellTrail);
                }
            }
        }

        private void GetEcal()
        {
            csvList = File.ReadAllLines(ecalPath).Skip(1).ToList();
            foreach(string line in csvList)
            {
                string[] values = line.Split(',');
                tradeList.Add(new Trades { time = Convert.ToDateTime(values[0]), direction = values[1] });
            }
        }
    }


    public class Trades
    {
        public DateTime time { get; set; }
        public string direction { get; set; }
    }


}

The culprit of slowdown is the For loop inside the CalcBar () method.

+4
source share
4 answers

Have you tried to comment on this method? We have too little information. For example, the most expensive operation is

Bars.Time[0] == tradeList.ElementAt(i).time

We do not know this. You must view it first.

What's next...

tradeList.ElementAt(i).direction == "Up"

. . , , .

ElementAt. []. .

. , . , , . . , .

dateTimes. . , DateTime.

Parallel.ForEach . . , , .

, . , , Neural Network? .

+7
  • RemoveAt , . . . .

    , , , (sourceList.Except(removedList)); - .

  • CSV .

    .

  • ElementAt . , [], .

  • , direction "" "".

, . , - , Parallel.For for. " " , .

+6

- , . :

Bars.Time[0] == tradeList.ElementAt(i).time;

Tom , LINQ, , , :

tradeList.Where(t => t.time == Bars.Time[0]);

if, , :

tradeList.ElementAt(i).direction == "Down" || tradeList.ElementAt(i).direction == "Up";

, LINQ :

tradeList.RemoveAll(d => d.direction == "Down" || d => d.Direction == "Up");

RemoveAll Tom:

tradeList.Where(t => t.time == Bars.Time[0])
    .RemoveAll(d => d.direction == "Up" || d => d.direction == "Down");

, , foreach. , PLINQ. PLINQ, :

tradeList.AsParallel().tradeList.Where(t => t.time != Bars.Time[0] 
    && (d => d.direction != "Up" || d => d.direction != "Down"));

RemoveAll() Where(), , . , bool (LE SE) , , . -.

-1

Source: https://habr.com/ru/post/1677968/


All Articles