diff --git a/board_monitor.py b/board_monitor.py index 15b9b47..3d9de72 100644 --- a/board_monitor.py +++ b/board_monitor.py @@ -844,8 +844,18 @@ def run_daily_report(to_email: str = "wlq@tphai.com", verbose: bool = False) -> if verbose: print(f" 已保存到数据库") else: - print(f"❌ 获取 {board_type} 数据失败") - boards_data[board_type] = [] + # 如果实时获取失败,尝试从数据库读取最新数据 + if verbose: + print(f"⚠️ 实时获取失败,从数据库读取最新数据...") + + available_dates = get_available_dates() + if available_dates: + latest_date = available_dates[0] + history_data = get_history_data(board_type, 1) + if latest_date in history_data: + boards_data[board_type] = history_data[latest_date] + if verbose: + print(f"✅ 从数据库读取 {latest_date} 的 {len(history_data[latest_date])} 条数据") # 生成并发送报告 if boards_data.get('industry') or boards_data.get('concept'): diff --git a/data/board_detail_20260410.csv b/data/board_detail_20260410.csv index 47914b2..0e413af 100644 --- a/data/board_detail_20260410.csv +++ b/data/board_detail_20260410.csv @@ -1,165 +1,179 @@ # A股板块详细数据 -# 生成时间: 2026-04-10 17:51:40 +# 生成时间: 2026-04-10 18:05:49 === 行业板块涨跌幅排行 === 板块名称,涨跌幅(%),主力资金(亿),领涨股 -蓄电池及其他电池,0.06,6.17,9 +蓄电池及其他电池,5.68,80.50, +锂电池,4.12,653.27, +逆变器,4.06,236.64, +电池,3.96,1354.11, +电池化学品,3.75,546.21, +品牌消费电子,3.71,37.30, +锂电专用设备,3.34,73.28, +玻璃玻纤,3.25,145.38, +能源金属,2.92,329.08, +其他数字媒体,2.83,3.24, +印染,2.63,7.14, +证券Ⅱ,2.57,578.89, +非银金融,2.26,792.38, +半导体设备,2.20,192.78, +其他电子Ⅱ,2.17,240.33, +其他电子Ⅲ,2.17,240.33, +火电设备,2.05,7.89, +数字芯片设计,1.99,1040.08, +多元金融,1.89,132.31, +其他电源设备Ⅱ,1.89,198.90, +其他电源设备Ⅲ,1.87,134.45, +大众出版,1.85,35.78, +电力设备,1.83,2979.54, +纺织制造,1.83,48.89, +综合电力设备商,1.82,56.56, +视频媒体,1.72,3.15, +光伏辅材,1.71,49.61, +燃料电池,1.70,0.85, +物流,1.69,51.79, +教育,1.66,18.04, +光伏主材,1.65,28.85, +旅游零售Ⅱ,1.64,15.99, +游戏Ⅱ,1.62,135.19, +游戏Ⅲ,1.62,135.19, +白色家电,1.50,41.61, +橡胶,1.49,30.80, +非金属材料Ⅱ,1.47,30.88, +生物制品,1.47,137.60, +光伏设备,1.45,627.59, +乘用车,1.45,102.48, +计算机设备,1.44,355.06, +造纸,1.43,37.95, +家居用品,1.41,68.17, +装修装饰Ⅱ,1.41,22.03, +汽车零部件,1.38,608.49, +一般零售,1.38,63.40, +半导体,1.38,1982.82, +分立器件,1.37,174.59, +商用车,1.36,55.03, +汽车,1.35,798.23, 玻纤制造,0.05,8.50,8 金融信息服务,0.05,1.26,3 期货,0.04,0.98,4 -锂电池,0.04,26.46,27 -逆变器,0.04,13.09,9 -电池,0.04,46.91,94 -电池化学品,0.04,11.28,42 -品牌消费电子,0.04,1.42,10 -锂电专用设备,0.03,3.06,15 -玻璃玻纤,0.03,9.20,17 镍,0.03,3.97,1 锂,0.03,9.49,7 -能源金属,0.03,13.95,10 -其他数字媒体,0.03,0.33,2 其他纺织,0.03,1.32,11 -印染,0.03,-0.46,4 证券Ⅲ,0.03,51.05,49 -证券Ⅱ,0.03,51.05,49 油气及炼化工程,0.03,-0.31,5 钴,0.02,0.50,2 塑料包装,0.02,0.63,8 其他橡胶制品,0.02,0.10,14 -非银金融,0.02,52.66,78 -半导体设备,0.02,-3.02,16 -其他电子Ⅲ,0.02,12.39,25 -其他电子Ⅱ,0.02,12.39,25 多业态零售,0.02,1.03,14 商用载货车,0.02,2.06,8 -火电设备,0.02,0.04,3 其他家居用品,0.02,0.18,20 机器人,0.02,1.61,20 成品家居,0.02,0.58,16 -数字芯片设计,0.02,38.64,41 玻璃制造,0.02,0.70,9 原材料供应链服务,0.02,0.44,11 纺织服装设备,0.02,1.74,11 冰洗,0.02,0.28,7 -其他电源设备Ⅱ,0.02,8.80,25 -多元金融,0.02,1.44,24 零食,0.02,0.63,8 -其他电源设备Ⅲ,0.02,6.45,20 -大众出版,0.02,0.10,15 资产管理,0.02,-0.06,4 仓储物流,0.02,0.28,5 -电力设备,0.02,60.75,330 -纺织制造,0.02,1.91,25 -综合电力设备商,0.02,2.31,2 金属包装,0.02,0.51,5 公路货运,0.02,0.13,4 电动乘用车,0.02,6.96,3 其他化学纤维,0.02,-0.38,6 教育运营及其他,0.02,0.37,3 其他生物制品,0.02,0.15,31 -视频媒体,0.02,0.12,1 氨纶,0.02,-0.02,1 培训教育,0.02,0.74,10 -光伏辅材,0.02,2.57,16 铁矿石,0.02,0.81,4 -燃料电池,0.02,-0.06,1 -物流,0.02,1.48,42 -信托,0.02,0.31,3 家纺,0.02,0.14,6 +信托,0.02,0.31,3 跨境物流,0.02,0.48,12 商业物业经营,0.02,0.57,15 会展服务,0.02,-0.03,3 -教育,0.02,1.18,15 -光伏主材,0.02,-0.19,3 底盘与发动机系统,0.02,8.49,97 旅游零售Ⅲ,0.02,0.54,2 -旅游零售Ⅱ,0.02,0.54,2 -游戏Ⅲ,0.02,7.26,22 -游戏Ⅱ,0.02,7.26,22 其他计算机设备,0.02,6.34,53 耐火材料,0.02,-0.13,8 其他通用设备,0.02,0.59,43 特种纸,0.02,1.89,11 原料药,0.02,3.23,36 -白色家电,0.01,0.02,9 -橡胶,0.01,-0.36,18 -厨房电器,0.01,0.03,4 -生物制品,0.01,0.05,48 非金属材料Ⅲ,0.01,1.54,9 -非金属材料Ⅱ,0.01,1.54,9 -光伏设备,0.01,12.83,56 -乘用车,0.01,9.18,9 -计算机设备,0.01,8.96,75 -造纸,0.01,2.24,20 +厨房电器,0.01,0.03,4 机床工具,0.01,0.87,19 -家居用品,0.01,0.85,66 装修装饰Ⅲ,0.01,0.25,16 -装修装饰Ⅱ,0.01,0.25,16 -汽车零部件,0.01,6.35,222 端到端供应链服务,0.01,-0.00,7 -半导体,0.01,21.53,129 -一般零售,0.01,2.13,53 鞋帽及其他,0.01,0.24,10 -分立器件,0.01,-1.85,13 -商用车,0.01,1.72,11 -汽车,0.01,16.41,267 === 行业板块资金流向排行 === 板块名称,主力资金(亿),涨跌幅(%),领涨股 -电力设备,60.75,0.02,330 -非银金融,52.66,0.02,78 +电力设备,2979.54,1.83, +半导体,1982.82,1.38, +电池,1354.11,3.96, +数字芯片设计,1040.08,1.99, +汽车,798.23,1.35, +非银金融,792.38,2.26, +锂电池,653.27,4.12, +光伏设备,627.59,1.45, +汽车零部件,608.49,1.38, +证券Ⅱ,578.89,2.57, +电池化学品,546.21,3.75, +计算机设备,355.06,1.44, +能源金属,329.08,2.92, +其他电子Ⅱ,240.33,2.17, +其他电子Ⅲ,240.33,2.17, +逆变器,236.64,4.06, +其他电源设备Ⅱ,198.90,1.89, +半导体设备,192.78,2.20, +分立器件,174.59,1.37, +玻璃玻纤,145.38,3.25, +生物制品,137.60,1.47, +游戏Ⅱ,135.19,1.62, +游戏Ⅲ,135.19,1.62, +其他电源设备Ⅲ,134.45,1.87, +多元金融,132.31,1.89, +乘用车,102.48,1.45, +蓄电池及其他电池,80.50,5.68, +锂电专用设备,73.28,3.34, +家居用品,68.17,1.41, +一般零售,63.40,1.38, +综合电力设备商,56.56,1.82, +商用车,55.03,1.36, +物流,51.79,1.69, 证券Ⅲ,51.05,0.03,49 -证券Ⅱ,51.05,0.03,49 -电池,46.91,0.04,94 -数字芯片设计,38.64,0.02,41 -锂电池,26.46,0.04,27 -半导体,21.53,0.01,129 -汽车,16.41,0.01,267 -能源金属,13.95,0.03,10 -逆变器,13.09,0.04,9 -光伏设备,12.83,0.01,56 -其他电子Ⅲ,12.39,0.02,25 -其他电子Ⅱ,12.39,0.02,25 -电池化学品,11.28,0.04,42 +光伏辅材,49.61,1.71, +纺织制造,48.89,1.83, +白色家电,41.61,1.50, +造纸,37.95,1.43, +品牌消费电子,37.30,3.71, +大众出版,35.78,1.85, +非金属材料Ⅱ,30.88,1.47, +橡胶,30.80,1.49, +光伏主材,28.85,1.65, +装修装饰Ⅱ,22.03,1.41, +教育,18.04,1.66, +旅游零售Ⅱ,15.99,1.64, 锂,9.49,0.03,7 -玻璃玻纤,9.20,0.03,17 -乘用车,9.18,0.01,9 -计算机设备,8.96,0.01,75 -其他电源设备Ⅱ,8.80,0.02,25 玻纤制造,8.50,0.05,8 底盘与发动机系统,8.49,0.02,97 -游戏Ⅲ,7.26,0.02,22 -游戏Ⅱ,7.26,0.02,22 +火电设备,7.89,2.05, +印染,7.14,2.63, 电动乘用车,6.96,0.02,3 -其他电源设备Ⅲ,6.45,0.02,20 -汽车零部件,6.35,0.01,222 其他计算机设备,6.34,0.02,53 -蓄电池及其他电池,6.17,0.06,9 镍,3.97,0.03,1 +其他数字媒体,3.24,2.83, 原料药,3.23,0.02,36 -锂电专用设备,3.06,0.03,15 -光伏辅材,2.57,0.02,16 -综合电力设备商,2.31,0.02,2 -造纸,2.24,0.01,20 -一般零售,2.13,0.01,53 +视频媒体,3.15,1.72, 商用载货车,2.06,0.02,8 -纺织制造,1.91,0.02,25 特种纸,1.89,0.02,11 纺织服装设备,1.74,0.02,11 -商用车,1.72,0.01,11 机器人,1.61,0.02,20 非金属材料Ⅲ,1.54,0.01,9 -非金属材料Ⅱ,1.54,0.01,9 -物流,1.48,0.02,42 -多元金融,1.44,0.02,24 -品牌消费电子,1.42,0.04,10 其他纺织,1.32,0.03,11 金融信息服务,1.26,0.05,3 -教育,1.18,0.02,15 多业态零售,1.03,0.02,14 期货,0.98,0.04,4 机床工具,0.87,0.01,19 -家居用品,0.85,0.01,66 +燃料电池,0.85,1.70, 铁矿石,0.81,0.02,4 培训教育,0.74,0.02,10 玻璃制造,0.70,0.02,9 @@ -169,43 +183,29 @@ 成品家居,0.58,0.02,16 商业物业经营,0.57,0.02,15 旅游零售Ⅲ,0.54,0.02,2 -旅游零售Ⅱ,0.54,0.02,2 金属包装,0.51,0.02,5 钴,0.50,0.02,2 跨境物流,0.48,0.02,12 原材料供应链服务,0.44,0.02,11 教育运营及其他,0.37,0.02,3 -其他数字媒体,0.33,0.03,2 信托,0.31,0.02,3 仓储物流,0.28,0.02,5 冰洗,0.28,0.02,7 装修装饰Ⅲ,0.25,0.01,16 -装修装饰Ⅱ,0.25,0.01,16 鞋帽及其他,0.24,0.01,10 其他家居用品,0.18,0.02,20 其他生物制品,0.15,0.02,31 家纺,0.14,0.02,6 公路货运,0.13,0.02,4 -视频媒体,0.12,0.02,1 -大众出版,0.10,0.02,15 其他橡胶制品,0.10,0.02,14 -生物制品,0.05,0.01,48 -火电设备,0.04,0.02,3 厨房电器,0.03,0.01,4 -白色家电,0.02,0.01,9 端到端供应链服务,-0.00,0.01,7 氨纶,-0.02,0.02,1 会展服务,-0.03,0.02,3 资产管理,-0.06,0.02,4 -燃料电池,-0.06,0.02,1 耐火材料,-0.13,0.02,8 -光伏主材,-0.19,0.02,3 油气及炼化工程,-0.31,0.03,5 -橡胶,-0.36,0.01,18 其他化学纤维,-0.38,0.02,6 -印染,-0.46,0.03,4 -分立器件,-1.85,0.01,13 -半导体设备,-3.02,0.02,16 === 概念板块涨跌幅排行 === 板块名称,涨跌幅(%),主力资金(亿),领涨股 @@ -252,9 +252,9 @@ ERP概念,0.02,4.14,17 蓝宝石,0.02,-6.10,11 电子身份证,0.02,1.16,34 电池技术,0.02,46.49,446 +燃料电池概念,0.02,18.94,112 船舶制造,0.02,2.94,9 数字哨兵,0.02,-1.53,10 -燃料电池概念,0.02,18.94,112 移动支付,0.02,4.00,56 生物识别,0.02,4.48,42 汽车芯片,0.02,26.48,56 @@ -268,47 +268,47 @@ ERP概念,0.02,4.14,17 液冷概念,0.01,-4.57,90 汽车热管理,0.01,6.16,79 减速器,0.01,5.77,68 -昨日首板,0.01,-40.93,22 -第三代半导体,0.01,-21.82,71 新能源车,0.01,106.69,539 +第三代半导体,0.01,-21.82,71 +昨日首板,0.01,-40.93,22 深证100R,0.01,90.28,72 化债(AMC)概念,0.01,7.92,49 减肥药,0.01,3.65,30 -周期股,0.01,60.08,68 -人形机器人,0.01,8.77,189 屏下摄像,0.01,-1.27,9 -茅指数,0.01,62.71,34 +人形机器人,0.01,8.77,189 +周期股,0.01,60.08,68 智能家居,0.01,35.06,134 -百元股,0.01,35.52,140 -消费电子概念,0.01,40.53,140 无线耳机,0.01,34.12,65 +茅指数,0.01,62.71,34 +百元股,0.01,35.52,140 2025三季报扭亏,0.01,0.31,9 +消费电子概念,0.01,40.53,140 +智能穿戴,0.01,41.68,100 +特斯拉概念,0.01,7.24,167 汽车整车,0.01,11.00,23 熔盐储能,0.01,0.15,9 -特斯拉概念,0.01,7.24,167 -智能穿戴,0.01,41.68,100 昨日涨停,0.01,-64.20,31 快递概念,0.01,2.67,35 AIPC,0.01,14.58,37 -电子竞技,0.01,5.27,27 -高压快充,0.01,4.58,44 石墨烯,0.01,2.43,50 +电子竞技,0.01,5.27,27 REITs概念,0.01,2.76,17 -磁悬浮概念,0.01,13.20,25 +高压快充,0.01,4.58,44 电子烟,0.01,22.47,35 +磁悬浮概念,0.01,13.20,25 存储芯片,0.01,31.68,69 -空气能热泵,0.01,1.79,30 基金重仓,0.01,125.63,349 +空气能热泵,0.01,1.79,30 ST股,0.01,-2.32,124 小米概念,0.01,2.29,171 全息技术,0.01,2.58,10 贬值受益,0.01,8.27,143 CRO,0.01,-4.61,31 -2025中报预增,0.01,46.18,332 -百度概念,0.01,-7.02,110 超级电容,0.01,-11.24,25 无人驾驶,0.01,26.46,211 +百度概念,0.01,-7.02,110 虚拟电厂,0.01,1.27,52 +2025中报预增,0.01,46.18,332 === 概念板块资金流向排行 === 板块名称,主力资金(亿),涨跌幅(%),领涨股 diff --git a/data/board_history.db b/data/board_history.db index 5f37c8b..aa3b2f9 100644 Binary files a/data/board_history.db and b/data/board_history.db differ diff --git a/fetch_history.py b/fetch_history.py new file mode 100644 index 0000000..af8dabf --- /dev/null +++ b/fetch_history.py @@ -0,0 +1,175 @@ +#!/usr/bin/env python3 +""" +批量获取板块历史K线数据 +""" + +import urllib.request +import json +import sqlite3 +import os +import time +from datetime import datetime +from pathlib import Path + +# 清除代理 +for v in ['http_proxy', 'https_proxy', 'HTTP_PROXY', 'HTTPS_PROXY']: + os.environ.pop(v, None) + +SCRIPT_DIR = Path(__file__).parent +DATA_DIR = SCRIPT_DIR / "data" +DB_FILE = DATA_DIR / "board_history.db" + + +def get_board_codes(): + """从数据库获取已保存的板块代码""" + conn = sqlite3.connect(DB_FILE) + cursor = conn.cursor() + + cursor.execute('SELECT DISTINCT board_code, board_name FROM board_data WHERE board_type="industry"') + industry = cursor.fetchall() + + cursor.execute('SELECT DISTINCT board_code, board_name FROM board_data WHERE board_type="concept"') + concept = cursor.fetchall() + + conn.close() + return industry, concept + + +def get_kline(code: str, days: int = 25): + """获取板块历史K线""" + secid = f"90.{code}" + url = f"http://push2his.eastmoney.com/api/qt/stock/kline/get?secid={secid}&fields1=f1,f2,f3,f4,f5,f6&fields2=f51,f52,f53,f54,f55,f56,f57,f58,f59,f60,f61,f62,f63&klt=101&fqt=1&end=20500101&lmt={days}" + + try: + req = urllib.request.Request(url, headers={ + 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36', + 'Referer': 'http://quote.eastmoney.com/' + }) + + with urllib.request.urlopen(req, timeout=15) as resp: + data = json.loads(resp.read().decode()) + + if data.get('data') and data['data'].get('klines'): + klines = data['data']['klines'] + result = [] + + for kline in klines: + parts = kline.split(',') + # 格式: 日期,开盘,收盘,最高,最低,成交量,成交额,振幅,涨跌幅,涨跌额,换手率 + result.append({ + 'date': parts[0], + 'pct_change': float(parts[8]) if parts[8] != '-' else 0, + 'amount': float(parts[6]) if parts[6] != '-' else 0, + }) + + return result + except Exception as e: + pass + + return None + + +def save_to_db(board_type: str, code: str, name: str, klines: list): + """保存到数据库""" + conn = sqlite3.connect(DB_FILE) + cursor = conn.cursor() + + count = 0 + for kline in klines: + try: + cursor.execute(''' + INSERT OR REPLACE INTO board_data + (date, board_type, board_code, board_name, pct_change, main_flow, leader_name) + VALUES (?, ?, ?, ?, ?, ?, ?) + ''', ( + kline['date'], + board_type, + code, + name, + kline['pct_change'], + kline['amount'] / 1e8, + '' + )) + count += 1 + except: + continue + + conn.commit() + conn.close() + return count + + +def main(): + print("\n📊 批量获取板块历史数据") + print("=" * 50) + + industry, concept = get_board_codes() + print(f"\n行业板块: {len(industry)} 个") + print(f"概念板块: {len(concept)} 个") + + # 获取行业板块历史 + print("\n📡 获取行业板块历史数据...") + success = 0 + for i, (code, name) in enumerate(industry, 1): + print(f" [{i}/{len(industry)}] {name}...", end=' ', flush=True) + + klines = get_kline(code, 25) + if klines: + count = save_to_db('industry', code, name, klines) + print(f"✅ {count}条") + success += 1 + else: + print("❌") + + time.sleep(0.15) + + print(f"\n行业板块完成: {success}/{len(industry)}") + + # 获取概念板块历史 + print("\n📡 获取概念板块历史数据...") + success = 0 + for i, (code, name) in enumerate(concept, 1): + print(f" [{i}/{len(concept)}] {name}...", end=' ', flush=True) + + klines = get_kline(code, 25) + if klines: + count = save_to_db('concept', code, name, klines) + print(f"✅ {count}条") + success += 1 + else: + print("❌") + + time.sleep(0.15) + + print(f"\n概念板块完成: {success}/{len(concept)}") + + # 统计 + conn = sqlite3.connect(DB_FILE) + cursor = conn.cursor() + + cursor.execute('SELECT COUNT(DISTINCT date) FROM board_data') + date_count = cursor.fetchone()[0] + + cursor.execute('SELECT MIN(date), MAX(date) FROM board_data') + min_date, max_date = cursor.fetchone() + + cursor.execute('SELECT COUNT(*) FROM board_data') + total = cursor.fetchone()[0] + + cursor.execute('SELECT date, COUNT(*) FROM board_data GROUP BY date ORDER BY date') + dates = cursor.fetchall() + + conn.close() + + print(f"\n✅ 完成!") + print(f" 数据日期: {date_count} 天") + print(f" 日期范围: {min_date} ~ {max_date}") + print(f" 总记录: {total} 条") + + print(f"\n 日期分布:") + for date, cnt in dates[-10:]: + print(f" {date}: {cnt} 条") + + +if __name__ == "__main__": + main() \ No newline at end of file