December 3, 2023
+++ date = 2023-12-03T21:10:42Z description = “A Python script that evaluates seasonal investing” draft = false image = “https://images.unsplash.com/photo-1600682322637-95c40966e79f?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3wxMTc3M3wwfDF8c2VhcmNofDM3fHxweXRob258ZW58MHx8fHwxNzAxMjYwMzIyfDA&ixlib=rb-4.0.3&q=80&w=2000” slug = “stock-seasonality-python-tutorial” summary = “A Python script that evaluates seasonal investing” tags = [“Tutorials”, “Python”] title = “Stock Seasonality in Python - A Tutorial”
+++
Normally I’d add this to my Python Tutorial page but sometimes these small scripts are better found (and indexed) by Google if they’re in their own post. After writing my article on Seasonal Trading and Investing Strategies, I decided to port Eric’s R code to Python.
While Eric’s code in R is very compact, the Python version feels more expressive and easier to deduce. I spent an hour or so trying to figure out the various methods that were called from the PerformanceAnalytics library and the ROC function from the xts library. As a machine learning guy, ROC means something completely different than the xts library method.
```import pandas as pd import numpy as np import yfinance as yf import matplotlib.pyplot as plt import datetime as dt
tickers =‘NVDA’
start=dt.datetime(1970,1,1) end = dt.datetime.now()
assets=yf.download(tickers,start,end) #[‘Adj Close’]
assets.rename(columns={‘Adj Close’: ‘Adj_Close’}, inplace=True)
assets.head()
assets[‘daily_returns’] = assets[‘Adj_Close’].pct_change()
#assets = assets[‘daily_returns’][1:] assets = assets[1:]
plt.plot(assets[‘daily_returns’])
first_half = assets[assets.index.month.isin([1,2,3,4,11,12])] second_half = assets[assets.index.month.isin([5,6,7,8,9,10])]
first_half.head()
first_half[‘FH_Culm_Return’] = (1 + first_half[‘daily_returns’]).cumprod() - 1
plt.plot(first_half[‘FH_Culm_Return’])
second_half[‘SH_Culm_Return’] = (1 + second_half[‘daily_returns’]).cumprod() - 1
plt.plot(second_half[‘SH_Culm_Return’])
s1 = first_half[‘FH_Culm_Return’] s2 = second_half[‘SH_Culm_Return’]
s1.fillna(method=‘ffill’, inplace=True) s2.fillna(method=‘ffill’, inplace=True)
out = pd.concat([s1, s2], axis=1)
out.fillna(method =‘ffill’, inplace=True) out
#out = out.resample(‘1M’).asfreq().ffill()
plt.figure(figsize=(20,5)) plt.title(tickers+” Seasonal Performance”) plt.xlabel(‘Year’) plt.ylabel(‘Culmulative Perf’) plt.plot(out.FH_Culm_Return, color = “black”, label=‘Nov-Apr’) plt.plot(out.SH_Culm_Return, color = “red”, label=‘May-Oct’) plt.legend() plt.show() ```
I did spend time on Stackoverflow piecing together some data munging requirements. While you can do anything in Python, R’s handling of data was a bit more elegant. Still, I prefer Python over R any day.
This is what the MSFT looks like from the year 2000 on in R.
MSFT Seasonality in R
And this is what MSFT looks like from the year 2000 in Python.
MSFT Seasonality in Python
Granted I need to add the drawdown and the daily return part to the Python code, but the hard nut has been cracked.