Skip to content
FINSABER v2.0

Financial backtesting, made explicit.

A package-oriented framework for evaluating strategies over prices, news, filings, and extensible market data with clear timing, adjustment, liquidity, slippage, and LLM-cost assumptions.

FINSABER

FINSABER is a research framework for evaluating financial trading strategies over price, news, filings, and extensible market data. The v2.0 branch upgrades the original FINSABER code into a package-oriented backtesting framework with explicit execution assumptions and structured result artifacts.

2Backtest engines
4+Data modalities
5Cost controls
CSV/JSONResult artifacts

Framework Highlights

If you are new to the framework, read in this order:

  1. Backtesting Concepts for finance and backtesting vocabulary.
  2. Quick Start to run a short buy-and-hold example.
  3. Configuration to understand every important run setting.
  4. Data and Strategies when plugging in your own dataset or model.
  5. Execution Model and Results before interpreting performance.

The installable wheel intentionally focuses on reusable backtesting infrastructure. Paper-specific FinMem, FinAgent, FinCon, and FinRL integrations remain available in the repository, but the package exports data loaders, execution models, metrics, result writers, selectors, and strategy interfaces.

Workflow

The repository includes the original FINSABER pipeline figure:

FINSABER framework pipeline

At the framework level, the upgraded backtesting path follows this lifecycle:

flowchart LR
    A[TradingData] --> B[TradeConfig]
    B --> C{Engine}
    C --> D[FINSABERBt]
    C --> E[FINSABER]
    D --> F[Strategy decisions]
    E --> F
    F --> G[Execution model]
    G --> H[Metrics and artifacts]

The dataset implements TradingData, the config defines the market universe and execution assumptions, the engine iterates through dates and tickers, the strategy emits decisions, and the execution layer applies fills, costs, liquidity constraints, and metrics. See Architecture for the detailed lifecycle.

Start Quickly

from finsaber import FINSABERBt, FinsaberParquetDataset
from finsaber.strategy.timing import BuyAndHoldStrategy

data = FinsaberParquetDataset(r"I:\Data\finsaber2\sp500_2000_2025_parquet")

config = {
    "data_loader": data,
    "tickers": ["AAPL"],
    "date_from": "2024-01-02",
    "date_to": "2024-01-10",
    "setup_name": "demo",
    "execution_timing": "next_open",
    "save_results": True,
    "silence": True,
}

results = FINSABERBt(config).run_iterative_tickers(BuyAndHoldStrategy)
print(results["AAPL"]["total_return"])
from finsaber import TradingData

class MyDataset(TradingData):
    def get_data_by_date(self, date):
        return {"price": {}, "news": {}, "filing_k": {}, "filing_q": {}}
from finsaber.strategy.timing_llm import BaseStrategyIso

class MyAgent(BaseStrategyIso):
    def on_data(self, date, today_data, framework):
        price = today_data["price"]["AAPL"]["adjusted_close"]
        framework.buy(date, "AAPL", price, -1)

Engines

Use FINSABERBt for Backtrader-compatible timing strategies and baseline technical strategies.

Use FINSABER for Python-native or LLM-style strategies that consume date-level data and submit orders through the framework object.