🎁 Get the FREE AI Skills Starter Guide β€” Subscribe β†’
BytesAgainBytesAgain
πŸ¦€ ClawHub

Free A Share Real Time Data

by @wangdinglu

Fetch China A-share stock market data (bars, realtime quotes, tick-by-tick transactions) via mootdx/TDX protocol. Use when working with Chinese stock data, mootdx library, TDX quotes, intraday minute bars, transaction history, or real-time A-share market data.

Versionv1.0.1
Downloads2,069
Stars⭐ 1
TERMINAL
clawhub install free-a-share-real-time-data

πŸ“– About This Skill


name: mootdx-china-stock-data description: Fetch China A-share stock market data (bars, realtime quotes, tick-by-tick transactions) via mootdx/TDX protocol. Use when working with Chinese stock data, mootdx library, TDX quotes, intraday minute bars, transaction history, or real-time A-share market data.

Mootdx China A-Share Stock Data Client

A wrapper around the mootdx library (TDX protocol) for fetching China A-share market data including K-line bars, real-time quotes, and tick-by-tick transaction records.

Installation

pip install mootdx

> mootdx depends on tdxpy internally. Both are installed together.

Verify & Demo

python scripts/setup_and_verify.py           # Install + verify + connectivity test
python scripts/setup_and_verify.py --check   # Verify only (skip install)
python scripts/setup_and_verify.py --demo    # Full API demo with real output

The --demo mode exercises every major API and prints real data β€” useful as a runnable reference for correct calling patterns.

Critical: Time & Timezone Considerations

Trading Hours (Beijing Time, UTC+8)

| Session | Time | |---------|------| | Morning | 09:30 - 11:30 (120 min) | | Lunch break | 11:30 - 13:00 | | Afternoon | 13:00 - 15:00 (120 min) | | Total | 240 trading minutes/day |

Trading Time Bypass Patch

Problem: mootdx / tdxpy has a built-in time_frame() check that blocks API calls outside trading hours. On servers with non-Beijing timezone, this breaks even during valid trading hours.

Solution: Monkey-patch tdxpy.hq.time_frame to always return True:

import tdxpy.hq
tdxpy.hq.time_frame = lambda: True

This patch is applied automatically during MootdxClient.__init__(). Without it, transactions() and transaction() calls will silently return empty results outside detected trading hours.

Trading Calendar

When querying historical data, always check if a date is a trading day. Non-trading days (weekends, holidays) have no data. The client uses TradingCalendarStrategy.is_trading_day(date_str) for this β€” you must have a trading calendar service available.

Date/Time Parameter Formats

| Parameter | Format | Example | |-----------|--------|---------| | date | YYYYMMDD | "20250210" | | time | HH:MM:SS or HH:MM | "10:30:00" or "10:30" |

Stock Code Format

mootdx uses pure numeric codes (TDX format). Convert from standard format:

| Standard Format | TDX Format | Market | |----------------|------------|--------| | 000001.SZ | 000001 | Shenzhen | | 600300.SH | 600300 | Shanghai | | 300750.SZ | 300750 | Shenzhen (ChiNext) | | 688001.SH | 688001 | Shanghai (STAR) |

Conversion: Strip the .SH / .SZ / .BJ suffix.

> Important: mootdx does NOT support Beijing Stock Exchange (.BJ) stocks. Filter them out before calling.

API Reference

1. Initialize Client

from mootdx.quotes import Quotes
client = Quotes.factory(market='std')

2. get_bars() β€” K-Line / Candlestick Data

Fetch historical or real-time K-line bars.

await client.get_bars(
    stock_code="000001.SZ",   # Standard format (auto-converted)
    frequency=7,               # K-line period (see table below)
    offset=240,                # Number of bars to fetch
    date="20250210",           # Optional: specific date (YYYYMMDD)
    time="10:30:00",           # Optional: specific time (HH:MM:SS)
    filter_by_time=True        # Filter to closest bar matching time
)

Frequency codes:

| Code | Period | |------|--------| | 7 | 1-minute bars | | 8 | 1-minute bars (alternative) | | 4 | Daily bars | | 9 | Daily bars (alternative) |

Return format (list of dicts):

{
    "stock_code": "000001.SZ",
    "datetime": "2025-02-10 10:30:00",
    "open": 12.50,
    "high": 12.65,
    "low": 12.45,
    "close": 12.60,
    "vol": 150000.0,
    "amount": 1890000.0
}

Start position calculation: For historical dates, the start parameter is calculated as the number of trading minutes (for 1-min bars) or trading days (for daily bars) between now and the target datetime. This accounts for:

  • Whether today is a trading day
  • Current trading session status (pre-market / in-session / post-market)
  • Lunch break gap (11:30-13:00)
  • 3. get_realtime_quote() β€” Single Stock Real-Time Quote

    await client.get_realtime_quote(stock_code="000001.SZ")
    

    Returns (dict): Price, OHLC, volume, amount, and full Level-2 order book (5-level bid/ask):

    {
        "stock_code": "000001.SZ",
        "price": 12.60,
        "last_close": 12.50,
        "open": 12.45, "high": 12.65, "low": 12.40,
        "volume": 5000000, "amount": 63000000,
        "bid1": 12.59, "bid2": 12.58, ..., "bid5": 12.55,
        "ask1": 12.60, "ask2": 12.61, ..., "ask5": 12.65,
        "bid_vol1": 500, ..., "ask_vol5": 300,
        "pct_chg": 0.8
    }
    

    4. get_realtime_quotes() β€” Batch Real-Time Quotes

    Native batch interface β€” much faster than looping get_realtime_quote().

    await client.get_realtime_quotes(["000001.SZ", "600300.SH", "300750.SZ"])
    

    Returns (list of dicts):

    {
        "stock_code": "000001.SZ",
        "trade_date": "2025-02-10",
        "open": 12.45, "high": 12.65, "low": 12.40, "close": 12.60,
        "pre_close": 12.50,
        "change": 0.15,
        "pct_chg": 1.2048,
        "vol": 5000000.0,
        "amount": 63000000.0,
        "is_realtime": true
    }
    

    > pct_chg is calculated from today's open price, not previous close.

    5. get_batch_bars() β€” Batch K-Line Data

    Parallel fetch K-line bars for multiple stocks with concurrency control.

    await client.get_batch_bars(
        stock_codes=["000001.SZ", "600300.SH"],
        date="20250210",
        time="10:30:00",
        max_concurrent=10
    )
    

    Returns: Dict[str, List[Dict]] β€” {stock_code: [bar_data, ...]}

    6. get_transactions_history() β€” Historical Tick Data

    Tick-by-tick transaction records for a specific historical date.

    await client.get_transactions_history(
        stock_code="000001.SZ",
        date="20250210",         # Required: YYYYMMDD
        start=0,
        offset=1000
    )
    

    Returns (list of dicts):

    {
        "stock_code": "000001.SZ",
        "time": "09:30:05",
        "price": 12.50,
        "vol": 100,
        "buyorsell": 0,          # 0=buy, 1=sell, 2=neutral
        "num": 5,                # Number of trades in this tick
        "volume": 100
    }
    

    7. get_transactions_realtime() β€” Real-Time Tick Data

    Today's live tick-by-tick transaction stream.

    await client.get_transactions_realtime(
        stock_code="000001.SZ",
        start=0,
        offset=1000
    )
    

    Same return format as get_transactions_history().

    8. get_transactions_with_fallback() β€” Tick Data with Fallback

    Tries real-time first, falls back to today's historical data if empty.

    await client.get_transactions_with_fallback(
        stock_code="000001.SZ",
        start=0, offset=1000,
        use_history_fallback=True
    )
    

    Raw mootdx API (Low-Level)

    If using mootdx directly without the wrapper:

    from mootdx.quotes import Quotes

    client = Quotes.factory(market='std')

    K-line bars

    df = client.bars(symbol="000001", frequency=7, start=0, offset=240)

    Real-time quotes (supports list of symbols for batch)

    df = client.quotes(symbol="000001") df = client.quotes(symbol=["000001", "600300"])

    Historical transactions

    df = client.transactions(symbol="000001", start=0, offset=1000, date="20250210")

    Real-time transactions

    df = client.transaction(symbol="000001", start=0, offset=1000)

    > All raw APIs return pandas DataFrames.

    Common Pitfalls

    1. Empty results outside trading hours: Apply the time_frame patch (see above) 2. Beijing Exchange stocks: .BJ codes are NOT supported β€” always filter them out 3. Rate limiting: Default rate limit is 0.005s between calls; adjust if connection drops 4. Weekend/holiday queries: Always validate against trading calendar before querying 5. 1-min bar offset calculation: Must account for 240 trading minutes/day with lunch gap

    Additional Resources

  • For detailed method signatures and time calculation logic, see api-reference.md