Search Framework:
StrategyRunner
Namespace: WealthLab.Backtest
Parent: Object

A helper class the provides a simplified method of running Strategy backtests and obtaining their performance results. Can be utilized within a WL8 Extension, or even within Strategy code itself.

StrategyRunner

A helper class the provides a simplified method of running Strategy backtests and obtaining their performance results. Can be utilized within a WL8 Extension, or even within Strategy code itself.

StrategyRunner

Members
BacktestSettings
public BacktestSettings BacktestSettings

Determines the backtest settings to use during the backtest.

Example Code
using WealthLab.Backtest;
using WealthLab.Core;
using System;

namespace WealthScript1
{
	public class MyStrategy : UserStrategyBase
	{
		//Initialize
		public override void Initialize(BarHistory bars)
		{
		}

		//Execute
		public override void Execute(BarHistory bars, int idx)
		{
		}

		//Backtest Completed (executes once)
		public override void BacktestComplete()
		{
			StrategyRunner sr = new StrategyRunner();
			foreach (BarHistory bars in BacktestData)
				sr.Symbols.Add(bars.Symbol);
			sr.BacktestSettings.CommissionType = CommissionType.None;
			Backtester bt = sr.RunBacktest("RSI Agita");
			WriteToDebugLog("RSI Agita on backtested data without commission: " + bt.NetProfit.ToString("N2"));
			WriteToDebugLog("Number of Trades: " + bt.Metrics.PositionCount.ToString("N0"));
			double profit = bt.NetProfit;
			sr.BacktestSettings.CommissionType = CommissionType.Flat;
			sr.BacktestSettings.CommissionAmount = 4.95;
			bt = sr.RunBacktest("RSI Agita");
			WriteToDebugLog("RSI Agita on backtested data with $4.95 flat commission: " + bt.NetProfit.ToString("N2"));
			WriteToDebugLog("Number of Trades: " + bt.Metrics.PositionCount.ToString("N0"));
			profit -= bt.NetProfit;
			WriteToDebugLog("Difference: " + profit.ToString("N2"));
		}

	}
}

BacktestSettings
public BacktestSettings BacktestSettings

Determines the backtest settings to use during the backtest.

Example Code
using WealthLab.Backtest;
using WealthLab.Core;
using System;

namespace WealthScript1
{
	public class MyStrategy : UserStrategyBase
	{
		//Initialize
		public override void Initialize(BarHistory bars)
		{
		}

		//Execute
		public override void Execute(BarHistory bars, int idx)
		{
		}

		//Backtest Completed (executes once)
		public override void BacktestComplete()
		{
			StrategyRunner sr = new StrategyRunner();
			foreach (BarHistory bars in BacktestData)
				sr.Symbols.Add(bars.Symbol);
			sr.BacktestSettings.CommissionType = CommissionType.None;
			Backtester bt = sr.RunBacktest("RSI Agita");
			WriteToDebugLog("RSI Agita on backtested data without commission: " + bt.NetProfit.ToString("N2"));
			WriteToDebugLog("Number of Trades: " + bt.Metrics.PositionCount.ToString("N0"));
			double profit = bt.NetProfit;
			sr.BacktestSettings.CommissionType = CommissionType.Flat;
			sr.BacktestSettings.CommissionAmount = 4.95;
			bt = sr.RunBacktest("RSI Agita");
			WriteToDebugLog("RSI Agita on backtested data with $4.95 flat commission: " + bt.NetProfit.ToString("N2"));
			WriteToDebugLog("Number of Trades: " + bt.Metrics.PositionCount.ToString("N0"));
			profit -= bt.NetProfit;
			WriteToDebugLog("Difference: " + profit.ToString("N2"));
		}

	}
}

BenchmarkData
public BarHistory BenchmarkData

Specifies a BarHistory instance to use for the benchmark backtest, which is used in computing certain performance metrics like Alpha and Beta. If this property is null or empty, the StrategyRunner will attempt to load benchmark data from the BenchmarkSymbol property.


BenchmarkData
public BarHistory BenchmarkData

Specifies a BarHistory instance to use for the benchmark backtest, which is used in computing certain performance metrics like Alpha and Beta. If this property is null or empty, the StrategyRunner will attempt to load benchmark data from the BenchmarkSymbol property.


BenchmarkSymbol
public string BenchmarkSymbol

Specifies the symbol to use for the benchmark backtest, which is used in computing certain performance metrics like Alpha and Beta. If the StrategyRunner's BenchmarkData propery is null or empty, it will attempt to load the benchmark data using this symbol.

Example Code
using WealthLab.Backtest;
using WealthLab.Core;
using System;

namespace WealthScript1
{
	public class MyStrategy : UserStrategyBase
	{
		//Initialize
		public override void Initialize(BarHistory bars)
		{
		}

		//Execute
		public override void Execute(BarHistory bars, int idx)
		{
		}

		//Backtest Completed (executes once)
		public override void BacktestComplete()
		{
			StrategyRunner sr = new StrategyRunner();
			foreach (BarHistory bars in BacktestData)
				sr.Symbols.Add(bars.Symbol);
			sr.BenchmarkSymbol = "SPY";
			Backtester bt = sr.RunBacktest("RSI Agita");
			WriteToDebugLog("RSI Agita on backtested data with SPY benchmark Alpha= " + bt.Metrics.Alpha.ToString("N2"));
			sr.BenchmarkSymbol = "QQQ";
			bt = sr.RunBacktest("RSI Agita");
			WriteToDebugLog("RSI Agita on backtested data with QQQ benchmark Alpha= " + bt.Metrics.Alpha.ToString("N2"));
		}

	}
}

BenchmarkSymbol
public string BenchmarkSymbol

Specifies the symbol to use for the benchmark backtest, which is used in computing certain performance metrics like Alpha and Beta. If the StrategyRunner's BenchmarkData propery is null or empty, it will attempt to load the benchmark data using this symbol.

Example Code
using WealthLab.Backtest;
using WealthLab.Core;
using System;

namespace WealthScript1
{
	public class MyStrategy : UserStrategyBase
	{
		//Initialize
		public override void Initialize(BarHistory bars)
		{
		}

		//Execute
		public override void Execute(BarHistory bars, int idx)
		{
		}

		//Backtest Completed (executes once)
		public override void BacktestComplete()
		{
			StrategyRunner sr = new StrategyRunner();
			foreach (BarHistory bars in BacktestData)
				sr.Symbols.Add(bars.Symbol);
			sr.BenchmarkSymbol = "SPY";
			Backtester bt = sr.RunBacktest("RSI Agita");
			WriteToDebugLog("RSI Agita on backtested data with SPY benchmark Alpha= " + bt.Metrics.Alpha.ToString("N2"));
			sr.BenchmarkSymbol = "QQQ";
			bt = sr.RunBacktest("RSI Agita");
			WriteToDebugLog("RSI Agita on backtested data with QQQ benchmark Alpha= " + bt.Metrics.Alpha.ToString("N2"));
		}

	}
}

Data
public List<BarHistory> Data

If its DataSet and Symbols property are null and/or empty, the StrategyRunner will use the contents of its Data property as source data for backtesting. You can add BarHistory instances to the Data property manually as required.

Example Code
using WealthLab.Backtest;
using WealthLab.Core;
using WealthLab.Data;

namespace WealthScript1
{
	public class MyStrategy : UserStrategyBase
	{
		//Initialize
		public override void Initialize(BarHistory bars)
		{
		}

		//Execute
		public override void Execute(BarHistory bars, int idx)
		{
		}

		//Backtest Completed (executes once)
		public override void BacktestComplete()
		{
			StrategyRunner sr = new StrategyRunner();
			sr.Data = BacktestData;
			Backtester bt = sr.RunBacktest("RSI Agita");
			WriteToDebugLog("RSI Agita on currently selected Data: " + bt.NetProfit.ToString("N2"));
			WriteToDebugLog("Number of Trades: " + bt.Metrics.PositionCount.ToString("N0"));
		}

	}
}

Data
public List<BarHistory> Data

If its DataSet and Symbols property are null and/or empty, the StrategyRunner will use the contents of its Data property as source data for backtesting. You can add BarHistory instances to the Data property manually as required.

Example Code
using WealthLab.Backtest;
using WealthLab.Core;
using WealthLab.Data;

namespace WealthScript1
{
	public class MyStrategy : UserStrategyBase
	{
		//Initialize
		public override void Initialize(BarHistory bars)
		{
		}

		//Execute
		public override void Execute(BarHistory bars, int idx)
		{
		}

		//Backtest Completed (executes once)
		public override void BacktestComplete()
		{
			StrategyRunner sr = new StrategyRunner();
			sr.Data = BacktestData;
			Backtester bt = sr.RunBacktest("RSI Agita");
			WriteToDebugLog("RSI Agita on currently selected Data: " + bt.NetProfit.ToString("N2"));
			WriteToDebugLog("Number of Trades: " + bt.Metrics.PositionCount.ToString("N0"));
		}

	}
}

DataRange
public DataRange DataRange

Determines the data range to use for the backtest. The default range is the most recent 10 years.

Example Code
using WealthLab.Backtest;
using WealthLab.Core;
using System;

namespace WealthScript1
{
	public class MyStrategy : UserStrategyBase
	{
		//Initialize
		public override void Initialize(BarHistory bars)
		{
		}

		//Execute
		public override void Execute(BarHistory bars, int idx)
		{
		}

		//Backtest Completed (executes once)
		public override void BacktestComplete()
		{
			StrategyRunner sr = new StrategyRunner();
			foreach (BarHistory bars in BacktestData)
				sr.Symbols.Add(bars.Symbol);
			sr.DataRange = new DataRange(DataRangeType.YearRange, 0, DateTime.Now.Date.AddYears(-10), DateTime.Now.Date);
			Backtester bt = sr.RunBacktest("RSI Agita");
			WriteToDebugLog("RSI Agita Current Range on backtested data: " + bt.NetProfit.ToString("N2"));
			WriteToDebugLog("Number of Trades: " + bt.Metrics.PositionCount.ToString("N0"));
			sr.DataRange.StartDate = DateTime.Now.Date.AddYears(-20);
			sr.DataRange.EndDate = DateTime.Now.AddYears(-10);
			bt = sr.RunBacktest("RSI Agita");
			WriteToDebugLog("RSI Agita Ealier Range on backtested data: " + bt.NetProfit.ToString("N2"));
			WriteToDebugLog("Number of Trades: " + bt.Metrics.PositionCount.ToString("N0"));
		}

	}
}

DataRange
public DataRange DataRange

Determines the data range to use for the backtest. The default range is the most recent 10 years.

Example Code
using WealthLab.Backtest;
using WealthLab.Core;
using System;

namespace WealthScript1
{
	public class MyStrategy : UserStrategyBase
	{
		//Initialize
		public override void Initialize(BarHistory bars)
		{
		}

		//Execute
		public override void Execute(BarHistory bars, int idx)
		{
		}

		//Backtest Completed (executes once)
		public override void BacktestComplete()
		{
			StrategyRunner sr = new StrategyRunner();
			foreach (BarHistory bars in BacktestData)
				sr.Symbols.Add(bars.Symbol);
			sr.DataRange = new DataRange(DataRangeType.YearRange, 0, DateTime.Now.Date.AddYears(-10), DateTime.Now.Date);
			Backtester bt = sr.RunBacktest("RSI Agita");
			WriteToDebugLog("RSI Agita Current Range on backtested data: " + bt.NetProfit.ToString("N2"));
			WriteToDebugLog("Number of Trades: " + bt.Metrics.PositionCount.ToString("N0"));
			sr.DataRange.StartDate = DateTime.Now.Date.AddYears(-20);
			sr.DataRange.EndDate = DateTime.Now.AddYears(-10);
			bt = sr.RunBacktest("RSI Agita");
			WriteToDebugLog("RSI Agita Ealier Range on backtested data: " + bt.NetProfit.ToString("N2"));
			WriteToDebugLog("Number of Trades: " + bt.Metrics.PositionCount.ToString("N0"));
		}

	}
}

DataSet
public DataSet DataSet

If assigned a value, the StrategyRunner will use this DataSet as its data source for the backtest. You can use the DataSetFactory class to obtain a DataSet instance by name.

Example Code
using WealthLab.Backtest;
using WealthLab.Core;
using WealthLab.Data;

namespace WealthScript1
{
	public class MyStrategy : UserStrategyBase
	{
		//Initialize
		public override void Initialize(BarHistory bars)
		{
		}

		//Execute
		public override void Execute(BarHistory bars, int idx)
		{
		}

		//Backtest Completed (executes once)
		public override void BacktestComplete()
		{
			StrategyRunner sr = new StrategyRunner();
			DataSet cryptos = DataSetFactory.Instance.Find("Cryptocurrency - Top 20");
			sr.DataSet = cryptos;
			Backtester bt = sr.RunBacktest("RSI Agita");
			WriteToDebugLog("RSI Agita on Cryptos Net Profit: " + bt.NetProfit.ToString("N2"));
			WriteToDebugLog("Number of Trades: " + bt.Metrics.PositionCount.ToString("N0"));
		}

	}
}

DataSet
public DataSet DataSet

If assigned a value, the StrategyRunner will use this DataSet as its data source for the backtest. You can use the DataSetFactory class to obtain a DataSet instance by name.

Example Code
using WealthLab.Backtest;
using WealthLab.Core;
using WealthLab.Data;

namespace WealthScript1
{
	public class MyStrategy : UserStrategyBase
	{
		//Initialize
		public override void Initialize(BarHistory bars)
		{
		}

		//Execute
		public override void Execute(BarHistory bars, int idx)
		{
		}

		//Backtest Completed (executes once)
		public override void BacktestComplete()
		{
			StrategyRunner sr = new StrategyRunner();
			DataSet cryptos = DataSetFactory.Instance.Find("Cryptocurrency - Top 20");
			sr.DataSet = cryptos;
			Backtester bt = sr.RunBacktest("RSI Agita");
			WriteToDebugLog("RSI Agita on Cryptos Net Profit: " + bt.NetProfit.ToString("N2"));
			WriteToDebugLog("Number of Trades: " + bt.Metrics.PositionCount.ToString("N0"));
		}

	}
}

PerformOptimization
public OptimizationResultList PerformOptimization(string optMethod, string stratName, OptimizationRunComplete runComplete = null)
public OptimizationResultList PerformOptimization(string optMethod, Strategy s, OptimizationRunComplete runComplete = null)

Allows you to perform an optimization, using the Optimization Method specified by name in the optMethod parameter. Prior to running an optimization, you should configure the StrategyRunner data, scale, etc. in the same manner as required by RunBacktest. Also note that if you disabled a Strategy's parameter(s) in the Strategy window, the disabled state will carry over here and the disabled parameters will not participate in the optimization.

There are two versions of this method, allowing you to specify the Strategy to optimize by either name (stratName parameter) or by instance (s parameter).

The last parameter, runComplete, accepts a method containing two parameters and returning void. The StrategyRunner calls this method, is assigned, after each optimization run has been completed. The first parameter of the callback is an OptimizationResult instance and contains information on the results of the current run. The second parameter is a double containing the percent overall completion of the optimization.

The PerformOptimization method returns an instance of the OptimizationResultList class, which is a List<OptimizationResult> with a few additional members and contains the the results of each optimization run.

Example Code
using WealthLab.Backtest;
using WealthLab.Core;
using WealthLab.Data;
using System;

namespace WealthScript1 
{
	public class MyStrategy : UserStrategyBase
	{
		//Initialize
		public override void Initialize(BarHistory bars)
		{
		}

		//Execute
		public override void Execute(BarHistory bars, int idx)
		{
		}

		//Backtest Completed (executes once)
		public override void BacktestComplete()
		{
			StrategyRunner sr = new StrategyRunner();
			sr.DataSet = DataSetFactory.Instance.Find("Dow 30");
			OptimizationResultList orl = sr.PerformOptimization("Exhaustive", "Knife Juggler", RunCompleted);
			foreach (OptimizationResult or in orl)
			{
				WriteToDebugLog(or.ToString() + "\t" + or.AnnualizedReturn.ToString("N2") + "%", false);
			}
		}

		//delegated method
		private void RunCompleted(OptimizationResult or, double pctComplete)
		{
			WriteToStatusBar("Run: " + or.RunNumber + "   " + pctComplete.ToString("N2") + "%");
		}
	}
}

PositionSize
public PositionSize PositionSize

Determines the position to use for the backtest. The default position size is 10% of equity.

Example Code
using WealthLab.Backtest;
using WealthLab.Core;
using System;

namespace WealthScript1
{
	public class MyStrategy : UserStrategyBase
	{
		//Initialize
		public override void Initialize(BarHistory bars)
		{
		}

		//Execute
		public override void Execute(BarHistory bars, int idx)
		{
		}

		//Backtest Completed (executes once)
		public override void BacktestComplete()
		{
			StrategyRunner sr = new StrategyRunner();
			foreach (BarHistory bars in BacktestData)
				sr.Symbols.Add(bars.Symbol);
			Backtester bt = sr.RunBacktest("RSI Agita");
			WriteToDebugLog("RSI Agita on backtested data with 10% of equity: " + bt.NetProfit.ToString("N2"));
			WriteToDebugLog("Number of Trades: " + bt.Metrics.PositionCount.ToString("N0"));
			sr.PositionSize.Amount = 20;
			bt = sr.RunBacktest("RSI Agita");
			WriteToDebugLog("RSI Agita on backtested data with 20% of equity: " + bt.NetProfit.ToString("N2"));
			WriteToDebugLog("Number of Trades: " + bt.Metrics.PositionCount.ToString("N0"));
		}

	}
}

PositionSize
public PositionSize PositionSize

Determines the position to use for the backtest. The default position size is 10% of equity.

Example Code
using WealthLab.Backtest;
using WealthLab.Core;
using System;

namespace WealthScript1
{
	public class MyStrategy : UserStrategyBase
	{
		//Initialize
		public override void Initialize(BarHistory bars)
		{
		}

		//Execute
		public override void Execute(BarHistory bars, int idx)
		{
		}

		//Backtest Completed (executes once)
		public override void BacktestComplete()
		{
			StrategyRunner sr = new StrategyRunner();
			foreach (BarHistory bars in BacktestData)
				sr.Symbols.Add(bars.Symbol);
			Backtester bt = sr.RunBacktest("RSI Agita");
			WriteToDebugLog("RSI Agita on backtested data with 10% of equity: " + bt.NetProfit.ToString("N2"));
			WriteToDebugLog("Number of Trades: " + bt.Metrics.PositionCount.ToString("N0"));
			sr.PositionSize.Amount = 20;
			bt = sr.RunBacktest("RSI Agita");
			WriteToDebugLog("RSI Agita on backtested data with 20% of equity: " + bt.NetProfit.ToString("N2"));
			WriteToDebugLog("Number of Trades: " + bt.Metrics.PositionCount.ToString("N0"));
		}

	}
}

RunBacktest
public Backtester RunBacktest(string strategyName)
public Backtester RunBacktest(StrategyBase sb)

The RunBacktest method has two overrides. One lets you provide a Strategy Name, and the second an instance of the StrategyBase class that represents an already compiled Strategy. Call this method after having set the various properties that control the backtest scale, range, etc. The result is an instance of the Backtester class. You can query its Metrics property and various other properties to examine the performance results of the backtest.

If the DataSet property is assigned, the StrategyRunner will load the historical data for that DataSet's Symbols into its Data property. If DataSet is null, the StrategyRunner will next check its Symbols property, loading the data for these symbols into its Data property. As a last resort, the StrategyRunner will use its Data property, which you can pre-load with BarHistory instances manually if desired.

Example Code
using WealthLab.Backtest;
using WealthLab.Core;
using WealthLab.Data;

namespace WealthScript1
{
	public class MyStrategy : UserStrategyBase
	{
		//Initialize
		public override void Initialize(BarHistory bars)
		{
		}

		//Execute
		public override void Execute(BarHistory bars, int idx)
		{
		}

		//Backtest Completed (executes once)
		public override void BacktestComplete()
		{
			StrategyRunner sr = new StrategyRunner();
			sr.DataSet = DataSetFactory.Instance.Find("Dow 30");
			Backtester bt = sr.RunBacktest("Neo Master");
			WriteToDebugLog("Neo Master on Dow 30 Net Profit: " + bt.NetProfit.ToString("N2"));
		}

	}
}

RunBacktest
public Backtester RunBacktest(string strategyName)
public Backtester RunBacktest(StrategyBase sb)

The RunBacktest method has two overrides. One lets you provide a Strategy Name, and the second an instance of the StrategyBase class that represents an already compiled Strategy. Call this method after having set the various properties that control the backtest scale, range, etc.

The result is an instance of the Backtester class. You can query the result's Metrics property and various other properties to examine the performance results of the backtest.

If the DataSet property is assigned, the StrategyRunner will load the historical data for that DataSet's Symbols into its Data property. If DataSet is null, the StrategyRunner will next check its Symbols property, loading the data for these symbols into its Data property. As a last resort, the StrategyRunner will use its Data property, which you can pre-load with BarHistory instances manually if desired.

Example Code
using WealthLab.Backtest;
using WealthLab.Core;
using WealthLab.Data;

namespace WealthScript1
{
	public class MyStrategy : UserStrategyBase
	{
		//Initialize
		public override void Initialize(BarHistory bars)
		{
		}

		//Execute
		public override void Execute(BarHistory bars, int idx)
		{
		}

		//Backtest Completed (executes once)
		public override void BacktestComplete()
		{
			StrategyRunner sr = new StrategyRunner();
			sr.DataSet = DataSetFactory.Instance.Find("Dow 30");
			Backtester bt = sr.RunBacktest("Neo Master");
			WriteToDebugLog("Neo Master on Dow 30 Net Profit: " + bt.NetProfit.ToString("N2"));
		}

	}
}

Scale
public HistoryScale Scale

Determines the data scale, or frequency, to use for the backtest. The default scale is Daily.

Example Code
using WealthLab.Backtest;
using WealthLab.Core;
using WealthLab.Data;

namespace WealthScript1
{
	public class MyStrategy : UserStrategyBase
	{
		//Initialize
		public override void Initialize(BarHistory bars)
		{
		}

		//Execute
		public override void Execute(BarHistory bars, int idx)
		{
		}

		//Backtest Completed (executes once)
		public override void BacktestComplete()
		{
			StrategyRunner sr = new StrategyRunner();
			string firstSymbol = BacktestData[0].Symbol;
			sr.Symbols.Add(firstSymbol);
			Backtester bt = sr.RunBacktest("RSI Agita");
			WriteToDebugLog("RSI Agita Daily on " + firstSymbol + ": " + bt.NetProfit.ToString("N2"));
			WriteToDebugLog("Number of Trades: " + bt.Metrics.PositionCount.ToString("N0"));
			sr.Scale = HistoryScale.Weekly;
			bt = sr.RunBacktest("RSI Agita");
			WriteToDebugLog("RSI Agita Weekly on " + firstSymbol + ": " + bt.NetProfit.ToString("N2"));
			WriteToDebugLog("Number of Trades: " + bt.Metrics.PositionCount.ToString("N0"));
		}

	}
}

Scale
public HistoryScale Scale

Determines the data scale, or frequency, to use for the backtest. The default scale is Daily.

Example Code
using WealthLab.Backtest;
using WealthLab.Core;
using WealthLab.Data;

namespace WealthScript1
{
	public class MyStrategy : UserStrategyBase
	{
		//Initialize
		public override void Initialize(BarHistory bars)
		{
		}

		//Execute
		public override void Execute(BarHistory bars, int idx)
		{
		}

		//Backtest Completed (executes once)
		public override void BacktestComplete()
		{
			StrategyRunner sr = new StrategyRunner();
			string firstSymbol = BacktestData[0].Symbol;
			sr.Symbols.Add(firstSymbol);
			Backtester bt = sr.RunBacktest("RSI Agita");
			WriteToDebugLog("RSI Agita Daily on " + firstSymbol + ": " + bt.NetProfit.ToString("N2"));
			WriteToDebugLog("Number of Trades: " + bt.Metrics.PositionCount.ToString("N0"));
			sr.Scale = HistoryScale.Weekly;
			bt = sr.RunBacktest("RSI Agita");
			WriteToDebugLog("RSI Agita Weekly on " + firstSymbol + ": " + bt.NetProfit.ToString("N2"));
			WriteToDebugLog("Number of Trades: " + bt.Metrics.PositionCount.ToString("N0"));
		}

	}
}

Symbols
public List<string> Symbols

You can add symbols to the Symbols property to determine the data the StrategyRunner will execute with. The StrategyRunner will use the Symbols property if its DataSet property is null.

Example Code
using WealthLab.Backtest;
using WealthLab.Core;
using WealthLab.Data;

namespace WealthScript1
{
	public class MyStrategy : UserStrategyBase
	{
		//Initialize
		public override void Initialize(BarHistory bars)
		{
		}

		//Execute
		public override void Execute(BarHistory bars, int idx)
		{
		}

		//Backtest Completed (executes once)
		public override void BacktestComplete()
		{
			StrategyRunner sr = new StrategyRunner();
			sr.Symbols.Add("TQQQ");
			sr.Symbols.Add("SQQQ");
			Backtester bt = sr.RunBacktest("Neo Master");
			WriteToDebugLog("Neo Master on TQQQ/SQQQ Net Profit: " + bt.NetProfit.ToString("N2"));
		}

	}
}

Symbols
public List<string> Symbols

You can add symbols to the Symbols property to determine the data the StrategyRunner will execute with. The StrategyRunner will use the Symbols property if its DataSet property is null.

Example Code
using WealthLab.Backtest;
using WealthLab.Core;
using WealthLab.Data;

namespace WealthScript1
{
	public class MyStrategy : UserStrategyBase
	{
		//Initialize
		public override void Initialize(BarHistory bars)
		{
		}

		//Execute
		public override void Execute(BarHistory bars, int idx)
		{
		}

		//Backtest Completed (executes once)
		public override void BacktestComplete()
		{
			StrategyRunner sr = new StrategyRunner();
			sr.Symbols.Add("TQQQ");
			sr.Symbols.Add("SQQQ");
			Backtester bt = sr.RunBacktest("Neo Master");
			WriteToDebugLog("Neo Master on TQQQ/SQQQ Net Profit: " + bt.NetProfit.ToString("N2"));
		}

	}
}