# How the China Market Analyst Calculates PE, PB, and Fundamental Metrics in TradingAgents-CN

> Learn how the China Market Analyst calculates PE, PB, and fundamental metrics using real time data Tushare and MongoDB for accurate trading insights.

- Repository: [hsliuping/TradingAgents-CN](https://github.com/hsliuping/tradingagents-cn)
- Tags: how-to-guide
- Published: 2026-02-16

---

**The China Market Analyst calculates PE, PB, and fundamental metrics by combining real-time market prices from MongoDB with TTM earnings data from Tushare, validating the results against sensible ranges, and falling back to static daily values when dynamic calculation fails.**

The `TradingAgents-CN` repository implements a sophisticated fundamental analysis pipeline for Chinese A-share markets. The **China Market Analyst** ([`china_market_analyst.py`](https://github.com/hsliuping/TradingAgents-CN/blob/main/china_market_analyst.py)) orchestrates this process, delegating metric calculations to the **OptimizedChinaDataProvider** ([`optimized_china_data.py`](https://github.com/hsliuping/TradingAgents-CN/blob/main/optimized_china_data.py)) and the specialized **real-time metrics** module ([`realtime_metrics.py`](https://github.com/hsliuping/TradingAgents-CN/blob/main/realtime_metrics.py)).

## Architecture Overview

The analyst follows a hierarchical data retrieval strategy to ensure metric availability even when primary sources fail. The flow begins at `create_china_market_analyst` in [`tradingagents/agents/analysts/china_market_analyst.py`](https://github.com/hsliuping/TradingAgents-CN/blob/main/tradingagents/agents/analysts/china_market_analyst.py), which invokes `OptimizedChinaDataProvider.get_fundamentals_data`.

This entry point triggers `_estimate_financial_metrics`, which coordinates the multi-layered data acquisition pipeline. The system prioritizes **real-time calculated metrics** over static cached values, ensuring the analyst works with the most current market conditions available.

## Data Retrieval Pipeline

The `_get_real_financial_metrics` method implements a four-step fallback hierarchy to acquire raw financial data before calculating ratios.

### Step 1: Real-Time Price Acquisition

The system first attempts to replace the supplied price with the latest quote from the MongoDB `market_quotes` collection. This ensures that PE and PB calculations use the most recent trading price rather than stale closing values.

### Step 2: Cached MongoDB Financial Data

If the application cache is enabled, the provider loads a normalized document from the `stock_financial_data` collection. This cache stores previously parsed financial statements to reduce API load and improve response latency.

### Step 3: AKShare API Fallback

When MongoDB contains no relevant data, the system queries the **AKShare** API via [`tradingagents/providers/china/akshare.py`](https://github.com/hsliuping/TradingAgents-CN/blob/main/tradingagents/providers/china/akshare.py). This provider fetches complete financial statements including balance sheets, income statements, and cash flow data for the specified ticker.

### Step 4: Tushare API Final Fallback

As a last resort, the pipeline queries **Tushare** via [`tradingagents/providers/china/tushare.py`](https://github.com/hsliuping/TradingAgents-CN/blob/main/tradingagents/providers/china/tushare.py). This ensures that even when AKShare is unavailable or rate-limited, the analyst can still retrieve the necessary financial data to complete the analysis.

## Real-Time PE and PB Calculation Logic

Once raw data is acquired, the system parses it into standardized metrics through three specialized parsers: `_parse_mongodb_financial_data`, `_parse_akshare_financial_data`, and `_parse_financial_data` (for Tushare). All three parsers invoke `get_pe_pb_with_fallback` from [`tradingagents/dataflows/realtime_metrics.py`](https://github.com/hsliuping/TradingAgents-CN/blob/main/tradingagents/dataflows/realtime_metrics.py) to handle valuation ratios.

### Dynamic Calculation Path

The `get_pe_pb_with_fallback` function first attempts dynamic calculation via `calculate_realtime_pe_pb`. This method combines:

- **Real-time close price** from MongoDB `market_quotes`
- **TTM净利润** (trailing twelve months net profit) from Tushare
- **Total shares** from stock basic info

The calculation formulas implemented in the source code are:

```

PE = real_time_price / (TTM净利润 / total_shares)
PB = real_time_price / (净资产 / total_shares)

```

### Validation Ranges

Before accepting dynamically calculated values, the system passes them through `validate_pe_pb`, which enforces sensible market ranges:

- **PE**: must fall within [-100, 1000]
- **PB**: must fall within [0.1, 100]

Values outside these ranges are rejected as likely data errors or extreme outliers unsuitable for standard analysis.

## Fallback Strategy for Static Metrics

When dynamic calculation fails—due to missing real-time prices, unavailable TTM data, or validation failures—the system falls back to static fields stored in MongoDB's `stock_basic_info` collection.

The fallback path in `get_pe_pb_with_fallback` returns the pre-calculated values:

- `pe` (static price-to-earnings)
- `pb` (static price-to-book)
- `pe_ttm` (trailing twelve months PE)
- `pb_mrq` (most recent quarter PB)

These values represent Tushare's official daily basic data from the previous trading session, ensuring the analyst always has usable metrics even when real-time calculation is impossible.

## Assembling the Fundamentals Report

The `_generate_fundamentals_report` method assembles the final output using the metrics dictionary containing:

- **Valuation ratios**: `pe`, `pb`, `pe_ttm`, `pb_mrq`, `total_mv`
- **Profitability metrics**: `roe`, `roa`, `gross_margin`, `net_margin`
- **Leverage indicators**: `debt_ratio`, `current_ratio`
- **Data source tracking**: `source` field indicating `realtime_calculated_from_tushare_ttm` or `daily_basic`

These values populate markdown sections including "核心财务指标" (Core Financial Indicators) and "估值指标" (Valuation Indicators), which the China Market Analyst returns as the `china_market_report` for downstream consumption by portfolio managers or trading agents.

## Code Examples

### Obtaining a Complete Fundamentals Report

```python
from tradingagents.dataflows.optimized_china_data import OptimizedChinaDataProvider

provider = OptimizedChinaDataProvider()
ticker = "600036"  # China Merchants Bank

report = provider.get_fundamentals_data(ticker)

print(report)  # Markdown report containing PE, PB, ROE, etc.

```

### Direct Metric Extraction

```python
from tradingagents.dataflows.optimized_china_data import OptimizedChinaDataProvider

provider = OptimizedChinaDataProvider()
metrics = provider._estimate_financial_metrics("600036", "¥20.5")
print(f"PE: {metrics['pe']}, PB: {metrics['pb']}")

```

### Integration in Analyst Workflow

```python
from tradingagents.agents.analysts.china_market_analyst import create_china_market_analyst

state = {
    "trade_date": "2025-12-31",
    "company_of_interest": "600036",
    "messages": []
}

analyst = create_china_market_analyst(llm, toolkit)
result = analyst(state)
print(result["china_market_report"])

```

## Summary

- The **China Market Analyst** delegates metric calculation to `OptimizedChinaDataProvider`, which implements a four-tier data retrieval hierarchy: MongoDB cache → AKShare API → Tushare API.
- **Real-time PE and PB** are calculated dynamically using the formula `PE = price / (TTM_earnings / shares)` and `PB = price / (net_assets / shares)`, with validation ranges of PE ∈ [-100, 1000] and PB ∈ [0.1, 100].
- When dynamic calculation fails, the system falls back to **static daily basic values** stored in MongoDB's `stock_basic_info` collection.
- The final report aggregates valuation ratios, profitability metrics (ROE, ROA, margins), and leverage indicators into structured markdown sections for downstream trading agents.

## Frequently Asked Questions

### How does the China Market Analyst handle missing real-time price data?

When MongoDB's `market_quotes` collection lacks the latest price, the analyst continues using the supplied price parameter while attempting to retrieve financial metrics from cached or API sources. The `get_pe_pb_with_fallback` function then relies on static `pe` and `pb` fields from `stock_basic_info` rather than calculating dynamic ratios, ensuring the report always contains usable valuation metrics even during market hours with data delays.

### What validation rules ensure PE and PB calculations are reasonable?

The `validate_pe_pb` function in [`realtime_metrics.py`](https://github.com/hsliuping/TradingAgents-CN/blob/main/realtime_metrics.py) enforces strict bounds before accepting dynamically calculated values. **PE** must fall between **-100 and 1000**, accommodating loss-making companies (negative earnings) while rejecting extreme outliers. **PB** must range between **0.1 and 100**, preventing division-by-zero errors and filtering anomalous book values. Values outside these ranges trigger the fallback mechanism to static daily basic data.

### Which external APIs does the system use when MongoDB cache is empty?

The data retrieval pipeline queries **AKShare** as the primary external source for financial statements when MongoDB's `stock_financial_data` collection lacks the required records. If AKShare returns no data or encounters rate limits, the system falls back to **Tushare**, which provides the TTM净利润 (trailing twelve months net profit) and 净资产 (net assets) required for dynamic PE/PB calculations. Both APIs are wrapped in async providers located in `tradingagents/providers/china/`.

### Can I use the China Market Analyst for real-time trading decisions?

Yes, the analyst is designed for real-time workflows through its **dynamic calculation path**. By combining live prices from MongoDB `market_quotes` with Tushare-derived TTM earnings, it produces up-to-the-minute PE and PB ratios rather than relying on yesterday's closing valuations. However, production implementations should monitor the `source` field in the output dictionary—values of `realtime_calculated_from_tushare_ttm` indicate fresh calculations, while `daily_basic` signals fallback to static data that may not reflect current market conditions.