73 lines
3.4 KiB
Python
73 lines
3.4 KiB
Python
# -*- coding: utf-8 -*-
|
||
"""三源合议与路由 (2026-09-11, 纯逻辑, 零外部依赖)。
|
||
|
||
三票 (基本面 / 技术面 / 择时系统) 各是看多/看空/中性/无读数之一, 合成方向再定路由。
|
||
方案第四节的合议规则 (台账 009):
|
||
三票多数决定方向; 无读数弃权不计; 平局中性; 只有一方表态算弱; 三方一致算强。
|
||
路由表见方案附录丙。方向词与合议词一律中文原文, 取值只有看多/看空/中性/无读数。
|
||
"""
|
||
from __future__ import annotations
|
||
|
||
_BULL, _BEAR, _NEUT, _NA = "看多", "看空", "中性", "无读数"
|
||
|
||
|
||
def _reason(fund, tech, timing, direction, strength):
|
||
head = "、".join([f"基本面{fund}", f"技术面{tech}", f"择时{timing}"])
|
||
return head + " → " + direction + (("·" + strength) if strength else "")
|
||
|
||
|
||
def _route(fund, tech, timing, direction, tech_phase, fund_required):
|
||
"""附录丙路由表, 从上到下第一个命中。返回 (路由, 原因)。路由取值: 放行/观察/交人/跳过。"""
|
||
if fund_required and fund == _NA:
|
||
return "跳过", "没有买方评析"
|
||
if direction == _BEAR:
|
||
return "跳过", f"方向看空(基本面{fund}、技术面{tech}、择时{timing})"
|
||
if direction == _NEUT and tech_phase == "收口等待" and fund != _BEAR:
|
||
return "观察", "等技术面开口"
|
||
if direction == _NEUT and fund == _BULL and tech == _BEAR:
|
||
return "观察", "等技术面转向"
|
||
if fund == _BEAR and tech == _BULL:
|
||
return "交人", "基本面看空、技术面看多,试探仓"
|
||
if direction == _BULL:
|
||
voiced = [v for v in (fund, tech, timing) if v in (_BULL, _BEAR)]
|
||
if timing == _BEAR: # 异议在择时系统
|
||
return "交人", "方向看多但择时系统有异议"
|
||
if len(voiced) <= 1: # 只有一方表态
|
||
return "交人", "方向看多但只有一方表态"
|
||
return "放行", "方向看多" # 看多强, 或异议只在技术面
|
||
if fund == _NA and tech == _NA and timing == _NA:
|
||
return "放行", "三方都无读数,机械方案"
|
||
return "观察", "方向中性"
|
||
|
||
|
||
def decide(fund, tech, timing, *, tech_phase=None, fund_required=True) -> dict:
|
||
"""fund/tech/timing 是三个立场字符串 (看多/看空/中性/无读数)。tech_phase 是技术面相位
|
||
(收口等待 等), 路由用。fund_required: 无买方评析是否拦 (开关 PMS_FUND_REQUIRED)。"""
|
||
votes = {"fund": fund, "tech": tech, "timing": timing}
|
||
voiced = [v for v in (fund, tech, timing) if v in (_BULL, _BEAR)]
|
||
bulls = sum(1 for v in voiced if v == _BULL)
|
||
bears = sum(1 for v in voiced if v == _BEAR)
|
||
|
||
# ---- 方向: 多数决, 无读数弃权不计, 平局中性 ----
|
||
if bulls > bears:
|
||
direction = _BULL
|
||
elif bears > bulls:
|
||
direction = _BEAR
|
||
else:
|
||
direction = _NEUT
|
||
|
||
# ---- 强弱: 只有一方表态弱, 三方一致强, 其余 (两方表态) 为中 ----
|
||
if direction == _NEUT:
|
||
strength = None
|
||
elif len(voiced) <= 1:
|
||
strength = "弱"
|
||
elif bulls == 3 or bears == 3:
|
||
strength = "强"
|
||
else:
|
||
strength = "中"
|
||
|
||
route, route_reason = _route(fund, tech, timing, direction, tech_phase, fund_required)
|
||
return {"direction": direction, "votes": votes, "strength": strength,
|
||
"reason": _reason(fund, tech, timing, direction, strength),
|
||
"route": route, "route_reason": route_reason}
|