summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/FundLab.Api/akshare_collector.py43
1 files changed, 34 insertions, 9 deletions
diff --git a/src/FundLab.Api/akshare_collector.py b/src/FundLab.Api/akshare_collector.py
index 6543923..652f32d 100644
--- a/src/FundLab.Api/akshare_collector.py
+++ b/src/FundLab.Api/akshare_collector.py
@@ -150,22 +150,47 @@ def nav(code):
}
+def bond_maturity_date(code):
+ # Maturity is a best-effort enrichment: the quote endpoint has no expiry
+ # date, so a failure here only means maturity_date stays null.
+ try:
+ frame = ak.bond_zh_cov_info(symbol=code, indicator="基本信息")
+ if frame is None or frame.empty:
+ return None
+ return date_text(frame.iloc[0].get("EXPIRE_DATE"))
+ except Exception:
+ return None
+
+
def bond_quote(code):
code = text(code)
if code is None or not re.fullmatch(r"\d{6}", code):
raise ValueError("bond code must contain exactly six digits")
- frame = ak.bond_zh_cov_info(symbol=code, indicator="基本信息")
+ frame = ak.bond_zh_hs_cov_spot()
if frame is None or frame.empty:
- raise ValueError(f"AKShare returned no bond info for {code}")
+ raise ValueError(f"no valid quote for {code}")
+
+ prefix_rank = {"sh": 0, "sz": 1, "bj": 2}
+ candidates = []
+
+ for _, row in frame.iterrows():
+ symbol = text(row.get("symbol")) or ""
+ row_code = text(row.get("code")) or ""
+ if row_code != code and not symbol.endswith(code):
+ continue
+
+ price = decimal_text(row.get("trade"))
+ if price is None or Decimal(price) <= 0:
+ continue
+
+ prefix = symbol[:2].lower()
+ candidates.append((prefix_rank.get(prefix, 3), symbol, text(row.get("name")), price))
- row = frame.iloc[0]
- name = text(row.get("SECURITY_NAME_ABBR"))
- price = decimal_text(row.get("CURRENT_BOND_PRICE"))
- maturity_date = date_text(row.get("EXPIRE_DATE"))
+ if not candidates:
+ raise ValueError(f"no valid quote for {code}")
- if name is None and price is None and maturity_date is None:
- raise ValueError(f"AKShare returned no usable bond quote fields for {code}")
+ _, _, name, price = sorted(candidates, key=lambda item: (item[0], item[1]))[0]
return {
"schema_version": SCHEMA_VERSION,
@@ -177,7 +202,7 @@ def bond_quote(code):
"quote": {
"name": name,
"price": price,
- "maturity_date": maturity_date,
+ "maturity_date": bond_maturity_date(code),
},
}