fix: validate Shenwan constituent coverage
This commit is contained in:
@@ -68,7 +68,7 @@ from sentiment_engine import (
|
||||
)
|
||||
from strategy_tracking import StrategyTrackingService
|
||||
from trade_journal import TradeJournalService
|
||||
from tushare_client import TushareClient, TushareError
|
||||
from tushare_client import TushareClient, TushareError, _sector_coverage_issue
|
||||
|
||||
|
||||
LEGACY_SECRET_KEYS = {
|
||||
@@ -1729,6 +1729,22 @@ class DashboardService:
|
||||
|
||||
sector_date = str(sector.get("trade_date") or "").replace("-", "")
|
||||
sector_coverage = float(sector.get("coverage") or 0)
|
||||
sector_explained_count = int(
|
||||
sector.get("explained_count")
|
||||
if sector.get("explained_count") is not None
|
||||
else sector.get("quote_count") or 0
|
||||
)
|
||||
sector_explained_coverage = float(
|
||||
sector.get("explained_coverage")
|
||||
if sector.get("explained_coverage") is not None
|
||||
else sector_coverage
|
||||
)
|
||||
sector_coverage_issue = _sector_coverage_issue(
|
||||
int(sector.get("member_count") or 0),
|
||||
int(sector.get("quote_count") or 0),
|
||||
sector_explained_coverage,
|
||||
sector_explained_count,
|
||||
)
|
||||
sector_common = []
|
||||
if not sector:
|
||||
sector_common.append("未取得申万二级行业归属")
|
||||
@@ -1748,8 +1764,8 @@ class DashboardService:
|
||||
sector_inner.append(str(sector.get("inner_error") or sector.get("error") or "行业内核数据未通过校验"))
|
||||
if not sector.get("outer_precise", sector.get("precise")):
|
||||
sector_outer.append(str(sector.get("outer_error") or sector.get("error") or "行业外显数据未通过校验"))
|
||||
if sector and sector_coverage < 90:
|
||||
sector_inner.append(f"行业成分行情覆盖率仅 {sector_coverage:.1f}%,低于 90%")
|
||||
if sector and sector_coverage_issue and sector_coverage_issue not in sector_inner:
|
||||
sector_inner.append(sector_coverage_issue)
|
||||
if sector.get("realtime") and not sector.get("relative_turnover"):
|
||||
sector_inner.append("缺少行业相对全市场换手活跃度")
|
||||
|
||||
@@ -1850,7 +1866,7 @@ class DashboardService:
|
||||
invalid_fields[3].update(required[3])
|
||||
invalid_fields[4].update(required[4])
|
||||
else:
|
||||
if not sector.get("inner_precise", sector.get("precise")) or sector_coverage < 90:
|
||||
if not sector.get("inner_precise", sector.get("precise")) or sector_coverage_issue:
|
||||
invalid_fields[3].update(key for key in required[3] if key != "sector_name")
|
||||
if sector.get("realtime") and not sector.get("relative_turnover"):
|
||||
invalid_fields[3].add("sector_relative_turnover")
|
||||
@@ -2292,6 +2308,22 @@ class DashboardService:
|
||||
sector = sector or {}
|
||||
sector_date = str(sector.get("trade_date") or "").replace("-", "")
|
||||
sector_coverage = float(sector.get("coverage") or 0)
|
||||
sector_explained_count = int(
|
||||
sector.get("explained_count")
|
||||
if sector.get("explained_count") is not None
|
||||
else sector.get("quote_count") or 0
|
||||
)
|
||||
sector_explained_coverage = float(
|
||||
sector.get("explained_coverage")
|
||||
if sector.get("explained_coverage") is not None
|
||||
else sector_coverage
|
||||
)
|
||||
sector_coverage_issue = _sector_coverage_issue(
|
||||
int(sector.get("member_count") or 0),
|
||||
int(sector.get("quote_count") or 0),
|
||||
sector_explained_coverage,
|
||||
sector_explained_count,
|
||||
)
|
||||
if not sector:
|
||||
issues.append("行业层缺少申万二级行业归属")
|
||||
elif sector.get("taxonomy") != "sw_l2":
|
||||
@@ -2308,8 +2340,8 @@ class DashboardService:
|
||||
issues.append("行业内核缺少可核验的成分行情")
|
||||
if not sector.get("outer_precise", sector.get("precise")):
|
||||
issues.append("行业外显缺少申万官方行情")
|
||||
if sector and sector_coverage < 90:
|
||||
issues.append("行业成分行情覆盖率不足90%")
|
||||
if sector and sector_coverage_issue:
|
||||
issues.append(sector_coverage_issue)
|
||||
if sector.get("realtime") and not sector.get("relative_turnover"):
|
||||
issues.append("行业内核缺少相对全市场换手活跃度")
|
||||
|
||||
@@ -2742,7 +2774,7 @@ class DashboardService:
|
||||
and cached.get("inner_precise", cached.get("precise"))
|
||||
and cached.get("outer_precise", cached.get("precise"))
|
||||
and not cached.get("realtime")
|
||||
and int(cached.get("schema_version") or 0) >= 4
|
||||
and int(cached.get("schema_version") or 0) >= 6
|
||||
)
|
||||
if market_mode != "intraday" and cached_valid:
|
||||
return cached
|
||||
|
||||
Reference in New Issue
Block a user