stock-tracker

This commit is contained in:
C菌
2026-07-04 00:17:11 +08:00
commit 6087341a48
6463 changed files with 1929869 additions and 0 deletions
@@ -0,0 +1,6 @@
#!/usr/bin/env python
# -*- coding:utf-8 -*-
"""
Date: 2019/9/30 13:58
Desc:
"""
@@ -0,0 +1,153 @@
#!/usr/bin/env python
# -*- coding:utf-8 -*-
"""
Date: 2019/9/30 13:58
Desc: 期权配置文件
"""
import datetime
import json
import os
import re
# 中国金融期货交易所
CFFEX_OPTION_URL_300 = "http://www.cffex.com.cn/quote_IO.txt"
# 深圳证券交易所
SZ_OPTION_URL_300 = "http://www.szse.cn/api/report/ShowReport?SHOWTYPE=xlsx&CATALOGID=ysplbrb&TABKEY=tab1&random=0.10432465776720479"
# 上海证券交易所
SH_OPTION_URL_50 = "http://yunhq.sse.com.cn:32041/v1/sh1/list/self/510050"
SH_OPTION_URL_KING_50 = "http://yunhq.sse.com.cn:32041/v1/sho/list/tstyle/510050_{}"
SH_OPTION_URL_300 = "http://yunhq.sse.com.cn:32041/v1/sh1/list/self/510300"
SH_OPTION_URL_KING_300 = "http://yunhq.sse.com.cn:32041/v1/sho/list/tstyle/510300_{}"
SH_OPTION_URL_500 = "http://yunhq.sse.com.cn:32041/v1/sh1/list/self/510500"
SH_OPTION_URL_KING_500 = "http://yunhq.sse.com.cn:32041/v1/sho/list/tstyle/510500_{}"
SH_OPTION_URL_KC_50 = "http://yunhq.sse.com.cn:32041/v1/sh1/list/self/588000"
SH_OPTION_URL_KC_KING_50 = "http://yunhq.sse.com.cn:32041/v1/sho/list/tstyle/588000_{}"
SH_OPTION_URL_KC_50_YFD = "http://yunhq.sse.com.cn:32041/v1/sh1/list/self/588080"
SH_OPTION_URL_KING_50_YFD = "http://yunhq.sse.com.cn:32041/v1/sho/list/tstyle/588080_{}"
SH_OPTION_PAYLOAD = {
"select": "select: code,name,last,change,chg_rate,amp_rate,volume,amount,prev_close"
}
SH_OPTION_PAYLOAD_OTHER = {"select": "contractid,last,chg_rate,presetpx,exepx"}
# 大连商品交易所
DCE_OPTION_URL = "http://portal.dce.com.cn/publicweb/quotesdata/dayQuotesCh.html"
DCE_DAILY_OPTION_URL = (
"http://portal.dce.com.cn/publicweb/quotesdata/exportDayQuotesChData.html"
)
# 上海期货交易所
SHFE_OPTION_URL = "https://tsite.shfe.com.cn/data/dailydata/option/kx/kx{}.dat"
# 郑州商品交易所
CZCE_DAILY_OPTION_URL_3 = (
"http://www.czce.com.cn/cn/DFSStaticFiles/Option/{}/{}/OptionDataDaily.txt"
)
# PAYLOAD
SHFE_HEADERS = {"User-Agent": "Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)"}
DATE_PATTERN = re.compile(r"^([0-9]{4})[-/]?([0-9]{2})[-/]?([0-9]{2})")
def convert_date(date):
"""
transform a date string to datetime.date object
:param date, string, e.g. 2016-01-01, 20160101 or 2016/01/01
:return: object of datetime.date(such as 2016-01-01) or None
"""
if isinstance(date, datetime.date):
return date
elif isinstance(date, str):
match = DATE_PATTERN.match(date)
if match:
groups = match.groups()
if len(groups) == 3:
return datetime.date(
year=int(groups[0]), month=int(groups[1]), day=int(groups[2])
)
return None
def get_json_path(name, module_file):
"""
获取 JSON 配置文件的路径(从模块所在目录查找)
:param name: 文件名
:param module_file: filename
:return: str json_file_path
"""
module_folder = os.path.abspath(os.path.dirname(os.path.dirname(module_file)))
module_json_path = os.path.join(module_folder, "file_fold", name)
return module_json_path
def get_calendar():
"""
获取交易日历至 2019 年结束, 这里的交易日历需要按年更新
:return: json
"""
setting_file_name = "calendar.json"
setting_file_path = get_json_path(setting_file_name, __file__)
return json.load(open(setting_file_path, "r"))
def last_trading_day(day):
"""
获取前一个交易日
:param day: "%Y%m%d" or datetime.date()
:return last_day: "%Y%m%d" or datetime.date()
"""
calendar = get_calendar()
if isinstance(day, str):
if day not in calendar:
print("Today is not trading day" + day)
return False
pos = calendar.index(day)
last_day = calendar[pos - 1]
return last_day
elif isinstance(day, datetime.date):
d_str = day.strftime("%Y%m%d")
if d_str not in calendar:
print("Today is not working day" + d_str)
return False
pos = calendar.index(d_str)
last_day = calendar[pos - 1]
last_day = datetime.datetime.strptime(last_day, "%Y%m%d").date()
return last_day
def get_latest_data_date(day):
"""
获取最新的有数据的交易日
:param day: datetime.datetime
:return string YYYYMMDD
"""
calendar = get_calendar()
if day.strftime("%Y%m%d") in calendar:
if day.time() > datetime.time(17, 0, 0):
return day.strftime("%Y%m%d")
else:
return last_trading_day(day.strftime("%Y%m%d"))
else:
while day.strftime("%Y%m%d") not in calendar:
day = day - datetime.timedelta(days=1)
return day.strftime("%Y%m%d")
if __name__ == "__main__":
d = datetime.datetime(2018, 10, 5, 17, 1, 0)
print(get_latest_data_date(d))
@@ -0,0 +1,86 @@
#!/usr/bin/env python
# -*- coding:utf-8 -*-
"""
Date: 2024/7/5 15:00
Desc: 九期网-商品期权手续费
https://www.9qihuo.com/qiquanshouxufei
"""
from functools import lru_cache
from io import StringIO
import pandas as pd
import requests
from bs4 import BeautifulSoup
@lru_cache()
def option_comm_symbol() -> pd.DataFrame:
import urllib3
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
url = "https://www.9qihuo.com/qiquanshouxufei"
r = requests.get(url, verify=False)
soup = BeautifulSoup(r.text, features="lxml")
name = [
item.string.strip()
for item in soup.find(name="div", attrs={"id": "inst_list"}).find_all(name="a")
]
code = [
item["href"].split("?")[1].split("=")[1]
for item in soup.find(name="div", attrs={"id": "inst_list"}).find_all(name="a")
]
temp_df = pd.DataFrame([name, code]).T
temp_df.columns = ["品种名称", "品种代码"]
return temp_df
def option_comm_info(symbol: str = "工业硅期权") -> pd.DataFrame:
"""
九期网-商品期权手续费
https://www.9qihuo.com/qiquanshouxufei
:param symbol: choice of {"所有", "上海期货交易所", "大连商品交易所", "郑州商品交易所", "上海国际能源交易中心", "广州期货交易所"}
:type symbol: str
:return: 期权手续费
:rtype: pandas.DataFrame
"""
import urllib3
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
symbol_df = option_comm_symbol()
symbol_str = symbol_df[symbol_df["品种名称"].str.contains(symbol)][
"品种代码"
].values[0]
params = {"heyue": symbol_str}
url = "https://www.9qihuo.com/qiquanshouxufei"
r = requests.get(url, params=params, verify=False)
temp_df = pd.read_html(StringIO(r.text))[0]
market_symbol = temp_df.iloc[0, 0]
columns = temp_df.iloc[2, :]
temp_df = temp_df.iloc[3:, :]
temp_df.columns = columns
temp_df["交易所"] = market_symbol
temp_df.reset_index(drop=True, inplace=True)
temp_df.index.name = None
temp_df.columns.name = None
temp_df["现价"] = pd.to_numeric(temp_df["现价"], errors="coerce")
temp_df["成交量"] = pd.to_numeric(temp_df["成交量"], errors="coerce")
temp_df["每跳毛利/元"] = pd.to_numeric(temp_df["每跳毛利/元"], errors="coerce")
temp_df["每跳净利/元"] = pd.to_numeric(temp_df["每跳净利/元"], errors="coerce")
soup = BeautifulSoup(r.text, features="lxml")
raw_date_text = soup.find(name="a", attrs={"id": "dlink"}).previous
comm_update_time = raw_date_text.split("")[0].strip("(手续费更新时间:")
price_update_time = (
raw_date_text.split("")[1].strip("价格更新时间:").strip("。)")
)
temp_df["手续费更新时间"] = comm_update_time
temp_df["价格更新时间"] = price_update_time
return temp_df
if __name__ == "__main__":
option_comm_symbol_df = option_comm_symbol()
print(option_comm_symbol_df)
option_comm_info_df = option_comm_info(symbol="工业硅期权")
print(option_comm_info_df)
@@ -0,0 +1,672 @@
#!/usr/bin/env python
# -*- coding:utf-8 -*-
"""
Date: 2025/10/17 21:00
Desc: 商品期权数据
说明:
(1) 价格:自2019年12月02日起,纤维板报价单位由元/张改为元/立方米
(2) 价格:元/吨,鸡蛋为元/500千克,纤维板为元/立方米,胶合板为元/张
(3) 成交量、持仓量:手(按双边计算)
(4) 成交额:万元(按双边计算)
(5) 涨跌=收盘价-前结算价
(6) 涨跌1=今结算价-前结算价
(7) 合约系列:具有相同月份标的期货合约的所有期权合约的统称
(8) 隐含波动率:根据期权市场价格,利用期权定价模型计算的标的期货合约价格波动率
"""
import datetime
import warnings
from io import StringIO
import pandas as pd
import requests
from akshare.option.cons import (
get_calendar,
convert_date,
CZCE_DAILY_OPTION_URL_3,
SHFE_HEADERS,
)
def option_hist_dce(
symbol: str = "聚丙烯期权", trade_date: str = "20251016"
) -> pd.DataFrame:
"""
大连商品交易所-期权-日频行情数据
http://www.dce.com.cn/
:param trade_date: 交易日
:type trade_date: str
:param symbol: choice of {"玉米期权", "豆粕期权", "铁矿石期权", "液化石油气期权", "聚乙烯期权", "聚氯乙烯期权",
"聚丙烯期权", "棕榈油期权", "黄大豆1号期权", "黄大豆2号期权", "豆油期权", "乙二醇期权", "苯乙烯期权",
"鸡蛋期权", "玉米淀粉期权", "生猪期权", "原木期权"}
:type symbol: str
:return: 日频行情数据
:rtype: pandas.DataFrame
"""
option_code_map = {
"玉米期权": "c",
"豆粕期权": "m",
"铁矿石期权": "i",
"液化石油气期权": "pg",
"聚乙烯期权": "l",
"聚氯乙烯期权": "v",
"聚丙烯期权": "pp",
"棕榈油期权": "p",
"黄大豆1号期权": "a",
"黄大豆2号期权": "b",
"豆油期权": "y",
"乙二醇期权": "eg",
"苯乙烯期权": "eb",
"鸡蛋期权": "jd",
"玉米淀粉期权": "cs",
"生猪期权": "lh",
"原木期权": "lg",
}
calendar = get_calendar()
day = convert_date(trade_date) if trade_date is not None else datetime.date.today()
if day.strftime("%Y%m%d") not in calendar:
warnings.warn("%s非交易日" % day.strftime("%Y%m%d"))
return pd.DataFrame()
url = "http://www.dce.com.cn/dcereport/publicweb/dailystat/dayQuotes"
payload = {
"contractId": "",
"lang": "zh",
"optionSeries": "",
"statisticsType": 0,
"tradeDate": f"{trade_date}",
"tradeType": "2",
"varietyId": f"{option_code_map[symbol]}",
}
r = requests.post(url, json=payload)
data_json = r.json()
temp_df = pd.DataFrame(data_json["data"])
temp_df.rename(
columns={
"variety": "品种名称",
"contractId": "合约",
"open": "开盘价",
"high": "最高价",
"low": "最低价",
"close": "收盘价",
"lastClear": "前结算价",
"clearPrice": "结算价",
"diff": "涨跌",
"diff1": "涨跌1",
"delta": "Delta",
"volumn": "成交量", # 注意:你写的是“volumn”,可能是拼写错误,应为“volume”
"openInterest": "持仓量",
"diffI": "持仓量变化",
"turnover": "成交额",
"matchQtySum": "行权量",
"impliedVolatility": "隐含波动率(%)",
},
inplace=True,
)
temp_df = temp_df[
[
"品种名称",
"合约",
"开盘价",
"最高价",
"最低价",
"收盘价",
"前结算价",
"结算价",
"涨跌",
"涨跌1",
"Delta",
"隐含波动率(%)",
"成交量",
"持仓量",
"持仓量变化",
"成交额",
"行权量",
]
]
comma_cols = [
"开盘价",
"最高价",
"最低价",
"收盘价",
"前结算价",
"结算价",
"涨跌",
"涨跌1",
"Delta",
"隐含波动率(%)",
"成交额",
] # 需要处理的列
for col in comma_cols:
temp_df[col] = (
temp_df[col]
.astype(str)
.str.replace(",", "")
.pipe(pd.to_numeric, errors="coerce")
)
return temp_df
def __option_czce_daily_convert_numeric_columns(df):
# 定义要处理的列
columns_to_convert = [
"昨结算",
"今开盘",
"最高价",
"最低价",
"今收盘",
"今结算",
"涨跌1",
"涨跌2",
"成交量(手)",
"持仓量",
"增减量",
"成交额(万元)",
"DELTA",
"隐含波动率",
"行权量",
]
# 转换函数:去除逗号并转换为float
def convert_to_float(x):
try:
return float(str(x).replace(",", ""))
except: # noqa: E722
return x
# 创建 DataFrame 的副本以避免 SettingWithCopyWarning
df_copy = df.copy()
df_copy.columns = [item.strip() for item in df_copy]
# 应用转换
for col in columns_to_convert:
df_copy[col] = df_copy[col].apply(convert_to_float)
return df_copy
def option_hist_czce(
symbol: str = "白糖期权", trade_date: str = "20191017"
) -> pd.DataFrame:
"""
郑州商品交易所-期权-日频行情数据
http://www.czce.com.cn/cn/sspz/dejbqhqq/H770227index_1.htm#tabs-2
:param trade_date: 交易日
:type trade_date: str
:param symbol: choice of {"白糖期权", "棉花期权", "甲醇期权", "PTA期权", "动力煤期权", "菜籽粕期权", "菜籽油期权",
"花生期权", "对二甲苯期权", "烧碱期权", "纯碱期权", "短纤期权", "锰硅期权", "硅铁期权", "尿素期权", "苹果期权", "红枣期权",
"玻璃期权", "瓶片期权", "丙烯期货"}
:type symbol: str
:return: 日频行情数据
:rtype: pandas.DataFrame
"""
calendar = get_calendar()
day = convert_date(trade_date) if trade_date is not None else datetime.date.today()
if day.strftime("%Y%m%d") not in calendar:
warnings.warn("{}非交易日".format(day.strftime("%Y%m%d")))
return pd.DataFrame()
if day > datetime.date(year=2010, month=8, day=24):
url = CZCE_DAILY_OPTION_URL_3.format(day.strftime("%Y"), day.strftime("%Y%m%d"))
try:
r = requests.get(url)
f = StringIO(r.text)
table_df = pd.read_table(f, encoding="utf-8", skiprows=1, sep="|")
table_df.columns = [
"合约代码",
"昨结算",
"今开盘",
"最高价",
"最低价",
"今收盘",
"今结算",
"涨跌1",
"涨跌2",
"成交量(手)",
"持仓量",
"增减量",
"成交额(万元)",
"DELTA",
"隐含波动率",
"行权量",
]
if symbol == "白糖期权":
temp_df = table_df[table_df.iloc[:, 0].str.contains("SR")]
temp_df.reset_index(inplace=True, drop=True)
temp_df = temp_df.iloc[:-1, :].copy()
new_df = __option_czce_daily_convert_numeric_columns(temp_df)
return new_df
elif symbol == "棉花期权":
temp_df = table_df[table_df.iloc[:, 0].str.contains("CF")]
temp_df.reset_index(inplace=True, drop=True)
temp_df = temp_df.iloc[:-1, :].copy()
new_df = __option_czce_daily_convert_numeric_columns(temp_df)
return new_df
elif symbol == "甲醇期权":
temp_df = table_df[table_df.iloc[:, 0].str.contains("MA")]
temp_df.reset_index(inplace=True, drop=True)
temp_df = temp_df.iloc[:-1, :].copy()
new_df = __option_czce_daily_convert_numeric_columns(temp_df)
return new_df
elif symbol == "PTA期权":
temp_df = table_df[table_df.iloc[:, 0].str.contains("TA")]
temp_df.reset_index(inplace=True, drop=True)
temp_df = temp_df.iloc[:-1, :].copy()
new_df = __option_czce_daily_convert_numeric_columns(temp_df)
return new_df
elif symbol == "动力煤期权":
temp_df = table_df[table_df.iloc[:, 0].str.contains("ZC")]
temp_df.reset_index(inplace=True, drop=True)
temp_df = temp_df.iloc[:-1, :].copy()
new_df = __option_czce_daily_convert_numeric_columns(temp_df)
return new_df
elif symbol == "菜籽粕期权":
temp_df = table_df[table_df.iloc[:, 0].str.contains("RM")]
temp_df.reset_index(inplace=True, drop=True)
temp_df = temp_df.iloc[:-1, :].copy()
new_df = __option_czce_daily_convert_numeric_columns(temp_df)
return new_df
elif symbol == "菜籽油期权":
temp_df = table_df[table_df.iloc[:, 0].str.contains("OI")]
temp_df.reset_index(inplace=True, drop=True)
temp_df = temp_df.iloc[:-1, :].copy()
new_df = __option_czce_daily_convert_numeric_columns(temp_df)
return new_df
elif symbol == "花生期权":
temp_df = table_df[table_df.iloc[:, 0].str.contains("PK")]
temp_df.reset_index(inplace=True, drop=True)
temp_df = temp_df.iloc[:-1, :].copy()
new_df = __option_czce_daily_convert_numeric_columns(temp_df)
return new_df
elif symbol == "短纤期权":
temp_df = table_df[table_df.iloc[:, 0].str.contains("PF")]
temp_df.reset_index(inplace=True, drop=True)
temp_df = temp_df.iloc[:-1, :].copy()
new_df = __option_czce_daily_convert_numeric_columns(temp_df)
return new_df
elif symbol == "对二甲苯期权":
temp_df = table_df[table_df.iloc[:, 0].str.contains("PX")]
temp_df.reset_index(inplace=True, drop=True)
temp_df = temp_df.iloc[:-1, :].copy()
new_df = __option_czce_daily_convert_numeric_columns(temp_df)
return new_df
elif symbol == "烧碱期权":
temp_df = table_df[table_df.iloc[:, 0].str.contains("SH")]
temp_df.reset_index(inplace=True, drop=True)
temp_df = temp_df.iloc[:-1, :].copy()
new_df = __option_czce_daily_convert_numeric_columns(temp_df)
return new_df
elif symbol == "纯碱期权":
temp_df = table_df[table_df.iloc[:, 0].str.contains("SA")]
temp_df.reset_index(inplace=True, drop=True)
temp_df = temp_df.iloc[:-1, :].copy()
new_df = __option_czce_daily_convert_numeric_columns(temp_df)
return new_df
elif symbol == "短纤期权":
temp_df = table_df[table_df.iloc[:, 0].str.contains("PF")]
temp_df.reset_index(inplace=True, drop=True)
temp_df = temp_df.iloc[:-1, :].copy()
new_df = __option_czce_daily_convert_numeric_columns(temp_df)
return new_df
elif symbol == "锰硅期权":
temp_df = table_df[table_df.iloc[:, 0].str.contains("SM")]
temp_df.reset_index(inplace=True, drop=True)
temp_df = temp_df.iloc[:-1, :].copy()
new_df = __option_czce_daily_convert_numeric_columns(temp_df)
return new_df
elif symbol == "硅铁期权":
temp_df = table_df[table_df.iloc[:, 0].str.contains("SF")]
temp_df.reset_index(inplace=True, drop=True)
temp_df = temp_df.iloc[:-1, :].copy()
new_df = __option_czce_daily_convert_numeric_columns(temp_df)
return new_df
elif symbol == "尿素期权":
temp_df = table_df[table_df.iloc[:, 0].str.contains("UR")]
temp_df.reset_index(inplace=True, drop=True)
temp_df = temp_df.iloc[:-1, :].copy()
new_df = __option_czce_daily_convert_numeric_columns(temp_df)
return new_df
elif symbol == "苹果期权":
temp_df = table_df[table_df.iloc[:, 0].str.contains("AP")]
temp_df.reset_index(inplace=True, drop=True)
temp_df = temp_df.iloc[:-1, :].copy()
new_df = __option_czce_daily_convert_numeric_columns(temp_df)
return new_df
elif symbol == "红枣期权":
temp_df = table_df[table_df.iloc[:, 0].str.contains("CJ")]
temp_df.reset_index(inplace=True, drop=True)
temp_df = temp_df.iloc[:-1, :].copy()
new_df = __option_czce_daily_convert_numeric_columns(temp_df)
return new_df
elif symbol == "玻璃期权":
temp_df = table_df[table_df.iloc[:, 0].str.contains("FG")]
temp_df.reset_index(inplace=True, drop=True)
temp_df = temp_df.iloc[:-1, :].copy()
new_df = __option_czce_daily_convert_numeric_columns(temp_df)
return new_df
elif symbol == "瓶片期权":
temp_df = table_df[table_df.iloc[:, 0].str.contains("PR")]
temp_df.reset_index(inplace=True, drop=True)
temp_df = temp_df.iloc[:-1, :].copy()
new_df = __option_czce_daily_convert_numeric_columns(temp_df)
return new_df
elif symbol == "丙烯期权":
temp_df = table_df[table_df.iloc[:, 0].str.contains("PL")]
temp_df.reset_index(inplace=True, drop=True)
temp_df = temp_df.iloc[:-1, :].copy()
new_df = __option_czce_daily_convert_numeric_columns(temp_df)
return new_df
else:
return pd.DataFrame()
except: # noqa: E722
return pd.DataFrame()
else:
return pd.DataFrame()
def option_hist_shfe(
symbol: str = "铝期权", trade_date: str = "20250418"
) -> pd.DataFrame:
"""
上海期货交易所-期权-日频行情数据
https://www.shfe.com.cn/reports/tradedata/dailyandweeklydata/
:param trade_date: 交易日
:type trade_date: str
:param symbol: choice of {'原油期权', '铜期权', '铝期权', '锌期权', '铅期权', '螺纹钢期权', '镍期权', '锡期权', '氧化铝期权',
'黄金期权', '白银期权', '丁二烯橡胶期权', '天胶期权'}
:type symbol: str
:return: 日频行情数据
:rtype: pandas.DataFrame
"""
calendar = get_calendar()
day = convert_date(trade_date) if trade_date is not None else datetime.date.today()
if day.strftime("%Y%m%d") not in calendar:
warnings.warn("%s非交易日" % day.strftime("%Y%m%d"))
return pd.DataFrame()
if day > datetime.date(year=2010, month=8, day=24):
url = f"""https://www.shfe.com.cn/data/tradedata/option/dailydata/kx{day.strftime("%Y%m%d")}.dat"""
try:
r = requests.get(url, headers=SHFE_HEADERS)
json_data = r.json()
table_df = pd.DataFrame(
[
row
for row in json_data["o_curinstrument"]
if row["INSTRUMENTID"] not in ["小计", "合计"]
and row["INSTRUMENTID"] != ""
]
)
contract_df = table_df[table_df["PRODUCTNAME"].str.strip() == symbol]
contract_df.rename(
columns={
"INSTRUMENTID": "合约代码",
"OPENPRICE": "开盘价",
"HIGHESTPRICE": "最高价",
"LOWESTPRICE": "最低价",
"CLOSEPRICE": "收盘价",
"PRESETTLEMENTPRICE": "前结算价",
"SETTLEMENTPRICE": "结算价",
"ZD1_CHG": "涨跌1",
"ZD2_CHG": "涨跌2",
"VOLUME": "成交量",
"OPENINTEREST": "持仓量",
"OPENINTERESTCHG": "持仓量变化",
"TURNOVER": "成交额",
"DELTA": "德尔塔",
"EXECVOLUME": "行权量",
},
inplace=True,
)
contract_df = contract_df[
[
"合约代码",
"开盘价",
"最高价",
"最低价",
"收盘价",
"前结算价",
"结算价",
"涨跌1",
"涨跌2",
"成交量",
"持仓量",
"持仓量变化",
"成交额",
"德尔塔",
"行权量",
]
]
contract_df.reset_index(inplace=True, drop=True)
return contract_df
except: # noqa: E722
return pd.DataFrame()
else:
return pd.DataFrame()
def option_vol_shfe(
symbol: str = "铝期权", trade_date: str = "20250418"
) -> pd.DataFrame:
"""
上海期货交易所-期权-日频行情数据
https://www.shfe.com.cn/reports/tradedata/dailyandweeklydata/
:param trade_date: 交易日
:type trade_date: str
:param symbol: choice of {'原油期权', '铜期权', '铝期权', '锌期权', '铅期权', '螺纹钢期权', '镍期权', '锡期权', '氧化铝期权',
'黄金期权', '白银期权', '丁二烯橡胶期权', '天胶期权'}
:type symbol: str
:return: 日频行情数据
:rtype: pandas.DataFrame
"""
calendar = get_calendar()
day = convert_date(trade_date) if trade_date is not None else datetime.date.today()
if day.strftime("%Y%m%d") not in calendar:
warnings.warn("%s非交易日" % day.strftime("%Y%m%d"))
return pd.DataFrame()
if day > datetime.date(year=2010, month=8, day=24):
url = f"""https://www.shfe.com.cn/data/tradedata/option/dailydata/kx{day.strftime("%Y%m%d")}.dat"""
try:
r = requests.get(url, headers=SHFE_HEADERS)
json_data = r.json()
volatility_df = pd.DataFrame(json_data["o_cursigma"])
volatility_df = volatility_df[
volatility_df["PRODUCTNAME"].str.strip() == symbol
]
volatility_df.rename(
columns={
"INSTRUMENTID": "合约系列",
"VOLUME": "成交量",
"OPENINTEREST": "持仓量",
"OPENINTERESTCHG": "持仓量变化",
"TURNOVER": "成交额",
"EXECVOLUME": "行权量",
"SIGMA": "隐含波动率",
},
inplace=True,
)
volatility_df = volatility_df[
[
"合约系列",
"成交量",
"持仓量",
"持仓量变化",
"成交额",
"行权量",
"隐含波动率",
]
]
volatility_df.reset_index(inplace=True, drop=True)
return volatility_df
except: # noqa: E722
return pd.DataFrame()
else:
return pd.DataFrame()
def option_hist_gfex(
symbol: str = "工业硅", trade_date: str = "20230724"
) -> pd.DataFrame:
"""
广州期货交易所-日频率-量价数据
http://www.gfex.com.cn/gfex/rihq/hqsj_tjsj.shtml
:param trade_date: 交易日
:type trade_date: str
:param symbol: choice of {"工业硅", "碳酸锂"}
:type symbol: str
:return: 日频行情数据
:rtype: pandas.DataFrame
"""
calendar = get_calendar()
day = convert_date(trade_date) if trade_date is not None else datetime.date.today()
if day.strftime("%Y%m%d") not in calendar:
warnings.warn("%s非交易日" % day.strftime("%Y%m%d"))
return pd.DataFrame()
url = "http://www.gfex.com.cn/u/interfacesWebTiDayQuotes/loadList"
payload = {"trade_date": day.strftime("%Y%m%d"), "trade_type": "1"}
headers = {
"Accept": "application/json, text/javascript, */*; q=0.01",
"Accept-Encoding": "gzip, deflate",
"Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8",
"Cache-Control": "no-cache",
"Content-Length": "32",
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
"Host": "www.gfex.com.cn",
"Origin": "http://www.gfex.com.cn",
"Pragma": "no-cache",
"Proxy-Connection": "keep-alive",
"Referer": "http://www.gfex.com.cn/gfex/rihq/hqsj_tjsj.shtml",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "
"Chrome/108.0.0.0 Safari/537.36",
"X-Requested-With": "XMLHttpRequest",
"content-type": "application/x-www-form-urlencoded",
}
r = requests.post(url, data=payload, headers=headers)
data_json = r.json()
temp_df = pd.DataFrame(data_json["data"])
temp_df.rename(
columns={
"variety": "商品名称",
"diffI": "持仓量变化",
"high": "最高价",
"turnover": "成交额",
"impliedVolatility": "隐含波动率",
"diff": "涨跌",
"delta": "Delta",
"close": "收盘价",
"diff1": "涨跌1",
"lastClear": "前结算价",
"open": "开盘价",
"matchQtySum": "行权量",
"delivMonth": "合约名称",
"low": "最低价",
"clearPrice": "结算价",
"varietyOrder": "品种代码",
"openInterest": "持仓量",
"volumn": "成交量",
},
inplace=True,
)
temp_df = temp_df[
[
"商品名称",
"合约名称",
"开盘价",
"最高价",
"最低价",
"收盘价",
"前结算价",
"结算价",
"涨跌",
"涨跌1",
"Delta",
"成交量",
"持仓量",
"持仓量变化",
"成交额",
"行权量",
"隐含波动率",
]
]
temp_df = temp_df[temp_df["商品名称"].str.contains(symbol)]
temp_df.reset_index(inplace=True, drop=True)
return temp_df
def option_vol_gfex(symbol: str = "碳酸锂", trade_date: str = "20230724"):
"""
广州期货交易所-日频率-合约隐含波动率
http://www.gfex.com.cn/gfex/rihq/hqsj_tjsj.shtml
:param symbol: choice of choice of {"工业硅", "碳酸锂"}
:type symbol: str
:param trade_date: 交易日
:type trade_date: str
:return: 日频行情数据
:rtype: pandas.DataFrame
"""
symbol_code_map = {
"工业硅": "si",
"碳酸锂": "lc",
"多晶硅": "ps",
}
calendar = get_calendar()
day = convert_date(trade_date) if trade_date is not None else datetime.date.today()
if day.strftime("%Y%m%d") not in calendar:
warnings.warn("%s非交易日" % day.strftime("%Y%m%d"))
return
url = "http://www.gfex.com.cn/u/interfacesWebTiDayQuotes/loadListOptVolatility"
payload = {"trade_date": day.strftime("%Y%m%d")}
headers = {
"Accept": "application/json, text/javascript, */*; q=0.01",
"Accept-Encoding": "gzip, deflate",
"Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8",
"Cache-Control": "no-cache",
"Content-Length": "32",
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
"Host": "www.gfex.com.cn",
"Origin": "http://www.gfex.com.cn",
"Pragma": "no-cache",
"Proxy-Connection": "keep-alive",
"Referer": "http://www.gfex.com.cn/gfex/rihq/hqsj_tjsj.shtml",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "
"Chrome/108.0.0.0 Safari/537.36",
"X-Requested-With": "XMLHttpRequest",
"content-type": "application/x-www-form-urlencoded",
}
r = requests.post(url, data=payload, headers=headers)
data_json = r.json()
temp_df = pd.DataFrame(data_json["data"])
temp_df.rename(
columns={
"seriesId": "合约系列",
"varietyId": "-",
"hisVolatility": "隐含波动率",
},
inplace=True,
)
temp_df = temp_df[
[
"合约系列",
"隐含波动率",
]
]
temp_df = temp_df[temp_df["合约系列"].str.contains(symbol_code_map[symbol])]
temp_df.reset_index(inplace=True, drop=True)
return temp_df
if __name__ == "__main__":
option_hist_czce_df = option_hist_czce(symbol="白糖期权", trade_date="20250812")
print(option_hist_czce_df)
option_hist_dce_df = option_hist_dce(symbol="聚丙烯期权", trade_date="20250812")
print(option_hist_dce_df)
option_hist_shfe_df = option_hist_shfe(symbol="天胶期权", trade_date="20250418")
print(option_hist_shfe_df)
option_vol_shfe_df = option_vol_shfe(symbol="天胶期权", trade_date="20250418")
print(option_vol_shfe_df)
option_hist_gfex_df = option_hist_gfex(symbol="工业硅", trade_date="20250801")
print(option_hist_gfex_df)
option_vol_gfex_df = option_vol_gfex(symbol="多晶硅", trade_date="20250123")
print(option_vol_gfex_df)
@@ -0,0 +1,177 @@
#!/usr/bin/env python
# -*- coding:utf-8 -*-
"""
Date: 2022/1/23 10:21
Desc: 新浪财经-商品期权
https://stock.finance.sina.com.cn/futures/view/optionsDP.php
"""
import pandas as pd
import requests
from bs4 import BeautifulSoup
from akshare.utils import demjson
def option_commodity_contract_sina(symbol: str = "玉米期权") -> pd.DataFrame:
"""
当前可以查询的期权品种的合约日期
https://stock.finance.sina.com.cn/futures/view/optionsDP.php
:param symbol: choice of {"豆粕期权", "玉米期权", "铁矿石期权", "棉花期权", "白糖期权", "PTA期权", "甲醇期权", "橡胶期权", "沪铜期权", "黄金期权", "菜籽粕期权", "液化石油气期权", "动力煤期权", "菜籽油期权", "花生期权"}
:type symbol: str
:return: e.g., {'黄金期权': ['au2012', 'au2008', 'au2010', 'au2104', 'au2102', 'au2106', 'au2108']}
:rtype: dict
"""
url = "https://stock.finance.sina.com.cn/futures/view/optionsDP.php/pg_o/dce"
r = requests.get(url)
soup = BeautifulSoup(r.text, "lxml")
url_list = [
item.find("a")["href"]
for item in soup.find_all("li", attrs={"class": "active"})
if item.find("a") is not None
]
commodity_list = [
item.find("a").text
for item in soup.find_all("li", attrs={"class": "active"})
if item.find("a") is not None
]
comm_list_dict = {key: value for key, value in zip(commodity_list, url_list)}
url = "https://stock.finance.sina.com.cn" + comm_list_dict[symbol]
r = requests.get(url)
soup = BeautifulSoup(r.text, "lxml")
symbol = (
soup.find(attrs={"id": "option_symbol"}).find(attrs={"class": "selected"}).text
)
contract = [
item.text for item in soup.find(attrs={"id": "option_suffix"}).find_all("li")
]
temp_df = pd.DataFrame({symbol: contract})
temp_df.reset_index(inplace=True)
temp_df["index"] = temp_df.index + 1
temp_df.columns = ["序号", "合约"]
return temp_df
def option_commodity_contract_table_sina(
symbol: str = "黄金期权", contract: str = "au2204"
) -> pd.DataFrame:
"""
当前所有期权合约, 包括看涨期权合约和看跌期权合约
https://stock.finance.sina.com.cn/futures/view/optionsDP.php
:param symbol: choice of {"豆粕期权", "玉米期权", "铁矿石期权", "棉花期权", "白糖期权", "PTA期权", "甲醇期权", "橡胶期权", "沪铜期权", "黄金期权", "菜籽粕期权", "液化石油气期权", "动力煤期权", "菜籽油期权", "花生期权"}
:type symbol: str
:param contract: e.g., 'au2012'
:type contract: str
:return: 合约实时行情
:rtype: pandas.DataFrame
"""
url = "https://stock.finance.sina.com.cn/futures/view/optionsDP.php/pg_o/dce"
r = requests.get(url)
soup = BeautifulSoup(r.text, "lxml")
url_list = [
item.find("a")["href"]
for item in soup.find_all("li", attrs={"class": "active"})
if item.find("a") is not None
]
commodity_list = [
item.find("a").text
for item in soup.find_all("li", attrs={"class": "active"})
if item.find("a") is not None
]
comm_list_dict = {key: value for key, value in zip(commodity_list, url_list)}
url = "https://stock.finance.sina.com.cn/futures/api/openapi.php/OptionService.getOptionData"
params = {
"type": "futures",
"product": comm_list_dict[symbol].split("/")[-2],
"exchange": comm_list_dict[symbol].split("/")[-1],
"pinzhong": contract,
}
r = requests.get(url, params=params)
data_json = r.json()
up_df = pd.DataFrame(data_json["result"]["data"]["up"])
down_df = pd.DataFrame(data_json["result"]["data"]["down"])
temp_df = pd.concat([up_df, down_df], axis=1)
temp_df.columns = [
"看涨合约-买量",
"看涨合约-买价",
"看涨合约-最新价",
"看涨合约-卖价",
"看涨合约-卖量",
"看涨合约-持仓量",
"看涨合约-涨跌",
"行权价",
"看涨合约-看涨期权合约",
"看跌合约-买量",
"看跌合约-买价",
"看跌合约-最新价",
"看跌合约-卖价",
"看跌合约-卖量",
"看跌合约-持仓量",
"看跌合约-涨跌",
"看跌合约-看跌期权合约",
]
temp_df["看涨合约-买量"] = pd.to_numeric(temp_df["看涨合约-买量"], errors="coerce")
temp_df["看涨合约-买价"] = pd.to_numeric(temp_df["看涨合约-买价"], errors="coerce")
temp_df["看涨合约-最新价"] = pd.to_numeric(
temp_df["看涨合约-最新价"], errors="coerce"
)
temp_df["看涨合约-卖价"] = pd.to_numeric(temp_df["看涨合约-卖价"], errors="coerce")
temp_df["看涨合约-卖量"] = pd.to_numeric(temp_df["看涨合约-卖量"], errors="coerce")
temp_df["看涨合约-持仓量"] = pd.to_numeric(
temp_df["看涨合约-持仓量"], errors="coerce"
)
temp_df["看涨合约-涨跌"] = pd.to_numeric(temp_df["看涨合约-涨跌"], errors="coerce")
temp_df["行权价"] = pd.to_numeric(temp_df["行权价"], errors="coerce")
temp_df["看跌合约-买量"] = pd.to_numeric(temp_df["看跌合约-买量"], errors="coerce")
temp_df["看跌合约-买价"] = pd.to_numeric(temp_df["看跌合约-买价"], errors="coerce")
temp_df["看跌合约-最新价"] = pd.to_numeric(
temp_df["看跌合约-最新价"], errors="coerce"
)
temp_df["看跌合约-卖价"] = pd.to_numeric(temp_df["看跌合约-卖价"], errors="coerce")
temp_df["看跌合约-卖量"] = pd.to_numeric(temp_df["看跌合约-卖量"], errors="coerce")
temp_df["看跌合约-持仓量"] = pd.to_numeric(
temp_df["看跌合约-持仓量"], errors="coerce"
)
temp_df["看跌合约-涨跌"] = pd.to_numeric(temp_df["看跌合约-涨跌"], errors="coerce")
return temp_df
def option_commodity_hist_sina(symbol: str = "au2012C392") -> pd.DataFrame:
"""
合约历史行情-日频
https://stock.finance.sina.com.cn/futures/view/optionsDP.php
:param symbol: return of option_sina_option_commodity_contract_list(symbol="黄金期权", contract="au2012"), 看涨期权合约 filed
:type symbol: str
:return: 合约历史行情-日频
:rtype: pandas.DataFrame
"""
url = "https://stock.finance.sina.com.cn/futures/api/jsonp.php/var%20_m2009C30002020_7_17=/FutureOptionAllService.getOptionDayline"
params = {"symbol": symbol}
r = requests.get(url, params=params)
data_text = r.text
data_json = demjson.decode(data_text[data_text.find("[") : -2])
temp_df = pd.DataFrame(data_json)
temp_df.columns = ["open", "high", "low", "close", "volume", "date"]
temp_df = temp_df[["date", "open", "high", "low", "close", "volume"]]
temp_df["date"] = pd.to_datetime(temp_df["date"]).dt.date
temp_df["open"] = pd.to_numeric(temp_df["open"])
temp_df["high"] = pd.to_numeric(temp_df["high"])
temp_df["low"] = pd.to_numeric(temp_df["low"])
temp_df["close"] = pd.to_numeric(temp_df["close"])
temp_df["volume"] = pd.to_numeric(temp_df["volume"])
return temp_df
if __name__ == "__main__":
option_commodity_contract_sina_df = option_commodity_contract_sina(
symbol="棉花期权"
)
print(option_commodity_contract_sina_df)
option_commodity_contract_table_sina_df = option_commodity_contract_table_sina(
symbol="棉花期权", contract="cf2301"
)
print(option_commodity_contract_table_sina_df)
option_commodity_hist_sina_df = option_commodity_hist_sina(symbol="cf2301P21600")
print(option_commodity_hist_sina_df)
@@ -0,0 +1,63 @@
#!/usr/bin/env python
# -*- coding:utf-8 -*-
"""
Date: 2025/10/30 17:40
Desc: openctp-合约信息接口
http://openctp.cn/instruments.html
"""
import pandas as pd
import requests
def option_contract_info_ctp() -> pd.DataFrame:
"""
openctp-合约信息接口-期权合约
http://openctp.cn/instruments.html
:return: 期权合约信息
:rtype: pandas.DataFrame
"""
url = "http://dict.openctp.cn/instruments?types=option"
r = requests.get(url)
data_json = r.json()
temp_df = pd.DataFrame(data_json["data"])
# 字段映射:英文字段名 -> 中文字段名
column_mapping = {
"ExchangeID": "交易所ID",
"InstrumentID": "合约ID",
"InstrumentName": "合约名称",
"ProductClass": "商品类别",
"ProductID": "品种ID",
"VolumeMultiple": "合约乘数",
"PriceTick": "最小变动价位",
"LongMarginRatioByMoney": "做多保证金率",
"ShortMarginRatioByMoney": "做空保证金率",
"LongMarginRatioByVolume": "做多保证金/手",
"ShortMarginRatioByVolume": "做空保证金/手",
"OpenRatioByMoney": "开仓手续费率",
"OpenRatioByVolume": "开仓手续费/手",
"CloseRatioByMoney": "平仓手续费率",
"CloseRatioByVolume": "平仓手续费/手",
"CloseTodayRatioByMoney": "平今手续费率",
"CloseTodayRatioByVolume": "平今手续费/手",
"DeliveryYear": "交割年份",
"DeliveryMonth": "交割月份",
"OpenDate": "上市日期",
"ExpireDate": "最后交易日",
"DeliveryDate": "交割日",
"UnderlyingInstrID": "标的合约ID",
"UnderlyingMultiple": "标的合约乘数",
"OptionsType": "期权类型",
"StrikePrice": "行权价",
"InstLifePhase": "合约状态",
}
# 重命名列为中文
temp_df = temp_df.rename(columns=column_mapping)
return temp_df
# 使用示例
if __name__ == "__main__":
option_contract_info_ctp_df = option_contract_info_ctp()
print(option_contract_info_ctp_df)
@@ -0,0 +1,61 @@
# -*- coding:utf-8 -*-
# !/usr/bin/env python
"""
Date: 2025/9/8 16:20
Desc: 上海证券交易所-产品-股票期权-信息披露-当日合约
http://www.sse.com.cn/assortment/options/disclo/preinfo/
"""
import pandas as pd
import requests
def option_current_day_sse() -> pd.DataFrame:
"""
上海证券交易所-产品-股票期权-信息披露-当日合约
http://www.sse.com.cn/assortment/options/disclo/preinfo/
:return: 上交所期权当日合约
:rtype: pandas.DataFrame
"""
url = "http://query.sse.com.cn/commonQuery.do"
params = {
"isPagination": "false",
"expireDate": "",
"securityId": "",
"sqlId": "SSE_ZQPZ_YSP_GGQQZSXT_XXPL_DRHY_SEARCH_L",
}
headers = {
"Accept": "*/*",
"Accept-Encoding": "gzip, deflate",
"Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8",
"Cache-Control": "no-cache",
"Connection": "keep-alive",
"Host": "query.sse.com.cn",
"Pragma": "no-cache",
"Referer": "http://www.sse.com.cn/",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "
"Chrome/101.0.4951.67 Safari/537.36",
}
r = requests.get(url, params=params, headers=headers)
data_json = r.json()
temp_df = pd.DataFrame(data_json["result"])
dict_df = {
"SECURITY_ID": "合约编码",
"CONTRACT_ID": "合约交易代码",
"CONTRACT_SYMBOL": "合约简称",
"SECURITYNAMEBYID": "标的券名称及代码",
"CALL_OR_PUT": "类型",
"EXERCISE_PRICE": "行权价",
"CONTRACT_UNIT": "合约单位",
"END_DATE": "期权行权日",
"DELIVERY_DATE": "行权交收日",
"EXPIRE_DATE": "到期日",
"START_DATE": "开始日期",
}
temp_df = temp_df[dict_df.keys()].rename(columns=dict_df)
return temp_df
if __name__ == "__main__":
option_current_day_sse_df = option_current_day_sse()
print(option_current_day_sse_df)
@@ -0,0 +1,100 @@
# -*- coding:utf-8 -*-
# !/usr/bin/env python
"""
Date: 2025/9/13 16:00
Desc: 深圳证券交易所-期权子网-行情数据-当日合约
"""
from io import BytesIO
import pandas as pd
import requests
def option_current_day_szse() -> pd.DataFrame:
"""
深圳证券交易所-期权子网-行情数据-当日合约
https://www.sse.org.cn/option/quotation/contract/daycontract/index.html
:return: 深圳期权当日合约
:rtype: pandas.DataFrame
"""
import warnings
warnings.filterwarnings(
action="ignore", message="Workbook contains no default style"
)
url = "https://www.sse.org.cn/api/report/ShowReport"
params = {
"SHOWTYPE": "xlsx",
"CATALOGID": "option_drhy",
"TABKEY": "tab1",
}
r = requests.get(url, params=params)
temp_df = pd.read_excel(BytesIO(r.content))
temp_df["序号"] = pd.to_numeric(temp_df["序号"], errors="coerce")
temp_df["行权价"] = pd.to_numeric(temp_df["行权价"], errors="coerce")
temp_df["合约单位"] = pd.to_numeric(temp_df["合约单位"], errors="coerce")
temp_df["涨停价格"] = pd.to_numeric(temp_df["涨停价格"], errors="coerce")
temp_df["跌停价格"] = pd.to_numeric(temp_df["跌停价格"], errors="coerce")
temp_df["前结算价"] = pd.to_numeric(temp_df["前结算价"], errors="coerce")
temp_df["合约总持仓"] = pd.to_numeric(temp_df["合约总持仓"], errors="coerce")
temp_df["原行权价格"] = pd.to_numeric(temp_df["原行权价格"], errors="coerce")
temp_df["原合约单位"] = pd.to_numeric(temp_df["原合约单位"], errors="coerce")
temp_df["合约到期剩余交易天数"] = pd.to_numeric(
temp_df["合约到期剩余交易天数"], errors="coerce"
)
temp_df["合约到期剩余自然天数"] = pd.to_numeric(
temp_df["合约到期剩余自然天数"], errors="coerce"
)
temp_df["下次合约调整剩余交易天数"] = pd.to_numeric(
temp_df["下次合约调整剩余交易天数"], errors="coerce"
)
temp_df["下次合约调整剩余自然天数"] = pd.to_numeric(
temp_df["下次合约调整剩余自然天数"], errors="coerce"
)
temp_df["交易日期"] = pd.to_datetime(temp_df["交易日期"], errors="coerce").dt.date
temp_df["最后交易日"] = pd.to_datetime(
temp_df["最后交易日"], errors="coerce"
).dt.date
temp_df["行权日"] = pd.to_datetime(temp_df["行权日"], errors="coerce").dt.date
temp_df["到期日"] = pd.to_datetime(temp_df["到期日"], errors="coerce").dt.date
temp_df["交收日"] = pd.to_datetime(temp_df["交收日"], errors="coerce").dt.date
temp_df = temp_df[
[
"序号",
"合约编码",
"合约代码",
"合约简称",
"标的证券简称(代码)",
"合约类型",
"行权价",
"合约单位",
"最后交易日",
"行权日",
"到期日",
"交收日",
"新挂",
"涨停价格",
"跌停价格",
"前结算价",
"合约调整",
"停牌",
"合约总持仓",
"挂牌原因",
"原合约代码",
"原合约简称",
"原行权价格",
"原合约单位",
"合约到期剩余交易天数",
"合约到期剩余自然天数",
"下次合约调整剩余交易天数",
"下次合约调整剩余自然天数",
"交易日期",
]
]
return temp_df
if __name__ == "__main__":
option_current_day_szse_df = option_current_day_szse()
print(option_current_day_szse_df)
@@ -0,0 +1,82 @@
#!/usr/bin/env python
# -*- coding:utf-8 -*-
"""
Date: 2025/10/17 16:30
Desc: 郑州商品交易所-交易数据-历史行情下载-期权历史行情下载
http://www.czce.com.cn/cn/jysj/lshqxz/H770319index_1.htm
自 20200101 起,成交量、空盘量、成交额、行权量均为单边计算
郑州商品交易所-期权上市时间表
"SR": "20170419"
"CF": "20190410"
"TA": "20191216"
"MA": "20191217"
"RM": "20200116"
"ZC": "20200630"
"OI": "20220826"
"PK": "20220826"
"PX": "20230915"
"SH": "20230915"
"SA": "20231020"
"PF": "20231020"
"SM": "20231020"
"SF": "20231020"
"UR": "20231020"
"AP": "20231020"
"CJ": "20240621"
"FG": "20240621"
"PR": "20241227"
"""
import warnings
from io import StringIO
import pandas as pd
import requests
def option_hist_yearly_czce(symbol: str = "SR", year: str = "2021") -> pd.DataFrame:
"""
郑州商品交易所-交易数据-历史行情下载-期权历史行情下载
http://www.czce.com.cn/cn/jysj/lshqxz/H770319index_1.htm
:param symbol: choice of {"白糖": "SR", "棉花": "CF", "PTA": "TA", "甲醇": "MA", "菜籽粕": "RM",
"动力煤": "ZC", "菜籽油": "OI", "花生": "PK", "对二甲苯": "PX", "烧碱": "SH", "纯碱": "SA", "短纤": "PF",
"锰硅": "SM", "硅铁": "SF", "尿素": "UR", "苹果": "AP", "红枣": "CJ", "玻璃": "FG", "瓶片": "PR"}
:type symbol: str
:param year: 需要获取数据的年份, 注意品种的上市时间
:type year: str
:return: 指定年份的日频期权数据
:rtype: pandas.DataFrame
"""
symbol_year_dict = {
"SR": "2017",
"CF": "2019",
"TA": "2019",
"MA": "2019",
"RM": "2020",
"ZC": "2020",
"OI": "2022",
"PK": "2022",
"PX": "2023",
"SH": "2023",
"SA": "2023",
"PF": "2023",
"SM": "2023",
"SF": "2023",
"UR": "2023",
"AP": "2023",
"CJ": "2024",
"FG": "2024",
"PR": "2024",
}
if int(symbol_year_dict[symbol]) > int(year):
warnings.warn(f"{year} year, symbol {symbol} is not on trade")
return pd.DataFrame()
url = f"http://www.czce.com.cn/cn/DFSStaticFiles/Option/{year}/OptionDataAllHistory/{symbol}OPTIONS{year}.txt"
r = requests.get(url)
option_df = pd.read_table(StringIO(r.text), skiprows=1, sep="|", low_memory=False)
return option_df
if __name__ == "__main__":
option_hist_yearly_czce_df = option_hist_yearly_czce(symbol="RM", year="2025")
print(option_hist_yearly_czce_df)
@@ -0,0 +1,145 @@
# -*- coding:utf-8 -*-
# !/usr/bin/env python
"""
Date: 2024/6/27 22:20
Desc: 上海证券交易所-产品-股票期权-每日统计
https://www.sse.com.cn/assortment/options/date/
深圳证券交易所-市场数据-期权数据-日度概况
https://investor.szse.cn/market/option/day/index.html
"""
import pandas as pd
import requests
def option_daily_stats_sse(date: str = "20240626") -> pd.DataFrame:
"""
上海证券交易所-产品-股票期权-每日统计
https://www.sse.com.cn/assortment/options/date/
:param date: 交易日
:type date: str
:return: 每日统计
:rtype: pandas.DataFrame
"""
url = "http://query.sse.com.cn/commonQuery.do"
params = {
"isPagination": "false",
"sqlId": "COMMON_SSE_ZQPZ_YSP_QQ_SJTJ_MRTJ_CX",
"tradeDate": date,
}
headers = {
"Accept": "*/*",
"Accept-Encoding": "gzip, deflate",
"Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8",
"Cache-Control": "no-cache",
"Connection": "keep-alive",
"Host": "query.sse.com.cn",
"Pragma": "no-cache",
"Referer": "https://www.sse.com.cn/",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "
"Chrome/101.0.4951.67 Safari/537.36",
}
r = requests.get(url, params=params, headers=headers)
data_json = r.json()
temp_df = pd.DataFrame(data_json["result"])
temp_df.rename(
columns={
"CONTRACT_VOLUME": "合约数量",
"CALL_VOLUME": "认购成交量",
"LEAVES_QTY": "未平仓合约总数",
"CP_RATE": "认沽/认购",
"PUT_VOLUME": "认沽成交量",
"TRADE_DATE": "交易日",
"TOTAL_MONEY": "总成交额",
"TOTAL_VOLUME": "总成交量",
"SECURITY_CODE": "合约标的代码",
"LEAVES_CALL_QTY": "未平仓认购合约数",
"LEAVES_PUT_QTY": "未平仓认沽合约数",
"SECURITY_ABBR": "合约标的名称",
},
inplace=True,
)
temp_df = temp_df[
[
"合约标的代码",
"合约标的名称",
"合约数量",
"总成交额",
"总成交量",
"认购成交量",
"认沽成交量",
"认沽/认购",
"未平仓合约总数",
"未平仓认购合约数",
"未平仓认沽合约数",
"交易日",
]
]
temp_df["交易日"] = pd.to_datetime(temp_df["交易日"], errors="coerce").dt.date
for item in temp_df.columns[2:-1]:
temp_df[item] = temp_df[item].str.replace(",", "")
temp_df[item] = pd.to_numeric(temp_df[item], errors="coerce")
return temp_df
def option_daily_stats_szse(date: str = "20240626") -> pd.DataFrame:
"""
深圳证券交易所-市场数据-期权数据-日度概况
https://investor.szse.cn/market/option/day/index.html
:param date: 交易日
:type date: str
:return: 每日统计
:rtype: pandas.DataFrame
"""
url = "https://investor.szse.cn/api/report/ShowReport/data"
params = {
"SHOWTYPE": "JSON",
"CATALOGID": "ysprdzb",
"TABKEY": "tab1",
"txtQueryDate": "-".join([date[:4], date[4:6], date[6:]]),
"random": "0.0652692406565949",
}
r = requests.get(url, params=params)
data_json = r.json()
temp_df = pd.DataFrame(data_json[0]["data"])
temp_df.rename(
columns={
"bddm": "合约标的代码",
"bdmc": "合约标的名称",
"cjl": "成交量",
"rccjl": "认购成交量",
"rpcjl": "认沽成交量",
"rcrpccb": "认沽/认购持仓比",
"wpchyzs": "未平仓合约总数",
"wpcrchys": "未平仓认购合约数",
"wpcrphys": "未平仓认沽合约数",
},
inplace=True,
)
temp_df = temp_df[
[
"合约标的代码",
"合约标的名称",
"成交量",
"认购成交量",
"认沽成交量",
"认沽/认购持仓比",
"未平仓合约总数",
"未平仓认购合约数",
"未平仓认沽合约数",
]
]
temp_df["交易日"] = "-".join([date[:4], date[4:6], date[6:]])
temp_df["交易日"] = pd.to_datetime(temp_df["交易日"], errors="coerce").dt.date
for item in temp_df.columns[2:-1]:
temp_df[item] = temp_df[item].str.replace(",", "")
temp_df[item] = pd.to_numeric(temp_df[item], errors="coerce")
return temp_df
if __name__ == "__main__":
option_daily_stats_sse_df = option_daily_stats_sse(date="20240626")
print(option_daily_stats_sse_df)
option_daily_stats_szse_df = option_daily_stats_szse(date="20240626")
print(option_daily_stats_szse_df)
@@ -0,0 +1,188 @@
#!/usr/bin/env python
# -*- coding:utf-8 -*-
"""
Date: 2025/2/18 16:30
Desc: 东方财富网-行情中心-期权市场
https://quote.eastmoney.com/center/qqsc.html
"""
import pandas as pd
import requests
from akshare.utils.func import fetch_paginated_data
def option_current_em() -> pd.DataFrame:
"""
东方财富网-行情中心-期权市场
https://quote.eastmoney.com/center/qqsc.html
:return: 期权价格
:rtype: pandas.DataFrame
"""
url = "https://23.push2.eastmoney.com/api/qt/clist/get"
params = {
"pn": "1",
"pz": "100",
"po": "1",
"np": "1",
"ut": "bd1d9ddb04089700cf9c27f6f7426281",
"fltt": "2",
"invt": "2",
"fid": "f3",
"fs": "m:10,m:12,m:140,m:141,m:151,m:163,m:226",
"fields": "f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f12,f13,f14,f15,f16,f17,f18,f20,f21,"
"f23,f24,f25,f22,f28,f11,f62,f128,f136,f115,f152,f133,f108,f163,f161,f162",
}
temp_df = fetch_paginated_data(url=url, base_params=params)
temp_df.columns = [
"序号",
"_",
"最新价",
"涨跌幅",
"涨跌额",
"成交量",
"成交额",
"_",
"_",
"_",
"_",
"_",
"代码",
"市场标识",
"名称",
"_",
"_",
"今开",
"_",
"_",
"_",
"_",
"_",
"_",
"_",
"昨结",
"_",
"持仓量",
"_",
"_",
"_",
"_",
"_",
"_",
"_",
"行权价",
"剩余日",
"日增",
]
temp_df = temp_df[
[
"序号",
"代码",
"名称",
"最新价",
"涨跌额",
"涨跌幅",
"成交量",
"成交额",
"持仓量",
"行权价",
"剩余日",
"日增",
"昨结",
"今开",
"市场标识",
]
]
temp_df["最新价"] = pd.to_numeric(temp_df["最新价"], errors="coerce")
temp_df["涨跌额"] = pd.to_numeric(temp_df["涨跌额"], errors="coerce")
temp_df["涨跌幅"] = pd.to_numeric(temp_df["涨跌幅"], errors="coerce")
temp_df["成交量"] = pd.to_numeric(temp_df["成交量"], errors="coerce")
temp_df["成交额"] = pd.to_numeric(temp_df["成交额"], errors="coerce")
temp_df["持仓量"] = pd.to_numeric(temp_df["持仓量"], errors="coerce")
temp_df["行权价"] = pd.to_numeric(temp_df["行权价"], errors="coerce")
temp_df["剩余日"] = pd.to_numeric(temp_df["剩余日"], errors="coerce")
temp_df["日增"] = pd.to_numeric(temp_df["日增"], errors="coerce")
temp_df["昨结"] = pd.to_numeric(temp_df["昨结"], errors="coerce")
temp_df["今开"] = pd.to_numeric(temp_df["今开"], errors="coerce")
option_current_cffex_em_df = option_current_cffex_em()
big_df = pd.concat(objs=[temp_df, option_current_cffex_em_df], ignore_index=True)
big_df["序号"] = range(1, len(big_df) + 1)
return big_df
def option_current_cffex_em() -> pd.DataFrame:
url = "https://futsseapi.eastmoney.com/list/option/221"
params = {
"orderBy": "zdf",
"sort": "desc",
"pageSize": "20000",
"pageIndex": "0",
"token": "58b2fa8f54638b60b87d69b31969089c",
"field": "dm,sc,name,p,zsjd,zde,zdf,f152,vol,cje,ccl,xqj,syr,rz,zjsj,o",
"blockName": "callback",
"_:": "1706689899924",
}
r = requests.get(url, params=params)
data_json = r.json()
temp_df = pd.DataFrame(data_json["list"])
temp_df.reset_index(inplace=True)
temp_df["index"] = temp_df["index"] + 1
temp_df.rename(
columns={
"index": "序号",
"rz": "日增",
"dm": "代码",
"zsjd": "-",
"ccl": "持仓量",
"syr": "剩余日",
"o": "今开",
"p": "最新价",
"sc": "市场标识",
"xqj": "行权价",
"vol": "成交量",
"name": "名称",
"zde": "涨跌额",
"zdf": "涨跌幅",
"zjsj": "昨结",
"cje": "成交额",
},
inplace=True,
)
temp_df = temp_df[
[
"序号",
"代码",
"名称",
"最新价",
"涨跌额",
"涨跌幅",
"成交量",
"成交额",
"持仓量",
"行权价",
"剩余日",
"日增",
"昨结",
"今开",
"市场标识",
]
]
temp_df["最新价"] = pd.to_numeric(temp_df["最新价"], errors="coerce")
temp_df["涨跌额"] = pd.to_numeric(temp_df["涨跌额"], errors="coerce")
temp_df["涨跌幅"] = pd.to_numeric(temp_df["涨跌幅"], errors="coerce")
temp_df["成交量"] = pd.to_numeric(temp_df["成交量"], errors="coerce")
temp_df["成交额"] = pd.to_numeric(temp_df["成交额"], errors="coerce")
temp_df["持仓量"] = pd.to_numeric(temp_df["持仓量"], errors="coerce")
temp_df["行权价"] = pd.to_numeric(temp_df["行权价"], errors="coerce")
temp_df["剩余日"] = pd.to_numeric(temp_df["剩余日"], errors="coerce")
temp_df["日增"] = pd.to_numeric(temp_df["日增"], errors="coerce")
temp_df["昨结"] = pd.to_numeric(temp_df["昨结"], errors="coerce")
temp_df["今开"] = pd.to_numeric(temp_df["今开"], errors="coerce")
return temp_df
if __name__ == "__main__":
option_current_em_df = option_current_em()
print(option_current_em_df)
option_current_cffex_em_df = option_current_cffex_em()
print(option_current_cffex_em_df)
@@ -0,0 +1,358 @@
#!/usr/bin/env python
# -*- coding:utf-8 -*-
"""
Date: 2024/2/24 15:18
Desc: 金融期权数据
http://www.sse.com.cn/assortment/options/price/
http://www.szse.cn/market/product/option/index.html
http://www.cffex.com.cn/hs300gzqq/
http://www.cffex.com.cn/zz1000gzqq/
"""
from io import BytesIO
import pandas as pd
import requests
from akshare.option.cons import (
SH_OPTION_PAYLOAD,
SH_OPTION_PAYLOAD_OTHER,
SH_OPTION_URL_50,
SH_OPTION_URL_KING_50,
SH_OPTION_URL_300,
SH_OPTION_URL_KING_300,
SH_OPTION_URL_500,
SH_OPTION_URL_KING_500,
SH_OPTION_URL_KC_50,
SH_OPTION_URL_KC_KING_50,
SH_OPTION_URL_KC_50_YFD,
SH_OPTION_URL_KING_50_YFD,
CFFEX_OPTION_URL_300,
)
def option_finance_sse_underlying(symbol: str = "华夏科创50ETF期权") -> pd.DataFrame:
"""
期权标的当日行情
http://www.sse.com.cn/assortment/options/price/
:param symbol: choice of {"华夏上证50ETF期权", "华泰柏瑞沪深300ETF期权", "南方中证500ETF期权", "华夏科创50ETF期权", "易方达科创50ETF期权"}
:type symbol: str
:return: 期权标的当日行情
:rtype: pandas.DataFrame
"""
symbol_map = {
"华夏上证50ETF期权": SH_OPTION_URL_50,
"华泰柏瑞沪深300ETF期权": SH_OPTION_URL_300,
"南方中证500ETF期权": SH_OPTION_URL_500,
"华夏科创50ETF期权": SH_OPTION_URL_KC_50,
"易方达科创50ETF期权": SH_OPTION_URL_KC_50_YFD,
}
r = requests.get(symbol_map[symbol], params=SH_OPTION_PAYLOAD)
data_json = r.json()
raw_data = pd.DataFrame(data_json["list"])
raw_data.at[0, 0] = "510300"
raw_data.at[0, 8] = pd.to_datetime(
str(data_json["date"]) + str(data_json["time"]),
format="%Y%m%d%H%M%S",
)
raw_data.columns = [
"代码",
"名称",
"当前价",
"涨跌",
"涨跌幅",
"振幅",
"成交量(手)",
"成交额(万元)",
"更新日期",
]
return raw_data
def option_finance_board(
symbol: str = "嘉实沪深300ETF期权", end_month: str = "2306"
) -> pd.DataFrame:
"""
期权当前交易日的行情数据
主要为三个: 华夏上证50ETF期权, 华泰柏瑞沪深300ETF期权, 嘉实沪深300ETF期权,
沪深300股指期权, 中证1000股指期权, 上证50股指期权, 华夏科创50ETF期权, 易方达科创50ETF期权
http://www.sse.com.cn/assortment/options/price/
http://www.szse.cn/market/product/option/index.html
http://www.cffex.com.cn/hs300gzqq/
http://www.cffex.com.cn/zz1000gzqq/
:param symbol: choice of {"华夏上证50ETF期权", "华泰柏瑞沪深300ETF期权", "南方中证500ETF期权",
"华夏科创50ETF期权", "易方达科创50ETF期权", "嘉实沪深300ETF期权", "沪深300股指期权", "中证1000股指期权", "上证50股指期权"}
:type symbol: str
:param end_month: 2003; 2020 年 3 月到期的期权
:type end_month: str
:return: 当日行情
:rtype: pandas.DataFrame
"""
end_month = end_month[-2:]
if symbol == "华夏上证50ETF期权":
r = requests.get(
SH_OPTION_URL_KING_50.format(end_month),
params=SH_OPTION_PAYLOAD_OTHER,
)
data_json = r.json()
raw_data = pd.DataFrame(data_json["list"])
raw_data.index = [str(data_json["date"]) + str(data_json["time"])] * data_json[
"total"
]
raw_data.columns = ["合约交易代码", "当前价", "涨跌幅", "前结价", "行权价"]
raw_data["数量"] = [data_json["total"]] * data_json["total"]
raw_data.reset_index(inplace=True)
raw_data.columns = [
"日期",
"合约交易代码",
"当前价",
"涨跌幅",
"前结价",
"行权价",
"数量",
]
return raw_data
elif symbol == "华泰柏瑞沪深300ETF期权":
r = requests.get(
SH_OPTION_URL_KING_300.format(end_month),
params=SH_OPTION_PAYLOAD_OTHER,
)
data_json = r.json()
raw_data = pd.DataFrame(data_json["list"])
raw_data.index = [str(data_json["date"]) + str(data_json["time"])] * data_json[
"total"
]
raw_data.columns = ["合约交易代码", "当前价", "涨跌幅", "前结价", "行权价"]
raw_data["数量"] = [data_json["total"]] * data_json["total"]
raw_data.reset_index(inplace=True)
raw_data.columns = [
"日期",
"合约交易代码",
"当前价",
"涨跌幅",
"前结价",
"行权价",
"数量",
]
return raw_data
elif symbol == "南方中证500ETF期权":
r = requests.get(
SH_OPTION_URL_KING_500.format(end_month),
params=SH_OPTION_PAYLOAD_OTHER,
)
data_json = r.json()
raw_data = pd.DataFrame(data_json["list"])
raw_data.index = [str(data_json["date"]) + str(data_json["time"])] * data_json[
"total"
]
raw_data.columns = ["合约交易代码", "当前价", "涨跌幅", "前结价", "行权价"]
raw_data["数量"] = [data_json["total"]] * data_json["total"]
raw_data.reset_index(inplace=True)
raw_data.columns = [
"日期",
"合约交易代码",
"当前价",
"涨跌幅",
"前结价",
"行权价",
"数量",
]
return raw_data
elif symbol == "华夏科创50ETF期权":
r = requests.get(
SH_OPTION_URL_KC_KING_50.format(end_month),
params=SH_OPTION_PAYLOAD_OTHER,
)
data_json = r.json()
raw_data = pd.DataFrame(data_json["list"])
raw_data.index = [str(data_json["date"]) + str(data_json["time"])] * data_json[
"total"
]
raw_data.columns = ["合约交易代码", "当前价", "涨跌幅", "前结价", "行权价"]
raw_data["数量"] = [data_json["total"]] * data_json["total"]
raw_data.reset_index(inplace=True)
raw_data.columns = [
"日期",
"合约交易代码",
"当前价",
"涨跌幅",
"前结价",
"行权价",
"数量",
]
return raw_data
elif symbol == "易方达科创50ETF期权":
r = requests.get(
SH_OPTION_URL_KING_50_YFD.format(end_month),
params=SH_OPTION_PAYLOAD_OTHER,
)
data_json = r.json()
raw_data = pd.DataFrame(data_json["list"])
raw_data.index = [str(data_json["date"]) + str(data_json["time"])] * data_json[
"total"
]
raw_data.columns = ["合约交易代码", "当前价", "涨跌幅", "前结价", "行权价"]
raw_data["数量"] = [data_json["total"]] * data_json["total"]
raw_data.reset_index(inplace=True)
raw_data.columns = [
"日期",
"合约交易代码",
"当前价",
"涨跌幅",
"前结价",
"行权价",
"数量",
]
return raw_data
elif symbol == "嘉实沪深300ETF期权":
url = "http://www.szse.cn/api/report/ShowReport/data"
params = {
"SHOWTYPE": "JSON",
"CATALOGID": "ysplbrb",
"TABKEY": "tab1",
"PAGENO": "1",
"random": "0.10642298535346595",
}
r = requests.get(url, params=params)
data_json = r.json()
page_num = data_json[0]["metadata"]["pagecount"]
big_df = pd.DataFrame()
for page in range(1, page_num + 1):
params = {
"SHOWTYPE": "JSON",
"CATALOGID": "ysplbrb",
"TABKEY": "tab1",
"PAGENO": page,
"random": "0.10642298535346595",
}
r = requests.get(url, params=params)
data_json = r.json()
temp_df = pd.DataFrame(data_json[0]["data"])
big_df = pd.concat([big_df, temp_df], ignore_index=True)
big_df.columns = [
"合约编码",
"合约简称",
"标的名称",
"类型",
"行权价",
"合约单位",
"期权行权日",
"行权交收日",
]
big_df["期权行权日"] = pd.to_datetime(big_df["期权行权日"])
big_df["end_month"] = big_df["期权行权日"].dt.month.astype(str).str.zfill(2)
big_df = big_df[big_df["end_month"] == end_month]
del big_df["end_month"]
big_df.reset_index(inplace=True, drop=True)
return big_df
elif symbol == "沪深300股指期权":
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36"
}
r = requests.get(CFFEX_OPTION_URL_300, headers=headers)
raw_df = pd.read_table(BytesIO(r.content), sep=",")
raw_df["end_month"] = (
raw_df["instrument"]
.str.split("-", expand=True)
.iloc[:, 0]
.str.slice(
4,
)
)
raw_df = raw_df[raw_df["end_month"] == end_month]
del raw_df["end_month"]
raw_df.reset_index(inplace=True, drop=True)
return raw_df
elif symbol == "中证1000股指期权":
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36"
}
url = "http://www.cffex.com.cn/quote_MO.txt"
r = requests.get(url, headers=headers)
raw_df = pd.read_table(BytesIO(r.content), sep=",")
raw_df["end_month"] = (
raw_df["instrument"]
.str.split("-", expand=True)
.iloc[:, 0]
.str.slice(
4,
)
)
raw_df = raw_df[raw_df["end_month"] == end_month]
del raw_df["end_month"]
raw_df.reset_index(inplace=True, drop=True)
return raw_df
elif symbol == "上证50股指期权":
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36"
}
url = "http://www.cffex.com.cn/quote_HO.txt"
r = requests.get(url, headers=headers)
raw_df = pd.read_table(BytesIO(r.content), sep=",")
raw_df["end_month"] = (
raw_df["instrument"]
.str.split("-", expand=True)
.iloc[:, 0]
.str.slice(
4,
)
)
raw_df = raw_df[raw_df["end_month"] == end_month]
del raw_df["end_month"]
raw_df.reset_index(inplace=True, drop=True)
return raw_df
else:
return pd.DataFrame()
if __name__ == "__main__":
option_finance_sse_underlying_df = option_finance_sse_underlying(
symbol="华夏科创50ETF期权"
)
print(option_finance_sse_underlying_df)
option_finance_board_df = option_finance_board(
symbol="华夏上证50ETF期权", end_month="2306"
)
print(option_finance_board_df)
option_finance_board_df = option_finance_board(
symbol="华泰柏瑞沪深300ETF期权", end_month="2306"
)
print(option_finance_board_df)
option_finance_board_df = option_finance_board(
symbol="南方中证500ETF期权", end_month="2306"
)
print(option_finance_board_df)
option_finance_board_df = option_finance_board(
symbol="华夏科创50ETF期权", end_month="2306"
)
print(option_finance_board_df)
option_finance_board_df = option_finance_board(
symbol="易方达科创50ETF期权", end_month="2306"
)
print(option_finance_board_df)
option_finance_board_df = option_finance_board(
symbol="嘉实沪深300ETF期权", end_month="2306"
)
print(option_finance_board_df)
option_finance_board_df = option_finance_board(
symbol="沪深300股指期权", end_month="2306"
)
print(option_finance_board_df)
option_finance_board_df = option_finance_board(
symbol="中证1000股指期权", end_month="2306"
)
print(option_finance_board_df)
option_finance_board_df = option_finance_board(
symbol="上证50股指期权", end_month="2306"
)
print(option_finance_board_df)
@@ -0,0 +1,979 @@
#!/usr/bin/env python
"""
Date: 2024/6/21 18:00
Desc: 新浪财经-股票期权
https://stock.finance.sina.com.cn/option/quotes.html
期权-中金所-沪深 300 指数
https://stock.finance.sina.com.cn/futures/view/optionsCffexDP.php
期权-上交所-50ETF
期权-上交所-300ETF
期权-上交所-500ETF
https://stock.finance.sina.com.cn/option/quotes.html
"""
import datetime
import json
from functools import lru_cache
from typing import Dict, List, Tuple
import pandas as pd
import requests
from bs4 import BeautifulSoup
from akshare.option.option_em import option_current_em
from akshare.utils.func import set_df_columns
# 期权-中金所-上证50指数
def option_cffex_sz50_list_sina() -> Dict[str, List[str]]:
"""
新浪财经-中金所-上证 50 指数-所有合约, 返回的第一个合约为主力合约
目前新浪财经-中金所有上证 50 指数,沪深 300 指数和中证 1000 指数
:return: 中金所-上证 50 指数-所有合约
:rtype: dict
"""
url = "https://stock.finance.sina.com.cn/futures/view/optionsCffexDP.php/ho/cffex"
r = requests.get(url)
soup = BeautifulSoup(r.text, features="lxml")
symbol = soup.find(attrs={"id": "option_symbol"}).find_all("li")[0].text
temp_attr = soup.find(attrs={"id": "option_suffix"}).find_all("li")
contract = [item.text for item in temp_attr]
return {symbol: contract}
# 期权-中金所-沪深300指数
def option_cffex_hs300_list_sina() -> Dict[str, List[str]]:
"""
新浪财经-中金所-沪深 300 指数-所有合约, 返回的第一个合约为主力合约
目前新浪财经-中金所有沪深 300 指数和中证 1000 指数
:return: 中金所-沪深300指数-所有合约
:rtype: dict
"""
url = "https://stock.finance.sina.com.cn/futures/view/optionsCffexDP.php"
r = requests.get(url)
soup = BeautifulSoup(r.text, features="lxml")
symbol = soup.find(attrs={"id": "option_symbol"}).find_all("li")[1].text
temp_attr = soup.find(attrs={"id": "option_suffix"}).find_all("li")
contract = [item.text for item in temp_attr]
return {symbol: contract}
def option_cffex_zz1000_list_sina() -> Dict[str, List[str]]:
"""
新浪财经-中金所-中证 1000 指数-所有合约, 返回的第一个合约为主力合约
目前新浪财经-中金所有沪深 300 指数和中证 1000 指数
:return: 中金所-中证 1000 指数-所有合约
:rtype: dict
"""
url = "https://stock.finance.sina.com.cn/futures/view/optionsCffexDP.php/mo/cffex"
r = requests.get(url)
soup = BeautifulSoup(r.text, features="lxml")
symbol = soup.find(attrs={"id": "option_symbol"}).find_all("li")[2].text
temp_attr = soup.find(attrs={"id": "option_suffix"}).find_all("li")
contract = [item.text for item in temp_attr]
return {symbol: contract}
def option_cffex_sz50_spot_sina(symbol: str = "ho2303") -> pd.DataFrame:
"""
中金所-上证 50 指数-指定合约-实时行情
https://stock.finance.sina.com.cn/futures/view/optionsCffexDP.php/ho/cffex
:param symbol: 合约代码; 用 ak.option_cffex_sz300_list_sina() 函数查看
:type symbol: str
:return: 中金所-上证 50 指数-指定合约-看涨看跌实时行情
:rtype: pandas.DataFrame
"""
url = "https://stock.finance.sina.com.cn/futures/api/openapi.php/OptionService.getOptionData"
params = {
"type": "futures",
"product": "ho",
"exchange": "cffex",
"pinzhong": symbol,
}
r = requests.get(url, params=params)
data_text = r.text
data_json = json.loads(data_text[data_text.find("{") : data_text.rfind("}") + 1])
option_call_df = pd.DataFrame(
data_json["result"]["data"]["up"],
columns=[
"看涨合约-买量",
"看涨合约-买价",
"看涨合约-最新价",
"看涨合约-卖价",
"看涨合约-卖量",
"看涨合约-持仓量",
"看涨合约-涨跌",
"行权价",
"看涨合约-标识",
],
)
option_put_df = pd.DataFrame(
data_json["result"]["data"]["down"],
columns=[
"看跌合约-买量",
"看跌合约-买价",
"看跌合约-最新价",
"看跌合约-卖价",
"看跌合约-卖量",
"看跌合约-持仓量",
"看跌合约-涨跌",
"看跌合约-标识",
],
)
data_df = pd.concat(objs=[option_call_df, option_put_df], axis=1)
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["看跌合约-买价"] = 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")
return data_df
def option_cffex_hs300_spot_sina(symbol: str = "io2204") -> pd.DataFrame:
"""
中金所-沪深 300 指数-指定合约-实时行情
https://stock.finance.sina.com.cn/futures/view/optionsCffexDP.php
:param symbol: 合约代码; 用 option_cffex_hs300_list_sina 函数查看
:type symbol: str
:return: 中金所-沪深300指数-指定合约-看涨看跌实时行情
:rtype: pandas.DataFrame
"""
url = "https://stock.finance.sina.com.cn/futures/api/openapi.php/OptionService.getOptionData"
params = {
"type": "futures",
"product": "io",
"exchange": "cffex",
"pinzhong": symbol,
}
r = requests.get(url, params=params)
data_text = r.text
data_json = json.loads(data_text[data_text.find("{") : data_text.rfind("}") + 1])
option_call_df = pd.DataFrame(
data_json["result"]["data"]["up"],
columns=[
"看涨合约-买量",
"看涨合约-买价",
"看涨合约-最新价",
"看涨合约-卖价",
"看涨合约-卖量",
"看涨合约-持仓量",
"看涨合约-涨跌",
"行权价",
"看涨合约-标识",
],
)
option_put_df = pd.DataFrame(
data_json["result"]["data"]["down"],
columns=[
"看跌合约-买量",
"看跌合约-买价",
"看跌合约-最新价",
"看跌合约-卖价",
"看跌合约-卖量",
"看跌合约-持仓量",
"看跌合约-涨跌",
"看跌合约-标识",
],
)
data_df = pd.concat(objs=[option_call_df, option_put_df], axis=1)
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["看跌合约-买价"] = 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")
return data_df
def option_cffex_zz1000_spot_sina(symbol: str = "mo2208") -> pd.DataFrame:
"""
中金所-中证 1000 指数-指定合约-实时行情
https://stock.finance.sina.com.cn/futures/view/optionsCffexDP.php
:param symbol: 合约代码; 用 option_cffex_zz1000_list_sina 函数查看
:type symbol: str
:return: 中金所-中证 1000 指数-指定合约-看涨看跌实时行情
:rtype: pandas.DataFrame
"""
url = "https://stock.finance.sina.com.cn/futures/api/openapi.php/OptionService.getOptionData"
params = {
"type": "futures",
"product": "mo",
"exchange": "cffex",
"pinzhong": symbol,
}
r = requests.get(url, params=params)
data_text = r.text
data_json = json.loads(data_text[data_text.find("{") : data_text.rfind("}") + 1])
option_call_df = pd.DataFrame(
data_json["result"]["data"]["up"],
columns=[
"看涨合约-买量",
"看涨合约-买价",
"看涨合约-最新价",
"看涨合约-卖价",
"看涨合约-卖量",
"看涨合约-持仓量",
"看涨合约-涨跌",
"行权价",
"看涨合约-标识",
],
)
option_put_df = pd.DataFrame(
data_json["result"]["data"]["down"],
columns=[
"看跌合约-买量",
"看跌合约-买价",
"看跌合约-最新价",
"看跌合约-卖价",
"看跌合约-卖量",
"看跌合约-持仓量",
"看跌合约-涨跌",
"看跌合约-标识",
],
)
data_df = pd.concat(objs=[option_call_df, option_put_df], axis=1)
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["看跌合约-买价"] = 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")
return data_df
def option_cffex_sz50_daily_sina(symbol: str = "ho2303P2350") -> pd.DataFrame:
"""
新浪财经-中金所-上证 50 指数-指定合约-日频行情
:param symbol: 具体合约代码(包括看涨和看跌标识), 可以通过 ak.option_cffex_sz50_spot_sina 中的 call-标识 获取
:type symbol: str
:return: 日频率数据
:rtype: pandas.DataFrame
"""
year = datetime.datetime.now().year
month = datetime.datetime.now().month
day = datetime.datetime.now().day
url = (
f"https://stock.finance.sina.com.cn/futures/api/jsonp.php/var%20_{symbol}{year}_{month}_{day}"
f"=/FutureOptionAllService.getOptionDayline"
)
params = {"symbol": symbol}
r = requests.get(url, params=params)
data_text = r.text
data_df = pd.DataFrame(
eval(data_text[data_text.find("[") : data_text.rfind("]") + 1])
)
data_df.columns = ["open", "high", "low", "close", "volume", "date"]
data_df = data_df[
[
"date",
"open",
"high",
"low",
"close",
"volume",
]
]
data_df["date"] = pd.to_datetime(data_df["date"], errors="coerce").dt.date
data_df["open"] = pd.to_numeric(data_df["open"], errors="coerce")
data_df["high"] = pd.to_numeric(data_df["high"], errors="coerce")
data_df["low"] = pd.to_numeric(data_df["low"], errors="coerce")
data_df["close"] = pd.to_numeric(data_df["close"], errors="coerce")
data_df["volume"] = pd.to_numeric(data_df["volume"], errors="coerce")
return data_df
def option_cffex_hs300_daily_sina(symbol: str = "io2202P4350") -> pd.DataFrame:
"""
新浪财经-中金所-沪深300指数-指定合约-日频行情
:param symbol: 具体合约代码(包括看涨和看跌标识), 可以通过 ak.option_cffex_hs300_spot_sina 中的 call-标识 获取
:type symbol: str
:return: 日频率数据
:rtype: pandas.DataFrame
"""
year = datetime.datetime.now().year
month = datetime.datetime.now().month
day = datetime.datetime.now().day
url = (
f"https://stock.finance.sina.com.cn/futures/api/jsonp.php/var%20_{symbol}{year}_{month}_{day}"
f"=/FutureOptionAllService.getOptionDayline"
)
params = {"symbol": symbol}
r = requests.get(url, params=params)
data_text = r.text
data_df = pd.DataFrame(
eval(data_text[data_text.find("[") : data_text.rfind("]") + 1])
)
data_df.columns = ["open", "high", "low", "close", "volume", "date"]
data_df = data_df[
[
"date",
"open",
"high",
"low",
"close",
"volume",
]
]
data_df["date"] = pd.to_datetime(data_df["date"], errors="coerce").dt.date
data_df["open"] = pd.to_numeric(data_df["open"], errors="coerce")
data_df["high"] = pd.to_numeric(data_df["high"], errors="coerce")
data_df["low"] = pd.to_numeric(data_df["low"], errors="coerce")
data_df["close"] = pd.to_numeric(data_df["close"], errors="coerce")
data_df["volume"] = pd.to_numeric(data_df["volume"], errors="coerce")
return data_df
def option_cffex_zz1000_daily_sina(
symbol: str = "mo2208P6200",
) -> pd.DataFrame:
"""
新浪财经-中金所-中证 1000 指数-指定合约-日频行情
:param symbol: 具体合约代码(包括看涨和看跌标识), 可以通过 ak.option_cffex_zz1000_spot_sina 中的 call-标识 获取
:type symbol: str
:return: 日频率数据
:rtype: pandas.DataFrame
"""
year = datetime.datetime.now().year
month = datetime.datetime.now().month
day = datetime.datetime.now().day
url = (
f"https://stock.finance.sina.com.cn/futures/api/jsonp.php/var%20_{symbol}{year}_{month}_{day}"
f"=/FutureOptionAllService.getOptionDayline"
)
params = {"symbol": symbol}
r = requests.get(url, params=params)
data_text = r.text
data_df = pd.DataFrame(
eval(data_text[data_text.find("[") : data_text.rfind("]") + 1])
)
data_df.columns = ["open", "high", "low", "close", "volume", "date"]
data_df = data_df[
[
"date",
"open",
"high",
"low",
"close",
"volume",
]
]
data_df["date"] = pd.to_datetime(data_df["date"], errors="coerce").dt.date
data_df["open"] = pd.to_numeric(data_df["open"], errors="coerce")
data_df["high"] = pd.to_numeric(data_df["high"], errors="coerce")
data_df["low"] = pd.to_numeric(data_df["low"], errors="coerce")
data_df["close"] = pd.to_numeric(data_df["close"], errors="coerce")
data_df["volume"] = pd.to_numeric(data_df["volume"], errors="coerce")
return data_df
# 期权-上交所-50ETF
def option_sse_list_sina(symbol: str = "50ETF", exchange: str = "null") -> List[str]:
"""
新浪财经-期权-上交所-50ETF-合约到期月份列表
https://stock.finance.sina.com.cn/option/quotes.html
:param symbol: 50ETF or 300ETF
:type symbol: str
:param exchange: null
:type exchange: str
:return: 合约到期时间
:rtype: list
"""
url = "https://stock.finance.sina.com.cn/futures/api/openapi.php/StockOptionService.getStockName"
params = {"exchange": f"{exchange}", "cate": f"{symbol}"}
r = requests.get(url, params=params)
data_json = r.json()
date_list = data_json["result"]["data"]["contractMonth"]
return ["".join(i.split("-")) for i in date_list][1:]
def option_sse_expire_day_sina(
trade_date: str = "202102", symbol: str = "50ETF", exchange: str = "null"
) -> Tuple[str, int]:
"""
指定到期月份指定品种的剩余到期时间
:param trade_date: 到期月份: 202002, 20203, 20206, 20209
:type trade_date: str
:param symbol: 50ETF or 300ETF
:type symbol: str
:param exchange: null
:type exchange: str
:return: (到期时间, 剩余时间)
:rtype: tuple
"""
url = "https://stock.finance.sina.com.cn/futures/api/openapi.php/StockOptionService.getRemainderDay"
params = {
"exchange": f"{exchange}",
"cate": f"{symbol}",
"date": f"{trade_date[:4]}-{trade_date[4:]}",
}
r = requests.get(url, params=params)
data_json = r.json()
data = data_json["result"]["data"]
if int(data["remainderDays"]) < 0:
url = "https://stock.finance.sina.com.cn/futures/api/openapi.php/StockOptionService.getRemainderDay"
params = {
"exchange": f"{exchange}",
"cate": f"{'XD' + symbol}",
"date": f"{trade_date[:4]}-{trade_date[4:]}",
}
r = requests.get(url, params=params)
data_json = r.json()
data = data_json["result"]["data"]
return data["expireDay"], int(data["remainderDays"])
def option_sse_codes_sina(
symbol: str = "看涨期权",
trade_date: str = "202202",
underlying: str = "510050",
) -> pd.DataFrame:
"""
上海证券交易所-所有看涨和看跌合约的代码
:param symbol: choice of {"看涨期权", "看跌期权"}
:type symbol: str
:param trade_date: 期权到期月份
:type trade_date: "202002"
:param underlying: 标的产品代码 华夏上证 50ETF: 510050 or 华泰柏瑞沪深 300ETF: 510300
:type underlying: str
:return: 看涨看跌合约的代码
:rtype: Tuple[List, List]
"""
if symbol == "看涨期权":
url = "".join(
[
"https://hq.sinajs.cn/list=OP_UP_",
underlying,
str(trade_date)[-4:],
]
)
else:
url = "".join(
[
"https://hq.sinajs.cn/list=OP_DOWN_",
underlying,
str(trade_date)[-4:],
]
)
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://stock.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_temp = data_text.replace('"', ",").split(",")
temp_list = [i[7:] for i in data_temp if i.startswith("CON_OP_")]
temp_df = pd.DataFrame(temp_list)
temp_df.reset_index(inplace=True)
temp_df["index"] = temp_df.index + 1
temp_df.columns = [
"序号",
"期权代码",
]
return temp_df
def option_sse_spot_price_sina(symbol: str = "10003720") -> pd.DataFrame:
"""
新浪财经-期权-期权实时数据
:param symbol: 期权代码
:type symbol: str
:return: 期权量价数据
:rtype: pandas.DataFrame
"""
url = f"https://hq.sinajs.cn/list=CON_OP_{symbol}"
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://stock.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_list = data_text[data_text.find('"') + 1 : data_text.rfind('"')].split(",")
field_list = [
"买量",
"买价",
"最新价",
"卖价",
"卖量",
"持仓量",
"涨幅",
"行权价",
"昨收价",
"开盘价",
"涨停价",
"跌停价",
"申卖价五",
"申卖量五",
"申卖价四",
"申卖量四",
"申卖价三",
"申卖量三",
"申卖价二",
"申卖量二",
"申卖价一",
"申卖量一",
"申买价一",
"申买量一 ",
"申买价二",
"申买量二",
"申买价三",
"申买量三",
"申买价四",
"申买量四",
"申买价五",
"申买量五",
"行情时间",
"主力合约标识",
"状态码",
"标的证券类型",
"标的股票",
"期权合约简称",
"振幅",
"最高价",
"最低价",
"成交量",
"成交额",
]
data_df = pd.DataFrame(list(zip(field_list, data_list)), columns=["字段", ""])
return data_df
def option_sse_underlying_spot_price_sina(
symbol: str = "sh510300",
) -> pd.DataFrame:
"""
期权标的物的实时数据
:param symbol: sh510050 or sh510300
:type symbol: str
:return: 期权标的物的信息
:rtype: pandas.DataFrame
"""
url = f"https://hq.sinajs.cn/list={symbol}"
headers = {
"Accept": "*/*",
"Accept-Encoding": "gzip, deflate",
"Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8",
"Cache-Control": "no-cache",
"Host": "hq.sinajs.cn",
"Pragma": "no-cache",
"Proxy-Connection": "keep-alive",
"Referer": "https://vip.stock.finance.sina.com.cn/",
"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_list = data_text[data_text.find('"') + 1 : data_text.rfind('"')].split(",")
field_list = [
"证券简称",
"今日开盘价",
"昨日收盘价",
"最近成交价",
"最高成交价",
"最低成交价",
"买入价",
"卖出价",
"成交数量",
"成交金额",
"买数量一",
"买价位一",
"买数量二",
"买价位二",
"买数量三",
"买价位三",
"买数量四",
"买价位四",
"买数量五",
"买价位五",
"卖数量一",
"卖价位一",
"卖数量二",
"卖价位二",
"卖数量三",
"卖价位三",
"卖数量四",
"卖价位四",
"卖数量五",
"卖价位五",
"行情日期",
"行情时间",
"停牌状态",
]
data_df = pd.DataFrame(list(zip(field_list, data_list)), columns=["字段", ""])
return data_df
def option_sse_greeks_sina(symbol: str = "10003045") -> pd.DataFrame:
"""
期权基本信息表
:param symbol: 合约代码
:type symbol: str
:return: 期权基本信息表
:rtype: pandas.DataFrame
"""
url = f"https://hq.sinajs.cn/list=CON_SO_{symbol}"
headers = {
"Accept": "*/*",
"Accept-Encoding": "gzip, deflate",
"Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8",
"Cache-Control": "no-cache",
"Host": "hq.sinajs.cn",
"Pragma": "no-cache",
"Proxy-Connection": "keep-alive",
"Referer": "https://vip.stock.finance.sina.com.cn/",
"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_list = data_text[data_text.find('"') + 1 : data_text.rfind('"')].split(",")
field_list = [
"期权合约简称",
"成交量",
"Delta",
"Gamma",
"Theta",
"Vega",
"隐含波动率",
"最高价",
"最低价",
"交易代码",
"行权价",
"最新价",
"理论价值",
]
data_df = pd.DataFrame(
list(zip(field_list, [data_list[0]] + data_list[4:])),
columns=["字段", ""],
)
return data_df
def option_sse_minute_sina(symbol: str = "10003720") -> pd.DataFrame:
"""
指定期权品种在当前交易日的分钟数据, 只能获取当前交易日的数据, 不能获取历史分钟数据
https://stock.finance.sina.com.cn/option/quotes.html
:param symbol: 期权代码
:type symbol: str
:return: 指定期权的当前交易日的分钟数据
:rtype: pandas.DataFrame
"""
url = "https://stock.finance.sina.com.cn/futures/api/openapi.php/StockOptionDaylineService.getOptionMinline"
params = {"symbol": f"CON_OP_{symbol}"}
headers = {
"accept": "*/*",
"accept-encoding": "gzip, deflate, br",
"accept-language": "zh-CN,zh;q=0.9,en;q=0.8",
"cache-control": "no-cache",
"pragma": "no-cache",
"referer": "https://stock.finance.sina.com.cn/option/quotes.html",
"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": "same-origin",
"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, params=params, headers=headers)
data_json = r.json()
temp_df = data_json["result"]["data"]
data_df = pd.DataFrame(temp_df)
data_df = set_df_columns(
df=data_df, cols=["时间", "价格", "成交", "持仓", "均价", "日期"]
)
data_df = data_df[["日期", "时间", "价格", "成交", "持仓", "均价"]]
data_df["日期"] = pd.to_datetime(data_df["日期"], errors="coerce").dt.date
data_df["日期"] = data_df["日期"].ffill()
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")
return data_df
def option_sse_daily_sina(symbol: str = "10003889") -> pd.DataFrame:
"""
指定期权的日频率数据
:param symbol: 期权代码
:type symbol: str
:return: 指定期权的所有日频率历史数据
:rtype: pandas.DataFrame
"""
url = "https://stock.finance.sina.com.cn/futures/api/jsonp_v2.php//StockOptionDaylineService.getSymbolInfo"
params = {"symbol": f"CON_OP_{symbol}"}
headers = {
"accept": "*/*",
"accept-encoding": "gzip, deflate, br",
"accept-language": "zh-CN,zh;q=0.9,en;q=0.8",
"cache-control": "no-cache",
"pragma": "no-cache",
"referer": "https://stock.finance.sina.com.cn/option/quotes.html",
"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": "same-origin",
"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, params=params, headers=headers)
data_text = r.text
data_json = json.loads(data_text[data_text.find("(") + 1 : data_text.rfind(")")])
temp_df = pd.DataFrame(data_json)
temp_df.columns = ["日期", "开盘", "最高", "最低", "收盘", "成交量"]
temp_df["日期"] = pd.to_datetime(temp_df["日期"], errors="coerce").dt.date
temp_df["开盘"] = pd.to_numeric(temp_df["开盘"], errors="coerce")
temp_df["最高"] = pd.to_numeric(temp_df["最高"], errors="coerce")
temp_df["最低"] = pd.to_numeric(temp_df["最低"], errors="coerce")
temp_df["收盘"] = pd.to_numeric(temp_df["收盘"], errors="coerce")
temp_df["成交量"] = pd.to_numeric(temp_df["成交量"], errors="coerce")
return temp_df
def option_finance_minute_sina(symbol: str = "10002530") -> pd.DataFrame:
"""
指定期权的分钟频率数据
https://stock.finance.sina.com.cn/option/quotes.html
:param symbol: 期权代码
:type symbol: str
:return: 指定期权的分钟频率数据
:rtype: pandas.DataFrame
"""
url = "https://stock.finance.sina.com.cn/futures/api/openapi.php/StockOptionDaylineService.getFiveDayLine"
params = {
"symbol": f"CON_OP_{symbol}",
}
headers = {
"accept": "*/*",
"accept-encoding": "gzip, deflate, br",
"accept-language": "zh-CN,zh;q=0.9,en;q=0.8",
"cache-control": "no-cache",
"pragma": "no-cache",
"referer": "https://stock.finance.sina.com.cn/option/quotes.html",
"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": "same-origin",
"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, params=params, headers=headers)
data_text = r.json()
temp_df = pd.DataFrame()
for item in data_text["result"]["data"]:
temp_df = pd.concat(objs=[temp_df, pd.DataFrame(item)], ignore_index=True)
temp_df.ffill(inplace=True)
temp_df.columns = ["time", "price", "volume", "_", "average_price", "date"]
temp_df = temp_df[["date", "time", "price", "average_price", "volume"]]
temp_df["price"] = pd.to_numeric(temp_df["price"], errors="coerce")
temp_df["average_price"] = pd.to_numeric(temp_df["average_price"], errors="coerce")
temp_df["volume"] = pd.to_numeric(temp_df["volume"], errors="coerce")
return temp_df
@lru_cache()
def __option_current_em() -> pd.DataFrame:
inner_option_current_em_df = option_current_em()
return inner_option_current_em_df
def option_minute_em(symbol: str = "MO2404-P-4450") -> pd.DataFrame:
"""
东方财富网-行情中心-期权市场-分时行情
https://wap.eastmoney.com/quote/stock/151.cu2404P61000.html
:param symbol: 期权代码; 通过调用 ak.option_current_em() 获取
:type symbol: str
:return: 指定期权的分钟频率数据
:rtype: pandas.DataFrame
"""
inner_option_current_em_df = __option_current_em()
inner_option_current_em_df["标识"] = (
inner_option_current_em_df["市场标识"].astype(str)
+ "."
+ inner_option_current_em_df["代码"]
)
id_ = inner_option_current_em_df[inner_option_current_em_df["代码"] == symbol][
"标识"
].values[0]
url = "https://push2.eastmoney.com/api/qt/stock/trends2/get"
params = {
"secid": id_,
"fields1": "f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11,f12,f13,f14,f17",
"fields2": "f51,f53,f54,f55,f56,f57,f58",
"iscr": "0",
"iscca": "0",
"ut": "f057cbcbce2a86e2866ab8877db1d059",
"ndays": "1",
"cb": "quotepushdata1",
}
r = requests.get(url, params=params)
data_text = r.text
data_json = json.loads(data_text[data_text.find("(") + 1 : data_text.rfind(")")])
temp_df = pd.DataFrame([item.split(",") for item in data_json["data"]["trends"]])
temp_df.columns = ["time", "close", "high", "low", "volume", "amount", "-"]
temp_df = temp_df[["time", "close", "high", "low", "volume", "amount"]]
temp_df["close"] = pd.to_numeric(temp_df["close"], errors="coerce")
temp_df["high"] = pd.to_numeric(temp_df["high"], errors="coerce")
temp_df["low"] = pd.to_numeric(temp_df["low"], errors="coerce")
temp_df["volume"] = pd.to_numeric(temp_df["volume"], errors="coerce")
temp_df["amount"] = pd.to_numeric(temp_df["amount"], errors="coerce")
return temp_df
if __name__ == "__main__":
option_cffex_sz50_list_sina_df = option_cffex_sz50_list_sina()
print(option_cffex_sz50_list_sina_df)
# 期权-中金所-沪深300指数
option_cffex_hs300_list_sina_df = option_cffex_hs300_list_sina()
print(option_cffex_hs300_list_sina_df)
option_cffex_zz1000_list_sina_df = option_cffex_zz1000_list_sina()
print(option_cffex_zz1000_list_sina_df)
option_cffex_sz50_spot_sina_df = option_cffex_sz50_spot_sina(symbol="ho2303")
print(option_cffex_sz50_spot_sina_df)
option_cffex_hs300_spot_sina_df = option_cffex_hs300_spot_sina(symbol="io2209")
print(option_cffex_hs300_spot_sina_df)
option_cffex_zz1000_spot_sina_df = option_cffex_zz1000_spot_sina(symbol="mo2209")
print(option_cffex_zz1000_spot_sina_df)
option_cffex_sz50_daily_sina_df = option_cffex_sz50_daily_sina(symbol="ho2303P2350")
print(option_cffex_sz50_daily_sina_df)
option_cffex_hs300_daily_sina_df = option_cffex_hs300_daily_sina(
symbol="io2202P4350"
)
print(option_cffex_hs300_daily_sina_df)
option_cffex_zz1000_daily_sina_df = option_cffex_zz1000_daily_sina(
symbol="mo2208P6200"
)
print(option_cffex_zz1000_daily_sina_df)
# 期权-上交所-50ETF
option_sse_list_sina_df = option_sse_list_sina(symbol="50ETF", exchange="null")
print(option_sse_list_sina_df)
option_sse_expire_day_sina_df = option_sse_expire_day_sina(
trade_date="202308", symbol="50ETF", exchange="null"
)
print(option_sse_expire_day_sina_df)
option_sse_codes_sina_df = option_sse_codes_sina(
symbol="看跌期权", trade_date="202209", underlying="510050"
)
print(option_sse_codes_sina_df)
option_sse_spot_price_sina_df = option_sse_spot_price_sina(symbol="10003686")
print(option_sse_spot_price_sina_df)
option_sse_underlying_spot_price_sina_df = option_sse_underlying_spot_price_sina(
symbol="sh510300"
)
print(option_sse_underlying_spot_price_sina_df)
option_sse_greeks_sina_df = option_sse_greeks_sina(symbol="10004023")
print(option_sse_greeks_sina_df)
option_sse_minute_sina_df = option_sse_minute_sina(symbol="10004023")
print(option_sse_minute_sina_df)
option_sse_daily_sina_df = option_sse_daily_sina(symbol="10004023")
print(option_sse_daily_sina_df)
option_finance_minute_sina_df = option_finance_minute_sina(symbol="10004023")
print(option_finance_minute_sina_df)
option_current_em_df = option_current_em()
print(option_current_em_df)
option_minute_em_df = option_minute_em(symbol="10008594")
print(option_minute_em_df)
@@ -0,0 +1,275 @@
# -*- coding:utf-8 -*-
# !/usr/bin/env python
"""
Date: 2024/7/30 17:00
Desc: 东方财富网-数据中心-特色数据-期权龙虎榜单
https://data.eastmoney.com/other/qqlhb.html
"""
import pandas as pd
import requests
def option_lhb_em(
symbol: str = "510050",
indicator: str = "期权交易情况-认沽交易量",
trade_date: str = "20220121",
) -> pd.DataFrame:
"""
东方财富网-数据中心-期货期权-期权龙虎榜单
https://data.eastmoney.com/other/qqlhb.html
:param symbol: 期权代码; choice of {"510050", "510300", "159919"}
:type symbol: str
:param indicator: 需要获取的指标; choice of {"期权交易情况-认沽交易量","期权持仓情况-认沽持仓量", "期权交易情况-认购交易量", "期权持仓情况-认购持仓量"}
:type indicator: str
:param trade_date: 交易日期
:type trade_date: str
:return: 期权龙虎榜单
:rtype: pandas.DataFrame
"""
url = "https://datacenter-web.eastmoney.com/api/data/get"
params = {
"type": "RPT_IF_BILLBOARD_TD",
"sty": "ALL",
"filter": f"""(SECURITY_CODE="{symbol}")(TRADE_DATE='{
"-".join([trade_date[:4], trade_date[4:6], trade_date[6:]])
}')""",
"p": "1",
"pss": "200",
"source": "IFBILLBOARD",
"client": "WEB",
"ut": "b2884a393a59ad64002292a3e90d46a5",
}
r = requests.get(url, params=params)
data_json = r.json()
temp_df = pd.DataFrame(data_json["result"]["data"])
if indicator == "期权交易情况-认沽交易量":
temp_df = temp_df.iloc[:7, :]
temp_df.columns = [
"交易类型",
"交易日期",
"证券代码",
"标的名称",
"-",
"-",
"机构",
"名次",
"交易量",
"增减",
"净认沽量",
"占总交易量比例",
"-",
"-",
"-",
"-",
"-",
"-",
"-",
"-",
"-",
"-",
"-",
"-",
"-",
]
temp_df = temp_df[
[
"交易类型",
"交易日期",
"证券代码",
"标的名称",
"名次",
"机构",
"交易量",
"增减",
"净认沽量",
"占总交易量比例",
]
]
temp_df["交易日期"] = pd.to_datetime(
temp_df["交易日期"], errors="coerce"
).dt.date
temp_df["名次"] = pd.to_numeric(temp_df["名次"], errors="coerce")
temp_df["交易量"] = pd.to_numeric(temp_df["交易量"], errors="coerce")
temp_df["增减"] = pd.to_numeric(temp_df["增减"], errors="coerce")
temp_df["净认沽量"] = pd.to_numeric(temp_df["净认沽量"], errors="coerce")
temp_df["占总交易量比例"] = pd.to_numeric(
temp_df["占总交易量比例"], errors="coerce"
)
temp_df.reset_index(drop=True, inplace=True)
return temp_df
elif indicator == "期权持仓情况-认沽持仓量":
temp_df = temp_df.iloc[7:14, :]
temp_df.columns = [
"交易类型",
"交易日期",
"证券代码",
"标的名称",
"-",
"-",
"机构",
"名次",
"-",
"-",
"-",
"-",
"-",
"持仓量",
"增减",
"净持仓量",
"占总交易量比例",
"-",
"-",
"-",
"-",
"-",
"-",
"-",
"-",
]
temp_df = temp_df[
[
"交易类型",
"交易日期",
"证券代码",
"标的名称",
"名次",
"机构",
"持仓量",
"增减",
"净持仓量",
"占总交易量比例",
]
]
temp_df["交易日期"] = pd.to_datetime(
temp_df["交易日期"], errors="coerce"
).dt.date
temp_df["名次"] = pd.to_numeric(temp_df["名次"], errors="coerce")
temp_df["持仓量"] = pd.to_numeric(temp_df["持仓量"], errors="coerce")
temp_df["增减"] = pd.to_numeric(temp_df["增减"], errors="coerce")
temp_df["净持仓量"] = pd.to_numeric(temp_df["净持仓量"], errors="coerce")
temp_df["占总交易量比例"] = pd.to_numeric(
temp_df["占总交易量比例"], errors="coerce"
)
temp_df.reset_index(drop=True, inplace=True)
return temp_df
elif indicator == "期权交易情况-认购交易量":
temp_df = temp_df.iloc[14:21, :]
temp_df.columns = [
"交易类型",
"交易日期",
"证券代码",
"标的名称",
"-",
"-",
"机构",
"名次",
"-",
"-",
"-",
"-",
"-",
"-",
"-",
"-",
"-",
"交易量",
"增减",
"净交易量",
"占总交易量比例",
"-",
"-",
"-",
"-",
]
temp_df = temp_df[
[
"交易类型",
"交易日期",
"证券代码",
"标的名称",
"名次",
"机构",
"交易量",
"增减",
"净交易量",
"占总交易量比例",
]
]
temp_df["交易日期"] = pd.to_datetime(
temp_df["交易日期"], errors="coerce"
).dt.date
temp_df["名次"] = pd.to_numeric(temp_df["名次"], errors="coerce")
temp_df["交易量"] = pd.to_numeric(temp_df["交易量"], errors="coerce")
temp_df["增减"] = pd.to_numeric(temp_df["增减"], errors="coerce")
temp_df["净交易量"] = pd.to_numeric(temp_df["净交易量"], errors="coerce")
temp_df["占总交易量比例"] = pd.to_numeric(
temp_df["占总交易量比例"], errors="coerce"
)
temp_df.reset_index(drop=True, inplace=True)
return temp_df
elif indicator == "期权持仓情况-认购持仓量":
temp_df = temp_df.iloc[21:, :]
temp_df.rename(
columns={
"MEMBER_RANK": "名次",
"MEMBER_NAME_ABBR": "机构",
"BUY_POSITION": "持仓量",
"BUY_POSITION_CHANGE": "增减",
"NET_BUY_POSITION": "净持仓量",
"BUY_POSITION_RATIO": "占总交易量比例",
"TRADE_TYPE": "交易类型",
"TRADE_DATE": "交易日期",
"SECURITY_CODE": "证券代码",
"TARGET_NAME": "标的名称",
},
inplace=True,
)
temp_df = temp_df[
[
"交易类型",
"交易日期",
"证券代码",
"标的名称",
"名次",
"机构",
"持仓量",
"增减",
"净持仓量",
"占总交易量比例",
]
]
temp_df["交易日期"] = pd.to_datetime(
temp_df["交易日期"], errors="coerce"
).dt.date
temp_df["名次"] = pd.to_numeric(temp_df["名次"], errors="coerce")
temp_df["持仓量"] = pd.to_numeric(temp_df["持仓量"], errors="coerce")
temp_df["增减"] = pd.to_numeric(temp_df["增减"], errors="coerce")
temp_df["净持仓量"] = pd.to_numeric(temp_df["净持仓量"], errors="coerce")
temp_df["占总交易量比例"] = pd.to_numeric(
temp_df["占总交易量比例"], errors="coerce"
)
temp_df.reset_index(drop=True, inplace=True)
return temp_df
if __name__ == "__main__":
option_lhb_em_df = option_lhb_em(
symbol="510300", indicator="期权交易情况-认购交易量", trade_date="20220124"
)
print(option_lhb_em_df)
option_lhb_em_df = option_lhb_em(
symbol="510300", indicator="期权交易情况-认沽交易量", trade_date="20220124"
)
print(option_lhb_em_df)
option_lhb_em_df = option_lhb_em(
symbol="159919", indicator="期权持仓情况-认购持仓量", trade_date="20240712"
)
print(option_lhb_em_df)
option_lhb_em_df = option_lhb_em(
symbol="510300", indicator="期权持仓情况-认沽持仓量", trade_date="20220124"
)
print(option_lhb_em_df)
@@ -0,0 +1,71 @@
#!/usr/bin/env python
# -*- coding:utf-8 -*-
"""
Date: 2025/6/16 18:00
Desc: 唯爱期货-期权保证金
https://www.iweiai.com/qihuo/yuanyou
"""
import requests
import pandas as pd
from io import StringIO
from bs4 import BeautifulSoup
from functools import lru_cache
@lru_cache()
def option_margin_symbol() -> pd.DataFrame:
"""
获取商品期权品种代码和名称
:return: 商品期权品种代码和名称
:rtype: pandas.DataFrame
"""
url = "https://www.iweiai.com/qiquan/yuanyou"
r = requests.get(url)
soup = BeautifulSoup(r.content, features="lxml")
symbol_text = [
item.get_text() for item in soup.find_all("a") if "qiquan" in item["href"]
]
symbol_url = [
item["href"] for item in soup.find_all("a") if "qiquan" in item["href"]
]
symbol_df = pd.DataFrame([symbol_text, symbol_url]).T
symbol_df.columns = ["symbol", "url"]
return symbol_df
def option_margin(symbol: str = "原油期权") -> pd.DataFrame:
"""
获取商品期权保证金
:param symbol: 商品期权品种名称, "原油期权"可以通过 ak.option_margin_symbol() 获取所有商品期权品种代码和名称
:type symbol: str
:return: 商品期权保证金
:rtype: pandas.DataFrame
"""
option_margin_symbol_df = option_margin_symbol()
url = option_margin_symbol_df[option_margin_symbol_df["symbol"] == symbol][
"url"
].values[0]
r = requests.get(url)
soup = BeautifulSoup(r.content, features="lxml")
updated_time = soup.find_all("small")[0].get_text().strip("最近更新:")
temp_df = pd.read_html(StringIO(r.text))[0]
temp_df["更新时间"] = updated_time
temp_df["结算价"] = pd.to_numeric(temp_df["结算价"], errors="coerce")
temp_df["交易乘数"] = pd.to_numeric(temp_df["交易乘数"], errors="coerce")
temp_df["买方权利金"] = pd.to_numeric(temp_df["买方权利金"], errors="coerce")
temp_df["卖方保证金"] = pd.to_numeric(temp_df["卖方保证金"], errors="coerce")
temp_df["开仓手续费"] = pd.to_numeric(temp_df["开仓手续费"], errors="coerce")
temp_df["平今手续费"] = pd.to_numeric(temp_df["平今手续费"], errors="coerce")
temp_df["平昨手续费"] = pd.to_numeric(temp_df["平昨手续费"], errors="coerce")
temp_df["手续费(开+平今)"] = pd.to_numeric(
temp_df["手续费(开+平今)"], errors="coerce"
)
return temp_df
if __name__ == "__main__":
option_margin_df = option_margin(symbol="原油期权")
print(option_margin_df)
@@ -0,0 +1,85 @@
# -*- coding:utf-8 -*-
# !/usr/bin/env python
"""
Date: 2025/3/11 17:00
Desc: 东方财富网-数据中心-特色数据-期权折溢价
https://data.eastmoney.com/other/premium.html
"""
import pandas as pd
from akshare.utils.func import fetch_paginated_data
def option_premium_analysis_em() -> pd.DataFrame:
"""
东方财富网-数据中心-特色数据-期权折溢价
https://data.eastmoney.com/other/premium.html
:return: 期权折溢价
:rtype: pandas.DataFrame
"""
url = "https://push2.eastmoney.com/api/qt/clist/get"
params = {
"fid": "f250",
"po": "1",
"pz": "100",
"pn": "1",
"np": "1",
"fltt": "2",
"invt": "2",
"ut": "b2884a393a59ad64002292a3e90d46a5",
"fields": "f1,f2,f3,f12,f13,f14,f161,f250,f330,f331,f332,f333,f334,f335,f337,f301,f152",
"fs": "m:10",
}
temp_df = fetch_paginated_data(url, params)
temp_df.columns = [
"-",
"-",
"最新价",
"涨跌幅",
"期权代码",
"-",
"期权名称",
"-",
"行权价",
"折溢价率",
"到期日",
"-",
"-",
"-",
"标的名称",
"标的最新价",
"标的涨跌幅",
"盈亏平衡价",
]
temp_df = temp_df[
[
"期权代码",
"期权名称",
"最新价",
"涨跌幅",
"行权价",
"折溢价率",
"标的名称",
"标的最新价",
"标的涨跌幅",
"盈亏平衡价",
"到期日",
]
]
temp_df["最新价"] = pd.to_numeric(temp_df["最新价"], errors="coerce")
temp_df["涨跌幅"] = pd.to_numeric(temp_df["涨跌幅"], errors="coerce")
temp_df["行权价"] = pd.to_numeric(temp_df["行权价"], errors="coerce")
temp_df["折溢价率"] = pd.to_numeric(temp_df["折溢价率"], errors="coerce")
temp_df["标的最新价"] = pd.to_numeric(temp_df["标的最新价"], errors="coerce")
temp_df["标的涨跌幅"] = pd.to_numeric(temp_df["标的涨跌幅"], errors="coerce")
temp_df["盈亏平衡价"] = pd.to_numeric(temp_df["盈亏平衡价"], errors="coerce")
temp_df["到期日"] = pd.to_datetime(
temp_df["到期日"].astype(str), errors="coerce"
).dt.date
return temp_df
if __name__ == "__main__":
option_premium_analysis_em_df = option_premium_analysis_em()
print(option_premium_analysis_em_df)
@@ -0,0 +1,87 @@
# -*- coding:utf-8 -*-
# !/usr/bin/env python
"""
Date: 2025/3/13 21:50
Desc: 东方财富网-数据中心-特色数据-期权风险分析
https://data.eastmoney.com/other/riskanal.html
"""
import pandas as pd
from akshare.utils.func import fetch_paginated_data
def option_risk_analysis_em() -> pd.DataFrame:
"""
东方财富网-数据中心-特色数据-期权风险分析
https://data.eastmoney.com/other/riskanal.html
:return: 期权风险分析
:rtype: pandas.DataFrame
"""
url = "https://push2.eastmoney.com/api/qt/clist/get"
params = {
"fid": "f12",
"po": "1",
"pz": "100",
"pn": "1",
"np": "1",
"fltt": "2",
"invt": "2",
"ut": "b2884a393a59ad64002292a3e90d46a5",
"fields": "f1,f2,f3,f12,f13,f14,f302,f303,f325,f326,f327,f329,f328,f301,f152,f154",
"fs": "m:10",
}
temp_df = fetch_paginated_data(url, params)
temp_df.columns = [
"-",
"-",
"最新价",
"涨跌幅",
"期权代码",
"-",
"期权名称",
"-",
"-",
"到期日",
"杠杆比率",
"实际杠杆比率",
"Delta",
"Gamma",
"Vega",
"Theta",
"Rho",
]
temp_df = temp_df[
[
"期权代码",
"期权名称",
"最新价",
"涨跌幅",
"杠杆比率",
"实际杠杆比率",
"Delta",
"Gamma",
"Vega",
"Rho",
"Theta",
"到期日",
]
]
temp_df["最新价"] = pd.to_numeric(temp_df["最新价"], errors="coerce")
temp_df["涨跌幅"] = pd.to_numeric(temp_df["涨跌幅"], errors="coerce")
temp_df["杠杆比率"] = pd.to_numeric(temp_df["杠杆比率"], errors="coerce")
temp_df["实际杠杆比率"] = pd.to_numeric(temp_df["实际杠杆比率"], errors="coerce")
temp_df["Delta"] = pd.to_numeric(temp_df["Delta"], errors="coerce")
temp_df["Gamma"] = pd.to_numeric(temp_df["Gamma"], errors="coerce")
temp_df["Vega"] = pd.to_numeric(temp_df["Vega"], errors="coerce")
temp_df["Rho"] = pd.to_numeric(temp_df["Rho"], errors="coerce")
temp_df["Theta"] = pd.to_numeric(temp_df["Theta"], errors="coerce")
temp_df["到期日"] = pd.to_datetime(
temp_df["到期日"], format="%Y%m%d", errors="coerce"
).dt.date
return temp_df
if __name__ == "__main__":
option_risk_analysis_em_df = option_risk_analysis_em()
print(option_risk_analysis_em_df)
@@ -0,0 +1,73 @@
# -*- coding:utf-8 -*-
# !/usr/bin/env python
"""
Date: 2025/9/8 16:20
Desc: 上海证券交易所-产品-股票期权-期权风险指标
"""
import pandas as pd
import requests
def option_risk_indicator_sse(date: str = "20240626") -> pd.DataFrame:
"""
上海证券交易所-产品-股票期权-期权风险指标
http://www.sse.com.cn/assortment/options/risk/
:param date: 日期; 20150209 开始
:type date: str
:return: 期权风险指标
:rtype: pandas.DataFrame
"""
url = "http://query.sse.com.cn/commonQuery.do"
params = {
"isPagination": "false",
"trade_date": date,
"sqlId": "SSE_ZQPZ_YSP_GGQQZSXT_YSHQ_QQFXZB_DATE_L",
"contractSymbol": "",
}
headers = {
"Accept": "*/*",
"Accept-Encoding": "gzip, deflate",
"Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8",
"Cache-Control": "no-cache",
"Connection": "keep-alive",
"Host": "query.sse.com.cn",
"Pragma": "no-cache",
"Referer": "http://www.sse.com.cn/",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "
"Chrome/101.0.4951.67 Safari/537.36",
}
r = requests.get(url, params=params, headers=headers)
data_json = r.json()
temp_df = pd.DataFrame(data_json["result"])
temp_df = temp_df[
[
"TRADE_DATE",
"SECURITY_ID",
"CONTRACT_ID",
"CONTRACT_SYMBOL",
"DELTA_VALUE",
"THETA_VALUE",
"GAMMA_VALUE",
"VEGA_VALUE",
"RHO_VALUE",
"IMPLC_VOLATLTY",
]
]
temp_df["TRADE_DATE"] = pd.to_datetime(
temp_df["TRADE_DATE"], errors="coerce"
).dt.date
temp_df["DELTA_VALUE"] = pd.to_numeric(temp_df["DELTA_VALUE"], errors="coerce")
temp_df["THETA_VALUE"] = pd.to_numeric(temp_df["THETA_VALUE"], errors="coerce")
temp_df["GAMMA_VALUE"] = pd.to_numeric(temp_df["GAMMA_VALUE"], errors="coerce")
temp_df["VEGA_VALUE"] = pd.to_numeric(temp_df["VEGA_VALUE"], errors="coerce")
temp_df["RHO_VALUE"] = pd.to_numeric(temp_df["RHO_VALUE"], errors="coerce")
temp_df["IMPLC_VOLATLTY"] = pd.to_numeric(
temp_df["IMPLC_VOLATLTY"], errors="coerce"
)
return temp_df
if __name__ == "__main__":
option_risk_indicator_sse_df = option_risk_indicator_sse(date="20240626")
print(option_risk_indicator_sse_df)
@@ -0,0 +1,89 @@
# -*- coding:utf-8 -*-
# !/usr/bin/env python
"""
Date: 2025/3/11 17:00
Desc: 东方财富网-数据中心-特色数据-期权价值分析
https://data.eastmoney.com/other/valueAnal.html
"""
import pandas as pd
from akshare.utils.func import fetch_paginated_data
def option_value_analysis_em() -> pd.DataFrame:
"""
东方财富网-数据中心-特色数据-期权价值分析
https://data.eastmoney.com/other/valueAnal.html
:return: 期权价值分析
:rtype: pandas.DataFrame
"""
url = "https://push2.eastmoney.com/api/qt/clist/get"
params = {
"fid": "f301",
"po": "1",
"pz": "100",
"pn": "1",
"np": "1",
"fltt": "2",
"invt": "2",
"ut": "b2884a393a59ad64002292a3e90d46a5",
"fields": "f1,f2,f3,f12,f13,f14,f298,f299,f249,f300,f330,f331,f332,f333,f334,f335,f336,f301,f152",
"fs": "m:10",
}
temp_df = fetch_paginated_data(url, params)
temp_df.columns = [
"-",
"-",
"最新价",
"-",
"期权代码",
"-",
"期权名称",
"-",
"隐含波动率",
"时间价值",
"内在价值",
"理论价格",
"到期日",
"-",
"-",
"-",
"标的名称",
"标的最新价",
"-",
"标的近一年波动率",
]
temp_df = temp_df[
[
"期权代码",
"期权名称",
"最新价",
"时间价值",
"内在价值",
"隐含波动率",
"理论价格",
"标的名称",
"标的最新价",
"标的近一年波动率",
"到期日",
]
]
temp_df["最新价"] = pd.to_numeric(temp_df["最新价"], errors="coerce")
temp_df["时间价值"] = pd.to_numeric(temp_df["时间价值"], errors="coerce")
temp_df["内在价值"] = pd.to_numeric(temp_df["内在价值"], errors="coerce")
temp_df["隐含波动率"] = pd.to_numeric(temp_df["隐含波动率"], errors="coerce")
temp_df["理论价格"] = pd.to_numeric(temp_df["理论价格"], errors="coerce")
temp_df["标的最新价"] = pd.to_numeric(temp_df["标的最新价"], errors="coerce")
temp_df["标的近一年波动率"] = pd.to_numeric(
temp_df["标的近一年波动率"], errors="coerce"
)
temp_df["到期日"] = pd.to_datetime(
temp_df["到期日"].astype(str), errors="coerce"
).dt.date
return temp_df
if __name__ == "__main__":
option_value_analysis_em_df = option_value_analysis_em()
print(option_value_analysis_em_df)