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

[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)
[![Rust](https://img.shields.io/badge/rust-1.70%2B-orange.svg)](https://www.rust-lang.org)

基于[缠中说禅](https://zh.wikipedia.org/wiki/%E7%BC%A0%E4%B8%AD%E8%AF%B4%E7%A6%85)理论的量化技术分析核心库，用 Rust 实现。支持流式数据处理，可作为独立 Rust crate 使用，也可通过 PyO3 绑定在 Python 中调用（见 [`chanlun-py`](../chanlun-py/)）。

约 9,400 行 Rust 代码，覆盖缠论的完整算法体系：K线包含处理、分型识别、笔划分、线段划分、中枢识别、背驰检测、买卖点识别、多周期联立分析。

---

## 目录

- [核心概念](#核心概念)
- [项目结构](#项目结构)
- [快速开始](#快速开始)
- [数据管线](#数据管线)
- [核心类型](#核心类型)
- [配置体系](#配置体系)
- [算法模块](#算法模块)
- [技术指标](#技术指标)
- [Python 绑定](#python-绑定)
- [数据序列化](#数据序列化)
- [许可](#许可)

---

## 核心概念

缠论是一种源自中国的技术分析理论，将价格走势分解为层级结构，从最底层K线逐渐向上构造：

```
原始K线 → 包含处理 → 缠论K线 → 顶底分型 → 笔 → 线段 → 中枢 → 买卖点
```

核心理念：
- **走势终完美**：任何级别的任何走势类型终要完成
- **自同构性**：不同级别的走势呈现相同的形态结构
- **完全分类**：将走势分为上涨、下跌、盘整三种

---

## 项目结构

```
chanlun/
├── Cargo.toml                  # 依赖: serde, byteorder, chrono
└── src/
    ├── lib.rs                  # 模块注册
    ├── config.rs               # 缠论配置 (60+ 参数, serde)
    ├── types/                   # 基础类型
    │   ├── mod.rs
    │   ├── bsp_type.rs         # 买卖点类型 (18 种)
    │   ├── direction.rs        # 相对方向 (9 种)
    │   ├── fractal.rs           # 分型结构 (5 种)
    │   └── gap.rs              # 缺口
    ├── kline/                   # K线层
    │   ├── mod.rs
    │   ├── bar.rs              # 原始K线 (OHLCV + 指标)
    │   └── chan_kline.rs       # 缠论K线 (包含处理 + 合并)
    ├── indicators/              # 技术指标
    │   ├── mod.rs
    │   ├── macd.rs             # MACD (平滑异同移动平均线)
    │   ├── rsi.rs              # RSI (相对强弱指数)
    │   └── kdj.rs              # KDJ (随机指标)
    ├── algorithm/               # 核心算法
    │   ├── mod.rs
    │   ├── bi.rs               # 笔划分算法
    │   ├── segment.rs          # 线段划分算法
    │   ├── hub.rs              # 中枢识别算法
    │   └── divergence.rs       # 背驰检测算法
    ├── structure/               # 结构体
    │   ├── mod.rs
    │   ├── dash_line.rs        # 虚线 (笔/线段的通用抽象)
    │   ├── fractal_obj.rs      # 分型对象
    │   ├── segment_feat.rs     # 线段特征
    │   └── feat_fractal.rs     # 特征分型
    ├── business/                # 业务层
    │   ├── mod.rs
    │   ├── bsp.rs              # 基础买卖点 + 买卖点
    │   ├── observer.rs         # 观察者 (单周期分析器)
    │   ├── synthesizer.rs      # K线合成器 (周期合成)
    │   └── multi_frame.rs      # 立体分析器 (多周期联立)
    └── utils/                   # 工具
        ├── mod.rs
        ├── datetime.rs          # 时间戳转换
        └── format.rs            # 格式化输出
```

---

## 快速开始

### Cargo 依赖

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

### 基本用法

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

// 1. 创建配置
let 配置 = 缠论配置::default();

// 2. 创建观察者（单周期分析器）
let mut 观察员 = 观察者::new("BTCUSD".into(), 3600, 配置);

// 3. 逐根投喂K线（流式增量分析）
for k线 in k线数据流 {
    观察员.增加原始K线(k线);
}

// 4. 读取分析结果
for 笔 in 观察员.笔序列() {
    println!("笔: {:?}", 笔.方向());
}
for 中枢 in 观察员.中枢序列() {
    println!("中枢: 高={:?}, 低={:?}", 中枢.高(), 中枢.低());
}
```

### 多周期分析

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

// 周期组: [最小输入周期, 更多显示周期...]
let mut 分析器 = 立体分析器::new(
    "BTCUSD".into(),
    vec![60, 300, 1800, 7200],  // 1分钟 → 5分钟 → 30分钟 → 2小时
    缠论配置::default(),
    std::collections::HashMap::new(),
);

// 只投喂最小周期K线，大周期自动合成
for k线 in 小周期K线流 {
    分析器.投喂K线(k线);
}

// 获取各周期观察者
let 观察员_1min = 分析器.获取观察员(60);
let 观察员_5min = 分析器.获取观察员(300);
```

---

## 数据管线

缠论分析按严格的层级顺序进行，每收到一根新K线，增量更新所有层级：

```
原始K线 (K线)
  │
  ├── 指标计算: MACD / RSI / KDJ (增量更新)
  │
  ├── 包含处理 → 缠论K线 (缠论K线)
  │     │
  │     ├── 顺序包含合并
  │     ├── 逆序包含合并
  │     └── 方向判定 (向上/向下)
  │
  ├── 分型识别 → 分型 (分型)
  │     │
  │     ├── 由左中右三根缠论K线构成
  │     ├── 类型: 顶分型 / 底分型 / 上 / 下 / 散
  │     └── 强度: 强 / 中 / 弱
  │
  ├── 笔划分 → 笔 (虚线, 标识="笔")
  │     │
  │     ├── 递归分析算法
  │     ├── 支持笔弱化、次级成笔等策略
  │     └── 实际高/低点选择 (first/last)
  │
  ├── 线段划分 → 线段 (虚线, 标识="线段")
  │     │
  │     ├── 特征序列提取
  │     ├── 缺口检测 (老阴/老阳)
  │     ├── 笔破坏判断
  │     ├── 缺口突破修正
  │     └── 非缺口下穿刺修正
  │
  ├── 中枢识别 → 中枢 (中枢)
  │     │
  │     ├── 连续三笔/段重叠构成
  │     ├── 中枢延伸 (添加虚线)
  │     ├── 中枢扩展 (≥9段时生成扩展中枢)
  │     ├── 第三类买卖点检测
  │     └── 多级中枢: 笔中枢 / 线段中枢 / 扩展线段中枢
  │
  └── 买卖点识别 → 买卖点 (买卖点)
        │
        ├── 6 类买卖点: T1 / T1P / T2 / T2S / T3A / T3B
        ├── 指标匹配: MACD / KDJ / RSI
        ├── 背驰确认
        └── 中枢来源: 实 / 虚 / 合
```

**流式增量处理**：`观察者.__处理数据` 每收到一根新K线就逐层触发所有后续分析，而非批量重算。这使得该库适合实时交易系统。

---

## 核心类型

### 枚举类型

| 类型 | 变体 | 说明 |
|------|------|------|
| `相对方向` | 向上 / 向下 / 向上缺口 / 向下缺口 / 衔接向上 / 衔接向下 / 顺 / 逆 / 同 | 两个价格区间的相对位置关系 |
| `分型结构` | 上 / 下 / 顶 / 底 / 散 | 三根K线构成的形态 |
| `买卖点类型` | 一买/一卖/二买/二卖/三买/三卖 + T1~T3B | 18 种买卖点分类 |

### 数据结构

| 类型 | 关键字段 | 所有权模型 |
|------|---------|-----------|
| `K线` | 标识, 序号, 周期, 时间戳, 高, 低, 开盘价, 收盘价, 成交量, macd?, rsi?, kdj? | 值类型 (Clone) |
| `缠论K线` | 序号, 时间戳, 高, 低, 方向, 分型?, 分型特征值, 原始起始序号, 原始结束序号, 标的K线 | Rc 引用 |
| `分型` | 左?, 中, 右?, 结构, 时间戳, 分型特征值 | Rc 引用 |
| `虚线` | 标识, 序号, 级别, 文, 武, 有效性, 基础序列, 特征序列, 实/虚/合_中枢序列, 确认K线, 模式, 前一缺口 | Rc 引用 |
| `线段特征` | 标识, 线段方向, (list子类) | Rc 引用 |
| `特征分型` | 左, 中, 右, 结构 | Rc 引用 |
| `中枢` | 序号, 标识, 级别, 基础序列, 第三买卖线?, 本级_第三买卖线? | Rc 引用 |
| `基础买卖点` | 类型, 买卖点K线, 买卖点分型, 备注, 偏移, 失效偏移, 有效性, 破位值 | 值类型 |
| `买卖点` | (继承基础买卖点) | 值类型 |
| `缺口` | 高, 低 | 值类型 |

### 服务类型

| 类型 | 职责 |
|------|------|
| `观察者` | 单周期分析器，接收K线流，维护所有层级序列 |
| `K线合成器` | 将小周期K线合成为大周期K线 |
| `立体分析器` | 多周期联立分析，内含合成器+每周期一个观察者 |

### 静态算法类

这些类型只包含 `#[staticmethod]` / `classmethod`，不创建实例：

| 类型 | 职责 |
|------|------|
| `笔` | 笔划分算法：分型→笔 (递归分析) |
| `线段` | 线段划分算法：笔→线段 (特征序列+缺口处理) |
| `中枢` | 中枢识别/管理：虚线→中枢 (重叠检测+扩展) |
| `背驰分析` | 背驰检测：MACD/斜率/测度三种方式 |
| `指标` | K线取值工具：按计算方式取价格 |

---

## 配置体系

`缠论配置` 是一个 serde 驱动的结构体，62 个字段全部带默认值，支持 JSON 往返。

### 配置分组

```rust
let config = 缠论配置 {
    // ---- 缠K ----
    缠K合并替换: false,        // false: 在原地合并, true: 产出新缠K

    // ---- 笔 ----
    笔内元素数量: 5,           // 成笔最低K线数
    笔弱化: false,             // 放宽成笔条件（弱化后最低3根）
    笔次级成笔: false,         // 允许次高/次低成笔
    笔内相同终点取舍: false,  // false: 取first, true: 取last

    // ---- 线段 ----
    线段_特征序列忽视老阴老阳: false,  // 缺口时不严格处理包含
    线段_缺口后紧急修正: true,        // 缺口后自动修正
    线段_修正: false,                 // 短路修正（不推荐）

    // ---- 分析开关 ----
    分析笔: true,
    分析线段: true,
    分析扩展线段: true,
    分析笔中枢: true,
    分析线段中枢: true,

    // ---- 指标参数 ----
    平滑异同移动平均线_快线周期: 13,   // MACD 快线 EMA 周期
    平滑异同移动平均线_慢线周期: 31,   // MACD 慢线 EMA 周期
    平滑异同移动平均线_信号周期: 11,   // MACD 信号线 EMA 周期
    相对强弱指数_周期: 13,
    相对强弱指数_超买阈值: 75.0,
    相对强弱指数_超卖阈值: 25.0,
    随机指标_RSV周期: 13,
    随机指标_K值平滑周期: 5,
    随机指标_D值平滑周期: 5,
    随机指标_超买阈值: 80.0,
    随机指标_超卖阈值: 20.0,

    // ---- 买卖点 ----
    买卖点偏移: 1,             // 最大偏移量
    买卖点_指标模式: "配置",   // 配置 / 任意 / 全量 / 相对
    买卖点_计算方式: "峰",     // 峰 / 面
    买卖点_背离率: f64::INFINITY,
    买卖点_中枢来源: "合",     // 实 / 虚 / 合

    // ---- 背驰 ----
    线段内部背驰_MACD: true,
    线段内部背驰_斜率: true,
    线段内部背驰_测度: true,
    线段内部背驰_模式: "相对", // 全量 / 任意 / 配置 / 相对

    // ---- 图表推送 ----
    图表展示: true,
    推送K线: true,
    推送笔: true,
    推送线段: true,
    推送中枢: true,

    // ... 还有 20+ 个图表细分开关
    ..Default::default()
};
```

### 配置方法

```rust
// JSON 往返
let json = config.to_json();
let config2 = 缠论配置::from_json(&json)?;

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

// 静默模式（关闭所有推送）
let silent = config.不推送();

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

---

## 算法模块

### 笔划分 (`algorithm::bi`)

核心递归算法 `笔.分析`，每次收到新分型时：
1. 检查顶/底分型交替
2. 验证笔内K线数量 ≥ 配置阈值
3. 确定实际高/低点（考虑笔弱化、次高点/次低点）
4. 检查笔内起始分型包含整笔条件
5. 支持笔弱化策略：当严格条件不满足时，尝试放宽到3根

### 线段划分 (`algorithm::segment`)

最复杂的递归算法，核心方法 `线段.分析`：
1. **特征序列提取**：从笔序列中提取同向特征序列（`线段特征.静态分析`）
2. **缺口处理**：
   - 有缺口（老阴/老阳）：严格包含处理，等待特征分型完成
   - 无缺口（小阳/少阴）：允许逆序包含
3. **四种修正机制**（依次尝试）：
   - `_缺口突破`：老阳/老阴时价格突破前线段极值
   - `_非缺口下穿刺`：贯穿伤后出现方向相同的3笔
   - `_缺口后紧急修正`：前一线段有缺口时自动修正
   - `_修正`：配置启用的短路修正（≥9笔）
4. **线段破坏判定**：新线段形成后，前一线段被破坏

### 中枢识别 (`algorithm::hub`)

核心递归算法 `中枢.分析`：
1. **基础检查**：三条连续虚线，重叠且方向关系正确
2. **中枢延伸**：在后继虚线中找离开中枢的虚线，未离开则加入基础序列
3. **第三买卖点**：虚线离开中枢（向上缺口/向下缺口），记录第三买卖线
4. **中枢完成**：第三买卖线确立后，在中枢之上的虚线开始新中枢
5. **中枢扩展**：≥9段时调用线段扩展分析生成扩展中枢
6. **多级中枢**：笔中枢、线段中枢、扩展线段中枢、线段线段中枢等

### 背驰检测 (`algorithm::divergence`)

三种检测方式，可自由组合：

| 方式 | 原理 | 方法 |
|------|------|------|
| MACD背驰 | 进入段vs离开段的MACD柱面积对比 | `MACD背驰` |
| 斜率背驰 | 价格变化速率减弱 | `斜率背驰` |
| 测度背驰 | 价格-时间向量长度缩减 | `测度背驰` |

组合模式：
- **全量**：三种全满足
- **任意**：任一种满足
- **配置**：根据配置开关组合
- **相对**：至少两种满足

---

## 技术指标

三个指标均位于 `indicators/` 模块，支持增量计算（适合流式数据）。

### MACD (`indicators::macd`)

```rust
pub struct 平滑异同移动平均线 {
    // 输入
    pub 时间戳: i64, pub 收盘价: f64,
    pub 快线周期: i64, pub 慢线周期: i64, pub 信号周期: i64,

    // 输出
    pub DIF: Option<f64>,    // 快线EMA - 慢线EMA
    pub DEA: Option<f64>,    // DIF的信号线EMA
    pub MACD柱: Option<f64>, // DIF - DEA

    // 计算中间值 (增量用)
    pub 快线EMA: Option<f64>,
    pub 慢线EMA: Option<f64>,
    pub DEA_EMA: Option<f64>,
}
```

### RSI (`indicators::rsi`)

```rust
pub struct 相对强弱指数 {
    pub 时间戳: i64, pub 收盘价: f64,
    pub 周期: i64,
    pub 超买阈值: f64, pub 超卖阈值: f64,

    pub RSI: Option<f64>,
    pub RSI_SMA: Option<f64>,  // RSI的SMA信号线

    // Wilder平滑中间值
    pub 平均上涨: Option<f64>,
    pub 平均下跌: Option<f64>,
}
```

### KDJ (`indicators::kdj`)

```rust
pub struct 随机指标 {
    pub 时间戳: i64, pub 最高价: f64, pub 最低价: f64, pub 收盘价: f64,
    pub RSV周期: i64, pub K值平滑周期: i64, pub D值平滑周期: i64,
    pub 超买阈值: f64, pub 超卖阈值: f64,

    pub K: Option<f64>,  // RSV的移动平均
    pub D: Option<f64>,  // K的移动平均
    pub J: Option<f64>,  // 3*K - 2*D
}
```

所有三个指标都提供 `首次计算` → `增量计算` 的流式计算接口，以及对应的 `_K线` 便捷版本。

---

## Python 绑定

Python 调用通过独立的 [`chanlun-py`](../chanlun-py/) crate 提供，使用 PyO3 包装：

```bash
cd chanlun-py
cargo build --release
cp target/release/libchanlun.so ~/.local/lib/python3.14/site-packages/chanlun/_chanlun.cpython-314-x86_64-linux-gnu.so
```

```python
import chanlun

# 创建配置
config = chanlun.缠论配置()
config.笔内元素数量 = 7

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

# 投喂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.中枢序列)}")
```

所有类型、方法、字段名与 `chan.py` 完全一致，API 兼容。

---

## 数据序列化

### K线二进制格式

K 线以大端字节序 `struct.pack(">6d")` 格式序列化，每根 48 字节：

| 偏移 | 大小 | 字段 |
|------|------|------|
| 0 | 8 | 时间戳 (Unix秒 as f64) |
| 8 | 8 | 开盘价 |
| 16 | 8 | 最高价 |
| 24 | 8 | 最低价 |
| 32 | 8 | 收盘价 |
| 40 | 8 | 成交量 |

```rust
// 序列化
let bytes = k线.to_bytes();  // Vec<u8>, 48 bytes

// 反序列化
let k线 = K线::读取大端字节数组(&bytes, 3600, "bar");
```

### 配置 JSON

```json
{
  "标识": "BTCUSD",
  "笔内元素数量": 5,
  "平滑异同移动平均线_快线周期": 13,
  "平滑异同移动平均线_慢线周期": 31
}
```

使用 `#[serde(default)]` 实现前向/后向兼容，缺失字段自动使用默认值。

---

## 许可

MIT License. 详见 [LICENSE](LICENSE).

---

## 相关项目

- [`chan.py`](../chan.py) — Python 参考实现（~4200 行）
- [`chanlun-py`](../chanlun-py/) — PyO3 绑定，将本 crate 导出为 Python 模块
- [`main.py`](../main.py) — Python 图表程序入口
