I'm comparing the performance of WL6 and WL8 using the same ASCII DataSet containing 7,000 symbols and the same script. Here are the results:
Data Loading Time:
WL6: 50 sec
WL8: 8 min 20 sec
Script Execution Time:
WL6: 1 min 58 sec
WL8: 4 min 5 sec
As shown, WL6 loads data nearly 10 times faster than WL8 and executes the backtest over twice as fast.
Is there any explanation for this difference, and is it expected behavior?
Data Loading Time:
WL6: 50 sec
WL8: 8 min 20 sec
Script Execution Time:
WL6: 1 min 58 sec
WL8: 4 min 5 sec
As shown, WL6 loads data nearly 10 times faster than WL8 and executes the backtest over twice as fast.
Is there any explanation for this difference, and is it expected behavior?
Rename
Event Providers would explain long data loading times. Disable Event Providers.
I'm not sure about script execution. How was it measured? Are you including post-processing by perhaps a different set of Performance Visualizers?
I'm not sure about script execution. How was it measured? Are you including post-processing by perhaps a different set of Performance Visualizers?
Where and how can I disable Event Providers?
Script execution was measured manually with a timer.
I am unsure if I am including post-processing, and there are no extra Performance Visualizers, only the ones that come with WL8 by default.
Script execution was measured manually with a timer.
I am unsure if I am including post-processing, and there are no extra Performance Visualizers, only the ones that come with WL8 by default.
Data Manager > Event Providers
Once you're there, hit F1 to read about how to use Events.
All Performance Visualizer are different from those in WL6 because they're from a
different app. So you're including post processing.
Disable the Performance Visualizers and re-open the Strategy.
In WL8, they're in Preferences > Backtest.
In WL6, they're in Preferences too (as I recall).
Once you're there, hit F1 to read about how to use Events.
All Performance Visualizer are different from those in WL6 because they're from a
different app. So you're including post processing.
Disable the Performance Visualizers and re-open the Strategy.
In WL8, they're in Preferences > Backtest.
In WL6, they're in Preferences too (as I recall).
After disabling all Event Providers and removing all Performance Visualizers except "Metric Report" in WL8, here are the results:
Data Loading Time:
WL8: 6 min 30 sec
Script Execution Time:
WL8: 5 min 12 sec
While data loading time improved by 25%, it remained eight times slower than WL6. Meanwhile, script execution time worsened, indicating that these changes did not provide any benefit.
Data Loading Time:
WL8: 6 min 30 sec
Script Execution Time:
WL8: 5 min 12 sec
While data loading time improved by 25%, it remained eight times slower than WL6. Meanwhile, script execution time worsened, indicating that these changes did not provide any benefit.
QUOTE:
Data Loading Time:
WL8: 6 min 30 sec
Loading ASCII files for any program is going to be really slow. If you need speed, I would subscribe to a regular historical data provider so you're loading binary files instead.
Loading ASCII is only one aspect of the issue. The bigger concern is script execution time, as WL8 is more than twice as slow as WL6.
It may be slower depending on the underlying code. Here is more info:
https://www.wealth-lab.com/Discussion/WL8-optimization-compared-to-WL6-11639
https://www.wealth-lab.com/Discussion/WL8-optimization-compared-to-WL6-11639
But let's do a truly fair comparison. Here's RSI Agita run on a 3.1 million 1 minute bar DataSet in WL6 and WL8. Note, you have to time the execution of the strategy only, not the time it takes to load visualizers post execution, because that would not be a fair comparison. I'll add the code for both strategies WL6 and WL8 that includes the timing and reporting of execution speed.
WL6 Code:
WL8 Code:
Results:
On my system with the 3.1 million bar ASCII DataSet
WL6: 00:00:19.1281920 (19 seconds)
WL8: 00:00:05.6337500 (5 seconds)
Clearly WL8 is almost FOUR TIMES FASTER in Strategy execution. This makes sense because deep down all it's doing is running .NET code, and MSoft greatly optimized code execution in .NET8 compared to the old .NET framework that WL6 uses.
WL6 Code:
CODE:
/* RSIAgita RSI Agita Strategy */ using System; using System.Collections.Generic; using System.Text; using System.Drawing; using WealthLab; using WealthLab.Indicators; namespace WealthLab.Strategies { public class RSIAgita : WealthScript { //Create parameters private StrategyParameter rsiPeriod; private StrategyParameter overbought; private StrategyParameter oversold; public RSIAgita() { rsiPeriod = CreateParameter("RSI Period", 20, 10, 60, 5); oversold = CreateParameter("Oversold", 30, 10, 40, 5); overbought = CreateParameter("Overbought", 55, 40, 80, 5); } protected override void Execute() { int level; int period = rsiPeriod.ValueInt; //Create and plot 20 period RSI RSI rsi20 = RSI.Series(Close, period); ChartPane rsiPane = CreatePane(50, true, true); PlotSeries(rsiPane, rsi20, Color.Navy, LineStyle.Solid, 3); DrawHorzLine(rsiPane, oversold.Value, Color.Red, LineStyle.Dotted, 2); DrawHorzLine(rsiPane, overbought.Value, Color.Green, LineStyle.Dotted, 2); DateTime dt = DateTime.Now; //Trading system main loop for (int bar = period + 1; bar < Bars.Count; bar++) { //Entries are allowed only if price is below last entry price double lastEntryPrice = IsLastPositionActive ? LastPosition.EntryPrice : Double.MaxValue; //Check penetration of RSI below levels 35 down to 5 level = oversold.ValueInt; while (level > 0) { if (CrossUnder(bar, rsi20, level)) if (Bars.Close[bar] < lastEntryPrice) BuyAtMarket(bar + 1); level -= 5; } //Exit all long positions if RSI crosses above 45 if (CrossOver(bar, rsi20, overbought.ValueInt)) foreach (Position pos in Positions) if (pos.Active) SellAtMarket(bar + 1, pos); } TimeSpan span = DateTime.Now - dt; PrintDebug(span.ToString()); } } }
WL8 Code:
CODE:
using System; using WealthLab.Core; using WealthLab.Indicators; using System.Drawing; using WealthLab.Backtest; namespace WealthScript1 { public class RSIAgita : UserStrategyBase { public RSIAgita() { AddParameter("RSI Period", ParameterType.Int32, 15, 5, 50, 5); AddParameter("Oversold", ParameterType.Int32, 25, 10, 60, 5); AddParameter("Overbought", ParameterType.Int32, 70, 10, 60, 5); } //create indicators and other objects here, this is executed prior to the main trading loop public override void Initialize(BarHistory bars) { period = Parameters[0].AsInt; oversold = Parameters[1].AsInt; overbought = Parameters[2].AsInt; //Create and plot RSI rsi = RSI.Series(bars.Close, period); PlotTimeSeries(rsi, "rsi", "RSI", WLColor.Aqua); DrawHorzLine(oversold, WLColor.Red, 2, LineStyle.Dotted, "RSI"); DrawHorzLine(overbought, WLColor.Green, 2, LineStyle.Dotted, "RSI"); StartIndex = period + 1; dt = DateTime.Now; } public override void BacktestComplete() { TimeSpan span = DateTime.Now - dt; WriteToDebugLog(span.ToString()); } //execute the strategy rules here, this is executed once for each bar in the backtest history public override void Execute(BarHistory bars, int idx) { //Entries are allowed only if price is below last entry price double lastEntryPrice = Double.MaxValue; if (LastOpenPosition != null) lastEntryPrice = LastOpenPosition.EntryPrice; //Check penetration of RSI below levels 35 down to 5 level = oversold; while (level > 0) { if (rsi.CrossesUnder(level, idx)) if (bars.Close[idx] < lastEntryPrice) PlaceTrade(bars, TransactionType.Buy, OrderType.Market); level -= 5; } //Exit all long positions if RSI crosses above 45 if (rsi.CrossesOver(overbought, idx)) foreach (Position pos in GetPositions()) if (pos.IsOpen) ClosePosition(pos, OrderType.Market); } //declare private variables below int oversold, overbought, level, period; RSI rsi; DateTime dt; } }
Results:
On my system with the 3.1 million bar ASCII DataSet
WL6: 00:00:19.1281920 (19 seconds)
WL8: 00:00:05.6337500 (5 seconds)
Clearly WL8 is almost FOUR TIMES FASTER in Strategy execution. This makes sense because deep down all it's doing is running .NET code, and MSoft greatly optimized code execution in .NET8 compared to the old .NET framework that WL6 uses.
Re: Loading time
ASCII loading should take a while the first time, but it should be converted to a binary cache file for faster access. That conversion works well in WL6 any time the file changes, but I'm recalling some misguided logic in WL8 that prevents that from happening unless you request "All Data" and the file has at least 20,000 records in it.
Changing that has been on the "To Do" list for some time.
ASCII loading should take a while the first time, but it should be converted to a binary cache file for faster access. That conversion works well in WL6 any time the file changes, but I'm recalling some misguided logic in WL8 that prevents that from happening unless you request "All Data" and the file has at least 20,000 records in it.
Changing that has been on the "To Do" list for some time.
Thanks for your responses.
I'll review my script later to enhance its compatibility with WL8 and take advantage of its speed capabilities.
I'll review my script later to enhance its compatibility with WL8 and take advantage of its speed capabilities.
Your Response
Post
Edit Post
Login is required