- 金融科技
- 后端
【免费下载链接】gekko
A bitcoin trading bot written in node - https://gekko.wizb.it/
导读
本文围绕 Gekko(一个基于 Node.js 的比特币/加密货币交易机器人,仓库位于当前项目根目录)的**历史数据导入(Importing)**功能展开。回测(backtesting)必须依赖历史行情数据,而 Gekko 提供了一条从交易所直接拉取历史成交(trades)并加工成蜡烛图(candles)落库的自动化链路。读完本文,你将掌握两种导入方式——通过 Gekko UI 的图形化导入向导,以及通过命令行的--import模式,并能理解底层importer模式从拉取成交到批量写入数据库的完整工作流程,以及哪些交易所支持该功能。
为什么需要导入历史数据
在 docs/features/backtesting.md 中已经说明:要对策略进行回测,必须有可用的历史市场数据。获取这类数据最便捷的方式,就是让 Gekko 直接从交易所的历史成交数据接口中导入。需要特别注意的是,并非所有交易所都支持导入,具体支持范围请参见 docs/introduction/supported_exchanges.md 中的支持列表。
Gekko 对交易所的能力做了三种区分:
- Monitoring(监控):从交易所获取实时市场数据,用于存储和运行交易模拟;
- Live Trading(实盘交易):基于策略信号自动下单,将 Gekko 变成真正的交易机器人;
- Importing(导入):从交易所获取历史市场数据,方便你一次性拉取一个月甚至更长时间的数据用于回测。
支持导入(Importing 列为 ✓)的交易所包括 Binance、Poloniex、GDAX、Kraken、Bitfinex、coinfalcon、The Rock Trading、Luno,以及标有*(自 0.6 起暂时停用)的 BTCC 等;而 Bitstamp、Bittrex、EXMO、Gemini、Okcoin.cn、Cex.io、BTC Markets、zaif、bx.in.th、bitcoin.co.id 等交易所则不支持导入(✕)。Bittrex 不支持导入的原因在仓库中被标注为 API 问题。以上支持情况以仓库文档为准,导入功能对交易所的可用性取决于对方是否开放可用的历史成交数据接口。
方式一:通过 Gekko UI 导入
如果你使用 Gekko 的 Web UI,导入操作非常简单,不需要接触配置文件:
- 在导航栏进入Local tab(本地数据标签页);
- 滚动到页面底部,点击"Go to the importer"(进入导入器);
- 在导入页面底部选择市场(market)和日期范围(daterange);
- 点击import按钮,Gekko 便会自动从交易所下载历史市场数据。
导入期间,UI 会展示实时的导入进度(当前处理到的市场时间戳等)。这一交互流程背后的实现位于 web/routes/import.js:前端提交一个包含config对象的 POST 请求后,后端以mode = 'importer'启动流水线(pipeline),并把本次导入登记到importManager缓存中;流水线运行过程中通过 WebSocket 广播import_update事件(携带latest与done字段)来驱动界面上的进度条,出错时则广播import_error。也就是说,UI 导入本质上是对命令行导入模式的封装,二者共享同一套核心实现。
方式二:通过命令行导入
如果你在命令行环境运行 Gekko,可以参考 docs/commandline/Importing.md 中的说明,步骤如下。
步骤 1:启用并配置 candleWriter 插件
导入的目的是把数据存进数据库,因此必须启用candleWriter插件(关于插件启用方法见 docs/commandline/plugins.md)。该插件负责把导入得到的蜡烛图写入数据库。在插件清单 plugins.js 中,candleWriter被声明为支持importer模式的插件。
candleWriter 本身依赖一个数据库适配器(adapter),默认配置位于 config/plugins/candleWriter.toml:
enabled = true adapter = "sqlite"即默认使用 SQLite 存储;你也可以在 config/adapters 下切换为mongodb.toml或postgresql.toml。以 MongoDB 为例,其适配器配置如下:
connectionString = "mongodb://mongodb/gekko" path = "plugins/mongodb" version = 0.1 [[dependencies]] module = "mongojs" version = "2.4.0"步骤 2:正确配置 config.watch
确保配置文件中的config.watch设置正确,它决定了从哪个交易所、哪个市场对(交易对)导入数据。
步骤 3:配置 importer.daterange
在配置文件中设置importer.daterange的from与to属性,指定要导入的时间范围,例如:
[importer] [importer.daterange] from = "2015-09-01" to = "2015-10-01"从 core/markets/importer.js 的源码可以看到日期范围的解析逻辑:
from与to会通过moment.utc()解析为 UTC 时间;- 如果省略
to,代码会默认将其设置为moment().utc(),即当前时刻,并在日志中提示No end date specified for importing, setting to ...; - 如果
from或to非法(!from.isValid()/!to.isValid()),进程会直接以错误退出(util.die('invalid from')); - 如果
to <= from,同样会报错This daterange does not make sense.。
步骤 4:运行导入命令
node gekko --config config.js --import启动后控制台会输出类似如下的日志:
2016-06-26 09:12:16 (INFO): Gekko v0.2.2 started 2016-06-26 09:12:16 (INFO): I'm gonna make you rich, Bud Fox. 2016-06-26 09:12:17 (INFO): Setting up Gekko in importer mode 2016-06-26 09:12:17 (INFO): 2016-06-26 09:12:17 (INFO): Setting up: 2016-06-26 09:12:17 (INFO): Candle writer 2016-06-26 09:12:17 (INFO): Store candles in a database 2016-06-26 09:12:17 (INFO): 2016-06-26 09:12:17 (WARN): The plugin Trading Advisor does not support the mode importer. It has been disabled. 2016-06-26 09:12:17 (WARN): The plugin Advice logger does not support the mode importer. It has been disabled. 2016-06-26 09:12:17 (WARN): The plugin Profit Simulator does not support the mode importer. It has been disabled. 2016-06-26 09:12:18 (DEBUG): Processing 798 new trades. 2016-06-26 09:12:18 (DEBUG): From 2015-09-09 12:00:04 UTC to 2015-09-09 13:58:55 UTC. (2 hours) 2016-06-26 09:12:20 (DEBUG): Processing 211 new trades. (...)日志中那些WARN很值得注意:Trading Advisor、Advice logger、Profit Simulator 等插件不支持importer模式,因此被自动禁用。这一行为来自 core/pluginUtil.js 的load函数——插件清单中每个插件都声明了自己支持的modes数组,若当前 Gekko 模式(此处为importer)不在其中,插件会被跳过并打印上述警告。这就是为什么导入模式下只有 candleWriter(及数据库写入)参与工作,而策略、交易建议相关插件不会运行。
底层原理:importer 模式的数据流
导入过程远比"下载数据"四个字复杂。从源码可以还原出完整的数据流水线,入口在 core/markets/importer.js:
- 检查交易所能力:通过
exchangeChecker.cantFetchFullHistory(config.watch)校验所选交易所是否支持拉取完整历史成交;不支持则直接终止(util.die(error, true))。对应实现位于 exchange/exchangeChecker.js。 - 选择抓取器(fetcher):按
config.watch.exchange从importers/exchanges目录加载对应交易所的抓取实现(如 importers/exchanges/binance.js、poloniex.js、kraken.js等),并传入from/to日期范围。 - 逐批拉取成交:fetcher 通过事件总线
bus发出trades事件,将一段时间的成交数据交给Market.processTrades。 - 成交 → 蜡烛图:
processTrades把成交写入TradeBatcher(core/budfox/tradeBatcher.js),后者按时间窗口聚合成批次后触发new batch事件,交由CandleManager(core/budfox/candleManager.js)加工成 OHLCV 蜡烛,并发出candles事件。 - 推送蜡烛:
pushCandles把蜡烛逐根 push 进一个Readable流(objectMode: true),由流水线下游的 candleWriter 消费。 - 收尾:fetcher 发出
done事件后,Market在processTrades中检测到this.done为真,打印Done importing!并发出end事件结束导入。
抓取器的分块策略:以 Binance 为例
importers/exchanges/binance.js 展示了抓取器如何处理大时间范围:它采用**按小时分块(1h step)**的推进方式——每次getTrades(from, handleFetch)只拉取从当前from起的一小段成交,拉完后将from前进 1 小时(并补偿可能的闰秒:from.clone().add(1, 'h').subtract(1, 's')),再继续下一段;当from越过终点end时,发出done事件并过滤掉超出end的成交。这样既避免了一次性请求过大数据量,也便于断点式推进。日志中 "Processing 798 new trades" 与 "From ... to ... (2 hours)" 正是这种分批处理过程的体现。
导入进度如何上报
在Market.processTrades中,如果 Gekko 以子进程模式运行(gekkoEnv === 'child-process'),每处理一批成交都会通过process.send({event: 'marketUpdate', payload: lastAt})把最新成交时间戳上报给父进程;父进程侧由 core/workers/pipeline/messageHandlers/importerHandler.js 接收并回调,UI 正是借此持续刷新"已导入到哪个时间点"的进度信息。整个 pipeline 的调度在 core/workers/pipeline/parent.js 中完成。
蜡烛如何落库
candleWriter 的写入端由所选数据库适配器提供。以 MongoDB 为例,plugins/mongodb/writer.js 中的processCandle会把蜡烛先缓存在candleCache数组中,攒满 100 根或进入finalize时一次性批量写入historyCollection(集合名来自 plugins/mongodb/util.js 的settings.historyCollection)。批量插入使用{ ordered: false },这样即使个别蜡烛因重复键等原因失败,也不会拖垮整批写入(失败详情仅记入 debug 日志)。写入的每条蜡烛记录包含start(开盘时间戳)、open/high/low/close、vwp(成交量加权价格)、volume、trades(成交笔数)以及pair(交易对)等字段。此外,若同时启用了adviceWriter,该 Store 还会负责把策略建议写入adviceCollection。
导入完成后
数据一旦导入成功,就被持久化在所选适配器的数据库中。之后你可以:
- 在 docs/commandline/backtesting.md 与 docs/features/backtesting.md 中了解如何利用这些数据运行回测;
- 通过
backtest.toml(config/backtest.toml)中的daterange = "scan"让 Gekko 扫描数据库中已有的日期范围,或显式指定[daterange] from / to来精确限定回测区间。
值得一提的是,回测时 Gekko 的 candleLoader(core/tools/candleLoader.js)会按需从数据库读取蜡烛,因此导入的日期范围越完整,回测的灵活性就越高——这就是"先导入、再回测"这一标准工作流的意义所在。
小结
Gekko 的历史数据导入功能同时提供了 UI 向导与命令行两种入口,核心链路由importer模式下的 Market 流、各交易所 fetcher、TradeBatcher/CandleManager 聚合器与数据库 writer 协作完成。使用时要记住三个要点:只支持列表中的交易所、必须启用 candleWriter 及对应数据库适配器、正确配置config.watch与importer.daterange(to可省略,缺省为当前时间)。理解这条链路后,无论手动导入还是通过 UI 发起导入,你都能准确预判数据会以何种格式、何种粒度写入哪个数据库集合,为后续回测打下可靠的数据基础。
- 金融科技
- 后端
【免费下载链接】gekko
A bitcoin trading bot written in node - https://gekko.wizb.it/
相关推荐
Gekko 历史数据导入(Importer)完整指南:从交易所拉取行情数据用于回测
Gekko 历史数据导入(Importer)完整指南:从交易所拉取行情数据用于回测 本文基于 Gekko 官方命令行文档整理并深入仓库源码验证,讲解如何通过命令
金融科技后端Cherry Studio 架构评审指南:用引擎/声明配对识别实体泄漏,按缺陷高度给出最小合规修复
Cherry Studio 架构评审指南:用引擎/声明配对识别实体泄漏,按缺陷高度给出最小合规修复 本文是 Cherry Studio 仓库内 gh pr re
金融科技后端Gekko 回测实战指南:用历史数据验证你的比特币交易策略
Gekko 回测实战指南:用历史数据验证你的比特币交易策略 Gekko 是一个基于 Node.js 的开源比特币交易机器人,回测(Backtesting)是它最
金融科技后端
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考