chanlun — 缠论技术分析 Rust 核心库
基于缠中说禅理论的量化技术分析核心库,将 Python 参考实现 (chan.py, ~4200行) 完整移植为 Rust,同时保持了 API 的完全兼容。
约 13,700 行 Rust 代码,39 个源文件,覆盖缠论的完整算法体系:K线包含处理、分型识别、笔划分、线段划分(含特征序列与缺口处理)、中枢识别(含延伸/扩展/多级中枢)、背驰检测(MACD/斜率/测度三种方式)、买卖点识别(18种类型)、多周期联立分析。
核心 crate 位于 chanlun/ 目录。Python 绑定通过独立的 chanlun-py crate 实现,使用 PyO3 将 Rust 核心封装为 Python 模块,API 与 chan.py 完全一致。所有类型名、方法名、字段名均使用中文标识符,与 Python 版本保持 1:1 对应。
目录
核心概念
缠论是一种源自中国的技术分析理论,将价格走势分解为层级结构,从最底层K线逐渐向上构造:
原始K线 → 包含处理 → 缠论K线 → 顶底分型 → 笔 → 线段 → 中枢 → 买卖点
核心理念:
- 走势终完美:任何级别的任何走势类型终要完成
- 自同构性:不同级别的走势呈现相同的形态结构,可通过递归分析进行多级别联立
- 完全分类:将走势分为上涨、下跌、盘整三种,每个节点都可通过买卖点找到操作依据
项目结构
chanlun/
├── Cargo.toml # 依赖: serde, byteorder, chrono, cached, tracing
└── src/
├── lib.rs # 模块注册 (#![allow(non_snake_case)])
├── main.rs # 入口(CLI 工具)
├── config.rs # 缠论配置 (62 字段, serde, 622 行)
│
├── types/ # 基础类型 (5 文件, 514 行)
│ ├── mod.rs # 重导出: 买卖点类型, 相对方向, 分型结构, 缺口, SyncF64
│ ├── direction.rs # 相对方向 (9 变体): 向上/向下/向上缺口/向下缺口/衔接向上/衔接向下/顺/逆/同
│ ├── bsp_type.rs # 买卖点类型 (18 变体): 一二三买/卖 + T1/T1P/T2/T2S/T3A/T3B
│ ├── fractal.rs # 分型结构 (5 变体) + 有高低 trait
│ ├── gap.rs # 缺口: 高/低价格区间 + 居中截取
│ └── sync_f64.rs # SyncF64: 基于 AtomicU64 的线程安全 f64 容器
│
├── kline/ # K线层 (2 文件, 1113 行)
│ ├── mod.rs #
│ ├── bar.rs # 原始K线 (388 行): OHLCV + RwLock<指标容器>, Clone/Display, 大端字节序序列化
│ └── chan_kline.rs # 缠论K线 (725 行): 经包含处理后的K线, 分型标记, AtomicI64/SyncF64 内部可变性
│
├── indicators/ # 技术指标 (6 文件, 1589 行)
│ ├── mod.rs # K线取值: 开/高/低/收/高低均值/高低收均值/开高低收均值
│ ├── macd.rs # 平滑异同移动平均线 (215 行): EMA 快慢线 + DIF/DEA/MACD柱
│ ├── rsi.rs # 相对强弱指数 (240 行): Wilder SMA 平滑 + 超买超卖线
│ ├── kdj.rs # 随机指标 (289 行): RSV → K → D → J + 超买超卖阈值
│ ├── boll.rs # 布林带 (169 行): 中轨/上轨/下轨 + 带宽
│ ├── calculator.rs # 指标计算器 (476 行): 增量计算 + 回填新指标 + 均线
│ └── container.rs # 指标容器 (202 行): 注册表模式, 动态指标存取
│
├── algorithm/ # 核心算法 (4 文件, 4987 行)
│ ├── mod.rs #
│ ├── bi.rs # 笔划分算法 (1009 行): 递归分析, 笔弱化, 次级成笔, 实际高/低点
│ ├── segment.rs # 线段划分算法 (2078 行): 特征序列, 缺口处理, 四种修正机制, 扩展线段
│ ├── hub.rs # 中枢识别算法 (1041 行): 重叠检测, 延伸/扩展, 第三买卖点, 多级中枢
│ └── divergence.rs # 背驰检测 (227 行): MACD背驰/斜率背驰/测度背驰 + 四种组合模式
│
├── structure/ # 结构体 (4 文件, 2089 行)
│ ├── mod.rs #
│ ├── dash_line.rs # 虚线 (1712 行): 笔/线段的通用抽象, 买卖意义, MACD行为统计, 分段, 背驰检测
│ ├── fractal_obj.rs # 分型 (344 行): 左中右构型, 分型模式开关, 强度判定, MACD分型匹配
│ ├── segment_feat.rs # 线段特征 (668 行): 特征序列元素, 文/武取极值, 静态分析, 分型序列
│ └── feat_fractal.rs # 特征分型 (62 行): 三线段特征元素构成的分型
│
├── business/ # 业务层 (4 文件, 1648 行)
│ ├── mod.rs #
│ ├── observer.rs # 观察者 (1138 行): 单周期分析器, 流式管线, 3级线段/扩展/混合扩展
│ ├── bsp.rs # 基础买卖点 + 买卖点工厂 (595 行): 18种类型, 偏移/失效/终结
│ ├── synthesizer.rs # K线合成器 (161 行): 小周期→大周期合成, 时间戳对齐
│ └── multi_frame.rs # 立体分析器 (192 行): 多周期联立, 合成器+观察者协调
│
└── utils/ # 工具 (2 文件, 145 行)
├── mod.rs #
├── datetime.rs # 时间戳转换: 字符串↔Unix时间戳
└── format.rs # 格式化: f64→最小字符串 (format_f64_g)
快速开始
Cargo 依赖
[]
= { = "path/to/chanlun" }
基本用法 — 单周期分析
use 缠论配置;
use K线;
use 观察者;
// 1. 创建配置(所有字段带默认值)
let 配置 = default;
// 2. 创建观察者(返回 Arc<RwLock<观察者>>)
let 观察员 = new;
// 3. 逐根投喂K线(流式增量分析,每根K线触发全管线运算)
for k线 in k线数据流
// 4. 读取分析结果
let obs = 观察员.read.unwrap;
println!;
println!;
println!;
// 遍历笔
for 笔 in &obs.笔序列
便捷投喂 — 直接从 OHLCV
let 观察员 = new;
let mut obs = 观察员.write.unwrap;
obs.投喂原始数据;
// ... 继续投喂 ...
加载 .nb 数据文件
let 观察员 = new;
观察员.write.unwrap.读取数据文件?;
多周期分析
use 立体分析器;
// 周期组: [最小输入周期, 更多显示周期...]
// 只投喂最小周期K线,大周期自动合成
let mut 分析器 = new;
// 投喂最小周期K线
for k线 in 小周期K线流
// 获取各周期观察者
if let Some = 分析器.获取观察者
数据管线
缠论分析按严格的层级顺序进行,每收到一根新K线,增量更新所有层级(而非批量重算)。这是该库适合实时交易系统的关键设计。
管线流程
原始K线 (K线)
│
├── 指标计算: MACD / RSI / KDJ / BOLL (增量更新, 含回填新指标)
│ ├── K线取值: 开/高/低/收/高低均值/高低收均值/开高低收均值
│ ├── 多参数组: MACD_参数列表 / RSI_周期列表 / KDJ_参数列表 / BOLL_参数列表
│ └── 均线组: SMA/EMA (均线_类型列表 × 均线_周期列表)
│
├── 包含处理 → 缠论K线 (缠论K线)
│ ├── 顺序包含合并 (顺方向取极值)
│ ├── 逆序包含合并 (更新时间/标的K线)
│ ├── 方向判定 (相对方向: 向上/向下/向上缺口/向下缺口/衔接/包含)
│ └── 合并替换模式: 缠K合并替换=false(原地修改) / true(产出新缠K)
│
├── 分型识别 → 分型 (分型)
│ ├── 由左中右三根缠论K线构成
│ ├── 类型: 顶分型 / 底分型 / 三连向上 / 三连向下 / 向右扩散
│ ├── 强度: 强 / 中 / 弱 (基于左中右收盘价关系)
│ ├── 分型模式: 全局开关控制缓存/实时读取
│ └── MACD柱子分型匹配 (左中右MACD柱形态判定)
│
├── 笔划分 → 笔 (虚线, 标识="笔", 级别=1)
│ ├── 递归分析算法: 顶底分型交替验证
│ ├── 成笔条件: 笔内元素数量≥5 (弱化模式≥3)
│ ├── 笔弱化策略: 放宽条件时尝试次高/次低成笔
│ ├── 实际高/低点选择: first/last (笔内相同终点取舍)
│ ├── 笔内起始分型包含整笔验证
│ └── 笔内原始K线包含整笔验证
│
├── 线段划分 → 线段 (虚线, 标识="线段", 级别=2)
│ ├── 特征序列提取: 从笔序列中提取同向特征序列元素 (线段特征.静态分析)
│ ├── 缺口处理:
│ │ ├── 有缺口 (老阴/老阳): 严格包含处理, 等待特征分型完成
│ │ └── 无缺口 (小阳/少阴): 允许逆序包含
│ ├── 四种修正机制 (依次尝试):
│ │ ├── _缺口突破: 老阳/老阴时价格突破前线段极值
│ │ ├── _非缺口下穿刺: 贯穿伤后出现方向相同的3笔
│ │ ├── _缺口后紧急修正: 前一线段有缺口时自动修正
│ │ └── _修正: 配置启用的短路修正 (≥9笔)
│ ├── 线段破坏判定: 新线段形成后前一线段被破坏
│ ├── 3级递归: 线段 → 线段<线段> → 线段<线段<线段>>
│ └── 扩展线段分析: 扩展线段 → 扩展线段<扩展线段> → ...
│
├── 中枢识别 → 中枢 (中枢)
│ ├── 基础检查: 三条连续虚线重叠且方向关系正确
│ ├── 中枢延伸: 后继虚线未离开中枢则加入基础序列
│ ├── 第三买卖点: 虚线离开中枢后不回中枢, 记录第三买卖线
│ ├── 中枢完成: 第三买卖线确立后开始新中枢
│ ├── 中枢扩展: ≥9段时调用扩展分析生成扩展中枢
│ └── 多级中枢:
│ ├── 笔中枢 (级别=1, 基于笔序列)
│ ├── 线段中枢 (级别=2, 基于线段序列)
│ ├── 扩展线段中枢 (基于扩展线段序列)
│ ├── 混合扩展中枢 (基于扩展线段<线段>序列)
│ └── 线段<线段>中枢 / 扩展线段<扩展线段>中枢 等
│
└── 买卖点识别 → 基础买卖点 (18种类型)
├── 6 类经典买卖点: 一买/一卖/二买/二卖/三买/三卖
├── 12 类扩展买卖点: T1/T1P/T2/T2S/T3A/T3B 各含买卖
├── 指标匹配: MACD柱子匹配 / KDJ金叉死叉 / RSI超买超卖
├── 背驰确认: MACD背驰 / 斜率背驰 / 测度背驰
├── 中枢来源策略: 实 / 虚 / 合
├── 买卖意义缓存: LRU 128条目, 指针身份key
└── 偏移/失效偏移/终结K线管理
流式增量处理
观察者.__处理数据 每收到一根新K线:
- 计算指标并挂载到新K线
- 执行缠K包含处理,产出缠K
- 识别分型,添加到分型序列
- 递归分析笔(可能生成新笔或修改最后一笔)
- 递归分析中枢(笔中枢)
- 递归分析线段(3级递归:线段→线段<线段>→线段<线段<线段>>)
- 递归分析扩展线段(3级递归)
- 递归分析混合扩展线段(3级递归,源序列为线段序列组[i])
每步都只处理最后几个元素,时间复杂度 O(1) 均摊。
核心类型详解
枚举类型
相对方向 (types::direction)
用于描述两个价格区间(两根K线或两个分型)之间的位置关系,共 9 个变体:
| 变体 | 说明 | 示例场景 |
|---|---|---|
向上 |
后K线高低点均高于前K线,且不构成缺口 | 正常上涨 |
向下 |
后K线高低点均低于前K线,且不构成缺口 | 正常下跌 |
向上缺口 |
后K线低点 > 前K线高点 | 大幅高开 |
向下缺口 |
后K线高点 < 前K线低点 | 大幅低开 |
衔接向上 |
后K线低点 == 前K线高点 | 精准衔接上涨 |
衔接向下 |
后K线高点 == 前K线低点 | 精准衔接下跌 |
顺 |
前K线包含后K线(前高≥后高 且 前低≤后低) | 顺序包含 |
逆 |
后K线包含前K线(前高≤后高 且 前低≥后低) | 逆序包含 |
同 |
两K线高低点完全相同 | 重复数据 |
提供方法:翻转(), 是否向上(), 是否向下(), 是否包含(), 是否缺口(), 是否衔接(), 分析(前高,前低,后高,后低)
分型结构 (types::fractal)
三根K线构成的结构形态,共 5 个变体:
| 变体 | 左中右关系 |
|---|---|
上 |
向上类 + 向上类 |
下 |
向下类 + 向下类 |
顶 |
向上类 + 向下类(Λ 形) |
底 |
向下类 + 向上类(V 形) |
散 |
逆序包含 + 逆序包含 |
提供方法:分析(左,中,右, 可以逆序包含, 忽视顺序包含) — 通用分型识别
买卖点类型 (types::bsp_type)
18 种买卖点分类:
| 类别 | 买点 | 卖点 | 说明 |
|---|---|---|---|
| 一类 | 一买 |
一卖 |
中枢背驰后的第一类买卖点 |
| 二类 | 二买 |
二卖 |
回调到中枢内的第二类买卖点 |
| 三类 | 三买 |
三卖 |
离开中枢后不回中枢的第三类买卖点 |
| 扩展T1 | T1买 |
T1卖 |
事后确认型 |
| 扩展T1P | T1P买 |
T1P卖 |
事后确认型+ |
| 扩展T2 | T2买 |
T2卖 |
中枢回调型 |
| 扩展T2S | T2S买 |
T2S卖 |
中枢回调次级 |
| 扩展T3A | T3A买 |
T3A卖 |
第三类扩展A |
| 扩展T3B | T3B买 |
T3B卖 |
第三类扩展B |
提供方法:是买点(), 是卖点()
数据结构详解
K线 (kline::bar) — 原始OHLCV + 指标
K线 {
标识, 序号, 周期, 时间戳,
高, 低, 开盘价, 收盘价, 成交量,
指标: RwLock<指标容器> // MACD/RSI/KDJ/BOLL/均线
}
- 实现
Clone(深拷贝, 包括指标容器) - 支持大端字节序序列化 (
to_bytes()→ 48字节,from_bytes()) - 提供
创建普K()工厂方法,相等()结构化校验 获取MACD()计算两K线间的 MACD 柱面积 (阳/阴/合/总)截取rc()按 Arc 指针截取序列片段
缠论K线 (kline::chan_kline) — 包含处理后的K线
缠论K线 {
序号: AtomicI64,
时间戳: AtomicI64,
高: SyncF64, // 经包含处理可能被拉高
低: SyncF64, // 经包含处理可能被压低
方向: RwLock<相对方向>,
分型: RwLock<Option<分型结构>>,
分型特征值: SyncF64, // 历史高低点极值
周期, 标识,
原始起始序号, // 包含处理前
原始结束序号: AtomicI64, // 包含处理后更新
标的K线: RwLock<Arc<K线>>,
买卖点信息: RwLock<HashSet<String>>,
}
- 核心算法:
_兼并()— 顺序/逆序包含合并, 重复提交检测, 原地修改 分析()— 完整的普K→缠K+分型管线- 指标匹配:
与MACD柱子匹配()/与RSI匹配()/与KDJ匹配() - 时间戳对齐:跨周期对齐至基线
相等()— 20+ 字段逐项递归校验
分型 (structure::fractal_obj) — 顶/底分型
分型 {
左: Option<Arc<缠论K线>>,
中: Arc<缠论K线>, // 核心K线
右: Option<Arc<缠论K线>>,
结构: 分型结构, // 构造时缓存
时间戳: i64, // 构造时缓存
分型特征值: f64, // 构造时缓存
}
- 分型模式 (
分型模式: AtomicBool): 全局开关true(默认) —时间戳()/结构()/分型特征值()返回构造时缓存值false— 从中缠K 实时读取(逆序包含后使用)
- 提供方法:
强度()(强/中/弱),关系组()(左中右三组关系),与MACD柱子分型匹配() 相等()— 递归校验左/中/右缠K + 自有缓存字段- 实现
有高低trait: 高/低 → 中.高/中.低
虚线 (structure::dash_line) — 笔和线段的通用数据结构
虚线 {
标识: RwLock<String>, // "笔"/"线段"/"扩展线段"/"线段<线段>" 等
序号: AtomicI64,
级别: AtomicI64, // 笔=1, 线段=2, 线段<线段>=3, ...
文: Arc<分型>, // 起点分型(不可变)
武: RwLock<Arc<分型>>, // 终点分型(可变,用于动态更新)
有效性: AtomicBool,
基础序列: RwLock<Vec<Arc<虚线>>>, // 构成虚线的子级虚线序列
特征序列: RwLock<Vec<Option<Arc<线段特征>>>>, // 线段特征序列
实_中枢序列: RwLock<Vec<Arc<中枢>>>,
虚_中枢序列: RwLock<Vec<Arc<中枢>>>,
合_中枢序列: RwLock<Vec<Arc<中枢>>>,
确认K线: RwLock<Option<Arc<缠论K线>>>,
模式: RwLock<String>, // 买卖点匹配模式
_特征序列_显示: AtomicBool,
前一缺口: RwLock<Option<缺口>>,
前一结束位置: RwLock<Option<Arc<虚线>>>,
短路修正: AtomicBool,
}
- 静态工厂:
创建笔()(级别=1),创建线段()(级别=笔级别+1, 基础序列=笔序列) - 属性:
方向(),高(),低(),之前是(),之后是() - 数据访问:
获取普K序列(),获取缠K序列(),获取_武()(递归到底层笔) - 买卖点模式匹配:
全量/任意/配置/相对四种指标组合策略 - MACD相关:
计算MACD柱子均值(),武之MACD均值(),武之MACD极值() - 趋势分析:
计算K线序列MACD趋向背驰()(MACD柱/DIF/DEA三项背驰) - 分段:
计算MACD柱子分段()(按正负号分段) - 行为统计:
统计MACD行为()→MACD行为统计 {DIF上下穿0, DEA上下穿0, 金叉/死叉次数, 密集交叉区域} - 核心判断:
买卖意义()— LRU 缓存 128 条目,指针身份作为 key - 序列化:
获取数据文本()— 笔输出简洁格式,线段输出完整格式 相等()— 递归校验文/武/基础序列/特征序列/中枢序列/确认K线/模式/缺口/结束位置等全部字段
线段特征 (structure::segment_feat) — 特征序列元素
线段特征 {
序号: AtomicI64,
标识: RwLock<String>,
线段方向: 相对方向,
基础序列: Vec<Arc<虚线>>, // 构成该元素的虚线序列
}
- 虚拟端点:
文()— 取特征值最大/最小的起点分型 - 虚拟端点:
武()— 取特征值最大/最小的终点分型 - tiebreaker: 同特征值时取后时间戳
高()/低()— 文/武中分型特征值的较大/较小者方向()— 线段方向的翻转- 静态分析:从虚线序列生成特征序列元素列表,含分型替换逻辑
- 分型序列:从连续特征序列元素中提取特征分型
特征分型 (structure::feat_fractal)
特征分型 {
左: Arc<线段特征>,
中: Arc<线段特征>,
右: Arc<线段特征>,
结构: 分型结构, // 由左中右三元素分析得出
}
中枢 (algorithm::hub)
中枢 {
序号: AtomicI64,
标识: RwLock<String>, // "笔中枢<0>"/"线段中枢<1>" 等
级别: AtomicI64,
基础序列: RwLock<Vec<Arc<虚线>>>, // 至少3根, 延伸后可达9+
第三买卖线: RwLock<Option<Arc<虚线>>>,
本级_第三买卖线: RwLock<Option<Arc<虚线>>>,
}
- 属性:
高()(前三根虚线的最高重叠),低()(前三根虚线的最低重叠) 文()→武()→方向()延伸序列()→ 首尾之外的虚线获取数据文本()— 完整中枢结构化描述相等()— 逐项递归校验基础序列和第三买卖线- 向序列中添加/更新中枢(含显示名称映射)
基础买卖点 (business::bsp)
基础买卖点 {
备注: String,
类型: 买卖点类型,
买卖点分型: Arc<分型>,
买卖点K线: Arc<缠论K线>, // = 买卖点分型.中
当前K线: Arc<K线>,
失效K线: Option<Arc<K线>>,
终结K线: Option<Arc<K线>>,
破位值: f64,
结构: Option<分型结构>,
当前缠K序号: Option<i64>,
}
偏移()— 当前缠K序号与买卖点K线序号的差有效性()— 失效K线是否存在
服务类型
| 类型 | 职责 | 位置 |
|---|---|---|
观察者 |
单周期分析器, 接收K线流, 维护所有层级序列, 3级递归线段分析 | business::observer |
K线合成器 |
小周期→大周期合成, 高取max/低取min/量求和, 时间戳对齐 | business::synthesizer |
立体分析器 |
多周期联立, 内含合成器 + 每周期一个观察者, 对齐缠K序列 | business::multi_frame |
静态算法类
| 类型 | 职责 | 位置 |
|---|---|---|
笔 |
笔划分: 分型→笔 (递归分析, 笔弱化, 次级成笔, 实际高/低点, 是否背驰过) | algorithm::bi |
线段 |
线段划分: 笔→线段 (特征序列+缺口处理+四种修正+扩展分析+内部背驰判断) | algorithm::segment |
中枢 |
中枢识别: 虚线→中枢 (重叠检测+延伸/扩展+第三买卖点+向序列添加) | algorithm::hub |
背驰分析 |
背驰检测: MACD/斜率/测度 + 全量/任意/配置/相对四种组合 | algorithm::divergence |
指标计算器 |
指标增量计算: MACD/RSI/KDJ/BOLL + 回填新指标 + 均线 | indicators::calculator |
配置体系
缠论配置 是一个 serde 驱动的结构体,62 个字段全部带默认值,支持 JSON 往返和部分反序列化容错。
完整配置表
基础设置
| 字段 | 默认值 | 说明 |
|---|---|---|
标识 |
"bar" |
品种标识 |
缠K设置
| 字段 | 默认值 | 说明 |
|---|---|---|
缠K合并替换 |
false |
false=原地修改, true=产出新缠K |
笔设置
| 字段 | 默认值 | 说明 |
|---|---|---|
笔内元素数量 |
5 |
成笔最低缠K数 |
笔内相同终点取舍 |
false |
false=取first, true=取last |
笔内起始分型包含整笔 |
false |
起点分型区间必须包含整笔 |
笔内起始分型包含整笔_包括右 |
false |
同上+包含右端点 |
笔内原始K线包含整笔 |
false |
原始K线区间必须包含整笔 |
笔次级成笔 |
false |
允许在非分型处成笔 |
笔弱化 |
false |
放宽成笔条件 |
笔弱化_原始数量 |
3 |
弱化模式最小原始K线数 |
线段设置
| 字段 | 默认值 | 说明 |
|---|---|---|
线段_非缺口下穿刺 |
false |
非缺口下的穿刺处理 |
线段_特征序列忽视老阴老阳 |
false |
缺口时不严格处理包含 |
线段_缺口后紧急修正 |
true |
缺口后自动修正 |
线段_修正 |
false |
短路修正(不推荐) |
线段内部中枢图显 |
true |
线段内部中枢图表显示 |
扩展线段_当下分析 |
false |
扩展线段实时分析模式 |
分析开关
| 字段 | 默认值 | 说明 |
|---|---|---|
分析笔 |
true |
|
分析线段 |
true |
|
分析扩展线段 |
true |
|
分析笔中枢 |
true |
|
分析线段中枢 |
true |
终止
| 字段 | 默认值 | 说明 |
|---|---|---|
手动终止 |
"" |
手动终止时间字符串 |
指标设置
| 字段 | 默认值 | 说明 |
|---|---|---|
计算指标 |
true |
是否计算技术指标 |
计算BOLL |
false |
是否计算布林带 |
指标计算方式 |
"收" |
开/高/低/收/高低均值/高低收均值/开高低收均值 |
MACD 参数
| 字段 | 默认值 | 说明 |
|---|---|---|
平滑异同移动平均线_快线周期 |
13 |
|
平滑异同移动平均线_慢线周期 |
31 |
|
平滑异同移动平均线_信号周期 |
11 |
|
MACD_参数列表 |
[] |
多参数变体: Vec<(key, 快, 慢, 信号)> |
RSI 参数
| 字段 | 默认值 | 说明 |
|---|---|---|
相对强弱指数_周期 |
13 |
RSI计算周期 |
相对强弱指数_移动平均线周期 |
13 |
RSI SMA平滑周期 |
相对强弱指数_超买阈值 |
75.0 |
|
相对强弱指数_超卖阈值 |
25.0 |
|
RSI_周期列表 |
[] |
多周期变体: Vec<(key, 周期)> |
KDJ 参数
| 字段 | 默认值 | 说明 |
|---|---|---|
随机指标_RSV周期 |
13 |
|
随机指标_K值平滑周期 |
5 |
|
随机指标_D值平滑周期 |
5 |
|
随机指标_超买阈值 |
80.0 |
|
随机指标_超卖阈值 |
20.0 |
|
KDJ_参数列表 |
[] |
多参数变体 |
BOLL 参数
| 字段 | 默认值 | 说明 |
|---|---|---|
布林带_周期 |
20 |
|
布林带_标准差倍数 |
2.0 |
|
BOLL_参数列表 |
[] |
多参数变体 |
均线参数
| 字段 | 默认值 | 说明 |
|---|---|---|
均线_类型列表 |
[] |
["SMA", "EMA", ...] |
均线_周期列表 |
[] |
[5, 10, 20, ...] |
推送/图表显示
| 字段 | 默认值 |
|---|---|
图表展示 |
true |
推送K线 |
true |
推送笔 |
true |
推送线段 |
true |
推送中枢 |
true |
图表展示_笔 |
true |
图表展示_线段 |
true |
图表展示_扩展线段 |
true |
图表展示_扩展线段_线段 |
true |
图表展示_线段_线段 |
true |
图表展示_中枢_笔 |
true |
图表展示_中枢_线段 |
true |
图表展示_中枢_扩展线段 |
true |
图表展示_中枢_扩展线段_线段 |
true |
图表展示_中枢_线段_线段 |
true |
图表展示_中枢_线段内部 |
true |
买卖点设置
| 字段 | 默认值 | 说明 |
|---|---|---|
买卖点偏移 |
1 |
最大偏移量 |
买卖点激进识别 |
false |
|
买卖点与MACD柱强相关 |
false |
|
买卖点错过误差值 |
0.01 |
|
买卖点_指标模式 |
"配置" |
任意/配置/全量/相对 |
买卖点_指标匹配_MACD |
true |
|
买卖点_指标匹配_KDJ |
true |
|
买卖点_指标匹配_RSI |
true |
|
买卖点_背离率 |
INFINITY |
不使用 |
买卖点_T2_回调阈值 |
1.0 |
|
买卖点_T2S_最大层级 |
3 |
|
买卖点_峰值条件 |
false |
|
买卖点_计算方式 |
"峰" |
|
买卖点_计算线段BSP1 |
true |
|
买卖点_处理BSP2 |
true |
|
买卖点_计算线段BSP3 |
true |
|
买卖点_依赖T1 |
true |
|
买卖点_中枢来源 |
"合" |
实/虚/合 |
买卖点_调试输出 |
false |
背驰设置
| 字段 | 默认值 | 说明 |
|---|---|---|
线段内部背驰_MACD |
true |
使用 MACD 背驰 |
线段内部背驰_斜率 |
true |
使用斜率背驰 |
线段内部背驰_测度 |
true |
使用测度背驰 |
线段内部背驰_模式 |
"相对" |
任意/配置/全量/相对 |
文件
| 字段 | 默认值 | 说明 |
|---|---|---|
加载文件路径 |
"" |
数据文件路径 |
配置方法
// JSON 往返
let json = config.to_json; // 序列化
let config2 = from_json?; // 反序列化
// 文件 I/O
config.保存配置?; // 保存
let loaded = 加载配置?; // 加载
// 部分反序列化(缺失字段→默认值)
let config: 缠论配置 = from_str?;
// 静默模式
let silent = config.不推送; // 所有推送/展示开关设为 false
// 差异对比
let diffs = config_a.对比; // → ["笔内元素数量", ...]
// 多参数解析(列表非空则使用列表,否则使用默认单组)
let macd参数 = config._解析MACD参数列表; // Vec<(key, 快, 慢, 信号)>
let rsi周期 = config._解析RSI周期列表; // Vec<(key, 周期)>
let kdj参数 = config._解析KDJ参数列表; // Vec<(key, RSV, K, D)>
let boll参数 = config._解析BOLL参数列表; // Vec<(key, 周期, 倍数)>
// 复合key重组(兼容旧版 "1_open" 格式)
let configs = 按序号重组字典;
算法模块
笔划分 (algorithm::bi, 1009 行)
笔 是一个纯静态方法命名空间,核心方法:
| 方法 | 说明 |
|---|---|
分析() |
主算法:接收分型,递归分析生成笔 |
_获取缠K数量() |
计算可成笔的缠K数量(含弱化模式) |
_实际高点() / _实际低点() |
潜在成笔区域的最高/最低缠K |
_获取成笔核心分型() |
笔弱化模式下获取次高/次低成笔的候选分型 |
根据缠K找笔() |
在笔序列中查找包含指定缠K的笔 |
是否背驰过() |
检查笔范围内是否发生过MACD背驰 |
关键设计:
- 笔弱化:当严格条件不满足时,允许
笔弱化_原始数量(≥3) 根原始K线成笔 - 次级成笔:允许次高/次低成笔的候选分型
- 相同终点取舍:false=取first, true=取last (Python
list.index行为) - 笔内验证:起始分型包含整笔 / 原始K线包含整笔
线段划分 (algorithm::segment, 2078 行)
线段 是最复杂的算法模块,核心方法:
| 方法 | 说明 |
|---|---|
分析() |
主算法:从笔序列计算线段 |
扩展分析() |
扩展线段分析(不同的缺口处理策略) |
分割序列() |
将特征序列分割为前/后/三/贯穿伤四个部分 |
特征序列状态() |
返回 (特征_a, 特征_b, 特征_c) 布尔标志 |
四象() |
判断特征序列的类型:老阳/老阴/小阳/少阴 |
获取缺口() |
获取特征序列第一二元素间的缺口 |
判断线段内部是否背驰() |
线段内部进入段vs离开段背驰判断 |
是否背驰过() |
线段范围内是否发生过背驰 |
获取所有停顿位置() |
获取线段内部所有可能的停顿位置 |
获取内部中枢序列() |
获取线段内部的中枢序列 |
四种修正机制(按优先级):
_缺口突破— 老阳/老阴状态 + 价格突破前线段极值 → 线段完成_非缺口下穿刺— 贯穿伤存在 + 方向相同的3笔 → 线段完成_缺口后紧急修正— 前一线段有缺口 + 价格反向突破 → 修正前一结束位置_修正— 短线路径 (≥9笔) → 快速完成
中枢识别 (algorithm::hub, 1041 行)
中枢 既是数据结构也是算法命名空间:
| 方法 | 说明 |
|---|---|
分析() |
主算法:虚线→中枢,同时识别第三买卖点 |
线段扩展分析() |
中枢扩展:≥9段时生成扩展中枢 |
高() |
前三根虚线重叠区域的最高值 |
低() |
前三根虚线重叠区域的最低值 |
文() |
第一根虚线的起点分型 |
武() |
第三根虚线的终点分型 |
方向() |
当中枢高 > 中枢低时为向上,否则向下 |
延伸序列() |
首尾之外的虚线 |
获取离开虚线() |
找到离开中枢的虚线(第三买卖点) |
获取剩余虚线() |
第三买卖点之后的虚线 |
获取第N买卖线() |
获取第N个买卖点相关的虚线 |
中枢识别核心逻辑:
- 基础检查:三条连续虚线必须重叠(
max(低) < min(高))且方向关系正确 - 中枢延伸:在后继虚线中找离开中枢的虚线,未离开则加入基础序列
- 第三买卖点:虚线离开中枢且不回中枢,记录
第三买卖线 - 中枢完成:
第三买卖线确立后,在上方虚线开始新中枢 - 中枢扩展:≥9段时调用
线段扩展分析生成扩展中枢
背驰检测 (algorithm::divergence, 227 行)
背驰分析 提供三种检测方式:
| 方式 | 原理 | 方法 |
|---|---|---|
| MACD背驰 | 进入段vs离开段的MACD柱面积对比 (`阳 + | 阴 |
| 斜率背驰 | 价格变化速率 (dy/dx) 减弱 | 斜率背驰() |
| 测度背驰 | 价格-时间向量长度 (√(dx²+dy²)) 缩减 | 测度背驰() |
四种组合模式:
| 模式 | 条件 |
|---|---|
全量 |
MACD 且 斜率 且 测度 全满足 |
任意 |
MACD 或 斜率 或 测度 任意满足 |
配置 |
根据 线段内部背驰_MACD/斜率/测度 配置组合 |
相对 |
至少两种方式满足(多数投票) |
技术指标
所有指标位于 indicators/ 模块,均支持首次计算和增量计算两种模式。
统一指标容器 (indicators::container)
基于注册表模式,通过 指标值 枚举统一管理五种指标类型:
- 预注册默认槽位:
macd,rsi,kdj,boll,均线,单值 - 支持多参数变体:
MACD_13_31_11,RSI_14,KDJ_9_3_3等 - 便捷方法:
macd(),rsi(),kdj(),boll(),均线() - 动态注册:
注册(name, default_value),设置(name, value)
指标计算器 (indicators::calculator, 476 行)
指标计算器::计算并挂载(全序列, 配置) 是一次完整的指标计算周期:
- MACD组 — 遍历
_解析MACD参数列表(),对每个 (key, 快, 慢, 信号) 计算 - RSI组 — 遍历
_解析RSI周期列表() - KDJ组 — 遍历
_解析KDJ参数列表() - BOLL组 — 遍历
_解析BOLL参数列表() - 均线 — 遍历
均线_类型列表 × 均线_周期列表,MA/EMA 计算 - 回填新指标 — 如果当前K线有前序K线遗漏的指标,回溯填充
K线取值 (K线取值()) 支持 7 种计算方式:
开 / 高 / 低 / 收 / 高低均值 / 高低收均值 / 开高低收均值
MACD (indicators::macd, 215 行)
平滑异同移动平均线 {
时间戳, 收盘价, 快线周期, 慢线周期, 信号周期,
DIF: Option<f64>, // 快线EMA - 慢线EMA
DEA: Option<f64>, // DIF的信号线EMA
MACD柱: f64, // 2 * (DIF - DEA)
快线EMA: Option<f64>, // 计算中间值(增量用)
慢线EMA: Option<f64>,
DEA_EMA: Option<f64>,
}
首次计算(收盘价, 时间戳, 快线周期, 慢线周期, 信号周期)— 初始EMA=SMA近似增量计算(prev, 收盘价, 时间戳)— EMA递推公式计算K线MACD(普K序列, 快, 慢, 信号)— 遍历序列批量计算
RSI (indicators::rsi, 240 行)
相对强弱指数 {
时间戳, 收盘价, 周期,
超买阈值, 超卖阈值,
RSI: Option<f64>,
RSI_SMA: Option<f64>, // RSI的SMA信号线
平均上涨: Option<f64>, // Wilder平滑中间值(增量用)
平均下跌: Option<f64>,
}
- Wilder SMA 平滑算法
首次计算()— 初始均值=SMA增量计算()— Wilder递推
KDJ (indicators::kdj, 289 行)
随机指标 {
时间戳, 最高价, 最低价, 收盘价,
RSV周期, K值平滑周期, D值平滑周期,
超买阈值, 超卖阈值,
K: Option<f64>, // RSV的移动平均
D: Option<f64>, // K的移动平均
J: Option<f64>, // 3*K - 2*D
}
首次计算(全体)— 从序列计算初始KDJ值增量计算(全体, 当前, 周期, K平滑, D平滑)— 增量更新
BOLL (indicators::boll, 169 行)
布林带 {
时间戳, 收盘价, 周期,
标准差倍数,
中轨: Option<f64>, // SMA
上轨: Option<f64>, // 中轨 + 倍数 * 标准差
下轨: Option<f64>, // 中轨 - 倍数 * 标准差
}
线程安全与并发
内部可变性策略
缠K/虚线/中枢等结构体需要在多 Arc 共享时支持原地修改(如笔动态替换武、中枢延伸添加虚线)。Rust 中 Arc 的 &self 是不可变的,因此大量字段使用以下策略实现内部可变性:
| 机制 | 类型 | 适用场景 |
|---|---|---|
SyncF64 |
AtomicU64 位转换 |
价格字段 (高/低/分型特征值),需跨线程原子读写 |
AtomicI64 |
原子整数 | 序号/时间戳/原始结束序号 |
AtomicBool |
原子布尔 | 有效性/短路修正/特征序列显示 |
RwLock<T> |
读写锁 | 复杂字段 (Arc<分型>/Vec/标识/模式/中枢序列) |
全局缓存
- 买卖意义缓存:
LazyLock<Mutex<LruCache<(usize, usize), (bool, String)>>>— 128条目,key为 (虚线指针, 观察者指针) 地址对 - 与 Python 对齐:Python 使用
@lru_cache(maxsize=128)装饰器,Rust 使用全局LazyLock<Mutex<>>替代 PyO3 的thread_local!(解决跨线程不可见问题)
Send + Sync 保证
所有核心数据结构(缠论K线, 虚线, 中枢, 观察者)均实现 Send + Sync,可以安全地跨线程传递和共享:
// 编译期断言
;
;
;
观察者 使用 Arc<RwLock<观察者>> 模式,多线程可以并发读取同一个观察者的分析结果。
RwLock 死锁预防
Rust 的 RwLock 是非递归锁。在已有读锁的线程中尝试获取写锁会死锁。核心规则:
- 将读锁作用域化:在所有调用带写锁的方法之前释放
prev_guard - 典型模式:
{ let prev_guard = ... ; /* 使用 prev_guard */ } // 作用域结束释放 → 安全调用回填
Python 绑定
Python 调用通过独立的 chanlun-py crate 提供,使用 PyO3 包装。所有类型、方法、字段名与 chan.py 完全一致,API 兼容。
# 创建/修改配置
=
= 7
=
# 创建观察者
=
# 通过 Python 属性直接修改配置(自动同步到核心层)
= True
# 投喂K线
=
# 获取分析结果
# 全局开关
= False # 从缠K实时读取分型值(逆序包含后使用)
绑定层特性
- 配置缓存:
obs.配置返回同一个 Python 对象(而非每次新建),确保 Python 端修改后 Rust 端可见 - 分型模式: 模块级
chanlun.分型模式getter/setter,控制分型值的读取策略 - 数据文件兼容:
chanlun.读取数据文件("file.nb", config, 观察员=obs)与 Python 版签名一致 - 跨线程身份: 全局
LazyLock保证跨线程is判断一致
数据序列化
K线二进制格式
与 Python struct.pack(">6d") 完全兼容的大端字节序格式,每根K线 48 字节:
| 偏移 | 大小 | 字段 |
|---|---|---|
| 0 | 8 字节 | 时间戳 (Unix秒 as f64) |
| 8 | 8 字节 | 开盘价 |
| 16 | 8 字节 | 最高价 |
| 24 | 8 字节 | 最低价 |
| 32 | 8 字节 | 收盘价 |
| 40 | 8 字节 | 成交量 |
// 序列化
let bytes: = k线.to_bytes;
// 反序列化
let k线 = 读取大端字节数组;
// 解析原始数据(不构造K线)
let = 解析原始数据?;
// 批量保存
保存到DAT文件?;
配置 JSON
- 使用
#[serde(default)]实现前向/后向兼容,缺失字段自动使用默认值 - 字符串枚举字段(
指标计算方式,买卖点_指标模式,线段内部背驰_模式)带有自定义反序列化器,非法值自动回退默认值并发出warn!日志
结构化相等校验
所有核心结构体都实现了 相等(&self, other, 浮点容差) → (bool, String) 方法,递归校验包括:
- 浮点字段使用容差比较(而非直接
==) Arc指针共享的结构体深度校验值语义- 嵌套容器(Vec, Option, HashMap)逐一比对
- 返回详细的差异描述,便于调试
测试
核心层测试 (chanlun/)
测试覆盖:
- 配置: 默认值、JSON 往返、部分反序列化、非法值回退、不推送模式
- K线: 方向判定、大端字节序列化往返
- 缠K: 创建/镜像/包含合并/分型识别、三K线生成分型
- 分型: 左中右构造、字段读写、关联指针
- 虚线: Cell/RefCell 读写、Clone 后 Rc 指针一致、多 Arc 共享可见性、获取武递归、武修改不影响文
- 线段特征: 文取max/min, 武取max/min, tiebreaker, 添加/删除
- 中枢: 字段读写、Clone 后指针一致、多 Arc 共享
- 买卖点: 偏移/失效偏移/有效性、18种类型生成
- 观察者: 指针一致性 (普K/分型/笔/线段/中枢)、重复计算确定性、重置后数据一致、RefCell 借用安全、跨线程 Send/Sync
Python 绑定层测试 (chanlun-py/tests/test_all.py)
&&
# 107+ tests, 涵盖:
# - 指标挂载与回填
# - 跨线程身份一致性 (is 判断)
# - 买卖意义/趋向背驰/行为统计/停顿位置/线段内部背驰等 双端(Rust绑定 vs chan.py)数据对比
许可
MIT License. 详见 LICENSE.
相关项目
chan.py— Python 参考实现(~4200 行)chanlun-py— PyO3 绑定,将本 crate 导出为 Pythonchanlun模块main.py— Python 图表可视化程序