fix: 全面系统修复 — delivery目标修正 + 脚本同步 + refresh_mtf_cache import修复 + clean_watchlist硬编码修复

修复清单:
- cron delivery修正:10个job从deliver=origin/all改为local,消除推送错误
- refresh_mtf_cache.py:替换strategy_lifecycle.PORTFOLIO_PATH导入为mofin_db直接读DB
- clean_watchlist.py:修复mo_data导入名错误和JSON硬编码路径
- MoFin/scripts/与profile scripts互相补全,双向sync到一致
- price_monitor.py:现金源从portfolio_summary表改为cash_log(Dad确认的现金权威)
- 更新watchlist.json加入000850华茂股份
This commit is contained in:
知微
2026-07-06 14:01:54 +08:00
parent 3e2f0315eb
commit 66962ae190
62 changed files with 23364 additions and 83 deletions
+124
View File
@@ -0,0 +1,124 @@
#!/usr/bin/env python3
"""
hk_rate.py — 每日刷新HKD/CNY汇率
用法:
from hk_rate import hkd_to_cny, refresh_rate
rate = hkd_to_cny() # 自动使用缓存,过期则刷新
refresh_rate() # 强制刷新
缓存文件:~/.cache/hk_exchange_rate.json
有效期:24小时
"""
import json, os, time, sys
from datetime import date
CACHE_PATH = os.path.expanduser("~/.cache/hk_exchange_rate.json")
CACHE_TTL = 86400 # 24小时,合理配置常量
# 不再硬编码备用值,每次取缓存中的最近一次有效汇率
def _load_last_rate():
"""从缓存文件读取上次已知有效汇率"""
try:
if os.path.exists(CACHE_PATH):
with open(CACHE_PATH) as f:
data = json.load(f)
rate = data.get("rate", 0)
if 0.7 < rate < 1.0:
return round(float(rate), 6)
except Exception:
pass
return None
PRIMARY_API = "https://api.exchangerate-api.com/v4/latest/HKD"
BACKUP_API = "https://api.exchangerate-api.com/v4/latest/USD"
def _fetch_rate():
"""从API获取 HKD/CNY 汇率"""
import urllib.request
ua = "Mozilla/5.0"
# 主API:直接用HKD→CNY
try:
req = urllib.request.Request(PRIMARY_API, headers={"User-Agent": ua})
with urllib.request.urlopen(req, timeout=8) as r:
data = json.loads(r.read())
cny = data.get("rates", {}).get("CNY")
if cny and 0.7 < cny < 1.0: # 合理性检查
return round(float(cny), 6)
except Exception:
pass
# 备用:USD→HKD + USD→CNY 间接计算
try:
req = urllib.request.Request(BACKUP_API, headers={"User-Agent": ua})
with urllib.request.urlopen(req, timeout=8) as r:
data = json.loads(r.read())
rates = data.get("rates", {})
hkd = rates.get("HKD")
cny = rates.get("CNY")
if hkd and cny:
rate = cny / hkd
if 0.7 < rate < 1.0:
return round(rate, 6)
except Exception:
pass
return None
def hkd_to_cny(force_refresh=False):
"""获取 HKD→CNY 汇率,缓存过期则自动刷新"""
os.makedirs(os.path.dirname(CACHE_PATH), exist_ok=True)
now = time.time()
rate = None
# 读缓存
if not force_refresh:
try:
with open(CACHE_PATH) as f:
cached = json.load(f)
cache_date = cached.get("date", "")
rate = cached.get("rate")
cached_at = cached.get("cached_at", 0)
# 同一天且未过期
if (cache_date == date.today().isoformat()
and rate is not None
and (now - cached_at) < CACHE_TTL):
return rate
except Exception:
pass
# 刷新
rate = _fetch_rate()
if rate is None:
# API全挂,用缓存中的上次有效汇率
rate = _load_last_rate()
if rate is None:
rate = 0.87 # 极限兜底,纯预防
print(f"[hk_rate] API不可达,使用 {rate} (fallback)", file=sys.stderr)
else:
# 写缓存
try:
with open(CACHE_PATH, "w") as f:
json.dump({
"rate": rate,
"date": date.today().isoformat(),
"cached_at": now,
"source": "exchangerate-api.com",
}, f)
except Exception:
pass
return rate
def refresh_rate():
return hkd_to_cny(force_refresh=True)
if __name__ == "__main__":
r = hkd_to_cny()
print(f"HKD/CNY = {r}")