我有一个小程序,用于算法股票交易。该代码在我的 8 核台式机上必须循环大约 192 万亿次。我考虑过租一台 64 核机器来运行它,但它不符合成本效益。
这只是一小段代码。但是 for 循环必须在每个要计算的柱上循环(大约 180 万个),然后它循环检查匹配的列表大约有 80 万个项目。
目前我能想到的加快速度的唯一方法是删除匹配的项目,因为它只发生一次(日期时间)。
还有其他人有办法加快这段代码的速度吗?我的桌面巨兽花了大约 45 个小时来运行该程序的一次迭代。
基本上我正在做的是计算每个柱,查看当前柱的日期时间是否与我手动创建的 CSV 文件中的日期时间匹配。然后从列表对象中,我获取交易方向并设置一个 bool 值来建立仓位。
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; }
}
}
速度变慢的罪魁祸首是 CalcBar() 方法内的 For 循环。
最佳答案
您是否尝试过分析此方法?我们掌握的信息太少了。例如,成本最高的操作可能是
Bars.Time[0] == tradeList.ElementAt(i).time
我们不知道这一点。您应该首先对其进行概要分析。
下一步...
tradeList.ElementAt(i).direction == "Up"
不要使用字符串。弦很慢。您可以在这里使用枚举,它将针对整数进行优化,并且整数比较比字符串快得多。
不要使用ElementAt方法。仅使用 [] 运算符。速度更快了。
考虑使用字典而不是列表。它比列表快得多。列表必须遍历每个元素才能找到您需要的内容。字典没有。这可能是真正关键的部分。
考虑使用整数而不是日期时间。将整数视为秒。它会比 DateTime 更快。
并使用Parallel.ForEach代替普通的for。然后它将使用其他核心。普通的可能只使用一个核心。
哦,还有一件事。如果是股票应用,也许你可以尝试使用神经网络?但这是一个完全不同的故事。
关于c# - 加速此代码 — 192 万亿次 for() 循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44196461/