Skip to content

Get A-Share Real-Time Quotes with Python: Tencent Finance API Tutorial

Don't want to pay for market data? This tutorial shows you how to get A-share real-time quotes for free using Python. With a 15-minute delay, it's perfect for quantitative research and strategy validation.


Why Choose Tencent Finance API?

Free Market Data Comparison

SourceDelayCostStabilityQuality
Tencent Finance15 minFree⭐⭐⭐⭐Good
Sina Finance15 minFree⭐⭐⭐⭐Good
TongdaXin VIPReal-time¥300/year⭐⭐⭐⭐⭐Excellent
JoinQuantReal-time¥3000+/year⭐⭐⭐⭐⭐Excellent
Exchange OfficialReal-time¥10000+/year⭐⭐⭐⭐⭐Best

Conclusion: Among free options, Tencent and Sina are most reliable. Tencent's response format is cleaner and easier to parse.


Complete Implementation

1. Core Fetcher

python
# -*- coding: utf-8 -*-
"""
Tencent Finance Real-Time Quote Fetcher

Supports:
- A-share real-time quotes (15-min delay)
- 5-level order book
- Real-time trades
- Intraday data

Data Source: Tencent Finance API (Free, 15-min delayed)
"""

import requests
import pandas as pd
from datetime import datetime
from typing import Optional, List, Dict


class TencentStockFetcher:
    """Tencent Finance Real-Time Quote Fetcher"""
    
    QUOTE_URL = "https://qt.gtimg.cn/q="
    
    def __init__(self):
        self.session = requests.Session()
        self.session.headers.update({
            'Referer': 'https://stockapp.finance.qq.com',
            'User-Agent': 'Mozilla/5.0'
        })
    
    def get_realtime_quote(self, symbols: List[str]) -> pd.DataFrame:
        """
        Get real-time quotes
        
        Args:
            symbols: Stock codes, e.g., ['sh600000', 'sz000001']
        
        Returns:
            DataFrame with real-time quote data
        """
        if not symbols:
            return pd.DataFrame()
        
        # Build code list (Tencent format)
        codes = []
        for symbol in symbols:
            if symbol.startswith('6') or symbol.startswith('9'):
                codes.append(f'sh{symbol}')
            else:
                codes.append(f'sz{symbol}')
        
        # Request quote data
        code_str = ','.join(codes)
        url = f"{self.QUOTE_URL}{code_str}"
        
        try:
            resp = self.session.get(url, timeout=10)
            resp.encoding = 'gbk'  # Tencent returns GBK encoding
            data = resp.text
            
            return self._parse_quote_data(data)
        except Exception as e:
            print(f"Failed to fetch quotes: {e}")
            return pd.DataFrame()
    
    def _parse_quote_data(self, data: str) -> pd.DataFrame:
        """Parse Tencent quote data"""
        results = []
        
        for line in data.strip().split('\n'):
            if not line.startswith('v_'):
                continue
            
            try:
                # Format: v_sh600000="51~浦发银行~600000~7.85~7.84~7.86~..."
                parts = line.split('~')
                if len(parts) < 50:
                    continue
                
                symbol = parts[2]
                name = parts[1]
                
                row = {
                    'symbol': symbol,
                    'name': name,
                    'price': float(parts[3]) if parts[3] else 0,
                    'open': float(parts[5]) if parts[5] else 0,
                    'high': float(parts[33]) if parts[33] else 0,
                    'low': float(parts[34]) if parts[34] else 0,
                    'close': float(parts[4]) if parts[4] else 0,
                    'volume': float(parts[6]) if parts[6] else 0,
                    'amount': float(parts[37]) if parts[37] else 0,
                    'bid': float(parts[11]) if parts[11] else 0,
                    'ask': float(parts[13]) if parts[13] else 0,
                    'bid_vol': float(parts[10]) if parts[10] else 0,
                    'ask_vol': float(parts[12]) if parts[12] else 0,
                    'change': float(parts[3]) - float(parts[4]) if parts[3] and parts[4] else 0,
                    'change_pct': float(parts[32]) if parts[32] else 0,
                    'timestamp': datetime.now()
                }
                
                results.append(row)
            except Exception as e:
                print(f"Failed to parse data: {e}")
                continue
        
        return pd.DataFrame(results)

2. Real-Time Monitor

python
# -*- coding: utf-8 -*-
"""
Tencent Finance Real-Time Monitor

Usage:
    python monitor.py                  # Monitor default stocks
    python monitor.py 600000,000001    # Monitor specific stocks
"""

import argparse
import time
from datetime import datetime
from tencent_fetcher import TencentStockFetcher


def main():
    parser = argparse.ArgumentParser(description='Tencent Finance Real-Time Monitor')
    parser.add_argument('symbols', nargs='?', default='600000,000001,300750',
                       help='Stock codes, comma-separated')
    parser.add_argument('--interval', type=int, default=60,
                       help='Refresh interval in seconds, default 60')
    
    args = parser.parse_args()
    
    fetcher = TencentStockFetcher()
    symbols = args.symbols.split(',')
    
    print(f"\nMonitoring: {symbols}")
    print("Data delay: ~15 minutes")
    print("Press Ctrl+C to stop\n")
    
    try:
        while True:
            df = fetcher.get_realtime_quote(symbols)
            
            if df.empty:
                print("Failed to fetch data, retrying in 5s...")
                time.sleep(5)
                continue
            
            # Clear screen
            print("\033[2J\033[H", end='')
            print(f"Updated: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n")
            
            # Display quotes
            for _, row in df.iterrows():
                icon = '📈' if row['change'] > 0 else '📉' if row['change'] < 0 else '➖'
                print(f"{icon} {row['symbol']} {row['name']:<10} "
                      f{row['price']:.2f} "
                      f"({row['change_pct']:+.2f}%) "
                      f"Change: {row['change']:.2f}")
            
            print(f"\nNext update: {args.interval}s")
            time.sleep(args.interval)
            
    except KeyboardInterrupt:
        print("\nMonitoring stopped")


if __name__ == "__main__":
    main()

Usage Examples

Install Dependencies

bash
pip install requests pandas

Get Single Stock Quote

python
from tencent_fetcher import TencentStockFetcher

fetcher = TencentStockFetcher()

# Get real-time quotes
df = fetcher.get_realtime_quote(['600000', '000001', '300750'])

print(df[['symbol', 'name', 'price', 'change_pct']])

Output:

  symbol    name   price  change_pct
0  600000  浦发银行  7.85      +1.28
1  000001  平安银行  10.23     -0.58
2  300750  宁德时代  180.50    +0.00

Monitor Multiple Stocks

bash
# Monitor default stocks (refresh every 60s)
python monitor.py

# Monitor specific stocks
python monitor.py 600000,000001,300750

# Custom refresh interval (30s)
python monitor.py 600000,000001 --interval 30

Integrate into Your Project

python
from tencent_fetcher import TencentStockFetcher

fetcher = TencentStockFetcher()

# Get stock price
df = fetcher.get_realtime_quote(['600000'])
current_price = df.iloc[0]['price']
change_pct = df.iloc[0]['change_pct']

# Check if price is up
if change_pct > 0:
    print(f"📈 Up {change_pct}%")
elif change_pct < 0:
    print(f"📉 Down {abs(change_pct)}%")
else:
    print("➖ Unchanged")

Data Fields

FieldDescriptionExample
symbolStock code600000
nameStock name浦发银行
priceCurrent price7.85
openOpen price7.80
highHigh price7.92
lowLow price7.78
closePrevious close7.75
volumeVolume (lots)123456
amountTurnover (CNY)98765432
bidBid price (buy 1)7.84
askAsk price (sell 1)7.86
bid_volBid volume1000
ask_volAsk volume1500
changePrice change+0.10
change_pctChange %+1.28

Important Notes

1. Data Delay

  • Free API, ~15 minute delay
  • Suitable for: quantitative research, strategy validation, offline analysis
  • NOT suitable for: live trading, high-frequency trading

2. Trading Hours

Real-time data only available during trading hours (9:30-15:00 on trading days):

  • Morning: 9:30 - 11:30
  • Afternoon: 13:00 - 15:00

Outside trading hours, returns closing price.

3. Rate Limits

  • Recommended refresh interval ≥ 30 seconds
  • Avoid大量 requests in short time (may get IP blocked)
  • Monitoring 10-20 stocks is fine

4. Encoding

Tencent returns GBK encoding, handled in code:

python
resp.encoding = 'gbk'

5. Stock Code Format

Tencent format:

  • Shanghai: sh600000
  • Shenzhen: sz000001

Auto-converted in the code.


Advanced Usage

1. Get All A-Share List

python
def get_stock_list(self) -> pd.DataFrame:
    """Get A-share stock list"""
    all_stocks = []
    
    for i in range(1, 100):
        url = f"http://vip.stock.finance.sina.com.cn/quotes_service/api/json_v2.php/Market_Center.getHQNodeData?page={i}&num=80&sort=symbol&asc=1&node=hs_a"
        resp = self.session.get(url, timeout=10)
        data = resp.json()
        if not data:
            break
        all_stocks.extend(data)
    
    return pd.DataFrame(all_stocks)

2. Combine with SimTradeData

python
# SimTradeData for historical data
from simtradedata.fetchers.baostock_fetcher import BaoStockFetcher

# Tencent for real-time data
from tencent_fetcher import TencentStockFetcher

# Historical + Real-time = Complete data pipeline
historical = baostock_fetcher.fetch_daily('600000', '2026-01-01', '2026-03-10')
realtime = tencent_fetcher.get_realtime_quote(['600000'])

3. Data Persistence

python
import sqlite3

# Save to database
conn = sqlite3.connect('stock_data.db')
df.to_sql('realtime_quotes', conn, if_exists='append', index=False)

How It Works

Tencent Quote API

https://qt.gtimg.cn/q=sh600000,sz000001

Response format (GBK encoded):

v_sh600000="51~浦发银行~600000~7.85~7.84~7.86~7.80~7.92~7.78~..."

Fields separated by ~, parsed by position.

API Features

  • No API Key required - Direct access
  • Batch support - Up to 100 stocks per request
  • Fast response - Typically < 500ms
  • Stable - Official Tencent API

Summary

Pros

✅ Completely free ✅ No registration required ✅ Good data quality ✅ Stable API ✅ Batch queries supported

Cons

❌ 15-minute delay ❌ Unofficial API (may change) ❌ Not suitable for live trading

Use Cases

  • ✅ Quantitative strategy research
  • ✅ Historical backtesting validation
  • ✅ Stock monitoring tools
  • ✅ Learning projects

Full code available: https://github.com/your-username/tencent-realtime

Related Projects:


If this article helped you, please like, bookmark, and share!

Questions? Email me: cnyfdr@gmail.com 🐶

有想法?给我发邮件 cnyfdr@gmail.com