# How the TradingAgents-CN Data Source Manager Prioritizes and Falls Back Between Tushare, AKShare, and BaoStock

> Discover how the TradingAgents-CN DataSourceManager automatically prioritizes AKShare, Tushare, and BaoStock, ensuring seamless fallback for uninterrupted data retrieval.

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

---

**The `DataSourceManager` automatically prioritizes AKShare, then Tushare, then BaoStock, and seamlessly falls back to the next available provider when the current source fails or returns an error.**

The `DataSourceManager` in the [TradingAgents-CN](https://github.com/hsliuping/TradingAgents-CN) repository orchestrates data retrieval from Chinese stock market providers. Understanding how this component prioritizes Tushare, AKShare, and BaoStock—and how it handles failures—is critical for ensuring resilient quantitative trading workflows.

## Architecture of the Data Source Manager

Located in [`tradingagents/dataflows/data_source_manager.py`](https://github.com/hsliuping/TradingAgents-CN/blob/main/tradingagents/dataflows/data_source_manager.py), the `DataSourceManager` class encapsulates all logic for source detection, priority ordering, and fallback execution. It maintains a `current_source` attribute representing the active provider and implements methods to automatically switch sources when data retrieval fails.

## Detecting Available Data Sources

### Source Availability Verification

During initialization, the manager calls `_check_available_sources` (lines 15‑84) to determine which providers are functional. This method verifies:

- Whether the Tushare API token is configured and valid
- If the AKShare package is installed and importable
- If the BaoStock package is installed and importable

Only sources passing these checks are considered for the priority list.

## Data Source Priority and Fallback Order

### Database-Driven Priority Configuration

The manager attempts to load a custom priority order from MongoDB via `_get_data_source_priority_order` (lines 91‑171). It queries the `system_configs` collection for `data_source_configs` entries, sorting by a numeric `priority` field in descending order. Each entry maps to the internal `ChinaDataSource` enum (e.g., `"akshare"`, `"tushare"`, `"baostock"`).

### Default Hard-Coded Priority

When no database configuration exists, the manager uses the hard-coded default order defined at lines 164‑168:

```

AKShare → Tushare → BaoStock

```

This default prioritizes **AKShare** for its comprehensive A-share coverage, followed by **Tushare** for professional-grade data, and finally **BaoStock** as a reliable backup.

### MongoDB Cache Priority

If `use_mongodb_cache` is enabled, MongoDB becomes the highest-priority source, checked before any API provider. This is handled separately from the Tushare/AKShare/BaoStock fallback chain.

## The Fallback Mechanism in Action

### Initial Source Selection

The manager determines the starting provider through `_get_default_source` (lines 206‑222). If MongoDB caching is active, it returns `MONGODB`. Otherwise, it reads the `DEFAULT_CHINA_DATA_SOURCE` environment variable (defaulting to `AKShare`).

### Automatic Fallback Execution

When `get_stock_data` (lines 311‑352) encounters a failure or receives the error marker `❌` from the current provider, it triggers `_try_fallback_sources` (lines 382‑424). This method:

1. Retrieves the priority list from the configuration step
2. Iterates through the ordered sources, skipping the already-tried provider
3. Calls each subsequent provider directly until one returns valid data
4. Returns the first successful result or an aggregate error if all sources fail

This **linear iteration** design prevents infinite recursion while ensuring every available source gets exactly one attempt per request cycle.

## Practical Implementation Examples

### Basic Automatic Usage

Allow the manager to select the optimal source automatically:

```python
from tradingagents.dataflows.data_source_manager import DataSourceManager

manager = DataSourceManager()

# Automatically selects MongoDB > AKShare > Tushare > BaoStock

result = manager.get_stock_data('600519', start_date='2024-01-01', end_date='2024-01-31')
print(result)

```

### Forcing a Specific Source with Fallback

Override the default to test Tushare specifically, allowing automatic fallback if it fails:

```python
from tradingagents.dataflows.data_source_manager import DataSourceManager, ChinaDataSource

manager = DataSourceManager()

# Force Tushare even if AKShare is available

manager.set_current_source(ChinaDataSource.TUSHARE)

# If Tushare fails (e.g., missing token), automatically falls back

# to AKShare, then BaoStock according to the priority list

result = manager.get_stock_data('600519', start_date='2024-01-01', end_date='2024-01-31')
print(result)

```

### Inspecting the Computed Priority Order

Verify which fallback chain applies to a specific symbol:

```python
from tradingagents.dataflows.data_source_manager import DataSourceManager

mgr = DataSourceManager()
fallback_order = mgr._get_data_source_priority_order('600519')
print([src.name for src in fallback_order])

# Output without DB config: ['AKSHARE', 'TUSHARE', 'BAOSTOCK']

```

## Summary

- The `DataSourceManager` in [`tradingagents/dataflows/data_source_manager.py`](https://github.com/hsliuping/TradingAgents-CN/blob/main/tradingagents/dataflows/data_source_manager.py) orchestrates all Chinese stock data retrieval with robust fallback capabilities.
- **Priority determination** checks MongoDB cache first, then consults the `system_configs` collection for custom orders, defaulting to **AKShare → Tushare → BaoStock**.
- **Fallback execution** occurs in `_try_fallback_sources` (lines 382‑424), which linearly iterates through the priority list when the current provider returns an error or `❌` marker.
- The `DEFAULT_CHINA_DATA_SOURCE` environment variable and `use_mongodb_cache` flag provide deployment-specific configuration hooks without code changes.

## Frequently Asked Questions

### What is the default priority order if I don't configure MongoDB?

If no custom configuration exists in the `system_configs` collection, the manager uses the hard-coded default order: **AKShare first, then Tushare, then BaoStock**. This is defined in the `default_order` list within `_get_data_source_priority_order` at lines 164‑168 of [`data_source_manager.py`](https://github.com/hsliuping/TradingAgents-CN/blob/main/data_source_manager.py).

### How does the manager handle a missing Tushare API token?

During initialization, `_check_available_sources` (lines 15‑84) verifies the presence and validity of the Tushare token. If the token is missing or invalid, Tushare is excluded from the available sources list. Consequently, it will be skipped during fallback attempts, and the manager will proceed to the next available provider in the priority chain.

### Can I override the default source without modifying the database?

Yes. You can set the `DEFAULT_CHINA_DATA_SOURCE` environment variable to `"TUSHARE"`, `"AKSHARE"`, or `"BAOSTOCK"`. The `_get_default_source` method (lines 206‑222) reads this variable, defaulting to `AKShare` if the variable is unset. Alternatively, you can call `manager.set_current_source(ChinaDataSource.YOUR_CHOICE)` at runtime to force a specific provider.

### Does the fallback mechanism support recursive retries?

No. The `_try_fallback_sources` method (lines 382‑424) implements a **linear iteration** through the priority list, not recursion. It calls each subsequent provider directly until one succeeds. This design prevents infinite recursion and stack overflow while ensuring that every available source gets exactly one attempt per request cycle.