
最近,美国AI实验室nof1.ai发起了一场引人瞩目的实验——给六个顶级AI模型(Claude、DeepSeek、Gemini、GPT-5、Grok和通义千问)各发1万美金,让它们在真实的加密货币永续合约市场上较量。这不是模拟盘,而是真金白银的实战。实验结果令人意外:国产AI模型Qwen和DeepSeek遥遥领先,而GPT-5和Gemini双双翻车。这场竞赛最大的价值在于,团队将使用到的一些提示词、数据结构、决策流程全部开源,为我们提供了研究AI量化交易的绝佳范本。

本文将基于这个公开的架构,详细拆解一个AI量化交易工作流的每个节点、每个逻辑,帮助你理解AI是如何在真实市场中做出交易决策的。特别地,本文将这套架构适配到中国商品期货市场,让你可以在主流的期货合约上运行AI交易策略。
这个AI量化交易系统采用经典的”感知-决策-执行”三段式架构,整个工作流由多个核心节点组成:

核心节点说明: 1. 定时触发器 - 系统心跳,每3分钟触发一次 2. 参数重置 - 账户状态监控与性能统计 3. 市场数据获取 - 多维度数据获取与指标计算 4. 持仓数据获取 - 当前持仓状态追踪 5. 数据合并 - 整合账户与市场信息 6. AI智能体 - 核心决策引擎 7. 交易执行 - 信号解析与订单处理
让我们逐一深入剖析每个节点的设计逻辑。
定时触发器是整个工作流的启动器,类似于人体的心跳,周期性地驱动系统运转。
设计考量: - 3分钟周期:平衡数据新鲜度与API调用限制,可根据策略需要进行修改 - 固定间隔:确保策略执行的稳定性和可预测性
这是一个关键的状态管理节点,负责初始化、追踪和计算账户的各项核心指标。
// 初始化检查 - 首次运行时设置基准值
if (_G('invoketime') === null) {
_G('invoketime', 0);
_G('STARTTIME', Date.now());
const initAccount = exchange.GetAccount();
_G('initmoney', initAccount.Equity);
}
// 累计调用次数
const invoketime = _G('invoketime') + 1;
_G('invoketime', invoketime);
// 计算运行时长(分钟)
const duringtime = Math.floor((Date.now() - _G('STARTTIME')) / 60000);
// 获取当前账户信息
const currentAccount = exchange.GetAccount();
const currentAccountValue = currentAccount.Equity;
// 计算总收益率
const initMoney = _G('initmoney');
const totalReturnPercent = ((currentAccountValue - initMoney) / initMoney * 100).toFixed(2);
// 记录收益到系统日志
LogProfit(currentAccountValue - initMoney, "&")
// 返回5个核心指标
return [{
json: {
invoketime: invoketime,
duringtime: duringtime,
totalReturnPercent: totalReturnPercent + '%',
availableCash: currentAccount.Balance.toFixed(2),
currentAccountValue: currentAccountValue.toFixed(2)
}
}];
{
"invoketime": 42, // 系统调用次数
"duringtime": 126, // 运行时长(分钟)
"totalReturnPercent": "3.45%", // 总收益率
"availableCash": "10345.67", // 可用资金
"currentAccountValue": "10345.00" // 账户总价值
}
_G()函数实现跨周期的数据持久化initmoney作为收益计算的基准LogProfit()函数将收益实时反馈到系统图表这是整个系统的”眼睛”,负责采集、处理和计算市场的各类数据与技术指标。
市场数据采集节点的功能可以分为三个层次:
// 解析合约列表
const contracts = $vars.contractList ?
($vars.contractList.includes(',') ? $vars.contractList.split(',') : [$vars.contractList]) : [];
if (contracts.length === 0) {
return {};
}
// 为每个合约获取市场数据
const allContractsData = {};
for (let i = 0; i < contracts.length; i++) {
const contract = contracts[i];
try {
allContractsData[contract] = getMarketDataForContract(contract);
} catch (e) {
allContractsData[contract] = { error: e.toString() };
}
}
return { data: allContractsData };
function getMarketDataForContract(symbol) {
// 切换到对应合约
exchange.SetContractType(symbol);
// 获取3分钟和4小时K线数据
const kline3m = exchange.GetRecords(PERIOD_M3); // 3分钟周期
const kline4h = exchange.GetRecords(PERIOD_H4); // 4小时周期
// 数据有效性检查
if (!kline3m || kline3m.length < 50 || !kline4h || kline4h.length < 50) {
return { error: "K线数据不足" };
}
// 计算3分钟周期技术指标
const ema20_3m = TA.EMA(kline3m, 20); // 20周期指数移动平均
const macd_3m = TA.MACD(kline3m, 12, 26, 9); // MACD指标
const rsi7_3m = TA.RSI(kline3m, 7); // 7周期RSI
const rsi14_3m = TA.RSI(kline3m, 14); // 14周期RSI
// 计算4小时周期技术指标
const ema20_4h = TA.EMA(kline4h, 20); // 20周期EMA
const ema50_4h = TA.EMA(kline4h, 50); // 50周期EMA
const macd_4h = TA.MACD(kline4h, 12, 26, 9); // MACD指标
const rsi14_4h = TA.RSI(kline4h, 14); // 14周期RSI
const atr3_4h = TA.ATR(kline4h, 3); // 3周期ATR(波动率)
const atr14_4h = TA.ATR(kline4h, 14); // 14周期ATR
// 获取最新K线和最近10根K线
const latest3m = kline3m[kline3m.length - 1];
const latest4h = kline4h[kline4h.length - 1];
const recent10_3m = kline3m.slice(-10);
const recent10_4h = kline4h.slice(-10);
// 计算平均成交量
const volumes4h = recent10_4h.map(k => k.Volume);
const avgVolume4h = volumes4h.reduce((a, b) => a + b, 0) / volumes4h.length;
// 返回结构化数据...
}
双时间框架策略: - 3分钟短周期:捕捉短期波动,用于精确入场和出场时机 - 4小时长周期:判断大趋势方向,避免逆势交易
这种多时间框架分析是专业量化交易的标准配置,相当于给AI同时提供”显微镜”和”望远镜”两种视角。
return {
symbol: symbol,
current_price: latest3m.Close,
current_ema20: ema20_3m[ema20_3m.length - 1],
current_macd: macd_3m[2][macd_3m[2].length - 1],
current_rsi_7: rsi7_3m[rsi7_3m.length - 1],
intraday_3min: {
mid_prices: recent10_3m.map(k => k.Close),
ema_20_series: recent10_3m.map((k, i) => ema20_3m[ema20_3m.length - 10 + i]),
macd_series: recent10_3m.map((k, i) => macd_3m[2][macd_3m[2].length - 10 + i]),
rsi_7_series: recent10_3m.map((k, i) => rsi7_3m[rsi7_3m.length - 10 + i]),
rsi_14_series: recent10_3m.map((k, i) => rsi14_3m[rsi14_3m.length - 10 + i])
},
longer_term_4hour: {
ema_20: ema20_4h[ema20_4h.length - 1],
ema_50: ema50_4h[ema50_4h.length - 1],
atr_3: atr3_4h[atr3_4h.length - 1],
atr_14: atr14_4h[atr14_4h.length - 1],
current_volume: latest4h.Volume,
average_volume: avgVolume4h,
macd_series: recent10_4h.map((k, i) => macd_4h[2][macd_4h[2].length - 10 + i]),
rsi_14_series: recent10_4h.map((k, i) => rsi14_4h[rsi14_4h.length - 10 + i])
}
};
1. EMA(指数移动平均线) - 作用:判断趋势方向和支撑/阻力位 - 价格在EMA20上方 → 短期看涨 - EMA20上穿EMA50 → 黄金交叉,买入信号
2. MACD(平滑异同移动平均线) - 作用:判断动量和趋势转折 - MACD柱状图由负转正 → 动量转强 - DIF线上穿DEA线 → 金叉信号
3. RSI(相对强弱指标) - 作用:判断超买超卖 - RSI > 70 → 超买,可能回调 - RSI < 30 → 超卖,可能反弹
4. ATR(真实波动幅度) - 作用:衡量市场波动率,用于调整止损距离
持仓数据获取节点负责追踪每个合约的当前持仓状态,为AI提供完整的仓位信息。
function getAllPositions() {
// 获取当前账户权益
const curequity = exchange.GetAccount().Equity;
// 获取合约列表
const contracts = $vars.contractList ?
($vars.contractList.includes(',') ? $vars.contractList.split(',') : [$vars.contractList]) : [];
// 计算每个合约的风险金额 = 账户权益 / 合约数量
const risk_usd = contracts.length > 0 ? curequity / contracts.length * 0.05: 0;
// 获取所有实际持仓
const rawPositions = exchange.GetPositions();
// 创建持仓映射表 (合约代码 -> 持仓对象)
const positionMap = {};
if (rawPositions && rawPositions.length > 0) {
for (let pos of rawPositions) {
if (pos.Amount && Math.abs(pos.Amount) > 0) {
// 直接使用合约代码作为键
positionMap[pos.Symbol] = pos;
}
}
}
// 为每个合约创建position信息
const allPositions = [];
for (let i = 0; i < contracts.length; i++) {
const contract = contracts[i];
const pos = positionMap[contract];
if (pos) {
// 有持仓的情况 - 构建完整持仓信息
// 获取退出计划
const exitPlan = _G(`exit_plan_${contract}`) || {
profit_target: null,
stop_loss: null,
invalidation_condition: ""
};
allPositions.push({
symbol: contract,
quantity: Math.abs(pos.Amount), // 持仓数量
entry_price: pos.Price, // 入场价格
current_price: currentPrice, // 当前价格
unrealized_pnl: _N(pos.Profit, 2), // 未实现盈亏
exit_plan: exitPlan, // 退出计划
confidence: exitPlan?.confidence || null,
risk_usd: risk_usd, // 风险金额
sl_oid: null, // 止损订单ID
tp_oid: null, // 止盈订单ID
wait_for_fill: false,
entry_oid: pos.Info?.posId || -1,
notional_usd: _N(Math.abs(pos.Amount) * currentPrice, 2)
});
} else {
// 没有持仓的情况 - 所有字段设为null
allPositions.push({
symbol: contract,
quantity: null, // 关键字段:null表示无持仓
entry_price: null,
current_price: null,
unrealized_pnl: null,
exit_plan: null,
confidence: null,
risk_usd: risk_usd, // 仍然返回risk_usd用于开仓计算
sl_oid: null,
tp_oid: null,
wait_for_fill: false,
entry_oid: null,
notional_usd: null
});
}
}
return allPositions;
}
将市场数据、持仓数据整合成一个完整的数据包,为AI提供决策所需的全部上下文。
// 获取输入数据
const inputData = $input.all();
// 第一个输入是市场数据,第二个是持仓数据
const marketData = inputData[0].json.data;
const positions = inputData[1].json;
// 返回整理后的数据
return [{
json: {
marketData: marketData,
positions: positions
}
}];

AI智能体使用两种提示词协同工作:
系统提示词 (System Message)
↓ 定义"我是谁"
- 角色: 中国商品期货波段交易员
- 规则: 交易纪律、风险管理、持仓限制
- 格式: JSON输出结构要求
- 特点: 固定不变,只设置一次
用户提示词 (User Message)
↓ 提供"当前状况"
- 市场数据: 所有合约的价格、指标、K线
- 账户信息: 可用资金、总收益、运行时长
- 持仓状态: 每个合约的持仓详情
- 特点: 每3分钟动态更新
作用: 定义AI的身份、规则和输出格式
核心内容: 1. 角色定义: “您是中国商品期货波段交易员” 2. 交易约束: - 最多N个持仓 (N = 合约数量) - 风险控制 (单笔3-5%) - 必须设置止损/止盈/失效条件 3. 分析框架: - 4小时看趋势方向 - 3分钟找入场时机 4. 输出格式: JSON结构,包含signal/profit_target/stop_loss等字段
特点: 像给AI发的”工作手册”,一次设置,全程有效
作用: 提供实时数据,让AI基于当前市场做决策
内容结构:
`距离你开始交易已经过去了 ${duringtime} 分钟。
当前时间是 ${now},你已经被调用了 ${invoketime} 次。
**所有合约的当前市场状态**
${JSON.stringify(marketData)} // rb2505/hc2505的价格、指标
**以下是你的账户信息**
当前总收益率: ${totalReturnPercent}
可用现金: ${availableCash}
账户价值: ${currentAccountValue}
**当前实时持仓**
${JSON.stringify(positions)} // 每个合约的持仓详情
`
特点: 像给AI发的”实时报告”,每3分钟刷新一次
这样分离的好处: - 规则稳定,不会被数据干扰 - 数据实时,反映最新市场 - 易于调试和优化
解析AI输出的交易信号,转换为具体的交易指令并执行。
工作流程:
AI输出JSON → 解析信号 → 循环处理每个合约 → 执行对应操作
// 1. 解析AI输出
function parseAIOutput(output) {
// 清理markdown代码块标记,提取JSON
const cleaned = output.replace(/```[a-z]*\n?/gi, '').trim();
const start = cleaned.indexOf('{');
const end = cleaned.lastIndexOf('}');
return JSON.parse(cleaned.substring(start, end + 1));
}
const signals = parseAIOutput($input.first().json.output);
// 2. 循环处理每个合约的信号
for (const contract in signals) {
const args = signals[contract].trade_signal_args;
switch(args.signal) {
case 'entry':
executeEntry(contract, args); // 开仓
break;
case 'close':
executeClose(contract); // 平仓
break;
case 'hold':
monitorPosition(contract); // 监控持仓
break;
}
}
1. 开仓 (executeEntry) - 设置合约 - 获取当前价格 - 计算开仓手数 - 执行买入/卖出 - 保存退出计划
2. 平仓 (executeClose) - 取消挂单 - 查找持仓 - 市价平仓 - 清理退出计划
3. 监控 (monitorPosition) - 检查持仓 - 对比当前价与止盈/止损价 - 触发时自动平仓
SetContractType(contract)切换不同期货合约_G()持久化存储每个合约的止盈止损价格为方便了解AI交易运行逻辑,将AI交易信号分析和持仓状态进行可视化呈现。

这个节点把AI的”想法”变成真实的交易动作。
希望这篇详细的技术拆解能帮助你理解AI量化交易在商品期货市场的运作逻辑,并在自己的实践中做出更明智的决策。
完整源码与实盘记录: - 优宽量化平台:https://www.youquant.com - 策略地址:https://www.youquant.com/strategy/409645 - 可替换不同AI模型、调整提示词、选择交易合约
风险提示: - 本文仅供技术学习,不构成投资建议 - 期货交易风险极高,可能导致本金全部损失 - 务必在充分测试后再使用真实资金 - 建议先在模拟账户上运行至少1个月,优化提示词 - 期货交易具有高杠杆特性,请谨慎评估自身风险承受能力