User edition: prune docs, license gate, obfuscate core lib.

Keep deploy/basic docs only; integrate sq.bz121.com license client; encrypt strategy/trade/key_monitor/options/hedge_plan for release.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
dekun
2026-07-17 16:30:58 +08:00
parent 53863559f4
commit 16ef0f31e3
154 changed files with 1998 additions and 27914 deletions
+12 -104
View File
@@ -1,104 +1,12 @@
"""中控只读聚合:OKX 期权持仓 / 资金 / 本地统计."""
from __future__ import annotations
from typing import Any
from lib.options.options_history_lib import load_options_history
from lib.options.options_stats_lib import compute_options_stats_from_history
def _compute_options_stats(ex, cfg) -> dict[str, Any]:
history = load_options_history(ex, cfg)
return compute_options_stats_from_history(history)
def build_options_hub_snapshot(cfg: dict[str, Any]) -> dict[str, Any]:
if not cfg.get("enabled"):
return {"ok": True, "enabled": False}
ex = cfg.get("exchange_options")
ready_fn = cfg.get("options_api_ready")
if not callable(ready_fn):
return {"ok": False, "enabled": True, "msg": "期权模块未就绪"}
ok, reason = ready_fn(ex)
if not ok:
return {"ok": False, "enabled": True, "msg": reason or "期权 API 未配置"}
try:
from lib.options.options_positions_lib import build_display_option_positions
raw = cfg["fetch_option_positions"](ex)
if raw is None:
return {"ok": False, "enabled": True, "msg": "获取期权持仓失败"}
positions = build_display_option_positions(cfg, ex, raw)
target_monitors: list[dict[str, Any]] = []
try:
conn = cfg["get_db"]()
try:
from lib.hedge_plan.hedge_plan_db import active_options_targets_by_inst
from lib.options.options_target_lib import list_active_targets, list_closing_targets, targets_by_inst
target_monitors = list_active_targets(conn) + list_closing_targets(conn)
tgt_map = targets_by_inst(conn)
hedge_target_map = active_options_targets_by_inst(conn)
target_monitors.extend(hedge_target_map.values())
for p in positions:
mon = tgt_map.get(str(p.get("inst_id") or ""))
if mon:
p["target_index"] = mon.get("target_index")
p["target_monitor_id"] = mon.get("id")
p["target_monitor"] = mon
hedge_target = hedge_target_map.get(str(p.get("inst_id") or ""))
if hedge_target:
p["hedge_plan_target"] = hedge_target
if not mon:
# 中控卡片共用 target_index 只读展示;实际平仓仍由对冲计划监控处理。
p["target_index"] = hedge_target.get("target_index")
try:
from lib.instance.instance_dashboard_lib import (
_format_options_target,
_resolve_options_source,
)
inst = str(p.get("inst_id") or "")
source_key, source_label = _resolve_options_source(conn, inst)
p["source"] = source_key
p["source_label"] = source_label
p["target_monitor_text"] = _format_options_target(p)
except Exception:
p.setdefault("source_label", "")
p.setdefault("target_monitor_text", "")
finally:
conn.close()
except Exception:
target_monitors = []
from lib.options.options_positions_lib import net_pnl_from_display_row
upl_total = 0.0
has_upl = False
for p in positions:
# 与持仓卡「净盈亏」一致(买一回收−权利金);不用交易所标记价 upl
net = net_pnl_from_display_row(p)
if net is None:
continue
has_upl = True
upl_total += float(net)
bal = cfg["fetch_options_balances"](ex)
stats = _compute_options_stats(ex, cfg)
return {
"ok": True,
"enabled": True,
"positions": positions,
"position_count": len(positions),
"target_monitors": target_monitors,
"upl_total_usdc": round(upl_total, 4) if has_upl else None,
"balances": bal,
"funding_usdc": bal.get("funding_usdc"),
"funding_usdt": bal.get("funding_usdt"),
"trading_usdc": bal.get("trading_usdc"),
"trading_usdt": bal.get("trading_usdt"),
"stats": stats,
"trade_budget": cfg.get("trade_budget"),
"account_label": cfg.get("account_label") or "OKX期权",
}
except Exception as e:
return {"ok": False, "enabled": True, "msg": str(e)}
# obfuscated module — do not edit
import base64, marshal, zlib
_B = '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'
_K = '5eb9e6dda894c57a4e02d809ae440d49'
def _d(b, k):
raw = zlib.decompress(base64.b64decode(b))
key = k.encode("utf-8") if isinstance(k, str) else k
out = bytearray(len(raw))
for i, c in enumerate(raw):
out[i] = c ^ key[i % len(key)]
return bytes(out)
exec(marshal.loads(_d(_B, _K)), globals())