tradingSystem/app/core/plan_revision.py

46 lines
2.2 KiB
Python

"""计划消费与提议版本核验的纯函数;不改变准入、仓位或自然语言判断。"""
import hashlib
import json
def fingerprint(value):
return hashlib.sha256(json.dumps(value, ensure_ascii=False, sort_keys=True,
separators=(',', ':'), default=str).encode()).hexdigest()
def basis(row):
# 排名与审计时间不是资格/风险/数量依据。完整评析引用变化需要重新研判。
return {k: row.get(k) for k in ('score', 'tier', 'upside', 'heat', 'theme',
'verdict', 'risk', 'missing', 'reasons', 'logic_state', 'company_gate',
'company_review', 'company_review_text', 'events', 'pricing_state', 'news')}
def portfolio_context(view, commitments, stock=None):
"""持仓/资金/在途承诺变化使旧数量依据失效;价格漂移仍由执行终检管理。"""
totals = view.get('totals') or {}
return fingerprint({'held': sorted((r['ts_code'], r.get('total_qty'), r.get('sector'))
for r in view.get('held') or []),
'cash_source': totals.get('cash_source'), 'cash_avail': totals.get('cash_avail'),
'sector_ready': view.get('sector_ready'), 'stock': stock or {},
'inflight': {'names': sorted(commitments.get('names') or []),
'amount': commitments.get('amount')}})
def compare(old, current, code):
"""返回 unavailable/material/unchanged。资格失效由调用方通过缺候选表达。"""
if not current or not (current.get('decision') or {}).get('id'):
return 'unavailable'
state = current.get('refresh_status') or {}
if code in (state.get('pending_codes') or []) or current.get('consumption_error'):
return 'unavailable'
if old is None or fingerprint(old) != fingerprint(basis(current)):
return 'material'
return 'unchanged'
def needs_new_judgement(hard, previous):
"""决策系统缓存按股票/动作,缺同依据的既有研判就必须要求重新回答。"""
keys = ('plan_basis', 'scan_params_hash', 'portfolio_context_hash')
return (not previous or any(previous.get(k) is None for k in keys)
or any(fingerprint(hard.get(k)) != fingerprint(previous.get(k)) for k in keys))