#!/usr/bin/env python # -*- coding:utf-8 -*- """ Created on 2023/12/06 @author: Monday @group : waditu Desc: 腾讯-股票-实时行情-成交明细 成交明细-每个交易日 16:00 提供当日数据 港股报价延时 15 分钟 """ import warnings import pandas as pd import requests from io import StringIO from tushare.util.verify_token import require_permission from tushare.util.format_stock_code import format_stock_code from tushare.stock.rtq_vars import zh_sina_a_stock_cookies, zh_sina_a_stock_headers import time import json from typing import Optional from tushare.util.form_date import get_current_date from tushare.stock import rtq_vars from tushare.util.format_stock_code import symbol_verify headers = { "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36 Edg/119.0.0.0" } @require_permission(event_name="realtime_tick", event_detail="个股历史分笔数据") def realtime_tick(ts_code: str = "000001.SZ", src: Optional[str] = "tx", page_count: Optional[int] = None) -> pd.DataFrame: """ 历史分笔数据 :param ts_code: 股票代码 :type ts_code: str :param src: 来源 腾讯财经tx 新浪财经sina :type src: str :param page_count: 限制页数 :type page_count: str :return: 历史分笔数据 :rtype: pandas.DataFrame 1、TIME : 成交时间 2、PRICE : 成交价格 3、PCHANGE : 涨跌幅 4、CHANGE : 价格变动 5、VOLUME : 成交量(手) 6、AMOUNT : 成交额(元) 7、TYPE : 性质 """ symbol = symbol_verify(ts_code) if src == "sina": return get_stock_sina_a_divide_amount(symbol, page_count) elif src == 'dc': return get_stock_dc_a_divide_amount(symbol, page_count) else: return get_stock_tx_a_divide_amount(symbol, page_count) def get_stock_tx_a_divide_amount(symbol: str = "sz000001", page_count: Optional[int] = None) -> pd.DataFrame: """ 腾讯财经-历史分笔数据 https://gu.qq.com/sz300494/gp/detail :param symbol: 股票代码 :type symbol: str :param page_count: 限制页数 :type page_count: str :return: 历史分笔数据 :rtype: pandas.DataFrame """ symbols = str(symbol).lower().split(".") symbol = f"{symbols[1]}{symbols[0]}" big_df = pd.DataFrame() page = 0 warnings.warn("正在下载数据,请稍等") while True: try: url = "http://stock.gtimg.cn/data/index.php" params = { "appn": "detail", "action": "data", "c": symbol, "p": page, } r = requests.get(url, headers=headers, params=params) text_data = r.text temp_df = ( pd.DataFrame(eval(text_data[text_data.find("["):])[1].split("|")) .iloc[:, 0] .str.split("/", expand=True) ) page += 1 big_df = pd.concat([big_df, temp_df], ignore_index=True) time.sleep(0.5) if page_count and page >= page_count: break except: break if not big_df.empty: big_df = big_df.iloc[:, 1:].copy() # big_df.columns = ["成交时间", "成交价格", "价格变动", "成交量", "成交金额", "性质"] big_df.columns = rtq_vars.TICK_COLUMNS big_df.reset_index(drop=True, inplace=True) property_map = { "S": "卖盘", "B": "买盘", "M": "中性盘", } # big_df["性质"] = big_df["性质"].map(property_map) big_df["TYPE"] = big_df["TYPE"].map(property_map) big_df = big_df.astype( { "TIME": str, "PRICE": float, "CHANGE": float, "VOLUME": int, "AMOUNT": int, "TYPE": str, } ) return big_df def get_stock_sina_a_divide_amount(symbol: str = "sz000001", page_count: Optional[int] = None, ) -> pd.DataFrame: """ 腾新浪财经-历史分笔数据 https://vip.stock.finance.sina.com.cn/quotes_service/view/vMS_tradedetail.php?symbol=sh688553 :param symbol: 股票代码 :type symbol: str :param page_count: 限制页数 :type page_count: str :return: 历史分笔数据 :rtype: pandas.DataFrame """ warnings.warn("正在下载数据,请稍等") symbols = str(symbol).lower().split(".") symbol = f"{symbols[1]}{symbols[0]}" page = 0 big_df = pd.DataFrame() while True: try: url = "https://vip.stock.finance.sina.com.cn/quotes_service/view/vMS_tradedetail.php" params = { "symbol": symbol, "date": get_current_date(date_format="%Y-%m-%d"), "page": page } response = requests.get(url, headers=zh_sina_a_stock_headers, cookies=zh_sina_a_stock_cookies, params=params) temp_df = (pd.read_html(StringIO(response.content.decode("GBK")))[3]) big_df = pd.concat([big_df, temp_df], ignore_index=True) page += 1 if page_count and page >= page_count: break except: break time.sleep(0.5) if not big_df.empty: big_df = big_df.iloc[:, 0:].copy() # big_df.columns = ["成交时间", "成交价格", "涨跌幅", "价格变动", "成交量(手)", "成交额(元)", "性质"] big_df.columns = rtq_vars.TODAY_TICK_COLUMNS big_df.reset_index(drop=True, inplace=True) # big_df = big_df.astype( # { # "成交时间": str, # "成交价格": float, # "涨跌幅": str, # "价格变动": str, # "成交量(手)": int, # "成交额(元)": int, # "性质": str, # } # ) big_df = big_df.astype( { "TIME": str, "PRICE": float, "PCHANGE": str, "CHANGE": str, "VOLUME": int, "AMOUNT": int, "TYPE": str, } ) return big_df def __event_stream(url, params, ): response = requests.get(url, params=params, stream=True) event_data = "" for line in response.iter_lines(): # 过滤掉保持连接的空行 if line: event_data += line.decode() + "\n" elif event_data: yield event_data event_data = "" def get_stock_dc_a_divide_amount(symbol: str = "000001", page_count: Optional[int] = None) -> pd.DataFrame: """ 东方财富-分时数据 https://quote.eastmoney.com/f1.html?newcode=0.000001 :param symbol: 股票代码 :type symbol: str :return: 分时数据 :rtype: pandas.DataFrame """ symbols = str(symbol).lower().split(".") symbol = symbols[0] # print(symbol) market_code = 1 if symbol.startswith("6") else 0 url = "https://70.push2.eastmoney.com/api/qt/stock/details/sse" params = { "fields1": "f1,f2,f3,f4", "fields2": "f51,f52,f53,f54,f55", "mpi": "2000", "ut": "bd1d9ddb04089700cf9c27f6f7426281", "fltt": "2", "pos": "-0", "secid": f"{market_code}.{symbol}", "wbp2u": "|0|0|0|web", } big_df = pd.DataFrame() # 创建一个空的 DataFrame for event in __event_stream(url, params): # 从每个事件的数据行中删除 "data: ",然后解析 JSON event_json = json.loads(event.replace("data: ", "")) # 将 JSON 数据转换为 DataFrame,然后添加到主 DataFrame 中 temp_df = pd.DataFrame( [item.split(",") for item in event_json["data"]["details"]] ) big_df = pd.concat(objs=[big_df, temp_df], ignore_index=True) break big_df.columns = ["TIME", "PRICE", "VOLUME", "-", "TYPE"] big_df["TYPE"] = big_df["TYPE"].map( {"2": "买盘", "1": "卖盘", "4": "中性盘"} ) big_df = big_df[["TIME", "PRICE", "VOLUME", "TYPE"]] big_df["PRICE"] = pd.to_numeric(big_df["PRICE"], errors="coerce") big_df["VOLUME"] = pd.to_numeric(big_df["VOLUME"], errors="coerce") return big_df if __name__ == '__main__': df = realtime_tick(ts_code="000001.SZ", src="dc", page_count=1) print(help(realtime_tick)) print(df) # r = get_stock_dc_a_divide_amount() # print(r)