- ago
There seems to be something broken with the latest WL 8 Update (Build: 172).
Before the update each portfolio backtest run returns the same results.
After the update each run returns slightly different results.

I am using target limit orders:
ClosePosition(pos, OrderType.Limit, targetPrice);

Each trade has a clearly weight assigned.

May it has something to do with:
QUOTE:
Changed Backtester SignalSorter to properly order random weights for multiple stop/limit Transactions on the same bar for the same-symbol.


Can you please check this issue.
0
235
13 Replies

Reply

Bookmark

Jump to End
Cone8
- ago
#1
If the strategy uses stop and limit exits, it's probably because there are some bars where both exits could have occurred and you have selected (by default) Preference > Backtest > Other Settings > Exit Prioritization > Neutral (Random) .

The change you suggested only affects stop and limit strategies with multiple same-symbol entries on the same bar... and it actually fixed the previous problem with that entry scenario that you're describing. (e.g., the backtester should always give more priority to BUY a higher limit price before a lower price.)

Anyway, let me know if "Exit Prioritization" is the reason (select Pessimistic, for example), and, if it's not, we'll take another look.
0
- ago
#2
Also if you could email us the strategy to support@wealth-lab.com we can take a closer look.
0
- ago
#3
@Cone
QUOTE:
the backtester should always give more priority to BUY a higher limit price before a lower price.

Shouldn't it be the other way (lower price has higher priority for BUY)?
And this only applies to limit orders that are not fillable at market open.
0
Cone8
- ago
#4
Why should it be the other way? When you try to explain it, you'll see why. But just take the simple example of buying 2 positions: 1% below today's close and 2% below today's close. If today's open is at [yesterday's] close, which order should fill first?

Remember, priority/weights only have context for Entry signals (Buy and Short). Exit signals will always fill in a backtest - no priority required.
0
- ago
#5
yes you are right. The closer one will be filled first.
0
- ago
#6
Thanks for your response.
I did some quick tests.

It seems that the problem has nothing to do with limit orders.
I already have an issue on my trading signals.

So for example when I am using the following entry code for my portfolio backtest:

CODE:
priority = 8.5415; var trade = PlaceTrade(bars, TransactionType.Buy, OrderType.Market, 0, priority.ToString("N6")); trade.Weight = priority;

With the following strategy settings:

CODE:
Max Open Pos: 10 Max Open Per Symbol: 1

I got for example the following signals:

CODE:
NSF | Symbol | Action | Order Type | Weight ------------------------------------------- No | XYZ | Buy | Market | 0.5712 Yes | XYZ | Buy | Market | 7.4134

Shouldn't the signal with not NSF (so entry for today) should have a weight of "8.5415"?
Also the weight for the not NSF signal differs each run (seems to be a random between 0 and 1).

For signals that have no NSF equivalent the weight equals the defined priority.
0
Cone8
- ago
#7
Thanks for those details. The Market order weight should not change from what you had set.
We'll look into it and get to the bottom of it right away.
0
Cone8
- ago
#8
I cannot duplicate what you're reporting. A critical detail must be missing, so I'm afraid you'll have to provide a strategy that actually makes this happen.

The only way I can get the random weight (a value between 0 and 1) is by not assigning the value as you have shown in your snippet. I'd urge you to first look for another Buy at Market signal in your code for which Transaction.Weight is not assigned.
0
- ago
#9
I think I found the issue which has changed behavior in the latest WL8 Update (172).

I currently use the following entry/exit logic.
This is just a sample strategy to show the effect.

1. Check if any positions are open and close them on next open after 9 bars.
2. Check if RSI < 30 and place entry order for next bar.

The idea is to close open positions for the symbol on the next bar and if the entry
condition does apply open the position again on the next bar with a specfic weight.

Here are the strategy settings I used for this backtest:


The strategy generates the following signals:


As you can see in the signals screenshot the weight which I expected to be assigned for the entry signal
is assigned to the NSF Sell position.

The following code has worked before the update (at least the weight was proper set).
Not sure what in the background is happening. But does no work anymore as expected after the update.

Variant A:
CODE:
public class MyStrategy : UserStrategyBase { private RSI _rsi; //create indicators and other objects here, this is executed prior to the main trading loop public override void Initialize(BarHistory bars) { _rsi = RSI.Series(bars.Close, 14); } //execute the strategy rules here, this is executed once for each bar in the backtest history public override void Execute(BarHistory bars, int idx) { foreach (var pos in OpenPositions) { int offset = idx - pos.EntryBar + 1; if (offset >= 9) ClosePosition(pos, OrderType.Market); } if (_rsi[idx] < 30.0) { double priority = 100.0 - _rsi[idx]; var trade = PlaceTrade(bars, TransactionType.Buy, OrderType.Market, 0, priority.ToString("N6", CultureInfo.InvariantCulture)); trade.Weight = priority; } } }

But when I swap the order of 1. and 2. so that the new orders are placed first and
the close is afterwards the weights are set as expected for the new signals.
But the results are complete different. So this results in different behavior.

Variant B:
CODE:
public class MyStrategy : UserStrategyBase { private RSI _rsi; //create indicators and other objects here, this is executed prior to the main trading loop public override void Initialize(BarHistory bars) { _rsi = RSI.Series(bars.Close, 14); } //execute the strategy rules here, this is executed once for each bar in the backtest history public override void Execute(BarHistory bars, int idx) { if (_rsi[idx] < 30.0) { double priority = 100.0 - _rsi[idx]; var trade = PlaceTrade(bars, TransactionType.Buy, OrderType.Market, 0, priority.ToString("N6", CultureInfo.InvariantCulture)); trade.Weight = priority; } foreach (var pos in OpenPositions) { int offset = idx - pos.EntryBar + 1; if (offset >= 9) ClosePosition(pos, OrderType.Market); } } }

My latest discovery is that when I deactivate "Retain NSF Positions" that also Variant A has proper weights assigned.

Could you please explain to me how to use entry and exit orders correctly so that I can simulate the behavior described above?
0
Cone8
- ago
#10
Thank you for the analysis. Clearly there's an bug. We'll get this nailed down and get a hot fix out ASAP.
0
Cone8
- ago
#11
Okay, with your help, we have it resolved. Thanks again.

It's a 3-day weekend, but I'd bet that Glitch will probably get a hotfix out before next Tuesday's open.
0
Cone8
- ago
#12
Build 173 is now available with the fix.
0
- ago
#13
Thx for the quick fix of this issue.
I did a first test and it seem to work again.
1

Reply

Bookmark

Jump to Top