Does ActivePositions.Count peek?
Author: Sammy_G
Creation Date: 12/7/2010 8:54 PM
profile picture

Sammy_G

#1
Test script:
CODE:
Please log in to see this code.

Check the debug window. You will notice that for those bars where the alert was successful - meaning, it resulted in a trade on the next bar - the ActivePositions.Count is immediately reset to the new value. But the script has no means of knowing beforehand whether or not the Limit price alert would actually result in a trade on the next bar. This suggests that the ActivePositions.Count is peeking into the ActivePositions List.
profile picture

Cone

#2
"Alert" means a trading alert on a bar in the future (off the chart). I know what you mean, but that term doesn't apply to signals that occur on bar + 1 during backtesting.

When a Position is created, it is added to the Positions List. If it is active, it's added to the ActivePositions List. It's as simple as that. If you program in a logical manner, meaning as you would trade, a script won't peek. See WealthScript Programming Guide: Programming Trading Strategies > Peeking > Trading based on Position Active Status

In short, there are several ways to peek, some of them are valid (see the "Valid Peeking" topic), but you have to avoid the ones that aren't.
profile picture

Sammy_G

#3
I can understand the ActivePositions count being reset after a trade is executed; I am unable to understand why it would reset on the bar before the trade bar.
profile picture

Eugene

#4
Maybe because it all happened in the past?

Since today's not 1st of month, replace this:
CODE:
Please log in to see this code.
...with this to produce an Alert and check the Debug log:
CODE:
Please log in to see this code.
P.S. You forgot a check that the has actually been created (same for the exit):
CODE:
Please log in to see this code.
profile picture

Sammy_G

#5
Eugene, if you use bar = Bars.Count -1, then obviously only an alert is generated; since no position has been created ActivePositions.Count will show zero.
In other words, for ActivePositions.Count to peek, position(s) need to have been created. You can confirm that by changing to bar = Bars.Count - 20 and running it over a number of symbols; as long as they generated a trade you will notice how the ActivePositions.Count changes on the bar before the actual trade.
profile picture

Cone

#6
QUOTE:
you will notice how the ActivePositions.Count changes on the bar before the actual trade.
Of course it does. At the risk of repeating, when you're processing bar but create a trade on bar + 1, the Position is added to the list immediately. This is what you're calling peeking, but it's only peeking if you try to access that new Position immediately. Clear?

In other words, generating a trading signal that occurs on bar + 1 should be the last Position operation you do in a bar loop. After a trading signal, you should not check anything just added or changed in the Positions (or ActivePositions) List. See WealthScript Programming Guide: Programming Trading Strategies > Peeking > Trading based on Position Active Status
profile picture

Sammy_G

#7
Hmmm...the guide does it call it a subtle peeking error. Implicit in their description, and also from the examples above, is that a position's active status does change based on the alert even though the future outcome of the alert is unknown (if its a Limit price alert).
Qs:
1) Has the treatment of ActivePositions.Count changed since WL4?
2) Does it mean multi-position scripts should *not* rely on the Active Position Count while tabulating the # of open positions?
3) I want to copy the ActivePositions List to another List; what 'type' of receiving List should I create?
profile picture

Cone

#8
QUOTE:
that a position's active status does change based on the alert even though the future outcome of the alert is unknown (if its a Limit price alert).
Incorrect. An Alert cannot change a Position's status. An Alert is not the same as a position. An Alert is an action that will take place on a bar that does not yet exist.

1. No, but ActivePositions didn't exist in 4x. It's a list that's created for your convenience by extracting all the active Positions from the Positions list. Look, here's how to replicate the ActivePositions list (it's what WLP does for you internally when you access ActivePositions) -
CODE:
Please log in to see this code.


2. Of course you can count on it, but only before you execute trades on the bar being processed.

3. Use the code above. If you run it just before you access ActivePositions, apList will have the same Positions as ActivePositions.
profile picture

Sammy_G

#9
- I do know the difference between an alert and a position (!!). I guess what I meant was the process of executing trades, manifested externally as an alert.
- Will need to get used to the way ActivePositions.Count updates as its not intuitive; I would have expected the count to update only when the position gets traded.
*/
(No reply needed).

Thanks for all the info.
profile picture

Cone

#10
QUOTE:
ActivePositions.Count updates as its not intuitive
I want to make sure that you and anyone reading this knows that this is not an ActivePositions thing. In backtesting, when you execute a trade on bar + 1 and a Position is created, it's created immediately. That Position is added to the Positions list and is Active. Therefore, it will show up in ActivePositions. All that happens on "bar" even though the trade occurs on bar + 1. It's your job not to peek in your code (assuming you don't want to) - after you execute a trading signal, wait for the next bar before you start doing anything with Positions.

In summary, it's really simple: you tell Wealth-Lab the bar on which to create a trade and it does it, immediately. It doesn't care if you're in a loop whose index is bar. (It's an error, however, to exit a Position on a bar number that's prior to the Position.EntryBar.)
profile picture

Sammy_G

#11
You haven't explained why the position needs to be created 'immediately'. What's wrong with waiting for updating the count and a position's status on the bar where the trade actually occurs?
profile picture

Cone

#12
Trading entry signals are functions.
You pass the number of a bar on which a signal should test if a trade is created.
The function returns a Position if it's successful.
If it is, everything is updated - you have a new Position, the Position is added to the Positions list, and it is active.
The function doesn't know or care about what you think the current bar is. It does not matter. That is the design.
profile picture

Sammy_G

#13
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.
profile picture

Cone

#14
You've got it the idea, after all, it's described in the Programming Guide. Sure, the second script peeks. It's an error to write code like that. You can peek in Wealth-Lab if you want to, and there are reasons to do it legally, as described in the Programming Guide.

However, I sincerely doubt that someone is misusing peeking (on purpose) to impress clients. It will be obvious to everyone after the first few trades that something is wrong with the Strategy, the fake would be discovered, they would forever be disgraced and would have a difficult time staying in the T.A. business. After all, they got Madoff, right? That's a pretty good incentive (or disincentive) to do it right.

The take away (already covered in the Programming Guide) is that a trading signal should be the last thing you process (w.r.t. Positions, LastPosition, IsActiveLastPosition, ActivePositions, etc.) on the current bar. This is the way you trade -> you do your processing, create an Alert, place the order, and wait for the next bar's (day's) close. To attempt to find out if your trade executed on previous bar by accessing the Positions list is a user error (and foolhardy).