首页 / 资讯中心 / 文章详情

mplfinance砖型图与点数图实战:用价格重采样过滤噪声、识别趋势

mplfinance砖型图与点数图实战:用价格重采样过滤噪声、识别趋势 ★ FEATURED ARTICLE
如果你已经跟着这个系列用 mplfinance 把蜡烛图、成交量、均线子图玩熟了那么 v0.12.6a3 这个版本最值得花时间的就是 Price-movement 模块带来的砖型图和点数图。这两个图不画时间和不规则的摆动只画价格行为的“骨架”在识别趋势过滤噪声上比传统K线干净得多。我拿某指数ETF的日线数据连续捣鼓了好几天总算把这两类图从“能出图”推进到“能用在复盘和信号确认里”。这篇就把思路、参数、坑一次性说清楚。如果你只是想截图发个朋友圈那看个示例就行如果你想把这俩图真正用到自己的研究和复盘流程里建议从头看一遍尤其是后两章关于价格重采样和索引错位的部分很多报错都是在那里出的。1. 先搞清楚砖型图和点数图到底解决什么问题1.1 从K线到砖型过滤噪声的底层逻辑传统K线图最大的问题不是信息不够而是信息太多。一根日K开盘、最高、最低、收盘四个价位全画出来遇到震荡行情一天之内可能给你画好几根上下影线都很长的K线均线也跟着来回缠绕。你想回答“当前到底处于上涨趋势还是下跌趋势”这种基础问题时反而容易被短期杂音干扰。砖型图做了一件很极端的事把时间轴直接扔掉只保留“价格变化是否达到一个固定阈值”。设置一个砖块大小比如4元那么只有当收盘价相对上一根砖的收盘价变动超过4元时才产生一根新砖涨了4元画一根向上的绿砖跌了4元画一根向下的红砖价格波动小于4元的时候这段时间的所有K线都被当成“无意义噪声”直接忽略。这就是砖型图的灵魂它不是更快而是更慢。它把“短期波动不够格”的部分全过滤掉画出来的每一根砖都代表一次真正跨越阈值的方向性动作。所以你在砖型图上看到的趋势往往比K线图更晚出现但一旦出现延续性更强不容易被一两根影线骗过去。实际用起来砖型图最适合两类场景一是判断中期趋势方向配合支撑阻力位观察价格是否有效突破二是做策略回测时用砖型图过滤掉震荡市里的伪信号减少频繁开平仓。1.2 点数图的X/O体系与反转阈值思想点数图的历史比K线图还老它把价格运动抽象成两套符号X代表当前处于上涨过程O代表当前处于下跌过程。画图的时候每一列只能出现一种符号价格上涨超过一个格值就在当前这一列往上加一个X价格下跌超过一个格值就在当前这一列往下加一个O。关键逻辑在于反转如果当前在画X列多头行情价格回调幅度达到一定的格数就换到相邻列开始画O反之亦然。这种画法和砖型图最大的区别在于“反转阈值”这个思想。砖型图只看绝对涨跌幅度方向变了就画反方向的砖点数图则要求反向波动积累到一定格数才承认趋势反转这个积累过程在图上表现为一次换列。传统点数图常用三格反转也就是说下跌至少要达到3个格值的距离才会从X列切换成O列。这个机制天然帮你过滤掉了“假摔”和“假突破”。点数图的另一个优势是能比较清晰地看出密集成交区。X和O在某一价格水平反复堆叠形成横向的“拥堵带”这是K线图上很难直观量化的支撑阻力区间。我在复盘某只活跃票时发现点数图上的拥堵带往往和成交密集区高度吻合后续价格到这个位置也确实经常出现停顿。2. v0.12.6a3 的 Price-movement 实现拆解2.1 plot 函数里新增的两个 type 入口在这个版本里mpf.plot的type参数多了两个可选值renko和pnf。传入之后mplfinance 不会再像传统K线那样直接画原始数据而是先调用内部的price_movement模块对 Dataframe 做一次重采样把原始OHLC数据换算成“砖型标准数据”或“点数图标准数据”再交给底层绘图引擎按OHLC方式渲染。这一点很关键它意味着砖型图和点数图本质上还是用OHLC的画法渲染的只是喂进去的数据被替换了。所以很多你已经熟悉的参数比如style、figsize、panel_ratios、returnfig在砖型图和点数图下依然有效。但也有一些参数要格外小心尤其是mav、ema这类基于时间序列计算的指标它们用在重采样后的虚拟索引上意义不大版本里面甚至会主动忽略或警告。我们直接看用法import mplfinance as mpf import pandas as pd # 原始数据要求列名是 open/high/low/close/volume df pd.read_csv(my_data.csv, index_col0, parse_datesTrue) df df[[open, high, low, close, volume]].copy() # 砖型图 mpf.plot(df, typerenko, renko_size4.0, renko_offset0.0, styleyahoo, figsize(12, 7), titleRenko Demo) # 点数图 mpf.plot(df, typepnf, pnf_size1.0, pnf_offset0.0, styleyahoo, figsize(12, 7), titlePF Demo)跑通之后可以看到横轴上的数字不再是日期而是重采样后的“砖序号”或“列序号”这是符合预期的。值得留意的是直接在plot里写这两个 type 是最省事的方式但你如果需要对重采样后的数据进行二次加工也可以直接调用底层函数renko_df mpf.price_movement.renko(df, size4.0, offset0.0) pnf_df mpf.price_movement.pnf(df, size1.0, offset0.0)这两个函数返回的DataFrame同样是标准OHLC结构拿到手之后你可以自己再用typecandle去画我们后面会讲到它的一种实际用法。2.2 renko_size 和 pnf_size 的取值依据renko_size就是一块砖的价格高度pnf_size就是点数图里的一个格值。参数本身不复杂复杂的是怎么取值。我见过最偷懒的做法是随便填一个数比如填 5然后发现图上一共只有几根砖根本看不出结构。正确做法至少要参考两个东西一是当前标的的价格水平二是近期的价格波动幅度。举个具体例子某指数ETF价格在80到120元之间波动日均振幅在2到3元之间。如果你把renko_size设成 0.5那几乎每根K线的波动都能画出一块砖砖型图退化成一根根密集的小柱体过滤噪声的效果基本丧失。如果你把renko_size设成 20那可能两三周才出一根砖图形太稀疏没有实际参考价值。我通常先取近期收盘价的中位数med再按 1% 到 2% 的幅度估一个初始值然后微调价格80到120的时候砖块大小3到4比较舒服价格200到400的时候砖块大小5到8才容易出结构。点数图格值也类似但更依赖你希望多灵敏地捕捉反转。格值设小换列频繁图形横向展开很宽格值设大换列稀少图形更“钝”。表1是我在测试时常用的一组初始对照具体数值得结合你的标的和数据频率重新调。价格水平日波动率renko_size初始值pnf_size初始值20 - 502%左右1 - 20.5 - 180 - 1201.5%左右3 - 41200 - 4001.5%左右5 - 82 - 3500以上1%左右10 - 155 - 83. 实操从日线数据到砖型图的完整流程3.1 数据预处理OHLC对齐与 NaN 清理mplfinance 对输入数据的格式要求一直比较严格索引必须是DatetimeIndex列名必须是小写的open/high/low/close/volume。到了砖型图这里我会再加一道工序把数据质量检查得更仔细因为砖型的重采样逻辑依赖high、low、close之间的相对比较任何一个脏数据都可能导致整段重采样结果错位。我习惯在绘图前做这几步import pandas as pd df pd.read_csv(my_data.csv, index_col0, parse_datesTrue) df df[[open, high, low, close, volume]].copy() # 删除缺失关键价位的数据 df.dropna(subset[open, high, low, close], inplaceTrue) # 删除最高价小于最低价的异常行 df df.loc[df[high] df[low]].copy() # 删除收盘价小于等于0的行 df df[df[close] 0] # 索引去重 df df[~df.index.duplicated(keeplast)]这里每一步都有它的道理。索引去重尤其容易被忽略mplfinance在按时间顺序处理数据时如果遇到重复时间戳重采样后会出现并列的相同虚拟序号后面加指标时经常会报“index keys overlap”之类的错。另一点是顺序问题我建议先把数据按时间升序排好再做去重df df.sort_index()3.2 砖块颜色、边框和偏移量的调整砖型图的颜色沿用 mplfinance 的marketcolors机制也就是说上涨砖块的颜色对应up下跌砖块的颜色对应down。你可以直接用内置 style也可以自己定义一套颜色体系mc mpf.make_marketcolors(up#2ca02c, down#d62728, edgeinherit, wickinherit, volumeinherit) style mpf.make_mpf_style(marketcolorsmc, gridstyle--, y_on_rightTrue) mpf.plot(df, typerenko, renko_size4.0, stylestyle, figsize(12, 7))需要注意一个容易误解的细节第一根砖的方向在内部实现里是根据第一根K线的收盘价与renko_offset基准价的比较来确定的而不是看这根K线本身收阳还是收阴。如果你的数据起点恰好在下跌过程中第一根砖画成红色是正常的后续砖块颜色会沿着这根砖的方向延续直到价格反向波动超过一个砖块大小。renko_offset参数我平时很少动它相当于给第一块砖设定一个价格锚点。如果你发现第一块砖的下沿没有落在某个整数价位上看起来有点别扭可以设renko_offset为某个整数价格比如 100让第一块砖从100开始往上或往下累。3.3 用 style 统一多图外观我自己不太喜欢每次画图都重新声明一遍颜色和网格所以会先把style定成全局的。mplfinance 支持传入自定义style也支持通过mpf.available_styles()查看内置方案。对砖型图来说内置的yahoo和charles都还行前者是绿涨红跌后者是蓝涨红跌看着比较舒服。有一点必须提醒如果你原来的K线代码里挂了均线比如mav(5,10)或者挂了额外的指标线在切到typerenko或typepnf时最好先去掉。原因在于均线是沿着时间索引计算的而砖型图内部的索引已经被替换成了虚拟砖序号一条“砖均线”除了让你误判趋势没有任何参考意义。我在0.12.6a3版本里亲测过挂mav时它并不会报错但画出来的均线位置完全对不上横向坐标容易造成误读。如果你确实想在砖型图旁边看传统均线更稳妥的做法是上下两个面板分开放上面放K线图下面放砖型图两个图共用同一个标的但互不污染数据。4. 实操点数图的绘制与常见参数陷阱4.1 生成点数图时的最小化和列切换条件点数图的代码入口同样很简单mpf.plot(df, typepnf, pnf_size1.0, pnf_offset0.0, styleyahoo, figsize(12, 7), titlePoint Figure)出来之后你会看到一排排的X和O。这里的“列”就是传统点数图里的列画X的列表示当前被定义为上涨状态画O的列表示当前被定义为下跌状态。列之间的切换不是看单根K线涨跌而是看反向累积幅度是否达到内部反转条件。我在用的时候踩过一个很隐蔽的坑pnf_size不只是控制格子大小它会间接控制反转灵敏度。比如说某标的当前价格100pnf_size设为1.0传统三格反转意识要求反向波动达到3个格值也就是3元才换列如果你把pnf_size调到0.5那可能反向波动1.5元就换列了。不要以为调大pnf_size只是“把格子变大”它同时会显著减少换列次数让整个图变得更平缓。在实际绘制时我还习惯关闭成交量子图单纯看价格结构。点数图本来就没有时间轴加上成交量子图之后横轴对齐关系会很别扭。如果你确实需要参考量能我会把它放在上方独立绘制而不是和点数图共用横轴。4.2 与K线图同屏对比的布局技巧砖型图和点数图最大的优势在于“结构干净”但很多使用场景还是需要和原始K线做对比。mplfinance 支持returnfigTrue返回figure和axes对象我们可以利用这一点把两类图并列摆放。我常用的方式有两种。第一种是直接创建两个独立的figure分别绘制K线图和砖型图再导出图片拼在一起fig1, ax1 mpf.plot(df, typecandle, styleyahoo, returnfigTrue, figsize(12, 4.8)) fig2, ax2 mpf.plot(df, typerenko, renko_size4.0, styleyahoo, returnfigTrue, figsize(12, 4.8)) fig1.savefig(candle.png, dpi150, bbox_inchestight) fig2.savefig(renko.png, dpi150, bbox_inchestight)第二种方式是在一个figure里用两个subplot区域手动摆放。这个操作稍麻烦但好处是能精确控制比例。核心思路是先用mpf.plot(..., returnfigTrue)拿到底层axes再把砖型图数据画到指定子图上fig mpf.plot(df, typecandle, styleyahoo, returnfigTrue, figsize(12, 9), panel_ratios(3, 2)) ax_main fig.axes[0] # 这里可以用 price_movement.renko 拿到重采样数据后 # 再通过 pandas 的 DataFrame.plot 放到 ax_main 下方区域我坦白说第二种方式在0.12.6a3下需要处理坐标轴刻度冲突比较费时间。大多数时候我会选择两个独立图片并排观察简单直接不需要去迁就两个完全不同的横轴体系。5. 我踩过的坑与最终建议5.1 砖型图在回测中的滞后问题砖型图有一个固有缺陷不是bug而是模型本身带来的最后一根砖的方向和你当前的实际价格走势之间存在滞后。比如价格连续下跌画了一串红砖现在开始反弹但反弹幅度还不足以超过最后一根红砖顶部加一个砖块大小那么砖型图上仍然不会出现新的绿砖。使用者在“砖型图还没有发出反转信号”和“价格已经实际反弹”之间会产生一个时间差。这个滞后在策略信号里必须被正视。我在自己的一版回测逻辑里最初直接用砖型图最后一根砖的方向作为信号方向结果发现实盘模拟时总是慢半拍胜率看起来还行但回撤明显变大。后来改成“砖型图方向 收盘价确认”双条件即砖型图出现新方向砖之后还必须等当天收盘价站上关键价格位信号才会执行效果明显稳定一些。5.2 不同标的的参数敏感度差异砖块大小和点数格值真的没有一个万能参数。同一套参数用在低价区间、波动平缓的标的上图可能稀稀拉拉几乎看不到结构用在价格高、波动剧烈的标的上图形又会密到横向膨胀。我建议每次换标的时候都重新算一遍参数。你可以先取最近60个交易日的收盘价中位数med然后用med * 0.01到med * 0.02作为砖块大小的初始范围再根据图形观察调整。点数图格值可以稍大一点因为反转阈值本身就是格值的好几倍格值太小会让图形横向拉得很长不利于打印或看盘。5.3 这个版本里值得注意的限制v0.12.6a3 在我实测中已经能正常跑出砖型图和点数图但毕竟是alpha版本几个小限制需要知道。第一不要在typerenko或typepnf下同时使用mav和extra_indicators。重采样后的索引和原始索引不一致额外指标经常因为对齐失败报错或者画到完全错误的位置。第二数据量太少的时候比如只有几十根K线重采样后可能只剩几块砖图形空荡荡的这时候要把砖块大小调小让基础结构至少能铺满画面。第三砖型图和点数图对索引重复值非常敏感哪怕只有一行重复时间戳也可能导致重采样后出现无法预期的跳变先把索引处理好再画图。还有一个小排查技巧当你觉得图不对劲的时候先调用price_movement.renko或price_movement.pnf拿到重采样结果的DataFrame用print看中间数据。很多“画错”其实是重采样结果不符合预期和绘图引擎没关系中间数据一打印就什么都清楚了。最后再分享一个我自己的使用习惯砖型图和点数图我一般不会单独作为最终决策依据它们更适合用来和K线图相互验证。K线负责看当下砖型图负责看方向点数图负责看关键价位。三者合在一起复盘效率比单看任何一种图都要高很多。
阅读完成 · 觉得有帮助?
咨询建站