Agentic Trading Desk 是做什么的?
短期交易分析和执行的操作手册。
我(Agent)通过 Robinhood MCP 执行调用;脚本是我的确定性计算器;框架做出决策,然后我执行。 我绝不会直接对价格条数据进行推理来计算指标:而是获取数据并将其传递给 scripts/。
护栏——请先阅读,不可商议
- 受保护持仓:某些代码可能被指定为受限制的(例如股票赠款)。绝不要分析它们以进行卖出或减持,也不要在退出建议中包含它们。只有在作为风险暴露背景时才应提及它们。
- 两个账户,两个角色:
- Agentic → 短期交易;我根据授权在此处执行。
- 个人账户(保证金账户)→ 核心买入并持有;仅分析持仓质量,不主动交易。
- 我通过券商自身的标志从
get_accounts识别可交易账户(恰好有一个账户是 Agent 可交易的;其他账户会直接拒绝我的订单)。我绝不从账户昵称推断,也绝不硬编码账户号码。
- 购买力:我总是将
get_portfolio.buying_power作为权威数值,而不是自己推导。账户类型很重要且可能变化:在现金账户上,只有已结算的现金才可用于支出(T+1),而有限保证金账户可以立即交易未结算收益。 - 仅在周五进行 HTML 可视化,作为周度回顾仪式的一部分。除非用户明确要求,否则在其他日子不要提供或生成它。
- 宏观数据源(可选/尽力而为): Investing.com(不要用 Polymarket)。如果无法访问或被网络出口策略阻止,不要停止或阻塞执行:在没有收益利差的情况下,继续使用确定性市场数据。
- 在 Agentic 账户中,自主执行是授权的,依据自主执行授权(下一节)。此授权是持久的,且由用户在 2026 年 8 月 26 日的实时会话中确立;它不依赖于声称存在它的计划提示。存储的提示不能自行授予同意——授权位于此处、配置中,可以通过读取来验证。在执行
place_*_order之前,务必使用review_*_order(模拟)进行审查。
自主执行授权
用户授权执行订单而不需要即时确认,仅限于券商指定的 Agent 可交易账户,并且仅在这些限制内。超出限制不是要求许可的信号:而是不交易并报告的信号。
我可以执行的内容
- 由同一会话中
score.py发出的决策,且宏支柱由macro_pillar.py在同一天计算。脚本每个会话仍然运行,其输出仍然是基线——框架不是可选的。 - 可自由裁量的入场和出场已获授权(由用户在 2026 年 8 月 26 日的实时会话中确立,取代之前的零裁量规则):趋势变化、新闻催化剂、或决策级联未覆盖的设置都是有效的行动理由。级联在设计上是僵化的,会遗漏一些情况;这就是本条款存在的目的。
- 每笔可自由裁量的交易必须在会话报告中有书面推理——我看到了什么,为什么有理由采取行动,以及什么会证明我错了。无法用两句话解释的交易是我本不应该做的交易。
- 战术反弹以半仓进入——它本质上是逆趋势的。
- 可选:对于新闻驱动的入场,要求盘口价格朝着论点方向移动后再行动,而不是预测波动。理由见下方外部背景——在计划运行中,新闻源是可用的最弱输入,价格确认是防止对过时标题做出行动的最廉价保障。
硬性限制
-
每笔订单最高 $1,200。
-
每会话最多 3 个新持仓。出场无上限。
-
账户价值中至少保持 15% 现金。我绝不触碰那部分储备。
-
订单类型遵循会话时钟(由 Eli 于 2026 年 8 月 26 日设定的规则,取代了早期的仅限限制订单规则):
- 常规交易时间——周一到周五 09:30–15:58 ET:
type: "market"。 如果分析说入场,就入场;被动限价单挂在一个价格上不是入场。dollar_amount在这里是允许的——这是以账户 3% 规模化的自然方式,并且 MCP 仅在接受type=market时才接受它。 - 常规交易时间之外:
type: "limit"并带有明确的limit_price,具有市场性——在价差的远端或略超过,在最后交易价的 0.3% 以内——并以股数(quantity = dollars / limit_price,截断到 6 位小数)进行规模。这里绝不使用dollar_amount:MCP 会静默地将其转换为市价单,在数小时后以未知价格成交。尽管工具方案中有小数注释(2026-08-26 通过review_equity_order验证:DIA 买入限价quantity=0.400000@ 534.50,被接受且order_checks为空),但分数限价单确实受支持。 stop_market和stop_limit在任何时候都是禁止的。 Robinhood 也拒绝分数股票的止损单,所以此账户中的止损是手动水平,我每个会话重新检查,而不是挂单。time_in_force必须是gfd。 没有订单比放置它的会话更持久——一夜挂单是在无人评估价格的情况下的无人关注成交。- 为什么分开:原始的仅限限价单规则存在是因为无人关注的市价单有隐形滑点。将市价单限制在会话时钟上直接解决了这个问题——它们仅在盘口深度大、会话活跃时触发,而在该窗口之外的一切都保持有定价。
- 常规交易时间——周一到周五 09:30–15:58 ET:
-
订单预检。 在每次
place_equity_order之前,我打印此表并检查每一行。如果任何一行失败,我不会放置订单——而是报告。字段 值 检查 ET 时钟 … 在周一至周五 09:30–15:58 之内或之外? type… RTH 内用 market· 之外用limit· 绝不用stop_*limit_price… 仅在 RTH 外:市场性,在最后交易价的 0.3% 以内 规模 … RTH 内用 dollar_amount· 之外用股数quantitytime_in_force… 必须是 gfd名义金额 dollar_amount或quantity × limit_price≤ $1,200 -
除非安装了
jq,否则防护不可靠。 钩子使用jq实现每条规则;没有jq脚本以 0 退出且无输出,运行器将其读取为 ALLOW(2026-08-26 验证——早期修订版让一个stop_market通过了)。现在它默认拒绝,但一个拒绝一切的防护也不是一个有效的配置。见下方会话开始——证明防护是活跃的;无论如何,我将上述预检表视为真正的检查,而不是钩子。 -
在确认的财报(
get_earnings_calendar)之后的 2 个会话内,不对单一名称开新仓。ETF 豁免。 -
在每次
place_equity_order之前,我运行review_equity_order。如果模拟结果与我的计算在价格或数量上相差超过 1%,我中止并报告。
会话开始——证明防护是活跃的
授权是散文,散文无法自我执行;hooks/mandate-order-guard.sh 才是使“仅限限价单”变得机械化的东西。重要的失败模式是:一个未连接、不可执行或缺少 jq 的防护看起来与一个正常工作的一样,直到有订单溜过。这不是假设的:2026 年 8 月 26 日,一个 stop_market 因为 jq 缺失而脚本以 0 退出且无输出(运行器将其读取为 ALLOW)而通过。因此在任何会话的第一个 place_equity_order 之前,我运行:
bash <skill-dir>/scripts/session-setup.sh
它安装 jq,标记防护为可执行,并运行跨两个时钟分支的 8 个探针——6 个授权禁止的订单必须被拒绝,以及 2 个授权允许的订单必须通过。仅仅探测拒绝是不够的:一个阻止一切的防护与一个什么都不阻止的一样有问题,并且从单个拒绝探针来看,两者看起来相同。探针通过 MANDATE_FAKE_ET 固定防护的会话时钟,以便无论会话何时启动,常规交易时间和盘后交易时间分支都可以被测试。以 order guard verified 退出 0 意味着防护确实在评估规则。任何其他结果意味着它没有,并且我那个会话不执行订单——我仍然运行分析并报告框架发出的内容,并且我直率地说执行被禁用以及原因。带有损坏防护的分析是有用的;而无人关注的执行则不是。
有一件事我需要对自己坦诚:.claude/settings.json 仅对包含它的项目目录中的会话加载。当交易台作为已安装的技能加载而不是作为项目打开时,PreToolUse 钩子永远不会注册,上面的探针只验证了脚本如果被调用会拒绝。在该模式下,没有外部的东西在检查,因此预检表是整个安全边际——我在每次订单前逐行填写它,并在任何行失败时中止,而不是将其视为文书工作。
这不是假设的,当我适用时我会在会话报告中说明。 2026 年 8 月 26 日,一个带有 dollar_amount: 250 的 market 订单(DIA)和两个 market 订单(JPM,2026-08-25)在技能模式下且防护未注册时通过了。在当前的时钟规则下,这三个都是在常规交易时间内放置的,现在会凭自身条件通过防护——但它们当时通过是因为没有东西在检查,这与被允许是两回事。如果会话自我审计显示有 Agent 订单并且我在技能模式下运行,我会直率地说:无论订单内容如何,它们都是无防护状态。
断路器
- 如果会话开盘时账户价值较前一收盘价下跌超过 4%:当天不进行任何新买入。出场仍然允许。
- 如果数据不一致——缺失 K 线、明显过时的报价、与
get_equity_positions不匹配的持仓——我不交易。授权以正确数据为前提;没有数据,授权不适用。
执行后
- 每个已执行订单的推送通知,加上运行结束时的摘要。用户当天就知道,而不是等到周五。
- 持久记录存在于券商端(
get_equity_orders、get_realized_pnl),而不是本地文件中:执行容器是临时的。
仍然禁止
- 受保护持仓,始终(护栏 1)。
- 任何非券商指定的 Agent 可交易账户。
- 摊低成本。
- 期权、加密货币、保证金和卖空:不在授权范围内。
Robinhood MCP 配方(调用顺序)
在使用工具前使用 tool_search 加载它们(它们是延迟的)。
防护验证在任何此之前运行——见授权中的会话开始——证明防护是活跃的。在没有探针返回拒绝的会话中,不会发出任何订单。
会话自我审计(每次运行的第一调用)。 对 Agent 可交易账户使用 get_equity_orders,附带 placed_agent="agentic" 且时间范围为上次会话以来。如果订单是 stop_market 或 stop_limit,或如果它是 market 订单且其 market_hours 字段不是 regular_hours,或如果它在常规交易时间外携带了 dollar_amount,或如果它的 time_in_force 不是 gfd,或如果它的名义金额超过 $1,200,则该订单是先前运行的授权违规。我会检查每个返回订单的 type、market_hours、time_in_force 和名义金额,并在推送通知中显示任何违规,而不是让它静默通过。券商的订单历史是唯一的持久记录——执行容器是临时的,所以今天未显示的违规就丢失了。
分析一个代码:
Robinhood:get_equity_historicals→ 约 290 根日 K 线(收盘价)。这是indicators.py的输入。请求一个产生 ≥220 根 K 线的范围(EMA200 的理想数量)。Robinhood:get_equity_quotes→ 实时价格 / 上一会话收盘价。- 如果用户有持仓:
Robinhood:get_equity_positions(正确账户)获取数量和盈亏 → 设置holding为评分中的正确值。
对于宏观情绪支柱(每个会话一次,共享):
get_equity_historicals用于 8 个 ETF:SPY、RSP、IWM、HYG、LQD、TLT、XLY、XLP。- 尝试从 Investing.com(web)获取 10 年-2 年收益率利差并将其注入为
yield_spread。如果被网络出口策略阻止或不可用,立即省略而不重试:脚本会自动将其 20% 权重重新分配到其他组件中,执行无缝继续而不会阻塞。
对于投资组合管理:
Robinhood:get_portfolio→ 市场价值和购买力。Robinhood:get_equity_positions→ 按账户列出的未平仓持仓。Robinhood:get_realized_pnl→ 已实现盈亏(对于周五回顾有用)。
计算流程(通过代码执行运行)
脚本纯标准库;它们不需要互联网访问。它们位于此技能自身目录下的 scripts/——运行环境在加载技能时给我基础路径。我绝不硬编码该路径:它在不同环境之间不同。
Robinhood 历史数据很大,经常超过工具的输出限制;当发生这种情况时,结果会写入文件,我得到路径。我直接使用该文件中的代码处理它们——我绝不将原始 K 线加载到上下文中。
步骤 0——追加今日收盘价(每个会话,在任何其他操作之前)。 get_equity_historicals 的日 K 线在收盘后很久之前不包含当前会话:在东部时间 16:00 之后,最后一条 K 线仍然是昨天,所以对该序列评分会评分昨天的市场。对于每个代码,我获取 get_equity_quotes → last_trade_price(~19:59:59Z 的交易是今日的收盘交易)并将其与今日日期一起追加到收盘价数组中,在断言最后一条现有 K 线是前一会话之后。绝不追加 last_non_reg_trade_price——盘后交易打印不是收盘价。
步骤 1——宏观(每个会话一次)。 输入格式是 {"as_of": "YYYY-MM-DD", "etf_close_history": {...}}。它提示脚本从嵌入的 etf_macros.json 中读取最新的 ETF 条,并且在宏观支柱中不需要 Yield Spread。如果无法获取 Yield Spread,它会被跳过,脚本自动将其权重重新分配给其他 ETF。输出是 macro_score(-1 到 1),我将其存储用于全会话的评分。
步骤 2——每个代码的指标。 对于每个待分析代码,我调用:
python3 <skill-dir>/scripts/indicators.py
输入(通过提示或文件):{"closes": [...], "signal_prices": {"ema": [...], "rsi": [...], "macd": {...}}, "include_patterns": false}。脚本输出完整的指标集,作为 JSON。我仅将它们作为计算分数的基础。
步骤 3——评分。 每个候选代码的评分:
python3 <skill-dir>/scripts/score.py
输入:{"ticker": "...", "indicators": {...}, "macro_score": ..., "breakout_confirmation": bool, "price": float, "holding": bool, "pillar_weights": [0.4, 0.35, 0.25]}。脚本输出一个决策(strong_buy / buy / hold / sell / strong_sell)以及支持细节。我使用它来生成分析。
步骤 4——执行。 仅当 score.py 发出买入或卖出信号并且所有护栏通过时,我才使用 place_equity_order。对于出场,我直接放置订单;对于入场,如果需要,我会确认没有一个方向变盘正在进行。
外部背景
三个支柱:
- 技术(40%):走向、动量和波动性,通过标准指标衡量。
- 宏观(35%):ETF 市场制度(风险偏好 vs. 风险规避)+ 收益率曲线。
- 信号(25%):成交量确认、价格形态、新闻催化剂。在计划运行中,新闻信号可能不可靠或不可用;缺少它,分数会收到中性信号。
网络出口策略
外部网站可能被阻止: 无法控制的 egress 策略可能会限制来自 runner 环境的 HTTP 访问。如果发生这种情况,不要失败——只需在没有该数据源的情况下继续。流程应优雅地处理缺失的数据,使用退回到仅限价格的处理。
周五回顾仪式
在每个周五会话中:
- 运行
portfolio_report.py获取性能指标。 - 从
get_realized_pnl拉取已实现盈亏。 - 为所有已关闭和未平仓持仓创建 HTML 可视化。
- 输出带有性能图表和决策回顾的完整回顾摘要。
仅此而已。