Advertisement
BAMpas

seasonality by month SPY x20yrs python

Sep 8th, 2024
73
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.21 KB | None | 0 0
  1. import yfinance as yf
  2. import pandas as pd
  3. import plotly.graph_objects as go
  4.  
  5. # Fetch SPY data for the past 20 years
  6. spy_data = yf.download('SPY', start='2004-01-01', end='2024-09-08')
  7.  
  8. # Resample to monthly data (last business day of each month)
  9. spy_monthly = spy_data['Adj Close'].resample('M').ffill()
  10.  
  11. # Create a DataFrame for percentage changes
  12. monthly_pct_change = spy_monthly.pct_change().dropna() * 100
  13.  
  14. # Add Year and Month columns for grouping
  15. monthly_pct_change = monthly_pct_change.to_frame(name='Monthly Change')
  16. monthly_pct_change['Year'] = monthly_pct_change.index.year
  17. monthly_pct_change['Month'] = monthly_pct_change.index.strftime('%b')
  18.  
  19. # Calculate percentage change for each year and month
  20. yearly_changes = monthly_pct_change.groupby(['Year', 'Month'])['Monthly Change'].mean().reset_index()
  21.  
  22. # Create a pivot table for easier plotting, with months sorted correctly
  23. month_order = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
  24. pivot_table = yearly_changes.pivot(index='Year', columns='Month', values='Monthly Change')[month_order]
  25.  
  26. # Create a DataFrame to store data for plotting
  27. plot_data = []
  28. plot_data_totals = []
  29.  
  30. # Loop through each month to prepare data for plotting
  31. for month in month_order:
  32. # Data for each month across all years
  33. month_data = pivot_table[month].dropna()
  34. month_avg = month_data.mean()
  35.  
  36. # Add all years' data for the current month
  37. for year in month_data.index:
  38. plot_data.append({'Month': month, 'Year': str(year), 'Monthly Change': month_data[year]})
  39.  
  40. # Add the total average at the end of the current month's data
  41. plot_data_totals.append({'Month': month, 'Year': 'Total Avg', 'Monthly Change': month_avg})
  42.  
  43. # Convert plot data to DataFrame
  44. plot_df = pd.DataFrame(plot_data)
  45. plot_df_totals = pd.DataFrame(plot_data_totals)
  46.  
  47. # Define consistent colors for each month
  48. colors = {
  49. 'Jan': '#1f77b4', 'Feb': '#ff7f0e', 'Mar': '#2ca02c', 'Apr': '#d62728',
  50. 'May': '#9467bd', 'Jun': '#8c564b', 'Jul': '#e377c2', 'Aug': '#7f7f7f',
  51. 'Sep': '#bcbd22', 'Oct': '#17becf', 'Nov': '#1f77b4', 'Dec': '#ff7f0e'
  52. }
  53.  
  54. # Plot data organized by Month, grouped correctly
  55. fig = go.Figure()
  56.  
  57. # Plot each month with grouped years
  58. for month in month_order:
  59. month_df = plot_df[plot_df['Month'] == month]
  60. fig.add_trace(go.Bar(x=month_df['Month'] + ' ' + month_df['Year'],
  61. y=month_df['Monthly Change'],
  62. name=month,
  63. marker_color=colors[month])) # Set color for each month
  64.  
  65. # Plot each month's total
  66. for month in month_order:
  67. month_df = plot_df_totals[plot_df_totals['Month'] == month]
  68. fig.add_trace(go.Bar(x=month_df['Month'] + ' ' + month_df['Year'],
  69. y=month_df['Monthly Change'],
  70. name=month,
  71. marker_color=colors[month], # Match color for totals
  72. showlegend=False)) # Hide legend for total bars
  73.  
  74. fig.update_layout(
  75. title="SPY Monthly Percentage Change Over the Past 20 Years (Grouped by Month)",
  76. xaxis_title="Month and Year",
  77. yaxis_title="Percentage Change",
  78. barmode='group'
  79. )
  80.  
  81. fig.show()
  82.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement