rebuild(runtime): govern market operations and job truth

This commit is contained in:
leefer
2026-07-30 10:14:29 +08:00
parent 4fc8691eee
commit d8f0dd930c
39 changed files with 2224 additions and 79 deletions
+62
View File
@@ -130,6 +130,59 @@ class TushareProvider:
)
return datasets
def realtime_market_inputs(
self,
trade_date: str,
previous_trade_date: str,
identifiers: tuple[str, ...],
) -> dict[str, ProviderResult | dict[str, Any]]:
current = _compact(trade_date)
previous = _compact(previous_trade_date)
quotes = self._query(
"rt_k",
{"ts_code": ",".join(identifiers)},
"",
unit="mixed",
)
normalized = tuple(
{
**row,
"trade_date": current,
"pct_chg": _change(row.get("close"), row.get("pre_close")),
"amount_unit": "yuan",
}
for row in quotes.rows
if _number(row.get("close")) > 0 and _number(row.get("pre_close")) > 0
)
daily = ProviderResult(
normalized,
replace(
quotes.metadata,
coverage=min(len(normalized) / max(len(identifiers), 1), 1),
state=SnapshotState.REALTIME,
),
)
return {
"daily": daily,
"price_limits": self._query(
"stk_limit",
{"trade_date": current},
"ts_code,trade_date,up_limit,down_limit",
unit="yuan/share",
),
"previous_limit_up": self._query(
"limit_list_d",
{"trade_date": previous, "limit_type": "U"},
(
"trade_date,ts_code,industry,name,close,pct_chg,amount,limit_amount,"
"float_mv,total_mv,turnover_ratio,fd_amount,first_time,last_time,"
"open_times,up_stat,limit_times"
),
unit="mixed",
empty_is_complete=True,
),
}
def sector_members(self, representative: str, trade_date: str) -> ProviderResult:
target = _compact(trade_date)
industry, members = self._sector_memberships(representative, target)
@@ -354,6 +407,9 @@ class TushareProvider:
) -> ProviderResult:
raise ProviderError("Tushare不提供动态竞价快照")
def event_reasons(self, trade_date: str) -> ProviderResult:
raise ProviderError("Tushare涨跌停榜单不提供可用的事件原因字段")
def screener_inputs(self, trade_dates: tuple[str, ...]) -> dict[str, ProviderResult | None]:
if len(trade_dates) < 21:
raise ProviderError("选股因子至少需要21个交易日")
@@ -628,6 +684,12 @@ def _display(value: str) -> str:
return f"{compact[:4]}-{compact[4:6]}-{compact[6:]}"
def _change(close: Any, previous: Any) -> float:
current = _number(close)
prior = _number(previous)
return round((current / prior - 1) * 100, 4) if current > 0 and prior > 0 else 0.0
def _quarter_periods(through: str, count: int) -> tuple[str, ...]:
year = int(through[:4])
quarter = (int(through[4:6]) - 1) // 3