Quick Start
This page walks through the shortest complete workflow: load data, define a run configuration, execute a strategy, and inspect output files.
What You Will Run
The example buys and holds AAPL over a short date range. It is intentionally simple because the first goal is to confirm the framework, data loader, execution model, and result writer are working.
Start small
Use one ticker and a short date range first. After the run succeeds, expand to more tickers, longer periods, selectors, or LLM strategies.
Step 1: Load Data
from finsaber import FinsaberParquetDataset
data = FinsaberParquetDataset(r"I:\Data\finsaber2\sp500_2000_2025_parquet")
The loader reads daily prices plus optional news and filings. It returns data through the common TradingData interface, so the engine does not need to know whether the source is parquet, memory, or a custom database.
Step 2: Define The Run
config = {
"data_loader": data,
"tickers": ["AAPL"],
"date_from": "2024-01-02",
"date_to": "2024-01-10",
"setup_name": "buy_hold_aapl",
"cash": 100_000,
"execution_timing": "next_open",
"commission_per_share": 0.0049,
"min_commission": 0.99,
"slippage_perc": 0.0005,
"liquidity_cap_pct": 0.025,
"save_results": True,
"silence": True,
}
The important financial choice is execution_timing="next_open". The strategy observes data for day t, submits an order, and the order fills at the next available adjusted open. This is usually safer than same-day close execution for date-level text data.
Step 3: Run A Strategy
Buy And Hold On Parquet Data
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": "buy_hold_aapl",
"cash": 100_000,
"execution_timing": "next_open",
"commission_per_share": 0.0049,
"min_commission": 0.99,
"slippage_perc": 0.0005,
"liquidity_cap_pct": 0.025,
"save_results": True,
"silence": True,
}
results = FINSABERBt(config).run_iterative_tickers(BuyAndHoldStrategy)
print(results["AAPL"]["total_return"])
from finsaber import FINSABER, FinsaberParquetDataset
from finsaber.strategy.timing_llm import BaseStrategyIso
class BuyOnce(BaseStrategyIso):
def on_data(self, date, today_data, framework):
bar = today_data["price"]["AAPL"]
if "AAPL" not in framework.portfolio:
framework.buy(date, "AAPL", bar["adjusted_close"], -1)
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": "buy_once_aapl",
"execution_timing": "next_open",
"save_results": True,
"silence": True,
}
results = FINSABER(config).run_iterative_tickers(BuyOnce)
This run uses adjusted prices for fills and valuation, applies commission, caps orders to 2.5% of prior average volume, and writes metrics and CSV artifacts under backtest/output/buy_hold_aapl/BuyAndHoldStrategy/.
Step 4: Read The Result
window = "2024-01-02_2024-01-10"
metrics = results[window]["AAPL"]
print(metrics["final_value"])
print(metrics["total_return"])
print(metrics["sharpe_ratio"])
If save_results=True, inspect:
backtest/output/buy_hold_aapl/BuyAndHoldStrategy/
run_config.json
run_summary.csv
2024-01-02_2024-01-10/AAPL/metrics.json
2024-01-02_2024-01-10/AAPL/equity_curve.csv
2024-01-02_2024-01-10/AAPL/orders.csv
Use run_summary.csv for comparisons across many tickers. Use metrics.json for one ticker. Use equity_curve.csv to plot portfolio value over time.
Configuration Checklist
Every run should specify:
data_loader: aTradingDataimplementation.tickers: a ticker list or"all".date_fromanddate_to: inclusive backtest dates.execution_timing: usually"next_open"for date-level features.setup_name: a stable run name for output paths.- Cost controls such as
commission_per_share,slippage_perc, andliquidity_cap_pct.
See Configuration for the full field guide.
In-Memory Dataset
For small experiments, wrap a date-keyed dictionary with FinsaberDataset.
from datetime import date
from finsaber import FINSABERBt, FinsaberDataset
from finsaber.strategy.timing import BuyAndHoldStrategy
loader = FinsaberDataset(data={
date(2024, 1, 2): {
"price": {
"DEMO": {
"open": 100.0,
"high": 102.0,
"low": 99.0,
"close": 101.0,
"adjusted_close": 101.0,
"volume": 1_000_000,
}
}
}
})
Use this format for unit tests, toy examples, or custom pipelines that already produce Python dictionaries. Use FinsaberParquetDataset for large historical runs.
See examples/custom_dataset_example.py for a runnable custom data example.
Result Location
By default, results are written under:
Set log_base_dir in the config to redirect output.