I am going to conclude by summarizing things as I understand them and make some take-home points.
*/
Having active position count being modified in WLab internally not on the trade bar but on the prior one has some significant implications. Lets consider a single-position script. In real life, when you get an alert to close a position, that is coming from the last bar (Bars.Count -1); the position count, if checked for this bar, would equal one, which is correct. However, if the trade gets filled the next day things get a bit dicey. When that day's data is downloaded, the bar which was previously Bars.Count -1 rolls back and becomes just another bar. Simultaneously, the position count gets reset to zero for that bar for reasons mentioned in the thread above.
When the ActivePosition count of a bar is set to 0, it makes the next bar available for new trades. To repeat: In real life, that bar was available only for closing a trade and not for new trades, but on backtesting it not only had an open position closed but also was made available for opening a new position. This can lead to unreliable results on backtesting. Lets consider two common scenarios and see how they are affected:
1) Single-position script: These are probably the most common type that people create. As long as your script has the trade logic like this (test script A):
CODE:
Please log in to see this code.
you are likely immune to the issue noted above. The reason is not because its using IsLastPositionActive, which btw also gets affected just the same as ActivePositions.Count does, but b/c of the presence of the || else || argument. One can prove that IsLastPositionActive is also affected by the position count getting reset on the pre-trade bar by using the following script (test script B):
CODE:
Please log in to see this code.
The script is apparently similar to test script A but just check your trades: they have doubled in number! Now each bar not only closes a trade but also opens another one, all because the position count got reset.
For single-position scripts, just stick to the logic of test script A and your backtest results won't be unreliable. That trade logic incidentally is from the default template.
2) Multi-position script: These are a different ball game altogether from a single-position script. Since you are opening/closing multiple positions on a symbol, not only do you have to reliably count the number of open positions but also use this value inside the exit and entry rules separately. A position count > 0 would trigger exit rules and a position count < max # of positions would allow entry rules to kick in; since these are not mutually exclusive you can't use the || else || argument like you could in a single-position script. Using ActivePosition count in multiple locations inside the script would be unreliable as a counter because if a position(s) got closed, it would allow simultaneous opening of an equal number of new positions in backtesting - but for which you never got alerts in real life (I can post a test script demonstrating this if anyone wants). My suggestion would be to either
use an external counter (e.g. an integer variable) or create a Positions List and add/delete items from it as positions get opened/closed. Each script is different so you would have to assess the logic yourself.
I would be remiss if I didn't mention the possibility of some folks deliberately exploiting the ActivePosition unreliability to create scripts that generate wonderful backtest results in order to impress their clients.
==============================
Hopefully, these ideas make sense to others.