Custom PosSizer - how to detect last SizePosition call
Author: avishn
Creation Date: 5/25/2010 9:22 AM
profile picture

avishn

#1
I'm collecting some stats in my PosSizer and would like to dump the results into CSV file when the PosSizer is done. What's the best way to achieve it? Is there something like "Destroy" as the opposite to "Initialize"?
profile picture

Eugene

#2
Could you elaborate on your task a bit, maybe there's a more elegant way of doing that something?
profile picture

avishn

#3
I want to export number of candidates for every bar as well as number of rejected trades.
profile picture

Eugene

#4
I thought that you could save the data stored as class-level variables from the PosSizer's destructor. Have checked it and it won't work. Let me think about it.
profile picture

Eugene

#5
I think the best way is to append to the CSV file with each SizePosition call.
profile picture

avishn

#6
I'm trying to truncate output CSV file in Initialize() method and then append with every SizePosition call as you've suggested, but it appears that for every strategy run Initialize is called 3 or 4 times, at least 2 of them after the position sizing process is completed (so I'm obviously losing CSV content). Am I completely off base here?
profile picture

avishn

#7
...and another question -- should EquityCurve[bar] match "equity" value when in SizePositions method (they don't match for me)?
profile picture

Eugene

#8
QUOTE:
I'm trying to truncate output CSV file in Initialize() method and then append with every SizePosition call as you've suggested, but it appears that for every strategy run Initialize is called 3 or 4 times,

Have you tried using constructor of the class vs. Initialize()? In my test, it's being run one time per Strategy run.
QUOTE:
...and another question -- should EquityCurve[bar] match "equity" value when in SizePositions method (they don't match for me)?

I believe you should use the "equity" value. Also see a note on p.2 of the PosSizer API doc re: accessing CashCurve/EquityCurve values.
profile picture

avishn

#9
Constructor works fine, thank you.

EquityCurve values seem to match equity curve chart displayed after the backtest is completed. Why is "equity" value is different at the same bar? Is it possible it does not include the results of the trades being closed at that bar?

BTW, it seems that I've just answered my own question from above. SizePositions seems to be always called at the last bar even if there are no attempts to open positions at that bar. In fact, even if script does not trade at all it seems that SizePositions is still called at the last bar. Is it a bug or a feature?
profile picture

avishn

#10
Well, it appears there's more.

When strategy is executed the first time SizePositions is called (number_of_positions + 1) times.
Any subsequent backtest appears to execute SizePositions (number_of_positions + 2) times. There's one additional execution at last bar before the main (position) loop and another execution at the last bar after. First and last executions have null passed in as curPosition argument.

Considering also that Initialize() is called 3 (4) times instead of the expected single call... Can anybody shed any light on all of this?
profile picture

Eugene

#11
QUOTE:
In fact, even if script does not trade at all it seems that SizePositions is still called at the last bar. Is it a bug or a feature?

I can't tell precisely but considering that PosSizers must also be called to a) size Alerts, and b) set size for the right click trade menu, there's good chance it's a feature.
QUOTE:
There's one additional execution at last bar before the main (position) loop and another execution at the last bar after.

Yes, I reported it a few months ago. According to the developer, it's not that important since end user isn't going to notice it, and fixing it isn't that trivial.
QUOTE:
Why is "equity" value is different at the same bar?

I'll ask that.
profile picture

avishn

#12
QUOTE:
According to the developer, it's not that important...

It is not an isolated problem, there's similar issue with Initialize() method. What's bothering me is that on top of all this mess with duplicate method calls, it also appears that WLP is swallowing all exceptions coming from the position sizers. It's like somebody gave up on debugging it.
profile picture

Eugene

#13
Initialize() is called each time the PosSizer is about to be used to size Positions in a
backtest
- including 1) Alerts, and b) the right click trade menu - I can count three calls here.
QUOTE:
Why is "equity" value is different at the same bar?

The developer said that the "equity" value is the most up to date, and the EquityCurve series is only updated after the processing for that bar completes. Otherwise it's worth investigating.
profile picture

avishn

#14
Can I rely on methods such as NetProfitAsOfBarPercent(bar) when called from within position sizer SizePosition() (no peeking)? I keep track of all open positions in my position sizer and then re-examine them on subsequent calls to SizePosition, but I'm seeing some strange results such as pos.NetProfitAsOfBarPercent is set to negative infinity when SizePosition is called the last time (with curPosition == null, I think this is what you referred to as "Alert sizing")
profile picture

Eugene

#15
Why NetProfitAsOfBarPercent?

I've had no problems using the NetProfit property for open positions from the ActivePositions property.
profile picture

avishn

#16
Could be I'm doing something wrong... I need access to the current open+closed profit % at given bar. Wouldn't NetProfitAsOfBarPercent be the right tool for the job? Regardless, it seems that all values (including NetProfit) are correct until the last SizePosition call where they all of a sudden being set to some seemingly random values... The easiest way to reproduce is to set the debugger to interrupt SizePosition call and wait till the last (curPosition == null) call, then inspect NetProfit of any closed position.

EDIT1: removed

EDIT2: Shouldn't try to get NetProfit for rejected positions (i.e. skipped because of size = 0 or not enough equity on the next bar). Duh!

Sorry for the confusion.