我如何从零搭建一个个人 K 线回测系统:从 ETF 策略测试开始
本项目目前基本上除了复杂的交易规则和数据存储方面,基本上由纯血gpt5.5 和 claude 进行编写完成和测试(包括ui方面),本篇文章主要讲述的是我在构建系统时的思路展示和设计流程。
当前的 AI coding 强度已经到达了让个人开发者用几天的时间就可以做出一个非常优秀的项目。我们所需要做的只是提供设计思路和整合资源。
一、我手里的第一个开源项目:daily_stock_analysis
首先介绍我们的第一个开源项目:daily_stock_analysis。
GitHub 地址:
https://github.com/ZhuLinsen/daily_stock_analysis

该项目是一个 LLM 驱动的 A/H/美股智能分析器,核心能力包括多数据源行情、实时新闻、LLM 决策仪表盘、多渠道推送、股票分析、市场复盘、Agent 问股、历史报告、风险警报、持仓管理等。
该项目当前在github上目前有34k颗🌟
简单来说,daily_stock更像是一个 AI 投研助手。
它擅长回答的问题是:
- 这个标的现在怎么看?
- 市场发生了什么?
- 有哪些利好和利空?
- 风险在哪里?
- 当前市场情绪怎么样?
- 有没有值得关注的新闻或事件?
这些能力非常有价值,尤其是在新闻舆情、市场情绪、AI 报告、大盘复盘这些方向上。
但问题是:如果我们要做的是测试交易策略,它并不适合作为第一阶段的策略测试主引擎。
二、为什么我没有直接使用 LLM 系统自带能力?
虽然 daily_stock_analysis 本身已经有技术分析、策略系统、AI 报告和回测能力,但我还是决定单独写一个 K 线回测系统。
这不是因为开源项目不够强,而是因为我们的目标不一样。
LLM 情绪分析系统更适合做信息分析,它像一个投研助手,帮我理解市场发生了什么。但交易测试需要的是一个“规则实验室”。
从测试交易的角度来看,我更需要回答这些问题:
- 如果过去每次满足这个规则我都买,会发生什么?
- 这套规则亏损最大的时候有多难受?
- 胜率是多少?
- 收益率是多少?
- 有没有连续亏损?
- 是不是经常小赚大亏?
- 这个信号到底有没有价值?
这些问题需要的是明确规则、可重复计算、可量化统计、可拆解结果、可回测验证,而不是一段看起来很合理的 AI 分析报告。
比如,LLM 可能会输出:
当前市场情绪中性偏暖,短期可以关注,但仍需警惕成交量不足和上方压力。
这句话对理解市场有帮助,但它不是严格的交易规则。我无法直接回测“短期可以关注”这句话。
但我可以回测下面这种规则:
close > MA20 |
这就是我单独搭建 K 线回测系统的原因。
LLM 可以帮我解释市场,但回测需要的是明确规则。“可以关注”不能直接回测,“close > MA20 且 RSI < 70”可以回测。
三、两个系统的定位
首先在构建时,我们需要明确两个系统之间的定位,给它们做明确的分工。
系统 A:K 线回测系统
这是我们需要自己搭建的系统暂时命名为 personal-kline-assistant。
它的主要职责是:
- 日 K 数据管理
- MA / RSI / ATR / 成交量指标计算
- BUY_CANDIDATE / WATCH / AVOID 信号生成
- 策略回测
- ETF 策略验证
- 模拟交易记录
- 后续交易计划和风控
它更像是一个交易规则测试平台。
它回答的问题是:这套规则是否成立?
或者说:当前是否满足技术条件?这个信号过去表现如何?如果按这个规则交易,结果怎么样?
系统 B:LLM 情绪分析系统
也就是前面提到的 daily_stock_analysis。
它的主要职责是:
- 新闻舆情分析
- 大盘复盘
- 多市场信息聚合
- 基本面和资金面补充
- AI 报告生成
- 风险警报
- 多 Agent 观点汇总
- 事件告警
- 历史报告
- 通知推送
它更像是一个 AI 投研与风险分析工具。
它回答的问题是:外部环境是否支持这次技术信号?
或者说:有没有新闻风险?大盘情绪怎么样?资金面是否配合?政策面有没有不确定性?这个信号最可能失败在哪里?
四、我的整合思路:K 线是主信号,LLM 是过滤器
我最终采用的思路是:
K线系统先筛选机会 |
一句话总结:K 线是主信号,LLM 是过滤器,风控是最终闸门。
这条边界非常重要。
因为如果没有边界,两个系统可能会出现冲突:
K线系统:AVOID |
如果我是一个成熟交易员,也许可以综合判断。但假如我现在是金融新手,如果系统给我太多互相冲突的结论,我很容易只选择自己想听的那个。
所以我给自己设定了一个规则:没有 K 线 BUY_CANDIDATE,LLM 再看好也不交易。
这样LLM 的设定不再是用来制造更多交易理由的,而是用来帮我拦截风险。
五、完整链路设计
两个系统整合后的完整链路大概是这样:
- K 线系统导入 ETF 历史数据。
- K 线系统计算技术指标。
- K 线系统生成
BUY_CANDIDATE、WATCH、NEUTRAL、AVOID、SELL_WARNING。 - 只有
BUY_CANDIDATE进入 LLM 分析。 - LLM 系统分析大盘情绪、新闻舆情、资金面、风险事件、政策环境、板块强弱。
- LLM 输出情绪评分、风险评分、风险等级、市场状态、利好因素、利空因素、反方观点。
- 决策层合并结果,给出通过、降级、观察、禁止等动作。
- 系统生成模拟交易计划。
- 进入回测或模拟验证。
- 记录结果并复盘。
这个链路的重点不是让 AI 替我做交易,而是让每一次“可能交易”都经过明确的规则筛选和风险检查。
六、K 线信号优先级
我给 K 线系统的信号定义了一个简单优先级。
BUY_CANDIDATE:允许进入 LLM 审查。
WATCH:只观察,不调用深度 LLM。
NEUTRAL:不交易。
AVOID:不交易。
SELL_WARNING:如果已有持仓,进入风险复查。
这里最关键的是:只有 BUY_CANDIDATE 才进入下一步 LLM 分析。
这可以减少无效调用,也可以防止 AI 报告带偏交易纪律。
七、LLM 结果只作为风险过滤
LLM 输出的结果不直接决定买卖,而是作为风险过滤条件。
我计划让它返回这些字段:
- 情绪评分
sentimentScore:0 - 100 - 风险评分
riskScore:0 - 100 - 风险等级
riskLevel:LOW / MEDIUM / HIGH - 市场状态
marketState:STRONG / NEUTRAL / WEAK - 行动约束
actionConstraint:ALLOW / WATCH / REDUCE / BLOCK
然后再由 K 线系统生成最终决策。
一个简单决策表可以是:
| K 线信号 | LLM 风险 | 最终动作 |
|---|---|---|
| BUY_CANDIDATE | LOW | 允许模拟 |
| BUY_CANDIDATE | MEDIUM | 继续观察 / 降低仓位 |
| BUY_CANDIDATE | HIGH | 禁止 |
| WATCH | 任意 | 只观察 |
| NEUTRAL | 任意 | 不交易 |
| AVOID | 任意 | 不交易 |
这样做的好处是:K 线系统负责机会,LLM 系统负责风险,最终动作由规则生成。
八、两个系统之间如何通信
第一阶段我们采用:HTTP API 通信 + MySQL 落库缓存。的方式来实现双系统之间的通信。
整体数据流如下:
K线回测系统 |
也就是说,K 线系统负责发起请求,LLM 系统负责返回分析结果,K 线系统负责保存最终结果。
我不会让 LLM 系统直接写 K 线系统的数据库。
九、数据流设计
更具体一点,流程如下:
- K 线系统生成
technical_signal。 - 判断
signal_type是否为BUY_CANDIDATE。 - 如果不是
BUY_CANDIDATE,不调用 LLM。 - 如果是
BUY_CANDIDATE,K 线系统调用 LLM 系统 API。 - LLM 系统返回
sentimentScore、riskScore、riskLevel、summary、positiveFactors、negativeFactors、riskFactors、contrarianView、rawReport。 - K 线系统保存到
ai_analysis_snapshot。 - K 线系统根据规则生成
final_trade_decision。 - 前端展示最终结果。
这种设计的重点是保持两个系统的独立性。
daily_stock_analysis 继续作为一个外部 LLM 分析服务存在,负责完成它擅长的信息分析、新闻舆情、AI 报告和风险总结。
personal-kline-assistant 则作为我的主系统,负责保存数据、生成最终决策、展示结果和后续复盘。
十、为什么要保存 AI 分析结果
LLM 调用有成本,也可能比较慢。而且同一天同一个标的,没必要重复分析多次。
所以我们需要将 LLM 的分析结果保存到自己的 MySQL 里。
例如 ai_analysis_snapshot 表,用来保存:
symbol_codeanalysis_datesentiment_scorerisk_scorerisk_levelsummarypositive_factorsnegative_factorsrisk_factorscontrarian_viewraw_report
然后再生成最终决策,保存到 final_trade_decision 表中:
symbol_codedecision_datetechnical_signaltechnical_scoreai_sentiment_scoreai_risk_scoreai_risk_levelfinal_actionposition_policydecision_reasonreject_reason
这样前端就可以展示 K 线信号、技术评分、AI 情绪分、AI 风险分、最终动作、风险摘要和反方观点。
十二、当前阶段我更关心什么?
很多人看到这里可能会问:那这套流程跑下来,到底赚不赚钱?
我的回答可能会有点扫兴:当前阶段,我还不把“赚钱”作为第一目标。
因为如果我连下面这些问题都没有搞清楚,就直接谈盈利,其实不太现实:
- K 线信号是否合理?
BUY_CANDIDATE过去表现怎么样?AVOID是否真的帮我避开风险?- LLM 风险过滤有没有减少错误信号?
- 回测结果是否可复现?
- 模拟交易是否能按规则执行?
所以第一阶段的目标不是赚钱,而是验证规则能不能跑通、系统能不能稳定、信号能不能解释、风险能不能记录、结果能不能复盘。
这听起来没有“AI 自动赚钱”那么刺激,但我觉得它更真实。
十三、我的个人感受
在当下 AI 如此强大的时代,个人开发者确实会有一种感觉:好像 AI 已经能把很多代码都写完了,那个人开发者还能做什么?
但真正做项目之后,你就会发现问题的关键不在于“AI 能不能写代码”。
而关键在于:
- 你要解决什么问题?
- 你怎么定义边界?
- 你怎么设计流程?
- 你怎么验证结果?
- 你怎么长期使用它?
AI 可以帮我写代码,也可以帮我分析新闻。但它不能替我定义交易纪律。
所以我现在更愿意把这个项目看成一个长期实验:
- 用工程化方式理解交易。
- 用规则减少主观冲动。
- 用回测验证策略。
- 用 LLM 过滤风险。
- 用复盘持续修正。
十四、总结
这篇文章主要记录了我们在第一阶段的整体系统设计。
我们没有直接使用 LLM 系统自带的策略和回测能力,而是先搭建自己的 K 线回测系统,通过和 LLM 系统进行数据交互从而实现更加可控,更低的风险控制。
而 daily_stock_analysis 这类 LLM 情绪分析系统,我不会不用,而是把它放到第二层:
K线系统先产生候选信号 |
当前第一阶段,我只想跑通这条链路:
BUY_CANDIDATE |
总的来说,这不是一个“AI 自动炒股系统”。
更准确地说,它是一个个人交易辅助系统。
它的价值不是让我们立刻变成交易高手,而是让我们先做到:
- 少一点冲动。
- 多一点规则。
- 少一点幻想。
- 多一点验证。
这就是第一阶段最重要的事情。

交流与讨论
评论由 Valine / LeanCloud 提供,点击后连接第三方服务。