如何将Python获取的Truedata API实时数据正确存入pandas DataFrame
问题根因
代码返回空DataFrame是几个明确的逻辑错误导致的:
symbols初始化为空列表,传给start_live_data不会订阅任何标的,根本不会产生行情数据- 缺失
logging模块导入,初始化TD客户端时调用logging.DEBUG会直接抛出NameError中断流程 live_data_objs定义为空字典后全程没有写入任何行情数据,直接转DataFrame必然为空- DataFrame生成逻辑写在回调函数注册之前,后续推送的实时tick数据根本不会被捕获存储
- 遍历
req_ids时仅打印了touchline_data的快照内容,没有把数据写入待转存的结构中
修正后可运行代码
先补全账号、订阅标的配置,调整数据存储逻辑,在回调中实时写入tick数据到DataFrame:
from truedata_ws.websocket.TD import TD import time import pandas as pd import logging # 补全缺失的依赖导入 # 替换为你的真实账号信息 username = "你的Truedata账号用户名" password = "你的Truedata账号密码" realtime_port = 8084 url = "push.truedata.in" # 替换为你需要订阅的标的代码列表,空列表无法拉取任何数据 symbols = ["NIFTY 50", "BANKNIFTY", "RELIANCE"] # 提前定义行情字段,和TD接口返回的tick字段对齐,可根据实际返回结构调整 tick_columns = ["symbol_id", "timestamp", "ltp", "ltq", "total_volume", "bid_price", "ask_price", "bid_qty", "ask_qty"] # 初始化空DataFrame存储全量实时行情 realtime_df = pd.DataFrame(columns=tick_columns) # 初始化TD客户端 td_obj = TD( username, password, live_port=realtime_port, url=url, log_level=logging.DEBUG, log_format="%(message)s" ) print("\nStarting Real Time Feed.... ") req_ids = td_obj.start_live_data(symbols) time.sleep(1) # 等待初始快照推送 # 先存储连接建立后的第一批touchline快照数据 for req_id in req_ids: snapshot = td_obj.touchline_data[req_id] print(f"初始快照数据 -> {snapshot}") snapshot_row = pd.DataFrame([snapshot], columns=tick_columns) realtime_df = pd.concat([realtime_df, snapshot_row], ignore_index=True) # 注册行情回调,实时处理推送的tick数据 @td_obj.trade_callback def strategy_callback(symbol_id, tick_data): global realtime_df print(f"实时tick更新 -> {tick_data}") # 将新到的tick追加到DataFrame tick_row = pd.DataFrame([tick_data], columns=tick_columns) realtime_df = pd.concat([realtime_df, tick_row], ignore_index=True) # 可在此处添加策略逻辑,直接读取realtime_df即可使用全量行情数据 print(f"当前已存储行情条数:{len(realtime_df)}") print(realtime_df.tail()) # 打印最新5条数据验证写入结果 # 保持长连接持续接收行情 while True: time.sleep(120)
优化建议
- 如果订阅标的多、tick推送频率高,每次收到tick就做
pd.concat会有明显性能损耗,建议先用列表缓存tick数据,攒到固定条数再批量转DataFrame,参考写法:
tick_cache = [] CACHE_THRESHOLD = 100 # 每攒100条批量写入一次 @td_obj.trade_callback def strategy_callback(symbol_id, tick_data): global realtime_df, tick_cache tick_cache.append(tick_data) if len(tick_cache) >= CACHE_THRESHOLD: batch_df = pd.DataFrame(tick_cache, columns=tick_columns) realtime_df = pd.concat([realtime_df, batch_df], ignore_index=True) tick_cache.clear()
- 运行前先打印一次
tick_data的实际键名,如果和预设的tick_columns不匹配,对应调整列名即可保证数据对齐 - 不要在循环或回调里反复重新初始化
realtime_df,否则会清空之前存储的所有行情数据 - 确认你的Truedata账号有对应订阅标的的实时行情权限,否则会出现连接成功但无数据推送的问题
内容的提问来源于stack exchange,提问作者jyotirmay
相关产品推荐
相关产品推荐

