前阵子重构策略回测框架,把板块轮动的逻辑抽出来做了个独立模块。过程中发现,市场资金在不同板块间的迁移,本质上是个多体博弈——跟流体在管道里寻找最小阻力路径很像。
最早用的是一张 N×N 的热力矩阵,纵轴横轴都是行业板块,颜色深浅代表资金净流入。但矩阵的问题是:相邻关系丢失了。比如有色金属和煤炭在产业链上紧密相邻,但在字母序的矩阵里,它们可能隔了十个列——你看不出谁和谁挨着。
后来换了个思路:用 扇区图(Sector Map)。把每个板块画成一个扇形,角度由市值权重决定,半径方向上的「水位线」代表资金强度。这样一来,地理上相邻的扇区天然就是产业链上下游,轮动的视觉轨迹就变成了「水位依次漫过相邻扇区」——直观得多。
📊 扇区轮动示意图(占位)
实现上没用什么重型可视化库,就是 Canvas 加上 requestAnimationFrame 做逐帧插值。每个扇区的目标水位由日频的资金流数据驱动,过渡曲线用了缓出(ease-out cubic),模拟资金流动的「惯性」——一个板块开始吸金后不会立刻停止,会有一段自然的衰减。
// 扇区动画核心:资金水位插值 function tickSector(sector, target) { const dx = target.level - sector.level; if (Math.abs(dx) < 0.001) return; sector.velocity += dx * 0.02; sector.velocity *= 0.92; // 阻尼 sector.level += sector.velocity; }
阻尼系数的调参过程很有意思:0.90 以下动画太「黏」,跟不上真实行情;0.95 以上又太「弹」,看起来像在抽风。最后还是回到 0.92——一个没道理的、纯靠肉眼调的 magic number。
做可视化最大的教训:不要追求精确还原数据,要追求「看一眼就能感知到异常」。工具是认知的延伸,不是数据的中转站。
下一步想把板块间的关联强度也编码进去——如果两个扇区之间有资金联动,就在弧边画一条发光的连线,发光强度正比于相关系数。不过还没想好怎么避免视觉噪声,先搁着。有想法的朋友欢迎交流。
相关代码片段已经同步到 GitHub,做了脱敏处理,有兴趣的可以拿去跑着玩。
#系统设计 #可视化 #资金轮动