Skip to content

04. 工具调用:读取交易和计算风险,不能靠模型心算

上一章练习参考答案

第一题,stopLoss 缺失时应该返回 NEEDS_MORE_CONTEXT。没有止损就无法计算这笔训练交易承担了多少风险,也无法评价执行是否合理。

第二题,plannedSetup 是交易前计划,比如“突破后等待回踩确认”。entryReason 是实际入场理由,比如“看到放量突破马上追多”。复盘最重要的地方,往往就是计划和实际理由不一致。

第三题,截图原图适合放对象存储,OCR 文字适合放可检索字段,人工备注适合放 screenshotNotes 或单独的 ReviewContext。不要把所有东西都塞进一个大字段。

新问题:模型算出来的风险,你敢信吗

现在我们有交易模型了。产品又会追问:

“报告里能不能给出盈亏比、最终 R 值?用户很关心自己到底是不是高亏低盈。”

当然可以。但这里不能让模型自己算。

如果入场 100,止损 95,止盈 110,模型说盈亏比是 1.5,你怎么发现?如果模型这次算对了,下次算错了,测试怎么写?如果同一笔交易刷新两次,结果不一样,用户会怎么想?

风险计算必须是工具,不是文案。

RiskCalculator

伴生工程把风险计算放在 RiskCalculator

java
@Component
public class RiskCalculator {

    public RiskMetrics calculate(TradeRecord trade) {
        if (!trade.hasRiskPlan()) {
            return new RiskMetrics(0, 0);
        }
        double risk = Math.abs(trade.entryPrice() - trade.stopLoss());
        double reward = Math.abs(trade.takeProfit() - trade.entryPrice());
        double realized = "long".equalsIgnoreCase(trade.direction())
                ? trade.exitPrice() - trade.entryPrice()
                : trade.entryPrice() - trade.exitPrice();
        return new RiskMetrics(round(reward / risk), round(realized / risk));
    }
}

T-1001 来说:

  • 入场价:100
  • 止损价:95
  • 止盈价:110
  • 出场价:96

所以风险是 5,计划收益是 10,盈亏比是 2.0。实际亏损是 4,也就是 -0.8R。

Tool 的工程意义

在 Spring AI Alibaba 里,工具调用的意义不是“让模型显得更厉害”。它的意义是把确定性能力交给代码。

你可以把工具理解成模型可以请求的业务函数:

java
public RiskMetrics calculateRisk(String tradeId) {
    TradeRecord trade = tradeRepository.findById(tradeId)
            .orElseThrow();
    return riskCalculator.calculate(trade);
}

这样模型负责解释:

“这笔交易计划盈亏比为 2.0,但最终为 -0.8R,说明交易没有按计划等到确认。”

代码负责保证:

“2.0 和 -0.8 是可重复、可测试、可审计的。”

本章效果

调用复盘接口后,重点看两个字段:

json
{
  "riskReward": 2.0,
  "realizedR": -0.8,
  "sections": {
    "risk": "计划盈亏比 2.0,最终约 -0.8R,说明风险先暴露,训练问题要回到入场确认。"
  }
}

这不是模型随口算的。它来自 RiskCalculator,所以你可以写单元测试保护它。

这一章真正解决了什么

本章解决的是“确定性计算不能交给生成式输出”。

AI 复盘系统里,越是关键数字,越应该来自工具。模型可以解释数字,但不能发明数字。

练习题

  1. 如果 risk = 0,也就是入场价等于止损价,应该怎么处理?
  2. 空头交易的 realizedR 计算为什么不能直接用 exitPrice - entryPrice
  3. 你会把风险计算结果存库,还是每次实时计算?分别适合什么场景?

Built with VitePress. Deployed on Cloudflare Pages.