A Python-based multi-asset backtesting system featuring automated data downloading, yield-to-price pricing engines, a core backtest engine with pluggable rebalancing algorithms, and an interactive FastAPI-based web console.
The system is designed for backtesting long-term asset allocation strategies (e.g., Permanent Portfolio) with support for arbitrary asset configurations.
Updates
-
2026-02-22
- Added a public template file for trend models so that users can more easily plug in their own models.
- Adjusted internal subproject references to point to the latest data/code snapshot.
- Cleaned up
.gitignorerules so thatconfig/assets.jsonis handled correctly and old file paths are no longer referenced.
-
2026-02-18
- Refactored the data loading and processing pipeline into clearer stages: incremental raw data download (per selected asset) and full-portfolio processing/alignment driven by configuration.
- Introduced the
DataProcessorclass to centralize yield-to-price engines (bond/cash) and build a flexible multi-asset price matrix that only drops fully-empty dates, deferring final "barrel effect" trimming to the backtest layer. - Updated the FastAPI endpoints:
POST /api/assets/downloadnow strictly works on user-selected assets, whilePOST /api/assets/processalways rebuildsaligned_assets.csvfrom all assets defined inconfig/assets.json, independent of UI selection.
-
2026-02-17
- Added UI controls for configuring an unsupervised trend model (model type, fixed lookback window, threshold) and wiring it through the backtest engine.
- Introduced a new
signal_weighted_rebalancealgorithm option that tilts portfolio weights based on per-asset trend signals (implementation details remain private). - Enhanced the Performance Chart to display Total Return, CAGR, Sharpe Ratio, and Max Drawdown for both the strategy and all selected benchmarks.
- Added a second subplot below the performance chart that shows the portfolio's asset weights over time as a stacked area plot.
project_root/
├── backend/
│ ├── api.py # FastAPI implementation and interactive Web UI (/ui)
│ └── service.py # Backtest service layer: Request/Result models and core orchestration
│
├── data/ # Raw asset data (CSV files named using sanitized asset names)
├── data_processed/
│ ├── aligned_assets.csv # Global aligned price matrix (built from all configured assets)
│ └── backtest_results_*.html # Interactive Plotly charts generated from backtest runs
│
├── data_loader/
│ ├── yahoo_downloader.py # Incremental OHLCV downloader using yfinance
│ ├── akshare_downloader.py # Incremental OHLCV downloader using akshare
│ └── data_processor.py # Yield-to-price conversion and multi-asset alignment
│
├── strategies/
│ ├── backtest_engine.py # Core simulation engine (Time loop + algorithm execution)
│ ├── trend_models_template.py # A template for trend_models.py
│ └── algorithms_template.py # A template for algorithms.py
│
├── utils/
│ ├── decorators.py # Generic decorators (e.g., @retry)
│ └── tools.py # Timezone and date utility functions
│
├── logs/app.log # System runtime logs
├── logger.py # Global logging configuration
├── main_download.py # Entry point: Data synchronization and processing
├── main_backtest.py # Entry point: CLI-based backtest execution
├── requirements.txt
└── README.md
- Algorithm Management: Automatically discovers rebalancing strategies from the
algorithmsmodule. - Job Execution: Orchestrates the full backtest workflow, including path resolution, engine instantiation, and result aggregation.
- Models: Defines
BacktestConfigandBacktestResultusing Pydantic for robust data validation.
- Web Interface: Provides an interactive dashboard at
/uiusing Tailwind CSS. - REST Endpoints:
GET /api/algorithms: Lists available rebalancing strategies.GET /api/assets: Retrieves configured assets and their local data availability.POST /api/assets: Creates an asset configuration.PUT /api/assets/{name}: Updates an asset configuration.DELETE /api/assets/{name}: Deletes an asset configuration.POST /api/assets/download: Incrementally downloads raw CSV data for selected assets (60s cooldown).POST /api/assets/process: Processes and aligns data for all configured assets intodata_processed/aligned_assets.csv.POST /api/backtest: Executes backtest simulations synchronously.
- Incremental Sync: Each asset is stored as
data/<sanitized_name>.csv. The downloader reads local history and only requests the missing date range from Yahoo Finance. - Column Normalization: Standardizes yfinance output into consistent OHLCV columns (
Open,High,Low,Close,Volume) and fills common gaps (e.g., zero/NaN OHLC usingClose). - Batch Mode:
download_batch(assets, start_year=1985)respects per-assetinitial_start_datewhen provided, otherwise falls back tostart_year.
- Yield-to-Price Engines:
bond_pricing_engine: Converts yield series into a synthetic total return price series (duration-based approximation).cash_pricing_engine: Converts short-rate yields into a cash-like cumulative return series.
- Alignment Strategy:
- Builds a multi-asset price matrix in-memory.
- Drops only dates where all assets are missing (
dropna(how="all")), preserving partial-missing dates. - Final date-range trimming for a specific backtest run is deferred to the backtest layer based on the selected asset subset.
- Persistence:
process_and_align(...)writes the aligned matrix todata_processed/aligned_assets.csv.
python -m venv .venv
source .venv/bin/activate # Windows: .venv\Scripts\activatepip install -r requirements.txt-
Configure assets via Web UI (Assets Management) or by editing
config/assets.json. -
Download / update raw data:
-
Via Web UI:
- Select assets in the Assets table and click Download Data (calls
POST /api/assets/download).
- Select assets in the Assets table and click Download Data (calls
-
Via CLI:
python main_download.py
-
-
Process and align data:
- Via Web UI:
- Click Process Data to rebuild
data_processed/aligned_assets.csvfrom all configured assets (callsPOST /api/assets/process).
- Click Process Data to rebuild
- Via Web UI:
mv strategies/algorithms_template.py strategies/algorithms.py
mv strategies/trend_models_template.py strategies/trend_models.pypython main_backtest.py-
Start the server:
python backend/api.py
-
Navigate to
http://127.0.0.1:8000/ui. -
(Optional) Download / process data.
-
Configure parameters and click Run Backtest.
- Rate Limiting: The Yahoo Finance downloader is subject to API rate limits. The system implements a 60-second cooldown on the download endpoint.
- Processing vs Selection:
Download Dataoperates on selected assets.Process Dataalways rebuildsaligned_assets.csvfrom all assets inconfig/assets.json.
- Adding Algorithms: New strategies can be added as static methods ending in
_rebalancewithinstrategies/algorithms.py. They will be automatically detected by the system.
