Learn how you can become a Python programmer in just 12 weeks.

    We respect your privacy. Unsubscribe at anytime.

    Multiple Time Frame Analysis on a Stock using Pandas

    What will we investigate in this tutorial?

    A key element to success in trading is to understand the market and the trend of the stock before you buy it. In this tutorial we will not cover how to read the market, but take a top-down analysis approach to stock prices. We will use what is called Multiple Time Frame Analysis on a stock starting with a 1-month, 1-week, and 1-day perspective. Finally, we will compare that with a Simple Moving Average with a monthly view.

    Step 1: Gather the data with different time frames

    We will use the Pandas-datareader library to collect the time series of a stock. The library has an endpoint to read data from Yahoo! Finance, which we will use as it does not require registration and can deliver the data we need.

    import pandas_datareader as pdr
    import datetime as dt
    
    ticker = "MSFT"
    start = dt.datetime(2019, 1, 1)
    end = dt.datetime.now()
    day = pdr.get_data_yahoo(ticker, start, end, interval='d')
    week = pdr.get_data_yahoo(ticker, start, end, interval='wk')
    month = pdr.get_data_yahoo(ticker, start, end, interval='mo')
    

    Where the key is to set the interval to ‘d’ (Day), ‘wk’ (Week), and ‘mo’ (Month).

    This will give us 3 DataFrames, each indexed with different intervals.

    Dayly.

                      High         Low  ...      Volume   Adj Close
    Date                                ...                        
    2019-01-02  101.750000   98.940002  ...  35329300.0   98.860214
    2019-01-03  100.190002   97.199997  ...  42579100.0   95.223351
    2019-01-04  102.510002   98.930000  ...  44060600.0   99.652115
    2019-01-07  103.269997  100.980003  ...  35656100.0   99.779205
    2019-01-08  103.970001  101.709999  ...  31514400.0  100.502670
    

    Weekly.

                      High         Low  ...       Volume   Adj Close
    Date                                ...                         
    2019-01-01  103.269997   97.199997  ...  157625100.0   99.779205
    2019-01-08  104.879997  101.260002  ...  150614100.0   99.769432
    2019-01-15  107.900002  101.879997  ...  127262100.0  105.302940
    2019-01-22  107.879997  104.660004  ...  142112700.0  102.731720
    2019-01-29  106.379997  102.169998  ...  203449600.0  103.376968
    

    Monthly.

                      High         Low  ...        Volume   Adj Close
    Date                                ...                          
    2019-01-01  107.900002   97.199997  ...  7.142128e+08  102.096245
    2019-02-01  113.239998  102.349998  ...  4.690959e+08  109.526405
    2019-03-01  120.820000  108.800003  ...  5.890958e+08  115.796768
    2019-04-01  131.369995  118.099998  ...  4.331577e+08  128.226700
    2019-05-01  130.649994  123.040001  ...  5.472188e+08  121.432449
    2019-06-01  138.399994  119.010002  ...  5.083165e+08  132.012497
    

    Step 2: Combine data and interpolate missing points

    The challenge to connect the DataFrames is that they have different index entries. If we add the data points from Daily with Weekly, there will be a lot of missing entries that Daily has, but Weekly does not have.

                       day        week
    Date                              
    2019-01-02  101.120003         NaN
    2019-01-03   97.400002         NaN
    2019-01-04  101.930000         NaN
    2019-01-07  102.059998         NaN
    2019-01-08  102.800003  102.050003
    ...                ...         ...
    2020-08-13  208.699997         NaN
    2020-08-14  208.899994         NaN
    2020-08-17  210.279999         NaN
    2020-08-18  211.490005  209.699997
    2020-08-19  209.699997  209.699997
    

    To deal with that we can choose to interpolate by using the DataFrame interpolate function.

    import pandas_datareader as pdr
    import datetime as dt
    import pandas as pd
    
    ticker = "MSFT"
    start = dt.datetime(2019, 1, 1)
    end = dt.datetime.now()
    day = pdr.get_data_yahoo(ticker, start, end, interval='d')
    week = pdr.get_data_yahoo(ticker, start, end, interval='wk')
    month = pdr.get_data_yahoo(ticker, start, end, interval='mo')
    data = pd.DataFrame()
    data['day'] = day['Close']
    data['week'] = week['Close']
    data['week'] = data['week'].interpolate(method='linear')
    print(data)
    

    Which results in the following output.

                       day        week
    Date                              
    2019-01-02  101.120003         NaN
    2019-01-03   97.400002         NaN
    2019-01-04  101.930000         NaN
    2019-01-07  102.059998         NaN
    2019-01-08  102.800003  102.050003
    ...                ...         ...
    2020-08-13  208.699997  210.047998
    2020-08-14  208.899994  209.931998
    2020-08-17  210.279999  209.815997
    2020-08-18  211.490005  209.699997
    2020-08-19  209.699997  209.699997
    

    Where the missing points (except the first entry) will be linearly put between. This can be done for months as well, but we need to be more careful because of three things. First, some dates (1st of the month) do not exist in the data DataFrame. To solve that we use an outer-join, which will include them. Second, this introduces some extra dates, which are not trading dates. Hence, we need to delete them afterwards, which we can do by deleting the column (drop) and removing rows with NA value (dropna). Thirdly, we also need to understand that the monthly view looks backwards. Hence, the 1st of January is first finalized the last day of January. Therefore we shift it back in the join.

    import pandas_datareader as pdr
    import datetime as dt
    import pandas as pd
    
    ticker = "MSFT"
    start = dt.datetime(2019, 1, 1)
    end = dt.datetime.now()
    day = pdr.get_data_yahoo(ticker, start, end, interval='d')
    week = pdr.get_data_yahoo(ticker, start, end, interval='wk')
    month = pdr.get_data_yahoo(ticker, start, end, interval='mo')
    
    data = pd.DataFrame()
    data['day'] = day['Close']
    data['week'] = week['Close']
    data['week'] = data['week'].interpolate(method='index')
    data = data.join(month['Close'].shift(), how='outer')
    data['month'] = data['Close'].interpolate(method='index')
    data = data.drop(columns=['Close']).dropna()
    data['SMA20'] = data['day'].rolling(20).mean()
    

    Step 3: Visualize the output and take a look at it

    To visualize it is straight forward by using matplotlib.

    import pandas_datareader as pdr
    import datetime as dt
    import matplotlib.pyplot as plt
    import pandas as pd
    
    ticker = "MSFT"
    start = dt.datetime(2019, 1, 1)
    end = dt.datetime.now()
    day = pdr.get_data_yahoo(ticker, start, end, interval='d')
    week = pdr.get_data_yahoo(ticker, start, end, interval='wk')
    month = pdr.get_data_yahoo(ticker, start, end, interval='mo')
    
    data = pd.DataFrame()
    data['day'] = day['Close']
    data['week'] = week['Close']
    data['week'] = data['week'].interpolate(method='index')
    data = data.join(month['Close'].shift(), how='outer')
    data['month'] = data['Close'].interpolate(method='index')
    data = data.drop(columns=['Close']).dropna()
    data.plot()
    plt.show()
    

    Which results in the following graph.

    As expected the monthly price is adjusted to be the closing day-price the day before. Hence, it looks like the monthly-curve is crossing the day-curve on the 1st every month (which is almost true).

    To really appreciate the Multiple Time Frames Analysis, it is better to keep the graphs separate and interpret them each isolated.

    Step 4: How to use these different Multiple Time Frame Analysis

    Given the picture it is a good idea to start top down. First look at the monthly picture, which shows the overall trend.

    Month view of MFST.

    In the case of MSFT it is a clear growing trend, with the exception of two declines. But the overall impression is a company in growth that does not seem to slow down. Even the Dow theory (see this tutorial on it) suggest that there will be secondary movements in a general bull trend.

    Secondly, we will look at the weekly view.

    Weekly view of MFST

    Here your impression is a bit more volatile. It shows many smaller ups and downs, with a big one in March, 2020. It could also indicate a small decline in the growth right and the end. Also, the Dow theory could suggest that it will turn. Though it is not certain.

    Finally, on the daily view it gives a more volatile picture, which can be used to when to enter the market.

    Day view of MFST

    Here you could also be a bit worried. Is this the start of a smaller bull market.

    To sum up. In the month-view, we have concluded a growth. The week-view shows signs of possible change. Finally, the day-view is also showing signs of possible decline.

    As an investor, and based on the above, I would not enter the market right now. If both the month-view and week-view showed growth, while the day-view decline, that would be a good indicator. You want the top level to show growth, while a day-view might show a small decline.

    Finally, remember that you should not just use one way to interpret to enter the market or not.

    Step 5: Is monthly the same as a Simple Moving Average?

    Good question, I am glad you asked. The Simple Moving Average (SMA) can be calculated easy with DataFrames using rolling and mean function.

    Best way is to just try it.

    import pandas_datareader as pdr
    import datetime as dt
    import matplotlib.pyplot as plt
    import pandas as pd
    
    ticker = "MSFT"
    start = dt.datetime(2019, 1, 1)
    end = dt.datetime.now()
    day = pdr.get_data_yahoo(ticker, start, end, interval='d')
    week = pdr.get_data_yahoo(ticker, start, end, interval='wk')
    month = pdr.get_data_yahoo(ticker, start, end, interval='mo')
    
    data = pd.DataFrame()
    data['day'] = day['Close']
    data['week'] = week['Close']
    data['week'] = data['week'].interpolate(method='index')
    data = data.join(month['Close'].shift(), how='outer')
    data['month'] = data['Close'].interpolate(method='index')
    data = data.drop(columns=['Close']).dropna()
    data['SMA20'] = data['day'].rolling(20).mean()
    data.plot()
    plt.show()
    

    As you see, the SMA is not as reactive on the in crisis in March, 2020, as the monthly view is. This shows a difference in them. This does not exclude the one from the other, but shows a difference in how they react.

    Comparing the month-view with a Simple Moving Average of a month (20 trade days)

    Please remember, that the monthly view is first updated at the end of a month, while SMA is updated on a daily basis.

    Other differences is that SMA is an average of the 20 last days, while the monthly is the actual value of the last day of a month (as we look at Close). This implies that the monthly view can be much more volatile than the SMA.

    Conclusion

    It is advised to make analysis from bigger time frames and zoom in. This way you first look at overall trends, and get a bigger picture of the market. This should eliminate not to fall into being focused on a small detail in the market, but understand it on a higher level.

    12% Investment Solution

    Would you like to get 12% in return of your investments?

    D. A. Carter promises and shows how his simple investment strategy will deliver that in the book The 12% Solution. The book shows how to test this statement by using backtesting.

    Did Carter find a strategy that will consistently beat the market?

    Actually, it is not that hard to use Python to validate his calculations. But we can do better than that. If you want to work smarter than traditional investors then continue to read here.

    Python Circle

    Do you know what the 5 key success factors every programmer must have?

    How is it possible that some people become programmer so fast?

    While others struggle for years and still fail.

    Not only do they learn python 10 times faster they solve complex problems with ease.

    What separates them from the rest?

    I identified these 5 success factors that every programmer must have to succeed:

    1. Collaboration: sharing your work with others and receiving help with any questions or challenges you may have.
    2. Networking: the ability to connect with the right people and leverage their knowledge, experience, and resources.
    3. Support: receive feedback on your work and ask questions without feeling intimidated or judged.
    4. Accountability: stay motivated and accountable to your learning goals by surrounding yourself with others who are also committed to learning Python.
    5. Feedback from the instructor: receiving feedback and support from an instructor with years of experience in the field.

    I know how important these success factors are for growth and progress in mastering Python.

    That is why I want to make them available to anyone struggling to learn or who just wants to improve faster.

    With the Python Circle community, you can take advantage of 5 key success factors every programmer must have.

    Python Circle
    Python Circle

    Be part of something bigger and join the Python Circle community.

    7 thoughts on “Multiple Time Frame Analysis on a Stock using Pandas”

    1. As I assume people are looking at this with the intention to copy ideas, please make sure you point out weaknesses in creating interpolated values. Creating automated strategies (or letting an algorithm learn from these inputs) is very dangerous as your values create a “look ahead bias”:

      2020-08-13 208.699997 210.047998
      2020-08-14 208.899994 209.931998
      2020-08-17 210.279999 209.815997 <— !!
      2020-08-18 211.490005 209.699997 <— !!
      2020-08-19 209.699997 209.699997

      As an example: your daily view on data does not know about the future, therefore does not know about the 209.699 value yet. When closing at 210 or 211, you are suggesting your machine that it can use the future value of 209 form the 19th Aug. 2020 to estimate the drop of the daily prices.

      Reply
      • Hi Shuhari,
        Thank you for taking the time to write a comment.
        I happy that you share your knowledge.
        I am not sure I follow along – that is just me not fully understanding the context. You say there is a forward bias. In the above tutorial we use the Close price. Hence, I do not fully understand how the daily close price can be biased?
        Please help me understand, so I can improve this tutorial.
        Thank you so much.
        Rune

        Reply
    2. Hello sir, I’m a beginner in programming. I have few questions. Correct me if I’m wrong.

      1. Can I use 4 hour, 1 hour and 15 minutes timeframes?
      2. I trade using renko charts. Is it possible to build renko charts using yahoo Finance?

      Reply
      • Hi Vijay,
        Great question.
        With the Yahoo! Finance free API you can only get daily, weekly, or monthly data. Unfortunately, the API does not offer 4 hours, 1 hour, 15 minute timeframes.
        I am not aware of a free api, which provides that.
        Cheers,
        Rune

        Reply
    3. You can get 1m, 5m, 15m, 1h, 1D, 3Month etc. from yahoo finance. Contact me if interested…..
      txt 7572178884 “Let’s Code some Python”
      In exchange for some Collaboration on Python coding projects.
      I could use some help.

      Reply

    Leave a Comment