用 Claude Code 和 Alpaca 构建 24/7 AI 交易 Agent
本文是使用 Claude Code Routines 与 Alpaca 免费模拟交易 API 构建自主交易 Agent 的分步教程。涵盖研究、决策、执行、记录循环与完整代码护栏,助你部署一个安全、可解释、可自动运行的交易 Agent,是 2026 年 Agent 化交易的实践指南。
VibeTrading Editorial Team
发布于 2026年7月3日 · 最后更新于 2026年7月17日
2026 年最热门的 AI 交易趋势之一是使用 Claude Code Routines 构建自主交易 Agent。与简单的基于规则的机器人不同,这些 Agent 可以研究市场状况、形成观点、决定是否交易、通过经纪商 API 执行,并记录其推理过程。
在本教程中,你将构建一个连接到 Alpaca 免费模拟交易 API 的 Claude Code 交易 Agent。到最后,你将拥有一个可以按计划运行并带有适当风险护栏的工作系统。
这个 Agent 做什么
Agent 在循环中运行:
- 研究 — 获取观察列表的价格、技术信号和最近头条。
- 决策 — Claude 分析数据并输出结构化的交易决策。
- 执行 — 如果决策通过信心和风险检查,通过 Alpaca 下单。
- 记录 — 写入结构化日志条目,解释每个决策。
先决条件
- 一个 Alpaca 账户(免费)
- 一个 Anthropic API key,可访问 Claude
- Node.js 20+ 或 Python 3.11+
- 安装并认证的 Claude Code
- 用于 24/7 运行的服务器或云实例(本地笔记本不行)
第 1 步:设置 Alpaca 连接
创建 alpaca.js,包含账户信息、报价和订单放置的辅助函数。
const ALPACA_BASE_URL = "https://paper-api.alpaca.markets";
const ALPACA_KEY = process.env.ALPACA_API_KEY;
const ALPACA_SECRET = process.env.ALPACA_API_SECRET;
async function alpacaFetch(path, options = {}) {
const res = await fetch(`${ALPACA_BASE_URL}${path}`, {
...options,
headers: {
"APCA-API-KEY-ID": ALPACA_KEY,
"APCA-API-SECRET-KEY": ALPACA_SECRET,
"Content-Type": "application/json",
...options.headers,
},
});
return res.json();
}
export async function getAccount() {
return alpacaFetch("/v2/account");
}
export async function getLatestQuote(symbol) {
const res = await fetch(
`https://data.alpaca.markets/v2/stocks/${symbol}/quotes/latest`,
{
headers: {
"APCA-API-KEY-ID": ALPACA_KEY,
"APCA-API-SECRET-KEY": ALPACA_SECRET,
},
}
);
return res.json();
}
export async function placeOrder(order) {
return alpacaFetch("/v2/orders", {
method: "POST",
body: JSON.stringify(order),
});
}第 2 步:构建研究模块
研究模块为 Claude 收集干净的数据。
// research.js
import { getAccount, getLatestQuote } from "./alpaca.js";
function rsi(prices, period = 14) {
const gains = [];
const losses = [];
for (let i = 1; i < prices.length; i++) {
const change = prices[i] - prices[i - 1];
gains.push(change > 0 ? change : 0);
losses.push(change < 0 ? Math.abs(change) : 0);
}
const avgGain = average(gains.slice(-period));
const avgLoss = average(losses.slice(-period));
if (avgLoss === 0) return 100;
const rs = avgGain / avgLoss;
return 100 - 100 / (1 + rs);
}
function average(arr) {
return arr.reduce((a, b) => a + b, 0) / arr.length;
}
export async function buildMarketData(watchlist) {
const account = await getAccount();
const tickers = await Promise.all(
watchlist.map(async (symbol) => {
const quote = await getLatestQuote(symbol);
return {
symbol,
price: quote.quote.ap,
bid: quote.quote.bp,
ask: quote.quote.ap,
};
})
);
return {
timestamp: new Date().toISOString(),
account: {
buying_power: account.buying_power,
portfolio_value: account.portfolio_value,
},
watchlist: tickers,
};
}本示例仅使用最新报价。对于真实策略,你需要历史 K 线来计算 RSI、移动平均线和其他指标。
第 3 步:创建 Claude 决策 Prompt
Prompt 是系统中最重要的部分。它告诉 Claude 如何作为一个有纪律的交易者行事。
# system_prompt.md
你是一个有纪律的算法交易 Agent。分析市场数据并决定是否下单。
规则:
- 单笔交易的风险 Never 超过投资组合价值的 2%。
- 只在美国常规市场时间(东部时间 9:30 AM - 4:00 PM)交易。
- 如果不确定,不要交易。默认动作是 NO_TRADE。
- 始终用 plain language 解释你的推理。
以这种 exact 格式输出有效 JSON:
{
"decision": "BUY" | "SELL" | "NO_TRADE",
"symbol": "TICKER or null",
"qty": number or null,
"reasoning": "2-3 sentence explanation",
"confidence": "LOW" | "MEDIUM" | "HIGH"
}第 4 步:执行决策
// execution.js
import { placeOrder } from "./alpaca.js";
export async function executeDecision(decision, account) {
if (decision.decision === "NO_TRADE") {
console.log("No trade:", decision.reasoning);
return null;
}
if (decision.confidence === "LOW") {
console.log("Skipping low-confidence signal:", decision.reasoning);
return null;
}
const portfolioValue = parseFloat(account.portfolio_value);
const maxRisk = portfolioValue * 0.02;
// 验证仓位大小
if (decision.qty * decision.estimatedPrice > maxRisk) {
throw new Error("Position exceeds 2% risk limit");
}
return placeOrder({
symbol: decision.symbol,
qty: decision.qty,
side: decision.decision.toLowerCase(),
type: "market",
time_in_force: "day",
});
}第 5 步:记录每个周期
日志将脚本变成学习系统。
// journal.js
import fs from "fs";
import path from "path";
export function writeJournalEntry({ marketData, decision, order, timestamp }) {
const entry = {
timestamp,
market_snapshot: marketData,
agent_decision: decision,
order_result: order || "NO_ORDER_PLACED",
};
const logPath = path.join("./journal", `${timestamp.split("T")[0]}.jsonl`);
fs.mkdirSync("./journal", { recursive: true });
fs.appendFileSync(logPath, JSON.stringify(entry) + "\n");
}第 6 步:接入 Claude Code Routine
创建 agent.js 作为主入口:
// agent.js
import { buildMarketData } from "./research.js";
import { getTradeDecision } from "./claude.js";
import { executeDecision } from "./execution.js";
import { writeJournalEntry } from "./journal.js";
const WATCHLIST = ["AAPL", "MSFT", "NVDA", "TSLA"];
async function runCycle() {
const timestamp = new Date().toISOString();
console.log(`Starting cycle: ${timestamp}`);
const marketData = await buildMarketData(WATCHLIST);
const decision = await getTradeDecision(marketData);
const order = await executeDecision(decision, marketData.account);
writeJournalEntry({ marketData, decision, order, timestamp });
console.log(`Cycle complete: ${decision.decision}`);
}
runCycle().catch(console.error);然后在你的 CLAUDE.md 中定义 routine:
## Routines
### trading-cycle
Schedule: every 15 minutes on weekdays between 9:30 AM and 4:15 PM ET
Command: node agent.js
Description: Run one full trading cycle第 7 步:添加护栏
在接触真实资本之前,添加这些安全检查:
- 每日亏损限制: 如果一天内下跌超过 3%,停止交易。
- 市场时间检查: 在交易前验证市场是否开放。
- 仓位大小验证: 在代码中而不仅仅是在 prompt 中执行 2% 规则。
- 紧急停止开关: 一个简单的文件标志或环境变量,可以立即停止 Agent。
始终从 Alpaca 模拟交易开始。在运行数周并审查每个日志条目之前,Never 部署真实资金。
部署选项
对于 24/7 运行,你有三个主要选择:
| 选项 | 成本 | 最适合 |
|---|---|---|
| Cloud VPS (Hetzner, DigitalOcean) | $5-10/月 | 完全控制,易于调试 |
| AWS Lambda + EventBridge | ~$1-5/月 | 低维护,按执行付费 |
| Docker on managed container service | 不一 | 团队,复杂工作负载 |
常见错误
- 过度拟合 prompt。 在一个市场机制有效的 prompt 可能在另一个机制中失败。
- 忽略费用。 滑点和佣金会侵蚀频繁交易的回报。
- 没有监控。 Agent 可能在悄无声息地亏钱数天。
- 太多上下文。 给 Claude 喂噪音数据会导致噪音决策。
下一步
现在你已经有了骨架,可以扩展它:
- 添加历史 K 线和技术指标。
- 通过新闻 API 整合新闻情绪。
- 构建一个仪表板来可视化日志条目。
- 在实盘部署任何策略之前运行回测。
相关阅读: Top AI Trading GitHub Projects | AI Trading for Beginners | How to Backtest Without Overfitting