Some questions about the backtest module

Hi,Mr.

Under the guidence of the Tutorial and your answers in the forums,we successfully created a payout function,but we met some new problems about the backtest function,as is shown below:

port = alphien.portfolio.Portfolio(tkr)
port.payout(payout,data)
port.evaluate()
port.backtest()

The payout funtion has a dataframe input which contains the ohlc data,and a weightmatrix output,just like the example you showed yesterday in other questions in the forums.But we cannot get the backtest function worked,the error is as follows:

---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-8-4df52dd42d2e> in <module>
1 port = alphien.portfolio.Portfolio(tkr)
2 port.payout(payout,data)
----> 3 port.evaluate()
4 port.backtest()

/mnt/public/IT/Libs/Python/alphien/portfolio/portfolio.py in evaluate(self, startDate, endDate, zoom, period, lastN, computationDataPoints, rollEval, alignAndFillDates)
374 if rollEval is None:
375 self.singleEval(startDate=startDate, endDate=endDate, zoom=zoom, period=period, lastN=lastN, computationDataPoints=computationDataPoints,
–> 376 rollEval=False, alignAndFillDates=alignAndFillDates)
377 else:
378 self.rollEval(startDate=startDate, endDate=endDate, zoom=zoom, period=period, rollingWindow=rollEval, computationDataPoints=computationDataPoints)

/mnt/public/IT/Libs/Python/alphien/portfolio/portfolio.py in singleEval(self, startDate, endDate, zoom, period, lastN, computationDataPoints, rollEval, alignAndFillDates, composeLogic)
456 #align indicator with the underlying asset
457 if alignAndFillDates:
–> 458 weights = mergeAndFill(self.features.pxs, weights)
459
460 #remove leading NAs

AttributeError: ‘NoneType’ object has no attribute ‘pxs’

Can you tell us what goes wrong and give us some more precise details of this Portfolio module?

Could you give me some more details please, especially the size of “data”, as well as the size of the output from your function “payout”. If you give me the code that generated “data”, even better. Thanks

The input data is a dataframe that contains six columns which are date,ticker and the four ohlc data,the output dataframe is the weightmatrix just like other payout in the Tutorial.

Hi Andrew,

The input is not clear to me. How can a column be ticker? Let’s take an example and say we’re only looking at data for 2016, so around 253 days. Let not include dates in the dimensions as they are the index.

Your input dataframe is 253 x 5 (provided ticker is something like ‘bb_live’). Or it is 253 x (5*number of tickers)?

If you create a portfolio like:

pf = alphien.portfolio.Portfolio([‘AMZN.US Equity’, ‘AAPL.US equity’])

The portfolio pf has 2 assets. So your payout has to have 2 columns. If we backtest for 2016, the payout should be number_of_rebalancing_dates x 2, each column being the allocation for AMZN and AAPL respectively. Your number of rebalancing dates have to be less than 253 (you could rebalance only once a month for e.g., and you’d get 12 x 2 for 2016.


To summarise, your portfolio function can take an input data frame of any dimension (columns) but should output a dataframe of exactly “number_of_assets_in_the_portfolio” columns. The number of row is capped by the number of dates in your backtest.


Hope this help.

My input data has the form like this:

date	asset	open_price	close_price	high_price	low_price
0 2007-01-03 A.US Equity 34.9792 34.30 35.480 34.05
1 2007-01-04 A.US Equity 34.2894 34.41 34.600 33.46
2 2007-01-05 A.US Equity 34.2894 34.09 34.400 34.00
3 2007-01-08 A.US Equity 33.9696 33.97 34.080 33.68
4 2007-01-09 A.US Equity 34.0695 34.01 34.320 33.63
… … … … … … …
1491069 2016-12-23 ZTS.US Equity 53.2000 53.78 53.780 53.18
1491070 2016-12-27 ZTS.US Equity 53.7800 53.72 54.150 53.65
1491071 2016-12-28 ZTS.US Equity 53.7600 53.44 53.850 53.35
1491072 2016-12-29 ZTS.US Equity 53.4747 53.62 53.779 53.40
1491073 2016-12-30 ZTS.US Equity 53.6400 53.53 53.740 53.27

And my output weightmatrix is:

asset	A.US Equity	AA.US Equity	AAL.US Equity	AAP.US Equity	AAPL.US Equity	ABBV.US Equity	ABC.US Equity	ABK.US Equity	ABT.US Equity	ACAS.US Equity	…	XOM.US Equity	XRAY.US Equity	XRX.US Equity	XTO.US Equity	XYL.US Equity	YHOO.US Equity	YUM.US Equity	ZBH.US Equity	ZION.US Equity	ZTS.US Equity
date
2007-01-03 0.0 0.0 0.0 0.00 0.00 0.0 0.0 0.00 0.0 0.0 … 0.00 0.0 0.00 0.00 0.0 0.00 0.0 0.00 0.00 0.0
2007-01-04 0.0 0.0 0.0 0.00 0.00 0.0 0.0 0.00 0.0 0.0 … 0.00 0.0 0.00 0.00 0.0 0.00 0.0 0.02 0.00 0.0
2007-01-05 0.0 0.0 0.0 0.00 0.00 0.0 0.0 0.00 0.0 0.0 … 0.00 0.0 0.00 0.02 0.0 0.00 0.0 0.00 0.00 0.0
2007-01-08 0.0 0.0 0.0 0.00 0.02 0.0 0.0 0.00 0.0 0.0 … 0.02 0.0 0.00 0.02 0.0 0.00 0.0 0.00 0.00 0.0
2007-01-09 0.0 0.0 0.0 0.00 0.02 0.0 0.0 0.02 0.0 0.0 … 0.00 0.0 0.00 0.00 0.0 0.00 0.0 0.00 0.00 0.0
… … … … … … … … … … … … … … … … … … … … … …

I am sure the number of columns and the number of assets are matched,if not,it will raise another error different from the Traceback.

I see. So the input format is different from the expected format.

The input dataframe should have dates as indices; here your index is not a date. This is also why I was confused with the fact that there is a ticker column. With a date as index, you won’t be able to have duplicated dates as row: a row is a single date. This is quite important as our backtesting engine will align all dates and handle non trading days.

Instead of having input dimensions = ( nb_days * nb_tickers ) x ( 6 ), try to have ( nb_days ) x ( number_of_tickers * 4 ) or 5 as you may want to include adjusted price ‘bb_live’ in here. This is natively returned by getHistoryData. If the variable tkr is a list of tickers, this call returns the expected format:

px = alphien.data.getHistoryData(tkr, field=[‘ohlc’, ‘bb_live’])

With this as input and the weight matrix as you generate it, dates will align well and the backtest will work.