rebuild(runtime): govern market operations and job truth
This commit is contained in:
@@ -34,7 +34,7 @@ def build_snapshot(
|
||||
up_count = sum(_number(row.get("pct_chg")) > 0 for row in daily_rows)
|
||||
down_count = sum(_number(row.get("pct_chg")) < 0 for row in daily_rows)
|
||||
flat_count = len(daily_rows) - up_count - down_count
|
||||
amount = sum(_number(row.get("amount")) * 1000 for row in daily_rows)
|
||||
amount = sum(_amount_yuan(row) for row in daily_rows)
|
||||
seal_rate = len(limits) / max(len(limits) + len(broken), 1) * 100
|
||||
sectors = _sectors(limits)
|
||||
previous_sectors = _sectors(previous_limits)
|
||||
@@ -63,6 +63,66 @@ def build_snapshot(
|
||||
}
|
||||
|
||||
|
||||
def build_realtime_inputs(
|
||||
inputs: dict[str, ProviderResult | dict[str, Any]],
|
||||
directory: dict[str, dict[str, Any]],
|
||||
) -> dict[str, ProviderResult | dict[str, Any]]:
|
||||
daily_result = inputs.get("daily")
|
||||
limits_result = inputs.get("price_limits")
|
||||
previous_result = inputs.get("previous_limit_up")
|
||||
if not isinstance(daily_result, ProviderResult) or not isinstance(
|
||||
limits_result, ProviderResult
|
||||
):
|
||||
return inputs
|
||||
prices = {str(row.get("ts_code") or ""): row for row in limits_result.rows}
|
||||
previous = {
|
||||
str(row.get("ts_code") or ""): row
|
||||
for row in previous_result.rows
|
||||
} if isinstance(previous_result, ProviderResult) else {}
|
||||
pools: dict[str, list[dict[str, Any]]] = {
|
||||
"limit_up": [],
|
||||
"limit_down": [],
|
||||
"broken": [],
|
||||
}
|
||||
for quote in daily_result.rows:
|
||||
identifier = str(quote.get("ts_code") or "")
|
||||
price = prices.get(identifier) or {}
|
||||
current = _number(quote.get("close"))
|
||||
high = _number(quote.get("high"))
|
||||
up_limit = _number(price.get("up_limit"))
|
||||
down_limit = _number(price.get("down_limit"))
|
||||
event_type = ""
|
||||
if up_limit > 0 and current >= up_limit - 0.001:
|
||||
event_type = "limit_up"
|
||||
elif up_limit > 0 and high >= up_limit - 0.001:
|
||||
event_type = "broken"
|
||||
elif down_limit > 0 and current <= down_limit + 0.001:
|
||||
event_type = "limit_down"
|
||||
if not event_type:
|
||||
continue
|
||||
identity = directory.get(identifier) or {}
|
||||
prior_streak = int(_number(previous.get(identifier, {}).get("limit_times")))
|
||||
pools[event_type].append(
|
||||
{
|
||||
**quote,
|
||||
"name": str(quote.get("name") or identity.get("name") or ""),
|
||||
"industry": str(identity.get("sector") or ""),
|
||||
"first_time": "",
|
||||
"last_time": "",
|
||||
"open_times": 0,
|
||||
"limit_times": prior_streak + 1 if event_type == "limit_up" else 1,
|
||||
"fd_amount": 0,
|
||||
}
|
||||
)
|
||||
metadata = daily_result.metadata
|
||||
return {
|
||||
**inputs,
|
||||
"limit_up": ProviderResult(tuple(pools["limit_up"]), metadata),
|
||||
"limit_down": ProviderResult(tuple(pools["limit_down"]), metadata),
|
||||
"broken": ProviderResult(tuple(pools["broken"]), metadata),
|
||||
}
|
||||
|
||||
|
||||
def _rows(
|
||||
inputs: dict[str, ProviderResult | dict[str, Any]], key: str
|
||||
) -> tuple[dict[str, Any], ...]:
|
||||
@@ -74,7 +134,7 @@ def _pool(rows: tuple[dict[str, Any], ...], status: str) -> list[dict[str, Any]]
|
||||
result = []
|
||||
for row in rows:
|
||||
identifier = str(row.get("ts_code") or "")
|
||||
amount = _number(row.get("amount")) * 1000
|
||||
amount = _amount_yuan(row)
|
||||
result.append(
|
||||
{
|
||||
"identifier": identifier,
|
||||
@@ -238,6 +298,11 @@ def _number(value: Any, default: float = 0.0) -> float:
|
||||
return default
|
||||
|
||||
|
||||
def _amount_yuan(row: dict[str, Any]) -> float:
|
||||
amount = _number(row.get("amount"))
|
||||
return amount if row.get("amount_unit") == "yuan" else amount * 1000
|
||||
|
||||
|
||||
def _time(value: Any) -> str:
|
||||
text = str(value or "").strip().replace(":", "")
|
||||
if len(text) < 4 or not text[:4].isdigit():
|
||||
|
||||
Reference in New Issue
Block a user