chore: capture deployed state

This commit is contained in:
知微
2026-07-20 17:30:43 +08:00
parent 4dcfee8140
commit 5d3b8e6fdd
14 changed files with 33422 additions and 2882 deletions
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
+29640
View File
File diff suppressed because it is too large Load Diff
+304 -154
View File
@@ -35,10 +35,10 @@
{
"date": "2026-07-20",
"high": 15.75,
"low": 14.1,
"close": 14.21,
"volume": 37396292.0,
"amount": 55424.0
"low": 13.05,
"close": 13.41,
"volume": 41864386.0,
"amount": 56681.0
}
],
"688775": [
@@ -77,10 +77,10 @@
{
"date": "2026-07-20",
"high": 149.0,
"low": 135.76,
"close": 138.34,
"volume": 6157193.0,
"amount": 86656.0
"low": 129.5,
"close": 136.32,
"volume": 4713131.0,
"amount": 63136.0
}
],
"688475": [
@@ -118,11 +118,11 @@
},
{
"date": "2026-07-20",
"high": 27.74,
"high": 27.78,
"low": 26.4,
"close": 26.64,
"volume": 5999240.0,
"amount": 16223.0
"close": 27.73,
"volume": 6881480.0,
"amount": 18584.0
}
],
"688778": [
@@ -161,10 +161,10 @@
{
"date": "2026-07-20",
"high": 46.45,
"low": 44.09,
"close": 44.14,
"volume": 7684619.0,
"amount": 34599.0
"low": 42.05,
"close": 43.0,
"volume": 9254116.0,
"amount": 40066.0
}
],
"688501": [
@@ -203,10 +203,10 @@
{
"date": "2026-07-20",
"high": 17.8,
"low": 16.64,
"close": 16.79,
"volume": 1904231.0,
"amount": 3272.0
"low": 15.42,
"close": 15.91,
"volume": 2834080.0,
"amount": 4591.0
}
],
"688510": [
@@ -245,10 +245,10 @@
{
"date": "2026-07-20",
"high": 22.46,
"low": 20.63,
"close": 21.0,
"volume": 5596808.0,
"amount": 12011.0
"low": 20.25,
"close": 20.76,
"volume": 6770593.0,
"amount": 14184.0
}
],
"688513": [
@@ -287,10 +287,10 @@
{
"date": "2026-07-20",
"high": 59.9,
"low": 54.5,
"close": 54.63,
"volume": 4293163.0,
"amount": 24190.0
"low": 53.67,
"close": 57.6,
"volume": 3704960.0,
"amount": 20838.0
}
],
"688518": [
@@ -329,10 +329,10 @@
{
"date": "2026-07-20",
"high": 19.78,
"low": 18.31,
"close": 18.46,
"volume": 18674329.0,
"amount": 35390.0
"low": 16.81,
"close": 17.24,
"volume": 21448924.0,
"amount": 38124.0
}
],
"00700": [
@@ -372,9 +372,9 @@
"date": "2026-07-20",
"high": 488.8,
"low": 458.0,
"close": 461.6,
"volume": 36237657.0,
"amount": 16928705332.905
"close": 477.8,
"volume": 30822839.0,
"amount": 14678311361.3
}
],
"688533": [
@@ -413,10 +413,10 @@
{
"date": "2026-07-20",
"high": 21.74,
"low": 20.4,
"close": 20.59,
"volume": 1359591.0,
"amount": 2855.0
"low": 19.96,
"close": 20.22,
"volume": 992552.0,
"amount": 2026.0
}
],
"01088": [
@@ -454,11 +454,11 @@
},
{
"date": "2026-07-20",
"high": 42.5,
"high": 43.66,
"low": 41.54,
"close": 42.4,
"volume": 13003969.0,
"amount": 547347699.16
"close": 43.6,
"volume": 11166601.0,
"amount": 483013474.62
}
],
"688566": [
@@ -497,10 +497,10 @@
{
"date": "2026-07-20",
"high": 27.11,
"low": 25.0,
"close": 25.0,
"volume": 3344706.0,
"amount": 8599.0
"low": 24.81,
"close": 25.25,
"volume": 2923287.0,
"amount": 7436.0
}
],
"01211": [
@@ -538,11 +538,11 @@
},
{
"date": "2026-07-20",
"high": 91.45,
"high": 91.5,
"low": 87.25,
"close": 88.7,
"volume": 26427225.0,
"amount": 2340941950.5
"close": 90.15,
"volume": 18345094.0,
"amount": 1653609373.75
}
],
"688639": [
@@ -581,10 +581,10 @@
{
"date": "2026-07-20",
"high": 17.56,
"low": 16.1,
"close": 16.14,
"volume": 10030710.0,
"amount": 16760.0
"low": 15.56,
"close": 15.99,
"volume": 9039229.0,
"amount": 14474.0
}
],
"688582": [
@@ -623,10 +623,10 @@
{
"date": "2026-07-20",
"high": 43.8,
"low": 38.5,
"close": 38.61,
"volume": 10970620.0,
"amount": 44852.0
"low": 36.01,
"close": 36.95,
"volume": 9774815.0,
"amount": 37047.0
}
],
"01478": [
@@ -666,9 +666,9 @@
"date": "2026-07-20",
"high": 7.02,
"low": 6.52,
"close": 6.67,
"volume": 7833000.0,
"amount": 52372235.0
"close": 6.73,
"volume": 4247000.0,
"amount": 28512618.0
}
],
"688755": [
@@ -707,10 +707,10 @@
{
"date": "2026-07-20",
"high": 25.89,
"low": 23.8,
"close": 24.01,
"volume": 1862009.0,
"amount": 4574.0
"low": 22.97,
"close": 23.23,
"volume": 1436355.0,
"amount": 3390.0
}
],
"02202": [
@@ -750,9 +750,9 @@
"date": "2026-07-20",
"high": 2.55,
"low": 2.34,
"close": 2.48,
"volume": 40325958.0,
"amount": 98037795.66
"close": 2.44,
"volume": 13295500.0,
"amount": 32619014.9
}
],
"688692": [
@@ -791,10 +791,10 @@
{
"date": "2026-07-20",
"high": 231.68,
"low": 215.0,
"close": 215.4,
"volume": 1706538.0,
"amount": 38102.0
"low": 209.0,
"close": 216.1,
"volume": 1795104.0,
"amount": 38484.0
}
],
"300750": [
@@ -832,11 +832,11 @@
},
{
"date": "2026-07-20",
"high": 375.24,
"low": 360.0,
"close": 360.0,
"volume": 512453.0,
"amount": 1884671.0
"high": 377.6,
"low": 353.8,
"close": 376.43,
"volume": 447908.0,
"amount": 1663278.0
}
],
"688696": [
@@ -875,10 +875,10 @@
{
"date": "2026-07-20",
"high": 67.39,
"low": 62.37,
"close": 62.9,
"volume": 1185875.0,
"amount": 7647.0
"low": 61.5,
"close": 62.72,
"volume": 1078476.0,
"amount": 6756.0
}
],
"518880": [
@@ -916,11 +916,11 @@
},
{
"date": "2026-07-20",
"high": 8.326,
"high": 8.362,
"low": 8.256,
"close": 8.311,
"volume": 2844769.0,
"amount": 235805.0
"close": 8.318,
"volume": 2007208.0,
"amount": 167139.0
}
],
"688708": [
@@ -959,10 +959,10 @@
{
"date": "2026-07-20",
"high": 46.18,
"low": 43.51,
"close": 44.09,
"volume": 1442625.0,
"amount": 6448.0
"low": 42.31,
"close": 44.91,
"volume": 1781103.0,
"amount": 7823.0
}
],
"688779": [
@@ -1000,11 +1000,11 @@
},
{
"date": "2026-07-20",
"high": 7.03,
"high": 7.04,
"low": 6.67,
"close": 6.69,
"volume": 26278826.0,
"amount": 17957.0
"close": 6.9,
"volume": 37370857.0,
"amount": 25733.0
}
],
"300035": [
@@ -1043,10 +1043,10 @@
{
"date": "2026-07-20",
"high": 12.68,
"low": 12.05,
"close": 12.08,
"volume": 158047.0,
"amount": 19469.0
"low": 11.85,
"close": 12.09,
"volume": 186464.0,
"amount": 22594.0
}
],
"688789": [
@@ -1084,11 +1084,11 @@
},
{
"date": "2026-07-20",
"high": 47.73,
"high": 47.88,
"low": 45.19,
"close": 46.1,
"volume": 2179608.0,
"amount": 10118.0
"close": 47.71,
"volume": 1814330.0,
"amount": 8528.0
}
],
"600563": [
@@ -1146,9 +1146,9 @@
"date": "2026-07-20",
"high": 1072.0,
"low": 950.55,
"close": 979.46,
"volume": 561861.0,
"amount": 5648563.0
"close": 1004.0,
"volume": 453665.0,
"amount": 4609438.0
}
],
"601899": [
@@ -1186,11 +1186,11 @@
},
{
"date": "2026-07-20",
"high": 28.82,
"high": 29.45,
"low": 27.92,
"close": 28.36,
"volume": 2904169.0,
"amount": 824106.0
"close": 29.35,
"volume": 2757683.0,
"amount": 799203.0
}
],
"688981": [
@@ -1229,10 +1229,10 @@
{
"date": "2026-07-20",
"high": 155.51,
"low": 139.02,
"close": 139.88,
"volume": 102952043.0,
"amount": 1517166.0
"low": 138.11,
"close": 144.0,
"volume": 93942500.0,
"amount": 1346494.0
}
],
"688372": [
@@ -1271,10 +1271,10 @@
{
"date": "2026-07-20",
"high": 139.2,
"low": 120.66,
"close": 120.73,
"volume": 11689864.0,
"amount": 151702.0
"low": 115.0,
"close": 120.5,
"volume": 13508171.0,
"amount": 166596.0
}
],
"688411": [
@@ -1313,10 +1313,10 @@
{
"date": "2026-07-20",
"high": 193.48,
"low": 179.03,
"close": 181.68,
"volume": 4238973.0,
"amount": 78494.0
"low": 175.6,
"close": 181.35,
"volume": 4399767.0,
"amount": 80465.0
}
],
"688271": [
@@ -1354,11 +1354,11 @@
},
{
"date": "2026-07-20",
"high": 113.43,
"low": 109.86,
"close": 110.37,
"volume": 8809320.0,
"amount": 97913.0
"high": 119.85,
"low": 107.89,
"close": 118.0,
"volume": 13911975.0,
"amount": 158683.0
}
],
"688439": [
@@ -1397,10 +1397,10 @@
{
"date": "2026-07-20",
"high": 42.38,
"low": 39.58,
"close": 39.58,
"volume": 3189314.0,
"amount": 13157.0
"low": 37.05,
"close": 37.89,
"volume": 3734574.0,
"amount": 14394.0
}
],
"688588": [
@@ -1439,10 +1439,10 @@
{
"date": "2026-07-20",
"high": 9.19,
"low": 8.55,
"close": 8.6,
"volume": 4173682.0,
"amount": 3684.0
"low": 8.46,
"close": 8.63,
"volume": 4281284.0,
"amount": 3721.0
}
],
"688621": [
@@ -1481,10 +1481,10 @@
{
"date": "2026-07-20",
"high": 61.75,
"low": 56.73,
"close": 57.58,
"volume": 6154202.0,
"amount": 36271.0
"low": 54.72,
"close": 56.88,
"volume": 4638705.0,
"amount": 26217.0
}
],
"000850": [
@@ -1515,10 +1515,10 @@
{
"date": "2026-07-20",
"high": 4.24,
"low": 3.98,
"close": 4.08,
"volume": 159057.0,
"amount": 6535.0
"low": 3.94,
"close": 3.98,
"volume": 110497.0,
"amount": 4439.0
}
],
"301308": [
@@ -1617,10 +1617,10 @@
{
"date": "2026-07-20",
"high": 10.58,
"low": 10.3,
"close": 10.3,
"volume": 245805.0,
"amount": 25674.0
"low": 10.15,
"close": 10.35,
"volume": 193759.0,
"amount": 19951.0
}
],
"688087": [
@@ -1642,11 +1642,11 @@
},
{
"date": "2026-07-20",
"high": 38.23,
"high": 38.97,
"low": 35.99,
"close": 36.18,
"volume": 2780918.0,
"amount": 10256.0
"close": 38.57,
"volume": 2483595.0,
"amount": 9341.0
}
],
"688466": [
@@ -1669,10 +1669,10 @@
{
"date": "2026-07-20",
"high": 13.19,
"low": 12.44,
"close": 12.6,
"volume": 1788822.0,
"amount": 2286.0
"low": 11.94,
"close": 12.28,
"volume": 1944699.0,
"amount": 2412.0
}
],
"600111": [
@@ -1694,5 +1694,155 @@
"volume": 35790245.0,
"amount": 1105458.0
}
],
"688425": [
{
"date": "2026-07-20",
"high": 4.15,
"low": 4.08,
"close": 4.14,
"volume": 1496345.0,
"amount": 618.0
}
],
"688608": [
{
"date": "2026-07-20",
"high": 115.2,
"low": 110.0,
"close": 114.41,
"volume": 1143940.0,
"amount": 12834.0
}
],
"688800": [
{
"date": "2026-07-20",
"high": 65.11,
"low": 62.65,
"close": 63.51,
"volume": 1447347.0,
"amount": 9241.0
}
],
"688758": [
{
"date": "2026-07-20",
"high": 25.26,
"low": 22.95,
"close": 24.79,
"volume": 3826638.0,
"amount": 9338.0
}
],
"688289": [
{
"date": "2026-07-20",
"high": 15.64,
"low": 15.35,
"close": 15.52,
"volume": 755498.0,
"amount": 1172.0
}
],
"688726": [
{
"date": "2026-07-20",
"high": 39.6,
"low": 38.03,
"close": 38.48,
"volume": 1020332.0,
"amount": 3950.0
}
],
"688576": [
{
"date": "2026-07-20",
"high": 39.29,
"low": 38.18,
"close": 38.67,
"volume": 61912.0,
"amount": 239.0
}
],
"688122": [
{
"date": "2026-07-20",
"high": 49.28,
"low": 48.3,
"close": 48.95,
"volume": 1345698.0,
"amount": 6582.0
}
],
"605090": [
{
"date": "2026-07-20",
"high": 39.6,
"low": 37.7,
"close": 38.19,
"volume": 87773.0,
"amount": 33970.0
}
],
"603766": [
{
"date": "2026-07-20",
"high": 13.15,
"low": 12.91,
"close": 13.01,
"volume": 26823.0,
"amount": 3485.0
}
],
"688550": [
{
"date": "2026-07-20",
"high": 44.8,
"low": 43.0,
"close": 44.58,
"volume": 977623.0,
"amount": 4270.0
}
],
"688281": [
{
"date": "2026-07-20",
"high": 44.4,
"low": 43.0,
"close": 43.01,
"volume": 473467.0,
"amount": 2067.0
}
],
"688617": [
{
"date": "2026-07-20",
"high": 224.9,
"low": 201.31,
"close": 220.22,
"volume": 2634862.0,
"amount": 55058.0
}
],
"688606": [
{
"date": "2026-07-20",
"high": 45.44,
"low": 43.62,
"close": 44.26,
"volume": 544130.0,
"amount": 2421.0
}
],
"688314": [
{
"date": "2026-07-20",
"high": 35.91,
"low": 30.24,
"close": 31.14,
"volume": 2832553.0,
"amount": 9286.0
}
]
}
File diff suppressed because it is too large Load Diff
+2 -2
View File
@@ -139,8 +139,8 @@ def generate():
insights.append("风险板块: " + " | ".join(loser_insights[:3]))
# ── 洞察4:资金流向异动 ──
big_inflow = [s for s in sectors if s.get("net_inflow", 0) > 50]
big_outflow = [s for s in sectors if s.get("net_inflow", 0) < -50]
big_inflow = [s for s in sectors if (s.get("net_inflow") or 0) > 50]
big_outflow = [s for s in sectors if (s.get("net_inflow") or 0) < -50]
if big_inflow:
top = max(big_inflow, key=lambda s: s["net_inflow"])
insights.append(
+76 -2
View File
@@ -868,22 +868,95 @@ def build_report():
})
# JSON文件
# 已迁移到DB的旧JSON文件:不再报"无读取方"假警报,真实健康信号看DB表新鲜度
MIGRATED_TO_DB = {
"multi_tf_cache.json": "mtf_cache",
"macro_context.json": "macro_context_log",
"market.json": "market_snapshots",
"live_prices.json": "live_prices",
"price_history.json": "price_events",
"macro_risk_state.json": "macro_context_log",
}
json_entities = []
for jf in sorted(WEB_DATA.glob("*.json")):
if jf.name == "stocks": continue
if jf.stem.startswith("temp_"): continue
readers = flows["json_read"].get(jf.name, [])
size = jf.stat().st_size / 1024
migrated = MIGRATED_TO_DB.get(jf.name)
desc = JSON_DESC.get(jf.name, "")
if migrated:
desc = (desc + " " if desc else "") + f"(已迁移到DB表 {migrated},此为遗留文件)"
json_entities.append({
"name": jf.name,
"desc": JSON_DESC.get(jf.name, ""),
"desc": desc,
"size_kb": round(size, 1),
"readers": readers[:10],
"writers": [], # 难以精确追踪
"last_modified": datetime.fromtimestamp(jf.stat().st_mtime).strftime("%m-%d %H:%M"),
"warn": len(readers) == 0 and jf.name not in ("portfolio.json", "market.json"),
"warn": (len(readers) == 0 and jf.name not in ("portfolio.json", "market.json")
and not migrated),
"migrated_to_db": migrated or None,
})
# ── DB表新鲜度:真实数据管道健康信号(替代对遗留JSON文件的mtime检查)──
# 注意:活跃数据在 /home/hmo/MoFin/data/mofin.dblive_prices/mtf_cache 今日有写入),
# 不用 get_conn()(它指向 web-dashboard 的库,那边部分表是旧的)
db_freshness = []
FRESHNESS_TABLES = [
("mtf_cache", "updated_at", "多周期均线缓存"),
("macro_context_log", "created_at", "宏观上下文"),
("market_snapshots", "created_at", "市场快照"),
("live_prices", "updated_at", "实时价格"),
("price_events", "created_at", "价格事件"),
]
try:
_fc = sqlite3.connect("/home/hmo/MoFin/data/mofin.db", timeout=10)
for tname, tcol, label in FRESHNESS_TABLES:
try:
row = _fc.execute(
f"SELECT MAX({tcol}) FROM {tname}").fetchone()
if row and row[0]:
last_dt = datetime.fromisoformat(str(row[0]).replace("Z", ""))
age_h = (now - last_dt).total_seconds() / 3600
db_freshness.append({
"table": tname, "label": label,
"last_record": last_dt.strftime("%m-%d %H:%M"),
"age_hours": round(age_h, 1),
"warn": age_h > 24,
})
else:
db_freshness.append({"table": tname, "label": label,
"last_record": None, "age_hours": -1, "warn": True})
except Exception:
pass # 表不存在或列名不同,跳过
_fc.close()
except Exception:
pass
# price_events 特殊处理:活跃存储是 price_events.jsonprice_monitor 实时写入),
# DB 表是旧遗留。读 JSON 最后一条事件的时间。
try:
_pe_path = Path("/home/hmo/web-dashboard/data/price_events.json")
if _pe_path.exists():
_pe = json.loads(_pe_path.read_text(encoding="utf-8"))
_items = _pe if isinstance(_pe, list) else _pe.get("events", [])
if _items:
_last = _items[-1]
_ts = _last.get("timestamp") or _last.get("created_at") or ""
_dt = datetime.fromisoformat(str(_ts).replace("Z", ""))
_age = (now - _dt).total_seconds() / 3600
# 替换 db_freshness 里 price_events 那条(DB 旧数据)
db_freshness = [f for f in db_freshness if f["table"] != "price_events"]
db_freshness.append({
"table": "price_events.json", "label": "价格事件",
"last_record": _dt.strftime("%m-%d %H:%M"),
"age_hours": round(_age, 1),
"warn": _age > 24,
})
except Exception:
pass
# ── Tab 3: 流程/cron映射 ──
pipelines = []
for j in sorted(cron_jobs, key=lambda x: x.get("name","")):
@@ -912,6 +985,7 @@ def build_report():
"entities": entities,
"json_files": json_entities,
"pipelines": pipelines,
"db_freshness": db_freshness,
}
out_path = WEB_DATA / "mofin_health.json"
with open(out_path, "w") as f:
@@ -20,27 +20,22 @@ from strategy_lifecycle import regenerate_all
result = regenerate_all(stdout=True)
print(f"\n重评完成: {result.get('ok',0)}/{result.get('total',0)}成功")
# Step 1.5: 持仓 12 维 LLM 深度分析(每日强制,14只约8-10分钟
# Step 1.5: 持仓 12 维 LLM 深度分析——后台分离执行(12-40分钟,不能阻塞 cron 的 120s 超时
print("\n" + "=" * 50)
print("🧠 持仓12维LLM分析(每日强制刷新")
print("🧠 持仓12维LLM分析(后台分离启动")
print("=" * 50)
import subprocess as _sp
analysis_result = {"ok": 0, "fail": 0, "skip": 0}
analysis_result = {"mode": "detached"}
try:
r = _sp.run(
_log = open("/tmp/holdings_12d_daily.log", "a")
_sp.Popen(
["python3", "/home/hmo/.hermes/profiles/position-analyst/scripts/batch_reassess.py",
"--type", "holding", "--today"],
capture_output=True, text=True, timeout=3600)
print(r.stdout[-2000:] if len(r.stdout) > 2000 else r.stdout)
if r.returncode != 0 and r.stderr:
print(f"⚠️ stderr: {r.stderr[:300]}")
# 从输出尾部解析统计
import re as _re
m = _re.search(r"完成: (\d+)成功, (\d+)失败, (\d+)跳过", r.stdout)
if m:
analysis_result = {"ok": int(m.group(1)), "fail": int(m.group(2)), "skip": int(m.group(3))}
stdout=_log, stderr=_log, start_new_session=True)
print(" ✅ 12维分析已后台启动,日志: /tmp/holdings_12d_daily.log(结果落DB,不阻塞盘前流程)")
except Exception as e:
print(f"⚠️ 12维分析步骤异常: {e}")
print(f" ⚠️ 12维分析启动失败: {e}")
analysis_result = {"mode": "detached", "error": str(e)[:100]}
# Step 2: 自选退出
print("\n" + "=" * 50)
+1 -1
View File
@@ -581,7 +581,7 @@ def run_once(round_label=""):
# === 第三步:买入区偏离检测 + 自动重评 ===
reassesed_codes = []
# 先做急跌检测(仅持仓,自选股不推送暴跌告警)
holdings_codes = {d["code"] for d in active if d.get("shares", 0) > 0}
holdings_codes = {d["code"] for d in active if (d.get("shares") or 0) > 0}
for d in active:
code = d["code"]
# 非持仓跳过
+2 -1
View File
@@ -10,7 +10,8 @@ from datetime import datetime
DB_PATH = Path("/home/hmo/MoFin/data/mofin.db")
def main():
conn = sqlite3.connect(str(DB_PATH))
conn = sqlite3.connect(str(DB_PATH), timeout=30)
conn.execute("PRAGMA busy_timeout=30000")
conn.row_factory = sqlite3.Row
# 读未提拔候选(按评分降序)
@@ -13,7 +13,7 @@
import json, sys, os, re, urllib.request, sqlite3
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..'))
from datetime import datetime
from mo_data import read_decisions, read_portfolio, get_price
from mo_data import read_decisions, read_portfolio
DB_PATH = '/home/hmo/web-dashboard/data/mofin.db'
OUTPUT_PATH = "/home/hmo/web-dashboard/data/strategy_staleness_report.json"
@@ -23,7 +23,25 @@ CRITICAL_DAYS = 21 # 超过21天→严重警告
DIVERGENCE_WARN = 30 # 偏离买入区>30%→警告
DIVERGENCE_CRIT = 50 # 偏离>50%→严重
# ── 使用 mo_data.get_price 统一获取价格 ──
def get_price(code):
"""从腾讯API获取当前价"""
try:
market = "sh" if code.startswith("6") else "sz" if code.startswith("0") or code.startswith("3") else ""
if code.startswith(("00", "30")) or code.startswith("68"):
market = "sh" if code.startswith("6") else "sz"
elif code.startswith(("01", "02", "03")):
market = "sz"
url = f"http://qt.gtimg.cn/q={market}{code}"
req = urllib.request.Request(url, headers={"User-Agent": "curl/7.81"})
with urllib.request.urlopen(req, timeout=5) as resp:
raw = resp.read().decode("gbk")
parts = raw.split("~")
if len(parts) > 3:
price = float(parts[3]) if parts[3] else 0
chg = float(parts[32]) if parts[32] else 0
return price, chg if price > 0 else (None, None)
except: pass
return None, None
def parse_buy_zone(current):
"""从策略current字段提取买入区间最低和最高"""
+13
View File
@@ -0,0 +1,13 @@
#!/bin/bash
# sync_profile_scripts.sh — 把 deploy/profile-scripts 全部硬链接到 profile scripts 目录
# 每次部署(scp/git)后必须跑:scp替换文件会破坏硬链接(inode变更),导致cron跑旧版本。
set -e
SRC="/home/hmo/MoFin/deploy/profile-scripts"
DST="/home/hmo/.hermes/profiles/position-analyst/scripts"
count=0
for f in "$SRC"/*.py; do
name=$(basename "$f")
ln -f "$f" "$DST/$name"
count=$((count+1))
done
echo "synced $count scripts (hardlink)"
+393 -327
View File
File diff suppressed because it is too large Load Diff