I have a small program which I am using for algorithmic stock trading. The code has to loop about 192 trillion times on my 8-core desktop machine. I thought about renting out a 64 core machine to run this, but it wasn't cost effective.
It's just this bit of code. But the for loops has to loop on every bar to be calculated (about 1.8million) and then the list it loops through to check for a match is about 800k items.
The only way I could think of to speed it up for now, is to remove the matched item, as it only happens once (DateTime).
Does anyone else have a way to speed this code up a bit faster? It's taking my desktop beast about 45 hours to run through one iteration of the program.
Basically what I am doing is calculating on every bar, looking for to see if the current bar DateTime matches a DateTime I have in a CSV file that I created by hand. Then from the list Object, I grab the trade direction and set a bool to take a 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 the slowdown is the For Loop inside the CalcBar() method.