Technical Indicator Calculations in TradingAgents stockstats.py: Implementation and Architecture

The stockstats.py module in TradingAgents-CN wraps the stockstats library to compute technical indicators like SMA, MACD, and RSI by fetching price data from Yahoo Finance or local CSV caches and extracting values for specific trading dates.

The hsliuping/TradingAgents-CN repository implements a robust pipeline for technical indicator calculations in TradingAgents stockstats.py, bridging raw price data and algorithmic trading decisions. This implementation leverages the third-party stockstats library while adding intelligent caching, date-specific extraction, and both offline and online data modes.

Architecture of the Technical Indicator Pipeline

The StockstatsUtils Wrapper Class

At the core of the technical indicator calculations in TradingAgents stockstats.py lies the StockstatsUtils class, defined in tradingagents/dataflows/technical/stockstats.py. This class exposes a single public static method, get_stock_stats, which orchestrates the entire workflow from data ingestion to indicator extraction.

The method signature accepts five parameters: symbol (ticker string), indicator (stockstats-compatible name), curr_date (target date in YYYY-MM-DD format), data_dir (local CSV storage path), and online (boolean flag for live data fetching).

Input Parameters and Configuration

The technical indicator calculations in TradingAgents stockstats.py rely on precise parameterization to ensure accurate temporal alignment. The indicator parameter must follow the stockstats naming convention of "<field>_<window>_<type>", such as "close_50_sma" for a 50-day simple moving average of closing prices or "macdh" for MACD histogram.

The curr_date parameter enables point-in-time analysis, allowing trading agents to query specific historical trading days rather than retrieving entire time series.

Data Loading and Caching Mechanisms

Offline Mode with Local CSV Files

When online=False, the technical indicator calculations in TradingAgents stockstats.py operate in offline mode, reading from pre-downloaded CSV files. The implementation expects files named {symbol}-YFin-data-2015-01-01-2025-03-25.csv located in the specified data_dir (lines 37-41 in stockstats.py).

This mode ensures deterministic backtesting by using static historical data rather than potentially changing live feeds.

Online Mode with Yahoo Finance Integration

In online mode (online=True), the system dynamically fetches a 15-year window of price data from Yahoo Finance using the yfinance library. The implementation calculates the date range from 15 years prior to the current date (lines 50-52) and checks for cached files in config["data_cache_dir"] to minimize API calls (lines 58-66).

If cached data exists, it loads from disk; otherwise, it downloads fresh data with auto_adjust=True for split/dividend adjustments, saves to cache, and proceeds (lines 70-78).

Computing Technical Indicators

Lazy Evaluation via stockstats

The technical indicator calculations in TradingAgents stockstats.py leverage lazy evaluation through the stockstats library's wrap function. After loading price data into a pandas DataFrame, the code calls df = wrap(data) (line 43 or 80), converting the DataFrame into a StockDataFrame object.

Accessing df[indicator] (line 84) triggers the actual computation. The stockstats library dynamically calculates the requested indicator—whether simple moving averages, exponential moving averages, MACD, RSI, Bollinger Bands, or ATR—based on the underlying price columns (open, high, low, close, volume).

Date Filtering and Value Extraction

Following computation, the system filters the DataFrame to the specific trading date using df[df["Date"].str.startswith(curr_date)] (line 85). This string-matching approach accommodates the Date column's string format while ensuring exact date alignment.

If matching rows exist, the function returns matching_rows[indicator].values[0] (line 88) as the numeric indicator value. If the date falls on a weekend or market holiday, the function returns the string "N/A: Not a trading day (weekend or holiday)" (line 91), providing clear feedback for calendar-aware trading logic.

High-Level API Integration

Single Indicator Retrieval

While StockstatsUtils.get_stock_stats provides the core functionality, most trading agents interact with the technical indicator calculations in TradingAgents stockstats.py through the high-level wrapper interface.get_stockstats_indicator. This function (lines 98-108 in interface.py) handles argument forwarding, date formatting validation, and error logging before delegating to the underlying utility class.

Window-Based Historical Analysis

For temporal pattern recognition, the repository provides get_stock_stats_indicators_window in interface.py (lines 53-86). This function accepts a look_back_days parameter and iterates backward from the curr_date, calling get_stockstats_indicator for each day. It aggregates results into a human-readable report format that includes the indicator values, usage descriptions, and trading tips—particularly useful for LLM-based agents interpreting market conditions.

The function references the best_ind_params dictionary (lines 63-34) to document common indicator patterns such as "close_50_sma", "macd", "rsi", "boll_ub", and "atr".

Supported Technical Indicators

The technical indicator calculations in TradingAgents stockstats.py support any indicator valid in the underlying stockstats library. Common implementations include:

  • Moving Averages: close_50_sma (50-day SMA), close_200_sma (200-day SMA), close_12_ema (12-day EMA)
  • MACD: macd (line), macds (signal), macdh (histogram)
  • Momentum Oscillators: rsi (Relative Strength Index), cci (Commodity Channel Index)
  • Volatility Measures: atr (Average True Range), boll_ub (Bollinger Upper Band), boll_lb (Bollinger Lower Band)

Indicator names must follow the stockstats convention of <field>_<window>_<type> or recognized aliases like macd.

Code Examples

Example 1 – Get a Single Indicator Value Offline

from tradingagents.dataflows.technical.stockstats import StockstatsUtils

symbol = "AAPL"
indicator = "close_50_sma"
date = "2023-07-14"
data_dir = "/path/to/price_data"      # Contains pre-downloaded CSV

value = StockstatsUtils.get_stock_stats(
    symbol=symbol,
    indicator=indicator,
    curr_date=date,
    data_dir=data_dir,
    online=False,
)

print(f"{symbol} {indicator} on {date}: {value}")

Output: AAPL close_50_sma on 2023-07-14: 176.32

Example 2 – Fetch a Window of Historical Values Online

from tradingagents.dataflows.interface import get_stock_stats_indicators_window

symbol = "GOOG"
indicator = "macd"
curr_date = "2024-04-22"
look_back_days = 5
online = True   # Downloads fresh data if cache missing

report = get_stock_stats_indicators_window(
    symbol=symbol,
    indicator=indicator,
    curr_date=curr_date,
    look_back_days=look_back_days,
    online=online,
)

print(report)

Sample Output:


## macd values from 2024-04-17 to 2024-04-22:

2024-04-22: 0.0143
2024-04-21: 0.0128
2024-04-20: 0.0115
2024-04-19: 0.0101
2024-04-18: 0.0090

MACD: Computes momentum via differences of EMAs.
Usage: Look for crossovers and divergence as signals of trend changes.
Tips: Confirm with other indicators in low-volatility or sideways markets.

Example 3 – Handling Non-Trading Days

value = StockstatsUtils.get_stock_stats(
    symbol="MSFT",
    indicator="rsi",
    curr_date="2024-01-01",   # New Year's Day (market closed)

    data_dir="/data/price",
    online=False,
)

print(value)

Output: N/A: Not a trading day (weekend or holiday)

Key Files and Implementation Details

File Role Location
tradingagents/dataflows/technical/stockstats.py Core wrapper implementing StockstatsUtils.get_stock_stats with offline/online data loading and indicator extraction. Lines 13-90
tradingagents/dataflows/interface.py High-level API providing get_stockstats_indicator and get_stock_stats_indicators_window for agent integration. Lines 53-108
tradingagents/config/config_manager.py Configuration management supplying data_cache_dir for online mode caching. config_manager.py
tradingagents/dataflows/providers/us/yfinance.py Reference implementation for Yahoo Finance data retrieval used in online mode. yfinance provider

Summary

  • Technical indicator calculations in TradingAgents stockstats.py rely on a thin wrapper around the stockstats library, exposing functionality through StockstatsUtils.get_stock_stats.
  • The system supports both offline mode (reading pre-downloaded CSV files from 2015-2025) and online mode (fetching 15-year windows from Yahoo Finance with intelligent caching).
  • Indicator computation uses lazy evaluation via the wrap function; accessing df[indicator] triggers stockstats to calculate values like SMA, MACD, RSI, and Bollinger Bands.
  • The high-level API in interface.py provides window-based historical analysis and human-readable reports for LLM-based trading agents.
  • Non-trading days (weekends/holidays) return explicit "N/A" messages rather than null values, ensuring robust calendar-aware logic.

Frequently Asked Questions

How does TradingAgents stockstats.py handle missing trading days?

When the requested curr_date falls on a weekend or market holiday, the get_stock_stats method filters the DataFrame for matching dates and finds no rows. In this case, it returns the string "N/A: Not a trading day (weekend or holiday)" rather than a numeric value, allowing calling agents to handle calendar logic explicitly.

What is the difference between online and offline modes in stockstats.py?

Offline mode (online=False) reads from a static CSV file named {symbol}-YFin-data-2015-01-01-2025-03-25.csv stored in the specified data_dir, ensuring reproducible backtests. Online mode (online=True) downloads a rolling 15-year window from Yahoo Finance using yfinance, caches the result in config["data_cache_dir"] for subsequent calls, and provides access to the most recent market data.

Which technical indicators are supported by the stockstats.py implementation?

The wrapper supports any indicator valid in the underlying stockstats library, including but not limited to: simple moving averages (close_50_sma, close_200_sma), exponential moving averages (close_12_ema), MACD components (macd, macds, macdh), RSI, Bollinger Bands (boll_ub, boll_lb), and ATR. Indicator names must follow the stockstats convention of <field>_<window>_<type> or recognized aliases.

How does the high-level API in interface.py extend stockstats.py functionality?

The interface.py module provides two key wrappers: get_stockstats_indicator (lines 98-108) which formats dates and handles errors when calling StockstatsUtils.get_stock_stats, and get_stock_stats_indicators_window (lines 53-86) which iterates over a look-back period to generate human-readable reports containing historical indicator values, usage descriptions, and trading tips for LLM-based agents.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →