feat: 修复报错
This commit is contained in:
63
python-app/app/market/providers/akshare_provider.py
Normal file
63
python-app/app/market/providers/akshare_provider.py
Normal file
@@ -0,0 +1,63 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from datetime import datetime
|
||||
|
||||
import akshare as ak
|
||||
import pandas as pd
|
||||
|
||||
from market.provider_base import MarketDataProvider
|
||||
|
||||
|
||||
class AkshareCnProvider(MarketDataProvider):
|
||||
@property
|
||||
def provider_name(self) -> str:
|
||||
return "akshare"
|
||||
|
||||
@property
|
||||
def channel(self) -> str:
|
||||
return "cn"
|
||||
|
||||
def fetch_spot(self) -> pd.DataFrame:
|
||||
df = ak.stock_zh_a_spot_em()
|
||||
if df.empty:
|
||||
raise RuntimeError("未获取到 A 股实时行情数据")
|
||||
return df
|
||||
|
||||
def search_spot(self, query: str, limit: int) -> pd.DataFrame:
|
||||
q = query.strip().lower()
|
||||
if not q:
|
||||
return pd.DataFrame()
|
||||
|
||||
df = self.fetch_spot()
|
||||
code = df["代码"].astype(str).str.lower()
|
||||
name = df["名称"].astype(str).str.lower()
|
||||
|
||||
exact = df[(code == q) | (name == q)]
|
||||
if not exact.empty:
|
||||
return exact.head(limit)
|
||||
|
||||
starts = df[code.str.startswith(q) | name.str.startswith(q)]
|
||||
if not starts.empty:
|
||||
return starts.head(limit)
|
||||
|
||||
return df[code.str.contains(q, na=False) | name.str.contains(q, na=False)].head(limit)
|
||||
|
||||
def fetch_daily_kline(self, code: str, start: datetime, end: datetime) -> pd.DataFrame:
|
||||
hist = ak.stock_zh_a_hist(
|
||||
symbol=code,
|
||||
period="daily",
|
||||
start_date=start.strftime("%Y%m%d"),
|
||||
end_date=end.strftime("%Y%m%d"),
|
||||
adjust="qfq",
|
||||
)
|
||||
if hist.empty:
|
||||
raise RuntimeError(f"未获取到 K 线数据: {code}")
|
||||
|
||||
frame = pd.DataFrame(
|
||||
{
|
||||
"date": pd.to_datetime(hist["日期"]),
|
||||
"close": pd.to_numeric(hist["收盘"], errors="coerce"),
|
||||
"volume": pd.to_numeric(hist["成交量"], errors="coerce"),
|
||||
}
|
||||
).dropna()
|
||||
return frame.sort_values("date").reset_index(drop=True)
|
||||
Reference in New Issue
Block a user