十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Gekko 回测实战指南:用历史数据验证你的比特币交易策略

Gekko 回测实战指南:用历史数据验证你的比特币交易策略 金融科技后端【免费下载链接】gekkoA bitcoin trading bot written in node - https://gekko.wizb.it/项目地址https://gitcode.com/gh_mirrors/ge/gekko点击查看免费下载Gekko 是一个基于 Node.js 的开源比特币交易机器人回测Backtesting是它最核心的验证能力你可以在几十秒内把一套策略跑完过去数周甚至数月的行情从而在投入真金白银之前评估策略的历史表现。本文以 Gekko 官方的 docs/features/backtesting.md 为主线结合 core/markets/backtest.js、plugins/paperTrader/paperTrader.js、plugins/performanceAnalyzer/performanceAnalyzer.js 等源码实现讲透回测的原理、插件配置、数据准备、命令执行与结果解读帮助你真正跑通一次可靠的 Gekko 回测并正确看待它的局限。什么是 Gekko 回测回测是一种仿真simulation在数秒时间内模拟策略在一段较长历史行情例如过去 30 天上的运行过程。Gekko 会把历史 K 线一条条喂给策略策略产生买卖建议由模拟成交模块按价格和手续费撮合最终输出一份包含市场表现与策略表现的统计报告。回测的前提是本地已经存在行情数据。Gekko 不会在回测时去交易所拉取实时数据而是从本地数据库MongoDB、PostgreSQL 或 SQLite由config.adapter决定读取蜡烛图因此数据是否完整、连续直接决定回测结果的可靠性。回测在 Gekko 中是一个独立的运行模式mode。入口 gekko.js 会读取配置、确定模式后交给 core/pipeline.js 组装整条流水线当mode backtest时core/pipeline.js 会加载core/markets/backtest.js作为行情来源取代实时市场。回测前必须牢记的三件事原文档开篇就强调了三条重要提醒它们是理解回测结果的基石过去表现好不代表未来表现好。回测只能说明策略在历史上如何运作市场结构、波动率与参与者行为都会变化。警惕过拟合overfitting。不要反复调整策略参数直到回测利润很高就假设实盘也能同样赚钱——这种对着历史数据调参的做法很容易把噪声当成规律实盘表现往往远差于回测。回测模拟是有局限的。在大市场如 BTC/USD上这种差异通常不明显但在成交量极低的小市场上回测与实盘的差异可能非常大原因详见下文简化模拟与低流动性市场的局限。值得一提的是Gekko 在启动回测时还会打印一行警告见 core/markets/backtest.jsWARNING: BACKTESTING FEATURE NEEDS PROPER TESTING WARNING: ACT ON THESE NUMBERS AT YOUR OWN RISK!这行警告是源码写死的意味着官方也承认回测数字仅供研究参考行动后果自负。简化模拟Paper Trader 如何假装成交回测中的交易模拟由一个叫Paper Trader纸面交易者的模块完成源码在 plugins/paperTrader/paperTrader.js。它并不真正下单而是根据市场 K 线结合手续费fee、滑点slippage和价差spread来估算一次交易的实际执行成本。在实盘中价格并不是一个单一数字订单簿orderbook上同时存在买单bid和卖单ask你想买时成交在 ask 侧想卖时成交在 bid 侧两者之间的差距就是spread价差而当你下单量大到超过订单簿当前深度时成交价还会向不利方向移动这就是slippage滑点。从源码看Paper Trader 的成交模型非常直接plugins/paperTrader/paperTrader.js手续费根据feeUsing选择feeMaker或feeTaker并换算成成交比例fee 1 - rawFee / 100收到long买入建议时把全部currency按当前收盘价换成asset扣掉手续费后入账收到short卖出建议时把全部asset按当前价卖出换回currency每个 K 线收盘时刷新this.price candle.close并用它作为模拟成交价。其默认配置见 config/plugins/paperTrader.tomlfeeMaker 0.25 feeTaker 0.25 feeUsing maker slippage 0.05 [simulationBalance] asset 1 currency 100各参数含义参数默认值说明feeMaker0.25Maker 单手续费百分比你挂单吃单方时支付的手续费率feeTaker0.25Taker 单手续费百分比你立即吃掉订单簿深度时支付的手续费率feeUsingmaker回测使用哪档费率可选maker或takerslippage0.05滑点百分比用于估算大额订单相对当前价的偏差simulationBalance.asset1模拟起始资产如 BTC数量simulationBalance.currency100模拟起始计价币如 USD数量这套默认值在大多数大市场USD/BTC、BTC/ETH 等上表现良好但在成交量与流动性都很低的小市场上它就不够准确了详见后文。另外Paper Trader 还支持trailing stop移动止损触发器当策略给出的建议携带trigger且类型为trailingStop时它会创建止损实例并随价格上移触发后自动模拟卖出见 plugins/paperTrader/paperTrader.js。回测需要哪三个插件回测模式下你需要启用并正确配置以下三个插件官方文档见 docs/commandline/backtesting.mdTrading Advisor交易顾问—— 负责运行你的策略、产生买卖建议Paper Trader纸面交易者—— 负责模拟执行交易Performance Analyzer绩效分析器—— 负责统计策略表现。这三个插件的运行模式声明可以在 plugins.js 中查到tradingAdvisor、paperTrader、performanceAnalyzer都同时支持realtime与backtest两种模式见 plugins.js 与 plugins.js。反之candleWriter只支持realtime/importerplugins.js因此在回测模式下它会被自动禁用——命令行日志里就会出现The plugin SQLite Datastore does not support the mode backtest. It has been disabled.这样的提示。Trading Advisor 的典型配置见 config/plugins/tradingAdvisor.tomlenabled true candleSize 60 historySize 25 method MACD [talib] enabled false version 1.0.2candleSize策略使用的 K 线周期秒60表示 1 分钟线historySize策略预热期需要的 K 线数量用于初始化均线等指标method使用的策略名仓库strategies/下内置了 DEMA、MACD、RSI、CCI、PPO、TSI、UO、StochRSI、TMA 以及 talib/tulip 系列等十余种策略也可在 docs/strategies/creating_a_strategy.md 的指引下编写自定义策略[talib]是否使用 TA-Lib 指标库及其版本。Performance Analyzer 的配置config/plugins/performanceAnalyzer.toml则非常简单# Used to calculate sharpe ratio # yearly % of riskfree return for example # treasury bonds or bank interest. riskFreeReturn 2riskFreeReturn是无风险年化收益率如国债或银行利息的百分比它参与 Sharpe 比率的计算风险调整后的超额收益越高说明策略在承担同等风险时赚得越多。同时请务必配置好config.watch要观察哪个交易对、哪个交易所因为 Paper Trader 与 Performance Analyzer 都依赖watch.currency和watch.asset来确定模拟账户的币种结构见 plugins/paperTrader/paperTrader.js。历史数据从哪来回测必须依赖本地历史数据获取途径按易用程度排序让 Gekko 直接导入历史数据importer 模式但只有部分交易所支持批量拉取历史 K 线用实时模式攒数据通过 UI或命令行配合 SQLite 存储让 Gekko 在真实市场上运行把行情写入本地数据库。这种方式最通用但缺点是慢——想攒一周数据就得实跑一周。数据落地后存放在由config.adapter指定的数据库中config/adapters/ 下提供了 mongodb、postgresql、sqlite 三种适配器每个适配器目录都包含 reader/writer 等实现回测时由对应 adapter 的reader按时间范围读取蜡烛。配置回测时间范围回测的时间范围在backtest配置节中设置默认配置见 config/backtest.tomlbatchSize 50 # scan for available dateranges daterange scan # or specify it like so: # [daterange] # from 2015-01-01 # to 2016-01-01两种方式daterange scan推荐让 Gekko 扫描本地数据库自动找出实际可用的连续时间范围。扫描逻辑实现在 core/tools/dateRangeScanner.js它会检查candles表是否连续按 60 分钟一批、每批最多允许缺失 3 分钟见 core/tools/dateRangeScanner.js然后返回所有连续可用区间的{from, to}列表。如果数据有缺口日志会提示The database has N candles missing, Figuring out which ones...直接指定把backtest.daterange设为一个对象包含from与to两个键值为可被 moment 解析的日期字符串如2015-01-01。运行时 core/markets/backtest.js 会做严格校验to from时报This daterange does not make sense.日期非法时报invalid from/invalid to。当模式为回测且daterange scan时core/pipeline.js 会先调用prepareDateRange完成扫描再启动市场。运行回测配置就绪后用命令行启动回测node gekko --config config.js --backtest这里--backtest是 Gekko 的模式参数。当前仓库的默认配置是 TOML 格式如 config/backtest.toml如果你沿用仓库自带的 TOML 配置则使用node gekko --config 你的配置文件即可命令行工作流与插件配置的完整说明见 docs/commandline/backtesting.md 与 docs/commandline/plugins.md。一次典型的回测启动日志如下来自官方文档2016-06-11 08:53:20 (INFO): Gekko v0.2.1 started 2016-06-11 08:53:20 (INFO): Im gonna make you rich, Bud Fox. 2016-06-11 08:53:20 (INFO): Setting up Gekko in backtest mode 2016-06-11 08:53:20 (INFO): 2016-06-11 08:53:20 (WARN): The plugin SQLite Datastore does not support the mode backtest. It has been disabled. 2016-06-11 08:53:20 (INFO): Setting up: 2016-06-11 08:53:20 (INFO): Trading Advisor 2016-06-11 08:53:20 (INFO): Calculate trading advice 2016-06-11 08:53:20 (INFO): Using the trading method: DEMA 2016-06-11 08:53:20 (INFO): 2016-06-11 08:53:20 (INFO): Setting up: 2016-06-11 08:53:20 (INFO): Profit Simulator 2016-06-11 08:53:20 (INFO): Paper trader that logs fake profits. 2016-06-11 08:53:20 (INFO):回测运行期间Paper Trader 会逐条打印模拟成交记录2016-06-11 08:58:20 (INFO): Profit simulator got advice to long 2016-05-30 04:37:00, buying 1.1880062 BTC 2016-06-11 08:58:21 (INFO): Profit simulator got advice to short 2016-05-31 21:37:00, selling 1.1880062 BTC 2016-06-11 08:58:21 (INFO): Profit simulator got advice to long 2016-06-01 12:37:00, buying 1.14506098 BTC ...回测执行原理按批流式读取历史从源码结构看回测市场 core/markets/backtest.js 是一个 Node.js 可读流Readable它以batch批次为单位从数据库 reader 拉取蜡烛每次拉取config.backtest.batchSize分钟默认 50 分钟的 K 线逐根 K 线推入流中由 core/pipeline.js 分发给 Trading Advisor、Paper Trader 等下游消费者迭代器到达to边界后结束并推送{isFinished: true}见 core/markets/backtest.js。如果某一批次查询到的蜡烛数少于batchSize且尚未到达结束时间说明数据库存在数据缺口Gekko 会打印警告Simulation based on incomplete market data (N missing between ... and ...).见 core/markets/backtest.js如果某个区间完全没有蜡烛则会直接报错退出Query returned no candles (do you have local data for the specified range?)。解读回测结果PROFIT REPORT 与性能指标回测结束后Performance Analyzer 会输出一份盈亏报告。以下是一份完整的 PROFIT REPORT 示例来自官方文档2016-06-11 08:53:22 (INFO): (PROFIT REPORT) start time: 2016-05-29 23:34:00 2016-06-11 08:53:22 (INFO): (PROFIT REPORT) end time: 2016-06-10 08:56:00 2016-06-11 08:53:22 (INFO): (PROFIT REPORT) timespan: 11 days days 2016-06-11 08:53:22 (INFO): (PROFIT REPORT) start price: 516.19 2016-06-11 08:53:22 (INFO): (PROFIT REPORT) end price: 578.97 2016-06-11 08:53:22 (INFO): (PROFIT REPORT) Buy and Hold profit: 12.162189999999995% 2016-06-11 08:53:22 (INFO): (PROFIT REPORT) amount of trades: 10 2016-06-11 08:53:22 (INFO): (PROFIT REPORT) original simulated balance: 616.19000 USD 2016-06-11 08:53:22 (INFO): (PROFIT REPORT) current simulated balance: 602.59867 USD 2016-06-11 08:53:22 (INFO): (PROFIT REPORT) simulated profit: -13.59133 USD (-2.20570%) 2016-06-11 08:53:22 (INFO): (PROFIT REPORT) simulated yearly profit: -435.53244 USD (-70.68152%)可以看到虽然这段时间市场本身上涨了 12.16%Buy and Hold但 DEMA 策略在这个区间反而亏了 2.21%——这正是回测最有价值的地方区分策略收益与市场 Beta 收益。除了这些基础字段Performance Analyzer 在 plugins/performanceAnalyzer/performanceAnalyzer.js 中还会计算一组更专业的指标供 UI 或导出使用指标计算方式含义profit/relativeProfit期末余额 − 期初余额 / 相对百分比策略绝对与相对盈亏yearlyProfit/relativeYearlyProfit按时间跨度年化年化盈亏便于跨回测比较marketendPrice / startPrice − 100%同期市场本身涨跌幅alpharelativeProfit − market跑赢/跑输大盘的超额收益exposure持仓时间 / 总时间资金处于持仓状态的时间占比sharpe(relativeYearlyProfit − riskFreeReturn) / stdev(roundtrip 收益) / √(trades/(trades−2))风险调整后收益需要配置performanceAnalyzer.riskFreeReturndownside亏损 roundtrip 收益的 25 分位 × 调整因子下行风险亏损端尾部ratioRoundTrips盈利 roundtrip 数 / 总 roundtrip 数 × 100%一轮完整买入→卖出周期的胜率其中roundtrip完整往返交易指一次买入后卖出的完整闭环Performance Analyzer 在收到tradeCompleted事件时记录买卖配对、持续时间与盈亏见 plugins/performanceAnalyzer/performanceAnalyzer.js并以此计算胜率、Sharpe 与下行风险。如果回测期间没有任何交易finalize会直接跳过报告输出plugins/performanceAnalyzer/performanceAnalyzer.js。低流动性市场的局限原文档特别用一整节警告回测模拟在低成交量、低流动性的小市场上会明显失真。请看下面这种回测结果图价格频繁出现上下尖刺。这些尖刺并不是真实的行情波动而是订单簿两侧交替成交造成的假象——先有人吃掉了一个 bid价格被砸下去又有人吃掉了一个 ask价格被拉上来。尖刺上下跳动的幅度正是订单簿上 ask 与 bid 之间的spread价差。在这种市场里模拟统计会非常不准确除非你主动配置更高的slippage来把价差因素纳入成本。这是 Gekko 回测模型固有的一项局限模拟成交使用 K 线收盘价candle.close作为近似成交价见 plugins/paperTrader/paperTrader.js无法精确反映你在订单簿上的真实成交位置低流动性市场里一次模拟成交可能跨越多个真实价位价差与滑点造成的执行成本偏差会被成倍放大相反在大而深的市场上如 BTC/USD收盘价近似成交价的误差相对可接受。因此对低流动性交易对做回测时建议适当调高 config/plugins/paperTrader.toml 中的slippage与手续费并把回测结论当作下限而非预期同时务必对参数做敏感性分析而不是单点过拟合。小结Gekko 的回测是一套完整、自洽的本地仿真流程从 config/backtest.toml 定义时间范围到 core/markets/backtest.js 按批流式回放历史 K 线再到 Paper Trader 模拟带手续费的成交、Performance Analyzer 汇总盈亏与风险指标最终在命令行或 UI 中呈现一份可比的绩效报告。用一句话概括正确的回测姿势数据要完整连续、范围要用scan扫描确认、参数不要过拟合、小市场要调高滑点并降低对绝对收益的预期。把回测当作策略研究的显微镜而不是收益的预言机它才能真正为你的实盘决策保驾护航。想进一步深入可以阅读 docs/commandline/backtesting.md命令行完整流程、docs/commandline/plugins.md插件配置与 docs/strategies/creating_a_strategy.md如何编写你自己的策略。赞分享金融科技后端【免费下载链接】gekkoA bitcoin trading bot written in node - https://gekko.wizb.it/项目地址https://gitcode.com/gh_mirrors/ge/gekko点击查看免费下载相关推荐Cherry Studio 架构评审指南用引擎/声明配对识别实体泄漏按缺陷高度给出最小合规修复Cherry Studio 架构评审指南用引擎/声明配对识别实体泄漏按缺陷高度给出最小合规修复 本文是 Cherry Studio 仓库内 gh pr re金融科技后端NautilusTrader策略回测历史数据回测的准确性与可靠性NautilusTrader策略回测历史数据回测的准确性与可靠性 引言回测准确性的重要性 在量化交易领域策略回测Backtesting是验证交易策略有金融科技后端CodeBERT 快速上手完整指南10 分钟跑通自然语言代码搜索与代码补全CodeBERT 快速上手完整指南10 分钟跑通自然语言代码搜索与代码补全 你打开一个两千行的陌生代码库只会用 CtrlF 搜函数名或者你清楚功能应该金融科技后端上一篇从原子到复合PPTist组件设计的演进之路下一篇OOTDiffusion 人体解析部署指南detectron2 模型导出 Caffe2/ONNX/TorchScript 与推理实战创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表