港股和美股免费api接口(整理自网络)

 

1.港股

实时行情

import requests
hk_sina_stock_list_url = "http://vip.stock.finance.sina.com.cn/quotes_service/api/json_v2.php/Market_Center.getHKStockData"
hk_sina_stock_dict_payload = {
    "page": "1",
    "num": "3000",
    "sort": "symbol",
    "asc": "1",
    "node": "qbgg_hk",
    "_s_r_a": "page"
}
def sina_hk_real():
    """
    新浪财经-港股的所有港股的实时行情数据
    http://vip.stock.finance.sina.com.cn/mkt/#qbgg_hk
    :return: 实时行情数据
    :rtype: []
    """
    res = requests.get(hk_sina_stock_list_url, params=hk_sina_stock_dict_payload)
    if res.status_code != 200:
        logging.error(f"sina_hk_real/status_code:{res.status_code}/text:{res.text}")
        return []
    else:
        try:
            data_json = res.json()
            """
            {'symbol': '00021',  # 港股代码
            'name': '大中华地产控股',  # 中文名称
            'engname': 'GREAT CHI PPT',  # 英文名称
            'tradetype': 'EQTY',  # 交易类型
            'lasttrade': '0.000',  # 最新价
            'prevclose': '0.118',  # 前一个交易日收盘价
            'open': '0.000',  # 开盘价
            'high': '0.000',  # 最高价
            'low': '0.000',  # 最低价
            'volume': '0',  # 成交量(万)
            'currentvolume': '0',  # 每手股数
            'amount': '0',  # 成交额(万)
            'ticktime': '2022-04-08 10:54:17',  # 当前数据时间戳
            'buy': '0.115',  # 买一
            'sell': '0.120',  # 卖一
            'high_52week': '0.247',  # 52周最高价
            'low_52week': '0.110',  # 52周最低价
            'eps': '-0.003',   # 每股收益
            'dividend': None,   # 股息
            'stocks_sum': '3975233406', 
            'pricechange': '0.000',  # 涨跌额
            'changepercent': '0.0000000',  # 涨跌幅
            'market_value': '0.000',  # 港股市值
            'pe_ratio': '0.0000000'
            }
            """
        except Exception as e:
            logging.error(f"sina_hk_real/error: res.json()/detail:{e.__str__()}")
            return []
        res = [
            {"stock_code": d["symbol"],
             "name": d["name"],
             "eng_name": d["engname"],
             "date": d["ticktime"][:10],
             "time": d["ticktime"][11:],
             "now": float(d["lasttrade"]),
             "open": float(d["open"]),
             "close": float(d["prevclose"]),
             "high": float(d["high"]),
             "low": float(d["low"]),
             "volume": float(d["amount"]) * 10000,
             "turnover": float(d["volume"]) * 10000,
             "buy": float(d["buy"]),
             "sell": float(d["sell"]),
             "change": float(d["pricechange"]),
             "change_rate": float(d["changepercent"]),
             "stock_type": "hk"}
            for d in data_json
        ]
    return res

股票代码

def get_hk_stock_codes():
    stocks = sina_hk_real()
    return [{"stock_code": i["stock_code"],
             "name": i["name"],
             "eng_name": i["eng_name"],
             "stock_type": "hk"}
            for i in stocks]

1分钟级k线

import requests
hk_tencent_minute = "https://web.ifzq.gtimg.cn/appstock/app/minute/query?code={}"
def tencent_hk_minute(stock_code, latest_minute=True):
    prefix_code = "hk" + stock_code
    res = requests.get(hk_tencent_minute.format(prefix_code), headers=headers)
    if res.status_code != 200:
        logging.error(f"tencent_hk_minute/status_code:{res.status_code}/text:{res.text}")
        return []
    else:
        try:
            data_json = res.json()
        except Exception as e:
            logging.error(f"tencent_hk_minute/error: res.json()/detail:{e.__str__()}")
            return []
        if "data" in data_json \
                and prefix_code in data_json["data"] \
                and "data" in data_json["data"][prefix_code] \
                and "data" in data_json["data"][prefix_code]["data"] \
                and data_json["data"][prefix_code]["data"]["data"]:
            date = data_json["data"][prefix_code]["data"]["date"]
            date = date[:4] + "-" + date[4:6] + "-" + date[6:]
            res = []
            prev = 0
            for d in data_json["data"][prefix_code]["data"]["data"]:
                d = d.split(" ")
                res.append({
                    "datetime": date + " " + d[0][:2] + ":" + d[0][2:] + ":00",
                    "close": float(d[1]),
                    "volume": float(d[2]) - prev,
                    "stock_type": "hk"
                })
                prev = float(d[2]) - prev

            if latest_minute:
                return res[-1]
            else:
                return res
        else:
            return []
print(tencent_hk_minute("00001"))

天级别k线

import requests
from py_mini_racer import py_mini_racer
hk_sina_stock_hist_url = "https://finance.sina.com.cn/stock/hkstock/{}/klc_kl.js"

def sina_hk_daily(symbol, adjust=""):
    """
    新浪财经-港股-个股的历史行情数据
    https://stock.finance.sina.com.cn/hkstock/quotes/02912.html
    """
    res = requests.get(hk_sina_stock_hist_url.format(symbol))
    js_code = py_mini_racer.MiniRacer()
    js_code.eval(hk_js_decode)
    dict_list: list = js_code.call(
        "d", res.text.split("=")[1].split(";")[0].replace('"', "")
    )  # 执行js解密代码
    dict_list.sort(key=lambda x: x["date"])
    
    if adjust == "qfq":
        # 使用前复权
        res = requests.get(hk_sina_stock_hist_qfq_url.format(symbol))
        try:
            qfq = json.loads(res.text.split("=")[1].split("\n")[0])["data"]
            if len(qfq) == 1:
                return dict_list
        except SyntaxError as e:
            return dict_list
        qfq = sorted(map(lambda x: (x["d"], float(x["f"])), qfq))
        n = len(qfq)
        qfq_index = 0
        for data_index in range(len(dict_list)):
            while qfq_index + 1 < n and qfq[qfq_index + 1][0] <= dict_list[data_index]["date"][:10]:
                qfq_index += 1
            dict_list[data_index]["high"] *= qfq[qfq_index][1]
            dict_list[data_index]["low"] *= qfq[qfq_index][1]
            dict_list[data_index]["open"] *= qfq[qfq_index][1]
            dict_list[data_index]["close"] *= qfq[qfq_index][1]
    return dict_list
 print(sina_hk_daily("00001"))
def tencent_hk_daily(symbol, day=0):
    prefix_code = "hk" + symbol
    res = requests.get(hk_tencent_daily.format(prefix_code, day), headers=headers)
    if res.status_code != 200:
        logging.error(f"tencent_hk_daily/status_code:{res.status_code}/text:{res.text}")
        return []
    else:
        try:
            data_json = json.loads(res.text.split("=")[1].split("\n")[0])
        except Exception as e:
            logging.error(f"tencent_hk_daily/error: res.json()/detail:{e.__str__()}")
            return []
        if "data" in data_json \
                and prefix_code in data_json["data"] \
                and "day" in data_json["data"][prefix_code]:
            res = []
            for d in data_json["data"][prefix_code]["day"]:
                res.append({
                        "day": d[0],
                        "open": float(d[1]),
                        "close": float(d[2]),
                        "high": float(d[3]),
                        "low": float(d[4]),
                        "volume": float(d[5])
                    })
            return res
        else:
            return []

2.美股

实时行情

import requests
import pandas as pd
def em_us_real():
    """
    东方财富-美股-实时行情
    http://quote.eastmoney.com/center/gridlist.html#us_stocks
    :return: 美股-实时行情; 延迟 15 min
    "f1": "_",
    "f2": "最新价",
    "f3": "涨跌幅",
    "f4": "涨跌额",
    "f5": "成交量",
    "f6": "成交额",
    "f7": "振幅",
    "f8": "换手率",
    "f9": "-",
    "f10": "_",
    "f11": "_",
    "f12": "简称",
    "f13": "编码",
    "f14": "名称",
    "f15": "最高价",
    "f16": "最低价",
    "f17": "开盘价",
    "f18": "昨收价",
    "f20": "总市值",
    "f21": "_",
    "f22": "_",
    "f23": "_",
    "f24": "_",
    "f25": "_",
    "f26": "_",
    "f33": "_",
    "f62": "_",
    "f115": "市盈率",
    "f124": "时间戳",
    "f128": "_",
    "f140": "_",
    "f141": "_",
    "f136": "_",
    "f152": "_",
    """
    url = "http://72.push2.eastmoney.com/api/qt/clist/get"
    params = {
        "pn": "1",
        "pz": "20000",
        "po": "1",
        "np": "1",
        "ut": "bd1d9ddb04089700cf9c27f6f7426281",
        "fltt": "2",
        "invt": "2",
        "fid": "f3",
        "fs": "m:105,m:106,m:107",
        "fields": "f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f12,f13,f14,f15,f16,f17,f18,f20,f21,"
                  "f23,f24,f25,f26,f22,f33,f11,f62,f128,f136,f115,f124,f152",
        "_": str(int(time.time() * 1000)),
    }
    res = requests.get(url, params=params)
    if res.status_code != 200:
        logging.error(f"em_us_real/status_code:{res.status_code}/text:{res.text}")
        return []
    else:
        try:
            data_json = res.json()
        except Exception as e:
            logging.error(f"em_us_real/error: res.json()/detail:{e.__str__()}")
            return []
        if "data" in data_json and "diff" in data_json["data"] and data_json["data"]["diff"]:
            res = []
            for d in data_json["data"]["diff"]:
                _datetime = mystriptime(d["f124"])
                res.append({"stock_code": d["f12"],
                            "name": d["f14"],
                            "eng_name": d["f12"],
                            "date": _datetime.strftime("%Y-%m-%d"),
                            "time": _datetime.strftime("%H:%M:%M"),
                            "now": pd.to_numeric(d["f2"], errors="coerce"),
                            "open": pd.to_numeric(d["f17"], errors="coerce"),
                            "close": pd.to_numeric(d["f18"], errors="coerce"),
                            "high": pd.to_numeric(d["f15"], errors="coerce"),
                            "low": pd.to_numeric(d["f16"], errors="coerce"),
                            "volume": pd.to_numeric(d["f6"], errors="coerce"),
                            "turnover": pd.to_numeric(d["f5"], errors="coerce"),
                            "buy": pd.to_numeric(d["f2"], errors="coerce"),
                            "sell": pd.to_numeric(d["f2"], errors="coerce"),
                            "change": pd.to_numeric(d["f4"], errors="coerce"),
                            "change_rate": pd.to_numeric(d["f3"], errors="coerce"),
                            "stock_type": "us"})
            return res
        else:
            return []

美股代码

 

def get_us_stock_codes():
    stocks = em_us_real()
    return [{"stock_code": i["stock_code"],
             "name": i["name"],
             "eng_name": i["eng_name"],
             "stock_type": "us"}
            for i in stocks]

1分钟级k线

import requests
headers = {
    "User-Agent": (
        "Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
        "AppleWebKit/537.36 (KHTML, like Gecko) "
        "Chrome/100.0.4896.75 "
        "Safari/537.36"
    )
}
def tencent_us_minute(stock_code, latest_minute=True):
    prefix_code = "us" + stock_code + ".OQ"
    res = requests.get(us_tencent_minute.format(prefix_code), headers=headers)
    if res.status_code != 200:
        logging.error(f"tencent_hk_minute/status_code:{res.status_code}/text:{res.text}")
        return []
    else:
        try:
            data_json = res.json()
        except Exception as e:
            logging.error(f"tencent_hk_minute/error: res.json()/detail:{e.__str__()}")
            return []
        if "data" in data_json \
                and prefix_code in data_json["data"] \
                and "data" in data_json["data"][prefix_code] \
                and "data" in data_json["data"][prefix_code]["data"] \
                and data_json["data"][prefix_code]["data"]["data"]:
            date = data_json["data"][prefix_code]["data"]["date"]
            date = date[:4] + "-" + date[4:6] + "-" + date[6:]
            res = []
            prev = 0
            for d in data_json["data"][prefix_code]["data"]["data"]:
                d = d.split(" ")
                res.append({
                    "datetime": date + " " + d[0][:2] + ":" + d[0][2:] + ":00",
                    "close": float(d[1]),
                    "volume": float(d[2]) - prev,
                    "stock_type": "hk"
                })
                prev = float(d[2]) - prev

            if latest_minute:
                return res[-1]
            else:
                return res
        else:
            return []

 天k线

 

import requests
from py_mini_racer import py_mini_racer
us_sina_stock_hist_qfq_url = "https://finance.sina.com.cn/us_stock/company/reinstatement/{}_qfq.js"
us_tencent_daily = "http://web.ifzq.gtimg.cn/appstock/app/fqkline/get?_var=kline_dayqfq&param={},day,,,{},qfq"
def sina_us_daily(symbol, adjust=""):
    url = f"https://finance.sina.com.cn/staticdata/us/{symbol}"
    res = requests.get(url)
    js_code = py_mini_racer.MiniRacer()
    js_code.eval(zh_js_decode)
    dict_list = js_code.call(
        "d", res.text.split("=")[1].split(";")[0].replace('"', "")
    )  # 执行js解密代码
    if adjust == "qfq":
        # 使用前复权
        res = requests.get(us_sina_stock_hist_qfq_url.format(symbol))
        try:
            qfq = json.loads(res.text.split("=")[1].split("\n")[0])["data"]
            if len(qfq) == 1:
                return dict_list
        except SyntaxError as e:
            return dict_list
        qfq = sorted(map(lambda x: (x["d"], float(x["f"]), float(x["c"])), qfq))
        n = len(qfq)
        qfq_index = 0
        for data_index in range(len(dict_list)):
            while qfq_index + 1 < n and qfq[qfq_index + 1][0] <= dict_list[data_index]["date"][:10]:
                qfq_index += 1
            dict_list[data_index]["high"] *= qfq[qfq_index][1]
            dict_list[data_index]["high"] += qfq[qfq_index][2]
            dict_list[data_index]["low"] *= qfq[qfq_index][1]
            dict_list[data_index]["low"] += qfq[qfq_index][2]
            dict_list[data_index]["open"] *= qfq[qfq_index][1]
            dict_list[data_index]["open"] += qfq[qfq_index][2]
            dict_list[data_index]["close"] *= qfq[qfq_index][1]
            dict_list[data_index]["close"] += qfq[qfq_index][2]
    return dict_list


def tencent_us_daily(symbol, day=0):
    prefix_code = "us" + symbol + ".OQ"
    res = requests.get(us_tencent_daily.format(prefix_code, day), headers=headers)
    if res.status_code != 200:
        logging.error(f"tencent_hk_daily/status_code:{res.status_code}/text:{res.text}")
        return []
    else:
        try:
            data_json = json.loads(res.text.split("=")[1].split("\n")[0])
        except Exception as e:
            logging.error(f"tencent_hk_daily/error: res.json()/detail:{e.__str__()}")
            return []
        if "data" in data_json \
                and prefix_code in data_json["data"] \
                and "day" in data_json["data"][prefix_code]:
            res = []
            for d in data_json["data"][prefix_code]["day"]:
                res.append({
                    "day": d[0],
                    "open": float(d[1]),
                    "close": float(d[2]),
                    "high": float(d[3]),
                    "low": float(d[4]),
                    "volume": float(d[5])
                })
            return res
        else:
            return []

 

更便捷的方法,建议使用akshare,虽然获取速度很慢,但接口获取方式是可以参考的。

posted @ 2022-04-11 16:31  不要不说  阅读(3311)  评论(0编辑  收藏  举报