title: Line System description: Core data structure for time series


Line System

The Line System is the fundamental data structure in Backtrader for handling time series data.

Overview

classDiagram
    LineRoot <|-- LineBuffer

    LineBuffer <|-- LineSeries

    LineSeries <|-- LineIterator

    LineIterator <|-- Indicator

    LineIterator <|-- Observer

    LineIterator <|-- Strategy

```bash

## Hierarchy

### LineRoot

Base interface providing core operations:

```python
class LineRoot:
    def get(self, size=None):
        """Get data as array."""

    def __len__(self):
        """Return line length."""

    def datetime(self, index=0):
        """Get datetime at index."""

```bash

### LineBuffer

Circular buffer implementation for efficient memory usage:

```python
class LineBuffer:
    def __getitem__(self, key):
        """Access data by index.
        [0] = current, [-1] = previous, [-2] = 2 bars ago
        """

    def __setitem__(self, key, value):
        """Set data at index."""

    @property
    def minperiod(self):
        """Minimum data points needed."""

```bash

### LineSeries

Time series operations:

```python
class LineSeries:
    def align(self):
        """Align to data timeframe."""

    def date(self, index=0):
        """Get date at index."""

    def time(self, index=0):
        """Get time at index."""

```bash

### LineIterator

Execution phases and iteration logic:

```python
class LineIterator:

# Line types
    IndType = 0  # Indicator
    ObsType = 2  # Observer
    StrType = 3  # Strategy

    def prenext(self):
        """Called before minperiod satisfied."""

    def nextstart(self):
        """Called when minperiod first satisfied."""

    def next(self):
        """Called for each bar after minperiod."""

```bash

## Access Patterns

### Current and Historical Data

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

# Current value
        current = self.data.close[0]

# Previous values
        prev1 = self.data.close[-1]
        prev2 = self.data.close[-2]

# Slice (returns array)
        recent = self.data.close.get(size=5)

```bash

### Data Length

```python

# Total bars available

total_bars = len(self.data)

# Bars processed so far in next()

processed_bars = len(self.data.close)

```bash

### Datetime Access

```python

# Current bar datetime

dt = self.data.datetime.datetime(0)
date = self.data.datetime.date(0)
time = self.data.datetime.time(0)

```bash

## Line Aliases

Common line aliases for data feeds:

| Alias | Line | Description |

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

| `datetime` | datetime | Bar timestamp |

| `open` | open | Opening price |

| `high` | high | Highest price |

| `low` | low | Lowest price |

| `close` | close | Closing price |

| `volume` | volume | Trading volume |

| `openinterest` | openinterest | Open interest |

## Creating Custom Lines

### In Strategies

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

# Create a custom line
        self.lines.custom = self.data.close  # Alias

```bash

### In Indicators

```python
class MyIndicator(bt.Indicator):
    lines = ('signal',)  # Define output line

    def __init__(self):
        super().__init__()
        self.lines.signal = self.data.close - self.data.close(-1)

```bash

## Performance Considerations

### Circular Buffer

The circular buffer design:

- Fixed memory allocation
- Efficient append operations
- Automatic rollover

### Memory Management

```python

# Use qbuffer to limit memory for long backtests

data = bt.feeds.CSVGeneric(dataname='data.csv')
data.qbuffer(1000)  # Keep last 1000 bars in memory

```bash

## Common Patterns

### Lagging Values

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

# Lagged close price
        self.close_lag1 = self.data.close(-1)
        self.close_lag5 = self.data.close(-5)

```bash

### Price Change

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

# Price change
        self.change = self.data.close - self.data.close(-1)

# Percent change
        self.pct_change = (self.data.close / self.data.close(-1)) - 1

```bash

### Rolling Operations

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

# Rolling sum (manual)
        self.rolling_sum = bt.indicators.SumN(self.data.close, period=20)

# Or use indicator
        self.sma = bt.indicators.SMA(self.data.close, period=20)

```bash

## See Also

- [Phase System](phase-system.md)
- [Architecture Overview](overview.md)