akshare-one 0.3.2__tar.gz → 0.3.3__tar.gz

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.
Files changed (57) hide show
  1. {akshare_one-0.3.2 → akshare_one-0.3.3}/PKG-INFO +3 -3
  2. akshare_one-0.3.3/akshare_one/__init__.py +214 -0
  3. {akshare_one-0.3.2 → akshare_one-0.3.3}/akshare_one/modules/cache.py +1 -0
  4. {akshare_one-0.3.2 → akshare_one-0.3.3}/akshare_one/modules/financial/base.py +5 -0
  5. akshare_one-0.3.3/akshare_one/modules/financial/eastmoney.py +184 -0
  6. {akshare_one-0.3.2 → akshare_one-0.3.3}/akshare_one/modules/financial/factory.py +2 -0
  7. akshare_one-0.3.3/akshare_one/modules/financial/sina.py +298 -0
  8. akshare_one-0.3.3/akshare_one/modules/info/base.py +25 -0
  9. akshare_one-0.3.3/akshare_one/modules/info/eastmoney.py +52 -0
  10. akshare_one-0.3.3/akshare_one/modules/info/factory.py +44 -0
  11. {akshare_one-0.3.2 → akshare_one-0.3.3}/akshare_one.egg-info/PKG-INFO +3 -3
  12. {akshare_one-0.3.2 → akshare_one-0.3.3}/akshare_one.egg-info/SOURCES.txt +5 -4
  13. akshare_one-0.3.3/akshare_one.egg-info/requires.txt +5 -0
  14. {akshare_one-0.3.2 → akshare_one-0.3.3}/pyproject.toml +3 -3
  15. {akshare_one-0.3.2 → akshare_one-0.3.3}/tests/test_financial.py +36 -2
  16. akshare_one-0.3.3/tests/test_info.py +33 -0
  17. {akshare_one-0.3.2 → akshare_one-0.3.3}/tests/test_news.py +0 -5
  18. akshare_one-0.3.2/akshare_one/__init__.py +0 -31
  19. akshare_one-0.3.2/akshare_one/financial.py +0 -46
  20. akshare_one-0.3.2/akshare_one/insider.py +0 -33
  21. akshare_one-0.3.2/akshare_one/modules/financial/sina.py +0 -273
  22. akshare_one-0.3.2/akshare_one/news.py +0 -27
  23. akshare_one-0.3.2/akshare_one/stock.py +0 -78
  24. akshare_one-0.3.2/akshare_one.egg-info/requires.txt +0 -5
  25. {akshare_one-0.3.2 → akshare_one-0.3.3}/LICENSE +0 -0
  26. {akshare_one-0.3.2 → akshare_one-0.3.3}/README.md +0 -0
  27. {akshare_one-0.3.2 → akshare_one-0.3.3}/akshare_one/indicators.py +0 -0
  28. {akshare_one-0.3.2 → akshare_one-0.3.3}/akshare_one/modules/eastmoney/client.py +0 -0
  29. {akshare_one-0.3.2 → akshare_one-0.3.3}/akshare_one/modules/eastmoney/utils.py +0 -0
  30. {akshare_one-0.3.2 → akshare_one-0.3.3}/akshare_one/modules/historical/base.py +0 -0
  31. {akshare_one-0.3.2 → akshare_one-0.3.3}/akshare_one/modules/historical/eastmoney.py +0 -0
  32. {akshare_one-0.3.2 → akshare_one-0.3.3}/akshare_one/modules/historical/eastmoney_direct.py +0 -0
  33. {akshare_one-0.3.2 → akshare_one-0.3.3}/akshare_one/modules/historical/factory.py +0 -0
  34. {akshare_one-0.3.2 → akshare_one-0.3.3}/akshare_one/modules/historical/sina.py +0 -0
  35. {akshare_one-0.3.2 → akshare_one-0.3.3}/akshare_one/modules/indicators/__init__.py +0 -0
  36. {akshare_one-0.3.2 → akshare_one-0.3.3}/akshare_one/modules/indicators/base.py +0 -0
  37. {akshare_one-0.3.2 → akshare_one-0.3.3}/akshare_one/modules/indicators/factory.py +0 -0
  38. {akshare_one-0.3.2 → akshare_one-0.3.3}/akshare_one/modules/indicators/simple.py +0 -0
  39. {akshare_one-0.3.2 → akshare_one-0.3.3}/akshare_one/modules/indicators/talib.py +0 -0
  40. {akshare_one-0.3.2 → akshare_one-0.3.3}/akshare_one/modules/insider/base.py +0 -0
  41. {akshare_one-0.3.2 → akshare_one-0.3.3}/akshare_one/modules/insider/factory.py +0 -0
  42. {akshare_one-0.3.2 → akshare_one-0.3.3}/akshare_one/modules/insider/xueqiu.py +0 -0
  43. {akshare_one-0.3.2 → akshare_one-0.3.3}/akshare_one/modules/news/base.py +0 -0
  44. {akshare_one-0.3.2 → akshare_one-0.3.3}/akshare_one/modules/news/eastmoney.py +0 -0
  45. {akshare_one-0.3.2 → akshare_one-0.3.3}/akshare_one/modules/news/factory.py +0 -0
  46. {akshare_one-0.3.2 → akshare_one-0.3.3}/akshare_one/modules/realtime/base.py +0 -0
  47. {akshare_one-0.3.2 → akshare_one-0.3.3}/akshare_one/modules/realtime/eastmoney.py +0 -0
  48. {akshare_one-0.3.2 → akshare_one-0.3.3}/akshare_one/modules/realtime/eastmoney_direct.py +0 -0
  49. {akshare_one-0.3.2 → akshare_one-0.3.3}/akshare_one/modules/realtime/factory.py +0 -0
  50. {akshare_one-0.3.2 → akshare_one-0.3.3}/akshare_one/modules/realtime/xueqiu.py +0 -0
  51. {akshare_one-0.3.2 → akshare_one-0.3.3}/akshare_one/modules/utils.py +0 -0
  52. {akshare_one-0.3.2 → akshare_one-0.3.3}/akshare_one.egg-info/dependency_links.txt +0 -0
  53. {akshare_one-0.3.2 → akshare_one-0.3.3}/akshare_one.egg-info/top_level.txt +0 -0
  54. {akshare_one-0.3.2 → akshare_one-0.3.3}/setup.cfg +0 -0
  55. {akshare_one-0.3.2 → akshare_one-0.3.3}/tests/test_indicators.py +0 -0
  56. {akshare_one-0.3.2 → akshare_one-0.3.3}/tests/test_insider.py +0 -0
  57. {akshare_one-0.3.2 → akshare_one-0.3.3}/tests/test_stock.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: akshare-one
3
- Version: 0.3.2
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.15
13
- Requires-Dist: cachetools>=6.1.0
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
@@ -0,0 +1,214 @@
1
+ """Akshare One - Unified interface for Chinese market data
2
+
3
+ Provides standardized access to various financial data sources with:
4
+ - Consistent symbol formats
5
+ - Unified data schemas
6
+ - Cleaned and normalized outputs
7
+
8
+ Example:
9
+ >>> from akshare_one import get_hist_data, get_realtime_data
10
+ >>> # 获取股票历史数据
11
+ >>> df = get_hist_data("600000", interval="day")
12
+ >>> print(df.head())
13
+ >>> # 获取股票实时数据
14
+ >>> df = get_realtime_data(symbol="600000")
15
+ """
16
+
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()
@@ -6,4 +6,5 @@ CACHE_CONFIG = {
6
6
  "realtime_cache": TTLCache(maxsize=500, ttl=60), # 实时数据缓存1分钟
7
7
  "news_cache": TTLCache(maxsize=500, ttl=3600),
8
8
  "financial_cache": TTLCache(maxsize=500, ttl=86400), # 财务数据缓存24小时
9
+ "info_cache": TTLCache(maxsize=500, ttl=86400), # 信息数据缓存24小时
9
10
  }
@@ -20,3 +20,8 @@ class FinancialDataProvider(ABC):
20
20
  def get_cash_flow(self) -> pd.DataFrame:
21
21
  """Fetches cash flow data"""
22
22
  pass
23
+
24
+ @abstractmethod
25
+ def get_financial_metrics(self) -> pd.DataFrame:
26
+ """Fetch financial metrics"""
27
+ pass
@@ -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