import pandas as pd import plotly.express as px import requests import orjson def get_spy_heatmap(): # Load stock screener data with open(f"json/stock-screener/data.json", 'rb') as file: stock_screener_data = orjson.loads(file.read()) stock_screener_data_dict = {item['symbol']: item for item in stock_screener_data} with open(f"json/etf/holding/SPY.json","rb") as file: data = orjson.loads(file.read())['holdings'] for item in data: try: item['marketCap'] = stock_screener_data_dict[item['symbol']]['marketCap'] item['sector'] = stock_screener_data_dict[item['symbol']]['sector'] item['industry'] = stock_screener_data_dict[item['symbol']]['industry'] item['change1W'] = stock_screener_data_dict[item['symbol']]['change1W'] item['change1M'] = stock_screener_data_dict[item['symbol']]['change1M'] item['change3M'] = stock_screener_data_dict[item['symbol']]['change3M'] item['change6M'] = stock_screener_data_dict[item['symbol']]['change6M'] item['change1Y'] = stock_screener_data_dict[item['symbol']]['change1Y'] item['change3Y'] = stock_screener_data_dict[item['symbol']]['change3Y'] except: pass # Create DataFrame df = pd.DataFrame(data) # Convert relevant columns to numeric types df["marketCap"] = pd.to_numeric(df["marketCap"]) # Drop rows where the marketCap == 0 df = df[df["marketCap"] > 0] return df def create_treemap(time_period): save_html = True df = get_spy_heatmap() if (time_period == '1D'): change_percent = 'changesPercentage' range_color = (-3,3) elif (time_period == '1W'): change_percent = 'change1W' range_color = (-5,5) elif (time_period == '1M'): change_percent = 'change1M' range_color = (-20,20) elif (time_period == '3M'): change_percent = 'change3M' range_color = (-30,30) elif (time_period == '6M'): change_percent = 'change6M' range_color = (-50,50) elif (time_period == '1Y'): change_percent = 'change6M' range_color = (-100,100) elif (time_period == '3Y'): change_percent = 'change3Y' range_color = (-100,100) color_scale = [ (0, "#ff2c1c"), # Bright red at -5% (0.5, "#484454"), # Grey around 0% (1, "#30dc5c"), # Bright green at 5% ] # Generate the treemap with fixed dimensions fig = px.treemap( df, path=[px.Constant("S&P 500 - Stocknear.com"), "sector", "industry", "symbol"], values="marketCap", color=change_percent, hover_data=[change_percent, "symbol", "marketCap"], color_continuous_scale=color_scale, range_color=range_color, color_continuous_midpoint=0, width=1200, # Fixed width height=800 # Fixed height ) # Update layout with fixed dimensions and other settings fig.update_layout( margin=dict(t=20, l=0, r=0, b=10), font=dict(size=13), # Default font size for sectors/industries coloraxis_colorbar=None, paper_bgcolor="rgba(0,0,0,0)", plot_bgcolor="rgba(0,0,0,0)", autosize=True, # Disable autosize width=1200, # Fixed width height=1200 # Fixed height ) templates = { "root": "%{label}", "sector": "%{label}", "industry": "%{label}", "symbol": "%{customdata[1]}
" + "%{customdata[0]:.2f}%" } # Update text templates based on the level fig.data[0].texttemplate = templates["symbol"] # Default template for symbols # Set the text position, border, and ensure the custom font sizes are applied fig.update_traces( textposition="middle center", marker=dict(line=dict(color="black", width=1)), hoverinfo='skip', hovertemplate=None, ) # Disable the color bar fig.update(layout_coloraxis_showscale=False) if save_html: fixed_html = f"""
{fig.to_html( include_plotlyjs='cdn', full_html=False, config=dict( displayModeBar=False, responsive=False, staticPlot=True ) )}
""" with open(f"json/heatmap/{time_period}.html", "w") as f: f.write(fixed_html) if __name__ == "__main__": for time in ['1D',"1W","1M","3M","6M","1Y","3Y"]: create_treemap(time_period = time)