BlackArbsCEO / Adv_Fin_ML_Exercises

Experimental solutions to selected exercises from the book [Advances in Financial Machine Learning by Marcos Lopez De Prado]
MIT License
1.7k stars 633 forks source link

Mistakes in crossing moving averages #3

Closed ptegelaar closed 6 years ago

ptegelaar commented 6 years ago

The crossing moving averages in the Labeling and MetaLabeling for Supervised Classification.ipynb notebook don't work correctly. In the current version, the following example would trigger a down cross, where there is none:

>>> df = pd.DataFrame(
>>>     data=[[645.16614, 645.166140, 645.166140],
>>>                [460.31423, 539.536477, 546.578455]],
>>>     columns=['price', 'fast', 'slow'],
>>>     index=['2014-03-10 18:33:42', '2014-03-10 19:33:58']
>>> )
>>>
>>> def get_down_cross_(df):
>>>     crit1 = df.fast.shift(1) > df.slow
>>>     crit2 = df.fast < df.slow
>>>     return df.fast[(crit1) & (crit2)]
>>> 
>>> get_down_cross(df)
2014-03-10 19:33:58    539.536477
Name: fast, dtype: float64

The slower moving average should be shifted as well, like so (as well as the upper and lower Bollinger Bands):

def get_up_cross(df):
    crit1 = df.fast.shift(1) < df.slow.shift(1)
    crit2 = df.fast > df.slow
    return df.fast[(crit1) & (crit2)]

def get_down_cross(df):
    crit1 = df.fast.shift(1) > df.slow.shift(1)
    crit2 = df.fast < df.slow
    return df.fast[(crit1) & (crit2)]

def get_up_cross(df, col):
    # col is price column
    crit1 = df[col].shift(1) < df.upper.shift(1)
    crit2 = df[col] > df.upper
    return df[col][(crit1) & (crit2)]

def get_down_cross(df, col):
    # col is price column    
    crit1 = df[col].shift(1) > df.lower.shift(1)
    crit2 = df[col] < df.lower
    return df[col][(crit1) & (crit2)]
BlackArbsCEO commented 6 years ago

Good catch, Thanks. Fixed in cb6bd1069a53674be0d6205ce133671fe287be63.