tradingSystem/app/core/timing_rules.py

32 lines
1.8 KiB
Python
Raw Normal View History

# -*- coding: utf-8 -*-
"""择时系统立场合成 (2026-09-11 三源合议, 纯逻辑, 零外部依赖)。
输入是决策系统的昨夜定性 (BUY/WATCH/SELL/AVOID/DROPPED, 或超期/) 与当天盘中转多留痕
规则见技术面接入与三源合议方案第四节:
昨夜 BUY 看多, WATCH 中性, SELL/AVOID/DROPPED 看空, 超期或缺无读数
当天盘中转多留痕把无读数与中性升为看多, 与看空相遇归中性
立场取值只有: 看多 / 看空 / 中性 / 无读数无读数是弃权, 绝不折成看空 (设计原则二)
研判闸不当选票 (设计原则三): 这一票只用昨夜定性与盘中转多留痕, 不重复计入研判结论
"""
from __future__ import annotations
_NIGHTLY = {"BUY": "看多", "WATCH": "中性", "SELL": "看空", "AVOID": "看空", "DROPPED": "看空"}
def synthesize(nightly, *, intraday_flip_at=None, fresh=True) -> dict:
"""nightly: 昨夜定性字符串 (BUY 等) 或 None/空; fresh: 昨夜结论是否在有效期内 (超期传 False);
intraday_flip_at: 当天盘中转多留痕的时刻字符串, 没有传 None"""
n = str(nightly or "").strip().upper()
base = _NIGHTLY.get(n, "中性") if (n and fresh) else "无读数"
stance = base
if intraday_flip_at: # 当天盘中转多留痕
if base in ("无读数", "中性"):
stance = "看多"
elif base == "看空":
stance = "中性" # 盘中转多与昨夜看空相遇, 归中性
# base 已是看多则维持看多
return {"stance": stance, "nightly": (n or None), "fresh": bool(fresh),
"intraday_flip_at": intraday_flip_at,
"no_read_why": ("没有昨夜结论或已超期" if stance == "无读数" else None)}