%22%22%22Fetch%20S%26P%20500%20constituent%20returns%20for%20the%20last%205%20years%20via%20yfinance.%22%22%22%0A%0A%23%20%2F%2F%2F%20script%0A%23%20requires-python%20%3D%20%22%3E%3D3.11%22%0A%23%20dependencies%20%3D%20%5B%0A%23%20%20%20%20%20%22yfinance%22%2C%0A%23%20%20%20%20%20%22pandas%22%2C%0A%23%20%20%20%20%20%22numpy%22%2C%0A%23%20%20%20%20%20%22lxml%22%2C%0A%23%20%20%20%20%20%22requests%22%2C%0A%23%20%20%20%20%20%22pyarrow%22%2C%0A%23%20%20%20%20%20%22marimo%22%0A%23%20%5D%0A%23%20%2F%2F%2F%0A%0Aimport%20marimo%0A%0A__generated_with%20%3D%20%220.23.5%22%0Aapp%20%3D%20marimo.App()%0A%0Awith%20app.setup%3A%0A%20%20%20%20import%20io%0A%20%20%20%20from%20pathlib%20import%20Path%0A%0A%20%20%20%20import%20pandas%20as%20pd%0A%20%20%20%20import%20requests%0A%20%20%20%20import%20yfinance%20as%20yf%0A%0A%0A%40app.cell%0Adef%20_()%3A%0A%20%20%20%20%23%20%E2%94%80%E2%94%80%201.%20S%26P%20500%20tickers%20from%20Wikipedia%20%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%0A%0A%20%20%20%20resp%20%3D%20requests.get(%0A%20%20%20%20%20%20%20%20%22https%3A%2F%2Fen.wikipedia.org%2Fwiki%2FList_of_S%2526P_500_companies%22%2C%0A%20%20%20%20%20%20%20%20headers%3D%7B%22User-Agent%22%3A%20%22Mozilla%2F5.0%20(research%20script)%22%7D%2C%0A%20%20%20%20%20%20%20%20timeout%3D30%2C%0A%20%20%20%20)%0A%20%20%20%20resp.raise_for_status()%0A%20%20%20%20tables%20%3D%20pd.read_html(io.StringIO(resp.text))%0A%20%20%20%20tickers%20%3D%20tables%5B0%5D%5B%22Symbol%22%5D.str.replace(%22.%22%2C%20%22-%22%2C%20regex%3DFalse).tolist()%0A%20%20%20%20print(f%22Found%20%7Blen(tickers)%7D%20tickers%20in%20the%20S%26P%20500%20index%22)%0A%0A%20%20%20%20%23%20%E2%94%80%E2%94%80%202.%20Download%205%20years%20of%20adjusted%20close%20prices%20%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%0A%0A%20%20%20%20raw%20%3D%20yf.download(%0A%20%20%20%20%20%20%20%20tickers%2C%0A%20%20%20%20%20%20%20%20period%3D%225y%22%2C%0A%20%20%20%20%20%20%20%20auto_adjust%3DTrue%2C%0A%20%20%20%20%20%20%20%20progress%3DTrue%2C%0A%20%20%20%20%20%20%20%20threads%3DTrue%2C%0A%20%20%20%20)%5B%22Close%22%5D%0A%0A%20%20%20%20print(f%22%5CnRaw%20download%3A%20%7Braw.shape%5B0%5D%7D%20trading%20days%20x%20%7Braw.shape%5B1%5D%7D%20tickers%22)%0A%0A%20%20%20%20%23%20%E2%94%80%E2%94%80%203.%20Clean%3A%20keep%20tickers%20with%20%3C5%25%20missing%20days%2C%20forward-fill%20short%20gaps%20%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%0A%0A%20%20%20%20threshold%20%3D%200.05%0A%20%20%20%20missing_frac%20%3D%20raw.isna().mean()%0A%20%20%20%20keep%20%3D%20missing_frac%5Bmissing_frac%20%3C%3D%20threshold%5D.index%0A%20%20%20%20raw%20%3D%20raw%5Bkeep%5D.ffill()%0A%0A%20%20%20%20print(f%22After%20cleaning%3A%20%7Braw.shape%5B0%5D%7D%20days%20x%20%7Braw.shape%5B1%5D%7D%20assets%22)%0A%0A%20%20%20%20%23%20%E2%94%80%E2%94%80%204.%20Returns%20%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%0A%0A%20%20%20%20pct_returns%20%3D%20raw.pct_change().dropna()%0A%20%20%20%20print(f%22Return%20matrix%20shape%3A%20%7Bpct_returns.shape%7D%20%20(T%3D%7Bpct_returns.shape%5B0%5D%7D%2C%20N%3D%7Bpct_returns.shape%5B1%5D%7D)%22)%0A%0A%20%20%20%20%23%20%E2%94%80%E2%94%80%205.%20Save%20%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%0A%0A%20%20%20%20out_dir%20%3D%20Path(__file__).parent%20%2F%20%22data%22%0A%0A%20%20%20%20pct_returns.to_parquet(out_dir%20%2F%20%22sp500_pct_returns.parquet%22)%0A%20%20%20%20print(%22%5CnSaved%20data%2Fsp500_pct_returns.parquet%22)%0A%0A%20%20%20%20print(f%22Date%20range%3A%20%7Bpct_returns.index%5B0%5D.date()%7D%20%E2%86%92%20%7Bpct_returns.index%5B-1%5D.date()%7D%22)%0A%20%20%20%20print(f%22Assets%3A%20%7Bpct_returns.shape%5B1%5D%7D%22)%0A%20%20%20%20print(f%22Trading%20days%3A%20%7Bpct_returns.shape%5B0%5D%7D%22)%0A%20%20%20%20return%0A%0A%0Aif%20__name__%20%3D%3D%20%22__main__%22%3A%0A%20%20%20%20app.run()%0A
7e6b50c45bcbe1cced9ac54187e745c6