- ago
Hello

I have created a custom Position sizer class extension derived from BasicPositionSizer class with overridden Name, Description and SizePosition method.

However, the UI does not load this sizer and am not able to see it in the Pos Size config for a strategy.

Is there anything else I need to do to make it load in the UI?
0
638
Solved
18 Replies

Reply

Bookmark

Sort
- ago
#1
Hello,

Did you target NET 6.0?
0
- ago
#2
Yes. The target is .NET 6.0. I have all other extensions such as Broker, Data Provider etc. working.
CODE:
<TargetFramework>net6.0-windows</TargetFramework>
0
- ago
#3
Great. Assuming the compiled DLL is present in the WL8 folder, let's review the code (you may skip the SizePosition logic for brevity).
0
- ago
#4
There is nothing special in the code. Here it is for your reference.
CODE:
using RoboT; using RoboT.Data; using RoboT.Models.Market; using WealthLab.Backtest; using WealthLab.Core; namespace WealthLab.RoboT.Adapters {    /// <summary>    /// Default position sizer    /// </summary>    public class RPositionSizer : BasicPositionSizer    {       public static readonly string SName = $"{Manager.AppName} Pos Sizer";       public static readonly string SDescription = $"Sizes positions based on lot size and margin requirements.";       #region Display Aspects       /// <inheritdoc />       public override string Name => SName;       /// <inheritdoc />       public override string Description => SDescription;       /// <inheritdoc />       public override string URL => Manager.Url;       /// <inheritdoc />       public override string GlyphResource => Manager.LogoResourcePath;       /// <inheritdoc />       public override bool DisableGlyphReverse => true;       #endregion       #region Properties       /// <summary>       /// Data manager       /// </summary>       protected IDataManager DataManager => _dataManager ??= Locator.Instance.GetDataManager();       #endregion       #region Sizing       /// <inheritdoc />       public override double SizePosition(Transaction t, BarHistory bars, int idx, double basisPrice, double equity, double cash)       {          // Calculate using base          var qty = (int)base.SizePosition(t, bars, idx, basisPrice, equity, cash);                    // Return          return qty;       }       #endregion    } }

0
- ago
#5
Have you tried to put a breakpoint and see if some method fails?
0
Glitch8
 ( 8.38% )
- ago
#6
Also check the WL log which might contain an error message indicating why it failed to load.
0
- ago
#7
Checked both. No breakpoints in the class are hit. No logs in the WL Logs view.
0
- ago
#8
Well, maybe your class' Build Action is not marked for Compile then. That's a possible reason.

Otherwise, simplify. Start by removing those Locator and Manager references as possible.
0
- ago
#9
I checked - the class is compiled. To start again, I created a new class and copied the example of PosSizer given at https://www.wealth-lab.com/Support/ExtensionApi/PositionSizer

I then tried to create an instance of the class in my strategy Initialize like this.
CODE:
var posSizer = new TestMaxEntriesPerBar(); posSizer.Initialize();


and it didn't throw any error - I checked by putting a breakpoint on those lines. The sizer instance was created successfully.

However, the sizer does not show in the UI in the strategy settings. The class I created from the example is -
CODE:
using WealthLab.Backtest; using WealthLab.Core; namespace WealthLab.RoboT.Adapters {    //A PosSizer that allows only a maximum number of entries per bar of data    public class TestMaxEntriesPerBar : BasicPositionSizer    {       //Name       public override string Name => "Test Max Entries per Bar";       //description       public override string Description => "Provides the basic Position Sizing options, with the additional ability to limit the number of entries taken on each bar (or day) of data.";       //initialize       public override void Initialize()       {          base.Initialize();          _maxEntries = Parameters[2].AsInt;          _considerIntraday = Parameters[3].AsBoolean;       }       //Size the position, if max entries exceeded, set size to zero       public override double SizePosition(Transaction t, BarHistory bars, int idx, double basisPrice, double equity, double cash)       {          int count = 0;          if (!_considerIntraday)          {             foreach (Transaction o in Orders)                if (o.TransactionType.IsEntry())                   count++;          }          else          {             if (t.Bars.Scale.IsIntraday)             {                var positionsInSymbolOpenedToday = Positions.AsParallel().AsOrdered().Reverse().TakeWhile(p => p.EntryDate.DayOfYear == t.EntryDate.DayOfYear && p.Symbol == t.Symbol);                count += positionsInSymbolOpenedToday.Count();             }          }          if (count >= _maxEntries)             return 0.0;          else             return base.SizePosition(t, bars, idx, basisPrice, equity, cash);       }       //private members       private int _maxEntries;       private bool _considerIntraday;       //add parameter to control how many entries per day       public override void GenerateParameters()       {          base.GenerateParameters();          Parameters.Add(new Parameter("Max Entries", ParameterType.Int32, 2, 1.0, 999999999.0));          Parameters.Add(new Parameter("For intraday trades, sum up positions opened during the day", ParameterType.Boolean, false));       }    } }
0
- ago
#10
I created a blank VS project to test and the UI still doesn't load the custom PosSizer.

Pls look into this. Here is the project with a single class derived from PositionSizerBase with minimal overrides. Even such a simple class/project wouldn't load. Seems like a bug to me.

WLExts.csproj
CODE:
<Project Sdk="Microsoft.NET.Sdk">    <PropertyGroup>       <TargetFramework>net6.0-windows</TargetFramework>       <ImplicitUsings>enable</ImplicitUsings>       <Nullable>enable</Nullable>       <RootNamespace>WealthLab.WLExts</RootNamespace>       <PlatformTarget>AnyCPU</PlatformTarget>       <Platforms>AnyCPU</Platforms>       <LangVersion>latest</LangVersion>       <AssemblyName>WealthLab.WLExts</AssemblyName>    </PropertyGroup>    <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">       <NoWarn>1701;1702;</NoWarn>       <ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch>          None       </ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch>    </PropertyGroup>    <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">       <NoWarn>1701;1702;</NoWarn>       <ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch>          None       </ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch>    </PropertyGroup>    <ItemGroup>       <Reference Include="WealthLab.Core">          <HintPath>C:\Program Files\Quantacula, LLC\WealthLab 8\WealthLab.Core.dll</HintPath>       </Reference>    </ItemGroup>    <Target Name="PostBuild" AfterTargets="PostBuildEvent">       <Exec Command="copy /Y &quot;$(TargetPath)&quot; &quot;C:\Program Files\Quantacula, LLC\WealthLab 8&quot;&#xD;&#xA;" />    </Target> </Project>


TestBasicMaxEntriesPerBar.cs
CODE:
using WealthLab.Backtest; using WealthLab.Core; namespace WealthLab.Exts {    //A PosSizer that allows only a maximum number of entries per bar of data    public class TestBasicMaxEntriesPerBar : PositionSizerBase    {       //Name       public override string Name => "Base Max Entries per Bar";       //description       public override string Description => "Provides the basic Position Sizing options, with the additional ability to limit the number of entries taken on each bar (or day) of data.";       //Size the position, if max entries exceeded, set size to zero       public override double SizePosition(Transaction t, BarHistory bars, int idx, double basisPrice, double equity, double cash)       {          return 0.0;       }    } }
0
- ago
#11
WL7|8 is 64-bit only. You should target x64 as the platform.
0
- ago
#12
I updated my project settings, but the problem persists.

CODE:
<Project Sdk="Microsoft.NET.Sdk">    <PropertyGroup>       <TargetFramework>net6.0-windows</TargetFramework>       <ImplicitUsings>enable</ImplicitUsings>       <Nullable>enable</Nullable>       <RootNamespace>WealthLab.WLExts</RootNamespace>       <PlatformTarget>x64</PlatformTarget>       <Platforms>x64</Platforms>       <LangVersion>latest</LangVersion>       <AssemblyName>WealthLab.WLExts</AssemblyName>    </PropertyGroup>    <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">       <NoWarn>1701;1702;</NoWarn>    </PropertyGroup>    <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">       <NoWarn>1701;1702;</NoWarn>    </PropertyGroup>    <ItemGroup>       <Reference Include="WealthLab.Core">          <HintPath>C:\Program Files\Quantacula, LLC\WealthLab 8\WealthLab.Core.dll</HintPath>       </Reference>    </ItemGroup>    <Target Name="PostBuild" AfterTargets="PostBuildEvent">       <Exec Command="copy /Y &quot;$(TargetPath)&quot; &quot;C:\Program Files\Quantacula, LLC\WealthLab 8&quot;&#xD;&#xA;" />    </Target> </Project>
0
- ago
#13
Well I just took the sample code, fixed it for V8 and it loaded instantly under 'Advanced Pos Sizer'.
0
Best Answer
- ago
#14
Ohhhhhh. Now I understood.

Referring to the help text provided in the PositionSizer Extension help page - https://www.wealth-lab.com/Support/ExtensionApi/PositionSizer

QUOTE:
The next time WL7 starts up, it should find your Position Sizer, and it should be available in the drop down list of Position Sizers in the Strategy Settings tab of the Strategy window.


I was checking in the "Position size" drop-down and was expecting my custom sizer name to appear beside the 5 options in the drop-down. I was under an impression that "Advanced Pos Sizer" in that drop-down is a custom positon sizer implementation that has its own logic.

Now, based on your last message, I selected the Advanced Pos Sizer in the "Position size" drop-down and my custom sizer is in the sub-drop-down that showed up.

Thanks, Eugene. The help content on the extension reference page must be updated to reflect this info.
1
Cone8
 ( 26.65% )
- ago
#15
Okay, thanks, we can clarify that better. (done)
1
- ago
#16
I had a feeling that you might be looking in the wrong place, hence the remark. Glad to help.

IMHO we should rename the "Advanced Pos Sizer" in the GUI to at least its plural version with ellipsis (i.e. "Advanced Pos Sizers...") to reflect that it's a group, not some single "advanced" option. @Glitch, what do you think?
0
Glitch8
 ( 8.38% )
- ago
#17
Grammatically I don’t think the change would be correct since it’s indicating which specific position sizing type should be selected. Better would be “An Advanced Pos Sizer.”
0
Cone8
 ( 26.65% )
- ago
#18
How about, "An Advanced Pos Sizer in the list below this selection".

Is the name of this selection really fooling anyone who uses it?
0

Reply

Bookmark

Sort