You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Kraken API Trades端点拉取历史数据出现时间戳跳变问题咨询

Kraken API历史成交数据拉取时间戳跳变问题排查

问题复现

编写Python脚本调用Kraken公开Trades接口拉取指定时间区间的历史成交数据,代码如下:

import pandas as pd
import json
import time
import urllib.request

def get_data(pair, since, until):
    global data
    global query
    global json_response
    global api_data
    
    data_columns= ["price", "volume", "time", "buy/sell", "market/limit", "miscellaneous"]
    data = pd.DataFrame(columns= data_columns)
    
    api_start = since
    app_start_time = time.time()
    counter = 1
    
    while api_start < until:
        last_time = time.time()
        api_domain = "https://api.kraken.com/0/public/Trades" + \
                    "?pair=%(pair)s&since=%(since)s" % {"pair":pair, "since": api_start}
        api_request = urllib.request.Request(api_domain)
        try:
            api_data = urllib.request.urlopen(api_request).read()
        except Exception:
            time.sleep(3)
        api_data = json.loads(api_data) 
        if len(api_data["error"]) != 0:
            print(api_data["error"])
            time.sleep(3)
            continue 
        query = pd.DataFrame(api_data["result"][pair], columns = data_columns)
        data = data.append(query, ignore_index= True)
        api_start = int(api_data["result"]["last"][:10])
        counter +=1
        time.sleep(1)    
        print("Request number: %s" %counter)
        print("Time since start: %s minutes" % round((time.time() - app_start_time)/60,2))
        print("Time since last request: %s seconds" % round((time.time() - last_time),2))
        print("last: %s" %api_start)
        print("")

get_data("XXBTZUSD", 1414761200, 1455761200)

拉取过程中出现异常:成功获取若干次响应后,返回数据中的UNIX时间戳直接从2015年对应的14亿级数值跳变到2022年对应的1654992002.801943,导致最终拉取的历史数据错误,异常响应示例如下:
Kraken API响应截图

问题结论

该异常是代码逻辑缺陷+Kraken API本身的设计限制共同导致的,不是单一原因。

代码存在的明确缺陷

  • 异常处理逻辑不完整:try块捕获请求异常(超时、限流、连接失败等)后,仅做了3秒休眠,没有跳过后续的JSON解析流程。如果请求失败,api_data会保留上一次请求成功的返回内容,后续解析直接使用旧数据,极易引发翻页游标错乱。
  • 游标处理无校验:Kraken接口返回的last字段是纳秒级时间戳字符串,代码直接截取前10位转为秒级时间戳作为下一次请求的since参数,既存在精度损失,也没有对返回的游标值做合理性校验,一旦接口返回异常游标,会直接把下一次请求的时间点拉到错误的位置。
  • 无入库数据校验:每一批拉取到的成交记录,没有校验时间戳是否落在预设的[since, until]区间内,异常数据会被直接追加到结果集中。

Kraken API本身的已知限制

Kraken公开Trades接口本身不支持稳定查询过久的历史归档数据,官方文档明确说明:当since参数传入的时间戳距离当前时间过久时,接口不会严格返回指定时间点之后的成交记录,翻页到归档数据边界时,会直接返回近期的成交数据,同时返回的last游标也会跳转到近期时间点,这是接口本身的设计规则,不属于偶发故障。

修复方案

  • 补全异常处理逻辑:请求失败后直接进入下一轮重试,不要执行后续解析流程,修复示例:
try:
    api_data = urllib.request.urlopen(api_request).read()
except Exception:
    time.sleep(3)
    continue # 请求失败直接重试,跳过后续解析
  • 增加游标合理性校验:每次拿到接口返回的last值后,先判断对应时间戳是否超过设置的until上限,同时和上一次请求的api_start做差值对比,如果单次翻页时间差超过合理阈值(如1小时),判定为返回异常,直接终止或重试,不要使用异常游标请求下一页。
  • 增加数据过滤逻辑:每一批成交记录追加到结果集前,先过滤掉时间戳不在目标时间区间内的异常数据。
  • 如果需要拉取2015年这类非常早期的历史成交数据,不要使用实时公开接口,Kraken官方提供了专门的历史归档数据导出渠道,公开Trades接口仅适合拉取最近几个月的实时/近线数据,过久的归档数据无法通过翻页稳定拉取。

内容的提问来源于stack exchange,提问作者Dalogh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 06:15:47