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 CHANGED
@@ -14,18 +14,201 @@ Example:
14
14
  >>> df = get_realtime_data(symbol="600000")
15
15
  """
16
16
 
17
- from .stock import get_hist_data, get_realtime_data
18
- from .news import get_news_data
19
- from .insider import get_inner_trade_data
20
- from .financial import get_balance_sheet, get_income_statement, get_cash_flow
21
-
22
-
23
- __all__ = [
24
- "get_hist_data",
25
- "get_realtime_data",
26
- "get_news_data",
27
- "get_inner_trade_data",
28
- "get_balance_sheet",
29
- "get_income_statement",
30
- "get_cash_flow",
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()
@@ -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
@@ -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
- if "更新日期" in raw_df.columns:
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
- "自由现金流": "free_cash_flow",
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
- # Filter columns
112
- available_columns = [col for col in required_columns if col in raw_df.columns]
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
- if "更新日期" in raw_df.columns:
132
- raw_df = raw_df.rename(columns={"更新日期": "update_time"})
133
- raw_df["update_time"] = pd.to_datetime(raw_df["update_time"])
134
-
135
- # Standardize column names
136
- column_mapping = {
137
- "类型": "report_type",
138
- "币种": "currency",
139
- "资产总计": "total_assets",
140
- "流动资产合计": "current_assets",
141
- "货币资金": "cash_and_equivalents",
142
- "存货": "inventory",
143
- "交易性金融资产": "current_investments",
144
- "应收票据及应收账款": "trade_and_non_trade_receivables",
145
- "非流动资产合计": "non_current_assets",
146
- "固定资产": "property_plant_and_equipment",
147
- "商誉": "goodwill_and_intangible_assets",
148
- "长期股权投资": "investments",
149
- "其他非流动金融资产": "non_current_investments",
150
- "实收资本(或股本)": "outstanding_shares",
151
- "递延所得税资产": "tax_assets",
152
- "负债合计": "total_liabilities",
153
- "流动负债合计": "current_liabilities",
154
- "短期借款": "current_debt",
155
- "应付票据及应付账款": "trade_and_non_trade_payables",
156
- "合同负债": "deferred_revenue",
157
- "吸收存款及同业存放": "deposit_liabilities",
158
- "非流动负债合计": "non_current_liabilities",
159
- "长期借款": "non_current_debt",
160
- "递延所得税负债": "tax_liabilities",
161
- "所有者权益(或股东权益)合计": "shareholders_equity",
162
- "未分配利润": "retained_earnings",
163
- "其他综合收益": "accumulated_other_comprehensive_income",
164
- }
165
- raw_df = raw_df.rename(columns=column_mapping)
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 total_debt
201
- if "current_debt" in raw_df.columns and "non_current_debt" in raw_df.columns:
202
- raw_df["total_debt"] = raw_df["current_debt"] + raw_df["non_current_debt"]
203
- required_columns.append("total_debt")
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
- # Filter columns
206
- available_columns = [col for col in required_columns if col in raw_df.columns]
207
- return raw_df[available_columns]
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
- if "更新日期" in raw_df.columns:
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
- # Select only required columns
251
- required_columns = [
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
- # Filter columns
272
- available_columns = [col for col in required_columns if col in raw_df.columns]
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.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
@@ -1,16 +1,13 @@
1
- akshare_one/__init__.py,sha256=W8FpPEXHDYu6JKPuAXylA3fpFt_axj3vNQC_kevjmY8,909
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/insider.py,sha256=ugr7TXjZvHkaQ-3cNmXeo9LCUqfmcbIwQx-gs-RItAA,1125
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=D-leZAXdKe5srbB4rrxdjNc8TWk2bflt7qtL_KBddY0,558
12
- akshare_one/modules/financial/factory.py,sha256=Lv66xSmmQyE8jZZvnYcgl_oZ0VUmBISN2yegsN38_oM,1345
13
- akshare_one/modules/financial/sina.py,sha256=xKR8RqePfi_vFBntet7e5xjvYHolVrXfOJHRK4x54b4,11187
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.2.dist-info/licenses/LICENSE,sha256=3bqxoD7aU4QS7kpNtQmRd4MikxXe6Gtm_DrojyFHGAc,1087
36
- akshare_one-0.3.2.dist-info/METADATA,sha256=1qV4rAqnvSDrYHQHbtho8lJgXhzCvbbSdfvup6zk400,2132
37
- akshare_one-0.3.2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
38
- akshare_one-0.3.2.dist-info/top_level.txt,sha256=kNiucyLVAGa89wmUSpXbBLWD7pF_RuahuiaOfLHZSyw,12
39
- akshare_one-0.3.2.dist-info/RECORD,,
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()