4. 绘制工具与数据准备
双轴复盘图的质量,八成取决于数据准备。很多人在通达信或同花顺里看到漂亮的分时图,就以为“导出即用”,结果把数据拖进 Excel 或 Python 后才发现:时间列是文本、成交量单位是“手”而价格是“元”、午休时段被压缩成连续时间轴、停牌日出现空行。本节围绕“导出—清洗—对齐—前置校验”这条真实工作链,讲清楚三款常用软件各自能导出什么、导出后要改什么,以及画双轴图之前必须完成的几项关键操作。
一、三款软件的数据能力与导出路径
通达信、同花顺、TradingView 的定位不同,导出的数据粒度也不同,选工具前先明确你要的是“分时(1 分钟)”还是“日线”。通达信在分时图界面右键通常有“输出数据/导出数据”入口,可导出当前分时或历史分时的 1 分钟数据,字段一般包含时间、开高低收、成交量、成交额;其优势是本地数据完整、支持批量导出多日分时,缺点是导出文件常为 .txt 或 .xls,编码可能是 GBK,且成交量默认以“手”为单位。同花顺的分时数据导出入口类似,但部分版本对历史分时导出有限制,更适合导出当日或近若干交易日的分时;它的字段命名与通达信略有差异,例如“成交量”列可能直接给“量”或“现量”。TradingView 则以图表和指标见长,导出能力相对弱:免费版通常只能导出图表图片,历史逐笔/分钟数据需要通过“导出图表数据”功能或 API/第三方数据源获取,且时间戳多为 UTC,需要转换为北京时间。
因此一个实用的选择原则是:需要多日分时批量复盘,优先用通达信导出;只需要当日或少量交易日,同花顺足够;需要跨市场、跨品种或做程序化回测,考虑 TradingView 配合外部数据源。无论哪款软件,导出后都不要直接画图,先进入清洗环节。
二、分时数据清洗的四个关键动作
第一,统一时间格式与交易时段。导出的时间列常见“09:30”“930”“2024/06/03 09:30”等混排。应统一为“HH:MM”或完整时间戳,并明确 A 股连续竞价时段为 09:30–11:30、13:00–15:00,午休 11:30–13:00 不属于交易时间。若直接按行号画图,午休会被“压缩”,分时曲线在 11:30 后突然跳到 13:00,视觉上产生虚假的连续走势。正确做法是保留时间列作为横轴分类轴,或在绘图时显式插入午休断点。
第二,统一价格与成交量的单位。价格一般为“元”,成交量在通达信/同花顺中常为“手”(1 手 = 100 股),成交额为“元”或“万元”。双轴图中价格轴与成交量轴量纲完全不同,必须先确认单位再设定坐标范围。例如某日分时成交量合计显示为 12.6 万手,换算成股数应为 1260 万股;若误把“手”当“股”,成交量轴会整体缩小 100 倍,量价对比关系完全失真。
第三,处理缺失值与异常值。停牌、集合竞价、数据断点会产生空行或 0 值。清洗时应删除全空行,对成交量缺失但价格连续的时段做标记而非随意插值;对明显异常(如成交量突增 10 倍且价格无对应波动)先核对是否为除权、复牌或数据源错误。清洗后建议保留一列“数据状态”标记正常/缺失/异常,便于复盘时回看。
第四,计算派生字段。双轴复盘图常需要均价线、累计成交量、量比等。均价可用累计成交额除以累计成交量得到;累计成交量按时间顺序累加;若要做“量价背离”判断,还可计算单位时间成交量与价格变动的比值。这些派生列应在清洗阶段一次算好,避免绘图时反复处理。
三、双轴图绘制的前置操作
清洗完成后,进入绘图前的最后准备。以 Excel 为例:将时间列设为横轴分类,价格列(收盘价或最新价)设为左轴主坐标,成交量列设为右轴次坐标,选择“组合图—折线+柱形”。关键前置操作有三点:一是确认横轴顺序,按时间升序排列,避免导出文件倒序导致曲线反向;二是设定双轴范围,价格轴不必从 0 开始(可分时图常用当日最高最低自适应),成交量轴必须从 0 开始,否则柱形高低失去可比性;三是处理午休断点,在 11:30 与 13:00 之间插入空行或使用分类轴,使曲线在午休处断开。
若用 Python(matplotlib/pandas)绘制,前置操作对应为:用 pd.to_datetime 统一时间、用 set_index 设时间索引、用 twinx() 创建次坐标轴、用 axvline 标注午休分界。下面给出一个最小可运行的处理骨架,参数为示例假设,实际使用时替换为你的导出文件路径与列名:
import pandas as pd
import matplotlib.pyplot as plt
# 示例:读取通达信导出的分时数据(假设列名如下)
df = pd.read_csv("fen shi_20240603.txt", sep="\t", encoding="gbk")
df.columns = ["时间", "开盘", "最高", "最低", "收盘", "成交量", "成交额"]
df["时间"] = pd.to_datetime(df["时间"], format="%H:%M").dt.time
df = df.sort_values("时间").reset_index(drop=True)
# 单位换算:手 -> 股(示例假设导出为手)
df["成交量股"] = df["成交量"] * 100
fig, ax1 = plt.subplots(figsize=(12, 5))
ax1.plot(df["时间"].astype(str), df["收盘"], color="#2563eb", label="价格")
ax1.set_ylabel("价格(元)")
ax2 = ax1.twinx()
ax2.bar(df["时间"].astype(str), df["成交量股"], color="#f59e0b", alpha=0.5, label="成交量")
ax2.set_ylabel("成交量(股)")
ax2.set_ylim(bottom=0)
plt.xticks(rotation=45)
plt.tight_layout()
plt.show()
这段代码体现了三个前置要点:时间排序、单位换算、次坐标轴从 0 开始。运行后应检查:曲线是否在 11:30 与 13:00 之间出现合理断点、成交量柱是否与价格走势在关键时点对应、坐标轴标签单位是否与原始数据一致。若发现曲线在午休处“连成一条斜线”,说明横轴被当成了连续数值轴,需要改为分类轴或插入断点。
四、一个可复用的前置检查表
把上述操作整理成一张检查表,每次导出新数据后逐项打勾,能显著减少返工。表中参数为示例,实际按你的数据源调整:
| 检查项 | 示例标准 | 不通过的典型表现 |
|---|---|---|
| 时间格式 | 统一为 HH:MM,升序排列 | 曲线反向、横轴出现乱序 |
| 交易时段 | 仅保留 09:30–11:30、13:00–15:00 | 午休被压缩成连续斜线 |
| 成交量单位 | 手×100 换算为股,或明确标注“手” | 量轴整体缩小 100 倍 |
| 次坐标轴起点 | 成交量轴从 0 开始 | 柱形高低失真、量价对比错误 |
| 缺失与异常 | 空行删除,异常点标记状态列 | 曲线断裂无说明、异常量误导判断 |
| 派生字段 | 均价、累计成交量已计算 | 绘图时临时计算、口径不一致 |
最后提醒一个容易被忽略的细节:不同软件导出的“收盘价”在分时数据中通常指该分钟的收盘价,而非当日收盘价;若你要画的是“最新价”曲线,应确认列名对应关系,避免把开盘价当收盘价使用。数据准备做到位,双轴图才能真正承担“量价关系复盘”的分析任务,而不是一张好看但不可信的示意图。