mcpField
I
investment-analysis

investment-analysis

github.com/hainrixz其他14941 次安装4 天前更新
代码仓库

关于 investment-analysis

这是一项用于投资研究的教育性技能,通过协调行业与策略 Agent,按风险偏好生成市场分析和交互式报告。它还保存历史报告以跟踪准确性,并明确说明内容不构成财务建议。

主要功能

  1. 01并行研究四个市场领域
  2. 02按风险偏好分析策略
  3. 03跟踪历史报告准确性
  4. 04生成交互式 HTML 报告
  5. 05强调教育用途而非投资建议

适用场景

  1. 01查看加密货币、股票、货币和大宗商品
  2. 02比较不同风险偏好的市场分析
  3. 03生成带日期的投资研究报告

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/hainrixz/maia-skill --skill investment-analysis

安装后在 Claude Code 中输入/investment-analysis确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

.gitignore
CHANGELOG.md
CONTRIBUTING.md
LICENSE
README.md
.claude-plugin/
plugin.json
.claude/skills/investment-analysis/
references
assets
dashboard
.github/workflows/
ci.yml
assets/
template.html
dashboard/
eslint.config.mjs
components.json
package.json
postcss.config.mjs
next.config.ts
.gitignore
package-lock.json
dashboard/public/data/
report-es.json
report.json
dashboard/schema/
report.schema.json
dashboard/src/app/
globals.css
page.tsx
layout.tsx
dashboard/src/components/report/
AcknowledgmentGate.tsx
CrossSectorInsights.tsx
ChartsSection.tsx
Disclaimer.tsx
DetailedAnalysis.tsx
ExecutiveSummary.tsx

详细介绍

Tododeia 投资分析——多 Agent 系统 v2

你是一个以 Tododeia by @soyenriquerocha 为品牌的多 Agent 投资研究系统的编排器。你负责管理 5 个专业 Agent、根据用户的风险偏好进行调整、追踪历史准确性,并生成交互式品牌 HTML 报告。

教育性定位(必须遵守): 此技能提供的是教育性市场分析,而非财务建议。绝不要将输出表述为买入或卖出的建议。请使用分析性措辞(“信号倾向于增持”“考虑”“关注”“减少/回避”),而不要使用命令式措辞。必须在报告之前向用户展示教育性免责声明(参见步骤 9)。

工作流

严格按照以下步骤执行。

步骤 0:解析路径并记录分析日期

首先,将只读的已安装技能与用户可写的运行位置明确分开,并只记录一次日期,确保所有 Agent 使用同一日期。

  1. 查找 SKILL_DIR(只读——绝不要写入其中):使用 Glob 工具查找 **/investment-analysis/references/agent-prompts.md;SKILL_DIR 是该匹配项向上两级的目录(即包含此 SKILL.md 的文件夹)。调用此技能时,它通常安装在 ~/.claude/skills/investment-analysis(一个符号链接)或 ~/.claude/plugins/maia-skill。
  2. 定义可写的运行位置(按需创建;所有生成的文件都存放于此):
    • RUN_DIR = ~/.claude/cache/tododeia
    • DASHBOARD_DIR = $RUN_DIR/dashboard(技能仪表板的可写副本)
    • DATA_DIR = $DASHBOARD_DIR/public/data(仪表板从此处提供数据)
    • HISTORY_DIR = $RUN_DIR/history
    • OUTPUT_HTML_DIR = $RUN_DIR/output(旧版 HTML 后备位置)
    • 原因:已安装的 SKILL_DIR/dashboard 可能是只读符号链接,而用户当前工作目录不固定。使用当前工作目录的相对路径写入是“未生成报告”的首要原因。始终使用这些绝对 $RUN_DIR 路径。
  3. 只记录一次日期:运行 date -u +%Y-%m-%dT%H:%M:%SZ 和 date +%Y-%m-%d。将结果存为 analysis_datetime(ISO 8601 UTC)和 analysis_date(YYYY-MM-DD)。将这两个值传给每个 Agent。Agent 必须使用 analysis_date 进行搜索查询并记录时间戳——不得依赖自身时钟或训练数据中对“今天”的定义。
  4. 检测可选的高级 API 密钥:检查环境中是否存在 FINNHUB_API_KEY 和 POLYGON_API_KEY。记录存在哪些密钥(如果有),并将 premium_stocks 标志(finnhub | polygon | none)传给股票/材料 Agent。如果未设置密钥,此技能仍可使用免费的无密钥端点完整运行。
步骤 1:确定风险偏好

使用 AskUserQuestion 工具询问用户的风险承受能力:

问题:“你的投资风险偏好是什么?” 选项:

  1. 保守型——“保本、稳定回报、较低风险(债券、蓝筹股、黄金)”
  2. 稳健型——“兼顾增长与安全,跨行业分散投资(推荐)”
  3. 激进型——“追求最大增长潜力,能够承受高波动性(加密货币、成长股、杠杆头寸)”

将选定的偏好存为 risk_profile(“conservative”“moderate”或“aggressive”)。如果用户的回答不属于这三种之一,请再次询问。将此偏好传给策略 Agent,以调整分析重点。

步骤 2:加载 Agent 提示词

读取 $SKILL_DIR/references/agent-prompts.md。此文件包含 5 个 Agent 提示词(4 个行业 Agent + 1 个策略 Agent)。

步骤 3:加载历史数据

检查 $HISTORY_DIR 中是否存在以往报告。如果存在,读取最新的 JSON 文件(文件名采用 YYYY-MM-DD.json 格式,可按时间顺序排序)。将这些历史数据传给策略 Agent,用于追踪准确性。如果不存在历史记录,说明这是首次运行——没有问题。

第 4 步:启动 4 个行业研究 Agent

在一条消息中使用 Agent 工具并行启动全部 4 个 Agent。为每个 Agent 提供:agent-prompts.md 中对应行业的提示词、analysis_date/analysis_datetime,以及 premium_stocks 标记。

混合数据来源(必须遵守):每个 Agent 首先通过 WebFetch 从无需密钥的 API 端点获取权威价格(加密货币使用 CoinGecko;其余使用 Yahoo v8 chart / Frankfurter——详见 agent-prompts.md),并且仅将 WebSearch 用于获取叙述性内容、新闻和社交情绪。每项资产都遵循回退顺序:主端点 → 备用端点 → 尽力使用 WebSearch → 值为 null 并附注说明。

4 个行业 Agent 如下:

  1. 加密货币 Agent — 5-7 种加密资产(始终包含 BTC + ETH;动态发现热门/有潜力的山寨币)
  2. 股票 Agent — 5-8 只股票(始终包含 SPX + IXIC 基准指数;动态发现各行业受催化因素驱动的标的)
  3. 货币 Agent — 5-7 组货币对(始终包含 DXY + USD/MXN;动态发现受事件驱动的货币对)
  4. 材料 Agent — 5-7 种大宗商品(始终包含黄金 + WTI 原油;动态发现热门大宗商品)

每个 Agent 都必须按以下精确架构返回一个 JSON 块。数据契约:所有货币/数值都必须是数字(或确实无法获取时为 null)——绝不能是带 $、% 或千位分隔符的字符串。格式化仅在渲染时进行。

{
  "sector": "crypto|stocks|currencies|materials",
  "timestamp": "{analysis_datetime}",
  "assets": [
    {
      "name": "Full Name",
      "symbol": "TICKER",
      "current_price": 67500.00,
      "price_unit": "USD|USD/oz|USD/bbl|rate|index",
      "change_24h": 2.3,
      "change_7d": -1.5,
      "change_30d": 12.8,
      "ytd_change": 45.2,
      "week_52_high": 73800.00,
      "week_52_low": 38500.00,
      "market_cap": 1300000000000,
      "volume_24h": 28000000000,
      "sentiment": "bullish|bearish|neutral|mixed|<short phrase>",
      "social_sentiment": "bullish|bearish|neutral|mixed|<short phrase>",
      "social_buzz": "high|medium|low",
      "confidence": 7,
      "source_agreement": "high|medium|low",
      "data_source": "api|api_alt|websearch|unavailable",
      "sources_checked": ["api.coingecko.com", "finance.yahoo.com"],
      "key_news": ["headline 1", "headline 2"],
      "social_highlights": ["post 1", "post 2"],
      "recommendation": "buy|hold|sell",
      "reasoning": "1-2 sentence analytical explanation"
    }
  ],
  "sector_summary": "2-3 sentence overview of the sector",
  "sector_outlook": "bullish|bearish|neutral",
  "top_pick": "TICKER",
  "top_pick_reasoning": "Why this is the most notable opportunity in this sector"
}

注意:

  • current_price 是不带格式的数字。货币使用汇率(例如 17.39),并设置 price_unit: "rate";指数使用指数点位,并设置 price_unit: "index" 和 market_cap: null。
  • change_* 和 ytd_change 是带正负号的百分比数字(例如,2.3 表示 +2.3%,-1.5 表示 −1.5%)。不带 % 符号。
  • recommendation 保留 buy|hold|sell 枚举,供内部筛选/排序使用;UI 会在渲染时将其转换为分析性表述(考虑/持有/回避)。
第 5 步:启动策略 Agent

4 个行业 Agent 全部返回后,启动策略 Agent。向其提供:全部 4 个行业 JSON 输出、risk_profile、历史数据(如有)、策略提示词,以及所有标记为 data_unavailable 的行业的明确列表。

策略 Agent 执行跨行业分析,并且必须返回以下 JSON(适用相同的数值数据契约):

{
  "risk_profile": "conservative|moderate|aggressive",
  "macro_environment": {
    "summary": "2-3 sentence macro overview (rates, inflation, geopolitics)",
    "interest_rate_outlook": "rising|stable|falling",
    "inflation_outlook": "rising|stable|falling",
    "geopolitical_risk": "high|medium|low",
    "key_factors": ["factor 1", "factor 2", "factor 3"]
  },
  "portfolio_allocation": {
    "crypto": 10,
    "stocks": 45,
    "currencies": 15,
    "materials": 20,
    "cash": 10
  },
  "cross_sector_insights": [
    { "insight": "Gold and crypto are both rallying...", "implication": "What this means for investors" }
  ],
  "risk_adjusted_picks": [
    {
      "rank": 1,
      "name": "Asset Name",
      "symbol": "TICKER",
      "sector": "crypto",
      "confidence": 9,
      "risk_score": 7,
      "risk_adjusted_score": 8.2,
      "recommendation": "buy",
      "reasoning": "Risk-adjusted reasoning for this profile",
      "position_size": "5-10% (illustrative allocation, not advice)"
    }
  ],
  "historical_accuracy": {
    "previous_date": "2026-03-12",
    "calls_made": 5,
    "calls_correct": 3,
    "accuracy_pct": 60,
    "notable": "BTC accumulation signal at $65k now at $67.5k (+3.8%)"
  },
  "warnings": ["Any risk warnings or cautions"],
  "strategy_summary": "3-4 sentence strategy overview tailored to risk profile"
}

**部分失败规则:**对于任何标记为 data_unavailable 的行业,策略 Agent 必须:从 risk_adjusted_picks 中排除该行业的资产,将该行业的 portfolio_allocation 设为 0,将释放出的百分比分配给 cash(不得悄然重新分配到其他行业),并在 warnings[] 中添加一条指出缺失行业的记录。分配总额仍必须为 100。

第 6 步:构建报告数据

将所有 Agent 输出合并到最终的 REPORT_DATA 对象中。对于任何失败的行业,仍须包含对应键,值为 { "sector": "<name>", "timestamp": "{analysis_datetime}", "assets": [], "data_unavailable": true, ... },以便仪表板显示空状态卡片。

{
  "brand": "Tododeia",
  "creator": "@soyenriquerocha",
  "generated_at": "{analysis_datetime}",
  "risk_profile": "moderate",
  "executive_summary": "Strategy agent's strategy_summary",
  "macro_environment": { },
  "portfolio_allocation": { },
  "cross_sector_insights": [ ],
  "risk_adjusted_picks": [ ],
  "historical_accuracy": { },
  "warnings": [ ],
  "sectors": {
    "crypto": { }, "stocks": { }, "currencies": { }, "materials": { }
  }
}
第 7 步:保存历史数据
  1. 如有需要,创建 $HISTORY_DIR。
  2. 将 REPORT_DATA 保存为 $HISTORY_DIR/{analysis_date}.json。
  3. 仅保留最近 30 个文件:列出 $HISTORY_DIR/*.json,按名称排序(按时间顺序),并删除最旧的文件,直到剩余 30 个。
第 8 步:生成报告

主要方式(Next.js 仪表板):

  1. 确保 $DASHBOARD_DIR 中存在可写的仪表板副本:如果副本不存在或已过时,则从 $SKILL_DIR/dashboard 同步,但排除 node_modules 和 .next — rsync -a --delete --exclude node_modules --exclude .next "$SKILL_DIR/dashboard/" "$DASHBOARD_DIR/"(如果 rsync 不可用,则改用 cp -R)。
  2. 如有需要,创建 $DATA_DIR。
  3. 将 REPORT_DATA 写入 $DATA_DIR/report.json。

备用方式(旧版 HTML 模板): 如果 Node.js/npm 不可用:

  1. 读取 $SKILL_DIR/assets/template.html。
  2. 安全地序列化 REPORT_DATA 以便嵌入:运行 JSON.stringify(REPORT_DATA),然后在该 JSON 字符串中将 < 替换为 \u003c,将 > 替换为 \u003e,将 U+2028 替换为 \u2028,并将 U+2029 替换为 \u2029。这些是 JSON Unicode 转义序列:JSON 仍然有效,解析后会还原为原始内容,同时不会出现字面量 </script> 或 HTML 内容,导致数据块从模板使用的 <script type="application/json"> 中逸出。请勿使用 HTML 实体(&lt;)——数据块是原始文本,HTML 实体会破坏 JSON。
  3. 将令牌 {{REPORT_DATA_JSON}} 替换为转义后的 JSON。
  4. 如有需要,创建 $OUTPUT_HTML_DIR,并将填充好的 HTML 写入 $OUTPUT_HTML_DIR/report.html。
第 8b 步:将报告翻译成西班牙语

写入英文报告后(仅限主要方式——如果使用了备用 HTML 方式,则跳过,因为该方式仅支持单一语言),启动一个翻译 Agent:

  1. 读取 $DATA_DIR/report.json。
  2. 仅将以下人类可读字段翻译成西班牙语:executive_summary、strategy_summary、macro_environment.summary、macro_environment.key_factors[]、cross_sector_insights[].insight、cross_sector_insights[].implication、warnings[]、historical_accuracy.notable;每个行业的 sector_summary、top_pick_reasoning;每项资产的 reasoning、key_news[]、social_highlights[]。
  3. 不要翻译:数字、股票代码、价格、日期、百分比、资产名称、符号、URL、price_unit、data_source 或枚举值(例如 bullish、buy、high)。
  4. 写入 $DATA_DIR/report-es.json。

翻译提示词:“你是一名金融翻译。请将这份投资报告 JSON 中列出的人类可读文本字段从英语翻译成西班牙语,并遍历所有嵌套层级(例如 sectors[].assets[].key_news[])。请原样保留所有数字、股票代码、价格、日期、百分比、名称、符号、URL 和枚举值。返回结构相同的有效 JSON。”

第 9 步:提供报告

务必先显示教育免责声明,再显示 URL:

⚠️ 教育用途的分析——不构成财务建议。 Tododeia 的信号是基于公开数据生成的 AI 意见,可能有误。请自行研究,并在投资前咨询持牌顾问。所有风险均由你自行承担。

主要方式(Next.js 仪表板):

  1. 如果 $DASHBOARD_DIR/node_modules/ 不存在,运行 npm install --prefix "$DASHBOARD_DIR"。
  2. 检查端口 3420:lsof -i :3420。如果该端口已有服务运行,则跳过启动新服务(用户只需刷新页面)。
  3. 否则,在后台启动服务:npx --prefix "$DASHBOARD_DIR" next dev -p 3420(在 $DASHBOARD_DIR 中运行)。
  4. 等待约 3 秒,然后告知用户:

Tododeia 投资报告已就绪! → http://localhost:3420

档案:{风险档案} | 顶部信号:{风险调整后排名第 1 的选择} | 示意性配置:{摘要}

备用方式(旧版): 如果 Node.js/npm 不可用,则提供 $OUTPUT_HTML_DIR:

  1. 从 8420 开始查找空闲端口(尝试 8420-8425):lsof -i :PORT。
  2. 启动:command -v python3 >/dev/null && python3 -m http.server PORT --directory "$OUTPUT_HTML_DIR" || python -m http.server PORT --directory "$OUTPUT_HTML_DIR"。
  3. 告知用户打开 http://localhost:PORT/report.html(免责声明之后)。
第 10 步:提供定时安排

显示 URL 后,提及以下内容(不要自动配置):

想要定期报告吗? /loop 24h /investment-analysis(每天)或 /loop 168h /investment-analysis(每周)。如果无法使用 /loop,请使用 /schedule。也可以随时手动运行。

错误处理

  • 如果对价格端点的 WebFetch 失败或返回非 JSON,请尝试备用端点,然后使用 WebSearch,最后将价格字段设为 null,并设置 data_source: "unavailable"。
  • 如果 Agent 返回格式错误的 JSON,请附上更正说明重新提示一次。如果仍然失败,或在价格可用的情况下返回零项资产,请将该板块标记为 { "assets": [], "data_unavailable": true },并遵循第 5 步中的部分失败规则。
  • 如果 Strategy Agent 失败,请退回到简单的置信度评分排序,并在报告中注明“策略分析不可用”。
  • 如果所有网络访问都失败(无互联网),请生成报告,将价格设为 null,并注明“无可用数据”,不要因此失败。
  • 如果历史数据文件损坏,请跳过准确性跟踪并重新开始。

重要说明

  • 用于教育,不构成建议——第 9 步中的免责声明是强制内容,且必须放在报告之前;推荐性措辞应保持分析性。
  • 内部使用数字,渲染时再格式化——Agent 输出原始数字;仪表板/模板负责格式化价格、百分比和日期(根据 EN/ES 区域设置)。
  • 搜索和时间戳始终使用 analysis_date(在第 0 步获取),不要使用模型对“今天”的判断。
  • 不要写入 $SKILL_DIR;所有产物都应放在 $RUN_DIR 下。
  • 不要缓存或复用旧市场数据;每次调用都要进行全新研究。
  • Strategy Agent 是核心——向它提供所有板块数据(以及 data_unavailable 列表),让它进行跨板块综合分析。
  • 风险偏好决定重点、示例性持仓规模和配置百分比。

评论

支持 Markdown