Skip to content

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)