Clone our Wealth-Lab 8 Extension Demo project on GitHub to get a head start in developing your own Extensions!

ScoreCard API

This document details the API for building ScoreCard extensions for Wealth-Lab 8. A ScoreCard generates a roster of Performance Metrics (such as APR, Net Profit, and Sharpe Ratio) based on the results of a backtest run. These Performance Metrics can be displayed in various Performance Visualizers (see VisualizerBase and Optimizations and can even be selected as optimization targets by certain Optimizers.

Build Environment

You can create a ScoreCard in a .NET development tool such as Visual Studio 2022. Create a class library project that targets .NET8, then reference the WealthLab.Core library DLL that you'll find in the WL8 installation folder.

Note: If you are using Visual Studio 2022, it will need to be updated to at least version 17.8.6 to use .NET8.

Your ScoreCard will be a class in this library that descends from ScoreCardBase, which is defined in the WealthLab.Core library, in the WealthLab.Backtest namespace. After you implement and build your library, simply copy the resulting assembly DLL into the WL8 installation folder. The next time WL8 starts up, it will discover your ScoreCard, making it available in appropriate locations of the WL8 user interface.

Visual Studio 2022 Build Environment

Accessing the Host (WL8) Environment

The IHost interface allows your extension to access information about the user's WealthLab environment. For example, the location of the user data folder, or obtaining a list of DataSets defined by the user. At any point in your extension's code base, you can access an instance of the IHost interface using the singleton class WLHost and its Instance property. Example:

//get user data folder
string folder = WLHost.Instance.DataFolder;

Descriptive Properties

public abstract string Name

Return the name of the ScoreCard, which appears in the Metrics Report and any other areas in the WL8 user interface that let the user select a ScoreCard.

public abstract List<string> MetricNames

Return a List containing the names of the Performance Metrics that your ScoreCard calculates and returns. Each Metric should be named a string that is valid .NET variable name. You'll be able to associate more descriptive labels for Metrics as described further on.

Calculating Metrics

public virtual void Initialize(Backtester bt)

Override this method to calculate your ScoreCard's Performance Metrics. Each Metric that you calculate should be assigned, using its Metric name as a property name, to the Metrics property of the Backtester instance passed in the bt parameter.

The Backtester class' Metrics property is a dynamic type, which means it accepts any property name that is a valid .NET variable name. In this way, you can inject your own custom Metric into the WL8 environment, and they can be picked up in any other place in WL8 that accesses Performance Metrics, such as Optimizers or Performance Visualizers.

The example below is a section of code from the Basic ScoreCard, and illustrates how it calculates and assigns the Gross Profit of Winning Trades and Gross Loss of Losing Trades Performance Metrics, by enumerating the Position instances contained in the Backtester instance.

 //gross profit
 double sum = 0;
 foreach (Position pos in bt.Positions)
     if (pos.Profit > 0)
         sum += pos.Profit;
 bt.Metrics.GrossProfitWinners = sum;

 //gross loss
 sum = 0;
 foreach (Position pos in bt.Positions)
     if (pos.Profit < 0)
         sum += pos.Profit;
 bt.Metrics.GrossLossLosers = sum; 

Performance Metrics Report

public abstract void LayoutMetricsReport(IMetricsReportHost reportHost)

WL8 calls this method in your ScoreCard when it needs to compile a performance metrics report, for example in the Metrics Report Performance Visualizer. Override this method to compose the report by calling one of the methods in the accompanying IMetricsReportHost instance (reportHost) for each line of the report.

The example below illustrates the first section of the Basic ScoreCard implementation of LayoutMetricsReport

 reportHost.AddHeader("Summary");
 reportHost.AddMetricDouble("Profit", true, false);
 reportHost.AddMetricDouble("ProfitPct", true, true);
 reportHost.AddMetricDouble("ProfitPerBar", true, false);
 reportHost.AddMetricDouble("APR", true, true, 2, "APR");
 reportHost.AddMetricDouble("Exposure", false, true);
 reportHost.AddMetricDouble("Alpha", false, false, 2, "Alpha (α)");
 reportHost.AddMetricDouble("Beta", false, false, 2, "Beta (β)");
 reportHost.AddMetricDouble("SharpeRatio", false, false);
 reportHost.AddMetricDouble("SortinoRatio", false, false);
 reportHost.AddMetricDouble("WLScore", false, false, 2, "WL Score");
 reportHost.AddSeparator();

Note that in your custom development you can "reuse" Metrics calculated by other Scorecards (such as Basic or Extended). The list of Metric names can be found in the Preferences dialog > Metric Columns tab. This allows you to build derivative Metrics, combine various Metrics, and save effort in recreating them.

public override string GetMetricTip(string itemName)

When the user clicks on a Performance Metric in the Metrics Report, WL8 calls this method to determine what tooltip hint (if any) to display for that Metric.

Metrics in Optimizations

public virtual int GetMetricValueDirection(string itemName)

WL8 calls this method to determine if a Performance Metric's value is typically "better" when it is higher (which returns 1) or lower (which returns -1). Examples of Performance Metrics that are considered "better" when higher are:

  • NetProfit
  • APR
  • SharpeRatio

and example of Performance Metrics that are considered better when lower are:

  • Beta
  • MarginInterest (the amount of margin interest paid)

The default return value is 1, so override this and return -1 for your Performance Metrics that are "better" when lower.

public virtual List<string> OptimizableMetricNames

Returns a List of Performance Metric names that are exposed to optimizations. The default implementation examines each of the calculated Metrics and includes those of type int or double. You can override this method if you want more specific control of which Metrics are exposed to optimizations.

public abstract string DefaultMetricName

Return the name of the Performance Metric that should appear when your ScoreCard is first selected in an optimization context.