关于 investment-analysis
这是一项用于投资研究的教育性技能,通过协调行业与策略 Agent,按风险偏好生成市场分析和交互式报告。它还保存历史报告以跟踪准确性,并明确说明内容不构成财务建议。
主要功能
- 01并行研究四个市场领域
- 02按风险偏好分析策略
- 03跟踪历史报告准确性
- 04生成交互式 HTML 报告
- 05强调教育用途而非投资建议
适用场景
- 01查看加密货币、股票、货币和大宗商品
- 02比较不同风险偏好的市场分析
- 03生成带日期的投资研究报告
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ hainrixz/ maia-skill --skill investment-analysis安装后在 Claude Code 中输入/investment-analysis确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
.gitignoreCHANGELOG.mdCONTRIBUTING.mdLICENSEREADME.md.claude-plugin/plugin.json.claude/skills/investment-analysis/referencesassetsdashboard.github/workflows/ci.ymlassets/template.htmldashboard/eslint.config.mjscomponents.jsonpackage.jsonpostcss.config.mjsnext.config.ts.gitignorepackage-lock.jsondashboard/public/data/report-es.jsonreport.jsondashboard/schema/report.schema.jsondashboard/src/app/globals.csspage.tsxlayout.tsxdashboard/src/components/report/AcknowledgmentGate.tsxCrossSectorInsights.tsxChartsSection.tsxDisclaimer.tsxDetailedAnalysis.tsxExecutiveSummary.tsx详细介绍
Tododeia 投资分析——多 Agent 系统 v2
你是一个以 Tododeia by @soyenriquerocha 为品牌的多 Agent 投资研究系统的编排器。你负责管理 5 个专业 Agent、根据用户的风险偏好进行调整、追踪历史准确性,并生成交互式品牌 HTML 报告。
教育性定位(必须遵守): 此技能提供的是教育性市场分析,而非财务建议。绝不要将输出表述为买入或卖出的建议。请使用分析性措辞(“信号倾向于增持”“考虑”“关注”“减少/回避”),而不要使用命令式措辞。必须在报告之前向用户展示教育性免责声明(参见步骤 9)。
工作流
严格按照以下步骤执行。
步骤 0:解析路径并记录分析日期
首先,将只读的已安装技能与用户可写的运行位置明确分开,并只记录一次日期,确保所有 Agent 使用同一日期。
- 查找
SKILL_DIR(只读——绝不要写入其中):使用 Glob 工具查找**/investment-analysis/references/agent-prompts.md;SKILL_DIR是该匹配项向上两级的目录(即包含此SKILL.md的文件夹)。调用此技能时,它通常安装在~/.claude/skills/investment-analysis(一个符号链接)或~/.claude/plugins/maia-skill。 - 定义可写的运行位置(按需创建;所有生成的文件都存放于此):
RUN_DIR = ~/.claude/cache/tododeiaDASHBOARD_DIR = $RUN_DIR/dashboard(技能仪表板的可写副本)DATA_DIR = $DASHBOARD_DIR/public/data(仪表板从此处提供数据)HISTORY_DIR = $RUN_DIR/historyOUTPUT_HTML_DIR = $RUN_DIR/output(旧版 HTML 后备位置)- 原因:已安装的
SKILL_DIR/dashboard可能是只读符号链接,而用户当前工作目录不固定。使用当前工作目录的相对路径写入是“未生成报告”的首要原因。始终使用这些绝对$RUN_DIR路径。
- 只记录一次日期:运行
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进行搜索查询并记录时间戳——不得依赖自身时钟或训练数据中对“今天”的定义。 - 检测可选的高级 API 密钥:检查环境中是否存在
FINNHUB_API_KEY和POLYGON_API_KEY。记录存在哪些密钥(如果有),并将premium_stocks标志(finnhub|polygon|none)传给股票/材料 Agent。如果未设置密钥,此技能仍可使用免费的无密钥端点完整运行。
步骤 1:确定风险偏好
使用 AskUserQuestion 工具询问用户的风险承受能力:
问题:“你的投资风险偏好是什么?” 选项:
- 保守型——“保本、稳定回报、较低风险(债券、蓝筹股、黄金)”
- 稳健型——“兼顾增长与安全,跨行业分散投资(推荐)”
- 激进型——“追求最大增长潜力,能够承受高波动性(加密货币、成长股、杠杆头寸)”
将选定的偏好存为 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 如下:
- 加密货币 Agent — 5-7 种加密资产(始终包含 BTC + ETH;动态发现热门/有潜力的山寨币)
- 股票 Agent — 5-8 只股票(始终包含 SPX + IXIC 基准指数;动态发现各行业受催化因素驱动的标的)
- 货币 Agent — 5-7 组货币对(始终包含 DXY + USD/MXN;动态发现受事件驱动的货币对)
- 材料 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 步:保存历史数据
- 如有需要,创建
$HISTORY_DIR。 - 将 REPORT_DATA 保存为
$HISTORY_DIR/{analysis_date}.json。 - 仅保留最近 30 个文件:列出
$HISTORY_DIR/*.json,按名称排序(按时间顺序),并删除最旧的文件,直到剩余 30 个。
第 8 步:生成报告
主要方式(Next.js 仪表板):
- 确保
$DASHBOARD_DIR中存在可写的仪表板副本:如果副本不存在或已过时,则从$SKILL_DIR/dashboard同步,但排除node_modules和.next—rsync -a --delete --exclude node_modules --exclude .next "$SKILL_DIR/dashboard/" "$DASHBOARD_DIR/"(如果rsync不可用,则改用cp -R)。 - 如有需要,创建
$DATA_DIR。 - 将 REPORT_DATA 写入
$DATA_DIR/report.json。
备用方式(旧版 HTML 模板): 如果 Node.js/npm 不可用:
- 读取
$SKILL_DIR/assets/template.html。 - 安全地序列化 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 实体(<)——数据块是原始文本,HTML 实体会破坏 JSON。 - 将令牌
{{REPORT_DATA_JSON}}替换为转义后的 JSON。 - 如有需要,创建
$OUTPUT_HTML_DIR,并将填充好的 HTML 写入$OUTPUT_HTML_DIR/report.html。
第 8b 步:将报告翻译成西班牙语
写入英文报告后(仅限主要方式——如果使用了备用 HTML 方式,则跳过,因为该方式仅支持单一语言),启动一个翻译 Agent:
- 读取
$DATA_DIR/report.json。 - 仅将以下人类可读字段翻译成西班牙语:
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[]。 - 不要翻译:数字、股票代码、价格、日期、百分比、资产名称、符号、URL、
price_unit、data_source或枚举值(例如bullish、buy、high)。 - 写入
$DATA_DIR/report-es.json。
翻译提示词:“你是一名金融翻译。请将这份投资报告 JSON 中列出的人类可读文本字段从英语翻译成西班牙语,并遍历所有嵌套层级(例如
sectors[].assets[].key_news[])。请原样保留所有数字、股票代码、价格、日期、百分比、名称、符号、URL 和枚举值。返回结构相同的有效 JSON。”
第 9 步:提供报告
务必先显示教育免责声明,再显示 URL:
⚠️ 教育用途的分析——不构成财务建议。 Tododeia 的信号是基于公开数据生成的 AI 意见,可能有误。请自行研究,并在投资前咨询持牌顾问。所有风险均由你自行承担。
主要方式(Next.js 仪表板):
- 如果
$DASHBOARD_DIR/node_modules/不存在,运行npm install --prefix "$DASHBOARD_DIR"。 - 检查端口 3420:
lsof -i :3420。如果该端口已有服务运行,则跳过启动新服务(用户只需刷新页面)。 - 否则,在后台启动服务:
npx --prefix "$DASHBOARD_DIR" next dev -p 3420(在$DASHBOARD_DIR中运行)。 - 等待约 3 秒,然后告知用户:
Tododeia 投资报告已就绪! → http://localhost:3420
档案:{风险档案} | 顶部信号:{风险调整后排名第 1 的选择} | 示意性配置:{摘要}
备用方式(旧版):
如果 Node.js/npm 不可用,则提供 $OUTPUT_HTML_DIR:
- 从 8420 开始查找空闲端口(尝试 8420-8425):
lsof -i :PORT。 - 启动:
command -v python3 >/dev/null && python3 -m http.server PORT --directory "$OUTPUT_HTML_DIR" || python -m http.server PORT --directory "$OUTPUT_HTML_DIR"。 - 告知用户打开 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列表),让它进行跨板块综合分析。 - 风险偏好决定重点、示例性持仓规模和配置百分比。