市场宽度实时定时版
from jqdata import * import datetime as dt import numpy as np import pandas as pd import seaborn as sns import matplotlib.pyplot as plt import json, textwrap # 获取股票和价格数据 stocks = get_index_stocks("000985.XSHG") now = dt.datetime.now().strftime('%Y-%m-%d %H:%M:%S') yesterday = (dt.datetime.now() - dt.timedelta(days=1)).strftime("%Y-%m-%d") count = 90 #1年的交易日 price_hist = get_price(stocks,end_date=yesterday,frequency="1d",fields=["close"],count=count + 19,panel=False) # 获取行业信息 def getStockIndustry(stocks): industry = get_industry(stocks) dict = { stock: info["sw_l1"]["industry_name"] for stock, info in industry.items() if "sw_l1" in info } industry_2_stock = {} for stock, info in industry.items(): if "sw_l1" in info: industry_name = info["sw_l1"]["industry_name"] ls = industry_2_stock.get(industry_name, []) ls.append(stock) industry_2_stock[industry_name] = ls return pd.Series(dict), industry_2_stock def update_price(): cur_price = get_price(stocks,end_date=now,frequency="1m",fields=["close"],count=1,panel=False) cur_price['time'] = pd.to_datetime(cur_price['time']).dt.floor('d') new_price = pd.concat([price_hist, cur_price], ignore_index=True) new_price= new_price.sort_values(['code', 'time']).reset_index(drop=True) return new_price def update_df(): # 处理数据 h = update_price() h["date"] = pd.DatetimeIndex(h.time).date df_close = h.pivot(index="code", columns="date", values="close").dropna(axis=0) df_ma20 = df_close.rolling(window=20, axis=1).mean().iloc[:, -count:] df_bias = df_close.iloc[:, -count:] > df_ma20 df_bias["industry_name"], industry_2_stock = getStockIndustry(stocks) df_ratio = ( (df_bias.groupby("industry_name").sum() * 100.0) / df_bias.groupby("industry_name").count() ).round() df_ratio.loc['合计'] = df_ratio.sum().astype("int32") DF = df_ratio.T return DF #====================================================================== def update_html(DF): industry_cols = DF.columns[:-1] df = DF.iloc[:, :-1].copy() # 创建数据框副本,避免修改原始数据 df.insert(len(industry_cols), '市场平均', df[industry_cols].mean(axis=1).round().astype(int)) df.index = pd.to_datetime(df.index) use_cols = [c for c in df.columns if c not in {'合计'}] # 1. 只保留 [x, y, value] 三元组给 ECharts data_js = [ [j, i, int(df.iloc[i, j])] for i in range(len(df)) for j in range(len(df.columns)) ] # print("data_js:", data_js) # 2. 行业名、日期单独传两份数组,前端用索引去取 cols = df.columns.tolist() # print("cols:", cols) dates = [str(d) for d in df.index.date] # print("dates:", dates) cell_w = 40 # 每列宽 80 px cell_h = 40 # 每行高 26 px(足够看清文字) width = len(use_cols) * cell_w # 留边给 visualMap height = len(df) * cell_h # 随行情自动增高 # 写进单文件 HTML html = textwrap.dedent(f'''\ <!doctype html> <html> <head> <meta charset="utf-8"><title>行业热力图(可点击)</title> <script src="https://cdn.jsdelivr.net/npm/echarts@5/dist/echarts.min.js"></script> <style> #wrapper{{width:100%;max-height:70vh;overflow:auto;border:1px solid #ddd}} #chart{{width:{width}px;height:{height}px;margin:auto}} </style> </head> <body> <div id="chart" style="width:{{width}}px;height:{{height}}px;margin:auto"></div> <script> const raw = {json.dumps(data_js)}; const cols = {json.dumps(cols)}; const dates = {json.dumps(dates)}; const myChart = echarts.init(document.getElementById('chart')); const option = {{ tooltip: {{ position: 'top', formatter: p => {{ const [x, y, val] = p.data; return `${{dates[y]}}<br/>${{cols[x]}}: <b>${{val}}</b>`; }} }}, animation: true, grid: {{left: '10%', right: '5%', bottom: '5%', top: '2%'}}, xAxis: {{ type: 'category', data: cols, position: 'top', axisLabel: {{interval: 0,rotate: 45,fontSize: 11}}, splitArea: {{show: true}} }}, yAxis: {{ type: 'category', data: dates, splitArea: {{show: true}} }}, visualMap: {{ min: 0, max: 100, calculable: true, type: 'continuous', orient: 'horizontal', left: 'center', bottom: '2%', inRange: {{color: [ '#005824','#238b45','#5cb85c','#90ee90','#ffff99', '#ffaa99','#ff7d66','#f54437','#b00000' ]}} }}, series: [{{ name: '热力图', type: 'heatmap', data: raw, label: {{show: true, fontSize: 11, color: '#000'}}, itemStyle: {{borderWidth: 1, borderColor: '#fff'}}, emphasis: {{itemStyle: {{shadowBlur: 12, shadowColor: 'rgba(0,0,0,.4'}}}} }}] }}; myChart.setOption(option); // 点击事件 myChart.on('click', params => {{ const [,,val,ind,dt] = params.data; alert(`${{dt}}\\n${{ind}}: ${{val}}`); }}); </script> </body> </html>''') open('行业宽度-定时刷新版.html','w',encoding='utf-8').write(html) print("可以打开-行业宽度-定时刷新版.html") # 定时刷新 10分钟一次 while True: DF = update_df() update_html(DF) time.sleep(60 * 10)
本文来自博客园,作者:羊驼之歌,转载请注明原文链接:https://www.cnblogs.com/shijieli/p/19131049

浙公网安备 33010602011771号