stock-tracker
This commit is contained in:
@@ -0,0 +1,6 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding:utf-8 -*-
|
||||
"""
|
||||
Date: 2019/9/30 13:58
|
||||
Desc:
|
||||
"""
|
||||
@@ -0,0 +1,911 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding:utf-8 -*-
|
||||
"""
|
||||
Date: 2024/4/29 16:00
|
||||
Desc: 中国证券投资基金业协会-信息公示数据
|
||||
中国证券投资基金业协会-新版: https://gs.amac.org.cn
|
||||
"""
|
||||
|
||||
import pandas as pd
|
||||
import requests
|
||||
|
||||
from akshare.utils.tqdm import get_tqdm
|
||||
|
||||
headers = {
|
||||
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "
|
||||
"Chrome/123.0.0.0 Safari/537.36",
|
||||
"Content-Type": "application/json",
|
||||
}
|
||||
|
||||
|
||||
def _get_pages(url: str = "", payload: str = "") -> pd.DataFrame:
|
||||
"""
|
||||
中国证券投资基金业协会-信息公示-私募基金管理人公示 页数
|
||||
暂时不使用本函数, 直接可以获取所有数据
|
||||
"""
|
||||
res = requests.post(url=url, json=payload, headers=headers)
|
||||
res.encoding = "utf-8"
|
||||
json_df = res.json()
|
||||
return json_df["totalPages"]
|
||||
|
||||
|
||||
def get_data(url: str = "", payload: str = "") -> pd.DataFrame:
|
||||
"""
|
||||
中国证券投资基金业协会-信息公示-私募基金管理人公示
|
||||
"""
|
||||
res = requests.post(url=url, json=payload, headers=headers)
|
||||
res.encoding = "utf-8"
|
||||
json_df = res.json()
|
||||
return json_df
|
||||
|
||||
|
||||
# 中国证券投资基金业协会-信息公示-会员信息
|
||||
# 中国证券投资基金业协会-信息公示-会员信息-会员机构综合查询
|
||||
def amac_member_info() -> pd.DataFrame:
|
||||
"""
|
||||
中国证券投资基金业协会-信息公示-会员信息-会员机构综合查询
|
||||
https://gs.amac.org.cn/amac-infodisc/res/pof/member/index.html
|
||||
:return: 会员机构综合查询
|
||||
:rtype: pandas.DataFrame
|
||||
"""
|
||||
url = "https://gs.amac.org.cn/amac-infodisc/api/pof/pofMember"
|
||||
params = {
|
||||
"rand": "0.7665138514630696",
|
||||
"page": "1",
|
||||
"size": "20",
|
||||
}
|
||||
r = requests.post(url, params=params, json={}, headers=headers)
|
||||
data_json = r.json()
|
||||
total_page = data_json["totalPages"]
|
||||
big_df = pd.DataFrame()
|
||||
tqdm = get_tqdm()
|
||||
for page in tqdm(range(0, int(total_page)), leave=False):
|
||||
params.update({"page": page})
|
||||
r = requests.post(url, params=params, json={}, headers=headers)
|
||||
data_json = r.json()
|
||||
temp_df = pd.DataFrame(data_json["content"])
|
||||
big_df = pd.concat(objs=[big_df, temp_df], ignore_index=True)
|
||||
keys_list = [
|
||||
"managerName",
|
||||
"memberBehalf",
|
||||
"memberType",
|
||||
"memberCode",
|
||||
"memberDate",
|
||||
"primaryInvestType",
|
||||
"markStar",
|
||||
] # 定义要取的 value 的 keys
|
||||
manager_data_out = pd.DataFrame(big_df)
|
||||
manager_data_out = manager_data_out[keys_list]
|
||||
manager_data_out.columns = [
|
||||
"机构(会员)名称",
|
||||
"会员代表",
|
||||
"会员类型",
|
||||
"会员编号",
|
||||
"入会时间",
|
||||
"机构类型",
|
||||
"是否星标",
|
||||
]
|
||||
manager_data_out["入会时间"] = pd.to_datetime(
|
||||
manager_data_out["入会时间"], unit="ms"
|
||||
).dt.date
|
||||
return manager_data_out
|
||||
|
||||
|
||||
# 中国证券投资基金业协会-信息公示-从业人员信息
|
||||
# 中国证券投资基金业协会-信息公示-从业人员信息-基金从业人员资格注册信息
|
||||
def amac_person_fund_org_list(symbol: str = "公募基金管理公司") -> pd.DataFrame:
|
||||
"""
|
||||
中国证券投资基金业协会-信息公示-从业人员信息-基金从业人员资格注册信息
|
||||
https://gs.amac.org.cn/amac-infodisc/res/pof/person/personOrgList.html
|
||||
:param symbol: choice of {"公募基金管理公司", "公募基金管理公司资管子公司", "商业银行", "证券公司", "证券公司子公司",
|
||||
"私募基金管理人", "保险公司子公司", "保险公司", "外包服务机构", "期货公司", "期货公司资管子公司", "媒体机构",
|
||||
"证券投资咨询机构", "评价机构", "外资私募证券基金管理人", "支付结算", "独立服务机构", "地方自律组织", "境外机构",
|
||||
"律师事务所", "会计师事务所", "交易所", "独立第三方销售机构", "证券公司资管子公司", "证券公司私募基金子公司", "其他"}
|
||||
:type symbol: str
|
||||
:return: 基金从业人员资格注册信息
|
||||
:rtype: pandas.DataFrame
|
||||
"""
|
||||
symbol_map = {
|
||||
"保险公司子公司": "bxgszgs",
|
||||
"期货公司资管子公司": "qhgszgzgs",
|
||||
"公募基金管理公司资管子公司": "gmjjglgszgzgs",
|
||||
"商业银行": "syyh",
|
||||
"交易所": "jys",
|
||||
"证券公司私募基金子公司": "zqgssmjjzgs",
|
||||
"地方自律组织": "dfzlzz",
|
||||
"证券公司": "zqgs",
|
||||
"评价机构": "pjjg",
|
||||
"独立第三方销售机构": "dldsfxsjg",
|
||||
"证券投资咨询机构": "zqtzzxjg",
|
||||
"外资私募证券基金管理人": "wzsmzqjjglr",
|
||||
"境外机构": "jwjg",
|
||||
"证券公司子公司": "zqgszgs",
|
||||
"公募基金管理公司": "gmjjglgs",
|
||||
"媒体机构": "mtjg",
|
||||
"支付结算": "zfjs",
|
||||
"证券公司资管子公司": "zqgszgzgs",
|
||||
"会计师事务所": "kjssws",
|
||||
"独立服务机构": "dlfwjg",
|
||||
"律师事务所": "lssws",
|
||||
"期货公司": "qhgs",
|
||||
"保险公司": "bxgs",
|
||||
"其他": "qt",
|
||||
"外包服务机构": "wbfwjg",
|
||||
"私募基金管理人": "smjjglr",
|
||||
}
|
||||
url = "https://gs.amac.org.cn/amac-infodisc/api/pof/personOrg"
|
||||
params = {
|
||||
"rand": "0.7665138514630696",
|
||||
"page": "1",
|
||||
"size": "20",
|
||||
}
|
||||
r = requests.post(
|
||||
url,
|
||||
params=params,
|
||||
json={"orgType": symbol_map[symbol], "page": "1"},
|
||||
headers=headers,
|
||||
)
|
||||
data_json = r.json()
|
||||
total_page = data_json["totalPages"]
|
||||
big_df = pd.DataFrame()
|
||||
tqdm = get_tqdm()
|
||||
for page in tqdm(range(0, int(total_page)), leave=False):
|
||||
params.update({"page": page})
|
||||
r = requests.post(
|
||||
url,
|
||||
params=params,
|
||||
json={"orgType": symbol_map[symbol], "page": "1"},
|
||||
verify=False,
|
||||
headers=headers,
|
||||
)
|
||||
data_json = r.json()
|
||||
temp_df = pd.DataFrame(data_json["content"])
|
||||
big_df = pd.concat(objs=[big_df, temp_df], ignore_index=True)
|
||||
keys_list = [
|
||||
"orgName",
|
||||
"orgType",
|
||||
"workerTotalNum",
|
||||
"operNum",
|
||||
"salesmanNum",
|
||||
"investmentManagerNum",
|
||||
"fundManagerNum",
|
||||
] # 定义要取的 value 的 keys
|
||||
manager_data_out = pd.DataFrame(big_df)
|
||||
manager_data_out = manager_data_out[keys_list]
|
||||
manager_data_out.reset_index(inplace=True)
|
||||
manager_data_out["index"] = manager_data_out.index + 1
|
||||
manager_data_out.columns = [
|
||||
"序号",
|
||||
"机构名称",
|
||||
"机构类型",
|
||||
"员工人数",
|
||||
"基金从业资格",
|
||||
"基金销售业务资格",
|
||||
"基金经理",
|
||||
"投资经理",
|
||||
]
|
||||
manager_data_out["员工人数"] = pd.to_numeric(manager_data_out["员工人数"])
|
||||
manager_data_out["基金从业资格"] = pd.to_numeric(manager_data_out["基金从业资格"])
|
||||
manager_data_out["基金销售业务资格"] = pd.to_numeric(
|
||||
manager_data_out["基金销售业务资格"]
|
||||
)
|
||||
manager_data_out["基金经理"] = pd.to_numeric(manager_data_out["基金经理"])
|
||||
manager_data_out["投资经理"] = pd.to_numeric(manager_data_out["投资经理"])
|
||||
return manager_data_out
|
||||
|
||||
|
||||
# 中国证券投资基金业协会-信息公示-从业人员信息-债券投资交易相关人员公示
|
||||
def amac_person_bond_org_list() -> pd.DataFrame:
|
||||
"""
|
||||
中国证券投资基金业协会-信息公示-从业人员信息-债券投资交易相关人员公示
|
||||
https://human.amac.org.cn/web/org/personPublicity.html
|
||||
:return: 债券投资交易相关人员公示
|
||||
:rtype: pandas.DataFrame
|
||||
"""
|
||||
import urllib3
|
||||
import ssl
|
||||
|
||||
ctx = ssl.create_default_context()
|
||||
ctx.options |= ssl.OP_LEGACY_SERVER_CONNECT
|
||||
# 使用自定义的 SSL 上下文发起 HTTPS 请求
|
||||
http = urllib3.PoolManager(ssl_context=ctx)
|
||||
|
||||
url = "https://human.amac.org.cn/web/api/publicityAddress?rand=0.6288001872566391&pageNum=1&pageSize=5000"
|
||||
r = http.request(method="GET", url=url)
|
||||
data_json = r.json()
|
||||
temp_df = pd.DataFrame(data_json["list"])
|
||||
temp_df.reset_index(inplace=True)
|
||||
temp_df["index"] = range(1, len(temp_df) + 1)
|
||||
temp_df.columns = [
|
||||
"序号",
|
||||
"_",
|
||||
"_",
|
||||
"机构名称",
|
||||
"机构类型",
|
||||
"公示网址",
|
||||
]
|
||||
temp_df = temp_df[
|
||||
[
|
||||
"序号",
|
||||
"机构类型",
|
||||
"机构名称",
|
||||
"公示网址",
|
||||
]
|
||||
]
|
||||
return temp_df
|
||||
|
||||
|
||||
# 中国证券投资基金业协会-信息公示-私募基金管理人公示
|
||||
# 中国证券投资基金业协会-信息公示-私募基金管理人公示-私募基金管理人综合查询
|
||||
def amac_manager_info() -> pd.DataFrame:
|
||||
"""
|
||||
中国证券投资基金业协会-信息公示-私募基金管理人公示-私募基金管理人综合查询
|
||||
https://gs.amac.org.cn/amac-infodisc/res/pof/manager/index.html
|
||||
:return: 私募基金管理人综合查询
|
||||
:rtype: pandas.DataFrame
|
||||
"""
|
||||
url = "https://gs.amac.org.cn/amac-infodisc/api/pof/manager"
|
||||
params = {
|
||||
"rand": "0.7665138514630696",
|
||||
"page": "1",
|
||||
"size": "100",
|
||||
}
|
||||
r = requests.post(url, params=params, json={}, verify=False, headers=headers)
|
||||
data_json = r.json()
|
||||
total_page = data_json["totalPages"]
|
||||
big_df = pd.DataFrame()
|
||||
tqdm = get_tqdm()
|
||||
for page in tqdm(range(0, int(total_page)), leave=False):
|
||||
params.update({"page": page})
|
||||
r = requests.post(url, params=params, json={}, verify=False, headers=headers)
|
||||
data_json = r.json()
|
||||
temp_df = pd.DataFrame(data_json["content"])
|
||||
big_df = pd.concat(objs=[big_df, temp_df], ignore_index=True)
|
||||
keys_list = [
|
||||
"managerName",
|
||||
"artificialPersonName",
|
||||
"primaryInvestType",
|
||||
"registerProvince",
|
||||
"registerNo",
|
||||
"establishDate",
|
||||
"registerDate",
|
||||
] # 定义要取的 value 的 keys
|
||||
manager_data_out = pd.DataFrame(big_df)
|
||||
manager_data_out = manager_data_out[keys_list]
|
||||
manager_data_out.columns = [
|
||||
"私募基金管理人名称",
|
||||
"法定代表人/执行事务合伙人(委派代表)姓名",
|
||||
"机构类型",
|
||||
"注册地",
|
||||
"登记编号",
|
||||
"成立时间",
|
||||
"登记时间",
|
||||
]
|
||||
manager_data_out["成立时间"] = pd.to_datetime(
|
||||
manager_data_out["成立时间"], unit="ms"
|
||||
).dt.date
|
||||
manager_data_out["登记时间"] = pd.to_datetime(
|
||||
manager_data_out["登记时间"], unit="ms"
|
||||
).dt.date
|
||||
return manager_data_out
|
||||
|
||||
|
||||
# 中国证券投资基金业协会-信息公示-私募基金管理人公示-私募基金管理人分类公示
|
||||
def amac_manager_classify_info() -> pd.DataFrame:
|
||||
"""
|
||||
中国证券投资基金业协会-信息公示-私募基金管理人公示-私募基金管理人分类公示
|
||||
https://gs.amac.org.cn/amac-infodisc/res/pof/manager/managerList.html
|
||||
:return: 私募基金管理人分类公示
|
||||
:rtype: pandas.DataFrame
|
||||
"""
|
||||
url = "https://gs.amac.org.cn/amac-infodisc/api/pof/manager"
|
||||
params = {
|
||||
"rand": "0.7665138514630696",
|
||||
"page": "1",
|
||||
"size": "100",
|
||||
}
|
||||
r = requests.post(url, params=params, json={}, verify=False, headers=headers)
|
||||
data_json = r.json()
|
||||
total_page = data_json["totalPages"]
|
||||
big_df = pd.DataFrame()
|
||||
tqdm = get_tqdm()
|
||||
for page in tqdm(range(0, int(total_page)), leave=False):
|
||||
params.update({"page": page})
|
||||
r = requests.post(url, params=params, json={}, verify=False, headers=headers)
|
||||
data_json = r.json()
|
||||
temp_df = pd.DataFrame(data_json["content"])
|
||||
big_df = pd.concat(objs=[big_df, temp_df], ignore_index=True)
|
||||
keys_list = [
|
||||
"managerName",
|
||||
"artificialPersonName",
|
||||
"primaryInvestType",
|
||||
"registerNo",
|
||||
"registerProvince",
|
||||
"officeAdrAgg",
|
||||
"establishDate",
|
||||
"registerDate",
|
||||
"fundCount",
|
||||
"memberType",
|
||||
"hasSpecialTips",
|
||||
"hasCreditTips",
|
||||
] # 定义要取的 value 的 keys
|
||||
manager_data_out = pd.DataFrame(big_df)
|
||||
manager_data_out = manager_data_out[keys_list]
|
||||
manager_data_out.columns = [
|
||||
"私募基金管理人名称",
|
||||
"法定代表人/执行事务合伙人(委派代表)姓名",
|
||||
"机构类型",
|
||||
"登记编号",
|
||||
"注册地",
|
||||
"办公地",
|
||||
"成立时间",
|
||||
"登记时间",
|
||||
"在管基金数量",
|
||||
"会员类型",
|
||||
"是否有提示信息",
|
||||
"是否有诚信信息",
|
||||
]
|
||||
manager_data_out["成立时间"] = pd.to_datetime(
|
||||
manager_data_out["成立时间"], unit="ms"
|
||||
).dt.date
|
||||
manager_data_out["登记时间"] = pd.to_datetime(
|
||||
manager_data_out["登记时间"], unit="ms"
|
||||
).dt.date
|
||||
manager_data_out["在管基金数量"] = pd.to_numeric(manager_data_out["在管基金数量"])
|
||||
manager_data_out["是否有提示信息"] = manager_data_out["是否有提示信息"].map(
|
||||
{True: "是", False: "否"}
|
||||
)
|
||||
manager_data_out["是否有诚信信息"] = manager_data_out["是否有诚信信息"].map(
|
||||
{True: "是", False: "否"}
|
||||
)
|
||||
return manager_data_out
|
||||
|
||||
|
||||
# 中国证券投资基金业协会-信息公示-私募基金管理人公示-证券公司私募基金子公司管理人信息公示
|
||||
def amac_member_sub_info() -> pd.DataFrame:
|
||||
"""
|
||||
中国证券投资基金业协会-信息公示-私募基金管理人公示-证券公司私募基金子公司管理人信息公示
|
||||
https://gs.amac.org.cn/amac-infodisc/res/pof/member/index.html?primaryInvestType=private
|
||||
:return: 证券公司私募基金子公司管理人信息公示
|
||||
:rtype: pandas.DataFrame
|
||||
"""
|
||||
url = "https://gs.amac.org.cn/amac-infodisc/api/pof/pofMember"
|
||||
params = {
|
||||
"rand": "0.7665138514630696",
|
||||
"page": "1",
|
||||
"size": "100",
|
||||
}
|
||||
r = requests.post(url, params=params, json={}, verify=False, headers=headers)
|
||||
data_json = r.json()
|
||||
total_page = data_json["totalPages"]
|
||||
big_df = pd.DataFrame()
|
||||
tqdm = get_tqdm()
|
||||
for page in tqdm(range(0, int(total_page)), leave=False):
|
||||
params.update({"page": page})
|
||||
r = requests.post(url, params=params, json={}, verify=False, headers=headers)
|
||||
data_json = r.json()
|
||||
temp_df = pd.DataFrame(data_json["content"])
|
||||
big_df = pd.concat(objs=[big_df, temp_df], ignore_index=True)
|
||||
keys_list = [
|
||||
"managerName",
|
||||
"memberBehalf",
|
||||
"memberType",
|
||||
"memberCode",
|
||||
"memberDate",
|
||||
"primaryInvestType",
|
||||
] # 定义要取的 value 的 keys
|
||||
manager_data_out = pd.DataFrame(big_df)
|
||||
manager_data_out = manager_data_out[keys_list]
|
||||
manager_data_out.columns = [
|
||||
"机构(会员)名称",
|
||||
"会员代表",
|
||||
"会员类型",
|
||||
"会员编号",
|
||||
"入会时间",
|
||||
"公司类型",
|
||||
]
|
||||
manager_data_out["入会时间"] = pd.to_datetime(
|
||||
manager_data_out["入会时间"], unit="ms"
|
||||
).dt.date
|
||||
return manager_data_out
|
||||
|
||||
|
||||
# 中国证券投资基金业协会-信息公示-基金产品
|
||||
# 中国证券投资基金业协会-信息公示-基金产品-私募基金管理人基金产品
|
||||
def amac_fund_info(start_page: str = "1", end_page: str = "2000") -> pd.DataFrame:
|
||||
"""
|
||||
中国证券投资基金业协会-信息公示-基金产品-私募基金管理人基金产品
|
||||
https://gs.amac.org.cn/amac-infodisc/res/pof/fund/index.html
|
||||
:param start_page: 开始页码, 获取指定页码直接的数据
|
||||
:type start_page: str
|
||||
:param end_page: 结束页码, 获取指定页码直接的数据
|
||||
:type end_page: str
|
||||
:return: 私募基金管理人基金产品
|
||||
:rtype: pandas.DataFrame
|
||||
"""
|
||||
url = "https://gs.amac.org.cn/amac-infodisc/api/pof/fund"
|
||||
params = {
|
||||
"rand": "0.7665138514630696",
|
||||
"page": "1",
|
||||
"size": "100",
|
||||
}
|
||||
r = requests.post(url, params=params, json={}, verify=False, headers=headers)
|
||||
data_json = r.json()
|
||||
total_page = int(data_json["totalPages"])
|
||||
if total_page > int(end_page):
|
||||
real_end_page = int(end_page)
|
||||
else:
|
||||
real_end_page = total_page
|
||||
big_df = pd.DataFrame()
|
||||
tqdm = get_tqdm()
|
||||
for page in tqdm(range(int(start_page) - 1, real_end_page), leave=False):
|
||||
params.update({"page": page})
|
||||
r = requests.post(url, params=params, json={}, verify=False, headers=headers)
|
||||
data_json = r.json()
|
||||
temp_df = pd.DataFrame(data_json["content"])
|
||||
big_df = pd.concat(objs=[big_df, temp_df], ignore_index=True)
|
||||
keys_list = [
|
||||
"fundName",
|
||||
"managerName",
|
||||
"managerType",
|
||||
"workingState",
|
||||
"putOnRecordDate",
|
||||
"establishDate",
|
||||
"mandatorName",
|
||||
] # 定义要取的 value 的 keys
|
||||
manager_data_out = big_df[keys_list].copy()
|
||||
manager_data_out.columns = [
|
||||
"基金名称",
|
||||
"私募基金管理人名称",
|
||||
"私募基金管理人类型",
|
||||
"运行状态",
|
||||
"备案时间",
|
||||
"建立时间",
|
||||
"托管人名称",
|
||||
]
|
||||
manager_data_out["建立时间"] = pd.to_datetime(
|
||||
manager_data_out["建立时间"], unit="ms"
|
||||
).dt.date
|
||||
manager_data_out["备案时间"] = pd.to_datetime(
|
||||
manager_data_out["备案时间"], unit="ms"
|
||||
).dt.date
|
||||
return manager_data_out
|
||||
|
||||
|
||||
# 中国证券投资基金业协会-信息公示-基金产品-证券公司集合资管产品公示
|
||||
def amac_securities_info() -> pd.DataFrame:
|
||||
"""
|
||||
中国证券投资基金业协会-信息公示-基金产品公示-证券公司集合资管产品公示
|
||||
https://gs.amac.org.cn/amac-infodisc/res/pof/securities/index.html
|
||||
:return: 证券公司集合资管产品公示
|
||||
:rtype: pandas.DataFrame
|
||||
"""
|
||||
url = "https://gs.amac.org.cn/amac-infodisc/api/pof/securities"
|
||||
params = {
|
||||
"rand": "0.7665138514630696",
|
||||
"page": "1",
|
||||
"size": "100",
|
||||
}
|
||||
r = requests.post(url, params=params, json={}, verify=False, headers=headers)
|
||||
data_json = r.json()
|
||||
total_page = data_json["totalPages"]
|
||||
big_df = pd.DataFrame()
|
||||
tqdm = get_tqdm()
|
||||
for page in tqdm(range(0, int(total_page)), leave=False):
|
||||
params.update({"page": page})
|
||||
r = requests.post(url, params=params, json={}, verify=False, headers=headers)
|
||||
data_json = r.json()
|
||||
temp_df = pd.DataFrame(data_json["content"])
|
||||
big_df = pd.concat(objs=[big_df, temp_df], ignore_index=True)
|
||||
keys_list = [
|
||||
"cpmc",
|
||||
"cpbm",
|
||||
"gljg",
|
||||
"slrq",
|
||||
"dqr",
|
||||
"tzlx",
|
||||
"sffj",
|
||||
"tgjg",
|
||||
"barq",
|
||||
"yzzt",
|
||||
] # 定义要取的 value 的 keys
|
||||
manager_data_out = pd.DataFrame(big_df)
|
||||
manager_data_out = manager_data_out[keys_list]
|
||||
manager_data_out.columns = [
|
||||
"产品名称",
|
||||
"产品编码",
|
||||
"管理人名称",
|
||||
"成立日期",
|
||||
"到期时间",
|
||||
"投资类型",
|
||||
"是否分级",
|
||||
"托管人名称",
|
||||
"备案日期",
|
||||
"运作状态",
|
||||
]
|
||||
return manager_data_out
|
||||
|
||||
|
||||
# 中国证券投资基金业协会-信息公示-基金产品-证券公司直投基金
|
||||
def amac_aoin_info() -> pd.DataFrame:
|
||||
"""
|
||||
中国证券投资基金业协会-信息公示-基金产品公示-证券公司直投基金
|
||||
https://gs.amac.org.cn/amac-infodisc/res/aoin/product/index.html
|
||||
:return: 证券公司直投基金
|
||||
:rtype: pandas.DataFrame
|
||||
"""
|
||||
url = "https://gs.amac.org.cn/amac-infodisc/api/aoin/product"
|
||||
params = {
|
||||
"rand": "0.7665138514630696",
|
||||
"page": "1",
|
||||
"size": "100",
|
||||
}
|
||||
r = requests.post(url, params=params, json={}, verify=False, headers=headers)
|
||||
data_json = r.json()
|
||||
total_page = data_json["totalPages"]
|
||||
big_df = pd.DataFrame()
|
||||
tqdm = get_tqdm()
|
||||
for page in tqdm(range(0, int(total_page)), leave=False):
|
||||
params.update({"page": page})
|
||||
r = requests.post(url, params=params, json={}, verify=False, headers=headers)
|
||||
data_json = r.json()
|
||||
temp_df = pd.DataFrame(data_json["content"])
|
||||
big_df = pd.concat(objs=[big_df, temp_df], ignore_index=True)
|
||||
keys_list = [
|
||||
"code",
|
||||
"name",
|
||||
"aoinName",
|
||||
"managerName",
|
||||
"createDate",
|
||||
] # 定义要取的 value 的 keys
|
||||
manager_data_out = pd.DataFrame(big_df)
|
||||
manager_data_out = manager_data_out[keys_list]
|
||||
manager_data_out.columns = [
|
||||
"产品编码",
|
||||
"产品名称",
|
||||
"直投子公司",
|
||||
"管理机构",
|
||||
"设立日期",
|
||||
]
|
||||
manager_data_out["设立日期"] = pd.to_datetime(
|
||||
manager_data_out["设立日期"], unit="ms"
|
||||
).dt.date
|
||||
return manager_data_out
|
||||
|
||||
|
||||
# 中国证券投资基金业协会-信息公示-基金产品公示-证券公司私募投资基金
|
||||
def amac_fund_sub_info() -> pd.DataFrame:
|
||||
"""
|
||||
中国证券投资基金业协会-信息公示-基金产品公示-证券公司私募投资基金
|
||||
https://gs.amac.org.cn/amac-infodisc/res/pof/subfund/index.html
|
||||
:return: 证券公司私募投资基金
|
||||
:rtype: pandas.DataFrame
|
||||
"""
|
||||
url = "https://gs.amac.org.cn/amac-infodisc/api/pof/subfund"
|
||||
params = {
|
||||
"rand": "0.7665138514630696",
|
||||
"page": "1",
|
||||
"size": "100",
|
||||
}
|
||||
r = requests.post(url, params=params, json={}, verify=False, headers=headers)
|
||||
data_json = r.json()
|
||||
total_page = data_json["totalPages"]
|
||||
big_df = pd.DataFrame()
|
||||
tqdm = get_tqdm()
|
||||
for page in tqdm(range(0, int(total_page)), leave=False):
|
||||
params.update({"page": page})
|
||||
r = requests.post(url, params=params, json={}, verify=False, headers=headers)
|
||||
data_json = r.json()
|
||||
temp_df = pd.DataFrame(data_json["content"])
|
||||
big_df = pd.concat(objs=[big_df, temp_df], ignore_index=True)
|
||||
keys_list = [
|
||||
"productCode",
|
||||
"productName",
|
||||
"mgrName",
|
||||
"trustee",
|
||||
"foundDate",
|
||||
"registeredDate",
|
||||
] # 定义要取的 value 的 keys
|
||||
manager_data_out = pd.DataFrame(big_df)
|
||||
manager_data_out = manager_data_out[keys_list]
|
||||
manager_data_out.columns = [
|
||||
"产品编码",
|
||||
"产品名称",
|
||||
"私募基金管理人名称",
|
||||
"托管人名称",
|
||||
"成立日期",
|
||||
"备案日期",
|
||||
]
|
||||
manager_data_out["备案日期"] = pd.to_datetime(
|
||||
manager_data_out["备案日期"], unit="ms"
|
||||
).dt.date
|
||||
manager_data_out["成立日期"] = pd.to_datetime(
|
||||
manager_data_out["成立日期"], unit="ms"
|
||||
).dt.date
|
||||
return manager_data_out
|
||||
|
||||
|
||||
# 中国证券投资基金业协会-信息公示-基金产品公示-基金公司及子公司集合资管产品公示
|
||||
def amac_fund_account_info() -> pd.DataFrame:
|
||||
"""
|
||||
中国证券投资基金业协会-信息公示-基金产品公示-基金公司及子公司集合资管产品公示
|
||||
https://gs.amac.org.cn/amac-infodisc/res/fund/account/index.html
|
||||
:return: 基金公司及子公司集合资管产品公示
|
||||
:rtype: pandas.DataFrame
|
||||
"""
|
||||
import warnings
|
||||
|
||||
warnings.filterwarnings(action="ignore", category=FutureWarning)
|
||||
|
||||
url = "https://gs.amac.org.cn/amac-infodisc/api/fund/account"
|
||||
params = {
|
||||
"rand": "0.7665138514630696",
|
||||
"page": "1",
|
||||
"size": "100",
|
||||
}
|
||||
r = requests.post(url, params=params, json={}, verify=False, headers=headers)
|
||||
data_json = r.json()
|
||||
total_page = data_json["totalPages"]
|
||||
big_df = pd.DataFrame()
|
||||
tqdm = get_tqdm()
|
||||
for page in tqdm(range(0, int(total_page)), leave=False):
|
||||
params.update({"page": page})
|
||||
r = requests.post(url, params=params, json={}, verify=False, headers=headers)
|
||||
data_json = r.json()
|
||||
temp_df = pd.DataFrame(data_json["content"])
|
||||
big_df = pd.concat(objs=[big_df, temp_df], ignore_index=True)
|
||||
keys_list = [
|
||||
"registerDate",
|
||||
"registerCode",
|
||||
"name",
|
||||
"manager",
|
||||
] # 定义要取的 value 的 keys
|
||||
manager_data_out = pd.DataFrame(big_df)
|
||||
manager_data_out = manager_data_out[keys_list]
|
||||
manager_data_out.columns = [
|
||||
"成立日期",
|
||||
"产品编码",
|
||||
"产品名称",
|
||||
"管理人名称",
|
||||
]
|
||||
manager_data_out["成立日期"] = pd.to_datetime(
|
||||
manager_data_out["成立日期"], unit="ms"
|
||||
).dt.date
|
||||
return manager_data_out
|
||||
|
||||
|
||||
# 中国证券投资基金业协会-信息公示-基金产品公示-资产支持专项计划
|
||||
def amac_fund_abs() -> pd.DataFrame:
|
||||
"""
|
||||
中国证券投资基金业协会-信息公示-基金产品公示-资产支持专项计划公示信息
|
||||
https://gs.amac.org.cn/amac-infodisc/res/fund/abs/index.html
|
||||
:return: 资产支持专项计划公示信息
|
||||
:rtype: pandas.DataFrame
|
||||
"""
|
||||
url = "https://gs.amac.org.cn/amac-infodisc/api/fund/abs"
|
||||
params = {
|
||||
"rand": "0.7665138514630696",
|
||||
"page": "1",
|
||||
"size": "100",
|
||||
}
|
||||
r = requests.post(url, params=params, json={}, verify=False, headers=headers)
|
||||
data_json = r.json()
|
||||
total_page = data_json["totalPages"]
|
||||
big_df = pd.DataFrame()
|
||||
tqdm = get_tqdm()
|
||||
for page in tqdm(range(0, int(total_page)), leave=False):
|
||||
params.update({"page": page})
|
||||
r = requests.post(url, params=params, json={}, verify=False, headers=headers)
|
||||
data_json = r.json()
|
||||
temp_df = pd.DataFrame(data_json["content"])
|
||||
big_df = pd.concat(objs=[big_df, temp_df], ignore_index=True)
|
||||
big_df.reset_index(inplace=True)
|
||||
big_df["index"] = range(1, len(big_df) + 1)
|
||||
big_df.columns = [
|
||||
"编号",
|
||||
"_",
|
||||
"_",
|
||||
"专项计划全称",
|
||||
"备案编号",
|
||||
"管理人",
|
||||
"托管人",
|
||||
"备案通过时间",
|
||||
"成立日期",
|
||||
"预期到期时间",
|
||||
]
|
||||
big_df["备案通过时间"] = pd.to_datetime(big_df["备案通过时间"], unit="ms").dt.date
|
||||
big_df["成立日期"] = pd.to_datetime(big_df["成立日期"], unit="ms").dt.date
|
||||
big_df["预期到期时间"] = pd.to_datetime(
|
||||
big_df["预期到期时间"], unit="ms", errors="coerce"
|
||||
).dt.date
|
||||
big_df = big_df[
|
||||
[
|
||||
"编号",
|
||||
"备案编号",
|
||||
"专项计划全称",
|
||||
"管理人",
|
||||
"托管人",
|
||||
"成立日期",
|
||||
"预期到期时间",
|
||||
"备案通过时间",
|
||||
]
|
||||
]
|
||||
return big_df
|
||||
|
||||
|
||||
# 中国证券投资基金业协会-信息公示-基金产品公示-期货公司集合资管产品公示
|
||||
def amac_futures_info() -> pd.DataFrame:
|
||||
"""
|
||||
中国证券投资基金业协会-信息公示-基金产品公示-期货公司集合资管产品公示
|
||||
https://gs.amac.org.cn/amac-infodisc/res/pof/futures/index.html
|
||||
:return: 期货公司集合资管产品公示
|
||||
:rtype: pandas.DataFrame
|
||||
"""
|
||||
url = "https://gs.amac.org.cn/amac-infodisc/api/pof/futures"
|
||||
params = {
|
||||
"rand": "0.7665138514630696",
|
||||
"page": "1",
|
||||
"size": "100",
|
||||
}
|
||||
r = requests.post(url, params=params, json={}, verify=False, headers=headers)
|
||||
data_json = r.json()
|
||||
total_page = data_json["totalPages"]
|
||||
big_df = pd.DataFrame()
|
||||
tqdm = get_tqdm()
|
||||
for page in tqdm(range(0, int(total_page)), leave=False):
|
||||
params.update({"page": page})
|
||||
r = requests.post(url, params=params, json={}, verify=False, headers=headers)
|
||||
data_json = r.json()
|
||||
temp_df = pd.DataFrame(data_json["content"])
|
||||
big_df = pd.concat(objs=[big_df, temp_df], ignore_index=True)
|
||||
keys_list = [
|
||||
"mpiName",
|
||||
"mpiProductCode",
|
||||
"aoiName",
|
||||
"mpiTrustee",
|
||||
"mpiCreateDate",
|
||||
"tzlx",
|
||||
"sfjgh",
|
||||
"registeredDate",
|
||||
"dueDate",
|
||||
"fundStatus",
|
||||
] # 定义要取的 value 的 keys
|
||||
manager_data_out = pd.DataFrame(big_df)
|
||||
manager_data_out = manager_data_out[keys_list]
|
||||
manager_data_out.columns = [
|
||||
"产品名称",
|
||||
"产品编码",
|
||||
"管理人名称",
|
||||
"托管人名称",
|
||||
"成立日期",
|
||||
"投资类型",
|
||||
"是否分级",
|
||||
"备案日期",
|
||||
"到期日",
|
||||
"运作状态",
|
||||
]
|
||||
return manager_data_out
|
||||
|
||||
|
||||
# 中国证券投资基金业协会-信息公示-诚信信息
|
||||
# 中国证券投资基金业协会-信息公示-诚信信息-已注销私募基金管理人名单
|
||||
def amac_manager_cancelled_info() -> pd.DataFrame:
|
||||
"""
|
||||
中国证券投资基金业协会-信息公示-诚信信息公示-已注销私募基金管理人名单
|
||||
https://gs.amac.org.cn/amac-infodisc/res/cancelled/manager/index.html
|
||||
主动注销: 100
|
||||
依公告注销: 200
|
||||
协会注销: 300
|
||||
:return: 已注销私募基金管理人名单
|
||||
:rtype: pandas.DataFrame
|
||||
"""
|
||||
url = "https://gs.amac.org.cn/amac-infodisc/api/cancelled/manager"
|
||||
params = {
|
||||
"rand": "0.7665138514630696",
|
||||
"page": "1",
|
||||
"size": "100",
|
||||
}
|
||||
r = requests.post(url, params=params, json={}, verify=False, headers=headers)
|
||||
data_json = r.json()
|
||||
total_page = data_json["totalPages"]
|
||||
big_df = pd.DataFrame()
|
||||
tqdm = get_tqdm()
|
||||
for page in tqdm(range(0, int(total_page)), leave=False):
|
||||
params.update({"page": page})
|
||||
r = requests.post(url, params=params, json={}, verify=False, headers=headers)
|
||||
data_json = r.json()
|
||||
temp_df = pd.DataFrame(data_json["content"])
|
||||
big_df = pd.concat(objs=[big_df, temp_df], ignore_index=True)
|
||||
keys_list = [
|
||||
"orgName",
|
||||
"orgCode",
|
||||
"orgSignDate",
|
||||
"cancelDate",
|
||||
"status",
|
||||
] # 定义要取的 value 的 keys
|
||||
manager_data_out = pd.DataFrame(big_df)
|
||||
manager_data_out = manager_data_out[keys_list]
|
||||
manager_data_out.columns = [
|
||||
"管理人名称",
|
||||
"统一社会信用代码",
|
||||
"登记时间",
|
||||
"注销时间",
|
||||
"注销类型",
|
||||
]
|
||||
manager_data_out["登记时间"] = pd.to_datetime(
|
||||
manager_data_out["登记时间"], unit="ms"
|
||||
).dt.date
|
||||
manager_data_out["注销时间"] = pd.to_datetime(
|
||||
manager_data_out["注销时间"], unit="ms"
|
||||
).dt.date
|
||||
manager_data_out.sort_values(["注销时间"], ignore_index=True, inplace=True)
|
||||
return manager_data_out
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
# 中国证券投资基金业协会-信息公示-会员信息
|
||||
# 中国证券投资基金业协会-信息公示-会员信息-会员机构综合查询
|
||||
amac_member_info_df = amac_member_info()
|
||||
print(amac_member_info_df)
|
||||
|
||||
# 中国证券投资基金业协会-信息公示-从业人员信息
|
||||
# 中国证券投资基金业协会-信息公示-从业人员信息-基金从业人员资格注册信息
|
||||
amac_person_fund_org_list_df = amac_person_fund_org_list(symbol="公募基金管理公司")
|
||||
print(amac_person_fund_org_list_df)
|
||||
|
||||
# 中国证券投资基金业协会-信息公示-从业人员信息
|
||||
# 中国证券投资基金业协会-信息公示-从业人员信息-债券投资交易相关人员公示
|
||||
amac_person_bond_org_list_df = amac_person_bond_org_list()
|
||||
print(amac_person_bond_org_list_df)
|
||||
|
||||
# 中国证券投资基金业协会-信息公示-私募基金管理人公示
|
||||
# 中国证券投资基金业协会-信息公示-私募基金管理人公示-私募基金管理人综合查询
|
||||
amac_manager_info_df = amac_manager_info()
|
||||
print(amac_manager_info_df)
|
||||
|
||||
# 中国证券投资基金业协会-信息公示-私募基金管理人公示-私募基金管理人分类公示
|
||||
amac_manager_classify_info_df = amac_manager_classify_info()
|
||||
print(amac_manager_classify_info_df)
|
||||
|
||||
# 中国证券投资基金业协会-信息公示-私募基金管理人公示-证券公司私募基金子公司管理人信息公示
|
||||
amac_member_sub_info_df = amac_member_sub_info()
|
||||
print(amac_member_sub_info_df)
|
||||
|
||||
# 中国证券投资基金业协会-信息公示-基金产品
|
||||
# 中国证券投资基金业协会-信息公示-基金产品-私募基金管理人基金产品
|
||||
amac_fund_info_df = amac_fund_info(start_page="1", end_page="100")
|
||||
print(amac_fund_info_df)
|
||||
|
||||
example_df = amac_fund_info_df[
|
||||
amac_fund_info_df["私募基金管理人名称"].str.contains("聚宽")
|
||||
]
|
||||
print(example_df)
|
||||
|
||||
# 中国证券投资基金业协会-信息公示-基金产品-证券公司集合资管产品公示
|
||||
amac_securities_info_df = amac_securities_info()
|
||||
print(amac_securities_info_df)
|
||||
|
||||
# 中国证券投资基金业协会-信息公示-基金产品-证券公司直投基金
|
||||
amac_aoin_info_df = amac_aoin_info()
|
||||
print(amac_aoin_info_df)
|
||||
|
||||
# 中国证券投资基金业协会-信息公示-基金产品公示-证券公司私募投资基金
|
||||
amac_fund_sub_info_df = amac_fund_sub_info()
|
||||
print(amac_fund_sub_info_df)
|
||||
|
||||
# 中国证券投资基金业协会-信息公示-基金产品公示-基金公司及子公司集合资管产品公示
|
||||
amac_fund_account_info_df = amac_fund_account_info()
|
||||
print(amac_fund_account_info_df)
|
||||
|
||||
# 中国证券投资基金业协会-信息公示-基金产品公示-资产支持专项计划
|
||||
amac_fund_abs_df = amac_fund_abs()
|
||||
print(amac_fund_abs_df)
|
||||
|
||||
# 中国证券投资基金业协会-信息公示-基金产品公示-期货公司集合资管产品公示
|
||||
amac_futures_info_df = amac_futures_info()
|
||||
print(amac_futures_info_df)
|
||||
|
||||
# 中国证券投资基金业协会-信息公示-诚信信息
|
||||
# 中国证券投资基金业协会-信息公示-诚信信息-已注销私募基金管理人名单
|
||||
amac_manager_cancelled_info_df = amac_manager_cancelled_info()
|
||||
print(amac_manager_cancelled_info_df)
|
||||
@@ -0,0 +1,145 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding:utf-8 -*-
|
||||
"""
|
||||
Date: 2025/9/20 17:40
|
||||
Desc: 东方财富网站-天天基金网-基金档案-基金公告
|
||||
https://fundf10.eastmoney.com/jjgg_000001.html
|
||||
"""
|
||||
|
||||
import time
|
||||
|
||||
import pandas as pd
|
||||
import requests
|
||||
|
||||
|
||||
def fund_announcement_dividend_em(symbol: str = "000001") -> pd.DataFrame:
|
||||
"""
|
||||
东方财富网站-天天基金网-基金档案-基金公告-分红配送
|
||||
https://fundf10.eastmoney.com/jjgg_000001_2.html
|
||||
:param symbol: 基金代码; 可以通过调用 ak.fund_name_em() 接口获取
|
||||
:type symbol: str
|
||||
:return: 分红配送-公告列表
|
||||
:rtype: pandas.DataFrame
|
||||
"""
|
||||
url = "http://api.fund.eastmoney.com/f10/JJGG"
|
||||
headers = {
|
||||
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "
|
||||
"Chrome/80.0.3987.149 Safari/537.36",
|
||||
"Referer": f"http://fundf10.eastmoney.com/jjgg_{symbol}_2.html",
|
||||
}
|
||||
params = {
|
||||
"fundcode": symbol,
|
||||
"pageIndex": "1",
|
||||
"pageSize": "1000",
|
||||
"type": "2",
|
||||
"_": round(time.time() * 1000),
|
||||
}
|
||||
r = requests.get(url, params=params, headers=headers)
|
||||
data_json = r.json()
|
||||
temp_df = pd.DataFrame(data_json["Data"])
|
||||
temp_df.columns = [
|
||||
"基金代码",
|
||||
"公告标题",
|
||||
"基金名称",
|
||||
"_",
|
||||
"_",
|
||||
"公告日期",
|
||||
"_",
|
||||
"报告ID",
|
||||
]
|
||||
temp_df = temp_df[["基金代码", "公告标题", "基金名称", "公告日期", "报告ID"]]
|
||||
temp_df.sort_values(by=["公告日期"], inplace=True, ignore_index=True)
|
||||
temp_df["公告日期"] = pd.to_datetime(temp_df["公告日期"], errors="coerce").dt.date
|
||||
return temp_df
|
||||
|
||||
|
||||
def fund_announcement_report_em(symbol: str = "000001") -> pd.DataFrame:
|
||||
"""
|
||||
东方财富网站-天天基金网-基金档案-基金公告-定期报告
|
||||
https://fundf10.eastmoney.com/jjgg_000001_3.html
|
||||
:param symbol: 基金代码; 可以通过调用 ak.fund_name_em() 接口获取
|
||||
:type symbol: str
|
||||
:return: 定期报告-公告列表
|
||||
:rtype: pandas.DataFrame
|
||||
"""
|
||||
url = "http://api.fund.eastmoney.com/f10/JJGG"
|
||||
headers = {
|
||||
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "
|
||||
"Chrome/80.0.3987.149 Safari/537.36",
|
||||
"Referer": f"http://fundf10.eastmoney.com/jjgg_{symbol}_3.html",
|
||||
}
|
||||
params = {
|
||||
"fundcode": symbol,
|
||||
"pageIndex": "1",
|
||||
"pageSize": "1000",
|
||||
"type": "3",
|
||||
"_": round(time.time() * 1000),
|
||||
}
|
||||
r = requests.get(url, params=params, headers=headers)
|
||||
data_json = r.json()
|
||||
temp_df = pd.DataFrame(data_json["Data"])
|
||||
temp_df.columns = [
|
||||
"基金代码",
|
||||
"公告标题",
|
||||
"基金名称",
|
||||
"_",
|
||||
"_",
|
||||
"公告日期",
|
||||
"_",
|
||||
"报告ID",
|
||||
]
|
||||
temp_df = temp_df[["基金代码", "公告标题", "基金名称", "公告日期", "报告ID"]]
|
||||
temp_df.sort_values(by=["公告日期"], inplace=True, ignore_index=True)
|
||||
temp_df["公告日期"] = pd.to_datetime(temp_df["公告日期"], errors="coerce").dt.date
|
||||
return temp_df
|
||||
|
||||
|
||||
def fund_announcement_personnel_em(symbol: str = "000001") -> pd.DataFrame:
|
||||
"""
|
||||
东方财富网站-天天基金网-基金档案-基金公告-人事调整
|
||||
https://fundf10.eastmoney.com/jjgg_000001_4.html
|
||||
:param symbol: 基金代码; 可以通过调用 ak.fund_name_em() 接口获取
|
||||
:type symbol: str
|
||||
:return: 人事调整-公告列表
|
||||
:rtype: pandas.DataFrame
|
||||
"""
|
||||
url = "http://api.fund.eastmoney.com/f10/JJGG"
|
||||
headers = {
|
||||
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.149 Safari/537.36",
|
||||
"Referer": f"http://fundf10.eastmoney.com/jjgg_{symbol}_4.html",
|
||||
}
|
||||
params = {
|
||||
"fundcode": symbol,
|
||||
"pageIndex": "1",
|
||||
"pageSize": "1000",
|
||||
"type": "4",
|
||||
"_": round(time.time() * 1000),
|
||||
}
|
||||
r = requests.get(url, params=params, headers=headers)
|
||||
data_json = r.json()
|
||||
temp_df = pd.DataFrame(data_json["Data"])
|
||||
temp_df.columns = [
|
||||
"基金代码",
|
||||
"公告标题",
|
||||
"基金名称",
|
||||
"_",
|
||||
"_",
|
||||
"公告日期",
|
||||
"_",
|
||||
"报告ID",
|
||||
]
|
||||
temp_df = temp_df[["基金代码", "公告标题", "基金名称", "公告日期", "报告ID"]]
|
||||
temp_df.sort_values(by=["公告日期"], inplace=True, ignore_index=True)
|
||||
temp_df["公告日期"] = pd.to_datetime(temp_df["公告日期"], errors="coerce").dt.date
|
||||
return temp_df
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
fund_announcement_dividend_em_df = fund_announcement_dividend_em(symbol="000001")
|
||||
print(fund_announcement_dividend_em_df)
|
||||
|
||||
fund_announcement_report_em_df = fund_announcement_report_em(symbol="000001")
|
||||
print(fund_announcement_report_em_df)
|
||||
|
||||
fund_announcement_personnel_em_df = fund_announcement_personnel_em(symbol="000001")
|
||||
print(fund_announcement_personnel_em_df)
|
||||
@@ -0,0 +1,106 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding:utf-8 -*-
|
||||
"""
|
||||
Date: 2023/11/11 16:30
|
||||
Desc: 东方财富-基金
|
||||
"""
|
||||
|
||||
from io import StringIO
|
||||
|
||||
import pandas as pd
|
||||
import requests
|
||||
|
||||
|
||||
def fund_aum_em() -> pd.DataFrame:
|
||||
"""
|
||||
东方财富-基金-基金公司排名列表
|
||||
https://fund.eastmoney.com/Company/lsgm.html
|
||||
:return: 基金公司排名列表
|
||||
:rtype: pandas.DataFrame
|
||||
"""
|
||||
url = "https://fund.eastmoney.com/Company/home/gspmlist"
|
||||
params = {"fundType": "0"}
|
||||
r = requests.get(url, params=params)
|
||||
temp_df = pd.read_html(StringIO(r.text))[0]
|
||||
del temp_df["相关链接"]
|
||||
del temp_df["天相评级"]
|
||||
temp_df.columns = [
|
||||
"序号",
|
||||
"基金公司",
|
||||
"成立时间",
|
||||
"全部管理规模",
|
||||
"全部基金数",
|
||||
"全部经理数",
|
||||
]
|
||||
expanded_df = temp_df["全部管理规模"].str.split(" ", expand=True)
|
||||
temp_df["全部管理规模"] = expanded_df.iloc[:, 0].str.replace(",", "")
|
||||
temp_df["更新日期"] = expanded_df.iloc[:, 1]
|
||||
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
|
||||
return temp_df
|
||||
|
||||
|
||||
def fund_aum_trend_em() -> pd.DataFrame:
|
||||
"""
|
||||
东方财富-基金-基金市场管理规模走势图
|
||||
https://fund.eastmoney.com/Company/default.html
|
||||
:return: 基金市场管理规模走势图
|
||||
:rtype: pandas.DataFrame
|
||||
"""
|
||||
url = "https://fund.eastmoney.com/Company/home/GetFundTotalScaleForChart"
|
||||
payload = {"fundType": "0"}
|
||||
r = requests.get(url, data=payload)
|
||||
data_json = r.json()
|
||||
temp_df = pd.DataFrame()
|
||||
temp_df["date"] = data_json["x"]
|
||||
temp_df["value"] = data_json["y"]
|
||||
temp_df["date"] = pd.to_datetime(temp_df["date"], errors="coerce").dt.date
|
||||
temp_df["value"] = pd.to_numeric(temp_df["value"], errors="coerce")
|
||||
return temp_df
|
||||
|
||||
|
||||
def fund_aum_hist_em(year: str = "2023") -> pd.DataFrame:
|
||||
"""
|
||||
东方财富-基金-基金公司历年管理规模排行列表
|
||||
https://fund.eastmoney.com/Company/lsgm.html
|
||||
:param year: query year
|
||||
:type year: str
|
||||
:return: 基金公司历年管理规模排行列表
|
||||
:rtype: pandas.DataFrame
|
||||
"""
|
||||
url = "https://fund.eastmoney.com/Company/home/HistoryScaleTable"
|
||||
params = {"year": year}
|
||||
r = requests.get(url, params=params)
|
||||
temp_df = pd.read_html(StringIO(r.text))[0]
|
||||
temp_df.columns = [
|
||||
"序号",
|
||||
"基金公司",
|
||||
"总规模",
|
||||
"股票型",
|
||||
"混合型",
|
||||
"债券型",
|
||||
"指数型",
|
||||
"QDII",
|
||||
"货币型",
|
||||
]
|
||||
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["QDII"] = pd.to_numeric(temp_df["QDII"], errors="coerce")
|
||||
temp_df["货币型"] = pd.to_numeric(temp_df["货币型"], errors="coerce")
|
||||
return temp_df
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
fund_aum_em_df = fund_aum_em()
|
||||
print(fund_aum_em_df)
|
||||
|
||||
fund_aum_trend_em_df = fund_aum_trend_em()
|
||||
print(fund_aum_trend_em_df)
|
||||
|
||||
fund_em_aum_hist_df = fund_aum_hist_em(year="2023")
|
||||
print(fund_em_aum_hist_df)
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,497 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding:utf-8 -*-
|
||||
"""
|
||||
Date: 2025/4/27 00:00
|
||||
Desc: 东方财富-ETF行情
|
||||
https://quote.eastmoney.com/sh513500.html
|
||||
"""
|
||||
|
||||
from functools import lru_cache
|
||||
|
||||
import pandas as pd
|
||||
import requests
|
||||
|
||||
from akshare.utils.func import fetch_paginated_data
|
||||
|
||||
|
||||
@lru_cache()
|
||||
def _fund_etf_code_id_map_em() -> dict:
|
||||
"""
|
||||
东方财富-ETF代码和市场标识映射
|
||||
https://quote.eastmoney.com/center/gridlist.html#fund_etf
|
||||
:return: ETF 代码和市场标识映射
|
||||
:rtype: dict
|
||||
"""
|
||||
url = "https://88.push2.eastmoney.com/api/qt/clist/get"
|
||||
params = {
|
||||
"pn": "1",
|
||||
"pz": "100",
|
||||
"po": "1",
|
||||
"np": "1",
|
||||
"ut": "bd1d9ddb04089700cf9c27f6f7426281",
|
||||
"fltt": "2",
|
||||
"invt": "2",
|
||||
"wbp2u": "|0|0|0|web",
|
||||
"fid": "f3",
|
||||
"fs": "b:MK0021,b:MK0022,b:MK0023,b:MK0024",
|
||||
"fields": "f3,f12,f13",
|
||||
}
|
||||
temp_df = fetch_paginated_data(url, params)
|
||||
temp_dict = dict(zip(temp_df["f12"], temp_df["f13"]))
|
||||
return temp_dict
|
||||
|
||||
|
||||
def fund_etf_spot_em() -> pd.DataFrame:
|
||||
"""
|
||||
东方财富-ETF 实时行情
|
||||
https://quote.eastmoney.com/center/gridlist.html#fund_etf
|
||||
:return: ETF 实时行情
|
||||
:rtype: pandas.DataFrame
|
||||
"""
|
||||
url = "https://push2delay.eastmoney.com/api/qt/clist/get"
|
||||
params = {
|
||||
"pn": "1",
|
||||
"pz": "100",
|
||||
"po": "1",
|
||||
"np": "1",
|
||||
"ut": "bd1d9ddb04089700cf9c27f6f7426281",
|
||||
"fltt": "2",
|
||||
"invt": "2",
|
||||
"wbp2u": "|0|0|0|web",
|
||||
"fid": "f12",
|
||||
"fs": "b:MK0021,b:MK0022,b:MK0023,b:MK0024,b:MK0827",
|
||||
"fields": (
|
||||
"f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,"
|
||||
"f12,f13,f14,f15,f16,f17,f18,f20,f21,"
|
||||
"f23,f24,f25,f22,f11,f30,f31,f32,f33,"
|
||||
"f34,f35,f38,f62,f63,f64,f65,f66,f69,"
|
||||
"f72,f75,f78,f81,f84,f87,f115,f124,f128,"
|
||||
"f136,f152,f184,f297,f402,f441"
|
||||
),
|
||||
}
|
||||
temp_df = fetch_paginated_data(url, params)
|
||||
temp_df.rename(
|
||||
columns={
|
||||
"f12": "代码",
|
||||
"f14": "名称",
|
||||
"f2": "最新价",
|
||||
"f4": "涨跌额",
|
||||
"f3": "涨跌幅",
|
||||
"f5": "成交量",
|
||||
"f6": "成交额",
|
||||
"f7": "振幅",
|
||||
"f17": "开盘价",
|
||||
"f15": "最高价",
|
||||
"f16": "最低价",
|
||||
"f18": "昨收",
|
||||
"f8": "换手率",
|
||||
"f10": "量比",
|
||||
"f30": "现手",
|
||||
"f31": "买一",
|
||||
"f32": "卖一",
|
||||
"f33": "委比",
|
||||
"f34": "外盘",
|
||||
"f35": "内盘",
|
||||
"f62": "主力净流入-净额",
|
||||
"f184": "主力净流入-净占比",
|
||||
"f66": "超大单净流入-净额",
|
||||
"f69": "超大单净流入-净占比",
|
||||
"f72": "大单净流入-净额",
|
||||
"f75": "大单净流入-净占比",
|
||||
"f78": "中单净流入-净额",
|
||||
"f81": "中单净流入-净占比",
|
||||
"f84": "小单净流入-净额",
|
||||
"f87": "小单净流入-净占比",
|
||||
"f38": "最新份额",
|
||||
"f21": "流通市值",
|
||||
"f20": "总市值",
|
||||
"f402": "基金折价率",
|
||||
"f441": "IOPV实时估值",
|
||||
"f297": "数据日期",
|
||||
"f124": "更新时间",
|
||||
},
|
||||
inplace=True,
|
||||
)
|
||||
temp_df = temp_df[
|
||||
[
|
||||
"代码",
|
||||
"名称",
|
||||
"最新价",
|
||||
"IOPV实时估值",
|
||||
"基金折价率",
|
||||
"涨跌额",
|
||||
"涨跌幅",
|
||||
"成交量",
|
||||
"成交额",
|
||||
"开盘价",
|
||||
"最高价",
|
||||
"最低价",
|
||||
"昨收",
|
||||
"振幅",
|
||||
"换手率",
|
||||
"量比",
|
||||
"委比",
|
||||
"外盘",
|
||||
"内盘",
|
||||
"主力净流入-净额",
|
||||
"主力净流入-净占比",
|
||||
"超大单净流入-净额",
|
||||
"超大单净流入-净占比",
|
||||
"大单净流入-净额",
|
||||
"大单净流入-净占比",
|
||||
"中单净流入-净额",
|
||||
"中单净流入-净占比",
|
||||
"小单净流入-净额",
|
||||
"小单净流入-净占比",
|
||||
"现手",
|
||||
"买一",
|
||||
"卖一",
|
||||
"最新份额",
|
||||
"流通市值",
|
||||
"总市值",
|
||||
"数据日期",
|
||||
"更新时间",
|
||||
]
|
||||
]
|
||||
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")
|
||||
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["IOPV实时估值"] = pd.to_numeric(temp_df["IOPV实时估值"], 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["数据日期"], format="%Y%m%d", errors="coerce"
|
||||
)
|
||||
temp_df["更新时间"] = (
|
||||
pd.to_datetime(temp_df["更新时间"], unit="s", errors="coerce")
|
||||
.dt.tz_localize("UTC")
|
||||
.dt.tz_convert("Asia/Shanghai")
|
||||
)
|
||||
return temp_df
|
||||
|
||||
|
||||
def get_market_id(symbol: str) -> int:
|
||||
"""
|
||||
东方财富-ETF市场标识判断
|
||||
:param symbol: ETF 代码
|
||||
:type symbol: str
|
||||
:return: ETF 代码和市场标识(1:上证 0:深证)
|
||||
:rtype: int
|
||||
"""
|
||||
if symbol.startswith(("0", "1", "3", "2", "5", "6")):
|
||||
if symbol.startswith(("5", "6")):
|
||||
return 1
|
||||
else:
|
||||
return 0
|
||||
else:
|
||||
return 1
|
||||
|
||||
|
||||
def fund_etf_hist_em(
|
||||
symbol: str = "159707",
|
||||
period: str = "daily",
|
||||
start_date: str = "19700101",
|
||||
end_date: str = "20500101",
|
||||
adjust: str = "",
|
||||
) -> pd.DataFrame:
|
||||
"""
|
||||
东方财富-ETF行情
|
||||
https://quote.eastmoney.com/sz159707.html
|
||||
:param symbol: ETF 代码
|
||||
:type symbol: str
|
||||
:param period: choice of {'daily', 'weekly', 'monthly'}
|
||||
:type period: str
|
||||
:param start_date: 开始日期
|
||||
:type start_date: str
|
||||
:param end_date: 结束日期
|
||||
:type end_date: str
|
||||
:param adjust: choice of {"qfq": "前复权", "hfq": "后复权", "": "不复权"}
|
||||
:type adjust: str
|
||||
:return: 每日行情
|
||||
:rtype: pandas.DataFrame
|
||||
"""
|
||||
# code_id_dict = _fund_etf_code_id_map_em()
|
||||
adjust_dict = {"qfq": "1", "hfq": "2", "": "0"}
|
||||
period_dict = {"daily": "101", "weekly": "102", "monthly": "103"}
|
||||
url = "https://push2his.eastmoney.com/api/qt/stock/kline/get"
|
||||
params = {
|
||||
"fields1": "f1,f2,f3,f4,f5,f6",
|
||||
"fields2": "f51,f52,f53,f54,f55,f56,f57,f58,f59,f60,f61,f116",
|
||||
"ut": "7eea3edcaed734bea9cbfc24409ed989",
|
||||
"klt": period_dict[period],
|
||||
"fqt": adjust_dict[adjust],
|
||||
"beg": start_date,
|
||||
"end": end_date,
|
||||
}
|
||||
try:
|
||||
# market_id = code_id_dict[symbol]
|
||||
market_id = get_market_id(symbol)
|
||||
params.update({"secid": f"{market_id}.{symbol}"})
|
||||
r = requests.get(url, timeout=15, params=params)
|
||||
data_json = r.json()
|
||||
except KeyError:
|
||||
market_id = 1
|
||||
params.update({"secid": f"{market_id}.{symbol}"})
|
||||
r = requests.get(url, timeout=15, params=params)
|
||||
data_json = r.json()
|
||||
if not data_json["data"]:
|
||||
market_id = 0
|
||||
params.update({"secid": f"{market_id}.{symbol}"})
|
||||
r = requests.get(url, timeout=15, params=params)
|
||||
data_json = r.json()
|
||||
if not (data_json["data"] and data_json["data"]["klines"]):
|
||||
return pd.DataFrame()
|
||||
temp_df = pd.DataFrame([item.split(",") for item in data_json["data"]["klines"]])
|
||||
temp_df.columns = [
|
||||
"日期",
|
||||
"开盘",
|
||||
"收盘",
|
||||
"最高",
|
||||
"最低",
|
||||
"成交量",
|
||||
"成交额",
|
||||
"振幅",
|
||||
"涨跌幅",
|
||||
"涨跌额",
|
||||
"换手率",
|
||||
]
|
||||
temp_df.index = pd.to_datetime(temp_df["日期"], errors="coerce")
|
||||
temp_df.reset_index(inplace=True, drop=True)
|
||||
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 fund_etf_hist_min_em(
|
||||
symbol: str = "159707",
|
||||
start_date: str = "1979-09-01 09:32:00",
|
||||
end_date: str = "2222-01-01 09:32:00",
|
||||
period: str = "5",
|
||||
adjust: str = "",
|
||||
) -> pd.DataFrame:
|
||||
"""
|
||||
东方财富-ETF 行情
|
||||
https://quote.eastmoney.com/sz159707.html
|
||||
:param symbol: ETF 代码
|
||||
:type symbol: str
|
||||
:param start_date: 开始日期
|
||||
:type start_date: str
|
||||
:param end_date: 结束日期
|
||||
:type end_date: str
|
||||
:param period: choice of {"1", "5", "15", "30", "60"}
|
||||
:type period: str
|
||||
:param adjust: choice of {'', 'qfq', 'hfq'}
|
||||
:type adjust: str
|
||||
:return: 每日分时行情
|
||||
:rtype: pandas.DataFrame
|
||||
"""
|
||||
# code_id_dict = _fund_etf_code_id_map_em()
|
||||
# 商品期货类 ETF
|
||||
# code_id_dict.update(
|
||||
# {
|
||||
# "159980": "0",
|
||||
# "159981": "0",
|
||||
# "159985": "0",
|
||||
# "511090": "1",
|
||||
# "511220": "1",
|
||||
# "511380": "1",
|
||||
# }
|
||||
# )
|
||||
adjust_map = {
|
||||
"": "0",
|
||||
"qfq": "1",
|
||||
"hfq": "2",
|
||||
}
|
||||
if period == "1":
|
||||
url = "https://push2his.eastmoney.com/api/qt/stock/trends2/get"
|
||||
params = {
|
||||
"fields1": "f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11,f12,f13",
|
||||
"fields2": "f51,f52,f53,f54,f55,f56,f57,f58",
|
||||
"ut": "7eea3edcaed734bea9cbfc24409ed989",
|
||||
"ndays": "5",
|
||||
"iscr": "0",
|
||||
"secid": f"{get_market_id(symbol)}.{symbol}",
|
||||
}
|
||||
r = requests.get(url, timeout=15, params=params)
|
||||
data_json = r.json()
|
||||
temp_df = pd.DataFrame(
|
||||
[item.split(",") for item in data_json["data"]["trends"]]
|
||||
)
|
||||
temp_df.columns = [
|
||||
"时间",
|
||||
"开盘",
|
||||
"收盘",
|
||||
"最高",
|
||||
"最低",
|
||||
"成交量",
|
||||
"成交额",
|
||||
"均价",
|
||||
]
|
||||
temp_df.index = pd.to_datetime(temp_df["时间"])
|
||||
temp_df = temp_df[start_date:end_date]
|
||||
temp_df.reset_index(drop=True, inplace=True)
|
||||
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)
|
||||
return temp_df
|
||||
else:
|
||||
url = "https://push2his.eastmoney.com/api/qt/stock/kline/get"
|
||||
params = {
|
||||
"fields1": "f1,f2,f3,f4,f5,f6",
|
||||
"fields2": "f51,f52,f53,f54,f55,f56,f57,f58,f59,f60,f61",
|
||||
"ut": "7eea3edcaed734bea9cbfc24409ed989",
|
||||
"klt": period,
|
||||
"fqt": adjust_map[adjust],
|
||||
"secid": f"{get_market_id(symbol)}.{symbol}",
|
||||
"beg": "0",
|
||||
"end": "20500000",
|
||||
}
|
||||
r = requests.get(url, timeout=15, params=params)
|
||||
data_json = r.json()
|
||||
temp_df = pd.DataFrame(
|
||||
[item.split(",") for item in data_json["data"]["klines"]]
|
||||
)
|
||||
temp_df.columns = [
|
||||
"时间",
|
||||
"开盘",
|
||||
"收盘",
|
||||
"最高",
|
||||
"最低",
|
||||
"成交量",
|
||||
"成交额",
|
||||
"振幅",
|
||||
"涨跌幅",
|
||||
"涨跌额",
|
||||
"换手率",
|
||||
]
|
||||
temp_df.index = pd.to_datetime(temp_df["时间"])
|
||||
temp_df = temp_df[start_date:end_date]
|
||||
temp_df.reset_index(drop=True, inplace=True)
|
||||
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["时间"]).astype(str)
|
||||
temp_df = temp_df[
|
||||
[
|
||||
"时间",
|
||||
"开盘",
|
||||
"收盘",
|
||||
"最高",
|
||||
"最低",
|
||||
"涨跌幅",
|
||||
"涨跌额",
|
||||
"成交量",
|
||||
"成交额",
|
||||
"振幅",
|
||||
"换手率",
|
||||
]
|
||||
]
|
||||
return temp_df
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
fund_etf_spot_em_df = fund_etf_spot_em()
|
||||
print(fund_etf_spot_em_df)
|
||||
|
||||
fund_etf_hist_hfq_em_df = fund_etf_hist_em(
|
||||
symbol="513500",
|
||||
period="daily",
|
||||
start_date="20000101",
|
||||
end_date="20230201",
|
||||
adjust="hfq",
|
||||
)
|
||||
print(fund_etf_hist_hfq_em_df)
|
||||
|
||||
fund_etf_hist_qfq_em_df = fund_etf_hist_em(
|
||||
symbol="511010",
|
||||
period="daily",
|
||||
start_date="20000101",
|
||||
end_date="20230718",
|
||||
adjust="",
|
||||
)
|
||||
print(fund_etf_hist_qfq_em_df)
|
||||
|
||||
fund_etf_hist_em_df = fund_etf_hist_em(
|
||||
symbol="159985",
|
||||
period="daily",
|
||||
start_date="20000101",
|
||||
end_date="20231211",
|
||||
adjust="",
|
||||
)
|
||||
print(fund_etf_hist_em_df)
|
||||
|
||||
fund_etf_hist_min_em_df = fund_etf_hist_min_em(
|
||||
symbol="511380",
|
||||
period="1",
|
||||
adjust="",
|
||||
start_date="2025-04-10 09:30:00",
|
||||
end_date="2025-04-10 17:40:00",
|
||||
)
|
||||
print(fund_etf_hist_min_em_df)
|
||||
@@ -0,0 +1,205 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding:utf-8 -*-
|
||||
"""
|
||||
Date: 2025/11/10 15:30
|
||||
Desc: 新浪财经-基金行情
|
||||
https://vip.stock.finance.sina.com.cn/fund_center/index.html#jjhqetf
|
||||
"""
|
||||
|
||||
import pandas as pd
|
||||
import py_mini_racer
|
||||
import requests
|
||||
|
||||
from akshare.stock.cons import hk_js_decode
|
||||
from akshare.utils import demjson
|
||||
|
||||
|
||||
def fund_etf_category_sina(symbol: str = "LOF基金") -> pd.DataFrame:
|
||||
"""
|
||||
新浪财经-基金列表
|
||||
https://vip.stock.finance.sina.com.cn/fund_center/index.html#jjhqetf
|
||||
:param symbol: choice of {"封闭式基金", "ETF基金", "LOF基金"}
|
||||
:type symbol: str
|
||||
:return: 指定 symbol 的基金列表
|
||||
:rtype: pandas.DataFrame
|
||||
"""
|
||||
fund_map = {
|
||||
"封闭式基金": "close_fund",
|
||||
"ETF基金": "etf_hq_fund",
|
||||
"LOF基金": "lof_hq_fund",
|
||||
}
|
||||
url = (
|
||||
"https://vip.stock.finance.sina.com.cn/quotes_service/api/jsonp.php/"
|
||||
"IO.XSRV2.CallbackList['da_yPT46_Ll7K6WD']/Market_Center.getHQNodeDataSimple"
|
||||
)
|
||||
params = {
|
||||
"page": "1",
|
||||
"num": "5000",
|
||||
"sort": "symbol",
|
||||
"asc": "0",
|
||||
"node": fund_map[symbol],
|
||||
"[object HTMLDivElement]": "qvvne",
|
||||
}
|
||||
r = requests.get(url, params=params)
|
||||
data_text = r.text
|
||||
data_json = demjson.decode(data_text[data_text.find("([") + 1 : -2])
|
||||
temp_df = pd.DataFrame(data_json)
|
||||
if symbol == "封闭式基金":
|
||||
temp_df.columns = [
|
||||
"代码",
|
||||
"名称",
|
||||
"最新价",
|
||||
"涨跌额",
|
||||
"涨跌幅",
|
||||
"买入",
|
||||
"卖出",
|
||||
"昨收",
|
||||
"今开",
|
||||
"最高",
|
||||
"最低",
|
||||
"成交量",
|
||||
"成交额",
|
||||
"_",
|
||||
"_",
|
||||
]
|
||||
else:
|
||||
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")
|
||||
return temp_df
|
||||
|
||||
|
||||
def fund_etf_hist_sina(symbol: str = "sh510050") -> pd.DataFrame:
|
||||
"""
|
||||
新浪财经-基金-ETF 基金-日行情数据
|
||||
https://finance.sina.com.cn/fund/quotes/159996/bc.shtml
|
||||
:param symbol: 基金名称, 可以通过 ak.fund_etf_category_sina() 函数获取
|
||||
:type symbol: str
|
||||
:return: 日行情数据
|
||||
:rtype: pandas.DataFrame
|
||||
"""
|
||||
url = (
|
||||
f"https://finance.sina.com.cn/realstock/company/{symbol}/hisdata_klc2/klc_kl.js"
|
||||
)
|
||||
r = requests.get(url)
|
||||
js_code = py_mini_racer.MiniRacer()
|
||||
js_code.eval(hk_js_decode)
|
||||
dict_list = js_code.call(
|
||||
"d", r.text.split("=")[1].split(";")[0].replace('"', "")
|
||||
) # 执行js解密代码
|
||||
temp_df = pd.DataFrame(dict_list)
|
||||
if temp_df.empty: # 处理获取数据为空的问题
|
||||
return pd.DataFrame()
|
||||
temp_df["date"] = pd.to_datetime(temp_df["date"], errors="coerce").dt.tz_localize(
|
||||
None
|
||||
)
|
||||
temp_df["open"] = pd.to_numeric(temp_df["open"], 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["close"] = pd.to_numeric(temp_df["close"], errors="coerce")
|
||||
temp_df["volume"] = pd.to_numeric(temp_df["volume"], errors="coerce")
|
||||
|
||||
# 转换日期列为日期类型
|
||||
temp_df["date"] = temp_df["date"].dt.date
|
||||
temp_df = temp_df.sort_values(by="date", ascending=True)
|
||||
return temp_df
|
||||
|
||||
|
||||
def fund_etf_dividend_sina(symbol: str = "sh510050") -> pd.DataFrame:
|
||||
"""
|
||||
新浪财经-基金-ETF 基金-累计分红
|
||||
https://finance.sina.com.cn/fund/quotes/510050/bc.shtml
|
||||
:param symbol: 基金名称, 可以通过 ak.fund_etf_category_sina() 函数获取
|
||||
:type symbol: str
|
||||
:return: 累计分红
|
||||
:rtype: pandas.DataFrame
|
||||
"""
|
||||
# 构建复权数据URL
|
||||
factor_url = f"https://finance.sina.com.cn/realstock/company/{symbol}/hfq.js"
|
||||
r = requests.get(factor_url)
|
||||
text = r.text
|
||||
if text.startswith("var"):
|
||||
json_str = text.split("=")[1].strip().rsplit("}", maxsplit=1)[0].strip()
|
||||
data = eval(json_str + "}") # 这里使用eval而不是json.loads因为数据格式特殊
|
||||
|
||||
if isinstance(data, dict) and "data" in data:
|
||||
df = pd.DataFrame(data["data"])
|
||||
# 重命名列
|
||||
df.columns = ["date", "f", "s", "u"] if len(df.columns) == 4 else df.columns
|
||||
# 移除1900-01-01的数据
|
||||
df = df[df["date"] != "1900-01-01"]
|
||||
# 转换日期
|
||||
df["date"] = pd.to_datetime(df["date"])
|
||||
# 转换数值类型
|
||||
df[["f", "s", "u"]] = df[["f", "s", "u"]].astype(float)
|
||||
# 按日期排序
|
||||
df = df.sort_values(by="date", ascending=True, ignore_index=True)
|
||||
temp_df = df[["date", "u"]].copy()
|
||||
temp_df.columns = ["日期", "累计分红"]
|
||||
temp_df["日期"] = pd.to_datetime(temp_df["日期"], errors="coerce").dt.date
|
||||
return temp_df
|
||||
else:
|
||||
return pd.DataFrame()
|
||||
else:
|
||||
return pd.DataFrame()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
fund_etf_category_sina_df = fund_etf_category_sina(symbol="封闭式基金")
|
||||
print(fund_etf_category_sina_df)
|
||||
|
||||
fund_etf_category_sina_df = fund_etf_category_sina(symbol="ETF基金")
|
||||
print(fund_etf_category_sina_df)
|
||||
|
||||
fund_etf_category_sina_df = fund_etf_category_sina(symbol="LOF基金")
|
||||
print(fund_etf_category_sina_df)
|
||||
|
||||
fund_etf_hist_sina_df = fund_etf_hist_sina(symbol="sh510050")
|
||||
print(fund_etf_hist_sina_df)
|
||||
|
||||
fund_etf_dividend_sina_df = fund_etf_dividend_sina(symbol="sh510050")
|
||||
print(fund_etf_dividend_sina_df)
|
||||
@@ -0,0 +1,71 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding:utf-8 -*-
|
||||
"""
|
||||
Date: 2026/1/20 15:00
|
||||
Desc: 上海证券交易所-ETF基金份额数据
|
||||
https://www.sse.com.cn/assortment/fund/etf/list/scale/
|
||||
"""
|
||||
|
||||
import pandas as pd
|
||||
import requests
|
||||
|
||||
|
||||
def fund_etf_scale_sse(date: str = "20250115") -> pd.DataFrame:
|
||||
"""
|
||||
上海证券交易所-产品-基金产品-ETF产品-ETF产品列表-基金规模
|
||||
https://www.sse.com.cn/assortment/fund/etf/list/scale/
|
||||
:param date: 统计日期, 默认为空返回最新数据, 格式如 "20250115"
|
||||
:type date: str
|
||||
:return: ETF基金份额数据
|
||||
:rtype: pandas.DataFrame
|
||||
"""
|
||||
data_str = "-".join([date[:4], date[4:6], date[6:]])
|
||||
url = "https://query.sse.com.cn/commonQuery.do"
|
||||
params = {
|
||||
"isPagination": "true",
|
||||
"pageHelp.pageSize": "10000",
|
||||
"pageHelp.pageNo": "1",
|
||||
"pageHelp.beginPage": "1",
|
||||
"pageHelp.cacheSize": "1",
|
||||
"pageHelp.endPage": "1",
|
||||
"sqlId": "COMMON_SSE_ZQPZ_ETFZL_XXPL_ETFGM_SEARCH_L",
|
||||
"STAT_DATE": data_str,
|
||||
}
|
||||
headers = {
|
||||
"Referer": "https://www.sse.com.cn/",
|
||||
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "
|
||||
"Chrome/88.0.4324.150 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={
|
||||
"NUM": "序号",
|
||||
"SEC_CODE": "基金代码",
|
||||
"SEC_NAME": "基金简称",
|
||||
"ETF_TYPE": "ETF类型",
|
||||
"STAT_DATE": "统计日期",
|
||||
"TOT_VOL": "基金份额",
|
||||
},
|
||||
inplace=True,
|
||||
)
|
||||
temp_df = temp_df[
|
||||
[
|
||||
"序号",
|
||||
"基金代码",
|
||||
"基金简称",
|
||||
"ETF类型",
|
||||
"统计日期",
|
||||
"基金份额",
|
||||
]
|
||||
]
|
||||
temp_df["序号"] = pd.to_numeric(temp_df["序号"], errors="coerce")
|
||||
temp_df["统计日期"] = pd.to_datetime(temp_df["统计日期"], errors="coerce").dt.date
|
||||
temp_df["基金份额"] = pd.to_numeric(temp_df["基金份额"], errors="coerce") * 10000
|
||||
return temp_df
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
fund_etf_scale_sse_df = fund_etf_scale_sse(date="20250115")
|
||||
print(fund_etf_scale_sse_df)
|
||||
@@ -0,0 +1,69 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding:utf-8 -*-
|
||||
"""
|
||||
Date: 2026/1/20 15:00
|
||||
Desc: 深圳证券交易所-ETF基金份额数据
|
||||
https://fund.szse.cn/marketdata/fundslist/index.html
|
||||
"""
|
||||
|
||||
import warnings
|
||||
|
||||
import pandas as pd
|
||||
import requests
|
||||
|
||||
|
||||
def fund_etf_scale_szse() -> pd.DataFrame:
|
||||
"""
|
||||
深圳证券交易所-基金产品-基金列表-ETF基金份额
|
||||
https://fund.szse.cn/marketdata/fundslist/index.html
|
||||
:return: ETF基金份额数据
|
||||
:rtype: pandas.DataFrame
|
||||
"""
|
||||
url = "https://fund.szse.cn/api/report/ShowReport"
|
||||
params = {
|
||||
"SHOWTYPE": "xlsx",
|
||||
"CATALOGID": "1000_lf",
|
||||
"TABKEY": "tab1",
|
||||
"random": "0.07610353191740105",
|
||||
}
|
||||
headers = {
|
||||
"Referer": "https://fund.szse.cn/marketdata/fundslist/index.html",
|
||||
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "
|
||||
"Chrome/88.0.4324.150 Safari/537.36",
|
||||
}
|
||||
r = requests.get(url, params=params, headers=headers)
|
||||
with warnings.catch_warnings(record=True):
|
||||
warnings.simplefilter("always")
|
||||
temp_df = pd.read_excel(r.content, engine="openpyxl", dtype={"基金代码": str})
|
||||
temp_df.rename(
|
||||
columns={
|
||||
"当前规模(份)": "基金份额",
|
||||
},
|
||||
inplace=True,
|
||||
)
|
||||
temp_df = temp_df[
|
||||
[
|
||||
"基金代码",
|
||||
"基金简称",
|
||||
"基金类别",
|
||||
"投资类别",
|
||||
"上市日期",
|
||||
"基金份额",
|
||||
"基金管理人",
|
||||
"基金发起人",
|
||||
"基金托管人",
|
||||
"净值",
|
||||
]
|
||||
]
|
||||
temp_df["上市日期"] = pd.to_datetime(temp_df["上市日期"], errors="coerce").dt.date
|
||||
temp_df["基金份额"] = (
|
||||
temp_df["基金份额"].astype(str).str.replace(",", "", regex=False)
|
||||
)
|
||||
temp_df["基金份额"] = pd.to_numeric(temp_df["基金份额"], errors="coerce")
|
||||
temp_df["净值"] = pd.to_numeric(temp_df["净值"], errors="coerce")
|
||||
return temp_df
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
fund_etf_scale_szse_df = fund_etf_scale_szse()
|
||||
print(fund_etf_scale_szse_df)
|
||||
@@ -0,0 +1,151 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding:utf-8 -*-
|
||||
"""
|
||||
Date: 2026/2/10 16:00
|
||||
Desc: 同花顺理财-基金数据-每日净值-ETF
|
||||
https://fund.10jqka.com.cn/datacenter/jz/kfs/etf/
|
||||
"""
|
||||
|
||||
import json
|
||||
|
||||
import pandas as pd
|
||||
import requests
|
||||
|
||||
|
||||
def fund_etf_category_ths(symbol: str = "ETF", date: str = "") -> pd.DataFrame:
|
||||
"""
|
||||
同花顺理财-基金数据-每日净值-实时行情
|
||||
https://fund.10jqka.com.cn/datacenter/jz/
|
||||
:param symbol: 基金类型; choice of {"股票型", "债券型", "混合型", "ETF", "LOF", "QDII", "保本型", "指数型", ""}; "" 表示全部
|
||||
:type symbol: str
|
||||
:param date: 查询日期
|
||||
:type date: str
|
||||
:return: 基金实时行情
|
||||
:rtype: pandas.DataFrame
|
||||
"""
|
||||
symbol_map = {
|
||||
"股票型": "gpx",
|
||||
"债券型": "zqx",
|
||||
"混合型": "hhx",
|
||||
"ETF": "ETF",
|
||||
"LOF": "LOF",
|
||||
"QDII": "QDII",
|
||||
"保本型": "bbx",
|
||||
"指数型": "zsx",
|
||||
"": "all",
|
||||
}
|
||||
inner_symbol = symbol_map.get(symbol, "ETF")
|
||||
inner_date = "-".join([date[:4], date[4:6], date[6:]]) if date != "" else 0
|
||||
url = (
|
||||
f"https://fund.10jqka.com.cn/data/Net/info/"
|
||||
f"{inner_symbol}_rate_desc_{inner_date}_0_1_9999_0_0_0_jsonp_g.html"
|
||||
)
|
||||
r = requests.get(url, timeout=15)
|
||||
data_text = r.text[2:-1]
|
||||
data_json = json.loads(data_text)
|
||||
temp_df = pd.DataFrame(data_json["data"]["data"]).T
|
||||
temp_df.reset_index(inplace=True, drop=True)
|
||||
temp_df.reset_index(inplace=True)
|
||||
temp_df["index"] = temp_df["index"] + 1
|
||||
temp_df.rename(
|
||||
columns={
|
||||
"index": "序号",
|
||||
"code": "基金代码",
|
||||
"typename": "基金类型",
|
||||
"net": "当前-单位净值",
|
||||
"name": "基金名称",
|
||||
"totalnet": "当前-累计净值",
|
||||
"newnet": "最新-单位净值",
|
||||
"newtotalnet": "最新-累计净值",
|
||||
"newdate": "最新-交易日",
|
||||
"net1": "前一日-单位净值",
|
||||
"totalnet1": "前一日-累计净值",
|
||||
"ranges": "增长值",
|
||||
"rate": "增长率",
|
||||
"shstat": "赎回状态",
|
||||
"sgstat": "申购状态",
|
||||
},
|
||||
inplace=True,
|
||||
)
|
||||
temp_df = temp_df[
|
||||
[
|
||||
"序号",
|
||||
"基金代码",
|
||||
"基金名称",
|
||||
"当前-单位净值",
|
||||
"当前-累计净值",
|
||||
"前一日-单位净值",
|
||||
"前一日-累计净值",
|
||||
"增长值",
|
||||
"增长率",
|
||||
"赎回状态",
|
||||
"申购状态",
|
||||
"最新-交易日",
|
||||
"最新-单位净值",
|
||||
"最新-累计净值",
|
||||
"基金类型",
|
||||
]
|
||||
]
|
||||
query_date = inner_date if inner_date != 0 else temp_df["最新-交易日"][0]
|
||||
temp_df["查询日期"] = query_date
|
||||
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["增长率"] = 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
|
||||
return temp_df
|
||||
|
||||
|
||||
def fund_etf_spot_ths(date: str = "") -> pd.DataFrame:
|
||||
"""
|
||||
同花顺理财-基金数据-每日净值-ETF-实时行情
|
||||
https://fund.10jqka.com.cn/datacenter/jz/kfs/etf/
|
||||
:param date: 查询日期
|
||||
:type date: str
|
||||
:return: ETF 实时行情
|
||||
:rtype: pandas.DataFrame
|
||||
"""
|
||||
return fund_etf_category_ths(date=date, symbol="ETF")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
fund_etf_category_ths_df = fund_etf_category_ths(date="20240620", symbol="股票型")
|
||||
print(fund_etf_category_ths_df)
|
||||
|
||||
fund_etf_category_ths_df = fund_etf_category_ths(date="20240620", symbol="债券型")
|
||||
print(fund_etf_category_ths_df)
|
||||
|
||||
fund_etf_category_ths_df = fund_etf_category_ths(date="20240620", symbol="混合型")
|
||||
print(fund_etf_category_ths_df)
|
||||
|
||||
fund_etf_category_ths_df = fund_etf_category_ths(date="20240620", symbol="ETF")
|
||||
print(fund_etf_category_ths_df)
|
||||
|
||||
fund_etf_category_ths_df = fund_etf_category_ths(date="20240620", symbol="LOF")
|
||||
print(fund_etf_category_ths_df)
|
||||
|
||||
fund_etf_category_ths_df = fund_etf_category_ths(date="20240620", symbol="QDII")
|
||||
print(fund_etf_category_ths_df)
|
||||
|
||||
fund_etf_category_ths_df = fund_etf_category_ths(date="20240620", symbol="保本型")
|
||||
print(fund_etf_category_ths_df)
|
||||
|
||||
fund_etf_category_ths_df = fund_etf_category_ths(date="20240620", symbol="指数型")
|
||||
print(fund_etf_category_ths_df)
|
||||
|
||||
fund_etf_category_ths_df = fund_etf_category_ths(date="20240620", symbol="")
|
||||
print(fund_etf_category_ths_df)
|
||||
|
||||
fund_etf_spot_ths_df = fund_etf_spot_ths(date="20240620")
|
||||
print(fund_etf_spot_ths_df)
|
||||
@@ -0,0 +1,167 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding:utf-8 -*-
|
||||
"""
|
||||
Date: 2025/12/22 17:00
|
||||
Desc: 天天基金-基金档案
|
||||
https://fundf10.eastmoney.com/jjfl_015641.html
|
||||
"""
|
||||
|
||||
import re
|
||||
from io import StringIO
|
||||
|
||||
import pandas as pd
|
||||
import requests
|
||||
from bs4 import BeautifulSoup
|
||||
|
||||
|
||||
def fund_fee_em(symbol: str = "015641", indicator: str = "认购费率") -> pd.DataFrame:
|
||||
"""
|
||||
天天基金-基金档案-购买信息
|
||||
https://fundf10.eastmoney.com/jjfl_015641.html
|
||||
:param symbol: 基金代码
|
||||
:type symbol: str
|
||||
:param indicator: choice of {"交易状态", "申购与赎回金额", "交易确认日", "运作费用", "认购费率(前端)", "认购费率(后端)","申购费率(前端)", "赎回费率"}
|
||||
:type indicator: str
|
||||
:return: 交易规则
|
||||
:rtype: pandas.DataFrame
|
||||
"""
|
||||
url = f"https://fundf10.eastmoney.com/jjfl_{symbol}.html"
|
||||
r = requests.get(url)
|
||||
soup = BeautifulSoup(r.text, features="html.parser")
|
||||
tables_dict = {}
|
||||
title_elements = soup.find_all(name="h4", class_="t")
|
||||
for title_elem in title_elements:
|
||||
title_text = title_elem.get_text(strip=True)
|
||||
title_text = re.sub(r"\s+", " ", title_text).strip()
|
||||
if title_text == "申购与赎回金额":
|
||||
next_table = title_elem.find_all_next("table")[0]
|
||||
next_next_table = title_elem.find_all_next("table")[1]
|
||||
table_html = str(next_table)
|
||||
next_table_html = str(next_next_table)
|
||||
df_1 = pd.read_html(StringIO(table_html))[0]
|
||||
df_2 = pd.read_html(StringIO(next_table_html))[0]
|
||||
df = pd.concat(objs=[df_1, df_2], ignore_index=True)
|
||||
tables_dict[title_text] = df
|
||||
continue
|
||||
else:
|
||||
next_table = title_elem.find_next("table")
|
||||
|
||||
if next_table:
|
||||
try:
|
||||
# 将表格转换为HTML字符串,然后使用pd.read_html读取
|
||||
table_html = str(next_table)
|
||||
df = pd.read_html(StringIO(table_html))[0]
|
||||
tables_dict[title_text] = df
|
||||
except Exception as e:
|
||||
print("Error:", e)
|
||||
continue
|
||||
|
||||
if indicator == "交易状态":
|
||||
temp_df = tables_dict[indicator]
|
||||
elif indicator == "申购与赎回金额":
|
||||
temp_df = tables_dict[indicator]
|
||||
elif indicator == "交易确认日":
|
||||
temp_df = tables_dict[indicator]
|
||||
elif indicator == "运作费用":
|
||||
temp_df = tables_dict[indicator]
|
||||
elif indicator == "认购费率(后端)":
|
||||
temp_df = tables_dict[indicator]
|
||||
elif indicator == "认购费率(前端)":
|
||||
temp_df = tables_dict[indicator]
|
||||
temp_df[["原费率", "天天基金优惠费率"]] = temp_df[
|
||||
"原费率|天天基金优惠费率"
|
||||
].str.split("|", expand=True)
|
||||
del temp_df["原费率|天天基金优惠费率"]
|
||||
temp_df.loc[3, "天天基金优惠费率"] = temp_df.loc[3, "原费率"]
|
||||
temp_df["原费率"] = temp_df["原费率"].str.strip()
|
||||
temp_df["天天基金优惠费率"] = temp_df["天天基金优惠费率"].str.strip()
|
||||
elif indicator == "申购费率(前端)":
|
||||
temp_df = tables_dict[indicator]
|
||||
if "原费率|天天基金优惠费率 银行卡购买|活期宝购买" not in temp_df.columns:
|
||||
# assert temp_df.columns.tolist() == ["适用金额", "适用期限", "费率"]
|
||||
return temp_df
|
||||
splited = temp_df["原费率|天天基金优惠费率 银行卡购买|活期宝购买"].str.split(
|
||||
"|", expand=True
|
||||
)
|
||||
if splited.shape[1] == 1:
|
||||
temp_df.rename(
|
||||
columns={"原费率|天天基金优惠费率 银行卡购买|活期宝购买": "原费率"},
|
||||
inplace=True,
|
||||
)
|
||||
temp_df["天天基金优惠费率-银行卡购买"] = temp_df["原费率"]
|
||||
temp_df["天天基金优惠费率-活期宝购买"] = temp_df["原费率"]
|
||||
else:
|
||||
temp_df[
|
||||
["原费率", "天天基金优惠费率-银行卡购买", "天天基金优惠费率-活期宝购买"]
|
||||
] = splited
|
||||
temp_df["天天基金优惠费率-银行卡购买"] = temp_df[
|
||||
"天天基金优惠费率-银行卡购买"
|
||||
].fillna(temp_df["原费率"])
|
||||
temp_df["天天基金优惠费率-活期宝购买"] = temp_df[
|
||||
"天天基金优惠费率-活期宝购买"
|
||||
].fillna(temp_df["原费率"])
|
||||
del temp_df["原费率|天天基金优惠费率 银行卡购买|活期宝购买"]
|
||||
temp_df["原费率"] = temp_df["原费率"].str.strip()
|
||||
temp_df["天天基金优惠费率-银行卡购买"] = temp_df[
|
||||
"天天基金优惠费率-银行卡购买"
|
||||
].str.strip()
|
||||
temp_df["天天基金优惠费率-活期宝购买"] = temp_df[
|
||||
"天天基金优惠费率-活期宝购买"
|
||||
].str.strip()
|
||||
elif indicator in ("赎回费率", "赎回费率(前端)", "赎回费率(后端)"):
|
||||
temp_df = tables_dict[indicator]
|
||||
if "原费率|天天基金优惠费率" in temp_df.columns:
|
||||
temp_df[["原费率", "天天基金优惠费率"]] = temp_df[
|
||||
"原费率|天天基金优惠费率"
|
||||
].str.split("|", expand=True)
|
||||
del temp_df["原费率|天天基金优惠费率"]
|
||||
else:
|
||||
temp_df = pd.DataFrame([])
|
||||
return temp_df
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
fund_fee_em_df = fund_fee_em(symbol="019005", indicator="交易状态")
|
||||
print(fund_fee_em_df)
|
||||
|
||||
fund_fee_em_df = fund_fee_em(symbol="019005", indicator="申购与赎回金额")
|
||||
print(fund_fee_em_df)
|
||||
|
||||
fund_fee_em_df = fund_fee_em(symbol="019005", indicator="交易确认日")
|
||||
print(fund_fee_em_df)
|
||||
|
||||
fund_fee_em_df = fund_fee_em(symbol="019005", indicator="运作费用")
|
||||
print(fund_fee_em_df)
|
||||
|
||||
fund_fee_em_df = fund_fee_em(symbol="019005", indicator="认购费率(前端)")
|
||||
print(fund_fee_em_df)
|
||||
|
||||
fund_fee_em_df = fund_fee_em(symbol="019005", indicator="申购费率(前端)")
|
||||
print(fund_fee_em_df)
|
||||
|
||||
fund_fee_em_df = fund_fee_em(symbol="000011", indicator="赎回费率")
|
||||
print(fund_fee_em_df)
|
||||
|
||||
fund_fee_em_df = fund_fee_em(symbol="018403", indicator="赎回费率")
|
||||
print(fund_fee_em_df)
|
||||
|
||||
fund_fee_em_df = fund_fee_em(symbol="100035", indicator="赎回费率(前端)")
|
||||
print(fund_fee_em_df)
|
||||
|
||||
fund_fee_em_df = fund_fee_em(symbol="022364", indicator="申购费率(前端)")
|
||||
print(fund_fee_em_df)
|
||||
|
||||
fund_fee_em_df = fund_fee_em(symbol="022365", indicator="申购费率(前端)")
|
||||
print(fund_fee_em_df)
|
||||
|
||||
fund_fee_em_df = fund_fee_em(symbol="006030", indicator="申购费率(前端)")
|
||||
print(fund_fee_em_df)
|
||||
|
||||
fund_fee_em_df = fund_fee_em(symbol="022568", indicator="申购费率(前端)")
|
||||
print(fund_fee_em_df)
|
||||
|
||||
fund_fee_em_df = fund_fee_em(symbol="960029", indicator="申购费率(前端)")
|
||||
print(fund_fee_em_df)
|
||||
|
||||
fund_fee_em_df = fund_fee_em(symbol="000011", indicator="认购费率(后端)")
|
||||
print(fund_fee_em_df)
|
||||
@@ -0,0 +1,263 @@
|
||||
# -*- coding:utf-8 -*-
|
||||
# !/usr/bin/env python
|
||||
"""
|
||||
Date: 2026/2/22 13:00
|
||||
Desc: 天天基金网-基金数据-分红送配
|
||||
https://fund.eastmoney.com/data/fundfenhong.html
|
||||
"""
|
||||
|
||||
import pandas as pd
|
||||
import requests
|
||||
|
||||
from akshare.utils.tqdm import get_tqdm
|
||||
|
||||
|
||||
def fund_fh_em(
|
||||
year: str = "2025",
|
||||
typ: str = "",
|
||||
rank: str = "BZDM",
|
||||
sort: str = "asc",
|
||||
page: int = -1,
|
||||
) -> pd.DataFrame:
|
||||
"""
|
||||
天天基金网-基金数据-分红送配-基金分红
|
||||
https://fund.eastmoney.com/data/fundfenhong.html#DJR,desc,1,,,
|
||||
:param year: 查询年份
|
||||
:type year: str
|
||||
:param typ: 基金类型;空串表示全部; choice of {"指数型-其他", "指数型-海外股票", "指数型-固收", "指数型-股票", "债券型-中短债",
|
||||
"债券型-长债", "债券型-理财", "债券型-混合债", "债券型-混合一级", "债券型-混合二级", "货币型-普通货币", "货币型-浮动净值",
|
||||
"混合型-平衡", "混合型-偏债", "混合型-偏股", "混合型-灵活", "混合型-绝对收益", "股票型", "REITs", "Reits", "QDII-商品",
|
||||
"QDII-普通股票", "QDII-混合债", "QDII-混合偏股", "QDII-纯债", "QDII-REITs", "FOF"}
|
||||
:type typ: str
|
||||
:param rank: 排序字段;choice of {"BZDM", "ABBNAME", "DJR", "FSRQ", "FHFCZ", "FFR"}; "BZDM": 基金代码,
|
||||
"ABBNAME": 基金简称, "DJR": 权益登记日, "FSRQ": 除息日期, "FHFCZ": 分红(元/份), "FFR": 分红发放日
|
||||
:type rank: str
|
||||
:param sort: 排序方向;排序方式; choice of {"asc", "desc"}
|
||||
:type sort: str
|
||||
:param page: 查询页数;请求第page页数据; -1 表示全部页面
|
||||
:type page: int
|
||||
:return: 基金分红
|
||||
:rtype: pandas.DataFrame
|
||||
"""
|
||||
|
||||
def get_df_from_response(response):
|
||||
text = response.text
|
||||
return pd.DataFrame(eval(text[text.find("[["): text.find(";var jjfh_jjgs")]))
|
||||
|
||||
url = "https://fund.eastmoney.com/Data/funddataIndex_Interface.aspx"
|
||||
params = {
|
||||
"dt": "8",
|
||||
"page": "1" if page == -1 else str(page),
|
||||
"rank": rank,
|
||||
"sort": sort,
|
||||
"gs": "",
|
||||
"ftype": typ,
|
||||
"year": year,
|
||||
}
|
||||
r = requests.get(url, params=params)
|
||||
data_list = [get_df_from_response(r)]
|
||||
if page == -1:
|
||||
data_text = r.text
|
||||
total_page = eval(data_text[data_text.find("=") + 1: data_text.find(";")])[0]
|
||||
tqdm = get_tqdm()
|
||||
for p in tqdm(range(2, total_page + 1), leave=False):
|
||||
params.update({"page": str(p)})
|
||||
r = requests.get(url, params=params)
|
||||
data_list.append(get_df_from_response(r))
|
||||
big_df = pd.concat(objs=data_list, ignore_index=True)
|
||||
big_df.reset_index(inplace=True)
|
||||
big_df["index"] = big_df.index + 1
|
||||
# 处理空数据时报错的问题
|
||||
if big_df.empty:
|
||||
big_df = big_df.reindex(
|
||||
columns=[
|
||||
"序号",
|
||||
"基金代码",
|
||||
"基金简称",
|
||||
"权益登记日",
|
||||
"除息日期",
|
||||
"分红",
|
||||
"分红发放日",
|
||||
"-",
|
||||
]
|
||||
)
|
||||
big_df.columns = [
|
||||
"序号",
|
||||
"基金代码",
|
||||
"基金简称",
|
||||
"权益登记日",
|
||||
"除息日期",
|
||||
"分红",
|
||||
"分红发放日",
|
||||
"-",
|
||||
]
|
||||
big_df = big_df[
|
||||
["序号", "基金代码", "基金简称", "权益登记日", "除息日期", "分红", "分红发放日"]
|
||||
]
|
||||
big_df["权益登记日"] = pd.to_datetime(big_df["权益登记日"]).dt.date
|
||||
big_df["除息日期"] = pd.to_datetime(big_df["除息日期"]).dt.date
|
||||
big_df["分红发放日"] = pd.to_datetime(big_df["分红发放日"]).dt.date
|
||||
big_df["分红"] = pd.to_numeric(big_df["分红"])
|
||||
return big_df
|
||||
|
||||
|
||||
def fund_cf_em(
|
||||
year: str = "2025",
|
||||
typ: str = "",
|
||||
rank: str = "FSRQ",
|
||||
sort: str = "desc",
|
||||
page: int = -1,
|
||||
) -> pd.DataFrame:
|
||||
"""
|
||||
天天基金网-基金数据-分红送配-基金拆分
|
||||
https://fund.eastmoney.com/data/fundchaifen.html#FSRQ,desc,1,,,
|
||||
:param year: 查询年份
|
||||
:type year: str
|
||||
:param typ: 基金类型;空串表示全部; choice of {"", "指数型-其他", "指数型-海外股票", "指数型-固收", "指数型-股票",
|
||||
"债券型-中短债", "债券型-长债", "债券型-可转债", "债券型-混合债", "债券型-混合一级", "债券型-混合二级",
|
||||
"商品(不含QDII)", "货币型", "混合型-平衡", "混合型-偏债", "混合型-偏股", "混合型-灵活", "股票型", "QDII", "FOF"}
|
||||
:type typ: str
|
||||
:param rank: 排序字段;choice of {"BZDM", "ABBNAME", "FSRQ", "FHFCZ"}; "BZDM": 基金代码,
|
||||
"ABBNAME": 基金简称, "FSRQ": 拆分折算日, "FHFCZ": 拆分折算(每份)
|
||||
:type rank: str
|
||||
:param sort: 排序方向;choice of {"asc", "desc"}
|
||||
:type sort: str
|
||||
:param page: 查询页数;请求第page页数据; -1 表示全部页面
|
||||
:type page: int
|
||||
:return: 基金拆分
|
||||
:rtype: pandas.DataFrame
|
||||
"""
|
||||
|
||||
def get_df_from_response(response):
|
||||
text = response.text
|
||||
code = text[text.find("[["): text.find(";var jjcf_jjgs")]
|
||||
if code:
|
||||
return pd.DataFrame(eval(code))
|
||||
return pd.DataFrame()
|
||||
|
||||
url = "https://fund.eastmoney.com/Data/funddataIndex_Interface.aspx"
|
||||
params = {
|
||||
"dt": "9",
|
||||
"page": "1" if page == -1 else str(page),
|
||||
"rank": rank,
|
||||
"sort": sort,
|
||||
"gs": "",
|
||||
"ftype": typ,
|
||||
"year": year,
|
||||
}
|
||||
r = requests.get(url, params=params)
|
||||
data_list = [get_df_from_response(r)]
|
||||
if page == -1:
|
||||
data_text = r.text
|
||||
total_page = eval(data_text[data_text.find("=") + 1: data_text.find(";")])[0]
|
||||
tqdm = get_tqdm()
|
||||
for p in tqdm(range(2, total_page + 1), leave=False):
|
||||
params.update({"page": str(p)})
|
||||
r = requests.get(url, params=params)
|
||||
data_list.append(get_df_from_response(r))
|
||||
big_df = pd.concat(objs=data_list, ignore_index=True)
|
||||
big_df.reset_index(inplace=True)
|
||||
big_df.loc[:, "index"] = big_df["index"] + 1
|
||||
# 处理空数据时报错的问题
|
||||
if big_df.empty:
|
||||
big_df = big_df.reindex(
|
||||
columns=[
|
||||
"序号",
|
||||
"基金代码",
|
||||
"基金简称",
|
||||
"拆分折算日",
|
||||
"拆分类型",
|
||||
"拆分折算",
|
||||
"-",
|
||||
]
|
||||
)
|
||||
big_df.columns = [
|
||||
"序号",
|
||||
"基金代码",
|
||||
"基金简称",
|
||||
"拆分折算日",
|
||||
"拆分类型",
|
||||
"拆分折算",
|
||||
"-",
|
||||
]
|
||||
big_df = big_df[
|
||||
["序号", "基金代码", "基金简称", "拆分折算日", "拆分类型", "拆分折算"]
|
||||
]
|
||||
big_df["拆分折算日"] = pd.to_datetime(big_df["拆分折算日"]).dt.date
|
||||
big_df["拆分折算"] = pd.to_numeric(big_df["拆分折算"], errors="coerce")
|
||||
return big_df
|
||||
|
||||
|
||||
def fund_fh_rank_em() -> pd.DataFrame:
|
||||
"""
|
||||
天天基金网-基金数据-分红送配-基金分红排行
|
||||
https://fund.eastmoney.com/data/fundleijifenhong.html
|
||||
:return: 基金分红排行
|
||||
:rtype: pandas.DataFrame
|
||||
"""
|
||||
url = "https://fund.eastmoney.com/Data/funddataIndex_Interface.aspx"
|
||||
params = {
|
||||
"dt": "10",
|
||||
"page": "1",
|
||||
"rank": "FHFCZ",
|
||||
"sort": "desc",
|
||||
"gs": "",
|
||||
"ftype": "",
|
||||
}
|
||||
r = requests.get(url, params=params)
|
||||
data_text = r.text
|
||||
total_page = eval(data_text[data_text.find("=") + 1: data_text.find(";")])[0]
|
||||
big_df = pd.DataFrame()
|
||||
tqdm = get_tqdm()
|
||||
for page in tqdm(range(1, total_page + 1), leave=False):
|
||||
params.update({"page": str(page)})
|
||||
r = requests.get(url, params=params)
|
||||
data_text = r.text
|
||||
temp_list = eval(
|
||||
data_text[data_text.find("[["): data_text.find(";var fhph_jjgs")]
|
||||
)
|
||||
temp_df = pd.DataFrame(temp_list)
|
||||
big_df = pd.concat(objs=[big_df, temp_df], ignore_index=True)
|
||||
|
||||
big_df.reset_index(inplace=True)
|
||||
big_df["index"] = big_df.index + 1
|
||||
# 处理空数据时报错的问题
|
||||
if big_df.empty:
|
||||
big_df = big_df.reindex(
|
||||
columns=[
|
||||
"序号",
|
||||
"基金代码",
|
||||
"基金简称",
|
||||
"累计分红",
|
||||
"累计次数",
|
||||
"成立日期",
|
||||
"-",
|
||||
]
|
||||
)
|
||||
big_df.columns = [
|
||||
"序号",
|
||||
"基金代码",
|
||||
"基金简称",
|
||||
"累计分红",
|
||||
"累计次数",
|
||||
"成立日期",
|
||||
"-",
|
||||
]
|
||||
big_df = big_df[
|
||||
["序号", "基金代码", "基金简称", "累计分红", "累计次数", "成立日期"]
|
||||
]
|
||||
big_df["成立日期"] = pd.to_datetime(big_df["成立日期"]).dt.date
|
||||
big_df["累计分红"] = pd.to_numeric(big_df["累计分红"], errors="coerce")
|
||||
big_df["累计次数"] = pd.to_numeric(big_df["累计次数"], errors="coerce")
|
||||
return big_df
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
fund_fh_em_df = fund_fh_em(year="2025")
|
||||
print(fund_fh_em_df)
|
||||
|
||||
fund_cf_em_df = fund_cf_em(year="2025")
|
||||
print(fund_cf_em_df)
|
||||
|
||||
fund_fh_rank_em_df = fund_fh_rank_em()
|
||||
print(fund_fh_rank_em_df)
|
||||
@@ -0,0 +1,54 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding:utf-8 -*-
|
||||
"""
|
||||
Date: 2026/05/01
|
||||
Desc: 同花顺-基金基本信息
|
||||
https://fund.10jqka.com.cn/161130/interduce.html
|
||||
"""
|
||||
|
||||
import pandas as pd
|
||||
import requests
|
||||
from bs4 import BeautifulSoup
|
||||
|
||||
from akshare.utils.cons import headers
|
||||
|
||||
|
||||
def fund_info_ths(symbol: str = "161130") -> pd.DataFrame:
|
||||
"""
|
||||
同花顺-基金数据-基金基本信息
|
||||
https://fund.10jqka.com.cn/161130/interduce.html
|
||||
:param symbol: 基金代码
|
||||
:type symbol: str
|
||||
:return: 基金基本信息
|
||||
:rtype: pandas.DataFrame
|
||||
"""
|
||||
url = f"https://fund.10jqka.com.cn/{symbol}/interduce.html"
|
||||
r = requests.get(url, headers=headers, timeout=15)
|
||||
soup = BeautifulSoup(r.content, features="lxml", from_encoding="utf-8")
|
||||
|
||||
# 查找基金信息对话框
|
||||
g_dialog = soup.find("ul", class_="g-dialog")
|
||||
if not g_dialog:
|
||||
raise ValueError("未找到基金信息,可能网页结构已变化")
|
||||
|
||||
# 提取所有基金信息
|
||||
fund_data = {}
|
||||
lis = g_dialog.find_all("li")
|
||||
for li in lis:
|
||||
key_elem = li.find("span", class_="key")
|
||||
value_elem = li.find("span", class_="value")
|
||||
if key_elem and value_elem:
|
||||
key = key_elem.get_text(strip=True)
|
||||
value = value_elem.get_text(strip=True)
|
||||
fund_data[key] = value
|
||||
|
||||
# 转换为DataFrame
|
||||
temp_df = pd.DataFrame(list(fund_data.items()), columns=["字段", "值"])
|
||||
|
||||
return temp_df
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
# 测试获取基金基本信息
|
||||
fund_info_ths_df = fund_info_ths(symbol="161130")
|
||||
print(fund_info_ths_df)
|
||||
@@ -0,0 +1,83 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding:utf-8 -*-
|
||||
"""
|
||||
Date: 2023/11/7 18:30
|
||||
Desc: 基金数据-新发基金-新成立基金
|
||||
https://fund.eastmoney.com/data/xinfound.html
|
||||
"""
|
||||
|
||||
import pandas as pd
|
||||
import requests
|
||||
|
||||
from akshare.utils import demjson
|
||||
|
||||
|
||||
def fund_new_found_em() -> pd.DataFrame:
|
||||
"""
|
||||
基金数据-新发基金-新成立基金
|
||||
https://fund.eastmoney.com/data/xinfound.html
|
||||
:return: 新成立基金
|
||||
:rtype: pandas.DataFrame
|
||||
"""
|
||||
url = "https://fund.eastmoney.com/data/FundNewIssue.aspx"
|
||||
params = {
|
||||
"t": "xcln",
|
||||
"sort": "jzrgq,desc",
|
||||
"y": "",
|
||||
"page": "1,50000",
|
||||
"isbuy": "1",
|
||||
"v": "0.4069919776543214",
|
||||
}
|
||||
r = requests.get(url, params=params)
|
||||
data_text = r.text
|
||||
data_json = demjson.decode(data_text.strip("var newfunddata="))
|
||||
temp_df = pd.DataFrame(data_json["datas"])
|
||||
temp_df.columns = [
|
||||
"基金代码",
|
||||
"基金简称",
|
||||
"发行公司",
|
||||
"_",
|
||||
"基金类型",
|
||||
"募集份额",
|
||||
"成立日期",
|
||||
"成立来涨幅",
|
||||
"基金经理",
|
||||
"申购状态",
|
||||
"集中认购期",
|
||||
"_",
|
||||
"_",
|
||||
"_",
|
||||
"_",
|
||||
"_",
|
||||
"_",
|
||||
"_",
|
||||
"优惠费率",
|
||||
]
|
||||
temp_df = temp_df[
|
||||
[
|
||||
"基金代码",
|
||||
"基金简称",
|
||||
"发行公司",
|
||||
"基金类型",
|
||||
"集中认购期",
|
||||
"募集份额",
|
||||
"成立日期",
|
||||
"成立来涨幅",
|
||||
"基金经理",
|
||||
"申购状态",
|
||||
"优惠费率",
|
||||
]
|
||||
]
|
||||
temp_df["募集份额"] = pd.to_numeric(temp_df["募集份额"], errors="coerce")
|
||||
temp_df["成立日期"] = pd.to_datetime(temp_df["成立日期"], errors="coerce").dt.date
|
||||
temp_df["成立来涨幅"] = pd.to_numeric(
|
||||
temp_df["成立来涨幅"].str.replace(",", ""), errors="coerce"
|
||||
)
|
||||
temp_df["优惠费率"] = temp_df["优惠费率"].str.strip("%")
|
||||
temp_df["优惠费率"] = pd.to_numeric(temp_df["优惠费率"], errors="coerce")
|
||||
return temp_df
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
fund_new_found_em_df = fund_new_found_em()
|
||||
print(fund_new_found_em_df)
|
||||
@@ -0,0 +1,139 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding:utf-8 -*-
|
||||
"""
|
||||
Date: 2026/2/27
|
||||
Desc: 同花顺-新发基金
|
||||
https://fund.10jqka.com.cn/datacenter/xfjj/
|
||||
"""
|
||||
|
||||
import json
|
||||
|
||||
import pandas as pd
|
||||
import requests
|
||||
|
||||
|
||||
def fund_new_found_ths(symbol: str = "全部") -> pd.DataFrame:
|
||||
"""
|
||||
同花顺-基金数据-新发基金
|
||||
https://fund.10jqka.com.cn/datacenter/xfjj/
|
||||
:param symbol: 选择基金类型; choice of {"全部", "发行中", "将发行"}
|
||||
:type symbol: str
|
||||
:return: 新发基金数据
|
||||
:rtype: pandas.DataFrame
|
||||
"""
|
||||
url = "https://fund.10jqka.com.cn/datacenter/xfjj/"
|
||||
r = requests.get(url, timeout=15)
|
||||
r.encoding = "utf-8"
|
||||
|
||||
# 从页面中提取 jsonData
|
||||
# 找到 jsonData= 的位置
|
||||
start_idx = r.text.find("jsonData=")
|
||||
if start_idx == -1:
|
||||
raise ValueError("未找到 jsonData,可能页面结构已变化")
|
||||
|
||||
# 找到第一个 {
|
||||
start_bracket = r.text.find("{", start_idx)
|
||||
if start_bracket == -1:
|
||||
raise ValueError("未找到 JSON 开始括号")
|
||||
|
||||
# 通过计数括号找到完整的JSON对象
|
||||
count = 0
|
||||
end_idx = start_bracket
|
||||
for i in range(start_bracket, len(r.text)):
|
||||
if r.text[i] == "{":
|
||||
count += 1
|
||||
elif r.text[i] == "}":
|
||||
count -= 1
|
||||
if count == 0:
|
||||
end_idx = i + 1
|
||||
break
|
||||
|
||||
if end_idx == start_bracket:
|
||||
raise ValueError("未找到完整的 JSON 对象")
|
||||
|
||||
json_str = r.text[start_bracket:end_idx]
|
||||
data_json = json.loads(json_str)
|
||||
|
||||
# 转换为 DataFrame
|
||||
temp_df = pd.DataFrame(data_json).T
|
||||
temp_df.reset_index(inplace=True, drop=True)
|
||||
|
||||
# 根据 symbol 筛选数据
|
||||
if symbol == "发行中":
|
||||
# 发行中: zzfx=1
|
||||
temp_df = temp_df[temp_df["zzfx"] == 1]
|
||||
elif symbol == "将发行":
|
||||
# 将发行: zzfx != 1 (即 buy=0 且起始日在未来)
|
||||
temp_df = temp_df[temp_df["zzfx"] != 1]
|
||||
|
||||
# 提取 manager 字段(可能是数组)
|
||||
if "manager" in temp_df.columns:
|
||||
temp_df["manager"] = temp_df["manager"].apply(
|
||||
lambda x: x[0] if isinstance(x, list) and len(x) > 0 else (x if pd.notna(x) else "")
|
||||
)
|
||||
|
||||
# 重命名列
|
||||
temp_df.rename(
|
||||
columns={
|
||||
"code": "基金代码",
|
||||
"name": "基金名称",
|
||||
"type": "投资类型",
|
||||
"jjlx": "基金类型",
|
||||
"tzfg": "投资风格",
|
||||
"start": "募集起始日",
|
||||
"end": "募集终止日",
|
||||
"orgname": "管理人",
|
||||
"manager": "基金经理",
|
||||
"zgrgfl": "认购费率",
|
||||
"zdrg": "最低认购",
|
||||
"zdje": "认购金额",
|
||||
"zzfx": "发行中",
|
||||
"buy": "可购买",
|
||||
},
|
||||
inplace=True,
|
||||
)
|
||||
|
||||
# 选择需要的列
|
||||
columns_order = [
|
||||
"基金代码",
|
||||
"基金名称",
|
||||
"投资类型",
|
||||
"募集起始日",
|
||||
"募集终止日",
|
||||
"管理人",
|
||||
"基金经理",
|
||||
"认购费率",
|
||||
"最低认购",
|
||||
"基金类型",
|
||||
"投资风格",
|
||||
]
|
||||
|
||||
# 只保留存在的列
|
||||
existing_columns = [col for col in columns_order if col in temp_df.columns]
|
||||
temp_df = temp_df[existing_columns]
|
||||
|
||||
# 数据类型转换
|
||||
if "募集起始日" in temp_df.columns:
|
||||
temp_df["募集起始日"] = pd.to_datetime(temp_df["募集起始日"], errors="coerce").dt.date
|
||||
if "募集终止日" in temp_df.columns:
|
||||
temp_df["募集终止日"] = pd.to_datetime(temp_df["募集终止日"], errors="coerce").dt.date
|
||||
if "认购费率" in temp_df.columns:
|
||||
temp_df["认购费率"] = pd.to_numeric(temp_df["认购费率"], errors="coerce")
|
||||
if "最低认购" in temp_df.columns:
|
||||
temp_df["最低认购"] = pd.to_numeric(temp_df["最低认购"], errors="coerce")
|
||||
|
||||
return temp_df
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
# 测试获取全部新发基金
|
||||
fund_new_found_ths_df = fund_new_found_ths(symbol="全部")
|
||||
print(fund_new_found_ths_df)
|
||||
|
||||
# 测试获取发行中的基金
|
||||
fund_new_found_ths_issue_df = fund_new_found_ths(symbol="发行中")
|
||||
print(fund_new_found_ths_issue_df)
|
||||
|
||||
# 测试获取将发行的基金
|
||||
fund_new_found_ths_future_df = fund_new_found_ths(symbol="将发行")
|
||||
print(fund_new_found_ths_future_df)
|
||||
@@ -0,0 +1,356 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding:utf-8 -*-
|
||||
"""
|
||||
Date: 2025/3/11 17:00
|
||||
Desc: 东方财富-LOF 行情
|
||||
https://quote.eastmoney.com/center/gridlist.html#fund_lof
|
||||
https://quote.eastmoney.com/sz166009.html
|
||||
"""
|
||||
|
||||
from functools import lru_cache
|
||||
|
||||
import pandas as pd
|
||||
import requests
|
||||
|
||||
from akshare.utils.func import fetch_paginated_data
|
||||
|
||||
|
||||
@lru_cache()
|
||||
def _fund_lof_code_id_map_em() -> dict:
|
||||
"""
|
||||
东方财富-LOF 代码和市场标识映射
|
||||
https://quote.eastmoney.com/center/gridlist.html#fund_lof
|
||||
:return: LOF 代码和市场标识映射
|
||||
:rtype: pandas.DataFrame
|
||||
"""
|
||||
url = "https://2.push2.eastmoney.com/api/qt/clist/get"
|
||||
params = {
|
||||
"pn": "1",
|
||||
"pz": "100",
|
||||
"po": "1",
|
||||
"np": "1",
|
||||
"ut": "bd1d9ddb04089700cf9c27f6f7426281",
|
||||
"fltt": "2",
|
||||
"invt": "2",
|
||||
"wbp2u": "|0|0|0|web",
|
||||
"fid": "f12",
|
||||
"fs": "b:MK0404,b:MK0405,b:MK0406,b:MK0407",
|
||||
"fields": "f3,f12,f13",
|
||||
}
|
||||
temp_df = fetch_paginated_data(url, params)
|
||||
temp_dict = dict(zip(temp_df["f12"], temp_df["f13"]))
|
||||
return temp_dict
|
||||
|
||||
|
||||
def fund_lof_spot_em() -> pd.DataFrame:
|
||||
"""
|
||||
东方财富-LOF 实时行情
|
||||
https://quote.eastmoney.com/center/gridlist.html#fund_lof
|
||||
:return: LOF 实时行情
|
||||
:rtype: pandas.DataFrame
|
||||
"""
|
||||
url = "https://88.push2.eastmoney.com/api/qt/clist/get"
|
||||
params = {
|
||||
"pn": "1",
|
||||
"pz": "100",
|
||||
"po": "1",
|
||||
"np": "1",
|
||||
"ut": "bd1d9ddb04089700cf9c27f6f7426281",
|
||||
"fltt": "2",
|
||||
"invt": "2",
|
||||
"wbp2u": "|0|0|0|web",
|
||||
"fid": "f3",
|
||||
"fs": "b:MK0404,b:MK0405,b:MK0406,b:MK0407",
|
||||
"fields": "f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f12,f13,f14,"
|
||||
"f15,f16,f17,f18,f20,f21,f23,f24,f25,f22,f11,f62,f128,f136,f115,f152",
|
||||
}
|
||||
temp_df = fetch_paginated_data(url, params)
|
||||
temp_df.rename(
|
||||
columns={
|
||||
"f12": "代码",
|
||||
"f14": "名称",
|
||||
"f2": "最新价",
|
||||
"f4": "涨跌额",
|
||||
"f3": "涨跌幅",
|
||||
"f5": "成交量",
|
||||
"f6": "成交额",
|
||||
"f17": "开盘价",
|
||||
"f15": "最高价",
|
||||
"f16": "最低价",
|
||||
"f18": "昨收",
|
||||
"f8": "换手率",
|
||||
"f21": "流通市值",
|
||||
"f20": "总市值",
|
||||
},
|
||||
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")
|
||||
temp_df["总市值"] = pd.to_numeric(temp_df["总市值"], errors="coerce")
|
||||
return temp_df
|
||||
|
||||
|
||||
def fund_lof_hist_em(
|
||||
symbol: str = "166009",
|
||||
period: str = "daily",
|
||||
start_date: str = "19700101",
|
||||
end_date: str = "20500101",
|
||||
adjust: str = "",
|
||||
) -> pd.DataFrame:
|
||||
"""
|
||||
东方财富-LOF 行情
|
||||
https://quote.eastmoney.com/sz166009.html
|
||||
:param symbol: LOF 代码
|
||||
:type symbol: str
|
||||
:param period: choice of {'daily', 'weekly', 'monthly'}
|
||||
:type period: str
|
||||
:param start_date: 开始日期
|
||||
:type start_date: str
|
||||
:param end_date: 结束日期
|
||||
:type end_date: str
|
||||
:param adjust: choice of {"qfq": "前复权", "hfq": "后复权", "": "不复权"}
|
||||
:type adjust: str
|
||||
:return: 每日行情
|
||||
:rtype: pandas.DataFrame
|
||||
"""
|
||||
code_id_dict = _fund_lof_code_id_map_em()
|
||||
adjust_dict = {"qfq": "1", "hfq": "2", "": "0"}
|
||||
period_dict = {"daily": "101", "weekly": "102", "monthly": "103"}
|
||||
url = "https://push2his.eastmoney.com/api/qt/stock/kline/get"
|
||||
params = {
|
||||
"fields1": "f1,f2,f3,f4,f5,f6",
|
||||
"fields2": "f51,f52,f53,f54,f55,f56,f57,f58,f59,f60,f61,f116",
|
||||
"ut": "7eea3edcaed734bea9cbfc24409ed989",
|
||||
"klt": period_dict[period],
|
||||
"fqt": adjust_dict[adjust],
|
||||
"secid": f"{code_id_dict[symbol]}.{symbol}",
|
||||
"beg": start_date,
|
||||
"end": end_date,
|
||||
}
|
||||
r = requests.get(url, params=params)
|
||||
data_json = r.json()
|
||||
if not (data_json["data"] and data_json["data"]["klines"]):
|
||||
return pd.DataFrame()
|
||||
temp_df = pd.DataFrame([item.split(",") for item in data_json["data"]["klines"]])
|
||||
temp_df.columns = [
|
||||
"日期",
|
||||
"开盘",
|
||||
"收盘",
|
||||
"最高",
|
||||
"最低",
|
||||
"成交量",
|
||||
"成交额",
|
||||
"振幅",
|
||||
"涨跌幅",
|
||||
"涨跌额",
|
||||
"换手率",
|
||||
]
|
||||
temp_df.index = pd.to_datetime(temp_df["日期"])
|
||||
temp_df.reset_index(inplace=True, drop=True)
|
||||
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 fund_lof_hist_min_em(
|
||||
symbol: str = "166009",
|
||||
start_date: str = "1979-09-01 09:32:00",
|
||||
end_date: str = "2222-01-01 09:32:00",
|
||||
period: str = "5",
|
||||
adjust: str = "",
|
||||
) -> pd.DataFrame:
|
||||
"""
|
||||
东方财富-LOF 分时行情
|
||||
https://quote.eastmoney.com/sz166009.html
|
||||
:param symbol: LOF 代码
|
||||
:type symbol: str
|
||||
:param start_date: 开始日期时间
|
||||
:type start_date: str
|
||||
:param end_date: 结束日期时间
|
||||
:type end_date: str
|
||||
:param period: choice of {"1", "5", "15", "30", "60"}
|
||||
:type period: str
|
||||
:param adjust: choice of {'', 'qfq', 'hfq'}
|
||||
:type adjust: str
|
||||
:return: 每日分时行情
|
||||
:rtype: pandas.DataFrame
|
||||
"""
|
||||
code_id_dict = _fund_lof_code_id_map_em()
|
||||
adjust_map = {
|
||||
"": "0",
|
||||
"qfq": "1",
|
||||
"hfq": "2",
|
||||
}
|
||||
if period == "1":
|
||||
url = "https://push2his.eastmoney.com/api/qt/stock/trends2/get"
|
||||
params = {
|
||||
"fields1": "f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11,f12,f13",
|
||||
"fields2": "f51,f52,f53,f54,f55,f56,f57,f58",
|
||||
"ut": "7eea3edcaed734bea9cbfc24409ed989",
|
||||
"ndays": "5",
|
||||
"iscr": "0",
|
||||
"secid": f"{code_id_dict[symbol]}.{symbol}",
|
||||
}
|
||||
r = requests.get(url, params=params)
|
||||
data_json = r.json()
|
||||
temp_df = pd.DataFrame(
|
||||
[item.split(",") for item in data_json["data"]["trends"]]
|
||||
)
|
||||
temp_df.columns = [
|
||||
"时间",
|
||||
"开盘",
|
||||
"收盘",
|
||||
"最高",
|
||||
"最低",
|
||||
"成交量",
|
||||
"成交额",
|
||||
"均价",
|
||||
]
|
||||
temp_df.index = pd.to_datetime(temp_df["时间"])
|
||||
temp_df = temp_df[start_date:end_date]
|
||||
temp_df.reset_index(drop=True, inplace=True)
|
||||
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)
|
||||
return temp_df
|
||||
else:
|
||||
url = "https://push2his.eastmoney.com/api/qt/stock/kline/get"
|
||||
params = {
|
||||
"fields1": "f1,f2,f3,f4,f5,f6",
|
||||
"fields2": "f51,f52,f53,f54,f55,f56,f57,f58,f59,f60,f61",
|
||||
"ut": "7eea3edcaed734bea9cbfc24409ed989",
|
||||
"klt": period,
|
||||
"fqt": adjust_map[adjust],
|
||||
"secid": f"{code_id_dict[symbol]}.{symbol}",
|
||||
"beg": "0",
|
||||
"end": "20500000",
|
||||
}
|
||||
r = requests.get(url, params=params)
|
||||
data_json = r.json()
|
||||
temp_df = pd.DataFrame(
|
||||
[item.split(",") for item in data_json["data"]["klines"]]
|
||||
)
|
||||
temp_df.columns = [
|
||||
"时间",
|
||||
"开盘",
|
||||
"收盘",
|
||||
"最高",
|
||||
"最低",
|
||||
"成交量",
|
||||
"成交额",
|
||||
"振幅",
|
||||
"涨跌幅",
|
||||
"涨跌额",
|
||||
"换手率",
|
||||
]
|
||||
temp_df.index = pd.to_datetime(temp_df["时间"])
|
||||
temp_df = temp_df[start_date:end_date]
|
||||
temp_df.reset_index(drop=True, inplace=True)
|
||||
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["时间"]).astype(str)
|
||||
temp_df = temp_df[
|
||||
[
|
||||
"时间",
|
||||
"开盘",
|
||||
"收盘",
|
||||
"最高",
|
||||
"最低",
|
||||
"涨跌幅",
|
||||
"涨跌额",
|
||||
"成交量",
|
||||
"成交额",
|
||||
"振幅",
|
||||
"换手率",
|
||||
]
|
||||
]
|
||||
return temp_df
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
fund_lof_spot_em_df = fund_lof_spot_em()
|
||||
print(fund_lof_spot_em_df)
|
||||
|
||||
fund_lof_hist_em_df = fund_lof_hist_em(
|
||||
symbol="166009",
|
||||
period="daily",
|
||||
start_date="20000101",
|
||||
end_date="20230703",
|
||||
adjust="",
|
||||
)
|
||||
print(fund_lof_hist_em_df)
|
||||
|
||||
fund_lof_hist_qfq_em_df = fund_lof_hist_em(
|
||||
symbol="166009",
|
||||
period="daily",
|
||||
start_date="20000101",
|
||||
end_date="20230703",
|
||||
adjust="qfq",
|
||||
)
|
||||
print(fund_lof_hist_qfq_em_df)
|
||||
|
||||
fund_lof_hist_em_df = fund_lof_hist_em(
|
||||
symbol="166009",
|
||||
period="daily",
|
||||
start_date="20000101",
|
||||
end_date="20250311",
|
||||
adjust="hfq",
|
||||
)
|
||||
print(fund_lof_hist_em_df)
|
||||
|
||||
fund_lof_hist_min_em_df = fund_lof_hist_min_em(
|
||||
symbol="166009",
|
||||
period="1",
|
||||
adjust="",
|
||||
start_date="2025-03-11 09:30:00",
|
||||
end_date="2025-03-11 14:40:00",
|
||||
)
|
||||
print(fund_lof_hist_min_em_df)
|
||||
@@ -0,0 +1,101 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding:utf-8 -*-
|
||||
"""
|
||||
Date: 2025/9/14 18:00
|
||||
Desc: 基金经理大全
|
||||
https://fund.eastmoney.com/manager/default.html
|
||||
"""
|
||||
|
||||
import pandas as pd
|
||||
import requests
|
||||
|
||||
from akshare.utils import demjson
|
||||
from akshare.utils.tqdm import get_tqdm
|
||||
|
||||
|
||||
def fund_manager_em() -> pd.DataFrame:
|
||||
"""
|
||||
天天基金网-基金数据-基金经理大全
|
||||
https://fund.eastmoney.com/manager/default.html
|
||||
:return: 基金经理大全
|
||||
:rtype: pandas.DataFrame
|
||||
"""
|
||||
big_df = pd.DataFrame()
|
||||
url = "https://fund.eastmoney.com/Data/FundDataPortfolio_Interface.aspx"
|
||||
params = {
|
||||
"dt": "14",
|
||||
"mc": "returnjson",
|
||||
"ft": "all",
|
||||
"pn": "500",
|
||||
"pi": "1",
|
||||
"sc": "abbname",
|
||||
"st": "asc",
|
||||
}
|
||||
r = requests.get(url, params=params)
|
||||
data_text = r.text
|
||||
data_json = demjson.decode(data_text.strip("var returnjson= "))
|
||||
total_page = data_json["pages"]
|
||||
tqdm = get_tqdm()
|
||||
for page in tqdm(range(1, total_page + 1), leave=False):
|
||||
params.update(
|
||||
{
|
||||
"pi": page,
|
||||
}
|
||||
)
|
||||
r = requests.get(url, params=params)
|
||||
data_text = r.text
|
||||
data_json = demjson.decode(data_text.strip("var returnjson= "))
|
||||
temp_df = pd.DataFrame(data_json["data"])
|
||||
big_df = pd.concat(objs=[big_df, temp_df], ignore_index=True)
|
||||
big_df.reset_index(inplace=True)
|
||||
big_df["index"] = range(1, len(big_df) + 1)
|
||||
big_df.columns = [
|
||||
"序号",
|
||||
"_",
|
||||
"姓名",
|
||||
"_",
|
||||
"所属公司",
|
||||
"现任基金代码",
|
||||
"现任基金",
|
||||
"累计从业时间",
|
||||
"现任基金最佳回报",
|
||||
"_",
|
||||
"_",
|
||||
"现任基金资产总规模",
|
||||
"_",
|
||||
]
|
||||
big_df = big_df[
|
||||
[
|
||||
"序号",
|
||||
"姓名",
|
||||
"所属公司",
|
||||
"现任基金代码",
|
||||
"现任基金",
|
||||
"累计从业时间",
|
||||
"现任基金资产总规模",
|
||||
"现任基金最佳回报",
|
||||
]
|
||||
]
|
||||
big_df["现任基金最佳回报"] = (
|
||||
big_df["现任基金最佳回报"].str.split("%", expand=True).iloc[:, 0]
|
||||
)
|
||||
big_df["现任基金资产总规模"] = (
|
||||
big_df["现任基金资产总规模"].str.split("亿元", expand=True).iloc[:, 0]
|
||||
)
|
||||
big_df["累计从业时间"] = pd.to_numeric(big_df["累计从业时间"], errors="coerce")
|
||||
big_df["现任基金最佳回报"] = pd.to_numeric(
|
||||
big_df["现任基金最佳回报"], errors="coerce"
|
||||
)
|
||||
big_df["现任基金资产总规模"] = pd.to_numeric(
|
||||
big_df["现任基金资产总规模"], errors="coerce"
|
||||
)
|
||||
big_df["现任基金代码"] = big_df["现任基金代码"].apply(lambda x: x.split(","))
|
||||
big_df["现任基金"] = big_df["现任基金"].apply(lambda x: x.split(","))
|
||||
big_df = big_df.explode(column=["现任基金代码", "现任基金"])
|
||||
big_df.reset_index(drop=True, inplace=True)
|
||||
return big_df
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
fund_manager_em_df = fund_manager_em()
|
||||
print(fund_manager_em_df)
|
||||
@@ -0,0 +1,43 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding:utf-8 -*-
|
||||
"""
|
||||
Date: 2025/9/16 21:00
|
||||
Desc: 天天基金-基金档案
|
||||
https://fundf10.eastmoney.com/jbgk_015641.html
|
||||
"""
|
||||
|
||||
from io import StringIO
|
||||
|
||||
import pandas as pd
|
||||
import requests
|
||||
|
||||
|
||||
def fund_overview_em(symbol: str = "015641") -> pd.DataFrame:
|
||||
"""
|
||||
天天基金-基金档案-基本概况
|
||||
https://fundf10.eastmoney.com/jbgk_015641.html
|
||||
:param symbol: 基金代码
|
||||
:type symbol: str
|
||||
:return: 基本概况
|
||||
:rtype: pandas.DataFrame
|
||||
"""
|
||||
url = f"https://fundf10.eastmoney.com/jbgk_{symbol}.html"
|
||||
r = requests.get(url)
|
||||
html_content = pd.read_html(StringIO(r.text))
|
||||
|
||||
if len(html_content) == 0:
|
||||
temp_df = pd.DataFrame([])
|
||||
else:
|
||||
df_dict = {}
|
||||
# 最后一个表格的数据是我们想要的,按照Key-Value的形式存储
|
||||
for _, row in html_content[-1].iterrows():
|
||||
df_dict[row[0]] = row[1]
|
||||
df_dict[row[2]] = row[3]
|
||||
temp_df = pd.DataFrame([df_dict])
|
||||
|
||||
return temp_df
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
fund_overview_em_df = fund_overview_em(symbol="015641")
|
||||
print(fund_overview_em_df)
|
||||
@@ -0,0 +1,336 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding:utf-8 -*-
|
||||
"""
|
||||
Date: 2024/6/7 20:00
|
||||
Desc: 天天基金网-基金档案-投资组合
|
||||
https://fundf10.eastmoney.com/ccmx_000001.html
|
||||
"""
|
||||
|
||||
from io import StringIO
|
||||
|
||||
import pandas as pd
|
||||
import requests
|
||||
from bs4 import BeautifulSoup
|
||||
|
||||
from akshare.utils import demjson
|
||||
|
||||
|
||||
def fund_portfolio_hold_em(symbol: str = "000001", date: str = "2024") -> pd.DataFrame:
|
||||
"""
|
||||
天天基金网-基金档案-投资组合-基金持仓
|
||||
https://fundf10.eastmoney.com/ccmx_000001.html
|
||||
:param symbol: 基金代码
|
||||
:type symbol: str
|
||||
:param date: 查询年份
|
||||
:type date: str
|
||||
:return: 基金持仓
|
||||
:rtype: pandas.DataFrame
|
||||
"""
|
||||
url = "https://fundf10.eastmoney.com/FundArchivesDatas.aspx"
|
||||
params = {
|
||||
"type": "jjcc",
|
||||
"code": symbol,
|
||||
"topline": "10000",
|
||||
"year": date,
|
||||
"month": "",
|
||||
"rt": "0.913877030254846",
|
||||
}
|
||||
r = requests.get(url, params=params)
|
||||
data_text = r.text
|
||||
data_json = demjson.decode(data_text[data_text.find("{") : -1])
|
||||
soup = BeautifulSoup(data_json["content"], features="lxml")
|
||||
item_label = [
|
||||
item.text.split("\xa0\xa0")[1]
|
||||
for item in soup.find_all(name="h4", attrs={"class": "t"})
|
||||
]
|
||||
|
||||
column_name = [
|
||||
"序号",
|
||||
"股票代码",
|
||||
"股票名称",
|
||||
"占净值比例",
|
||||
"持股数",
|
||||
"持仓市值",
|
||||
"季度",
|
||||
]
|
||||
big_df = pd.DataFrame(columns=column_name)
|
||||
|
||||
for item in range(len(item_label)):
|
||||
temp_df = pd.read_html(
|
||||
StringIO(data_json["content"]), converters={"股票代码": str}
|
||||
)[item]
|
||||
del temp_df["相关资讯"]
|
||||
temp_df.rename(columns={"占净值 比例": "占净值比例"}, inplace=True)
|
||||
temp_df["占净值比例"] = (
|
||||
temp_df["占净值比例"].str.split("%", expand=True).iloc[:, 0]
|
||||
)
|
||||
temp_df.rename(
|
||||
columns={"持股数(万股)": "持股数", "持仓市值(万元)": "持仓市值"},
|
||||
inplace=True,
|
||||
)
|
||||
temp_df.rename(
|
||||
columns={"持股数 (万股)": "持股数", "持仓市值 (万元)": "持仓市值"},
|
||||
inplace=True,
|
||||
)
|
||||
temp_df.rename(
|
||||
columns={"持股数(万股)": "持股数", "持仓市值(万元人民币)": "持仓市值"},
|
||||
inplace=True,
|
||||
)
|
||||
temp_df.rename(
|
||||
columns={
|
||||
"持股数 (万股)": "持股数",
|
||||
"持仓市值 (万元人民币)": "持仓市值",
|
||||
},
|
||||
inplace=True,
|
||||
)
|
||||
|
||||
temp_df["季度"] = item_label[item]
|
||||
temp_df = temp_df[column_name]
|
||||
big_df = (
|
||||
pd.concat(objs=[temp_df, big_df], ignore_index=True)
|
||||
if not big_df.empty
|
||||
else temp_df
|
||||
)
|
||||
|
||||
if not big_df.empty:
|
||||
big_df["占净值比例"] = pd.to_numeric(big_df["占净值比例"], errors="coerce")
|
||||
big_df["持股数"] = pd.to_numeric(big_df["持股数"], errors="coerce")
|
||||
big_df["持仓市值"] = pd.to_numeric(big_df["持仓市值"], errors="coerce")
|
||||
del big_df["序号"]
|
||||
big_df.reset_index(inplace=True, drop=False)
|
||||
big_df["index"] = big_df["index"] + 1
|
||||
big_df.rename(columns={"index": "序号"}, inplace=True)
|
||||
return big_df
|
||||
|
||||
|
||||
def fund_portfolio_bond_hold_em(
|
||||
symbol: str = "000001", date: str = "2023"
|
||||
) -> pd.DataFrame:
|
||||
"""
|
||||
天天基金网-基金档案-投资组合-债券持仓
|
||||
https://fundf10.eastmoney.com/ccmx1_000001.html
|
||||
:param symbol: 基金代码
|
||||
:type symbol: str
|
||||
:param date: 查询年份
|
||||
:type date: str
|
||||
:return: 债券持仓
|
||||
:rtype: pandas.DataFrame
|
||||
"""
|
||||
url = "https://fundf10.eastmoney.com/FundArchivesDatas.aspx"
|
||||
params = {
|
||||
"type": "zqcc",
|
||||
"code": symbol,
|
||||
"year": date,
|
||||
"rt": "0.913877030254846",
|
||||
}
|
||||
r = requests.get(url, params=params)
|
||||
data_text = r.text
|
||||
data_json = demjson.decode(data_text[data_text.find("{") : -1])
|
||||
soup = BeautifulSoup(data_json["content"], features="lxml")
|
||||
item_label = [
|
||||
item.text.split("\xa0\xa0")[1]
|
||||
for item in soup.find_all(name="h4", attrs={"class": "t"})
|
||||
]
|
||||
big_df = pd.DataFrame()
|
||||
for item in range(len(item_label)):
|
||||
temp_df = pd.read_html(
|
||||
StringIO(data_json["content"]), converters={"债券代码": str}
|
||||
)[item]
|
||||
temp_df["占净值比例"] = (
|
||||
temp_df["占净值比例"].str.split("%", expand=True).iloc[:, 0]
|
||||
)
|
||||
temp_df.rename(columns={"持仓市值(万元)": "持仓市值"}, inplace=True)
|
||||
temp_df["季度"] = item_label[item]
|
||||
temp_df = temp_df[
|
||||
[
|
||||
"序号",
|
||||
"债券代码",
|
||||
"债券名称",
|
||||
"占净值比例",
|
||||
"持仓市值",
|
||||
"季度",
|
||||
]
|
||||
]
|
||||
big_df = pd.concat(objs=[big_df, temp_df], ignore_index=True)
|
||||
big_df["占净值比例"] = pd.to_numeric(big_df["占净值比例"], errors="coerce")
|
||||
big_df["持仓市值"] = pd.to_numeric(big_df["持仓市值"], errors="coerce")
|
||||
big_df["序号"] = range(1, len(big_df) + 1)
|
||||
return big_df
|
||||
|
||||
|
||||
def fund_portfolio_industry_allocation_em(
|
||||
symbol: str = "000001", date: str = "2023"
|
||||
) -> pd.DataFrame:
|
||||
"""
|
||||
天天基金网-基金档案-投资组合-行业配置
|
||||
https://fundf10.eastmoney.com/hytz_000001.html
|
||||
:param symbol: 基金代码
|
||||
:type symbol: str
|
||||
:param date: 查询年份
|
||||
:type date: str
|
||||
:return: 行业配置
|
||||
:rtype: pandas.DataFrame
|
||||
"""
|
||||
url = "https://api.fund.eastmoney.com/f10/HYPZ/"
|
||||
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": "api.fund.eastmoney.com",
|
||||
"Pragma": "no-cache",
|
||||
"Referer": "https://fundf10.eastmoney.com/",
|
||||
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "
|
||||
"Chrome/99.0.4844.82 Safari/537.36",
|
||||
}
|
||||
params = {
|
||||
"fundCode": symbol,
|
||||
"year": date,
|
||||
"callback": "jQuery183006997159478989867_1648016188499",
|
||||
}
|
||||
r = requests.get(url, params=params, headers=headers)
|
||||
data_text = r.text
|
||||
data_json = demjson.decode(data_text[data_text.find("{") : -1])
|
||||
temp_list = []
|
||||
for item in data_json["Data"]["QuarterInfos"]:
|
||||
temp_list.extend(item["HYPZInfo"])
|
||||
temp_df = pd.DataFrame(temp_list)
|
||||
temp_df.reset_index(inplace=True)
|
||||
temp_df["index"] = temp_df.index + 1
|
||||
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")
|
||||
return temp_df
|
||||
|
||||
|
||||
def fund_portfolio_change_em(
|
||||
symbol: str = "003567", indicator: str = "累计买入", date: str = "2023"
|
||||
) -> pd.DataFrame:
|
||||
"""
|
||||
天天基金网-基金档案-投资组合-重大变动
|
||||
https://fundf10.eastmoney.com/ccbd_000001.html
|
||||
:param symbol: 基金代码
|
||||
:type symbol: str
|
||||
:param indicator: choice of {"累计买入", "累计卖出"}
|
||||
:type indicator: str
|
||||
:param date: 查询年份
|
||||
:type date: str
|
||||
:return: 重大变动
|
||||
:rtype: pandas.DataFrame
|
||||
"""
|
||||
indicator_map = {
|
||||
"累计买入": "1",
|
||||
"累计卖出": "2",
|
||||
}
|
||||
url = "https://fundf10.eastmoney.com/FundArchivesDatas.aspx"
|
||||
params = {
|
||||
"type": "zdbd",
|
||||
"code": symbol,
|
||||
"zdbd": indicator_map[indicator],
|
||||
"year": date,
|
||||
"rt": "0.913877030254846",
|
||||
}
|
||||
r = requests.get(url, params=params)
|
||||
data_text = r.text
|
||||
data_json = demjson.decode(data_text[data_text.find("{") : -1])
|
||||
soup = BeautifulSoup(data_json["content"], features="lxml")
|
||||
item_label = [
|
||||
item.text.split("\xa0\xa0")[1]
|
||||
for item in soup.find_all(name="h4", attrs={"class": "t"})
|
||||
]
|
||||
big_df = pd.DataFrame()
|
||||
for item in range(len(item_label)):
|
||||
temp_df = pd.read_html(
|
||||
StringIO(data_json["content"]), converters={"股票代码": str}
|
||||
)[item]
|
||||
del temp_df["相关资讯"]
|
||||
temp_df["占期初基金资产净值比例(%)"] = (
|
||||
temp_df["占期初基金资产净值比例(%)"]
|
||||
.str.split("%", expand=True)
|
||||
.iloc[:, 0]
|
||||
)
|
||||
temp_df["季度"] = item_label[item]
|
||||
temp_df.columns = [
|
||||
"序号",
|
||||
"股票代码",
|
||||
"股票名称",
|
||||
"本期累计买入金额",
|
||||
"占期初基金资产净值比例",
|
||||
"季度",
|
||||
]
|
||||
temp_df = temp_df[
|
||||
[
|
||||
"序号",
|
||||
"股票代码",
|
||||
"股票名称",
|
||||
"本期累计买入金额",
|
||||
"占期初基金资产净值比例",
|
||||
"季度",
|
||||
]
|
||||
]
|
||||
big_df = pd.concat(objs=[big_df, temp_df], ignore_index=True)
|
||||
del big_df["序号"]
|
||||
big_df.reset_index(inplace=True)
|
||||
big_df["index"] = big_df.index + 1
|
||||
big_df.rename(columns={"index": "序号"}, inplace=True)
|
||||
|
||||
big_df["本期累计买入金额"] = pd.to_numeric(
|
||||
big_df["本期累计买入金额"], errors="coerce"
|
||||
)
|
||||
big_df["占期初基金资产净值比例"] = pd.to_numeric(
|
||||
big_df["占期初基金资产净值比例"], errors="coerce"
|
||||
)
|
||||
return big_df
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
fund_portfolio_hold_em_df = fund_portfolio_hold_em(symbol="000001", date="2024")
|
||||
print(fund_portfolio_hold_em_df)
|
||||
|
||||
fund_portfolio_bond_hold_em_df = fund_portfolio_bond_hold_em(
|
||||
symbol="000001", date="2023"
|
||||
)
|
||||
print(fund_portfolio_bond_hold_em_df)
|
||||
|
||||
fund_portfolio_industry_allocation_em_df = fund_portfolio_industry_allocation_em(
|
||||
symbol="000001", date="2023"
|
||||
)
|
||||
print(fund_portfolio_industry_allocation_em_df)
|
||||
|
||||
fund_portfolio_change_em_df = fund_portfolio_change_em(
|
||||
symbol="003567", indicator="累计买入", date="2023"
|
||||
)
|
||||
print(fund_portfolio_change_em_df)
|
||||
|
||||
fund_portfolio_change_em_df = fund_portfolio_change_em(
|
||||
symbol="003567", indicator="累计卖出", date="2023"
|
||||
)
|
||||
print(fund_portfolio_change_em_df)
|
||||
@@ -0,0 +1,135 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding:utf-8 -*-
|
||||
"""
|
||||
Date: 2023/4/5 22:05
|
||||
Desc: 乐咕乐股-基金仓位
|
||||
https://legulegu.com/stockdata/fund-position/pos-stock
|
||||
"""
|
||||
|
||||
import pandas as pd
|
||||
import requests
|
||||
|
||||
from akshare.stock_feature.stock_a_indicator import get_token_lg, get_cookie_csrf
|
||||
|
||||
|
||||
def fund_stock_position_lg() -> pd.DataFrame:
|
||||
"""
|
||||
乐咕乐股-基金仓位-股票型基金仓位
|
||||
https://legulegu.com/stockdata/fund-position/pos-stock
|
||||
:return: 股票型基金仓位
|
||||
:rtype: pandas.DataFrame
|
||||
"""
|
||||
url = "https://legulegu.com/api/stockdata/fund-position"
|
||||
token = get_token_lg()
|
||||
params = {
|
||||
"token": token,
|
||||
"type": "pos_stock",
|
||||
"category": "总仓位",
|
||||
"marketId": "5",
|
||||
}
|
||||
r = requests.get(
|
||||
url,
|
||||
params=params,
|
||||
**get_cookie_csrf(url="https://legulegu.com/stockdata/fund-position/pos-stock"),
|
||||
)
|
||||
data_json = r.json()
|
||||
temp_df = pd.DataFrame(data_json)
|
||||
temp_df["date"] = pd.to_datetime(temp_df["date"]).dt.date
|
||||
temp_df = temp_df[
|
||||
[
|
||||
"date",
|
||||
"close",
|
||||
"position",
|
||||
]
|
||||
]
|
||||
temp_df["date"] = pd.to_datetime(temp_df["date"]).dt.date
|
||||
temp_df["close"] = pd.to_numeric(temp_df["close"], errors="coerce")
|
||||
temp_df["position"] = pd.to_numeric(temp_df["position"], errors="coerce")
|
||||
return temp_df
|
||||
|
||||
|
||||
def fund_balance_position_lg() -> pd.DataFrame:
|
||||
"""
|
||||
乐咕乐股-基金仓位-平衡混合型基金仓位
|
||||
https://legulegu.com/stockdata/fund-position/pos-pingheng
|
||||
:return: 平衡混合型基金仓位
|
||||
:rtype: pandas.DataFrame
|
||||
"""
|
||||
url = "https://legulegu.com/api/stockdata/fund-position"
|
||||
token = get_token_lg()
|
||||
params = {
|
||||
"token": token,
|
||||
"type": "pos_pingheng",
|
||||
"category": "总仓位",
|
||||
"marketId": "5",
|
||||
}
|
||||
r = requests.get(
|
||||
url,
|
||||
params=params,
|
||||
**get_cookie_csrf(
|
||||
url="https://legulegu.com/stockdata/fund-position/pos-pingheng"
|
||||
),
|
||||
)
|
||||
data_json = r.json()
|
||||
temp_df = pd.DataFrame(data_json)
|
||||
temp_df["date"] = pd.to_datetime(temp_df["date"]).dt.date
|
||||
temp_df = temp_df[
|
||||
[
|
||||
"date",
|
||||
"close",
|
||||
"position",
|
||||
]
|
||||
]
|
||||
temp_df["date"] = pd.to_datetime(temp_df["date"]).dt.date
|
||||
temp_df["close"] = pd.to_numeric(temp_df["close"], errors="coerce")
|
||||
temp_df["position"] = pd.to_numeric(temp_df["position"], errors="coerce")
|
||||
return temp_df
|
||||
|
||||
|
||||
def fund_linghuo_position_lg() -> pd.DataFrame:
|
||||
"""
|
||||
乐咕乐股-基金仓位-灵活配置型基金仓位
|
||||
https://legulegu.com/stockdata/fund-position/pos-linghuo
|
||||
:return: 灵活配置型基金仓位
|
||||
:rtype: pandas.DataFrame
|
||||
"""
|
||||
url = "https://legulegu.com/api/stockdata/fund-position"
|
||||
token = get_token_lg()
|
||||
params = {
|
||||
"token": token,
|
||||
"type": "pos_linghuo",
|
||||
"category": "总仓位",
|
||||
"marketId": "5",
|
||||
}
|
||||
r = requests.get(
|
||||
url,
|
||||
params=params,
|
||||
**get_cookie_csrf(
|
||||
url="https://legulegu.com/stockdata/fund-position/pos-linghuo"
|
||||
),
|
||||
)
|
||||
data_json = r.json()
|
||||
temp_df = pd.DataFrame(data_json)
|
||||
temp_df["date"] = pd.to_datetime(temp_df["date"]).dt.date
|
||||
temp_df = temp_df[
|
||||
[
|
||||
"date",
|
||||
"close",
|
||||
"position",
|
||||
]
|
||||
]
|
||||
temp_df["date"] = pd.to_datetime(temp_df["date"]).dt.date
|
||||
temp_df["close"] = pd.to_numeric(temp_df["close"], errors="coerce")
|
||||
temp_df["position"] = pd.to_numeric(temp_df["position"], errors="coerce")
|
||||
return temp_df
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
fund_stock_position_lg_df = fund_stock_position_lg()
|
||||
print(fund_stock_position_lg_df)
|
||||
|
||||
fund_balance_position_lg_df = fund_balance_position_lg()
|
||||
print(fund_balance_position_lg_df)
|
||||
|
||||
fund_linghuo_position_lg_df = fund_linghuo_position_lg()
|
||||
print(fund_linghuo_position_lg_df)
|
||||
@@ -0,0 +1,555 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding:utf-8 -*-
|
||||
"""
|
||||
Date: 2024/7/24 13:00
|
||||
Desc: 东方财富网-数据中心-开放基金排行
|
||||
https://fund.eastmoney.com/data/fundranking.html
|
||||
名词解释
|
||||
https://help.1234567.com.cn/list_236.html
|
||||
"""
|
||||
|
||||
from datetime import datetime, date
|
||||
|
||||
import pandas as pd
|
||||
import requests
|
||||
|
||||
from akshare.utils import demjson
|
||||
|
||||
|
||||
def __one_year_ago(date_str: str) -> date:
|
||||
# 将字符串格式的日期转换为date对象
|
||||
given_date = date(int(date_str[0:4]), int(date_str[4:6]), int(date_str[6:8]))
|
||||
|
||||
try:
|
||||
# 尝试直接设置为前一年,保持相同的月和日
|
||||
one_year_before = given_date.replace(year=given_date.year - 1)
|
||||
except ValueError:
|
||||
# 如果前一年没有相同的月和日(比如2月29日),则设置为2月28日
|
||||
one_year_before = given_date.replace(year=given_date.year - 1, day=28)
|
||||
|
||||
return one_year_before
|
||||
|
||||
|
||||
def fund_open_fund_rank_em(symbol: str = "全部") -> pd.DataFrame:
|
||||
"""
|
||||
东方财富网-数据中心-开放基金排行
|
||||
https://fund.eastmoney.com/data/fundranking.html
|
||||
:param symbol: choice of {"全部", "股票型", "混合型", "债券型", "指数型", "QDII", "FOF"}
|
||||
:type symbol: str
|
||||
:return: 开放基金排行
|
||||
:rtype: pandas.DataFrame
|
||||
"""
|
||||
current_date = datetime.now().date().isoformat()
|
||||
last_date = __one_year_ago(current_date.replace("-", "")).isoformat()
|
||||
url = "https://fund.eastmoney.com/data/rankhandler.aspx"
|
||||
type_map = {
|
||||
"全部": ["all", "1nzf"],
|
||||
"股票型": ["gp", "1nzf"],
|
||||
"混合型": ["hh", "1nzf"],
|
||||
"债券型": ["zq", "1nzf"],
|
||||
"指数型": ["zs", "1nzf"],
|
||||
"QDII": ["qdii", "1nzf"],
|
||||
"LOF": ["lof", "1nzf"],
|
||||
"FOF": ["fof", "1nzf"],
|
||||
}
|
||||
params = {
|
||||
"op": "ph",
|
||||
"dt": "kf",
|
||||
"ft": type_map[symbol][0],
|
||||
"rs": "",
|
||||
"gs": "0",
|
||||
"sc": type_map[symbol][1],
|
||||
"st": "desc",
|
||||
"sd": last_date,
|
||||
"ed": current_date,
|
||||
"qdii": "",
|
||||
"tabSubtype": ",,,,,",
|
||||
"pi": "1",
|
||||
"pn": "30000",
|
||||
"dx": "1",
|
||||
"v": "0.1591891419018292",
|
||||
}
|
||||
headers = {
|
||||
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "
|
||||
"Chrome/81.0.4044.138 Safari/537.36",
|
||||
"Referer": "https://fund.eastmoney.com/fundguzhi.html",
|
||||
}
|
||||
r = requests.get(url, params=params, headers=headers)
|
||||
data_text = r.text
|
||||
data_json = demjson.decode(data_text[data_text.find("{") : -1])
|
||||
temp_df = pd.DataFrame(data_json["datas"])
|
||||
temp_df = temp_df.iloc[:, 0].str.split(",", expand=True)
|
||||
temp_df.reset_index(inplace=True)
|
||||
temp_df["index"] = list(range(1, len(temp_df) + 1))
|
||||
temp_df.columns = [
|
||||
"序号",
|
||||
"基金代码",
|
||||
"基金简称",
|
||||
"_",
|
||||
"日期",
|
||||
"单位净值",
|
||||
"累计净值",
|
||||
"日增长率",
|
||||
"近1周",
|
||||
"近1月",
|
||||
"近3月",
|
||||
"近6月",
|
||||
"近1年",
|
||||
"近2年",
|
||||
"近3年",
|
||||
"今年来",
|
||||
"成立来",
|
||||
"_",
|
||||
"_",
|
||||
"自定义",
|
||||
"_",
|
||||
"手续费",
|
||||
"_",
|
||||
"_",
|
||||
"_",
|
||||
"_",
|
||||
]
|
||||
temp_df = temp_df[
|
||||
[
|
||||
"序号",
|
||||
"基金代码",
|
||||
"基金简称",
|
||||
"日期",
|
||||
"单位净值",
|
||||
"累计净值",
|
||||
"日增长率",
|
||||
"近1周",
|
||||
"近1月",
|
||||
"近3月",
|
||||
"近6月",
|
||||
"近1年",
|
||||
"近2年",
|
||||
"近3年",
|
||||
"今年来",
|
||||
"成立来",
|
||||
"自定义",
|
||||
"手续费",
|
||||
]
|
||||
]
|
||||
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["近1周"] = pd.to_numeric(temp_df["近1周"], errors="coerce")
|
||||
temp_df["近1月"] = pd.to_numeric(temp_df["近1月"], errors="coerce")
|
||||
temp_df["近3月"] = pd.to_numeric(temp_df["近3月"], errors="coerce")
|
||||
temp_df["近6月"] = pd.to_numeric(temp_df["近6月"], errors="coerce")
|
||||
temp_df["近1年"] = pd.to_numeric(temp_df["近1年"], errors="coerce")
|
||||
temp_df["近2年"] = pd.to_numeric(temp_df["近2年"], errors="coerce")
|
||||
temp_df["近3年"] = pd.to_numeric(temp_df["近3年"], 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 fund_exchange_rank_em() -> pd.DataFrame:
|
||||
"""
|
||||
东方财富网-数据中心-场内交易基金排行
|
||||
https://fund.eastmoney.com/data/fbsfundranking.html
|
||||
:return: 场内交易基金数据
|
||||
:rtype: pandas.DataFrame
|
||||
"""
|
||||
url = "https://fund.eastmoney.com/data/rankhandler.aspx"
|
||||
params = {
|
||||
"op": "ph",
|
||||
"dt": "fb",
|
||||
"ft": "ct",
|
||||
"rs": "",
|
||||
"gs": "0",
|
||||
"sc": "1nzf",
|
||||
"st": "desc",
|
||||
"pi": "1",
|
||||
"pn": "30000",
|
||||
"v": "0.1591891419018292",
|
||||
}
|
||||
headers = {
|
||||
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "
|
||||
"Chrome/81.0.4044.138 Safari/537.36",
|
||||
"Referer": "https://fund.eastmoney.com/fundguzhi.html",
|
||||
}
|
||||
r = requests.get(url, params=params, headers=headers)
|
||||
text_data = r.text
|
||||
json_data = demjson.decode(text_data[text_data.find("{") : -1])
|
||||
temp_df = pd.DataFrame(json_data["datas"])
|
||||
temp_df = temp_df.iloc[:, 0].str.split(",", expand=True)
|
||||
temp_df.reset_index(inplace=True)
|
||||
temp_df["index"] = list(range(1, len(temp_df) + 1))
|
||||
temp_df.columns = [
|
||||
"序号",
|
||||
"基金代码",
|
||||
"基金简称",
|
||||
"_",
|
||||
"日期",
|
||||
"单位净值",
|
||||
"累计净值",
|
||||
"近1周",
|
||||
"近1月",
|
||||
"近3月",
|
||||
"近6月",
|
||||
"近1年",
|
||||
"近2年",
|
||||
"近3年",
|
||||
"今年来",
|
||||
"成立来",
|
||||
"成立日期",
|
||||
"_",
|
||||
"_",
|
||||
"_",
|
||||
"_",
|
||||
"_",
|
||||
"类型",
|
||||
"_",
|
||||
]
|
||||
temp_df = temp_df[
|
||||
[
|
||||
"序号",
|
||||
"基金代码",
|
||||
"基金简称",
|
||||
"类型",
|
||||
"日期",
|
||||
"单位净值",
|
||||
"累计净值",
|
||||
"近1周",
|
||||
"近1月",
|
||||
"近3月",
|
||||
"近6月",
|
||||
"近1年",
|
||||
"近2年",
|
||||
"近3年",
|
||||
"今年来",
|
||||
"成立来",
|
||||
"成立日期",
|
||||
]
|
||||
]
|
||||
temp_df["日期"] = pd.to_datetime(temp_df["日期"], errors="coerce").dt.date
|
||||
temp_df["成立日期"] = pd.to_datetime(temp_df["成立日期"]).dt.date
|
||||
temp_df["单位净值"] = pd.to_numeric(temp_df["单位净值"], errors="coerce")
|
||||
temp_df["累计净值"] = pd.to_numeric(temp_df["累计净值"], errors="coerce")
|
||||
temp_df["近1周"] = pd.to_numeric(temp_df["近1周"], errors="coerce")
|
||||
temp_df["近1月"] = pd.to_numeric(temp_df["近1月"], errors="coerce")
|
||||
temp_df["近3月"] = pd.to_numeric(temp_df["近3月"], errors="coerce")
|
||||
temp_df["近6月"] = pd.to_numeric(temp_df["近6月"], errors="coerce")
|
||||
temp_df["近1年"] = pd.to_numeric(temp_df["近1年"], errors="coerce")
|
||||
temp_df["近2年"] = pd.to_numeric(temp_df["近2年"], errors="coerce")
|
||||
temp_df["近3年"] = pd.to_numeric(temp_df["近3年"], errors="coerce")
|
||||
temp_df["今年来"] = pd.to_numeric(temp_df["今年来"], errors="coerce")
|
||||
temp_df["成立来"] = pd.to_numeric(temp_df["成立来"], errors="coerce")
|
||||
return temp_df
|
||||
|
||||
|
||||
def fund_money_rank_em() -> pd.DataFrame:
|
||||
"""
|
||||
东方财富网-数据中心-货币型基金排行
|
||||
https://fund.eastmoney.com/data/hbxfundranking.html
|
||||
:return: 货币型基金排行
|
||||
:rtype: pandas.DataFrame
|
||||
"""
|
||||
url = "https://api.fund.eastmoney.com/FundRank/GetHbRankList"
|
||||
params = {
|
||||
"intCompany": "0",
|
||||
"MinsgType": "",
|
||||
"IsSale": "1",
|
||||
"strSortCol": "SYL_1N",
|
||||
"orderType": "desc",
|
||||
"pageIndex": "1",
|
||||
"pageSize": "10000",
|
||||
}
|
||||
headers = {
|
||||
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "
|
||||
"Chrome/81.0.4044.138 Safari/537.36",
|
||||
"Referer": "https://fund.eastmoney.com/fundguzhi.html",
|
||||
}
|
||||
r = requests.get(url, params=params, headers=headers)
|
||||
json_data = r.json()
|
||||
temp_df = pd.DataFrame(json_data["Data"])
|
||||
temp_df.reset_index(inplace=True)
|
||||
temp_df["index"] = list(range(1, len(temp_df) + 1))
|
||||
temp_df.columns = [
|
||||
"序号",
|
||||
"近1年",
|
||||
"近2年",
|
||||
"近3年",
|
||||
"近5年",
|
||||
"_",
|
||||
"_",
|
||||
"基金代码",
|
||||
"基金简称",
|
||||
"日期",
|
||||
"万份收益",
|
||||
"年化收益率7日",
|
||||
"_",
|
||||
"年化收益率14日",
|
||||
"年化收益率28日",
|
||||
"近1月",
|
||||
"近3月",
|
||||
"近6月",
|
||||
"今年来",
|
||||
"成立来",
|
||||
"_",
|
||||
"手续费",
|
||||
"_",
|
||||
"_",
|
||||
"_",
|
||||
"_",
|
||||
"_",
|
||||
"_",
|
||||
]
|
||||
temp_df = temp_df[
|
||||
[
|
||||
"序号",
|
||||
"基金代码",
|
||||
"基金简称",
|
||||
"日期",
|
||||
"万份收益",
|
||||
"年化收益率7日",
|
||||
"年化收益率14日",
|
||||
"年化收益率28日",
|
||||
"近1月",
|
||||
"近3月",
|
||||
"近6月",
|
||||
"近1年",
|
||||
"近2年",
|
||||
"近3年",
|
||||
"近5年",
|
||||
"今年来",
|
||||
"成立来",
|
||||
"手续费",
|
||||
]
|
||||
]
|
||||
temp_df["日期"] = pd.to_datetime(temp_df["日期"], errors="coerce").dt.date
|
||||
temp_df["万份收益"] = pd.to_numeric(temp_df["万份收益"], errors="coerce")
|
||||
temp_df["年化收益率7日"] = pd.to_numeric(temp_df["年化收益率7日"], errors="coerce")
|
||||
temp_df["年化收益率14日"] = pd.to_numeric(
|
||||
temp_df["年化收益率14日"], errors="coerce"
|
||||
)
|
||||
temp_df["年化收益率28日"] = pd.to_numeric(
|
||||
temp_df["年化收益率28日"], errors="coerce"
|
||||
)
|
||||
temp_df["近1月"] = pd.to_numeric(temp_df["近1月"], errors="coerce")
|
||||
temp_df["近3月"] = pd.to_numeric(temp_df["近3月"], errors="coerce")
|
||||
temp_df["近6月"] = pd.to_numeric(temp_df["近6月"], errors="coerce")
|
||||
temp_df["近1年"] = pd.to_numeric(temp_df["近1年"], errors="coerce")
|
||||
temp_df["近2年"] = pd.to_numeric(temp_df["近2年"], errors="coerce")
|
||||
temp_df["近3年"] = pd.to_numeric(temp_df["近3年"], errors="coerce")
|
||||
temp_df["近5年"] = pd.to_numeric(temp_df["近5年"], errors="coerce")
|
||||
temp_df["今年来"] = pd.to_numeric(temp_df["今年来"], errors="coerce")
|
||||
temp_df["成立来"] = pd.to_numeric(temp_df["成立来"], errors="coerce")
|
||||
return temp_df
|
||||
|
||||
|
||||
def fund_lcx_rank_em() -> pd.DataFrame:
|
||||
"""
|
||||
东方财富网-数据中心-理财基金排行
|
||||
# 该接口暂时没有数据
|
||||
https://fund.eastmoney.com/data/lcxfundranking.html#t;c0;r;sSYL_Z;ddesc;pn50;f;os1;
|
||||
:return: 理财基金排行
|
||||
:rtype: pandas.DataFrame
|
||||
"""
|
||||
url = "https://api.fund.eastmoney.com/FundRank/GetLcRankList"
|
||||
params = {
|
||||
"intCompany": "0",
|
||||
"MinsgType": "undefined",
|
||||
"IsSale": "1",
|
||||
"strSortCol": "SYL_Z",
|
||||
"orderType": "desc",
|
||||
"pageIndex": "1",
|
||||
"pageSize": "50",
|
||||
"FBQ": "",
|
||||
"callback": "jQuery18303264654966943197_1603867158043",
|
||||
}
|
||||
headers = {
|
||||
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "
|
||||
"Chrome/81.0.4044.138 Safari/537.36",
|
||||
"Referer": "https://fund.eastmoney.com/fundguzhi.html",
|
||||
}
|
||||
r = requests.get(url, params=params, headers=headers)
|
||||
try:
|
||||
data_json = r.json()
|
||||
except: # noqa: E722
|
||||
return pd.DataFrame()
|
||||
temp_df = pd.DataFrame(data_json["Data"])
|
||||
temp_df.reset_index(inplace=True)
|
||||
temp_df["index"] = list(range(1, len(temp_df) + 1))
|
||||
temp_df.columns = [
|
||||
"序号",
|
||||
"近1周",
|
||||
"基金代码",
|
||||
"基金简称",
|
||||
"日期",
|
||||
"万份收益",
|
||||
"年化收益率-7日",
|
||||
"_",
|
||||
"年化收益率-14日",
|
||||
"年化收益率-28日",
|
||||
"近1月",
|
||||
"近3月",
|
||||
"近6月",
|
||||
"今年来",
|
||||
"成立来",
|
||||
"可购买",
|
||||
"手续费",
|
||||
"_",
|
||||
"_",
|
||||
"_",
|
||||
"_",
|
||||
"_",
|
||||
"_",
|
||||
]
|
||||
temp_df = temp_df[
|
||||
[
|
||||
"序号",
|
||||
"基金代码",
|
||||
"基金简称",
|
||||
"日期",
|
||||
"万份收益",
|
||||
"年化收益率-7日",
|
||||
"年化收益率-14日",
|
||||
"年化收益率-28日",
|
||||
"近1周",
|
||||
"近1月",
|
||||
"近3月",
|
||||
"近6月",
|
||||
"今年来",
|
||||
"成立来",
|
||||
"可购买",
|
||||
"手续费",
|
||||
]
|
||||
]
|
||||
return temp_df
|
||||
|
||||
|
||||
def fund_hk_rank_em() -> pd.DataFrame:
|
||||
"""
|
||||
东方财富网-数据中心-香港基金排行
|
||||
https://overseas.1234567.com.cn/FundList
|
||||
:return: 香港基金排行
|
||||
:rtype: pandas.DataFrame
|
||||
"""
|
||||
format_date = datetime.now().date().isoformat()
|
||||
url = "https://overseas.1234567.com.cn/overseasapi/OpenApiHander.ashx"
|
||||
params = {
|
||||
"api": "HKFDApi",
|
||||
"m": "MethodFundList",
|
||||
"action": "1",
|
||||
"pageindex": "0",
|
||||
"pagesize": "5000",
|
||||
"dy": "1",
|
||||
"date1": format_date,
|
||||
"date2": format_date,
|
||||
"sortfield": "Y",
|
||||
"sorttype": "-1",
|
||||
"isbuy": "0",
|
||||
}
|
||||
headers = {
|
||||
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "
|
||||
"Chrome/81.0.4044.138 Safari/537.36",
|
||||
"Referer": "https://fund.eastmoney.com/fundguzhi.html",
|
||||
}
|
||||
r = requests.get(url, params=params, headers=headers)
|
||||
data_json = r.json()
|
||||
temp_df = pd.DataFrame(data_json["Data"])
|
||||
temp_df.reset_index(inplace=True)
|
||||
temp_df["index"] = list(range(1, len(temp_df) + 1))
|
||||
temp_df.columns = [
|
||||
"序号",
|
||||
"_",
|
||||
"香港基金代码",
|
||||
"基金代码",
|
||||
"_",
|
||||
"基金简称",
|
||||
"可购买",
|
||||
"日期",
|
||||
"单位净值",
|
||||
"日增长率",
|
||||
"_",
|
||||
"近1周",
|
||||
"近1月",
|
||||
"近3月",
|
||||
"近6月",
|
||||
"近1年",
|
||||
"近2年",
|
||||
"近3年",
|
||||
"今年来",
|
||||
"成立来",
|
||||
"币种",
|
||||
]
|
||||
temp_df = temp_df[
|
||||
[
|
||||
"序号",
|
||||
"基金代码",
|
||||
"基金简称",
|
||||
"币种",
|
||||
"日期",
|
||||
"单位净值",
|
||||
"日增长率",
|
||||
"近1周",
|
||||
"近1月",
|
||||
"近3月",
|
||||
"近6月",
|
||||
"近1年",
|
||||
"近2年",
|
||||
"近3年",
|
||||
"今年来",
|
||||
"成立来",
|
||||
"可购买",
|
||||
"香港基金代码",
|
||||
]
|
||||
]
|
||||
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["近1周"] = pd.to_numeric(temp_df["近1周"], errors="coerce")
|
||||
temp_df["近1月"] = pd.to_numeric(temp_df["近1月"], errors="coerce")
|
||||
temp_df["近3月"] = pd.to_numeric(temp_df["近3月"], errors="coerce")
|
||||
temp_df["近6月"] = pd.to_numeric(temp_df["近6月"], errors="coerce")
|
||||
temp_df["近1年"] = pd.to_numeric(temp_df["近1年"], errors="coerce")
|
||||
temp_df["近2年"] = pd.to_numeric(temp_df["近2年"], errors="coerce")
|
||||
temp_df["近3年"] = pd.to_numeric(temp_df["近3年"], 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["可购买"] = temp_df["可购买"].map(
|
||||
lambda x: "可购买" if x == "1" else "不可购买"
|
||||
)
|
||||
return temp_df
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
fund_open_fund_rank_em_df = fund_open_fund_rank_em(symbol="全部")
|
||||
print(fund_open_fund_rank_em_df)
|
||||
|
||||
fund_open_fund_rank_em_df = fund_open_fund_rank_em(symbol="股票型")
|
||||
print(fund_open_fund_rank_em_df)
|
||||
|
||||
fund_open_fund_rank_em_df = fund_open_fund_rank_em(symbol="混合型")
|
||||
print(fund_open_fund_rank_em_df)
|
||||
|
||||
fund_open_fund_rank_em_df = fund_open_fund_rank_em(symbol="债券型")
|
||||
print(fund_open_fund_rank_em_df)
|
||||
|
||||
fund_open_fund_rank_em_df = fund_open_fund_rank_em(symbol="指数型")
|
||||
print(fund_open_fund_rank_em_df)
|
||||
|
||||
fund_open_fund_rank_em_df = fund_open_fund_rank_em(symbol="QDII")
|
||||
print(fund_open_fund_rank_em_df)
|
||||
|
||||
fund_open_fund_rank_em_df = fund_open_fund_rank_em(symbol="FOF")
|
||||
print(fund_open_fund_rank_em_df)
|
||||
|
||||
fund_exchange_rank_em_df = fund_exchange_rank_em()
|
||||
print(fund_exchange_rank_em_df)
|
||||
|
||||
fund_money_rank_em_df = fund_money_rank_em()
|
||||
print(fund_money_rank_em_df)
|
||||
|
||||
fund_lcx_rank_em_df = fund_lcx_rank_em()
|
||||
print(fund_lcx_rank_em_df)
|
||||
|
||||
fund_hk_rank_em_df = fund_hk_rank_em()
|
||||
print(fund_hk_rank_em_df)
|
||||
@@ -0,0 +1,375 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding:utf-8 -*-
|
||||
"""
|
||||
Date: 2023/12/12 16:30
|
||||
Desc: 基金评级
|
||||
https://fund.eastmoney.com/data/fundrating.html
|
||||
"""
|
||||
|
||||
import pandas as pd
|
||||
import requests
|
||||
from bs4 import BeautifulSoup
|
||||
|
||||
|
||||
def fund_rating_all() -> pd.DataFrame:
|
||||
"""
|
||||
天天基金网-基金评级-基金评级总汇
|
||||
https://fund.eastmoney.com/data/fundrating.html
|
||||
:return: 基金评级总汇
|
||||
:rtype: pandas.DataFrame
|
||||
"""
|
||||
url = "https://fund.eastmoney.com/data/fundrating.html"
|
||||
r = requests.get(url)
|
||||
soup = BeautifulSoup(r.text, features="lxml")
|
||||
data_text = soup.find(name="div", attrs={"id": "fundinfo"}).find("script").string
|
||||
data_content = [
|
||||
item.split("|")
|
||||
for item in data_text.split("var")[6]
|
||||
.split("=")[1]
|
||||
.strip()
|
||||
.strip(";")
|
||||
.strip('"')
|
||||
.strip("|")
|
||||
.split("|_")
|
||||
]
|
||||
temp_df = pd.DataFrame(data_content)
|
||||
temp_df.columns = [
|
||||
"代码",
|
||||
"简称",
|
||||
"类型",
|
||||
"基金经理",
|
||||
"-",
|
||||
"基金公司",
|
||||
"-",
|
||||
"5星评级家数",
|
||||
"-",
|
||||
"-",
|
||||
"招商证券",
|
||||
"-",
|
||||
"上海证券",
|
||||
"-",
|
||||
"晨星评级",
|
||||
"-",
|
||||
"济安金信",
|
||||
"-",
|
||||
"手续费",
|
||||
"-",
|
||||
"-",
|
||||
"-",
|
||||
"-",
|
||||
"-",
|
||||
"-",
|
||||
"-",
|
||||
"-",
|
||||
]
|
||||
temp_df = temp_df[
|
||||
[
|
||||
"代码",
|
||||
"简称",
|
||||
"基金经理",
|
||||
"基金公司",
|
||||
"5星评级家数",
|
||||
"上海证券",
|
||||
"招商证券",
|
||||
"济安金信",
|
||||
"晨星评级",
|
||||
"手续费",
|
||||
"类型",
|
||||
]
|
||||
]
|
||||
temp_df["5星评级家数"] = pd.to_numeric(temp_df["5星评级家数"], 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["手续费"].str.strip("%"), errors="coerce") / 100
|
||||
)
|
||||
return temp_df
|
||||
|
||||
|
||||
def fund_rating_sh(date: str = "20230630") -> pd.DataFrame:
|
||||
"""
|
||||
天天基金网-基金评级-上海证券评级
|
||||
https://fund.eastmoney.com/data/fundrating_3.html
|
||||
:param date: 日期; https://fund.eastmoney.com/data/fundrating_3.html 获取查询日期
|
||||
:type date: str
|
||||
:return: 上海证券评级
|
||||
:rtype: pandas.DataFrame
|
||||
"""
|
||||
url = "https://fund.eastmoney.com/data/fundrating_3.html"
|
||||
r = requests.get(url)
|
||||
soup = BeautifulSoup(r.text, "lxml")
|
||||
date_list = [
|
||||
item["value"] for item in soup.find("select", attrs={"id": "rqoptions"})
|
||||
]
|
||||
date_format = "-".join([date[:4], date[4:6], date[6:]])
|
||||
if date_format not in date_list:
|
||||
raise "请访问 https://fund.eastmoney.com/data/fundrating_3.html 获取查询日期"
|
||||
url = f"https://fund.eastmoney.com/data/fundrating_3_{'-'.join([date[:4], date[4:6], date[6:]])}.html"
|
||||
r = requests.get(url)
|
||||
soup = BeautifulSoup(r.text, "lxml")
|
||||
data_text = soup.find("div", attrs={"id": "fundinfo"}).find("script").string
|
||||
data_content = [
|
||||
item.split("|")
|
||||
for item in data_text.split("var")[1]
|
||||
.split("=")[1]
|
||||
.strip()
|
||||
.strip(";")
|
||||
.strip('"')
|
||||
.strip("|")
|
||||
.split("|_")
|
||||
]
|
||||
temp_df = pd.DataFrame(data_content)
|
||||
temp_df.columns = [
|
||||
"代码",
|
||||
"简称",
|
||||
"类型",
|
||||
"基金经理",
|
||||
"_",
|
||||
"基金公司",
|
||||
"_",
|
||||
"3年期评级-3年评级",
|
||||
"3年期评级-较上期",
|
||||
"5年期评级-5年评级",
|
||||
"5年期评级-较上期",
|
||||
"单位净值",
|
||||
"日期",
|
||||
"日增长率",
|
||||
"近1年涨幅",
|
||||
"近3年涨幅",
|
||||
"近5年涨幅",
|
||||
"手续费",
|
||||
"_",
|
||||
"_",
|
||||
"_",
|
||||
"_",
|
||||
]
|
||||
temp_df = temp_df[
|
||||
[
|
||||
"代码",
|
||||
"简称",
|
||||
"基金经理",
|
||||
"基金公司",
|
||||
"3年期评级-3年评级",
|
||||
"3年期评级-较上期",
|
||||
"5年期评级-5年评级",
|
||||
"5年期评级-较上期",
|
||||
"单位净值",
|
||||
"日期",
|
||||
"日增长率",
|
||||
"近1年涨幅",
|
||||
"近3年涨幅",
|
||||
"近5年涨幅",
|
||||
"手续费",
|
||||
"类型",
|
||||
]
|
||||
]
|
||||
temp_df["日期"] = pd.to_datetime(temp_df["日期"], errors="coerce").dt.date
|
||||
temp_df["3年期评级-3年评级"] = pd.to_numeric(
|
||||
temp_df["3年期评级-3年评级"], errors="coerce"
|
||||
)
|
||||
temp_df["3年期评级-较上期"] = pd.to_numeric(
|
||||
temp_df["3年期评级-较上期"], errors="coerce"
|
||||
)
|
||||
temp_df["5年期评级-5年评级"] = pd.to_numeric(
|
||||
temp_df["5年期评级-5年评级"], errors="coerce"
|
||||
)
|
||||
temp_df["5年期评级-较上期"] = pd.to_numeric(
|
||||
temp_df["5年期评级-较上期"], errors="coerce"
|
||||
)
|
||||
temp_df["单位净值"] = pd.to_numeric(temp_df["单位净值"], errors="coerce")
|
||||
temp_df["日增长率"] = pd.to_numeric(temp_df["日增长率"], errors="coerce")
|
||||
temp_df["近1年涨幅"] = pd.to_numeric(temp_df["近1年涨幅"], errors="coerce")
|
||||
temp_df["近3年涨幅"] = pd.to_numeric(temp_df["近3年涨幅"], errors="coerce")
|
||||
temp_df["近5年涨幅"] = pd.to_numeric(temp_df["近5年涨幅"], errors="coerce")
|
||||
return temp_df
|
||||
|
||||
|
||||
def fund_rating_zs(date: str = "20230331") -> pd.DataFrame:
|
||||
"""
|
||||
天天基金网-基金评级-招商证券评级
|
||||
https://fund.eastmoney.com/data/fundrating_2.html
|
||||
:param date: 日期; https://fund.eastmoney.com/data/fundrating_2.html 获取查询日期
|
||||
:type date: str
|
||||
:return: 招商证券评级-混合型
|
||||
:rtype: pandas.DataFrame
|
||||
"""
|
||||
url = "https://fund.eastmoney.com/data/fundrating_2.html"
|
||||
r = requests.get(url)
|
||||
soup = BeautifulSoup(r.text, "lxml")
|
||||
date_list = [
|
||||
item["value"] for item in soup.find("select", attrs={"id": "rqoptions"})
|
||||
]
|
||||
date_format = "-".join([date[:4], date[4:6], date[6:]])
|
||||
if date_format not in date_list:
|
||||
raise "请访问 https://fund.eastmoney.com/data/fundrating_2.html 获取查询日期"
|
||||
url = f"https://fund.eastmoney.com/data/fundrating_2_{'-'.join([date[:4], date[4:6], date[6:]])}.html"
|
||||
r = requests.get(url)
|
||||
soup = BeautifulSoup(r.text, "lxml")
|
||||
data_text = soup.find("div", attrs={"id": "fundinfo"}).find("script").string
|
||||
data_content = [
|
||||
item.split("|")
|
||||
for item in data_text.split("var")[1]
|
||||
.split("=")[1]
|
||||
.strip()
|
||||
.strip(";")
|
||||
.strip('"')
|
||||
.strip("|")
|
||||
.split("|_")
|
||||
]
|
||||
temp_df = pd.DataFrame(data_content)
|
||||
temp_df.columns = [
|
||||
"代码",
|
||||
"简称",
|
||||
"_",
|
||||
"基金经理",
|
||||
"_",
|
||||
"基金公司",
|
||||
"_",
|
||||
"3年期评级-3年评级",
|
||||
"3年期评级-较上期",
|
||||
"单位净值",
|
||||
"日期",
|
||||
"日增长率",
|
||||
"近1年涨幅",
|
||||
"近3年涨幅",
|
||||
"近5年涨幅",
|
||||
"手续费",
|
||||
"_",
|
||||
"_",
|
||||
"_",
|
||||
"_",
|
||||
]
|
||||
temp_df = temp_df[
|
||||
[
|
||||
"代码",
|
||||
"简称",
|
||||
"基金经理",
|
||||
"基金公司",
|
||||
"3年期评级-3年评级",
|
||||
"3年期评级-较上期",
|
||||
"单位净值",
|
||||
"日期",
|
||||
"日增长率",
|
||||
"近1年涨幅",
|
||||
"近3年涨幅",
|
||||
"近5年涨幅",
|
||||
"手续费",
|
||||
]
|
||||
]
|
||||
temp_df["日期"] = pd.to_datetime(temp_df["日期"], errors="coerce").dt.date
|
||||
temp_df["3年期评级-3年评级"] = pd.to_numeric(
|
||||
temp_df["3年期评级-3年评级"], errors="coerce"
|
||||
)
|
||||
temp_df["3年期评级-较上期"] = pd.to_numeric(
|
||||
temp_df["3年期评级-较上期"], errors="coerce"
|
||||
)
|
||||
temp_df["单位净值"] = pd.to_numeric(temp_df["单位净值"], errors="coerce")
|
||||
temp_df["日增长率"] = pd.to_numeric(temp_df["日增长率"], errors="coerce")
|
||||
temp_df["近1年涨幅"] = pd.to_numeric(temp_df["近1年涨幅"], errors="coerce")
|
||||
temp_df["近3年涨幅"] = pd.to_numeric(temp_df["近3年涨幅"], errors="coerce")
|
||||
temp_df["近5年涨幅"] = pd.to_numeric(temp_df["近5年涨幅"], errors="coerce")
|
||||
return temp_df
|
||||
|
||||
|
||||
def fund_rating_ja(date: str = "20230331") -> pd.DataFrame:
|
||||
"""
|
||||
天天基金网-基金评级-济安金信评级
|
||||
https://fund.eastmoney.com/data/fundrating_4.html
|
||||
:param date: 日期; https://fund.eastmoney.com/data/fundrating_4.html 获取查询日期
|
||||
:type date: str
|
||||
:return: 济安金信评级
|
||||
:rtype: pandas.DataFrame
|
||||
"""
|
||||
url = "https://fund.eastmoney.com/data/fundrating_4.html"
|
||||
r = requests.get(url)
|
||||
soup = BeautifulSoup(r.text, "lxml")
|
||||
date_list = [
|
||||
item["value"] for item in soup.find("select", attrs={"id": "rqoptions"})
|
||||
]
|
||||
date_format = "-".join([date[:4], date[4:6], date[6:]])
|
||||
if date_format not in date_list:
|
||||
raise "请访问 http://fund.eastmoney.com/data/fundrating_4.html 获取查询日期"
|
||||
url = f"https://fund.eastmoney.com/data/fundrating_4_{'-'.join([date[:4], date[4:6], date[6:]])}.html"
|
||||
r = requests.get(url)
|
||||
soup = BeautifulSoup(r.text, "lxml")
|
||||
data_text = soup.find("div", attrs={"id": "fundinfo"}).find("script").string
|
||||
data_content = [
|
||||
item.split("|")
|
||||
for item in data_text.split("var")[1]
|
||||
.split("=")[1]
|
||||
.strip()
|
||||
.strip(";")
|
||||
.strip('"')
|
||||
.strip("|")
|
||||
.split("|_")
|
||||
]
|
||||
temp_df = pd.DataFrame(data_content)
|
||||
temp_df.columns = [
|
||||
"代码",
|
||||
"简称",
|
||||
"类型",
|
||||
"基金经理",
|
||||
"_",
|
||||
"基金公司",
|
||||
"_",
|
||||
"3年期评级-3年评级",
|
||||
"3年期评级-较上期",
|
||||
"单位净值",
|
||||
"日期",
|
||||
"日增长率",
|
||||
"近1年涨幅",
|
||||
"近3年涨幅",
|
||||
"近5年涨幅",
|
||||
"手续费",
|
||||
"_",
|
||||
"_",
|
||||
"_",
|
||||
"_",
|
||||
]
|
||||
temp_df = temp_df[
|
||||
[
|
||||
"代码",
|
||||
"简称",
|
||||
"基金经理",
|
||||
"基金公司",
|
||||
"3年期评级-3年评级",
|
||||
"3年期评级-较上期",
|
||||
"单位净值",
|
||||
"日期",
|
||||
"日增长率",
|
||||
"近1年涨幅",
|
||||
"近3年涨幅",
|
||||
"近5年涨幅",
|
||||
"手续费",
|
||||
"类型",
|
||||
]
|
||||
]
|
||||
temp_df["日期"] = pd.to_datetime(temp_df["日期"], errors="coerce").dt.date
|
||||
temp_df["3年期评级-3年评级"] = pd.to_numeric(
|
||||
temp_df["3年期评级-3年评级"], errors="coerce"
|
||||
)
|
||||
temp_df["3年期评级-较上期"] = pd.to_numeric(
|
||||
temp_df["3年期评级-较上期"], errors="coerce"
|
||||
)
|
||||
temp_df["单位净值"] = pd.to_numeric(temp_df["单位净值"], errors="coerce")
|
||||
temp_df["日增长率"] = pd.to_numeric(temp_df["日增长率"], errors="coerce")
|
||||
temp_df["近1年涨幅"] = pd.to_numeric(temp_df["近1年涨幅"], errors="coerce")
|
||||
temp_df["近3年涨幅"] = pd.to_numeric(temp_df["近3年涨幅"], errors="coerce")
|
||||
temp_df["近5年涨幅"] = pd.to_numeric(temp_df["近5年涨幅"], errors="coerce")
|
||||
return temp_df
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
fund_rating_all_df = fund_rating_all()
|
||||
print(fund_rating_all_df)
|
||||
|
||||
fund_rating_sh_df = fund_rating_sh(date="20230630")
|
||||
print(fund_rating_sh_df)
|
||||
|
||||
fund_rating_zs_df = fund_rating_zs(date="20230331")
|
||||
print(fund_rating_zs_df)
|
||||
|
||||
fund_rating_ja_df = fund_rating_ja(date="20230331")
|
||||
print(fund_rating_ja_df)
|
||||
@@ -0,0 +1,240 @@
|
||||
# -*- coding:utf-8 -*-
|
||||
# !/usr/bin/env python
|
||||
"""
|
||||
Date: 2024/7/24 23:30
|
||||
Desc: 巨潮资讯-数据中心-专题统计-基金报表
|
||||
https://webapi.cninfo.com.cn/#/thematicStatistics
|
||||
"""
|
||||
|
||||
import pandas as pd
|
||||
import py_mini_racer
|
||||
import requests
|
||||
|
||||
from akshare.datasets import get_ths_js
|
||||
|
||||
|
||||
def _get_file_content_cninfo(file: str = "cninfo.js") -> str:
|
||||
"""
|
||||
获取 JS 文件的内容
|
||||
:param file: JS 文件名
|
||||
:type file: str
|
||||
:return: 文件内容
|
||||
:rtype: str
|
||||
"""
|
||||
setting_file_path = get_ths_js(file)
|
||||
with open(setting_file_path, encoding="utf-8") as f:
|
||||
file_data = f.read()
|
||||
return file_data
|
||||
|
||||
|
||||
def fund_report_stock_cninfo(date: str = "20210630") -> pd.DataFrame:
|
||||
"""
|
||||
巨潮资讯-数据中心-专题统计-基金报表-基金重仓股
|
||||
https://webapi.cninfo.com.cn/#/thematicStatistics
|
||||
:param date: 报告时间; choice of {"XXXX0331", "XXXX0630", "XXXX0930", "XXXX1231"}
|
||||
:type date: str
|
||||
:return: 基金重仓股
|
||||
:rtype: pandas.DataFrame
|
||||
"""
|
||||
url = "https://webapi.cninfo.com.cn/api/sysapi/p_sysapi1112"
|
||||
js_code = py_mini_racer.MiniRacer()
|
||||
js_content = _get_file_content_cninfo("cninfo.js")
|
||||
js_code.eval(js_content)
|
||||
mcode = js_code.call("getResCode1")
|
||||
headers = {
|
||||
"Accept": "*/*",
|
||||
"Accept-Enckey": mcode,
|
||||
"Accept-Encoding": "gzip, deflate",
|
||||
"Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8",
|
||||
"Cache-Control": "no-cache",
|
||||
"Content-Length": "0",
|
||||
"Host": "webapi.cninfo.com.cn",
|
||||
"Origin": "https://webapi.cninfo.com.cn",
|
||||
"Pragma": "no-cache",
|
||||
"Proxy-Connection": "keep-alive",
|
||||
"Referer": "https://webapi.cninfo.com.cn/",
|
||||
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "
|
||||
"Chrome/93.0.4577.63 Safari/537.36",
|
||||
"X-Requested-With": "XMLHttpRequest",
|
||||
}
|
||||
params = {
|
||||
"rdate": "-".join([date[:4], date[4:6], date[6:]]),
|
||||
}
|
||||
r = requests.post(url, headers=headers, params=params)
|
||||
data_json = r.json()
|
||||
temp_df = pd.DataFrame(data_json["records"])
|
||||
temp_df.rename(
|
||||
columns={
|
||||
"F003N": "持股总市值",
|
||||
"F002N": "持股总数",
|
||||
"F001N": "基金覆盖家数",
|
||||
"SECNAME": "股票简称",
|
||||
"ID": "序号",
|
||||
"SECCODE": "股票代码",
|
||||
"ENDDATE": "报告期",
|
||||
},
|
||||
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["序号"] = range(1, len(temp_df) + 1)
|
||||
return temp_df
|
||||
|
||||
|
||||
def fund_report_industry_allocation_cninfo(date: str = "20210630") -> pd.DataFrame:
|
||||
"""
|
||||
巨潮资讯-数据中心-专题统计-基金报表-基金行业配置
|
||||
https://webapi.cninfo.com.cn/#/thematicStatistics
|
||||
:param date: 报告时间; choice of {"XXXX0331", "XXXX0630", "XXXX0930", "XXXX1231"}, 从 2017 年开始
|
||||
:type date: str
|
||||
:return: 基金行业配置
|
||||
:rtype: pandas.DataFrame
|
||||
"""
|
||||
url = "https://webapi.cninfo.com.cn/api/sysapi/p_sysapi1113"
|
||||
js_code = py_mini_racer.MiniRacer()
|
||||
js_content = _get_file_content_cninfo("cninfo.js")
|
||||
js_code.eval(js_content)
|
||||
mcode = js_code.call("getResCode1")
|
||||
headers = {
|
||||
"Accept": "*/*",
|
||||
"Accept-Enckey": mcode,
|
||||
"Accept-Encoding": "gzip, deflate",
|
||||
"Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8",
|
||||
"Cache-Control": "no-cache",
|
||||
"Content-Length": "0",
|
||||
"Host": "webapi.cninfo.com.cn",
|
||||
"Origin": "https://webapi.cninfo.com.cn",
|
||||
"Pragma": "no-cache",
|
||||
"Proxy-Connection": "keep-alive",
|
||||
"Referer": "https://webapi.cninfo.com.cn/",
|
||||
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "
|
||||
"Chrome/93.0.4577.63 Safari/537.36",
|
||||
"X-Requested-With": "XMLHttpRequest",
|
||||
}
|
||||
params = {
|
||||
"rdate": "-".join([date[:4], date[4:6], date[6:]]),
|
||||
}
|
||||
r = requests.post(url, headers=headers, params=params)
|
||||
data_json = r.json()
|
||||
temp_df = pd.DataFrame(data_json["records"])
|
||||
temp_df.rename(
|
||||
columns={
|
||||
"F004N": "行业规模",
|
||||
"F003N": "基金覆盖家数",
|
||||
"F002V": "证监会行业名称",
|
||||
"F001V": "行业编码",
|
||||
"ENDDATE": "报告期",
|
||||
"F005N": "占净资产比例",
|
||||
},
|
||||
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")
|
||||
return temp_df
|
||||
|
||||
|
||||
def fund_report_asset_allocation_cninfo() -> pd.DataFrame:
|
||||
"""
|
||||
巨潮资讯-数据中心-专题统计-基金报表-基金资产配置
|
||||
https://webapi.cninfo.com.cn/#/thematicStatistics
|
||||
:return: 基金资产配置
|
||||
:rtype: pandas.DataFrame
|
||||
"""
|
||||
url = "https://webapi.cninfo.com.cn/api/sysapi/p_sysapi1114"
|
||||
js_code = py_mini_racer.MiniRacer()
|
||||
js_content = _get_file_content_cninfo("cninfo.js")
|
||||
js_code.eval(js_content)
|
||||
mcode = js_code.call("getResCode1")
|
||||
headers = {
|
||||
"Accept": "*/*",
|
||||
"Accept-Enckey": mcode,
|
||||
"Accept-Encoding": "gzip, deflate",
|
||||
"Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8",
|
||||
"Cache-Control": "no-cache",
|
||||
"Content-Length": "0",
|
||||
"Host": "webapi.cninfo.com.cn",
|
||||
"Origin": "https://webapi.cninfo.com.cn",
|
||||
"Pragma": "no-cache",
|
||||
"Proxy-Connection": "keep-alive",
|
||||
"Referer": "https://webapi.cninfo.com.cn/",
|
||||
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "
|
||||
"Chrome/93.0.4577.63 Safari/537.36",
|
||||
"X-Requested-With": "XMLHttpRequest",
|
||||
}
|
||||
r = requests.post(url, headers=headers)
|
||||
data_json = r.json()
|
||||
temp_df = pd.DataFrame(data_json["records"])
|
||||
temp_df.rename(
|
||||
columns={
|
||||
"F001N": "基金覆盖家数",
|
||||
"F008N": "现金货币类占净资产比例",
|
||||
"F007N": "债券固定收益类占净资产比例",
|
||||
"F006N": "股票权益类占净资产比例",
|
||||
"ENDDATE": "报告期",
|
||||
"F005N": "基金市场净资产规模",
|
||||
},
|
||||
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"
|
||||
)
|
||||
return temp_df
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
fund_report_stock_cninfo_df = fund_report_stock_cninfo(date="20210630")
|
||||
print(fund_report_stock_cninfo_df)
|
||||
|
||||
fund_report_industry_allocation_cninfo_df = fund_report_industry_allocation_cninfo(
|
||||
date="20210930"
|
||||
)
|
||||
print(fund_report_industry_allocation_cninfo_df)
|
||||
|
||||
fund_report_asset_allocation_cninfo_df = fund_report_asset_allocation_cninfo()
|
||||
print(fund_report_asset_allocation_cninfo_df)
|
||||
@@ -0,0 +1,126 @@
|
||||
# -*- coding:utf-8 -*-
|
||||
# !/usr/bin/env python
|
||||
"""
|
||||
Date: 2023/10/27 20:30
|
||||
Desc: 天天基金网-基金数据-规模份额
|
||||
https://fund.eastmoney.com/data/cyrjglist.html
|
||||
"""
|
||||
|
||||
import pandas as pd
|
||||
import requests
|
||||
|
||||
from akshare.utils import demjson
|
||||
|
||||
|
||||
def fund_scale_change_em() -> pd.DataFrame:
|
||||
"""
|
||||
天天基金网-基金数据-规模份额-规模变动
|
||||
https://fund.eastmoney.com/data/gmbdlist.html
|
||||
:return: 规模变动
|
||||
:rtype: pandas.DataFrame
|
||||
"""
|
||||
url = "https://fund.eastmoney.com/data/FundDataPortfolio_Interface.aspx"
|
||||
params = {
|
||||
"dt": "9",
|
||||
"pi": "1",
|
||||
"pn": "50",
|
||||
"mc": "hypzDetail",
|
||||
"st": "desc",
|
||||
"sc": "reportdate",
|
||||
}
|
||||
r = requests.get(url, params=params)
|
||||
data_text = r.text
|
||||
data_json = demjson.decode(data_text[data_text.find("{") : -1])
|
||||
total_page = data_json["pages"]
|
||||
big_df = pd.DataFrame()
|
||||
for page in range(1, int(total_page) + 1):
|
||||
params.update({"pi": page})
|
||||
r = requests.get(url, params=params)
|
||||
data_text = r.text
|
||||
data_json = demjson.decode(data_text[data_text.find("{") : -1])
|
||||
temp_df = pd.DataFrame(data_json["data"])
|
||||
big_df = pd.concat(objs=[big_df, temp_df], ignore_index=True)
|
||||
big_df.reset_index(inplace=True)
|
||||
big_df["index"] = big_df["index"] + 1
|
||||
big_df.columns = [
|
||||
"序号",
|
||||
"截止日期",
|
||||
"基金家数",
|
||||
"期间申购",
|
||||
"期间赎回",
|
||||
"期末总份额",
|
||||
"期末净资产",
|
||||
]
|
||||
big_df["截止日期"] = pd.to_datetime(big_df["截止日期"], errors="coerce").dt.date
|
||||
big_df["基金家数"] = pd.to_numeric(big_df["基金家数"], errors="coerce")
|
||||
big_df["期间申购"] = pd.to_numeric(
|
||||
big_df["期间申购"].str.replace(",", ""), errors="coerce"
|
||||
)
|
||||
big_df["期间赎回"] = pd.to_numeric(
|
||||
big_df["期间赎回"].str.replace(",", ""), errors="coerce"
|
||||
)
|
||||
big_df["期末总份额"] = pd.to_numeric(
|
||||
big_df["期末总份额"].str.replace(",", ""), errors="coerce"
|
||||
)
|
||||
big_df["期末净资产"] = pd.to_numeric(
|
||||
big_df["期末净资产"].str.replace(",", ""), errors="coerce"
|
||||
)
|
||||
return big_df
|
||||
|
||||
|
||||
def fund_hold_structure_em() -> pd.DataFrame:
|
||||
"""
|
||||
天天基金网-基金数据-规模份额-持有人结构
|
||||
https://fund.eastmoney.com/data/cyrjglist.html
|
||||
:return: 持有人结构
|
||||
:rtype: pandas.DataFrame
|
||||
"""
|
||||
url = "https://fund.eastmoney.com/data/FundDataPortfolio_Interface.aspx"
|
||||
params = {
|
||||
"dt": "11",
|
||||
"pi": "1",
|
||||
"pn": "50",
|
||||
"mc": "hypzDetail",
|
||||
"st": "desc",
|
||||
"sc": "reportdate",
|
||||
}
|
||||
r = requests.get(url, params=params)
|
||||
data_text = r.text
|
||||
data_json = demjson.decode(data_text[data_text.find("{") : -1])
|
||||
total_page = data_json["pages"]
|
||||
big_df = pd.DataFrame()
|
||||
for page in range(1, int(total_page) + 1):
|
||||
params.update({"pi": page})
|
||||
r = requests.get(url, params=params)
|
||||
data_text = r.text
|
||||
data_json = demjson.decode(data_text[data_text.find("{") : -1])
|
||||
temp_df = pd.DataFrame(data_json["data"])
|
||||
big_df = pd.concat(objs=[big_df, temp_df], ignore_index=True)
|
||||
big_df.reset_index(inplace=True)
|
||||
big_df["index"] = big_df["index"] + 1
|
||||
big_df.columns = [
|
||||
"序号",
|
||||
"截止日期",
|
||||
"基金家数",
|
||||
"机构持有比列",
|
||||
"个人持有比列",
|
||||
"内部持有比列",
|
||||
"总份额",
|
||||
]
|
||||
big_df["截止日期"] = pd.to_datetime(big_df["截止日期"], errors="coerce").dt.date
|
||||
big_df["基金家数"] = pd.to_numeric(big_df["基金家数"], errors="coerce")
|
||||
big_df["机构持有比列"] = pd.to_numeric(big_df["机构持有比列"], errors="coerce")
|
||||
big_df["个人持有比列"] = pd.to_numeric(big_df["个人持有比列"], errors="coerce")
|
||||
big_df["内部持有比列"] = pd.to_numeric(big_df["内部持有比列"], errors="coerce")
|
||||
big_df["总份额"] = pd.to_numeric(
|
||||
big_df["总份额"].str.replace(",", ""), errors="coerce"
|
||||
)
|
||||
return big_df
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
fund_scale_change_em_df = fund_scale_change_em()
|
||||
print(fund_scale_change_em_df)
|
||||
|
||||
fund_hold_structure_em_df = fund_hold_structure_em()
|
||||
print(fund_hold_structure_em_df)
|
||||
@@ -0,0 +1,248 @@
|
||||
# -*- coding:utf-8 -*-
|
||||
# !/usr/bin/env python
|
||||
"""
|
||||
Date: 2024/9/1 16:20
|
||||
Desc: 新浪财经-基金规模
|
||||
https://vip.stock.finance.sina.com.cn/fund_center/index.html#jjgmall
|
||||
"""
|
||||
|
||||
import pandas as pd
|
||||
import requests
|
||||
|
||||
from akshare.utils import demjson
|
||||
|
||||
|
||||
def fund_scale_open_sina(symbol: str = "股票型基金") -> pd.DataFrame:
|
||||
"""
|
||||
新浪财经-基金数据中心-基金规模-开放式基金
|
||||
https://vip.stock.finance.sina.com.cn/fund_center/index.html#jjhqetf
|
||||
:param symbol: choice of {"股票型基金", "混合型基金", "债券型基金", "货币型基金", "QDII基金"}
|
||||
:type symbol: str
|
||||
:return: 基金规模
|
||||
:rtype: pandas.DataFrame
|
||||
"""
|
||||
fund_map = {
|
||||
"股票型基金": "2",
|
||||
"混合型基金": "1",
|
||||
"债券型基金": "3",
|
||||
"货币型基金": "5",
|
||||
"QDII基金": "6",
|
||||
}
|
||||
url = (
|
||||
"http://vip.stock.finance.sina.com.cn/fund_center/data/jsonp.php/IO.XSRV2."
|
||||
"CallbackList['J2cW8KXheoWKdSHc']/NetValueReturn_Service.NetValueReturnOpen"
|
||||
)
|
||||
params = {
|
||||
"page": "1",
|
||||
"num": "10000",
|
||||
"sort": "zmjgm",
|
||||
"asc": "0",
|
||||
"ccode": "",
|
||||
"type2": fund_map[symbol],
|
||||
"type3": "",
|
||||
}
|
||||
r = requests.get(url, params=params)
|
||||
data_text = r.text
|
||||
data_json = demjson.decode(data_text[data_text.find("({") + 1 : -2])
|
||||
temp_df = pd.DataFrame(data_json["data"])
|
||||
temp_df.reset_index(inplace=True)
|
||||
temp_df["index"] = range(1, len(temp_df) + 1)
|
||||
temp_df.rename(
|
||||
columns={
|
||||
"index": "序号",
|
||||
"symbol": "基金代码",
|
||||
"sname": "基金简称",
|
||||
"per_nav": "-",
|
||||
"total_nav": "-",
|
||||
"three_month": "-",
|
||||
"six_month": "-",
|
||||
"one_year": "-",
|
||||
"form_year": "-",
|
||||
"form_start": "-",
|
||||
"name": "-",
|
||||
"zmjgm": "总募集规模",
|
||||
"clrq": "成立日期",
|
||||
"jjjl": "基金经理",
|
||||
"dwjz": "单位净值",
|
||||
"ljjz": "-",
|
||||
"jzrq": "更新日期",
|
||||
"zjzfe": "最近总份额",
|
||||
"jjglr_code": "-",
|
||||
},
|
||||
inplace=True,
|
||||
)
|
||||
temp_df = temp_df[
|
||||
[
|
||||
"序号",
|
||||
"基金代码",
|
||||
"基金简称",
|
||||
"单位净值",
|
||||
"总募集规模",
|
||||
"最近总份额",
|
||||
"成立日期",
|
||||
"基金经理",
|
||||
"更新日期",
|
||||
]
|
||||
]
|
||||
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_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 fund_scale_close_sina() -> pd.DataFrame:
|
||||
"""
|
||||
新浪财经-基金数据中心-基金规模-封闭式基金
|
||||
https://vip.stock.finance.sina.com.cn/fund_center/index.html#jjhqetf
|
||||
:return: 基金规模
|
||||
:rtype: pandas.DataFrame
|
||||
"""
|
||||
url = (
|
||||
"http://vip.stock.finance.sina.com.cn/fund_center/data/jsonp.php/IO.XSRV2."
|
||||
"CallbackList['_bjN6KvXOkfPy2Bu']/NetValueReturn_Service.NetValueReturnClose"
|
||||
)
|
||||
params = {
|
||||
"page": "1",
|
||||
"num": "1000",
|
||||
"sort": "zmjgm",
|
||||
"asc": "0",
|
||||
"ccode": "",
|
||||
"type2": "",
|
||||
"type3": "",
|
||||
}
|
||||
r = requests.get(url, params=params)
|
||||
data_text = r.text
|
||||
data_json = demjson.decode(data_text[data_text.find("({") + 1 : -2])
|
||||
temp_df = pd.DataFrame(data_json["data"])
|
||||
temp_df.reset_index(inplace=True)
|
||||
temp_df["index"] = range(1, len(temp_df) + 1)
|
||||
temp_df.rename(
|
||||
columns={
|
||||
"index": "序号",
|
||||
"symbol": "基金代码",
|
||||
"sname": "基金简称",
|
||||
"per_nav": "-",
|
||||
"total_nav": "-",
|
||||
"three_month": "-",
|
||||
"six_month": "-",
|
||||
"one_year": "-",
|
||||
"form_year": "-",
|
||||
"form_start": "-",
|
||||
"name": "-",
|
||||
"zmjgm": "总募集规模",
|
||||
"clrq": "成立日期",
|
||||
"jjjl": "基金经理",
|
||||
"dwjz": "单位净值",
|
||||
"ljjz": "-",
|
||||
"jzrq": "更新日期",
|
||||
"zjzfe": "最近总份额",
|
||||
"jjglr_code": "-",
|
||||
},
|
||||
inplace=True,
|
||||
)
|
||||
temp_df = temp_df[
|
||||
[
|
||||
"序号",
|
||||
"基金代码",
|
||||
"基金简称",
|
||||
"单位净值",
|
||||
"总募集规模",
|
||||
"最近总份额",
|
||||
"成立日期",
|
||||
"基金经理",
|
||||
"更新日期",
|
||||
]
|
||||
]
|
||||
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_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 fund_scale_structured_sina() -> pd.DataFrame:
|
||||
"""
|
||||
新浪财经-基金数据中心-基金规模-分级子基金
|
||||
https://vip.stock.finance.sina.com.cn/fund_center/index.html#jjgmfjall
|
||||
:return: 基金规模
|
||||
:rtype: pandas.DataFrame
|
||||
"""
|
||||
url = (
|
||||
"http://vip.stock.finance.sina.com.cn/fund_center/data/jsonp.php/IO.XSRV2."
|
||||
"CallbackList['cRrwseM7NWX68rDa']/NetValueReturn_Service.NetValueReturnCX"
|
||||
)
|
||||
params = {
|
||||
"page": "1",
|
||||
"num": "1000",
|
||||
"sort": "zmjgm",
|
||||
"asc": "0",
|
||||
"ccode": "",
|
||||
"type2": "",
|
||||
"type3": "",
|
||||
}
|
||||
r = requests.get(url, params=params)
|
||||
data_text = r.text
|
||||
data_json = demjson.decode(data_text[data_text.find("({") + 1 : -2])
|
||||
temp_df = pd.DataFrame(data_json["data"])
|
||||
temp_df.reset_index(inplace=True)
|
||||
temp_df["index"] = range(1, len(temp_df) + 1)
|
||||
temp_df.rename(
|
||||
columns={
|
||||
"index": "序号",
|
||||
"symbol": "基金代码",
|
||||
"sname": "基金简称",
|
||||
"per_nav": "-",
|
||||
"total_nav": "-",
|
||||
"three_month": "-",
|
||||
"six_month": "-",
|
||||
"one_year": "-",
|
||||
"form_year": "-",
|
||||
"form_start": "-",
|
||||
"name": "-",
|
||||
"zmjgm": "总募集规模",
|
||||
"clrq": "成立日期",
|
||||
"jjjl": "基金经理",
|
||||
"dwjz": "单位净值",
|
||||
"ljjz": "-",
|
||||
"jzrq": "更新日期",
|
||||
"zjzfe": "最近总份额",
|
||||
"jjglr_code": "-",
|
||||
},
|
||||
inplace=True,
|
||||
)
|
||||
temp_df = temp_df[
|
||||
[
|
||||
"序号",
|
||||
"基金代码",
|
||||
"基金简称",
|
||||
"单位净值",
|
||||
"总募集规模",
|
||||
"最近总份额",
|
||||
"成立日期",
|
||||
"基金经理",
|
||||
"更新日期",
|
||||
]
|
||||
]
|
||||
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_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__":
|
||||
fund_scale_open_sina_df = fund_scale_open_sina(symbol="股票型基金")
|
||||
print(fund_scale_open_sina_df)
|
||||
|
||||
fund_scale_close_sina_df = fund_scale_close_sina()
|
||||
print(fund_scale_close_sina_df)
|
||||
|
||||
fund_scale_structured_sina_df = fund_scale_structured_sina()
|
||||
print(fund_scale_structured_sina_df)
|
||||
|
||||
fund_scale_open_sina_df = fund_scale_open_sina(symbol="股票型基金")
|
||||
print(fund_scale_open_sina_df)
|
||||
@@ -0,0 +1,130 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding:utf-8 -*-
|
||||
"""
|
||||
Date: 2026/4/2 22:00
|
||||
Desc: 深圳证券交易所-基金规模日频数据
|
||||
https://www.szse.cn/market/fund/volume/etf/index.html
|
||||
"""
|
||||
|
||||
import io
|
||||
import random
|
||||
import warnings
|
||||
from datetime import date, datetime
|
||||
|
||||
import pandas as pd
|
||||
import requests
|
||||
|
||||
|
||||
def _parse_date(date_str: str) -> date:
|
||||
if len(date_str) != 8 or not date_str.isdigit():
|
||||
raise ValueError("start_date 和 end_date 格式应为 YYYYMMDD")
|
||||
try:
|
||||
return datetime.strptime(date_str, "%Y%m%d").date()
|
||||
except ValueError as err:
|
||||
raise ValueError("start_date 和 end_date 应为有效日期") from err
|
||||
|
||||
|
||||
def fund_scale_daily_szse(
|
||||
start_date: str = "20260401", end_date: str = "20260401", symbol: str = "ETF"
|
||||
) -> pd.DataFrame:
|
||||
"""
|
||||
深圳证券交易所-基金产品-基金规模-日频数据
|
||||
https://www.szse.cn/market/fund/volume/etf/index.html
|
||||
:param start_date: 开始日期, 格式如 "20260401"
|
||||
:type start_date: str
|
||||
:param end_date: 结束日期, 格式如 "20260401"
|
||||
:type end_date: str
|
||||
:param symbol: 基金类别, choice of {"ETF", "LOF", "REITS"}
|
||||
:type symbol: str
|
||||
:return: 深交所基金规模日频数据;
|
||||
日期范围不能超过 6 个月, 否则返回带表头的空 DataFrame
|
||||
:rtype: pandas.DataFrame
|
||||
"""
|
||||
columns = ["日期", "基金代码", "基金简称", "基金份额"]
|
||||
symbol_map = {
|
||||
"ETF": {
|
||||
"jjlb": "ETF",
|
||||
"referer": "https://www.szse.cn/market/fund/volume/etf/index.html",
|
||||
},
|
||||
"LOF": {
|
||||
"jjlb": "LOF",
|
||||
"referer": "https://www.szse.cn/market/fund/volume/lof/index.html",
|
||||
},
|
||||
"REITS": {
|
||||
"jjlb": "不动产基金",
|
||||
"referer": "https://www.szse.cn/market/fund/volume/reits/index.html",
|
||||
},
|
||||
}
|
||||
if symbol not in symbol_map:
|
||||
raise ValueError("symbol 应为 {'ETF', 'LOF', 'REITS'}")
|
||||
start = _parse_date(start_date)
|
||||
end = _parse_date(end_date)
|
||||
if start > end:
|
||||
raise ValueError("start_date 不能大于 end_date")
|
||||
|
||||
url = "https://www.szse.cn/api/report/ShowReport"
|
||||
headers = {
|
||||
"Host": "www.szse.cn",
|
||||
"Referer": symbol_map[symbol]["referer"],
|
||||
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 "
|
||||
"(KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36",
|
||||
}
|
||||
params = {
|
||||
"SHOWTYPE": "xlsx",
|
||||
"CATALOGID": "scsj_fund_jjgm",
|
||||
"TABKEY": "tab1",
|
||||
"txtStart": start.strftime("%Y-%m-%d"),
|
||||
"txtEnd": end.strftime("%Y-%m-%d"),
|
||||
"jjlb": symbol_map[symbol]["jjlb"],
|
||||
"random": str(random.random()),
|
||||
}
|
||||
r = requests.get(url, params=params, headers=headers, timeout=15)
|
||||
r.raise_for_status()
|
||||
with warnings.catch_warnings(record=True):
|
||||
warnings.simplefilter("always")
|
||||
temp_df = pd.read_excel(io.BytesIO(r.content), engine="openpyxl")
|
||||
|
||||
temp_df = temp_df.dropna(how="all")
|
||||
if temp_df.empty:
|
||||
return pd.DataFrame(columns=columns)
|
||||
|
||||
temp_df.rename(
|
||||
columns={
|
||||
"基金规模(份)": "基金份额",
|
||||
},
|
||||
inplace=True,
|
||||
)
|
||||
|
||||
if "基金代码" in temp_df.columns:
|
||||
code_series = pd.to_numeric(temp_df["基金代码"], errors="coerce")
|
||||
temp_df = temp_df[code_series.notna()].copy()
|
||||
temp_df["基金代码"] = (
|
||||
code_series[code_series.notna()].astype(int).astype(str).str.zfill(6)
|
||||
)
|
||||
|
||||
if "日期" in temp_df.columns:
|
||||
temp_df["日期"] = pd.to_datetime(temp_df["日期"], errors="coerce").dt.date
|
||||
temp_df = temp_df[temp_df["日期"].notna()]
|
||||
|
||||
if temp_df.empty:
|
||||
return pd.DataFrame(columns=columns)
|
||||
|
||||
for item in ["基金份额"]:
|
||||
if item in temp_df.columns:
|
||||
temp_df[item] = temp_df[item].astype(str).str.replace(",", "", regex=False)
|
||||
temp_df[item] = pd.to_numeric(temp_df[item], errors="coerce")
|
||||
|
||||
for item in columns:
|
||||
if item not in temp_df.columns:
|
||||
temp_df[item] = pd.NA
|
||||
temp_df = temp_df[columns]
|
||||
return temp_df
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
for item_symbol in ["ETF", "LOF", "REITS"]:
|
||||
fund_scale_daily_szse_df = fund_scale_daily_szse(
|
||||
start_date="20260401", end_date="20260402", symbol=item_symbol
|
||||
)
|
||||
print(item_symbol)
|
||||
print(fund_scale_daily_szse_df)
|
||||
@@ -0,0 +1,332 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding:utf-8 -*-
|
||||
"""
|
||||
Date: 2024/10/27 22:30
|
||||
Desc: 雪球基金-基金详情
|
||||
https://danjuanfunds.com/funding/003545
|
||||
"""
|
||||
|
||||
import pandas as pd
|
||||
import requests
|
||||
|
||||
|
||||
def fund_individual_basic_info_xq(
|
||||
symbol: str = "000001", timeout: float = None
|
||||
) -> pd.DataFrame:
|
||||
"""
|
||||
雪球基金-基金详情
|
||||
https://danjuanfunds.com/djapi/fund/675091
|
||||
:param symbol: 基金代码
|
||||
:type symbol: str
|
||||
:param timeout: choice of None or a positive float number
|
||||
:type timeout: float
|
||||
:return: 基金信息
|
||||
:rtype: pandas.DataFrame
|
||||
"""
|
||||
url = f"https://danjuanfunds.com/djapi/fund/{symbol}"
|
||||
headers = {
|
||||
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "
|
||||
"Chrome/80.0.3987.149 Safari/537.36"
|
||||
}
|
||||
r = requests.get(url, headers=headers, timeout=timeout)
|
||||
json_data = r.json()["data"]
|
||||
temp_df = pd.json_normalize(json_data)
|
||||
temp_df.rename(
|
||||
columns={
|
||||
"fd_code": "基金代码",
|
||||
"fd_name": "基金名称",
|
||||
"fd_full_name": "基金全称",
|
||||
"found_date": "成立时间",
|
||||
"totshare": "最新规模",
|
||||
"keeper_name": "基金公司",
|
||||
"manager_name": "基金经理",
|
||||
"trup_name": "托管银行",
|
||||
"type_desc": "基金类型",
|
||||
"rating_source": "评级机构",
|
||||
"rating_desc": "基金评级",
|
||||
"invest_orientation": "投资策略",
|
||||
"invest_target": "投资目标",
|
||||
"performance_bench_mark": "业绩比较基准",
|
||||
},
|
||||
inplace=True,
|
||||
)
|
||||
if "评级机构" not in temp_df.columns:
|
||||
temp_df["评级机构"] = pd.NA
|
||||
temp_df = temp_df[
|
||||
[
|
||||
"基金代码",
|
||||
"基金名称",
|
||||
"基金全称",
|
||||
"成立时间",
|
||||
"最新规模",
|
||||
"基金公司",
|
||||
"基金经理",
|
||||
"托管银行",
|
||||
"基金类型",
|
||||
"评级机构",
|
||||
"基金评级",
|
||||
"投资策略",
|
||||
"投资目标",
|
||||
"业绩比较基准",
|
||||
]
|
||||
]
|
||||
temp_df = temp_df.T.reset_index()
|
||||
temp_df.columns = ["item", "value"]
|
||||
return temp_df
|
||||
|
||||
|
||||
def fund_individual_achievement_xq(
|
||||
symbol: str = "000001", timeout: float = None
|
||||
) -> pd.DataFrame:
|
||||
"""
|
||||
雪球基金-基金业绩
|
||||
https://danjuanfunds.com/djapi/fundx/base/fund/achievement/675091
|
||||
:param symbol: 基金代码
|
||||
:type symbol: str
|
||||
:param timeout: choice of None or a positive float number
|
||||
:type timeout: float
|
||||
:return: 基金业绩
|
||||
:rtype: pandas.DataFrame
|
||||
"""
|
||||
url = f"https://danjuanfunds.com/djapi/fundx/base/fund/achievement/{symbol}"
|
||||
headers = {
|
||||
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "
|
||||
"Chrome/80.0.3987.149 Safari/537.36"
|
||||
}
|
||||
r = requests.get(url, headers=headers, timeout=timeout)
|
||||
json_data = r.json()["data"]
|
||||
combined_df = None
|
||||
type_dict = {
|
||||
"annual_performance_list": "年度业绩",
|
||||
"stage_performance_list": "阶段业绩",
|
||||
}
|
||||
for k, v in type_dict.items():
|
||||
temp_df = pd.DataFrame.from_dict(json_data[k], orient="columns")
|
||||
temp_df["type"] = v
|
||||
temp_df = temp_df[
|
||||
[
|
||||
"type",
|
||||
"period_time",
|
||||
"self_nav",
|
||||
"self_max_draw_down",
|
||||
"self_nav_rank",
|
||||
]
|
||||
]
|
||||
temp_df.columns = [
|
||||
"业绩类型",
|
||||
"周期",
|
||||
"本产品区间收益",
|
||||
"本产品最大回撒",
|
||||
"周期收益同类排名",
|
||||
]
|
||||
combined_df = pd.concat([combined_df, temp_df], ignore_index=True)
|
||||
combined_df = combined_df.map(
|
||||
lambda x: x if "%" not in str(x) else x.replace("%", "")
|
||||
)
|
||||
combined_df[["本产品区间收益", "本产品最大回撒"]] = combined_df[
|
||||
["本产品区间收益", "本产品最大回撒"]
|
||||
].astype(float)
|
||||
return combined_df
|
||||
|
||||
|
||||
def fund_individual_analysis_xq(
|
||||
symbol: str = "000001", timeout: float = None
|
||||
) -> pd.DataFrame:
|
||||
"""
|
||||
雪球基金-基金数据分析
|
||||
https://danjuanfunds.com/djapi/fund/base/quote/data/index/analysis/675091
|
||||
:param symbol: 基金代码
|
||||
:type symbol: str
|
||||
:param timeout: choice of None or a positive float number
|
||||
:type timeout: float
|
||||
:return: 基金数据分析
|
||||
:rtype: pandas.DataFrame
|
||||
"""
|
||||
url = f"https://danjuanfunds.com/djapi/fund/base/quote/data/index/analysis/{symbol}"
|
||||
headers = {
|
||||
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "
|
||||
"Chrome/80.0.3987.149 Safari/537.36"
|
||||
}
|
||||
r = requests.get(url, headers=headers, timeout=timeout)
|
||||
json_data = r.json()["data"]["index_data_list"]
|
||||
temp_df = pd.json_normalize(json_data)
|
||||
temp_df = temp_df[
|
||||
[
|
||||
"index_time_period",
|
||||
"investment_cost_performance",
|
||||
"risk_control",
|
||||
"self_index.volatility_rank",
|
||||
"self_index.sharpe_rank",
|
||||
"self_index.max_draw_down",
|
||||
]
|
||||
]
|
||||
temp_df.columns = [
|
||||
"周期",
|
||||
"较同类风险收益比",
|
||||
"较同类抗风险波动",
|
||||
"年化波动率",
|
||||
"年化夏普比率",
|
||||
"最大回撤",
|
||||
]
|
||||
temp_df = temp_df.map(lambda x: x if "%" not in str(x) else x.replace("%", ""))
|
||||
temp_df[["年化波动率", "最大回撤"]] *= 100
|
||||
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 fund_individual_profit_probability_xq(
|
||||
symbol: str = "000001", timeout: float = None
|
||||
) -> pd.DataFrame:
|
||||
"""
|
||||
雪球基金-盈利概率-历史任意时点买入,持有满 X 年,盈利概率 Y%
|
||||
https://danjuanfunds.com/djapi/fundx/base/fund/profit/ratio/675091
|
||||
:param symbol: 基金代码
|
||||
:type symbol: str
|
||||
:param timeout: choice of None or a positive float number
|
||||
:type timeout: float
|
||||
:return: 盈利概率
|
||||
:rtype: pandas.DataFrame
|
||||
"""
|
||||
url = f"https://danjuanfunds.com/djapi/fundx/base/fund/profit/ratio/{symbol}"
|
||||
headers = {
|
||||
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "
|
||||
"Chrome/80.0.3987.149 Safari/537.36"
|
||||
}
|
||||
r = requests.get(url, headers=headers, timeout=timeout)
|
||||
json_data = r.json()["data"]["data_list"]
|
||||
temp_df = pd.DataFrame.from_dict(json_data, orient="columns")
|
||||
temp_df = temp_df[
|
||||
[
|
||||
"holding_time",
|
||||
"profit_ratio",
|
||||
"average_income",
|
||||
]
|
||||
]
|
||||
temp_df.columns = [
|
||||
"持有时长",
|
||||
"盈利概率",
|
||||
"平均收益",
|
||||
]
|
||||
temp_df = temp_df.map(lambda x: x if "%" not in str(x) else x.replace("%", ""))
|
||||
temp_df["盈利概率"] = pd.to_numeric(temp_df["盈利概率"], errors="coerce")
|
||||
temp_df["平均收益"] = pd.to_numeric(temp_df["平均收益"], errors="coerce")
|
||||
return temp_df
|
||||
|
||||
|
||||
def fund_individual_detail_info_xq(
|
||||
symbol: str = "000001", timeout: float = None
|
||||
) -> pd.DataFrame:
|
||||
"""
|
||||
雪球基金-交易规则
|
||||
https://danjuanfunds.com/djapi/fund/detail/675091
|
||||
:param symbol: 基金代码
|
||||
:type symbol: str
|
||||
:param timeout: choice of None or a positive float number
|
||||
:type timeout: float
|
||||
:return: 交易规则
|
||||
:rtype: pandas.DataFrame
|
||||
"""
|
||||
url = f"https://danjuanfunds.com/djapi/fund/detail/{symbol}"
|
||||
headers = {
|
||||
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "
|
||||
"Chrome/80.0.3987.149 Safari/537.36"
|
||||
}
|
||||
r = requests.get(url, headers=headers, timeout=timeout)
|
||||
json_data = r.json()["data"]
|
||||
combined_df = None
|
||||
rate_type_dict = {
|
||||
"declare_rate_table": "买入规则",
|
||||
"withdraw_rate_table": "卖出规则",
|
||||
"other_rate_table": "其他费用",
|
||||
}
|
||||
for k, v in rate_type_dict.items():
|
||||
temp_df = pd.DataFrame.from_dict(json_data["fund_rates"][k], orient="columns")
|
||||
temp_df["rate_type"] = v
|
||||
temp_df = temp_df[
|
||||
[
|
||||
"rate_type",
|
||||
"name",
|
||||
"value",
|
||||
]
|
||||
]
|
||||
temp_df.columns = [
|
||||
"费用类型",
|
||||
"条件或名称",
|
||||
"费用",
|
||||
]
|
||||
combined_df = pd.concat(objs=[combined_df, temp_df], ignore_index=True)
|
||||
combined_df["费用"] = pd.to_numeric(combined_df["费用"], errors="coerce")
|
||||
return combined_df
|
||||
|
||||
|
||||
def fund_individual_detail_hold_xq(
|
||||
symbol: str = "002804", date: str = "20231231", timeout: float = None
|
||||
) -> pd.DataFrame:
|
||||
"""
|
||||
雪球基金-持仓
|
||||
https://danjuanfunds.com/rn/fund-detail/archive?id=103&code=002804
|
||||
:param symbol: 基金代码
|
||||
:type symbol: str
|
||||
:param date: 财报日期
|
||||
:type date: str
|
||||
:param timeout: choice of None or a positive float number
|
||||
:type timeout: float
|
||||
:return: 雪球基金-持仓
|
||||
:rtype: pandas.DataFrame
|
||||
"""
|
||||
url = "https://danjuanfunds.com/djapi/fundx/base/fund/record/asset/percent"
|
||||
headers = {
|
||||
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "
|
||||
"Chrome/80.0.3987.149 Safari/537.36"
|
||||
}
|
||||
params = {
|
||||
"fund_code": f"{symbol}",
|
||||
"report_date": f"{'-'.join([date[:4], date[4:6], date[6:]])}",
|
||||
}
|
||||
r = requests.get(url, headers=headers, params=params, timeout=timeout)
|
||||
data_json = r.json()
|
||||
temp_df = pd.DataFrame.from_dict(data_json["data"]["chart_list"], orient="columns")
|
||||
temp_df = temp_df[
|
||||
[
|
||||
"type_desc",
|
||||
"percent",
|
||||
]
|
||||
]
|
||||
temp_df.columns = [
|
||||
"资产类型",
|
||||
"仓位占比",
|
||||
]
|
||||
temp_df["仓位占比"] = pd.to_numeric(temp_df["仓位占比"], errors="coerce")
|
||||
return temp_df
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
fund_individual_basic_info_xq_df = fund_individual_basic_info_xq(symbol="000005")
|
||||
print(fund_individual_basic_info_xq_df)
|
||||
|
||||
fund_individual_achievement_xq_df = fund_individual_achievement_xq(symbol="000001")
|
||||
print(fund_individual_achievement_xq_df)
|
||||
|
||||
fund_individual_analysis_xq_df = fund_individual_analysis_xq(symbol="000001")
|
||||
print(fund_individual_analysis_xq_df)
|
||||
|
||||
fund_individual_profit_probability_xq_df = fund_individual_profit_probability_xq(
|
||||
symbol="000001"
|
||||
)
|
||||
print(fund_individual_profit_probability_xq_df)
|
||||
|
||||
fund_individual_detail_info_xq_df = fund_individual_detail_info_xq(symbol="000001")
|
||||
print(fund_individual_detail_info_xq_df)
|
||||
|
||||
fund_individual_detail_hold_xq_df = fund_individual_detail_hold_xq(
|
||||
symbol="002804", date="20231231"
|
||||
)
|
||||
print(fund_individual_detail_hold_xq_df)
|
||||
Reference in New Issue
Block a user