修复主力合约识别:按持仓量判定并移除当月占位

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
dekun
2026-06-15 18:28:51 +08:00
parent 404872007f
commit 9c0e5d9c57
4 changed files with 109 additions and 46 deletions
+47 -21
View File
@@ -51,6 +51,52 @@ def _sina_headers() -> dict:
return {"Referer": "https://finance.sina.com.cn"}
def _parse_sina_futures_quote(parts: list) -> Optional[dict]:
"""解析新浪 nf_/CFF_RE_ 期货行情字段。"""
if len(parts) < 9:
return None
price = None
for idx in (8, 7, 6, 5):
if len(parts) > idx and parts[idx]:
try:
val = float(parts[idx])
if val > 0:
price = val
break
except ValueError:
pass
if price is None:
price = 0.0
open_interest = 0.0
volume = 0.0
if len(parts) > 13 and parts[13]:
try:
open_interest = float(parts[13])
except ValueError:
pass
if len(parts) > 14 and parts[14]:
try:
volume = float(parts[14])
except ValueError:
pass
prev_close = None
if len(parts) > 9 and parts[9]:
try:
prev_close = float(parts[9])
except ValueError:
pass
return {
"name": parts[0],
"price": price,
"volume": volume,
"open_interest": open_interest,
"prev_close": prev_close,
}
def _fetch_sina_raw(sina_code: str) -> Optional[dict]:
try:
url = f"https://hq.sinajs.cn/list={sina_code}"
@@ -62,27 +108,7 @@ def _fetch_sina_raw(sina_code: str) -> Optional[dict]:
if not body:
return None
parts = body.split(",")
if len(parts) < 9:
return None
price = float(parts[8])
volume = float(parts[14]) if len(parts) > 14 and parts[14] else 0
prev_close = None
if len(parts) > 9 and parts[9]:
try:
prev_close = float(parts[9])
except ValueError:
pass
if prev_close is None and len(parts) > 2 and parts[2]:
try:
prev_close = float(parts[2])
except ValueError:
pass
return {
"name": parts[0],
"price": price,
"volume": volume,
"prev_close": prev_close,
}
return _parse_sina_futures_quote(parts)
except Exception as exc:
logger.debug("sina fetch failed %s: %s", sina_code, exc)
return None