add daily tool scripts: hardcode_scanner, branch_scanner, prune_branches
This commit is contained in:
@@ -0,0 +1,68 @@
|
||||
#!/usr/bin/env python3
|
||||
"""每30分钟扫描所有持仓的分支状态,发现可操作的分支就推"""
|
||||
import sys, json, os
|
||||
sys.path.insert(0, '/home/hmo/MoFin')
|
||||
sys.path.insert(0, '/home/hmo/web-dashboard')
|
||||
from strategy_tree import detect_scenario
|
||||
|
||||
DEC_PATH = '/home/hmo/web-dashboard/data/decisions.json'
|
||||
PF_PATH = '/home/hmo/web-dashboard/data/portfolio.json'
|
||||
XMPP_BRIDGE = "http://127.0.0.1:5805/"
|
||||
XMPP_USER = "hmo@yoin.fun"
|
||||
|
||||
def push(msg):
|
||||
try:
|
||||
from urllib.request import Request, urlopen
|
||||
payload = json.dumps({"to": XMPP_USER, "body": msg, "type": "chat"}).encode()
|
||||
req = Request(XMPP_BRIDGE, data=payload, headers={"Content-Type": "application/json"})
|
||||
urlopen(req, timeout=5)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
def main():
|
||||
scenario = detect_scenario()
|
||||
if not scenario.get('id'):
|
||||
return 0 # SILENT
|
||||
|
||||
alives = []
|
||||
dec = json.load(open(DEC_PATH))
|
||||
pf = json.load(open(PF_PATH))
|
||||
pf_codes = {h['code'] for h in pf.get('holdings', [])}
|
||||
|
||||
for e in dec.get('decisions', []):
|
||||
code = e.get('code', '')
|
||||
tree = e.get('strategy_tree', {})
|
||||
if not tree or not tree.get('branches'):
|
||||
continue
|
||||
branches = tree['branches']
|
||||
price = e.get('price', 0)
|
||||
shares = e.get('shares', 0)
|
||||
cost = e.get('cost', 0)
|
||||
if price <= 0:
|
||||
continue
|
||||
# 用 strategy_tree 评估
|
||||
try:
|
||||
from strategy_tree import evaluate_branches
|
||||
results = evaluate_branches(code, scenario['id'], price, shares, cost)
|
||||
for r in results:
|
||||
if r.get('applicable') and r.get('action_type') != 'hold':
|
||||
is_held = code in pf_codes
|
||||
label = '持仓' if is_held else '自选'
|
||||
alives.append(f" {label} {r.get('action_type','?')} {code}@{price} | 情景{scenario.get('label','')}→{r.get('branch_id','').split('_')[-1]}| {r.get('rationale','')[:30]}")
|
||||
break
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
if not alives:
|
||||
return 0 # SILENT
|
||||
|
||||
# 只推单一情景行 + 操作列表
|
||||
out_lines = [f"【知微】分支扫描 | {scenario.get('label','')}({scenario.get('id','')})"]
|
||||
out_lines.extend(alives)
|
||||
msg = '\n'.join(out_lines)
|
||||
print(msg)
|
||||
push(msg)
|
||||
return 1
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(main())
|
||||
Reference in New Issue
Block a user