Storage
Backtide persists all downloaded OHLCV bars and dividend data in a local DuckDB database so that subsequent runs can reuse previously fetched data instead of hitting the network again. The storage layer is fully automatic — bars are written as they are downloaded — but convenience functions are exposed for inspection and housekeeping.
The database file is located at the path specified by the storage_path
setting in DataConfig. By default, this is .backtide/database.duckdb,
relative to the working directory.
Querying data
All query functions return a dataframe whose type matches the configured DataFrameLibrary.
| Function | Description |
|---|---|
query_bars |
Retrieve stored OHLCV bars, optionally filtered by symbol, interval and provider. |
query_bars_summary |
Get a compact summary of every stored series (symbol, interval, provider, date range, row count). |
query_dividends |
Retrieve stored dividend records, optionally filtered by symbol and provider. |
query_instruments |
List the instrument metadata cached during download. |
>>> from backtide.storage import query_bars, query_bars_summary
>>> # Show everything in the database
>>> summary = query_bars_summary()
>>> print(summary.head())
symbol ... sparkline
0 AAPL ... [235.8233184814453, 238.0689697265625, 241.109...
1 AAPL ... [263.3500061035156, 262.7300109863281, 262.450...
2 BTC-EUR ... [40018.60546875, 41089.29296875, 39215.9804687...
3 EUR-USD ... [1.1055831909179688, 1.1038745641708374, 1.094...
4 MSFT ... [419.4018249511719, 426.8497619628906, 427.067...
[5 rows x 12 columns]
>>> # Fetch daily bars for a specific symbol
>>> df = query_bars("AAPL", "1d")
>>> print(df.head())
symbol interval provider ... adj_close volume n_trades
0 AAPL 1d yahoo ... 0.098207 469033600.0 None
1 AAPL 1d yahoo ... 0.093083 175884800.0 None
2 AAPL 1d yahoo ... 0.086251 105728000.0 None
3 AAPL 1d yahoo ... 0.088386 86441600.0 None
4 AAPL 1d yahoo ... 0.090949 73449600.0 None
[5 rows x 13 columns]
Deleting data
Use delete_symbols to remove bars (and any orphaned dividend records)
from the database. You can target specific symbols, intervals and providers,
or pass a list of (symbol, interval, provider) triples for batch deletion.
>>> from backtide.storage import delete_symbols
>>> # Delete all daily bars for AAPL
>>> delete_symbols("AAPL", "1d")
>>> # Delete everything for a specific provider
>>> delete_symbols(provider="yahoo")
Storage in the UI
The Storage page in the Streamlit application provides a visual overview of all stored series. From there you can inspect date ranges, row counts and sparklines, select series for analysis, or delete them in bulk.
The Experiment page also offers a Use stored data toggle. When enabled, the backtest draws exclusively from the local database without downloading new data — the available date range is determined entirely by what has already been stored.
Layout on disk
Underneath storage_path (default .backtide/) the application keeps a
handful of subdirectories alongside the DuckDB file. The DuckDB file stores
market data and experiment results; the subdirectories store user-defined
artifacts (strategies, indicators, configs, logs).
.backtide/
├── database.duckdb # OHLCV bars, dividends, instruments, experiment results
├── strategies/
│ └── <name>.pkl # One pickled strategy instance per saved strategy
├── indicators/
│ └── <name>.pkl # One pickled indicator instance per saved indicator
└── experiments/
└── <experiment_id>/
├── config.toml # Exact configuration the run was launched with
└── logs.txt # Full per-experiment engine log (info + debug)