Files
MoFin/venv/lib/python3.12/site-packages/tushare/stock/histroy_divide.py
T
知微 fa45d8aa5f fix: 小果地址统一node122(兼容LAN+EasyTier)
- health_checklist.json: 192.168.1.122→node122
- ocr_client.py: docstring IP→node122
- docs/market-data-requirements.md: IP→node122
- 所有API调用通过ProxyHandler({})绕过系统代理
  Privoxy对node122:18003返回500,直连正常
2026-06-30 02:56:35 +08:00

256 lines
8.4 KiB
Python

#!/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)