Skip to content

[Watchlists] watchlist.py — WatchlistManager class with get_sector, get_all_tickers, list_sectors #38

Description

@DogInfantry

Part of epic: #31
Depends on: #37 (config.yaml watchlists section must exist first)

What

Create watchlist.py with a WatchlistManager class that reads the watchlists: section from config.yaml and exposes three methods used by the pipeline and CLI.

Implementation

from typing import List
import yaml

class WatchlistManager:
    def __init__(self, config_path: str = 'config.yaml'):
        with open(config_path) as f:
            cfg = yaml.safe_load(f)
        self.watchlists = cfg.get('watchlists', {})

    def get_sector(self, sector: str) -> List[str]:
        """Return ticker list for a GICS sector name (case-insensitive)."""
        return self.watchlists.get(sector.lower(), [])

    def get_all_tickers(self) -> List[str]:
        """Return deduplicated flat list of all tickers across all sectors."""
        seen = set()
        result = []
        for tickers in self.watchlists.values():
            for t in tickers:
                if t not in seen:
                    seen.add(t)
                    result.append(t)
        return result

    def list_sectors(self) -> List[str]:
        """Return all available sector names."""
        return list(self.watchlists.keys())

Unit tests (tests/test_watchlist.py)

def test_get_sector_returns_list():
    wm = WatchlistManager('config.yaml')
    tickers = wm.get_sector('technology')
    assert isinstance(tickers, list)
    assert len(tickers) > 0
    assert 'AAPL' in tickers

def test_get_all_tickers_no_duplicates():
    wm = WatchlistManager('config.yaml')
    all_t = wm.get_all_tickers()
    assert len(all_t) == len(set(all_t))

def test_list_sectors_has_11():
    wm = WatchlistManager('config.yaml')
    assert len(wm.list_sectors()) == 11

def test_unknown_sector_returns_empty():
    wm = WatchlistManager('config.yaml')
    assert wm.get_sector('nonexistent') == []

Acceptance Criteria

  • watchlist.py exists at repo root (or src/watchlist.py)
  • All 3 methods implemented and documented with docstrings
  • All 4 unit tests pass
  • WatchlistManager imported and used in pipeline_v2.py to replace hardcoded ticker list

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requesthelp wantedExtra attention is needed

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions