chanlun 26.6.4

基于缠论(缠中说禅)理论的量化技术分析核心库,支持流式数据处理和多周期联立分析。
Documentation

chanlun — 缠论技术分析 Rust 核心库

License: MIT Rust edition

基于缠中说禅理论的量化技术分析核心库,将 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 依赖

[dependencies]
chanlun = { path = "path/to/chanlun" }

基本用法 — 单周期分析

use chanlun::config::缠论配置;
use chanlun::kline::bar::K线;
use chanlun::business::observer::观察者;

// 1. 创建配置(所有字段带默认值)
let 配置 = 缠论配置::default();

// 2. 创建观察者(返回 Arc<RwLock<观察者>>)
let 观察员 = 观察者::new("BTCUSD".into(), 3600, 配置);

// 3. 逐根投喂K线(流式增量分析,每根K线触发全管线运算)
for k线 in k线数据流 {
    观察员.write().unwrap().增加原始K线(k线);
}

// 4. 读取分析结果
let obs = 观察员.read().unwrap();
println!("笔数量: {}", obs.笔序列.len());
println!("线段数量: {}", obs.线段序列().len());
println!("中枢数量: {}", obs.中枢序列().len());

// 遍历笔
forin &obs.笔序列 {
    println!("笔方向: {}, 高: {}, 低: {}",.方向(),.(),.());
}

便捷投喂 — 直接从 OHLCV

let 观察员 = 观察者::new("ETHUSD".into(), 300, Default::default());
let mut obs = 观察员.write().unwrap();
obs.投喂原始数据(1736640000, 3500.0, 3550.0, 3480.0, 3520.0, 1200.0);
// ... 继续投喂 ...

加载 .nb 数据文件

let 观察员 = 观察者::new("btcusd".into(), 300, Default::default());
观察员.write().unwrap().读取数据文件("btcusd-300-1000000-1100000.nb", Default::default())?;

多周期分析

use chanlun::business::multi_frame::立体分析器;

// 周期组: [最小输入周期, 更多显示周期...]
// 只投喂最小周期K线,大周期自动合成
let mut 分析器 = 立体分析器::new(
    "BTCUSD".into(),
    vec![60, 300, 1800, 7200],  // 1分钟 → 5分钟 → 30分钟 → 2小时
    None,                       // 默认配置
    None,                       // 无周期特定配置
);

// 投喂最小周期K线
for k线 in 小周期K线流 {
    分析器.投喂K线(k线);
}

// 获取各周期观察者
if let Some(日线观察员) = 分析器.获取观察者(86400) {
    let obs = 日线观察员.read().unwrap();
    println!("日线笔数: {}", obs.笔序列.len());
}

数据管线

缠论分析按严格的层级顺序进行,每收到一根新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线:

  1. 计算指标并挂载到新K线
  2. 执行缠K包含处理,产出缠K
  3. 识别分型,添加到分型序列
  4. 递归分析笔(可能生成新笔或修改最后一笔)
  5. 递归分析中枢(笔中枢)
  6. 递归分析线段(3级递归:线段→线段<线段>→线段<线段<线段>>)
  7. 递归分析扩展线段(3级递归)
  8. 递归分析混合扩展线段(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(&json)?;                // 反序列化

// 文件 I/O
config.保存配置("/path/to/config.json")?;                  // 保存
let loaded = 缠论配置::加载配置("/path/to/config.json")?;  // 加载

// 部分反序列化(缺失字段→默认值)
let config: 缠论配置 = serde_json::from_str(r#"{"笔内元素数量": 7}"#)?;

// 静默模式
let silent = config.不推送();  // 所有推送/展示开关设为 false

// 差异对比
let diffs = config_a.对比(&config_b);  // → ["笔内元素数量", ...]

// 多参数解析(列表非空则使用列表,否则使用默认单组)
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 = 缠论配置::按序号重组字典(&default_config, &raw_json);

算法模块

笔划分 (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离开段背驰判断
是否背驰过() 线段范围内是否发生过背驰
获取所有停顿位置() 获取线段内部所有可能的停顿位置
获取内部中枢序列() 获取线段内部的中枢序列

四种修正机制(按优先级):

  1. _缺口突破 — 老阳/老阴状态 + 价格突破前线段极值 → 线段完成
  2. _非缺口下穿刺 — 贯穿伤存在 + 方向相同的3笔 → 线段完成
  3. _缺口后紧急修正 — 前一线段有缺口 + 价格反向突破 → 修正前一结束位置
  4. _修正 — 短线路径 (≥9笔) → 快速完成

中枢识别 (algorithm::hub, 1041 行)

中枢 既是数据结构也是算法命名空间:

方法 说明
分析() 主算法:虚线→中枢,同时识别第三买卖点
线段扩展分析() 中枢扩展:≥9段时生成扩展中枢
高() 前三根虚线重叠区域的最高值
低() 前三根虚线重叠区域的最低值
文() 第一根虚线的起点分型
武() 第三根虚线的终点分型
方向() 当中枢高 > 中枢低时为向上,否则向下
延伸序列() 首尾之外的虚线
获取离开虚线() 找到离开中枢的虚线(第三买卖点)
获取剩余虚线() 第三买卖点之后的虚线
获取第N买卖线() 获取第N个买卖点相关的虚线

中枢识别核心逻辑:

  1. 基础检查:三条连续虚线必须重叠(max(低) < min(高))且方向关系正确
  2. 中枢延伸:在后继虚线中找离开中枢的虚线,未离开则加入基础序列
  3. 第三买卖点:虚线离开中枢且不回中枢,记录 第三买卖线
  4. 中枢完成:第三买卖线 确立后,在上方虚线开始新中枢
  5. 中枢扩展:≥9段时调用 线段扩展分析 生成扩展中枢

背驰检测 (algorithm::divergence, 227 行)

背驰分析 提供三种检测方式:

方式 原理 方法
MACD背驰 进入段vs离开段的MACD柱面积对比 (`阳 +
斜率背驰 价格变化速率 (dy/dx) 减弱 斜率背驰()
测度背驰 价格-时间向量长度 (√(dx²+dy²)) 缩减 测度背驰()

四种组合模式:

模式 条件
全量 MACD 且 斜率 且 测度 全满足
任意 MACD 或 斜率 或 测度 任意满足
配置 根据 线段内部背驰_MACD/斜率/测度 配置组合
相对 至少两种方式满足(多数投票)

技术指标

所有指标位于 indicators/ 模块,均支持首次计算增量计算两种模式。

统一指标容器 (indicators::container)

基于注册表模式,通过 指标值 枚举统一管理五种指标类型:

pub enum 指标值 {
    MACD(平滑异同移动平均线),
    RSI(相对强弱指数),
    KDJ(随机指标),
    BOLL(布林带),
    均线(HashMap<String, f64>),
    单值(HashMap<String, f64>),
}
  • 预注册默认槽位: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 行)

指标计算器::计算并挂载(全序列, 配置) 是一次完整的指标计算周期:

  1. MACD组 — 遍历 _解析MACD参数列表(),对每个 (key, 快, 慢, 信号) 计算
  2. RSI组 — 遍历 _解析RSI周期列表()
  3. KDJ组 — 遍历 _解析KDJ参数列表()
  4. BOLL组 — 遍历 _解析BOLL参数列表()
  5. 均线 — 遍历 均线_类型列表 × 均线_周期列表,MA/EMA 计算
  6. 回填新指标 — 如果当前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,可以安全地跨线程传递和共享:

// 编译期断言
fn _需要_Send_Sync<T: Send + Sync>() {}
_需要_Send_Sync::<缠论K线>();
_需要_Send_Sync::<虚线>();
_需要_Send_Sync::<中枢>();

观察者 使用 Arc<RwLock<观察者>> 模式,多线程可以并发读取同一个观察者的分析结果。

RwLock 死锁预防

Rust 的 RwLock非递归锁。在已有读锁的线程中尝试获取写锁会死锁。核心规则:

  • 将读锁作用域化:在所有调用带写锁的方法之前释放 prev_guard
  • 典型模式:{ let prev_guard = ... ; /* 使用 prev_guard */ } // 作用域结束释放 → 安全调用回填

Python 绑定

Python 调用通过独立的 chanlun-py crate 提供,使用 PyO3 包装。所有类型、方法、字段名与 chan.py 完全一致,API 兼容。

cd chanlun-py
maturin develop --release
import chanlun

# 创建/修改配置
config = chanlun.缠论配置()
config.笔内元素数量 = 7
config.MACD_参数列表 = [("my_macd", 12, 26, 9)]

# 创建观察者
obs = chanlun.观察者("BTCUSD", 3600, config)

# 通过 Python 属性直接修改配置(自动同步到核心层)
obs.配置.笔弱化 = True

# 投喂K线
k = chanlun.K线.创建普K("bar", 1736640000, 50000, 51000, 49000, 50500, 100, 0, 3600)
obs.增加原始K线(k)

# 获取分析结果
print(f"笔数量: {len(obs.笔序列)}")
print(f"线段数量: {len(obs.线段序列)}")
print(f"中枢数量: {len(obs.中枢序列)}")

# 全局开关
chanlun.分型模式 = 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: [u8; 48] = k线.to_bytes();

// 反序列化
let k线 = K线::读取大端字节数组(&bytes, 周期, 标识);

// 解析原始数据(不构造K线)
let (时间戳,,,,,) = K线::解析原始数据(&bytes)?;

// 批量保存
K线::保存到DAT文件("output.dat", &[&k1, &k2])?;

配置 JSON

{
  "标识": "BTCUSD",
  "笔内元素数量": 5,
  "平滑异同移动平均线_快线周期": 13,
  "平滑异同移动平均线_慢线周期": 31,
  "买卖点_指标模式": "配置",
  "线段内部背驰_模式": "相对"
}
  • 使用 #[serde(default)] 实现前向/后向兼容,缺失字段自动使用默认值
  • 字符串枚举字段(指标计算方式, 买卖点_指标模式, 线段内部背驰_模式)带有自定义反序列化器,非法值自动回退默认值并发出 warn! 日志

结构化相等校验

所有核心结构体都实现了 相等(&self, other, 浮点容差) → (bool, String) 方法,递归校验包括:

  • 浮点字段使用容差比较(而非直接 ==
  • Arc 指针共享的结构体深度校验值语义
  • 嵌套容器(Vec, Option, HashMap)逐一比对
  • 返回详细的差异描述,便于调试

测试

核心层测试 (chanlun/)

cargo test                     # 运行所有测试
cargo test -- test_重复计算    # 运行匹配模式的测试

测试覆盖:

  • 配置: 默认值、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)

cd chanlun-py && maturin develop
python3 -m pytest tests/test_all.py -v
# 107+ tests, 涵盖:
#   - 指标挂载与回填
#   - 跨线程身份一致性 (is 判断)
#   - 买卖意义/趋向背驰/行为统计/停顿位置/线段内部背驰等 双端(Rust绑定 vs chan.py)数据对比

许可

MIT License. 详见 LICENSE.


相关项目

  • chan.py — Python 参考实现(~4200 行)
  • chanlun-py — PyO3 绑定,将本 crate 导出为 Python chanlun 模块
  • main.py — Python 图表可视化程序