ZhuLinsen/daily_stock_analysis · warning · DataFetchError

[AlphaVantage] {stock_code} is not a US stock

Error message

[AlphaVantage] {stock_code} is not a US stock

What it means

A guard DataFetchError raised by AlphaVantageFetcher._fetch_raw_data when is_us_stock_code(stock_code) returns False. AlphaVantage's TIME_SERIES_DAILY only covers US symbols, so the fetcher rejects A-share/HK/ETF codes upfront with a clear message instead of sending a doomed API call. The intent is that DataFetcherManager routes the code to a source that supports its market.

Source

Thrown at data_provider/alphavantage_fetcher.py:45

class AlphaVantageFetcher(BaseFetcher):
    name = "AlphaVantageFetcher"
    priority = 3

    def __init__(self):
        from src.config import get_config
        config = get_config()
        self._api_key = getattr(config, 'alphavantage_api_key', None) or os.getenv('ALPHAVANTAGE_API_KEY')
        if not self._api_key:
            logger.debug("[AlphaVantage] API key not configured, fetcher disabled")

    def _is_us_stock(self, stock_code: str) -> bool:
        return is_us_stock_code(stock_code)

    def _fetch_raw_data(self, stock_code: str, start_date: str, end_date: str) -> pd.DataFrame:
        if not self._api_key:
            raise DataFetchError("[AlphaVantage] API key not configured")
        if not self._is_us_stock(stock_code):
            raise DataFetchError(f"[AlphaVantage] {stock_code} is not a US stock")

        symbol = stock_code.strip().upper()
        params = {
            'function': 'TIME_SERIES_DAILY',
            'symbol': symbol,
            'outputsize': 'compact',
            'apikey': self._api_key,
        }

        try:
            self.random_sleep(0.5, 1.5)
            resp = requests.get(_AV_BASE_URL, params=params, timeout=30)
            resp.raise_for_status()
            data = resp.json()
        except Exception as e:
            raise DataFetchError(f"[AlphaVantage] HTTP request failed for {symbol}: {e}") from e

        if 'Note' in data:

View on GitHub (pinned to 5159bd72e8)

Solutions

  1. Only route plain US tickers (e.g. 'AAPL', 'AMD') to AlphaVantageFetcher; move it after market-aware sources in the chain.
  2. If your code format is valid US but rejected, check is_us_stock_code's rules and normalize the symbol (strip suffixes, uppercase) before fetching.
  3. Catch this error as a routing signal and dispatch to Akshare/Baostock per market.

Example fix

# before
df = av_fetcher.fetch('600519', start, end)  # raises

# after
from data_provider.utils import is_us_stock_code
if is_us_stock_code(code):
    df = av_fetcher.fetch(code, start, end)
else:
    df = manager.fetch(code, start, end)  # market-aware routing
Defensive patterns

Strategy: validation

Validate before calling

from data_provider.utils import is_us_stock_code
if not is_us_stock_code(stock_code):
    raise ValueError(f'{stock_code} must go to an A-share/HK source, not AlphaVantage')

Type guard

from data_provider.utils import is_us_stock_code

def requires_alpha_vantage(code: str) -> bool:
    """True only for plain US tickers AlphaVantage can serve."""
    return is_us_stock_code(code)

Try / catch

try:
    df = av_fetcher.fetch(code, start, end)
except DataFetchError as e:
    if 'is not a US stock' in str(e):
        df = manager.fetch(code, start, end)  # market-aware routing
    else:
        raise

Prevention

When it happens

Trigger: Passing codes like '600519' (A-share), 'hk00700' (HK), or an ETF code to AlphaVantageFetcher; also US-like strings that the is_us_stock_code heuristic rejects (e.g. lowercase-only symbols or ones with unexpected suffixes). The check happens before any HTTP request.

Common situations: AlphaVantage placed too early in the fetcher priority list so non-US codes hit it first; user config mixing markets in one watchlist; a custom code format (e.g. 'AAPL.US') failing the US heuristic.

Related errors


AI-assisted analysis of ZhuLinsen/daily_stock_analysis@5159bd72e8 (2026-08-15). Data as JSON: /api/errors/34c257f9c72f4fdb. Report an issue: GitHub.