☰
解析同花顺日线文件:Python读取本地K线数据实战指南
2026/10/31 13:33:04 网站建设 项目流程

简介:面向金融数据分析初学者与Python开发者,这份资源聚焦同花顺.day二进制日线文件的高效解析。同花顺日线文件以固定长度记录存储日期、开盘、收盘、最高、最低、成交量及成交额等关键行情字段,直接读取需要自行处理字节偏移与数据类型转换。压缩包内共2个文件:一个600000.day示例数据文件,一份getAllData.py解析脚本,整体仅4KB,携带和部署非常方便。已有2237人学习下载,适合希望快速上手股票历史数据提取的读者。借助脚本可快速掌握二进制解析的核心思路:二进制模式打开、头信息读取、记录循环、struct解包等,约20行Python代码即可完成基础解析;理解后还可进一步扩展错误处理、多文件批量解析或对接Pandas做深入分析,为后续量化研究打下基础。 最近一段时间在做本地行情数据的整理,绕来绕去还是回到了一个经典动作:解析同花顺日线文件。如果你试过把同花顺里的历史K线完整导出,大概会明白我的处境——界面导出有各种限制,复制粘贴又只覆盖最近一段,想要拿到干净、连续、能批量喂给策略回测的日线数据,最直接的办法就是自己动手把本地的 .day 文件读一遍。

做这件事的典型人群有两类。一类是做量化策略的,需要把任意股票的历史日线数据拉出来做回测,但第三方接口要么收费、要么字段不全;另一类是纯做复盘的,想把同花顺里积累多年的数据沉淀成自己的数据库,方便跨软件迁移或者做自定义统计。我自己属于前者偏后者的状态,所以选择从文件格式入手,而不是继续依赖界面操作。

这篇文章会把同花顺日线文件的存储位置、二进制结构、解析原理、Python实操代码、常见踩坑点以及应用扩展整个链路讲清楚。基于常见实践的补充说明我会明确标注,方便不同版本、不同数据下载工具的朋友对照排查。

1. 项目概述:为什么要自己动手解析同花顺日线文件

1.1 日线文件能做什么,解决什么问题

同花顺本身是提供K线查看的,但“看”和“用”是两回事。界面上的K线数据只能一条条看,或者通过受限导出拿一小段,一旦涉及跨标的、跨周期、长时间的统计,就必须有一份本地化、结构化、自己能控制格式的数据。

日线文件解析本质上就是把同花顺客户端下载下来的 .day 二进制文件,转换成 CSV、DataFrame 或其他可编程处理的数据格式。做完之后,你可以批量读取几百只股票的完整历史日线数据,再做均线、涨幅、回撤、突破信号之类的计算,也可以直接作为本地量化回测的数据源。

这个需求不是偶尔用一次,而是高频、刚性的。尤其是当你想把某只票从上市第一天到现在的每一天K线都拉出来对比时,靠手动操作几乎不可能。解析本地文件成了最省力、最稳定的一条路。

1.2 文件位置与命名规则:先找到你机器上的数据在哪

不同版本的同花顺安装路径有差异,但目录结构基本一致。以 Windows 系统为例,默认路径通常是C:\同花顺\vipdoc\sh和C:\同花顺\vipdoc\sz,也有安装在C:\new_jy这种目录下的。你可以直接在安装目录里搜vipdoc文件夹。

vipdoc下按市场分成子目录:sh放上海市场,sz放深圳市场,有的版本还有bj(北交所)目录。每个目录里是大量.day后缀的文件,文件名规则是“市场前缀 + 六位代码”,比如:

  • sh600000.day:浦发银行
  • sz000001.day:平安银行
  • sh000001.day:上证指数

这里有一个非常容易踩的坑:指数文件也混在同目录里。sh000001.day是上证指数,sz399001.day是深证成指,如果你只想分析个股,靠文件后缀判断不了,需要在代码里按代码段过滤。后面批量解析部分我会给过滤规则。

2. 数据格式拆解与解析原理

2.1 二进制记录的字段排布:一条K线占32字节

我实测过的同花顺 .day 文件,每条日线记录固定占 32 字节,按顺序排列如下:

字段占用字节类型说明
日期4 字节整型常见格式为 YYYYMMDD,如 20230101
开盘价4 字节整型通常放大了100倍,读出来要除以100
最高价4 字节整型放大100倍
最低价4 字节整型放大100倍
收盘价4 字节整型放大100倍
成交额4 字节浮点型单位因软件版本而异
成交量4 字节整型常见单位是手
保留字段4 字节整型通常填0或预留

为什么价格要用放大100倍的整数存?这是老式行情数据格式的通用做法。早期为了节省存储空间、加快读写速度,浮点运算成本又比现在高,直接用整数存“分”级别精度,既保持固定字节长度,也保证数据一致。解析时只要记得除以100还原成元,就不会出错。

2.2 字节序、日期格式与单位陷阱

二进制解析最容易翻车的两个点,是字节序和日期存储格式,我一个个说。

字节序方面,常见的 .day 文件是小端序(little-endian),也就是低位字节在前。Python 的struct.unpack里用<前缀指定小端序,例如'<IIIIIfII'。不要想当然用>去读,否则日期和价格会变成一串毫无意义的大数字。跨平台时尤其要注意,虽然绝大多数 Windows 和 Linux 机器都是小端序,但显式写<是最稳妥的。

日期格式方面,我这里描述的是最主流的 YYYYMMDD 整数格式,比如 20230101 表示 2023年1月1日。但我也见过个别老版本数据文件把日期存成“相对于某基准日的偏移天数”,读出来会是一个几千、几万的小数字,而不是八位数。判断方法很简单:解出来的第一个字段如果是 8 位数且前四位看着像年份,就是 YYYYMMDD;如果是一个不规律的小整数,就说明这个文件的日期列可能用了偏移格式。遇到这种情况,建议先用十六进制编辑器看看文件头,或者拿一条日期已知的记录反推偏移,不要直接套用 YYYYMMDD 逻辑。

单位方面,价格除以100基本通用,但成交量和成交额的单位不是统一的。同一份文件里,成交量有可能是“手”,也可能是“股”,成交额可能是“元”,也可能被缩放过。我的做法是:解析完先拿一只熟悉股票的数据去和同花顺K线页面核对数值,如果成交量差了100倍,做一次乘法换算就行。实用补充:单位不统一不影响文件解析流程,但会影响后续计算,所以这个核对步骤不能省略。

2.3 复权数据的正确认知:.day 文件里基本是不复权价

这是整个解析项目里最需要提前建立认知的地方。本地 .day 文件保存的通常是“不复权”的原始交易数据,也就是当天实际成交的开高低收、成交量和成交额。你看到某个股票历史价格中有突然向下跳空的大缺口,不是数据错了,是中间发生过除权除息。

因此,如果你要计算长期收益率、回撤这类对价格连续性敏感的指标,直接拿不复权价算,会出现明显失真,比如贵州茅台历史上多次十送十,不复权的长期涨幅曲线看起来就没那么顺畅。正确做法是另外维护一份除权除息/复权因子表,在应用层做前复权或后复权处理,而不是寄希望于 .day 文件里直接给出复权价。

3. Python 解析实操:从单文件到批量处理

3.1 环境准备与依赖安装

解析 .day 文件只需要 Python 标准库里的struct和os就够了,但为了后续数据处理方便,我建议装上pandas,一个是做表格工具,一个是本地数据框。另外可以装一个numpy,计算指标时更高效。

pip install pandas numpy

3.2 实现单文件日线解析

下面是一段可以直接跑通的完整代码。我加了比较详细的注释,方便你对照前面讲的字段排布理解:

import struct import pandas as pd def parse_day_file(filepath): """ 解析同花顺 .day 文件,返回包含日线数据的 DataFrame。 基于常见 32 字节记录格式实现,价格字段放大100倍。 """ records = [] # 以二进制只读方式打开文件 with open(filepath, 'rb') as f: while True: # 每条记录固定32字节 chunk = f.read(32) if len(chunk) < 32: break # 按小端序解析:日期、开、高、低、收、成交额(float)、成交量、保留字段 date, open_p, high_p, low_p, close_p, amount, volume, _ = struct.unpack('<IIIIIfII', chunk) # 简单的合法性过滤:如果日期明显不是YYYMMDD,说明格式可能不对,直接停 if date < 19900101 or date > 21000101: break records.append({ 'date': int(date), 'open': open_p / 100.0, 'high': high_p / 100.0, 'low': low_p / 100.0, 'close': close_p / 100.0, 'amount': amount, 'volume': volume, }) df = pd.DataFrame(records) df['date'] = pd.to_datetime(df['date'], format='%Y%m%d') return df # 示例用法 if __name__ == '__main__': df = parse_day_file('C:/同花顺/vipdoc/sh/sh600000.day') print(df.head()) print(df.tail()) print('总记录数:', len(df))

这段代码有三个关键设计,我说一下为什么这么做。

第一,循环读文件而不是一次性读整个文件。虽然 .day 文件单个也就几MB,但保持按记录读取更贴近二进制格式本质,也方便中途校验和调试。

第二,日期合法性判断。如果不做判断,一旦遇到文件末尾的脏数据或者版本异常,会往 DataFrame 里塞进一堆数值异常的行。这个if实际上是第一道安全网。

第三,pd.to_datetime把整数日期转成时间对象。后续做时间索引、按年筛选、画K线图都方便。

3.3 批量解析整个市场:加上个股过滤规则

单文件解析只是开胃菜,批量处理才是这个项目的常态。我会写一个遍历vipdoc目录、自动解析所有 .day 文件并汇总成一张大表的脚本。

import os import pandas as pd def is_stock_code(code): """ 判断是不是个股代码,过滤掉指数和其他特殊标的。 依据常见代码段: - 沪市主板:600/601/603/605 - 深市主板:000/001/002/003 - 创业板:300/301 - 科创板:688/689 """ return code.startswith(('600', '601', '603', '605', '000', '001', '002', '003', '300', '301', '688', '689')) def batch_parse_day_files(root_dir): """ 递归遍历 root_dir,解析所有 .day 文件。 返回 DataFrame,列包括:股票代码、日期、开高低收、成交额、成交量。 """ all_dfs = [] for dirpath, _, filenames in os.walk(root_dir): for fname in filenames: if not fname.endswith('.day'): continue market = fname[:2] # sh / sz / bj code = fname[2:8] # 六位代码 # 只保留股票,过滤指数等特殊文件 if not is_stock_code(code): continue filepath = os.path.join(dirpath, fname) df = parse_day_file(filepath) if df.empty: continue df['symbol'] = f'{market}{code}' all_dfs.append(df) if not all_dfs: return pd.DataFrame() return pd.concat(all_dfs, ignore_index=True) # 示例用法 if __name__ == '__main__': result = batch_parse_day_files('C:/同花顺/vipdoc') print(result.sample(5)) print('标的数量:', result['symbol'].nunique()) print('总行数:', len(result))

这里最容易被忽略的是is_stock_code。如果少了这个过滤,指数、基金、债券文件会混进来,后续做股票筛选时会发现结果里莫名其妙多出“上证指数”“沪深300”这些标的。另外,不同版本的目录也有可能包含sh、sz、bj之外的文件夹,所以用os.walk递归遍历更保险。

3.4 与行情软件核对数据:这一步别偷懒

解析完之后,强烈建议拿一只你熟悉的股票做核对。比如你常看的某只票,打开同花顺界面找到最近一个交易日的开高低收,再对比脚本解析出来的同一行数据,重点看三点:收盘价是否一致、成交金额数量级是否一致、日期是否逐日连续。

成交量单位尤其值得核对。假设某只票当天成交了 100 万股,.day 文件里读出来的 volume 是 10000,那就说明文件单位是“手”,需要乘以100换算成“股”。同花顺界面默认显示的成交量多是以“手”为单位,但不同软件版本和不同数据源处理不同,所以拿实际数值直接对比是最靠谱的。这个步骤只要做一次,后续所有文件都按统一逻辑处理就行。

4. 常见问题与排查技巧

4.1 高频踩坑问题整理

我把实际解析过程中遇到过的典型问题做成了一张速查表,按“症状、可能原因、解决办法”的顺序排列:

症状可能原因解决办法
日期读出 1900 年或多年以前的年份字节序反了把<改成<确认小端序,或用 hexdump 查看头部前4字节
日期是一串几千几万的小数而不是八位数日期存储为偏移天数反推基准日期,或换另一份数据源确认
价格看起来是几百万没有除以100,或价格放大倍数不同统一除以100;如果仍异常,检查文件版本
成交量和同花顺界面差100倍文件单位是股,界面单位是手,或反过来用最新一天数据对比,乘以或除以100
某只股票只有很短历史本地下载的数据不完整在同花顺里下载完整日线数据后重新解析
停牌期间日期缺失正常现象,停牌日无交易记录不要补0,按实际交易日对齐
读出的数据包含指数没有做代码过滤用代码段前缀过滤掉指数和特殊标的
文件读到一半报错文件被占用或损坏复制一份再解析,不要直接读原始文件

4.2 数据异常时的自查顺序

如果你解析出来的数据怎么看都不对,别急着改代码,先按顺序排查。

第一步,用十六进制编辑器或xxd查看 .day 文件头几十字节,对照表格确认字段布局是不是 32 字节一条。这一步能排除 99% 的版本问题。

第二步,打印前两条原始struct.unpack出来的整数,看看日期、价格的数量级是否符合预期。如果日期和价格全都异常,优先怀疑字节序;如果只有价格异常,优先怀疑缩放倍数。

第三步,挑一只刚上市不久的股票,历史记录少,方便逐条对照。拿最近五个交易日的K线去和同花顺界面比,逐一核对开高低收和成交量,基本能定位问题在哪。

第四步,如果单个文件正常但批量汇总后异常,检查是不是把不同市场的文件混在一起处理了,比如北交所数据和沪深数据在字段定义上可能有细微差异。我的建议是先把 sh、sz、bj 分开解析,确认单独正常后再合表。

5. 解析结果的落地应用:让数据真正为策略服务

5.1 快速计算技术指标:一个20日新高筛选示例

数据解析完成后,马上可以做一些有实用价值的计算。我拿一个最简单的“20日收盘价新高”筛选来举例,这类逻辑在短线复盘里很常用。

# 假设 result 是 batch_parse_day_files 返回的 DataFrame # 先排序,再按股票分组计算20日新高等 result = result.sort_values(['symbol', 'date']) result['pct_chg'] = result.groupby('symbol')['close'].pct_change() * 100 result['high_20'] = result.groupby('symbol')['high'].rolling(20).max().reset_index(level=0, drop=True) # 筛选出最新交易日创20日新高的股票 latest_date = result['date'].max() today_df = result[result['date'] == latest_date] new_high_stocks = today_df[today_df['high'] >= today_df['high_20']] print(new_high_stocks[['symbol', 'date', 'close', 'high_20']].head(20))

这里有一个容易踩的细节:groupby之后做rolling,索引会重新对齐,需要reset_index或者按 sanity 顺序处理,否则会有错位。我上面写法是按symbol分组后对high做 20 日滚动,再把结果对齐回去。

有了这个列表,每天收盘后可以自动跑一遍,找出哪些股票创了阶段新高,再结合自己的交易系统做下一层判断。整个过程从文件解析到输出候选名单,几十秒就能完成。

5.2 把数据接入本地数据库或回测框架

再进一步,你可以把解析结果落地成 SQLite、ClickHouse 或其他数据库表,也可以直接输出成 CSV 给第三方回测平台用。

SQLite 是一个很轻量的选择,不需要单独配置服务端:

import sqlite3 conn = sqlite3.connect('daily_data.db') result.to_sql('daily_kline', conn, if_exists='replace', index=False) # 查询示例:取某只股票最近30个交易日 query = "SELECT * FROM daily_kline WHERE symbol='sh600000' ORDER BY date DESC LIMIT 30;" print(pd.read_sql_query(query, conn))

落到数据库之后,后续可以做跨标的横截面分析、存增量更新、对接更复杂的回测流程。如果你已经有自己的可视化系统,也可以把 .day 文件解析作为数据入口,把本地分析链路彻底跑通。

最后分享一个我自己的小习惯:解析前先打开同花顺,把目标的日线数据从上到下刷新一遍,确认没有缺口,再用脚本批量读取。很多诡异的数据问题,其实不是解析代码的锅,而是上游数据没下载完整。数据底子打牢了,后面所有计算才有意义。顺便说一句,如果你只是临时想看某只股票的历史收盘价,不必写整套工程,解析出一个 DataFrame 后用to_clipboard()直接粘到 Excel 里就够了,灵活运用工具才是效率最大化的关键。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询