Data module for tzutrader - Yahoo Finance integration
This module provides data streaming and fetching capabilities using Yahoo Finance as the data source via the yfnim library.
Features:
- Historical OHLCV data retrieval
- Real-time/delayed quote data
- Multiple time intervals (1m, 5m, 15m, 30m, 1h, 1d, 1wk, 1mo)
- Simple caching mechanism
- Iterator interface for streaming data
- Mock data generation for testing
Types
CSVDataStream = ref object filename*: string data*: seq[OHLCV] index*: int symbol*: string
- CSV-based data stream for backtesting Reads OHLCV data from CSV files
DataStream = ref object symbol*: string interval*: Interval cache*: seq[OHLCV] cacheStart*: int64 cacheEnd*: int64 useCache*: bool
- Data stream for a specific symbol
Interval = enum Int1m = "1m", ## 1 minute (max ~7 days history) Int5m = "5m", ## 5 minutes (max ~60 days history) Int15m = "15m", ## 15 minutes (max ~60 days history) Int30m = "30m", ## 30 minutes (max ~60 days history) Int1h = "1h", ## 1 hour (max ~2 years history) Int1d = "1d", ## 1 day (unlimited history) Int1wk = "1wk", ## 1 week (unlimited history) Int1mo = "1mo" ## 1 month (unlimited history)
- Time intervals for data fetching (matching yfnim)
Quote = object symbol*: string timestamp*: int64 regularMarketPrice*: float64 regularMarketChange*: float64 regularMarketChangePercent*: float64 regularMarketVolume*: float64 regularMarketOpen*: float64 regularMarketDayHigh*: float64 regularMarketDayLow*: float64 regularMarketPreviousClose*: float64
- Real-time quote data
Procs
proc `$`(ds: DataStream): string {....raises: [], tags: [], forbids: [].}
- String representation of DataStream
proc `$`(interval: Interval): string {....raises: [], tags: [], forbids: [].}
- String representation of Interval
proc `$`(quote: Quote): string {....raises: [], tags: [], forbids: [].}
- String representation of Quote
proc `$`(stream: CSVDataStream): string {....raises: [], tags: [], forbids: [].}
- String representation of CSV stream
proc addToCache(ds: DataStream; data: seq[OHLCV]) {....raises: [], tags: [], forbids: [].}
- Add data to cache
proc clearCache(ds: DataStream) {....raises: [], tags: [], forbids: [].}
- Clear the data stream cache
proc fetch(ds: DataStream; days: int): seq[OHLCV] {....raises: [], tags: [TimeEffect], forbids: [].}
- Fetch historical data for the last N days
proc fetch(ds: DataStream; startTime, endTime: int64): seq[OHLCV] {....raises: [], tags: [], forbids: [].}
- Fetch historical OHLCV data for the time range Uses cache if available and valid
proc fetchHistoryYfnim(ds: DataStream; startTime, endTime: int64): seq[OHLCV] {. ...raises: [], tags: [], forbids: [].}
- Fallback: Generate mock data
proc fetchMultiple(symbols: seq[string]; startTime, endTime: int64; interval: Interval = Int1d): Table[string, seq[OHLCV]] {. ...raises: [], tags: [], forbids: [].}
- Fetch data for multiple symbols
proc fetchQuoteYfnim(symbol: string): Quote {....raises: [], tags: [TimeEffect], forbids: [].}
- Fallback: Generate mock quote
proc generateMockOHLCV(symbol: string; startTime, endTime: int64; interval: Interval; startPrice: float64 = 100.0; volatility: float64 = 0.02): seq[OHLCV] {....raises: [], tags: [], forbids: [].}
-
Generate mock OHLCV data for testing
Args: symbol: Stock symbol startTime: Start timestamp (Unix) endTime: End timestamp (Unix) interval: Time interval between bars startPrice: Starting price (default 100.0) volatility: Daily volatility as decimal (default 0.02 = 2%)
proc generateMockQuote(symbol: string; price: float64 = 100.0): Quote {. ...raises: [], tags: [TimeEffect], forbids: [].}
- Generate a mock quote for testing
proc getCached(ds: DataStream; startTime, endTime: int64): seq[OHLCV] {. ...raises: [], tags: [], forbids: [].}
- Get data from cache for the specified time range
proc hasNext(stream: CSVDataStream): bool {....raises: [], tags: [], forbids: [].}
- Check if stream has more data
proc isCached(ds: DataStream; startTime, endTime: int64): bool {....raises: [], tags: [], forbids: [].}
- Check if requested time range is in cache
proc latest(ds: DataStream): OHLCV {....raises: [DataError], tags: [TimeEffect], forbids: [].}
- Get the most recent OHLCV bar
proc len(stream: CSVDataStream): int {....raises: [], tags: [], forbids: [].}
- Get total number of bars in stream
proc maxHistory(interval: Interval): int64 {....raises: [], tags: [], forbids: [].}
proc newCSVDataStream(filename: string; symbol: string = ""): CSVDataStream {. ...raises: [IOError, DataError], tags: [ReadIOEffect], forbids: [].}
-
Create a new CSV data stream
Args: filename: Path to CSV file symbol: Optional symbol name (extracted from filename if not provided)
Example: let stream = newCSVDataStream("data/AAPL.csv") for bar in stream.items(): echo bar
proc newDataStream(symbol: string; interval: Interval = Int1d; useCache: bool = true): DataStream {....raises: [], tags: [], forbids: [].}
- Create a new data stream for a symbol
proc next(stream: CSVDataStream): OHLCV {....raises: [], tags: [], forbids: [].}
- Get next bar from stream Raises IndexDefect if at end of stream
proc peek(stream: CSVDataStream): OHLCV {....raises: [], tags: [], forbids: [].}
- Get current bar without advancing Raises IndexDefect if at end of stream
proc readCSV(filename: string; hasHeader: bool = true): seq[OHLCV] {. ...raises: [IOError, DataError, DataError], tags: [ReadIOEffect], forbids: [].}
-
Read OHLCV data from CSV file
CSV Format: timestamp,open,high,low,close,volume 1609459200,100.0,105.0,95.0,102.0,1000000.0
Args: filename: Input CSV file path hasHeader: Skip first line if true (default true)
Returns: Sequence of OHLCV bars
proc remaining(stream: CSVDataStream): int {....raises: [], tags: [], forbids: [].}
- Get number of remaining bars
proc reset(stream: CSVDataStream) {....raises: [], tags: [], forbids: [].}
- Reset the stream to the beginning
proc writeCSV(data: seq[OHLCV]; filename: string; includeHeader: bool = true) {. ...raises: [IOError], tags: [WriteIOEffect], forbids: [].}
-
Write OHLCV data to CSV file
CSV Format: timestamp,open,high,low,close,volume 1609459200,100.0,105.0,95.0,102.0,1000000.0
Args: data: OHLCV data to write filename: Output CSV file path includeHeader: Include column headers (default true)
Iterators
iterator items(stream: CSVDataStream): OHLCV {....raises: [], tags: [], forbids: [].}
- Iterate over all bars in stream
iterator stream(ds: DataStream; startTime, endTime: int64): OHLCV {....raises: [], tags: [], forbids: [].}
- Stream OHLCV data one bar at a time