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

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

核心节点说明:
让我们逐一深入剖析每个节点的设计逻辑。
定时触发器是整个工作流的启动器,类似于人体的心跳,周期性地驱动系统运转。
设计考量:
这是一个关键的状态管理节点,负责初始化、追踪和计算账户的各项核心指标。
// 初始化检查 - 首次运行时设置基准值
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()函数将收益实时反馈到系统图表这是整个系统的"眼睛",负责采集、处理和计算市场的各类数据与技术指标。
市场数据采集节点的功能可以分为三个层次:
层次1:合约列表解析与循环采集
// 解析合约列表
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 };
层次2:多周期K线数据获取与指标计算
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;
  
  // 返回结构化数据...
}
双时间框架策略:
这种多时间框架分析是专业量化交易的标准配置,相当于给AI同时提供"显微镜"和"望远镜"两种视角。
层次3:数据结构化输出
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(指数移动平均线)
2. MACD(平滑异同移动平均线)
3. RSI(相对强弱指标)
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的身份、规则和输出格式
核心内容:
特点: 像给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量化交易在商品期货市场的运作逻辑,并在自己的实践中做出更明智的决策。
完整源码与实盘记录:
风险提示: