"""拉取建材价格指数,更新 data.json 并刷新 index.html。""" import json import pandas as pd import akshare as ak df = ak.macro_china_construction_index() df['日期'] = pd.to_datetime(df['日期']) df = df.sort_values('日期').reset_index(drop=True) for w in [5, 10, 20, 60]: df[f'MA{w}'] = df['最新值'].rolling(w).mean().round(1) df[f'MA{w}_dir'] = df[f'MA{w}'].diff().apply(lambda x: 'up' if x > 0 else ('down' if x < 0 else 'flat')) latest = df.iloc[-1] signals = [] if latest['最新值'] > latest['MA5']: signals.append(('短期', '偏多', '价格 > MA5')) else: signals.append(('短期', '偏空', '价格 < MA5')) if latest['MA5'] > latest['MA20']: signals.append(('中期', '偏多', 'MA5 > MA20')) else: signals.append(('中期', '偏空', 'MA5 < MA20')) if latest['MA20'] > latest['MA60']: signals.append(('长期', '偏多', 'MA20 > MA60')) else: signals.append(('长期', '偏空', 'MA20 < MA60')) momentum_5d = latest['最新值'] - df.iloc[-6]['最新值'] signals.append(('动量(5日)', '偏多' if momentum_5d > 0 else '偏空', f"{momentum_5d:+d}")) bull_count = sum(1 for _, s, _ in signals if s == '偏多') if bull_count >= 3: overall = ('偏多', '#16a34a') elif bull_count <= 1: overall = ('偏空', '#dc2626') else: overall = ('震荡', '#d97706') summary = { 'date': latest['日期'].strftime('%Y-%m-%d'), 'value': int(latest['最新值']), 'change': round(float(latest['涨跌幅']), 4), 'chg_3m': round(float(latest['近3月涨跌幅']), 4), 'chg_6m': round(float(latest['近6月涨跌幅']), 4), 'chg_1y': round(float(latest['近1年涨跌幅']), 4), } mas = {} for w in [5, 10, 20, 60]: mas[f'MA{w}'] = { 'value': float(latest[f'MA{w}']), 'direction': latest[f'MA{w}_dir'], 'price_vs_ma': 'above' if latest['最新值'] > latest[f'MA{w}'] else 'below' } rows = [] for _, r in df.tail(30).iterrows(): rows.append({ 'date': r['日期'].strftime('%m-%d'), 'value': int(r['最新值']), 'chg': round(float(r['涨跌幅']), 4), 'MA5': None if pd.isna(r['MA5']) else round(float(r['MA5']), 1), 'MA20': None if pd.isna(r['MA20']) else round(float(r['MA20']), 1), 'MA60': None if pd.isna(r['MA60']) else round(float(r['MA60']), 1), }) output = { 'summary': summary, 'mas': mas, 'signals': [{'period': p, 'signal': s, 'detail': d} for p, s, d in signals], 'overall': {'signal': overall[0], 'color': overall[1]}, 'recent': rows, } with open('data.json', 'w') as f: json.dump(output, f, ensure_ascii=False, indent=2) SENTINEL = '/*__DATA_SENTINEL__*/{}' html = open('index.html').read() html = html.replace(SENTINEL, json.dumps(output, ensure_ascii=False)) open('index.html', 'w').write(html) print(f"刷新完成: {summary['date']} → {summary['value']} (日涨跌 {summary['change']:+.2f}%)") print(f"综合信号: {overall[0]}") print("信号明细:") for p, s, d in signals: print(f" {p}: {s} ({d})")