PosSizer for rotational strategy with overlapping buys and sells
Author: Panache
Creation Date: 11/21/2016 10:36 PM
profile picture

Panache

#1
I have a Strategy which buys an unknown number of stocks every Monday and holds them for two weeks. I would like to backtest the Strategy assuming that it is always fully invested. The problem is that I can't use 100% of my equity on the first Monday, or I have nothing left to buy the next Monday. Therefore, I want to spread 50% of my equity equally when the Strategy buys each Monday.

Is there an existing PosSizer which will let me do this?
profile picture

Eugene

#2
PosSizers like Spread Equity Equally and Graded equity percentage that equalize equity are designed to deal with multiple entry signals on the same bar. If experimenting with options "For last position, use all what's left" and "Skipped signals solution" in Position Options doesn't lead to desirable result, you might have to develop a custom PosSizer for your position sizing technique.
profile picture

Panache

#3
Thanks. I just wanted to make sure I wasn't missing anything so I wasn't reinventing the wheel.

I was looking through the WIKI for some documentation on how to write PosSizers, but I couldn't find anything. I've downloaded the MS123 demo, but is there any more explanation?
profile picture

Eugene

#4
profile picture

Panache

#5
Great. MaxEntriesPerDay is a very helpful example. I have a couple of questions:

My Strategies sometimes use SetContext(symbol, false) and then create orders for those symbols. In order to make sure I am spreading the equity equally among all the trades entered on each date, can I simply look for all trades with the same Positions[n].EntryBar (as in the example), or should I use Date[Positions[n].EntryBar] in my PosSizer and then check for all positions being entered on that date?

I assume the Skipped Trade Solution just sets the basisPrice equal to the price on bar + 1.

Visual Studio won't let me add this.numPercent.Increment = 0.25M in the InitializeComponent void of Average Volume Limitation. What do I need to do to modify the Increment in my NumericUpDown control?

Finally, is there any easy way to modify the UI for the Fidelity controls? It's not a big deal, but I would like to add ThousandsSeparator to FixedDollar.

profile picture

Eugene

#6
QUOTE:
or should I use Date[Positions[n].EntryBar] in my PosSizer and then check for all positions being entered on that date?

It's important to use EntryDate in this context and not EntryBar. Check out this FAQ:

Why checking for EntryBar/ExitBar in portfolio simulations may produce unexpected results in PosSizers and Performance Visualizers?

QUOTE:
I assume the Skipped Trade Solution just sets the basisPrice equal to the price on bar + 1.

Yes, on the whole.
profile picture

Panache

#7
QUOTE:
It's important to use EntryDate in this context and not EntryBar. Check out this FAQ:

Why checking for EntryBar/ExitBar in portfolio simulations may produce unexpected results in PosSizers and Performance Visualizers?


Thanks. I knew I had read that, but I couldn't remember where.

However, that brings up two more questions (sorry):

First, if a symbol is going to trade on bar+1, do I want to access the EquityCurve as of bar or bar+1? In the U.S., if I sold one position on Date[bar], the funds wouldn't be available to purchase a new position until Date[bar+1], but I don't know how Wealth-Lab keeps track of the EquityCurve.

Second, after the first position on a given date is sized, does that change the EquityCurve returned for the next position traded on that date? Concretely, I would like to simply use EquityCurve[bar] to find the amount of equity on that date. I can then count the number of other symbols trading on that date by looping through each Positions[n].EntryDate. Finally, I would size the current position by dividing the equity by the number of symbols trading on that date.

I'm assuming the CashCurve changes as each position is sized, which is why Spread Equity Equally didn't work with the Cash option selected. If the EquityCurve does the same thing, I'd appreciate knowing how you got around it in Spread Equity Equally.
profile picture

Eugene

#8
QUOTE:
First, if a symbol is going to trade on bar+1, do I want to access the EquityCurve as of bar or bar+1?

You wouldn't want to access the EquityCurve[bar+1] as this will throw an IndexOutOfBounds on the last bar. Just like with your everyday WealthScript Strategy creation.

QUOTE:
Second, after the first position on a given date is sized, does that change the EquityCurve returned for the next position traded on that date?

I think it was answered in my post #4 in this thread: Spread Equity Equally PosSizer?

QUOTE:
If the EquityCurve does the same thing, I'd appreciate knowing how you got around it in Spread Equity Equally.

No specific treatment was required, it should work.
profile picture

Panache

#9
Last question for now (I hope):

Is it possible to size positions for trades which are not currentPos and, if so, how? I'm thinking about trying to get around the problem with the CashCurve by sizing all the trades on the same date at the same time. That would allow me to read the CashCurve once and divide it equally among the symbols to be traded on that date.
profile picture

Eugene

#10
QUOTE:
Is it possible to size positions for trades which are not currentPos

No, this is impossible.
profile picture

Panache

#11
Thanks. That's what I assumed, but I thought it was worth asking.
profile picture

Panache

#12
I'm getting closer. Does Positions[n].Size include EntryCommission? The QuickRef says it is just Shares times EntryPrice.

If it doesn't include EntryCommission, can a PosSizer access commissions, and if so, how?
profile picture

Eugene

#13
QUOTE:
Does Positions[n].Size include EntryCommission? The QuickRef says it is just Shares times EntryPrice.

If you don't take our word for it, just set a breakpoint and examine the property under debugger. ;)

QUOTE:
can a PosSizer access commissions, and if so, how?

I don't think so. Commission is applied after PosSizer. This may (or may not) interest you: Finding out the Commissions structure used, post #4 and PortfolioEquityEx.cs in the Community Components source code.
profile picture

Panache

#14
I'm doing something stupid, but I can't figure out what it is.

When I substitute
CODE:
Please log in to see this code.


for

CODE:
Please log in to see this code.


my PosSizer gives me no trades.
profile picture

Eugene

#15
This default line (#2) will simply reflect whatever position sizing is configured in the respective dropdown control. It's something else.
profile picture

Panache

#16
Literally, that's the only thing I'm changing. If I comment out line 489-494 in the attached Abacus.cs file it returns the dropdown position sizes. With those lines active, it gives no trades.

profile picture

Eugene

#17
In post #14 you said that after substituting lines 489-494 with the default line your PosSizer gives no trades. In post #16 you're saying the opposite thing. Anyway, there's something odd about Abacus.cs that I've noticed and it's line 600; the code shouldn't even compile as ReturnSize is simply missing.
profile picture

Panache

#18
Sorry for the misunderstanding. Post #14 said when I substitute lines 489-494 for the default line, the PosSizer gives me no trades.

Line 600 is a label. Line 603 is the return.

I've done some more debugging, and the problem appears to be that the PosSizer isn't reading the Positions object. If I use

CODE:
Please log in to see this code.


or even

CODE:
Please log in to see this code.


I still get no trades. Is there something I need to be adding to read to read the Positions object?
profile picture

Eugene

#19
Before anything else, is the size on line 420 declared as a class-level variable on purpose? Unless true I would move it inside the SizePosition method body.
profile picture

Panache

#20
There's no reason it has to be.
profile picture

Panache

#21
The PosSizer can access the Bars object, just not the Positions object.

CODE:
Please log in to see this code.


Works.
profile picture

Panache

#22
The problem is not that the PosSizer can't read the Positions object. The problem is that the Positions object the PosSizer is seeing appears to be different from what the Strategy is generating, ie. the PosSizer isn't seeing any positions until they are sized by the PosSizer.

To demonstrate the problem, here's a real simple Strategy

CODE:
Please log in to see this code.


As expected, the Debug Window shows:

1 11/18/2016 12:00:00 AM
2 11/18/2016 12:00:00 AM

I inserted the following code at the beginning of the SizePosition method of my PosSizer:

CODE:
Please log in to see this code.


The Output Window shows:

Date 11/17/2016 12:00:00 AM
Count 0
Date 11/17/2016 12:00:00 AM
Count 1
Entry Bar 11/18/2016 12:00:00 AM
Date 11/18/2016 12:00:00 AM
Count 2
Entry Bar 11/18/2016 12:00:00 AM
Entry Bar 11/18/2016 12:00:00 AM

bars.Date[bar] in SizePosition method of the PosSizer is the date of the bar used to determine the basisPrice, ie. the bar before the entry date. That's easy enough to deal with. More importantly, the Positions object seen by the PosSizer does not have any positions added to it until they are sized by the PosSizer.

At least I think I've now figured out the problem. I still don't know how to deal with it. Concretely, in order to spread equity equally, I need to know, in advance, how many positions are going to be established on each date.

I would appreciate knowing how you deal with this in Spread Equity Equally. Is there some object other than Positions the PosSizer should be reading?
profile picture

Eugene

#23
QUOTE:
the PosSizer isn't seeing any positions until they are sized by the PosSizer.

That's right, in a PosSizer you have access to the preceding positions and cannot peek at future positions if you mean this.

QUOTE:
how many positions are going to be established on each date.

Talking about each call of SizePosition() vs. each date, the closest thing is the Candidates.Count property (which is broken for sizing Alerts but is OK for backtests). This is how "Spread Equity Equally" works. Being based on Candidates.Count, it does not deal with Positions altogether.
profile picture

Panache

#24
Thank you Eugene. Looking at Candidates instead of Positions makes everything work the way I expected it to.

I have one last (I hope) issue that I'm hoping you can tell me how to resolve. I had created a variable for _commissionValue which was saved in the ICustomSettings. I implemented your suggestion in #13, so I no longer need it. However, I keep getting debug error messages when I simply eliminate it and renumber the Parse(tokens). Is there an easy way to do it?

CODE:
Please log in to see this code.
profile picture

Eugene

#25
a) With WLP closed, eliminate one line in WealthLabConfig.txt starting from PositionSize=

Then to get rid of your config string:

b) delete these lines in WealthLabConfig.txt: PosSizer.Abacus.CommissionValue= and Abacus.CommissionValue= (if it exists)
c) Adjust your ReadSettings/WriteSettings methods
d) It would take one more step to rebuild any workspaces which had the PosSizer applied to any Strategies inside it
profile picture

Panache

#26
Thanks again.

btw -- By taking commissions into account, so far, I haven't found the need to add a Margin Factor to size positions correctly. Also, included in my PosSizer is a working implementation of Spread Cash Equally if you're interested.
profile picture

Eugene

#27
Thanks for the update. Yes, that sounds pretty interesting.
profile picture

Panache

#28
Here you go.
profile picture

Eugene

#29
Nice, thank you.
profile picture

Panache

#30
I just found my first bug -- it isn't sizing Alerts. Do I have to process the Alerts object as well as the Candidates object?
profile picture

Eugene

#31
It's not your bug. As per Open Issues:

(62853) In PosSizers, the Candidates list is empty for Alert sizing
The collection functions as advertised for historical backtests, but for sizing Alerts at Bars.Count it is not being populated.
profile picture

Panache

#32
Does that mean I need to check if bars.[bar] == bars.Count and deal with those separately?

How do I access the Alerts object in a PosSizer? In a Strategy, it allows me to access Alerts.Count, which would make spread cash possible.
profile picture

Eugene

#33
1 - Yes. I guess this answer is pretty evident, isn't it.

2 - Candidates is the Alerts for position sizing. And it's been broken.
profile picture

Panache

#34
For others who may find this thread useful, there is one other peculiarity about alerts -- cash = 0. Therefore, all percentage sizing has to be percentages of equity.
profile picture

Eugene

#35
If anybody has interest in installing this PosSizer, here are steps to take:

1. Unzip archive in post #28
2. Take "Abacus Position Sizer.dll" and unblock the DLL as suggested
3. At the risk of breaking your Wealth-Lab, do NOT take other files as their versions are obsolete (WLP) or unsuitable (WLD)
4. Put that single file in the WLP/D main folder
5. Restart WLP/D

profile picture

innertrader

#36
What is the path to the WLP/D main folder? Is that shorthand for Wealth-Lab Pro 6/Data folder? Or Wealth-Lab Pro/Developer version of software?
profile picture

Eugene

#37
The path to the Wealth-Lab Pro/Developer main folder (abbreviation: WLP/D), is:

For WLP: C:\Program Files\Fidelity Investments\Wealth-Lab Pro 6\
For WLD: C:\Program Files\MS123\Wealth-Lab Developer 6\

In the correct folder you should see many similar DLLs there. This is not the same as the Data subfolder here or in %AppData% - these are not scanned for DLLs by WLP/D.
profile picture

innertrader

#38
I tried this PosSizer and got 0 trades. Is there documentation on how to set the options?