akshare-one 0.3.2__py3-none-any.whl → 0.3.3__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- akshare_one/__init__.py +198 -15
- akshare_one/modules/cache.py +1 -0
- akshare_one/modules/financial/base.py +5 -0
- akshare_one/modules/financial/eastmoney.py +184 -0
- akshare_one/modules/financial/factory.py +2 -0
- akshare_one/modules/financial/sina.py +119 -94
- akshare_one/modules/info/base.py +25 -0
- akshare_one/modules/info/eastmoney.py +52 -0
- akshare_one/modules/info/factory.py +44 -0
- {akshare_one-0.3.2.dist-info → akshare_one-0.3.3.dist-info}/METADATA +3 -3
- {akshare_one-0.3.2.dist-info → akshare_one-0.3.3.dist-info}/RECORD +14 -14
- akshare_one/financial.py +0 -46
- akshare_one/insider.py +0 -33
- akshare_one/news.py +0 -27
- akshare_one/stock.py +0 -78
- {akshare_one-0.3.2.dist-info → akshare_one-0.3.3.dist-info}/WHEEL +0 -0
- {akshare_one-0.3.2.dist-info → akshare_one-0.3.3.dist-info}/licenses/LICENSE +0 -0
- {akshare_one-0.3.2.dist-info → akshare_one-0.3.3.dist-info}/top_level.txt +0 -0
akshare_one/__init__.py
CHANGED
@@ -14,18 +14,201 @@ Example:
|
|
14
14
|
>>> df = get_realtime_data(symbol="600000")
|
15
15
|
"""
|
16
16
|
|
17
|
-
from
|
18
|
-
|
19
|
-
from .
|
20
|
-
from .
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
"
|
29
|
-
|
30
|
-
"
|
31
|
-
|
17
|
+
from typing import Optional, Literal
|
18
|
+
import pandas as pd
|
19
|
+
from .modules.financial.factory import FinancialDataFactory
|
20
|
+
from .modules.historical.factory import HistoricalDataFactory
|
21
|
+
from .modules.realtime.factory import RealtimeDataFactory
|
22
|
+
from .modules.info.factory import InfoDataFactory
|
23
|
+
from .modules.news.factory import NewsDataFactory
|
24
|
+
from .modules.insider.factory import InsiderDataFactory
|
25
|
+
|
26
|
+
|
27
|
+
def get_basic_info(
|
28
|
+
symbol: str, source: Literal["eastmoney"] = "eastmoney"
|
29
|
+
) -> pd.DataFrame:
|
30
|
+
"""获取股票基础信息
|
31
|
+
|
32
|
+
Args:
|
33
|
+
symbol: 股票代码 (e.g. '600000')
|
34
|
+
source: 数据源 ('eastmoney')
|
35
|
+
|
36
|
+
Returns:
|
37
|
+
pd.DataFrame:
|
38
|
+
- price: 最新价
|
39
|
+
- symbol: 股票代码
|
40
|
+
- name: 股票简称
|
41
|
+
- total_shares: 总股本
|
42
|
+
- float_shares: 流通股
|
43
|
+
- total_market_cap: 总市值
|
44
|
+
- float_market_cap: 流通市值
|
45
|
+
- industry: 行业
|
46
|
+
- listing_date: 上市时间
|
47
|
+
"""
|
48
|
+
provider = InfoDataFactory.get_provider(source, symbol=symbol)
|
49
|
+
return provider.get_basic_info()
|
50
|
+
|
51
|
+
|
52
|
+
def get_hist_data(
|
53
|
+
symbol: str,
|
54
|
+
interval: Literal["minute", "hour", "day", "week", "month", "year"] = "day",
|
55
|
+
interval_multiplier: int = 1,
|
56
|
+
start_date: str = "1970-01-01",
|
57
|
+
end_date: str = "2030-12-31",
|
58
|
+
adjust: Literal["none", "qfq", "hfq"] = "none",
|
59
|
+
source: Literal["eastmoney", "eastmoney_direct", "sina"] = "eastmoney",
|
60
|
+
) -> pd.DataFrame:
|
61
|
+
"""Get historical market data
|
62
|
+
|
63
|
+
Args:
|
64
|
+
symbol: 股票代码 (e.g. '600000')
|
65
|
+
interval: 时间间隔 ('minute','hour','day','week','month','year')
|
66
|
+
interval_multiplier: 时间间隔倍数 (e.g. 5 for 5 minutes)
|
67
|
+
start_date: 开始日期 (YYYY-MM-DD)
|
68
|
+
end_date: 结束日期 (YYYY-MM-DD)
|
69
|
+
adjust: 复权类型 ('none','qfq','hfq')
|
70
|
+
source: 数据源 ('eastmoney', 'eastmoney_direct', 'sina') (default: 'eastmoney')
|
71
|
+
|
72
|
+
Returns:
|
73
|
+
pd.DataFrame:
|
74
|
+
- timestamp: 时间戳(UTC时区)
|
75
|
+
- open: 开盘价
|
76
|
+
- high: 最高价
|
77
|
+
- low: 最低价
|
78
|
+
- close: 收盘价
|
79
|
+
- volume: 成交量
|
80
|
+
"""
|
81
|
+
kwargs = {
|
82
|
+
"symbol": symbol,
|
83
|
+
"interval": interval,
|
84
|
+
"interval_multiplier": interval_multiplier,
|
85
|
+
"start_date": start_date,
|
86
|
+
"end_date": end_date,
|
87
|
+
"adjust": adjust,
|
88
|
+
}
|
89
|
+
provider = HistoricalDataFactory.get_provider(source, **kwargs)
|
90
|
+
return provider.get_hist_data()
|
91
|
+
|
92
|
+
|
93
|
+
def get_realtime_data(
|
94
|
+
symbol: Optional[str] = None,
|
95
|
+
source: Literal["eastmoney", "eastmoney_direct", "xueqiu"] = "xueqiu",
|
96
|
+
) -> pd.DataFrame:
|
97
|
+
"""Get real-time market quotes
|
98
|
+
|
99
|
+
Args:
|
100
|
+
symbol: 股票代码 (如 "600000")
|
101
|
+
source: 数据源 ('eastmoney', 'eastmoney_direct', 'xueqiu')
|
102
|
+
|
103
|
+
Returns:
|
104
|
+
pd.DataFrame:
|
105
|
+
- symbol: 股票代码
|
106
|
+
- price: 最新价
|
107
|
+
- change: 涨跌额
|
108
|
+
- pct_change: 涨跌幅(%)
|
109
|
+
- timestamp: 时间戳
|
110
|
+
- volume: 成交量(手)
|
111
|
+
- amount: 成交额(元)
|
112
|
+
- open: 今开
|
113
|
+
- high: 最高
|
114
|
+
- low: 最低
|
115
|
+
- prev_close: 昨收
|
116
|
+
"""
|
117
|
+
provider = RealtimeDataFactory.get_provider(source, symbol=symbol)
|
118
|
+
return provider.get_current_data()
|
119
|
+
|
120
|
+
|
121
|
+
def get_news_data(
|
122
|
+
symbol: str, source: Literal["eastmoney"] = "eastmoney"
|
123
|
+
) -> pd.DataFrame:
|
124
|
+
"""获取个股新闻数据
|
125
|
+
|
126
|
+
Args:
|
127
|
+
symbol: 股票代码 (如 "300059")
|
128
|
+
source: 数据源 ('eastmoney')
|
129
|
+
|
130
|
+
Returns:
|
131
|
+
pd.DataFrame:
|
132
|
+
- keyword: 关键词
|
133
|
+
- title: 新闻标题
|
134
|
+
- content: 新闻内容
|
135
|
+
- publish_time: 发布时间
|
136
|
+
- source: 文章来源
|
137
|
+
- url: 新闻链接
|
138
|
+
"""
|
139
|
+
provider = NewsDataFactory.get_provider(source, symbol=symbol)
|
140
|
+
return provider.get_news_data()
|
141
|
+
|
142
|
+
|
143
|
+
def get_balance_sheet(symbol: str, source: Literal["sina"] = "sina") -> pd.DataFrame:
|
144
|
+
"""获取资产负债表数据
|
145
|
+
|
146
|
+
Args:
|
147
|
+
symbol: 股票代码 (如 "600600")
|
148
|
+
source: 数据源 ("sina")
|
149
|
+
|
150
|
+
Returns:
|
151
|
+
pd.DataFrame: 资产负债表数据
|
152
|
+
"""
|
153
|
+
provider = FinancialDataFactory.get_provider(source, symbol=symbol)
|
154
|
+
return provider.get_balance_sheet()
|
155
|
+
|
156
|
+
|
157
|
+
def get_income_statement(symbol: str, source: Literal["sina"] = "sina") -> pd.DataFrame:
|
158
|
+
"""获取利润表数据
|
159
|
+
|
160
|
+
Args:
|
161
|
+
symbol: 股票代码 (如 "600600")
|
162
|
+
source: 数据源 ("sina")
|
163
|
+
|
164
|
+
Returns:
|
165
|
+
pd.DataFrame: 利润表数据
|
166
|
+
"""
|
167
|
+
provider = FinancialDataFactory.get_provider(source, symbol=symbol)
|
168
|
+
return provider.get_income_statement()
|
169
|
+
|
170
|
+
|
171
|
+
def get_cash_flow(symbol: str, source: Literal["sina"] = "sina") -> pd.DataFrame:
|
172
|
+
"""获取现金流量表数据
|
173
|
+
|
174
|
+
Args:
|
175
|
+
symbol: 股票代码 (如 "600600")
|
176
|
+
source: 数据源 ("sina")
|
177
|
+
|
178
|
+
Returns:
|
179
|
+
pd.DataFrame: 现金流量表数据
|
180
|
+
"""
|
181
|
+
provider = FinancialDataFactory.get_provider(source, symbol=symbol)
|
182
|
+
return provider.get_cash_flow()
|
183
|
+
|
184
|
+
|
185
|
+
def get_financial_metrics(
|
186
|
+
symbol: str, source: Literal["eastmoney"] = "eastmoney"
|
187
|
+
) -> pd.DataFrame:
|
188
|
+
"""获取三大财务报表关键指标
|
189
|
+
|
190
|
+
Args:
|
191
|
+
symbol: 股票代码 (如 "600600")
|
192
|
+
source: 数据源 ('eastmoney')
|
193
|
+
|
194
|
+
Returns:
|
195
|
+
pd.DataFrame: 财务关键指标数据
|
196
|
+
"""
|
197
|
+
provider = FinancialDataFactory.get_provider(source, symbol=symbol)
|
198
|
+
return provider.get_financial_metrics()
|
199
|
+
|
200
|
+
|
201
|
+
def get_inner_trade_data(
|
202
|
+
symbol: str, source: Literal["xueqiu"] = "xueqiu"
|
203
|
+
) -> pd.DataFrame:
|
204
|
+
"""获取雪球内部交易数据
|
205
|
+
|
206
|
+
Args:
|
207
|
+
symbol: 股票代码,如"600000"
|
208
|
+
source: 数据源 (目前支持 "xueqiu")
|
209
|
+
|
210
|
+
Returns:
|
211
|
+
pd.DataFrame: 内部交易数据
|
212
|
+
"""
|
213
|
+
provider = InsiderDataFactory.get_provider(source, symbol=symbol)
|
214
|
+
return provider.get_inner_trade_data()
|
akshare_one/modules/cache.py
CHANGED
@@ -0,0 +1,184 @@
|
|
1
|
+
from cachetools import cached
|
2
|
+
import pandas as pd
|
3
|
+
import requests
|
4
|
+
|
5
|
+
from akshare_one.modules.cache import CACHE_CONFIG
|
6
|
+
from .base import FinancialDataProvider
|
7
|
+
|
8
|
+
|
9
|
+
class EastMoneyFinancialReport(FinancialDataProvider):
|
10
|
+
_balance_sheet_rename_map = {
|
11
|
+
"REPORT_DATE": "report_date",
|
12
|
+
"TOTAL_ASSETS": "total_assets",
|
13
|
+
"FIXED_ASSET": "fixed_assets_net",
|
14
|
+
"MONETARYFUNDS": "cash_and_equivalents",
|
15
|
+
"ACCOUNTS_RECE": "accounts_receivable",
|
16
|
+
"INVENTORY": "inventory",
|
17
|
+
"TOTAL_LIABILITIES": "total_liabilities",
|
18
|
+
"ACCOUNTS_PAYABLE": "trade_and_non_trade_payables",
|
19
|
+
"ADVANCE_RECEIVABLES": "deferred_revenue",
|
20
|
+
"TOTAL_EQUITY": "shareholders_equity",
|
21
|
+
}
|
22
|
+
|
23
|
+
_income_statement_rename_map = {
|
24
|
+
"REPORT_DATE": "report_date",
|
25
|
+
"TOTAL_OPERATE_INCOME": "revenue",
|
26
|
+
"TOTAL_OPERATE_COST": "total_operating_costs",
|
27
|
+
"OPERATE_PROFIT": "operating_profit",
|
28
|
+
"PARENT_NETPROFIT": "net_income_common_stock",
|
29
|
+
}
|
30
|
+
|
31
|
+
_cash_flow_rename_map = {
|
32
|
+
"REPORT_DATE": "report_date",
|
33
|
+
"NETCASH_OPERATE": "net_cash_flow_from_operations",
|
34
|
+
"NETCASH_INVEST": "net_cash_flow_from_investing",
|
35
|
+
"NETCASH_FINANCE": "net_cash_flow_from_financing",
|
36
|
+
"CCE_ADD": "change_in_cash_and_equivalents",
|
37
|
+
}
|
38
|
+
|
39
|
+
def __init__(self, symbol):
|
40
|
+
super().__init__(symbol)
|
41
|
+
|
42
|
+
def get_income_statement(self):
|
43
|
+
pass
|
44
|
+
|
45
|
+
def get_balance_sheet(self):
|
46
|
+
pass
|
47
|
+
|
48
|
+
def get_cash_flow(self):
|
49
|
+
pass
|
50
|
+
|
51
|
+
@cached(
|
52
|
+
CACHE_CONFIG["financial_cache"],
|
53
|
+
key=lambda self, symbol=None: f"financial_metrics_{self.symbol}",
|
54
|
+
)
|
55
|
+
def get_financial_metrics(self) -> pd.DataFrame:
|
56
|
+
"""获取三大财务报表关键指标"""
|
57
|
+
balance_sheet = self._fetch_balance_sheet()
|
58
|
+
income_statement = self._fetch_income_statement()
|
59
|
+
cash_flow = self._fetch_cash_flow()
|
60
|
+
|
61
|
+
if balance_sheet.empty and income_statement.empty and cash_flow.empty:
|
62
|
+
return pd.DataFrame()
|
63
|
+
|
64
|
+
merged = pd.merge(
|
65
|
+
balance_sheet, income_statement, on="report_date", how="outer"
|
66
|
+
)
|
67
|
+
merged = pd.merge(merged, cash_flow, on="report_date", how="outer")
|
68
|
+
|
69
|
+
# Convert report_date to datetime and format as YYYY-MM-DD
|
70
|
+
merged["report_date"] = pd.to_datetime(merged["report_date"]).dt.strftime(
|
71
|
+
"%Y-%m-%d"
|
72
|
+
)
|
73
|
+
|
74
|
+
# Sort by report_date in descending order (most recent first)
|
75
|
+
merged = merged.sort_values("report_date", ascending=False).reset_index(
|
76
|
+
drop=True
|
77
|
+
)
|
78
|
+
|
79
|
+
return merged
|
80
|
+
|
81
|
+
def _fetch_balance_sheet(self) -> pd.DataFrame:
|
82
|
+
"""
|
83
|
+
Get stock balance sheet data from East Money API
|
84
|
+
"""
|
85
|
+
try:
|
86
|
+
# API endpoint and parameters
|
87
|
+
api_url = "https://datacenter-web.eastmoney.com/api/data/v1/get"
|
88
|
+
params = {
|
89
|
+
"reportName": "RPT_DMSK_FN_BALANCE",
|
90
|
+
"filter": f'(SECURITY_CODE="{self.symbol}")',
|
91
|
+
"pageNumber": "1",
|
92
|
+
"pageSize": "1000",
|
93
|
+
"sortColumns": "REPORT_DATE",
|
94
|
+
"sortTypes": "-1",
|
95
|
+
"columns": ",".join(self._balance_sheet_rename_map.keys()),
|
96
|
+
}
|
97
|
+
|
98
|
+
# Fetch data from API
|
99
|
+
response = requests.get(api_url, params=params)
|
100
|
+
response.raise_for_status()
|
101
|
+
data = response.json()
|
102
|
+
|
103
|
+
# Extract the actual data
|
104
|
+
if data.get("result") and data["result"].get("data"):
|
105
|
+
df = pd.DataFrame(data["result"]["data"])
|
106
|
+
df.rename(columns=self._balance_sheet_rename_map, inplace=True)
|
107
|
+
return df
|
108
|
+
else:
|
109
|
+
print("No balance sheet data found in API response")
|
110
|
+
return pd.DataFrame()
|
111
|
+
|
112
|
+
except Exception as e:
|
113
|
+
print(f"Error occurred: {str(e)}")
|
114
|
+
return pd.DataFrame()
|
115
|
+
|
116
|
+
def _fetch_income_statement(self) -> pd.DataFrame:
|
117
|
+
"""
|
118
|
+
Get stock income statement data from East Money API
|
119
|
+
"""
|
120
|
+
try:
|
121
|
+
# API endpoint and parameters
|
122
|
+
api_url = "https://datacenter-web.eastmoney.com/api/data/v1/get"
|
123
|
+
params = {
|
124
|
+
"reportName": "RPT_DMSK_FN_INCOME",
|
125
|
+
"filter": f'(SECURITY_CODE="{self.symbol}")',
|
126
|
+
"pageNumber": "1",
|
127
|
+
"pageSize": "1000",
|
128
|
+
"sortColumns": "REPORT_DATE",
|
129
|
+
"sortTypes": "-1",
|
130
|
+
"columns": ",".join(self._income_statement_rename_map.keys()),
|
131
|
+
}
|
132
|
+
|
133
|
+
# Fetch data from API
|
134
|
+
response = requests.get(api_url, params=params)
|
135
|
+
response.raise_for_status()
|
136
|
+
data = response.json()
|
137
|
+
|
138
|
+
# Extract the actual data
|
139
|
+
if data.get("result") and data["result"].get("data"):
|
140
|
+
df = pd.DataFrame(data["result"]["data"])
|
141
|
+
df.rename(columns=self._income_statement_rename_map, inplace=True)
|
142
|
+
return df
|
143
|
+
else:
|
144
|
+
print("No income statement data found in API response")
|
145
|
+
return pd.DataFrame()
|
146
|
+
|
147
|
+
except Exception as e:
|
148
|
+
print(f"Error occurred: {str(e)}")
|
149
|
+
return pd.DataFrame()
|
150
|
+
|
151
|
+
def _fetch_cash_flow(self) -> pd.DataFrame:
|
152
|
+
"""
|
153
|
+
Get stock cash flow statement data from East Money API
|
154
|
+
"""
|
155
|
+
try:
|
156
|
+
# API endpoint and parameters
|
157
|
+
api_url = "https://datacenter-web.eastmoney.com/api/data/v1/get"
|
158
|
+
params = {
|
159
|
+
"reportName": "RPT_DMSK_FN_CASHFLOW",
|
160
|
+
"filter": f'(SECURITY_CODE="{self.symbol}")',
|
161
|
+
"pageNumber": "1",
|
162
|
+
"pageSize": "1000",
|
163
|
+
"sortColumns": "REPORT_DATE",
|
164
|
+
"sortTypes": "-1",
|
165
|
+
"columns": ",".join(self._cash_flow_rename_map.keys()),
|
166
|
+
}
|
167
|
+
|
168
|
+
# Fetch data from API
|
169
|
+
response = requests.get(api_url, params=params)
|
170
|
+
response.raise_for_status()
|
171
|
+
data = response.json()
|
172
|
+
|
173
|
+
# Extract the actual data
|
174
|
+
if data.get("result") and data["result"].get("data"):
|
175
|
+
df = pd.DataFrame(data["result"]["data"])
|
176
|
+
df.rename(columns=self._cash_flow_rename_map, inplace=True)
|
177
|
+
return df
|
178
|
+
else:
|
179
|
+
print("No cash flow statement data found in API response")
|
180
|
+
return pd.DataFrame()
|
181
|
+
|
182
|
+
except Exception as e:
|
183
|
+
print(f"Error occurred: {str(e)}")
|
184
|
+
return pd.DataFrame()
|
@@ -1,3 +1,4 @@
|
|
1
|
+
from .eastmoney import EastMoneyFinancialReport
|
1
2
|
from .sina import SinaFinancialReport
|
2
3
|
from .base import FinancialDataProvider
|
3
4
|
|
@@ -9,6 +10,7 @@ class FinancialDataFactory:
|
|
9
10
|
|
10
11
|
_providers = {
|
11
12
|
"sina": SinaFinancialReport,
|
13
|
+
"eastmoney": EastMoneyFinancialReport,
|
12
14
|
}
|
13
15
|
|
14
16
|
@classmethod
|
@@ -7,6 +7,12 @@ from .base import FinancialDataProvider
|
|
7
7
|
|
8
8
|
|
9
9
|
class SinaFinancialReport(FinancialDataProvider):
|
10
|
+
"""Financial data provider for Sina finance reports.
|
11
|
+
|
12
|
+
Provides standardized access to balance sheet, income statement,
|
13
|
+
and cash flow data from Sina finance API.
|
14
|
+
"""
|
15
|
+
|
10
16
|
def __init__(self, symbol: str) -> None:
|
11
17
|
super().__init__(symbol)
|
12
18
|
self.stock = (
|
@@ -77,40 +83,41 @@ class SinaFinancialReport(FinancialDataProvider):
|
|
77
83
|
raw_df["report_date"], format="%Y%m%d"
|
78
84
|
)
|
79
85
|
|
80
|
-
|
81
|
-
raw_df = raw_df.rename(columns={"更新日期": "update_time"})
|
82
|
-
raw_df["update_time"] = pd.to_datetime(raw_df["update_time"])
|
83
|
-
|
84
|
-
# Standardize column names
|
86
|
+
# Define column mappings and required columns
|
85
87
|
column_mapping = {
|
86
|
-
"类型": "report_type",
|
87
88
|
"币种": "currency",
|
88
|
-
"净利润": "net_income",
|
89
|
-
"固定资产折旧、油气资产折耗、生产性生物资产折旧": "depreciation_and_amortization",
|
90
|
-
"无形资产摊销": "share_based_compensation",
|
91
89
|
"经营活动产生的现金流量净额": "net_cash_flow_from_operations",
|
92
90
|
"购建固定资产、无形资产和其他长期资产支付的现金": "capital_expenditure",
|
93
91
|
"取得子公司及其他营业单位支付的现金净额": "business_acquisitions_and_disposals",
|
94
|
-
"投资支付的现金": "investment_acquisitions_and_disposals",
|
95
92
|
"投资活动产生的现金流量净额": "net_cash_flow_from_investing",
|
96
93
|
"取得借款收到的现金": "issuance_or_repayment_of_debt_securities",
|
97
94
|
"吸收投资收到的现金": "issuance_or_purchase_of_equity_shares",
|
98
|
-
"分配股利、利润或偿付利息支付的现金": "dividends_and_other_cash_distributions",
|
99
95
|
"筹资活动产生的现金流量净额": "net_cash_flow_from_financing",
|
100
96
|
"现金及现金等价物净增加额": "change_in_cash_and_equivalents",
|
101
97
|
"汇率变动对现金及现金等价物的影响": "effect_of_exchange_rate_changes",
|
102
98
|
"期末现金及现金等价物余额": "ending_cash_balance",
|
103
|
-
"
|
99
|
+
"销售商品、提供劳务收到的现金": "cash_from_sales",
|
100
|
+
"收到的税费返还": "tax_refunds_received",
|
101
|
+
"支付给职工以及为职工支付的现金": "cash_paid_to_employees",
|
102
|
+
"支付的各项税费": "taxes_paid",
|
103
|
+
"经营活动现金流入小计": "total_cash_inflow_from_operations",
|
104
|
+
"经营活动现金流出小计": "total_cash_outflow_from_operations",
|
105
|
+
"收回投资所收到的现金": "cash_from_investment_recovery",
|
106
|
+
"取得投资收益收到的现金": "cash_from_investment_income",
|
107
|
+
"处置固定资产、无形资产收回的现金": "cash_from_asset_sales",
|
108
|
+
"投资活动现金流入小计": "total_cash_inflow_from_investing",
|
109
|
+
"投资活动现金流出小计": "total_cash_outflow_from_investing",
|
110
|
+
"分配股利、利润或偿付利息所支付的现金": "cash_paid_for_dividends_and_interest",
|
111
|
+
"偿还债务支付的现金": "cash_paid_for_debt_repayment",
|
112
|
+
"筹资活动现金流入小计": "total_cash_inflow_from_financing",
|
113
|
+
"筹资活动现金流出小计": "total_cash_outflow_from_financing",
|
114
|
+
"期初现金及现金等价物余额": "beginning_cash_balance",
|
115
|
+
"现金的期末余额": "ending_cash",
|
116
|
+
"现金等价物的期末余额": "ending_cash_equivalents",
|
104
117
|
}
|
105
|
-
raw_df = raw_df.rename(columns=column_mapping)
|
106
|
-
|
107
|
-
# Select only required columns
|
108
|
-
required_columns = ["report_date"]
|
109
|
-
required_columns.extend(column_mapping.values())
|
110
118
|
|
111
|
-
|
112
|
-
|
113
|
-
return raw_df[available_columns]
|
119
|
+
required_columns = ["report_date"] + list(column_mapping.values())
|
120
|
+
return raw_df.rename(columns=column_mapping).reindex(columns=required_columns)
|
114
121
|
|
115
122
|
def _clean_balance_data(self, raw_df: pd.DataFrame) -> pd.DataFrame:
|
116
123
|
"""清理和标准化资产负债表数据
|
@@ -128,47 +135,48 @@ class SinaFinancialReport(FinancialDataProvider):
|
|
128
135
|
raw_df["report_date"], format="%Y%m%d"
|
129
136
|
)
|
130
137
|
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
138
|
+
# Define and apply column mappings in one optimized operation
|
139
|
+
raw_df = raw_df.rename(
|
140
|
+
columns={
|
141
|
+
"币种": "currency",
|
142
|
+
"资产总计": "total_assets",
|
143
|
+
"流动资产合计": "current_assets",
|
144
|
+
"货币资金": "cash_and_equivalents",
|
145
|
+
"存货": "inventory",
|
146
|
+
"交易性金融资产": "current_investments",
|
147
|
+
"应收票据及应收账款": "trade_and_non_trade_receivables",
|
148
|
+
"非流动资产合计": "non_current_assets",
|
149
|
+
"固定资产": "property_plant_and_equipment",
|
150
|
+
"商誉": "goodwill_and_intangible_assets",
|
151
|
+
"长期股权投资": "investments",
|
152
|
+
"其他非流动金融资产": "non_current_investments",
|
153
|
+
"实收资本(或股本)": "outstanding_shares",
|
154
|
+
"递延所得税资产": "tax_assets",
|
155
|
+
"负债合计": "total_liabilities",
|
156
|
+
"流动负债合计": "current_liabilities",
|
157
|
+
"短期借款": "current_debt",
|
158
|
+
"应付票据及应付账款": "trade_and_non_trade_payables",
|
159
|
+
"合同负债": "deferred_revenue",
|
160
|
+
"吸收存款及同业存放": "deposit_liabilities",
|
161
|
+
"非流动负债合计": "non_current_liabilities",
|
162
|
+
"长期借款": "non_current_debt",
|
163
|
+
"递延所得税负债": "tax_liabilities",
|
164
|
+
"所有者权益(或股东权益)合计": "shareholders_equity",
|
165
|
+
"未分配利润": "retained_earnings",
|
166
|
+
"其他综合收益": "accumulated_other_comprehensive_income",
|
167
|
+
"应收账款": "accounts_receivable",
|
168
|
+
"预付款项": "prepayments",
|
169
|
+
"其他应收款": "other_receivables",
|
170
|
+
"固定资产净值": "fixed_assets_net",
|
171
|
+
"在建工程": "construction_in_progress",
|
172
|
+
"资本公积": "capital_reserve",
|
173
|
+
"少数股东权益": "minority_interest",
|
174
|
+
}
|
175
|
+
)
|
166
176
|
|
167
177
|
# Select only required columns
|
168
178
|
required_columns = [
|
169
179
|
"report_date",
|
170
|
-
"report_period",
|
171
|
-
"period",
|
172
180
|
"currency",
|
173
181
|
"total_assets",
|
174
182
|
"current_assets",
|
@@ -195,16 +203,49 @@ class SinaFinancialReport(FinancialDataProvider):
|
|
195
203
|
"shareholders_equity",
|
196
204
|
"retained_earnings",
|
197
205
|
"accumulated_other_comprehensive_income",
|
206
|
+
"accounts_receivable",
|
207
|
+
"prepayments",
|
208
|
+
"other_receivables",
|
209
|
+
"fixed_assets_net",
|
210
|
+
"construction_in_progress",
|
211
|
+
"capital_reserve",
|
212
|
+
"current_ratio",
|
213
|
+
"debt_to_assets",
|
214
|
+
"minority_interest",
|
198
215
|
]
|
199
216
|
|
200
|
-
# Calculate
|
201
|
-
|
202
|
-
|
203
|
-
|
217
|
+
# Calculate financial ratios using vectorized operations
|
218
|
+
cols = ["current_debt", "non_current_debt"]
|
219
|
+
raw_df[cols] = raw_df[cols].apply(pd.to_numeric, errors="coerce")
|
220
|
+
raw_df["total_debt"] = raw_df[cols].fillna(0).sum(axis=1)
|
221
|
+
|
222
|
+
# Pre-calculate denominator conditions
|
223
|
+
valid_current_liab = raw_df["current_liabilities"].ne(0)
|
224
|
+
valid_total_assets = raw_df["total_assets"].ne(0)
|
225
|
+
|
226
|
+
# Calculate ratios in one operation
|
227
|
+
ratios = pd.DataFrame(
|
228
|
+
{
|
229
|
+
"current_ratio": raw_df["current_assets"]
|
230
|
+
/ raw_df["current_liabilities"],
|
231
|
+
"cash_ratio": raw_df["cash_and_equivalents"]
|
232
|
+
/ raw_df["current_liabilities"],
|
233
|
+
"debt_to_assets": raw_df["total_debt"] / raw_df["total_assets"],
|
234
|
+
}
|
235
|
+
)
|
204
236
|
|
205
|
-
#
|
206
|
-
|
207
|
-
|
237
|
+
# Apply conditions
|
238
|
+
cond = pd.DataFrame(
|
239
|
+
{
|
240
|
+
"current_ratio": valid_current_liab,
|
241
|
+
"cash_ratio": valid_current_liab,
|
242
|
+
"debt_to_assets": valid_total_assets,
|
243
|
+
},
|
244
|
+
index=ratios.index,
|
245
|
+
)
|
246
|
+
raw_df = raw_df.join(ratios.where(cond))
|
247
|
+
|
248
|
+
return raw_df.reindex(columns=required_columns)
|
208
249
|
|
209
250
|
def _clean_income_data(self, raw_df: pd.DataFrame) -> pd.DataFrame:
|
210
251
|
"""清理和标准化利润表数据
|
@@ -222,15 +263,12 @@ class SinaFinancialReport(FinancialDataProvider):
|
|
222
263
|
raw_df["report_date"], format="%Y%m%d"
|
223
264
|
)
|
224
265
|
|
225
|
-
|
226
|
-
raw_df = raw_df.rename(columns={"更新日期": "update_time"})
|
227
|
-
raw_df["update_time"] = pd.to_datetime(raw_df["update_time"])
|
228
|
-
|
229
|
-
# Standardize column names
|
266
|
+
# Define column mappings and required columns
|
230
267
|
column_mapping = {
|
231
|
-
"类型": "report_type",
|
232
268
|
"币种": "currency",
|
233
269
|
"营业总收入": "revenue",
|
270
|
+
"营业收入": "operating_revenue",
|
271
|
+
"营业总成本": "total_operating_costs",
|
234
272
|
"营业成本": "cost_of_revenue",
|
235
273
|
"营业利润": "operating_profit",
|
236
274
|
"销售费用": "selling_general_and_administrative_expenses",
|
@@ -244,30 +282,17 @@ class SinaFinancialReport(FinancialDataProvider):
|
|
244
282
|
"少数股东损益": "net_income_non_controlling_interests",
|
245
283
|
"基本每股收益": "earnings_per_share",
|
246
284
|
"稀释每股收益": "earnings_per_share_diluted",
|
285
|
+
"投资收益": "investment_income",
|
286
|
+
"公允价值变动收益": "fair_value_adjustments",
|
287
|
+
"资产减值损失": "asset_impairment_loss",
|
288
|
+
"财务费用": "financial_expenses",
|
289
|
+
"营业税金及附加": "taxes_and_surcharges",
|
290
|
+
"其他综合收益": "other_comprehensive_income",
|
291
|
+
"综合收益总额": "total_comprehensive_income",
|
247
292
|
}
|
248
|
-
raw_df = raw_df.rename(columns=column_mapping)
|
249
293
|
|
250
|
-
|
251
|
-
|
252
|
-
"report_date",
|
253
|
-
"period",
|
254
|
-
"currency",
|
255
|
-
"revenue",
|
256
|
-
"cost_of_revenue",
|
257
|
-
"operating_profit",
|
258
|
-
"operating_expense",
|
259
|
-
"selling_general_and_administrative_expenses",
|
260
|
-
"research_and_development",
|
261
|
-
"interest_expense",
|
262
|
-
"ebit",
|
263
|
-
"income_tax_expense",
|
264
|
-
"net_income",
|
265
|
-
"net_income_common_stock",
|
266
|
-
"net_income_non_controlling_interests",
|
267
|
-
"earnings_per_share",
|
268
|
-
"earnings_per_share_diluted",
|
269
|
-
]
|
294
|
+
required_columns = ["report_date"] + list(column_mapping.values())
|
295
|
+
return raw_df.rename(columns=column_mapping).reindex(columns=required_columns)
|
270
296
|
|
271
|
-
|
272
|
-
|
273
|
-
return raw_df[available_columns]
|
297
|
+
def get_financial_metrics(self):
|
298
|
+
pass
|
@@ -0,0 +1,25 @@
|
|
1
|
+
from abc import ABC, abstractmethod
|
2
|
+
import pandas as pd
|
3
|
+
|
4
|
+
|
5
|
+
class InfoDataProvider(ABC):
|
6
|
+
def __init__(self, symbol: str) -> None:
|
7
|
+
self.symbol = symbol
|
8
|
+
|
9
|
+
@abstractmethod
|
10
|
+
def get_basic_info(self) -> pd.DataFrame:
|
11
|
+
"""Fetches stock basic info data
|
12
|
+
|
13
|
+
Returns:
|
14
|
+
pd.DataFrame:
|
15
|
+
- price: 最新价
|
16
|
+
- symbol: 股票代码
|
17
|
+
- name: 股票简称
|
18
|
+
- total_shares: 总股本
|
19
|
+
- float_shares: 流通股
|
20
|
+
- total_market_cap: 总市值
|
21
|
+
- float_market_cap: 流通市值
|
22
|
+
- industry: 行业
|
23
|
+
- listing_date: 上市时间
|
24
|
+
"""
|
25
|
+
pass
|
@@ -0,0 +1,52 @@
|
|
1
|
+
from cachetools import cached
|
2
|
+
import pandas as pd
|
3
|
+
import akshare as ak
|
4
|
+
|
5
|
+
from ..cache import CACHE_CONFIG
|
6
|
+
from .base import InfoDataProvider
|
7
|
+
|
8
|
+
|
9
|
+
class EastmoneyInfo(InfoDataProvider):
|
10
|
+
_basic_info_rename_map = {
|
11
|
+
"最新": "price",
|
12
|
+
"股票代码": "symbol",
|
13
|
+
"股票简称": "name",
|
14
|
+
"总股本": "total_shares",
|
15
|
+
"流通股": "float_shares",
|
16
|
+
"总市值": "total_market_cap",
|
17
|
+
"流通市值": "float_market_cap",
|
18
|
+
"行业": "industry",
|
19
|
+
"上市时间": "listing_date",
|
20
|
+
}
|
21
|
+
|
22
|
+
@cached(
|
23
|
+
CACHE_CONFIG["info_cache"],
|
24
|
+
key=lambda self, symbol=None: f"eastmoney_{symbol}",
|
25
|
+
)
|
26
|
+
def get_basic_info(self) -> pd.DataFrame:
|
27
|
+
"""获取东方财富个股信息"""
|
28
|
+
info_df = ak.stock_individual_info_em(symbol=self.symbol)
|
29
|
+
info_df = info_df.set_index("item").T
|
30
|
+
info_df.reset_index(drop=True, inplace=True)
|
31
|
+
info_df.rename(columns=self._basic_info_rename_map, inplace=True)
|
32
|
+
|
33
|
+
if "symbol" in info_df.columns:
|
34
|
+
info_df["symbol"] = info_df["symbol"].astype(str)
|
35
|
+
|
36
|
+
if "listing_date" in info_df.columns:
|
37
|
+
info_df["listing_date"] = pd.to_datetime(
|
38
|
+
info_df["listing_date"], format="%Y%m%d"
|
39
|
+
)
|
40
|
+
|
41
|
+
numeric_cols = [
|
42
|
+
"price",
|
43
|
+
"total_shares",
|
44
|
+
"float_shares",
|
45
|
+
"total_market_cap",
|
46
|
+
"float_market_cap",
|
47
|
+
]
|
48
|
+
for col in numeric_cols:
|
49
|
+
if col in info_df.columns:
|
50
|
+
info_df[col] = pd.to_numeric(info_df[col], errors="coerce")
|
51
|
+
|
52
|
+
return info_df
|
@@ -0,0 +1,44 @@
|
|
1
|
+
from .eastmoney import EastmoneyInfo
|
2
|
+
from .base import InfoDataProvider
|
3
|
+
|
4
|
+
|
5
|
+
class InfoDataFactory:
|
6
|
+
"""
|
7
|
+
Factory class for creating info data providers
|
8
|
+
"""
|
9
|
+
|
10
|
+
_providers = {
|
11
|
+
"eastmoney": EastmoneyInfo,
|
12
|
+
}
|
13
|
+
|
14
|
+
@classmethod
|
15
|
+
def get_provider(cls, provider_name: str, **kwargs) -> InfoDataProvider:
|
16
|
+
"""
|
17
|
+
Get a info data provider by name
|
18
|
+
|
19
|
+
Args:
|
20
|
+
provider_name: Name of the provider (e.g., 'eastmoney')
|
21
|
+
**kwargs: Additional arguments to pass to the provider's constructor
|
22
|
+
|
23
|
+
Returns:
|
24
|
+
InfoDataProvider: An instance of the requested provider
|
25
|
+
|
26
|
+
Raises:
|
27
|
+
ValueError: If the requested provider is not found
|
28
|
+
"""
|
29
|
+
provider_class = cls._providers.get(provider_name.lower())
|
30
|
+
if not provider_class:
|
31
|
+
raise ValueError(f"Unknown info data provider: {provider_name}")
|
32
|
+
|
33
|
+
return provider_class(**kwargs)
|
34
|
+
|
35
|
+
@classmethod
|
36
|
+
def register_provider(cls, name: str, provider_class: type):
|
37
|
+
"""
|
38
|
+
Register a new info data provider
|
39
|
+
|
40
|
+
Args:
|
41
|
+
name: Name to associate with this provider
|
42
|
+
provider_class: The provider class to register
|
43
|
+
"""
|
44
|
+
cls._providers[name.lower()] = provider_class
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: akshare-one
|
3
|
-
Version: 0.3.
|
3
|
+
Version: 0.3.3
|
4
4
|
Summary: Standardized interface for Chinese financial market data, built on AKShare with unified data formats and simplified APIs
|
5
5
|
License-Expression: MIT
|
6
6
|
Project-URL: Homepage, https://github.com/zwldarren/akshare-one
|
@@ -9,8 +9,8 @@ Keywords: akshare,financial-data,stock-data,quant
|
|
9
9
|
Requires-Python: >=3.10
|
10
10
|
Description-Content-Type: text/markdown
|
11
11
|
License-File: LICENSE
|
12
|
-
Requires-Dist: akshare>=1.17.
|
13
|
-
Requires-Dist: cachetools>=
|
12
|
+
Requires-Dist: akshare>=1.17.20
|
13
|
+
Requires-Dist: cachetools>=5.5.2
|
14
14
|
Provides-Extra: talib
|
15
15
|
Requires-Dist: ta-lib>=0.6.4; extra == "talib"
|
16
16
|
Dynamic: license-file
|
@@ -1,16 +1,13 @@
|
|
1
|
-
akshare_one/__init__.py,sha256=
|
2
|
-
akshare_one/financial.py,sha256=uCTFpcoeCxDo1iwewGPq9_TppwoHXBJFT4QlMgFOgRQ,1472
|
1
|
+
akshare_one/__init__.py,sha256=FskUp8Xpt9eN79AA2YZMLm53XGjYj2EYvuD0jkRLWsY,6504
|
3
2
|
akshare_one/indicators.py,sha256=x3Amff9CG_GvQpA-sqGfFwEAIvaaXlBxDfzTxD05taQ,12533
|
4
|
-
akshare_one/
|
5
|
-
akshare_one/news.py,sha256=Pqap-23VCosG9vf70eEeFAC4O0emS-CORHjwkuDuoUA,696
|
6
|
-
akshare_one/stock.py,sha256=VFMNn3Sqa2P9dKZueOa8ekqbxo4jc08iXS94B8eClMo,2344
|
7
|
-
akshare_one/modules/cache.py,sha256=LBOfMQE9-Mr49GRS7d0dATGdMZCZcQWiY41p4GUI2DA,382
|
3
|
+
akshare_one/modules/cache.py,sha256=t8zaB9mvvskivBpuS2SjiR1q07CzRNJb2xtkjyZgBPk,465
|
8
4
|
akshare_one/modules/utils.py,sha256=msHqsjWSRULbX-3Bnit1p26a4a7MOEuNfkPSaECXr4k,333
|
9
5
|
akshare_one/modules/eastmoney/client.py,sha256=npxW6H8tfehDBAVAsUBOD0T4zpn7OnXfM-t2ZWr02hs,3206
|
10
6
|
akshare_one/modules/eastmoney/utils.py,sha256=0hs1kE51kZs3A9cOK448w5K8YKHaKZi0WWgtGZHVPGc,3000
|
11
|
-
akshare_one/modules/financial/base.py,sha256=
|
12
|
-
akshare_one/modules/financial/
|
13
|
-
akshare_one/modules/financial/
|
7
|
+
akshare_one/modules/financial/base.py,sha256=TG3ncf3rXfgWCk4qUORN01uxT1SgLWiyjkt5Jb9eoxo,688
|
8
|
+
akshare_one/modules/financial/eastmoney.py,sha256=xVKJLT8kS8eZ_eQHkSMNDcMIi9CHwCIGwvuqj1cYBWw,6762
|
9
|
+
akshare_one/modules/financial/factory.py,sha256=UV6_ebqXGkmlfcfb39aX5hBjXyBLi29WbZ4AqxaPcXU,1442
|
10
|
+
akshare_one/modules/financial/sina.py,sha256=cclYraGz1O01fwYmY55VJCbyoT3kURCQTNENYNL7xRs,12948
|
14
11
|
akshare_one/modules/historical/base.py,sha256=4jdHW99-5U1mzv0WPopIkxeh20yYUDrNFzn7xazfwZU,1292
|
15
12
|
akshare_one/modules/historical/eastmoney.py,sha256=VbOaf0zXxuGmmm60x4FMh-9T5N9mYTUGmG1suMFUPfU,8489
|
16
13
|
akshare_one/modules/historical/eastmoney_direct.py,sha256=EF5AhViBwdNywqZnJYacRrdw4Up0gbuUr7RgssK7rpw,2893
|
@@ -21,6 +18,9 @@ akshare_one/modules/indicators/base.py,sha256=DhFivpVIUIkdIv24U2WoOy1GCDySxsw0tD
|
|
21
18
|
akshare_one/modules/indicators/factory.py,sha256=pKx57oej_L0Lz3kkXwzVievKpOYph0T_Y7fzSwO3Zd4,1021
|
22
19
|
akshare_one/modules/indicators/simple.py,sha256=vAqE3v9HYpW-Sy6KsG9oV5fppWchQTxtz1M_508sQtY,9342
|
23
20
|
akshare_one/modules/indicators/talib.py,sha256=w0KpV-BXVxU0LmWs_EbXJUFgo9dbMeUQijjJMkjtWtU,10773
|
21
|
+
akshare_one/modules/info/base.py,sha256=Kof-e1I2usx1VOc1d05kyL-8B_QEDOsbry4R3dV0zZE,697
|
22
|
+
akshare_one/modules/info/eastmoney.py,sha256=Ou4BTw_PC1tJcEpoRTqrR-hqjgcDjWHuX6InbYiCXLU,1663
|
23
|
+
akshare_one/modules/info/factory.py,sha256=xvwPrgce0p9U4qAQBJM7FFw3zJks6m2hLHwHf0t1rfU,1308
|
24
24
|
akshare_one/modules/insider/base.py,sha256=NE45w-B9sQ2AoUSSKNPU9U6wPHK4fiLV5Zgj_byrBMQ,977
|
25
25
|
akshare_one/modules/insider/factory.py,sha256=32bueJA3E8yCZc0v5EAen_48RZ23yojYzpzaZyQ6WnA,1324
|
26
26
|
akshare_one/modules/insider/xueqiu.py,sha256=6WKEvdE-8cjVQjTsJIkgnqhaQUS5sXZCyxKPLMLyers,4109
|
@@ -32,8 +32,8 @@ akshare_one/modules/realtime/eastmoney.py,sha256=IRAPokCm_-aOn16w5_dkbKVjdYcqL-y
|
|
32
32
|
akshare_one/modules/realtime/eastmoney_direct.py,sha256=HiHrhsTcDTswMg4b7JSUXHLtf-oYziWxLGXLhFJ2pYo,1275
|
33
33
|
akshare_one/modules/realtime/factory.py,sha256=_7jBDgqWqkt5xTTT1SpZoUHM9IpMRpcUQeyyCglM5z0,1528
|
34
34
|
akshare_one/modules/realtime/xueqiu.py,sha256=j_cjJZD0fTva_jgXKeQAJSFVHKJHb5zMu3Crf_8zLs0,2301
|
35
|
-
akshare_one-0.3.
|
36
|
-
akshare_one-0.3.
|
37
|
-
akshare_one-0.3.
|
38
|
-
akshare_one-0.3.
|
39
|
-
akshare_one-0.3.
|
35
|
+
akshare_one-0.3.3.dist-info/licenses/LICENSE,sha256=3bqxoD7aU4QS7kpNtQmRd4MikxXe6Gtm_DrojyFHGAc,1087
|
36
|
+
akshare_one-0.3.3.dist-info/METADATA,sha256=a2RtfPXBTGrbQu4dlHfJs_NuvHyWKnOEX4pTXhtaWKk,2132
|
37
|
+
akshare_one-0.3.3.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
38
|
+
akshare_one-0.3.3.dist-info/top_level.txt,sha256=kNiucyLVAGa89wmUSpXbBLWD7pF_RuahuiaOfLHZSyw,12
|
39
|
+
akshare_one-0.3.3.dist-info/RECORD,,
|
akshare_one/financial.py
DELETED
@@ -1,46 +0,0 @@
|
|
1
|
-
"""财务报表数据模块
|
2
|
-
|
3
|
-
包含资产负债表、利润表和现金流量表相关功能
|
4
|
-
"""
|
5
|
-
|
6
|
-
import pandas as pd
|
7
|
-
from akshare_one.modules.financial.factory import FinancialDataFactory
|
8
|
-
|
9
|
-
|
10
|
-
def get_balance_sheet(symbol: str, source: str = "sina") -> "pd.DataFrame":
|
11
|
-
"""获取资产负债表数据
|
12
|
-
|
13
|
-
Args:
|
14
|
-
symbol: 股票代码 (如 "600600")
|
15
|
-
source: 数据源 ("sina")
|
16
|
-
"""
|
17
|
-
if source == "sina":
|
18
|
-
provider = FinancialDataFactory.get_provider(source, symbol=symbol)
|
19
|
-
return provider.get_balance_sheet()
|
20
|
-
raise ValueError(f"Unsupported data source: {source}")
|
21
|
-
|
22
|
-
|
23
|
-
def get_income_statement(symbol: str, source: str = "sina") -> "pd.DataFrame":
|
24
|
-
"""获取利润表数据
|
25
|
-
|
26
|
-
Args:
|
27
|
-
symbol: 股票代码 (如 "600600")
|
28
|
-
source: 数据源 ("sina")
|
29
|
-
"""
|
30
|
-
if source == "sina":
|
31
|
-
provider = FinancialDataFactory.get_provider(source, symbol=symbol)
|
32
|
-
return provider.get_income_statement()
|
33
|
-
raise ValueError(f"Unsupported data source: {source}")
|
34
|
-
|
35
|
-
|
36
|
-
def get_cash_flow(symbol: str, source: str = "sina") -> "pd.DataFrame":
|
37
|
-
"""获取现金流量表数据
|
38
|
-
|
39
|
-
Args:
|
40
|
-
symbol: 股票代码 (如 "600600")
|
41
|
-
source: 数据源 ("sina")
|
42
|
-
"""
|
43
|
-
if source == "sina":
|
44
|
-
provider = FinancialDataFactory.get_provider(source, symbol=symbol)
|
45
|
-
return provider.get_cash_flow()
|
46
|
-
raise ValueError(f"Unsupported data source: {source}")
|
akshare_one/insider.py
DELETED
@@ -1,33 +0,0 @@
|
|
1
|
-
"""内部交易数据模块
|
2
|
-
|
3
|
-
包含上市公司内部交易相关功能
|
4
|
-
"""
|
5
|
-
|
6
|
-
import pandas as pd
|
7
|
-
from .modules.insider.factory import InsiderDataFactory
|
8
|
-
|
9
|
-
|
10
|
-
def get_inner_trade_data(symbol: str, source: str = "xueqiu") -> "pd.DataFrame":
|
11
|
-
"""获取雪球内部交易数据
|
12
|
-
|
13
|
-
Args:
|
14
|
-
source: 数据源 (目前支持 "xueqiu")
|
15
|
-
symbol: 股票代码,如"600000"
|
16
|
-
|
17
|
-
Returns:
|
18
|
-
pd.DataFrame:
|
19
|
-
- symbol: 股票代码
|
20
|
-
- issuer: 股票名称
|
21
|
-
- name: 变动人
|
22
|
-
- title: 董监高职务
|
23
|
-
- transaction_date: 变动日期(UTC时区)
|
24
|
-
- transaction_shares: 变动股数
|
25
|
-
- transaction_price_per_share: 成交均价
|
26
|
-
- shares_owned_after_transaction: 变动后持股数
|
27
|
-
- relationship: 与董监高关系
|
28
|
-
- is_board_director: 是否为董事会成员
|
29
|
-
- transaction_value: 交易金额(变动股数*成交均价)
|
30
|
-
- shares_owned_before_transaction: 变动前持股数
|
31
|
-
"""
|
32
|
-
provider = InsiderDataFactory.get_provider(source, symbol=symbol)
|
33
|
-
return provider.get_inner_trade_data()
|
akshare_one/news.py
DELETED
@@ -1,27 +0,0 @@
|
|
1
|
-
"""新闻数据模块
|
2
|
-
|
3
|
-
包含股票新闻相关功能
|
4
|
-
"""
|
5
|
-
|
6
|
-
import pandas as pd
|
7
|
-
from .modules.news.factory import NewsDataFactory
|
8
|
-
|
9
|
-
|
10
|
-
def get_news_data(symbol: str, source: str = "eastmoney") -> "pd.DataFrame":
|
11
|
-
"""获取个股新闻数据
|
12
|
-
|
13
|
-
Args:
|
14
|
-
symbol: 股票代码 (如 "300059")
|
15
|
-
source: 数据源 ('eastmoney')
|
16
|
-
|
17
|
-
Returns:
|
18
|
-
pd.DataFrame:
|
19
|
-
- keyword: 关键词
|
20
|
-
- title: 新闻标题
|
21
|
-
- content: 新闻内容
|
22
|
-
- publish_time: 发布时间
|
23
|
-
- source: 文章来源
|
24
|
-
- url: 新闻链接
|
25
|
-
"""
|
26
|
-
provider = NewsDataFactory.get_provider(source, symbol=symbol)
|
27
|
-
return provider.get_news_data()
|
akshare_one/stock.py
DELETED
@@ -1,78 +0,0 @@
|
|
1
|
-
"""股票市场数据模块
|
2
|
-
|
3
|
-
包含股票历史数据和实时数据相关功能
|
4
|
-
"""
|
5
|
-
|
6
|
-
from typing import Optional
|
7
|
-
import pandas as pd
|
8
|
-
|
9
|
-
from akshare_one.modules.historical.factory import HistoricalDataFactory
|
10
|
-
from akshare_one.modules.realtime.factory import RealtimeDataFactory
|
11
|
-
|
12
|
-
|
13
|
-
def get_hist_data(
|
14
|
-
symbol: str,
|
15
|
-
interval: str = "day",
|
16
|
-
interval_multiplier: int = 1,
|
17
|
-
start_date: str = "1970-01-01",
|
18
|
-
end_date: str = "2030-12-31",
|
19
|
-
adjust: str = "none",
|
20
|
-
source: str = "eastmoney",
|
21
|
-
) -> "pd.DataFrame":
|
22
|
-
"""Get historical market data
|
23
|
-
|
24
|
-
Args:
|
25
|
-
symbol: 股票代码 (e.g. '600000')
|
26
|
-
interval: 时间间隔 ('minute','hour','day','week','month','year')
|
27
|
-
interval_multiplier: 时间间隔倍数 (e.g. 5 for 5 minutes)
|
28
|
-
start_date: 开始日期 (YYYY-MM-DD)
|
29
|
-
end_date: 结束日期 (YYYY-MM-DD)
|
30
|
-
adjust: 复权类型 ('none','qfq','hfq')
|
31
|
-
source: 数据源 ('eastmoney', 'eastmoney_direct', 'sina') (default: 'eastmoney')
|
32
|
-
|
33
|
-
Returns:
|
34
|
-
pd.DataFrame:
|
35
|
-
- timestamp: 时间戳(UTC时区)
|
36
|
-
- open: 开盘价
|
37
|
-
- high: 最高价
|
38
|
-
- low: 最低价
|
39
|
-
- close: 收盘价
|
40
|
-
- volume: 成交量
|
41
|
-
"""
|
42
|
-
kwargs = {
|
43
|
-
"symbol": symbol,
|
44
|
-
"interval": interval,
|
45
|
-
"interval_multiplier": interval_multiplier,
|
46
|
-
"start_date": start_date,
|
47
|
-
"end_date": end_date,
|
48
|
-
"adjust": adjust,
|
49
|
-
}
|
50
|
-
provider = HistoricalDataFactory.get_provider(source, **kwargs)
|
51
|
-
return provider.get_hist_data()
|
52
|
-
|
53
|
-
|
54
|
-
def get_realtime_data(
|
55
|
-
symbol: Optional[str] = None, source: str = "xueqiu"
|
56
|
-
) -> "pd.DataFrame":
|
57
|
-
"""Get real-time market quotes
|
58
|
-
|
59
|
-
Args:
|
60
|
-
symbol: 股票代码 (如 "600000")
|
61
|
-
source: 数据源 ('eastmoney', 'eastmoney_direct', 'xueqiu')
|
62
|
-
|
63
|
-
Returns:
|
64
|
-
pd.DataFrame:
|
65
|
-
- symbol: 股票代码
|
66
|
-
- price: 最新价
|
67
|
-
- change: 涨跌额
|
68
|
-
- pct_change: 涨跌幅(%)
|
69
|
-
- timestamp: 时间戳
|
70
|
-
- volume: 成交量(手)
|
71
|
-
- amount: 成交额(元)
|
72
|
-
- open: 今开
|
73
|
-
- high: 最高
|
74
|
-
- low: 最低
|
75
|
-
- prev_close: 昨收
|
76
|
-
"""
|
77
|
-
provider = RealtimeDataFactory.get_provider(source, symbol=symbol)
|
78
|
-
return provider.get_current_data()
|
File without changes
|
File without changes
|
File without changes
|