0

To backtest financial data I've written an algorithm, I have code as following: import pandas as pd import numpy as np import datetime from datetime import datetime from datetime import timedelta import matplotlib.pyplot as plt

start_date = '2016-01-01'
end_date = '2017-09-15'
symbols = ['PAEL']
def data_symbol():
    dates=pd.date_range(start_date,end_date) 
    df=pd.DataFrame(index=dates)
    for symbol in symbols:
        df_temp=pd.read_csv('/home/furqan/Desktop/python_data/{}.csv'.format(symbol),usecols=['Date','Close'],
                        parse_dates=True,index_col='Date',na_values=['nan'])
        df=df.join(df_temp)
        df=df.fillna(method='ffill')
        df=df.fillna(method='bfill')
        df.index.names = ['Date']
    return df

def bollinger_start(df,window,std_dev):
    rolling_mean = df['Close'].rolling(window).mean()
    rolling_std = df['Close'].rolling(window).std()

    df['Bollinger High'] = rolling_mean + (rolling_std * std_dev)
    df['Bollinger Low'] = rolling_mean - (rolling_std * std_dev)

    #df['Short'] = None
    #df['Long'] = None
    df['Position'] = None
    print(df.tail())

    for row in range(len(df)):

        if (df['Close'].iloc[row] > df['Bollinger High'].iloc[row]) and (df['Close'].iloc[row-1] < df['Bollinger High'].iloc[row-1]):
            df['Position'].iloc[row] = -1

        if (df['Close'].iloc[row] < df['Bollinger Low'].iloc[row]) and (df['Close'].iloc[row-1] > df['Bollinger Low'].iloc[row-1]):
            df['Position'].iloc[row] = 1

    df['Position'].fillna(method='ffill',inplace=True)

    df['Market Return'] = np.log(df['Close'] / df['Close'].shift(1))
    df['Strategy Return'] = df['Market Return'] * df['Position']
    print(df.tail())
    df[['Strategy Return', 'Market Return']].cumsum().plot()
    plt.show()

df = data_symbol()
bollinger_start(df,50,2)

and the dataframe (df) as follows:

            Close  Bollinger High  Bollinger Low Position
Date                                                     
2017-09-11  71.31      115.253111      59.547689     None
2017-09-12  73.15      114.761653      58.966347     None
2017-09-13  75.14      113.992835      58.615965     None
2017-09-14  74.08      113.116464      58.290736     None
2017-09-15  73.37      112.222221      57.970179     None

The above code lines give an error as follow:

A value is trying to be set on a copy of a slice from a DataFrame

I am unable to figure out how to solve this error.

Furqan Hashim
  • 1,304
  • 2
  • 15
  • 35
  • Those lines actually shouldn't give you that error. Are you sure that the error occurs there? – Konstantin Sep 17 '17 at 15:10
  • Or, better to say, it depends on what is df. Probably you assign to df a view of a data frame, such as with `df = df_other.loc[<...>, <...>]`. Please post more code, specifically on how df is defined. – Konstantin Sep 17 '17 at 15:11
  • I think the error comes from here. I am going to edit post with full code. – Furqan Hashim Sep 17 '17 at 15:12
  • Please post the complete Traceback – wwii Sep 17 '17 at 15:17
  • Warning (from warnings module): File "/usr/local/lib/python3.5/dist-packages/pandas/core/indexing.py", line 132 self._setitem_with_indexer(indexer, value) SettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrame See the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy – Furqan Hashim Sep 17 '17 at 15:17
  • Possible duplicate of [How to deal with SettingWithCopyWarning in Pandas?](https://stackoverflow.com/questions/20625582/how-to-deal-with-settingwithcopywarning-in-pandas) – wwii Sep 17 '17 at 15:19
  • Still can't understand why I am getting this error? – Furqan Hashim Sep 17 '17 at 15:25
  • 1
    That is not an error but a warning. Also, folks above are asking for the problem line which you respond *I think the error comes from here*. Yet I still can't see where warning derives? Please post some input data and make sure what you post is runnable from our blank environments so we can reproduce issue. – Parfait Sep 17 '17 at 15:42
  • I can't see at the moment, where it hits you. You may try to create an example that others can re-run (that is, which does not read data from a file), as Parfait said. Also, I would strongly recommend to use at/iat instead of loc/iloc whenever you are accessing individual cells in your table. Its way faster! – Konstantin Sep 20 '17 at 09:11

0 Answers0