WealthScript Techniques | MultiSystem, or Calling a Strategy From Another

Modified on 2017/08/29 18:00 by Eugene — Categorized as: Knowledge Base

Note:

This article saw the light before Wealth-Lab 6.2 started providing effortless multiple system (and even multiple portfolio) backtesting via Combination Strategy interface. We highly recommend to explore this new feature.

Still, this design pattern of several Strategies in the same script may be useful in two cases which are out of scope for the architecture of Combination Strategies:


The problem

Is there a way to programmatically call one strategy from another?

The approach

There are two possible known ways to "call" a strategy.

The first is outlined in our Wiki KB article, Interacting Dynamically with Portfolio Level Equity, and includes making a call to the undocumented method TradingSystemExecutor. This is approximately how Wealth-Lab itself executes a strategy internally. Since it's unsupported, you can download the source code for Community.Components and dig deeper into Utility.cs class which contains all the code.

The other one is more straightforward and can be easily used to create a primitive "multi-system" Strategy:

Code example

Notice a workaround that closes all positions which are still left open on the last bar:

using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using WealthLab;
using WealthLab.Indicators;

namespace WealthLab.Strategies { public class Multisystem : WealthScript { protected override void Execute() { System1.Run(this); System2.Run(this); } } class System1 { public static void Run(WealthScript obj) { for(int bar = 20; bar < obj.Bars.Count; bar++) { if (obj.IsLastPositionActive) { obj.SellAtStop( bar+1, obj.LastPosition, Lowest.Series( obj.Low,10 )[bar] ); } else { obj.BuyAtStop( bar+1, Highest.Series( obj.High,20 )[bar], "System1" ); } // Workaround to prevent open positions from one system to be available for the next system to close if( bar == obj.Bars.Count-1 ) obj.SellAtClose( bar, Position.AllPositions, "Close All" ); } } } class System2 { public static void Run(WealthScript obj) { for(int bar = 20; bar < obj.Bars.Count; bar++) { if (obj.IsLastPositionActive) { obj.SellAtMarket( bar+1, obj.LastPosition ); } else { obj.BuyAtLimit( bar+1, obj.Low[bar]*0.95, "System2" ); }

// Workaround to prevent open positions from one system to be available for the next system to close if( bar == obj.Bars.Count-1 ) obj.SellAtClose( bar, Position.AllPositions, "Close All" ); } } } }