update
This commit is contained in:
parent
2749d50046
commit
eeac457323
@ -157,12 +157,25 @@ class StockAgent:
|
|||||||
us_market_open = self._is_market_hours('US')
|
us_market_open = self._is_market_hours('US')
|
||||||
hk_market_open = self._is_market_hours('0700.HK')
|
hk_market_open = self._is_market_hours('0700.HK')
|
||||||
|
|
||||||
if not us_market_open and not hk_market_open:
|
# 检查是否是盘后分析时间
|
||||||
logger.debug("非交易时间(美股和港股均闭市),跳过本次分析")
|
us_after_hours = self._is_after_hours('US')
|
||||||
continue
|
hk_after_hours = self._is_after_hours('0700.HK')
|
||||||
|
|
||||||
# 确定要分析的股票列表
|
# 确定要分析的股票列表
|
||||||
stocks_to_analyze = []
|
stocks_to_analyze = []
|
||||||
|
analysis_type = "盘中" # 默认为盘中分析
|
||||||
|
|
||||||
|
# 盘后分析:优先级更高,用于日线级别分析
|
||||||
|
if us_after_hours or hk_after_hours:
|
||||||
|
analysis_type = "盘后"
|
||||||
|
if us_after_hours:
|
||||||
|
stocks_to_analyze.extend(us_stocks)
|
||||||
|
logger.info(f"美股盘后分析,分析 {len(us_stocks)} 只美股(日线级别)")
|
||||||
|
if hk_after_hours:
|
||||||
|
stocks_to_analyze.extend(hk_stocks)
|
||||||
|
logger.info(f"港股盘后分析,分析 {len(hk_stocks)} 只港股(日线级别)")
|
||||||
|
else:
|
||||||
|
# 盘中分析
|
||||||
if us_market_open:
|
if us_market_open:
|
||||||
stocks_to_analyze.extend(us_stocks)
|
stocks_to_analyze.extend(us_stocks)
|
||||||
logger.info(f"美股交易时间,分析 {len(us_stocks)} 只美股")
|
logger.info(f"美股交易时间,分析 {len(us_stocks)} 只美股")
|
||||||
@ -170,25 +183,26 @@ class StockAgent:
|
|||||||
stocks_to_analyze.extend(hk_stocks)
|
stocks_to_analyze.extend(hk_stocks)
|
||||||
logger.info(f"港股交易时间,分析 {len(hk_stocks)} 只港股")
|
logger.info(f"港股交易时间,分析 {len(hk_stocks)} 只港股")
|
||||||
|
|
||||||
|
# 如果没有需要分析的股票
|
||||||
if not stocks_to_analyze:
|
if not stocks_to_analyze:
|
||||||
logger.debug("没有需要分析的股票")
|
logger.debug("没有需要分析的股票")
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# 分析股票并收集结果
|
# 分析股票并收集结果
|
||||||
logger.info(f"开始分析 {len(stocks_to_analyze)} 只股票")
|
logger.info(f"开始{analysis_type}分析 {len(stocks_to_analyze)} 只股票")
|
||||||
analysis_results = []
|
analysis_results = []
|
||||||
|
|
||||||
for symbol in stocks_to_analyze:
|
for symbol in stocks_to_analyze:
|
||||||
if not self.running:
|
if not self.running:
|
||||||
break
|
break
|
||||||
result = await self.analyze_symbol(symbol)
|
result = await self.analyze_symbol(symbol, is_after_hours=(analysis_type == "盘后"))
|
||||||
if result:
|
if result:
|
||||||
analysis_results.append(result)
|
analysis_results.append(result)
|
||||||
|
|
||||||
# 生成并发送汇总报告
|
# 生成并发送汇总报告
|
||||||
await self._send_summary_report(analysis_results)
|
await self._send_summary_report(analysis_results, analysis_type)
|
||||||
|
|
||||||
logger.info("本次分析完成")
|
logger.info(f"本次{analysis_type}分析完成")
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"分析循环出错: {e}")
|
logger.error(f"分析循环出错: {e}")
|
||||||
@ -256,12 +270,65 @@ class StockAgent:
|
|||||||
"""判断当前是否在任一市场的交易时间(美股或港股)"""
|
"""判断当前是否在任一市场的交易时间(美股或港股)"""
|
||||||
return self._is_market_hours('US') or self._is_market_hours('0700.HK')
|
return self._is_market_hours('US') or self._is_market_hours('0700.HK')
|
||||||
|
|
||||||
async def analyze_symbol(self, symbol: str) -> Optional[Dict[str, Any]]:
|
def _is_after_hours(self, symbol: str) -> bool:
|
||||||
|
"""
|
||||||
|
判断当前是否是盘后分析时间(收盘后2小时内)
|
||||||
|
|
||||||
|
美股收盘时间:
|
||||||
|
- 夏令时: 北京时间 04:00 收盘
|
||||||
|
- 冬令时: 北京时间 05:00 收盘
|
||||||
|
|
||||||
|
港股收盘时间: 北京时间 16:00 收盘
|
||||||
|
|
||||||
|
盘后分析时间: 收盘后 2 小时内
|
||||||
|
|
||||||
|
Args:
|
||||||
|
symbol: 股票代码(用于判断是美股还是港股)
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
是否是盘后分析时间
|
||||||
|
"""
|
||||||
|
from datetime import datetime
|
||||||
|
|
||||||
|
# 获取当前时间
|
||||||
|
now = datetime.now()
|
||||||
|
|
||||||
|
# 检查是否为周末
|
||||||
|
if now.weekday() >= 5: # 5=周六, 6=周日
|
||||||
|
return False
|
||||||
|
|
||||||
|
# 判断是港股还是美股
|
||||||
|
is_hk_stock = symbol and symbol.endswith('.HK') if symbol else False
|
||||||
|
|
||||||
|
# 获取当前小时和分钟
|
||||||
|
hour = now.hour
|
||||||
|
minute = now.minute
|
||||||
|
current_time = hour * 100 + minute # 转换为数字,如 1630 表示 16:30
|
||||||
|
|
||||||
|
if is_hk_stock:
|
||||||
|
# 港股盘后: 16:00-18:00 (收盘后2小时)
|
||||||
|
return 1600 <= current_time < 1800
|
||||||
|
else:
|
||||||
|
# 美股盘后
|
||||||
|
# 判断夏令时/冬令时(简单判断:3-11月为夏令时)
|
||||||
|
is_summer = 3 <= now.month <= 11
|
||||||
|
|
||||||
|
if is_summer:
|
||||||
|
# 夏令时: 04:00-06:00 (收盘后2小时)
|
||||||
|
return 400 <= current_time < 600
|
||||||
|
else:
|
||||||
|
# 冬令时: 05:00-07:00 (收盘后2小时)
|
||||||
|
return 500 <= current_time < 700
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
|
async def analyze_symbol(self, symbol: str, is_after_hours: bool = False) -> Optional[Dict[str, Any]]:
|
||||||
"""
|
"""
|
||||||
分析单个股票
|
分析单个股票
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
symbol: 股票代码
|
symbol: 股票代码
|
||||||
|
is_after_hours: 是否是盘后分析(盘后会更关注日线级别机会)
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
分析结果字典,包含股票信息和信号
|
分析结果字典,包含股票信息和信号
|
||||||
@ -499,12 +566,13 @@ class StockAgent:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async def _send_summary_report(self, results: List[Dict[str, Any]]):
|
async def _send_summary_report(self, results: List[Dict[str, Any]], analysis_type: str = "盘中"):
|
||||||
"""
|
"""
|
||||||
生成并发送分析汇总报告
|
生成并发送分析汇总报告
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
results: 所有股票的分析结果列表
|
results: 所有股票的分析结果列表
|
||||||
|
analysis_type: 分析类型 ("盘中" 或 "盘后")
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
now = datetime.now()
|
now = datetime.now()
|
||||||
@ -542,8 +610,9 @@ class StockAgent:
|
|||||||
high_quality_signals.sort(key=lambda x: x.get('confidence', 0), reverse=True)
|
high_quality_signals.sort(key=lambda x: x.get('confidence', 0), reverse=True)
|
||||||
|
|
||||||
# 构建汇总报告
|
# 构建汇总报告
|
||||||
|
analysis_tag = f"【{analysis_type}分析】"
|
||||||
logger.info(f"\n{'='*80}")
|
logger.info(f"\n{'='*80}")
|
||||||
logger.info(f"📊 股票分析汇总报告")
|
logger.info(f"📊 股票分析汇总报告 {analysis_tag}")
|
||||||
logger.info(f"{'='*80}")
|
logger.info(f"{'='*80}")
|
||||||
logger.info(f"时间: {now.strftime('%Y-%m-%d %H:%M:%S')}")
|
logger.info(f"时间: {now.strftime('%Y-%m-%d %H:%M:%S')}")
|
||||||
logger.info(f"分析总数: {total} 只 (美股: {len(us_results)}, 港股: {len(hk_results)})")
|
logger.info(f"分析总数: {total} 只 (美股: {len(us_results)}, 港股: {len(hk_results)})")
|
||||||
@ -581,7 +650,8 @@ class StockAgent:
|
|||||||
await self._send_feishu_summary(
|
await self._send_feishu_summary(
|
||||||
now, total, with_signals, notified,
|
now, total, with_signals, notified,
|
||||||
buy_signals, sell_signals, high_quality_signals,
|
buy_signals, sell_signals, high_quality_signals,
|
||||||
len(us_results), len(hk_results)
|
len(us_results), len(hk_results),
|
||||||
|
analysis_type
|
||||||
)
|
)
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@ -599,13 +669,15 @@ class StockAgent:
|
|||||||
sell_signals: List,
|
sell_signals: List,
|
||||||
high_quality_signals: List,
|
high_quality_signals: List,
|
||||||
us_count: int = 0,
|
us_count: int = 0,
|
||||||
hk_count: int = 0
|
hk_count: int = 0,
|
||||||
|
analysis_type: str = "盘中"
|
||||||
):
|
):
|
||||||
"""发送飞书汇总报告"""
|
"""发送飞书汇总报告"""
|
||||||
try:
|
try:
|
||||||
# 构建内容
|
# 构建内容
|
||||||
|
analysis_tag = f"【{analysis_type}分析】"
|
||||||
content_parts = [
|
content_parts = [
|
||||||
f"**📊 股票分析汇总报告**",
|
f"**📊 股票分析汇总报告 {analysis_tag}**",
|
||||||
f"",
|
f"",
|
||||||
f"⏰ 时间: {now.strftime('%Y-%m-%d %H:%M')}",
|
f"⏰ 时间: {now.strftime('%Y-%m-%d %H:%M')}",
|
||||||
f"",
|
f"",
|
||||||
@ -643,8 +715,9 @@ class StockAgent:
|
|||||||
|
|
||||||
content = "\n".join(content_parts)
|
content = "\n".join(content_parts)
|
||||||
|
|
||||||
# 发送飞书
|
# 发送飞书 - 标题包含分析类型
|
||||||
title = f"📊 股票分析汇总 ({now.strftime('%H:%M')})"
|
type_tag = "盘后" if analysis_type == "盘后" else "分析"
|
||||||
|
title = f"📊 股票{type_tag}汇总 ({now.strftime('%H:%M')})"
|
||||||
color = "blue"
|
color = "blue"
|
||||||
|
|
||||||
await self.feishu.send_card(title, content, color)
|
await self.feishu.send_card(title, content, color)
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user