ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

波浪理论图解5.pdf解析:矢量折线、铁律校验与回测

波浪理论图解5.pdf解析:矢量折线、铁律校验与回测 简介这份《波浪理论图解》PDF面向股票、期货等金融市场技术分析的学习者与交易者适合已有一定K线基础、希望系统理解艾略特波浪结构的读者用以解决浪型划分不清、买卖节奏难把握的问题。全包共1个PDF文件242KB篇幅精炼便于随时查阅和打印对照盘面。内容围绕波浪理论三要素——浪型、幅度与时间展开并给出理想化的艾略特波浪序列作为参照逐浪讲解第1浪至第5浪推动浪及A、B、C调整浪的市场心理与量能特征如第1浪易被忽视、第3浪资金涌入且常现延伸、第5浪泡沫化、B浪具迷惑性反弹、C浪杀伤力强等同时结合波浪特性说明实际应用中的局限与灵活处理原则。目前已有178人学习适合作为技术分析入门的图解手册与复盘资料帮助读者建立数浪框架并与其它技术指标、基本面分析配合使用。1. 波浪理论图解5.pdf 从一叠静态图变成可执行规则的那一刻拿到一份叫波浪理论图解5.pdf 的资料多数人的第一反应是看把第 3 页那组推动浪箭头截图贴进复盘笔记再对着 K 线手动数浪。做过几十个标的就会发现真正的问题不在看不懂而在没法复现——同一段走势今天数成 1-2-3-4-5明天数成 A-B-C没有判据就没有样本回溯统计也就无从谈起。把这份图解拆开看它只由三类东西构成带方向的折线几何、标注在转折点旁的浪级符号与比例数字、以及页内统一的坐标尺度。这三类东西恰好对应三类可编程对象矢量路径、文本包围盒、仿射变换矩阵。把它们抽出来之后波浪理论就从看图说话变成一组能跑回测的约束条件——铁律做硬过滤斐波那契比例做打分浪级嵌套做一致性校验。后面几章按这个顺序落地读者最好手边有一份带矢量折线的图解 PDF 和一段日线行情。2. 把波浪理论图解5.pdf 转成带浪级坐标的结构化数据图解类 PDF 的分析目标很具体得到一张转折点表每行是(时间, 价格, 浪级标签)。这件事的难点从来不是写代码而是先判断这份 PDF 里的图形到底是什么形态再决定走矢量解析还是图像识别。两条路线的成本差一个数量级选错了后面全白做。2.1 先判断图解是矢量绘制还是扫描位图判断只需要三行探测代码把结果对号入座即可。探测手段命中特征后续处理路径page.get_drawings()返回非空页面里有 path items含直线段或贝塞尔直接取顶点不需要 OCRget_drawings()为空、get_images()非空整页被压成一张大位图300dpi 渲染后再做角点/骨架提取page.get_text(words)返回空列表没有文字层浪级符号只能靠 OCR 或模板匹配我最常见的误判是看到页面上有文字就以为一定有文字层。很多图解 PDF 是文字也一起转成了图get_text()返回空这时候硬写提取逻辑只会拿到空数组。2.2 用 PyMuPDF 抽取折线顶点与浪级标注先拿折线。波浪图解的折线一般由大量短直线段拼成取每段的两个端点再去重就能还原出转折点序列。import fitz # PyMuPDF def extract_polylines(page, min_pts6, dedup0.5): 从一页 PDF 中抽取候选折线返回顶点列表的列表 result [] for d in page.get_drawings(): pts [] for item in d[items]: if item[0] l: # 直线段item[1] 起点, item[2] 终点 pts.extend([item[1], item[2]]) elif item[0] c: # 三次贝塞尔取首尾端点近似 pts.extend([item[1], item[4]]) uniq [] for p in pts: # dedup 控制相邻点合并阈值PDF 用户单位1 单位约等于 1/72 英寸 if not uniq or (abs(p.x - uniq[-1].x) dedup or abs(p.y - uniq[-1].y) dedup): uniq.append(fitz.Point(p)) if len(uniq) min_pts: result.append(uniq) return resultmin_pts用来过滤坐标轴刻度线、方框边框这类短路径dedup是整套解析里最需要手调的参数取值太小会让同一个拐点被拆成三四个点太大则会把真实的窄幅回撤浪吞掉。经验值是按页面宽度定标dedup ≈ page.rect.width / 1200。再拿标注。浪级符号是有限集合直接白名单过滤比全量 OCR 稳得多。WAVE_TOKENS {1, 2, 3, 4, 5, A, B, C, I, II, III, IV, V} def extract_labels(page): labels [] for w in page.get_text(words): # (x0, y0, x1, y1, word, block, line, word_no) txt w[4].strip().upper().replace(Ⅳ, IV).replace(Ⅴ, V) if txt in WAVE_TOKENS: labels.append({ text: txt, cx: (w[0] w[2]) / 2, # 包围盒中心横坐标 cy: (w[1] w[3]) / 2, # 包围盒中心纵坐标 }) return labels标注拿到之后做一次最近邻匹配每个标签找距离最近的折线顶点距离超过page.rect.height * 0.03的直接丢弃。这一步会顺手清掉图例区里那些不属于浪级的编号。注意罗马数字在不同字体下可能被映射成Ⅳ、Ⅴ这类兼容字符先做 Unicode 归一化再比对否则浪 IV永远匹配不上。2.3 图解坐标映射到价格轴的参数表与仿射公式图上坐标是 PDF 用户单位纵轴向下增长行情价格是数值纵轴向上增长。中间必须有一次带轴类型的线性变换参数集中在下面这张表里。参数含义取值示例调错的后果page_offsetPDF 页序与图解编号的偏移6抽到目录页折线为空y_top_px/y_bot_px图中已知高点、低点的像素纵坐标120 / 540比例整体缩放错位price_top/price_bot上述两点对应的真实价格48.60 / 21.35所有价格平移错位x_left_px/x_right_px图内时间轴左右端点80 / 760日期全部偏移t_left/t_right上述两点对应日期2019-01-02 / 2021-06-30与 K 线对不上log_scale纵轴是否对数False长周期图上高浪被压缩import math def map_point(cx, cy, cfg): 把 PDF 页面坐标映射为 (交易日索引比例, 价格) # 纵向PDF 向下增长价格向上增长需要反向 ratio_y (cfg[y_bot_px] - cy) / (cfg[y_bot_px] - cfg[y_top_px]) if cfg[log_scale]: lo, hi math.log(cfg[price_bot]), math.log(cfg[price_top]) price math.exp(lo ratio_y * (hi - lo)) else: price cfg[price_bot] ratio_y * (cfg[price_top] - cfg[price_bot]) # 横向线性插值出时间进度 0~1 ratio_x (cx - cfg[x_left_px]) / (cfg[x_right_px] - cfg[x_left_px]) return round(ratio_x, 6), round(price, 4)page_offset是这份图解最容易踩的坑封面、版权页、目录页都在正文之前图解编号图 5-3和 PDF 的doc[4]完全不是一回事。定位办法是遍历所有页找get_drawings()返回路径最多且文字层含1/2/3/4/5的那一页把它记为正文起点。验证整条映射链路是否正确的办法很土但有效取图内标注的三个浪级点映射后在真实 K 线上标出来肉眼比对相对位置。三个点都能落在对应日的价格 ±1.5% 内映射才算过关。3. 波浪理论三大铁律的代码化与浪级递归校验数据抽出来只是原料真正决定数浪能不能自动化的是判定逻辑。波浪理论里可以量化的部分封装得相当好三大铁律是二值判断斐波那契比例是区间打分浪级嵌套是递归调用同一套函数。把这三层分开写好处是每一层都能单独测。3.1 用 ZigZag 从 K 线提取摆动点ZigZag 负责把连续 K 线压成转折点序列是所有后续判断的输入。阈值选固定百分比还是 ATR 倍数直接决定浪级粗细。import numpy as np import pandas as pd def zigzag(df: pd.DataFrame, pct: float 0.05, use_atr: bool False): df 需含 high/low/close返回 [(idx, price, H|L), ...] thr pct if use_atr: atr (df[high] - df[low]).rolling(14).mean().iloc[-1] thr atr * pct / df[close].iloc[-1] # pct 在此模式下表示 ATR 倍数 pivots, last_i, last_p, direction [], 0, df[close].iloc[0], 0 for i, (h, l, c) in enumerate(zip(df[high], df[low], df[close])): if direction 0 and c last_p * (1 thr): direction, last_p, last_i 1, c, i pivots.append((i, c, H)) elif direction 0 and c last_p * (1 - thr): direction, last_p, last_i -1, c, i pivots.append((i, c, L)) return pivotspct0.05适合日线级别找中浪做日内微浪要降到0.008~0.015use_atrTrue时参数含义变成 ATR 倍数波动率差异大的品种之间可比性更好但同一次回测里别混用两种口径。摆动点序列出来后先做一次方向交替检查——连续两个H说明阈值偏小需要放大。3.2 三大铁律的判定函数一个标准推动浪由六个点、五段组成。铁律就是三段可以直接编码的硬约束。def check_impulse(p, tol0.0): p [P0..P5] 六个点方向向上返回 (是否合法, 原因) P0, P1, P2, P3, P4, P5 p # 铁律一2 浪不能回撤超过 1 浪起点 if P2 P0 * (1 - tol): return False, rule1: wave2 retraces beyond start of wave1 # 铁律二3 浪不能是最短的那一段 l1, l3, l5 P1 - P0, P3 - P2, P5 - P4 if l3 min(l1, l5): return False, rule2: wave3 is the shortest # 铁律三4 浪不能进入 1 浪的价格区间 if P4 P1 * (1 tol): return False, rule3: wave4 overlaps wave1 territory return True, oktol是容差实物价格和指数上一般留0.001~0.003用来吸收停牌、分红调整造成的跳空。三个if的顺序不能随意换实际数据里3 浪最短是最常被误判为合法的失效模式把它放在重叠判断之前能提前拦掉一批明显的错误标注。还有一条不成文但要写进代码的5 浪正常情况下要创新高P5 P3不创新高就是失败五浪。失败五浪在真实行情里出现频率不低所以它不能直接判废应该打标记降权——truncatedTrue的形态在打分环节扣 15 分而不是清零。3.3 斐波那契比例打分与浪级嵌套铁律过了之后用比例区间做连续打分把像不像量化成 0~100。浪段常见比例区间计算基准在本方案里的作用2 浪回撤0.382–0.618极限 0.7861 浪长度超出 1.0 由铁律一拦截3 浪延伸1.618 / 2.6181 浪长度落在区间得满分4 浪回撤0.236–0.3823 浪长度与 1 浪重叠由铁律三拦截5 浪0.618×1 浪 或 1.0×3 浪1 浪或 3 浪用于区分标准与延伸形态B 浪反弹0.5–0.786A 浪长度超过 A 浪起点倾向锯齿形C 浪1.0 / 1.618A 浪长度决定修正结束估算位浪级嵌套的检查方式是递归把已经确认的 3 浪内部再跑一次zigzagcheck_impulse看它能不能数出完整的五小浪。数得出来标注升级为已确认 3 浪数不出来降级成候选 3 浪。这一步会明显拉长运行时间实际做法是只对当前未收盘的最后一浪做递归已确认的老浪缓存结果。def score_impulse(p): l1, l3, l5 p[1] - p[0], p[3] - p[2], p[5] - p[4] s 0 r2 (p[1] - p[2]) / l1 s 30 if 0.382 r2 0.618 else (15 if r2 0.786 else 0) # 2 浪 r3 l3 / l1 s 30 if 1.5 r3 2.8 else (12 if r3 1.0 else 0) # 3 浪 r4 (p[3] - p[4]) / l3 s 20 if 0.236 r4 0.382 else (8 if r4 0.5 else 0) # 4 浪 s 20 if p[5] p[3] else -15 # 失败五浪降权 return max(s, 0)权重分配没有唯一解但 2 浪和 3 浪加起来占 60 分是有理由的这两段的形态稳定性在同级别中最高4 浪和 5 浪变体太多给高分只会放大噪声。4. 波浪理论图解5.pdf 的标注回放与人工交叉校验解析结果必须能被看回去否则无法判断是代码错了还是行情本身不符合规则。回放的目标很直接把从 PDF 里抽出来的浪级标签和折线叠加到真实 K 线上用眼睛做最后一道验收。4.1 把解析出的浪级点渲染回行情图import matplotlib.pyplot as plt def replay(df, labels, waves, titlewave replay): fig, ax plt.subplots(figsize(14, 6)) ax.plot(df.index, df[close], lw1.0, color#333, labelclose) # labels: [{text:3,t:Timestamp,price:float}, ...] for lb in labels: ax.annotate(lb[text], (lb[t], lb[price]), textcoordsoffset points, xytext(0, 9), hacenter, fontsize10, color#c0392b) # waves: [((t0,p0),(t1,p1)), ...] 从 PDF 折线映射而来 for (t0, p0), (t1, p1) in waves: ax.plot([t0, t1], [p0, p1], lw1.8, color#c0392b, alpha0.85) ax.set_yscale(log) # 与 cfg[log_scale] 保持一致 ax.grid(alpha0.25); ax.set_title(title) return fig, axxytext(0, 9)控制标签离点的偏移像素太近会和 K 线柱子重叠。set_yscale必须与映射阶段的log_scale一致否则回放图看起来对得上、实际价格全偏——这是最隐蔽的一种自欺。4.2 常见解析失真与排错对照表现象根因定位方法修正转折点数量翻倍dedup过小打印len(uniq)与页面宽度比调到width/1200附近浪级标签整体偏移文字层与图形层坐标系不同打印page.rotation、page.cropbox用page.rect而非mediabox换算折线为空位图 PDF 或抽到了目录页get_drawings()长度、页序加page_offset或转图像流程罗马数字匹配失败字体连字映射打印原始w[4]的码点Unicode 归一化后再比对价格与 K 线偏差超 5%原图用的是对数轴比对高低两段的比例打开log_scale重算同一页抽出多条无关折线坐标轴、方框也被算作 path按顶点数与包围盒面积过滤保留面积最大的一条主干排错顺序建议固定下来先确认页对了再确认折线对了最后确认坐标映射对了。跳过前两步直接调映射公式通常是在给一个本来就错的输入做精细化。校验的量化标准也定死随机抽 20 个解析出的浪级点人工比对真实日期价格命中率低于 85% 就不要继续往下做回测先回去调dedup和log_scale这两个参数。5. 进阶浪型打分、参数敏感性与图解复现的边界打分函数写完最容易犯的错是把它当成一个可以调参刷分的模型。实际做法是先做敏感性扫描看结论稳不稳而不是看哪个参数回测收益最高。把 ZigZag 阈值从 0.02 扫到 0.12、步长 0.01对同一段行情输出合法推动浪数量和平均得分两列如果合法数量随阈值剧烈跳变比如 0.05 处有 12 个、0.06 处只剩 3 个说明这段行情本身处在模糊区任何基于它的结论都不该被采信。for pct in [0.02, 0.03, 0.04, 0.05, 0.06, 0.08, 0.10, 0.12]: piv zigzag(df, pctpct) cnt, sc 0, [] for i in range(len(piv) - 5): # 滑动取六点窗口 p [v[1] for v in piv[i:i 6]] ok, _ check_impulse(p) if ok: cnt 1; sc.append(score_impulse(p)) print(pct, cnt, round(sum(sc) / len(sc), 1) if sc else 0)一个可以带走的技巧是给每个浪级点加确认时间字段记录该点在多少根 K 线之后才被 ZigZag 确认为转折。这个字段能直接暴露未来函数——如果某个标注的确认时间早于它自己的形成时间说明阈值太小导致 ZigZag 在盘中就反向记录了回测结果会系统性偏乐观。最后要说清这份图解的边界。波浪理论图解5.pdf 提供的是一套静态结论和示例判读不同人看同一张图能数出不同浪级这是方法本身的性质不是解析代码能修掉的缺陷。代码能做的只有三件事把图解里的几何和标注无损提取出来、用铁律把明显不成立的数法剔除、用比例给出可比较的得分。真正需要人来定的是浪级起点和主趋势方向这两个前提一旦这两点变了后面所有计算都是在正确答案之外做精确运算。把解析管线、判定函数和回放工具都搭好价值不在于自动数浪而在于每次改动前提时能在几秒内看到所有受影响的标的和浪型。本文还有配套的精品资源点击获取
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进