stock-tracker

This commit is contained in:
C菌
2026-07-04 00:17:11 +08:00
commit 6087341a48
6463 changed files with 1929869 additions and 0 deletions
@@ -0,0 +1,6 @@
#!/usr/bin/env python
# -*- coding:utf-8 -*-
"""
Date: 2019/12/27 18:02
Desc:
"""
@@ -0,0 +1,19 @@
#!/usr/bin/env python
# -*- coding:utf-8 -*-
"""
Date: 2019/12/30 21:02
Desc:
"""
stock_em_sy_js = """
function getCode(num) {
var str = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
var codes = str.split('');
num = num || 6;
var code = "";
for (var i = 0; i < num; i++) {
code += codes[Math.floor(Math.random() * 52)]
}
return code
}
"""
@@ -0,0 +1,79 @@
#!/usr/bin/env python
# -*- coding:utf-8 -*-
"""
Date: 2024/4/30 10:30
Desc: 破净股统计历史走势
https://www.legulegu.com/stockdata/below-net-asset-statistics
"""
import pandas as pd
import requests
from akshare.utils.cons import headers
def stock_a_below_net_asset_statistics(symbol: str = "全部A股") -> pd.DataFrame:
"""
破净股统计历史走势
https://www.legulegu.com/stockdata/below-net-asset-statistics
:param symbol: choice of {"全部A股", "沪深300", "上证50", "中证500"}
:type symbol: str
:return: 破净股统计历史走势
:rtype: pandas.DataFrame
"""
symbol_map = {
"全部A股": "1",
"沪深300": "000300.XSHG",
"上证50": "000016.SH",
"中证500": "000905.SH",
}
url = "https://legulegu.com/stockdata/below-net-asset-statistics-data"
params = {
"marketId": symbol_map[symbol],
"token": "325843825a2745a2a8f9b9e3355cb864",
}
r = requests.get(url, params=params, headers=headers)
data_json = r.json()
temp_df = pd.DataFrame(data_json)
temp_df["date"] = pd.to_datetime(temp_df["date"], unit="ms").dt.date
del temp_df["marketId"]
big_df = temp_df.iloc[:, :3]
big_df.columns = ["below_net_asset", "total_company", "date"]
big_df["below_net_asset_ratio"] = round(
big_df["below_net_asset"] / big_df["total_company"], 4
)
big_df = big_df[
["date", "below_net_asset", "total_company", "below_net_asset_ratio"]
]
big_df["date"] = pd.to_datetime(big_df["date"], errors="coerce").dt.date
big_df["below_net_asset"] = pd.to_numeric(
big_df["below_net_asset"], errors="coerce"
)
big_df["total_company"] = pd.to_numeric(big_df["total_company"], errors="coerce")
big_df["below_net_asset_ratio"] = pd.to_numeric(
big_df["below_net_asset_ratio"], errors="coerce"
)
big_df.sort_values(["date"], inplace=True, ignore_index=True)
return big_df
if __name__ == "__main__":
stock_a_below_net_asset_statistics_df = stock_a_below_net_asset_statistics(
symbol="全部A股"
)
print(stock_a_below_net_asset_statistics_df)
stock_a_below_net_asset_statistics_df = stock_a_below_net_asset_statistics(
symbol="沪深300"
)
print(stock_a_below_net_asset_statistics_df)
stock_a_below_net_asset_statistics_df = stock_a_below_net_asset_statistics(
symbol="上证50"
)
print(stock_a_below_net_asset_statistics_df)
stock_a_below_net_asset_statistics_df = stock_a_below_net_asset_statistics(
symbol="中证500"
)
print(stock_a_below_net_asset_statistics_df)
@@ -0,0 +1,52 @@
#!/usr/bin/env python
# -*- coding:utf-8 -*-
"""
Date: 2026/5/20 17:30
Desc: 乐咕乐股-创新高、新低的股票数量
https://www.legulegu.com/stockdata/high-low-statistics
"""
import pandas as pd
import requests
from akshare.utils.cons import headers
def stock_a_high_low_statistics(symbol: str = "all") -> pd.DataFrame:
"""
乐咕乐股-创新高、新低的股票数量
https://www.legulegu.com/stockdata/high-low-statistics
:param symbol: choice of {"all", "sz50", "hs300", "zz500"}
:type symbol: str
:return: 创新高、新低的股票数量
:rtype: pandas.DataFrame
"""
url = f"https://www.legulegu.com/stockdata/member-ship/get-high-low-statistics/{symbol}"
r = requests.get(url, headers=headers)
data_json = r.json()
temp_df = pd.DataFrame(data_json)
del temp_df["indexCode"]
temp_df["date"] = pd.to_datetime(temp_df["date"], errors="coerce").dt.date
temp_df["close"] = pd.to_numeric(temp_df["close"], errors="coerce")
temp_df["high20"] = pd.to_numeric(temp_df["high20"], errors="coerce")
temp_df["low20"] = pd.to_numeric(temp_df["low20"], errors="coerce")
temp_df["high60"] = pd.to_numeric(temp_df["high60"], errors="coerce")
temp_df["low60"] = pd.to_numeric(temp_df["low60"], errors="coerce")
temp_df["high120"] = pd.to_numeric(temp_df["high120"], errors="coerce")
temp_df["low120"] = pd.to_numeric(temp_df["low120"], errors="coerce")
temp_df.sort_values(by=["date"], inplace=True, ignore_index=True)
return temp_df
if __name__ == "__main__":
stock_a_high_low_statistics_df = stock_a_high_low_statistics(symbol="all")
print(stock_a_high_low_statistics_df)
stock_a_high_low_statistics_df = stock_a_high_low_statistics(symbol="sz50")
print(stock_a_high_low_statistics_df)
stock_a_high_low_statistics_df = stock_a_high_low_statistics(symbol="hs300")
print(stock_a_high_low_statistics_df)
stock_a_high_low_statistics_df = stock_a_high_low_statistics(symbol="zz500")
print(stock_a_high_low_statistics_df)
@@ -0,0 +1,95 @@
#!/usr/bin/env python
# -*- coding:utf-8 -*-
"""
Date: 2025/10/30 20:24
Desc: 市盈率, 市净率和股息率查询
https://www.legulegu.com/stocklist
https://www.legulegu.com/s/000001
"""
from datetime import datetime
from hashlib import md5
import pandas as pd
import requests
from bs4 import BeautifulSoup
from akshare.utils.cons import headers
def get_cookie_csrf(url: str = "") -> dict:
"""
乐咕乐股-主板市盈率
https://legulegu.com/stockdata/shanghaiPE
:return: 指定市场的市盈率数据
:rtype: pandas.DataFrame
"""
# 创建独立的 session,避免污染全局状态
session = requests.Session()
session.headers.update(headers)
r = session.get(url)
soup = BeautifulSoup(r.text, features="lxml")
csrf_tag = soup.find(name="meta", attrs={"name": "_csrf"})
csrf_token = csrf_tag.attrs["content"]
# 创建新的 headers
local_headers = headers.copy()
local_headers.update({"X-CSRF-Token": csrf_token})
return {"cookies": r.cookies, "headers": local_headers}
def get_token_lg() -> str:
"""
生成乐咕的 token
https://legulegu.com/s/002488
:return: token
:rtype: str
"""
current_date_str = datetime.now().date().isoformat()
obj = md5()
obj.update(current_date_str.encode("utf-8"))
token = obj.hexdigest()
return token
def stock_hk_indicator_eniu(
symbol: str = "hk01093", indicator: str = "市盈率"
) -> pd.DataFrame:
"""
亿牛网-港股指标
https://eniu.com/gu/hk01093/roe
:param symbol: 港股代码
:type symbol: str
:param indicator: 需要获取的指标, choice of {"港股", "市盈率", "市净率", "股息率", "ROE", "市值"}
:type indicator: str
:return: 指定 symbol 和 indicator 的数据
:rtype: pandas.DataFrame
"""
if indicator == "港股":
url = "https://eniu.com/static/data/stock_list.json"
r = requests.get(url, headers=headers)
data_json = r.json()
temp_df = pd.DataFrame(data_json)
temp_df = temp_df[temp_df["stock_id"].str.contains("hk")]
temp_df.reset_index(inplace=True, drop=True)
return temp_df
if indicator == "市盈率":
url = f"https://eniu.com/chart/peh/{symbol}"
elif indicator == "市净率":
url = f"https://eniu.com/chart/pbh/{symbol}"
elif indicator == "股息率":
url = f"https://eniu.com/chart/dvh/{symbol}"
elif indicator == "ROE":
url = f"https://eniu.com/chart/roeh/{symbol}"
else:
url = f"https://eniu.com/chart/marketvalueh/{symbol}"
r = requests.get(url, headers=headers)
data_json = r.json()
temp_df = pd.DataFrame(data_json)
return temp_df
if __name__ == "__main__":
stock_hk_indicator_eniu_df = stock_hk_indicator_eniu(
symbol="hk01093", indicator="市盈率"
)
print(stock_hk_indicator_eniu_df)
@@ -0,0 +1,621 @@
#!/usr/bin/env python
# -*- coding:utf-8 -*-
"""
Date: 2025/3/20 20:00
Desc: 乐咕乐股-A 股市盈率和市净率
https://legulegu.com/stockdata/shanghaiPE
"""
from datetime import datetime
import pandas as pd
import py_mini_racer
import requests
from akshare.stock_feature.stock_a_indicator import get_cookie_csrf
hash_code = """
function e(n) {
var e, t, r = "", o = -1, f;
if (n && n.length) {
f = n.length;
while ((o += 1) < f) {
e = n.charCodeAt(o);
t = o + 1 < f ? n.charCodeAt(o + 1) : 0;
if (55296 <= e && e <= 56319 && 56320 <= t && t <= 57343) {
e = 65536 + ((e & 1023) << 10) + (t & 1023);
o += 1
}
if (e <= 127) {
r += String.fromCharCode(e)
} else if (e <= 2047) {
r += String.fromCharCode(192 | e >>> 6 & 31, 128 | e & 63)
} else if (e <= 65535) {
r += String.fromCharCode(224 | e >>> 12 & 15, 128 | e >>> 6 & 63, 128 | e & 63)
} else if (e <= 2097151) {
r += String.fromCharCode(240 | e >>> 18 & 7, 128 | e >>> 12 & 63, 128 | e >>> 6 & 63, 128 | e & 63)
}
}
}
return r
}
function t(n) {
var e, t, r, o, f, i = [], h;
e = t = r = o = f = 0;
if (n && n.length) {
h = n.length;
n += "";
while (e < h) {
r = n.charCodeAt(e);
t += 1;
if (r < 128) {
i[t] = String.fromCharCode(r);
e += 1
} else if (r > 191 && r < 224) {
o = n.charCodeAt(e + 1);
i[t] = String.fromCharCode((r & 31) << 6 | o & 63);
e += 2
} else {
o = n.charCodeAt(e + 1);
f = n.charCodeAt(e + 2);
i[t] = String.fromCharCode(
(r & 15) << 12 | (o & 63) << 6 | f & 63);
e += 3
}
}
}
return i.join("")
}
function r(n, e) {
var t = (n & 65535) + (e & 65535)
, r = (n >> 16) + (e >> 16) + (t >> 16);
return r << 16 | t & 65535
}
function o(n, e) {
return n << e | n >>> 32 - e
}
function f(n, e) {
var t = e ? "0123456789ABCDEF" : "0123456789abcdef", r = "", o, f = 0, i = n.length;
for (; f < i; f += 1) {
o = n.charCodeAt(f);
r += t.charAt(o >>> 4 & 15) + t.charAt(o & 15)
}
return r
}
function i(n) {
var e, t = n.length, r = "";
for (e = 0; e < t; e += 1) {
r += String.fromCharCode(n.charCodeAt(e) & 255, n.charCodeAt(e) >>> 8 & 255)
}
return r
}
function h(n) {
var e, t = n.length, r = "";
for (e = 0; e < t; e += 1) {
r += String.fromCharCode(n.charCodeAt(e) >>> 8 & 255, n.charCodeAt(e) & 255)
}
return r
}
function u(n) {
var e, t = n.length * 32, r = "";
for (e = 0; e < t; e += 8) {
r += String.fromCharCode(n[e >> 5] >>> 24 - e % 32 & 255)
}
return r
}
function a(n) {
var e, t = n.length * 32, r = "";
for (e = 0; e < t; e += 8) {
r += String.fromCharCode(n[e >> 5] >>> e % 32 & 255)
}
return r
}
function c(n) {
var e, t = n.length * 8, r = Array(n.length >> 2), o = r.length;
for (e = 0; e < o; e += 1) {
r[e] = 0
}
for (e = 0; e < t; e += 8) {
r[e >> 5] |= (n.charCodeAt(e / 8) & 255) << e % 32
}
return r
}
function l(n) {
var e, t = n.length * 8, r = Array(n.length >> 2), o = r.length;
for (e = 0; e < o; e += 1) {
r[e] = 0
}
for (e = 0; e < t; e += 8) {
r[e >> 5] |= (n.charCodeAt(e / 8) & 255) << 24 - e % 32
}
return r
}
function D(n, e) {
var t = e.length, r = Array(), o, f, i, h, u, a, c, l;
a = Array(Math.ceil(n.length / 2));
h = a.length;
for (o = 0; o < h; o += 1) {
a[o] = n.charCodeAt(o * 2) << 8 | n.charCodeAt(o * 2 + 1)
}
while (a.length > 0) {
u = Array();
i = 0;
for (o = 0; o < a.length; o += 1) {
i = (i << 16) + a[o];
f = Math.floor(i / t);
i -= f * t;
if (u.length > 0 || f > 0) {
u[u.length] = f
}
}
r[r.length] = i;
a = u
}
c = "";
for (o = r.length - 1; o >= 0; o--) {
c += e.charAt(r[o])
}
l = Math.ceil(n.length * 8 / (Math.log(e.length) / Math.log(2)));
for (o = c.length; o < l; o += 1) {
c = e[0] + c
}
return c
}
function B(n, e) {
var t = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/", r = "", o = n.length, f, i, h;
e = e || "=";
for (f = 0; f < o; f += 3) {
h = n.charCodeAt(f) << 16 | (f + 1 < o ? n.charCodeAt(f + 1) << 8 : 0) | (f + 2 < o ? n.charCodeAt(f + 2) : 0);
for (i = 0; i < 4; i += 1) {
if (f * 8 + i * 6 > n.length * 8) {
r += e
} else {
r += t.charAt(h >>> 6 * (3 - i) & 63)
}
}
}
return r
}
function hex(n) {
return f(u(n, h), t)
}
function u(n) {
n = h ? e(n) : n;
return a(C(c(n), n.length * 8))
}
function l(n, t) {
var r, o, f, i, u;
n = h ? e(n) : n;
t = h ? e(t) : t;
r = c(n);
if (r.length > 16) {
r = C(r, n.length * 8)
}
o = Array(16),
f = Array(16);
for (u = 0; u < 16; u += 1) {
o[u] = r[u] ^ 909522486;
f[u] = r[u] ^ 1549556828
}
i = C(o.concat(c(t)), 512 + t.length * 8);
return a(C(f.concat(i), 512 + 128))
}
function C(n, e) {
var t, o, f, i, h, u = 1732584193, a = -271733879, c = -1732584194, l = 271733878;
n[e >> 5] |= 128 << e % 32;
n[(e + 64 >>> 9 << 4) + 14] = e;
for (t = 0; t < n.length; t += 16) {
o = u;
f = a;
i = c;
h = l;
u = s(u, a, c, l, n[t + 0], 7, -680876936);
l = s(l, u, a, c, n[t + 1], 12, -389564586);
c = s(c, l, u, a, n[t + 2], 17, 606105819);
a = s(a, c, l, u, n[t + 3], 22, -1044525330);
u = s(u, a, c, l, n[t + 4], 7, -176418897);
l = s(l, u, a, c, n[t + 5], 12, 1200080426);
c = s(c, l, u, a, n[t + 6], 17, -1473231341);
a = s(a, c, l, u, n[t + 7], 22, -45705983);
u = s(u, a, c, l, n[t + 8], 7, 1770035416);
l = s(l, u, a, c, n[t + 9], 12, -1958414417);
c = s(c, l, u, a, n[t + 10], 17, -42063);
a = s(a, c, l, u, n[t + 11], 22, -1990404162);
u = s(u, a, c, l, n[t + 12], 7, 1804603682);
l = s(l, u, a, c, n[t + 13], 12, -40341101);
c = s(c, l, u, a, n[t + 14], 17, -1502002290);
a = s(a, c, l, u, n[t + 15], 22, 1236535329);
u = w(u, a, c, l, n[t + 1], 5, -165796510);
l = w(l, u, a, c, n[t + 6], 9, -1069501632);
c = w(c, l, u, a, n[t + 11], 14, 643717713);
a = w(a, c, l, u, n[t + 0], 20, -373897302);
u = w(u, a, c, l, n[t + 5], 5, -701558691);
l = w(l, u, a, c, n[t + 10], 9, 38016083);
c = w(c, l, u, a, n[t + 15], 14, -660478335);
a = w(a, c, l, u, n[t + 4], 20, -405537848);
u = w(u, a, c, l, n[t + 9], 5, 568446438);
l = w(l, u, a, c, n[t + 14], 9, -1019803690);
c = w(c, l, u, a, n[t + 3], 14, -187363961);
a = w(a, c, l, u, n[t + 8], 20, 1163531501);
u = w(u, a, c, l, n[t + 13], 5, -1444681467);
l = w(l, u, a, c, n[t + 2], 9, -51403784);
c = w(c, l, u, a, n[t + 7], 14, 1735328473);
a = w(a, c, l, u, n[t + 12], 20, -1926607734);
u = F(u, a, c, l, n[t + 5], 4, -378558);
l = F(l, u, a, c, n[t + 8], 11, -2022574463);
c = F(c, l, u, a, n[t + 11], 16, 1839030562);
a = F(a, c, l, u, n[t + 14], 23, -35309556);
u = F(u, a, c, l, n[t + 1], 4, -1530992060);
l = F(l, u, a, c, n[t + 4], 11, 1272893353);
c = F(c, l, u, a, n[t + 7], 16, -155497632);
a = F(a, c, l, u, n[t + 10], 23, -1094730640);
u = F(u, a, c, l, n[t + 13], 4, 681279174);
l = F(l, u, a, c, n[t + 0], 11, -358537222);
c = F(c, l, u, a, n[t + 3], 16, -722521979);
a = F(a, c, l, u, n[t + 6], 23, 76029189);
u = F(u, a, c, l, n[t + 9], 4, -640364487);
l = F(l, u, a, c, n[t + 12], 11, -421815835);
c = F(c, l, u, a, n[t + 15], 16, 530742520);
a = F(a, c, l, u, n[t + 2], 23, -995338651);
u = E(u, a, c, l, n[t + 0], 6, -198630844);
l = E(l, u, a, c, n[t + 7], 10, 1126891415);
c = E(c, l, u, a, n[t + 14], 15, -1416354905);
a = E(a, c, l, u, n[t + 5], 21, -57434055);
u = E(u, a, c, l, n[t + 12], 6, 1700485571);
l = E(l, u, a, c, n[t + 3], 10, -1894986606);
c = E(c, l, u, a, n[t + 10], 15, -1051523);
a = E(a, c, l, u, n[t + 1], 21, -2054922799);
u = E(u, a, c, l, n[t + 8], 6, 1873313359);
l = E(l, u, a, c, n[t + 15], 10, -30611744);
c = E(c, l, u, a, n[t + 6], 15, -1560198380);
a = E(a, c, l, u, n[t + 13], 21, 1309151649);
u = E(u, a, c, l, n[t + 4], 6, -145523070);
l = E(l, u, a, c, n[t + 11], 10, -1120210379);
c = E(c, l, u, a, n[t + 2], 15, 718787259);
a = E(a, c, l, u, n[t + 9], 21, -343485551);
u = r(u, o);
a = r(a, f);
c = r(c, i);
l = r(l, h)
}
return Array(u, a, c, l)
}
function A(n, e, t, f, i, h) {
return r(o(r(r(e, n), r(f, h)), i), t)
}
function s(n, e, t, r, o, f, i) {
return A(e & t | ~e & r, n, e, o, f, i)
}
function w(n, e, t, r, o, f, i) {
return A(e & r | t & ~r, n, e, o, f, i)
}
function F(n, e, t, r, o, f, i) {
return A(e ^ t ^ r, n, e, o, f, i)
}
function E(n, e, t, r, o, f, i) {
return A(t ^ (e | ~r), n, e, o, f, i)
}
"""
def stock_market_pe_lg(symbol: str = "深证") -> pd.DataFrame:
"""
乐咕乐股-主板市盈率
https://legulegu.com/stockdata/shanghaiPE
:param symbol: choice of {"上证", "深证", "创业板", "科创版"}
:type symbol: str
:return: 指定市场的市盈率数据
:rtype: pandas.DataFrame
"""
js_functions = py_mini_racer.MiniRacer()
js_functions.eval(hash_code)
token = js_functions.call("hex", datetime.now().date().isoformat()).lower()
if symbol in {"上证", "深证", "创业板"}:
url = "https://legulegu.com/api/stock-data/market-pe"
symbol_map = {
"上证": "1",
"深证": "2",
"创业板": "4",
}
url_map = {
"上证": "https://legulegu.com/stockdata/shanghaiPE",
"深证": "https://legulegu.com/stockdata/shenzhenPE",
"创业板": "https://legulegu.com/stockdata/cybPE",
}
params = {"token": token, "marketId": symbol_map[symbol]}
r = requests.get(url, params=params, **get_cookie_csrf(url=url_map[symbol]))
data_json = r.json()
temp_df = pd.DataFrame(data_json["data"])
temp_df["date"] = (
pd.to_datetime(temp_df["date"], utc=True)
.dt.tz_convert("Asia/Shanghai")
.dt.date
)
temp_df = temp_df[
[
"date",
"close",
"pe",
]
]
temp_df.columns = [
"日期",
"指数",
"平均市盈率",
]
return temp_df
else:
url = "https://legulegu.com/api/stockdata/get-ke-chuang-ban-pe"
params = {"token": token}
r = requests.get(
url,
params=params,
**get_cookie_csrf(url="https://legulegu.com/stockdata/ke-chuang-ban-pe"),
)
data_json = r.json()
temp_df = pd.DataFrame(data_json["data"])
temp_df["date"] = (
pd.to_datetime(temp_df["date"], utc=True)
.dt.tz_convert("Asia/Shanghai")
.dt.date
)
temp_df = temp_df[
[
"date",
"close",
"pe",
]
]
temp_df.columns = [
"日期",
"总市值",
"市盈率",
]
return temp_df
def stock_index_pe_lg(symbol: str = "沪深300") -> pd.DataFrame:
"""
乐咕乐股-指数市盈率
https://legulegu.com/stockdata/sz50-ttm-lyr
:param symbol: choice of {"上证50", "沪深300", "上证380", "创业板50", "中证500", "上证180", "深证红利", "深证100", "中证1000", "上证红利", "中证100", "中证800"}
:type symbol: str
:return: 指定指数的市盈率数据
:rtype: pandas.DataFrame
"""
js_functions = py_mini_racer.MiniRacer()
js_functions.eval(hash_code)
token = js_functions.call("hex", datetime.now().date().isoformat()).lower()
symbol_map = {
"上证50": "000016.SH",
"沪深300": "000300.SH",
"上证380": "000009.SH",
"创业板50": "399673.SZ",
"中证500": "000905.SH",
"上证180": "000010.SH",
"深证红利": "399324.SZ",
"深证100": "399330.SZ",
"中证1000": "000852.SH",
"上证红利": "000015.SH",
"中证100": "000903.SH",
"中证800": "000906.SH",
}
url = "https://legulegu.com/api/stockdata/index-basic-pe"
params = {"token": token, "indexCode": symbol_map[symbol]}
r = requests.get(
url,
params=params,
**get_cookie_csrf(url="https://legulegu.com/stockdata/sz50-ttm-lyr"),
)
data_json = r.json()
temp_df = pd.DataFrame(data_json["data"])
temp_df["date"] = (
pd.to_datetime(temp_df["date"], utc=True)
.dt.tz_convert("Asia/Shanghai")
.dt.date
)
temp_df = temp_df[
[
"date",
"close",
"lyrPe",
"addLyrPe",
"middleLyrPe",
"ttmPe",
"addTtmPe",
"middleTtmPe",
]
]
temp_df.columns = [
"日期",
"指数",
"等权静态市盈率",
"静态市盈率",
"静态市盈率中位数",
"等权滚动市盈率",
"滚动市盈率",
"滚动市盈率中位数",
]
return temp_df
def stock_market_pb_lg(symbol: str = "上证") -> pd.DataFrame:
"""
乐咕乐股-主板市净率
https://legulegu.com/stockdata/shanghaiPB
:param symbol: choice of {"上证", "深证", "创业板", "科创版"}
:type symbol: str
:return: 指定市场的市净率数据
:rtype: pandas.DataFrame
"""
js_functions = py_mini_racer.MiniRacer()
js_functions.eval(hash_code)
token = js_functions.call("hex", datetime.now().date().isoformat()).lower()
url = "https://legulegu.com/api/stockdata/index-basic-pb"
symbol_map = {"上证": "1", "深证": "2", "创业板": "4", "科创版": "7"}
url_map = {
"上证": "https://legulegu.com/stockdata/shanghaiPB",
"深证": "https://legulegu.com/stockdata/shenzhenPB",
"创业板": "https://legulegu.com/stockdata/cybPB",
"科创版": "https://legulegu.com/stockdata/ke-chuang-ban-pb",
}
params = {"token": token, "indexCode": symbol_map[symbol]}
r = requests.get(url, params=params, **get_cookie_csrf(url=url_map[symbol]))
data_json = r.json()
temp_df = pd.DataFrame(data_json["data"])
temp_df["date"] = (
pd.to_datetime(temp_df["date"], utc=True)
.dt.tz_convert("Asia/Shanghai")
.dt.date
)
temp_df = temp_df[
[
"date",
"close",
"addPb",
"pb",
"middlePb",
]
]
temp_df.columns = [
"日期",
"指数",
"市净率",
"等权市净率",
"市净率中位数",
]
return temp_df
def stock_index_pb_lg(symbol: str = "上证50") -> pd.DataFrame:
"""
乐咕乐股-指数市净率
https://legulegu.com/stockdata/sz50-pb
:param symbol: choice of {"上证50", "沪深300", "上证380", "创业板50", "中证500", "上证180", "深证红利", "深证100", "中证1000", "上证红利", "中证100", "中证800"}
:type symbol: str
:return: 指定指数的市净率数据
:rtype: pandas.DataFrame
"""
js_functions = py_mini_racer.MiniRacer()
js_functions.eval(hash_code)
token = js_functions.call("hex", datetime.now().date().isoformat()).lower()
symbol_map = {
"上证50": "000016.SH",
"沪深300": "000300.SH",
"上证380": "000009.SH",
"创业板50": "399673.SZ",
"中证500": "000905.SH",
"上证180": "000010.SH",
"深证红利": "399324.SZ",
"深证100": "399330.SZ",
"中证1000": "000852.SH",
"上证红利": "000015.SH",
"中证100": "000903.SH",
"中证800": "000906.SH",
}
url = "https://legulegu.com/api/stockdata/index-basic-pb"
params = {"token": token, "indexCode": symbol_map[symbol]}
r = requests.get(
url,
params=params,
**get_cookie_csrf(url="https://legulegu.com/stockdata/zz500-ttm-lyr"),
)
data_json = r.json()
temp_df = pd.DataFrame(data_json["data"])
temp_df["date"] = (
pd.to_datetime(temp_df["date"], utc=True)
.dt.tz_convert("Asia/Shanghai")
.dt.date
)
temp_df = temp_df[
[
"date",
"close",
"addPb",
"pb",
"middlePb",
]
]
temp_df.columns = [
"日期",
"指数",
"市净率",
"等权市净率",
"市净率中位数",
]
return temp_df
if __name__ == "__main__":
stock_market_pe_lg_df = stock_market_pe_lg(symbol="上证")
print(stock_market_pe_lg_df)
stock_market_pe_lg_df = stock_market_pe_lg(symbol="科创版")
print(stock_market_pe_lg_df)
for item in {"上证", "深证", "创业板", "科创版"}:
print(item)
stock_market_pe_lg_df = stock_market_pe_lg(symbol=item)
print(stock_market_pe_lg_df)
stock_index_pe_lg_df = stock_index_pe_lg(symbol="沪深300")
print(stock_index_pe_lg_df)
for item in [
"上证50",
"沪深300",
"上证380",
"创业板50",
"中证500",
"上证180",
"深证红利",
"深证100",
"中证1000",
"上证红利",
"中证100",
"中证800",
]:
stock_index_pe_lg_df = stock_index_pe_lg(symbol=item)
print(stock_index_pe_lg_df)
for item in {"上证", "深证", "创业板", "科创版"}:
stock_market_pb_lg_df = stock_market_pb_lg(symbol=item)
print(stock_market_pb_lg_df)
for item in [
"上证50",
"沪深300",
"上证380",
"创业板50",
"中证500",
"上证180",
"深证红利",
"深证100",
"中证1000",
"上证红利",
"中证100",
"中证800",
]:
stock_index_pe_lg_df = stock_index_pb_lg(symbol=item)
print(stock_index_pe_lg_df)
@@ -0,0 +1,97 @@
#!/usr/bin/env python
# -*- coding:utf-8 -*-
"""
Date: 2024/4/21 17:00
Desc: 东方财富网-数据中心-特色数据-股票账户统计
东方财富网-数据中心-特色数据-股票账户统计: 股票账户统计详细数据
https://data.eastmoney.com/cjsj/gpkhsj.html
"""
import pandas as pd
import requests
def stock_account_statistics_em() -> pd.DataFrame:
"""
东方财富网-数据中心-特色数据-股票账户统计
https://data.eastmoney.com/cjsj/gpkhsj.html
:return: 股票账户统计数据
:rtype: pandas.DataFrame
"""
url = "https://datacenter-web.eastmoney.com/api/data/v1/get"
params = {
"reportName": "RPT_STOCK_OPEN_DATA",
"columns": "ALL",
"pageSize": "500",
"sortColumns": "STATISTICS_DATE",
"sortTypes": "-1",
"source": "WEB",
"client": "WEB",
"p": "1",
"pageNo": "1",
"pageNum": "1",
"pageNumber": "1",
}
r = requests.get(url, params=params)
data_json = r.json()
temp_df = pd.DataFrame(data_json["result"]["data"])
temp_df.columns = [
"数据日期",
"新增投资者-数量",
"新增投资者-环比",
"新增投资者-同比",
"期末投资者-总量",
"期末投资者-A股账户",
"期末投资者-B股账户",
"上证指数-收盘",
"上证指数-涨跌幅",
"沪深总市值",
"沪深户均市值",
"-",
]
temp_df = temp_df[
[
"数据日期",
"新增投资者-数量",
"新增投资者-环比",
"新增投资者-同比",
"期末投资者-总量",
"期末投资者-A股账户",
"期末投资者-B股账户",
"沪深总市值",
"沪深户均市值",
"上证指数-收盘",
"上证指数-涨跌幅",
]
]
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["期末投资者-A股账户"] = pd.to_numeric(
temp_df["期末投资者-A股账户"], errors="coerce"
)
temp_df["期末投资者-B股账户"] = pd.to_numeric(
temp_df["期末投资者-B股账户"], 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.sort_values(["数据日期"], ignore_index=True, inplace=True)
return temp_df
if __name__ == "__main__":
stock_account_statistics_em_df = stock_account_statistics_em()
print(stock_account_statistics_em_df)
@@ -0,0 +1,45 @@
#!/usr/bin/env python
# -*- coding:utf-8 -*-
"""
Date: 2023/4/11 20:40
Desc: 全部A股-等权重市净率、中位数市净率
https://www.legulegu.com/stockdata/all-pb
"""
import pandas as pd
import requests
from akshare.stock_feature.stock_a_indicator import get_token_lg, get_cookie_csrf
def stock_a_all_pb() -> pd.DataFrame:
"""
全部A股-等权重市净率、中位数市净率
https://legulegu.com/stockdata/all-pb
:return: 全部A股-等权重市盈率、中位数市盈率
:rtype: pandas.DataFrame
"""
url = "https://legulegu.com/api/stock-data/market-index-pb"
params = {
"marketId": "ALL",
"token": get_token_lg(),
}
r = requests.get(
url,
params=params,
**get_cookie_csrf(url="https://legulegu.com/stockdata/all-pb"),
)
data_json = r.json()
temp_df = pd.DataFrame(data_json["data"])
temp_df["date"] = (
pd.to_datetime(temp_df["date"], utc=True)
.dt.tz_convert("Asia/Shanghai")
.dt.date
)
del temp_df["weightingAveragePB"]
return temp_df
if __name__ == "__main__":
stock_a_all_pb_df = stock_a_all_pb()
print(stock_a_all_pb_df)
@@ -0,0 +1,271 @@
#!/usr/bin/env python
# -*- coding:utf-8 -*-
"""
Date: 2023/8/20 20:00
Desc: 东方财富网-数据中心-研究报告-东方财富分析师指数
https://data.eastmoney.com/invest/invest/list.html
"""
import pandas as pd
import requests
from akshare.utils.tqdm import get_tqdm
from akshare.utils.cons import headers
def stock_analyst_rank_em(year: str = "2024") -> pd.DataFrame:
"""
东方财富网-数据中心-研究报告-东方财富分析师指数-东方财富分析师指数
https://data.eastmoney.com/invest/invest/list.html
:param year: 从 2015 年至今
:type year: str
:return: 东方财富分析师指数
:rtype: pandas.DataFrame
"""
url = "https://data.eastmoney.com/dataapi/invest/list"
params = {
"sortColumns": "YEAR_YIELD",
"sortTypes": "-1",
"pageSize": "500",
"pageNumber": "1",
"reportName": "RPT_ANALYST_INDEX_RANK",
"columns": "ALL",
"source": "WEB",
"client": "WEB",
"filter": f'(YEAR="{year}")',
"distinct": "ANALYST_CODE",
"limit": "top100",
}
r = requests.get(url, params=params, headers=headers)
data_json = r.json()
total_page = data_json["result"]["pages"]
big_df = pd.DataFrame()
tqdm = get_tqdm()
for page in tqdm(range(1, total_page + 1), leave=False):
params.update({"pageNumber": page})
r = requests.get(url, params=params, headers=headers)
data_json = r.json()
data_df = pd.DataFrame(data_json["result"]["data"])
big_df = pd.concat(objs=[big_df, data_df], ignore_index=True)
big_df.reset_index(inplace=True)
big_df["index"] = list(range(1, len(big_df) + 1))
big_df.columns = [
"序号",
"分析师ID",
"分析师名称",
"更新日期",
"年度",
"分析师单位",
"_",
"年度指数",
f"{year}年收益率",
"3个月收益率",
"6个月收益率",
"12个月收益率",
"成分股个数",
f"{year}最新个股评级-股票名称",
"_",
f"{year}最新个股评级-股票代码",
"_",
"行业代码",
"行业",
]
big_df = big_df[
[
"序号",
"分析师名称",
"分析师单位",
"年度指数",
f"{year}年收益率",
"3个月收益率",
"6个月收益率",
"12个月收益率",
"成分股个数",
f"{year}最新个股评级-股票名称",
f"{year}最新个股评级-股票代码",
"分析师ID",
"行业代码",
"行业",
"更新日期",
"年度",
]
]
big_df["更新日期"] = pd.to_datetime(big_df["更新日期"], errors="coerce").dt.date
big_df["年度指数"] = pd.to_numeric(big_df["年度指数"], errors="coerce")
big_df[f"{year}年收益率"] = pd.to_numeric(
big_df[f"{year}年收益率"], errors="coerce"
)
big_df["3个月收益率"] = pd.to_numeric(big_df["3个月收益率"], errors="coerce")
big_df["6个月收益率"] = pd.to_numeric(big_df["6个月收益率"], errors="coerce")
big_df["12个月收益率"] = pd.to_numeric(big_df["12个月收益率"], errors="coerce")
big_df["成分股个数"] = pd.to_numeric(big_df["成分股个数"], errors="coerce")
return big_df
def stock_analyst_detail_em(
analyst_id: str = "11000200926", indicator: str = "最新跟踪成分股"
) -> pd.DataFrame:
"""
东方财富网-数据中心-研究报告-东方财富分析师指数-东方财富分析师指数2020最新排行-分析师详情
https://data.eastmoney.com/invest/invest/11000257131.html
:param analyst_id: 分析师 ID, 从 ak.stock_analyst_rank_em() 获取
:type analyst_id: str
:param indicator: choice of {"最新跟踪成分股", "历史跟踪成分股", "历史指数"}
:type indicator: str
:return: 具体指标的数据
:rtype: pandas.DataFrame
"""
url = "https://datacenter.eastmoney.com/special/api/data/v1/get"
if indicator == "最新跟踪成分股":
params = {
"reportName": "RPT_RESEARCHER_NTCSTOCK",
"columns": "ALL",
"source": "WEB",
"client": "WEB",
"sortColumns": "CHANGE_DATE",
"sortTypes": "-1",
"pageNumber": "1",
"pageSize": "1000",
"filter": f'(ANALYST_CODE="{analyst_id}")',
}
r = requests.get(url, params=params, headers=headers)
data_json = r.json()
temp_df = pd.DataFrame(data_json["result"]["data"])
temp_df.reset_index(inplace=True)
temp_df["index"] = list(range(1, len(temp_df) + 1))
temp_df.columns = [
"序号",
"最新评级日期",
"-",
"-",
"-",
"-",
"股票代码",
"-",
"股票名称",
"调入日期",
"当前评级名称",
"成交价格(前复权)",
"最新价格",
"阶段涨跌幅",
]
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
elif indicator == "历史跟踪成分股":
params = {
"reportName": "RPT_RESEARCHER_HISTORYSTOCK",
"columns": "ALL",
"source": "WEB",
"client": "WEB",
"sortColumns": "CHANGE_DATE",
"sortTypes": "-1",
"pageNumber": "1",
"pageSize": "1000",
"filter": f'(ANALYST_CODE="{analyst_id}")',
}
r = requests.get(url, params=params, headers=headers)
data_json = r.json()
temp_df = pd.DataFrame(data_json["result"]["data"])
temp_df.reset_index(inplace=True)
temp_df["index"] = list(range(1, len(temp_df) + 1))
temp_df.columns = [
"序号",
"-",
"-",
"-",
"股票代码",
"-",
"股票名称",
"调入日期",
"调出日期",
"调入时评级名称",
"调出原因",
"累计涨跌幅",
]
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")
return temp_df
elif indicator == "历史指数":
params = {
"reportName": "RPT_RESEARCHER_DETAILS",
"columns": "ALL",
"sortColumns": "TRADE_DATE",
"sortTypes": "-1",
"filter": f'(ANALYST_CODE="{analyst_id}")',
"source": "WEB",
"client": "WEB",
}
r = requests.get(url, params=params, headers=headers)
data_json = r.json()
temp_df = pd.DataFrame(data_json["result"]["data"])
temp_df = temp_df[
[
"TRADE_DATE",
"INDEX_HVALUE",
]
]
temp_df.columns = ["date", "value"]
temp_df["date"] = pd.to_datetime(temp_df["date"], errors="coerce").dt.date
temp_df["value"] = pd.to_numeric(temp_df["value"], errors="coerce")
temp_df.sort_values(["date"], inplace=True, ignore_index=True)
return temp_df
if __name__ == "__main__":
stock_analyst_rank_em_df = stock_analyst_rank_em(year="2024")
print(stock_analyst_rank_em_df)
stock_analyst_detail_em_df = stock_analyst_detail_em(
analyst_id="11000200926", indicator="最新跟踪成分股"
)
print(stock_analyst_detail_em_df)
stock_analyst_detail_em_df = stock_analyst_detail_em(
analyst_id="11000200926", indicator="历史跟踪成分股"
)
print(stock_analyst_detail_em_df)
stock_analyst_detail_em_df = stock_analyst_detail_em(
analyst_id="11000200926", indicator="历史指数"
)
print(stock_analyst_detail_em_df)
@@ -0,0 +1,328 @@
#!/usr/bin/env python
# -*- coding:utf-8 -*-
"""
Date: 2025/3/27 14:20
Desc: 同花顺-板块-概念板块
https://q.10jqka.com.cn/thshy/
"""
from typing import Dict
from datetime import datetime
from functools import lru_cache
from io import StringIO
import pandas as pd
import requests
from bs4 import BeautifulSoup
import py_mini_racer
from akshare.datasets import get_ths_js
from akshare.utils import demjson
from akshare.utils.tqdm import get_tqdm
def _get_file_content_ths(file: str = "ths.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
@lru_cache()
def _get_stock_board_concept_name_ths() -> dict:
"""
获取同花顺概念板块代码和名称字典
:return: 获取同花顺概念板块代码和名称字典
:rtype: dict
"""
js_code = py_mini_racer.MiniRacer()
js_content = _get_file_content_ths("ths.js")
js_code.eval(js_content)
v_code = js_code.call("v")
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "
"Chrome/89.0.4389.90 Safari/537.36",
"Cookie": f"v={v_code}",
}
url = "https://q.10jqka.com.cn/gn/detail/code/307822/"
r = requests.get(url, headers=headers)
soup = BeautifulSoup(r.text, features="lxml")
code_list = [
item["href"].split("/")[-2]
for item in soup.find(name="div", attrs={"class": "cate_inner"}).find_all("a")
]
name_list = [
item.text
for item in soup.find(name="div", attrs={"class": "cate_inner"}).find_all("a")
]
name_code_map = dict(zip(name_list, code_list))
temp_dict = __stock_board_concept_summary_ths()
name_code_map.update(temp_dict)
return name_code_map
def stock_board_concept_name_ths() -> pd.DataFrame:
"""
同花顺-板块-概念板块-概念
http://q.10jqka.com.cn/thshy/
:return: 所有概念板块的名称和链接
:rtype: pandas.DataFrame
"""
code_name_ths_map = _get_stock_board_concept_name_ths()
temp_df = pd.DataFrame.from_dict(code_name_ths_map, orient="index")
temp_df.reset_index(inplace=True)
temp_df.columns = ["name", "code"]
temp_df = temp_df[
[
"name",
"code",
]
]
return temp_df
def stock_board_concept_info_ths(symbol: str = "阿里巴巴概念") -> pd.DataFrame:
"""
同花顺-板块-概念板块-板块简介
http://q.10jqka.com.cn/gn/detail/code/301558/
:param symbol: 板块简介
:type symbol: str
:return: 板块简介
:rtype: pandas.DataFrame
"""
stock_board_ths_map_df = stock_board_concept_name_ths()
symbol_code = stock_board_ths_map_df[stock_board_ths_map_df["name"] == symbol][
"code"
].values[0]
url = f"http://q.10jqka.com.cn/gn/detail/code/{symbol_code}/"
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "
"Chrome/89.0.4389.90 Safari/537.36",
}
r = requests.get(url, headers=headers)
soup = BeautifulSoup(r.text, features="lxml")
name_list = [
item.text.strip()
for item in soup.find(name="div", attrs={"class": "board-infos"}).find_all("dt")
]
value_list = [
item.text.strip().replace("\n", "/")
for item in soup.find(name="div", attrs={"class": "board-infos"}).find_all("dd")
]
temp_df = pd.DataFrame([name_list, value_list]).T
temp_df.columns = ["项目", ""]
return temp_df
def stock_board_concept_index_ths(
symbol: str = "阿里巴巴概念",
start_date: str = "20200101",
end_date: str = "20250228",
) -> pd.DataFrame:
"""
同花顺-板块-概念板块-指数数据
https://q.10jqka.com.cn/gn/detail/code/301558/
:param start_date: 开始时间
:type start_date: str
:param end_date: 结束时间
:type end_date: str
:param symbol: 指数数据
:type symbol: str
:return: 指数数据
:rtype: pandas.DataFrame
"""
js_code = py_mini_racer.MiniRacer()
js_content = _get_file_content_ths("ths.js")
js_code.eval(js_content)
v_code = js_code.call("v")
code_map = _get_stock_board_concept_name_ths()
symbol_code = code_map[symbol]
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "
"Chrome/89.0.4389.90 Safari/537.36",
}
url = f"https://q.10jqka.com.cn/gn/detail/code/{symbol_code}"
r = requests.get(url=url, headers=headers)
soup = BeautifulSoup(r.text, features="lxml")
inner_code = soup.find(name="input", attrs={"id": "clid"})["value"]
big_df = pd.DataFrame()
current_year = datetime.now().year
begin_year = int(start_date[:4])
tqdm = get_tqdm()
for year in tqdm(range(begin_year, current_year + 1), leave=False):
url = f"https://d.10jqka.com.cn/v4/line/bk_{inner_code}/01/{year}.js"
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "
"Chrome/89.0.4389.90 Safari/537.36",
"Referer": "http://q.10jqka.com.cn",
"Host": "d.10jqka.com.cn",
"Cookie": f"v={v_code}",
}
r = requests.get(url, headers=headers)
data_text = r.text
try:
demjson.decode(data_text[data_text.find("{") : -1])
except: # noqa: E722
continue
temp_df = demjson.decode(data_text[data_text.find("{") : -1])
temp_df = pd.DataFrame(temp_df["data"].split(";"))
temp_df = temp_df.iloc[:, 0].str.split(",", expand=True)
big_df = pd.concat(objs=[big_df, temp_df], ignore_index=True)
if len(big_df.columns) == 11:
big_df.columns = [
"日期",
"开盘价",
"最高价",
"最低价",
"收盘价",
"成交量",
"成交额",
"_",
"_",
"_",
"_",
]
else:
big_df.columns = [
"日期",
"开盘价",
"最高价",
"最低价",
"收盘价",
"成交量",
"成交额",
"_",
"_",
"_",
"_",
"_",
]
big_df = big_df[
[
"日期",
"开盘价",
"最高价",
"最低价",
"收盘价",
"成交量",
"成交额",
]
]
big_df["日期"] = pd.to_datetime(big_df["日期"], errors="coerce").dt.date
big_df.index = pd.to_datetime(big_df["日期"], errors="coerce")
big_df = big_df[start_date:end_date]
big_df.reset_index(drop=True, inplace=True)
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["成交量"], errors="coerce")
big_df["成交额"] = pd.to_numeric(big_df["成交额"], errors="coerce")
return big_df
@lru_cache()
def __stock_board_concept_summary_ths() -> Dict:
"""
同花顺-数据中心-概念板块-概念时间表-辅助函数
https://q.10jqka.com.cn/gn/
:return: 概念时间表
:rtype: dict
"""
js_code = py_mini_racer.MiniRacer()
js_content = _get_file_content_ths("ths.js")
js_code.eval(js_content)
v_code = js_code.call("v")
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "
"Chrome/89.0.4389.90 Safari/537.36",
"Cookie": f"v={v_code}",
}
url = "http://q.10jqka.com.cn/gn/index/field/addtime/order/desc/page/1/ajax/1/"
r = requests.get(url, headers=headers)
soup = BeautifulSoup(r.text, features="lxml")
page_num = soup.find(name="span", attrs={"class": "page_info"}).text.split("/")[1]
big_dict = dict()
tqdm = get_tqdm()
for page in tqdm(range(1, int(page_num) + 1), leave=False):
url = f"http://q.10jqka.com.cn/gn/index/field/addtime/order/desc/page/{page}/ajax/1/"
r = requests.get(url, headers=headers)
try:
soup = BeautifulSoup(r.text, features="lxml")
temp_dict = {
item.get_text(): item["href"].rsplit("/")[-2]
for item in soup.find_all(name="a")
if "detail" in item["href"]
}
big_dict.update(temp_dict)
except ValueError:
break
return big_dict
def stock_board_concept_summary_ths() -> pd.DataFrame:
"""
同花顺-数据中心-概念板块-概念时间表
https://q.10jqka.com.cn/gn/
:return: 概念时间表
:rtype: pandas.DataFrame
"""
js_code = py_mini_racer.MiniRacer()
js_content = _get_file_content_ths("ths.js")
js_code.eval(js_content)
v_code = js_code.call("v")
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "
"Chrome/89.0.4389.90 Safari/537.36",
"Cookie": f"v={v_code}",
}
url = "http://q.10jqka.com.cn/gn/index/field/addtime/order/desc/page/1/ajax/1/"
r = requests.get(url, headers=headers)
soup = BeautifulSoup(r.text, features="lxml")
page_num = soup.find(name="span", attrs={"class": "page_info"}).text.split("/")[1]
big_df = pd.DataFrame()
tqdm = get_tqdm()
for page in tqdm(range(1, int(page_num) + 1), leave=False):
url = f"http://q.10jqka.com.cn/gn/index/field/addtime/order/desc/page/{page}/ajax/1/"
r = requests.get(url, headers=headers)
try:
temp_df = pd.read_html(StringIO(r.text))[0]
big_df = pd.concat(objs=[big_df, temp_df], ignore_index=True)
except ValueError:
break
big_df["日期"] = pd.to_datetime(big_df["日期"], errors="coerce").dt.date
big_df["成分股数量"] = pd.to_numeric(big_df["成分股数量"], errors="coerce")
return big_df
if __name__ == "__main__":
stock_board_concept_name_ths_df = stock_board_concept_name_ths()
print(stock_board_concept_name_ths_df)
stock_board_concept_info_ths_df = stock_board_concept_info_ths(
symbol="阿里巴巴概念"
)
print(stock_board_concept_info_ths_df)
stock_board_concept_index_ths_df = stock_board_concept_index_ths(
symbol="DeepSeek概念", start_date="20200101", end_date="20250321"
)
print(stock_board_concept_index_ths_df)
stock_board_concept_summary_ths_df = stock_board_concept_summary_ths()
print(stock_board_concept_summary_ths_df)
for stock in stock_board_concept_name_ths_df["name"]:
print(stock)
stock_board_industry_index_ths_df = stock_board_concept_index_ths(symbol=stock)
print(stock_board_industry_index_ths_df)
@@ -0,0 +1,409 @@
#!/usr/bin/env python
# -*- coding:utf-8 -*-
"""
Date: 2025/2/28 13:20
Desc: 同花顺-板块-同花顺行业
https://q.10jqka.com.cn/thshy/
"""
from datetime import datetime
from functools import lru_cache
from io import StringIO
import pandas as pd
import requests
from bs4 import BeautifulSoup
import py_mini_racer
from akshare.datasets import get_ths_js
from akshare.utils import demjson
from akshare.utils.tqdm import get_tqdm
def _get_file_content_ths(file: str = "ths.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
@lru_cache()
def _get_stock_board_industry_name_ths() -> dict:
"""
获取同花顺行业代码和名称字典
:return: 获取同花顺行业代码和名称字典
:rtype: dict
"""
js_code = py_mini_racer.MiniRacer()
js_content = _get_file_content_ths("ths.js")
js_code.eval(js_content)
v_code = js_code.call("v")
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "
"Chrome/89.0.4389.90 Safari/537.36",
"Cookie": f"v={v_code}",
}
url = "https://q.10jqka.com.cn/thshy/detail/code/881272/"
r = requests.get(url, headers=headers)
soup = BeautifulSoup(r.text, features="lxml")
code_list = [
item["href"].split("/")[-2]
for item in soup.find(name="div", attrs={"class": "cate_inner"}).find_all("a")
]
name_list = [
item.text
for item in soup.find(name="div", attrs={"class": "cate_inner"}).find_all("a")
]
name_code_map = dict(zip(name_list, code_list))
return name_code_map
def stock_board_industry_name_ths() -> pd.DataFrame:
"""
同花顺-板块-行业板块-行业
http://q.10jqka.com.cn/thshy/
:return: 所有行业板块的名称和链接
:rtype: pandas.DataFrame
"""
code_name_ths_map = _get_stock_board_industry_name_ths()
temp_df = pd.DataFrame.from_dict(code_name_ths_map, orient="index")
temp_df.reset_index(inplace=True)
temp_df.columns = ["name", "code"]
temp_df = temp_df[
[
"name",
"code",
]
]
return temp_df
def stock_board_industry_info_ths(symbol: str = "半导体") -> pd.DataFrame:
"""
同花顺-板块-行业板块-板块简介
http://q.10jqka.com.cn/gn/detail/code/301558/
:param symbol: 板块简介
:type symbol: str
:return: 板块简介
:rtype: pandas.DataFrame
"""
stock_board_ths_map_df = stock_board_industry_name_ths()
symbol_code = stock_board_ths_map_df[stock_board_ths_map_df["name"] == symbol][
"code"
].values[0]
url = f"http://q.10jqka.com.cn/thshy/detail/code/{symbol_code}/"
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "
"Chrome/89.0.4389.90 Safari/537.36",
}
r = requests.get(url, headers=headers)
soup = BeautifulSoup(r.text, features="lxml")
name_list = [
item.text.strip()
for item in soup.find(name="div", attrs={"class": "board-infos"}).find_all("dt")
]
value_list = [
item.text.strip().replace("\n", "/")
for item in soup.find(name="div", attrs={"class": "board-infos"}).find_all("dd")
]
temp_df = pd.DataFrame([name_list, value_list]).T
temp_df.columns = ["项目", ""]
return temp_df
def stock_board_industry_index_ths(
symbol: str = "元件",
start_date: str = "20200101",
end_date: str = "20240108",
) -> pd.DataFrame:
"""
同花顺-板块-行业板块-指数数据
https://q.10jqka.com.cn/thshy/detail/code/881270/
:param start_date: 开始时间
:type start_date: str
:param end_date: 结束时间
:type end_date: str
:param symbol: 指数数据
:type symbol: str
:return: 指数数据
:rtype: pandas.DataFrame
"""
code_map = _get_stock_board_industry_name_ths()
symbol_code = code_map[symbol]
big_df = pd.DataFrame()
current_year = datetime.now().year
begin_year = int(start_date[:4])
tqdm = get_tqdm()
js_code = py_mini_racer.MiniRacer()
js_content = _get_file_content_ths("ths.js")
js_code.eval(js_content)
v_code = js_code.call("v")
for year in tqdm(range(begin_year, current_year + 1), leave=False):
url = f"https://d.10jqka.com.cn/v4/line/bk_{symbol_code}/01/{year}.js"
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "
"Chrome/89.0.4389.90 Safari/537.36",
"Referer": "http://q.10jqka.com.cn",
"Host": "d.10jqka.com.cn",
"Cookie": f"v={v_code}",
}
r = requests.get(url, headers=headers)
data_text = r.text
try:
demjson.decode(data_text[data_text.find("{") : -1])
except: # noqa: E722
continue
temp_df = demjson.decode(data_text[data_text.find("{") : -1])
temp_df = pd.DataFrame(temp_df["data"].split(";"))
temp_df = temp_df.iloc[:, 0].str.split(",", expand=True)
big_df = pd.concat(objs=[big_df, temp_df], ignore_index=True)
if len(big_df.columns) == 11:
big_df.columns = [
"日期",
"开盘价",
"最高价",
"最低价",
"收盘价",
"成交量",
"成交额",
"_",
"_",
"_",
"_",
]
else:
big_df.columns = [
"日期",
"开盘价",
"最高价",
"最低价",
"收盘价",
"成交量",
"成交额",
"_",
"_",
"_",
"_",
"_",
]
big_df = big_df[
[
"日期",
"开盘价",
"最高价",
"最低价",
"收盘价",
"成交量",
"成交额",
]
]
big_df["日期"] = pd.to_datetime(big_df["日期"], errors="coerce").dt.date
big_df.index = pd.to_datetime(big_df["日期"], errors="coerce")
big_df = big_df[start_date:end_date]
big_df.reset_index(drop=True, inplace=True)
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["成交量"], errors="coerce")
big_df["成交额"] = pd.to_numeric(big_df["成交额"], errors="coerce")
return big_df
def stock_xgsr_ths() -> pd.DataFrame:
"""
同花顺-数据中心-新股数据-新股上市首日
https://data.10jqka.com.cn/ipo/xgsr/
:return: 新股上市首日
:rtype: pandas.DataFrame
"""
js_code = py_mini_racer.MiniRacer()
js_content = _get_file_content_ths("ths.js")
js_code.eval(js_content)
v_code = js_code.call("v")
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "
"Chrome/89.0.4389.90 Safari/537.36",
"Cookie": f"v={v_code}",
"hexin-v": v_code,
}
url = "https://data.10jqka.com.cn/ipo/xgsr/field/SSRQ/order/desc/page/1/ajax/1/free/1/"
r = requests.get(url, headers=headers)
soup = BeautifulSoup(r.text, features="lxml")
page_num = soup.find(name="span", attrs={"class": "page_info"}).text.split("/")[1]
big_df = pd.DataFrame()
tqdm = get_tqdm()
for page in tqdm(range(1, int(page_num) + 1), leave=False):
url = f"https://data.10jqka.com.cn/ipo/xgsr/field/SSRQ/order/desc/page/{page}/ajax/1/free/1/"
v_code = js_code.call("v")
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "
"Chrome/89.0.4389.90 Safari/537.36",
"Cookie": f"v={v_code}",
"hexin-v": v_code,
}
r = requests.get(url, headers=headers)
temp_df = pd.read_html(StringIO(r.text))[0]
big_df = pd.concat(objs=[big_df, temp_df], ignore_index=True)
big_df.rename(columns={"发行价(元)": "发行价"}, inplace=True)
big_df["序号"] = pd.to_numeric(big_df["序号"], errors="coerce")
big_df["股票代码"] = big_df["股票代码"].astype(str).str.zfill(6)
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["首日最高价"], errors="coerce")
big_df["首日最低价"] = pd.to_numeric(big_df["首日最低价"], errors="coerce")
big_df["首日涨跌幅"] = (
pd.to_numeric(big_df["首日涨跌幅"].str.strip("%"), errors="coerce") / 100
)
big_df["上市日期"] = pd.to_datetime(big_df["上市日期"], errors="coerce").dt.date
return big_df
def stock_ipo_benefit_ths() -> pd.DataFrame:
"""
同花顺-数据中心-新股数据-IPO受益股
https://data.10jqka.com.cn/ipo/syg/
:return: IPO受益股
:rtype: pandas.DataFrame
"""
js_code = py_mini_racer.MiniRacer()
js_content = _get_file_content_ths("ths.js")
js_code.eval(js_content)
v_code = js_code.call("v")
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "
"Chrome/89.0.4389.90 Safari/537.36",
"Cookie": f"v={v_code}",
"hexin-v": v_code,
}
url = "https://data.10jqka.com.cn/ipo/syg/field/invest/order/desc/page/1/ajax/1/free/1/"
r = requests.get(url, headers=headers)
soup = BeautifulSoup(r.text, features="lxml")
page_num = soup.find(name="span", attrs={"class": "page_info"}).text.split("/")[1]
big_df = pd.DataFrame()
tqdm = get_tqdm()
for page in tqdm(range(1, int(page_num) + 1), leave=False):
url = f"https://data.10jqka.com.cn/ipo/syg/field/invest/order/desc/page/{page}/ajax/1/free/1/"
v_code = js_code.call("v")
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "
"Chrome/89.0.4389.90 Safari/537.36",
"Cookie": f"v={v_code}",
"hexin-v": v_code,
}
r = requests.get(url, headers=headers)
temp_df = pd.read_html(StringIO(r.text))[0]
big_df = pd.concat(objs=[big_df, temp_df], ignore_index=True)
big_df.columns = [
"序号",
"股票代码",
"股票简称",
"收盘价",
"涨跌幅",
"市值",
"参股家数",
"投资总额",
"投资占市值比",
"参股对象",
]
big_df["股票代码"] = big_df["股票代码"].astype(str).str.zfill(6)
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["投资占市值比"], errors="coerce")
return big_df
def stock_board_industry_summary_ths() -> pd.DataFrame:
"""
同花顺-数据中心-行业板块-同花顺行业一览表
https://q.10jqka.com.cn/thshy/
:return: 同花顺行业一览表
:rtype: pandas.DataFrame
"""
js_code = py_mini_racer.MiniRacer()
js_content = _get_file_content_ths("ths.js")
js_code.eval(js_content)
v_code = js_code.call("v")
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "
"Chrome/89.0.4389.90 Safari/537.36",
"Cookie": f"v={v_code}",
}
url = "http://q.10jqka.com.cn/thshy/index/field/199112/order/desc/page/1/ajax/1/"
r = requests.get(url, headers=headers)
soup = BeautifulSoup(r.text, features="lxml")
page_num = soup.find(name="span", attrs={"class": "page_info"}).text.split("/")[1]
big_df = pd.DataFrame()
tqdm = get_tqdm()
for page in tqdm(range(1, int(page_num) + 1), leave=False):
url = f"http://q.10jqka.com.cn/thshy/index/field/199112/order/desc/page/{page}/ajax/1/"
r = requests.get(url, headers=headers)
temp_df = pd.read_html(StringIO(r.text))[0]
big_df = pd.concat(objs=[big_df, temp_df], ignore_index=True)
big_df.columns = [
"序号",
"板块",
"涨跌幅",
"总成交量",
"总成交额",
"净流入",
"上涨家数",
"下跌家数",
"均价",
"领涨股",
"领涨股-最新价",
"领涨股-涨跌幅",
]
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["上涨家数"], 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["领涨股-涨跌幅"], errors="coerce")
return big_df
if __name__ == "__main__":
stock_board_industry_name_ths_df = stock_board_industry_name_ths()
print(stock_board_industry_name_ths_df)
stock_board_industry_info_ths_df = stock_board_industry_info_ths(symbol="橡胶制品")
print(stock_board_industry_info_ths_df)
stock_board_industry_index_ths_df = stock_board_industry_index_ths(
symbol="消费电子", start_date="20240101", end_date="20240724"
)
print(stock_board_industry_index_ths_df)
stock_board_industry_summary_ths_df = stock_board_industry_summary_ths()
print(stock_board_industry_summary_ths_df)
for stock in stock_board_industry_name_ths_df["name"]:
print(stock)
stock_board_industry_index_ths_df = stock_board_industry_index_ths(symbol=stock)
print(stock_board_industry_index_ths_df)
stock_xgsr_ths_df = stock_xgsr_ths()
print(stock_xgsr_ths_df)
stock_ipo_benefit_ths_df = stock_ipo_benefit_ths()
print(stock_ipo_benefit_ths_df)
@@ -0,0 +1,62 @@
#!/usr/bin/env python
# -*- coding:utf-8 -*-
"""
Date: 2026/5/27 17:05
Desc: 乐估乐股-底部研究-巴菲特指标
https://legulegu.com/stockdata/marketcap-gdp
"""
import pandas as pd
import requests
from akshare.stock_feature.stock_a_indicator import get_token_lg, get_cookie_csrf
def stock_buffett_index_lg() -> pd.DataFrame:
"""
乐估乐股-底部研究-巴菲特指标
https://legulegu.com/stockdata/marketcap-gdp
:return: 巴菲特指标
:rtype: pandas.DataFrame
"""
token = get_token_lg()
url = "https://legulegu.com/api/stockdata/marketcap-gdp/get-marketcap-gdp"
params = {"token": token}
r = requests.get(
url,
params=params,
**get_cookie_csrf(url="https://legulegu.com/stockdata/marketcap-gdp"),
)
data_json = r.json()
temp_df = pd.DataFrame(data_json["data"])
rename_map = {
"marketCap": "总市值",
"gdp": "GDP",
"close": "收盘价",
"date": "日期",
"quantileInAllHistory": "总历史分位数",
"quantileInRecent10Years": "近十年分位数",
}
existing_rename = {k: v for k, v in rename_map.items() if k in temp_df.columns}
temp_df.rename(columns=existing_rename, inplace=True)
base_cols = ["日期", "收盘价", "总市值", "GDP"]
optional_cols = ["近十年分位数", "总历史分位数"]
available_cols = base_cols + [c for c in optional_cols if c in temp_df.columns]
temp_df = temp_df[available_cols]
temp_df["日期"] = pd.to_datetime(temp_df["日期"], utc=True).dt.date
temp_df["收盘价"] = pd.to_numeric(temp_df["收盘价"], errors="coerce")
temp_df["总市值"] = pd.to_numeric(temp_df["总市值"], errors="coerce")
temp_df["GDP"] = pd.to_numeric(temp_df["GDP"], errors="coerce")
for col in optional_cols:
if col in temp_df.columns:
temp_df[col] = pd.to_numeric(temp_df[col], errors="coerce")
return temp_df
if __name__ == "__main__":
stock_buffett_index_lg_df = stock_buffett_index_lg()
print(stock_buffett_index_lg_df)
@@ -0,0 +1,87 @@
#!/usr/bin/env python
# -*- coding:utf-8 -*-
"""
Date: 2022/7/13 16:16
Desc: 新浪财经-股票-行业分类
http://vip.stock.finance.sina.com.cn/mkt/
"""
import math
import pandas as pd
import requests
from bs4 import BeautifulSoup
from tqdm import tqdm
def stock_classify_board() -> dict:
"""
http://vip.stock.finance.sina.com.cn/mkt/
:return: 股票分类字典
:rtype: dict
"""
url = "http://vip.stock.finance.sina.com.cn/quotes_service/api/json_v2.php/Market_Center.getHQNodes"
r = requests.get(url)
data_json = r.json()
big_dict = {}
class_name_list = [
BeautifulSoup(item[0], "lxml").find("font").text
if "font" in item[0]
else item[0]
for item in data_json[1][0][1]
] # 沪深股市
for num, class_name in enumerate(class_name_list):
temp_df = pd.DataFrame([item for item in data_json[1][0][1][num][1:][0]])
if temp_df.shape[1] == 5:
temp_df.columns = ["name", "_", "code", "_", "_"]
temp_df = temp_df[["name", "code"]]
if temp_df.shape[1] == 4:
temp_df.columns = ["name", "_", "code", "_"]
temp_df = temp_df[["name", "code"]]
if temp_df.shape[1] == 3:
temp_df.columns = ["name", "_", "code"]
temp_df = temp_df[["name", "code"]]
big_dict.update({class_name: temp_df})
return big_dict
def stock_classify_sina(symbol: str = "热门概念") -> pd.DataFrame:
"""
按 symbol 分类后的股票
http://vip.stock.finance.sina.com.cn/mkt/
:param symbol: choice of {'申万行业', '申万二级', '热门概念', '地域板块'}
:type symbol: str
:return: 分类后的股票
:rtype: pandas.DataFrame
"""
stock_classify_board_dict = stock_classify_board()
data_df = pd.DataFrame()
for num in tqdm(range(len(stock_classify_board_dict[symbol]["code"])), leave=False):
url = "http://vip.stock.finance.sina.com.cn/quotes_service/api/json_v2.php/Market_Center.getHQNodeStockCount"
params = {"node": stock_classify_board_dict[symbol]["code"][num]}
r = requests.get(url, params=params)
page_num = math.ceil(int(r.json()) / 80)
url = "http://vip.stock.finance.sina.com.cn/quotes_service/api/json_v2.php/Market_Center.getHQNodeData"
big_df = pd.DataFrame()
for page in range(1, page_num + 1):
params = {
"page": page,
"num": "80",
"sort": "symbol",
"asc": "1",
"node": stock_classify_board_dict[symbol]["code"][num],
"symbol": "",
"_s_r_a": "init",
}
r = requests.get(url, params=params)
data_json = r.json()
temp_df = pd.DataFrame(data_json)
big_df = pd.concat([big_df, temp_df], ignore_index=True)
big_df["class"] = stock_classify_board_dict[symbol]["name"][num]
data_df = pd.concat([data_df, big_df], ignore_index=True)
return data_df
if __name__ == "__main__":
stock_classify_sina_df = stock_classify_sina(symbol="热门概念")
print(stock_classify_sina_df)
@@ -0,0 +1,313 @@
#!/usr/bin/env python
# -*- coding:utf-8 -*-
"""
Date: 2024/4/4 18:20
Desc: 东方财富网-数据中心-特色数据-千股千评
https://data.eastmoney.com/stockcomment/
"""
import json
import re
import time
import pandas as pd
import requests
from akshare.utils.tqdm import get_tqdm
def stock_comment_em() -> pd.DataFrame:
"""
东方财富网-数据中心-特色数据-千股千评
https://data.eastmoney.com/stockcomment/
:return: 千股千评数据
:rtype: pandas.DataFrame
"""
url = "https://datacenter-web.eastmoney.com/api/data/v1/get"
params = {
"sortColumns": "SECURITY_CODE",
"sortTypes": "1",
"pageSize": "500",
"pageNumber": "1",
"reportName": "RPT_DMSK_TS_STOCKNEW",
"quoteColumns": "f2~01~SECURITY_CODE~CLOSE_PRICE,f8~01~SECURITY_CODE~TURNOVERRATE,"
"f3~01~SECURITY_CODE~CHANGE_RATE,f9~01~SECURITY_CODE~PE_DYNAMIC",
"columns": "ALL",
"filter": "",
"token": "894050c76af8597a853f5b408b759f5d",
}
r = requests.get(url, params=params)
data_json = r.json()
total_page = data_json["result"]["pages"]
big_df = pd.DataFrame()
tqdm = get_tqdm()
for page in tqdm(range(1, total_page + 1), leave=False):
params.update({"pageNumber": page})
r = requests.get(url, params=params)
data_json = r.json()
temp_df = pd.DataFrame(data_json["result"]["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 = big_df[
[
"序号",
"代码",
"名称",
"最新价",
"涨跌幅",
"换手率",
"市盈率",
"主力成本",
"机构参与度",
"综合得分",
"上升",
"目前排名",
"关注指数",
"交易日",
]
]
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["主力成本"], 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["目前排名"], errors="coerce")
big_df["关注指数"] = pd.to_numeric(big_df["关注指数"], errors="coerce")
big_df["交易日"] = pd.to_datetime(big_df["交易日"], errors="coerce").dt.date
return big_df
def stock_comment_detail_zlkp_jgcyd_em(symbol: str = "600000") -> pd.DataFrame:
"""
东方财富网-数据中心-特色数据-千股千评-主力控盘-机构参与度
https://data.eastmoney.com/stockcomment/stock/600000.html
:param symbol: 股票代码
:type symbol: str
:return: 主力控盘-机构参与度
:rtype: pandas.DataFrame
"""
url = "https://datacenter-web.eastmoney.com/api/data/v1/get"
params = {
"reportName": "RPT_DMSK_TS_STOCKEVALUATE",
"filter": f'(SECURITY_CODE="{symbol}")',
"columns": "ALL",
"source": "WEB",
"client": "WEB",
"sortColumns": "TRADE_DATE",
"sortTypes": "-1",
}
r = requests.get(url, params=params)
data_json = r.json()
temp_df = pd.DataFrame(data_json["result"]["data"])
temp_df = temp_df[["TRADE_DATE", "ORG_PARTICIPATE"]]
temp_df.columns = ["交易日", "机构参与度"]
temp_df["交易日"] = pd.to_datetime(temp_df["交易日"], errors="coerce").dt.date
temp_df.sort_values(["交易日"], inplace=True)
temp_df.reset_index(inplace=True, drop=True)
temp_df["机构参与度"] = pd.to_numeric(temp_df["机构参与度"], errors="coerce") * 100
return temp_df
def stock_comment_detail_zhpj_lspf_em(symbol: str = "600000") -> pd.DataFrame:
"""
东方财富网-数据中心-特色数据-千股千评-综合评价-历史评分
https://data.eastmoney.com/stockcomment/stock/600000.html
:param symbol: 股票代码
:type symbol: str
:return: 综合评价-历史评分
:rtype: pandas.DataFrame
"""
url = "https://datacenter-web.eastmoney.com/api/data/v1/get"
params = {
"filter": f'(SECURITY_CODE="{symbol}")',
"columns": "ALL",
"source": "WEB",
"client": "WEB",
"reportName": "RPT_STOCK_HISTORYMARK",
"sortColumns": "DIAGNOSE_DATE",
"sortTypes": "1",
}
r = requests.get(url=url, params=params)
data_json = r.json()
temp_df = pd.DataFrame(data_json["result"]["data"])
temp_df.rename(
columns={
"TOTAL_SCORE": "评分",
"DIAGNOSE_DATE": "交易日",
},
inplace=True,
)
temp_df = temp_df[["交易日", "评分"]]
temp_df["交易日"] = pd.to_datetime(temp_df["交易日"], errors="coerce").dt.date
temp_df.sort_values(by=["交易日"], inplace=True)
temp_df.reset_index(inplace=True, drop=True)
temp_df["评分"] = pd.to_numeric(temp_df["评分"], errors="coerce")
return temp_df
def stock_comment_detail_scrd_focus_em(symbol: str = "600000") -> pd.DataFrame:
"""
东方财富网-数据中心-特色数据-千股千评-市场热度-用户关注指数
https://data.eastmoney.com/stockcomment/stock/600000.html
:param symbol: 股票代码
:type symbol: str
:return: 市场热度-用户关注指数
:rtype: pandas.DataFrame
"""
url = "https://datacenter-web.eastmoney.com/api/data/v1/get"
params = {
"filter": f'(SECURITY_CODE="{symbol}")',
"columns": "ALL",
"source": "WEB",
"client": "WEB",
"reportName": "RPT_STOCK_MARKETFOCUS",
"sortColumns": "TRADE_DATE",
"sortTypes": "-1",
"pageSize": "30",
}
r = requests.get(url=url, params=params)
data_json = r.json()
temp_df = pd.DataFrame(data_json["result"]["data"])
temp_df.rename(
columns={
"MARKET_FOCUS": "用户关注指数",
"TRADE_DATE": "交易日",
},
inplace=True,
)
temp_df = temp_df[["交易日", "用户关注指数"]]
temp_df["交易日"] = pd.to_datetime(temp_df["交易日"], errors="coerce").dt.date
temp_df.sort_values(by=["交易日"], inplace=True)
temp_df.reset_index(inplace=True, drop=True)
temp_df["用户关注指数"] = pd.to_numeric(temp_df["用户关注指数"], errors="coerce")
return temp_df
def stock_comment_detail_scrd_desire_em(
symbol: str = "600000",
) -> pd.DataFrame:
"""
东方财富网-数据中心-特色数据-千股千评-市场热度-市场参与意愿
https://data.eastmoney.com/stockcomment/stock/600000.html
:param symbol: 股票代码
:type symbol: str
:return: 市场热度-市场参与意愿
:rtype: pandas.DataFrame
"""
url = "https://datacenter-web.eastmoney.com/api/data/v1/get"
params = {
"callback": f"jQuery11230899775623921407_{int(time.time() * 1000)}",
"filter": f'(SECURITY_CODE="{symbol}")',
"columns": "ALL",
"source": "WEB",
"client": "WEB",
"reportName": "RPT_STOCK_PARTICIPATION",
"sortColumns": "TRADE_DATE",
"sortTypes": "-1",
"pageSize": "30",
"_": int(time.time() * 1000),
}
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "
"Chrome/91.0.4472.124 Safari/537.36",
"Referer": "https://data.eastmoney.com/",
"Accept": "*/*",
"Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8",
}
r = requests.get(url, params=params, headers=headers)
jsonp_data = r.text
json_str = re.search(r"\((.*)\)", jsonp_data).group(1)
data_json = json.loads(json_str)
data_list = data_json["result"]["data"]
temp_df = pd.DataFrame(data_list)
temp_df["TRADE_DATE"] = pd.to_datetime(
temp_df["TRADE_DATE"], errors="coerce"
).dt.date
column_mapping = {
"SECURITY_INNER_CODE": "内部代码",
"SECURITY_CODE": "股票代码",
"TRADE_DATE": "交易日期",
"PARTICIPATION_WISH": "参与意愿",
"PARTICIPATION_WISH_5DAYS": "5日平均参与意愿",
"PARTICIPATION_WISH_CHANGE": "参与意愿变化",
"PARTICIPATION_WISH_5DAYSCHANGE": "5日平均变化",
}
temp_df = temp_df.rename(columns=column_mapping)
column_order = [
"交易日期",
"股票代码",
"内部代码",
"参与意愿",
"5日平均参与意愿",
"参与意愿变化",
"5日平均变化",
]
temp_df = temp_df[column_order]
del temp_df["内部代码"]
temp_df.sort_values(by=["交易日期"], ignore_index=True, inplace=True)
return temp_df
if __name__ == "__main__":
stock_comment_em_df = stock_comment_em()
print(stock_comment_em_df)
stock_comment_detail_zlkp_jgcyd_em_df = stock_comment_detail_zlkp_jgcyd_em(
symbol="600000"
)
print(stock_comment_detail_zlkp_jgcyd_em_df)
stock_comment_detail_zhpj_lspf_em_df = stock_comment_detail_zhpj_lspf_em(
symbol="600000"
)
print(stock_comment_detail_zhpj_lspf_em_df)
stock_comment_detail_scrd_focus_em_df = stock_comment_detail_scrd_focus_em(
symbol="600000"
)
print(stock_comment_detail_scrd_focus_em_df)
stock_comment_detail_scrd_desire_em_df = stock_comment_detail_scrd_desire_em(
symbol="600000"
)
print(stock_comment_detail_scrd_desire_em_df)
@@ -0,0 +1,183 @@
#!/usr/bin/env python
# -*- coding:utf-8 -*-
"""
Date: 2024/7/16 22:00
Desc: 富途牛牛-主题投资-概念板块-成分股
https://www.futunn.com/quote/sparks-us
"""
import json
import pandas as pd
import requests
from bs4 import BeautifulSoup
def _stock_concept_cons_futu(symbol: str = "巴菲特持仓") -> pd.DataFrame:
"""
富途牛牛-主题投资-概念板块-成分股
https://www.futunn.com/quote/sparks-us
:param symbol: 板块名称; choice of {"巴菲特持仓", "佩洛西持仓"}
:type symbol: str
:return: 概念板块
:rtype: pandas.DataFrame
"""
symbol_map = {
"巴菲特持仓": "BK2999",
"佩洛西持仓": "BK20883",
}
url = f"https://www.futunn.com/stock/{symbol_map[symbol]}"
# 定义查询参数
params = {"global_content": json.dumps({"promote_id": 13766, "sub_promote_id": 24})}
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 "
"(KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36",
}
r = requests.get(url, params=params, headers=headers)
soup = BeautifulSoup(r.text, features="lxml")
temp_code_name = [
item.find_all("div", attrs={"class": "fix-left"})
for item in soup.find(name="div", attrs={"class": "content-main"}).find_all("a")
]
temp_value_list = [
item.find_all("div", attrs={"class": "middle"})
for item in soup.find(name="div", attrs={"class": "content-main"}).find_all("a")
]
code_name_list = [item[0].find_all("span") for item in temp_code_name]
quant_list = [item[0].find_all("span") for item in temp_value_list]
temp_df = pd.DataFrame(
[
[item[0]["title"] for item in code_name_list],
[item[1]["title"] for item in code_name_list],
[item[0]["title"] for item in quant_list],
[item[1]["title"] for item in quant_list],
[item[2]["title"] for item in quant_list],
[item[3]["title"] for item in quant_list],
[item[4]["title"] for item in quant_list],
[item[5]["title"] for item in quant_list],
[item[6]["title"] for item in quant_list],
[item[7]["title"] for item in quant_list],
[item[8]["title"] for item in quant_list],
[item[9]["title"] for item in quant_list],
[item[10]["title"] for item in quant_list],
[item[11]["title"] for item in quant_list],
[item[12]["title"] for item in quant_list],
[item[13]["title"] for item in quant_list],
[item[14]["title"] for item in quant_list],
]
).T
temp_df.columns = [
"代码",
"股票名称",
"最新价",
"涨跌额",
"涨跌幅",
"成交量",
"成交额",
"-",
"-",
"-",
"-",
"-",
"-",
"-",
"-",
"-",
"-",
]
temp_df = temp_df[
[
"代码",
"股票名称",
"最新价",
"涨跌额",
"涨跌幅",
"成交量",
"成交额",
]
]
return temp_df
def stock_concept_cons_futu(symbol: str = "特朗普概念股") -> pd.DataFrame:
"""
富途牛牛-主题投资-概念板块-成分股
https://www.futunn.com/quote/sparks-us
:param symbol: 板块名称; choice of {"巴菲特持仓", "佩洛西持仓", "特朗普概念股"}
:type symbol: str
:return: 概念板块
:rtype: pandas.DataFrame
"""
if symbol == "特朗普概念股":
url = "https://www.futunn.com/quote-api/quote-v2/get-plate-stock"
params = {
"marketType": "2",
"plateId": "10102960",
"page": "0",
"pageSize": "30",
}
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 "
"(KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36",
"Quote-Token": "7f74cd2a5e",
}
r = requests.get(url, params=params, headers=headers)
data_json = r.json()
total_page = data_json["data"]["pagination"]["pageCount"]
big_df = pd.DataFrame()
for page in range(0, total_page):
params.update(
{
"page": page,
}
)
if page == 1:
headers.update({"Quote-Token": "a3043d6fed"})
r = requests.get(url, params=params, headers=headers)
data_json = r.json()
temp_df = pd.DataFrame(data_json["data"]["list"])
big_df = pd.concat(objs=[big_df, temp_df], ignore_index=True)
big_df.rename(
columns={
"stockCode": "代码",
"name": "股票名称",
"price": "最新价",
"change": "涨跌额",
"changeRatio": "涨跌幅",
"tradeVolumn": "成交量",
"tradeTrunover": "成交额",
},
inplace=True,
)
big_df = big_df[
[
"代码",
"股票名称",
"最新价",
"涨跌额",
"涨跌幅",
"成交量",
"成交额",
]
]
big_df["最新价"] = pd.to_numeric(big_df["最新价"], errors="coerce")
big_df["涨跌额"] = pd.to_numeric(big_df["涨跌额"], errors="coerce")
return big_df
else:
temp_df = _stock_concept_cons_futu(symbol)
temp_df["最新价"] = pd.to_numeric(temp_df["最新价"], errors="coerce")
temp_df["涨跌额"] = pd.to_numeric(temp_df["涨跌额"], errors="coerce")
return temp_df
if __name__ == "__main__":
stock_concept_cons_futu_df = stock_concept_cons_futu(symbol="特朗普概念股")
print(stock_concept_cons_futu_df)
stock_concept_cons_futu_df = stock_concept_cons_futu(symbol="巴菲特持仓")
print(stock_concept_cons_futu_df)
stock_concept_cons_futu_df = stock_concept_cons_futu(symbol="佩洛西持仓")
print(stock_concept_cons_futu_df)
@@ -0,0 +1,47 @@
#!/usr/bin/env python
# -*- coding:utf-8 -*-
"""
Date: 2023/4/7 15:05
Desc: 乐咕乐股-大盘拥挤度
https://legulegu.com/stockdata/ashares-congestion
"""
import pandas as pd
import requests
from akshare.stock_feature.stock_a_indicator import get_token_lg, get_cookie_csrf
def stock_a_congestion_lg() -> pd.DataFrame:
"""
乐咕乐股-大盘拥挤度
https://legulegu.com/stockdata/ashares-congestion
:return: 大盘拥挤度
:rtype: pandas.DataFrame
"""
url = "https://legulegu.com/api/stockdata/ashares-congestion"
token = get_token_lg()
params = {"token": token}
r = requests.get(
url,
params=params,
**get_cookie_csrf(url="https://legulegu.com/stockdata/ashares-congestion"),
)
data_json = r.json()
temp_df = pd.DataFrame(data_json["items"])
temp_df["date"] = pd.to_datetime(temp_df["date"]).dt.date
temp_df = temp_df[
[
"date",
"close",
"congestion",
]
]
temp_df["close"] = pd.to_numeric(temp_df["close"], errors="coerce")
temp_df["congestion"] = pd.to_numeric(temp_df["congestion"], errors="coerce")
return temp_df
if __name__ == "__main__":
stock_a_congestion_lg_df = stock_a_congestion_lg()
print(stock_a_congestion_lg_df)
@@ -0,0 +1,313 @@
#!/usr/bin/env python
# -*- coding:utf-8 -*-
"""
Date: 2025/11/4 18:00
Desc: 东方财富网-概念板-行情中心-日K-筹码分布
https://quote.eastmoney.com/concept/sz000001.html
"""
from datetime import datetime
import pandas as pd
import py_mini_racer
import requests
def stock_cyq_em(symbol: str = "000001", adjust: str = "") -> pd.DataFrame:
"""
东方财富网-概念板-行情中心-日K-筹码分布
https://quote.eastmoney.com/concept/sz000001.html
:param symbol: 股票代码
:type symbol: str
:param adjust: choice of {"qfq": "前复权", "hfq": "后复权", "": "不复权"}
:type adjust: str
:return: 筹码分布
:rtype: pandas.DataFrame
"""
html_str = """
// @ts-nocheck
/**
* 计算分布及相关指标
* @param {number} index 当前选中的K线的索引
* @return {{x: Array.<number>, y: Array.<number>}}
*/
/**
this.range = 120;
*/
function CYQCalculator(index, klinedata) {
var maxprice = 0;
var minprice = 0;
var factor = 150;
var start = this.range ? Math.max(0, index - this.range + 1) : 0;
/**
* K图数据[time,open,close,high,low,volume,amount,amplitude,turnoverRate]
*/
var kdata = klinedata.slice(start, Math.max(1, index + 1));
if (kdata.length === 0) throw 'invaild index';
for (var i = 0; i < kdata.length; i++) {
var elements = kdata[i];
maxprice = !maxprice ? elements.high : Math.max(maxprice, elements.high);
minprice = !minprice ? elements.low : Math.min(minprice, elements.low);
}
// 精度不小于0.01 产品逻辑
var accuracy = Math.max(0.01, (maxprice - minprice) / (factor - 1));
/**
* 值域
* @type {Array.<number>}
*/
var yrange = [];
for (var i = 0; i < factor; i++) {
yrange.push((minprice + accuracy * i).toFixed(2) / 1);
}
/**
* 横轴数据
*/
var xdata = createNumberArray(factor);
for (var i = 0; i < kdata.length; i++) {
var eles = kdata[i];
var open = eles.open,
close = eles.close,
high = eles.high,
low = eles.low,
avg = (open + close + high + low) / 4,
turnoverRate = Math.min(1, eles.hsl / 100 || 0);
var H = Math.floor((high - minprice) / accuracy),
L = Math.ceil((low - minprice) / accuracy),
// G点坐标, 一字板时, X为进度因子
GPoint = [high == low ? factor - 1 : 2 / (high - low), Math.floor((avg - minprice) / accuracy)];
// 衰减
for (var n = 0; n < xdata.length; n++) {
xdata[n] *= (1 - turnoverRate);
}
if (high == low) {
// 一字板时,画矩形面积是三角形的2倍
xdata[GPoint[1]] += GPoint[0] * turnoverRate / 2;
} else {
for (var j = L; j <= H; j++) {
var curprice = minprice + accuracy * j;
if (curprice <= avg) {
// 上半三角叠加分布分布
if (Math.abs(avg - low) < 1e-8) {
xdata[j] += GPoint[0] * turnoverRate;
} else {
xdata[j] += (curprice - low) / (avg - low) * GPoint[0] * turnoverRate;
}
} else {
// 下半三角叠加分布分布
if (Math.abs(high - avg) < 1e-8) {
xdata[j] += GPoint[0] * turnoverRate;
} else {
xdata[j] += (high - curprice) / (high - avg) * GPoint[0] * turnoverRate;
}
}
}
}
}
var currentprice = klinedata[index].close;
var totalChips = 0;
for (var i = 0; i < factor; i++) {
var x = xdata[i].toPrecision(12) / 1;
//if (x < 0) xdata[i] = 0;
totalChips += x;
}
var result = new CYQData();
result.x = xdata;
result.y = yrange;
result.benefitPart = result.getBenefitPart(currentprice);
result.avgCost = getCostByChip(totalChips * 0.5).toFixed(2);
result.percentChips = {
'90': result.computePercentChips(0.9),
'70': result.computePercentChips(0.7)
};
return result;
/**
* 获取指定筹码处的成本
* @param {number} chip 堆叠筹码
*/
function getCostByChip(chip) {
var result = 0,
sum = 0;
for (var i = 0; i < factor; i++) {
var x = xdata[i].toPrecision(12) / 1;
if (sum + x > chip) {
result = minprice + i * accuracy;
break;
}
sum += x;
}
return result;
}
/**
* 筹码分布数据
*/
function CYQData() {
/**
* 筹码堆叠
* @type {Array.<number>}
*/
this.x = arguments[0];
/**
* 价格分布
* @type {Array.<number>}
*/
this.y = arguments[1];
/**
* 获利比例
* @type {number}
*/
this.benefitPart = arguments[2];
/**
* 平均成本
* @type {number}
*/
this.avgCost = arguments[3];
/**
* 百分比筹码
* @type {{Object.<string, {{priceRange: number[], concentration: number}}>}}
*/
this.percentChips = arguments[4];
/**
* 计算指定百分比的筹码
* @param {number} percent 百分比大于0,小于1
*/
this.computePercentChips = function (percent) {
if (percent > 1 || percent < 0) throw 'argument "percent" out of range';
var ps = [(1 - percent) / 2, (1 + percent) / 2];
var pr = [getCostByChip(totalChips * ps[0]), getCostByChip(totalChips * ps[1])];
return {
priceRange: [pr[0].toFixed(2), pr[1].toFixed(2)],
concentration: pr[0] + pr[1] === 0 ? 0 : (pr[1] - pr[0]) / (pr[0] + pr[1])
};
};
/**
* 获取指定价格的获利比例
* @param {number} price 价格
*/
this.getBenefitPart = function (price) {
var below = 0;
for (var i = 0; i < factor; i++) {
var x = xdata[i].toPrecision(12) / 1;
if (price >= minprice + i * accuracy) {
below += x;
}
}
return totalChips == 0 ? 0 : below / totalChips;
};
}
}
function createNumberArray(count) {
var array = [];
for (var i = 0; i < count; i++) {
array.push(0);
}
return array;
}
"""
js_code = py_mini_racer.MiniRacer()
js_code.eval(html_str)
adjust_dict = {"qfq": "1", "hfq": "2", "": "0"}
market_code = 1 if symbol.startswith("6") else 0
url = "https://push2his.eastmoney.com/api/qt/stock/kline/get"
params = {
"secid": f"{market_code}.{symbol}",
"fields1": "f1,f2,f3,f4,f5,f6",
"fields2": "f51,f52,f53,f54,f55,f56,f57,f58,f59,f60,f61",
"klt": "101",
"fqt": adjust_dict[adjust],
"end": datetime.now().date().strftime("%Y%m%d"),
"lmt": "210",
}
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 = [
"date",
"open",
"close",
"high",
"low",
"volume",
"volume_money",
"zf",
"zdf",
"zde",
"hsl",
]
for item in temp_df.columns[1:]:
temp_df[item] = pd.to_numeric(temp_df[item])
temp_df["index"] = range(0, len(temp_df))
records = temp_df.to_dict(orient="records")
date_list = []
benefit_part = []
avg_cost = []
pct_70_low = []
pct_70_high = []
pct_90_low = []
pct_90_high = []
pct_70_con = []
pct_90_con = []
for i in range(0, len(records)):
mcode = js_code.call("CYQCalculator", i, records)
date_list.append(records[i]["date"])
benefit_part.append(mcode["benefitPart"])
avg_cost.append(mcode["avgCost"])
pct_70_low.append(mcode["percentChips"]["70"]["priceRange"][0])
pct_70_high.append(mcode["percentChips"]["70"]["priceRange"][1])
pct_90_low.append(mcode["percentChips"]["90"]["priceRange"][0])
pct_90_high.append(mcode["percentChips"]["90"]["priceRange"][1])
pct_70_con.append(mcode["percentChips"]["70"]["concentration"])
pct_90_con.append(mcode["percentChips"]["90"]["concentration"])
temp_df = pd.DataFrame(
[
date_list,
benefit_part,
avg_cost,
pct_90_low,
pct_90_high,
pct_90_con,
pct_70_low,
pct_70_high,
pct_70_con,
]
).T
temp_df.columns = [
"日期",
"获利比例",
"平均成本",
"90成本-低",
"90成本-高",
"90集中度",
"70成本-低",
"70成本-高",
"70集中度",
]
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["90成本-低"] = pd.to_numeric(temp_df["90成本-低"], errors="coerce")
temp_df["90成本-高"] = pd.to_numeric(temp_df["90成本-高"], errors="coerce")
temp_df["90集中度"] = pd.to_numeric(temp_df["90集中度"], errors="coerce")
temp_df["70成本-低"] = pd.to_numeric(temp_df["70成本-低"], errors="coerce")
temp_df["70成本-高"] = pd.to_numeric(temp_df["70成本-高"], errors="coerce")
temp_df["70集中度"] = pd.to_numeric(temp_df["70集中度"], errors="coerce")
temp_df = temp_df.iloc[-90:, :].copy()
temp_df.reset_index(inplace=True, drop=True)
return temp_df
if __name__ == "__main__":
stock_cyq_em_df = stock_cyq_em(symbol="000001", adjust="")
print(stock_cyq_em_df)
@@ -0,0 +1,298 @@
#!/usr/bin/env python
# -*- coding:utf-8 -*-
"""
Date: 2024/5/1 20:00
Desc: 巨潮资讯-首页-公告查询-信息披露
http://www.cninfo.com.cn/new/commonUrl/pageOfSearch?url=disclosure/list/search
"""
import math
from functools import lru_cache
import pandas as pd
import requests
from akshare.utils.tqdm import get_tqdm
@lru_cache()
def __get_category_dict() -> dict:
"""
获取巨潮资讯-首页-公告查询-信息披露-类别字典
http://www.cninfo.com.cn/new/js/app/disclosure/notice/history-notice.js?v=20231124083101
:return: dict
:rtype: dict
"""
big_dict = {
"年报": "category_ndbg_szsh",
"半年报": "category_bndbg_szsh",
"一季报": "category_yjdbg_szsh",
"三季报": "category_sjdbg_szsh",
"业绩预告": "category_yjygjxz_szsh",
"权益分派": "category_qyfpxzcs_szsh",
"董事会": "category_dshgg_szsh",
"监事会": "category_jshgg_szsh",
"股东大会": "category_gddh_szsh",
"日常经营": "category_rcjy_szsh",
"公司治理": "category_gszl_szsh",
"中介报告": "category_zj_szsh",
"首发": "category_sf_szsh",
"增发": "category_zf_szsh",
"股权激励": "category_gqjl_szsh",
"配股": "category_pg_szsh",
"解禁": "category_jj_szsh",
"公司债": "category_gszq_szsh",
"可转债": "category_kzzq_szsh",
"其他融资": "category_qtrz_szsh",
"股权变动": "category_gqbd_szsh",
"补充更正": "category_bcgz_szsh",
"澄清致歉": "category_cqdq_szsh",
"风险提示": "category_fxts_szsh",
"特别处理和退市": "category_tbclts_szsh",
"退市整理期": "category_tszlq_szsh",
}
return big_dict
@lru_cache()
def __get_stock_json(symbol: str = "沪深京") -> dict:
"""
获取巨潮资讯-首页-公告查询-信息披露-股票代码字典
:param symbol: choice of {"沪深京", "港股", "三板", "基金", "债券"}
:type symbol: str
:return: 股票代码字典
:rtype: dict
"""
url = "http://www.cninfo.com.cn/new/data/szse_stock.json"
if symbol == "沪深京":
url = "http://www.cninfo.com.cn/new/data/szse_stock.json"
elif symbol == "港股":
url = "http://www.cninfo.com.cn/new/data/hke_stock.json"
elif symbol == "三板":
url = "http://www.cninfo.com.cn/new/data/gfzr_stock.json"
elif symbol == "基金":
url = "http://www.cninfo.com.cn/new/data/fund_stock.json"
elif symbol == "债券":
url = "http://www.cninfo.com.cn/new/data/bond_stock.json"
r = requests.get(url)
text_json = r.json()
temp_df = pd.DataFrame([item for item in text_json["stockList"]])
return dict(zip(temp_df["code"], temp_df["orgId"]))
def stock_zh_a_disclosure_report_cninfo(
symbol: str = "000001",
market: str = "沪深京",
keyword: str = "",
category: str = "",
start_date: str = "20230618",
end_date: str = "20231219",
) -> pd.DataFrame:
"""
巨潮资讯-首页-公告查询-信息披露公告
http://www.cninfo.com.cn/new/commonUrl/pageOfSearch?url=disclosure/list/search
:param symbol: 股票代码
:type symbol: str
:param market: choice of {"沪深京", "港股", "三板", "基金", "债券", "监管", "预披露"}
:type market: str
:param keyword: 关键词
:type keyword: str
:param category: choice of {'年报', '半年报', '一季报', '三季报', '业绩预告', '权益分派',
'董事会', '监事会', '股东大会', '日常经营', '公司治理', '中介报告',
'首发', '增发', '股权激励', '配股', '解禁', '公司债', '可转债', '其他融资',
'股权变动', '补充更正', '澄清致歉', '风险提示', '特别处理和退市', '退市整理期'}
:type category: str
:param start_date: 开始时间
:type start_date: str
:param end_date: 开始时间
:type end_date: str
:return: 指定 symbol 的数据
:rtype: pandas.DataFrame
"""
column_map = {
"沪深京": "szse",
"港股": "hke",
"三板": "third",
"基金": "fund",
"债券": "bond",
"监管": "regulator",
"预披露": "pre_disclosure",
}
stock_id_map = ""
if market == "沪深京" or "基金":
stock_id_map = __get_stock_json(market)
category_dict = __get_category_dict()
url = "http://www.cninfo.com.cn/new/hisAnnouncement/query"
stock_item = "" if symbol == "" else f"{symbol},{stock_id_map[symbol]}"
category_item = "" if category == "" else f"{category_dict[category]}"
payload = {
"pageNum": "1",
"pageSize": "30",
"column": column_map[market],
"tabName": "fulltext",
"plate": "",
"stock": stock_item,
"searchkey": keyword,
"secid": "",
"category": category_item,
"trade": "",
"seDate": f"{'-'.join([start_date[:4], start_date[4:6], start_date[6:]])}~"
f"{'-'.join([end_date[:4], end_date[4:6], end_date[6:]])}",
"sortName": "",
"sortType": "",
"isHLtitle": "true",
}
r = requests.post(url, params=payload)
text_json = r.json()
page_num = math.ceil(int(text_json["totalAnnouncement"]) / 30)
big_df = pd.DataFrame()
tqdm = get_tqdm()
for page in tqdm(range(1, page_num + 1), leave=False):
payload.update({"pageNum": page})
r = requests.post(url, data=payload)
text_json = r.json()
temp_df = pd.DataFrame(text_json["announcements"])
big_df = pd.concat(objs=[big_df, temp_df], ignore_index=True)
big_df.rename(
columns={
"secCode": "代码",
"secName": "简称",
"announcementTitle": "公告标题",
"announcementTime": "公告时间",
},
inplace=True,
)
big_df = big_df[["代码", "简称", "公告标题", "公告时间", "announcementId", "orgId"]]
big_df["公告时间"] = pd.to_datetime(
big_df["公告时间"], unit="ms", utc=True, errors="coerce"
)
big_df["公告时间"] = (
big_df["公告时间"]
.dt.tz_convert("Asia/Shanghai")
.dt.tz_localize(None)
.astype(str)
)
url_list = []
for item in zip(
big_df["代码"], big_df["announcementId"], big_df["orgId"], big_df["公告时间"]
):
url_format = (
f"http://www.cninfo.com.cn/new/disclosure/detail?stockCode={item[0]}&"
f"announcementId={item[1]}&orgId={item[2]}&announcementTime={item[3]}"
)
url_list.append(url_format)
big_df["公告链接"] = url_list
big_df = big_df[["代码", "简称", "公告标题", "公告时间", "公告链接"]]
return big_df
def stock_zh_a_disclosure_relation_cninfo(
symbol: str = "000001",
market: str = "沪深京",
start_date: str = "20230618",
end_date: str = "20231219",
) -> pd.DataFrame:
"""
巨潮资讯-首页-数据-预约披露调研
http://www.cninfo.com.cn/new/commonUrl?url=data/yypl
:param symbol: 股票代码
:type symbol: str
:param market: choice of {"沪深京", "港股", "三板", "基金", "债券", "监管", "预披露"}
:type market: str
:param start_date: 开始时间
:type start_date: str
:param end_date: 开始时间
:type end_date: str
:return: 指定 symbol 的数据
:rtype: pandas.DataFrame
"""
column_map = {
"沪深京": "szse",
"港股": "hke",
"三板": "third",
"基金": "fund",
"债券": "bond",
"监管": "regulator",
"预披露": "pre_disclosure",
}
stock_id_map = ""
if market == "沪深京":
stock_id_map = __get_stock_json(symbol)
stock_item = "" if symbol == "" else f"{symbol},{stock_id_map[symbol]}"
url = "http://www.cninfo.com.cn/new/hisAnnouncement/query"
payload = {
"pageNum": "1",
"pageSize": "30",
"column": column_map[market],
"tabName": "relation",
"plate": "",
"stock": stock_item,
"searchkey": "",
"secid": "",
"category": "",
"trade": "",
"seDate": f"{'-'.join([start_date[:4], start_date[4:6], start_date[6:]])}~"
f"{'-'.join([end_date[:4], end_date[4:6], end_date[6:]])}",
"sortName": "",
"sortType": "",
"isHLtitle": "true",
}
r = requests.post(url, data=payload)
text_json = r.json()
page_num = math.ceil(int(text_json["totalAnnouncement"]) / 30)
big_df = pd.DataFrame()
tqdm = get_tqdm()
for page in tqdm(range(1, page_num + 1), leave=False):
payload.update({"pageNum": page})
r = requests.post(url, data=payload)
text_json = r.json()
temp_df = pd.DataFrame(text_json["announcements"])
big_df = pd.concat(objs=[big_df, temp_df], ignore_index=True)
big_df.rename(
columns={
"secCode": "代码",
"secName": "简称",
"announcementTitle": "公告标题",
"announcementTime": "公告时间",
},
inplace=True,
)
big_df = big_df[["代码", "简称", "公告标题", "公告时间", "announcementId", "orgId"]]
big_df["公告时间"] = pd.to_datetime(
big_df["公告时间"], unit="ms", utc=True, errors="coerce"
)
big_df["公告时间"] = (
big_df["公告时间"]
.dt.tz_convert("Asia/Shanghai")
.dt.tz_convert(None)
.astype(str)
)
url_list = []
for item in zip(
big_df["代码"], big_df["announcementId"], big_df["orgId"], big_df["公告时间"]
):
url_format = (
f"http://www.cninfo.com.cn/new/disclosure/detail?stockCode={item[0]}"
f"&announcementId={item[1]}&orgId={item[2]}&announcementTime={item[3]}"
)
url_list.append(url_format)
big_df["公告链接"] = url_list
big_df = big_df[["代码", "简称", "公告标题", "公告时间", "公告链接"]]
return big_df
if __name__ == "__main__":
stock_zh_a_disclosure_report_cninfo_df = stock_zh_a_disclosure_report_cninfo(
symbol="164701",
market="基金",
keyword="大模型",
category="",
start_date="20240422",
end_date="20250422",
)
print(stock_zh_a_disclosure_report_cninfo_df)
stock_zh_a_disclosure_relation_cninfo_df = stock_zh_a_disclosure_relation_cninfo(
symbol="000001", market="沪深京", start_date="20230619", end_date="20231220"
)
print(stock_zh_a_disclosure_relation_cninfo_df)
@@ -0,0 +1,432 @@
#!/usr/bin/env python
# -*- coding:utf-8 -*-
"""
Date: 2024/2/1 16:20
Desc: 东方财富网-数据中心-新股数据-打新收益率
东方财富网-数据中心-新股申购-打新收益率
https://data.eastmoney.com/xg/xg/dxsyl.html
东方财富网-数据中心-新股数据-新股申购与中签查询
https://data.eastmoney.com/xg/xg/default_2.html
"""
import pandas as pd
import requests
from akshare.utils.tqdm import get_tqdm
def stock_dxsyl_em() -> pd.DataFrame:
"""
东方财富网-数据中心-新股申购-打新收益率
https://data.eastmoney.com/xg/xg/dxsyl.html
:return: 打新收益率数据
:rtype: pandas.DataFrame
"""
url = "https://datacenter-web.eastmoney.com/api/data/v1/get"
params = {
"sortColumns": "LISTING_DATE,SECURITY_CODE",
"sortTypes": "-1,-1",
"pageSize": "5000",
"pageNumber": "1",
"reportName": "RPTA_APP_IPOAPPLY",
"quoteColumns": "f2~01~SECURITY_CODE,f14~01~SECURITY_CODE",
"quoteType": "0",
"columns": "ALL",
"source": "WEB",
"client": "WEB",
"filter": """((APPLY_DATE>'2010-01-01')(|@APPLY_DATE="NULL"))((LISTING_DATE>'2010-01-01')(|@LISTING_DATE="NULL"))(TRADE_MARKET_CODE!="069001017")""",
}
r = requests.get(url, params=params)
data_json = r.json()
total_page = data_json["result"]["pages"]
big_df = pd.DataFrame()
tqdm = get_tqdm()
for page in tqdm(range(1, total_page + 1), leave=False):
params.update({"pageNumber": page})
r = requests.get(url, params=params)
data_json = r.json()
temp_df = pd.DataFrame(data_json["result"]["data"])
big_df = pd.concat([big_df, temp_df], ignore_index=True)
big_df.reset_index(inplace=True)
big_df["index"] = big_df.index + 1
big_df.rename(
columns={
"index": "序号",
"SECURITY_CODE": "股票代码",
"f14": "股票简称",
"ISSUE_PRICE": "发行价",
"LATELY_PRICE": "最新价",
"ONLINE_ISSUE_LWR": "网上-发行中签率",
"ONLINE_VA_SHARES": "网上-有效申购股数",
"ONLINE_VA_NUM": "网上-有效申购户数",
"ONLINE_ES_MULTIPLE": "网上-超额认购倍数",
"OFFLINE_VAP_RATIO": "网下-配售中签率",
"OFFLINE_VATS": "网下-有效申购股数",
"OFFLINE_VAP_OBJECT": "网下-有效申购户数",
"OFFLINE_VAS_MULTIPLE": "网下-配售认购倍数",
"ISSUE_NUM": "总发行数量",
"LD_OPEN_PREMIUM": "开盘溢价",
"LD_CLOSE_CHANGE": "首日涨幅",
"LISTING_DATE": "上市日期",
},
inplace=True,
)
big_df = big_df[
[
"序号",
"股票代码",
"股票简称",
"发行价",
"最新价",
"网上-发行中签率",
"网上-有效申购股数",
"网上-有效申购户数",
"网上-超额认购倍数",
"网下-配售中签率",
"网下-有效申购股数",
"网下-有效申购户数",
"网下-配售认购倍数",
"总发行数量",
"开盘溢价",
"首日涨幅",
"上市日期",
]
]
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["网上-有效申购户数"], 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["网下-有效申购户数"], 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["首日涨幅"], errors="coerce")
big_df["上市日期"] = pd.to_datetime(big_df["上市日期"], errors="coerce").dt.date
return big_df
def stock_xgsglb_em(symbol: str = "全部股票") -> pd.DataFrame:
"""
新股申购与中签查询
https://data.eastmoney.com/xg/xg/default_2.html
:param symbol: choice of {"全部股票", "沪市主板", "科创板", "深市主板", "创业板", "北交所"}
:type symbol: str
:return: 新股申购与中签数据
:rtype: pandas.DataFrame
"""
market_map = {
"全部股票": """(APPLY_DATE>'2010-01-01')""",
"沪市主板": """(APPLY_DATE>'2010-01-01')(SECURITY_TYPE_CODE in ("058001001","058001008"))(TRADE_MARKET_CODE in ("069001001001","069001001003","069001001006"))""",
"科创板": """(APPLY_DATE>'2010-01-01')(SECURITY_TYPE_CODE in ("058001001","058001008"))(TRADE_MARKET_CODE="069001001006")""",
"深市主板": """(APPLY_DATE>'2010-01-01')(SECURITY_TYPE_CODE="058001001")(TRADE_MARKET_CODE in ("069001002001","069001002002","069001002003","069001002005"))""",
"创业板": """(APPLY_DATE>'2010-01-01')(SECURITY_TYPE_CODE="058001001")(TRADE_MARKET_CODE="069001002002")""",
}
url = "http://datacenter-web.eastmoney.com/api/data/v1/get"
if symbol == "北交所":
params = {
"sortColumns": "APPLY_DATE",
"sortTypes": "-1",
"pageSize": "500",
"pageNumber": "1",
"columns": "ALL",
"reportName": "RPT_NEEQ_ISSUEINFO_LIST",
"quoteColumns": "f14~01~SECURITY_CODE~SECURITY_NAME_ABBR",
"source": "NEEQSELECT",
"client": "WEB",
}
r = requests.get(url, params=params)
data_json = r.json()
total_page = data_json["result"]["pages"]
big_df = pd.DataFrame()
tqdm = get_tqdm()
for page in tqdm(range(1, 1 + int(total_page)), leave=False):
params.update({"pageNumber": page})
r = requests.get(url, params=params)
data_json = r.json()
temp_df = pd.DataFrame(data_json["result"]["data"])
big_df = pd.concat([big_df, temp_df], ignore_index=True)
big_df.rename(
columns={
"ORG_CODE": "-",
"SECURITY_CODE": "代码",
"SECUCODE": "带市场标识股票代码",
"SECURITY_NAME_ABBR": "简称",
"APPLY_CODE": "申购代码",
"EXPECT_ISSUE_NUM": "发行总数",
"PRICE_WAY": "定价方式",
"ISSUE_PRICE": "发行价格",
"ISSUE_PE_RATIO": "发行市盈率",
"APPLY_DATE": "申购日",
"RESULT_NOTICE_DATE": "发行结果公告日期",
"SELECT_LISTING_DATE": "上市首日-上市日",
"ONLINE_ISSUE_NUM": "网上-发行数量",
"APPLY_AMT_UPPER": "网上-顶格所需资金",
"APPLY_NUM_UPPER": "网上-申购上限",
"ONLINE_PAY_DATE": "网上申购缴款日期",
"ONLINE_REFUND_DATE": "网上申购资金退款日",
"INFO_CODE": "-",
"ONLINE_ISSUE_LWR": "中签率",
"NEWEST_PRICE": "最新价格-价格",
"CLOSE_PRICE": "首日收盘价",
"INITIAL_MULTIPLE": "-",
"PER_SHARES_INCOME": "上市首日-每百股获利",
"LD_CLOSE_CHANGE": "上市首日-涨幅",
"TURNOVERRATE": "首日换手率",
"AMPLITUDE": "首日振幅",
"ONLINE_APPLY_LOWER": "-",
"MAIN_BUSINESS": "主营业务",
"INDUSTRY_PE_RATIO": "行业市盈率",
"APPLY_AMT_100": "稳获百股需配资金",
"TAKE_UP_TIME": "资金占用时间",
"CAPTURE_PROFIT": "上市首日-约合年化收益",
"APPLY_SHARE_100": "每获配百股需配股数",
"AVERAGE_PRICE": "上市首日-均价",
"ORG_VAN": "参与申购人数",
"VA_AMT": "参与申购资金",
"ISSUE_PRICE_ADJFACTOR": "-",
},
inplace=True,
)
big_df["最新价格-累计涨幅"] = big_df["首日收盘价"] / big_df["最新价格-价格"]
big_df = big_df[
[
"代码",
"简称",
"申购代码",
"发行总数",
"网上-发行数量",
"网上-申购上限",
"网上-顶格所需资金",
"发行价格",
"申购日",
"中签率",
"稳获百股需配资金",
"最新价格-价格",
"最新价格-累计涨幅",
"上市首日-上市日",
"上市首日-均价",
"上市首日-涨幅",
"上市首日-每百股获利",
"上市首日-约合年化收益",
"发行市盈率",
"行业市盈率",
"参与申购资金",
"参与申购人数",
]
]
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["发行价格"], 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["最新价格-累计涨幅"], 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["上市首日-约合年化收益"], 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["参与申购人数"], errors="coerce")
big_df["申购日"] = pd.to_datetime(big_df["申购日"], errors="coerce").dt.date
big_df["上市首日-上市日"] = pd.to_datetime(
big_df["上市首日-上市日"], errors="coerce"
).dt.date
return big_df
else:
params = {
"sortColumns": "APPLY_DATE,SECURITY_CODE",
"sortTypes": "-1,-1",
"pageSize": "5000",
"pageNumber": "1",
"reportName": "RPTA_APP_IPOAPPLY",
"columns": "SECURITY_CODE,SECURITY_NAME,TRADE_MARKET_CODE,APPLY_CODE,TRADE_MARKET,MARKET_TYPE,ORG_TYPE,ISSUE_NUM,ONLINE_ISSUE_NUM,OFFLINE_PLACING_NUM,TOP_APPLY_MARKETCAP,PREDICT_ONFUND_UPPER,ONLINE_APPLY_UPPER,PREDICT_ONAPPLY_UPPER,ISSUE_PRICE,LATELY_PRICE,CLOSE_PRICE,APPLY_DATE,BALLOT_NUM_DATE,BALLOT_PAY_DATE,LISTING_DATE,AFTER_ISSUE_PE,ONLINE_ISSUE_LWR,INITIAL_MULTIPLE,INDUSTRY_PE_NEW,OFFLINE_EP_OBJECT,CONTINUOUS_1WORD_NUM,TOTAL_CHANGE,PROFIT,LIMIT_UP_PRICE,INFO_CODE,OPEN_PRICE,LD_OPEN_PREMIUM,LD_CLOSE_CHANGE,TURNOVERRATE,LD_HIGH_CHANG,LD_AVERAGE_PRICE,OPEN_DATE,OPEN_AVERAGE_PRICE,PREDICT_PE,PREDICT_ISSUE_PRICE2,PREDICT_ISSUE_PRICE,PREDICT_ISSUE_PRICE1,PREDICT_ISSUE_PE,PREDICT_PE_THREE,ONLINE_APPLY_PRICE,MAIN_BUSINESS",
"filter": market_map[symbol],
"source": "WEB",
"client": "WEB",
}
r = requests.get(url, params=params)
data_json = r.json()
total_page = data_json["result"]["pages"]
big_df = pd.DataFrame()
tqdm = get_tqdm()
for page in tqdm(range(1, total_page + 1), leave=False):
params.update({"pageNumber": page})
r = requests.get(url, params=params)
data_json = r.json()
temp_df = pd.DataFrame(data_json["result"]["data"])
big_df = pd.concat(objs=[big_df, temp_df], ignore_index=True)
big_df.rename(
columns={
"SECURITY_CODE": "股票代码",
"SECURITY_NAME": "股票简称",
"TRADE_MARKET_CODE": "-",
"APPLY_CODE": "申购代码",
"TRADE_MARKET": "交易所",
"MARKET_TYPE": "板块",
"ORG_TYPE": "-",
"ISSUE_NUM": "发行总数",
"ONLINE_ISSUE_NUM": "网上发行",
"OFFLINE_PLACING_NUM": "_",
"TOP_APPLY_MARKETCAP": "顶格申购需配市值",
"PREDICT_ONFUND_UPPER": "_",
"ONLINE_APPLY_UPPER": "申购上限",
"PREDICT_ONAPPLY_UPPER": "_",
"ISSUE_PRICE": "发行价格",
"LATELY_PRICE": "最新价",
"CLOSE_PRICE": "首日收盘价",
"APPLY_DATE": "申购日期",
"BALLOT_NUM_DATE": "中签号公布日",
"BALLOT_PAY_DATE": "中签缴款日期",
"LISTING_DATE": "上市日期",
"AFTER_ISSUE_PE": "发行市盈率",
"ONLINE_ISSUE_LWR": "中签率",
"INITIAL_MULTIPLE": "询价累计报价倍数",
"INDUSTRY_PE_NEW": "行业市盈率",
"OFFLINE_EP_OBJECT": "配售对象报价家数",
"CONTINUOUS_1WORD_NUM": "连续一字板数量",
"TOTAL_CHANGE": "涨幅",
"PROFIT": "每中一签获利",
"LIMIT_UP_PRICE": "_",
"INFO_CODE": "_",
"OPEN_PRICE": "_",
"LD_OPEN_PREMIUM": "_",
"LD_CLOSE_CHANGE": "_",
"TURNOVERRATE": "_",
"LD_HIGH_CHANG": "_",
"LD_AVERAGE_PRICE": "_",
"OPEN_DATE": "_",
"OPEN_AVERAGE_PRICE": "_",
"PREDICT_PE": "_",
"PREDICT_ISSUE_PRICE2": "_",
"PREDICT_ISSUE_PRICE": "_",
"PREDICT_ISSUE_PRICE1": "_",
"PREDICT_ISSUE_PE": "_",
"PREDICT_PE_THREE": "_",
"ONLINE_APPLY_PRICE": "_",
"MAIN_BUSINESS": "_",
"IS_REGISTRATION": "_",
},
inplace=True,
)
big_df = big_df[
[
"股票代码",
"股票简称",
"申购代码",
"交易所",
"板块",
"发行总数",
"网上发行",
"顶格申购需配市值",
"申购上限",
"发行价格",
"最新价",
"首日收盘价",
"申购日期",
"中签号公布日",
"中签缴款日期",
"上市日期",
"发行市盈率",
"行业市盈率",
"中签率",
"询价累计报价倍数",
"配售对象报价家数",
"连续一字板数量",
"涨幅",
"每中一签获利",
]
]
big_df["申购日期"] = pd.to_datetime(big_df["申购日期"], errors="coerce").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["发行总数"], 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["发行价格"], 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["行业市盈率"], 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["涨幅"], errors="coerce")
big_df["每中一签获利"] = pd.to_numeric(big_df["每中一签获利"], errors="coerce")
return big_df
if __name__ == "__main__":
stock_dxsyl_em_df = stock_dxsyl_em()
print(stock_dxsyl_em_df)
stock_xgsglb_em_df = stock_xgsglb_em(symbol="全部股票")
print(stock_xgsglb_em_df)
stock_xgsglb_em_df = stock_xgsglb_em(symbol="沪市主板")
print(stock_xgsglb_em_df)
stock_xgsglb_em_df = stock_xgsglb_em(symbol="科创板")
print(stock_xgsglb_em_df)
stock_xgsglb_em_df = stock_xgsglb_em(symbol="深市主板")
print(stock_xgsglb_em_df)
stock_xgsglb_em_df = stock_xgsglb_em(symbol="创业板")
print(stock_xgsglb_em_df)
stock_xgsglb_em_df = stock_xgsglb_em(symbol="北交所")
print(stock_xgsglb_em_df)
@@ -0,0 +1,59 @@
#!/usr/bin/env python
# -*- coding:utf-8 -*-
"""
Date: 2025/3/19 15:30
Desc: 乐咕乐股-股债利差
https://legulegu.com/stockdata/equity-bond-spread
"""
import pandas as pd
import requests
from akshare.stock_feature.stock_a_indicator import get_token_lg, get_cookie_csrf
def stock_ebs_lg() -> pd.DataFrame:
"""
乐咕乐股-股债利差
https://legulegu.com/stockdata/equity-bond-spread
:return: 股债利差
:rtype: pandas.DataFrame
"""
url = "https://legulegu.com/api/stockdata/equity-bond-spread"
token = get_token_lg()
params = {"token": token, "code": "000300.SH"}
r = requests.get(
url,
params=params,
**get_cookie_csrf(url="https://legulegu.com/stockdata/equity-bond-spread"),
)
data_json = r.json()
temp_df = pd.DataFrame(data_json["data"])
temp_df["date"] = pd.to_datetime(temp_df["date"], errors="coerce").dt.date
temp_df.rename(
columns={
"date": "日期",
"close": "沪深300指数",
"peSpread": "股债利差",
"peSpreadAverage": "股债利差均线",
},
inplace=True,
)
temp_df = temp_df[
[
"日期",
"沪深300指数",
"股债利差",
"股债利差均线",
]
]
temp_df["日期"] = pd.to_datetime(temp_df["日期"], errors="coerce").dt.date
temp_df["沪深300指数"] = pd.to_numeric(temp_df["沪深300指数"], 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__":
stock_ebs_lg_df = stock_ebs_lg()
print(stock_ebs_lg_df)
@@ -0,0 +1,343 @@
#!/usr/bin/env python
# -*- coding:utf-8 -*-
"""
Date: 2024/7/15 16:30
Desc: 新浪财经-ESG评级中心
https://finance.sina.com.cn/esg/
"""
import math
from akshare.utils.tqdm import get_tqdm
import pandas as pd
import requests
def stock_esg_msci_sina() -> pd.DataFrame:
"""
新浪财经-ESG评级中心-ESG评级-MSCI
https://finance.sina.com.cn/esg/grade.shtml
:return: MSCI
:rtype: pandas.DataFrame
"""
url = "https://global.finance.sina.com.cn/api/openapi.php/EsgService.getMsciEsgStocks?p=1&num=100"
r = requests.get(url)
data_json = r.json()
page_num = math.ceil(int(data_json["result"]["data"]["total"]) / 100)
big_df = pd.DataFrame()
tqdm = get_tqdm()
for page in tqdm(range(1, page_num + 1), leave=False):
headers = {
"Referer": "https://finance.sina.com.cn/",
"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",
}
url = f"https://global.finance.sina.com.cn/api/openapi.php/EsgService.getMsciEsgStocks?p={page}&num=100"
r = requests.get(url, headers=headers)
data_json = r.json()
temp_df = pd.DataFrame(data_json["result"]["data"]["data"])
big_df = pd.concat(objs=[big_df, temp_df], ignore_index=True)
big_df.rename(
columns={
"agency_id": "-",
"agency_name": "评级机构",
"symbol": "股票代码",
"delist": "-",
"comp_code": "-",
"name": "股票名称",
"market": "交易市场",
"industry_code": "行业代码",
"industry_name": "行业名称",
"sw1_code": "-",
"sw1_name": "-",
"sw2_code": "-",
"sw2_name": "-",
"sw3_code": "-",
"sw3_name": "-",
"hs1_code": "-",
"hs1_name": "-",
"hs2_code": "-",
"hs2_name": "-",
"hs3_code": "-",
"hs3_name": "-",
"factset_sector_code": "-",
"factset_sector_name": "-",
"factset_industry_code": "-",
"factset_industry_name": "-",
"date": "-",
"quarter_date": "评级日期",
"grade": "ESG等级",
"score": "-",
"env_score": "环境总评",
"env_grade": "-",
"social_score": "社会责任总评",
"social_grade": "-",
"governance_score": "治理总评",
"governance_grade": "-",
"change_status": "-",
"updated_time": "更新时间",
"created_time": "创建时间",
"esg_rating": "ESG评分",
},
inplace=True,
)
big_df = big_df[
[
"股票代码",
"ESG评分",
"环境总评",
"社会责任总评",
"治理总评",
"评级日期",
"交易市场",
]
]
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")
return big_df
def stock_esg_rft_sina() -> pd.DataFrame:
"""
新浪财经-ESG评级中心-ESG评级-路孚特
https://finance.sina.com.cn/esg/grade.shtml
:return: 路孚特
:rtype: pandas.DataFrame
"""
url = "https://global.finance.sina.com.cn/api/openapi.php/EsgService.getRftEsgStocks?p=1&num=20000"
r = requests.get(url)
data_json = r.json()
big_df = pd.DataFrame(data_json["result"]["data"]["data"])
big_df.rename(
columns={
"symbol": "股票代码",
"esg_score": "ESG评分",
"esg_score_date": "ESG评分日期",
"env_score": "环境总评",
"env_score_date": "环境总评日期",
"social_score": "社会责任总评",
"social_score_date": "社会责任总评日期",
"governance_score": "治理总评",
"governance_score_date": "治理总评日期",
"zy_score": "争议总评",
"zy_score_date": "争议总评日期",
"industry": "行业",
"exchange": "交易所",
},
inplace=True,
)
big_df = big_df[
[
"股票代码",
"ESG评分",
"ESG评分日期",
"环境总评",
"环境总评日期",
"社会责任总评",
"社会责任总评日期",
"治理总评",
"治理总评日期",
"争议总评",
"争议总评日期",
"行业",
"交易所",
]
]
big_df["ESG评分日期"] = pd.to_datetime(
big_df["ESG评分日期"], errors="coerce"
).dt.date
big_df["环境总评日期"] = pd.to_datetime(
big_df["环境总评日期"], errors="coerce"
).dt.date
big_df["社会责任总评日期"] = pd.to_datetime(
big_df["社会责任总评日期"], errors="coerce"
).dt.date
big_df["治理总评日期"] = pd.to_datetime(
big_df["治理总评日期"], errors="coerce"
).dt.date
big_df["争议总评日期"] = pd.to_datetime(
big_df["争议总评日期"], errors="coerce"
).dt.date
return big_df
def stock_esg_rate_sina() -> pd.DataFrame:
"""
新浪财经-ESG评级中心-ESG评级-ESG评级数据
https://finance.sina.com.cn/esg/grade.shtml
:return: ESG评级数据
:rtype: pandas.DataFrame
"""
url = "https://global.finance.sina.com.cn/api/openapi.php/EsgService.getEsgStocks?page=1&num=200"
r = requests.get(url)
data_json = r.json()
page_num = math.ceil(int(data_json["result"]["data"]["info"]["total"]) / 200)
big_df = pd.DataFrame()
tqdm = get_tqdm()
for page in tqdm(range(1, page_num + 1), leave=False):
url = f"https://global.finance.sina.com.cn/api/openapi.php/EsgService.getEsgStocks?page={page}&num=200"
r = requests.get(url)
data_json = r.json()
stock_num = len(data_json["result"]["data"]["info"]["stocks"])
for num in range(stock_num):
temp_df = pd.DataFrame(
data_json["result"]["data"]["info"]["stocks"][num]["esg_info"]
)
temp_df["symbol"] = data_json["result"]["data"]["info"]["stocks"][num][
"symbol"
]
temp_df["market"] = data_json["result"]["data"]["info"]["stocks"][num][
"market"
]
big_df = pd.concat(objs=[big_df, temp_df], ignore_index=True)
big_df.rename(
columns={
"symbol": "成分股代码",
"agency_name": "评级机构",
"esg_score": "评级",
"esg_dt": "评级季度",
"remark": "标识",
"market": "交易市场",
},
inplace=True,
)
big_df = big_df[
[
"成分股代码",
"评级机构",
"评级",
"评级季度",
"标识",
"交易市场",
]
]
return big_df
def stock_esg_zd_sina() -> pd.DataFrame:
"""
新浪财经-ESG评级中心-ESG评级-秩鼎
https://finance.sina.com.cn/esg/grade.shtml
:return: 秩鼎
:rtype: pandas.DataFrame
"""
url = "https://global.finance.sina.com.cn/api/openapi.php/EsgService.getZdEsgStocks"
params = {"p": "1", "num": "100"}
r = requests.get(url, params=params)
data_json = r.json()
tqdm = get_tqdm()
total_page = math.ceil(int(data_json["result"]["data"]["total"]) / 100)
temp_list = []
for page in tqdm(range(1, total_page + 1), leave=False):
params = {"p": str(page), "num": "100"}
r = requests.get(url, params=params)
data_json = r.json()
temp_df = pd.DataFrame(data_json["result"]["data"]["data"])
temp_list.append(temp_df)
big_df = pd.concat(temp_list, ignore_index=True)
big_df.rename(
columns={
"ticker": "股票代码",
"esg_score": "ESG评分",
"report_date": "评分日期",
"environmental_score": "环境总评",
"social_score": "社会责任总评",
"governance_score": "治理总评",
},
inplace=True,
)
big_df = big_df[
[
"股票代码",
"ESG评分",
"环境总评",
"社会责任总评",
"治理总评",
"评分日期",
]
]
big_df["评分日期"] = pd.to_datetime(big_df["评分日期"], errors="coerce").dt.date
return big_df
def stock_esg_hz_sina() -> pd.DataFrame:
"""
新浪财经-ESG评级中心-ESG评级-华证指数
https://finance.sina.com.cn/esg/grade.shtml
:return: 华证指数
:rtype: pandas.DataFrame
"""
url = "https://global.finance.sina.com.cn/api/openapi.php/EsgService.getHzEsgStocks"
params = {"p": 1, "num": "100"}
r = requests.get(url, params=params)
data_json = r.json()
total_page = math.ceil(int(data_json["result"]["data"]["total"]) / 100)
big_df = pd.DataFrame()
tqdm = get_tqdm()
for page in tqdm(range(1, total_page + 1), leave=False):
params = {"p": str(page), "num": "100"}
r = requests.get(url, params=params)
data_json = r.json()
temp_df = pd.DataFrame(data_json["result"]["data"]["data"])
big_df = pd.concat(objs=[big_df, temp_df], ignore_index=True)
big_df.rename(
columns={
"date": "日期",
"symbol": "股票代码",
"market": "交易市场",
"name": "股票名称",
"esg_score": "ESG评分",
"esg_score_grade": "ESG等级",
"e_score": "环境",
"e_score_grade": "环境等级",
"s_score": "社会",
"s_score_grade": "社会等级",
"g_score": "公司治理",
"g_score_grade": "公司治理等级",
},
inplace=True,
)
big_df = big_df[
[
"日期",
"股票代码",
"交易市场",
"股票名称",
"ESG评分",
"ESG等级",
"环境",
"环境等级",
"社会",
"社会等级",
"公司治理",
"公司治理等级",
]
]
big_df["日期"] = pd.to_datetime(big_df["日期"], errors="coerce").dt.date
big_df["ESG评分"] = pd.to_numeric(big_df["ESG评分"], 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")
return big_df
if __name__ == "__main__":
stock_esg_msci_sina_df = stock_esg_msci_sina()
print(stock_esg_msci_sina_df)
stock_esg_rft_sina_df = stock_esg_rft_sina()
print(stock_esg_rft_sina_df)
stock_esg_rate_sina_df = stock_esg_rate_sina()
print(stock_esg_rate_sina_df)
stock_esg_zd_sina_df = stock_esg_zd_sina()
print(stock_esg_zd_sina_df)
stock_esg_hz_sina_df = stock_esg_hz_sina()
print(stock_esg_hz_sina_df)
@@ -0,0 +1,273 @@
#!/usr/bin/env python
# -*- coding:utf-8 -*-
"""
Date: 2025/3/18 15:00
Desc: 东方财富网-数据中心-年报季报-分红送配
https://data.eastmoney.com/yjfp/
"""
import pandas as pd
import requests
from akshare.utils.tqdm import get_tqdm
def stock_fhps_em(date: str = "20231231") -> pd.DataFrame:
"""
东方财富网-数据中心-年报季报-分红送配
https://data.eastmoney.com/yjfp/
:param date: 分红送配报告期
:type date: str
:return: 分红送配
:rtype: pandas.DataFrame
"""
import warnings
warnings.simplefilter(action="ignore", category=FutureWarning)
url = "https://datacenter-web.eastmoney.com/api/data/v1/get"
params = {
"sortColumns": "PLAN_NOTICE_DATE",
"sortTypes": "-1",
"pageSize": "500",
"pageNumber": "1",
"reportName": "RPT_SHAREBONUS_DET",
"columns": "ALL",
"quoteColumns": "",
"js": '{"data":(x),"pages":(tp)}',
"source": "WEB",
"client": "WEB",
"filter": f"""(REPORT_DATE='{"-".join([date[:4], date[4:6], date[6:]])}')""",
}
r = requests.get(url, params=params)
data_json = r.json()
total_pages = int(data_json["result"]["pages"])
big_df = pd.DataFrame()
tqdm = get_tqdm()
for page in tqdm(range(1, total_pages + 1), leave=False):
params.update({"pageNumber": page})
r = requests.get(url, params=params)
data_json = r.json()
temp_df = pd.DataFrame(data_json["result"]["data"])
big_df = pd.concat(objs=[big_df, temp_df], ignore_index=True)
big_df.columns = [
"_",
"名称",
"_",
"_",
"代码",
"送转股份-送转总比例",
"送转股份-送转比例",
"送转股份-转股比例",
"现金分红-现金分红比例",
"预案公告日",
"股权登记日",
"除权除息日",
"_",
"方案进度",
"_",
"最新公告日期",
"_",
"_",
"_",
"每股收益",
"每股净资产",
"每股公积金",
"每股未分配利润",
"净利润同比增长",
"总股本",
"_",
"现金分红-股息率",
"-",
"-",
"-",
]
big_df = big_df[
[
"代码",
"名称",
"送转股份-送转总比例",
"送转股份-送转比例",
"送转股份-转股比例",
"现金分红-现金分红比例",
"现金分红-股息率",
"每股收益",
"每股净资产",
"每股公积金",
"每股未分配利润",
"净利润同比增长",
"总股本",
"预案公告日",
"股权登记日",
"除权除息日",
"方案进度",
"最新公告日期",
]
]
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["现金分红-股息率"], 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["每股未分配利润"], errors="coerce")
big_df["净利润同比增长"] = pd.to_numeric(big_df["净利润同比增长"], errors="coerce")
big_df["总股本"] = pd.to_numeric(big_df["总股本"], errors="coerce")
big_df["预案公告日"] = pd.to_datetime(big_df["预案公告日"], errors="coerce").dt.date
big_df["股权登记日"] = pd.to_datetime(big_df["股权登记日"], errors="coerce").dt.date
big_df["除权除息日"] = pd.to_datetime(big_df["除权除息日"], errors="coerce").dt.date
big_df["最新公告日期"] = pd.to_datetime(
big_df["最新公告日期"], errors="coerce"
).dt.date
big_df.sort_values(["最新公告日期"], inplace=True, ignore_index=True)
return big_df
def stock_fhps_detail_em(symbol: str = "300073") -> pd.DataFrame:
"""
东方财富网-数据中心-分红送配-分红送配详情
https://data.eastmoney.com/yjfp/detail/300073.html
:param symbol: 股票代码
:type symbol: str
:return: 分红送配详情
:rtype: pandas.DataFrame
"""
url = "https://datacenter-web.eastmoney.com/api/data/v1/get"
params = {
"sortColumns": "REPORT_DATE",
"sortTypes": "-1",
"pageSize": "500",
"pageNumber": "1",
"reportName": "RPT_SHAREBONUS_DET",
"columns": "ALL",
"quoteColumns": "",
"js": '{"data":(x),"pages":(tp)}',
"source": "WEB",
"client": "WEB",
"filter": f"""(SECURITY_CODE="{symbol}")""",
}
r = requests.get(url, params=params)
data_json = r.json()
total_pages = int(data_json["result"]["pages"])
big_df = pd.DataFrame()
tqdm = get_tqdm()
for page in tqdm(range(1, total_pages + 1), leave=False):
params.update({"pageNumber": page})
r = requests.get(url, params=params)
data_json = r.json()
temp_df = pd.DataFrame(data_json["result"]["data"])
big_df = pd.concat(objs=[big_df, temp_df], ignore_index=True)
big_df.columns = [
"_",
"-",
"_",
"_",
"-",
"送转股份-送转总比例",
"送转股份-送股比例",
"送转股份-转股比例",
"现金分红-现金分红比例",
"业绩披露日期",
"股权登记日",
"除权除息日",
"报告期",
"方案进度",
"现金分红-现金分红比例描述",
"最新公告日期",
"-",
"-",
"-",
"每股收益",
"每股净资产",
"每股公积金",
"每股未分配利润",
"净利润同比增长",
"总股本",
"预案公告日",
"现金分红-股息率",
"-",
"-",
"-",
]
big_df = big_df[
[
"报告期",
"业绩披露日期",
"送转股份-送转总比例",
"送转股份-送股比例",
"送转股份-转股比例",
"现金分红-现金分红比例",
"现金分红-现金分红比例描述",
"现金分红-股息率",
"每股收益",
"每股净资产",
"每股公积金",
"每股未分配利润",
"净利润同比增长",
"总股本",
"预案公告日",
"股权登记日",
"除权除息日",
"方案进度",
"最新公告日期",
]
]
big_df["报告期"] = pd.to_datetime(big_df["报告期"], errors="coerce").dt.date
big_df["业绩披露日期"] = pd.to_datetime(
big_df["业绩披露日期"], errors="coerce"
).dt.date
big_df["预案公告日"] = pd.to_datetime(big_df["预案公告日"], errors="coerce").dt.date
big_df["股权登记日"] = pd.to_datetime(big_df["股权登记日"], errors="coerce").dt.date
big_df["除权除息日"] = pd.to_datetime(big_df["除权除息日"], errors="coerce").dt.date
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["现金分红-股息率"], 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["每股未分配利润"], errors="coerce")
big_df["净利润同比增长"] = pd.to_numeric(big_df["净利润同比增长"], errors="coerce")
big_df["总股本"] = pd.to_numeric(big_df["总股本"], errors="coerce")
big_df.sort_values(["报告期"], inplace=True, ignore_index=True)
return big_df
if __name__ == "__main__":
stock_fhps_em_df = stock_fhps_em(date="20231231")
print(stock_fhps_em_df)
stock_fhps_detail_em_df = stock_fhps_detail_em(symbol="000005")
print(stock_fhps_detail_em_df)
@@ -0,0 +1,62 @@
#!/usr/bin/env python
# -*- coding:utf-8 -*-
"""
Date: 2024/5/13 10:30
Desc: 同花顺-分红情况
https://basic.10jqka.com.cn/new/603444/bonus.html
"""
from io import StringIO
import pandas as pd
import requests
def stock_fhps_detail_ths(symbol: str = "603444") -> pd.DataFrame:
"""
同花顺-分红情况
https://basic.10jqka.com.cn/new/603444/bonus.html
:param symbol: 股票代码
:type symbol: str
:return: 分红融资
:rtype: pandas.DataFrame
"""
url = f"https://basic.10jqka.com.cn/new/{symbol}/bonus.html"
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
"AppleWebKit/537.36 (KHTML, like Gecko) "
"Chrome/89.0.4389.90 Safari/537.36",
}
r = requests.get(url, headers=headers)
r.encoding = "gbk"
temp_df = pd.read_html(StringIO(r.text))[0]
temp_df["董事会日期"] = pd.to_datetime(
temp_df["董事会日期"], format="%Y-%m-%d", errors="coerce"
).dt.date
temp_df["股东大会预案公告日期"] = pd.to_datetime(
temp_df["股东大会预案公告日期"], format="%Y-%m-%d", errors="coerce"
).dt.date
temp_df["实施公告日"] = pd.to_datetime(
temp_df["实施公告日"], format="%Y-%m-%d", errors="coerce"
).dt.date
if "A股股权登记日" in temp_df.columns:
temp_df["A股股权登记日"] = pd.to_datetime(
temp_df["A股股权登记日"], format="%Y-%m-%d", errors="coerce"
).dt.date
temp_df["A股除权除息日"] = pd.to_datetime(
temp_df["A股除权除息日"], format="%Y-%m-%d", errors="coerce"
).dt.date
else:
temp_df["B股股权登记日"] = pd.to_datetime(
temp_df["B股股权登记日"], format="%Y-%m-%d", errors="coerce"
).dt.date
temp_df["B股除权除息日"] = pd.to_datetime(
temp_df["B股除权除息日"], format="%Y-%m-%d", errors="coerce"
).dt.date
temp_df.sort_values(by=["董事会日期"], ignore_index=True, inplace=True)
return temp_df
if __name__ == "__main__":
stock_fhps_detail_ths_df = stock_fhps_detail_ths(symbol="200596")
print(stock_fhps_detail_ths_df)
@@ -0,0 +1,472 @@
#!/usr/bin/env python
# -*- coding:utf-8 -*-
"""
Date: 2024/8/15 18:00
Desc: 同花顺-数据中心-资金流向
同花顺-数据中心-资金流向-个股资金流
https://data.10jqka.com.cn/funds/ggzjl/#refCountId=data_55f13c2c_254
同花顺-数据中心-资金流向-概念资金流
https://data.10jqka.com.cn/funds/gnzjl/#refCountId=data_55f13c2c_254
同花顺-数据中心-资金流向-行业资金流
https://data.10jqka.com.cn/funds/hyzjl/#refCountId=data_55f13c2c_254
同花顺-数据中心-资金流向-打单追踪
https://data.10jqka.com.cn/funds/ddzz/#refCountId=data_55f13c2c_254
"""
from io import StringIO
import pandas as pd
import requests
from bs4 import BeautifulSoup
import py_mini_racer
from akshare.utils.tqdm import get_tqdm
from akshare.datasets import get_ths_js
def _get_file_content_ths(file: str = "ths.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 stock_fund_flow_individual(symbol: str = "即时") -> pd.DataFrame:
"""
同花顺-数据中心-资金流向-个股资金流
https://data.10jqka.com.cn/funds/ggzjl/#refCountId=data_55f13c2c_254
:param symbol: choice of {“即时”, "3日排行", "5日排行", "10日排行", "20日排行"}
:type symbol: str
:return: 个股资金流
:rtype: pandas.DataFrame
"""
js_code = py_mini_racer.MiniRacer()
js_content = _get_file_content_ths("ths.js")
js_code.eval(js_content)
v_code = js_code.call("v")
headers = {
"Accept": "text/html, */*; q=0.01",
"Accept-Encoding": "gzip, deflate",
"Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8",
"Cache-Control": "no-cache",
"Connection": "keep-alive",
"hexin-v": v_code,
"Host": "data.10jqka.com.cn",
"Pragma": "no-cache",
"Referer": "http://data.10jqka.com.cn/funds/hyzjl/",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "
"Chrome/90.0.4430.85 Safari/537.36",
"X-Requested-With": "XMLHttpRequest",
}
url = "http://data.10jqka.com.cn/funds/ggzjl/field/code/order/desc/ajax/1/free/1/"
r = requests.get(url, headers=headers)
soup = BeautifulSoup(r.text, features="lxml")
raw_page = soup.find(name="span", attrs={"class": "page_info"}).text
page_num = raw_page.split("/")[1]
if symbol == "3日排行":
url = "http://data.10jqka.com.cn/funds/ggzjl/board/3/field/zdf/order/desc/page/{}/ajax/1/free/1/"
elif symbol == "5日排行":
url = "http://data.10jqka.com.cn/funds/ggzjl/board/5/field/zdf/order/desc/page/{}/ajax/1/free/1/"
elif symbol == "10日排行":
url = "http://data.10jqka.com.cn/funds/ggzjl/board/10/field/zdf/order/desc/page/{}/ajax/1/free/1/"
elif symbol == "20日排行":
url = "http://data.10jqka.com.cn/funds/ggzjl/board/20/field/zdf/order/desc/page/{}/ajax/1/free/1/"
else:
url = "http://data.10jqka.com.cn/funds/ggzjl/field/zdf/order/desc/page/{}/ajax/1/free/1/"
big_df = pd.DataFrame()
tqdm = get_tqdm()
for page in tqdm(range(1, int(page_num) + 1), leave=False):
js_code = py_mini_racer.MiniRacer()
js_content = _get_file_content_ths("ths.js")
js_code.eval(js_content)
v_code = js_code.call("v")
headers = {
"Accept": "text/html, */*; q=0.01",
"Accept-Encoding": "gzip, deflate",
"Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8",
"Cache-Control": "no-cache",
"Connection": "keep-alive",
"hexin-v": v_code,
"Host": "data.10jqka.com.cn",
"Pragma": "no-cache",
"Referer": "http://data.10jqka.com.cn/funds/hyzjl/",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "
"Chrome/90.0.4430.85 Safari/537.36",
"X-Requested-With": "XMLHttpRequest",
}
r = requests.get(url.format(page), headers=headers)
temp_df = pd.read_html(StringIO(r.text))[0]
big_df = pd.concat(objs=[big_df, temp_df], ignore_index=True)
del big_df["序号"]
big_df.reset_index(inplace=True)
big_df["index"] = range(1, len(big_df) + 1)
if symbol == "即时":
big_df.columns = [
"序号",
"股票代码",
"股票简称",
"最新价",
"涨跌幅",
"换手率",
"流入资金",
"流出资金",
"净额",
"成交额",
]
else:
big_df.columns = [
"序号",
"股票代码",
"股票简称",
"最新价",
"阶段涨跌幅",
"连续换手率",
"资金流入净额",
]
return big_df
def stock_fund_flow_concept(symbol: str = "即时") -> pd.DataFrame:
"""
同花顺-数据中心-资金流向-概念资金流
https://data.10jqka.com.cn/funds/gnzjl/#refCountId=data_55f13c2c_254
:param symbol: choice of {“即时”, "3日排行", "5日排行", "10日排行", "20日排行"}
:type symbol: str
:return: 概念资金流
:rtype: pandas.DataFrame
"""
js_code = py_mini_racer.MiniRacer()
js_content = _get_file_content_ths("ths.js")
js_code.eval(js_content)
v_code = js_code.call("v")
headers = {
"Accept": "text/html, */*; q=0.01",
"Accept-Encoding": "gzip, deflate",
"Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8",
"Cache-Control": "no-cache",
"Connection": "keep-alive",
"hexin-v": v_code,
"Host": "data.10jqka.com.cn",
"Pragma": "no-cache",
"Referer": "http://data.10jqka.com.cn/funds/gnzjl/",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "
"Chrome/90.0.4430.85 Safari/537.36",
"X-Requested-With": "XMLHttpRequest",
}
url = (
"http://data.10jqka.com.cn/funds/gnzjl/field/tradezdf/order/desc/ajax/1/free/1/"
)
r = requests.get(url, headers=headers)
soup = BeautifulSoup(r.text, features="lxml")
raw_page = soup.find(name="span", attrs={"class": "page_info"}).text
page_num = raw_page.split("/")[1]
if symbol == "3日排行":
url = "http://data.10jqka.com.cn/funds/gnzjl/board/3/field/tradezdf/order/desc/page/{}/ajax/1/free/1/"
elif symbol == "5日排行":
url = "http://data.10jqka.com.cn/funds/gnzjl/board/5/field/tradezdf/order/desc/page/{}/ajax/1/free/1/"
elif symbol == "10日排行":
url = "http://data.10jqka.com.cn/funds/gnzjl/board/10/field/tradezdf/order/desc/page/{}/ajax/1/free/1/"
elif symbol == "20日排行":
url = "http://data.10jqka.com.cn/funds/gnzjl/board/20/field/tradezdf/order/desc/page/{}/ajax/1/free/1/"
else:
url = "http://data.10jqka.com.cn/funds/gnzjl/field/tradezdf/order/desc/page/{}/ajax/1/free/1/"
big_df = pd.DataFrame()
tqdm = get_tqdm()
for page in tqdm(range(1, int(page_num) + 1), leave=False):
js_code = py_mini_racer.MiniRacer()
js_content = _get_file_content_ths("ths.js")
js_code.eval(js_content)
v_code = js_code.call("v")
headers = {
"Accept": "text/html, */*; q=0.01",
"Accept-Encoding": "gzip, deflate",
"Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8",
"Cache-Control": "no-cache",
"Connection": "keep-alive",
"hexin-v": v_code,
"Host": "data.10jqka.com.cn",
"Pragma": "no-cache",
"Referer": "http://data.10jqka.com.cn/funds/gnzjl/",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "
"Chrome/90.0.4430.85 Safari/537.36",
"X-Requested-With": "XMLHttpRequest",
}
r = requests.get(url.format(page), headers=headers)
temp_df = pd.read_html(StringIO(r.text))[0]
big_df = pd.concat(objs=[big_df, temp_df], ignore_index=True)
del big_df["序号"]
big_df.reset_index(inplace=True)
big_df["index"] = range(1, len(big_df) + 1)
if symbol == "即时":
big_df.columns = [
"序号",
"行业",
"行业指数",
"行业-涨跌幅",
"流入资金",
"流出资金",
"净额",
"公司家数",
"领涨股",
"领涨股-涨跌幅",
"当前价",
]
big_df["行业-涨跌幅"] = big_df["行业-涨跌幅"].str.strip("%")
big_df["领涨股-涨跌幅"] = big_df["领涨股-涨跌幅"].str.strip("%")
big_df["行业-涨跌幅"] = pd.to_numeric(big_df["行业-涨跌幅"], errors="coerce")
big_df["领涨股-涨跌幅"] = pd.to_numeric(
big_df["领涨股-涨跌幅"], errors="coerce"
)
else:
big_df.columns = [
"序号",
"行业",
"公司家数",
"行业指数",
"阶段涨跌幅",
"流入资金",
"流出资金",
"净额",
]
return big_df
def stock_fund_flow_industry(symbol: str = "即时") -> pd.DataFrame:
"""
同花顺-数据中心-资金流向-行业资金流
https://data.10jqka.com.cn/funds/hyzjl/#refCountId=data_55f13c2c_254
:param symbol: choice of {“即时”, "3日排行", "5日排行", "10日排行", "20日排行"}
:type symbol: str
:return: 行业资金流
:rtype: pandas.DataFrame
"""
js_code = py_mini_racer.MiniRacer()
js_content = _get_file_content_ths("ths.js")
js_code.eval(js_content)
v_code = js_code.call("v")
headers = {
"Accept": "text/html, */*; q=0.01",
"Accept-Encoding": "gzip, deflate",
"Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8",
"Cache-Control": "no-cache",
"Connection": "keep-alive",
"hexin-v": v_code,
"Host": "data.10jqka.com.cn",
"Pragma": "no-cache",
"Referer": "http://data.10jqka.com.cn/funds/hyzjl/",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "
"Chrome/90.0.4430.85 Safari/537.36",
"X-Requested-With": "XMLHttpRequest",
}
url = (
"http://data.10jqka.com.cn/funds/hyzjl/field/tradezdf/order/desc/ajax/1/free/1/"
)
r = requests.get(url, headers=headers)
soup = BeautifulSoup(r.text, features="lxml")
raw_page = soup.find(name="span", attrs={"class": "page_info"}).text
page_num = raw_page.split("/")[1]
if symbol == "3日排行":
url = "http://data.10jqka.com.cn/funds/hyzjl/board/3/field/tradezdf/order/desc/page/{}/ajax/1/free/1/"
elif symbol == "5日排行":
url = "http://data.10jqka.com.cn/funds/hyzjl/board/5/field/tradezdf/order/desc/page/{}/ajax/1/free/1/"
elif symbol == "10日排行":
url = "http://data.10jqka.com.cn/funds/hyzjl/board/10/field/tradezdf/order/desc/page/{}/ajax/1/free/1/"
elif symbol == "20日排行":
url = "http://data.10jqka.com.cn/funds/hyzjl/board/20/field/tradezdf/order/desc/page/{}/ajax/1/free/1/"
else:
url = "http://data.10jqka.com.cn/funds/hyzjl/field/tradezdf/order/desc/page/{}/ajax/1/free/1/"
big_df = pd.DataFrame()
tqdm = get_tqdm()
for page in tqdm(range(1, int(page_num) + 1), leave=False):
js_code = py_mini_racer.MiniRacer()
js_content = _get_file_content_ths("ths.js")
js_code.eval(js_content)
v_code = js_code.call("v")
headers = {
"Accept": "text/html, */*; q=0.01",
"Accept-Encoding": "gzip, deflate",
"Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8",
"Cache-Control": "no-cache",
"Connection": "keep-alive",
"hexin-v": v_code,
"Host": "data.10jqka.com.cn",
"Pragma": "no-cache",
"Referer": "http://data.10jqka.com.cn/funds/hyzjl/",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "
"Chrome/90.0.4430.85 Safari/537.36",
"X-Requested-With": "XMLHttpRequest",
}
r = requests.get(url.format(page), headers=headers)
temp_df = pd.read_html(StringIO(r.text))[0]
big_df = pd.concat(objs=[big_df, temp_df], ignore_index=True)
del big_df["序号"]
big_df.reset_index(inplace=True)
big_df["index"] = range(1, len(big_df) + 1)
if symbol == "即时":
big_df.columns = [
"序号",
"行业",
"行业指数",
"行业-涨跌幅",
"流入资金",
"流出资金",
"净额",
"公司家数",
"领涨股",
"领涨股-涨跌幅",
"当前价",
]
big_df["行业-涨跌幅"] = big_df["行业-涨跌幅"].str.strip("%")
big_df["领涨股-涨跌幅"] = big_df["领涨股-涨跌幅"].str.strip("%")
big_df["行业-涨跌幅"] = pd.to_numeric(big_df["行业-涨跌幅"], errors="coerce")
big_df["领涨股-涨跌幅"] = pd.to_numeric(
big_df["领涨股-涨跌幅"], errors="coerce"
)
else:
big_df.columns = [
"序号",
"行业",
"公司家数",
"行业指数",
"阶段涨跌幅",
"流入资金",
"流出资金",
"净额",
]
return big_df
def stock_fund_flow_big_deal() -> pd.DataFrame:
"""
同花顺-数据中心-资金流向-大单追踪
https://data.10jqka.com.cn/funds/ddzz
:return: 大单追踪
:rtype: pandas.DataFrame
"""
js_code = py_mini_racer.MiniRacer()
js_content = _get_file_content_ths("ths.js")
js_code.eval(js_content)
v_code = js_code.call("v")
headers = {
"Accept": "text/html, */*; q=0.01",
"Accept-Encoding": "gzip, deflate",
"Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8",
"Cache-Control": "no-cache",
"Connection": "keep-alive",
"hexin-v": v_code,
"Host": "data.10jqka.com.cn",
"Pragma": "no-cache",
"Referer": "http://data.10jqka.com.cn/funds/hyzjl/",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "
"Chrome/90.0.4430.85 Safari/537.36",
"X-Requested-With": "XMLHttpRequest",
}
url = "http://data.10jqka.com.cn/funds/ddzz/order/desc/ajax/1/free/1/"
r = requests.get(url, headers=headers)
soup = BeautifulSoup(r.text, features="lxml")
raw_page = soup.find(name="span", attrs={"class": "page_info"}).text
page_num = raw_page.split("/")[1]
url = "http://data.10jqka.com.cn/funds/ddzz/order/asc/page/{}/ajax/1/free/1/"
big_df = pd.DataFrame()
tqdm = get_tqdm()
for page in tqdm(range(1, int(page_num) + 1), leave=False):
js_code = py_mini_racer.MiniRacer()
js_content = _get_file_content_ths("ths.js")
js_code.eval(js_content)
v_code = js_code.call("v")
headers = {
"Accept": "text/html, */*; q=0.01",
"Accept-Encoding": "gzip, deflate",
"Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8",
"Cache-Control": "no-cache",
"Connection": "keep-alive",
"hexin-v": v_code,
"Host": "data.10jqka.com.cn",
"Pragma": "no-cache",
"Referer": "http://data.10jqka.com.cn/funds/hyzjl/",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "
"Chrome/90.0.4430.85 Safari/537.36",
"X-Requested-With": "XMLHttpRequest",
}
r = requests.get(url.format(page), headers=headers)
temp_df = pd.read_html(StringIO(r.text))[0]
big_df = pd.concat(objs=[big_df, temp_df], ignore_index=True)
big_df.columns = [
"成交时间",
"股票代码",
"股票简称",
"成交价格",
"成交量",
"成交额",
"大单性质",
"涨跌幅",
"涨跌额",
"详细",
]
del big_df["详细"]
return big_df
if __name__ == "__main__":
# 同花顺-数据中心-资金流向-个股资金流
stock_fund_flow_individual_df = stock_fund_flow_individual(symbol="即时")
print(stock_fund_flow_individual_df)
stock_fund_flow_individual_df = stock_fund_flow_individual(symbol="3日排行")
print(stock_fund_flow_individual_df)
stock_fund_flow_individual_df = stock_fund_flow_individual(symbol="5日排行")
print(stock_fund_flow_individual_df)
stock_fund_flow_individual_df = stock_fund_flow_individual(symbol="10日排行")
print(stock_fund_flow_individual_df)
stock_fund_flow_individual_df = stock_fund_flow_individual(symbol="20日排行")
print(stock_fund_flow_individual_df)
# 同花顺-数据中心-资金流向-概念资金流
stock_fund_flow_concept_df = stock_fund_flow_concept(symbol="即时")
print(stock_fund_flow_concept_df)
stock_fund_flow_concept_df = stock_fund_flow_concept(symbol="3日排行")
print(stock_fund_flow_concept_df)
stock_fund_flow_concept_df = stock_fund_flow_concept(symbol="5日排行")
print(stock_fund_flow_concept_df)
stock_fund_flow_concept_df = stock_fund_flow_concept(symbol="10日排行")
print(stock_fund_flow_concept_df)
stock_fund_flow_concept_df = stock_fund_flow_concept(symbol="20日排行")
print(stock_fund_flow_concept_df)
# 同花顺-数据中心-资金流向-行业资金流
stock_fund_flow_industry_df = stock_fund_flow_industry(symbol="即时")
print(stock_fund_flow_industry_df)
stock_fund_flow_industry_df = stock_fund_flow_industry(symbol="3日排行")
print(stock_fund_flow_industry_df)
stock_fund_flow_industry_df = stock_fund_flow_industry(symbol="5日排行")
print(stock_fund_flow_industry_df)
stock_fund_flow_industry_df = stock_fund_flow_industry(symbol="10日排行")
print(stock_fund_flow_industry_df)
stock_fund_flow_industry_df = stock_fund_flow_industry(symbol="20日排行")
print(stock_fund_flow_industry_df)
# 同花顺-数据中心-资金流向-大单追踪
stock_fund_flow_big_deal_df = stock_fund_flow_big_deal()
print(stock_fund_flow_big_deal_df)
@@ -0,0 +1,100 @@
#!/usr/bin/env python
# -*- coding:utf-8 -*-
"""
Date: 2025/2/11 16:00
Desc: 东方财富网-数据中心-股东大会
https://data.eastmoney.com/gddh/
"""
import pandas as pd
import requests
from akshare.utils.tqdm import get_tqdm
def stock_gddh_em() -> pd.DataFrame:
"""
东方财富网-数据中心-股东大会
https://data.eastmoney.com/gddh/
:return: 股东大会
:rtype: pandas.DataFrame
"""
url = "https://datacenter-web.eastmoney.com/api/data/v1/get"
params = {
"sortColumns": "NOTICE_DATE",
"sortTypes": "-1",
"pageSize": "500",
"pageNumber": "1",
"reportName": "RPT_GENERALMEETING_DETAIL",
"columns": "SECURITY_CODE,SECURITY_NAME_ABBR,MEETING_TITLE,START_ADJUST_DATE,EQUITY_RECORD_DATE,"
"ONSITE_RECORD_DATE,DECISION_NOTICE_DATE,NOTICE_DATE,WEB_START_DATE,"
"WEB_END_DATE,SERIAL_NUM,PROPOSAL",
"filter": '(IS_LASTDATE="1")',
"source": "WEB",
"client": "WEB",
}
r = requests.get(url, params=params)
data_json = r.json()
total_page = data_json["result"]["pages"]
big_df = pd.DataFrame()
tqdm = get_tqdm()
for page in tqdm(range(1, total_page + 1), leave=False):
params.update(
{
"pageNumber": page,
}
)
r = requests.get(url, params=params)
data_json = r.json()
temp_df = pd.DataFrame(data_json["result"]["data"])
big_df = pd.concat(objs=[big_df, temp_df], axis=0, ignore_index=True)
big_df.rename(
columns={
"SECURITY_CODE": "代码",
"SECURITY_NAME_ABBR": "简称",
"MEETING_TITLE": "股东大会名称",
"START_ADJUST_DATE": "召开开始日",
"EQUITY_RECORD_DATE": "股权登记日",
"ONSITE_RECORD_DATE": "现场登记日",
"DECISION_NOTICE_DATE": "决议公告日",
"NOTICE_DATE": "公告日",
"WEB_START_DATE": "网络投票时间-开始日",
"WEB_END_DATE": "网络投票时间-结束日",
"SERIAL_NUM": "序列号",
"PROPOSAL": "提案",
},
inplace=True,
)
big_df = big_df[
[
"代码",
"简称",
"股东大会名称",
"召开开始日",
"股权登记日",
"现场登记日",
"网络投票时间-开始日",
"网络投票时间-结束日",
"决议公告日",
"公告日",
"序列号",
"提案",
]
]
big_df["召开开始日"] = pd.to_datetime(big_df["召开开始日"], errors="coerce").dt.date
big_df["股权登记日"] = pd.to_datetime(big_df["股权登记日"], errors="coerce").dt.date
big_df["现场登记日"] = pd.to_datetime(big_df["现场登记日"], errors="coerce").dt.date
big_df["网络投票时间-开始日"] = pd.to_datetime(
big_df["网络投票时间-开始日"], errors="coerce"
).dt.date
big_df["网络投票时间-结束日"] = pd.to_datetime(
big_df["网络投票时间-结束日"], errors="coerce"
).dt.date
big_df["决议公告日"] = pd.to_datetime(big_df["决议公告日"], errors="coerce").dt.date
big_df["公告日"] = pd.to_datetime(big_df["公告日"], errors="coerce").dt.date
big_df["提案"] = big_df["提案"].str.replace("\r\n2", "").str.replace("\r\n3", "")
return big_df
if __name__ == "__main__":
stock_gddh_em_df = stock_gddh_em()
print(stock_gddh_em_df)
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,235 @@
#!/usr/bin/env python
# -*- coding:utf-8 -*-
"""
Date: 2024/10/1 22:00
Desc: 东方财富网-数据中心-特色数据-股东户数
https://data.eastmoney.com/gdhs/
"""
import pandas as pd
import requests
from akshare.utils.tqdm import get_tqdm
def stock_zh_a_gdhs(symbol: str = "20230930") -> pd.DataFrame:
"""
东方财富网-数据中心-特色数据-股东户数
https://data.eastmoney.com/gdhs/
:param symbol: choice of {"最新", "每个季度末"}, 其中 每个季度末需要写成 `20230930` 格式
:type symbol: str
:return: 股东户数
:rtype: pandas.DataFrame
"""
url = "https://datacenter-web.eastmoney.com/api/data/v1/get"
if symbol == "最新":
params = {
"sortColumns": "HOLD_NOTICE_DATE,SECURITY_CODE",
"sortTypes": "-1,-1",
"pageSize": "500",
"pageNumber": "1",
"reportName": "RPT_HOLDERNUMLATEST",
"columns": "SECURITY_CODE,SECURITY_NAME_ABBR,END_DATE,INTERVAL_CHRATE,AVG_MARKET_CAP,AVG_HOLD_NUM,"
"TOTAL_MARKET_CAP,TOTAL_A_SHARES,HOLD_NOTICE_DATE,HOLDER_NUM,PRE_HOLDER_NUM,"
"HOLDER_NUM_CHANGE,HOLDER_NUM_RATIO,END_DATE,PRE_END_DATE",
"quoteColumns": "f2,f3",
"source": "WEB",
"client": "WEB",
}
else:
params = {
"sortColumns": "HOLD_NOTICE_DATE,SECURITY_CODE",
"sortTypes": "-1,-1",
"pageSize": "500",
"pageNumber": "1",
"reportName": "RPT_HOLDERNUM_DET",
"columns": "SECURITY_CODE,SECURITY_NAME_ABBR,END_DATE,INTERVAL_CHRATE,AVG_MARKET_CAP,"
"AVG_HOLD_NUM,TOTAL_MARKET_CAP,TOTAL_A_SHARES,HOLD_NOTICE_DATE,HOLDER_NUM,"
"PRE_HOLDER_NUM,HOLDER_NUM_CHANGE,HOLDER_NUM_RATIO,END_DATE,PRE_END_DATE",
"quoteColumns": "f2,f3",
"source": "WEB",
"client": "WEB",
"filter": f"(END_DATE='{symbol[:4] + '-' + symbol[4:6] + '-' + symbol[6:]}')",
}
r = requests.get(url, params=params)
data_json = r.json()
total_page_num = data_json["result"]["pages"]
big_df = pd.DataFrame()
tqdm = get_tqdm()
for page_num in tqdm(range(1, total_page_num + 1), leave=False):
params.update(
{
"pageNumber": page_num,
}
)
r = requests.get(url, params=params)
data_json = r.json()
temp_df = pd.DataFrame(data_json["result"]["data"])
big_df = pd.concat(objs=[big_df, temp_df], ignore_index=True)
big_df.columns = [
"代码",
"名称",
"股东户数统计截止日-本次",
"区间涨跌幅",
"户均持股市值",
"户均持股数量",
"总市值",
"总股本",
"公告日期",
"股东户数-本次",
"股东户数-上次",
"股东户数-增减",
"股东户数-增减比例",
"股东户数统计截止日-上次",
"最新价",
"涨跌幅",
]
big_df = big_df[
[
"代码",
"名称",
"最新价",
"涨跌幅",
"股东户数-本次",
"股东户数-上次",
"股东户数-增减",
"股东户数-增减比例",
"区间涨跌幅",
"股东户数统计截止日-本次",
"股东户数统计截止日-上次",
"户均持股市值",
"户均持股数量",
"总市值",
"总股本",
"公告日期",
]
]
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["股东户数-增减"], errors="coerce")
big_df["股东户数-增减比例"] = pd.to_numeric(
big_df["股东户数-增减比例"], errors="coerce"
)
big_df["区间涨跌幅"] = pd.to_numeric(big_df["区间涨跌幅"], errors="coerce")
big_df["股东户数统计截止日-本次"] = pd.to_datetime(
big_df["股东户数统计截止日-本次"], errors="coerce"
).dt.date
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_datetime(big_df["公告日期"], errors="coerce").dt.date
return big_df
def stock_zh_a_gdhs_detail_em(symbol: str = "000001") -> pd.DataFrame:
"""
东方财富网-数据中心-特色数据-股东户数详情
https://data.eastmoney.com/gdhs/detail/000002.html
:param symbol: 股票代码
:type symbol: str
:return: 股东户数
:rtype: pandas.DataFrame
"""
url = "https://datacenter-web.eastmoney.com/api/data/v1/get"
params = {
"sortColumns": "END_DATE",
"sortTypes": "-1",
"pageSize": "500",
"pageNumber": "1",
"reportName": "RPT_HOLDERNUM_DET",
"columns": "SECURITY_CODE,SECURITY_NAME_ABBR,CHANGE_SHARES,CHANGE_REASON,END_DATE,INTERVAL_CHRATE,"
"AVG_MARKET_CAP,AVG_HOLD_NUM,TOTAL_MARKET_CAP,TOTAL_A_SHARES,HOLD_NOTICE_DATE,HOLDER_NUM,"
"PRE_HOLDER_NUM,HOLDER_NUM_CHANGE,HOLDER_NUM_RATIO,END_DATE,PRE_END_DATE",
"quoteColumns": "f2,f3",
"filter": f'(SECURITY_CODE="{symbol}")',
"source": "WEB",
"client": "WEB",
}
r = requests.get(url, params=params)
data_json = r.json()
total_page_num = data_json["result"]["pages"]
big_df = pd.DataFrame()
tqdm = get_tqdm()
for page_num in tqdm(range(1, total_page_num + 1), leave=False):
params.update(
{
"pageNumber": page_num,
}
)
r = requests.get(url, params=params)
data_json = r.json()
temp_df = pd.DataFrame(data_json["result"]["data"])
big_df = pd.concat(objs=[big_df, temp_df], ignore_index=True)
big_df.columns = [
"代码",
"名称",
"股本变动",
"股本变动原因",
"股东户数统计截止日",
"区间涨跌幅",
"户均持股市值",
"户均持股数量",
"总市值",
"总股本",
"股东户数公告日期",
"股东户数-本次",
"股东户数-上次",
"股东户数-增减",
"股东户数-增减比例",
"-",
"-",
"-",
]
big_df = big_df[
[
"股东户数统计截止日",
"区间涨跌幅",
"股东户数-本次",
"股东户数-上次",
"股东户数-增减",
"股东户数-增减比例",
"户均持股市值",
"户均持股数量",
"总市值",
"总股本",
"股本变动",
"股本变动原因",
"股东户数公告日期",
"代码",
"名称",
]
]
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["股东户数-增减比例"], 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["总股本"], errors="coerce")
big_df["股本变动"] = pd.to_numeric(big_df["股本变动"], errors="coerce")
big_df["股东户数统计截止日"] = pd.to_datetime(
big_df["股东户数统计截止日"], errors="coerce"
).dt.date
big_df["股东户数公告日期"] = pd.to_datetime(
big_df["股东户数公告日期"], errors="coerce"
).dt.date
big_df.sort_values(by=["股东户数统计截止日"], ignore_index=True, inplace=True)
return big_df
if __name__ == "__main__":
stock_zh_a_gdhs_df = stock_zh_a_gdhs(symbol="20230930")
print(stock_zh_a_gdhs_df)
stock_zh_a_gdhs_detail_em_df = stock_zh_a_gdhs_detail_em(symbol="002631")
print(stock_zh_a_gdhs_detail_em_df)
@@ -0,0 +1,133 @@
#!/usr/bin/env python
# -*- coding:utf-8 -*-
"""
Date: 2025/6/16 18:03
Desc: 东方财富网-数据中心-特色数据-高管持股
https://data.eastmoney.com/executive/gdzjc.html
"""
import pandas as pd
import requests
from akshare.utils.tqdm import get_tqdm
def stock_ggcg_em(symbol: str = "全部") -> pd.DataFrame:
"""
东方财富网-数据中心-特色数据-高管持股
https://data.eastmoney.com/executive/gdzjc.html
:param symbol: choice of {"全部", "股东增持", "股东减持"}
:type symbol: str
:return: 高管持股
:rtype: pandas.DataFrame
"""
symbol_map = {
"全部": "",
"股东增持": '(DIRECTION="增持")',
"股东减持": '(DIRECTION="减持")',
}
url = "https://datacenter-web.eastmoney.com/api/data/v1/get"
params = {
"sortColumns": "END_DATE,SECURITY_CODE,EITIME",
"sortTypes": "-1,-1,-1",
"pageSize": "500",
"pageNumber": "1",
"reportName": "RPT_SHARE_HOLDER_INCREASE",
"quoteColumns": "f2~01~SECURITY_CODE~NEWEST_PRICE,f3~01~SECURITY_CODE~CHANGE_RATE_QUOTES",
"quoteType": "0",
"columns": "ALL",
"source": "WEB",
"client": "WEB",
"filter": symbol_map[symbol],
}
r = requests.get(url, params=params)
data_json = r.json()
total_page = data_json["result"]["pages"]
big_df = pd.DataFrame()
tqdm = get_tqdm()
for page in tqdm(range(1, total_page + 1), leave=False):
params.update(
{
"pageNumber": page,
}
)
r = requests.get(url, params=params)
data_json = r.json()
temp_df = pd.DataFrame(data_json["result"]["data"])
big_df = pd.concat(objs=[big_df, temp_df], ignore_index=True)
big_df.columns = [
"持股变动信息-变动数量",
"公告日",
"代码",
"股东名称",
"持股变动信息-占总股本比例",
"_",
"-",
"变动截止日",
"-",
"变动后持股情况-持股总数",
"变动后持股情况-占总股本比例",
"_",
"变动后持股情况-占流通股比例",
"变动后持股情况-持流通股数",
"_",
"名称",
"持股变动信息-增减",
"_",
"持股变动信息-占流通股比例",
"变动开始日",
"_",
"最新价",
"涨跌幅",
"_",
]
big_df = big_df[
[
"代码",
"名称",
"最新价",
"涨跌幅",
"股东名称",
"持股变动信息-增减",
"持股变动信息-变动数量",
"持股变动信息-占总股本比例",
"持股变动信息-占流通股比例",
"变动后持股情况-持股总数",
"变动后持股情况-占总股本比例",
"变动后持股情况-持流通股数",
"变动后持股情况-占流通股比例",
"变动开始日",
"变动截止日",
"公告日",
]
]
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["持股变动信息-变动数量"])
big_df["持股变动信息-占总股本比例"] = pd.to_numeric(
big_df["持股变动信息-占总股本比例"]
)
big_df["持股变动信息-占流通股比例"] = pd.to_numeric(
big_df["持股变动信息-占流通股比例"]
)
big_df["变动后持股情况-持股总数"] = pd.to_numeric(big_df["变动后持股情况-持股总数"])
big_df["变动后持股情况-占总股本比例"] = pd.to_numeric(
big_df["变动后持股情况-占总股本比例"]
)
big_df["变动后持股情况-持流通股数"] = pd.to_numeric(
big_df["变动后持股情况-持流通股数"]
)
big_df["变动后持股情况-占流通股比例"] = pd.to_numeric(
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
return big_df
if __name__ == "__main__":
stock_ggcg_em_df = stock_ggcg_em(symbol="股东增持")
print(stock_ggcg_em_df)
@@ -0,0 +1,532 @@
#!/usr/bin/env python
# -*- coding:utf-8 -*-
"""
Date: 2024/12/18 17:30
Desc: 东方财富网-数据中心-特色数据-股权质押
东方财富网-数据中心-特色数据-股权质押-股权质押市场概况: https://data.eastmoney.com/gpzy/marketProfile.aspx
东方财富网-数据中心-特色数据-股权质押-上市公司质押比例: https://data.eastmoney.com/gpzy/pledgeRatio.aspx
东方财富网-数据中心-特色数据-股权质押-重要股东股权质押明细: https://data.eastmoney.com/gpzy/pledgeDetail.aspx
东方财富网-数据中心-特色数据-股权质押-质押机构分布统计-证券公司: https://data.eastmoney.com/gpzy/distributeStatistics.aspx
东方财富网-数据中心-特色数据-股权质押-质押机构分布统计-银行: https://data.eastmoney.com/gpzy/distributeStatistics.aspx
东方财富网-数据中心-特色数据-股权质押-行业数据: https://data.eastmoney.com/gpzy/industryData.aspx
"""
import math
import pandas as pd
import requests
from akshare.utils.tqdm import get_tqdm
def stock_gpzy_profile_em() -> pd.DataFrame:
"""
东方财富网-数据中心-特色数据-股权质押-股权质押市场概况
https://data.eastmoney.com/gpzy/marketProfile.aspx
:return: 股权质押市场概况
:rtype: pandas.DataFrame
"""
url = "https://datacenter-web.eastmoney.com/api/data/v1/get"
params = {
"sortColumns": "TRADE_DATE",
"sortTypes": "-1",
"pageSize": "500",
"pageNumber": "1",
"reportName": "RPT_CSDC_STATISTICS",
"columns": "ALL",
"quoteColumns": "",
"source": "WEB",
"client": "WEB",
}
r = requests.get(url, params=params)
data_json = r.json()
total_page = data_json["result"]["pages"]
big_df = pd.DataFrame()
for page in range(1, total_page + 1):
params.update({"pageNumber": page})
r = requests.get(url, params=params)
data_json = r.json()
temp_df = pd.DataFrame(data_json["result"]["data"])
big_df = pd.concat(objs=[big_df, temp_df], ignore_index=True)
big_df.columns = [
"交易日期",
"质押总股数",
"质押总市值",
"沪深300指数",
"涨跌幅",
"A股质押总比例",
"质押公司数量",
"质押笔数",
]
big_df = big_df[
[
"交易日期",
"A股质押总比例",
"质押公司数量",
"质押笔数",
"质押总股数",
"质押总市值",
"沪深300指数",
"涨跌幅",
]
]
big_df["交易日期"] = pd.to_datetime(big_df["交易日期"], errors="coerce").dt.date
big_df["A股质押总比例"] = pd.to_numeric(big_df["A股质押总比例"], 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["质押总市值"], errors="coerce")
big_df["沪深300指数"] = pd.to_numeric(big_df["沪深300指数"], errors="coerce")
big_df["涨跌幅"] = pd.to_numeric(big_df["涨跌幅"], errors="coerce")
big_df["A股质押总比例"] = big_df["A股质押总比例"] / 100
big_df["A股质押总比例"] = pd.to_numeric(big_df["A股质押总比例"], errors="coerce")
big_df.sort_values(["交易日期"], inplace=True)
big_df.reset_index(inplace=True, drop=True)
return big_df
def stock_gpzy_pledge_ratio_em(date: str = "20240906") -> pd.DataFrame:
"""
东方财富网-数据中心-特色数据-股权质押-上市公司质押比例
https://data.eastmoney.com/gpzy/pledgeRatio.aspx
:param date: 指定交易日, 访问 https://data.eastmoney.com/gpzy/pledgeRatio.aspx 查询
:type date: str
:return: 上市公司质押比例
:rtype: pandas.DataFrame
"""
trade_date = "-".join([date[:4], date[4:6], date[6:]])
url = "https://datacenter-web.eastmoney.com/api/data/v1/get"
params = {
"sortColumns": "PLEDGE_RATIO",
"sortTypes": "-1",
"pageSize": "500",
"pageNumber": "1",
"reportName": "RPT_CSDC_LIST",
"columns": "ALL",
"quoteColumns": "",
"source": "WEB",
"client": "WEB",
"filter": f"(TRADE_DATE='{trade_date}')",
}
r = requests.get(url, params=params)
data_json = r.json()
total_page = data_json["result"]["pages"]
big_df = pd.DataFrame()
tqdm = get_tqdm()
for page in tqdm(range(1, total_page + 1), leave=False):
params.update({"pageNumber": page})
r = requests.get(url, params=params)
data_json = r.json()
temp_df = pd.DataFrame(data_json["result"]["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 = big_df[
[
"序号",
"股票代码",
"股票简称",
"交易日期",
"所属行业",
"质押比例",
"质押股数",
"质押市值",
"质押笔数",
"无限售股质押数",
"限售股质押数",
"近一年涨跌幅",
"所属行业代码",
]
]
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["无限售股质押数"], errors="coerce")
big_df["限售股质押数"] = pd.to_numeric(big_df["限售股质押数"], errors="coerce")
big_df["近一年涨跌幅"] = pd.to_numeric(big_df["近一年涨跌幅"], errors="coerce")
big_df["交易日期"] = pd.to_datetime(big_df["交易日期"], errors="coerce").dt.date
return big_df
def _get_page_num_gpzy_market_pledge_ratio_detail(filter: str = None) -> int:
"""
东方财富网-数据中心-特色数据-股权质押-重要股东股权质押明细
https://data.eastmoney.com/gpzy/pledgeDetail.aspx
:return: int 获取 重要股东股权质押明细 的总页数
"""
url = "https://datacenter-web.eastmoney.com/api/data/v1/get"
params = {
"sortColumns": "NOTICE_DATE",
"sortTypes": "-1",
"pageSize": "500",
"pageNumber": "1",
"reportName": "RPTA_APP_ACCUMDETAILS",
"columns": "ALL",
"quoteColumns": "",
"source": "WEB",
"client": "WEB",
"filter": filter,
}
r = requests.get(url, params=params)
data_json = r.json()
total_page = math.ceil(int(data_json["result"]["count"]) / 500)
return total_page
def _stock_gpzy_pledge_ratio_detail_em(filter: str = None) -> pd.DataFrame:
"""
东方财富网-数据中心-特色数据-股权质押-重要股东股权质押明细
https://data.eastmoney.com/gpzy/pledgeDetail.aspx
:return: pandas.DataFrame
"""
url = "https://datacenter-web.eastmoney.com/api/data/v1/get"
total_page = _get_page_num_gpzy_market_pledge_ratio_detail(filter)
big_df = pd.DataFrame()
tqdm = get_tqdm()
for page in tqdm(range(1, total_page + 1), leave=False):
params = {
"sortColumns": "NOTICE_DATE",
"sortTypes": "-1",
"pageSize": "500",
"pageNumber": page,
"reportName": "RPTA_APP_ACCUMDETAILS",
"columns": "ALL",
"quoteColumns": "",
"source": "WEB",
"client": "WEB",
"filter": filter,
}
r = requests.get(url, params=params)
data_json = r.json()
temp_df = pd.DataFrame(data_json["result"]["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 = big_df[
[
"序号",
"股票代码",
"股票简称",
"股东名称",
"质押股份数量",
"占所持股份比例",
"占总股本比例",
"质押机构",
"最新价",
"质押日收盘价",
"预估平仓线",
"质押开始日期",
"质押结束日期",
"状态",
"公告日期",
]
]
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["质押日收盘价"], errors="coerce")
big_df["预估平仓线"] = pd.to_numeric(big_df["预估平仓线"], errors="coerce")
big_df["公告日期"] = pd.to_datetime(big_df["公告日期"], errors="coerce").dt.date
big_df["质押开始日期"] = pd.to_datetime(
big_df["质押开始日期"], errors="coerce"
).dt.date
big_df["质押结束日期"] = pd.to_datetime(
big_df["质押结束日期"], errors="coerce"
).dt.date
return big_df
def stock_gpzy_pledge_ratio_detail_em() -> pd.DataFrame:
return _stock_gpzy_pledge_ratio_detail_em()
def stock_gpzy_individual_pledge_ratio_detail_em(symbol: str) -> pd.DataFrame:
return _stock_gpzy_pledge_ratio_detail_em(filter=f'(SECURITY_CODE="{symbol}")')
def stock_gpzy_distribute_statistics_company_em() -> pd.DataFrame:
"""
东方财富网-数据中心-特色数据-股权质押-质押机构分布统计-证券公司
https://data.eastmoney.com/gpzy/distributeStatistics.aspx
:return: 质押机构分布统计-证券公司
:rtype: pandas.DataFrame
"""
url = "https://datacenter-web.eastmoney.com/api/data/v1/get"
params = {
"sortColumns": "ORG_NUM",
"sortTypes": "-1",
"pageSize": "500",
"pageNumber": "1",
"reportName": "RPT_GDZY_ZYJG_SUM",
"columns": "ALL",
"quoteColumns": "",
"source": "WEB",
"client": "WEB",
"filter": '(PFORG_TYPE="证券")',
}
r = requests.get(url, params=params)
data_json = r.json()
temp_df = pd.DataFrame(data_json["result"]["data"])
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")
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 stock_gpzy_distribute_statistics_bank_em() -> pd.DataFrame:
"""
东方财富网-数据中心-特色数据-股权质押-质押机构分布统计-银行
https://data.eastmoney.com/gpzy/distributeStatistics.aspx
:return: 质押机构分布统计-银行
:rtype: pandas.DataFrame
"""
url = "https://datacenter-web.eastmoney.com/api/data/v1/get"
params = {
"sortColumns": "ORG_NUM",
"sortTypes": "-1",
"pageSize": "500",
"pageNumber": "1",
"reportName": "RPT_GDZY_ZYJG_SUM",
"columns": "ALL",
"quoteColumns": "",
"source": "WEB",
"client": "WEB",
"filter": '(PFORG_TYPE="银行")',
}
r = requests.get(url, params=params)
data_json = r.json()
temp_df = pd.DataFrame(data_json["result"]["data"])
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")
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 stock_gpzy_industry_data_em() -> pd.DataFrame:
"""
东方财富网-数据中心-特色数据-股权质押-上市公司质押比例-行业数据
https://data.eastmoney.com/gpzy/industryData.aspx
:return: pandas.DataFrame
"""
url = "https://datacenter-web.eastmoney.com/api/data/v1/get"
params = {
"sortColumns": "AVERAGE_PLEDGE_RATIO",
"sortTypes": "-1",
"pageSize": "500",
"pageNumber": "1",
"reportName": "RPT_CSDC_INDUSTRY_STATISTICS",
"columns": "INDUSTRY_CODE,INDUSTRY,TRADE_DATE,AVERAGE_PLEDGE_RATIO,ORG_NUM,PLEDGE_TOTAL_NUM,"
"TOTAL_PLEDGE_SHARES,PLEDGE_TOTAL_MARKETCAP",
"quoteColumns": "",
"source": "WEB",
"client": "WEB",
}
r = requests.get(url, params=params)
data_json = r.json()
temp_df = pd.DataFrame(data_json["result"]["data"])
temp_df.reset_index(inplace=True)
temp_df["index"] = temp_df.index + 1
temp_df.columns = [
"序号",
"-",
"行业",
"统计时间",
"平均质押比例",
"公司家数",
"质押总笔数",
"质押总股本",
"最新质押市值",
]
temp_df = temp_df[
[
"序号",
"行业",
"平均质押比例",
"公司家数",
"质押总笔数",
"质押总股本",
"最新质押市值",
"统计时间",
]
]
temp_df["统计时间"] = pd.to_datetime(temp_df["统计时间"], errors="coerce").dt.date
temp_df["平均质押比例"] = pd.to_numeric(temp_df["平均质押比例"], errors="coerce")
temp_df["公司家数"] = pd.to_numeric(temp_df["公司家数"], errors="coerce")
temp_df["质押总笔数"] = pd.to_numeric(temp_df["质押总笔数"], errors="coerce")
temp_df["质押总股本"] = pd.to_numeric(temp_df["质押总股本"], errors="coerce")
temp_df["最新质押市值"] = pd.to_numeric(temp_df["最新质押市值"], errors="coerce")
return temp_df
if __name__ == "__main__":
stock_gpzy_profile_em_df = stock_gpzy_profile_em()
print(stock_gpzy_profile_em_df)
stock_em_gpzy_pledge_ratio_df = stock_gpzy_pledge_ratio_em(date="20241220")
print(stock_em_gpzy_pledge_ratio_df)
stock_gpzy_pledge_ratio_detail_em_df = stock_gpzy_pledge_ratio_detail_em()
print(stock_gpzy_pledge_ratio_detail_em_df)
stock_gpzy_individual_pledge_ratio_detail_em_df = (
stock_gpzy_individual_pledge_ratio_detail_em(symbol="603132")
)
print(stock_gpzy_individual_pledge_ratio_detail_em_df)
stock_em_gpzy_distribute_statistics_company_df = (
stock_gpzy_distribute_statistics_company_em()
)
print(stock_em_gpzy_distribute_statistics_company_df)
stock_em_gpzy_distribute_statistics_bank_df = (
stock_gpzy_distribute_statistics_bank_em()
)
print(stock_em_gpzy_distribute_statistics_bank_df)
stock_gpzy_industry_data_em_df = stock_gpzy_industry_data_em()
print(stock_gpzy_industry_data_em_df)
@@ -0,0 +1,94 @@
#!/usr/bin/env python
# -*- coding:utf-8 -*-
"""
Date: 2026/4/3 16:05
Desc: 乐咕乐股-股息率-A 股股息率
https://legulegu.com/stockdata/guxilv
"""
import pandas as pd
import requests
from akshare.stock_feature.stock_a_indicator import get_token_lg, get_cookie_csrf
def stock_a_gxl_lg(symbol: str = "上证A股") -> pd.DataFrame:
"""
乐咕乐股-股息率-A 股股息率
https://legulegu.com/stockdata/guxilv
:param symbol: choice of {"上证A股", "深证A股", "创业板", "科创板"}
:type symbol: str
:return: A 股股息率
:rtype: pandas.DataFrame
"""
symbol_map = {
"上证A股": "shangzheng",
"深证A股": "shenzheng",
"创业板": "chuangyeban",
"科创板": "kechuangban",
}
url = "https://legulegu.com/api/stockdata/guxilv"
token = get_token_lg()
params = {"token": token}
r = requests.get(
url,
params=params,
**get_cookie_csrf(url="https://legulegu.com/stockdata/guxilv"),
)
data_json = r.json()
temp_df = pd.DataFrame(data_json[symbol_map[symbol]])
temp_df["date"] = (
pd.to_datetime(temp_df["date"], utc=True)
.dt.tz_convert("Asia/Shanghai")
.dt.date
)
temp_df.rename(columns={"addDvTtm": "股息率", "date": "日期"}, inplace=True)
temp_df = temp_df[
[
"日期",
"股息率",
]
]
temp_df["股息率"] = pd.to_numeric(temp_df["股息率"], errors="coerce")
return temp_df
def stock_hk_gxl_lg() -> pd.DataFrame:
"""
乐咕乐股-股息率-恒生指数股息率
https://legulegu.com/stockdata/market/hk/dv/hsi
:return: 恒生指数股息率
:rtype: pandas.DataFrame
"""
url = "https://legulegu.com/api/stockdata/hs"
token = get_token_lg()
params = {"token": token, "indexCode": "HSI"}
r = requests.get(
url,
params=params,
**get_cookie_csrf(url="https://legulegu.com/stockdata/market/hk/dv/hsi"),
)
data_json = r.json()
temp_df = pd.DataFrame(data_json)
temp_df["date"] = (
pd.to_datetime(temp_df["date"], utc=True)
.dt.tz_convert("Asia/Shanghai")
.dt.date
)
temp_df.rename(columns={"dvRatio": "股息率", "date": "日期"}, inplace=True)
temp_df = temp_df[
[
"日期",
"股息率",
]
]
temp_df["股息率"] = pd.to_numeric(temp_df["股息率"], errors="coerce")
return temp_df
if __name__ == "__main__":
stock_a_gxl_lg_df = stock_a_gxl_lg(symbol="上证A股")
print(stock_a_gxl_lg_df)
stock_hk_gxl_lg_df = stock_hk_gxl_lg()
print(stock_hk_gxl_lg_df)
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,91 @@
#!/usr/bin/env python
# -*- coding:utf-8 -*-
"""
Date: 2025/10/15 22:30
Desc: 腾讯证券-行情首页-沪深京A股
https://quote.eastmoney.com/
"""
import datetime
import pandas as pd
import requests
from akshare.index.index_stock_zh import get_tx_start_year
from akshare.utils import demjson
from akshare.utils.tqdm import get_tqdm
def stock_zh_a_hist_tx(
symbol: str = "sz000001",
start_date: str = "19000101",
end_date: str = "20500101",
adjust: str = "",
timeout: float = None,
) -> pd.DataFrame:
"""
腾讯证券-日频-股票历史数据
https://gu.qq.com/sh000919/zs
:param symbol: 带市场标识的股票或者指数代码
:type symbol: str
:param start_date: 开始日期
:type start_date: str
:param end_date: 结束日期
:type end_date: str
:param adjust: choice of {"qfq": "前复权", "hfq": "后复权", "": "不复权"}
:type adjust: str
:param timeout: choice of None or a positive float number
:type timeout: float
:return: 前复权的股票和指数数据
:rtype: pandas.DataFrame
"""
init_start_date = get_tx_start_year(symbol=symbol)
if int(start_date.replace("-", "")) < int(init_start_date.replace("-", "")):
start_date = init_start_date
url = "https://proxy.finance.qq.com/ifzqgtimg/appstock/app/newfqkline/get"
range_start = int(start_date[:4])
if int(end_date.split("-")[0]) > datetime.date.today().year:
range_end = datetime.date.today().year + 1
else:
range_end = int(end_date.split("-")[0]) + 1
big_df = pd.DataFrame()
tqdm = get_tqdm()
for year in tqdm(range(range_start, range_end), leave=False):
params = {
"_var": f"kline_day{adjust}{year}",
"param": f"{symbol},day,{year}-01-01,{year + 1}-12-31,640,{adjust}",
"r": "0.8205512681390605",
}
r = requests.get(url, params=params, timeout=timeout)
data_text = r.text
data_json = demjson.decode(data_text[data_text.find("={") + 1 :])["data"][
symbol
]
if "day" in data_json.keys():
temp_df = pd.DataFrame(data_json["day"])
elif "hfqday" in data_json.keys():
temp_df = pd.DataFrame(data_json["hfqday"])
else:
temp_df = pd.DataFrame(data_json["qfqday"])
big_df = pd.concat([big_df, temp_df], ignore_index=True)
big_df = big_df.iloc[:, :6]
big_df.columns = ["date", "open", "close", "high", "low", "amount"]
big_df["date"] = pd.to_datetime(big_df["date"], errors="coerce").dt.date
big_df["open"] = pd.to_numeric(big_df["open"], errors="coerce")
big_df["close"] = pd.to_numeric(big_df["close"], errors="coerce")
big_df["high"] = pd.to_numeric(big_df["high"], errors="coerce")
big_df["low"] = pd.to_numeric(big_df["low"], errors="coerce")
big_df["amount"] = pd.to_numeric(big_df["amount"], errors="coerce")
big_df.drop_duplicates(inplace=True, ignore_index=True)
big_df.index = pd.to_datetime(big_df["date"], errors="coerce")
big_df.sort_index(inplace=True)
big_df = big_df[start_date:end_date]
big_df.reset_index(inplace=True, drop=True)
return big_df
if __name__ == "__main__":
stock_zh_a_hist_tx_df = stock_zh_a_hist_tx(
symbol="sz000001", start_date="20200101", end_date="20231027", adjust="hfq"
)
print(stock_zh_a_hist_tx_df)
@@ -0,0 +1,65 @@
#!/usr/bin/env python
# -*- coding:utf-8 -*-
"""
Date: 2024/11/21 18:26
Desc: 百度股市通-港股-财务报表-估值数据
https://gushitong.baidu.com/stock/hk-06969
"""
from curl_cffi import requests
import json
import urllib
import pandas as pd
def stock_hk_valuation_baidu(
symbol: str = "06969", indicator: str = "总市值", period: str = "近一年"
) -> pd.DataFrame:
"""
百度股市通-港股-财务报表-估值数据
https://gushitong.baidu.com/stock/hk-06969
:param symbol: 股票代码
:type symbol: str
:param indicator: choice of {"总市值", "市盈率(TTM)", "市盈率(静)", "市净率", "市现率"}
:type indicator: str
:param period: choice of {"近一年", "近三年", "全部"}
:type period: str
:return: 估值数据
:rtype: pandas.DataFrame
"""
url = "https://finance.baidu.com/opendata"
params = {
"openapi": "1",
"dspName": "iphone",
"tn": "tangram",
"client": "app",
"query": indicator,
"code": symbol,
"word": "",
"resource_id": "51171",
"market": "hk",
"tag": indicator,
"chart_select": period,
"industry_select": "",
"skip_industry": "1",
"finClientType": "pc",
}
r = requests.get(url, params=params)
data_json = r.json()
temp_df = pd.DataFrame(
data_json["Result"][0]["DisplayData"]["resultData"]["tplData"]["result"][
"chartInfo"
][0]["body"]
)
temp_df.columns = ["date", "value"]
temp_df["date"] = pd.to_datetime(temp_df["date"]).dt.date
temp_df["value"] = pd.to_numeric(temp_df["value"])
return temp_df
if __name__ == "__main__":
stock_hk_valuation_baidu_df = stock_hk_valuation_baidu(
symbol="06969", indicator="总市值", period="近三年"
)
print(stock_hk_valuation_baidu_df)
@@ -0,0 +1,286 @@
# -*- coding:utf-8 -*-
# !/usr/bin/env python
"""
Date: 2024/1/7 17:00
Desc: 雪球-沪深股市-热度排行榜
https://xueqiu.com/hq
"""
import math
import pandas as pd
import requests
from akshare.utils.tqdm import get_tqdm
def stock_hot_follow_xq(symbol: str = "最热门") -> pd.DataFrame:
"""
雪球-沪深股市-热度排行榜-关注排行榜
https://xueqiu.com/hq
:param symbol: choice of {"本周新增", "最热门"}
:type symbol: str
:return: 关注排行榜
:rtype: pandas.DataFrame
"""
symbol_map = {
"本周新增": "follow7d",
"最热门": "follow",
}
url = "https://xueqiu.com/service/v5/stock/screener/screen"
params = {
"category": "CN",
"size": "200",
"order": "desc",
"order_by": symbol_map[symbol],
"only_count": "0",
"page": "1",
}
headers = {
"Accept": "*/*",
"Accept-Encoding": "gzip, deflate, br",
"Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8",
"Cache-Control": "no-cache",
"Connection": "keep-alive",
"Host": "xueqiu.com",
"Pragma": "no-cache",
"Referer": "https://xueqiu.com/hq",
"sec-ch-ua": '" Not A;Brand";v="99", "Chromium";v="100", "Google Chrome";v="100"',
"sec-ch-ua-mobile": "?0",
"sec-ch-ua-platform": '"Windows"',
"Sec-Fetch-Dest": "empty",
"Sec-Fetch-Mode": "cors",
"Sec-Fetch-Site": "same-origin",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36",
"X-Requested-With": "XMLHttpRequest",
}
r = requests.get(url, params=params, headers=headers)
data_json = r.json()
total_num = data_json["data"]["count"]
total_page = math.ceil(total_num / 200)
tqdm = get_tqdm()
big_df = pd.DataFrame()
for page in tqdm(range(1, total_page + 1), leave=False):
params.update({"page": page})
r = requests.get(url, params=params, headers=headers)
data_json = r.json()
try:
temp_df = pd.DataFrame(data_json["data"]["list"])
except TypeError:
temp_df = pd.DataFrame()
big_df = pd.concat(objs=[big_df, temp_df], ignore_index=True)
if symbol == "本周新增":
big_df = big_df[
[
"symbol",
"name",
"follow7d",
"current",
]
]
else:
big_df = big_df[
[
"symbol",
"name",
"follow",
"current",
]
]
big_df.columns = [
"股票代码",
"股票简称",
"关注",
"最新价",
]
big_df["关注"] = pd.to_numeric(big_df["关注"], errors="coerce")
big_df["最新价"] = pd.to_numeric(big_df["最新价"], errors="coerce")
return big_df
def stock_hot_tweet_xq(symbol: str = "最热门") -> pd.DataFrame:
"""
雪球-沪深股市-热度排行榜-讨论排行榜
https://xueqiu.com/hq
:param symbol: choice of {"本周新增", "最热门"}
:type symbol: str
:return: 讨论排行榜
:rtype: pandas.DataFrame
"""
symbol_map = {
"本周新增": "tweet7d",
"最热门": "tweet",
}
url = "https://xueqiu.com/service/v5/stock/screener/screen"
params = {
"category": "CN",
"size": "200",
"order": "desc",
"order_by": symbol_map[symbol],
"only_count": "0",
"page": "1",
}
headers = {
"Accept": "*/*",
"Accept-Encoding": "gzip, deflate, br",
"Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8",
"Cache-Control": "no-cache",
"Connection": "keep-alive",
"Host": "xueqiu.com",
"Pragma": "no-cache",
"Referer": "https://xueqiu.com/hq",
"sec-ch-ua": '" Not A;Brand";v="99", "Chromium";v="100", "Google Chrome";v="100"',
"sec-ch-ua-mobile": "?0",
"sec-ch-ua-platform": '"Windows"',
"Sec-Fetch-Dest": "empty",
"Sec-Fetch-Mode": "cors",
"Sec-Fetch-Site": "same-origin",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36",
"X-Requested-With": "XMLHttpRequest",
}
r = requests.get(url, params=params, headers=headers)
data_json = r.json()
total_num = data_json["data"]["count"]
total_page = math.ceil(total_num / 200)
tqdm = get_tqdm()
big_df = pd.DataFrame()
for page in tqdm(range(1, total_page + 1), leave=False):
params.update({"page": page})
r = requests.get(url, params=params, headers=headers)
data_json = r.json()
try:
temp_df = pd.DataFrame(data_json["data"]["list"])
except TypeError:
temp_df = pd.DataFrame()
big_df = pd.concat(objs=[big_df, temp_df], ignore_index=True)
if symbol == "本周新增":
big_df = big_df[
[
"symbol",
"name",
"tweet7d",
"current",
]
]
else:
big_df = big_df[
[
"symbol",
"name",
"tweet",
"current",
]
]
big_df.columns = [
"股票代码",
"股票简称",
"关注",
"最新价",
]
big_df["关注"] = pd.to_numeric(big_df["关注"], errors="coerce")
big_df["最新价"] = pd.to_numeric(big_df["最新价"], errors="coerce")
return big_df
def stock_hot_deal_xq(symbol: str = "最热门") -> pd.DataFrame:
"""
雪球-沪深股市-热度排行榜-分享交易排行榜
https://xueqiu.com/hq
:param symbol: choice of {"本周新增", "最热门"}
:type symbol: str
:return: 分享交易排行榜
:rtype: pandas.DataFrame
"""
symbol_map = {
"本周新增": "deal7d",
"最热门": "deal",
}
url = "https://xueqiu.com/service/v5/stock/screener/screen"
params = {
"category": "CN",
"size": "10000",
"order": "desc",
"order_by": symbol_map[symbol],
"only_count": "0",
"page": "1",
}
headers = {
"Accept": "*/*",
"Accept-Encoding": "gzip, deflate, br",
"Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8",
"Cache-Control": "no-cache",
"Connection": "keep-alive",
"Host": "xueqiu.com",
"Pragma": "no-cache",
"Referer": "https://xueqiu.com/hq",
"sec-ch-ua": '" Not A;Brand";v="99", "Chromium";v="100", "Google Chrome";v="100"',
"sec-ch-ua-mobile": "?0",
"sec-ch-ua-platform": '"Windows"',
"Sec-Fetch-Dest": "empty",
"Sec-Fetch-Mode": "cors",
"Sec-Fetch-Site": "same-origin",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36",
"X-Requested-With": "XMLHttpRequest",
}
r = requests.get(url, params=params, headers=headers)
data_json = r.json()
total_num = data_json["data"]["count"]
total_page = math.ceil(total_num / 200)
tqdm = get_tqdm()
big_df = pd.DataFrame()
for page in tqdm(range(1, total_page + 1), leave=False):
params.update({"page": page})
r = requests.get(url, params=params, headers=headers)
data_json = r.json()
try:
temp_df = pd.DataFrame(data_json["data"]["list"])
except TypeError:
temp_df = pd.DataFrame()
big_df = pd.concat(objs=[big_df, temp_df], ignore_index=True)
if symbol == "本周新增":
big_df = big_df[
[
"symbol",
"name",
"deal7d",
"current",
]
]
else:
big_df = big_df[
[
"symbol",
"name",
"deal",
"current",
]
]
big_df.columns = [
"股票代码",
"股票简称",
"关注",
"最新价",
]
big_df["关注"] = pd.to_numeric(big_df["关注"], errors="coerce")
big_df["最新价"] = pd.to_numeric(big_df["最新价"], errors="coerce")
return big_df
if __name__ == "__main__":
stock_hot_follow_xq_df = stock_hot_follow_xq(symbol="本周新增")
print(stock_hot_follow_xq_df)
stock_hot_follow_xq_df = stock_hot_follow_xq(symbol="最热门")
print(stock_hot_follow_xq_df)
stock_hot_tweet_xq_df = stock_hot_tweet_xq(symbol="本周新增")
print(stock_hot_tweet_xq_df)
stock_hot_tweet_xq_df = stock_hot_tweet_xq(symbol="最热门")
print(stock_hot_tweet_xq_df)
stock_hot_deal_xq_df = stock_hot_deal_xq(symbol="本周新增")
print(stock_hot_deal_xq_df)
stock_hot_deal_xq_df = stock_hot_deal_xq(symbol="最热门")
print(stock_hot_deal_xq_df)
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,205 @@
# -*- coding:utf-8 -*-
# !/usr/bin/env python
"""
Date: 2025/2/19 22:00
Desc: 参考汇率和结算汇率
深港通-港股通业务信息
深港通-港股通业务信息: https://www.szse.cn/szhk/hkbussiness/exchangerate/index.html
沪港通-港股通信息披露: https://www.sse.com.cn/services/hkexsc/disclo/ratios/
"""
import warnings
from datetime import datetime
import pandas as pd
import requests
def stock_sgt_settlement_exchange_rate_szse() -> pd.DataFrame:
"""
深港通-港股通业务信息-结算汇率
https://www.szse.cn/szhk/hkbussiness/exchangerate/index.html
:return: 结算汇率
:rtype: pandas.DataFrame
"""
url = "https://www.szse.cn/api/report/ShowReport"
params = {
"SHOWTYPE": "xlsx",
"CATALOGID": "SGT_LSHL",
"TABKEY": "tab2",
"random": "0.9184251620553985",
}
r = requests.get(url, params=params)
with warnings.catch_warnings(record=True):
warnings.simplefilter("always")
temp_df = pd.read_excel(r.content, engine="openpyxl")
temp_df.sort_values(by="适用日期", inplace=True, ignore_index=True)
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"
)
return temp_df
def stock_sgt_reference_exchange_rate_szse() -> pd.DataFrame:
"""
深港通-港股通业务信息-参考汇率
https://www.szse.cn/szhk/hkbussiness/exchangerate/index.html
:return: 参考汇率
:rtype: pandas.DataFrame
"""
url = "https://www.szse.cn/api/report/ShowReport"
params = {
"SHOWTYPE": "xlsx",
"CATALOGID": "SGT_LSHL",
"TABKEY": "tab1",
"random": "0.9184251620553985",
}
r = requests.get(url, params=params)
with warnings.catch_warnings(record=True):
warnings.simplefilter("always")
temp_df = pd.read_excel(r.content, engine="openpyxl")
temp_df.sort_values(by="适用日期", inplace=True, ignore_index=True)
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"
)
return temp_df
def stock_sgt_reference_exchange_rate_sse() -> pd.DataFrame:
"""
沪港通-港股通信息披露-参考汇率
https://www.sse.com.cn/services/hkexsc/disclo/ratios/
:return: 参考汇率
:rtype: pandas.DataFrame
"""
current_date = datetime.now().date().isoformat().replace("-", "")
url = "https://query.sse.com.cn/commonSoaQuery.do"
params = {
"isPagination": "true",
"updateDate": "20120601",
"updateDateEnd": current_date,
"sqlId": "FW_HGT_GGTHL",
"pageHelp.cacheSize": "1",
"pageHelp.pageSize": "10000",
"pageHelp.pageNo": "1",
"pageHelp.beginPage": "1",
"pageHelp.endPage": "1",
}
headers = {
"Host": "query.sse.com.cn",
"Referer": "https://www.sse.com.cn/",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "
"Chrome/105.0.0.0 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={
"currencyType": "货币种类",
"buyPrice": "参考汇率买入价",
"updateDate": "-",
"validDate": "适用日期",
"sellPrice": "参考汇率卖出价",
},
inplace=True,
)
temp_df = temp_df[
[
"适用日期",
"参考汇率买入价",
"参考汇率卖出价",
"货币种类",
]
]
temp_df.sort_values("适用日期", inplace=True, ignore_index=True)
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"
)
return temp_df
def stock_sgt_settlement_exchange_rate_sse() -> pd.DataFrame:
"""
沪港通-港股通信息披露-结算汇兑
https://www.sse.com.cn/services/hkexsc/disclo/ratios/
:return: 结算汇兑比率
:rtype: pandas.DataFrame
"""
current_date = datetime.now().date().isoformat().replace("-", "")
url = "https://query.sse.com.cn/commonSoaQuery.do"
params = {
"isPagination": "true",
"updateDate": "20120601",
"updateDateEnd": current_date,
"sqlId": "FW_HGT_JSHDBL",
"pageHelp.cacheSize": "1",
"pageHelp.pageSize": "10000",
"pageHelp.pageNo": "1",
"pageHelp.beginPage": "1",
"pageHelp.endPage": "1",
}
headers = {
"Host": "query.sse.com.cn",
"Referer": "https://www.sse.com.cn/",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "
"Chrome/105.0.0.0 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={
"currencyType": "货币种类",
"buyPrice": "买入结算汇兑比率",
"updateDate": "-",
"validDate": "适用日期",
"sellPrice": "卖出结算汇兑比率",
},
inplace=True,
)
temp_df = temp_df[
[
"适用日期",
"买入结算汇兑比率",
"卖出结算汇兑比率",
"货币种类",
]
]
temp_df.sort_values("适用日期", inplace=True, ignore_index=True)
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"
)
return temp_df
if __name__ == "__main__":
stock_sgt_settlement_exchange_rate_szse_df = (
stock_sgt_settlement_exchange_rate_szse()
)
print(stock_sgt_settlement_exchange_rate_szse_df)
stock_sgt_reference_exchange_rate_szse_df = stock_sgt_reference_exchange_rate_szse()
print(stock_sgt_reference_exchange_rate_szse_df)
stock_sgt_reference_exchange_rate_sse_df = stock_sgt_reference_exchange_rate_sse()
print(stock_sgt_reference_exchange_rate_sse_df)
stock_sgt_settlement_exchange_rate_sse_df = stock_sgt_settlement_exchange_rate_sse()
print(stock_sgt_settlement_exchange_rate_sse_df)
@@ -0,0 +1,63 @@
# -*- coding:utf-8 -*-
# !/usr/bin/env python
"""
Date: 2024/2/5 18:00
Desc: 东方财富网-数据中心-沪深港通-市场概括
https://data.eastmoney.com/hsgt/hsgtDetail/scgk.html
"""
import pandas as pd
import requests
def stock_hsgt_fund_min_em(symbol: str = "北向资金") -> pd.DataFrame:
"""
东方财富-数据中心-沪深港通-市场概括-分时数据
https://data.eastmoney.com/hsgt/hsgtDetail/scgk.html
:param symbol: 北向资金; choice of {"北向资金", "南向资金"}
:type symbol: str
:return: 沪深港通持股-分时数据
:rtype: pandas.DataFrame
"""
url = "https://push2.eastmoney.com/api/qt/kamtbs.rtmin/get"
params = {
"fields1": "f1,f2,f3,f4",
"fields2": "f51,f54,f52,f58,f53,f62,f56,f57,f60,f61",
"ut": "b2884a393a59ad64002292a3e90d46a5",
"_": "1707125786160",
}
r = requests.get(url, params=params)
data_json = r.json()
if symbol == "南向资金":
n2s_str_list = data_json["data"]["n2s"]
temp_df = pd.DataFrame([item.split(",") for item in n2s_str_list])
temp_df["date"] = data_json["data"]["n2sDate"]
temp_df = temp_df.iloc[:, [0, 1, 3, 5, -1]]
temp_df.columns = ["时间", "港股通(沪)", "港股通(深)", "南向资金", "日期"]
temp_df = temp_df[["日期", "时间", "港股通(沪)", "港股通(深)", "南向资金"]]
temp_df["日期"] = pd.to_datetime(temp_df["日期"], errors="coerce").dt.date
temp_df["港股通(沪)"] = pd.to_numeric(temp_df["港股通(沪)"], errors="coerce")
temp_df["港股通(深)"] = pd.to_numeric(temp_df["港股通(深)"], errors="coerce")
temp_df["南向资金"] = pd.to_numeric(temp_df["南向资金"], errors="coerce")
return temp_df
else:
s2n_str_list = data_json["data"]["s2n"]
temp_df = pd.DataFrame([item.split(",") for item in s2n_str_list])
temp_df["date"] = data_json["data"]["s2nDate"]
temp_df = temp_df.iloc[:, [0, 1, 3, 5, -1]]
temp_df.columns = ["时间", "沪股通", "深股通", "北向资金", "日期"]
temp_df = temp_df[["日期", "时间", "沪股通", "深股通", "北向资金"]]
temp_df["日期"] = pd.to_datetime(temp_df["日期"], errors="coerce").dt.date
temp_df["沪股通"] = pd.to_numeric(temp_df["沪股通"], errors="coerce")
temp_df["深股通"] = pd.to_numeric(temp_df["深股通"], errors="coerce")
temp_df["北向资金"] = pd.to_numeric(temp_df["北向资金"], errors="coerce")
return temp_df
if __name__ == "__main__":
stock_hsgt_fund_min_em_df = stock_hsgt_fund_min_em(symbol="北向资金")
print(stock_hsgt_fund_min_em_df)
stock_hsgt_fund_min_em_df = stock_hsgt_fund_min_em(symbol="南向资金")
print(stock_hsgt_fund_min_em_df)
@@ -0,0 +1,241 @@
#!/usr/bin/env python
# -*- coding:utf-8 -*-
"""
Date: 2025/8/25 15:00
Desc: 东方财富-财经早餐
https://stock.eastmoney.com/a/czpnc.html
"""
from datetime import datetime
import pandas as pd
import requests
from akshare.request import make_request_with_retry_json
from akshare.utils.cons import headers
def stock_info_cjzc_em() -> pd.DataFrame:
"""
东方财富-财经早餐
https://stock.eastmoney.com/a/czpnc.html
:return: 财经早餐
:rtype: pandas.DataFrame
"""
url = "https://np-listapi.eastmoney.com/comm/web/getNewsByColumns"
params = {
"client": "web",
"biz": "web_news_col",
"column": "1207",
"order": "1",
"needInteractData": "0",
"page_index": "1",
"page_size": "200",
"req_trace": "1710314682980",
"fields": "code,showTime,title,mediaName,summary,image,url,uniqueUrl,Np_dst",
}
big_df = pd.DataFrame()
for page in range(1, 3):
params.update({"page_index": page})
r = requests.get(url, params=params)
data_json = r.json()
temp_df = pd.DataFrame(data_json["data"]["list"])
big_df = pd.concat(objs=[big_df, temp_df], ignore_index=True)
big_df = big_df[["title", "summary", "showTime", "uniqueUrl"]]
big_df.rename(
columns={
"title": "标题",
"summary": "摘要",
"showTime": "发布时间",
"uniqueUrl": "链接",
},
inplace=True,
)
return big_df
def stock_info_global_em() -> pd.DataFrame:
"""
东方财富-全球财经快讯
https://kuaixun.eastmoney.com/7_24.html
:return: 全球财经快讯
:rtype: pandas.DataFrame
"""
url = "https://np-weblist.eastmoney.com/comm/web/getFastNewsList"
params = {
"client": "web",
"biz": "web_724",
"fastColumn": "102",
"sortEnd": "",
"pageSize": "200",
"req_trace": "1710315450384",
}
r = requests.get(url, params=params)
data_json = r.json()
temp_df = pd.DataFrame(data_json["data"]["fastNewsList"])
temp_df = temp_df[["title", "summary", "showTime", "code"]]
temp_df["code"] = [
f"https://finance.eastmoney.com/a/{item}.html" for item in temp_df["code"]
]
temp_df.rename(
columns={
"title": "标题",
"summary": "摘要",
"showTime": "发布时间",
"code": "链接",
},
inplace=True,
)
return temp_df
def stock_info_global_sina() -> pd.DataFrame:
"""
新浪财经-全球财经快讯
https://finance.sina.com.cn/7x24
:return: 全球财经快讯
:rtype: pandas.DataFrame
"""
url = "https://zhibo.sina.com.cn/api/zhibo/feed"
params = {
"page": "1",
"page_size": "20",
"zhibo_id": "152",
"tag_id": "0",
"dire": "f",
"dpc": "1",
"pagesize": "20",
"type": "1",
}
r = requests.get(url, params=params)
data_json = r.json()
time_list = [
item["create_time"] for item in data_json["result"]["data"]["feed"]["list"]
]
text_list = [
item["rich_text"] for item in data_json["result"]["data"]["feed"]["list"]
]
temp_df = pd.DataFrame([time_list, text_list]).T
temp_df.columns = ["时间", "内容"]
return temp_df
def stock_info_global_futu() -> pd.DataFrame:
"""
富途牛牛-快讯
https://news.futunn.com/main/live
:return: 快讯
:rtype: pandas.DataFrame
"""
url = "https://news.futunn.com/news-site-api/main/get-flash-list"
params = {
"pageSize": "50",
}
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko)"
" Chrome/111.0.0.0 Safari/537.36"
}
r = requests.get(url, params=params, headers=headers)
data_json = r.json()
temp_df = pd.DataFrame(data_json["data"]["data"]["news"])
temp_df = temp_df[["title", "content", "time", "detailUrl"]]
temp_df["time"] = [
datetime.fromtimestamp(int(item)).strftime("%Y-%m-%d %H:%M:%S")
for item in temp_df["time"]
]
temp_df.rename(
columns={
"title": "标题",
"content": "内容",
"time": "发布时间",
"detailUrl": "链接",
},
inplace=True,
)
return temp_df
def stock_info_global_ths() -> pd.DataFrame:
"""
同花顺财经-全球财经直播
https://news.10jqka.com.cn/realtimenews.html
:return: 全球财经直播
:rtype: pandas.DataFrame
"""
url = "https://news.10jqka.com.cn/tapp/news/push/stock"
params = {
"page": "1",
"tag": "",
"track": "website",
}
r = requests.get(url, params=params, headers=headers)
data_json = r.json()
temp_df = pd.DataFrame(data_json["data"]["list"])
temp_df = temp_df[["title", "digest", "rtime", "url"]]
temp_df["rtime"] = [
datetime.fromtimestamp(int(item)).strftime("%Y-%m-%d %H:%M:%S")
for item in temp_df["rtime"]
]
temp_df.rename(
columns={
"title": "标题",
"digest": "内容",
"rtime": "发布时间",
"url": "链接",
},
inplace=True,
)
return temp_df
def stock_info_global_cls(symbol: str = "全部") -> pd.DataFrame:
"""
财联社-电报
https://www.cls.cn/telegraph
:param symbol: choice of {"全部", "重点"}
:type symbol: str
:return: 财联社-电报
:rtype: pandas.DataFrame
"""
url = "https://www.cls.cn/nodeapi/telegraphList"
data_json = make_request_with_retry_json(url, max_retries=10, headers=headers)
temp_df = pd.DataFrame(data_json["data"]["roll_data"])
big_df = temp_df.copy()
big_df = big_df[["title", "content", "ctime", "level"]]
big_df["ctime"] = pd.to_datetime(big_df["ctime"], unit="s", utc=True).dt.tz_convert(
"Asia/Shanghai"
)
big_df.columns = ["标题", "内容", "发布时间", "等级"]
big_df.sort_values(["发布时间"], inplace=True)
big_df.reset_index(inplace=True, drop=True)
big_df["发布日期"] = big_df["发布时间"].dt.date
big_df["发布时间"] = big_df["发布时间"].dt.time
if symbol == "重点":
big_df = big_df[(big_df["等级"] == "B") | (big_df["等级"] == "A")]
big_df.reset_index(inplace=True, drop=True)
big_df = big_df[["标题", "内容", "发布日期", "发布时间"]]
return big_df
else:
big_df = big_df[["标题", "内容", "发布日期", "发布时间"]]
return big_df
if __name__ == "__main__":
stock_info_cjzc_em_df = stock_info_cjzc_em()
print(stock_info_cjzc_em_df)
stock_info_global_em_df = stock_info_global_em()
print(stock_info_global_em_df)
stock_info_global_sina_df = stock_info_global_sina()
print(stock_info_global_sina_df)
stock_info_global_futu_df = stock_info_global_futu()
print(stock_info_global_futu_df)
stock_info_global_ths_df = stock_info_global_ths()
print(stock_info_global_ths_df)
stock_info_global_cls_df = stock_info_global_cls(symbol="全部")
print(stock_info_global_cls_df)
@@ -0,0 +1,86 @@
# -*- coding:utf-8 -*-
# !/usr/bin/env python
"""
Date: 2024/11/5 16:00
Desc: 雪球-行情中心-沪深股市-内部交易
https://xueqiu.com/hq/insider
"""
import pandas as pd
import requests
def stock_inner_trade_xq() -> pd.DataFrame:
"""
雪球-行情中心-沪深股市-内部交易
https://xueqiu.com/hq/insider
:return: 内部交易
:rtype: pandas.DataFrame
"""
url = "https://xueqiu.com/service/v5/stock/f10/cn/skholderchg"
params = {
"size": "100000",
"page": "1",
"extend": "true",
}
headers = {
"Accept": "*/*",
"Accept-Encoding": "gzip, deflate, br",
"Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8",
"Cache-Control": "no-cache",
"Connection": "keep-alive",
"Host": "xueqiu.com",
"Pragma": "no-cache",
"Referer": "https://xueqiu.com/hq",
"sec-ch-ua": '" Not A;Brand";v="99", "Chromium";v="100", "Google Chrome";v="100"',
"sec-ch-ua-mobile": "?0",
"sec-ch-ua-platform": '"Windows"',
"Sec-Fetch-Dest": "empty",
"Sec-Fetch-Mode": "cors",
"Sec-Fetch-Site": "same-origin",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "
"Chrome/100.0.4896.127 Safari/537.36",
"X-Requested-With": "XMLHttpRequest",
}
r = requests.get(url, params=params, headers=headers)
data_json = r.json()
temp_df = pd.DataFrame(data_json["data"]["items"])
temp_df.columns = [
"股票代码",
"股票名称",
"变动人",
"-",
"变动日期",
"变动股数",
"成交均价",
"变动后持股数",
"与董监高关系",
"董监高职务",
]
temp_df = temp_df[
[
"股票代码",
"股票名称",
"变动日期",
"变动人",
"变动股数",
"成交均价",
"变动后持股数",
"与董监高关系",
"董监高职务",
]
]
temp_df["变动日期"] = (
pd.to_datetime(temp_df["变动日期"], unit="ms", utc=True)
.dt.tz_convert("Asia/Shanghai")
.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__":
stock_inner_trade_xq_df = stock_inner_trade_xq()
print(stock_inner_trade_xq_df)
@@ -0,0 +1,199 @@
#!/usr/bin/env python
# -*- coding:utf-8 -*-
"""
Date: 2024/5/20 16:00
Desc: 互动易-提问与回答
https://irm.cninfo.com.cn/
"""
import pandas as pd
import requests
from akshare.utils.tqdm import get_tqdm
def _fetch_org_id(symbol: str = "000001") -> str:
"""
股票-互动易-组织代码
https://irm.cninfo.com.cn/
:return: 组织代码
:rtype: str
"""
url = "https://irm.cninfo.com.cn/newircs/index/queryKeyboardInfo"
params = {"_t": "1691144074"}
data = {"keyWord": symbol}
r = requests.post(url, params=params, data=data)
data_json = r.json()
org_id = data_json["data"][0]["secid"]
return org_id
def stock_irm_cninfo(symbol: str = "002594") -> pd.DataFrame:
"""
互动易-提问
https://irm.cninfo.com.cn/ircs/question/questionDetail?questionId=1515236357817618432
:param symbol: 股票代码
:type symbol: str
:return: 提问
:rtype: str
"""
url = "https://irm.cninfo.com.cn/newircs/company/question"
params = {
"_t": "1691142650",
"stockcode": symbol,
"orgId": _fetch_org_id(symbol),
"pageSize": "1000",
"pageNum": "1",
"keyWord": "",
"startDay": "",
"endDay": "",
}
r = requests.post(url, params=params)
data_json = r.json()
total_page = int(data_json["totalPage"])
total_page = 10 if total_page > 10 else total_page
big_df = pd.DataFrame()
tqdm = get_tqdm()
for page in tqdm(range(1, 1 + total_page), leave=False):
params.update({"pageNum": page})
r = requests.post(url, params=params)
data_json = r.json()
temp_df = pd.DataFrame(data_json["rows"])
big_df = pd.concat(objs=[big_df, temp_df], ignore_index=True)
big_df.rename(
columns={
"indexId": "问题编号",
"contentType": "-",
"trade": "行业",
"mainContent": "问题",
"attachmentUrl": "-",
"boardType": "行业代码",
"filetype": "-",
"pubDate": "提问时间",
"stockCode": "股票代码",
"companyShortName": "公司简称",
"author": "提问者编号",
"authorName": "提问者",
"authorLogo": "-",
"pubClient": "来源",
"attachedId": "回答ID",
"attachedContent": "回答内容",
"attachedAuthor": "回答者",
"attachedPubDate": "-",
"updateDate": "更新时间",
"isPraise": "-",
"isFavorite": "-",
"isForward": "-",
"praiseCount": "-",
"qaStatus": "-",
"rights": "-",
"topStatus": "-",
"companyLogo": "-",
"favoriteCount": "-",
"forwardCount": "-",
},
inplace=True,
)
big_df = big_df[
[
"股票代码",
"公司简称",
"行业",
"行业代码",
"问题",
"提问者",
"来源",
"提问时间",
"更新时间",
"提问者编号",
"问题编号",
"回答ID",
"回答内容",
"回答者",
]
]
big_df["行业"] = [item[0] for item in big_df["行业"]]
big_df["行业代码"] = [item[0] for item in big_df["行业代码"]]
big_df["提问时间"] = (
pd.to_datetime(big_df["提问时间"], unit="ms", errors="coerce")
.dt.tz_localize("UTC")
.dt.tz_convert("Asia/Shanghai")
.dt.strftime("%Y-%m-%d %H:%M:%S")
)
big_df["更新时间"] = (
pd.to_datetime(big_df["更新时间"], unit="ms", errors="coerce")
.dt.tz_localize("UTC")
.dt.tz_convert("Asia/Shanghai")
.dt.strftime("%Y-%m-%d %H:%M:%S")
)
big_df["来源"] = big_df["来源"].map(
{
"2": "APP",
"5": "公众号",
"4": "网站",
}
)
big_df["来源"] = big_df["来源"].fillna("网站")
return big_df
def stock_irm_ans_cninfo(symbol: str = "1513586704097333248") -> pd.DataFrame:
"""
互动易-回答
https://irm.cninfo.com.cn/ircs/question/questionDetail?questionId=1515236357817618432
:param symbol: 提问者编号; 通过 ak.stock_irm_cninfo() 来获取具体的提问者编号
:type symbol: str
:return: 回答
:rtype: str
"""
url = "https://irm.cninfo.com.cn/newircs/question/getQuestionDetail"
params = {"questionId": symbol, "_t": "1691146921"}
r = requests.get(url, params=params)
data_json = r.json()
temp_df = pd.DataFrame.from_dict(data_json["data"], orient="index").T
if "replyDate" not in temp_df.columns:
return pd.DataFrame()
temp_df.rename(
columns={
"questionContent": "问题",
"questioner": "提问者",
"questionDate": "提问时间",
"replyDate": "回答时间",
"replyContent": "回答内容",
"stockCode": "股票代码",
"shortName": "公司简称",
},
inplace=True,
)
temp_df = temp_df[
[
"股票代码",
"公司简称",
"问题",
"回答内容",
"提问者",
"提问时间",
"回答时间",
]
]
temp_df["提问时间"] = (
pd.to_datetime(temp_df["提问时间"], unit="ms", errors="coerce")
.dt.tz_localize("UTC")
.dt.tz_convert("Asia/Shanghai")
.dt.strftime("%Y-%m-%d %H:%M:%S")
)
temp_df["回答时间"] = (
pd.to_datetime(temp_df["回答时间"], unit="ms", errors="coerce")
.dt.tz_localize("UTC")
.dt.tz_convert("Asia/Shanghai")
.dt.strftime("%Y-%m-%d %H:%M:%S")
)
return temp_df
if __name__ == "__main__":
stock_irm_cninfo_df = stock_irm_cninfo(symbol="002594")
print(stock_irm_cninfo_df)
stock_irm_ans_cninfo_df = stock_irm_ans_cninfo(symbol="1495108801386602496")
print(stock_irm_ans_cninfo_df)
@@ -0,0 +1,189 @@
#!/usr/bin/env python
# -*- coding:utf-8 -*-
"""
date: 2022/2/14 20:02
desc: 东方财富网-数据中心-特色数据-机构调研
http://data.eastmoney.com/jgdy/
东方财富网-数据中心-特色数据-机构调研-机构调研统计: http://data.eastmoney.com/jgdy/tj.html
东方财富网-数据中心-特色数据-机构调研-机构调研详细: http://data.eastmoney.com/jgdy/xx.html
"""
import pandas as pd
import requests
from tqdm import tqdm
def stock_jgdy_tj_em(date: str = "20220101") -> pd.DataFrame:
"""
东方财富网-数据中心-特色数据-机构调研-机构调研统计
https://data.eastmoney.com/jgdy/tj.html
:param date: 开始时间
:type date: str
:return: 机构调研统计
:rtype: pandas.DataFrame
"""
url = "https://datacenter-web.eastmoney.com/api/data/v1/get"
params = {
"sortColumns": "NOTICE_DATE,SUM,RECEIVE_START_DATE,SECURITY_CODE",
"sortTypes": "-1,-1,-1,1",
"pageSize": "500",
"pageNumber": "1",
"reportName": "RPT_ORG_SURVEYNEW",
"columns": "ALL",
"quoteColumns": "f2~01~SECURITY_CODE~CLOSE_PRICE,f3~01~SECURITY_CODE~CHANGE_RATE",
"source": "WEB",
"client": "WEB",
"filter": f"""(NUMBERNEW="1")(IS_SOURCE="1")(NOTICE_DATE>'{"-".join([date[:4], date[4:6], date[6:]])}')""",
}
r = requests.get(url, params=params)
data_json = r.json()
total_page = data_json["result"]["pages"]
big_df = pd.DataFrame()
for page in tqdm(range(1, total_page + 1), leave=False):
params.update({"pageNumber": page})
r = requests.get(url, params=params)
data_json = r.json()
temp_df = pd.DataFrame(data_json["result"]["data"])
big_df = pd.concat([big_df, temp_df])
big_df.reset_index(inplace=True)
big_df["index"] = list(range(1, len(big_df) + 1))
big_df.columns = [
"序号",
"_",
"代码",
"名称",
"_",
"公告日期",
"接待日期",
"_",
"_",
"_",
"_",
"_",
"_",
"_",
"接待地点",
"_",
"接待方式",
"_",
"接待人员",
"_",
"_",
"_",
"_",
"_",
"接待机构数量",
"_",
"_",
"_",
"_",
"_",
"_",
"最新价",
"涨跌幅",
]
big_df = big_df[
[
"序号",
"代码",
"名称",
"最新价",
"涨跌幅",
"接待机构数量",
"接待方式",
"接待人员",
"接待地点",
"接待日期",
"公告日期",
]
]
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_datetime(big_df["接待日期"], errors="coerce").dt.date
big_df["公告日期"] = pd.to_datetime(big_df["公告日期"], errors="coerce").dt.date
return big_df
def stock_jgdy_detail_em(date: str = "20241211") -> pd.DataFrame:
"""
东方财富网-数据中心-特色数据-机构调研-机构调研详细
https://data.eastmoney.com/jgdy/xx.html
:param date: 开始时间
:type date: str
:return: 机构调研详细
:rtype: pandas.DataFrame
"""
url = "https://datacenter-web.eastmoney.com/api/data/v1/get"
params = {
"sortColumns": "NOTICE_DATE,RECEIVE_START_DATE,SECURITY_CODE,NUMBERNEW",
"sortTypes": "-1,-1,1,-1",
"pageSize": "50",
"pageNumber": "1",
"reportName": "RPT_ORG_SURVEY",
"columns": "SECUCODE,SECURITY_CODE,SECURITY_NAME_ABBR,NOTICE_DATE,RECEIVE_START_DATE,"
"RECEIVE_OBJECT,RECEIVE_PLACE,RECEIVE_WAY_EXPLAIN,INVESTIGATORS,RECEPTIONIST,ORG_TYPE",
"quoteColumns": "f2~01~SECURITY_CODE~CLOSE_PRICE,f3~01~SECURITY_CODE~CHANGE_RATE",
"quoteType": "0",
"source": "WEB",
"client": "WEB",
"filter": f"""(IS_SOURCE="1")(RECEIVE_START_DATE>'{"-".join([date[:4], date[4:6], date[6:]])}')""",
}
r = requests.get(url, params=params)
data_json = r.json()
total_page = data_json["result"]["pages"]
big_df = pd.DataFrame()
for page in tqdm(range(1, total_page + 1), leave=False):
params.update({"pageNumber": page})
r = requests.get(url, params=params)
data_json = r.json()
temp_df = pd.DataFrame(data_json["result"]["data"])
big_df = pd.concat([big_df, temp_df])
big_df.reset_index(inplace=True)
big_df["index"] = list(range(1, len(big_df) + 1))
big_df.columns = [
"序号",
"_",
"代码",
"名称",
"公告日期",
"调研日期",
"调研机构",
"接待地点",
"接待方式",
"调研人员",
"接待人员",
"机构类型",
"最新价",
"涨跌幅",
]
big_df = big_df[
[
"序号",
"代码",
"名称",
"最新价",
"涨跌幅",
"调研机构",
"机构类型",
"调研人员",
"接待方式",
"接待人员",
"接待地点",
"调研日期",
"公告日期",
]
]
big_df["最新价"] = pd.to_numeric(big_df["最新价"], errors="coerce")
big_df["涨跌幅"] = pd.to_numeric(big_df["涨跌幅"], errors="coerce")
big_df["调研日期"] = pd.to_datetime(big_df["调研日期"], errors="coerce").dt.date
big_df["公告日期"] = pd.to_datetime(big_df["公告日期"], errors="coerce").dt.date
return big_df
if __name__ == "__main__":
stock_jgdy_tj_em_df = stock_jgdy_tj_em(date="20180928")
print(stock_jgdy_tj_em_df)
stock_jgdy_detail_em_df = stock_jgdy_detail_em(date="20210915")
print(stock_jgdy_detail_em_df)
@@ -0,0 +1,96 @@
#!/usr/bin/env python
# -*- coding:utf-8 -*-
"""
Date: 2024/5/6 20:30
Desc: 同花顺-数据中心-营业部排名
https://data.10jqka.com.cn/market/longhu/
"""
from io import StringIO
import pandas as pd
import requests
from bs4 import BeautifulSoup
from akshare.utils.tqdm import get_tqdm
from akshare.utils.cons import headers
def stock_lh_yyb_most() -> pd.DataFrame:
"""
同花顺-数据中心-营业部排名-上榜次数最多
https://data.10jqka.com.cn/market/longhu/
:return: 上榜次数最多
:rtype: pandas.DataFrame
"""
url = "https://data.10jqka.com.cn/ifmarket/lhbyyb/type/1/tab/sbcs/field/sbcs/sort/desc/page/1/"
r = requests.get(url, headers=headers)
soup = BeautifulSoup(r.text, features="lxml")
page_str = soup.find(name="span", attrs={"class": "page_info"}).text
total_page = int(page_str.split("/")[1]) + 1
big_df = pd.DataFrame()
tqdm = get_tqdm()
for page in tqdm(range(1, total_page), leave=False):
url = f"https://data.10jqka.com.cn/ifmarket/lhbyyb/type/1/tab/sbcs/field/sbcs/sort/desc/page/{page}/"
r = requests.get(url, headers=headers)
temp_df = pd.read_html(StringIO(r.text))[0]
big_df = pd.concat(objs=[big_df, temp_df], ignore_index=True)
big_df.reset_index(inplace=True, drop=True)
return big_df
def stock_lh_yyb_capital() -> pd.DataFrame:
"""
同花顺-数据中心-营业部排名-资金实力最强
https://data.10jqka.com.cn/market/longhu/
:return: 资金实力最强
:rtype: pandas.DataFrame
"""
url = "https://data.10jqka.com.cn/ifmarket/lhbyyb/type/1/tab/zjsl/field/zgczje/sort/desc/page/1/"
r = requests.get(url, headers=headers)
soup = BeautifulSoup(r.text, features="lxml")
page_str = soup.find(name="span", attrs={"class": "page_info"}).text
total_page = int(page_str.split("/")[1]) + 1
big_df = pd.DataFrame()
tqdm = get_tqdm()
for page in tqdm(range(1, total_page), leave=False):
url = f"https://data.10jqka.com.cn/ifmarket/lhbyyb/type/1/tab/zjsl/field/zgczje/sort/desc/page/{page}/"
r = requests.get(url, headers=headers)
temp_df = pd.read_html(StringIO(r.text))[0]
big_df = pd.concat(objs=[big_df, temp_df], ignore_index=True)
big_df.reset_index(inplace=True, drop=True)
return big_df
def stock_lh_yyb_control() -> pd.DataFrame:
"""
同花顺-数据中心-营业部排名-抱团操作实力
https://data.10jqka.com.cn/market/longhu/
:return: 抱团操作实力
:rtype: pandas.DataFrame
"""
url = "https://data.10jqka.com.cn/ifmarket/lhbyyb/type/1/tab/btcz/field/xsjs/sort/desc/page/1/"
r = requests.get(url, headers=headers)
soup = BeautifulSoup(r.text, features="lxml")
page_str = soup.find(name="span", attrs={"class": "page_info"}).text
total_page = int(page_str.split("/")[1]) + 1
big_df = pd.DataFrame()
tqdm = get_tqdm()
for page in tqdm(range(1, total_page), leave=False):
url = f"https://data.10jqka.com.cn/ifmarket/lhbyyb/type/1/tab/btcz/field/xsjs/sort/desc/page/{page}/"
r = requests.get(url, headers=headers)
temp_df = pd.read_html(StringIO(r.text))[0]
big_df = pd.concat(objs=[big_df, temp_df], ignore_index=True)
big_df.reset_index(inplace=True, drop=True)
return big_df
if __name__ == "__main__":
stock_lh_yyb_most_df = stock_lh_yyb_most()
print(stock_lh_yyb_most_df)
stock_lh_yyb_capital_df = stock_lh_yyb_capital()
print(stock_lh_yyb_capital_df)
stock_lh_yyb_control_df = stock_lh_yyb_control()
print(stock_lh_yyb_control_df)
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,264 @@
#!/usr/bin/env python
# -*- coding:utf-8 -*-
"""
Date: 2024/5/10 00:00
Desc: 新浪财经-龙虎榜
https://vip.stock.finance.sina.com.cn/q/go.php/vInvestConsult/kind/lhb/index.phtml
"""
from io import StringIO
import pandas as pd
import requests
from bs4 import BeautifulSoup
from akshare.utils.tqdm import get_tqdm
def stock_lhb_detail_daily_sina(date: str = "20240222") -> pd.DataFrame:
"""
龙虎榜-每日详情
https://vip.stock.finance.sina.com.cn/q/go.php/vInvestConsult/kind/lhb/index.phtml
:param date: 交易日
:type date: str
:return: 龙虎榜-每日详情
:rtype: pandas.DataFrame
"""
date = "-".join([date[:4], date[4:6], date[6:]])
url = "https://vip.stock.finance.sina.com.cn/q/go.php/vInvestConsult/kind/lhb/index.phtml"
params = {"tradedate": date}
r = requests.get(url, params=params)
soup = BeautifulSoup(r.text, features="lxml")
selected_html = soup.find(name="div", attrs={"class": "list"}).find_all(
name="table", attrs={"class": "list_table"}
)
big_df = pd.DataFrame()
for table in selected_html:
temp_df = pd.read_html(StringIO(table.prettify()), header=0, skiprows=1)[0]
temp_symbol = pd.read_html(StringIO(table.prettify()))[0].iat[0, 0]
temp_df["指标"] = temp_symbol
big_df = pd.concat(objs=[big_df, temp_df], ignore_index=True)
big_df["股票代码"] = big_df["股票代码"].astype(str).str.zfill(6)
del big_df["查看详情"]
big_df.columns = [
"序号",
"股票代码",
"股票名称",
"收盘价",
"对应值",
"成交量",
"成交额",
"指标",
]
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")
return big_df
def _find_last_page(
url: str = "https://vip.stock.finance.sina.com.cn/q/go.php/vLHBData/kind/ggtj/index.phtml",
recent_day: str = "60",
):
params = {
"last": recent_day,
"p": "1",
}
r = requests.get(url, params=params)
soup = BeautifulSoup(r.text, "lxml")
try:
previous_page = int(soup.find_all(attrs={"class": "page"})[-2].text)
except: # noqa: E722
previous_page = 1
if previous_page != 1:
while True:
params = {
"last": recent_day,
"p": previous_page,
}
r = requests.get(url, params=params)
soup = BeautifulSoup(r.text, features="lxml")
last_page = int(soup.find_all(attrs={"class": "page"})[-2].text)
if last_page != previous_page:
previous_page = last_page
continue
else:
break
return previous_page
def stock_lhb_ggtj_sina(symbol: str = "5") -> pd.DataFrame:
"""
龙虎榜-个股上榜统计
https://vip.stock.finance.sina.com.cn/q/go.php/vLHBData/kind/ggtj/index.phtml
:param symbol: choice of {"5": 最近 5 ; "10": 最近 10 ; "30": 最近 30 ; "60": 最近 60 ;}
:type symbol: str
:return: 龙虎榜-个股上榜统计
:rtype: pandas.DataFrame
"""
url = (
"https://vip.stock.finance.sina.com.cn/q/go.php/vLHBData/kind/ggtj/index.phtml"
)
last_page_num = _find_last_page(url, symbol)
big_df = pd.DataFrame()
tqdm = get_tqdm()
for page in tqdm(range(1, last_page_num + 1), leave=False):
params = {
"last": symbol,
"p": page,
}
r = requests.get(url, params=params)
temp_df = pd.read_html(StringIO(r.text))[0].iloc[0:, :]
big_df = pd.concat(objs=[big_df, temp_df], ignore_index=True)
big_df["股票代码"] = big_df["股票代码"].astype(str).str.zfill(6)
big_df.columns = [
"股票代码",
"股票名称",
"上榜次数",
"累积购买额",
"累积卖出额",
"净额",
"买入席位数",
"卖出席位数",
]
return big_df
def stock_lhb_yytj_sina(symbol: str = "5") -> pd.DataFrame:
"""
龙虎榜-营业部上榜统计
https://vip.stock.finance.sina.com.cn/q/go.php/vLHBData/kind/yytj/index.phtml
:param symbol: choice of {"5": 最近 5 ; "10": 最近 10 ; "30": 最近 30 ; "60": 最近 60 ;}
:type symbol: str
:return: 龙虎榜-营业部上榜统计
:rtype: pandas.DataFrame
"""
url = (
"https://vip.stock.finance.sina.com.cn/q/go.php/vLHBData/kind/yytj/index.phtml"
)
last_page_num = _find_last_page(url, symbol)
big_df = pd.DataFrame()
tqdm = get_tqdm()
for page in tqdm(range(1, last_page_num + 1), leave=False):
params = {
"last": "5",
"p": page,
}
r = requests.get(url, params=params)
temp_df = pd.read_html(StringIO(r.text))[0].iloc[0:, :]
big_df = pd.concat([big_df, temp_df], ignore_index=True)
big_df.columns = [
"营业部名称",
"上榜次数",
"累积购买额",
"买入席位数",
"累积卖出额",
"卖出席位数",
"买入前三股票",
]
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")
return big_df
def stock_lhb_jgzz_sina(symbol: str = "5") -> pd.DataFrame:
"""
龙虎榜-机构席位追踪
https://vip.stock.finance.sina.com.cn/q/go.php/vLHBData/kind/jgzz/index.phtml
:param symbol: choice of {"5": 最近 5 ; "10": 最近 10 ; "30": 最近 30 ; "60": 最近 60 ;}
:type symbol: str
:return: 龙虎榜-机构席位追踪
:rtype: pandas.DataFrame
"""
url = (
"https://vip.stock.finance.sina.com.cn/q/go.php/vLHBData/kind/jgzz/index.phtml"
)
last_page_num = _find_last_page(url, symbol)
big_df = pd.DataFrame()
tqdm = get_tqdm()
for page in tqdm(range(1, last_page_num + 1), leave=False):
params = {
"last": symbol,
"p": page,
}
r = requests.get(url, params=params)
temp_df = pd.read_html(StringIO(r.text))[0].iloc[0:, :]
if temp_df.empty:
continue
big_df = pd.concat(objs=[big_df, temp_df], ignore_index=True)
big_df["股票代码"] = big_df["股票代码"].astype(str).str.zfill(6)
del big_df["当前价"]
del big_df["涨跌幅"]
big_df.columns = [
"股票代码",
"股票名称",
"累积买入额",
"买入次数",
"累积卖出额",
"卖出次数",
"净额",
]
big_df["买入次数"] = pd.to_numeric(big_df["买入次数"], errors="coerce")
big_df["卖出次数"] = pd.to_numeric(big_df["卖出次数"], errors="coerce")
return big_df
def stock_lhb_jgmx_sina() -> pd.DataFrame:
"""
龙虎榜-机构席位成交明细
https://vip.stock.finance.sina.com.cn/q/go.php/vLHBData/kind/jgmx/index.phtml
:return: 龙虎榜-机构席位成交明细
:rtype: pandas.DataFrame
"""
url = (
"https://vip.stock.finance.sina.com.cn/q/go.php/vLHBData/kind/jgmx/index.phtml"
)
params = {
"p": "1",
}
r = requests.get(url, params=params)
soup = BeautifulSoup(r.text, features="lxml")
try:
last_page_num = int(soup.find_all(attrs={"class": "page"})[-2].text)
except: # noqa: E722
last_page_num = 1
big_df = pd.DataFrame()
tqdm = get_tqdm()
for page in tqdm(range(1, last_page_num + 1), leave=False):
params = {
"p": page,
}
r = requests.get(url, params=params)
temp_df = pd.read_html(StringIO(r.text))[0].iloc[0:, :]
big_df = pd.concat(objs=[big_df, temp_df], ignore_index=True)
big_df["股票代码"] = big_df["股票代码"].astype(str).str.zfill(6)
big_df["交易日期"] = pd.to_datetime(big_df["交易日期"], errors="coerce").dt.date
big_df.rename(
columns={
"机构席位买入额(万)": "机构席位买入额",
"机构席位卖出额(万)": "机构席位卖出额",
},
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__":
stock_lhb_detail_daily_sina_df = stock_lhb_detail_daily_sina(date="20240222")
print(stock_lhb_detail_daily_sina_df)
stock_lhb_ggtj_sina_df = stock_lhb_ggtj_sina(symbol="5")
print(stock_lhb_ggtj_sina_df)
stock_lhb_yytj_sina_df = stock_lhb_yytj_sina(symbol="5")
print(stock_lhb_yytj_sina_df)
stock_lhb_jgzz_sina_df = stock_lhb_jgzz_sina(symbol="5")
print(stock_lhb_jgzz_sina_df)
stock_lhb_jgmx_sina_df = stock_lhb_jgmx_sina()
print(stock_lhb_jgmx_sina_df)
@@ -0,0 +1,101 @@
#!/usr/bin/env python
# -*- coding:utf-8 -*-
"""
Date: 2024/6/14 17:00
Desc: 东方财富网-数据中心-融资融券-融资融券账户统计-两融账户信息
https://www.szse.cn/disclosure/margin/object/index.html
"""
import pandas as pd
import requests
from akshare.utils.tqdm import get_tqdm
def stock_margin_account_info() -> pd.DataFrame:
"""
东方财富网-数据中心-融资融券-融资融券账户统计-两融账户信息
https://data.eastmoney.com/rzrq/zhtjday.html
:return: 融资融券账户统计
:rtype: pandas.DataFrame
"""
import warnings
warnings.filterwarnings(action="ignore", category=FutureWarning)
url = "https://datacenter-web.eastmoney.com/api/data/v1/get"
params = {
"reportName": "RPTA_WEB_MARGIN_DAILYTRADE",
"columns": "ALL",
"pageNumber": "1",
"pageSize": "500",
"sortColumns": "STATISTICS_DATE",
"sortTypes": "-1",
"p": "1",
"pageNo": "1",
"pageNum": "1",
}
r = requests.get(url=url, params=params)
data_json = r.json()
total_page = data_json["result"]["pages"]
tqdm = get_tqdm()
big_df = pd.DataFrame()
for page in tqdm(range(1, total_page + 1), leave=False):
params.update(
{
"pageNumber": page,
"p": page,
"pageNo": page,
"pageNum": page,
}
)
r = requests.get(url=url, params=params)
data_json = r.json()
temp_df = pd.DataFrame(data_json["result"]["data"])
big_df = pd.concat(objs=[big_df, temp_df], ignore_index=True)
big_df.rename(
columns={
"STATISTICS_DATE": "日期",
"FIN_BALANCE": "融资余额",
"LOAN_BALANCE": "融券余额",
"FIN_BUY_AMT": "融资买入额",
"LOAN_SELL_AMT": "融券卖出额",
"SECURITY_ORG_NUM": "证券公司数量",
"OPERATEDEPT_NUM": "营业部数量",
"PERSONAL_INVESTOR_NUM": "个人投资者数量",
"ORG_INVESTOR_NUM": "机构投资者数量",
"INVESTOR_NUM": "参与交易的投资者数量",
"MARGINLIAB_INVESTOR_NUM": "有融资融券负债的投资者数量",
"TOTAL_GUARANTEE": "担保物总价值",
"AVG_GUARANTEE_RATIO": "平均维持担保比例",
},
inplace=True,
)
big_df = big_df[
[
"日期",
"融资余额",
"融券余额",
"融资买入额",
"融券卖出额",
"证券公司数量",
"营业部数量",
"个人投资者数量",
"机构投资者数量",
"参与交易的投资者数量",
"有融资融券负债的投资者数量",
"担保物总价值",
"平均维持担保比例",
]
]
big_df["日期"] = pd.to_datetime(big_df["日期"], errors="coerce").dt.date
for item in big_df.columns[1:]:
big_df[item] = pd.to_numeric(big_df[item], errors="coerce")
big_df.sort_values(["日期"], ignore_index=True, inplace=True)
return big_df
if __name__ == "__main__":
stock_margin_account_info_df = stock_margin_account_info()
print(stock_margin_account_info_df)
@@ -0,0 +1,214 @@
#!/usr/bin/env python
# -*- coding:utf-8 -*-
"""
Date: 2026/1/13 15:20
Desc: 上海证券交易所-融资融券数据
https://www.sse.com.cn/market/othersdata/margin/sum/
"""
import pandas as pd
import requests
def stock_margin_ratio_pa(symbol: str = "深市", date: str = "20260113") -> pd.DataFrame:
"""
融资融券-标的证券名单及保证金比例查询
https://stock.pingan.com/static/webinfo/margin/business.html?businessType=0
:param symbol: choice of {"深市", "沪市", "北交所"}
:type symbol: str
:param date: 交易日期
:type date: str
:return: 标的证券名单及保证金比例查询
:rtype: pandas.DataFrame
"""
market_code = {
"深市": "00",
"沪市": "10",
"北交所": "30",
}
url = "https://stock.pingan.com/fss/servlet/fsscoreapp/stockSource/mrgRatio"
payload = {
"currentPage": 1,
"pageSize": 50000,
"type": "bdzq",
"setdate": "-".join([date[:4], date[4:6], date[6:]]),
"stockMes": "",
"market": market_code[symbol],
"appName": "AYLCH5",
"tokenId": "",
"appChannel": "LRSP",
"requestId": "194055910e2075c03e25fabf6ffc5a7f",
"channel": "pa18",
}
r = requests.post(url, json=payload)
data_json = r.json()
temp_df = pd.DataFrame(data_json["data"]["list"])
temp_df.rename(
columns={
"fiMarginRatio": "融资比例",
"secuCode": "证券代码",
"secuName": "证券简称",
"slMarginRatio": "融券比例",
},
inplace=True,
)
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 stock_margin_sse(
start_date: str = "20010106", end_date: str = "20230922"
) -> pd.DataFrame:
"""
上海证券交易所-融资融券数据-融资融券汇总
https://www.sse.com.cn/market/othersdata/margin/sum/
:param start_date: 交易开始日期
:type start_date: str
:param end_date: 交易结束日期
:type end_date: str
:return: 融资融券汇总
:rtype: pandas.DataFrame
"""
url = "https://query.sse.com.cn/marketdata/tradedata/queryMargin.do"
params = {
"isPagination": "true",
"beginDate": start_date,
"endDate": end_date,
"tabType": "",
"stockCode": "",
"pageHelp.pageSize": "5000",
"pageHelp.pageNo": "1",
"pageHelp.beginPage": "1",
"pageHelp.cacheSize": "1",
"pageHelp.endPage": "5",
}
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.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")
return temp_df
def stock_margin_detail_sse(date: str = "20230922") -> pd.DataFrame:
"""
上海证券交易所-融资融券数据-融资融券明细
https://www.sse.com.cn/market/othersdata/margin/detail/
:param date: 交易日期
:type date: str
:return: 融资融券明细
:rtype: pandas.DataFrame
"""
url = "https://query.sse.com.cn/marketdata/tradedata/queryMargin.do"
params = {
"isPagination": "true",
"tabType": "mxtype",
"detailsDate": date,
"stockCode": "",
"beginDate": "",
"endDate": "",
"pageHelp.pageSize": "5000",
"pageHelp.pageCount": "50",
"pageHelp.pageNo": "1",
"pageHelp.beginPage": "1",
"pageHelp.cacheSize": "1",
"pageHelp.endPage": "21",
}
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.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")
return temp_df
if __name__ == "__main__":
stock_margin_ratio_pa_df = stock_margin_ratio_pa(symbol="沪市", date="20260113")
print(stock_margin_ratio_pa_df)
stock_margin_sse_df = stock_margin_sse(start_date="20010106", end_date="20210401")
print(stock_margin_sse_df)
stock_margin_detail_sse_df = stock_margin_detail_sse(date="20230922")
print(stock_margin_detail_sse_df)
@@ -0,0 +1,156 @@
#!/usr/bin/env python
# -*- coding:utf-8 -*-
"""
Date: 2024/6/14 17:00
Desc: 深圳证券交易所-融资融券数据
https://www.szse.cn/disclosure/margin/object/index.html
"""
import warnings
from io import BytesIO
import pandas as pd
import requests
def stock_margin_underlying_info_szse(date: str = "20221129") -> pd.DataFrame:
"""
深圳证券交易所-融资融券数据-标的证券信息
https://www.szse.cn/disclosure/margin/object/index.html
:param date: 交易日
:type date: str
:return: 标的证券信息
:rtype: pandas.DataFrame
"""
url = "https://www.szse.cn/api/report/ShowReport"
params = {
"SHOWTYPE": "xlsx",
"CATALOGID": "1834_xxpl",
"txtDate": "-".join([date[:4], date[4:6], date[6:]]),
"tab1PAGENO": "1",
"random": "0.7425245522795993",
"TABKEY": "tab1",
}
headers = {
"Referer": "https://www.szse.cn/disclosure/margin/object/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(BytesIO(r.content), engine="openpyxl", dtype={"证券代码": str})
return temp_df
def stock_margin_szse(date: str = "20240411") -> pd.DataFrame:
"""
深圳证券交易所-融资融券数据-融资融券汇总
https://www.szse.cn/disclosure/margin/margin/index.html
:param date: 交易日
:type date: str
:return: 融资融券汇总
:rtype: pandas.DataFrame
"""
url = "https://www.szse.cn/api/report/ShowReport/data"
params = {
"SHOWTYPE": "JSON",
"CATALOGID": "1837_xxpl",
"txtDate": "-".join([date[:4], date[4:6], date[6:]]),
"tab1PAGENO": "1",
"random": "0.7425245522795993",
}
headers = {
"Referer": "https://www.szse.cn/disclosure/margin/object/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)
data_json = r.json()
temp_df = pd.DataFrame(data_json[0]["data"])
temp_df.columns = [
"融资买入额",
"融资余额",
"融券卖出量",
"融券余量",
"融券余额",
"融资融券余额",
]
temp_df["融资买入额"] = temp_df["融资买入额"].str.replace(",", "")
temp_df["融资买入额"] = pd.to_numeric(temp_df["融资买入额"], errors="coerce")
temp_df["融资余额"] = temp_df["融资余额"].str.replace(",", "")
temp_df["融资余额"] = pd.to_numeric(temp_df["融资余额"], errors="coerce")
temp_df["融券卖出量"] = temp_df["融券卖出量"].str.replace(",", "")
temp_df["融券卖出量"] = pd.to_numeric(temp_df["融券卖出量"], errors="coerce")
temp_df["融券余量"] = temp_df["融券余量"].str.replace(",", "")
temp_df["融券余量"] = pd.to_numeric(temp_df["融券余量"], errors="coerce")
temp_df["融券余额"] = temp_df["融券余额"].str.replace(",", "")
temp_df["融券余额"] = pd.to_numeric(temp_df["融券余额"], errors="coerce")
temp_df["融资融券余额"] = temp_df["融资融券余额"].str.replace(",", "")
temp_df["融资融券余额"] = pd.to_numeric(temp_df["融资融券余额"], errors="coerce")
return temp_df
def stock_margin_detail_szse(date: str = "20230925") -> pd.DataFrame:
"""
深证证券交易所-融资融券数据-融资融券交易明细
https://www.szse.cn/disclosure/margin/margin/index.html
:param date: 交易日期
:type date: str
:return: 融资融券明细
:rtype: pandas.DataFrame
"""
url = "https://www.szse.cn/api/report/ShowReport"
params = {
"SHOWTYPE": "xlsx",
"CATALOGID": "1837_xxpl",
"txtDate": "-".join([date[:4], date[4:6], date[6:]]),
"tab2PAGENO": "1",
"random": "0.24279342734085696",
"TABKEY": "tab2",
}
headers = {
"Referer": "https://www.szse.cn/disclosure/margin/margin/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(BytesIO(r.content), engine="openpyxl", dtype={"证券代码": str})
temp_df.columns = [
"证券代码",
"证券简称",
"融资买入额",
"融资余额",
"融券卖出量",
"融券余量",
"融券余额",
"融资融券余额",
]
temp_df["证券简称"] = temp_df["证券简称"].str.replace("&nbsp;", "")
temp_df["融资买入额"] = temp_df["融资买入额"].str.replace(",", "")
temp_df["融资买入额"] = pd.to_numeric(temp_df["融资买入额"], errors="coerce")
temp_df["融资余额"] = temp_df["融资余额"].str.replace(",", "")
temp_df["融资余额"] = pd.to_numeric(temp_df["融资余额"], errors="coerce")
temp_df["融券卖出量"] = temp_df["融券卖出量"].astype(str).str.replace(",", "")
temp_df["融券卖出量"] = pd.to_numeric(temp_df["融券卖出量"], errors="coerce")
temp_df["融券余量"] = temp_df["融券余量"].str.replace(",", "")
temp_df["融券余量"] = pd.to_numeric(temp_df["融券余量"], errors="coerce")
temp_df["融券余额"] = temp_df["融券余额"].str.replace(",", "")
temp_df["融券余额"] = pd.to_numeric(temp_df["融券余额"], errors="coerce")
temp_df["融资融券余额"] = temp_df["融资融券余额"].str.replace(",", "")
temp_df["融资融券余额"] = pd.to_numeric(temp_df["融资融券余额"], errors="coerce")
return temp_df
if __name__ == "__main__":
stock_margin_underlying_info_szse_df = stock_margin_underlying_info_szse(
date="20221129"
)
print(stock_margin_underlying_info_szse_df)
stock_margin_szse_df = stock_margin_szse(date="20240411")
print(stock_margin_szse_df)
stock_margin_detail_szse_df = stock_margin_detail_szse(date="20240411")
print(stock_margin_detail_szse_df)
@@ -0,0 +1,53 @@
#!/usr/bin/env python
# -*- coding:utf-8 -*-
"""
Date: 2026/5/18 18:22
Desc: 乐咕乐股网-赚钱效应分析
https://www.legulegu.com/stockdata/market-activity
"""
from io import StringIO
import pandas as pd
import requests
from bs4 import BeautifulSoup
from akshare.utils.cons import headers
def stock_market_activity_legu() -> pd.DataFrame:
"""
乐咕乐股网-赚钱效应分析
https://www.legulegu.com/stockdata/market-activity
:return: 乐咕乐股网-赚钱效应分析
:rtype: pandas.DataFrame
"""
url = "https://legulegu.com/stockdata/market-activity"
r = requests.get(url, headers=headers)
temp_df = pd.read_html(StringIO(r.text))[0]
temp_df_one = temp_df.iloc[:, :2]
temp_df_one.columns = ["item", "value"]
temp_df_two = temp_df.iloc[:, 2:4]
temp_df_two.columns = ["item", "value"]
temp_df_three = temp_df.iloc[:, 4:6]
temp_df_three.columns = ["item", "value"]
temp_df = pd.concat(
objs=[temp_df_one, temp_df_two, temp_df_three], ignore_index=True
)
temp_df.dropna(how="all", axis=0, inplace=True)
soup = BeautifulSoup(r.text, features="lxml")
item_str = soup.find(name="div", attrs={"class": "metric-activity"}).text.strip()
inner_temp_df = pd.DataFrame([item.strip() for item in item_str.split("\n")]).T
inner_temp_df.columns = ["item", "value"]
temp_df = pd.concat(objs=[temp_df, inner_temp_df], ignore_index=True)
item_str = soup.find(name="div", attrs={"class": "market-activity-meta"}).text.strip()
inner_temp_df = pd.DataFrame(["统计日期", item_str]).T
inner_temp_df.columns = ["item", "value"]
temp_df = pd.concat(objs=[temp_df, inner_temp_df], ignore_index=True)
temp_df.reset_index(inplace=True, drop=True)
return temp_df
if __name__ == "__main__":
stock_market_activity_legu_df = stock_market_activity_legu()
print(stock_market_activity_legu_df)
@@ -0,0 +1,174 @@
#!/usr/bin/env python
# -*- coding:utf-8 -*-
"""
Date: 2022/12/27 21:11
Desc: 东方财富-行情中心-盘口异动
https://quote.eastmoney.com/changes/
"""
import pandas as pd
import requests
def stock_changes_em(symbol: str = "大笔买入") -> pd.DataFrame:
"""
东方财富-行情中心-盘口异动
https://quote.eastmoney.com/changes/
:param symbol: choice of {'火箭发射', '快速反弹', '大笔买入', '封涨停板', '打开跌停板', '有大买盘',
'竞价上涨', '高开5日线', '向上缺口', '60日新高', '60日大幅上涨', '加速下跌', '高台跳水',
'大笔卖出', '封跌停板', '打开涨停板', '有大卖盘', '竞价下跌', '低开5日线', '向下缺口', '60日新低', '60日大幅下跌'}
:type symbol: str
:return: 盘口异动
:rtype: pandas.DataFrame
"""
url = "https://push2ex.eastmoney.com/getAllStockChanges"
symbol_map = {
"火箭发射": "8201",
"快速反弹": "8202",
"大笔买入": "8193",
"封涨停板": "4",
"打开跌停板": "32",
"有大买盘": "64",
"竞价上涨": "8207",
"高开5日线": "8209",
"向上缺口": "8211",
"60日新高": "8213",
"60日大幅上涨": "8215",
"加速下跌": "8204",
"高台跳水": "8203",
"大笔卖出": "8194",
"封跌停板": "8",
"打开涨停板": "16",
"有大卖盘": "128",
"竞价下跌": "8208",
"低开5日线": "8210",
"向下缺口": "8212",
"60日新低": "8214",
"60日大幅下跌": "8216",
}
reversed_symbol_map = {v: k for k, v in symbol_map.items()}
params = {
"type": symbol_map[symbol],
"pageindex": "0",
"pagesize": "5000",
"ut": "7eea3edcaed734bea9cbfc24409ed989",
"dpt": "wzchanges",
}
r = requests.get(url, params=params)
data_json = r.json()
temp_df = pd.DataFrame(data_json["data"]["allstock"])
temp_df["tm"] = pd.to_datetime(temp_df["tm"], format="%H%M%S").dt.time
temp_df.columns = [
"时间",
"代码",
"_",
"名称",
"板块",
"相关信息",
]
temp_df = temp_df[
[
"时间",
"代码",
"名称",
"板块",
"相关信息",
]
]
temp_df["板块"] = temp_df["板块"].astype(str)
temp_df["板块"] = temp_df["板块"].map(reversed_symbol_map)
return temp_df
def stock_board_change_em() -> pd.DataFrame:
"""
东方财富-行情中心-当日板块异动详情
https://quote.eastmoney.com/changes/
:return: 当日板块异动详情页
:rtype: pandas.DataFrame
"""
url = "https://push2ex.eastmoney.com/getAllBKChanges"
params = {
"ut": "7eea3edcaed734bea9cbfc24409ed989",
"dpt": "wzchanges",
"pageindex": "0",
"pagesize": "5000",
}
r = requests.get(url, params=params)
data_json = r.json()
data_df = pd.DataFrame(data_json["data"]["allbk"])
data_df.columns = [
"-",
"-",
"板块名称",
"涨跌幅",
"主力净流入",
"板块异动总次数",
"ms",
"板块具体异动类型列表及出现次数",
]
data_df["板块异动最频繁个股及所属类型-买卖方向"] = [
item["m"] for item in data_df["ms"]
]
data_df["板块异动最频繁个股及所属类型-股票代码"] = [
item["c"] for item in data_df["ms"]
]
data_df["板块异动最频繁个股及所属类型-股票名称"] = [
item["n"] for item in data_df["ms"]
]
data_df["板块异动最频繁个股及所属类型-买卖方向"] = data_df[
"板块异动最频繁个股及所属类型-买卖方向"
].map({0: "大笔买入", 1: "大笔卖出"})
data_df = data_df[
[
"板块名称",
"涨跌幅",
"主力净流入",
"板块异动总次数",
"板块异动最频繁个股及所属类型-股票代码",
"板块异动最频繁个股及所属类型-股票名称",
"板块异动最频繁个股及所属类型-买卖方向",
"板块具体异动类型列表及出现次数",
]
]
data_df["涨跌幅"] = pd.to_numeric(data_df["涨跌幅"], errors="coerce")
data_df["主力净流入"] = pd.to_numeric(data_df["主力净流入"], errors="coerce")
data_df["板块异动总次数"] = pd.to_numeric(
data_df["板块异动总次数"], errors="coerce"
)
return data_df
if __name__ == "__main__":
stock_changes_em_df = stock_changes_em(symbol="大笔买入")
print(stock_changes_em_df)
stock_board_change_em_df = stock_board_change_em()
print(stock_board_change_em_df)
for item in {
"火箭发射",
"快速反弹",
"大笔买入",
"封涨停板",
"打开跌停板",
"有大买盘",
"竞价上涨",
"高开5日线",
"向上缺口",
"60日新高",
"60日大幅上涨",
"加速下跌",
"高台跳水",
"大笔卖出",
"封跌停板",
"打开涨停板",
"有大卖盘",
"竞价下跌",
"低开5日线",
"向下缺口",
"60日新低",
"60日大幅下跌",
}:
stock_changes_em_df = stock_changes_em(symbol=item)
print(stock_changes_em_df)
@@ -0,0 +1,97 @@
#!/usr/bin/env python
# -*- coding:utf-8 -*-
"""
Date: 2022/9/21 16:49
Desc: 东方财富网-数据中心-特色数据-券商业绩月报
http://data.eastmoney.com/other/qsjy.html
"""
import pandas as pd
import requests
def stock_qsjy_em(date: str = "20200731") -> pd.DataFrame:
"""
东方财富网-数据中心-特色数据-券商业绩月报
http://data.eastmoney.com/other/qsjy.html
:param date: 数据月份 2010-06-01 开始, e.g., 需要 2011 7 , 则输入 2011-07-01
:type date: str
:return: 券商业绩月报
:rtype: pandas.DataFrame
"""
url = "https://datacenter-web.eastmoney.com/api/data/v1/get"
params = {
"sortColumns": "END_DATE",
"sortTypes": "-1",
"pageSize": "500",
"pageNumber": "1",
"reportName": "RPT_PERFORMANCE",
"columns": "SECURITY_CODE,SECURITY_NAME_ABBR,END_DATE,NETPROFIT,NP_YOY,NP_QOQ,ACCUMPROFIT,ACCUMPROFIT_YOY,OPERATE_INCOME,OI_YOY,OI_QOQ,ACCUMOI,ACCUMOI_YOY,NET_ASSETS,NA_YOY",
"source": "WEB",
"client": "WEB",
"filter": f"(END_DATE='{'-'.join([date[:4], date[4:6], date[6:]])}')",
}
r = requests.get(url, params=params)
data_json = r.json()
temp_df = pd.DataFrame(data_json["result"]["data"])
temp_df.columns = [
"代码",
"简称",
"-",
"当月净利润-净利润",
"当月净利润-同比增长",
"当月净利润-环比增长",
"当年累计净利润-累计净利润",
"当年累计净利润-同比增长",
"当月营业收入-营业收入",
"当月营业收入-环比增长",
"当月营业收入-同比增长",
"当年累计营业收入-累计营业收入",
"当年累计营业收入-同比增长",
"净资产-净资产",
"净资产-同比增长",
]
temp_df = temp_df[
[
"简称",
"代码",
"当月净利润-净利润",
"当月净利润-同比增长",
"当月净利润-环比增长",
"当年累计净利润-累计净利润",
"当年累计净利润-同比增长",
"当月营业收入-营业收入",
"当月营业收入-环比增长",
"当月营业收入-同比增长",
"当年累计营业收入-累计营业收入",
"当年累计营业收入-同比增长",
"净资产-净资产",
"净资产-同比增长",
]
]
temp_df["当月净利润-净利润"] = pd.to_numeric(temp_df["当月净利润-净利润"])
temp_df["当月净利润-同比增长"] = pd.to_numeric(temp_df["当月净利润-同比增长"])
temp_df["当月净利润-环比增长"] = pd.to_numeric(temp_df["当月净利润-环比增长"])
temp_df["当年累计净利润-累计净利润"] = pd.to_numeric(
temp_df["当年累计净利润-累计净利润"]
)
temp_df["当年累计净利润-同比增长"] = pd.to_numeric(
temp_df["当年累计净利润-同比增长"]
)
temp_df["当月营业收入-营业收入"] = pd.to_numeric(temp_df["当月营业收入-营业收入"])
temp_df["当月营业收入-环比增长"] = pd.to_numeric(temp_df["当月营业收入-环比增长"])
temp_df["当月营业收入-同比增长"] = pd.to_numeric(temp_df["当月营业收入-同比增长"])
temp_df["当年累计营业收入-累计营业收入"] = pd.to_numeric(
temp_df["当年累计营业收入-累计营业收入"]
)
temp_df["当年累计营业收入-同比增长"] = pd.to_numeric(
temp_df["当年累计营业收入-同比增长"]
)
temp_df["净资产-净资产"] = pd.to_numeric(temp_df["净资产-净资产"])
temp_df["净资产-同比增长"] = pd.to_numeric(temp_df["净资产-同比增长"])
return temp_df
if __name__ == "__main__":
stock_qsjy_em_df = stock_qsjy_em(date="20200430")
print(stock_qsjy_em_df)
@@ -0,0 +1,586 @@
#!/usr/bin/env python
# -*- coding:utf-8 -*-
"""
Date: 2024/9/20 15:30
Desc: 东方财富-数据中心-年报季报-业绩快报-三大报表
资产负债表
https://data.eastmoney.com/bbsj/202003/zcfz.html
利润表
https://data.eastmoney.com/bbsj/202003/lrb.html
现金流量表
https://data.eastmoney.com/bbsj/202003/xjll.html
"""
import pandas as pd
import requests
from akshare.utils.tqdm import get_tqdm
def stock_zcfz_em(date: str = "20240331") -> pd.DataFrame:
"""
东方财富-数据中心-年报季报-业绩快报-资产负债表
https://data.eastmoney.com/bbsj/202003/zcfz.html
:param date: choice of {"20200331", "20200630", "20200930", "20201231", "..."}; 20100331 开始
:type date: str
:return: 资产负债表
:rtype: pandas.DataFrame
"""
import warnings
warnings.filterwarnings(action="ignore", category=FutureWarning)
url = "https://datacenter-web.eastmoney.com/api/data/v1/get"
params = {
"sortColumns": "NOTICE_DATE,SECURITY_CODE",
"sortTypes": "-1,-1",
"pageSize": "500",
"pageNumber": "1",
"reportName": "RPT_DMSK_FN_BALANCE",
"columns": "ALL",
"filter": f"""(SECURITY_TYPE_CODE in ("058001001","058001008"))(TRADE_MARKET_CODE!="069001017")
(REPORT_DATE='{"-".join([date[:4], date[4:6], date[6:]])}')""",
}
r = requests.get(url, params=params)
data_json = r.json()
page_num = data_json["result"]["pages"]
big_df = pd.DataFrame()
tqdm = get_tqdm()
for page in tqdm(range(1, page_num + 1), leave=False):
params.update(
{
"pageNumber": page,
}
)
r = requests.get(url, params=params)
data_json = r.json()
temp_df = pd.DataFrame(data_json["result"]["data"])
big_df = pd.concat(objs=[big_df, temp_df], join="outer", ignore_index=True)
big_df.reset_index(inplace=True)
big_df["index"] = big_df.index + 1
big_df.columns = [
"序号",
"_",
"股票代码",
"_",
"_",
"股票简称",
"_",
"_",
"_",
"_",
"_",
"_",
"_",
"公告日期",
"_",
"资产-总资产",
"_",
"资产-货币资金",
"_",
"资产-应收账款",
"_",
"资产-存货",
"_",
"负债-总负债",
"负债-应付账款",
"_",
"负债-预收账款",
"_",
"股东权益合计",
"_",
"资产-总资产同比",
"负债-总负债同比",
"_",
"资产负债率",
"_",
"_",
"_",
"_",
"_",
"_",
"_",
"_",
"_",
"_",
"_",
"_",
"_",
"_",
"_",
"_",
"_",
"_",
"_",
"_",
"_",
"_",
"_",
"_",
]
big_df = big_df[
[
"序号",
"股票代码",
"股票简称",
"资产-货币资金",
"资产-应收账款",
"资产-存货",
"资产-总资产",
"资产-总资产同比",
"负债-应付账款",
"负债-预收账款",
"负债-总负债",
"负债-总负债同比",
"资产负债率",
"股东权益合计",
"公告日期",
]
]
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["资产-总资产同比"], 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["负债-总负债同比"], 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_datetime(big_df["公告日期"], errors="coerce").dt.date
return big_df
def stock_zcfz_bj_em(date: str = "20240331") -> pd.DataFrame:
"""
东方财富-数据中心-年报季报-业绩快报-资产负债表
https://data.eastmoney.com/bbsj/202003/zcfz.html
:param date: choice of {"20200331", "20200630", "20200930", "20201231", "..."}; 20100331 开始
:type date: str
:return: 资产负债表
:rtype: pandas.DataFrame
"""
import warnings
warnings.filterwarnings(action="ignore", category=FutureWarning)
url = "https://datacenter-web.eastmoney.com/api/data/v1/get"
params = {
"sortColumns": "NOTICE_DATE,SECURITY_CODE",
"sortTypes": "-1,-1",
"pageSize": "500",
"pageNumber": "1",
"reportName": "RPT_DMSK_FN_BALANCE",
"columns": "ALL",
"filter": f"""(TRADE_MARKET_CODE="069001017")
(REPORT_DATE='{"-".join([date[:4], date[4:6], date[6:]])}')""",
}
r = requests.get(url, params=params)
data_json = r.json()
page_num = data_json["result"]["pages"]
big_df = pd.DataFrame()
tqdm = get_tqdm()
for page in tqdm(range(1, page_num + 1), leave=False):
params.update(
{
"pageNumber": page,
}
)
r = requests.get(url, params=params)
data_json = r.json()
temp_df = pd.DataFrame(data_json["result"]["data"])
big_df = pd.concat(objs=[big_df, temp_df], join="outer", ignore_index=True)
big_df.reset_index(inplace=True)
big_df["index"] = big_df.index + 1
big_df.columns = [
"序号",
"_",
"股票代码",
"_",
"_",
"股票简称",
"_",
"_",
"_",
"_",
"_",
"_",
"_",
"公告日期",
"_",
"资产-总资产",
"_",
"资产-货币资金",
"_",
"资产-应收账款",
"_",
"资产-存货",
"_",
"负债-总负债",
"负债-应付账款",
"_",
"负债-预收账款",
"_",
"股东权益合计",
"_",
"资产-总资产同比",
"负债-总负债同比",
"_",
"资产负债率",
"_",
"_",
"_",
"_",
"_",
"_",
"_",
"_",
"_",
"_",
"_",
"_",
"_",
"_",
"_",
"_",
"_",
"_",
"_",
"_",
"_",
"_",
"_",
"_",
]
big_df = big_df[
[
"序号",
"股票代码",
"股票简称",
"资产-货币资金",
"资产-应收账款",
"资产-存货",
"资产-总资产",
"资产-总资产同比",
"负债-应付账款",
"负债-预收账款",
"负债-总负债",
"负债-总负债同比",
"资产负债率",
"股东权益合计",
"公告日期",
]
]
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["资产-总资产同比"], 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["负债-总负债同比"], 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_datetime(big_df["公告日期"], errors="coerce").dt.date
return big_df
def stock_lrb_em(date: str = "20240331") -> pd.DataFrame:
"""
东方财富-数据中心-年报季报-业绩快报-利润表
https://data.eastmoney.com/bbsj/202003/lrb.html
:param date: choice of {"20200331", "20200630", "20200930", "20201231", "..."}; 20100331 开始
:type date: str
:return: 利润表
:rtype: pandas.DataFrame
"""
import warnings
warnings.filterwarnings(action="ignore", category=FutureWarning)
url = "https://datacenter-web.eastmoney.com/api/data/v1/get"
params = {
"sortColumns": "NOTICE_DATE,SECURITY_CODE",
"sortTypes": "-1,-1",
"pageSize": "500",
"pageNumber": "1",
"reportName": "RPT_DMSK_FN_INCOME",
"columns": "ALL",
"filter": f"""(SECURITY_TYPE_CODE in ("058001001","058001008"))(TRADE_MARKET_CODE!="069001017")
(REPORT_DATE='{"-".join([date[:4], date[4:6], date[6:]])}')""",
}
r = requests.get(url, params=params)
data_json = r.json()
page_num = data_json["result"]["pages"]
big_df = pd.DataFrame()
tqdm = get_tqdm()
for page in tqdm(range(1, page_num + 1), leave=False):
params.update(
{
"pageNumber": page,
}
)
r = requests.get(url, params=params)
data_json = r.json()
temp_df = pd.DataFrame(data_json["result"]["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 = big_df[
[
"序号",
"股票代码",
"股票简称",
"净利润",
"净利润同比",
"营业总收入",
"营业总收入同比",
"营业总支出-营业支出",
"营业总支出-销售费用",
"营业总支出-管理费用",
"营业总支出-财务费用",
"营业总支出-营业总支出",
"营业利润",
"利润总额",
"公告日期",
]
]
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["营业总支出-营业支出"], 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["营业总支出-营业总支出"], errors="coerce"
)
big_df["营业利润"] = pd.to_numeric(big_df["营业利润"], errors="coerce")
big_df["利润总额"] = pd.to_numeric(big_df["利润总额"], errors="coerce")
big_df["公告日期"] = pd.to_datetime(big_df["公告日期"], errors="coerce").dt.date
return big_df
def stock_xjll_em(date: str = "20240331") -> pd.DataFrame:
"""
东方财富-数据中心-年报季报-业绩快报-现金流量表
https://data.eastmoney.com/bbsj/202003/xjll.html
:param date: choice of {"20200331", "20200630", "20200930", "20201231", "..."}; 20100331 开始
:type date: str
:return: 现金流量表
:rtype: pandas.DataFrame
"""
import warnings
warnings.filterwarnings(action="ignore", category=FutureWarning)
url = "https://datacenter-web.eastmoney.com/api/data/v1/get"
params = {
"sortColumns": "NOTICE_DATE,SECURITY_CODE",
"sortTypes": "-1,-1",
"pageSize": "500",
"pageNumber": "1",
"reportName": "RPT_DMSK_FN_CASHFLOW",
"columns": "ALL",
"filter": f"""(SECURITY_TYPE_CODE in ("058001001","058001008"))(TRADE_MARKET_CODE!="069001017")
(REPORT_DATE='{"-".join([date[:4], date[4:6], date[6:]])}')""",
}
r = requests.get(url, params=params)
data_json = r.json()
page_num = data_json["result"]["pages"]
big_df = pd.DataFrame()
tqdm = get_tqdm()
for page in tqdm(range(1, page_num + 1), leave=False):
params.update(
{
"pageNumber": page,
}
)
r = requests.get(url, params=params)
data_json = r.json()
temp_df = pd.DataFrame(data_json["result"]["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 = big_df[
[
"序号",
"股票代码",
"股票简称",
"净现金流-净现金流",
"净现金流-同比增长",
"经营性现金流-现金流量净额",
"经营性现金流-净现金流占比",
"投资性现金流-现金流量净额",
"投资性现金流-净现金流占比",
"融资性现金流-现金流量净额",
"融资性现金流-净现金流占比",
"公告日期",
]
]
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["投资性现金流-现金流量净额"], 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_datetime(big_df["公告日期"], errors="coerce").dt.date
return big_df
if __name__ == "__main__":
stock_zcfz_em_df = stock_zcfz_em(date="20240331")
print(stock_zcfz_em_df)
stock_zcfz_bj_em_df = stock_zcfz_bj_em(date="20240331")
print(stock_zcfz_bj_em_df)
stock_lrb_em_df = stock_lrb_em(date="20240331")
print(stock_lrb_em_df)
stock_xjll_em_df = stock_xjll_em(date="20240331")
print(stock_xjll_em_df)
@@ -0,0 +1,179 @@
#!/usr/bin/env python
# -*- coding:utf-8 -*-
"""
Date: 2025/2/28 13:00
Desc: 东方财富网-数据中心-研究报告-个股研报
https://data.eastmoney.com/report/stock.jshtml
"""
import datetime
import pandas as pd
import requests
from akshare.utils.tqdm import get_tqdm
def stock_research_report_em(symbol: str = "000001") -> pd.DataFrame:
"""
东方财富网-数据中心-研究报告-个股研报
https://data.eastmoney.com/report/stock.jshtml
:param symbol: 个股代码
:type symbol: str
:return: 个股研报
:rtype: pandas.DataFrame
"""
url = "https://reportapi.eastmoney.com/report/list"
params = {
"industryCode": "*",
"pageSize": "5000",
"industry": "*",
"rating": "*",
"ratingChange": "*",
"beginTime": "2000-01-01",
"endTime": f"{datetime.datetime.now().year + 1}-01-01",
"pageNo": "1",
"fields": "",
"qType": "0",
"orgCode": "",
"code": symbol,
"rcode": "",
"p": "1",
"pageNum": "1",
"pageNumber": "1",
}
r = requests.get(url, params=params)
data_json = r.json()
total_page = data_json["TotalPage"]
current_year = data_json["currentYear"]
big_df = pd.DataFrame()
tqdm = get_tqdm()
for page in tqdm(range(1, total_page + 1), leave=False):
params.update(
{
"pageNo": page,
"p": page,
"pageNum": page,
"pageNumber": page,
}
)
r = requests.get(url, params=params)
data_json = r.json()
temp_df = pd.DataFrame(data_json["data"])
big_df = pd.concat(objs=[big_df, temp_df], axis=0, ignore_index=True)
big_df.reset_index(inplace=True)
big_df["index"] = big_df["index"] + 1
predict_this_year_eps_title = f"{current_year}-盈利预测-收益"
predict_this_year_pe_title = f"{current_year}-盈利预测-市盈率"
predict_next_year_eps_title = f"{current_year + 1}-盈利预测-收益"
predict_next_year_pe_title = f"{current_year + 1}-盈利预测-市盈率"
predict_next_two_year_eps_title = f"{current_year + 2}-盈利预测-收益"
predict_next_two_year_pe_title = f"{current_year + 2}-盈利预测-市盈率"
big_df["pdfUrl"] = big_df["infoCode"].apply(
lambda x: f"https://pdf.dfcfw.com/pdf/H3_{x}_1.pdf"
)
big_df.rename(
columns={
"index": "序号",
"title": "报告名称",
"stockName": "股票简称",
"stockCode": "股票代码",
"orgCode": "-",
"orgName": "-",
"orgSName": "机构",
"publishDate": "日期",
"infoCode": "-",
"column": "-",
"predictNextTwoYearEps": predict_next_two_year_eps_title,
"predictNextTwoYearPe": predict_next_two_year_pe_title,
"predictNextYearEps": predict_next_year_eps_title,
"predictNextYearPe": predict_next_year_pe_title,
"predictThisYearEps": predict_this_year_eps_title,
"predictThisYearPe": predict_this_year_pe_title,
"predictLastYearEps": "-",
"predictLastYearPe": "-",
"actualLastTwoYearEps": "-",
"actualLastYearEps": "-",
"industryCode": "-",
"industryName": "-",
"emIndustryCode": "-",
"indvInduCode": "-",
"indvInduName": "行业",
"emRatingCode": "-",
"emRatingValue": "-",
"emRatingName": "东财评级",
"lastEmRatingCode": "-",
"lastEmRatingValue": "-",
"lastEmRatingName": "-",
"ratingChange": "-",
"reportType": "-",
"author": "-",
"indvIsNew": "-",
"researcher": "-",
"newListingDate": "-",
"newPurchaseDate": "-",
"newIssuePrice": "-",
"newPeIssueA": "-",
"indvAimPriceT": "-",
"indvAimPriceL": "-",
"attachType": "-",
"attachSize": "-",
"attachPages": "-",
"encodeUrl": "-",
"sRatingName": "-",
"sRatingCode": "-",
"market": "-",
"authorID": "-",
"count": "近一月个股研报数",
"orgType": "-",
"pdfUrl": "报告PDF链接",
},
inplace=True,
)
big_df = big_df[
[
"序号",
"股票代码",
"股票简称",
"报告名称",
"东财评级",
"机构",
"近一月个股研报数",
predict_this_year_eps_title,
predict_this_year_pe_title,
predict_next_year_eps_title,
predict_next_year_pe_title,
predict_next_two_year_eps_title,
predict_next_two_year_pe_title,
"行业",
"日期",
"报告PDF链接",
]
]
big_df["日期"] = pd.to_datetime(big_df["日期"], errors="coerce").dt.date
big_df["近一月个股研报数"] = pd.to_numeric(
big_df["近一月个股研报数"], errors="coerce"
)
big_df[predict_this_year_eps_title] = pd.to_numeric(
big_df[predict_this_year_eps_title], errors="coerce"
)
big_df[predict_this_year_pe_title] = pd.to_numeric(
big_df[predict_this_year_pe_title], errors="coerce"
)
big_df[predict_next_year_eps_title] = pd.to_numeric(
big_df[predict_next_year_eps_title], errors="coerce"
)
big_df[predict_next_year_pe_title] = pd.to_numeric(
big_df[predict_next_year_pe_title], errors="coerce"
)
big_df[predict_next_two_year_eps_title] = pd.to_numeric(
big_df[predict_next_two_year_eps_title], errors="coerce"
)
big_df[predict_next_two_year_pe_title] = pd.to_numeric(
big_df[predict_next_two_year_pe_title], errors="coerce"
)
return big_df
if __name__ == "__main__":
stock_research_report_em_df = stock_research_report_em(symbol="000001")
print(stock_research_report_em_df)
@@ -0,0 +1,151 @@
#!/usr/bin/env python
# -*- coding:utf-8 -*-
"""
Date: 2024/5/21 19:20
Desc: 上证e互动-提问与回答
https://sns.sseinfo.com/
"""
import warnings
from functools import lru_cache
import pandas as pd
import requests
from bs4 import BeautifulSoup
from akshare.utils.tqdm import get_tqdm
@lru_cache()
def _fetch_stock_uid() -> dict:
"""
上证e互动-代码ID映射
https://sns.sseinfo.com/list/company.do
:return: 代码ID映射
:rtype: str
"""
url = "https://sns.sseinfo.com/allcompany.do"
data = {
"code": "0",
"order": "2",
"areaId": "0",
"page": "1",
}
uid_list = list()
code_list = list()
tqdm = get_tqdm()
for page in tqdm(range(1, 73), leave=False):
data.update({"page": page})
r = requests.post(url, data=data)
data_json = r.json()
soup = BeautifulSoup(data_json["content"], features="lxml")
soup.find_all(name="a", attrs={"rel": "tag"})
uid_list.extend(
[item["uid"] for item in soup.find_all(name="a", attrs={"rel": "tag"})]
)
code_list.extend(
[
item.find("img")["src"].split("?")[0].split("/")[-1].split(".")[0]
for item in soup.find_all(name="a", attrs={"rel": "tag"})
]
)
code_uid_map = dict(zip(code_list, uid_list))
return code_uid_map
def stock_sns_sseinfo(symbol: str = "603119") -> pd.DataFrame:
"""
上证e互动-提问与回答
https://sns.sseinfo.com/company.do?uid=65
:param symbol: 股票代码
:type symbol: str
:return: 提问与回答
:rtype: str
"""
code_uid_map = _fetch_stock_uid()
url = "https://sns.sseinfo.com/ajax/userfeeds.do"
params = {
"typeCode": "company",
"type": "11",
"pageSize": "100",
"uid": code_uid_map[symbol],
"page": "1",
}
big_df = pd.DataFrame()
page = 1
warnings.warn("正在下载中")
while True:
params.update({"page": page})
r = requests.post(url, params=params)
if len(r.text) < 300:
break
else:
page += 1
r = requests.post(url, params=params)
soup = BeautifulSoup(r.text, features="lxml")
content_list = [
item.get_text().strip()
for item in soup.find_all(name="div", attrs={"class": "m_feed_txt"})
]
date_list = [
item.get_text().strip().split("\n")[0]
for item in soup.find_all(name="div", attrs={"class": "m_feed_from"})
]
source_list = [
item.get_text().strip().split("\n")[2]
for item in soup.find_all(name="div", attrs={"class": "m_feed_from"})
]
q_list = [
item.split(")")[1]
for index, item in enumerate(content_list)
if index % 2 == 0
]
stock_name = [
item.split("(")[0].strip(":")
for index, item in enumerate(content_list)
if index % 2 == 0
]
stock_code = [
item.split("(")[1].split(")")[0]
for index, item in enumerate(content_list)
if index % 2 == 0
]
a_list = [item for index, item in enumerate(content_list) if index % 2 != 0]
d_q_list = [item for index, item in enumerate(date_list) if index % 2 == 0]
d_a_list = [item for index, item in enumerate(date_list) if index % 2 != 0]
s_q_list = [item for index, item in enumerate(source_list) if index % 2 == 0]
s_a_list = [item for index, item in enumerate(source_list) if index % 2 != 0]
author_name = [
item["title"] for item in soup.find_all(name="a", attrs={"rel": "face"})
]
temp_df = pd.DataFrame(
[
stock_code,
stock_name,
q_list,
a_list,
d_q_list,
d_a_list,
s_q_list,
s_a_list,
author_name,
]
).T
temp_df.columns = [
"股票代码",
"公司简称",
"问题",
"回答",
"问题时间",
"回答时间",
"问题来源",
"回答来源",
"用户名",
]
big_df = pd.concat(objs=[big_df, temp_df], ignore_index=True)
return big_df
if __name__ == "__main__":
stock_sns_sseinfo_df = stock_sns_sseinfo(symbol="603119")
print(stock_sns_sseinfo_df)
@@ -0,0 +1,468 @@
#!/usr/bin/env python
# -*- coding:utf-8 -*-
"""
Date: 2024/9/15 15:30
Desc: 东方财富网-数据中心-特色数据-商誉
东方财富网-数据中心-特色数据-商誉-A股商誉市场概况: https://data.eastmoney.com/sy/scgk.html
东方财富网-数据中心-特色数据-商誉-商誉减值预期明细: https://data.eastmoney.com/sy/yqlist.html
东方财富网-数据中心-特色数据-商誉-个股商誉减值明细: https://data.eastmoney.com/sy/jzlist.html
东方财富网-数据中心-特色数据-商誉-个股商誉明细: https://data.eastmoney.com/sy/list.html
东方财富网-数据中心-特色数据-商誉-行业商誉: https://data.eastmoney.com/sy/hylist.html
"""
import pandas as pd
import requests
from akshare.utils.tqdm import get_tqdm
def stock_sy_profile_em() -> pd.DataFrame:
"""
东方财富网-数据中心-特色数据-商誉-A股商誉市场概况
https://data.eastmoney.com/sy/scgk.html
:return: A股商誉市场概况
:rtype: pandas.DataFrame
"""
url = "https://datacenter-web.eastmoney.com/api/data/v1/get"
params = {
"sortColumns": "REPORT_DATE",
"sortTypes": "-1",
"pageSize": "5000",
"pageNumber": "1",
"reportName": "RPT_GOODWILL_MARKETSTATISTICS",
"token": "894050c76af8597a853f5b408b759f5d",
"columns": "ALL",
"filter": """((GOODWILL_STATE="1")( | IMPAIRMENT_STATE="1"))(TRADE_BOARD="all")""",
}
r = requests.get(url, params=params)
data_json = r.json()
data_df = pd.DataFrame(data_json["result"]["data"])
data_df.columns = [
"_",
"报告期",
"商誉",
"商誉减值",
"净资产",
"商誉占净资产比例",
"商誉减值占净资产比例",
"净利润规模",
"商誉减值占净利润比例",
"_",
"_",
]
data_df = data_df[
[
"报告期",
"商誉",
"商誉减值",
"净资产",
"商誉占净资产比例",
"商誉减值占净资产比例",
"净利润规模",
"商誉减值占净利润比例",
]
]
data_df["报告期"] = pd.to_datetime(data_df["报告期"], errors="coerce").dt.date
data_df["商誉"] = pd.to_numeric(data_df["商誉"], errors="coerce")
data_df["商誉减值"] = pd.to_numeric(data_df["商誉减值"], errors="coerce")
data_df["净资产"] = pd.to_numeric(data_df["净资产"], errors="coerce")
data_df["商誉占净资产比例"] = pd.to_numeric(
data_df["商誉占净资产比例"], errors="coerce"
)
data_df["商誉减值占净资产比例"] = pd.to_numeric(
data_df["商誉减值占净资产比例"], errors="coerce"
)
data_df["净利润规模"] = pd.to_numeric(data_df["净利润规模"], errors="coerce")
data_df["商誉减值占净利润比例"] = pd.to_numeric(
data_df["商誉减值占净利润比例"], errors="coerce"
)
data_df.sort_values(["报告期"], inplace=True, ignore_index=True)
return data_df
def stock_sy_yq_em(date: str = "20240630") -> pd.DataFrame:
"""
东方财富网-数据中心-特色数据-商誉-商誉减值预期明细
https://data.eastmoney.com/sy/yqlist.html
:param date: 参考网站指定的数据日期
:type date: str
:return: 商誉减值预期明细
:rtype: pandas.DataFrame
"""
url = "https://datacenter-web.eastmoney.com/api/data/v1/get"
params = {
"sortColumns": "NOTICE_DATE,SECURITY_CODE",
"sortTypes": "-1,-1",
"pageSize": "5000",
"pageNumber": "1",
"columns": "ALL",
"token": "894050c76af8597a853f5b408b759f5d",
"reportName": "RPT_GOODWILL_STOCKPREDICT",
"filter": f"""(REPORT_DATE='{"-".join([date[:4], date[4:6], date[6:]])}')""",
}
r = requests.get(url, params=params)
data_json = r.json()
big_df = pd.DataFrame()
total_page = int(data_json["result"]["pages"])
tqdm = get_tqdm()
for page in tqdm(range(1, total_page + 1), leave=False):
params.update({"pageNumber": page})
r = requests.get(url, params=params)
data_json = r.json()
temp_df = pd.DataFrame(data_json["result"]["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.rename(
columns={
"index": "序号",
"SECUCODE": "-",
"SECURITY_CODE": "股票代码",
"ORG_CODE": "-",
"SECURITY_NAME_ABBR": "股票简称",
"TRADE_MARKET": "交易市场",
"INDUSTRY_NAME": "-",
"INDUSTRY_CODE": "-",
"NOTICE_DATE": "公告日期",
"REPORT_DATE": "数据日期",
"PE_REPORT_DATE": "-",
"PREDICT_NETPROFIT_LOWER": "预计净利润-下限",
"PREDICT_NETPROFIT_UPPER": "预计净利润-上限",
"PERFORM_CHANGE_UPPER": "业绩变动幅度-上限",
"PERFORM_CHANGE_LOWER": "业绩变动幅度-下限",
"PERFORM_CHANGE": "-",
"PERFORM_CHANGE_EXPLAIN": "业绩变动原因",
"PREDICT_TYPE": "-",
"PREDICT_INDICATOR_CODE": "-",
"PREDICT_PERIOD": "-",
"PE_SAMEREPORT_NETPROFIT": "上年度同期净利润",
"NETPROFIT": "-",
"PE_GOODWILL": "上年商誉",
"NEWEST_REPORT_DATE": "最新商誉报告期",
"NEWEST_GOODWILL": "最新一期商誉",
"PE_SAMEREPORT_DATE": "-",
},
inplace=True,
)
big_df = big_df[
[
"序号",
"股票代码",
"股票简称",
"业绩变动原因",
"最新商誉报告期",
"最新一期商誉",
"上年商誉",
"预计净利润-下限",
"预计净利润-上限",
"业绩变动幅度-下限",
"业绩变动幅度-上限",
"上年度同期净利润",
"公告日期",
"交易市场",
]
]
big_df["交易市场"] = big_df["交易市场"].map(
{"shzb": "沪市主板", "kcb": "科创板", "szzb": "深市主板", "cyb": "创业板"}
)
big_df["最新商誉报告期"] = pd.to_datetime(
big_df["最新商誉报告期"], errors="coerce"
).dt.date
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["业绩变动幅度-下限"], errors="coerce"
)
big_df["业绩变动幅度-上限"] = pd.to_numeric(
big_df["业绩变动幅度-上限"], errors="coerce"
)
big_df["上年度同期净利润"] = pd.to_numeric(
big_df["上年度同期净利润"], errors="coerce"
)
return big_df
def stock_sy_jz_em(date: str = "20240630") -> pd.DataFrame:
"""
东方财富网-数据中心-特色数据-商誉-个股商誉减值明细
https://data.eastmoney.com/sy/jzlist.html
:param date: 参考网站指定的数据日期
:type date: str
:return: 个股商誉减值明细
:rtype: pandas.DataFrame
"""
url = "https://datacenter-web.eastmoney.com/api/data/v1/get"
params = {
"sortColumns": "GOODWILL_CHANGE",
"sortTypes": "-1",
"pageSize": "5000",
"pageNumber": "1",
"columns": "ALL",
"token": "894050c76af8597a853f5b408b759f5d",
"reportName": "RPT_GOODWILL_STOCKDETAILS",
"filter": f"""(REPORT_DATE='{"-".join([date[:4], date[4:6], date[6:]])}')""",
}
r = requests.get(url, params=params)
data_json = r.json()
big_df = pd.DataFrame()
total_page = int(data_json["result"]["pages"])
tqdm = get_tqdm()
for page in tqdm(range(1, total_page + 1), leave=False):
params.update({"pageNumber": page})
r = requests.get(url, params=params)
data_json = r.json()
temp_df = pd.DataFrame(data_json["result"]["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.rename(
columns={
"index": "序号",
"SECUCODE": "-",
"SECURITY_CODE": "股票代码",
"SECURITY_NAME_ABBR": "股票简称",
"ORG_CODE": "-",
"LISTING_DATE": "-",
"LISTING_STATE": "-",
"TRADE_BOARD": "交易市场",
"GOODWILL": "商誉",
"DATE_TYPE": "-",
"REPORT_TYPE_CODE": "-",
"DATA_ADJUST_TYPE": "-",
"NOTICE_DATE": "公告日期",
"REPORT_DATE": "数据日期",
"GOODWILL_PRE": "-",
"GOODWILL_CHANGE": "商誉减值",
"SUMSHEQUITY": "-",
"SUMSHEQUITY_RATIO": "商誉占净资产比例",
"SE_CHANGE_RATIO": "商誉减值占净资产比例",
"PARENTNETPROFIT": "净利润",
"PNP_CHANGE_RATIO": "商誉减值占净利润比例",
"PNP_YOY_RATIO": "-",
"INDUSTRY_CFT": "-",
"INDUSTRY_CFTCODE": "-",
"IS_SHOW": "-",
"MAXREPORTDATE": "-",
},
inplace=True,
)
big_df = big_df[
[
"序号",
"股票代码",
"股票简称",
"商誉",
"商誉减值",
"商誉占净资产比例",
"商誉减值占净资产比例",
"净利润",
"商誉减值占净利润比例",
"公告日期",
"交易市场",
]
]
big_df["交易市场"] = big_df["交易市场"].map(
{"shzb": "沪市主板", "kcb": "科创板", "szzb": "深市主板", "cyb": "创业板"}
)
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["净利润"], errors="coerce")
big_df["商誉减值占净利润比例"] = pd.to_numeric(
big_df["商誉减值占净利润比例"], errors="coerce"
)
big_df["商誉减值占净利润比例"] = pd.to_numeric(
big_df["商誉减值占净利润比例"], errors="coerce"
)
return big_df
def stock_sy_em(date: str = "20231231") -> pd.DataFrame:
"""
东方财富网-数据中心-特色数据-商誉-个股商誉明细
https://data.eastmoney.com/sy/list.html
:param date: 参考网站指定的数据日期
:type date: str
:return: 个股商誉明细
:rtype: pandas.DataFrame
"""
url = "https://datacenter-web.eastmoney.com/api/data/v1/get"
params = {
"sortColumns": "NOTICE_DATE,SECURITY_CODE",
"sortTypes": "-1,-1",
"pageSize": "5000",
"pageNumber": "1",
"columns": "ALL",
"token": "894050c76af8597a853f5b408b759f5d",
"reportName": "RPT_GOODWILL_STOCKDETAILS",
"filter": f"""(REPORT_DATE='{"-".join([date[:4], date[4:6], date[6:]])}')""",
}
r = requests.get(url, params=params)
data_json = r.json()
big_df = pd.DataFrame()
total_page = int(data_json["result"]["pages"])
tqdm = get_tqdm()
for page in tqdm(range(1, total_page + 1), leave=False):
params.update({"pageNumber": page})
r = requests.get(url, params=params)
data_json = r.json()
temp_df = pd.DataFrame(data_json["result"]["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.rename(
columns={
"index": "序号",
"SECUCODE": "-",
"SECURITY_CODE": "股票代码",
"SECURITY_NAME_ABBR": "股票简称",
"ORG_CODE": "-",
"LISTING_DATE": "-",
"LISTING_STATE": "-",
"TRADE_BOARD": "交易市场",
"GOODWILL": "商誉",
"DATE_TYPE": "-",
"REPORT_TYPE_CODE": "-",
"DATA_ADJUST_TYPE": "-",
"NOTICE_DATE": "公告日期",
"REPORT_DATE": "数据日期",
"GOODWILL_PRE": "上年商誉",
"GOODWILL_CHANGE": "商誉减值",
"SUMSHEQUITY": "-",
"SUMSHEQUITY_RATIO": "商誉占净资产比例",
"SE_CHANGE_RATIO": "商誉减值占净资产比例",
"PARENTNETPROFIT": "净利润",
"PNP_CHANGE_RATIO": "商誉减值占净利润比例",
"PNP_YOY_RATIO": "净利润同比",
"INDUSTRY_CFT": "-",
"INDUSTRY_CFTCODE": "-",
"IS_SHOW": "-",
"MAXREPORTDATE": "-",
},
inplace=True,
)
big_df = big_df[
[
"序号",
"股票代码",
"股票简称",
"商誉",
"商誉占净资产比例",
"净利润",
"净利润同比",
"上年商誉",
"公告日期",
"交易市场",
]
]
big_df["交易市场"] = big_df["交易市场"].map(
{"shzb": "沪市主板", "kcb": "科创板", "szzb": "深市主板", "cyb": "创业板"}
)
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["上年商誉"], errors="coerce")
return big_df
def stock_sy_hy_em(date: str = "20240930") -> pd.DataFrame:
"""
东方财富网-数据中心-特色数据-商誉-行业商誉
https://data.eastmoney.com/sy/hylist.html
:param date: 参考网站指定的数据日期
:type date: str
:return: 个股商誉明细
:rtype: pandas.DataFrame
"""
url = "https://datacenter-web.eastmoney.com/api/data/v1/get"
params = {
"sortColumns": "SUMSHEQUITY_RATIO",
"sortTypes": "-1",
"pageSize": "5000",
"pageNumber": "1",
"columns": "ALL",
"token": "894050c76af8597a853f5b408b759f5d",
"reportName": "RPT_GOODWILL_INDUSTATISTICS",
"filter": f"""(REPORT_DATE='{"-".join([date[:4], date[4:6], date[6:]])}')""",
}
r = requests.get(url, params=params)
data_json = r.json()
big_df = pd.DataFrame()
total_page = int(data_json["result"]["pages"])
tqdm = get_tqdm()
for page in tqdm(range(1, total_page + 1), leave=False):
params.update({"pageNumber": page})
r = requests.get(url, params=params)
data_json = r.json()
temp_df = pd.DataFrame(data_json["result"]["data"])
big_df = pd.concat(objs=[big_df, temp_df], ignore_index=True)
big_df.reset_index(inplace=True, drop=True)
big_df.rename(
columns={
"REPORT_DATE": "数据日期",
"INDUSTRY_NAME": "行业名称",
"INDUSTRY_CODE": "-",
"ORG_NUM": "公司家数",
"GOODWILL": "商誉规模",
"GOODWILL_CHANGE": "-",
"SUMSHEQUITY": "净资产",
"SUMSHEQUITY_RATIO": "商誉规模占净资产规模比例",
"SE_CHANGE_RATIO": "-",
"PARENTNETPROFIT": "净利润规模",
"PNP_CHANGE_RATIO": "-",
},
inplace=True,
)
big_df = big_df[
[
"行业名称",
"公司家数",
"商誉规模",
"净资产",
"商誉规模占净资产规模比例",
"净利润规模",
]
]
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["净利润规模"], errors="coerce")
return big_df
if __name__ == "__main__":
stock_sy_profile_em_df = stock_sy_profile_em()
print(stock_sy_profile_em_df)
stock_sy_yq_em_df = stock_sy_yq_em(date="20240630")
print(stock_sy_yq_em_df)
stock_sy_jz_em_df = stock_sy_jz_em(date="20240630")
print(stock_sy_jz_em_df)
stock_sy_em_df = stock_sy_em(date="20240630")
print(stock_sy_em_df)
stock_sy_hy_em_df = stock_sy_hy_em(date="20240930")
print(stock_sy_hy_em_df)
@@ -0,0 +1,970 @@
# -*- coding:utf-8 -*-
# !/usr/bin/env python
"""
Date: 2024/9/21 19:00
Desc: 同花顺-数据中心-技术选股
https://data.10jqka.com.cn/rank/cxg/
"""
import re
from io import StringIO
import pandas as pd
import py_mini_racer
import requests
from bs4 import BeautifulSoup
from akshare.datasets import get_ths_js
from akshare.utils.tqdm import get_tqdm
def _get_file_content_ths(file: str = "ths.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 stock_rank_cxg_ths(symbol: str = "创月新高") -> pd.DataFrame:
"""
同花顺-数据中心-技术选股-创新高
https://data.10jqka.com.cn/rank/cxg/
:param symbol: choice of {"创月新高", "半年新高", "一年新高", "历史新高"}
:type symbol: str
:return: 创新高数据
:rtype: pandas.DataFrame
"""
symbol_map = {
"创月新高": "4",
"半年新高": "3",
"一年新高": "2",
"历史新高": "1",
}
js_code = py_mini_racer.MiniRacer()
js_content = _get_file_content_ths("ths.js")
js_code.eval(js_content)
v_code = js_code.call("v")
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 "
"(KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36",
"Cookie": f"v={v_code}",
}
url = (
f"http://data.10jqka.com.cn/rank/cxg/board/{symbol_map[symbol]}/field/"
f"stockcode/order/asc/page/1/ajax/1/free/1/"
)
r = requests.get(url, headers=headers)
soup = BeautifulSoup(r.text, features="lxml")
try:
total_page = soup.find(name="span", attrs={"class": "page_info"}).text.split(
"/"
)[1]
except AttributeError:
total_page = 1
big_df = pd.DataFrame()
tqdm = get_tqdm()
for page in tqdm(range(1, int(total_page) + 1), leave=False):
v_code = js_code.call("v")
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 "
"(KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36",
"Cookie": f"v={v_code}",
}
url = (
f"http://data.10jqka.com.cn/rank/cxg/board/{symbol_map[symbol]}/field/stockcode/"
f"order/asc/page/{page}/ajax/1/free/1/"
)
r = requests.get(url, headers=headers)
html_fixed = re.sub(r'\srowspan="\d+"', '', r.text)
temp_df = pd.read_html(StringIO(html_fixed), header=0)[0] # 20260214 新增
big_df = pd.concat(objs=[big_df, temp_df], ignore_index=True)
big_df.columns = [
"序号",
"股票代码",
"股票简称",
"涨跌幅",
"换手率",
"最新价",
"前期高点",
"前期高点日期",
]
big_df["股票代码"] = big_df["股票代码"].astype(str).str.zfill(6)
big_df["涨跌幅"] = big_df["涨跌幅"].str.strip("%")
big_df["换手率"] = big_df["换手率"].str.strip("%")
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")
return big_df
def stock_rank_cxd_ths(symbol: str = "创月新低") -> pd.DataFrame:
"""
同花顺-数据中心-技术选股-创新低
https://data.10jqka.com.cn/rank/cxd/
:param symbol: choice of {"创月新低", "半年新低", "一年新低", "历史新低"}
:type symbol: str
:return: 创新低数据
:rtype: pandas.DataFrame
"""
symbol_map = {
"创月新低": "4",
"半年新低": "3",
"一年新低": "2",
"历史新低": "1",
}
js_code = py_mini_racer.MiniRacer()
js_content = _get_file_content_ths("ths.js")
js_code.eval(js_content)
v_code = js_code.call("v")
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 "
"(KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36",
"Cookie": f"v={v_code}",
}
url = (
f"http://data.10jqka.com.cn/rank/cxd/board/{symbol_map[symbol]}/field/"
f"stockcode/order/asc/page/1/ajax/1/free/1/"
)
r = requests.get(url, headers=headers)
soup = BeautifulSoup(r.text, features="lxml")
try:
total_page = soup.find(name="span", attrs={"class": "page_info"}).text.split(
"/"
)[1]
except AttributeError:
total_page = 1
big_df = pd.DataFrame()
tqdm = get_tqdm()
for page in tqdm(range(1, int(total_page) + 1), leave=False):
v_code = js_code.call("v")
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 "
"(KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36",
"Cookie": f"v={v_code}",
}
url = (
f"http://data.10jqka.com.cn/rank/cxd/board/{symbol_map[symbol]}/field/"
f"stockcode/order/asc/page/{page}/ajax/1/free/1/"
)
r = requests.get(url, headers=headers)
temp_df = pd.read_html(StringIO(r.text))[0].iloc[:, :-1] # 20260214 新增
big_df = pd.concat(objs=[big_df, temp_df], ignore_index=True)
big_df.columns = [
"序号",
"股票代码",
"股票简称",
"涨跌幅",
"换手率",
"最新价",
"前期低点",
"前期低点日期",
]
big_df["股票代码"] = big_df["股票代码"].astype(str).str.zfill(6)
big_df["涨跌幅"] = big_df["涨跌幅"].str.strip("%")
big_df["换手率"] = big_df["换手率"].str.strip("%")
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")
return big_df
def stock_rank_lxsz_ths() -> pd.DataFrame:
"""
同花顺-数据中心-技术选股-连续上涨
https://data.10jqka.com.cn/rank/lxsz/
:return: 连续上涨
:rtype: pandas.DataFrame
"""
js_code = py_mini_racer.MiniRacer()
js_content = _get_file_content_ths("ths.js")
js_code.eval(js_content)
v_code = js_code.call("v")
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 "
"(KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36",
"Cookie": f"v={v_code}",
}
url = "http://data.10jqka.com.cn/rank/lxsz/field/lxts/order/desc/page/1/ajax/1/free/1/"
r = requests.get(url, headers=headers)
soup = BeautifulSoup(r.text, features="lxml")
try:
total_page = soup.find(name="span", attrs={"class": "page_info"}).text.split(
"/"
)[1]
except AttributeError:
total_page = 1
big_df = pd.DataFrame()
tqdm = get_tqdm()
for page in tqdm(range(1, int(total_page) + 1), leave=False):
v_code = js_code.call("v")
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 "
"(KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36",
"Cookie": f"v={v_code}",
}
url = f"http://data.10jqka.com.cn/rank/lxsz/field/lxts/order/desc/page/{page}/ajax/1/free/1/"
r = requests.get(url, headers=headers)
temp_df = pd.read_html(StringIO(r.text), converters={"股票代码": str})[0]
big_df = pd.concat(objs=[big_df, temp_df], ignore_index=True)
big_df.columns = [
"序号",
"股票代码",
"股票简称",
"收盘价",
"最高价",
"最低价",
"连涨天数",
"连续涨跌幅",
"累计换手率",
"所属行业",
]
big_df["连续涨跌幅"] = big_df["连续涨跌幅"].str.strip("%")
big_df["累计换手率"] = big_df["累计换手率"].str.strip("%")
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["最低价"], errors="coerce")
big_df["连涨天数"] = pd.to_numeric(big_df["连涨天数"], errors="coerce")
return big_df
def stock_rank_lxxd_ths() -> pd.DataFrame:
"""
同花顺-数据中心-技术选股-连续下跌
https://data.10jqka.com.cn/rank/lxxd/
:return: 连续下跌
:rtype: pandas.DataFrame
"""
js_code = py_mini_racer.MiniRacer()
js_content = _get_file_content_ths("ths.js")
js_code.eval(js_content)
v_code = js_code.call("v")
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 "
"(KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36",
"Cookie": f"v={v_code}",
}
url = "http://data.10jqka.com.cn/rank/lxxd/field/lxts/order/desc/page/1/ajax/1/free/1/"
r = requests.get(url, headers=headers)
soup = BeautifulSoup(r.text, features="lxml")
try:
total_page = soup.find(name="span", attrs={"class": "page_info"}).text.split(
"/"
)[1]
except AttributeError:
total_page = 1
big_df = pd.DataFrame()
tqdm = get_tqdm()
for page in tqdm(range(1, int(total_page) + 1), leave=False):
v_code = js_code.call("v")
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 "
"(KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36",
"Cookie": f"v={v_code}",
}
url = f"http://data.10jqka.com.cn/rank/lxxd/field/lxts/order/desc/page/{page}/ajax/1/free/1/"
r = requests.get(url, headers=headers)
temp_df = pd.read_html(StringIO(r.text), converters={"股票代码": str})[0]
big_df = pd.concat(objs=[big_df, temp_df], ignore_index=True)
big_df.columns = [
"序号",
"股票代码",
"股票简称",
"收盘价",
"最高价",
"最低价",
"连涨天数",
"连续涨跌幅",
"累计换手率",
"所属行业",
]
big_df["连续涨跌幅"] = big_df["连续涨跌幅"].str.strip("%")
big_df["累计换手率"] = big_df["累计换手率"].str.strip("%")
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["最低价"], errors="coerce")
big_df["连涨天数"] = pd.to_numeric(big_df["连涨天数"], errors="coerce")
return big_df
def stock_rank_cxfl_ths() -> pd.DataFrame:
"""
同花顺-数据中心-技术选股-持续放量
https://data.10jqka.com.cn/rank/cxfl/
:return: 持续放量
:rtype: pandas.DataFrame
"""
js_code = py_mini_racer.MiniRacer()
js_content = _get_file_content_ths("ths.js")
js_code.eval(js_content)
v_code = js_code.call("v")
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 "
"(KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36",
"Cookie": f"v={v_code}",
}
url = "http://data.10jqka.com.cn/rank/cxfl/field/count/order/desc/ajax/1/free/1/page/1/free/1/"
r = requests.get(url, headers=headers)
soup = BeautifulSoup(r.text, features="lxml")
try:
total_page = soup.find(name="span", attrs={"class": "page_info"}).text.split(
"/"
)[1]
except AttributeError:
total_page = 1
big_df = pd.DataFrame()
tqdm = get_tqdm()
for page in tqdm(range(1, int(total_page) + 1), leave=False):
v_code = js_code.call("v")
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 "
"(KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36",
"Cookie": f"v={v_code}",
}
url = f"http://data.10jqka.com.cn/rank/cxfl/field/count/order/desc/ajax/1/free/1/page/{page}/free/1/"
r = requests.get(url, headers=headers)
soup = BeautifulSoup(r.text, 'html.parser')
table = soup.find('table', class_='m-table J-ajax-table')
if not table:
print("未找到表格")
exit()
rows = table.find('tbody').find_all('tr')
data = []
for row in rows:
cols = row.find_all('td')
if len(cols) >= 10: # 确保是数据行
item = {
'序号': cols[0].text.strip(),
'股票代码': cols[1].find('a').text.strip() if cols[1].find('a') else cols[1].text.strip(),
'股票简称': cols[2].find('a').text.strip() if cols[2].find('a') else cols[2].text.strip(),
'涨跌幅': cols[3].text.strip(),
'最新价': cols[4].text.strip(),
'成交量': cols[5].text.strip(),
'基准日成交量': cols[6].text.strip(),
'放量天数': cols[7].text.strip(),
'阶段涨跌幅': cols[8].text.strip(),
'所属行业': cols[9].find('a').text.strip() if cols[9].find('a') else cols[9].text.strip()
}
data.append(item)
temp_df = pd.DataFrame(data)
big_df = pd.concat(objs=[big_df, temp_df], ignore_index=True)
big_df.columns = [
"序号",
"股票代码",
"股票简称",
"涨跌幅",
"最新价",
"成交量",
"基准日成交量",
"放量天数",
"阶段涨跌幅",
"所属行业",
]
big_df["股票代码"] = big_df["股票代码"].astype(str).str.zfill(6)
big_df["涨跌幅"] = big_df["涨跌幅"].astype(str).str.strip("%")
big_df["阶段涨跌幅"] = big_df["阶段涨跌幅"].astype(str).str.strip("%")
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")
return big_df
def stock_rank_cxsl_ths() -> pd.DataFrame:
"""
同花顺-数据中心-技术选股-持续缩量
https://data.10jqka.com.cn/rank/cxsl/
:return: 持续缩量
:rtype: pandas.DataFrame
"""
js_code = py_mini_racer.MiniRacer()
js_content = _get_file_content_ths("ths.js")
js_code.eval(js_content)
v_code = js_code.call("v")
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 "
"(KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36",
"Cookie": f"v={v_code}",
}
url = "http://data.10jqka.com.cn/rank/cxsl/field/count/order/desc/ajax/1/free/1/page/1/free/1/"
r = requests.get(url, headers=headers)
soup = BeautifulSoup(r.text, features="lxml")
try:
total_page = soup.find(name="span", attrs={"class": "page_info"}).text.split(
"/"
)[1]
except AttributeError:
total_page = 1
big_df = pd.DataFrame()
tqdm = get_tqdm()
for page in tqdm(range(1, int(total_page) + 1), leave=False):
v_code = js_code.call("v")
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 "
"(KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36",
"Cookie": f"v={v_code}",
}
url = f"http://data.10jqka.com.cn/rank/cxsl/field/count/order/desc/ajax/1/free/1/page/{page}/free/1/"
r = requests.get(url, headers=headers)
soup = BeautifulSoup(r.text, 'html.parser')
table = soup.find('table', class_='m-table J-ajax-table')
if not table:
print("未找到表格")
exit()
rows = table.find('tbody').find_all('tr')
data = []
for row in rows:
cols = row.find_all('td')
if len(cols) >= 10: # 确保是数据行
item = {
'序号': cols[0].text.strip(),
'股票代码': cols[1].find('a').text.strip() if cols[1].find('a') else cols[1].text.strip(),
'股票简称': cols[2].find('a').text.strip() if cols[2].find('a') else cols[2].text.strip(),
'涨跌幅': cols[3].text.strip(),
'最新价': cols[4].text.strip(),
'成交量': cols[5].text.strip(),
'基准日成交量': cols[6].text.strip(),
'放量天数': cols[7].text.strip(),
'阶段涨跌幅': cols[8].text.strip(),
'所属行业': cols[9].find('a').text.strip() if cols[9].find('a') else cols[9].text.strip()
}
data.append(item)
temp_df = pd.DataFrame(data)
big_df = pd.concat(objs=[big_df, temp_df], ignore_index=True)
big_df.columns = [
"序号",
"股票代码",
"股票简称",
"涨跌幅",
"最新价",
"成交量",
"基准日成交量",
"缩量天数",
"阶段涨跌幅",
"所属行业",
]
big_df["股票代码"] = big_df["股票代码"].astype(str).str.zfill(6)
big_df["涨跌幅"] = big_df["涨跌幅"].astype(str).str.strip("%")
big_df["阶段涨跌幅"] = big_df["阶段涨跌幅"].astype(str).str.strip("%")
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")
return big_df
def stock_rank_xstp_ths(symbol: str = "500日均线") -> pd.DataFrame:
"""
同花顺-数据中心-技术选股-向上突破
https://data.10jqka.com.cn/rank/xstp/
:param symbol: choice of {"5日均线", "10日均线", "20日均线", "30日均线", "60日均线", "90日均线", "250日均线", "500日均线"}
:type symbol: str
:return: 向上突破
:rtype: pandas.DataFrame
"""
symbol_map = {
"5日均线": 5,
"10日均线": 10,
"20日均线": 20,
"30日均线": 30,
"60日均线": 60,
"90日均线": 90,
"250日均线": 250,
"500日均线": 500,
}
js_code = py_mini_racer.MiniRacer()
js_content = _get_file_content_ths("ths.js")
js_code.eval(js_content)
v_code = js_code.call("v")
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 "
"(KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36",
"Cookie": f"v={v_code}",
}
url = f"http://data.10jqka.com.cn/rank/xstp/board/{symbol_map[symbol]}/order/asc/ajax/1/free/1/page/1/free/1/"
r = requests.get(url, headers=headers)
soup = BeautifulSoup(r.text, features="lxml")
try:
total_page = soup.find(name="span", attrs={"class": "page_info"}).text.split(
"/"
)[1]
except AttributeError:
total_page = 1
big_df = pd.DataFrame()
tqdm = get_tqdm()
for page in tqdm(range(1, int(total_page) + 1), leave=False):
v_code = js_code.call("v")
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 "
"(KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36",
"Cookie": f"v={v_code}",
}
url = (
f"http://data.10jqka.com.cn/rank/xstp/board/{symbol_map[symbol]}/order/"
f"asc/ajax/1/free/1/page/{page}/free/1/"
)
r = requests.get(url, headers=headers)
pd.read_html(StringIO(r.text))
soup = BeautifulSoup(r.text, 'html.parser')
table = soup.find('table', class_='m-table J-ajax-table')
if not table:
print("未找到表格")
exit()
rows = table.find('tbody').find_all('tr')
data = []
for row in rows:
cols = row.find_all('td')
if len(cols) >= 8: # 确保是数据行
item = {
'序号': cols[0].text.strip(),
'股票代码': cols[1].find('a').text.strip() if cols[1].find('a') else cols[1].text.strip(),
'股票简称': cols[2].find('a').text.strip() if cols[2].find('a') else cols[2].text.strip(),
'最新价': cols[3].text.strip(),
'成交额': cols[4].text.strip(),
'成交量': cols[5].text.strip(),
'涨跌幅': cols[6].text.strip(),
'换手率': cols[7].text.strip(),
}
data.append(item)
temp_df = pd.DataFrame(data)
big_df = pd.concat(objs=[big_df, temp_df], ignore_index=True)
big_df.columns = [
"序号",
"股票代码",
"股票简称",
"最新价",
"成交额",
"成交量",
"涨跌幅",
"换手率",
]
big_df["股票代码"] = big_df["股票代码"].astype(str).str.zfill(6)
big_df["涨跌幅"] = big_df["涨跌幅"].astype(str).str.strip("%")
big_df["换手率"] = big_df["换手率"].astype(str).str.strip("%")
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")
return big_df
def stock_rank_xxtp_ths(symbol: str = "500日均线") -> pd.DataFrame:
"""
同花顺-数据中心-技术选股-向下突破
https://data.10jqka.com.cn/rank/xxtp/
:param symbol: choice of {"5日均线", "10日均线", "20日均线", "30日均线", "60日均线", "90日均线", "250日均线", "500日均线"}
:type symbol: str
:return: 向下突破
:rtype: pandas.DataFrame
"""
symbol_map = {
"5日均线": 5,
"10日均线": 10,
"20日均线": 20,
"30日均线": 30,
"60日均线": 60,
"90日均线": 90,
"250日均线": 250,
"500日均线": 500,
}
js_code = py_mini_racer.MiniRacer()
js_content = _get_file_content_ths("ths.js")
js_code.eval(js_content)
v_code = js_code.call("v")
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 "
"(KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36",
"Cookie": f"v={v_code}",
}
url = f"http://data.10jqka.com.cn/rank/xxtp/board/{symbol_map[symbol]}/order/asc/ajax/1/free/1/page/1/free/1/"
r = requests.get(url, headers=headers)
soup = BeautifulSoup(r.text, features="lxml")
try:
total_page = soup.find(name="span", attrs={"class": "page_info"}).text.split(
"/"
)[1]
except AttributeError:
total_page = 1
big_df = pd.DataFrame()
tqdm = get_tqdm()
for page in tqdm(range(1, int(total_page) + 1), leave=False):
v_code = js_code.call("v")
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 "
"(KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36",
"Cookie": f"v={v_code}",
}
url = (
f"http://data.10jqka.com.cn/rank/xxtp/board/{symbol_map[symbol]}/order/"
f"asc/ajax/1/free/1/page/{page}/free/1/"
)
r = requests.get(url, headers=headers)
soup = BeautifulSoup(r.text, 'html.parser')
table = soup.find('table', class_='m-table J-ajax-table')
if not table:
print("未找到表格")
exit()
rows = table.find('tbody').find_all('tr')
data = []
for row in rows:
cols = row.find_all('td')
if len(cols) >= 8: # 确保是数据行
item = {
'序号': cols[0].text.strip(),
'股票代码': cols[1].find('a').text.strip() if cols[1].find('a') else cols[1].text.strip(),
'股票简称': cols[2].find('a').text.strip() if cols[2].find('a') else cols[2].text.strip(),
'最新价': cols[3].text.strip(),
'成交额': cols[4].text.strip(),
'成交量': cols[5].text.strip(),
'涨跌幅': cols[6].text.strip(),
'换手率': cols[7].text.strip(),
}
data.append(item)
temp_df = pd.DataFrame(data)
big_df = pd.concat(objs=[big_df, temp_df], ignore_index=True)
big_df.columns = [
"序号",
"股票代码",
"股票简称",
"最新价",
"成交额",
"成交量",
"涨跌幅",
"换手率",
]
big_df["股票代码"] = big_df["股票代码"].astype(str).str.zfill(6)
big_df["涨跌幅"] = big_df["涨跌幅"].astype(str).str.strip("%")
big_df["换手率"] = big_df["换手率"].astype(str).str.strip("%")
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")
return big_df
def stock_rank_ljqs_ths() -> pd.DataFrame:
"""
同花顺-数据中心-技术选股-量价齐升
http://data.10jqka.com.cn/rank/ljqs/
:return: 量价齐升
:rtype: pandas.DataFrame
"""
js_code = py_mini_racer.MiniRacer()
js_content = _get_file_content_ths("ths.js")
js_code.eval(js_content)
v_code = js_code.call("v")
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 "
"(KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36",
"Cookie": f"v={v_code}",
}
url = "http://data.10jqka.com.cn/rank/ljqs/field/count/order/desc/ajax/1/free/1/page/1/free/1/"
r = requests.get(url, headers=headers)
soup = BeautifulSoup(r.text, features="lxml")
try:
total_page = soup.find(name="span", attrs={"class": "page_info"}).text.split(
"/"
)[1]
except AttributeError:
total_page = 1
big_df = pd.DataFrame()
tqdm = get_tqdm()
for page in tqdm(range(1, int(total_page) + 1), leave=False):
v_code = js_code.call("v")
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 "
"(KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36",
"Cookie": f"v={v_code}",
}
url = f"http://data.10jqka.com.cn/rank/ljqs/field/count/order/desc/ajax/1/free/1/page/{page}/free/1/"
r = requests.get(url, headers=headers)
soup = BeautifulSoup(r.text, 'html.parser')
table = soup.find('table', class_='m-table J-ajax-table')
if not table:
print("未找到表格")
exit()
rows = table.find('tbody').find_all('tr')
data = []
for row in rows:
cols = row.find_all('td')
if len(cols) >= 8: # 确保是数据行
item = {
'序号': cols[0].text.strip(),
'股票代码': cols[1].find('a').text.strip() if cols[1].find('a') else cols[1].text.strip(),
'股票简称': cols[2].find('a').text.strip() if cols[2].find('a') else cols[2].text.strip(),
'最新价': cols[3].text.strip(),
'量价齐升天数': cols[4].text.strip(),
'阶段涨幅': cols[5].text.strip(),
'累计换手率': cols[6].text.strip(),
'所属行业': cols[7].find('a').text.strip() if cols[7].find('a') else cols[7].text.strip()
}
data.append(item)
temp_df = pd.DataFrame(data)
big_df = pd.concat(objs=[big_df, temp_df], ignore_index=True)
big_df.columns = [
"序号",
"股票代码",
"股票简称",
"最新价",
"量价齐升天数",
"阶段涨幅",
"累计换手率",
"所属行业",
]
big_df["股票代码"] = big_df["股票代码"].astype(str).str.zfill(6)
big_df["阶段涨幅"] = big_df["阶段涨幅"].astype(str).str.strip("%")
big_df["累计换手率"] = big_df["累计换手率"].astype(str).str.strip("%")
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")
return big_df
def stock_rank_ljqd_ths() -> pd.DataFrame:
"""
同花顺-数据中心-技术选股-量价齐跌
http://data.10jqka.com.cn/rank/ljqd/
:return: 量价齐跌
:rtype: pandas.DataFrame
"""
js_code = py_mini_racer.MiniRacer()
js_content = _get_file_content_ths("ths.js")
js_code.eval(js_content)
v_code = js_code.call("v")
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 "
"(KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36",
"Cookie": f"v={v_code}",
}
url = "http://data.10jqka.com.cn/rank/ljqd/field/count/order/desc/ajax/1/free/1/page/1/free/1/"
r = requests.get(url, headers=headers)
soup = BeautifulSoup(r.text, features="lxml")
try:
total_page = soup.find(name="span", attrs={"class": "page_info"}).text.split(
"/"
)[1]
except AttributeError:
total_page = 1
big_df = pd.DataFrame()
tqdm = get_tqdm()
for page in tqdm(range(1, int(total_page) + 1), leave=False):
v_code = js_code.call("v")
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 "
"(KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36",
"Cookie": f"v={v_code}",
}
url = f"http://data.10jqka.com.cn/rank/ljqd/field/count/order/desc/ajax/1/free/1/page/{page}/free/1/"
r = requests.get(url, headers=headers)
soup = BeautifulSoup(r.text, 'html.parser')
table = soup.find('table', class_='m-table J-ajax-table')
if not table:
print("未找到表格")
exit()
rows = table.find('tbody').find_all('tr')
data = []
for row in rows:
cols = row.find_all('td')
if len(cols) >= 8: # 确保是数据行
item = {
'序号': cols[0].text.strip(),
'股票代码': cols[1].find('a').text.strip() if cols[1].find('a') else cols[1].text.strip(),
'股票简称': cols[2].find('a').text.strip() if cols[2].find('a') else cols[2].text.strip(),
'最新价': cols[3].text.strip(),
'量价齐跌天数': cols[4].text.strip(),
'阶段涨幅': cols[5].text.strip(),
'累计换手率': cols[6].text.strip(),
'所属行业': cols[7].find('a').text.strip() if cols[7].find('a') else cols[7].text.strip()
}
data.append(item)
temp_df = pd.DataFrame(data)
big_df = pd.concat(objs=[big_df, temp_df], ignore_index=True)
big_df.columns = [
"序号",
"股票代码",
"股票简称",
"最新价",
"量价齐跌天数",
"阶段涨幅",
"累计换手率",
"所属行业",
]
big_df["股票代码"] = big_df["股票代码"].astype(str).str.zfill(6)
big_df["阶段涨幅"] = big_df["阶段涨幅"].astype(str).str.strip("%")
big_df["累计换手率"] = big_df["累计换手率"].astype(str).str.strip("%")
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")
return big_df
def stock_rank_xzjp_ths() -> pd.DataFrame:
"""
同花顺-数据中心-技术选股-险资举牌
https://data.10jqka.com.cn/financial/xzjp/
:return: 险资举牌
:rtype: pandas.DataFrame
"""
js_code = py_mini_racer.MiniRacer()
js_content = _get_file_content_ths("ths.js")
js_code.eval(js_content)
big_df = pd.DataFrame()
v_code = js_code.call("v")
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 "
"(KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36",
"Cookie": f"v={v_code}",
}
url = "http://data.10jqka.com.cn/ajax/xzjp/field/DECLAREDATE/order/desc/ajax/1/free/1/"
r = requests.get(url, headers=headers)
soup = BeautifulSoup(r.text, 'html.parser')
table = soup.find('table', class_='m-table J-ajax-table')
if not table:
print("未找到表格")
exit()
rows = table.find('tbody').find_all('tr')
data = []
for row in rows:
cols = row.find_all('td')
if len(cols) >= 8: # 确保是数据行
item = {
'序号': cols[0].text.strip(),
'举牌公告日': cols[1].find('a').text.strip() if cols[1].find('a') else cols[1].text.strip(),
'股票代码': cols[2].find('a').text.strip() if cols[2].find('a') else cols[2].text.strip(),
'股票简称': cols[3].text.strip(),
'现价': cols[4].text.strip(),
'涨跌幅': cols[5].text.strip(),
'举牌方': cols[6].text.strip(),
'增持数量': cols[7].find('a').text.strip() if cols[7].find('a') else cols[7].text.strip(),
'交易均价': cols[8].find('a').text.strip() if cols[8].find('a') else cols[8].text.strip(),
'增持数量占总股本比例': cols[9].find('a').text.strip() if cols[9].find('a') else cols[9].text.strip(),
'变动后持股总数': cols[10].find('a').text.strip() if cols[10].find('a') else cols[10].text.strip(),
'变动后持股比例': cols[11].find('a').text.strip() if cols[11].find('a') else cols[11].text.strip(),
'历史数据': cols[12].find('a').text.strip() if cols[12].find('a') else cols[12].text.strip(),
}
data.append(item)
temp_df = pd.DataFrame(data)
big_df = pd.concat(objs=[big_df, temp_df], ignore_index=True)
big_df.columns = [
"序号",
"举牌公告日",
"股票代码",
"股票简称",
"现价",
"涨跌幅",
"举牌方",
"增持数量",
"交易均价",
"增持数量占总股本比例",
"变动后持股总数",
"变动后持股比例",
"历史数据",
]
big_df["涨跌幅"] = big_df["涨跌幅"].astype(str).str.zfill(6)
big_df["增持数量占总股本比例"] = (
big_df["增持数量占总股本比例"].astype(str).str.strip("%")
)
big_df["变动后持股比例"] = big_df["变动后持股比例"].astype(str).str.strip("%")
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_datetime(big_df["举牌公告日"], errors="coerce").dt.date
big_df["股票代码"] = big_df["股票代码"].astype(str).str.zfill(6)
big_df["现价"] = pd.to_numeric(big_df["现价"], errors="coerce")
big_df["交易均价"] = pd.to_numeric(big_df["交易均价"], errors="coerce")
del big_df["历史数据"]
return big_df
if __name__ == "__main__":
stock_rank_cxg_ths_df = stock_rank_cxg_ths(symbol="创月新高")
print(stock_rank_cxg_ths_df)
stock_rank_cxg_ths_df = stock_rank_cxg_ths(symbol="半年新高")
print(stock_rank_cxg_ths_df)
stock_rank_cxg_ths_df = stock_rank_cxg_ths(symbol="一年新高")
print(stock_rank_cxg_ths_df)
stock_rank_cxg_ths_df = stock_rank_cxg_ths(symbol="历史新高")
print(stock_rank_cxg_ths_df)
stock_rank_cxd_ths_df = stock_rank_cxd_ths(symbol="创月新低")
print(stock_rank_cxd_ths_df)
stock_rank_cxd_ths_df = stock_rank_cxd_ths(symbol="半年新低")
print(stock_rank_cxd_ths_df)
stock_rank_cxd_ths_df = stock_rank_cxd_ths(symbol="一年新低")
print(stock_rank_cxd_ths_df)
stock_rank_cxd_ths_df = stock_rank_cxd_ths(symbol="历史新低")
print(stock_rank_cxd_ths_df)
stock_rank_lxsz_ths_df = stock_rank_lxsz_ths()
print(stock_rank_lxsz_ths_df)
stock_rank_lxxd_ths_df = stock_rank_lxxd_ths()
print(stock_rank_lxxd_ths_df)
stock_rank_cxfl_ths_df = stock_rank_cxfl_ths()
print(stock_rank_cxfl_ths_df)
stock_rank_cxsl_ths_df = stock_rank_cxsl_ths()
print(stock_rank_cxsl_ths_df)
stock_rank_xstp_ths_df = stock_rank_xstp_ths(symbol="5日均线")
print(stock_rank_xstp_ths_df)
stock_rank_xxtp_ths_df = stock_rank_xxtp_ths(symbol="5日均线")
print(stock_rank_xxtp_ths_df)
stock_rank_ljqs_ths_df = stock_rank_ljqs_ths()
print(stock_rank_ljqs_ths_df)
stock_rank_ljqd_ths_df = stock_rank_ljqd_ths()
print(stock_rank_ljqd_ths_df)
stock_rank_xzjp_ths_df = stock_rank_xzjp_ths()
print(stock_rank_xzjp_ths_df)
@@ -0,0 +1,86 @@
#!/usr/bin/env python
# -*- coding:utf-8 -*-
"""
Date: 2024/4/29 15:00
Desc: 东方财富网-数据中心-特色数据-停复牌信息
https://data.eastmoney.com/tfpxx/
"""
import pandas as pd
import requests
def stock_tfp_em(date: str = "20240426") -> pd.DataFrame:
"""
东方财富网-数据中心-特色数据-停复牌信息
https://data.eastmoney.com/tfpxx/
:param date: 查询参数 "20240426"
:type date: str
:return: 停复牌信息表
:rtype: pandas.DataFrame
"""
url = "https://datacenter-web.eastmoney.com/api/data/v1/get"
params = {
"sortColumns": "SUSPEND_START_DATE",
"sortTypes": "-1",
"pageSize": "500",
"pageNumber": "1",
"reportName": "RPT_CUSTOM_SUSPEND_DATA_INTERFACE",
"columns": "ALL",
"source": "WEB",
"client": "WEB",
"filter": f"""(MARKET="全部")(DATETIME='{"-".join([date[:4], date[4:6], date[6:]])}')""",
}
r = requests.get(url, params=params)
data_json = r.json()
total_page = data_json["result"]["pages"]
big_df = pd.DataFrame()
for page in range(1, total_page + 1):
params.update({"pageNumber": page})
r = requests.get(url, params=params)
data_json = r.json()
temp_df = pd.DataFrame(data_json["result"]["data"])
big_df = pd.concat(objs=[big_df, temp_df], ignore_index=True)
big_df.reset_index(inplace=True)
big_df.columns = [
"序号",
"代码",
"名称",
"停牌时间",
"停牌截止时间",
"停牌期限",
"停牌原因",
"所属市场",
"停牌开始日期",
"预计复牌时间",
"-",
"-",
"-",
]
big_df = big_df[
[
"序号",
"代码",
"名称",
"停牌时间",
"停牌截止时间",
"停牌期限",
"停牌原因",
"所属市场",
"预计复牌时间",
]
]
big_df["停牌时间"] = pd.to_datetime(big_df["停牌时间"], errors="coerce").dt.date
big_df["停牌截止时间"] = pd.to_datetime(
big_df["停牌截止时间"], errors="coerce"
).dt.date
big_df["预计复牌时间"] = pd.to_datetime(
big_df["预计复牌时间"], errors="coerce"
).dt.date
return big_df
if __name__ == "__main__":
stock_tfp_em_df = stock_tfp_em(date="20240426")
print(stock_tfp_em_df)
@@ -0,0 +1,629 @@
# -*- coding:utf-8 -*-
# !/usr/bin/env python
"""
Date: 2025/5/8 20:00
Desc: 东方财富-股票-财务分析
"""
from functools import lru_cache
import pandas as pd
import requests
from bs4 import BeautifulSoup
from akshare.utils.tqdm import get_tqdm
@lru_cache()
def _stock_balance_sheet_by_report_ctype_em(symbol: str = "SH600519") -> str:
"""
东方财富-股票-财务分析-资产负债表-按报告期-公司类型判断
https://emweb.securities.eastmoney.com/PC_HSF10/NewFinanceAnalysis/Index?type=web&code=sh601878#zcfzb-0
:param symbol: 股票代码; 带市场标识
:type symbol: str
:return: 东方财富-股票-财务分析-资产负债表-按报告期-公司类型判断
:rtype: str
"""
url = "https://emweb.securities.eastmoney.com/PC_HSF10/NewFinanceAnalysis/Index"
params = {"type": "web", "code": symbol.lower()}
r = requests.get(url, params=params)
soup = BeautifulSoup(r.text, features="lxml")
company_type = soup.find(attrs={"id": "hidctype"})["value"]
return company_type
def stock_balance_sheet_by_report_em(symbol: str = "SH600519") -> pd.DataFrame:
"""
东方财富-股票-财务分析-资产负债表-按报告期
https://emweb.securities.eastmoney.com/PC_HSF10/NewFinanceAnalysis/Index?type=web&code=sh600519#lrb-0
:param symbol: 股票代码; 带市场标识
:type symbol: str
:return: 资产负债表-按报告期
:rtype: pandas.DataFrame
"""
company_type = _stock_balance_sheet_by_report_ctype_em(symbol=symbol)
url = "https://emweb.securities.eastmoney.com/PC_HSF10/NewFinanceAnalysis/zcfzbDateAjaxNew"
params = {
"companyType": company_type,
"reportDateType": "0",
"code": symbol,
}
r = requests.get(url, params=params)
data_json = r.json()
temp_df = pd.DataFrame(data_json["data"])
temp_df["REPORT_DATE"] = pd.to_datetime(temp_df["REPORT_DATE"]).dt.date
temp_df["REPORT_DATE"] = temp_df["REPORT_DATE"].astype(str)
need_date = temp_df["REPORT_DATE"].tolist()
sep_list = [",".join(need_date[i : i + 5]) for i in range(0, len(need_date), 5)]
big_df = pd.DataFrame()
tqdm = get_tqdm()
for item in tqdm(sep_list, leave=False):
url = "https://emweb.securities.eastmoney.com/PC_HSF10/NewFinanceAnalysis/zcfzbAjaxNew"
params = {
"companyType": company_type,
"reportDateType": "0",
"reportType": "1",
"dates": item,
"code": symbol,
}
r = requests.get(url, params=params)
data_json = r.json()
if "data" not in data_json.keys():
break
temp_df = pd.DataFrame(data_json["data"])
for col in temp_df.columns:
if temp_df[col].isnull().all(): # 检查列是否包含 None 或 NaN
temp_df[col] = pd.to_numeric(temp_df[col], errors="coerce")
if big_df.empty:
big_df = temp_df
else:
big_df = pd.concat(objs=[big_df, temp_df], ignore_index=True)
return big_df
def stock_balance_sheet_by_yearly_em(symbol: str = "SH600036") -> pd.DataFrame:
"""
东方财富-股票-财务分析-资产负债表-按年度
https://emweb.securities.eastmoney.com/PC_HSF10/NewFinanceAnalysis/Index?type=web&code=sh600519#lrb-0
:param symbol: 股票代码; 带市场标识
:type symbol: str
:return: 资产负债表-按年度
:rtype: pandas.DataFrame
"""
url = "https://emweb.securities.eastmoney.com/PC_HSF10/NewFinanceAnalysis/zcfzbDateAjaxNew"
company_type = _stock_balance_sheet_by_report_ctype_em(symbol)
params = {
"companyType": company_type,
"reportDateType": "1",
"code": symbol,
}
r = requests.get(url, params=params)
data_json = r.json()
try:
temp_df = pd.DataFrame(data_json["data"])
except: # noqa: E722
company_type = "3"
params.update({"companyType": company_type})
r = requests.get(url, params=params)
data_json = r.json()
temp_df = pd.DataFrame(data_json["data"])
temp_df["REPORT_DATE"] = pd.to_datetime(
temp_df["REPORT_DATE"], errors="coerce"
).dt.date
temp_df["REPORT_DATE"] = temp_df["REPORT_DATE"].astype(str)
need_date = temp_df["REPORT_DATE"].tolist()
sep_list = [",".join(need_date[i : i + 5]) for i in range(0, len(need_date), 5)]
big_df = pd.DataFrame()
tqdm = get_tqdm()
for item in tqdm(sep_list, leave=False):
url = "https://emweb.securities.eastmoney.com/PC_HSF10/NewFinanceAnalysis/zcfzbAjaxNew"
params = {
"companyType": company_type,
"reportDateType": "1",
"reportType": "1",
"dates": item,
"code": symbol,
}
r = requests.get(url, params=params)
data_json = r.json()
if "data" not in data_json.keys():
break
temp_df = pd.DataFrame(data_json["data"])
for col in temp_df.columns:
if temp_df[col].isnull().all(): # 检查列是否包含 None 或 NaN
temp_df[col] = pd.to_numeric(temp_df[col], errors="coerce")
if big_df.empty:
big_df = temp_df
else:
big_df = pd.concat(objs=[big_df, temp_df], ignore_index=True)
return big_df
def stock_profit_sheet_by_report_em(symbol: str = "SH600519") -> pd.DataFrame:
"""
东方财富-股票-财务分析-利润表-报告期
https://emweb.securities.eastmoney.com/PC_HSF10/NewFinanceAnalysis/Index?type=web&code=sh600519#lrb-0
:param symbol: 股票代码; 带市场标识
:type symbol: str
:return: 利润表-报告期
:rtype: pandas.DataFrame
"""
company_type = _stock_balance_sheet_by_report_ctype_em(symbol=symbol)
url = "https://emweb.securities.eastmoney.com/PC_HSF10/NewFinanceAnalysis/lrbDateAjaxNew"
params = {
"companyType": company_type,
"reportDateType": "0",
"code": symbol,
}
r = requests.get(url, params=params)
data_json = r.json()
temp_df = pd.DataFrame(data_json["data"])
temp_df["REPORT_DATE"] = pd.to_datetime(temp_df["REPORT_DATE"]).dt.date
temp_df["REPORT_DATE"] = temp_df["REPORT_DATE"].astype(str)
need_date = temp_df["REPORT_DATE"].tolist()
sep_list = [",".join(need_date[i : i + 5]) for i in range(0, len(need_date), 5)]
big_df = pd.DataFrame()
tqdm = get_tqdm()
for item in tqdm(sep_list, leave=False):
url = "https://emweb.securities.eastmoney.com/PC_HSF10/NewFinanceAnalysis/lrbAjaxNew"
params = {
"companyType": company_type,
"reportDateType": "0",
"reportType": "1",
"code": symbol,
"dates": item,
}
r = requests.get(url, params=params)
data_json = r.json()
if "data" not in data_json.keys():
break
temp_df = pd.DataFrame(data_json["data"])
for col in temp_df.columns:
if temp_df[col].isnull().all(): # 检查列是否包含 None 或 NaN
temp_df[col] = pd.to_numeric(temp_df[col], errors="coerce")
if big_df.empty:
big_df = temp_df
else:
big_df = pd.concat(objs=[big_df, temp_df], ignore_index=True)
return big_df
def stock_profit_sheet_by_yearly_em(symbol: str = "SH600519") -> pd.DataFrame:
"""
东方财富-股票-财务分析-利润表-按年度
https://emweb.securities.eastmoney.com/PC_HSF10/NewFinanceAnalysis/Index?type=web&code=sh600519#lrb-0
:param symbol: 股票代码; 带市场标识
:type symbol: str
:return: 利润表-按年度
:rtype: pandas.DataFrame
"""
company_type = _stock_balance_sheet_by_report_ctype_em(symbol=symbol)
url = "https://emweb.securities.eastmoney.com/PC_HSF10/NewFinanceAnalysis/lrbDateAjaxNew"
params = {
"companyType": company_type,
"reportDateType": "1",
"code": symbol,
}
r = requests.get(url, params=params)
data_json = r.json()
temp_df = pd.DataFrame(data_json["data"])
temp_df["REPORT_DATE"] = pd.to_datetime(temp_df["REPORT_DATE"]).dt.date
temp_df["REPORT_DATE"] = temp_df["REPORT_DATE"].astype(str)
need_date = temp_df["REPORT_DATE"].tolist()
sep_list = [",".join(need_date[i : i + 5]) for i in range(0, len(need_date), 5)]
big_df = pd.DataFrame()
tqdm = get_tqdm()
for item in tqdm(sep_list, leave=False):
url = "https://emweb.securities.eastmoney.com/PC_HSF10/NewFinanceAnalysis/lrbAjaxNew"
params = {
"companyType": company_type,
"reportDateType": "1",
"reportType": "1",
"dates": item,
"code": symbol,
}
r = requests.get(url, params=params)
data_json = r.json()
if "data" not in data_json.keys():
break
temp_df = pd.DataFrame(data_json["data"])
for col in temp_df.columns:
if temp_df[col].isnull().all(): # 检查列是否包含 None 或 NaN
temp_df[col] = pd.to_numeric(temp_df[col], errors="coerce")
if big_df.empty:
big_df = temp_df
else:
big_df = pd.concat(objs=[big_df, temp_df], ignore_index=True)
return big_df
def stock_profit_sheet_by_quarterly_em(
symbol: str = "SH600519",
) -> pd.DataFrame:
"""
东方财富-股票-财务分析-利润表-按单季度
https://emweb.securities.eastmoney.com/PC_HSF10/NewFinanceAnalysis/Index?type=web&code=sh600519#lrb-0
:param symbol: 股票代码; 带市场标识
:type symbol: str
:return: 利润表-按单季度
:rtype: pandas.DataFrame
"""
company_type = _stock_balance_sheet_by_report_ctype_em(symbol=symbol)
url = "https://emweb.securities.eastmoney.com/PC_HSF10/NewFinanceAnalysis/lrbDateAjaxNew"
params = {
"companyType": company_type,
"reportDateType": "2",
"code": symbol,
}
r = requests.get(url, params=params)
data_json = r.json()
temp_df = pd.DataFrame(data_json["data"])
temp_df["REPORT_DATE"] = pd.to_datetime(temp_df["REPORT_DATE"]).dt.date
temp_df["REPORT_DATE"] = temp_df["REPORT_DATE"].astype(str)
need_date = temp_df["REPORT_DATE"].tolist()
sep_list = [",".join(need_date[i : i + 5]) for i in range(0, len(need_date), 5)]
big_df = pd.DataFrame()
tqdm = get_tqdm()
for item in tqdm(sep_list, leave=False):
url = "https://emweb.securities.eastmoney.com/PC_HSF10/NewFinanceAnalysis/lrbAjaxNew"
params = {
"companyType": company_type,
"reportDateType": "0",
"reportType": "2",
"dates": item,
"code": symbol,
}
r = requests.get(url, params=params)
data_json = r.json()
if "data" not in data_json.keys():
break
temp_df = pd.DataFrame(data_json["data"])
for col in temp_df.columns:
if temp_df[col].isnull().all(): # 检查列是否包含 None 或 NaN
temp_df[col] = pd.to_numeric(temp_df[col], errors="coerce")
if big_df.empty:
big_df = temp_df
else:
big_df = pd.concat(objs=[big_df, temp_df], ignore_index=True)
return big_df
def stock_cash_flow_sheet_by_report_em(
symbol: str = "SH600519",
) -> pd.DataFrame:
"""
东方财富-股票-财务分析-现金流量表-按报告期
https://emweb.securities.eastmoney.com/PC_HSF10/NewFinanceAnalysis/Index?type=web&code=sh600519#lrb-0
:param symbol: 股票代码; 带市场标识
:type symbol: str
:return: 现金流量表-按报告期
:rtype: pandas.DataFrame
"""
company_type = _stock_balance_sheet_by_report_ctype_em(symbol=symbol)
url = "https://emweb.securities.eastmoney.com/PC_HSF10/NewFinanceAnalysis/xjllbDateAjaxNew"
params = {
"companyType": company_type,
"reportDateType": "0",
"code": symbol,
}
r = requests.get(url, params=params, timeout=10)
data_json = r.json()
temp_df = pd.DataFrame(data_json["data"])
temp_df["REPORT_DATE"] = pd.to_datetime(temp_df["REPORT_DATE"]).dt.date
temp_df["REPORT_DATE"] = temp_df["REPORT_DATE"].astype(str)
need_date = temp_df["REPORT_DATE"].tolist()
sep_list = [",".join(need_date[i : i + 5]) for i in range(0, len(need_date), 5)]
big_df = pd.DataFrame()
tqdm = get_tqdm()
for item in tqdm(sep_list, leave=False):
url = "https://emweb.securities.eastmoney.com/PC_HSF10/NewFinanceAnalysis/xjllbAjaxNew"
params = {
"companyType": company_type,
"reportDateType": "0",
"reportType": "1",
"dates": item,
"code": symbol,
}
r = requests.get(url, params=params)
data_json = r.json()
if "data" not in data_json.keys():
break
temp_df = pd.DataFrame(data_json["data"])
for col in temp_df.columns:
if temp_df[col].isnull().all(): # 检查列是否包含 None 或 NaN
temp_df[col] = pd.to_numeric(temp_df[col], errors="coerce")
if big_df.empty:
big_df = temp_df
else:
big_df = pd.concat(objs=[big_df, temp_df], ignore_index=True)
return big_df
def stock_cash_flow_sheet_by_yearly_em(
symbol: str = "SH600519",
) -> pd.DataFrame:
"""
东方财富-股票-财务分析-现金流量表-按年度
https://emweb.securities.eastmoney.com/PC_HSF10/NewFinanceAnalysis/Index?type=web&code=sh600519#lrb-0
:param symbol: 股票代码; 带市场标识
:type symbol: str
:return: 现金流量表-按年度
:rtype: pandas.DataFrame
"""
company_type = _stock_balance_sheet_by_report_ctype_em(symbol=symbol)
url = "https://emweb.securities.eastmoney.com/PC_HSF10/NewFinanceAnalysis/xjllbDateAjaxNew"
params = {
"companyType": company_type,
"reportDateType": "1",
"code": symbol,
}
r = requests.get(url, params=params)
data_json = r.json()
temp_df = pd.DataFrame(data_json["data"])
temp_df["REPORT_DATE"] = pd.to_datetime(temp_df["REPORT_DATE"]).dt.date
temp_df["REPORT_DATE"] = temp_df["REPORT_DATE"].astype(str)
need_date = temp_df["REPORT_DATE"].tolist()
sep_list = [",".join(need_date[i : i + 5]) for i in range(0, len(need_date), 5)]
big_df = pd.DataFrame()
tqdm = get_tqdm()
for item in tqdm(sep_list, leave=False):
url = "https://emweb.securities.eastmoney.com/PC_HSF10/NewFinanceAnalysis/xjllbAjaxNew"
params = {
"companyType": company_type,
"reportDateType": "1",
"reportType": "1",
"dates": item,
"code": symbol,
}
r = requests.get(url, params=params)
data_json = r.json()
if "data" not in data_json.keys():
break
temp_df = pd.DataFrame(data_json["data"])
for col in temp_df.columns:
if temp_df[col].isnull().all(): # 检查列是否包含 None 或 NaN
temp_df[col] = pd.to_numeric(temp_df[col], errors="coerce")
if big_df.empty:
big_df = temp_df
else:
big_df = pd.concat(objs=[big_df, temp_df], ignore_index=True)
return big_df
def stock_cash_flow_sheet_by_quarterly_em(
symbol: str = "SH600519",
) -> pd.DataFrame:
"""
东方财富-股票-财务分析-现金流量表-按单季度
https://emweb.securities.eastmoney.com/PC_HSF10/NewFinanceAnalysis/Index?type=web&code=sh600519#lrb-0
:param symbol: 股票代码; 带市场标识
:type symbol: str
:return: 现金流量表-按单季度
:rtype: pandas.DataFrame
"""
company_type = _stock_balance_sheet_by_report_ctype_em(symbol=symbol)
url = "https://emweb.securities.eastmoney.com/PC_HSF10/NewFinanceAnalysis/xjllbDateAjaxNew"
params = {
"companyType": company_type,
"reportDateType": "2",
"code": symbol,
}
r = requests.get(url, params=params)
data_json = r.json()
temp_df = pd.DataFrame(data_json["data"])
temp_df["REPORT_DATE"] = pd.to_datetime(temp_df["REPORT_DATE"]).dt.date
temp_df["REPORT_DATE"] = temp_df["REPORT_DATE"].astype(str)
need_date = temp_df["REPORT_DATE"].tolist()
sep_list = [",".join(need_date[i : i + 5]) for i in range(0, len(need_date), 5)]
big_df = pd.DataFrame()
tqdm = get_tqdm()
for item in tqdm(sep_list, leave=False):
url = "https://emweb.securities.eastmoney.com/PC_HSF10/NewFinanceAnalysis/xjllbAjaxNew"
params = {
"companyType": company_type,
"reportDateType": "0",
"reportType": "2",
"dates": item,
"code": symbol,
}
r = requests.get(url, params=params)
data_json = r.json()
if "data" not in data_json.keys():
break
temp_df = pd.DataFrame(data_json["data"])
for col in temp_df.columns:
if temp_df[col].isnull().all(): # 检查列是否包含 None 或 NaN
temp_df[col] = pd.to_numeric(temp_df[col], errors="coerce")
if big_df.empty:
big_df = temp_df
else:
big_df = pd.concat(objs=[big_df, temp_df], ignore_index=True)
return big_df
def __get_report_date_list_delisted_em(symbol: str = "SZ000013") -> list:
"""
东方财富-股票-财务分析-资产负债表-已退市股票-所有报告期
https://emweb.securities.eastmoney.com/pc_hsf10/pages/index.html?type=web&code=SZ000013
:param symbol: 已退市股票代码; 带市场标识
:type symbol: str
:return: 所有报告期
:rtype: list
"""
url = "https://datacenter.eastmoney.com/securities/api/data/get"
params = {
"type": "RPT_F10_FINANCE_GINCOME",
"sty": "SECUCODE,SECURITY_CODE,REPORT_DATE,REPORT_TYPE,REPORT_DATE_NAME",
"filter": f'(SECUCODE="{symbol[2:]}.{symbol[:2]}")',
"p": "1",
"ps": "200",
"sr": "-1",
"st": "REPORT_DATE",
"source": "HSF10",
"client": "PC",
"v": "07306678536291241",
}
r = requests.get(url, params=params)
data_json = r.json()
temp_df = pd.DataFrame(data_json["result"]["data"])
report_date_list = [item[0] for item in temp_df["REPORT_DATE"].str.split(" ")]
report_date_list = ["'" + item + "'" for item in report_date_list]
return report_date_list
def stock_balance_sheet_by_report_delisted_em(symbol: str = "SZ000013") -> pd.DataFrame:
"""
东方财富-股票-财务分析-资产负债表-已退市股票-按报告期
https://emweb.securities.eastmoney.com/pc_hsf10/pages/index.html?type=web&code=SZ000013#/cwfx/zcfzb
:param symbol: 已退市股票代码; 带市场标识
:type symbol: str
:return: 资产负债表-按报告期
:rtype: pandas.DataFrame
"""
report_date_list = __get_report_date_list_delisted_em(symbol)
url = "https://datacenter.eastmoney.com/securities/api/data/get"
params = {
"type": "RPT_F10_FINANCE_GBALANCE",
"sty": "F10_FINANCE_GBALANCE",
"filter": f"""(SECUCODE="{symbol[2:]}.{symbol[:2]}")(REPORT_DATE in ({",".join(report_date_list)}))""",
"p": "1",
"ps": "200",
"sr": "-1",
"st": "REPORT_DATE",
"source": "HSF10",
"client": "PC",
"v": "05767841728614413",
}
r = requests.get(url, params=params)
data_json = r.json()
temp_df = pd.DataFrame(data_json["result"]["data"])
temp_df["REPORT_DATE"] = pd.to_datetime(temp_df["REPORT_DATE"]).dt.date
temp_df.sort_values(
by=["REPORT_DATE"], ascending=False, inplace=True, ignore_index=True
)
return temp_df
def stock_profit_sheet_by_report_delisted_em(symbol: str = "SZ000013") -> pd.DataFrame:
"""
东方财富-股票-财务分析-利润表-已退市股票-按报告期
https://emweb.securities.eastmoney.com/pc_hsf10/pages/index.html?type=web&code=SZ000013#/cwfx/lrb
:param symbol: 已退市股票代码; 带市场标识
:type symbol: str
:return: 利润表-按报告期
:rtype: pandas.DataFrame
"""
report_date_list = __get_report_date_list_delisted_em(symbol)
url = "https://datacenter.eastmoney.com/securities/api/data/get"
params = {
"type": "RPT_F10_FINANCE_GINCOME",
"sty": "APP_F10_GINCOME",
"filter": f"""(SECUCODE="{symbol[2:]}.{symbol[:2]}")(REPORT_DATE in ({",".join(report_date_list)}))""",
"p": "1",
"ps": "200",
"sr": "-1",
"st": "REPORT_DATE",
"source": "HSF10",
"client": "PC",
"v": "05767841728614413",
}
r = requests.get(url, params=params)
data_json = r.json()
temp_df = pd.DataFrame(data_json["result"]["data"])
temp_df["REPORT_DATE"] = pd.to_datetime(temp_df["REPORT_DATE"]).dt.date
temp_df.sort_values(
by=["REPORT_DATE"], ascending=False, inplace=True, ignore_index=True
)
return temp_df
def stock_cash_flow_sheet_by_report_delisted_em(
symbol: str = "SZ000013",
) -> pd.DataFrame:
"""
东方财富-股票-财务分析-现金流量表-已退市股票-按报告期
https://emweb.securities.eastmoney.com/pc_hsf10/pages/index.html?type=web&code=SZ000013#/cwfx/xjllb
:param symbol: 已退市股票代码; 带市场标识
:type symbol: str
:return: 现金流量表-按报告期
:rtype: pandas.DataFrame
"""
report_date_list = __get_report_date_list_delisted_em(symbol)
url = "https://datacenter.eastmoney.com/securities/api/data/get"
params = {
"type": "RPT_F10_FINANCE_GCASHFLOW",
"sty": "APP_F10_GCASHFLOW",
"filter": f"""(SECUCODE="{symbol[2:]}.{symbol[:2]}")(REPORT_DATE in ({",".join(report_date_list)}))""",
"p": "1",
"ps": "200",
"sr": "-1",
"st": "REPORT_DATE",
"source": "HSF10",
"client": "PC",
"v": "05767841728614413",
}
r = requests.get(url, params=params)
data_json = r.json()
temp_df = pd.DataFrame(data_json["result"]["data"])
temp_df["REPORT_DATE"] = pd.to_datetime(temp_df["REPORT_DATE"]).dt.date
temp_df.sort_values(
by=["REPORT_DATE"], ascending=False, inplace=True, ignore_index=True
)
return temp_df
if __name__ == "__main__":
stock_balance_sheet_by_report_em_df = stock_balance_sheet_by_report_em(
symbol="SH600519"
)
print(stock_balance_sheet_by_report_em_df)
stock_balance_sheet_by_yearly_em_df = stock_balance_sheet_by_yearly_em(
symbol="SH600519"
)
print(stock_balance_sheet_by_yearly_em_df)
stock_profit_sheet_by_report_em_df = stock_profit_sheet_by_report_em(
symbol="SH600519"
)
print(stock_profit_sheet_by_report_em_df)
stock_profit_sheet_by_yearly_em_df = stock_profit_sheet_by_yearly_em(
symbol="SH600519"
)
print(stock_profit_sheet_by_yearly_em_df)
stock_profit_sheet_by_quarterly_em_df = stock_profit_sheet_by_quarterly_em(
symbol="SH600519"
)
print(stock_profit_sheet_by_quarterly_em_df)
stock_cash_flow_sheet_by_report_em_df = stock_cash_flow_sheet_by_report_em(
symbol="SH600519"
)
print(stock_cash_flow_sheet_by_report_em_df)
stock_cash_flow_sheet_by_yearly_em_df = stock_cash_flow_sheet_by_yearly_em(
symbol="SH601398"
)
print(stock_cash_flow_sheet_by_yearly_em_df)
stock_cash_flow_sheet_by_quarterly_em_df = stock_cash_flow_sheet_by_quarterly_em(
symbol="SH601398"
)
print(stock_cash_flow_sheet_by_quarterly_em_df)
stock_balance_sheet_by_report_delisted_em_df = (
stock_balance_sheet_by_report_delisted_em(symbol="SZ000013")
)
print(stock_balance_sheet_by_report_delisted_em_df)
stock_profit_sheet_by_report_delisted_em_df = (
stock_profit_sheet_by_report_delisted_em(symbol="SZ000013")
)
print(stock_profit_sheet_by_report_delisted_em_df)
stock_cash_flow_sheet_by_report_delisted_em_df = (
stock_cash_flow_sheet_by_report_delisted_em(symbol="SZ000013")
)
print(stock_cash_flow_sheet_by_report_delisted_em_df)
@@ -0,0 +1,55 @@
#!/usr/bin/env python
# -*- coding:utf-8 -*-
"""
Date: 2025/10/30 15:00
Desc: 全部A股-等权重市盈率中位数市盈率
https://www.legulegu.com/stockdata/a-ttm-lyr
"""
import pandas as pd
import requests
from akshare.stock_feature.stock_a_indicator import get_token_lg, get_cookie_csrf
def stock_a_ttm_lyr() -> pd.DataFrame:
"""
全部 A -等权重市盈率中位数市盈率
:return: 全部A股-等权重市盈率中位数市盈率
:rtype: pandas.DataFrame
"""
url = "https://legulegu.com/api/stock-data/market-ttm-lyr"
params = {
"marketId": "5",
"token": get_token_lg(),
}
# 获取 cookie 和 headers
csrf_data = get_cookie_csrf(url="https://www.legulegu.com/stockdata/a-ttm-lyr")
# 使用返回的 headers(已经是副本)
request_headers = csrf_data["headers"].copy()
request_headers.update(
{
"host": "www.legulegu.com",
"referer": "https://www.legulegu.com/stockdata/a-ttm-lyr",
}
)
# 使用独立的 session
session = requests.Session()
r = session.get(
url,
params=params,
cookies=csrf_data["cookies"],
headers=request_headers,
)
data_json = r.json()
temp_df = pd.DataFrame(data_json["data"])
temp_df["date"] = pd.to_datetime(temp_df["date"], errors="coerce").dt.date
# 关闭 session
session.close()
return temp_df
if __name__ == "__main__":
stock_a_ttm_lyr_df = stock_a_ttm_lyr()
print(stock_a_ttm_lyr_df)
@@ -0,0 +1,66 @@
#!/usr/bin/env python
# -*- coding:utf-8 -*-
"""
Date: 2025/12/24 18:26
Desc: 百度股市通-美股-财务报表-估值数据
https://gushitong.baidu.com/stock/us-NVDA
"""
import http.client
import json
import urllib
import pandas as pd
def stock_us_valuation_baidu(
symbol: str = "NVDA", indicator: str = "总市值", period: str = "近一年"
) -> pd.DataFrame:
"""
百度股市通-美股-财务报表-估值数据
https://gushitong.baidu.com/stock/us-NVDA
:param symbol: 股票代码
:type symbol: str
:param indicator: choice of {"总市值", "市盈率(TTM)", "市盈率(静)", "市净率", "市现率"}
:type indicator: str
:param period: choice of {"近一年", "近三年", "全部"}
:type period: str
:return: 估值数据
:rtype: pandas.DataFrame
"""
params = {
"openapi": "1",
"dspName": "iphone",
"tn": "tangram",
"client": "app",
"query": indicator,
"code": symbol,
"word": "",
"resource_id": "51171",
"market": "us",
"tag": indicator,
"chart_select": period,
"industry_select": "",
"skip_industry": "1",
"finClientType": "pc",
}
conn = http.client.HTTPSConnection("gushitong.baidu.com")
conn.request(method="GET", url=f"/opendata?{urllib.parse.urlencode(params)}")
r = conn.getresponse()
data_json = json.loads(r.read())
temp_df = pd.DataFrame(
data_json["Result"][0]["DisplayData"]["resultData"]["tplData"]["result"][
"chartInfo"
][0]["body"]
)
temp_df.columns = ["date", "value"]
temp_df["date"] = pd.to_datetime(temp_df["date"]).dt.date
temp_df["value"] = pd.to_numeric(temp_df["value"])
return temp_df
if __name__ == "__main__":
stock_us_valuation_baidu_df = stock_us_valuation_baidu(
symbol="NVDA", indicator="总市值", period="近一年"
)
print(stock_us_valuation_baidu_df)
@@ -0,0 +1,83 @@
#!/usr/bin/env python
# -*- coding:utf-8 -*-
"""
Date: 2024/11/26 18:00
Desc: 东方财富网-数据中心-估值分析-每日互动-每日互动-估值分析
https://data.eastmoney.com/gzfx/detail/300766.html
"""
import pandas as pd
from akshare.request import make_request_with_retry_json
def stock_value_em(symbol: str = "300766") -> pd.DataFrame:
"""
东方财富网-数据中心-估值分析-每日互动-每日互动-估值分析
https://data.eastmoney.com/gzfx/detail/300766.html
:param symbol: 股票代码
:type symbol: str
:return: 估值分析
:rtype: pandas.DataFrame
"""
url = "https://datacenter-web.eastmoney.com/api/data/v1/get"
params = {
"sortColumns": "TRADE_DATE",
"sortTypes": "-1",
"pageSize": "5000",
"pageNumber": "1",
"reportName": "RPT_VALUEANALYSIS_DET",
"columns": "ALL",
"quoteColumns": "",
"source": "WEB",
"client": "WEB",
"filter": f'(SECURITY_CODE="{symbol}")',
}
data_json = make_request_with_retry_json(url, params=params)
temp_json = data_json["result"]["data"]
temp_df = pd.DataFrame(temp_json)
temp_df.rename(
columns={
"TRADE_DATE": "数据日期",
"CLOSE_PRICE": "当日收盘价",
"CHANGE_RATE": "当日涨跌幅",
"TOTAL_MARKET_CAP": "总市值",
"NOTLIMITED_MARKETCAP_A": "流通市值",
"TOTAL_SHARES": "总股本",
"FREE_SHARES_A": "流通股本",
"PE_TTM": "PE(TTM)",
"PE_LAR": "PE(静)",
"PB_MRQ": "市净率",
"PEG_CAR": "PEG值",
"PCF_OCF_TTM": "市现率",
"PS_TTM": "市销率",
},
inplace=True,
)
temp_df = temp_df[
[
"数据日期",
"当日收盘价",
"当日涨跌幅",
"总市值",
"流通市值",
"总股本",
"流通股本",
"PE(TTM)",
"PE(静)",
"市净率",
"PEG值",
"市现率",
"市销率",
]
]
temp_df["数据日期"] = pd.to_datetime(temp_df["数据日期"], errors="coerce").dt.date
for item in temp_df.columns[1:]:
temp_df[item] = pd.to_numeric(temp_df[item], errors="coerce")
temp_df.sort_values(by="数据日期", ignore_index=True, inplace=True)
return temp_df
if __name__ == "__main__":
stock_value_em_df = stock_value_em(symbol="300766")
print(stock_value_em_df)
@@ -0,0 +1,148 @@
#!/usr/bin/env python
# -*- coding:utf-8 -*-
"""
Date: 2025/3/20 18:00
Desc: 东方财富-数据中心-年报季报
东方财富-数据中心-年报季报-业绩快报-业绩报表
https://data.eastmoney.com/bbsj/202003/yjbb.html
"""
import pandas as pd
import requests
from akshare.utils.tqdm import get_tqdm
def stock_yjbb_em(date: str = "20200331") -> pd.DataFrame:
"""
东方财富-数据中心-年报季报-业绩快报-业绩报表
https://data.eastmoney.com/bbsj/202003/yjbb.html
:param date: "20200331", "20200630", "20200930", "20201231"; 20100331 开始
:type date: str
:return: 业绩报表
:rtype: pandas.DataFrame
"""
import warnings
warnings.simplefilter(action="ignore", category=FutureWarning) # 忽略所有
url = "https://datacenter-web.eastmoney.com/api/data/v1/get"
params = {
"sortColumns": "UPDATE_DATE,SECURITY_CODE",
"sortTypes": "-1,-1",
"pageSize": "500",
"pageNumber": "1",
"reportName": "RPT_LICO_FN_CPD",
"columns": "ALL",
"filter": f"(REPORTDATE='{'-'.join([date[:4], date[4:6], date[6:]])}')",
}
r = requests.get(url, params=params)
data_json = r.json()
page_num = data_json["result"]["pages"]
big_df = pd.DataFrame()
tqdm = get_tqdm()
big_list = []
for page in tqdm(range(1, page_num + 1), leave=False):
params.update(
{
"pageNumber": page,
}
)
r = requests.get(url, params=params)
data_json = r.json()
temp_df = pd.DataFrame(data_json["result"]["data"])
big_list.append(temp_df)
big_df = pd.concat(big_list, 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["每股收益"] = 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["净利润-净利润"], 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["净资产收益率"], errors="coerce")
big_df["每股经营现金流量"] = pd.to_numeric(
big_df["每股经营现金流量"], errors="coerce"
)
big_df["销售毛利率"] = pd.to_numeric(big_df["销售毛利率"], errors="coerce")
big_df["最新公告日期"] = pd.to_datetime(
big_df["最新公告日期"], errors="coerce"
).dt.date
return big_df
if __name__ == "__main__":
stock_yjbb_em_df = stock_yjbb_em(date="20220331")
print(stock_yjbb_em_df)
@@ -0,0 +1,94 @@
#!/usr/bin/env python
# -*- coding:utf-8 -*-
"""
Date: 2023/6/8 16:34
Desc: 巨潮资讯-首页-数据-预约披露
http://www.cninfo.com.cn/new/commonUrl?url=data/yypl
"""
import pandas as pd
import requests
def stock_report_disclosure(
market: str = "沪深京", period: str = "2021年报"
) -> pd.DataFrame:
"""
巨潮资讯-首页-数据-预约披露
http://www.cninfo.com.cn/new/commonUrl?url=data/yypl
:param market: choice of {"沪深京": "szsh", "深市": "sz", "深主板": "szmb", "中小板": "szsme",
"创业板": "szcn", "沪市": "sh", "沪主板": "shmb", "科创板": "shkcp"}
:type market: str
:param period: 最近四期的财报
:type period: str
:return: 指定 market period 的数据
:rtype: pandas.DataFrame
"""
market_map = {
"沪深京": "szsh",
"深市": "sz",
"深主板": "szmb",
"创业板": "szcn",
"沪市": "sh",
"沪主板": "shmb",
"科创板": "shkcp",
"北交所": "bj",
}
year = period[:4]
period_map = {
f"{year}一季": f"{year}-03-31",
f"{year}半年报": f"{year}-06-30",
f"{year}三季": f"{year}-09-30",
f"{year}年报": f"{year}-12-31",
}
url = "http://www.cninfo.com.cn/new/information/getPrbookInfo"
params = {
"sectionTime": period_map[period],
"firstTime": "",
"lastTime": "",
"market": market_map[market],
"stockCode": "",
"orderClos": "",
"isDesc": "",
"pagesize": "10000",
"pagenum": "1",
}
r = requests.post(url, params=params)
text_json = r.json()
temp_df = pd.DataFrame(text_json["prbookinfos"])
temp_df.columns = [
"股票代码",
"股票简称",
"首次预约",
"实际披露",
"初次变更",
"二次变更",
"三次变更",
"报告期",
"-",
"组织码",
]
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_datetime(temp_df["二次变更"], errors="coerce").dt.date
temp_df["三次变更"] = pd.to_datetime(temp_df["三次变更"], errors="coerce").dt.date
temp_df["实际披露"] = pd.to_datetime(temp_df["实际披露"], errors="coerce").dt.date
return temp_df
if __name__ == "__main__":
stock_report_disclosure_df = stock_report_disclosure(
market="沪深京", period="2022年报"
)
print(stock_report_disclosure_df)
@@ -0,0 +1,368 @@
#!/usr/bin/env python
# -*- coding:utf-8 -*-
"""
Date: 2024/4/4 18:10
Desc: 东方财富-数据中心-年报季报
东方财富-数据中心-年报季报-业绩预告
https://data.eastmoney.com/bbsj/202003/yjyg.html
东方财富-数据中心-年报季报-预约披露时间
https://data.eastmoney.com/bbsj/202003/yysj.html
"""
import pandas as pd
import requests
from tqdm import tqdm
def stock_yjkb_em(date: str = "20211231") -> pd.DataFrame:
"""
东方财富-数据中心-年报季报-业绩快报
https://data.eastmoney.com/bbsj/202003/yjkb.html
:param date: 财报发布日期; choice of {"20200331", "20200630", "20200930", "20201231", ...}; 20100331 开始
:type date: str
:return: 业绩快报
:rtype: pandas.DataFrame
"""
url = "https://datacenter.eastmoney.com/securities/api/data/v1/get"
params = {
"sortColumns": "UPDATE_DATE,SECURITY_CODE",
"sortTypes": "-1,-1",
"pageSize": "500",
"pageNumber": "1",
"reportName": "RPT_FCI_PERFORMANCEE",
"columns": "ALL",
"filter": f"""(SECURITY_TYPE_CODE in ("058001001","058001008"))(TRADE_MARKET_CODE!="069001017")
(REPORT_DATE='{"-".join([date[:4], date[4:6], date[6:]])}')""",
}
r = requests.get(url, params=params)
data_json = r.json()
big_df = pd.DataFrame()
total_page = data_json["result"]["pages"]
for page in tqdm(range(1, total_page + 1), leave=False):
params.update(
{
"pageNumber": page,
}
)
r = requests.get(url, params=params)
data_json = r.json()
temp_df = pd.DataFrame(data_json["result"]["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["每股收益"] = 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["营业收入-季度环比增长"], 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["净利润-季度环比增长"], 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_datetime(big_df["公告日期"]).dt.date
return big_df
def stock_yjyg_em(date: str = "20200331") -> pd.DataFrame:
"""
东方财富-数据中心-年报季报-业绩预告
https://data.eastmoney.com/bbsj/202003/yjyg.html
:param date: 财报发布日期; choice of {"20200331", "20200630", "20200930", "20201231", ...}; 20081231 开始
:type date: str
:return: 业绩预告
:rtype: pandas.DataFrame
"""
url = "https://datacenter.eastmoney.com/securities/api/data/v1/get"
params = {
"sortColumns": "NOTICE_DATE,SECURITY_CODE",
"sortTypes": "-1,-1",
"pageSize": "500",
"pageNumber": "1",
"reportName": "RPT_PUBLIC_OP_NEWPREDICT",
"columns": "ALL",
"filter": f" (REPORT_DATE='{'-'.join([date[:4], date[4:6], date[6:]])}')",
}
r = requests.get(url, params=params)
data_json = r.json()
big_df = pd.DataFrame()
total_page = data_json["result"]["pages"]
for page in tqdm(range(1, total_page + 1), leave=False):
params.update(
{
"pageNumber": page,
}
)
r = requests.get(url, params=params)
data_json = r.json()
temp_df = pd.DataFrame(data_json["result"]["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["公告日期"] = 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")
return big_df
def stock_yysj_em(symbol: str = "沪深A股", date: str = "20200331") -> pd.DataFrame:
"""
东方财富-数据中心-年报季报-预约披露时间
https://data.eastmoney.com/bbsj/202003/yysj.html
:param symbol: choice of {'沪深A股', '沪市A股', '科创板', '深市A股', '创业板', '京市A股', 'ST板'}
:type symbol: str
:param date: "20190331", "20190630", "20190930", "20191231"; 20081231 开始
:type date: str
:return: 指定时间的上市公司预约披露时间数据
:rtype: pandas.DataFrame
"""
url = "https://datacenter-web.eastmoney.com/api/data/v1/get"
params = {
"sortColumns": "FIRST_APPOINT_DATE,SECURITY_CODE",
"sortTypes": "1,1",
"pageSize": "500",
"pageNumber": "1",
"reportName": "RPT_PUBLIC_BS_APPOIN",
"columns": "ALL",
"filter": f"""(SECURITY_TYPE_CODE in ("058001001","058001008"))(TRADE_MARKET_CODE!="069001017")
(REPORT_DATE='{"-".join([date[:4], date[4:6], date[6:]])}')""",
}
if symbol == "沪市A股":
params.update(
{
"filter": f"""(SECURITY_TYPE_CODE in ("058001001","058001008"))
(TRADE_MARKET_CODE in ("069001001001","069001001003","069001001006"))
(REPORT_DATE='{"-".join([date[:4], date[4:6], date[6:]])}')"""
}
)
elif symbol == "科创板":
params.update(
{
"filter": f"""(SECURITY_TYPE_CODE in ("058001001","058001008"))(TRADE_MARKET_CODE="069001001006")
(REPORT_DATE='{"-".join([date[:4], date[4:6], date[6:]])}')"""
}
)
elif symbol == "深市A股":
params.update(
{
"filter": f"""(SECURITY_TYPE_CODE="058001001")(TRADE_MARKET_CODE in
("069001002001","069001002002","069001002003","069001002005"))
(REPORT_DATE='{"-".join([date[:4], date[4:6], date[6:]])}')"""
}
)
elif symbol == "创业板":
params.update(
{
"filter": f"""(SECURITY_TYPE_CODE="058001001")(TRADE_MARKET_CODE="069001002002")
(REPORT_DATE='{"-".join([date[:4], date[4:6], date[6:]])}')"""
}
)
elif symbol == "京市A股":
params.update(
{
"filter": f"""(TRADE_MARKET_CODE="069001017")
(REPORT_DATE='{"-".join([date[:4], date[4:6], date[6:]])}')"""
}
)
elif symbol == "ST板":
params.update(
{
"filter": f"""(TRADE_MARKET_CODE in("069001001003","069001002005"))
(REPORT_DATE='{"-".join([date[:4], date[4:6], date[6:]])}')"""
}
)
r = requests.get(url, params=params)
data_json = r.json()
total_page = data_json["result"]["pages"]
big_df = pd.DataFrame()
for page in tqdm(range(1, total_page + 1), leave=False):
params.update(
{
"pageNumber": page,
}
)
r = requests.get(url, params=params)
data_json = r.json()
temp_df = pd.DataFrame(data_json["result"]["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["首次预约时间"] = pd.to_datetime(
big_df["首次预约时间"], errors="coerce"
).dt.date
big_df["一次变更日期"] = pd.to_datetime(
big_df["一次变更日期"], errors="coerce"
).dt.date
big_df["二次变更日期"] = pd.to_datetime(
big_df["二次变更日期"], errors="coerce"
).dt.date
big_df["三次变更日期"] = pd.to_datetime(
big_df["三次变更日期"], errors="coerce"
).dt.date
big_df["实际披露时间"] = pd.to_datetime(
big_df["实际披露时间"], errors="coerce"
).dt.date
return big_df
if __name__ == "__main__":
stock_yjkb_em_df = stock_yjkb_em(date="20200331")
print(stock_yjkb_em_df)
stock_yjyg_em_df = stock_yjyg_em(date="20250331")
print(stock_yjyg_em_df)
stock_yysj_em_df = stock_yysj_em(symbol="沪深A股", date="20211231")
print(stock_yysj_em_df)
@@ -0,0 +1,106 @@
#!/usr/bin/env python
# -*- coding:utf-8 -*-
"""
Date: 2022/4/27 19:18
Desc: 东方财富网-数据中心-特色数据-一致行动人
https://data.eastmoney.com/yzxdr/
"""
import pandas as pd
import requests
from akshare.utils.tqdm import get_tqdm
from akshare.utils import demjson
def stock_yzxdr_em(date: str = "20240930") -> pd.DataFrame:
"""
东方财富网-数据中心-特色数据-一致行动人
https://data.eastmoney.com/yzxdr/
:param date: 每年的季度末时间点
:type date: str
:return: 一致行动人
:rtype: pandas.DataFrame
"""
import warnings
warnings.simplefilter(action="ignore", category=FutureWarning) # 忽略所有
date = "-".join([date[:4], date[4:6], date[6:]])
url = "https://datacenter.eastmoney.com/api/data/get"
params = {
"type": "RPTA_WEB_YZXDRINDEX",
"sty": "ALL",
"source": "WEB",
"p": "1",
"ps": "500",
"st": "noticedate",
"sr": "-1",
"var": "mwUyirVm",
"filter": f"(enddate='{date}')",
"rt": "53575609",
}
r = requests.get(url, params=params)
data_text = r.text
data_json = demjson.decode(data_text[data_text.find("{") : -1])
total_pages = data_json["result"]["pages"]
big_df = pd.DataFrame()
tqdm = get_tqdm()
for page in tqdm(range(1, total_pages + 1), leave=False):
params.update(
{
"p": str(page),
"filter": f"(enddate='{date}')",
}
)
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["result"]["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["数据日期"] = pd.to_datetime(big_df["数据日期"], errors="coerce")
big_df["公告日期"] = pd.to_datetime(big_df["公告日期"], errors="coerce")
big_df = big_df[
[
"序号",
"股票代码",
"股票简称",
"一致行动人",
"股东排名",
"持股数量",
"持股比例",
"持股数量变动",
"行业",
"公告日期",
]
]
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")
return big_df
if __name__ == "__main__":
stock_yzxdr_em_df = stock_yzxdr_em(date="20240930")
print(stock_yzxdr_em_df)
@@ -0,0 +1,125 @@
#!/usr/bin/env python
# -*- coding:utf-8 -*-
"""
Date: 2025/2/11 20:32
Desc: 东方财富网-数据中心-重大合同-重大合同明细
https://data.eastmoney.com/zdht/mx.html
"""
import pandas as pd
import requests
from akshare.utils.tqdm import get_tqdm
def stock_zdhtmx_em(
start_date: str = "20200819", end_date: str = "20230819"
) -> pd.DataFrame:
"""
东方财富网-数据中心-重大合同-重大合同明细
https://data.eastmoney.com/zdht/mx.html
:param start_date: 开始日期, eg 20200819
:type start_date: str
:param end_date: 结束日期, eg 20230819
:type end_date: str
:return: 股东大会
:rtype: pandas.DataFrame
"""
import warnings
warnings.filterwarnings(action="ignore", category=FutureWarning)
url = "https://datacenter-web.eastmoney.com/api/data/v1/get"
params = {
"sortColumns": "DIM_RDATE",
"sortTypes": "-1",
"pageSize": "500",
"pageNumber": "1",
"columns": "ALL",
"token": "894050c76af8597a853f5b408b759f5d",
"reportName": "RPTA_WEB_ZDHT_LIST",
"filter": f"""(DIM_RDATE>='{"-".join([start_date[:4], start_date[4:6], start_date[6:]])}')
(DIM_RDATE<='{"-".join([end_date[:4], end_date[4:6], end_date[6:]])}')""",
}
r = requests.get(url, params=params)
data_json = r.json()
total_page = data_json["result"]["pages"]
big_df = pd.DataFrame()
tqdm = get_tqdm()
for page in tqdm(range(1, total_page + 1), leave=False):
params.update(
{
"pageNumber": page,
}
)
r = requests.get(url, params=params)
data_json = r.json()
temp_df = pd.DataFrame(data_json["result"]["data"])
big_df = pd.concat(objs=[big_df, temp_df], axis=0, ignore_index=True)
big_df.reset_index(inplace=True)
big_df["index"] = big_df["index"] + 1
big_df.rename(
columns={
"index": "序号",
"DIM_SCODE": "-",
"CONTENTS": "-",
"CONTRACTNAME": "合同名称",
"CONTRACTTYPE": "-",
"COUNTERPARTY": "其他签署方",
"COUNTERPARTYREL": "-",
"ISABOLISHED": "-",
"DIM_RDATE": "公告日期",
"REMARK": "-",
"SIGNATORY": "签署主体",
"SIGNATORYREL": "与上市公司关系",
"SIGNDATE": "签署日期",
"SIGNEFFECT": "-",
"UPDATEDATE": "-",
"YEAR": "-",
"AMOUNTS": "合同金额",
"SECURITYCODE": "股票代码",
"SECURITYSHORTNAME": "股票简称",
"CONTRACTTYPENAME": "合同类型",
"SIGNATORYRELNAME": "签署主体-与上市公司关系",
"COUNTERPARTYRELNAME": "其他签署方-与上市公司关系",
"SNDYYSR": "上年度营业收入",
"OPERATEREVE": "最新财务报表的营业收入",
"RCHANGE1DC": "-",
"RCHANGE20DC": "-",
"ZSNDYYSRBL": "占上年度营业收入比例",
},
inplace=True,
)
big_df = big_df[
[
"序号",
"股票代码",
"股票简称",
"签署主体",
"签署主体-与上市公司关系",
"其他签署方",
"其他签署方-与上市公司关系",
"合同类型",
"合同名称",
"合同金额",
"上年度营业收入",
"占上年度营业收入比例",
"最新财务报表的营业收入",
"签署日期",
"公告日期",
]
]
big_df["签署日期"] = pd.to_datetime(big_df["签署日期"], errors="coerce").dt.date
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"
)
return big_df
if __name__ == "__main__":
stock_zdhtmx_em_df = stock_zdhtmx_em(start_date="20220819", end_date="20230819")
print(stock_zdhtmx_em_df)
@@ -0,0 +1,201 @@
#!/usr/bin/env python
# -*- coding:utf-8 -*-
"""
Date: 2024/4/4 18:20
Desc: 增发和配股
东方财富网-数据中心-新股数据-增发-全部增发
https://data.eastmoney.com/other/gkzf.html
东方财富网-数据中心-新股数据-配股
https://data.eastmoney.com/xg/pg/
"""
import pandas as pd
import requests
from akshare.utils.tqdm import get_tqdm
def stock_qbzf_em() -> pd.DataFrame:
"""
东方财富网-数据中心-新股数据-增发-全部增发
https://data.eastmoney.com/other/gkzf.html
:return: 全部增发
:rtype: pandas.DataFrame
"""
import warnings
warnings.filterwarnings(action="ignore", category=FutureWarning)
url = "https://datacenter-web.eastmoney.com/api/data/v1/get"
params = {
"sortColumns": "ISSUE_DATE",
"sortTypes": "-1",
"pageSize": "500",
"pageNumber": "1",
"reportName": "RPT_SEO_DETAIL",
"columns": "ALL",
"quoteColumns": "f2~01~SECURITY_CODE~NEW_PRICE",
"quoteType": "0",
"source": "WEB",
"client": "WEB",
}
r = requests.get(url, params=params)
data_json = r.json()
total_page = data_json["result"]["pages"]
big_df = pd.DataFrame()
tqdm = get_tqdm()
for page in tqdm(range(1, total_page + 1), leave=False):
params.update(
{
"pageNumber": page,
}
)
r = requests.get(url, params=params)
data_json = r.json()
temp_df = pd.DataFrame(data_json["result"]["data"])
big_df = pd.concat(objs=[big_df, temp_df], ignore_index=True)
big_df.rename(
columns={
"SECURITY_NAME_ABBR": "股票简称",
"SECURITY_CODE": "股票代码",
"CORRECODE": "增发代码",
"SEO_TYPE": "发行方式",
"ISSUE_NUM": "发行总数",
"ONLINE_ISSUE_NUM": "网上发行",
"ISSUE_PRICE": "发行价格",
"NEW_PRICE": "最新价",
"ISSUE_DATE": "发行日期",
"ISSUE_LISTING_DATE": "增发上市日期",
"LOCKIN_PERIOD": "锁定期",
},
inplace=True,
)
big_df = big_df[
[
"股票代码",
"股票简称",
"增发代码",
"发行方式",
"发行总数",
"网上发行",
"发行价格",
"最新价",
"发行日期",
"增发上市日期",
"锁定期",
]
]
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["发行方式"].map({"2": "公开增发", "1": "定向增发"})
big_df["发行日期"] = pd.to_datetime(big_df["发行日期"], errors="coerce").dt.date
big_df["增发上市日期"] = pd.to_datetime(
big_df["增发上市日期"], errors="coerce"
).dt.date
return big_df
def stock_pg_em() -> pd.DataFrame:
"""
东方财富网-数据中心-新股数据-配股
https://data.eastmoney.com/xg/pg/
:return: 配股
:rtype: pandas.DataFrame
"""
import warnings
warnings.filterwarnings(action="ignore", category=FutureWarning)
url = "https://datacenter-web.eastmoney.com/api/data/v1/get"
params = {
"sortColumns": "EQUITY_RECORD_DATE",
"sortTypes": "-1",
"pageSize": "50000",
"pageNumber": "1",
"reportName": "RPT_IPO_ALLOTMENT",
"columns": "ALL",
"quoteColumns": "f2~01~SECURITY_CODE~NEW_PRICE",
"quoteType": "0",
"source": "WEB",
"client": "WEB",
}
r = requests.get(url, params=params)
data_json = r.json()
total_page = data_json["result"]["pages"]
big_df = pd.DataFrame()
tqdm = get_tqdm()
for page in tqdm(range(1, total_page + 1), leave=False):
params.update(
{
"pageNumber": page,
}
)
r = requests.get(url, params=params)
data_json = r.json()
temp_df = pd.DataFrame(data_json["result"]["data"])
big_df = pd.concat(objs=[big_df, temp_df], ignore_index=True)
big_df.columns = [
"_",
"_",
"股票代码",
"-",
"股票简称",
"配售代码",
"_",
"配股比例",
"配股价",
"配股前总股本",
"配股数量",
"配股后总股本",
"股权登记日",
"缴款起始日期",
"缴款截止日期",
"上市日",
"_",
"_",
"_",
"_",
"_",
"_",
"最新价",
]
big_df = big_df[
[
"股票代码",
"股票简称",
"配售代码",
"配股数量",
"配股比例",
"配股价",
"最新价",
"配股前总股本",
"配股后总股本",
"股权登记日",
"缴款起始日期",
"缴款截止日期",
"上市日",
]
]
big_df["配股比例"] = "10配" + big_df["配股比例"].astype(str)
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["配股后总股本"], errors="coerce")
big_df["股权登记日"] = pd.to_datetime(big_df["股权登记日"], errors="coerce").dt.date
big_df["缴款起始日期"] = pd.to_datetime(
big_df["缴款起始日期"], errors="coerce"
).dt.date
big_df["缴款截止日期"] = pd.to_datetime(
big_df["缴款截止日期"], errors="coerce"
).dt.date
big_df["上市日"] = pd.to_datetime(big_df["上市日"], errors="coerce").dt.date
return big_df
if __name__ == "__main__":
stock_qbzf_em_df = stock_qbzf_em()
print(stock_qbzf_em_df)
stock_pg_em_df = stock_pg_em()
print(stock_pg_em_df)
@@ -0,0 +1,62 @@
#!/usr/bin/env python
# -*- coding:utf-8 -*-
"""
Date: 2024/5/29 23:00
Desc: 百度股市通-A股-财务报表-估值数据
https://gushitong.baidu.com/stock/ab-002044
"""
import pandas as pd
import requests
def stock_zh_valuation_baidu(
symbol: str = "002044", indicator: str = "总市值", period: str = "近一年"
) -> pd.DataFrame:
"""
百度股市通-A股-财务报表-估值数据
https://gushitong.baidu.com/stock/ab-002044
:param symbol: 股票代码
:type symbol: str
:param indicator: choice of {"总市值", "市盈率(TTM)", "市盈率(静)", "市净率", "市现率"}
:type indicator: str
:param period: choice of {"近一年", "近三年", "近五年", "近十年", "全部"}
:type period: str
:return: 估值数据
:rtype: pandas.DataFrame
"""
url = "https://gushitong.baidu.com/opendata"
params = {
"openapi": "1",
"dspName": "iphone",
"tn": "tangram",
"client": "app",
"query": indicator,
"code": symbol,
"word": "",
"resource_id": "51171",
"market": "ab",
"tag": indicator,
"chart_select": period,
"industry_select": "",
"skip_industry": "1",
"finClientType": "pc",
}
r = requests.get(url, params=params)
data_json = r.json()
temp_df = pd.DataFrame(
data_json["Result"][0]["DisplayData"]["resultData"]["tplData"]["result"][
"chartInfo"
][0]["body"]
)
temp_df.columns = ["date", "value"]
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
if __name__ == "__main__":
stock_zh_valuation_baidu_df = stock_zh_valuation_baidu(
symbol="002044", indicator="总市值", period="近一年"
)
print(stock_zh_valuation_baidu_df)
@@ -0,0 +1,57 @@
#!/usr/bin/env python
# -*- coding:utf-8 -*-
"""
Date: 2022/10/10 17:26
Desc: 百度股市通- A 股或指数-股评-投票
https://gushitong.baidu.com/index/ab-000001
"""
import requests
import pandas as pd
def stock_zh_vote_baidu(
symbol: str = "000001", indicator: str = "指数"
) -> pd.DataFrame:
"""
百度股市通- A 股或指数-股评-投票
https://gushitong.baidu.com/index/ab-000001
:param symbol: 股票代码
:type symbol: str
:param indicator: choice of {"指数", "股票"}
:type indicator: str
:return: 投票数据
:rtype: pandas.DataFrame
"""
indicator_map = {"股票": "stock", "指数": "index"}
url = "https://finance.pae.baidu.com/vapi/v1/stockvoterecords"
params = {
"code": symbol,
"market": "ab",
"finance_type": indicator_map[indicator],
"select_type": "week",
"from_smart_app": "0",
"method": "query",
"finClientType": "pc",
}
temp_list = []
for item_period in ["day", "week", "month", "year"]:
params.update({"select_type": item_period})
r = requests.get(url, params=params)
data_json = r.json()
temp_list.append(
[
item
for item in data_json["Result"]["voteRecords"]["voteRes"]
if item["type"] == item_period
][0]
)
temp_df = pd.DataFrame(temp_list)
temp_df.columns = ["周期", "-", "看涨", "看跌", "看涨比例", "看跌比例"]
temp_df = temp_df[["周期", "看涨", "看跌", "看涨比例", "看跌比例"]]
return temp_df
if __name__ == "__main__":
stock_zh_vote_baidu_df = stock_zh_vote_baidu(symbol="000001", indicator="指数")
print(stock_zh_vote_baidu_df)
@@ -0,0 +1,542 @@
#!/usr/bin/env python
# -*- coding:utf-8 -*-
"""
Date: 2024/11/22 21:30
Desc: 首页-行情中心-涨停板行情-涨停股池
https://quote.eastmoney.com/ztb/detail#type=ztgc
涨停板行情专题为您展示了 6 个股票池分别为
1. 涨停股池包含当日当前涨停的所有A股股票(不含未中断连续一字涨停板的新股)
2. 昨日涨停股池包含上一交易日收盘时涨停的所有A股股票(不含未中断连续一字涨停板的新股)
3. 强势股池包含创下60日新高或近期多次涨停的A股股票
4. 次新股池包含上市一年以内且中断了连续一字涨停板的A股股票
5. 炸板股池包含当日触及过涨停板且当前未封板的A股股票
6. 跌停股池包含当日当前跌停的所有A股股票
涨停板行情专题统计不包含ST股票及科创板股票
"""
from datetime import datetime, timedelta
import pandas as pd
import requests
def stock_zt_pool_em(date: str = "20241008") -> pd.DataFrame:
"""
东方财富网-行情中心-涨停板行情-涨停股池
https://quote.eastmoney.com/ztb/detail#type=ztgc
:param date: 交易日
:type date: str
:return: 涨停股池
:rtype: pandas.DataFrame
"""
url = "https://push2ex.eastmoney.com/getTopicZTPool"
params = {
"ut": "7eea3edcaed734bea9cbfc24409ed989",
"dpt": "wz.ztzt",
"Pageindex": "0",
"pagesize": "10000",
"sort": "fbt:asc",
"date": date,
}
r = requests.get(url, params=params)
data_json = r.json()
if data_json["data"] is None:
return pd.DataFrame()
if len(data_json["data"]["pool"]) == 0:
return pd.DataFrame()
temp_df = pd.DataFrame(data_json["data"]["pool"])
temp_df.reset_index(inplace=True)
temp_df["index"] = range(1, len(temp_df) + 1)
temp_df.columns = [
"序号",
"代码",
"_",
"名称",
"最新价",
"涨跌幅",
"成交额",
"流通市值",
"总市值",
"换手率",
"连板数",
"首次封板时间",
"最后封板时间",
"封板资金",
"炸板次数",
"所属行业",
"涨停统计",
]
temp_df["涨停统计"] = (
temp_df["涨停统计"].apply(lambda x: dict(x)["days"]).astype(str)
+ "/"
+ temp_df["涨停统计"].apply(lambda x: dict(x)["ct"]).astype(str)
)
temp_df = temp_df[
[
"序号",
"代码",
"名称",
"涨跌幅",
"最新价",
"成交额",
"流通市值",
"总市值",
"换手率",
"封板资金",
"首次封板时间",
"最后封板时间",
"炸板次数",
"涨停统计",
"连板数",
"所属行业",
]
]
temp_df["首次封板时间"] = temp_df["首次封板时间"].astype(str).str.zfill(6)
temp_df["最后封板时间"] = temp_df["最后封板时间"].astype(str).str.zfill(6)
temp_df["最新价"] = temp_df["最新价"] / 1000
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 stock_zt_pool_previous_em(date: str = "20240415") -> pd.DataFrame:
"""
东方财富网-行情中心-涨停板行情-昨日涨停股池
https://quote.eastmoney.com/ztb/detail#type=zrzt
:param date: 交易日
:type date: str
:return: 昨日涨停股池
:rtype: pandas.DataFrame
"""
url = "https://push2ex.eastmoney.com/getYesterdayZTPool"
params = {
"ut": "7eea3edcaed734bea9cbfc24409ed989",
"dpt": "wz.ztzt",
"Pageindex": "0",
"pagesize": "5000",
"sort": "zs:desc",
"date": date,
}
r = requests.get(url, params=params)
data_json = r.json()
if data_json["data"] is None:
return pd.DataFrame()
if len(data_json["data"]["pool"]) == 0:
return pd.DataFrame()
temp_df = pd.DataFrame(data_json["data"]["pool"])
temp_df.reset_index(inplace=True)
temp_df["index"] = range(1, len(temp_df) + 1)
temp_df.columns = [
"序号",
"代码",
"_",
"名称",
"最新价",
"涨停价",
"涨跌幅",
"成交额",
"流通市值",
"总市值",
"换手率",
"振幅",
"涨速",
"昨日封板时间",
"昨日连板数",
"所属行业",
"涨停统计",
]
temp_df["涨停统计"] = (
temp_df["涨停统计"].apply(lambda x: dict(x)["days"]).astype(str)
+ "/"
+ temp_df["涨停统计"].apply(lambda x: dict(x)["ct"]).astype(str)
)
temp_df = temp_df[
[
"序号",
"代码",
"名称",
"涨跌幅",
"最新价",
"涨停价",
"成交额",
"流通市值",
"总市值",
"换手率",
"涨速",
"振幅",
"昨日封板时间",
"昨日连板数",
"涨停统计",
"所属行业",
]
]
temp_df["最新价"] = temp_df["最新价"] / 1000
temp_df["涨停价"] = temp_df["涨停价"] / 1000
temp_df["昨日封板时间"] = temp_df["昨日封板时间"].astype(str).str.zfill(6)
return temp_df
def stock_zt_pool_strong_em(date: str = "20241231") -> pd.DataFrame:
"""
东方财富网-行情中心-涨停板行情-强势股池
https://quote.eastmoney.com/ztb/detail#type=qsgc
:param date: 交易日
:type date: str
:return: 强势股池
:rtype: pandas.DataFrame
"""
url = "https://push2ex.eastmoney.com/getTopicQSPool"
params = {
"ut": "7eea3edcaed734bea9cbfc24409ed989",
"dpt": "wz.ztzt",
"Pageindex": "0",
"pagesize": "5000",
"sort": "zdp:desc",
"date": date,
}
r = requests.get(url, params=params)
data_json = r.json()
if data_json["data"] is None:
return pd.DataFrame()
if len(data_json["data"]["pool"]) == 0:
return pd.DataFrame()
temp_df = pd.DataFrame(data_json["data"]["pool"])
temp_df.reset_index(inplace=True)
temp_df["index"] = range(1, len(temp_df) + 1)
temp_df.columns = [
"序号",
"代码",
"_",
"名称",
"最新价",
"涨停价",
"_",
"涨跌幅",
"成交额",
"流通市值",
"总市值",
"换手率",
"是否新高",
"入选理由",
"量比",
"涨速",
"涨停统计",
"所属行业",
]
temp_df["涨停统计"] = (
temp_df["涨停统计"].apply(lambda x: dict(x)["days"]).astype(str)
+ "/"
+ temp_df["涨停统计"].apply(lambda x: dict(x)["ct"]).astype(str)
)
temp_df = temp_df[
[
"序号",
"代码",
"名称",
"涨跌幅",
"最新价",
"涨停价",
"成交额",
"流通市值",
"总市值",
"换手率",
"涨速",
"是否新高",
"量比",
"涨停统计",
"入选理由",
"所属行业",
]
]
temp_df["最新价"] = temp_df["最新价"] / 1000
temp_df["涨停价"] = temp_df["涨停价"] / 1000
explained_map = {1: "60日新高", 2: "近期多次涨停", 3: "60日新高且近期多次涨停"}
temp_df["入选理由"] = temp_df["入选理由"].apply(lambda x: explained_map[x])
temp_df["是否新高"] = temp_df["是否新高"].apply(lambda x: "" if x == 1 else "")
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 stock_zt_pool_sub_new_em(date: str = "20241231") -> pd.DataFrame:
"""
东方财富网-行情中心-涨停板行情-次新股池
https://quote.eastmoney.com/ztb/detail#type=cxgc
:param date: 交易日
:type date: str
:return: 次新股池
:rtype: pandas.DataFrame
"""
url = "https://push2ex.eastmoney.com/getTopicCXPooll"
params = {
"ut": "7eea3edcaed734bea9cbfc24409ed989",
"dpt": "wz.ztzt",
"Pageindex": "0",
"pagesize": "5000",
"sort": "ods:asc",
"date": date,
}
r = requests.get(url, params=params)
data_json = r.json()
if len(data_json["data"]["pool"]) == 0:
return pd.DataFrame()
temp_df = pd.DataFrame(data_json["data"]["pool"])
temp_df.reset_index(inplace=True)
temp_df["index"] = range(1, len(temp_df) + 1)
temp_df.columns = [
"序号",
"代码",
"_",
"名称",
"最新价",
"涨停价",
"_",
"涨跌幅",
"成交额",
"流通市值",
"总市值",
"转手率",
"开板几日",
"开板日期",
"上市日期",
"_",
"是否新高",
"涨停统计",
"所属行业",
]
temp_df["涨停统计"] = (
temp_df["涨停统计"].apply(lambda x: dict(x)["days"]).astype(str)
+ "/"
+ temp_df["涨停统计"].apply(lambda x: dict(x)["ct"]).astype(str)
)
temp_df = temp_df[
[
"序号",
"代码",
"名称",
"涨跌幅",
"最新价",
"涨停价",
"成交额",
"流通市值",
"总市值",
"转手率",
"开板几日",
"开板日期",
"上市日期",
"是否新高",
"涨停统计",
"所属行业",
]
]
temp_df["最新价"] = temp_df["最新价"] / 1000
temp_df["涨停价"] = temp_df["涨停价"] / 1000
temp_df.loc[temp_df["涨停价"] > 100000, "涨停价"] = pd.NA
temp_df["开板日期"] = pd.to_datetime(temp_df["开板日期"], format="%Y%m%d").dt.date
temp_df["上市日期"] = pd.to_datetime(temp_df["上市日期"], format="%Y%m%d").dt.date
temp_df.loc[temp_df["上市日期"] == 0, "上市日期"] = pd.NaT
temp_df["是否新高"] = temp_df["是否新高"].apply(lambda x: "" if x == 1 else "")
return temp_df
def stock_zt_pool_zbgc_em(date: str = "20241011") -> pd.DataFrame:
"""
东方财富网-行情中心-涨停板行情-炸板股池
https://quote.eastmoney.com/ztb/detail#type=zbgc
:param date: 交易日
:type date: str
:return: 炸板股池
:rtype: pandas.DataFrame
"""
thirty_days_ago = datetime.now() - timedelta(days=30)
thirty_days_ago_str = thirty_days_ago.strftime("%Y%m%d")
if int(date) < int(thirty_days_ago_str):
raise ValueError("炸板股池只能获取最近 30 个交易日的数据")
url = "https://push2ex.eastmoney.com/getTopicZBPool"
params = {
"ut": "7eea3edcaed734bea9cbfc24409ed989",
"dpt": "wz.ztzt",
"Pageindex": "0",
"pagesize": "5000",
"sort": "fbt:asc",
"date": date,
}
r = requests.get(url, params=params)
data_json = r.json()
if data_json["data"] is None:
return pd.DataFrame()
if len(data_json["data"]["pool"]) == 0:
return pd.DataFrame()
temp_df = pd.DataFrame(data_json["data"]["pool"])
temp_df.reset_index(inplace=True)
temp_df["index"] = range(1, len(temp_df) + 1)
temp_df.columns = [
"序号",
"代码",
"_",
"名称",
"最新价",
"涨停价",
"涨跌幅",
"成交额",
"流通市值",
"总市值",
"换手率",
"首次封板时间",
"炸板次数",
"振幅",
"涨速",
"涨停统计",
"所属行业",
]
temp_df["涨停统计"] = (
temp_df["涨停统计"].apply(lambda x: dict(x)["days"]).astype(str)
+ "/"
+ temp_df["涨停统计"].apply(lambda x: dict(x)["ct"]).astype(str)
)
temp_df = temp_df[
[
"序号",
"代码",
"名称",
"涨跌幅",
"最新价",
"涨停价",
"成交额",
"流通市值",
"总市值",
"换手率",
"涨速",
"首次封板时间",
"炸板次数",
"涨停统计",
"振幅",
"所属行业",
]
]
temp_df["最新价"] = temp_df["最新价"] / 1000
temp_df["涨停价"] = temp_df["涨停价"] / 1000
temp_df["首次封板时间"] = temp_df["首次封板时间"].astype(str).str.zfill(6)
return temp_df
def stock_zt_pool_dtgc_em(date: str = "20241011") -> pd.DataFrame:
"""
东方财富网-行情中心-涨停板行情-跌停股池
https://quote.eastmoney.com/ztb/detail#type=dtgc
:param date: 交易日
:type date: str
:return: 跌停股池
:rtype: pandas.DataFrame
"""
thirty_days_ago = datetime.now() - timedelta(days=30)
thirty_days_ago_str = thirty_days_ago.strftime("%Y%m%d")
if int(date) < int(thirty_days_ago_str):
raise ValueError("跌停股池只能获取最近 30 个交易日的数据")
url = "https://push2ex.eastmoney.com/getTopicDTPool"
params = {
"ut": "7eea3edcaed734bea9cbfc24409ed989",
"dpt": "wz.ztzt",
"Pageindex": "0",
"pagesize": "10000",
"sort": "fund:asc",
"date": date,
}
r = requests.get(url, params=params)
data_json = r.json()
if len(data_json["data"]["pool"]) == 0:
return pd.DataFrame()
temp_df = pd.DataFrame(data_json["data"]["pool"])
temp_df.reset_index(inplace=True)
temp_df["index"] = range(1, len(temp_df) + 1)
temp_df.columns = [
"序号",
"代码",
"_",
"名称",
"最新价",
"涨跌幅",
"成交额",
"流通市值",
"总市值",
"动态市盈率",
"换手率",
"封单资金",
"最后封板时间",
"板上成交额",
"连续跌停",
"开板次数",
"所属行业",
]
temp_df = temp_df[
[
"序号",
"代码",
"名称",
"涨跌幅",
"最新价",
"成交额",
"流通市值",
"总市值",
"动态市盈率",
"换手率",
"封单资金",
"最后封板时间",
"板上成交额",
"连续跌停",
"开板次数",
"所属行业",
]
]
temp_df["最新价"] = temp_df["最新价"] / 1000
temp_df["最后封板时间"] = temp_df["最后封板时间"].astype(str).str.zfill(6)
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
if __name__ == "__main__":
stock_zt_pool_em_df = stock_zt_pool_em(date="20241008")
print(stock_zt_pool_em_df)
stock_zt_pool_previous_em_df = stock_zt_pool_previous_em(date="20240415")
print(stock_zt_pool_previous_em_df)
stock_zt_pool_strong_em_df = stock_zt_pool_strong_em(date="20241231")
print(stock_zt_pool_strong_em_df)
stock_zt_pool_sub_new_em_df = stock_zt_pool_sub_new_em(date="20241231")
print(stock_zt_pool_sub_new_em_df)
stock_zt_pool_zbgc_em_df = stock_zt_pool_zbgc_em(date="20241011")
print(stock_zt_pool_zbgc_em_df)
stock_zt_pool_dtgc_em_df = stock_zt_pool_dtgc_em(date="20241011")
print(stock_zt_pool_dtgc_em_df)
@@ -0,0 +1,989 @@
var TOKEN_SERVER_TIME = 1572845499.629;
function v_cookie (r, n, t, e, a) {
var u = n[0],
c = n[1],
v = a[0],
s = t[0],
f = t[1],
l = r[0],
d = hr(a[1], e[0], t[2]),
p = t[3],
h = e[1],
g = yr(a[2], a[3], e[2]),
m = yr(a[4], r[1], t[4]),
w = r[2],
I = a[5],
_ = a[6],
y = a[7],
E = hr(n[2], r[3], r[4]),
A = t[5],
C = e[3],
b = e[4],
B = t[6],
R = a[8],
T = a[9],
S = n[3],
k = t[7],
x = t[8],
O = a[10],
L = n[4],
M = n[5],
N = a[11],
P = e[5],
j = hr(n[6], e[6], t[9], r[5]),
D = t[10],
W = e[7],
$ = r[6],
F = yr(r[7], t[11], e[8], n[7]),
X = r[8],
H = t[12],
K = r[9],
U = n[8],
V = e[9],
Y = r[10],
J = e[10],
q = r[11],
Q = a[12],
Z = n[9],
G = t[13],
z = t[14],
rr = t[15],
nr = n[10],
tr = a[13],
er = a[14],
ar = e[11],
or = r[12],
ir = yr(t[16], r[13], r[14], r[15]),
ur = t[17],
cr = t[18];
function vr () {
var r = arguments[n[11]];
return r.split(n[12]).reverse().join(e[12])
}
var sr = [new e[13](hr(a[15], n[13], a[16])), new e[13](a[17])];
function fr () {
var n = arguments[a[18]];
if (!n) return a[19];
for (var o = t[19], i = e[14], u = e[15]; u < n.length; u++)
{
var c = n.charCodeAt(u),
v = c ^ i;
i = c,
o += r[16].fromCharCode(v)
}
return o
}
var lr = '',
dr; !
function (o) {
var i = e[18],
c = e[19];
o[e[20]] = a[21];
function v (t, a, o, i, u) {
var c, v, s;
c = v = s = r;
var f, l, d;
f = l = d = n;
var p, h, g;
p = h = g = e;
var m = t + g[21] + a;
i && (m += l[15] + i),
u && (m += h[22] + u),
o && (m += v[17] + o),
l[14][g[23]] = m
}
o[e[24]] = l;
function s (t, e, a) {
var o = n[16];
this.setCookie(t, r[18], i + o + c, e, a)
}
o[t[22]] = f;
function f (o) {
var i = vr(e[25], a[22]),
c = a[23][n[17]],
v = u + i + o + t[23],
s = '';
if (s == -r[19])
{
if (v = o + t[23], c.substr(a[24], v.length) != v) return;
s = a[24]
}
var f = s + v[r[20]],
l = '';
return l == -e[26] && (l = c[t[24]])
}
o[e[27]] = v;
function l () {
var r, t, a;
r = t = a = e;
var i, u, c;
i = u = c = n;
var v = u[18];
this.setCookie(v, a[28]),
this.getCookie(v) || (o[i[19]] = u[20]),
this.delCookie(v)
}
o[n[21]] = s
}(dr || (dr = {}));
var pr;
function hr () {
var r = arguments[a[25]];
if (!r) return a[19];
for (var e = a[19], o = t[25], i = n[22], u = t[18]; u < r.length; u++)
{
var c = r.charCodeAt(u);
i = (i + t[26]) % o.length,
c ^= o.charCodeAt(i),
e += String.fromCharCode(c)
}
return e
} !
function (o) {
var i, u, d;
i = u = d = a;
var p, h, g;
p = h = g = t;
var m, w, I;
m = w = I = r;
var _, y, E;
_ = y = E = n;
var b, B, R;
b = B = R = e;
var T = B[29],
S = y[23],
k = m[22],
x = w[0],
O = E[24],
L = (C, Ar, R[30]),
M = b[31],
N = T + S,
P = p[28],
j,
W = m[23][y[25]],
$,
F;
function X (r) {
return function () {
F.appendChild(j),
j.addBehavior(u[26]),
j.load(N);
var n = r();
return F.removeChild(j),
n
}
}
function H () {
var r = A;
r = D;
try
{
return !!(N in B[32] && b[32][N])
} catch (n)
{
return void B[15]
}
}
function K (r) {
return P ? G(r) : j ? Y(r) : void _[26]
}
function U () {
if (P = H(), P) j = _[27][N];
else if (W[k + c][I[24]]) try
{
$ = new ActiveXObject(vr(I[25], y[28], w[26])),
$.open(),
$.write(y[29]),
$.close(),
F = $.w[B[33]][I[27]][_[30]],
j = F.createElement(I[28])
} catch (r)
{
j = W.createElement(N),
F = W[vr(I[29], d[27])] || W.getElementsByTagName(b[17])[I[27]] || W[m[30]]
}
}
o[w[31]] = U;
function V (r, n) {
var t = J;
if (void 0 === n) return Z(r);
if (t = sr, P) z(r, n);
else
{
if (!j) return void B[15];
Q(r, n)
}
}
o[v + x] = V;
function Y (r) {
X(function () {
return r = J(r),
j.getAttribute(r)
})()
}
function J (r) {
var n = z;
n = v;
var t = vr(Ir, w[32]),
e = new y[31](t + O + s + L, b[31]);
return r.replace(new B[13](d[28]), b[34]).replace(e, p[29])
}
function q (r) {
try
{
j.removeItem(r)
} catch (n) { }
}
o[M + f + l] = K;
function Q (r, n) {
var t = G;
t = cr,
X(function () {
var t = M;
r = J(r),
t = K;
try
{
j.setAttribute(r, n),
j.save(N)
} catch (e) { }
})()
}
function Z (r) {
var n, t, e;
if (n = t = e = g, P) q(r);
else
{
if (!j) return void t[18];
rr(r)
}
}
function G (r) {
try
{
return j.getItem(r)
} catch (n)
{
return y[20]
}
}
o[fr(w[33], p[30], R[35])] = Z;
function z (r, n) {
try
{
j.setItem(r, n)
} catch (t) { }
}
function rr (r) {
X(function () {
r = J(r),
j.removeAttribute(r),
j.save(N)
})()
}
}(pr || (pr = {}));
var gr = function () {
var o, i, u;
o = i = u = e;
var c, v, s;
c = v = s = a;
var f, l, g;
f = l = g = n;
var m, w, I;
m = w = I = t;
var _, E, A;
_ = E = A = r;
var C = yr(Cr, U, _[34]),
b = vr(A[35], m[31]),
R = hr(g[32], c[29], i[36]),
T = hr(l[33], g[34], i[37], tr);
function S (r) {
this[m[32]] = r;
for (var n = o[15], t = r[i[38]]; t > n; n++) this[n] = i[15]
}
return S[d + p + C][b + h] = function () {
for (var r = this[vr(h, E[36], E[37])], n = [], t = -I[26], e = o[15], a = r[A[20]]; a > e; e++) for (var u = this[e], f = r[e], d = t += f; n[d] = u & parseInt(v[30], l[35]), --f != s[24];)--d,
u >>= parseInt(i[39], c[31]);
return n
},
S[vr(w[33], v[32])][_[38]] = function (r) {
var n = dr,
t = this[vr(y, l[36], A[39])],
e = f[26];
n = B;
for (var a = v[24], o = t[l[37]]; o > a; a++)
{
var i = t[a],
u = l[26];
do u = (u << parseInt(R + T, g[35])) + r[e++];
while (--i > w[18]);
this[a] = u >>> w[18]
}
},
S
}(),
mr; !
function (o) {
var i, u, c;
i = u = c = n;
var v, s, f;
v = s = f = e;
var l, d, p;
l = d = p = a;
var h, w, I;
h = w = I = r;
var _, y, E;
_ = y = E = t;
var A = y[34],
C = (nr, U, h[40]),
b = p[25];
function B (r) {
for (var n = y[35], t = f[15], e = r[vr(c[38], I[41], H)], a = []; e > t;)
{
var o = k[r.charAt(t++)] << parseInt(g + A, d[31]) | k[r.charAt(t++)] << parseInt(n + m, h[42]) | k[r.charAt(t++)] << parseInt(I[43], i[35]) | k[r.charAt(t++)];
a.push(o >> parseInt(_[36], h[42]), o >> l[31] & parseInt(u[39], i[40]), o & parseInt(d[30], c[35]))
}
return a
}
function T (r) {
for (var n = (O, R, p[24]), t = I[27], e = r[E[24]]; e > t; t++) n = (n << E[37]) - n + r[t];
return n & parseInt(E[38], p[33])
}
for (var S = s[40], k = {},
x = s[15]; x < parseInt(I[44], l[34]); x++) k[S.charAt(x)] = x;
function L (r) {
var n = B(r),
t = n[u[26]];
if (t != b) return error = yr(V, u[41], s[41], v[42]),
void 0;
var e = n[s[26]],
a = [];
return P(n, +_[39], a, +_[18], e),
T(a) == e ? a : void 0
}
function M (r) {
var n = T(r),
t = [b, n];
return P(r, +l[24], t, +p[25], n),
N(t)
}
function N (r) {
var n, t, e;
n = t = e = f;
var a, o, u;
a = o = u = y;
var c, v, s;
c = v = s = h;
var d, p, g;
d = p = g = l;
var m, w, I;
m = w = I = i;
for (var _ = m[42], E = d[24], A = r[c[20]], b = []; A > E;)
{
var B = r[E++] << parseInt(fr(Z, d[35]), o[39]) | r[E++] << g[31] | r[E++];
b.push(S.charAt(B >> parseInt(m[43], t[43])), S.charAt(B >> parseInt(p[36], o[40]) & parseInt(I[44], I[45])), S.charAt(B >> n[44] & parseInt(_ + C, n[42])), S.charAt(B & parseInt(fr(d[37], c[45], or), a[41])))
}
return b.join(o[19])
}
function P (r, n, t, e, a) {
var o, i, u;
o = i = u = w;
var c, v, s;
c = v = s = E;
for (var f = r[v[24]]; f > n;) t[e++] = r[n++] ^ a & parseInt(u[46], s[42]),
a = ~(a * parseInt(v[43], v[40]))
}
o[E[44]] = N,
o[_[45]] = B,
o[v[45]] = M,
o[y[46]] = L
}(mr || (mr = {}));
var wr; !
function (o) {
var i = a[38],
u = r[47],
c = t[47],
v = vr(n[46], a[39], a[40]),
s = e[46],
f = e[47],
l = a[41],
d = a[42];
function p (o) {
var i = a[43],
u = vr(n[47], e[48], n[48]),
c = {},
v = function (o, c) {
var s, f, l, d;
for (c = c.replace(n[49], n[12]), c = c.substring(e[26], c[e[38]] - e[26]), s = c.split(e[49]), l = a[24]; l < s[yr(v, sr, t[48])]; l++) if (f = s[l].split(n[50]), f && !(f[a[44]] < t[39]))
{
for (d = n[35]; d < f[r[20]]; d++) f[n[11]] = f[n[11]] + r[48] + f[d];
f[n[26]] = new a[45](r[49]).test(f[n[26]]) ? f[e[15]].substring(r[19], f[e[15]][a[44]] - n[11]) : f[n[26]],
f[n[11]] = new r[50](i + u + w).test(f[n[11]]) ? f[e[26]].substring(t[26], f[r[19]][n[37]] - t[26]) : f[a[18]],
o[f[r[27]]] = f[n[11]]
}
return o
};
return new a[45](I + _).test(o) && (c = v(c, o)),
c
}
function h (n) {
for (var t = [], e = a[24]; e < n[r[20]]; e++) t.push(n.charCodeAt(e));
return t
}
function g (o) {
var u = a[46];
if (typeof o === vr(O, a[47], or) && o[a[48]]) try
{
var c = parseInt(o[a[48]]);
switch (c)
{
case parseInt(i + u, t[42]): break;
case parseInt(yr(t[49], r[51], e[50]), e[43]): top[t[50]][n[51]] = o[e[51]];
break;
case parseInt(yr(a[25], j, e[52]), n[52]): top[n[53]][t[51]] = o[t[52]]
}
} catch (v) { }
}
function m (r, n, t) {
}
function L () {
var e, a, o;
e = a = o = r;
var i, u, c;
i = u = c = n;
var v, s, f;
v = s = f = t;
var l = f[53],
d = c[54],
p = new e[52];
return typeof TOKEN_SERVER_TIME == y + l + d ? s[18] : (time = parseInt(TOKEN_SERVER_TIME), time)
}
function M () {
var o = new t[54];
try
{
return time = n[2].now(),
time / parseInt(fr(a[50], a[51], r[53]), t[40]) >>> e[15]
} catch (i)
{
return time = o.getTime(),
time / parseInt(e[53], a[25]) >>> r[27]
}
}
function N (r) {
for (var a = t[18], o = r[t[24]] - n[11]; o >= e[15]; o--) a = a << e[26] | +r[o];
return a
}
function P (a) {
var o = new r[50](n[55]);
if (K(a)) return a;
var i = o.test(a) ? -e[54] : -t[39],
u = a.split(r[54]);
return u.slice(i).join(fr(n[56], t[55], E))
}
function j (t) {
for (var o = n[26], i = e[15], u = t[vr(r[55], a[52], D)]; u > i; i++) o = (o << r[56]) - o + t.charCodeAt(i),
o >>>= n[26];
return o
}
function W (n, o) {
var i = new a[45](t[56], yr(r[57], $, t[57], r[58])),
u = new a[45](t[58]);
if (n)
{
var c = n.match(i);
if (c)
{
var v = c[e[26]];
return o && u.test(v) && (v = v.split(t[59]).pop().split(r[48])[e[15]]),
v
}
}
}
function $ (o) {
var i = n[57],
u = vr(e[55], e[56]),
f = e[4];
if (!(o > t[60]))
{
o = o || a[24];
var l = parseInt(E + c + A, r[42]),
d = n[14].createElement(e[57]);
d[r[59]] = n[58] + parseInt((new a[53]).getTime() / l) + r[60],
d[r[61]] = function () {
var n = a[46];
cr = r[19],
setTimeout(function () {
$(++o)
},
o * parseInt(C + n, a[33]))
},
d[t[61]] = d[hr(a[54], a[55], t[62])] = function () {
var a = n[59];
this[i + v + u + b] && this[e[58]] !== n[60] && this[s + B + a + f] !== e[59] && this[t[63]] !== n[61] || (cr = e[15], d[hr(N, r[62], n[62], e[25])] = d[t[64]] = r[63])
},
e[60][e[61]].appendChild(d)
}
}
function F () {
var r = a[56];
return Math.random() * parseInt(R + T + f + r, t[42]) >>> n[26]
}
function X (r) {
var e = new n[31](fr(t[65], t[66], a[57]), yr(c, n[63], t[57]));
if (r)
{
var o = r.match(e);
return o
}
}
o[S + k] = p,
o[r[64]] = $,
o[t[67]] = g,
o[t[68]] = h,
o[t[69]] = j,
o[t[70]] = F,
o[r[65]] = K,
o[x + l] = P,
o[t[71]] = W,
o[t[72]] = X,
o[hr(r[66], t[73], r[67], C)] = N,
o[t[74]] = M,
o[d + O] = L;
function K (n) {
return new r[50](t[75]).test(n)
}
o[r[68]] = m
}(wr || (wr = {}));
var Ir; !
function (o) {
var i = t[76],
u = t[77],
c = n[65],
v = t[78],
s = a[24],
f = n[26],
l = t[18],
d = t[18],
p = e[15],
h = a[24],
g = r[69],
m = '';
wr.eventBind(e[60], n[67], E),
wr.eventBind(r[71], t[79], E),
wr.eventBind(t[20], hr(e[64], A, a[59]), b),
wr.eventBind(e[60], r[72], y);
function w () {
return f
}
function I (r) {
f++
}
function _ () {
return {
x: p,
y: h,
trusted: g
}
}
function y (r) {
d++
}
function E (r) {
s++
}
function C () {
return l
}
function b (r) {
var o, i, u;
o = i = u = n;
var c, s, f;
c = s = f = t;
var d, m, w;
d = m = w = e;
var I, _, y;
I = _ = y = a;
var E = I[60],
A = d[65];
l++ ,
g = void 0 == r[E + A + v] || r[yr(f[80], s[81], i[68])],
p = r[s[82]],
h = r[c[83]]
}
function B () {
return d
}
function R () {
return s
}
o[r[73]] = R,
o[a[61]] = w,
o[fr(a[62], n[69])] = C,
o[n[70]] = B,
o[r[74]] = _
}(Ir || (Ir = {}));
var _r; !
function (u) {
var v = fr(n[71], t[84]),
s = r[75],
f = yr(dr, n[72], e[66], $),
l = r[76],
d = e[67],
p = r[77],
h = hr(dr, r[78], a[63], n[73]),
g = r[79],
m = n[74];
BROWSER_LIST = {
};
function w () {
var t, e, a;
t = e = a = r;
var o, i, u;
o = i = u = n;
return wr.booleanToDecimal(c)
}
function I (t) {
for (var o = n[26]; o < y[e[38]]; o++)
{
var i = y[o][r[94]];
if (t.test(i)) return !a[24]
}
return !a[18]
}
function E (t) {
}
function A () {
return a[73]
}
function B () {
return n[20]
}
function T () {
return I(new t[93](r[96]))
}
function S () {
return I(new a[45](t[98], r[97]))
}
function k () {
for (var r in BROWSER_LIST) if (BROWSER_LIST.hasOwnProperty(r))
{
var n = BROWSER_LIST[r];
if (n()) return + r.substr(a[18])
}
return e[15]
}
function x () {
var n, a, o;
n = a = o = r;
var i, u, c;
i = u = c = t;
var v, s, f;
v = s = f = e;
var l = s[75],
d = s[76];
return I(new u[93](o[98], v[71])) || E(l + F + d + X)
}
function O () {
}
function L () {
var r, n, t;
r = n = t = a;
var o, i, u;
o = i = u = e;
var c = l;
return c = p
}
function M () {
var r, n, a;
r = n = a = t;
var o, i, u;
o = i = u = e;
var c;
try
{
c = i[60].createElement(a[99]).getContext(i[78])
} catch (v) { }
return !!c
}
function J () {
var t, e, o;
t = e = o = n;
var i, u, c;
i = u = c = a;
var v, s, f;
return v = s = f = r,
-parseInt(s[100], c[31]) === (new e[2]).getTimezoneOffset()
}
function Q () {
try
{
} catch (e)
{
return r[101]
}
}
function Z () {
var n, a, o;
n = a = o = e;
var i, u, c;
i = u = c = r;
var v, s, f;
return v = s = f = t,
plugin_num = s[18],
plugin_num
}
var z = [R, x, S, T, L, Q, b, V, O, J, M, q, Y, B, tr, A];
var nr = [new e[13](n[85]), new n[31](e[82]), new r[50](e[83]), new r[50](t[102]), new n[31](e[84]), new a[45](a[78]), new a[45](e[85]), new e[13](t[103]), new a[45](r[103]), new t[93](r[104]), new a[45](r[105])];
function tr () {
return e[86]
}
u[e[87]] = rr,
u[a[79]] = k,
u[yr(c, e[88], r[106])] = Z,
u[K + U + m] = w
}(_r || (_r = {}));
function yr () {
var o = arguments[a[25]];
if (!o) return t[19];
for (var i = a[19], u = e[14], c = r[27]; c < o.length; c++)
{
var v = o.charCodeAt(c),
s = v ^ u;
u = u * c % a[80] + e[89],
i += n[86].fromCharCode(s)
}
return i
}
var Er; !
function (o) {
var i = a[81],
u = t[35],
c = r[107],
v = vr(S, a[56]),
f = r[27],
l = r[19],
d = a[25],
p = n[87],
h = parseInt(e[90], r[108]),
g = a[82],
m = parseInt(vr(s, t[104]), t[39]),
w = r[109],
I = t[40],
_ = parseInt(i + V, n[45]),
y = parseInt(u + c, n[52]),
E = parseInt(t[105], r[42]),
A = e[91],
C = parseInt(Y + v, r[42]),
b = parseInt(e[92], e[93]),
B = t[106],
R = parseInt(vr(e[94], e[95]), t[41]),
T = parseInt(a[83], e[93]),
k;
function x () {
var r = M();
return r
}
function O () {
var r = t[26],
a = n[35],
o = e[54],
i = n[88];
k = new gr([i, i, i, i, r, r, r, o, a, a, a, a, a, a, a, i, a, r]),
k[l] = wr.serverTimeNow(),
L(),
k[B] = cr,
k[T] = ur,
k[R] = e[15],
k[C] = _r.getBrowserFeature(),
k[g] = _r.getBrowserIndex(),
k[m] = _r.getPluginNum()
}
function L () {
var a = dr.getCookie(tr) || pr.get(ar);
if (a && a[r[20]] == parseInt(e[96], n[52]))
{
var o = mr.decode(a);
if (o && (k.decodeBuffer(o), k[f] != t[18])) return
}
k[f] = wr.random()
}
o[a[84]] = O;
function M () {
k[R]++ ,
k[l] = wr.serverTimeNow(),
k[d] = wr.timeNow(),
k[B] = cr,
k[w] = Ir.getMouseMove(),
k[I] = Ir.getMouseClick(),
k[_] = Ir.getMouseWhell(),
k[y] = Ir.getKeyDown(),
k[E] = Ir.getClickPos().x,
k[A] = Ir.getClickPos().y;
var r = k.toBuffer();
return mr.encode(r)
}
o[yr(r[3], n[89], e[97])] = x
}(Er || (Er = {}));
var Ar; !
function (o) {
var i = n[90],
u = a[85],
v = r[110],
s = a[86],
f = t[107],
p,
h,
m,
w,
I,
_;
function E (r) {
return N(r) && dr[a[87]]
}
function A (o) {
var i = wr.getOriginFromUrl(o);
return i ? !new n[31](yr(r[42], c, t[110]) + w).test(i[r[108]]) || !new e[13](I).test(i[a[18]]) : t[111]
}
function C (e) {
var o = (_r, g, Er.update());
return e + (new r[50](vr(a[88], a[89])).test(e) ? n[91] : vr(P, a[90], t[112])) + er + t[23] + r[111](o)
}
function b (o, i, u) {
if (r[112] in i) return i.apply(o, u);
switch (u[n[37]])
{
case n[26]:
return i();
case a[18]:
return i(u[n[26]]);
case r[108]:
return i(u[e[15]], u[r[19]]);
default:
return i(u[n[26]], u[r[108]], u[t[17]])
}
}
function B () {
var r = Er.update();
return r
}
function k (r, e, o) {
if (!r) return n[20];
var i = r[e];
if (!i) return t[111];
var u = o(i);
return d || (u[a[97]] = i + t[19]),
u[n[97]] = i,
r[e] = u,
a[21]
}
function M (o) {
var i, u, c;
i = u = c = n;
var v, s, l;
v = s = l = r;
var d, p, h;
d = p = h = e;
var g, m, w;
g = m = w = a;
var I, _, y;
I = _ = y = t;
var R = hr(I[121], w[106], d[109]),
T;
k(o, _[122],
function (r) {
var n = w[107];
return function () {
var t, e, a;
t = e = a = _;
var o, i, u;
o = i = u = l;
var c, v, s;
c = v = s = w;
var f = s[108];
try
{
A(arguments[s[18]]) && !E(arguments[o[19]]) ? arguments[a[26]] = C(arguments[s[18]]) : T = B(),
r.apply(this, arguments),
A(arguments[i[19]]) || this.setRequestHeader(ar, T)
} catch (d)
{
return n + f
}
}
}),
k(o, g[109],
function (r) {
var n = b;
n = M;
var t = vr(_[123], u[107]);
return function () {
var n = fr(f, c[108], I[124]),
e = s[122];
try
{
if (parseInt(this.status) === parseInt(h[110], v[123]))
{
for (var a = r.apply(this, arguments), o = new p[13](i[109], n + R), u, l, d = {}; u = o.exec(a);) d[u[m[18]].toLowerCase()] = u[v[108]];
wr.analysisRst(wr.parse(d[ir.toLowerCase()]))
}
} catch (g)
{
return e + t
}
return r.apply(this, arguments)
}
})
}
function N (r) {
var n = wr.getHostFromUrl(r, e[28]);
return n ? _.test(n) : e[28]
}
function j () {
var cookie_v;
cookie_v = B()
return cookie_v
}
o[n[111]] = j
}(Ar || (Ar = {}));
var Cr;
var cookie = (function (a) {
function _ () {
var cookie_v;
Er.Init();
cookie_v = Ar.Init();
return cookie_v
}
return function y () {
try
{
return _()
} catch (r)
{
return r
}
}
})()
return cookie()
}
function v () {
var v;
v = v_cookie(
["t", 34, '"$', 36, "\fb", 55, "ure", "lJ#K", "Flash", "getBro", "1", "analys", "CHAMELEON_CALLBACK", 30, "\u256f\u0930\u097b\u09ff\u09a4\u0934\u099d\u09c1\u099d\u09d9\u09a7\u09c3\u0995\u09f0\u09d3\u0a62\u0a6f\u09bc\u09ad\u0934", "F,sp-", String, "; expires=", "", 1, "length", "; ", '', '', "addBehavior", ";^l", ">*]+", 0, "div", "&~!", "", "Init", "('&%$#\"![", ">NJ", "\u254e\u096d\u095f", "W$R", "sdelif_esab", "Or)E", "decodeBuffer", 84, "f", "htgnel", 8, "110", "40", "\u2504\u2562", "255", "o", ":", '^".*"$', RegExp, 40, Date, "e9", ".", 19, 5, "t8JOi", "}B", "src", ".js", "onerror", "*q:", null, "getServerTime", "isIPAddr", "8-", "ZX9Y]V8aWs3VQZ7Y", "eventBind", !0, "wheel", '', "keydown", "getMouseMove", "getClickPos", "vent", "me", "MSG", 41, "th", "safari", "ActiveXObject", "maxHeight", "head", "Google Inc.", "vendor", "sgAppName", "opr", 94, "tugw`pj", "chrome", "2345Explorer", "ome", "TheWorld", "name", "\u2553\u253c\u2572\u251d\u2569\u253d\u254f\u252e\u254d\u2526", "Native Client", "i", "Shockwave", "systemLanguage", "740", !1, "plugins", "^ARM", "^iPod", "^BlackBerry", "\u2550\u0978\u094e\u09c1\u09bc\u0928\u0989\u09d8\u099a\u09f3\u09b7\u09dc", "0", 2, 7, "c", encodeURIComponent, "apply", "headers", "8S:+", "\u2560\u2509\u2567\u2503\u256c\u251b", "\u255e\u2530\u2543\u2526\u2554\u2520\u2562\u2507\u2561\u250e\u257c\u2519", "a", 14, ":dB2", "href", "click", "err", 16, "hostname", "`60w", "\fbf", "&X "],
[";", "Element", Date, "par", "i", "DOMMous", 21, "xmT", "wserFe", "h", !0, 1, "", Boolean, '', "; domain=", "n 1970 00:", "cookie", "checkcookie", "allow", !1, "delCookie", 2333, "torage", ")*+,/\\\\:;", '', 0, '', "eliflmth", '', "ducument", RegExp, "W", "qsU", 61, 2, "sdelif_esab", "length", "I", "ff", 16, 45, "3", "10010", "77", 8, "6e%d", "DT{e", "$", / /g, ":", "href", 10, "location", "ned", "\\.com\\.cn$|\\.com\\.hk$", 63, "rea", "https://s.thsi.cn/js/chameleon/time.1", "tat", "loaded", "interactive", "WY:ZYS", "E?`a", "addEventListener", "eScroll", "onmousewheel", "mousemove", "\u255e\u096e\u096e\u09e3\u09a5\u092e\u099a\u09d4\u0990", "\u2550\u2535\u2541\u250c\u2563\u2516\u2565\u2500\u2543\u252f\u2546\u2525\u254e", "getKeyDown", "H69<J", "v~g-", "", "ature", "callPhantom", "ActiveXObject", "Uint8Array", "WeakMap", "JX%<", "chrome", "@L:!", "20", "language", "localStorage", "^Win32", String, 3, 4, "=XAE", "hea", "&", "/", "\\R$", '^R"VP', "s", "include", "_raw", "x.", "isRst", "SCRIPT", "ta", "base", "$?", "^_self$", "#", "unload", "ro", "\u2550", "^(.*?):[ \\t]*([^\\r\\n]*)\\r?$", "g", "Init", "t6?x}", "\u2574\u0955\u097b\u09dc\u0995\u0911\u09ab\u09fe\u09ba\u09e2\u098e\u09fe\u09f9\u09f9\u09f3\u0a55", "=d' "],
["<=>?@[\\]^", "e", "HE9", "tot", "\u2503", "0", "dyS", "se", "getRoot", "NR", "nd", 60, "ng", "s", "get", "mit", 13, 3, 0, "", '', "\u255f\u253a\u255b\u253f", "getCookie", "=", "length", "V587", 1, String, !0, "___", "\u2553\u2536\u255a", "uBot", "base_fileds", 32, "2", "1", "20", 5, "255", 2, 8, 16, 10, "203", "base64Encode", "base64Decode", "decode", "760", "\u255b\u0978\u0954\u09f6\u09a4\u0935", 70, "location", "href", "redirect_url", "efi", Date, "\u2519", "^\\s*(?:https?:)?\\/{2,}([^\\/\\?\\#\\\\]+)", "\u255e", "[@:]", "@", 7, "onload", 'WY$PYS/FLV"P[_7[_R', "readyState", "onreadystatechange", '"^w', "\u2569\u2535\u2546\u256c\u2544\u257b\u2541\u2569\u2501\u2575\u2501\u2571\u2502\u253d\u2507\u252e\u2507\u2538\u2564\u254b\u2530\u2502\u252e\u2553\u257b\u2520\u257e\u2522\u250d\u2551\u256e\u2532\u2511\u254d\u2511\u254c\u2567\u254e", "analysisRst", "strToBytes", "strhash", "random", "getHostFromUrl", "getOriginFromUrl", 83, "timeNow", "^(\\d+\\.)+\\d+$", "d", "v", "ted", "touchmove", 85, "F(K9i", "clientX", "clientY", "\u257a\u2515\u256f\u253c", "postMessage", '', "ActiveXObject", "Apple Computer, Inc.", "Q", "chr", "\u2558\u2535\u2550", "BIDUBrowser", RegExp, "QQBrowser", "ro", "aef", "msDoNotTrack", "PDF|Acrobat", "canvas", "yE", "\u255b\u253a\u2554\u2533\u2546\u2527\u2540\u2525\u2556", "^Android", "^Linux [ix]\\d+", "011", "13", 15, "sub", "addEventListener", "jsonp_ignore", "\u2569", !1, 'L"', "Sj", "T{_,", "q*", "i", "tagName", "et", "{'K", "Pp<", "#x'", "open", "rS", "KN3", "#", "protocol", "\\.", "DEDAOL_NOELEMAHC"],
[83, "ffer", "\u2505", "20", "e", "ngsE", Error, "est", "\u2552\u095b\u0956\u09f0\u09a3\u0935\u09c0\u09e2", "1", "sr", "hexin-v", "", RegExp, 9527, 0, "**l>", "head", "Thu, 01 Ja", "00:00 GMT", "allow", "=", "; path=", "cookie", "Init", 33, 1, "setCookie", !0, "localS", "`{|}~]", "g", '', "frames", "___$&", 56, " ", "\b", "length", "10", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_", "\u2552\u096f\u0948\u09fe\u09a2", 16, 2, 6, "encode", "rea", "729", "*.", ",", "\u2506\u092c\u090b\u09a0\u09e1\u096d\u09df\u0981\u09c4\u098c", "redirect_url", "\u2506\u092d\u090a\u09a3", "1111101000", 3, 47, "tat", "script", "readyState", "complete", '', "body", "onwheel", "mousewheel", 37, "rus", "\u2554\u0975", "chr", "ActiveXObject", "WeakMap", "aT1Kg", "i", 24, "\u2554\u253c\u254e\u2521\u254c\u2529", "\u2547\u0971\u094f\u09f6\u09b9\u0933\u099d", "Shockwav", "hockwave", "$cdc_asdjflasutopfhvcZLmcfl_", "webgl2", "2>n|", "plugins", "platform", "^Win64", "^Linux armv|Android", "^iPhone", "^MacIntel", !1, "getPlatform", "6Y,", 2333, "100", 12, "14", 10, 36, "01", "60", "\u2542\u096d\u095e\u09f0\u09a4\u0938", "j", 17, "Request", "prototype", "`z}lc", "error", "s", "r", "target", "\u255e", "A", "U", "193", "host", "$"],
["se", "g@g?", Array, "*Y", Number, "^{.", "*}$", "und", "429", "496", "imeNow", "etti", "rg", "v", "hexin-v", Error, "L_%\\T8", ".baidu.", 1, "", Function, !0, " ", '', 0, 2, "#default#userData", "ydob", "^d", 89, "11111111", 8, "epytotorp", 10, 16, "\u2506\u2536\u2506\u2536\u2506", "14", 13, "10", "Syd", 44, "Domain", "serverT", '^"', "length", RegExp, "00", "tcejbo", "status_code", "n", 66, "\u2506\u2531\u2504\u2534", "htgnel", Date, "L%", 67, "5", "?)'", '', "[[?VS", "isT", "getMouseWhell", "}}", "TR", "ActiveXObject", "WE", "python", "Maxthon", 97, "chrome", "Ryp", "UBrowser", 54, !1, "ontouchstart", "\u254d\u0975\u0917\u09f2\u09be", "iso-8859-1", "defaultCharset", "^iPad", "getBrowserIndex", 256, "1", 5, "17", "Init", "XMLHttp", "tar", "allow", "@*", "?\\", "?", "\u2571\u2503\u256a\u2546\u2566\u2556\u2567\u2547\u2501\u2564\u2506\u2526\u2514\u2524\u2511\u2521\u2501\u2531\u2501\u253b\u250b\u253b\u2501\u2531\u2501\u2521\u2566\u252b\u257f", "den", "tia", 94, "ls", "\u2554\u2526\u2543", "_str", 37, "append", "Child", "\u255f", "\u2569\u0975\u094e\u09e5\u09a0\u092e\u09d1\u09ed\u09ce", "srcElement", "parentNode", "\u2543\u2522\u2545\u250b\u256a\u2507\u2562", "}*", "err", "or", "getAllResponseHeaders", "\\.?", "\\."]
);
return v
}