title: LineBuffer API 参考文档 description: 完整的 LineBuffer 类 API 参考,循环缓冲区实现


LineBuffer API 参考文档

LineBuffer 是 Backtrader 中最核心的数据结构之一,实现了高效的时间序列数据循环缓冲区。它约 1950 行代码,为整个框架提供数据存储和访问的基础设施。

类概览

class backtrader.LineBuffer(LineSingle, LineRootMixin):
    """实现循环缓冲区的时间序列数据存储。"""

```bash
LineBuffer 定义了一个类似 `array.array` 的接口其中索引 0 始终指向当前活跃的值这种设计使得在处理时间序列数据时无需传递索引变量即可访问当前值

### 核心特性

- **索引 0 始终指向当前值**- 当前值总是可通过 `buffer[0]` 访问
- **正索引获取历史值**- `buffer[-1]` 获取前一个值
- **负索引获取未来值**- `buffer[1]` 获取下一个值需要扩展
- **自动内存管理**- qbuffer 模式限制内存使用
- **线条绑定** - 值设置时自动同步到绑定的线条

## 循环缓冲区架构

### 缓冲区模式

LineBuffer 支持两种运行模式

| 模式 |  | 描述 |

|------|-----|------|

| `UnBounded` | 0 | 无界模式缓冲区随数据增长 |

| `QBuffer` | 1 | 队列缓冲区模式固定最大长度 |

```python

# 默认 UnBounded 模式

buffer = LineBuffer()
buffer.mode == LineBuffer.UnBounded  # True

# 启用 QBuffer 模式

buffer.qbuffer(savemem=1, extrasize=0)
buffer.mode == LineBuffer.QBuffer  # True

```bash

### 内存布局示意图

```mermaid
graph TD
    subgraph "LineBuffer 内部结构"
        A["_idx: 当前逻辑索引"]
        B["lencount: 逻辑长度"]
        C["array: 底层存储数组"]
        D["extension: 扩展区大小"]
        E["bindings: 绑定线条列表"]
        F["mode: 缓冲区模式"]
    end

    subgraph "数据访问示例 (10 个数据点)"
        G["array[0]=1.0"]
        H["array[1]=2.0"]
        I["array[2]=3.0"]
        J["array[3]=4.0"]
        K["array[4]=5.0"]
        L["array[5]=6.0"]
        M["..."]
        N["array[9]=10.0"]
    end

    subgraph "索引映射"
        O["buffer[0] → array[_idx] (当前值)"]
        P["buffer[-1] → array[_idx-1] (前值)"]
        Q["buffer[1] → array[_idx+1] (未来值)"]
    end

    A --> O
    O --> P
    O --> Q

```bash

### 数据存储模型

```python

# 底层使用 array.array('d') 存储

# 循环缓冲区逻辑映射

class LineBuffer:
    def __init__(self):
        self.array = array.array('d')  # 底层存储
        self._idx = -1                  # 当前逻辑索引
        self.lencount = 0               # 逻辑长度计数
        self.extension = 0              # 扩展区
        self.mode = self.UnBounded      # 运行模式

```bash

## 核心属性

### `array`

底层存储数组类型为 `array.array('d')`(双精度浮点数)。

```python

# 直接访问底层数组

raw_data = line_buffer.array

```bash

### `_idx`

当前逻辑索引位置索引 0 总是指向当前活跃值

```python

# 获取当前索引位置

current_idx = line_buffer._idx

# 设置索引位置(使用 set_idx 方法)

line_buffer.set_idx(100)

```bash

### `lencount`

缓冲区的逻辑长度计数器

```python

# 获取逻辑长度

logical_len = len(line_buffer)  # 返回 lencount

# 与实际数组长度的关系

actual_len = len(line_buffer.array)
logical_len = line_buffer.lencount

```bash

### `maxlen`

QBuffer 模式下的最大长度限制

```python

# 设置最大长度

line_buffer.qbuffer(savemem=1)
line_buffer.maxlen  # 默认为 _minperiod 的值

```bash

### `extension`

扩展区大小用于前瞻操作

```python

# 扩展缓冲区用于未来数据

line_buffer.extend(size=5)
line_buffer.extension  # 5

```bash

### `bindings`

绑定的线条列表当设置值时会同步更新

```python

# 添加绑定

other_line = LineBuffer()
line_buffer.addbinding(other_line)

# 设置值会自动同步到绑定

line_buffer[0] = 100.0  # other_line[0] 也会被设置为 100.0

```bash

## 数据操作方法

### `__getitem__(ago)` - 获取值

获取相对当前索引位置的值

```python

# 语法

value = buffer[ago]

# ago 参数:

# 0  : 当前值

# -1 : 前一个值

# -n : n 个周期前的值

# 1  : 下一个值(需要 extend)

# n  : n 个周期后的值

# 示例

current = buffer[0]      # 当前值

previous = buffer[-1]    # 前一个值

five_back = buffer[-5]   # 5 个周期前的值

```bash

- *性能优化**此方法经过热路径优化是整个框架中最频繁调用的方法之一

### `__setitem__(ago, value)` - 设置值

在相对位置设置值并更新所有绑定

```python

# 设置当前值

buffer[0] = 100.0

# 设置历史值(用于重放等场景)

buffer[-1] = 99.0

# 设置未来值(需要先 extend)

buffer[1] = 101.0

```bash

- *性能特性**
- 自动扩展数组以容纳索引
- NaN/None 值自动转换为默认值
- datetime 线条自动验证值范围
- 绑定线条自动同步更新

### `get(ago=0, size=1)` - 获取切片

获取相对位置的多个值

```python

# 获取最近 5 个值(从当前回溯)

values = buffer.get(ago=0, size=5)

# 返回: [buffer[-4], buffer[-3], buffer[-2], buffer[-1], buffer[0]]

# 获取 3 个周期前的 2 个值

values = buffer.get(ago=-3, size=2)

# 返回: [buffer[-4], buffer[-3]]

```bash

### `set(value, ago=0)` - 设置值(优化版)

优化的值设置方法减少开销

```python

# 性能优化的设置方法

buffer.set(100.0, ago=0)

```bash

## 缓冲区导航

### `home()` - 重置到起始

将逻辑索引重置到起始位置

```python
buffer.home()  # _idx = -1, lencount = 0

```bash
底层缓冲区保持不变使用 `buflen()` 获取实际数据长度

### `forward(value=NaN, size=1)` - 向前移动

将逻辑索引向前移动并扩展缓冲区

```python

# 向前移动一步(填充 NaN)

buffer.forward()

# 向前移动一步,填充指定值

buffer.forward(value=0.0)

# 向前移动多步

buffer.forward(size=5)

```bash

- *行为特性**
- 指标线条使用 NaN 填充
- 数据源线条使用 0.0 填充
- 遵循时钟同步非指标
- 自动扩展底层数组

### `backwards(size=1, force=False)` - 向后移动

将逻辑索引向后移动并减少缓冲区

```python

# 向后移动一步

buffer.backwards()

# 向后移动多步

buffer.backwards(size=5)

# 强制移动(QBuffer 模式)

buffer.backwards(size=1, force=True)

```bash

### `advance(size=1)` - 前进逻辑索引

仅前进逻辑索引不修改底层缓冲区

```python

# 前进逻辑索引

buffer.advance()
buffer._idx += 1
buffer.lencount += 1

```bash

### `rewind(size=1)` - 回退逻辑索引

仅回退逻辑索引不修改底层缓冲区

```python

# 回退逻辑索引

buffer.rewind()
buffer._idx -= 1
buffer.lencount -= 1

```bash

## 内存管理

### `qbuffer(savemem=0, extrasize=0)` - 启用队列缓冲区

启用内存高效的队列缓冲区模式

```python

# 启用 QBuffer 模式

buffer.qbuffer(savemem=1, extrasize=0)

# 参数说明:

# savemem  : 0=正常模式, >0=启用缓存模式

# extrasize: 额外空间(用于重采样/重放操作)

# 效果:

# mode = QBuffer

# maxlen = max(1, _minperiod)

# lenmark = maxlen - (not extrasize)

```bash

- *内存效果**

```python

# 无界模式:存储所有数据

# 内存使用: O(n),n 为数据点数量

# QBuffer 模式:只保留最近 maxlen 个数据点

# 内存使用: O(maxlen),固定上限

# 示例:10 年日线数据

# 无界模式: ~3650 个数据点

# QBuffer(maxlen=100): ~100 个数据点

# 节省: ~97% 内存

```bash

### `minbuffer(size)` - 确保最小缓冲区大小

确保缓冲区至少能容纳指定大小的数据

```python

# 确保缓冲区至少容纳 100 个数据点

buffer.minbuffer(100)

# 在 QBuffer 模式下,如果 maxlen < 100,会自动调整

# buffer.maxlen = 100

```bash

### `extend(value=float('nan'), size=0)` - 扩展缓冲区

扩展底层数组用于前瞻操作

```python

# 扩展 5 个位置用于未来数据

buffer.extend(size=5)
buffer.extension  # 5

# 扩展并填充值

buffer.extend(value=0.0, size=3)

```bash

## 缓冲区信息

### `__len__()` - 获取逻辑长度

返回缓冲区的逻辑长度计数器

```python
logical_len = len(buffer)

# 等价于: buffer.lencount

```bash

- *性能优化**直接返回 `lencount`,避免复杂计算

### `buflen()` - 获取实际数据长度

返回底层缓冲区中实际可存储的数据量

```python

# 实际可存储的数据量

actual_len = buffer.buflen()

# 返回: len(buffer.array) - buffer.extension

# 用途: 区分逻辑长度和物理容量

len(buffer)      # 逻辑长度(已处理的数据点)

buffer.buflen()  # 物理容量(实际存储的数据量)

```bash

## 线条绑定

### `addbinding(binding)` - 添加绑定

添加另一个线条作为绑定值设置时同步更新

```python

# 创建两个线条

source = LineBuffer()
target = LineBuffer()

# 添加绑定

source.addbinding(target)

# 设置值会自动同步

source[0] = 100.0
print(target[0])  # 100.0

```bash

- *应用场景**
- 指标输出线条绑定到策略访问
- 多个线条共享同一数据源
- 自动值传播机制

### `bind2lines(binding)` - 绑定到指定线条

绑定到所有者线条集合中的指定线条

```python

# 按索引绑定

line.bind2lines(0)  # 绑定到第 0 条线

# 按名称绑定

line.bind2lines('close')  # 绑定到名为 'close' 的线条

```bash

## exactbars 参数效果

`exactbars` 参数控制内存使用的严格程度

|  | 模式 | 描述 |

|----|------|------|

| `False` | 标准模式 | 保留所有历史数据 |

| `True` / `-1` | 精确模式 | 仅保留当前所需数据 |

| `-2` | 最小内存 | 最激进的内存优化 |

```python

# 在 Cerebro 中设置

cerebro = bt.Cerebro()
cerebro.run(exactbars=True)   # 精确模式

cerebro.run(exactbars=-1)     # 同 True

cerebro.run(exactbars=-2)     # 最小内存模式

```bash

### 内存对比表

| 模式 | 内存使用 | 数据保留 | 适用场景 |

|------|----------|----------|----------|

| `exactbars=False` |  | 所有历史数据 | 策略开发调试 |

| `exactbars=True` |  | 最小所需数据 | 长期回测 |

| `exactbars=-2` |  | 当前值 | 生产环境 |

```python

# 示例:10000 根 K 线回测

# exactbars=False: ~10000 × 8 字节 × 线条数

# exactbars=True:  ~minperiod × 8 字节 × 线条数

# exactbars=-2:    ~1 × 8 字节 × 线条数

```bash

## 性能优化技术

### 1. 预计算标志位

```python

# 在 __init__ 中预计算,避免重复检查

self._is_datetime_line = "datetime" in str(self._name).lower()
self._is_indicator = self._ltype == 0
self._default_value = float("nan") if self._is_indicator else 0.0

```bash

### 2. 快速 NaN 检测

```python

# 使用 NaN 自身不等特性,比 isinstance + math.isnan 快得多

if value != value:  # NaN 检测
    value = self._default_value

```bash

### 3. 属性直接访问

```python

# 预先初始化所有属性,消除运行时 hasattr 检查

self._idx = -1
self._array = array.array("d")
self._size = 0

# ... 所有属性在 __init__ 中初始化

```bash

### 4. 批量数组扩展

```python

# 批量扩展优于单次追加

self.array.extend([value] *size)  # 一次性

# 而不是:

# for _ in range(size):

# self.array.append(value)

```bash

### 5. 缓存优化

```python

# datetime() 方法缓存

if ago == 0 and tz is None and naive:

# 检查缓存
    if (self._dt_cache_idx == current_idx and
        self._dt_cache_tz == self._tz and
        self._dt_cache_value == value):
        return self._dt_cache_dt  # 缓存命中

```bash

### 性能对比

| 操作 | 优化前 | 优化后 | 提升 |

|------|--------|--------|------|

| `__len__()` | 0.611s | 0.05s | 92% |

| `__setitem__` | 基准 | 优化 | 15-20% |

| `__getitem__` | 基准 | 优化 | 10-15% |

| `forward()` | 基准 | 优化 | 20-30% |

## 日期时间方法

### `datetime(ago=0, tz=None, naive=True)` - 获取 datetime

获取指定偏移位置的 datetime 对象

```python

# 获取当前时间

dt = buffer.datetime()

# 获取前一根 K 线的时间

dt = buffer.datetime(ago=-1)

# 指定时区

dt = buffer.datetime(tz=pytz.UTC)

# 返回 naive datetime(无时区信息)

dt = buffer.datetime(naive=True)

```bash

### `date(ago=0)` - 获取日期

获取 datetime 的日期部分

```python
date_obj = buffer.date()

# 返回: datetime.date 对象

```bash

### `time(ago=0)` - 获取时间

获取 datetime 的时间部分

```python
time_obj = buffer.time()

# 返回: datetime.time 对象

```bash

### 便捷方法

```python

# dt 是 datetime 的简写

dt = buffer.dt(ago=-1)

# tm - 获取 struct_time

tm = buffer.tm()

# 兼容 strftime 格式化

# tm_raw - 带时区的 struct_time

tm_raw = buffer.tm_raw()

```bash

### 时间比较方法

```python

# 时间比较

buffer.tm_lt(other, ago=0)  # 小于

buffer.tm_le(other, ago=0)  # 小于等于

buffer.tm_eq(other, ago=0)  # 等于

buffer.tm_gt(other, ago=0)  # 大于

buffer.tm_ge(other, ago=0)  # 大于等于

```bash

## 子类

### LineActions

带有多条线的线条对象的基类

```python
class LineActions(LineBuffer, LineActionsMixin, metabase.ParamsMixin):
    """带有多条线的线条类基类"""
    _ltype = LineRoot.IndType  # 指标类型
    plotlines = object()        # 绘图配置

```bash

### LinesOperation / LineOwnOperation

用于线条间的运算

```python

# 二元操作

result = LinesOperation(line1, line2, operator.sub)

# 一元操作

result = LineOwnOperation(line, operator.neg)

```bash

### _LineDelay / _LineForward

延迟和前瞻线条

```python

# 延迟线条(历史访问)

delayed = LineDelay(line, ago=-10)  # 10 个周期前的值

# 前瞻线条(未来访问)

forward = LineForward(line, ago=5)   # 5 个周期后的值

```bash

### PseudoArray

非数组迭代器的包装器

```python

# 包装常数

pseudo = PseudoArray(itertools.repeat(1.0))

# 包装任意可迭代对象

pseudo = PseudoArray([1, 2, 3, 4, 5])

```bash

## 缓冲区操作示例

### 基本用法

```python
import backtrader as bt

# 创建缓冲区

buffer = bt.LineBuffer()

# 重置到起始

buffer.home()

# 添加数据

for i in range(10):
    buffer.forward()
    buffer[0] = float(i* 10)

# 访问数据

print(buffer[0])   # 90.0 (当前值)

print(buffer[-1])  # 80.0 (前一个值)

print(buffer[-5])  # 50.0 (5 个周期前)

```bash

### QBuffer 模式

```python

# 启用 QBuffer 模式

buffer = bt.LineBuffer()
buffer.qbuffer(savemem=1, extrasize=0)

# 添加超过 maxlen 的数据

for i in range(100):
    buffer.forward()
    buffer[0] = float(i)

# 只有最近的数据被保留

print(len(buffer))      # 100 (逻辑长度)

print(buffer.maxlen)    # 实际存储的限制

```bash

### 线条绑定

```python

# 创建源和目标缓冲区

source = bt.LineBuffer()
target = bt.LineBuffer()

# 添加绑定

source.addbinding(target)

# 设置值会同步

source.home()
target.home()

source.forward()
source[0] = 100.0

print(target[0])  # 100.0 (自动同步)

```bash

### 使用 extend 进行前瞻

```python

# 扩展缓冲区用于未来数据

buffer.extend(size=5)
buffer.extension  # 5

# 可以设置未来值

buffer[1] = 110.0
buffer[2] = 120.0

# 移动到未来位置

buffer.forward()
print(buffer[0])  # 110.0

```bash

## 常见用例

### 指标开发

```python
class MyIndicator(bt.Indicator):
    lines = ('output',)

    def __init__(self):

# 输出线条是 LineBuffer
        self.lines.output  # LineBuffer 实例

    def next(self):

# 设置输出值
        self.lines.output[0] = self.calculate()

```bash

### 数据访问

```python
class MyStrategy(bt.Strategy):
    def next(self):

# 数据线条是 LineBuffer
        close = self.data.close  # LineBuffer

# 访问当前值
        current_price = close[0]

# 访问历史值
        prev_price = close[-1]

# 获取多个值
        prices = close.get(ago=0, size=5)

```bash

### 内存优化

```python

# 为长期回测启用内存优化

cerebro = bt.Cerebro()

# 方法 1: exactbars

cerebro.run(exactbars=True)

# 方法 2: 预加载后使用 qbuffer

data = bt.feeds.BacktraderData(dataname='data.csv')
cerebro.adddata(data)
cerebro.run(runonce=True)  # 预加载所有数据

# 然后线条会使用 qbuffer 模式

```bash

## 注意事项

1. **索引含义**索引 0 总是当前值正索引是过去负索引是未来
2. **初始状态**创建后需要调用 `home()` 或先 `forward()` 才能访问数据
3. **QBuffer 限制**QBuffer 模式下超出 maxlen 的历史数据会被丢弃
4. **绑定更新**设置值会自动更新所有绑定线条
5. **性能考虑**:`forward()` 是热路径经过高度优化
6. **datetime 线条**datetime 线条使用特殊处理值必须 >= 1.0
7. **NaN 处理**指标使用 NaN 作为无效值数据源使用 0.0

## 相关文档

- [Strategy API](strategy_zh.md) - 策略中如何使用线条
- [Indicator API](indicator_zh.md) - 指标线条系统
- [Data Feeds API](data-feeds_zh.md) - 数据源线条
- [LineRoot API](lineroot_zh.md) - 线条基类