- ago
I'm trying to build a strategy that would trade between 3 different symbols, all of which may be entered independently or simultaneously. However, I want to ensure the portfolio is 100% invested at each trade.

How do I determine the portfolio value at the beginning of each cycle in the backtest?
0
418
Solved
11 Replies

Reply

Bookmark

Sort
- ago
#1
QUOTE:
How do I determine the portfolio value at the beginning of each cycle in the backtest?

I "think" you want the CurrentCash in the Execute{block}. But I would read about the CurrentEquity property as well. https://www.wealth-lab.com/Support/ApiReference/UserStrategyBase#CurrentCash

Let's be clear, the broker's cash level (in real-time) is a different number. You probably don't want that unless you're doing real-time trading.
1
Cone8
 ( 21.51% )
- ago
#2
This is a job for Rebalance.

Like in a rotation strategy, you'll need to know the status of other tickers in the portfolio, so the trade logic goes in PreExecute(). Use the result to store symbols that are longs in a static List<>. When the list changes, you exit the tickers not in the List, and Rebalance the ones that are, where the rebalance percentage is the list count / 100.0.
2
- ago
#3
The strategy is an in-at-the-open, out-at-the-close strategy so I don't need to rebalance.

When I use either CurrentEquity or CurrentCash I get the same number. However, I see two issues:
- first, the number in the debug log does not reflect the value of the previous transaction. For example, the previous transaction has a value of $2,336, but when I look at the Debug log the CurrentEquity value shows up as 121.70. The bars.Close[idx] value is off too.

- second, in the cases where I am trying to split the cash equally between two transactions. To get the quantity for each position, I am using the formula

_transaction1.Quantity = (CurrentEquity / 2 ) / external.close[idx] for the first, and

_transaction2.Quantity = (CurrentEquity / 2) / bars.close[idx] for the second.

where external is a defined symbol. However, the value that I get when I combine the two entered positions is only about 65% of the total cash/equity value.
0
Cone8
 ( 21.51% )
- ago
#4
CurrentEquity and CurrentCash will be the same if you're not holding a position, so that checks out for what you're doing.

As for your debug issues and quantity issues - and not knowing anything else - I'd have to say it's your code. In any case, make sure to configure margin higher (e.g. 1.2) when trading near 100% of equity so that you don't get NSF Positions for gaps higher on the open.
1
- ago
#5
Turns out it was the margin, thanks Cone.

with that said, I am making the assumption that I have to manually calculate the quantities of each position but maybe there's an existing method to do that?
0
- ago
#6
QUOTE:
I have to manually calculate the quantities of each position

I'm confused. The quantities held in each position are stored in each position object. What's there to calculate?

Perhaps if you showed us your calculation code it would be clearer.
0
- ago
#7
The strategy dumps at the end of each day so there's 100% of the cash available at the open for the next trade.

I'm trading a fixed set of stocks, all of which are identified within the code. For example, I may have 4 stocks - IBM, Microsoft, J&J and Boeing all hard coded.

On any specific day I may be in 1 or more positions. I want to ensure 100% of the funds are invested at the open each day there's a signal. For example, day one I may
only be in IBM, so all the cash is invested in that position until the close. On day two I may be in MSFT and Boeing so I need to split the available funds between them.

So for each day I need to determine how many shares (Transaction.Quantity) of each stock to trade. On day two, that's

QtyMSFT = (CurrentCash / 2) / (MSFT stock price) and
QtyBA = (CurrentCash / 2) / (Boeing stock price).

Turns out the issue I was having was I needed some margin in the backtest to ensure all shares would be able to trade.
0
- ago
#8
I understand now.

The problem is that your method needs to compute how many stocks you're going to buy on a given bar (day) in advance before purchasing anything, and that's tricky. You would have to do that in the PreExecute{block}. You could have PreExecute create a ...

CODE:
static List<BarHistory> stocks2buy;
so the stocks2buy.Count would be the number of stocks you would spread your equity (cash) across for a given bar.

And I'm not sure that static List is going to play nice with a multi-threaded parameter optimizer. I suppose you could allocate that List in the Global cache instead if you knew how long to make it in advance.

---
I'm wondering if it would be simpler--and wiser--to just have Execute sell the stocks when it's time so positions can remain open across bars? Then you can just set the Percent of Equity to 100% and let WL figure out how many shares that would be for each stock purchase automatically. Yes, the first purchase may take all the available equity, but if the other stocks are doing well the day before, then they would already be invested.

And you can have PreExecute sort the stocks2buy list so the most promising stock comes first, and the best stock gets all the available equity.

What if the market is doing poorly--high volatility? Do you really want to remain fully invested then?
1
Cone8
 ( 21.51% )
- ago
#9
QUOTE:
manually calculate the quantities of each position but maybe there's an existing method to do that?
To get precisely 100% you need to "peek" at the opening price and place a limit (or stop) order at that price. Use the NextSessionOpen indicator for the price.
1
Best Answer
- ago
#10
"What if the market is doing poorly--high volatility? Do you really want to remain fully invested then? "

Very valid question, and that's what I'm doing the backtesting for. Step one is to set up the basic functionality; steps 2 thru X will be to see what conditions/indicators are or are not helpful, and when a lower/zero investment level would make sense.

One point - I am looking at inverse pairs. I assume there are some cases there are instances where the short fund will perform better.
0
- ago
#11
"Use the NextSessionOpen indicator for the price."

Perfect, thanks Cone.
0

Reply

Bookmark

Sort