Python 行情数据留痕:symbol、timestamp、字段和 raw_snapshot 怎么记录

📅 2026/7/2 13:26:06
Python 行情数据留痕:symbol、timestamp、字段和 raw_snapshot 怎么记录
摘要研究报告里写“截至某日某时某股票价格为 X”一周后复查时发现数据源已刷新当时的快照没保存数字无法核对。这不是数据源的问题是取数流程里缺了一环——没有在取值的同时留下原始快照和字段溯源记录。本文给出一套最小留痕模型用 Python 保存请求参数、原始响应、字段路径和校验记录让报告里的每一个行情数字都能追溯到“什么时候、从哪个接口、用哪个字段取的、原始返回值是什么”。研究员用 Python 拉行情数据写报告最常见的一个坑不是数据源挂了而是报告交上去之后发现数据对不上回头查的时候数据源已经刷新了——那条行情的快照早就没了。问题不在数据源在于取值的时候没有同步留痕。你只记了数字本身没记这个数字是从哪个字段路径拿到的、原始返回体长什么样、取值时间是多少。一周后想复核只剩报告里一个孤零零的数字既查不到来源也复现不了当时的状态。本文给出一套最小留痕模型帮你把每一次行情取值都变成一条可追溯的记录。它不是数据库设计教程也不是生产级数据管道而是一套能让你的研究数据“经得起复核”的工程方法。1. 最小留痕模型一条记录至少包含什么每次取数至少保留以下六类信息。这六类合在一起构成了一个行情数字的“完整身世”。留痕维度核心字段回答什么问题时空坐标symbol、market、query_time什么品种、什么市场、什么时间取的数据来源data_source、query_method从哪个数据源、用哪种接入方式拿的时间语义payload_timestamp行情发生在什么时候不是取数时间取值路径field_name、field_path从返回体的哪条路径取到这个数字原始凭证raw_snapshot、raw_snapshot_hash原始返回体是什么有没有被改动过复核状态processing_note、review_status这个值后来有没有被人工修改、有没有复核过为什么raw_snapshot是必选项保存原始响应是留痕和日志最大的区别。日志只记录“发生了什么”原始快照记录的是“当时数据源交回了什么”。一周后如果价格对不上你可以把原始快照重新灌进校验脚本复现当时的取值过程。没有快照只剩猜测。2. 字段表研究报告引用的行情数据溯源记录以下字段表适合作为研究报告的数据引用附录每引用一个行情数字填一行。这张表的核心是让读者或审查者能从报告里的数字反查到你取数时的原始状态。字段名类型说明示例值report_idstr报告唯一标识RPT-2026-001report_sectionstr报告中的位置§3.2 估值分析symbolstr品种代码600519.SHmarketstr市场Adata_sourcestr数据源标识tickdbquery_methodstr接入方式RESTrequest_params_hashstr请求参数哈希sha256:abc123...requested_atstr请求发起时间ISO 86012026-07-01T14:30:0008:00payload_timestampint行情时间戳原始值1719823400000field_namestr取值字段名last_pricefield_pathstr字段在返回体中的路径data[0].last_pricefield_semanticsstr字段含义说明最新成交价快照value_rawstr原始返回值1675.00value_normalizedstr规范化后的值1675.00raw_snapshot_idstr原始快照唯一标识SNAP-20260701-001raw_snapshot_hashstr原始快照哈希sha256:def456...processing_notestr处理备注字段核对通过review_statusstr复核状态待复核 / 已复核 / 存疑注意上表中的payload_timestamp和value_raw为字段占位说明实际值以接口返回为准。request_params_hash和raw_snapshot_hash用于防篡改校验具体哈希算法可选用 SHA-256。3. Python 伪代码取值即留痕以下代码为教学伪代码展示取值留痕的核心逻辑流程非生产级可运行代码。实际使用时需根据数据源的接口文档调整字段路径和鉴权方式。importjsonimporthashlibfromdatetimeimportdatetime,timezonefromdecimalimportDecimaldeffetch_market_data(symbol:str,market:str)-dict:向行情数据源请求快照数据。 返回原始响应体。实际实现需替换为真实请求逻辑。 # 教学伪代码实际应使用 requests.get() 并处理超时、异常# response requests.get(..., params{...}, headers{...}, timeout10)# return response.json()passdefsave_raw_snapshot(data:dict)-tuple:保存原始响应快照返回 (snapshot_id, snapshot_hash)。raw_jsonjson.dumps(data,ensure_asciiFalse,sort_keysTrue)snapshot_idfSNAP-{datetime.now(timezone.utc).strftime(%Y%m%d-%H%M%S)}snapshot_hashhashlib.sha256(raw_json.encode()).hexdigest()# 实际实现将 raw_json 写入文件或数据库returnsnapshot_id,snapshot_hashdefextract_field_value(data:dict,field_path:str)-str:从返回体中按路径提取字段值。 例如 field_pathdata[0].last_price。 # 教学伪代码简化路径解析实际需处理嵌套和数组索引partsfield_path.replace([,.).replace(],).split(.)currentdataforpartinparts:ifisinstance(current,dict):currentcurrent.get(part)elifisinstance(current,list)andpart.isdigit():currentcurrent[int(part)]else:returnNonereturnstr(current)ifcurrentisnotNoneelseNonedefwrite_lineage_record(report_id:str,section:str,symbol:str,market:str,data_source:str,query_method:str,requested_at:str,payload_ts:int,field_name:str,field_path:str,field_semantics:str,value_raw:str,snapshot_id:str,snapshot_hash:str,processing_note:str)-dict:写入一条数据溯源记录。# 教学伪代码实际实现应写入数据库record{report_id:report_id,report_section:section,symbol:symbol,market:market,data_source:data_source,query_method:query_method,requested_at:requested_at,payload_timestamp:payload_ts,field_name:field_name,field_path:field_path,field_semantics:field_semantics,value_raw:value_raw,value_normalized:str(Decimal(value_raw))ifvalue_rawelseNone,raw_snapshot_id:snapshot_id,raw_snapshot_hash:snapshot_hash,processing_note:processing_note,review_status:待复核}# db.insert(record)returnrecorddefbuild_report_citation_note(record:dict)-str:根据溯源记录生成报告中可引用的数据来源注释。return(f数据来源{record[data_source]}{record[query_method]}f品种{record[symbol]}字段{record[field_path]}f请求时间{record[requested_at]}f快照 ID{record[raw_snapshot_id]}f复核状态{record[review_status]})4. 失败分支速查取数留痕流程中以下八类异常各有对应的处理方式。任何一类失败这条数据的review_status都应标记为“存疑”或直接阻断。失败场景处理方式请求成功但data为空记录value_rawNoneprocessing_note写明“数据为空”不填默认值JSON 解析失败保留原始响应文本processing_note记录“JSON解析失败”symbol缺失或与请求不一致阻断不写入溯源表。静默修正可能指向错误品种timestamp缺失或语义不明写入溯源表但review_status存疑processing_note标注“时间戳待确认”字段路径不存在value_raw留空processing_note写明“字段路径不存在”检查接口版本raw_snapshot未保存整条记录标记为“不可追溯”review_status存疑raw_snapshot_hash与原始不一致快照可能被篡改或损坏标记“哈希不一致”并阻断下游引用人工修改了值但未写processing_note复核时发现值与快照不一致且无备注标记“数据存疑”5. TickDB 在取数留痕流程中的合理位置TickDB 可作为候选结构化行情入口帮助统一保存请求参数、字段语义、原始快照和检查记录。它在取数留痕流程里的作用不是“保证数据一定正确”而是让你的取值动作有一个结构化的起点——symbol 和 market 有统一格式接口返回有明确的字段路径原始响应体可以完整保存。这些恰好是留痕模型前四类信息的基础。验证方式用自己的 symbol 发一次请求按本文字段表逐列填写。保存原始快照和哈希计算value_normalized写一条完整溯源记录。如果当前接口返回的字段路径和本文示例不同以官方文档或实测为准。不适合什么不替代研究报告的数据审核流程不承诺数据永远正确不保证所有字段在所有市场可用。具体端点、Header、字段枚举和错误码以 TickDB 官方文档和审核为准。6. 发布前检查清单序号检查项通过标准1请求参数已保存每次取数记录 symbol、market、请求时间、参数哈希2原始快照已保存raw_snapshot完整写入文件或数据库3快照哈希已计算raw_snapshot_hash可用于防篡改校验4字段路径明确报告引用的每个数字都能追溯到具体field_path5时间语义区分requested_at和payload_timestamp分开记录6异常有备注data为空、解析失败等情况在processing_note中写明7人工修改有留痕任何手工调整都在processing_note中说明原因8复核状态可查每条记录有review_status存疑数据不进入最终报告9报告中可引用每个行情数字附build_report_citation_note()生成的来源注释 本文取数留痕示例以 TickDB.ai 作为候选行情入口具体字段以官方文档和审核为准⚠️ 本文为技术教程不构成任何投资建议