fix: 修复多个 Issues

- #23 ETF 筹码分布:跳过 ETF/指数的筹码分布调用
- #16 OpenAI SOCKS 代理:改进错误提示,添加 httpx[socks] 依赖
- #15 大盘复盘报告:添加报告文件保存功能
This commit is contained in:
zhulinsen
2026-01-14 20:20:51 +08:00
parent b1bfea5dad
commit 3dded794d7
4 changed files with 34 additions and 4 deletions

View File

@@ -441,9 +441,14 @@ class GeminiAnalyzer:
logger.debug("OpenAI 兼容 API 未配置或配置无效") logger.debug("OpenAI 兼容 API 未配置或配置无效")
return return
# 分离 import 和客户端创建,以便提供更准确的错误信息
try: try:
from openai import OpenAI from openai import OpenAI
except ImportError:
logger.error("未安装 openai 库,请运行: pip install openai")
return
try:
# base_url 可选,不填则使用 OpenAI 官方默认地址 # base_url 可选,不填则使用 OpenAI 官方默认地址
client_kwargs = {"api_key": config.openai_api_key} client_kwargs = {"api_key": config.openai_api_key}
if config.openai_base_url and config.openai_base_url.startswith('http'): if config.openai_base_url and config.openai_base_url.startswith('http'):
@@ -453,10 +458,18 @@ class GeminiAnalyzer:
self._current_model_name = config.openai_model self._current_model_name = config.openai_model
self._use_openai = True self._use_openai = True
logger.info(f"OpenAI 兼容 API 初始化成功 (base_url: {config.openai_base_url}, model: {config.openai_model})") logger.info(f"OpenAI 兼容 API 初始化成功 (base_url: {config.openai_base_url}, model: {config.openai_model})")
except ImportError: except ImportError as e:
logger.error("未安装 openai 库,请运行: pip install openai") # 依赖缺失(如 socksio
if 'socksio' in str(e).lower() or 'socks' in str(e).lower():
logger.error(f"OpenAI 客户端需要 SOCKS 代理支持,请运行: pip install httpx[socks] 或 pip install socksio")
else:
logger.error(f"OpenAI 依赖缺失: {e}")
except Exception as e: except Exception as e:
logger.error(f"OpenAI 兼容 API 初始化失败: {e}") error_msg = str(e).lower()
if 'socks' in error_msg or 'socksio' in error_msg or 'proxy' in error_msg:
logger.error(f"OpenAI 代理配置错误: {e},如使用 SOCKS 代理请运行: pip install httpx[socks]")
else:
logger.error(f"OpenAI 兼容 API 初始化失败: {e}")
def _init_model(self) -> None: def _init_model(self) -> None:
""" """

View File

@@ -648,6 +648,8 @@ class AkshareFetcher(BaseFetcher):
数据来源ak.stock_cyq_em() 数据来源ak.stock_cyq_em()
包含:获利比例、平均成本、筹码集中度 包含:获利比例、平均成本、筹码集中度
注意ETF/指数没有筹码分布数据,会直接返回 None
Args: Args:
stock_code: 股票代码 stock_code: 股票代码
@@ -656,6 +658,11 @@ class AkshareFetcher(BaseFetcher):
""" """
import akshare as ak import akshare as ak
# ETF/指数没有筹码分布数据
if _is_etf_code(stock_code):
logger.debug(f"[API跳过] {stock_code} 是 ETF/指数,无筹码分布数据")
return None
try: try:
# 防封禁策略 # 防封禁策略
self._set_random_user_agent() self._set_random_user_agent()

View File

@@ -687,6 +687,15 @@ def run_market_review(notifier: NotificationService, analyzer=None, search_servi
review_report = market_analyzer.run_daily_review() review_report = market_analyzer.run_daily_review()
if review_report: if review_report:
# 保存报告到文件
date_str = datetime.now().strftime('%Y%m%d')
report_filename = f"market_review_{date_str}.md"
filepath = notifier.save_report_to_file(
f"# 🎯 大盘复盘\n\n{review_report}",
report_filename
)
logger.info(f"大盘复盘报告已保存: {filepath}")
# 推送通知 # 推送通知
if notifier.is_available(): if notifier.is_available():
# 添加标题 # 添加标题

View File

@@ -32,6 +32,7 @@ google-search-results>=2.4.0 # SerpAPI每月 100 次免费)
# 网络请求 # 网络请求
requests>=2.31.0 # HTTP 请求 requests>=2.31.0 # HTTP 请求
fake-useragent>=1.4.0 # 随机 User-Agent 防封禁 fake-useragent>=1.4.0 # 随机 User-Agent 防封禁
httpx[socks] # HTTP 客户端 + SOCKS 代理支持OpenAI 可选依赖)
# 数据库 # 数据库
# SQLite 是 Python 内置,无需额外安装 # SQLite 是 Python 内置,无需额外安装