Goal
Implement a small internal data model for historical exchange-rate and market time-series data.
Why
ARGUS uses multiple data sources such as the existing ExchangeRate API client, yfinance and possibly Frankfurter later. These sources return different response formats.
The analytics, dashboard, reporting, forecasting and future storage layers should not depend directly on external API response structures.
The storage research in docs/research-databases-and-storage.md already recommends a normalized model direction based on:
data_sources
instruments
price_bars
This ticket should turn that research into the first practical internal model that later storage and analytics code can use.
Implementation plan
- Define a small internal model for market time-series data.
- Support both FX rates and broader market data.
- Keep the model OHLCV-ready, but allow fields such as
open, high, low, adjusted_close and volume to be optional.
- Represent FX rates from simple rate sources as
close values.
- Add helper conversion logic for pandas-friendly output if useful.
- Add tests for the model and normalization behavior.
- Document the model briefly in
docs/ or near the implementation.
Scope
- Add internal model types for:
- data source metadata
- instruments
- price bars / time-series rows
- Define required fields for the first implementation:
- source name or source identifier
- instrument symbol
- asset class
- timestamp / date
- timeframe
- close value
- Define optional OHLCV-ready fields:
- open
- high
- low
- adjusted_close
- volume
- currency
- exchange
- base_currency
- quote_currency
- Add basic validation where useful:
- required fields are present
close is numeric
- timestamp/date can be handled consistently
- timeframe is set for daily data, for example
1d
- Add a small normalization helper or documented mapping for converting client data into the internal model.
Out of scope
- No DuckDB implementation in this ticket
- No database schema migration in this ticket
- No full replacement of existing data clients unless a very small adapter is needed
Acceptance criteria
Goal
Implement a small internal data model for historical exchange-rate and market time-series data.
Why
ARGUS uses multiple data sources such as the existing ExchangeRate API client, yfinance and possibly Frankfurter later. These sources return different response formats.
The analytics, dashboard, reporting, forecasting and future storage layers should not depend directly on external API response structures.
The storage research in
docs/research-databases-and-storage.mdalready recommends a normalized model direction based on:This ticket should turn that research into the first practical internal model that later storage and analytics code can use.
Implementation plan
open,high,low,adjusted_closeandvolumeto be optional.closevalues.docs/or near the implementation.Scope
closeis numeric1dOut of scope
Acceptance criteria
price_bars-style row with the rate stored asclosedocs/research-databases-and-storage.mdNote
Priority: Must