Binance期货资金费率API通过startTime/endTime分页拉取全量历史数据求助
分页逻辑错误及修复点
- 参数拼写错误:请求参数里的
endTIme拼写错误(第二个字母是大写I),Binance API参数严格区分大小写,正确参数名为endTime,参数错误会导致时间范围过滤失效。
- 参数拼写错误:请求参数里的
- 时间戳单位错误:
moment.unix()返回的是秒级时间戳,但Binance期货API要求传入毫秒级时间戳,应该使用moment.valueOf()获取毫秒时间戳。
- 时间戳单位错误:
- 初始数据丢失:首次请求拿到的
initialResult是最新的1000条数据,代码中没有将其加入结果数组,直接丢失了最新批次的数据。
- 初始数据丢失:首次请求拿到的
- 结果拼接逻辑错误:
fundingRates = [].concat(...)每次都会清空之前积累的结果,只保留当前请求的返回数据,最终只能拿到最后一批请求的结果,应该改为累加拼接。
- 结果拼接逻辑错误:
- 固定步长分页逻辑不合理:按照固定天数
days_per_batch向前滑动时间窗口,容易出现时间范围重叠、漏拉数据的问题,正确逻辑是每次取当前请求返回的最早一条数据的资金费率时间,减1毫秒作为下一次请求的endTime,直到返回结果为空或早于目标日期。
- 固定步长分页逻辑不合理:按照固定天数
- 未处理空返回情况:当请求的时间范围早于交易对上线时间时,API会返回空数组,代码没有判断该情况,会出现死循环或报错。
修正后完整代码
const moment = require('moment'); (async () => { try { const markets = symbols; // 你的交易对数组 const targetDate = moment("2018-01-01").valueOf(); // 转成毫秒时间戳方便比较 for (let i = 0; i < markets.length; i++) { const symbol = markets[i]; let fundingRates = []; let currentEndTime = Date.now(); // 从当前时间开始往回拉 let hasMore = true; while (hasMore && currentEndTime > targetDate) { const result = await binance.futuresFundingRate(symbol, { endTime: currentEndTime, limit: 1000 }); // 已经拉到最早数据,跳出循环 if (!result || result.length === 0) { hasMore = false; break; } // 转换格式并累加结果 const formattedResult = result.map(e => ({ symbol: e.symbol, fundingRate: e.fundingRate, fundingTime: moment(e.fundingTime) })); fundingRates = [...fundingRates, ...formattedResult]; // 取当前批次最早的时间,减1毫秒避免重复拉取同一条数据 const earliestTime = result[0].fundingTime; currentEndTime = earliestTime - 1; // 已经早于目标日期,跳出循环 if (earliestTime <= targetDate) { hasMore = false; } } exportToCSV(symbol, fundingRates); console.log(`processing ${i + 1} / ${markets.length}, symbol: ${symbol}, total records: ${fundingRates.length}`); } } catch (error) { console.error('Request error:', error); } })();
内容的提问来源于stack exchange,提问作者user16780074
相关产品推荐
相关产品推荐

