Katkat

Fetch and Cache Daily Stock Prices Across a Date Range

TradedeskSoftware Engineer · Online Assessment

Last updated

This problem tests your ability to build a resilient data-fetching client that handles network unreliability, data integrity validation, and efficient caching patterns.

Problem: Stock Data Fetcher

You are tasked with implementing a StockDataClient that retrieves daily opening and closing prices for a given ticker symbol over a specific date range. You must interact with a mock external API that provides data in paginated JSON format.

Requirements

  1. API Interface: Use a provided fetch_page(ticker, start_date, end_date, page_token) function which returns a dictionary: {'data': [...], 'next_page_token': str or None}.
  2. Data Integrity: Ensure the returned list includes every calendar date in the requested range. If the API returns missing dates, identify them as 'missing'.
  3. Resilience: Implement a bounded retry strategy (e.g., 3 attempts) with exponential backoff for transient network errors (HTTP 5xx, timeouts).
  4. Caching: Implement a local cache (in-memory) to avoid redundant requests for the same ticker-date pairs.
  5. Validation: Prices must be parsed as decimal.Decimal objects to maintain precision.

Function Signature

from decimal import Decimal
from typing import List, Dict, Optional
from datetime import date

class StockDataClient:
    def get_price_history(self, ticker: str, start_date: date, end_date: date) -> List[Dict]:
        """
        Returns a list of dicts: {'date': date, 'open': Decimal, 'close': Decimal}
        Sorted by date ascending.
        """
        pass

Example

Input: ticker='AAPL', start_date=2023-01-01, end_date=2023-01-02 Output:

[
  {"date": "2023-01-01", "open": "150.00", "close": "152.50"},
  {"date": "2023-01-02", "open": "152.50", "close": "151.00"}
]

Constraints

  • The range can span up to 5 years.
  • API results may contain duplicate date entries; ensure your client deduplicates them.
  • Handle cases where the API returns an empty list or an error code.

Hints

Hint 1

Use a set to track which dates have already been fetched to handle overlapping requests and duplicates efficiently.

Hint 2

Implement the retry logic as a decorator or a helper method to keep the main business logic clean and readable.

Hint 3

Since the API is paginated, use a 'while' loop to consume tokens until `next_page_token` becomes null.

Follow-up questions

  • How would you modify your implementation to support concurrent requests if the API supports fetching multiple tickers at once?
  • If the cache grows too large, what eviction policy would you implement and why?
  • How would you adapt this code if you needed to persist the cache to a database instead of keeping it in memory?