news 2026/9/8 18:30:33

用Delphi快速构建AI交易Agent的完整实践指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
用Delphi快速构建AI交易Agent的完整实践指南

在实际的桌面与后端技术方案中,用 Delphi 快速构建一个 AI 交易 agent 并不是天方夜谭。这个项目标题里的核心关键词很明确:Delphi、AI、agent。目标是在秒级完成一个可运行的交易决策工作流:拉取行情、交给大模型分析、生成结构化交易信号、再转成订单指令并记录日志。本篇文章会从原理、环境、最小案例、关键代码、验证方式、排错链路和生产化建议几个角度展开,帮助你用 Object Pascal 快速搭出一个能跑、能查、能扩展的 AI trading agent 框架。

需要注意,文中所有示例都是技术研究用途,不构成任何投资建议。真实交易涉及资金安全、合规审查、市场风险和系统稳定性,示例只适合在模拟行情、回测环境和自己掌控的测试账号中运行。

1. 先理解 AI 交易 Agent 的组成,再谈 Delphi 为什么合适

1.1 AI 交易 Agent 是什么

AI 交易 agent 本质上是把“数据采集、策略决策、订单执行、结果记录”四个环节连成一条自动化链路。传统程序化交易靠人写死规则,例如“价格突破 20 日均线就买入”;AI 交易 agent 则把决策环节替换成大模型或者机器学习模型,让模型根据行情上下文输出动作。

这个动作不能是一段随意自然语言,必须是结构化的,例如:

{ "action": "buy", "symbol": "BTCUSDT", "quantity": 0.01, "confidence": 0.78, "reason": "short_term_momentum_and_volume_increase" }

agent 要做的事就是把上面的 JSON 从模型输出中解析出来,校验 legality、做风控,最后转成交易所或券商接口能识别的订单结构。所以它并不是“一个模型”,而是一个围绕模型构建的工程系统。

1.2 Delphi 在这个场景里的定位

Delphi 的强项是 RADE(快速应用开发),编译生成原生程序,不依赖虚拟机,启动速度快,适合做需要长时间运行的桌面行情监控程序、本地服务程序。相比 Python 这类解释型语言,Delphi 在内存占用、并发线程稳定性、GUI 与后台任务结合方面都有优势。

AI 部分并不需要在 Delphi 里训练模型。Delphi 通过 HTTP 调用大模型 API,例如 OpenAI 兼容接口、本地 Ollama 服务、或者国内模型厂商提供的接口,拿到返回结果后使用System.JSON解析。这样分工很清晰:

  • Delphi 负责工程:调度、网络、解析、风控、日志、界面。
  • AI 模型负责语义理解:根据行情文本输出交易动作。

这也是“Build your own AI trading agent in seconds”这类项目能成立的原因,因为不需要从零写模型推理,只要把工程链路串好就可以。

1.3 整体工作链路

一条最小可运行链路大概是这样:

定时器触发 -> 拉取最新行情 -> 组装行情上下文文本 -> 发送给 AI 模型 -> 获取模型返回 JSON -> 解析交易信号 -> 风控校验 -> 模拟下单 -> 写日志

在工程实现上,这个链路可以拆成下面几个模块:

模块职责关键技术点
行情客户端拉取最新价格、K 线、成交量REST/WebSocket、JSON 解析、缓存
提示词构造器把行情转成模型可读文本文本模板、上下文长度控制、字段白名单
AI 客户端调用大模型接口HTTP 客户端、超时、重试、API Key 管理
信号解析器解析模型返回的 JSON容错解析、枚举校验、数值范围校验
风控模块限制单笔金额、每日次数、symbol 范围硬编码规则、配置文件、禁止真实资金
调度器按频率触发任务,处理并发TThread、TTimer、队列、互斥锁
日志模块记录输入输出和异常本地文件、结构化 JSON、滚动日志

理解这条链路之后,才能知道哪些代码可以先写简化版,哪些代码从一开始就不能偷懒。

2. 环境准备与项目骨架

2.1 Delphi 版本与依赖

本文示例基于 Delphi 11 Alexandria 或 Delphi 12 Athens 编写,使用 Windows 平台下的控制台程序模式,方便专注于逻辑而非界面。实际项目如果要做行情监控界面,可以使用 FMX 或 VCL 窗体工程,后台逻辑不变。

核心依赖全部来自 Delphi 自带的 RTL 和网络库:

功能单元说明
HTTP 客户端System.Net.HttpClient提供TNetHTTPClient,支持同步和异步请求
JSON 解析System.JSON提供TJSONObjectTJSONArray等类型
多线程System.Classes使用TThread做后台轮询
定时触发System.Threading使用TTimerTTask
环境变量读取System.SysUtils通过GetEnvironmentVariable读取配置

不需要安装第三方组件。如果要用数据库保存历史记录,可以再引入 FireDAC 连接 SQLite;如果要做更复杂的行情推送,可以引入 WebSocket 客户端库,但最小案例中先用 HTTP 轮询。

2.2 创建项目

打开 Delphi 后,选择File -> New -> Other,在 Delphi Projects 下选择 Console Application。生成的项目默认代码结构如下:

program AIAgentDemo; {$APPTYPE CONSOLE} uses System.SysUtils; begin try // 程序入口 except on E: Exception do Writeln(E.ClassName, ': ', E.Message); end; end.

为了跑通一个最小 demo,不需要急着建窗体和界面。把逻辑写在一个模块里反而更容易排查问题。

2.3 目录结构建议

虽然是最小案例,也建议按模块划分文件,方便后续扩展:

AIAgentDemo/ ├── AIAgentDemo.dpr ├── MarketDataSource.pas ├── AIClient.pas ├── SignalParser.pas ├── RiskManager.pas ├── AgentWorker.pas └── config.ini

config.ini不是必须的,Demo 阶段可以用常量,但一旦准备接入真实 API,就必须把 API Key、模型名称、超时时间、交易标的等配置外置。不要把密钥写死在代码里。

注意:先确认你的 Delphi 版本中System.Net.HttpClient支持 TLS 1.2 或 1.3。部分老旧 Delphi 版本默认 TLS 版本较低,调用现代大模型 API 时会直接握手失败。

3. 实现一个可运行的 AI 交易 Agent

这一章会给出一个最小闭环实现。代码示例用于说明思路,真实项目要结合自己的包名、路径和模型接口调整。

3.1 封装行情数据源

先定义行情数据接口,这样后续可以方便替换成真实数据源:

unit MarketDataSource; interface type TMarketData = record Symbol: string; Price: Double; Volume: Double; Timestamp: TDateTime; end; IMarketDataSource = interface function GetLatestData(const ASymbol: string): TMarketData; end; TSimulatedMarketDataSource = class(TInterfacedObject, IMarketDataSource) private FBasePrice: Double; public constructor Create; function GetLatestData(const ASymbol: string): TMarketData; end; implementation constructor TSimulatedMarketDataSource.Create; begin FBasePrice := 100.0; end; function TSimulatedMarketDataSource.GetLatestData(const ASymbol: string): TMarketData; begin // 模拟行情:在基础价格上随机波动 Result.Symbol := ASymbol; Result.Price := FBasePrice + Random * 10 - 5; Result.Volume := 1000 + Random * 500; Result.Timestamp := Now; end; end.

模拟数据源在开发和测试阶段非常重要。它不依赖外部网络,可以稳定复现问题。真实环境下,你只需要再实现一个类,内部通过 HTTP 调用行情服务商接口,并返回TMarketData即可。

3.2 调用 AI 模型生成交易信号

AI 客户端统一负责 HTTP 调用。下面是一个通用结构,假设接口兼容 OpenAI Chat Completions 格式:

unit AIClient; interface uses System.Net.HttpClient, System.JSON; type TAIClient = class private FHttpClient: TNetHTTPClient; FBaseUrl: string; FApiKey: string; FModel: string; public constructor Create(const ABaseUrl, AApiKey, AModel: string); destructor Destroy; override; function ChatCompletion(const APrompt: string): string; end; implementation constructor TAIClient.Create(const ABaseUrl, AApiKey, AModel: string); begin FHttpClient := TNetHTTPClient.Create(nil); FBaseUrl := ABaseUrl; FApiKey := AApiKey; FModel := AModel; end; destructor TAIClient.Destroy; begin FHttpClient.Free; inherited; end; function TAIClient.ChatCompletion(const APrompt: string): string; var LRequestBody: TJSONObject; LMessages: TJSONArray; LUserMessage: TJSONObject; LResponse: string; LJson: TJSONObject; LChoices: TJSONArray; begin LRequestBody := TJSONObject.Create; try LRequestBody.AddPair('model', FModel); LMessages := TJSONArray.Create; LUserMessage := TJSONObject.Create; LUserMessage.AddPair('role', 'user'); LUserMessage.AddPair('content', APrompt); LMessages.AddElement(LUserMessage); LRequestBody.AddPair('messages', LMessages); // 建议限制输出格式 LRequestBody.AddPair('temperature', TJSONNumber.Create(0.2)); LRequestBody.AddPair('max_tokens', TJSONNumber.Create(300)); LResponse := FHttpClient.Post( FBaseUrl + '/chat/completions', LRequestBody.ToJSON, nil, procedure(ARequest: TNetHTTPRequest) begin ARequest.CustomHeaders['Authorization'] := 'Bearer ' + FApiKey; ARequest.CustomHeaders['Content-Type'] := 'application/json'; end ).ContentAsString(); // 解析 choices[0].message.content LJson := TJSONObject.ParseJSONValue(LResponse) as TJSONObject; try LChoices := LJson.GetValue('choices') as TJSONArray; Result := ((LChoices.Items[0] as TJSONObject).GetValue('message') as TJSONObject) .GetValue<string>('content'); finally LJson.Free; end; finally LRequestBody.Free; end; end; end.

这段代码里有几个关键点先说明:

  • TNetHTTPClient.Post支持传入请求体字符串,并能通过匿名过程改写请求头。
  • Authorization头是常见的大模型 API 鉴权方式,但不同厂商可能用api-keyx-api-key,接入前必须查看对方文档。
  • temperature设置得较低,例如0.2,可以减少模型输出随机性,让交易信号更稳定。
  • max_tokens用于限制返回长度,防止模型一次性输出很长的自然语言导致解析困难。

3.3 解析 AI 返回的交易信号

模型返回的内容应当是 JSON 字符串,但实际输出可能会包含多余的解释文字,例如“好的,根据当前行情,我建议买入:{...}”。因此解析器要做两层处理。

unit SignalParser; interface uses System.JSON; type TActionType = (actBuy, actSell, actHold); TSignal = record Action: TActionType; Symbol: string; Quantity: Double; Confidence: Double; Reason: string; end; TSignalParser = class public class function Parse(const AContent: string): TSignal; end; implementation class function TSignalParser.Parse(const AContent: string): TSignal; var LJson: TJSONObject; LActionStr: string; LActionValue: TJSONValue; LStartPos, LEndPos: Integer; LCleanContent: string; begin // 如果模型输出包含额外文字,先提取最外层花括号片段 LStartPos := Pos('{', AContent); LEndPos := LastDelimiter('}', AContent); if (LStartPos > 0) and (LEndPos > LStartPos) then LCleanContent := Copy(AContent, LStartPos, LEndPos - LStartPos + 1) else LCleanContent := AContent; LJson := TJSONObject.ParseJSONValue(LCleanContent) as TJSONObject; if LJson = nil then raise Exception.Create('AI 返回内容不是有效 JSON'); try LActionValue := LJson.GetValue('action'); if Assigned(LActionValue) then LActionStr := LActionValue.Value else LActionStr := 'hold'; // 动作白名单校验 if LActionStr = 'buy' then Result.Action := actBuy else if LActionStr = 'sell' then Result.Action := actSell else Result.Action := actHold; Result.Symbol := LJson.GetValue<string>('symbol'); Result.Quantity := LJson.GetValue<double>('quantity'); Result.Confidence := LJson.GetValue<double>('confidence'); Result.Reason := LJson.GetValue<string>('reason'); finally LJson.Free; end; end; end.

这里要注意,ParseJSONValue是无法保证模型永远输出合法 JSON 的。当模型返回内容为空、包含 Markdown 代码块、或者花括号嵌套不完整时,解析就会失败。所以生产代码中还要加入异常捕获,并考虑对模型输出做预处理,例如去掉可能的 ```json 标记。

3.4 组合调度线程与风控校验

把 AI 客户端和行情数据源、信号解析器组合进一个后台线程,实现周期轮询:

unit AgentWorker; interface uses System.Classes, System.SysUtils, MarketDataSource, AIClient, SignalParser, RiskManager; type TAgentWorker = class(TThread) private FDataSource: IMarketDataSource; FAIClient: TAIClient; FRiskManager: TRiskManager; FSymbol: string; FIntervalSec: Integer; protected procedure Execute; override; public constructor Create(const ASymbol: string; AIntervalSec: Integer); destructor Destroy; override; end; implementation constructor TAgentWorker.Create(const ASymbol: string; AIntervalSec: Integer); begin inherited Create(True); FSymbol := ASymbol; FIntervalSec := AIntervalSec; FDataSource := TSimulatedMarketDataSource.Create; FAIClient := TAIClient.Create('https://api.example.com/v1', 'YOUR_API_KEY', 'gpt-4o-mini'); FRiskManager := TRiskManager.Create; FreeOnTerminate := False; end; destructor TAgentWorker.Destroy; begin FAIClient.Free; FRiskManager.Free; inherited; end; procedure TAgentWorker.Execute; var LData: TMarketData; LPrompt: string; LContent: string; LSignal: TSignal; begin while not Terminated do begin try LData := FDataSource.GetLatestData(FSymbol); LPrompt := Format( '当前时间: %s, 标的价格: %.2f, 成交量: %.0f。' + '请判断交易动作,只返回 JSON: {"action":"buy/sell/hold", "symbol":"%s", ' + '"quantity": 数量, "confidence": 0到1之间, "reason": "简短原因"}', [DateTimeToStr(LData.Timestamp), LData.Price, LData.Volume, FSymbol] ); LContent := FAIClient.ChatCompletion(LPrompt); LSignal := TSignalParser.Parse(LContent); if FRiskManager.Validate(LSignal) then // 这里接入模拟交易所接口,Demo 阶段只打印 Writeln(Format('下单: %s %s 数量 %.4f, 置信度 %.2f, 原因 %s', [FSymbol, LSignal.Action.ToString, LSignal.Quantity, LSignal.Confidence, LSignal.Reason])) else Writeln('风控拦截: ' + FSymbol + ' 的信号未通过校验'); except on E: Exception do Writeln('任务异常: ', E.Message); end; Sleep(FIntervalSec * 1000); end; end; end.

风控模块的职责在 Demo 中可以先简化为检查confidence范围和quantity是否超过上限:

unit RiskManager; interface uses SignalParser; type TRiskManager = class public function Validate(const ASignal: TSignal): Boolean; end; implementation function TRiskManager.Validate(const ASignal: TSignal): Boolean; begin Result := True; // 超出置信度范围 if (ASignal.Confidence < 0) or (ASignal.Confidence > 1) then Exit(False); // 单次数量过大 if ASignal.Quantity > 100 then Exit(False); // 不允许做空类高频买卖 if ASignal.Action = actSell then Exit(False); end; end.

Demo 中的风控很简单,但“必须存在”这一点很重要。因为没有校验的 agent 一旦接入真实接口,模型输出的一个小错误就可能变成不可控订单。

4. 关键参数与执行流程详解

4.1 提示词设计决定了 agent 的可靠性上限

AI 交易 agent 的决策质量并不完全取决于模型,提示词在很大程度上决定了模型输出是否稳定。同一份行情数据,如果提示词写得模糊,模型可能返回一大段分析文字,而不是结构化 JSON;如果提示词约束明确,模型会更容易遵循输出格式。

建议提示词包含以下信息:

  • 当前时间和行情数据。
  • 要求返回的动作枚举:buysellhold
  • 要求返回 JSON 结构。
  • 要求confidence在 0 到 1 之间。
  • 要求reason简短,且不能出现非交易原因。

示例提示词:

你现在是一个只负责输出 JSON 的交易决策程序。 当前时间:2025-01-01 10:00:00 标的价格:102.35 成交量:1200 请根据短期趋势判断买入、卖出还是持有。 只返回 JSON,不要包含其他解释,格式如下: {"action":"buy","symbol":"BTCUSDT","quantity":0.01,"confidence":0.8,"reason":"...}

temperature参数也建议调低。在 OpenAI 兼容接口里,temperature越高,输出越随机。对交易决策,随机性过大会导致同一行情反复出现 buy/sell 抖动,因此建议设置在0.10.3之间。

max_tokens设置 200 到 500 就够用。交易信号字段不多,太长输出反而容易在 JSON 之后夹带多余文本。

4.2 网络参数:超时、重试与流量控制

调用外部 AI 接口时,最常见的错误不是逻辑错误,而是网络超时、限流、连接重置。相关参数必须在一开始就设计好:

参数推荐值说明
ConnectTimeout10 秒建立连接的最长等待时间
ReadTimeout30 秒等待响应体的最长等待时间
重试次数2 到 3 次只有在连接超时和 429/5xx 错误时才重试
重试退避1 秒、2 秒、4 秒指数退避,避免连续打满接口
单标的轮询间隔5 到 60 秒根据策略频率和数据源限制调整
同时并发标的数建议不超过 5 个每增加一个标的就是多一份 API 成本和风险

在 Delphi 中,TNetHTTPClient可以设置超时参数:

FHttpClient.ConnectionTimeout := 10000; // 毫秒 FHttpClient.ResponseTimeout := 30000; // 毫秒

重试逻辑不要放在 HTTP 客户端内部,建议封装成一个服务方法,捕获异常后按次数和退避策略重试。要特别注意:当前代码里TAIClient.ChatCompletion没有重试,生产版本需要加一层循环,同时对429 Too Many Requests5xx做不同处理。

4.3 JSON 解析的容错策略

大模型输出的 JSON 不像普通程序那样永远合法。常见问题有:

  • 输出内容被 Markdown 代码块包裹,例如```json ... ```
  • 输出中包含解释性文字。
  • JSON 字段名被模型改写成Action而不是action
  • 数值字段返回字符串"0.5"
  • 字段缺失。

所以在解析前先做以下预处理:

  1. 移除首尾空白。
  2. 如果包含代码块标记,去掉```json```
  3. 提取最外层{到最后一个}的内容。
  4. 解析失败时记录原始内容,方便后续调整提示词或增加 few-shot 示例。

一个更稳妥的做法是不仅解析TSignalParser.Parse,还要在解析失败时把原始返回写入日志文件。这样即使模型输出异常,你也知道是哪个环节出了问题。

5. 运行验证与结果分析

5.1 控制台运行流程

把主程序入口补全,创建后台线程并启动:

program AIAgentDemo; {$APPTYPE CONSOLE} uses System.SysUtils, AgentWorker in 'AgentWorker.pas', MarketDataSource in 'MarketDataSource.pas', AIClient in 'AIClient.pas', SignalParser in 'SignalParser.pas', RiskManager in 'RiskManager.pas'; var LWorker: TAgentWorker; begin try Randomize; Writeln('AI Trading Agent Demo 启动'); LWorker := TAgentWorker.Create('BTCUSDT', 10); LWorker.Start; Writeln('按回车键退出'); Readln; LWorker.Terminate; LWorker.WaitFor; LWorker.Free; except on E: Exception do Writeln(E.ClassName, ': ', E.Message); end; end.

运行后预期输出类似:

AI Trading Agent Demo 启动 按回车键退出 下单: BTCUSDT buy 数量 0.0100, 置信度 0.78, 原因 short_term_momentum 下单: BTCUSDT hold 数量 0.0000, 置信度 0.55, 原因 no_clear_signal

Demo 阶段没有真正连接交易所,所以收到类似输出说明链路已经跑通。

5.2 验证点不只是“能启动”

很多项目卡在最容易出错的地方:程序能启动,但每次调用都失败,或者偶尔成功偶尔失败。对 AI 交易 agent,建议至少检查以下验证点:

  • 行情数据是否成功拉取,字段是否正确。
  • AI 请求是否成功返回,返回状态码是 200 还是 429/500。
  • AI 返回内容是否可被解析成TSignal
  • 风控逻辑是否拦截了异常信号。
  • 日志文件中是否有完整的请求输入和输出。

一个快速的验证方法是写一个单独的测试入口,不启动线程,直接执行一次完整链路:

LData := FDataSource.GetLatestData('BTCUSDT'); LPrompt := BuildPrompt(LData); LContent := FAIClient.ChatCompletion(LPrompt); LSignal := TSignalParser.Parse(LContent); Writeln(Format('action=%s, symbol=%s, quantity=%.4f, confidence=%.2f, reason=%s', [LSignal.Action.ToString, LSignal.Symbol, LSignal.Quantity, LSignal.Confidence, LSignal.Reason]));

这样可以在不依赖界面和定时任务的情况下,快速定位问题在哪个模块。

5.3 日志与回放

交易 agent 的日志必须做到“可回放”。也就是说,一段时间后你能根据之前记录的行情和模型输出,重演当时的决策过程。推荐每次都记录以下信息:

  • 时间戳(精确到毫秒)。
  • 行情快照(价格、成交量、标的)。
  • 发送给模型的完整提示词。
  • 模型原始返回。
  • 解析后的信号。
  • 风控结果。
  • 是否下单。
  • 异常信息(如果有)。

日志可以使用 JSON Lines 格式,每行一个事件,方便用脚本分析。

{"ts":"2025-01-01 10:00:00.123","symbol":"BTCUSDT","price":102.35,"action":"buy","confidence":0.78,"accepted":true}

6. 常见问题排查

6.1 典型问题速查表

问题现象常见原因检查方式处理建议
调用 AI 接口报 TLS 错误Delphi 版本默认 TLS 版本过低检查 HTTP 客户端日志,确认握手失败位置升级 Delphi 版本,或使用 WinHTTP 组件并启用 TLS 1.2
AI 返回内容解析失败模型输出包含 Markdown 或解释文字打印模型原始返回内容增加代码块过滤、花括号提取、失败日志
请求返回 401 或 403API Key 错误,或者鉴权头格式不对检查请求头是否完整发送对照接口文档确认Authorizationapi-key格式
程序运行一段时间不再输出线程阻塞或异常被反复吞掉查看日志文件或添加异常详情增加日志记录,避免空 except
风控一直拦截信号模型输出的类型与预期不符打印解析后信号字段调整提示词,或者在解析层增加字段类型转换
请求被限流轮询频率过高,超过 API 限制查看 HTTP 状态码是否为 429增加间隔,使用指数退避重试
模拟行情波动太大,策略不稳定随机数波动范围不合理查看日志中的价格历史使用固定种子或更平滑的随机模型

6.2 一条实用的排查链路

如果运行出错,不要盯着异常栈看,而是按以下顺序排查:

  1. 先确认输入:行情源是否真的返回了数据,字段是否完整。
  2. 再确认提示词:发送给模型的内容是否包含合适上下文,是否有格式约束。
  3. 确认 AI 接口:请求是否成功,返回状态码,原始返回内容。
  4. 确认解析器:是否把原始内容转成了TSignal
  5. 确认风控:为什么拦截,是置信度不合格还是数量越界。
  6. 最后确认执行端:是否真的按TSignal生成了订单指令。

这个顺序的本质是从输入到输出逐层推进。每一层都留下日志,问题就会很快浮出水面。

注意:不要只为 Success 情况写日志,异常分支同样需要日志。很多时候,agent 不触发交易并不代表它正常工作,也可能是解析器一直失败,信号被静默吞掉。

7. 生产化前必须补齐的能力

7.1 学习环境与生产环境的差异

最小 Demo 能跑通,和生产可用之间还有很长的距离。下表列出主要差异:

维度学习/Demo 环境生产环境
行情源随机数模拟交易所官方 API、行情服务商、合规数据源
AI 模型任意兼容接口根据时延、成本、稳定性选择模型,考虑本地部署
订单执行打印日志交易所/券商接口,需要签名、私钥、订单确认
资金安全无真实资金需要止损、最大回撤、单日亏损限制
风控简单校验多层级风控、人工审批、交易熔断
日志控制台输出结构化日志、集中采集、审计
监控指标监控、告警、看板
版本管理单机源码CI/CD、回滚、灰度发布
合规不做要求遵守当地法律法规和交易所规则

Demo 阶段可以直接把 API Key 写在常量里,但一旦进入生产,不仅要把 Key 外置,还要考虑密钥泄露后的吊销机制。建议至少使用环境变量或加密配置文件。

7.2 风控是第一优先级

对于交易 agent,风控的价值高于所有策略优化。没有风控的 agent 就像没有刹车的车。生产环境至少要加入这些风控:

  • 单笔订单数量上限。
  • 单日订单次数上限。
  • 单日亏损熔断。
  • 最大持仓数量限制。
  • 只允许操作白名单内的 symbol。
  • 模拟盘和真实盘配置严格隔离。
  • 关键订单走人工二次确认。

风控参数不要写死在代码里,建议放在配置文件中,并限制只有特定角色可以修改。

7.3 上线前检查清单

下面是一份可复用的检查清单,适合在接入真实交易前逐项确认:

检查项是否完成备注
行情源接入是否通过官方接口验证是/否不要用抓包非正规接口
AI 调用是否加入超时与重试是/否避免长时间阻塞
AI 输出是否做了容错解析是/否记录原始内容
风控是否覆盖异常信号是/否包括数量、置信度、频次
模拟盘是否运行满 7 天是/否观察长周期稳定性
是否配置结构化日志是/否可回放决策过程
是否配置告警是/否进程崩溃、接口连续失败
是否确认符合平台规则是/否不同平台对自动交易有不同要求
是否有手动停止和应急回滚方案是/否一键断开下单接口
API Key 是否安全存储是/否不提交到版本库

7.4 下一步扩展方向

最小 agent 跑通后,可以从以下方向继续扩展:

  • 增加真实行情源:先用 REST 轮询,再逐步过渡到 WebSocket 推送,降低延迟。
  • 增加回测引擎:把历史行情和 AI 决策组合,观察策略在不同市场环境下的表现。
  • 多策略并行:让多个模型或者多个提示词策略同时分析,再通过投票机制决定最终动作。
  • 本地模型接入:使用 Ollama 等本地推理方案,可以减少外部接口的时延和网络依赖,也避免行情数据外传。
  • 订单管理模块:增加未成交订单查询、撤单、持仓管理,形成真正可用的交易闭环。

从工程角度看,AI 交易 agent 的核心难点并不在于“让 AI 判断涨跌”,而在于如何把模型输出放到一个稳定、可审计、有风控的工程系统里。Delphi 的价值恰好体现在这里:它能让开发者快速搭建后端调度、网络、解析和日志链路,同时保持原生程序的性能和稳定性。对于想研究 agent 架构的开发者来说,用 Delphi 做一个最小版本,是一条值得走完的实践路径。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/6 1:35:58

大规模MIMO信道估计的Matlab仿真:LS、OMP、MOMP与CoSaMP算法对比

这次我们来看一个大规模 MIMO 通信系统信道估计的 Matlab 性能仿真项目。它要解决的问题很直接&#xff1a;基站端通过导频信号恢复出无线信道矩阵&#xff0c;再用归一化均方误差&#xff08;NMSE&#xff09;等指标&#xff0c;对比 LS、OMP、MOMP 和 CoSaMP 这四种算法的估计…

作者头像 李华
网站建设 2026/9/8 4:36:32

GRACE卫星重力数据缺失月份插值:基于奇异谱分析(SSA)的MATLAB实现

简介&#xff1a;本资源是一套面向地球物理与水文研究者的GRACE卫星Mascon数据缺失月份插值工具包&#xff0c;聚焦于利用奇异谱分析&#xff08;SSA&#xff09;算法实现时间序列重建&#xff0c;适用于缺乏多源辅助数据、难以构建神经网络模型的中小尺度研究场景。压缩包共14…

作者头像 李华
网站建设 2026/9/8 5:24:49

Codex生成可编辑PPT和海报:锁死格式是关键

Codex 生成的 PPT 和海报到底能不能编辑&#xff1f;先说结论&#xff1a;能&#xff0c;但有一个前提——你在让它生成之前&#xff0c;就要把输出格式锁死在 .pptx、HTML 或 SVG 这类真实可编辑的文件结构上&#xff0c;而不是让它输出一张 PNG 图片。 很多人把 Codex 当成“…

作者头像 李华
网站建设 2026/9/7 22:01:37

上运动神经元与下运动神经元:解剖通路、损伤鉴别与临床定位诊断全解析

平时在神经内科轮转或备考时&#xff0c;运动系统这部分总是让人既熟悉又头疼。熟悉的是“上运动神经元瘫痪”和“下运动神经元瘫痪”天天都在提&#xff0c;头疼的是&#xff0c;一旦问到“上运动神经元到底包括哪些结构”“皮质脊髓束在哪个平面交叉”“为什么上运动神经元损…

作者头像 李华
网站建设 2026/9/7 22:53:14

奇安信运维工程师面试复盘:容器调用链与安全运维实战

2020年底我准备跳槽时&#xff0c;投了奇安信的运维工程师岗位。整个面试流程走下来&#xff0c;最大的感受是&#xff1a;安全公司的运维岗&#xff0c;不只是“修机器、看监控”这么简单&#xff0c;它对底层原理的追问深度、对安全基线的要求&#xff0c;都比普通互联网公司…

作者头像 李华
网站建设 2026/9/8 6:11:22

大模型选型实战:五款主流LLM对比评估方法、评测脚本与成本分析

最近帮团队做大模型技术选型&#xff0c;正好赶上 GPT-5.6、Gemini 3.6 Flash、Grok 4.5、Kimi K3、GLM-5.2 这些新版本密集上线。打开官方文档看一眼&#xff0c;各家都在强调自己“推理更强”“长文本更好”“速度更快”&#xff0c;但真要给业务选一个接入&#xff0c;光靠官…

作者头像 李华