akshare-one 0.3.8__tar.gz → 0.3.9__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 (51) hide show
  1. {akshare_one-0.3.8 → akshare_one-0.3.9}/PKG-INFO +7 -9
  2. {akshare_one-0.3.8 → akshare_one-0.3.9}/pyproject.toml +15 -4
  3. {akshare_one-0.3.8 → akshare_one-0.3.9/src}/akshare_one/eastmoney/client.py +3 -3
  4. {akshare_one-0.3.8 → akshare_one-0.3.9/src}/akshare_one/modules/cache.py +7 -4
  5. {akshare_one-0.3.8 → akshare_one-0.3.9/src}/akshare_one/modules/financial/eastmoney_direct.py +7 -7
  6. {akshare_one-0.3.8 → akshare_one-0.3.9/src}/akshare_one/modules/financial/factory.py +3 -3
  7. {akshare_one-0.3.8 → akshare_one-0.3.9/src}/akshare_one/modules/financial/sina.py +3 -3
  8. {akshare_one-0.3.8 → akshare_one-0.3.9/src}/akshare_one/modules/historical/base.py +2 -2
  9. {akshare_one-0.3.8 → akshare_one-0.3.9/src}/akshare_one/modules/historical/eastmoney.py +1 -1
  10. {akshare_one-0.3.8 → akshare_one-0.3.9/src}/akshare_one/modules/historical/eastmoney_direct.py +2 -1
  11. {akshare_one-0.3.8 → akshare_one-0.3.9/src}/akshare_one/modules/historical/factory.py +4 -4
  12. {akshare_one-0.3.8 → akshare_one-0.3.9/src}/akshare_one/modules/historical/sina.py +2 -2
  13. {akshare_one-0.3.8 → akshare_one-0.3.9/src}/akshare_one/modules/indicators/factory.py +1 -1
  14. {akshare_one-0.3.8 → akshare_one-0.3.9/src}/akshare_one/modules/indicators/simple.py +9 -8
  15. {akshare_one-0.3.8 → akshare_one-0.3.9/src}/akshare_one/modules/indicators/talib.py +3 -3
  16. {akshare_one-0.3.8 → akshare_one-0.3.9/src}/akshare_one/modules/info/eastmoney.py +2 -2
  17. {akshare_one-0.3.8 → akshare_one-0.3.9/src}/akshare_one/modules/info/factory.py +3 -3
  18. {akshare_one-0.3.8 → akshare_one-0.3.9/src}/akshare_one/modules/insider/factory.py +3 -3
  19. {akshare_one-0.3.8 → akshare_one-0.3.9/src}/akshare_one/modules/insider/xueqiu.py +1 -1
  20. {akshare_one-0.3.8 → akshare_one-0.3.9/src}/akshare_one/modules/news/eastmoney.py +1 -1
  21. {akshare_one-0.3.8 → akshare_one-0.3.9/src}/akshare_one/modules/news/factory.py +3 -3
  22. {akshare_one-0.3.8 → akshare_one-0.3.9/src}/akshare_one/modules/realtime/eastmoney.py +1 -1
  23. {akshare_one-0.3.8 → akshare_one-0.3.9/src}/akshare_one/modules/realtime/factory.py +26 -3
  24. {akshare_one-0.3.8 → akshare_one-0.3.9/src}/akshare_one/modules/realtime/xueqiu.py +1 -1
  25. akshare_one-0.3.9/src/akshare_one/py.typed +0 -0
  26. akshare_one-0.3.8/LICENSE +0 -21
  27. akshare_one-0.3.8/akshare_one.egg-info/PKG-INFO +0 -74
  28. akshare_one-0.3.8/akshare_one.egg-info/SOURCES.txt +0 -48
  29. akshare_one-0.3.8/akshare_one.egg-info/dependency_links.txt +0 -1
  30. akshare_one-0.3.8/akshare_one.egg-info/requires.txt +0 -5
  31. akshare_one-0.3.8/akshare_one.egg-info/top_level.txt +0 -1
  32. akshare_one-0.3.8/setup.cfg +0 -4
  33. akshare_one-0.3.8/tests/test_financial.py +0 -107
  34. akshare_one-0.3.8/tests/test_indicators.py +0 -520
  35. akshare_one-0.3.8/tests/test_info.py +0 -82
  36. akshare_one-0.3.8/tests/test_insider.py +0 -66
  37. akshare_one-0.3.8/tests/test_news.py +0 -69
  38. akshare_one-0.3.8/tests/test_stock.py +0 -200
  39. {akshare_one-0.3.8 → akshare_one-0.3.9}/README.md +0 -0
  40. {akshare_one-0.3.8 → akshare_one-0.3.9/src}/akshare_one/__init__.py +0 -0
  41. {akshare_one-0.3.8 → akshare_one-0.3.9/src}/akshare_one/eastmoney/utils.py +0 -0
  42. {akshare_one-0.3.8 → akshare_one-0.3.9/src}/akshare_one/indicators.py +0 -0
  43. {akshare_one-0.3.8 → akshare_one-0.3.9/src}/akshare_one/modules/financial/base.py +0 -0
  44. {akshare_one-0.3.8 → akshare_one-0.3.9/src}/akshare_one/modules/indicators/__init__.py +0 -0
  45. {akshare_one-0.3.8 → akshare_one-0.3.9/src}/akshare_one/modules/indicators/base.py +0 -0
  46. {akshare_one-0.3.8 → akshare_one-0.3.9/src}/akshare_one/modules/info/base.py +0 -0
  47. {akshare_one-0.3.8 → akshare_one-0.3.9/src}/akshare_one/modules/insider/base.py +0 -0
  48. {akshare_one-0.3.8 → akshare_one-0.3.9/src}/akshare_one/modules/news/base.py +0 -0
  49. {akshare_one-0.3.8 → akshare_one-0.3.9/src}/akshare_one/modules/realtime/base.py +0 -0
  50. {akshare_one-0.3.8 → akshare_one-0.3.9/src}/akshare_one/modules/realtime/eastmoney_direct.py +0 -0
  51. {akshare_one-0.3.8 → akshare_one-0.3.9/src}/akshare_one/modules/utils.py +0 -0
@@ -1,19 +1,17 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: akshare-one
3
- Version: 0.3.8
3
+ Version: 0.3.9
4
4
  Summary: Standardized interface for Chinese financial market data, built on AKShare with unified data formats and simplified APIs
5
+ Keywords: akshare,financial-data,stock-data,quant
5
6
  License-Expression: MIT
7
+ Requires-Dist: akshare>=1.17.38
8
+ Requires-Dist: cachetools>=5.5.2
9
+ Requires-Dist: ta-lib>=0.6.4 ; extra == 'talib'
10
+ Requires-Python: >=3.10
6
11
  Project-URL: Homepage, https://github.com/zwldarren/akshare-one
7
12
  Project-URL: Repository, https://github.com/zwldarren/akshare-one.git
8
- Keywords: akshare,financial-data,stock-data,quant
9
- Requires-Python: >=3.10
10
- Description-Content-Type: text/markdown
11
- License-File: LICENSE
12
- Requires-Dist: akshare>=1.17.31
13
- Requires-Dist: cachetools>=5.5.2
14
13
  Provides-Extra: talib
15
- Requires-Dist: ta-lib>=0.6.4; extra == "talib"
16
- Dynamic: license-file
14
+ Description-Content-Type: text/markdown
17
15
 
18
16
  <div align="center">
19
17
  <h1>AKShare One</h1>
@@ -1,11 +1,11 @@
1
1
  [project]
2
2
  name = "akshare-one"
3
- version = "0.3.8"
3
+ version = "0.3.9"
4
4
  description = "Standardized interface for Chinese financial market data, built on AKShare with unified data formats and simplified APIs"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.10"
7
7
  dependencies = [
8
- "akshare>=1.17.31",
8
+ "akshare>=1.17.38",
9
9
  "cachetools>=5.5.2",
10
10
  ]
11
11
  license = "MIT"
@@ -23,17 +23,28 @@ talib = [
23
23
  [dependency-groups]
24
24
  dev = [
25
25
  "mkdocs-material>=9.6.15",
26
+ "mypy>=1.17.1",
27
+ "pandas-stubs>=2.3.0.250703",
26
28
  "pre-commit>=4.2.0",
27
29
  "pytest>=8.4.1",
28
30
  "pytest-cov>=6.2.1",
29
31
  "ruff>=0.12.1",
32
+ "types-cachetools>=6.1.0.20250717",
33
+ "types-requests>=2.32.4.20250809",
30
34
  ]
31
35
 
36
+ [build-system]
37
+ requires = ["uv_build>=0.8.12,<0.9.0"]
38
+ build-backend = "uv_build"
39
+
32
40
  [tool.pytest.ini_options]
33
41
  testpaths = ["tests"]
34
42
  python_files = "test_*.py"
35
43
  python_functions = "test_*"
36
44
  addopts = "-v --cov=akshare_one --cov-report=term-missing"
37
45
 
38
- [tool.setuptools.packages.find]
39
- include = ["akshare_one", "akshare_one.*"]
46
+ [tool.ruff]
47
+ line-length = 88
48
+
49
+ [tool.mypy]
50
+ strict = true
@@ -8,7 +8,7 @@ class EastMoneyClient:
8
8
  This class handles session management, request signing, and API calls.
9
9
  """
10
10
 
11
- def __init__(self):
11
+ def __init__(self) -> None:
12
12
  self.session = requests.Session()
13
13
 
14
14
  def _get_security_id(self, symbol: str) -> str:
@@ -61,7 +61,7 @@ class EastMoneyClient:
61
61
  }
62
62
  response = self.session.get(url, params=params)
63
63
  response.raise_for_status()
64
- return response.json()
64
+ return response.json() # type: ignore
65
65
 
66
66
  def fetch_realtime_quote(self, symbol: str) -> Dict[str, Any]:
67
67
  """
@@ -77,4 +77,4 @@ class EastMoneyClient:
77
77
  }
78
78
  response = self.session.get(url, params=params)
79
79
  response.raise_for_status()
80
- return response.json()
80
+ return response.json() # type: ignore
@@ -1,8 +1,11 @@
1
1
  from cachetools import TTLCache, cached
2
2
  import os
3
+ from typing import Any, Callable, TypeVar, Optional
4
+
5
+ F = TypeVar('F', bound=Callable[..., Any])
3
6
 
4
7
  # 缓存配置
5
- CACHE_CONFIG = {
8
+ CACHE_CONFIG: dict[str, TTLCache[Any, Any]] = {
6
9
  "hist_data_cache": TTLCache(maxsize=1000, ttl=3600), # 历史数据缓存1小时
7
10
  "realtime_cache": TTLCache(maxsize=500, ttl=60), # 实时数据缓存1分钟
8
11
  "news_cache": TTLCache(maxsize=500, ttl=3600), # 新闻数据缓存1小时
@@ -11,7 +14,7 @@ CACHE_CONFIG = {
11
14
  }
12
15
 
13
16
 
14
- def cache(cache_key, key=None):
17
+ def cache(cache_key: str, key: Optional[Callable[..., Any]] = None) -> Callable[[F], F]:
15
18
  cache_enabled = os.getenv("AKSHARE_ONE_CACHE_ENABLED", "true").lower() in (
16
19
  "1",
17
20
  "true",
@@ -19,9 +22,9 @@ def cache(cache_key, key=None):
19
22
  "on",
20
23
  )
21
24
 
22
- def decorator(func):
25
+ def decorator(func: F) -> F:
23
26
  if cache_enabled:
24
- return cached(CACHE_CONFIG[cache_key], key=key)(func)
27
+ return cached(CACHE_CONFIG[cache_key], key=key)(func) # type: ignore
25
28
  return func
26
29
 
27
30
  return decorator
@@ -35,17 +35,17 @@ class EastMoneyDirectFinancialReport(FinancialDataProvider):
35
35
  "CCE_ADD": "change_in_cash_and_equivalents",
36
36
  }
37
37
 
38
- def __init__(self, symbol):
38
+ def __init__(self, symbol: str) -> None:
39
39
  super().__init__(symbol)
40
40
 
41
- def get_income_statement(self):
42
- pass
41
+ def get_income_statement(self) -> pd.DataFrame:
42
+ return pd.DataFrame()
43
43
 
44
- def get_balance_sheet(self):
45
- pass
44
+ def get_balance_sheet(self) -> pd.DataFrame:
45
+ return pd.DataFrame()
46
46
 
47
- def get_cash_flow(self):
48
- pass
47
+ def get_cash_flow(self) -> pd.DataFrame:
48
+ return pd.DataFrame()
49
49
 
50
50
  @cache(
51
51
  "financial_cache",
@@ -14,7 +14,7 @@ class FinancialDataFactory:
14
14
  }
15
15
 
16
16
  @classmethod
17
- def get_provider(cls, provider_name: str, **kwargs) -> FinancialDataProvider:
17
+ def get_provider(cls, provider_name: str, **kwargs) -> FinancialDataProvider: # type: ignore
18
18
  """
19
19
  Get a financial data provider by name
20
20
 
@@ -35,7 +35,7 @@ class FinancialDataFactory:
35
35
  return provider_class(**kwargs)
36
36
 
37
37
  @classmethod
38
- def register_provider(cls, name: str, provider_class: type):
38
+ def register_provider(cls, name: str, provider_class: type) -> None:
39
39
  """
40
40
  Register a new financial data provider
41
41
 
@@ -43,4 +43,4 @@ class FinancialDataFactory:
43
43
  name: Name to associate with this provider
44
44
  provider_class: The provider class to register
45
45
  """
46
- cls._providers[name.lower()] = provider_class
46
+ cls._providers[name.lower()] = provider_class # type: ignore
@@ -1,5 +1,5 @@
1
1
  import pandas as pd
2
- import akshare as ak
2
+ import akshare as ak # type: ignore
3
3
 
4
4
  from ..cache import cache
5
5
  from .base import FinancialDataProvider
@@ -288,5 +288,5 @@ class SinaFinancialReport(FinancialDataProvider):
288
288
  required_columns = ["report_date"] + list(column_mapping.values())
289
289
  return raw_df.rename(columns=column_mapping).reindex(columns=required_columns)
290
290
 
291
- def get_financial_metrics(self):
292
- pass
291
+ def get_financial_metrics(self) -> pd.DataFrame:
292
+ return pd.DataFrame()
@@ -20,7 +20,7 @@ class HistoricalDataProvider(ABC):
20
20
  self.adjust = adjust
21
21
  self._validate_dates()
22
22
 
23
- def _validate_dates(self):
23
+ def _validate_dates(self) -> None:
24
24
  try:
25
25
  pd.to_datetime(self.start_date)
26
26
  pd.to_datetime(self.end_date)
@@ -28,7 +28,7 @@ class HistoricalDataProvider(ABC):
28
28
  raise ValueError("Invalid date format. Please use YYYY-MM-DD.")
29
29
 
30
30
  @classmethod
31
- def get_supported_intervals(cls):
31
+ def get_supported_intervals(cls) -> list[str]:
32
32
  return ["minute", "hour", "day", "week", "month", "year"]
33
33
 
34
34
  @abstractmethod
@@ -1,5 +1,5 @@
1
1
  from .base import HistoricalDataProvider
2
- import akshare as ak
2
+ import akshare as ak # type: ignore
3
3
  import pandas as pd
4
4
  from ..cache import cache
5
5
 
@@ -1,4 +1,5 @@
1
1
  import pandas as pd
2
+ from typing import Any
2
3
  from .base import HistoricalDataProvider
3
4
  from ..cache import cache
4
5
  from akshare_one.eastmoney.client import EastMoneyClient
@@ -8,7 +9,7 @@ from akshare_one.eastmoney.utils import parse_kline_data, resample_historical_da
8
9
  class EastMoneyDirectHistorical(HistoricalDataProvider):
9
10
  """Direct implementation for EastMoney historical stock data API"""
10
11
 
11
- def __init__(self, *args, **kwargs):
12
+ def __init__(self, *args: Any, **kwargs: Any) -> None:
12
13
  super().__init__(*args, **kwargs)
13
14
  self.client = EastMoneyClient()
14
15
 
@@ -16,7 +16,7 @@ class HistoricalDataFactory:
16
16
  }
17
17
 
18
18
  @classmethod
19
- def get_provider(cls, provider_name: str, **kwargs) -> HistoricalDataProvider:
19
+ def get_provider(cls, provider_name: str, **kwargs) -> HistoricalDataProvider: # type: ignore
20
20
  """
21
21
  Get a historical data provider by name
22
22
 
@@ -34,10 +34,10 @@ class HistoricalDataFactory:
34
34
  if not provider_class:
35
35
  raise ValueError(f"Unknown historical data provider: {provider_name}")
36
36
 
37
- return provider_class(**kwargs)
37
+ return provider_class(**kwargs) # type: ignore
38
38
 
39
39
  @classmethod
40
- def register_provider(cls, name: str, provider_class: type):
40
+ def register_provider(cls, name: str, provider_class: type) -> None:
41
41
  """
42
42
  Register a new historical data provider
43
43
 
@@ -45,4 +45,4 @@ class HistoricalDataFactory:
45
45
  name: Name to associate with this provider
46
46
  provider_class: The provider class to register
47
47
  """
48
- cls._providers[name.lower()] = provider_class
48
+ cls._providers[name.lower()] = provider_class # type: ignore
@@ -1,6 +1,6 @@
1
1
  from cachetools import cached
2
2
  from .base import HistoricalDataProvider
3
- import akshare as ak
3
+ import akshare as ak # type: ignore
4
4
  import pandas as pd
5
5
  from ..cache import CACHE_CONFIG
6
6
 
@@ -115,7 +115,7 @@ class SinaHistorical(HistoricalDataProvider):
115
115
 
116
116
  if self.interval_multiplier > 1:
117
117
  freq = f"{self.interval_multiplier}{'min' if self.interval == 'minute' else 'h'}"
118
- raw_df = self._resample_intraday_data(raw_df, freq)
118
+ raw_df = self._resample_data(raw_df, self.interval, self.interval_multiplier)
119
119
  else:
120
120
  raw_df = ak.stock_zh_b_daily(
121
121
  symbol=stock,
@@ -8,7 +8,7 @@ TALIB_AVAILABLE = False
8
8
  try:
9
9
  from .talib import TalibIndicatorCalculator
10
10
 
11
- _calculators["talib"] = TalibIndicatorCalculator
11
+ _calculators["talib"] = TalibIndicatorCalculator # type: ignore
12
12
  TALIB_AVAILABLE = True
13
13
  except ImportError:
14
14
  # talib is optional
@@ -220,13 +220,14 @@ class SimpleIndicatorCalculator(BaseIndicatorCalculator):
220
220
  def calculate_tsf(self, df: pd.DataFrame, window: int) -> pd.DataFrame:
221
221
  close = df["close"]
222
222
 
223
- def linear_reg_forecast(y):
223
+ def linear_reg_forecast(y: np.ndarray) -> float:
224
224
  x = np.arange(1, len(y) + 1)
225
225
  b_num = len(x) * np.sum(x * y) - np.sum(x) * np.sum(y)
226
226
  b_den = len(x) * np.sum(x * x) - np.sum(x) ** 2
227
227
  b = b_num / b_den if b_den != 0 else 0
228
228
  a = np.mean(y) - b * np.mean(x)
229
- return a + b * len(y)
229
+ result = a + b * len(y)
230
+ return float(result)
230
231
 
231
232
  tsf = close.rolling(window=window, min_periods=window).apply(
232
233
  linear_reg_forecast, raw=True
@@ -267,8 +268,8 @@ class SimpleIndicatorCalculator(BaseIndicatorCalculator):
267
268
 
268
269
  def calculate_cmo(self, df: pd.DataFrame, window: int) -> pd.DataFrame:
269
270
  close_diff = df["close"].diff(1)
270
- sum_up = close_diff.where(close_diff > 0, 0).rolling(window=window).sum()
271
- sum_down = -close_diff.where(close_diff < 0, 0).rolling(window=window).sum()
271
+ sum_up = close_diff.where(close_diff > 0, 0).rolling(window=window).sum() # type: ignore
272
+ sum_down = -close_diff.where(close_diff < 0, 0).rolling(window=window).sum() # type: ignore
272
273
  cmo = 100 * (sum_up - sum_down) / (sum_up + sum_down).replace(0, np.nan)
273
274
  cmo = cmo.fillna(0)
274
275
  return cmo.to_frame("cmo")
@@ -284,8 +285,8 @@ class SimpleIndicatorCalculator(BaseIndicatorCalculator):
284
285
  typical_price = (df["high"] + df["low"] + df["close"]) / 3
285
286
  money_flow = typical_price * df["volume"]
286
287
  price_diff = typical_price.diff()
287
- positive_mf = money_flow.where(price_diff > 0, 0)
288
- negative_mf = money_flow.where(price_diff < 0, 0)
288
+ positive_mf = money_flow.where(price_diff > 0, 0) # type: ignore
289
+ negative_mf = money_flow.where(price_diff < 0, 0) # type: ignore
289
290
  positive_mf_sum = positive_mf.rolling(window=window).sum()
290
291
  negative_mf_sum = negative_mf.rolling(window=window).sum()
291
292
  money_ratio = positive_mf_sum / negative_mf_sum.replace(0, np.nan)
@@ -304,7 +305,7 @@ class SimpleIndicatorCalculator(BaseIndicatorCalculator):
304
305
  low = df["low"]
305
306
  up_move = high.diff()
306
307
  down_move = -low.diff()
307
- minus_dm = down_move.where((down_move > up_move) & (down_move > 0), 0)
308
+ minus_dm = down_move.where((down_move > up_move) & (down_move > 0), 0) # type: ignore
308
309
  smoothed_minus_dm = self._wilder_smooth(minus_dm, window)
309
310
  return smoothed_minus_dm.to_frame("minus_dm")
310
311
 
@@ -319,7 +320,7 @@ class SimpleIndicatorCalculator(BaseIndicatorCalculator):
319
320
  low = df["low"]
320
321
  up_move = high.diff()
321
322
  down_move = -low.diff()
322
- plus_dm = up_move.where((up_move > down_move) & (up_move > 0), 0)
323
+ plus_dm = up_move.where((up_move > down_move) & (up_move > 0), 0) # type: ignore
323
324
  smoothed_plus_dm = self._wilder_smooth(plus_dm, window)
324
325
  return smoothed_plus_dm.to_frame("plus_dm")
325
326
 
@@ -1,4 +1,4 @@
1
- import talib
1
+ import talib # type: ignore
2
2
  import pandas as pd
3
3
  from .base import BaseIndicatorCalculator
4
4
 
@@ -136,7 +136,7 @@ class TalibIndicatorCalculator(BaseIndicatorCalculator):
136
136
  return pd.DataFrame({"tsf": tsf}, index=df.index)
137
137
 
138
138
  def calculate_apo(
139
- self, df: pd.DataFrame, fast_period: int, slow_period: int, ma_type
139
+ self, df: pd.DataFrame, fast_period: int, slow_period: int, ma_type: int
140
140
  ) -> pd.DataFrame:
141
141
  close = df["close"].values
142
142
  apo = talib.APO(
@@ -213,7 +213,7 @@ class TalibIndicatorCalculator(BaseIndicatorCalculator):
213
213
  return pd.DataFrame({"plus_dm": plus_dm}, index=df.index)
214
214
 
215
215
  def calculate_ppo(
216
- self, df: pd.DataFrame, fast_period: int, slow_period: int, ma_type
216
+ self, df: pd.DataFrame, fast_period: int, slow_period: int, ma_type: int
217
217
  ) -> pd.DataFrame:
218
218
  close = df["close"].values
219
219
  ppo = talib.PPO(
@@ -1,5 +1,5 @@
1
1
  import pandas as pd
2
- import akshare as ak
2
+ import akshare as ak # type: ignore
3
3
 
4
4
  from ..cache import cache
5
5
  from .base import InfoDataProvider
@@ -48,4 +48,4 @@ class EastmoneyInfo(InfoDataProvider):
48
48
  if col in info_df.columns:
49
49
  info_df[col] = pd.to_numeric(info_df[col], errors="coerce")
50
50
 
51
- return info_df
51
+ return info_df # type: ignore
@@ -12,7 +12,7 @@ class InfoDataFactory:
12
12
  }
13
13
 
14
14
  @classmethod
15
- def get_provider(cls, provider_name: str, **kwargs) -> InfoDataProvider:
15
+ def get_provider(cls, provider_name: str, **kwargs) -> InfoDataProvider: # type: ignore
16
16
  """
17
17
  Get a info data provider by name
18
18
 
@@ -33,7 +33,7 @@ class InfoDataFactory:
33
33
  return provider_class(**kwargs)
34
34
 
35
35
  @classmethod
36
- def register_provider(cls, name: str, provider_class: type):
36
+ def register_provider(cls, name: str, provider_class: type) -> None:
37
37
  """
38
38
  Register a new info data provider
39
39
 
@@ -41,4 +41,4 @@ class InfoDataFactory:
41
41
  name: Name to associate with this provider
42
42
  provider_class: The provider class to register
43
43
  """
44
- cls._providers[name.lower()] = provider_class
44
+ cls._providers[name.lower()] = provider_class # type: ignore
@@ -12,7 +12,7 @@ class InsiderDataFactory:
12
12
  }
13
13
 
14
14
  @classmethod
15
- def get_provider(cls, provider_name: str, **kwargs) -> InsiderDataProvider:
15
+ def get_provider(cls, provider_name: str, **kwargs) -> InsiderDataProvider: # type: ignore
16
16
  """
17
17
  Get an insider data provider by name
18
18
 
@@ -33,7 +33,7 @@ class InsiderDataFactory:
33
33
  return provider_class(**kwargs)
34
34
 
35
35
  @classmethod
36
- def register_provider(cls, name: str, provider_class: type):
36
+ def register_provider(cls, name: str, provider_class: type) -> None:
37
37
  """
38
38
  Register a new insider data provider
39
39
 
@@ -41,4 +41,4 @@ class InsiderDataFactory:
41
41
  name: Name to associate with this provider
42
42
  provider_class: The provider class to register
43
43
  """
44
- cls._providers[name.lower()] = provider_class
44
+ cls._providers[name.lower()] = provider_class # type: ignore
@@ -1,5 +1,5 @@
1
1
  import pandas as pd
2
- import akshare as ak
2
+ import akshare as ak # type: ignore
3
3
  from .base import InsiderDataProvider
4
4
  from ..utils import convert_xieqiu_symbol
5
5
  from ..cache import cache
@@ -1,5 +1,5 @@
1
1
  import pandas as pd
2
- import akshare as ak
2
+ import akshare as ak # type: ignore
3
3
 
4
4
  from ..cache import cache
5
5
  from .base import NewsDataProvider
@@ -12,7 +12,7 @@ class NewsDataFactory:
12
12
  }
13
13
 
14
14
  @classmethod
15
- def get_provider(cls, provider_name: str, **kwargs) -> NewsDataProvider:
15
+ def get_provider(cls, provider_name: str, **kwargs) -> NewsDataProvider: # type: ignore
16
16
  """
17
17
  Get a news data provider by name
18
18
 
@@ -33,7 +33,7 @@ class NewsDataFactory:
33
33
  return provider_class(**kwargs)
34
34
 
35
35
  @classmethod
36
- def register_provider(cls, name: str, provider_class: type):
36
+ def register_provider(cls, name: str, provider_class: type) -> None:
37
37
  """
38
38
  Register a new news data provider
39
39
 
@@ -41,4 +41,4 @@ class NewsDataFactory:
41
41
  name: Name to associate with this provider
42
42
  provider_class: The provider class to register
43
43
  """
44
- cls._providers[name.lower()] = provider_class
44
+ cls._providers[name.lower()] = provider_class # type: ignore
@@ -1,5 +1,5 @@
1
1
  import pandas as pd
2
- import akshare as ak
2
+ import akshare as ak # type: ignore
3
3
 
4
4
  from ..cache import cache
5
5
  from .base import RealtimeDataProvider
@@ -9,14 +9,37 @@ class RealtimeDataFactory:
9
9
  Factory class for creating realtime data providers
10
10
  """
11
11
 
12
- _providers = {
12
+ _providers: dict[str, type["RealtimeDataProvider"]] = {
13
13
  "eastmoney": EastmoneyRealtime,
14
14
  "xueqiu": XueQiuRealtime,
15
15
  "eastmoney_direct": EastMoneyDirectRealtime,
16
16
  }
17
17
 
18
18
  @classmethod
19
- def get_provider(cls, provider_name: str, **kwargs) -> RealtimeDataProvider:
19
+ def get_provider(cls, provider_name: str, **kwargs: object) -> "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
+ # Extract symbol from kwargs if present
38
+ symbol = kwargs.get("symbol", "")
39
+ if not isinstance(symbol, str):
40
+ raise ValueError("symbol must be a string")
41
+
42
+ return provider_class(symbol=symbol)
20
43
  """
21
44
  Get a realtime data provider by name
22
45
 
@@ -37,7 +60,7 @@ class RealtimeDataFactory:
37
60
  return provider_class(**kwargs)
38
61
 
39
62
  @classmethod
40
- def register_provider(cls, name: str, provider_class: type):
63
+ def register_provider(cls, name: str, provider_class: type) -> None:
41
64
  """
42
65
  Register a new realtime data provider
43
66
 
@@ -1,5 +1,5 @@
1
1
  import pandas as pd
2
- import akshare as ak
2
+ import akshare as ak # type: ignore
3
3
  from ..utils import convert_xieqiu_symbol
4
4
  from ..cache import cache
5
5
  from .base import RealtimeDataProvider
File without changes
akshare_one-0.3.8/LICENSE DELETED
@@ -1,21 +0,0 @@
1
- MIT License
2
-
3
- Copyright (c) 2025 zwldarren
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
@@ -1,74 +0,0 @@
1
- Metadata-Version: 2.4
2
- Name: akshare-one
3
- Version: 0.3.8
4
- Summary: Standardized interface for Chinese financial market data, built on AKShare with unified data formats and simplified APIs
5
- License-Expression: MIT
6
- Project-URL: Homepage, https://github.com/zwldarren/akshare-one
7
- Project-URL: Repository, https://github.com/zwldarren/akshare-one.git
8
- Keywords: akshare,financial-data,stock-data,quant
9
- Requires-Python: >=3.10
10
- Description-Content-Type: text/markdown
11
- License-File: LICENSE
12
- Requires-Dist: akshare>=1.17.31
13
- Requires-Dist: cachetools>=5.5.2
14
- Provides-Extra: talib
15
- Requires-Dist: ta-lib>=0.6.4; extra == "talib"
16
- Dynamic: license-file
17
-
18
- <div align="center">
19
- <h1>AKShare One</h1>
20
- <div>
21
- <a href="README_zh.md">中文</a> | <strong>English</strong>
22
- </div>
23
- </div>
24
-
25
- **AKShare One** is a data interface for obtaining Chinese A-shares, based on [AKShare](https://github.com/akfamily/akshare). It aims to simplify AKShare's usage and unify input/output formats from different data sources, making it easier to pass data to LLM.
26
-
27
- ## ✨ Features
28
-
29
- - 📊 Unified stock code formats across data sources
30
- - 🏗️ Standardized return data structures
31
- - 🛠️ Simplified API parameter design
32
- - ⏱️ Automatic timestamp and adjustment handling
33
-
34
- ## 🚀 Core Features
35
-
36
- | Function | Interface |
37
- |------|------|
38
- | Historical data | `get_hist_data` |
39
- | Real-time quotes | `get_realtime_data` |
40
- | Stock news | `get_news_data` |
41
- | Financial data | `get_balance_sheet`/`get_income_statement`/`get_cash_flow` |
42
- | Internal transactions | `get_inner_trade_data` |
43
- | Basic stock info | `get_basic_info` |
44
- | Financial metrics | `get_financial_metrics` |
45
- | Technical indicators | See [indicators.py](akshare-one/indicators.py) |
46
-
47
- ## 📦 Quick Installation
48
-
49
- ```bash
50
- pip install akshare-one
51
- ```
52
-
53
- ## 💻 Usage Example
54
-
55
- ```python
56
- from akshare_one import get_hist_data
57
- from akshare_one.indicators import get_sma
58
-
59
- # Get historical data
60
- df = get_hist_data(
61
- symbol="600000",
62
- interval="day",
63
- adjust="hfq"
64
- )
65
-
66
- # Calculate 20-day Simple Moving Average
67
- df_sma = get_sma(df, window=20)
68
- ```
69
-
70
- ## 📚 Documentation
71
-
72
- Full API documentation is now available on GitHub Pages:
73
-
74
- https://zwldarren.github.io/akshare-one/