Files
opencode-skill/skills/alphaear-reporter/scripts/schema/models.py
Kunthawat Greethong 58f9380ec4 Import 9 alphaear finance skills
- alphaear-deepear-lite: DeepEar Lite API integration
- alphaear-logic-visualizer: Draw.io XML finance diagrams
- alphaear-news: Real-time finance news (10+ sources)
- alphaear-predictor: Kronos time-series forecasting
- alphaear-reporter: Professional financial reports
- alphaear-search: Web search + local RAG
- alphaear-sentiment: FinBERT/LLM sentiment analysis
- alphaear-signal-tracker: Signal evolution tracking
- alphaear-stock: A-Share/HK/US stock data

Updates:
- All scripts updated to use universal .env path
- Added JINA_API_KEY, LLM_*, DEEPSEEK_API_KEY to .env.example
- Updated load_dotenv() to use ~/.config/opencode/.env
2026-03-27 10:11:37 +07:00

101 lines
6.1 KiB
Python

from pydantic import BaseModel, Field
from typing import List, Optional, Dict, Any
from datetime import datetime
class TransmissionNode(BaseModel):
node_name: str = Field(..., description="产业链节点名称")
impact_type: str = Field(..., description="利好/利空/中性")
logic: str = Field(..., description="该节点的传导逻辑")
class IntentAnalysis(BaseModel):
keywords: List[str] = Field(..., description="核心实体、事件或概念关键词")
search_queries: List[str] = Field(..., description="优化后的搜索引擎查询词")
is_specific_event: bool = Field(..., description="是否查询特定突发事件")
time_range: str = Field(..., description="时间范围 (recent/all/specific_date)")
intent_summary: str = Field(..., description="一句话意图描述")
class FilterResult(BaseModel):
"""LLM 筛选结果 - 快速判断是否有有效信号"""
has_valid_signals: bool = Field(..., description="列表中是否包含有效的金融信号")
selected_ids: List[int] = Field(default_factory=list, description="筛选出的有效信号 ID 列表")
themes: List[str] = Field(default_factory=list, description="信号涉及的主题")
reason: Optional[str] = Field(default=None, description="如果无有效信号,说明原因")
class InvestmentSignal(BaseModel):
# 核心元数据
signal_id: str = Field(default="unknown_sig", description="唯一信号 ID")
title: str = Field(..., description="信号标题")
summary: str = Field(default="暂无摘要分析", description="100 字核心观点快报")
reasoning: str = Field(default="", description="详细的推演逻辑和理由")
# 逻辑传导 (ISQ Key 1)
transmission_chain: List[TransmissionNode] = Field(default_factory=list, description="产业链传导逻辑链条")
# 信号质量 (ISQ Key 2) - 来自 isq_template.DEFAULT_ISQ_TEMPLATE
# 参考: src/schema/isq_template.py 的 DEFAULT_ISQ_TEMPLATE 定义
sentiment_score: float = Field(default=0.0, description="[ISQ] 情绪/走势 (-1.0=极度看空 ~ 0.0=中性 ~ 1.0=极度看多)")
confidence: float = Field(default=0.5, description="[ISQ] 确定性 (0.0=不可信 ~ 1.0=完全确定)")
intensity: int = Field(default=3, description="[ISQ] 强度/影响量级 (1=微弱 ~ 5=极强)")
expectation_gap: float = Field(default=0.5, description="[ISQ] 预期差/博弈空间 (0.0=充分定价 ~ 1.0=巨大预期差)")
timeliness: float = Field(default=0.8, description="[ISQ] 时效性 (0.0=长期 ~ 1.0=超短期)")
# 预测与博弈 (ISQ Key 3)
expected_horizon: str = Field(default="T+N", description="预期的反应时窗 (如: T+0, T+3, Long-term)")
price_in_status: str = Field(default="未知", description="市场预期消化程度 (未定价/部分定价/充分定价)")
# 关联实体
impact_tickers: List[Dict[str, Any]] = Field(default_factory=list, description="受影响的代码列表及其权重")
industry_tags: List[str] = Field(default_factory=list, description="关联行业标签")
# 溯源
sources: List[Dict[str, str]] = Field(default_factory=list, description="来源详情 (包含 title, url, source_name)")
class ResearchContext(BaseModel):
"""研究员搜集的背景信息结构"""
raw_signal: str = Field(..., description="原始信号内容")
tickers_found: List[Dict[str, Any]] = Field(default_factory=list, description="找到的相关标的及其基本面/股价信息")
industry_background: str = Field(..., description="行业背景及产业链现状")
latest_developments: List[str] = Field(default_factory=list, description="相关事件的最新进展")
key_risks: List[str] = Field(default_factory=list, description="潜在风险点")
search_results_summary: str = Field(..., description="搜索结果的综合摘要")
class ScanContext(BaseModel):
"""扫描员搜集的原始数据结构"""
hot_topics: List[str] = Field(..., description="当前市场热点话题")
news_summaries: List[Dict[str, Any]] = Field(..., description="关键新闻摘要列表")
market_data: Dict[str, Any] = Field(default_factory=dict, description="相关的市场行情数据")
sentiment_overview: str = Field(..., description="整体市场情绪概览")
raw_data_summary: str = Field(..., description="原始数据的综合摘要")
class SignalCluster(BaseModel):
theme_title: str = Field(..., description="主题名称")
signal_ids: List[int] = Field(..., description="包含的信号 ID 列表")
rationale: str = Field(..., description="聚类理由")
class ClusterContext(BaseModel):
"""信号聚类结果结构"""
clusters: List[SignalCluster] = Field(..., description="聚类列表")
class KLinePoint(BaseModel):
date: str = Field(..., description="日期")
open: float = Field(..., description="开盘价")
high: float = Field(..., description="最高价")
low: float = Field(..., description="最低价")
close: float = Field(..., description="收盘价")
volume: float = Field(..., description="成交量")
class ForecastResult(BaseModel):
ticker: str = Field(..., description="股票代码")
base_forecast: List[KLinePoint] = Field(default_factory=list, description="Kronos 模型原始预测")
adjusted_forecast: List[KLinePoint] = Field(default_factory=list, description="LLM 调整后的预测")
rationale: str = Field(default="", description="预测调整理由及逻辑说明")
timestamp: str = Field(default_factory=lambda: datetime.now().strftime("%Y-%m-%d %H:%M:%S"), description="生成时间")
class InvestmentReport(BaseModel):
overall_sentiment: str = Field(..., description="整体市场情绪评价")
market_entropy: float = Field(..., description="市场分歧度 (0-1, 1代表极高分歧)")
signals: List[InvestmentSignal] = Field(..., description="深度解析的投资信号列表")
forecasts: List[ForecastResult] = Field(default_factory=list, description="相关标的的预测结果")
timestamp: str = Field(..., description="报告生成时间")
meta_info: Optional[Dict[str, Any]] = Field(default_factory=dict, description="其他元数据")