Lines & Data Series Architecture
Relevant source files
The following files were used as context for generating this wiki page:
The "Lines" architecture is the foundational data structure and processing paradigm of the Backtrader framework. It is designed to represent financial time series data (like price, volume, or indicators) as a series of evolving arrays that can be indexed relatively (e.g., [0] for current value, [-1] for previous value). This architecture allows for a declarative style of technical analysis where complex indicators are built by combining these "Lines" using standard mathematical operators.
At its core, the system distinguishes between LineSeries (the data containers) and LineIterators (the objects that consume or produce data). A Strategy is a high-level LineIterator that orchestrates multiple data feeds and indicators, processing them bar-by-bar during a backtest.
Sources: backtrader/lineseries.py, backtrader/lineiterator.py, backtrader/strategy.py:122-125
Core Components
LineBuffer
The LineBuffer is the fundamental unit of storage. It wraps a numerical array and provides the logic for relative indexing and "forward" movement in time. It supports memory-saving schemes where older data is purged once it is no longer needed by any dependent indicators.
Sources: backtrader/linebuffer.py
LineSeries
LineSeries represents a collection of LineBuffer objects. For example, a basic OHLC data feed is a LineSeries containing lines for open, high, low, close, volume, openinterest, and datetime.
The diagram shows the relationship where a LineSeries acts as a container for multiple LineBuffer instances, each representing a single dimension of data.
Sources: backtrader/lineseries.py:532-535, backtrader/linebuffer.py
LineIterator
The LineIterator is the base class for objects that iterate over data. It defines the lifecycle methods (prenext, nextstart, next) that are called as the simulation progresses.
| Component Type | Description |
|---|---|
| Strategy | A top-level iterator that coordinates data feeds and indicators. |
| Indicator | A derived iterator that consumes lines to produce new lines. |
| Observer | An iterator used to track and plot strategy statistics (e.g., Broker Value). |
Sources: backtrader/lineiterator.py:27-35, backtrader/strategy.py:122-125
Data Flow and Execution
The execution flow in Backtrader is driven by the "Clock" (usually the first data feed). As the clock moves forward, the Strategy calls the update methods of its registered indicators and observers.
The diagram illustrates the bar-by-bar processing loop where Cerebro drives the DataFeed to load new values, which then triggers the Strategy and its associated Indicators to update.
Sources: backtrader/strategy.py:382-410, backtrader/lineiterator.py:161-175
Logic and Functional Operations
Backtrader uses a "Lazy Evaluation" or "Line Action" pattern for mathematical operations. Instead of calculating values immediately, operations on lines (like a + b) return a LineActions object (defined in functions.py). These objects are themselves LineSeries that calculate their values only when requested during the next() cycle.
Key Logic Classes
- DivByZero: Handles division while avoiding exceptions by returning a default value if the denominator is zero.
- If: A line-based ternary operator:
If(condition_line, value_if_true_line, value_if_false_line). - And/Or: Logical operations that reduce multiple lines into a single boolean line.
Sources: backtrader/functions.py:65-70, backtrader/functions.py:186-192, backtrader/functions.py:266-270
Memory Management (QBuffer)
The architecture supports memory-saving schemes via the qbuffer method. This is critical for long backtests with many indicators.
| Savemem Level | Description |
|---|---|
0 | No savings. All values are kept in memory. |
1 | Strict minimum. Only the current and necessary lookback values are kept. |
-1 / -2 | Used for plotting. Keeps data for elements that need to be rendered while saving others. |
Sources: backtrader/strategy.py:133-150, backtrader/linebuffer.py
Conclusion
The Lines & Data Series Architecture provides a robust framework for financial modeling by treating time-series data as first-class objects. By decoupling the storage (LineBuffer) from the logic (LineActions) and the execution (LineIterator), the system achieves a high degree of modularity. This allows developers to focus on strategy and indicator logic using relative indexing, while the underlying architecture handles data synchronization, memory management, and iteration.
Sources: backtrader/lineseries.py, backtrader/lineiterator.py, backtrader/strategy.py