Files
MoFin/venv/lib/python3.12/site-packages/akshare/futures/futures_hq_sina.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

299 lines
9.4 KiB
Python

#!/usr/bin/env python
# -*- coding:utf-8 -*-
"""
Date: 2025/3/5 18:00
Desc: 新浪财经-外盘期货
https://finance.sina.com.cn/money/future/hf.html
"""
import time
from typing import Union, List
import pandas as pd
import requests
from bs4 import BeautifulSoup
from akshare.utils import demjson
def _get_real_name_list() -> list:
"""
新浪-外盘期货所有品种的中文名称
https://finance.sina.com.cn/money/future/hf.html
:return: 外盘期货所有品种的中文名称
:rtype: list
"""
url = "https://finance.sina.com.cn/money/future/hf.html"
r = requests.get(url)
r.encoding = "gb2312"
data_text = r.text
need_text = data_text[
data_text.find("var oHF_1 = ") + 12 : data_text.find("var oHF_2") - 2
].replace("\n\t", "")
data_json = demjson.decode(need_text)
name_list = [item[0].strip() for item in data_json.values()]
return name_list
def futures_foreign_commodity_subscribe_exchange_symbol() -> list:
"""
需要订阅的行情的代码
https://finance.sina.com.cn/money/future/hf.html
:return: 需要订阅的行情的代码
:rtype: list
"""
url = "https://finance.sina.com.cn/money/future/hf.html"
r = requests.get(url)
r.encoding = "gb2312"
data_text = r.text
data_json = demjson.decode(
data_text[
data_text.find("var oHF_1 = ") + 12 : data_text.find("var oHF_2 = ") - 2
]
)
code_list = list(data_json.keys())
return code_list
def futures_hq_subscribe_exchange_symbol() -> pd.DataFrame:
"""
将品种字典转化为 pandas.DataFrame
https://finance.sina.com.cn/money/future/hf.html
:return: 品种对应表
:rtype: pandas.DataFrame
"""
inner_dict = {
"新加坡铁矿石": "FEF",
"马棕油": "FCPO",
"日橡胶": "RSS3",
"美国原糖": "RS",
"CME比特币期货": "BTC",
"NYBOT-棉花": "CT",
"LME镍3个月": "NID",
"LME铅3个月": "PBD",
"LME锡3个月": "SND",
"LME锌3个月": "ZSD",
"LME铝3个月": "AHD",
"LME铜3个月": "CAD",
"CBOT-黄豆": "S",
"CBOT-小麦": "W",
"CBOT-玉米": "C",
"CBOT-黄豆油": "BO",
"CBOT-黄豆粉": "SM",
"日本橡胶": "TRB",
"COMEX铜": "HG",
"NYMEX天然气": "NG",
"NYMEX原油": "CL",
"COMEX白银": "SI",
"COMEX黄金": "GC",
"CME-瘦肉猪": "LHC",
"布伦特原油": "OIL",
"伦敦金": "XAU",
"伦敦银": "XAG",
"伦敦铂金": "XPT",
"伦敦钯金": "XPD",
"欧洲碳排放": "EUA",
}
temp_df = pd.DataFrame.from_dict(inner_dict, orient="index")
temp_df.reset_index(inplace=True)
temp_df.columns = ["symbol", "code"]
return temp_df
def futures_foreign_commodity_realtime(symbol: Union[str, List[str]]) -> pd.DataFrame:
"""
新浪-外盘期货-行情数据
https://finance.sina.com.cn/money/future/hf.html
:param symbol: 通过调用 ak.futures_hq_subscribe_exchange_symbol() 函数来获取
:type symbol: list or str
:return: 行情数据
:rtype: pandas.DataFrame
"""
if isinstance(symbol, list):
payload = "?list=" + ",".join(["hf_" + item for item in symbol])
else:
symbol = symbol.split(",")
payload = "?list=" + ",".join(["hf_" + item for item in symbol])
url = "https://hq.sinajs.cn/" + payload
headers = {
"Accept": "*/*",
"Accept-Encoding": "gzip, deflate, br",
"Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8",
"Cache-Control": "no-cache",
"Connection": "keep-alive",
"Host": "hq.sinajs.cn",
"Pragma": "no-cache",
"Referer": "https://finance.sina.com.cn/",
"sec-ch-ua": '" Not;A Brand";v="99", "Google Chrome";v="97", "Chromium";v="97"',
"sec-ch-ua-mobile": "?0",
"sec-ch-ua-platform": '"Windows"',
"Sec-Fetch-Dest": "script",
"Sec-Fetch-Mode": "no-cors",
"Sec-Fetch-Site": "cross-site",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "
"Chrome/97.0.4692.71 Safari/537.36",
}
r = requests.get(url, headers=headers)
data_text = r.text
data_df = pd.DataFrame(
[
item.strip().split("=")[1].split(",")
for item in data_text.split(";")
if item.strip() != ""
]
)
data_df.iloc[:, 0] = data_df.iloc[:, 0].str.replace('"', "")
data_df.iloc[:, -1] = data_df.iloc[:, -1].str.replace('"', "")
# 处理伦敦金 XAU 的情况
if len(data_df.columns) == 14:
data_df["temp"] = None
data_df.columns = [
"current_price",
"-",
"bid",
"ask",
"high",
"low",
"time",
"last_settle_price",
"open",
"hold",
"-",
"-",
"date",
"symbol",
"current_price_rmb",
]
temp_symbol_code_df = futures_hq_subscribe_exchange_symbol()
temp_symbol_code_dict = dict(
zip(temp_symbol_code_df["code"], temp_symbol_code_df["symbol"])
)
data_df["symbol"] = [temp_symbol_code_dict[subscribe] for subscribe in symbol]
data_df = data_df[
[
"symbol",
"current_price",
"current_price_rmb",
"bid",
"ask",
"high",
"low",
"time",
"last_settle_price",
"open",
"hold",
"date",
]
]
data_df.columns = [
"名称",
"最新价",
"人民币报价",
"买价",
"卖价",
"最高价",
"最低价",
"行情时间",
"昨日结算价",
"开盘价",
"持仓量",
"日期",
]
data_df.dropna(how="all", inplace=True)
data_df["最新价"] = pd.to_numeric(data_df["最新价"], errors="coerce")
data_df["人民币报价"] = pd.to_numeric(data_df["人民币报价"], errors="coerce")
data_df["买价"] = pd.to_numeric(data_df["买价"], errors="coerce")
data_df["卖价"] = pd.to_numeric(data_df["卖价"], errors="coerce")
data_df["最高价"] = pd.to_numeric(data_df["最高价"], errors="coerce")
data_df["最低价"] = pd.to_numeric(data_df["最低价"], errors="coerce")
data_df["昨日结算价"] = pd.to_numeric(data_df["昨日结算价"], errors="coerce")
data_df["开盘价"] = pd.to_numeric(data_df["开盘价"], errors="coerce")
data_df["持仓量"] = pd.to_numeric(data_df["持仓量"], errors="coerce")
data_df["涨跌额"] = data_df["最新价"] - data_df["昨日结算价"]
data_df["涨跌幅"] = (
(data_df["最新价"] - data_df["昨日结算价"]) / data_df["昨日结算价"] * 100
)
data_df = data_df[
[
"名称",
"最新价",
"人民币报价",
"涨跌额",
"涨跌幅",
"开盘价",
"最高价",
"最低价",
"昨日结算价",
"持仓量",
"买价",
"卖价",
"行情时间",
"日期",
]
]
# 获取转换比例数据
url = "https://finance.sina.com.cn/money/future/hf.html"
r = requests.get(url)
r.encoding = "utf-8"
soup = BeautifulSoup(r.text, features="lxml")
data_text = soup.find_all(name="script", attrs={"type": "text/javascript"})[
-2
].string.strip()
raw_text = data_text[data_text.find("oHF_1 = ") : data_text.find("oHF_2")]
need_text = raw_text[raw_text.find("{") : raw_text.rfind("}") + 1]
data_json = demjson.decode(need_text)
price_mul = pd.DataFrame(
[
[item[0] for item in data_json.values()],
[item[1][0] for item in data_json.values()],
]
).T
price_mul.columns = ["symbol", "price"]
price_mul = price_mul[price_mul["symbol"].isin(data_df["名称"])]
price_mul.reset_index(inplace=True, drop=True)
price_mul["price"] = pd.to_numeric(price_mul["price"], errors="coerce")
# 获取汇率数据
url = "https://hq.sinajs.cn/?list=USDCNY"
r = requests.get(url, headers=headers)
data_text = r.text
usd_rmb = float(
data_text[data_text.find('"') + 1 : data_text.find(",美元人民币")].split(",")[
-1
]
)
# 计算人民币报价
data_df["最新价"] = pd.to_numeric(data_df["最新价"], errors="coerce")
data_df["人民币报价"] = data_df["最新价"] * price_mul["price"] * float(usd_rmb)
data_df.dropna(thresh=4, inplace=True)
return data_df
if __name__ == "__main__":
futures_hq_subscribe_exchange_symbol_df = futures_hq_subscribe_exchange_symbol()
print(futures_hq_subscribe_exchange_symbol_df)
print("开始接收实时行情, 每秒刷新一次")
subscribes = futures_foreign_commodity_subscribe_exchange_symbol()
futures_foreign_commodity_realtime_df = futures_foreign_commodity_realtime(
symbol="CT,NID"
)
print(futures_foreign_commodity_realtime_df)
futures_foreign_commodity_realtime_df = futures_foreign_commodity_realtime(
symbol=["XAU"]
)
print(futures_foreign_commodity_realtime_df)
while True:
futures_foreign_commodity_realtime_df = futures_foreign_commodity_realtime(
symbol=subscribes
)
print(futures_foreign_commodity_realtime_df)
time.sleep(3)