- ago
Hi,

I'm using Wealth-Lab 8 Build 173 and I'm seeing unexpected behavior with partial exits.

According to the UserStrategyBase documentation, if an exit Transaction.Quantity is smaller than the matched open Position.Quantity, Wealth-Lab should split the Position and close only the requested quantity.

However, in my test the complete Position disappears after the partial Sell.

I reduced the issue to a minimal C# strategy.

TEST SETUP

- Wealth-Lab 8 Build 173
- Symbol: SPY
- Daily data
- One single long Position
- NSF = false
- No Portfolio Sync involved
- No broker/live trading involved
- No Building Blocks involved
- No ClosePosition()
- No Rebalance()
- No PositionTag dependency required
- Entry quantity is generated by normal Strategy Position Sizing

CODE:
using WealthLab.Backtest; using WealthLab.Core; namespace WealthScript2 { public class MyStrategy : UserStrategyBase { public override void Initialize(BarHistory bars) { } public override void Execute(BarHistory bars, int idx) { if (idx == 10) { Transaction buy = PlaceTrade( bars, TransactionType.Buy, OrderType.Market ); WriteToDebugLog( "BUY | Qty=" + buy.Quantity + " | ManualQty=" + buy.ManualQuantity ); } if (idx == 20 && OpenPositions.Count > 0) { Position p = OpenPositions[0]; WriteToDebugLog( "BEFORE SELL" + " | PositionQty=" + p.Quantity + " | NSF=" + p.NSF + " | PositionTag=" + p.PositionTag ); Transaction sell = PlaceTrade( bars, TransactionType.Sell, OrderType.Market ); sell.Quantity = 10; WriteToDebugLog( "SELL" + " | TransactionQty=" + sell.Quantity + " | ManualQty=" + sell.ManualQuantity ); } if (idx >= 21 && idx <= 23) { WriteToDebugLog( "AFTER SELL" + " | OpenPositions=" + OpenPositions.Count ); foreach (Position p in OpenPositions) { WriteToDebugLog( "RESIDUAL" + " | Qty=" + p.Quantity + " | IsOpen=" + p.IsOpen ); } } } public override void BacktestComplete() { WriteToDebugLog( "===== BACKTEST COMPLETE =====" ); foreach (Transaction t in Backtester.TransactionLog) { WriteToDebugLog( "TRANS" + " | Type=" + t.TransactionType + " | Qty=" + t.Quantity + " | ManualQty=" + t.ManualQuantity + " | PositionTag=" + t.PositionTag + " | NSF=" + t.NSF ); } var positions = GetPositionsAllSymbols(true); foreach (Position p in positions) { WriteToDebugLog( "POS" + " | Qty=" + p.Quantity + " | IsOpen=" + p.IsOpen + " | PositionTag=" + p.PositionTag + " | NSF=" + p.NSF ); } WriteToDebugLog( "OpenPositionsAllSymbols.Count=" + OpenPositionsAllSymbols.Count ); } } }


ACTUAL RESULT

In my test the entry Position contains 54 shares:

BUY | Qty=54 | ManualQty=False

Before the exit:

BEFORE SELL
PositionQty=54
NSF=False

The exit Transaction is correctly assigned a quantity of 10:

SELL
TransactionQty=10
ManualQty=True

But on the next bar:

AFTER SELL
OpenPositions=0

And at BacktestComplete:

TRANS | Type=Buy | Qty=54 | ManualQty=False
TRANS | Type=Sell | Qty=10 | ManualQty=True

Positions.Count = 1

POS
Qty=10
IsOpen=False

OpenPositionsAllSymbols.Count=0

EXPECTED RESULT

Since the original Position contained 54 shares and the Sell Transaction.Quantity is 10, I expected Wealth-Lab to split the Position:

54 original shares
-10 shares closed
=44 shares still open

Expected:

OpenPositions.Count=1
Residual Position.Quantity=44

Instead, no residual Position exists.

I also tested UserStrategyBase.Rebalance().

With a Position of 54 shares, Rebalance generated:

Sell Quantity=9
PositionTag=0

but after execution the result was again:

OpenPositions=0
Closed Position Quantity=9

So both a manually assigned partial Transaction.Quantity and Rebalance produce a closed fragment without preserving the residual Position.

Could you please confirm whether there is a Backtest Setting that could cause this behavior, or whether this is a defect in Build 173?

If a setting is involved, please let me know which one should be used for partial Position splitting.

Thanks.
Riccardo
0
31
1 Replies

Reply

Bookmark

Jump to End
Cone8
- ago
#1
You're right. That doesn't look correct when Retain NSF is disabled. When enabled, the result is correct.
Thanks for the report. We'll look into it!
0

Reply

Bookmark

Jump to Top