akshare-one 0.3.8__tar.gz → 0.3.10__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.
- {akshare_one-0.3.8 → akshare_one-0.3.10}/PKG-INFO +7 -9
- {akshare_one-0.3.8 → akshare_one-0.3.10}/pyproject.toml +15 -4
- {akshare_one-0.3.8 → akshare_one-0.3.10/src}/akshare_one/eastmoney/client.py +3 -3
- {akshare_one-0.3.8 → akshare_one-0.3.10/src}/akshare_one/modules/cache.py +7 -4
- {akshare_one-0.3.8 → akshare_one-0.3.10/src}/akshare_one/modules/financial/eastmoney_direct.py +7 -7
- {akshare_one-0.3.8 → akshare_one-0.3.10/src}/akshare_one/modules/financial/factory.py +3 -3
- {akshare_one-0.3.8 → akshare_one-0.3.10/src}/akshare_one/modules/financial/sina.py +3 -3
- {akshare_one-0.3.8 → akshare_one-0.3.10/src}/akshare_one/modules/historical/base.py +2 -2
- {akshare_one-0.3.8 → akshare_one-0.3.10/src}/akshare_one/modules/historical/eastmoney.py +1 -1
- {akshare_one-0.3.8 → akshare_one-0.3.10/src}/akshare_one/modules/historical/eastmoney_direct.py +2 -1
- {akshare_one-0.3.8 → akshare_one-0.3.10/src}/akshare_one/modules/historical/factory.py +4 -4
- {akshare_one-0.3.8 → akshare_one-0.3.10/src}/akshare_one/modules/historical/sina.py +2 -2
- {akshare_one-0.3.8 → akshare_one-0.3.10/src}/akshare_one/modules/indicators/factory.py +1 -1
- {akshare_one-0.3.8 → akshare_one-0.3.10/src}/akshare_one/modules/indicators/simple.py +9 -8
- {akshare_one-0.3.8 → akshare_one-0.3.10/src}/akshare_one/modules/indicators/talib.py +3 -3
- {akshare_one-0.3.8 → akshare_one-0.3.10/src}/akshare_one/modules/info/eastmoney.py +2 -2
- {akshare_one-0.3.8 → akshare_one-0.3.10/src}/akshare_one/modules/info/factory.py +3 -3
- {akshare_one-0.3.8 → akshare_one-0.3.10/src}/akshare_one/modules/insider/factory.py +3 -3
- {akshare_one-0.3.8 → akshare_one-0.3.10/src}/akshare_one/modules/insider/xueqiu.py +1 -1
- {akshare_one-0.3.8 → akshare_one-0.3.10/src}/akshare_one/modules/news/eastmoney.py +1 -1
- {akshare_one-0.3.8 → akshare_one-0.3.10/src}/akshare_one/modules/news/factory.py +3 -3
- {akshare_one-0.3.8 → akshare_one-0.3.10/src}/akshare_one/modules/realtime/eastmoney.py +1 -1
- {akshare_one-0.3.8 → akshare_one-0.3.10/src}/akshare_one/modules/realtime/factory.py +26 -3
- {akshare_one-0.3.8 → akshare_one-0.3.10/src}/akshare_one/modules/realtime/xueqiu.py +1 -1
- akshare_one-0.3.10/src/akshare_one/py.typed +0 -0
- akshare_one-0.3.8/LICENSE +0 -21
- akshare_one-0.3.8/akshare_one.egg-info/PKG-INFO +0 -74
- akshare_one-0.3.8/akshare_one.egg-info/SOURCES.txt +0 -48
- akshare_one-0.3.8/akshare_one.egg-info/dependency_links.txt +0 -1
- akshare_one-0.3.8/akshare_one.egg-info/requires.txt +0 -5
- akshare_one-0.3.8/akshare_one.egg-info/top_level.txt +0 -1
- akshare_one-0.3.8/setup.cfg +0 -4
- akshare_one-0.3.8/tests/test_financial.py +0 -107
- akshare_one-0.3.8/tests/test_indicators.py +0 -520
- akshare_one-0.3.8/tests/test_info.py +0 -82
- akshare_one-0.3.8/tests/test_insider.py +0 -66
- akshare_one-0.3.8/tests/test_news.py +0 -69
- akshare_one-0.3.8/tests/test_stock.py +0 -200
- {akshare_one-0.3.8 → akshare_one-0.3.10}/README.md +0 -0
- {akshare_one-0.3.8 → akshare_one-0.3.10/src}/akshare_one/__init__.py +0 -0
- {akshare_one-0.3.8 → akshare_one-0.3.10/src}/akshare_one/eastmoney/utils.py +0 -0
- {akshare_one-0.3.8 → akshare_one-0.3.10/src}/akshare_one/indicators.py +0 -0
- {akshare_one-0.3.8 → akshare_one-0.3.10/src}/akshare_one/modules/financial/base.py +0 -0
- {akshare_one-0.3.8 → akshare_one-0.3.10/src}/akshare_one/modules/indicators/__init__.py +0 -0
- {akshare_one-0.3.8 → akshare_one-0.3.10/src}/akshare_one/modules/indicators/base.py +0 -0
- {akshare_one-0.3.8 → akshare_one-0.3.10/src}/akshare_one/modules/info/base.py +0 -0
- {akshare_one-0.3.8 → akshare_one-0.3.10/src}/akshare_one/modules/insider/base.py +0 -0
- {akshare_one-0.3.8 → akshare_one-0.3.10/src}/akshare_one/modules/news/base.py +0 -0
- {akshare_one-0.3.8 → akshare_one-0.3.10/src}/akshare_one/modules/realtime/base.py +0 -0
- {akshare_one-0.3.8 → akshare_one-0.3.10/src}/akshare_one/modules/realtime/eastmoney_direct.py +0 -0
- {akshare_one-0.3.8 → akshare_one-0.3.10/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.
|
3
|
+
Version: 0.3.10
|
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.41
|
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
|
-
|
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.
|
3
|
+
version = "0.3.10"
|
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.
|
8
|
+
"akshare>=1.17.41",
|
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.
|
39
|
-
|
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
|
{akshare_one-0.3.8 → akshare_one-0.3.10/src}/akshare_one/modules/financial/eastmoney_direct.py
RENAMED
@@ -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
|
-
|
41
|
+
def get_income_statement(self) -> pd.DataFrame:
|
42
|
+
return pd.DataFrame()
|
43
43
|
|
44
|
-
def get_balance_sheet(self):
|
45
|
-
|
44
|
+
def get_balance_sheet(self) -> pd.DataFrame:
|
45
|
+
return pd.DataFrame()
|
46
46
|
|
47
|
-
def get_cash_flow(self):
|
48
|
-
|
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
|
-
|
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
|
{akshare_one-0.3.8 → akshare_one-0.3.10/src}/akshare_one/modules/historical/eastmoney_direct.py
RENAMED
@@ -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.
|
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
|
-
|
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
|
@@ -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
|
@@ -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
|
|
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/
|