pmorissette / bt

bt - flexible backtesting for Python
http://pmorissette.github.io/bt
MIT License
2.22k stars 425 forks source link

Error when backtesting momentum on CAC 40 #28

Closed Fractally closed 9 years ago

Fractally commented 9 years ago

I tried backtesting a simple momentum strategy on the CAC 40. The strategy code is as follows:

s = bt.Strategy('Strategy1', 
    [bt.algos.RunWeekly(),
     bt.algos.SelectAll(),
     bt.algos.SelectMomentum(5, lookback=pd.DateOffset(months=1), lag=pd.DateOffset(days=1)),
     bt.algos.WeighEqually(),
     bt.algos.Rebalance()])

I generated the CAC 40 securities from a text file. The funny thing is that when I backtest the first 20 securities, everything is fine. The same for the last 20. When the entire 40 securities are used for the backtest, I get the following error:

Traceback (most recent call last):
  File "SampleBacktest.py", line 262, in <module>
    res = bt.run(t)
  File "/home/fractally/anaconda/lib/python2.7/site-packages/bt/backtest.py", line 25, in run
    bkt.run()
  File "/home/fractally/anaconda/lib/python2.7/site-packages/bt/backtest.py", line 155, in run
    self.strategy.run()
  File "bt/core.py", line 1132, in bt.core.Strategy.run (bt/core.c:14486)
  File "bt/core.py", line 1077, in bt.core.AlgoStack.__call__ (bt/core.c:13888)
  File "/home/fractally/anaconda/lib/python2.7/site-packages/bt/algos.py", line 1131, in __call__
    target.rebalance(item[1], child=item[0], base=base)
  File "bt/core.py", line 673, in bt.core.StrategyBase.rebalance (bt/core.c:8907)
  File "bt/core.py", line 900, in bt.core.SecurityBase.update (bt/core.c:11717)
ValueError: setting an array element with a sequence.

I have yet to find the issue - I'm not sure which array is set with a sequence internally. I'll see if I can find anything later. If someone could perhaps run the backtest on the tickers (that I will list below) using any simple momentum strategy (like the one I provided), to check if the same issue arises I would appreciate it. In order to use Yahoo Finance as the data source, just add .PA to each ticker symbol e.g. AC.PA. Any ideas on the error would also be great.

AC
AI
ALU
AIR
ALO
MT
CS
BNP
EN
CAP
CA
ACA
EDF
EI
GTO
GSZ
BN
KER
OR
LG
LR
MC
ML
ORA
RI
KER
PUB
RNO
SAF
SGO
SAN
SU
GLE
STM
TEC
FP
UL
FR
VK
VIE
DG
VIV

Thanks!

pmorissette commented 9 years ago

Hey @Fractally,

Thanks for reporting this - I am also encountering the same error. Let me look into it and get back to you.

Cheers, Phil

pmorissette commented 9 years ago

@Fractally,

So the error message was not very helpful here. I had to dig deeper to debug the code. Turns out you have two columns with the same name in your data frame. The list provided above has the ticker "KER" twice!

I'll add some code to check for this when creating a Backtest. Thanks for reporting the issue!

Cheers, Phil

Fractally commented 9 years ago

@pmorissette

Thanks for finding the simple mistake! I just didn't see that and the error message did not really indicate what the problem really was. Just so you know, I got the index composition from Wikipedia, where KER is listed twice for some reason. http://en.wikipedia.org/wiki/CAC_40

I think adding a check for something like this was a good idea. Thanks!

vfilimonov commented 9 years ago

@Fractally please note also that

  1. wikipedia lists of constituents are often incorrect (e.g. this list of CAC40 has 42 (!) tickers, but for instance misses Peugeot which was in index in December 2011)
  2. It is generally very bad idea of backtesting momentum portfolio strategies on index constituents because of the strong selection bias: back in (e.g.) 1970 from where you start your backtest you could not have known that these companies will be in the index in 2011. And the fact that they are in the index in 2011 is a reflection of their strong performance in comparison with other companies over recent decades.