Skip to content

Commit ed1e626

Browse files
committed
Support equity_search
1 parent 6c93381 commit ed1e626

File tree

4 files changed

+132
-2
lines changed

4 files changed

+132
-2
lines changed

openbb_akshare/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
from openbb_akshare.models.equity_historical import AKShareEquityHistoricalFetcher
1414
from openbb_akshare.models.equity_profile import AKShareEquityProfileFetcher
1515
from openbb_akshare.models.equity_screener import AKShareEquityScreenerFetcher
16+
from openbb_akshare.models.equity_search import AKShareEquitySearchFetcher
1617
from openbb_akshare.models.historical_dividends import AKShareHistoricalDividendsFetcher
1718
from openbb_akshare.models.income_statement import AKShareIncomeStatementFetcher
1819
from openbb_akshare.models.key_metrics import AKShareKeyMetricsFetcher
@@ -38,6 +39,7 @@
3839
"EquityHistorical": AKShareEquityHistoricalFetcher,
3940
"EquityInfo": AKShareEquityProfileFetcher,
4041
"EquityScreener": AKShareEquityScreenerFetcher,
42+
"EquitySearch": AKShareEquitySearchFetcher,
4143
"HistoricalDividends": AKShareHistoricalDividendsFetcher,
4244
"IncomeStatement": AKShareIncomeStatementFetcher,
4345
"KeyMetrics": AKShareKeyMetricsFetcher,
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
"""AKShare Equity Search Model."""
2+
3+
from typing import Any, Dict, List, Optional
4+
5+
from openbb_core.provider.abstract.fetcher import Fetcher
6+
from openbb_core.provider.standard_models.equity_search import (
7+
EquitySearchData,
8+
EquitySearchQueryParams,
9+
)
10+
from openbb_core.provider.utils.descriptions import (
11+
DATA_DESCRIPTIONS,
12+
QUERY_DESCRIPTIONS,
13+
)
14+
from pydantic import Field
15+
16+
import logging
17+
from openbb_akshare import project_name
18+
from mysharelib.tools import setup_logger
19+
20+
setup_logger(project_name)
21+
logger = logging.getLogger(__name__)
22+
23+
24+
class AKShareEquitySearchQueryParams(EquitySearchQueryParams):
25+
"""AKShare Equity Search Query.
26+
"""
27+
28+
use_cache: bool = Field(
29+
default=True,
30+
description="Whether to use a cached request. The quote is cached for one hour.",
31+
)
32+
limit: Optional[int] = Field(
33+
default=10000,
34+
description=QUERY_DESCRIPTIONS.get("limit", ""),
35+
)
36+
37+
38+
class AKShareEquitySearchData(EquitySearchData):
39+
"""AKShare Equity Search Data."""
40+
41+
42+
class AKShareEquitySearchFetcher(
43+
Fetcher[
44+
AKShareEquitySearchQueryParams,
45+
List[AKShareEquitySearchData],
46+
]
47+
):
48+
"""Transform the query, extract and transform the data from the AKShare endpoints."""
49+
50+
@staticmethod
51+
def transform_query(params: Dict[str, Any]) -> AKShareEquitySearchQueryParams:
52+
"""Transform the query."""
53+
return AKShareEquitySearchQueryParams(**params)
54+
55+
@staticmethod
56+
async def aextract_data(
57+
query: AKShareEquitySearchQueryParams, # pylint: disable=unused-argument
58+
credentials: Optional[Dict[str, str]],
59+
**kwargs: Any,
60+
) -> List[Dict]:
61+
"""Return the raw data from the AKShare endpoint."""
62+
63+
from openbb_akshare.utils.ak_equity_search import get_symbols
64+
api_key = credentials.get("akshare_api_key") if credentials else ""
65+
data = get_symbols(query.use_cache, api_key=api_key)
66+
if query.limit: data = data.head(query.limit)
67+
68+
return data.to_dict(orient="records")
69+
70+
@staticmethod
71+
def transform_data(
72+
query: AKShareEquitySearchQueryParams, data: Dict, **kwargs: Any
73+
) -> List[AKShareEquitySearchData]:
74+
"""Transform the data to the standard format."""
75+
76+
if query.query:
77+
filtered = [
78+
d for d in data
79+
if query.query in d.get('name', '') or query.query in d.get('symbol', '')
80+
]
81+
logger.info(f"Searching for {query.query} and found {len(filtered)} results.")
82+
return [AKShareEquitySearchData.model_validate(d) for d in filtered]
83+
84+
return [AKShareEquitySearchData.model_validate(d) for d in data]
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import logging
2+
import pandas as pd
3+
from mysharelib.tools import setup_logger, get_exchange
4+
from mysharelib.table_cache import TableCache
5+
from openbb_akshare import project_name
6+
7+
setup_logger(project_name)
8+
logger = logging.getLogger(__name__)
9+
10+
TABLE_SCHEMA = {
11+
"symbol": "TEXT", # Symbol (e.g. 600000)
12+
"name": "TEXT", # Short name of the asset
13+
"exchange": "TEXT" # Exchange code (e.g. SSE/SZSE)
14+
}
15+
16+
def get_symbols_df() -> pd.DataFrame:
17+
import akshare as ak
18+
19+
stock_info_a_code_name_df = ak.stock_info_a_code_name()
20+
stock_info_a_code_name_df.rename(columns={"code": "symbol"}, inplace=True)
21+
stock_info_a_code_name_df['exchange'] = [
22+
get_exchange(code)
23+
for code in stock_info_a_code_name_df['symbol']
24+
]
25+
# Get symbols for HK market
26+
hk_stock_list_df = ak.stock_hk_spot_em()
27+
stock_info_hk_code_name_df = hk_stock_list_df[["代码","名称"]].copy()
28+
stock_info_hk_code_name_df.rename(columns={"代码": "symbol", "名称": "name"}, inplace=True)
29+
stock_info_hk_code_name_df["exchange"] = "HKEX"
30+
31+
return pd.concat([stock_info_a_code_name_df, stock_info_hk_code_name_df], ignore_index=True)
32+
33+
def get_symbols(use_cache: bool = True, api_key : str = "") -> pd.DataFrame:
34+
cache = TableCache(TABLE_SCHEMA, project=project_name, table_name="symbols", primary_key="symbol")
35+
if use_cache:
36+
data = cache.read_dataframe()
37+
if not data.empty:
38+
logger.info(f"Loading symbols from {project_name} cache...")
39+
return data
40+
41+
logger.info(f"Generating symbols for {project_name} ...")
42+
data = get_symbols_df()
43+
cache.write_dataframe(data)
44+
return data

pyproject.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[tool.poetry]
22
name = "openbb-akshare"
3-
version = "0.9.23"
3+
version = "1.0.5"
44
description = "AKShare extension for OpenBB"
55
authors = ["Roger Ye <shugaoye@yahoo.com>"]
66
license = "AGPL-3.0-only"
@@ -11,7 +11,7 @@ packages = [{ include = "openbb_akshare" }]
1111
python = ">=3.9.21,<3.13"
1212
akshare = "1.17.39"
1313
openbb-core = { version = "^1.4.7" }
14-
mysharelib = "^0.9.0"
14+
mysharelib = "^1.0.1"
1515
ipywidgets = "^8.1.7"
1616

1717
[tool.poetry.group.dev.dependencies]

0 commit comments

Comments
 (0)