Back to Skills
    ๐Ÿฆž

    china-market-gateway

    **Name:** `china-market-gateway`

    By @etherdrake
    View on GitHub
    SKILL.md
    # China Market Gateway Skill
    
    **Name:** `china-market-gateway`  
    **Description:** Umbrella skill for retrieving Chinese finance data (A-shares, HK, funds, economic data) using Python. Pull stock prices, fund data, market news, and macro indicators from Eastmoney, Sina, CLS, Baidu, and other Chinese sources. Use when researching Chinese equities, mainland stock prices, HK market data, fund performance, or China-related financial news and economic indicators.  
    **License:** MIT  
    **Compatibility:** Requires Python 3.8+, network access to Chinese financial websites. May require proxy for regions with restricted access.  
    
    **Metadata:**
    - **Author:** Etherdrake
    - **Version:** 1.0.2
    - **Supported Markets:**  
      - A-shares  
      - HK  
      - Shanghai  
      - Shenzhen  
      - Fund  
      - Macro
    
    # YuanData - Chinese Finance Data Retrieval (Python)
    
    ## When to Use This Skill
    
    Use this skill when you need to:
    
    - Get real-time or historical stock prices for Chinese A-shares (Shanghai/Shenzhen)
    - Retrieve Hong Kong (HK) stock data
    - Search for Chinese company financial news
    - Research mainland China market information
    - Access Baidu Gushitong for stock analysis
    - Pull fund data and net asset values
    - Fetch macroeconomic indicators (GDP, CPI, PPI, PMI)
    - Track investment calendars and economic events
    
    ## Supported Sources
    
    | Source           | URL Pattern                                                          | Coverage                     |
    |------------------|----------------------------------------------------------------------|------------------------------|
    | Eastmoney        | `https://quote.eastmoney.com/{stockCode}.html`                       | A-shares, HK, indices        |
    | Sina Finance     | `https://finance.sina.com.cn/realstock/company/{stockCode}/nc.shtml` | A-shares, HK, US             |
    | CLS (่ดข่”็คพ)        | `https://www.cls.cn/searchPage`                                      | Market news, telegraph       |
    | Baidu Gushitong  | `https://gushitong.baidu.com/stock/ab-{stockCode}`                   | Stock analysis, quotes       |
    | Eastmoney Funds  | `https://fund.eastmoney.com/{fundCode}.html`                         | Fund data                    |
    | Eastmoney Macro  | `https://datacenter-web.eastmoney.com/api/data/v1/get`               | GDP, CPI, PPI, PMI           |
    
    ## Stock Code Formats
    
    Chinese stocks use specific prefixes:
    
    - **A-shares (Shanghai):** `sh000001` (SSE), `sh600000` (SSE)
    - **A-shares (Shenzhen):** `sz000001` (SZSE), `sz300000` (ChiNext)
    - **HK stocks:** `hk00001` (HKEX), `hk00700` (Tencent)
    - **US ADRs (for reference):** `usAAPL`
    
    ### Examples
    
    | Stock Code     | Company                    | Type       |
    |----------------|----------------------------|------------|
    | `sh000001`     | Shanghai Composite Index   | Index      |
    | `sh600519`     | Kweichow Moutai            | A-share    |
    | `sz000001`     | Ping An Bank               | A-share    |
    | `hk00700`      | Tencent                    | HK         |
    | `hk09660`      | Horizon Robotics           | HK         |
    
    ---
    
    # Part 1: Stock Data Retrieval (Python)
    
    ## 1. Setup and Dependencies
    
    ```python
    import requests
    from bs4 import BeautifulSoup
    import json
    import re
    import time
    from datetime import datetime, timedelta
    from typing import Optional, Dict, List, Any
    import logging
    
    # Configure logging
    logging.basicConfig(level=logging.INFO)
    logger = logging.getLogger(__name__)
    
    class YuanData:
        """Chinese Finance Data Retrieval Class"""
    
        def __init__(self, proxy: Optional[str] = None):
            self.session = requests.Session()
            self.proxy = proxy
            self.headers = {
                'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
                'Accept': 'application/json, text/html,application/xhtml+xml',
                'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8',
            }
            if proxy:
                self.session.proxies = {'http': proxy, 'https': proxy}
    
        def _request(self, url: str, headers: Optional[Dict] = None, 
                     timeout: int = 30) -> Optional[Any]:
            """Generic HTTP request handler"""
            try:
                req_headers = {**self.headers, **(headers or {})}
                response = self.session.get(url, headers=req_headers, timeout=timeout)
                response.raise_for_status()
                return response
            except Exception as e:
                logger.error(f"Request failed: {url} - {e}")
                return None
    ```
    
    ## 2. Sina Finance API (Real-Time Stock Data)
    
    ```python
    class SinaStockAPI:
        """Sina Finance Real-Time Stock Data"""
    
        BASE_URL = "http://hq.sinajs.cn"
    
        def __init__(self, yuan_data: YuanData):
            self.parent = yuan_data
    
        def get_stock_quote(self, stock_code: str) -> Optional[Dict]:
            """
            Get real-time stock quote from Sina
    
            Args:
                stock_code: Stock code (e.g., 'sh600519', 'hk00700')
    
            Returns:
                Dict with price, volume, change data
            """
            # Handle HK stock format (add leading zero)
            if stock_code.startswith('hk') and len(stock_code) == 6:
                stock_code = 'hk0' + stock_code[2:]
    
            timestamp = int(time.time() * 1000)
            url = f"{self.BASE_URL}/rn={timestamp}&list={stock_code}"
    
            headers = {
                'Host': 'hq.sinajs.cn',
                'Referer': 'https://finance.sina.com.cn/',
            }
    
            response = self.parent._request(url, headers=headers)
            if not response:
                return None
    
            # Parse response: var hq_str_sh600519="name,open,high,low,close,...";
            content = response.text
            match = re.search(r'hq_str_' + re.escape(stock_code) + r'="([^"]+)";', content)
    
            if not match or not match.group(1).strip():
                logger.warning(f"No data for {stock_code}")
                return None
    
            data = match.group(1).split(',')
            return self._parse_stock_data(stock_code, data)
    
        def _parse_stock_data(self, code: str, data: List[str]) -> Dict:
            """Parse Sina stock data response"""
            if code.startswith('sh') or code.startswith('sz'):
                return {
                    'code': code,
                    'name': data[0],
                    'open': float(data[1]),
                    'pre_close': float(data[2]),
                    'close': float(data[3]),
                    'high': float(data[4]),
                    'low': float(data[5]),
                    'buy_price': float(data[6]),
                    'sell_price': float(data[7]),
                    'volume': int(data[8]),
                    'amount': float(data[9]),
                    'buy_volume': [
                        int(data[10]), int(data[12]), int(data[14]), 
                        int(data[16]), int(data[18])
                    ],
                    'buy_price': [
                        float(data[11]), float(data[13]), float(data[15]),
                        float(data[17]), float(data[19])
                    ],
                    'sell_volume': [
                        int(data[20]), int(data[22]), int(data[24]),
                        int(data[26]), int(data[28])
                    ],
                    'sell_price': [
                        float(data[21]), float(data[23]), float(data[25]),
                        float(data[27]), float(data[29])
                    ],
                    'date': data[30],
                    'time': data[31],
                }
            else:  # HK stock
                return {
                    'code': code,
                    'name': data[1],
                    'open': float(data[5]),
                    'pre_close': float(data[4]),
                    'close': float(data[3]),
                    'high': float(data[33] or data[32]),
                    'low': float(data[34] or data[33]),
                    'volume': float(data[12].split('.')[0]) if '.' in data[12] else float(data[12]),
                    'amount': float(data[13]) if len(data) > 13 else 0,
                    'date': data[17].replace('/', '-'),
                    'time': data[18].replace(';', ''),
                }
    
        def get_multiple_quotes(self, stock_codes: List[str]) -> List[Dict]:
            """Get quotes for multiple stocks (with rate limiting)"""
            results = []
            for code in stock_codes:
                quote = self.get_stock_quote(code)
                if quote:
                    results.append(quote)
                time.sleep(0.1)  # Prevent rate limiting
            return results
    ```
    
    ## 3. Tencent Finance API (Alternative Source)
    
    ```python
    class TencentStockAPI:
        """Tencent Finance Real-Time Stock Data"""
    
        BASE_URL = "http://qt.gtimg.cn"
    
        def __init__(self, yuan_data: YuanData):
            self.parent = yuan_data
    
        def get_stock_quote(self, stock_code: str) -> Optional[Dict]:
            """
            Get real-time quote from Tencent
    
            Args:
                stock_code: e.g., 'sh600519', 'hk00700'
    
            Returns:
                Dict with price and metrics
            """
            if stock_code.startswith('hk'):
                for code_variant in [f"r_{stock_code}", stock_code]:
                    raw_data = self._fetch_tencent(code_variant)
                    if raw_data:
                        return self._parse_tencent_data(stock_code, raw_data)
            else:
                raw_data = self._fetch_tencent(stock_code)
                if raw_data:
                    return self._parse_tencent_data(stock_code, raw_data)
            return None
    
        def _fetch_tencent(self, code: str) -> Optional[str]:
            """Fetch raw data from Tencent API"""
            url = f"{self.BASE_URL}/?q={code}"
            headers = {
                'Host': 'qt.gtimg.cn',
                'Referer': 'https://gu.qq.com/',
            }
            response = self.parent._request(url, headers=headers)
            return response.text.strip() if response else None
    
        def _parse_tencent_data(self, code: str, raw_data: str) -> Dict:
            """Parse Tencent response (~ delimited)"""
            parts = raw_data.split('~')
            if len(parts) < 35:
                raise ValueError(f"Insufficient data for {code}")
    
            return {
                'code': code,
                'name': parts[1],
                'close': float(parts[3]),
           
    
    ... (truncated)