akshare-one 0.2.2__py3-none-any.whl → 0.3.0__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.
Files changed (40) hide show
  1. akshare_one/__init__.py +31 -31
  2. akshare_one/financial.py +46 -46
  3. akshare_one/indicators.py +395 -0
  4. akshare_one/insider.py +33 -33
  5. akshare_one/modules/cache.py +9 -9
  6. akshare_one/modules/eastmoney/client.py +88 -88
  7. akshare_one/modules/eastmoney/utils.py +104 -104
  8. akshare_one/modules/financial/base.py +22 -22
  9. akshare_one/modules/financial/factory.py +44 -44
  10. akshare_one/modules/financial/sina.py +273 -273
  11. akshare_one/modules/historical/base.py +47 -39
  12. akshare_one/modules/historical/eastmoney.py +241 -241
  13. akshare_one/modules/historical/eastmoney_direct.py +79 -79
  14. akshare_one/modules/historical/factory.py +48 -48
  15. akshare_one/modules/historical/sina.py +218 -218
  16. akshare_one/modules/indicators/__init__.py +0 -0
  17. akshare_one/modules/indicators/base.py +158 -0
  18. akshare_one/modules/indicators/factory.py +33 -0
  19. akshare_one/modules/indicators/simple.py +230 -0
  20. akshare_one/modules/indicators/talib.py +263 -0
  21. akshare_one/modules/insider/base.py +28 -28
  22. akshare_one/modules/insider/factory.py +44 -44
  23. akshare_one/modules/insider/xueqiu.py +115 -115
  24. akshare_one/modules/news/base.py +22 -22
  25. akshare_one/modules/news/eastmoney.py +47 -47
  26. akshare_one/modules/news/factory.py +44 -44
  27. akshare_one/modules/realtime/base.py +27 -27
  28. akshare_one/modules/realtime/eastmoney.py +57 -57
  29. akshare_one/modules/realtime/eastmoney_direct.py +37 -37
  30. akshare_one/modules/realtime/factory.py +48 -48
  31. akshare_one/modules/realtime/xueqiu.py +60 -60
  32. akshare_one/modules/utils.py +10 -10
  33. akshare_one/news.py +27 -27
  34. akshare_one/stock.py +78 -78
  35. {akshare_one-0.2.2.dist-info → akshare_one-0.3.0.dist-info}/METADATA +70 -66
  36. akshare_one-0.3.0.dist-info/RECORD +39 -0
  37. {akshare_one-0.2.2.dist-info → akshare_one-0.3.0.dist-info}/licenses/LICENSE +21 -21
  38. akshare_one-0.2.2.dist-info/RECORD +0 -33
  39. {akshare_one-0.2.2.dist-info → akshare_one-0.3.0.dist-info}/WHEEL +0 -0
  40. {akshare_one-0.2.2.dist-info → akshare_one-0.3.0.dist-info}/top_level.txt +0 -0
@@ -1,57 +1,57 @@
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 RealtimeDataProvider
7
-
8
-
9
- class EastmoneyRealtime(RealtimeDataProvider):
10
- @cached(
11
- CACHE_CONFIG["realtime_cache"],
12
- key=lambda self, symbol=None: f"eastmoney_{symbol if symbol else 'all'}",
13
- )
14
- def get_current_data(self) -> pd.DataFrame:
15
- """获取沪深京A股实时行情数据"""
16
- raw_df = ak.stock_zh_a_spot_em()
17
- df = self._clean_spot_data(raw_df)
18
- if self.symbol:
19
- df = df[df["symbol"] == self.symbol].reset_index(drop=True)
20
- return df
21
-
22
- def _clean_spot_data(self, raw_df: pd.DataFrame) -> pd.DataFrame:
23
- """清理和标准化实时行情数据"""
24
- column_mapping = {
25
- "代码": "symbol",
26
- "最新价": "price",
27
- "涨跌额": "change",
28
- "涨跌幅": "pct_change",
29
- "成交量": "volume",
30
- "成交额": "amount",
31
- "今开": "open",
32
- "最高": "high",
33
- "最低": "low",
34
- "昨收": "prev_close",
35
- }
36
-
37
- df = raw_df.rename(columns=column_mapping)
38
-
39
- # Change time to UTC
40
- df = df.assign(
41
- timestamp=lambda x: pd.Timestamp.now(tz="Asia/Shanghai").tz_convert("UTC")
42
- )
43
-
44
- required_columns = [
45
- "symbol",
46
- "price",
47
- "change",
48
- "pct_change",
49
- "timestamp",
50
- "volume",
51
- "amount",
52
- "open",
53
- "high",
54
- "low",
55
- "prev_close",
56
- ]
57
- return df[required_columns]
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 RealtimeDataProvider
7
+
8
+
9
+ class EastmoneyRealtime(RealtimeDataProvider):
10
+ @cached(
11
+ CACHE_CONFIG["realtime_cache"],
12
+ key=lambda self, symbol=None: f"eastmoney_{symbol if symbol else 'all'}",
13
+ )
14
+ def get_current_data(self) -> pd.DataFrame:
15
+ """获取沪深京A股实时行情数据"""
16
+ raw_df = ak.stock_zh_a_spot_em()
17
+ df = self._clean_spot_data(raw_df)
18
+ if self.symbol:
19
+ df = df[df["symbol"] == self.symbol].reset_index(drop=True)
20
+ return df
21
+
22
+ def _clean_spot_data(self, raw_df: pd.DataFrame) -> pd.DataFrame:
23
+ """清理和标准化实时行情数据"""
24
+ column_mapping = {
25
+ "代码": "symbol",
26
+ "最新价": "price",
27
+ "涨跌额": "change",
28
+ "涨跌幅": "pct_change",
29
+ "成交量": "volume",
30
+ "成交额": "amount",
31
+ "今开": "open",
32
+ "最高": "high",
33
+ "最低": "low",
34
+ "昨收": "prev_close",
35
+ }
36
+
37
+ df = raw_df.rename(columns=column_mapping)
38
+
39
+ # Change time to UTC
40
+ df = df.assign(
41
+ timestamp=lambda x: pd.Timestamp.now(tz="Asia/Shanghai").tz_convert("UTC")
42
+ )
43
+
44
+ required_columns = [
45
+ "symbol",
46
+ "price",
47
+ "change",
48
+ "pct_change",
49
+ "timestamp",
50
+ "volume",
51
+ "amount",
52
+ "open",
53
+ "high",
54
+ "low",
55
+ "prev_close",
56
+ ]
57
+ return df[required_columns]
@@ -1,37 +1,37 @@
1
- import pandas as pd
2
- from cachetools import cached
3
- from .base import RealtimeDataProvider
4
- from ..cache import CACHE_CONFIG
5
- from ..eastmoney.client import EastMoneyClient
6
- from ..eastmoney.utils import parse_realtime_data
7
-
8
-
9
- class EastMoneyDirectRealtime(RealtimeDataProvider):
10
- """Direct implementation for EastMoney realtime stock data API"""
11
-
12
- def __init__(self, symbol: str):
13
- super().__init__(symbol)
14
- self.client = EastMoneyClient()
15
-
16
- @cached(
17
- cache=CACHE_CONFIG["realtime_cache"],
18
- key=lambda self: f"eastmoney_direct_realtime_{self.symbol}",
19
- )
20
- def get_current_data(self) -> pd.DataFrame:
21
- """Get real-time stock data"""
22
- try:
23
- raw_data = self.client.fetch_realtime_quote(self.symbol)
24
-
25
- if raw_data.get("rc") != 0:
26
- raise ValueError(f"API returned error: {raw_data.get('msg')}")
27
-
28
- df = parse_realtime_data(raw_data)
29
-
30
- # Ensure the output matches the base class definition
31
- if self.symbol:
32
- df = df[df["symbol"] == self.symbol].reset_index(drop=True)
33
-
34
- return df
35
-
36
- except Exception as e:
37
- raise ValueError(f"Failed to get real-time data for {self.symbol}: {e}")
1
+ import pandas as pd
2
+ from cachetools import cached
3
+ from .base import RealtimeDataProvider
4
+ from ..cache import CACHE_CONFIG
5
+ from ..eastmoney.client import EastMoneyClient
6
+ from ..eastmoney.utils import parse_realtime_data
7
+
8
+
9
+ class EastMoneyDirectRealtime(RealtimeDataProvider):
10
+ """Direct implementation for EastMoney realtime stock data API"""
11
+
12
+ def __init__(self, symbol: str):
13
+ super().__init__(symbol)
14
+ self.client = EastMoneyClient()
15
+
16
+ @cached(
17
+ cache=CACHE_CONFIG["realtime_cache"],
18
+ key=lambda self: f"eastmoney_direct_realtime_{self.symbol}",
19
+ )
20
+ def get_current_data(self) -> pd.DataFrame:
21
+ """Get real-time stock data"""
22
+ try:
23
+ raw_data = self.client.fetch_realtime_quote(self.symbol)
24
+
25
+ if raw_data.get("rc") != 0:
26
+ raise ValueError(f"API returned error: {raw_data.get('msg')}")
27
+
28
+ df = parse_realtime_data(raw_data)
29
+
30
+ # Ensure the output matches the base class definition
31
+ if self.symbol:
32
+ df = df[df["symbol"] == self.symbol].reset_index(drop=True)
33
+
34
+ return df
35
+
36
+ except Exception as e:
37
+ raise ValueError(f"Failed to get real-time data for {self.symbol}: {e}")
@@ -1,48 +1,48 @@
1
- from .eastmoney import EastmoneyRealtime
2
- from .xueqiu import XueQiuRealtime
3
- from .base import RealtimeDataProvider
4
- from .eastmoney_direct import EastMoneyDirectRealtime
5
-
6
-
7
- class RealtimeDataFactory:
8
- """
9
- Factory class for creating realtime data providers
10
- """
11
-
12
- _providers = {
13
- "eastmoney": EastmoneyRealtime,
14
- "xueqiu": XueQiuRealtime,
15
- "eastmoney_direct": EastMoneyDirectRealtime,
16
- }
17
-
18
- @classmethod
19
- def get_provider(cls, provider_name: str, **kwargs) -> RealtimeDataProvider:
20
- """
21
- Get a realtime data provider by name
22
-
23
- Args:
24
- provider_name: Name of the provider (e.g., 'eastmoney')
25
- **kwargs: Additional arguments to pass to the provider's constructor
26
-
27
- Returns:
28
- RealtimeDataProvider: An instance of the requested provider
29
-
30
- Raises:
31
- ValueError: If the requested provider is not found
32
- """
33
- provider_class = cls._providers.get(provider_name.lower())
34
- if not provider_class:
35
- raise ValueError(f"Unknown realtime data provider: {provider_name}")
36
-
37
- return provider_class(**kwargs)
38
-
39
- @classmethod
40
- def register_provider(cls, name: str, provider_class: type):
41
- """
42
- Register a new realtime data provider
43
-
44
- Args:
45
- name: Name to associate with this provider
46
- provider_class: The provider class to register
47
- """
48
- cls._providers[name.lower()] = provider_class
1
+ from .eastmoney import EastmoneyRealtime
2
+ from .xueqiu import XueQiuRealtime
3
+ from .base import RealtimeDataProvider
4
+ from .eastmoney_direct import EastMoneyDirectRealtime
5
+
6
+
7
+ class RealtimeDataFactory:
8
+ """
9
+ Factory class for creating realtime data providers
10
+ """
11
+
12
+ _providers = {
13
+ "eastmoney": EastmoneyRealtime,
14
+ "xueqiu": XueQiuRealtime,
15
+ "eastmoney_direct": EastMoneyDirectRealtime,
16
+ }
17
+
18
+ @classmethod
19
+ def get_provider(cls, provider_name: str, **kwargs) -> RealtimeDataProvider:
20
+ """
21
+ Get a realtime data provider by name
22
+
23
+ Args:
24
+ provider_name: Name of the provider (e.g., 'eastmoney')
25
+ **kwargs: Additional arguments to pass to the provider's constructor
26
+
27
+ Returns:
28
+ RealtimeDataProvider: An instance of the requested provider
29
+
30
+ Raises:
31
+ ValueError: If the requested provider is not found
32
+ """
33
+ provider_class = cls._providers.get(provider_name.lower())
34
+ if not provider_class:
35
+ raise ValueError(f"Unknown realtime data provider: {provider_name}")
36
+
37
+ return provider_class(**kwargs)
38
+
39
+ @classmethod
40
+ def register_provider(cls, name: str, provider_class: type):
41
+ """
42
+ Register a new realtime data provider
43
+
44
+ Args:
45
+ name: Name to associate with this provider
46
+ provider_class: The provider class to register
47
+ """
48
+ cls._providers[name.lower()] = provider_class
@@ -1,60 +1,60 @@
1
- from cachetools import cached
2
- import pandas as pd
3
- import akshare as ak
4
- from ..utils import convert_xieqiu_symbol
5
- from ..cache import CACHE_CONFIG
6
- from .base import RealtimeDataProvider
7
-
8
-
9
- class XueQiuRealtime(RealtimeDataProvider):
10
- @cached(
11
- cache=CACHE_CONFIG["realtime_cache"],
12
- key=lambda self, symbol=None: f"xueqiu_{symbol}",
13
- )
14
- def get_current_data(self) -> pd.DataFrame:
15
- """获取雪球实时行情数据
16
-
17
- Args:
18
- symbol: 股票代码 ("600000")
19
-
20
- Returns:
21
- pd.DataFrame with columns:
22
- - symbol: 股票代码
23
- - price: 最新价
24
- - change: 涨跌额
25
- - pct_change: 涨跌幅(%)
26
- - timestamp: 时间戳
27
- - volume: 成交量(手)
28
- - amount: 成交额(元)
29
- - open: 今开
30
- - high: 最高
31
- - low: 最低
32
- - prev_close: 昨收
33
- """
34
- raw_df = ak.stock_individual_spot_xq(symbol=convert_xieqiu_symbol(self.symbol))
35
-
36
- # Transform to match standard format
37
- data = {
38
- "symbol": self.symbol,
39
- "price": float(raw_df.loc[raw_df["item"] == "现价", "value"].values[0]),
40
- "change": float(raw_df.loc[raw_df["item"] == "涨跌", "value"].values[0]),
41
- "pct_change": float(
42
- raw_df.loc[raw_df["item"] == "涨幅", "value"].values[0]
43
- ),
44
- "timestamp": pd.to_datetime(
45
- raw_df.loc[raw_df["item"] == "时间", "value"].values[0]
46
- )
47
- .tz_localize("Asia/Shanghai")
48
- .tz_convert("UTC"),
49
- "volume": int(raw_df.loc[raw_df["item"] == "成交量", "value"].values[0])
50
- / 100,
51
- "amount": float(raw_df.loc[raw_df["item"] == "成交额", "value"].values[0]),
52
- "open": float(raw_df.loc[raw_df["item"] == "今开", "value"].values[0]),
53
- "high": float(raw_df.loc[raw_df["item"] == "最高", "value"].values[0]),
54
- "low": float(raw_df.loc[raw_df["item"] == "最低", "value"].values[0]),
55
- "prev_close": float(
56
- raw_df.loc[raw_df["item"] == "昨收", "value"].values[0]
57
- ),
58
- }
59
-
60
- return pd.DataFrame([data])
1
+ from cachetools import cached
2
+ import pandas as pd
3
+ import akshare as ak
4
+ from ..utils import convert_xieqiu_symbol
5
+ from ..cache import CACHE_CONFIG
6
+ from .base import RealtimeDataProvider
7
+
8
+
9
+ class XueQiuRealtime(RealtimeDataProvider):
10
+ @cached(
11
+ cache=CACHE_CONFIG["realtime_cache"],
12
+ key=lambda self, symbol=None: f"xueqiu_{symbol}",
13
+ )
14
+ def get_current_data(self) -> pd.DataFrame:
15
+ """获取雪球实时行情数据
16
+
17
+ Args:
18
+ symbol: 股票代码 ("600000")
19
+
20
+ Returns:
21
+ pd.DataFrame with columns:
22
+ - symbol: 股票代码
23
+ - price: 最新价
24
+ - change: 涨跌额
25
+ - pct_change: 涨跌幅(%)
26
+ - timestamp: 时间戳
27
+ - volume: 成交量(手)
28
+ - amount: 成交额(元)
29
+ - open: 今开
30
+ - high: 最高
31
+ - low: 最低
32
+ - prev_close: 昨收
33
+ """
34
+ raw_df = ak.stock_individual_spot_xq(symbol=convert_xieqiu_symbol(self.symbol))
35
+
36
+ # Transform to match standard format
37
+ data = {
38
+ "symbol": self.symbol,
39
+ "price": float(raw_df.loc[raw_df["item"] == "现价", "value"].values[0]),
40
+ "change": float(raw_df.loc[raw_df["item"] == "涨跌", "value"].values[0]),
41
+ "pct_change": float(
42
+ raw_df.loc[raw_df["item"] == "涨幅", "value"].values[0]
43
+ ),
44
+ "timestamp": pd.to_datetime(
45
+ raw_df.loc[raw_df["item"] == "时间", "value"].values[0]
46
+ )
47
+ .tz_localize("Asia/Shanghai")
48
+ .tz_convert("UTC"),
49
+ "volume": int(raw_df.loc[raw_df["item"] == "成交量", "value"].values[0])
50
+ / 100,
51
+ "amount": float(raw_df.loc[raw_df["item"] == "成交额", "value"].values[0]),
52
+ "open": float(raw_df.loc[raw_df["item"] == "今开", "value"].values[0]),
53
+ "high": float(raw_df.loc[raw_df["item"] == "最高", "value"].values[0]),
54
+ "low": float(raw_df.loc[raw_df["item"] == "最低", "value"].values[0]),
55
+ "prev_close": float(
56
+ raw_df.loc[raw_df["item"] == "昨收", "value"].values[0]
57
+ ),
58
+ }
59
+
60
+ return pd.DataFrame([data])
@@ -1,10 +1,10 @@
1
- def convert_xieqiu_symbol(symbol: str) -> str:
2
- """
3
- Convert Symbol (600000) to XueQiu Symbol (SH600000)
4
- """
5
- if symbol.startswith("6"):
6
- return f"SH{symbol}"
7
- elif symbol.startswith("0") or symbol.startswith("3"):
8
- return f"SZ{symbol}"
9
- else: # TODO: add more cases
10
- return symbol
1
+ def convert_xieqiu_symbol(symbol: str) -> str:
2
+ """
3
+ Convert Symbol (600000) to XueQiu Symbol (SH600000)
4
+ """
5
+ if symbol.startswith("6"):
6
+ return f"SH{symbol}"
7
+ elif symbol.startswith("0") or symbol.startswith("3"):
8
+ return f"SZ{symbol}"
9
+ else: # TODO: add more cases
10
+ return symbol
akshare_one/news.py CHANGED
@@ -1,27 +1,27 @@
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()
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 CHANGED
@@ -1,78 +1,78 @@
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()
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()