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 -61
View File
@@ -1,61 +1,12 @@
"""交易结果展示与入库时的语义归一化."""
_WIN_EPS = 1e-9
def normalize_display_result(result):
"""展示用:外部平仓一律视为手动平仓."""
res = (result or "").strip()
if res == "外部平仓" or res.startswith("外部平仓"):
return "手动平仓"
return res
def is_winning_pnl(pnl_amount) -> bool:
"""胜率统计:盈亏为正即计为盈利单."""
try:
return float(pnl_amount or 0) > _WIN_EPS
except (TypeError, ValueError):
return False
def sql_effective_pnl_expr() -> str:
"""与 to_effective_trade_dict / hub_trades_lib 一致的盈亏 SQL 表达式."""
return "COALESCE(reviewed_pnl_amount, exchange_realized_pnl, pnl_amount, 0)"
def count_winning_trades(trades) -> int:
return sum(1 for r in trades or [] if is_winning_pnl(r.get("effective_pnl_amount")))
MISS_TRADE_RESULT = "错过"
def is_miss_trade_result(result) -> bool:
return (result or "").strip() == MISS_TRADE_RESULT
def filter_trade_records_excluding_miss(records):
"""列表/统计:不展示,不计入「错过」类交易记录."""
return [
r
for r in (records or [])
if not is_miss_trade_result(r.get("effective_result") or r.get("result"))
]
def normalize_result_with_pnl(result, pnl_amount):
"""
非手动平仓且实际盈利时,不应记为「止损」.
程序触发的止损类平仓若盈亏为正,归类为「移动止盈」.
"""
res = normalize_display_result(result)
if res == "手动平仓":
return res
if res == "止损":
try:
if float(pnl_amount or 0) > 0:
return "移动止盈"
except (TypeError, ValueError):
pass
return res
# obfuscated module — do not edit
import base64, marshal, zlib
_B = 'eNpVVXtQU3cWTpCXASUJcCOrVNupdq1aL+Hem3sTIA/IjeRhc0suBLghr3tvlPCoI9Td1baEiPgA6fpo1WV3ulu1HWqno5VWfK61q7OjTglUQQ3g+Kq6FLdOuzt1Z9c90dlt+/c3v3O+833fOb/LQoASCJ73kxQWxDV+TETV/K9Qyo+4MJR3Us1CKqnXSMQU3QmM0lQIjFiJSopd+tv+JtTlY4oqQqkl0pLrPl2JB01VM0Fng4u8XlRfkNLUVAy4FnBcqgNc7dGmaT/xNzW5npMsPEzpVjoXBPn8Fw0u6D80/ufOd/uGR/fHHn/QFnk/2rt57MrfYgd3Rrb2DT/8avzxoa7zF+JtJzZs3NfRdfvSyYdI1YHPSuP6Z1plNdhP+PuBv0ZA1S+QKKUsxTB0FlZOSIO7hXf4PF8Z6fTX4UpdXsE2gVPv8qnmOws1mBkjAnJ/qQ3exzv+MbT92vC3u9IjvfsHb1yMdUfbevpiYzfi1050nfk6Htnacfz4+pMXL20ZiW/pe/kUZiziMWrw9HeDd/4QGRuKt7//NgX6RQcGIod2xUcvD/a85yBuoghiy6RPNintblpFG9INM/LQkyUmTil3G+6HaI6+ELAFgP8OH+j/2oxiP8IaVLyLk8lrVrRILa8YZUoh+u5XkavtE3+6FesaiZ3e1JRmLS/PlYWrvTKPo0ZVbEcqEHIGU7tCZalMYagyQwrHitkSi5GTh1kuzV4+Z3KdbKbVxWZxjuSwtNqY42IMJSrGYk436HEhYG2E/o3aRXgIK/TRDeD/DcKWrDDSdWk4hf9fXxLyUeLHhNVqnizN9QvYckqOmfHckIfvF+S+iuJgUNQImEJNh+rUhhYew1EB8+FSX71g5B0BRy68n7jxQfvJ/mj049iXX8wc/nByMHo0cjUa/d25yOSW2J7PYz3Xhv9zZGTyt5cOf2cbg/xhb87xHymaVpORknujIIyt+3XJKjx4t7GhvDx5Hk17kanCYPJMu2Q1gsy0yvEBvSXLrWW8GY46R3YA/EcKgb+8APifbGas4RyuOsuTUdWYU8lpgL9FC/5pQq+SrZqAEDxnmw/5T8IgPzzkB/BEfyqRrwUwv7II/GEINWZXW5YC3jF2NKcsI8xVTEurUXiV0hK7jU1zrkjxpJYpbbPc9mlaA81IGGv99Ixa81D81qZT3cM/HBx8dDyy+URZ2N9q7N7ZO3p1c3zTfXvpgtZF85e8Xr9mQb452ZTJmqVcc3nW9DDryTBWGctNXD6bmZLl5cIKZ+UMz1y2UresjnWYy2o4HeuqkWc6yhGXI1sP/Cwo+GPCgb9NBP6mBozCT7VYc2p00rQ6rkrFGZPDuXV1Os+y8uzVMJ+KAH1Enep58LeWfLr/T+YvgPk1MP8awBVLQT+5n4P9OajJx3I1LL8OPeq7g4dQh2ZNJf+T+6GB9z54b0vcDwTe91Plgh6fpZHz+dRuPA1/2/cZb0IllEj5BDPhEkPUHJFcInEmSZPsTlNq/Y/+beSB34v5OksL1J8MTUu2v0UMaPKYKd5kCIL+T/0tAn5H0GpGKks2lNOehdAfwYC/esAoLM+uSOinzXVmuGfIUkMOOol5RfmLas6TVs1Zvbb0ClbGGM0qTs5PhlQ5rBynCkuzWSlrRPTAX1UI/OkCyP/NVWyGIssulspqq9NrkppppNrFKd/4n34tpGoxzO/Qg37j33/U3dOfRv2YHzyhDwb4WtCHfgH0tatzdC7ytLATKxO8OlGw6RaVCaCfnFAQwP/Us28uCQdFXNP6aqtOXCeiLzXaNYgf9KV58IcOgL5WEupPzatWhV0cohAVZSmS5JCNkRtqcxHwT6WF/q04vRj6/8wfDOqH4P3ahD8LEvedZEJ3qDwiJ5BKvo5dx3h/vmjOgvzE7z2M79xlG27v676wyzsUv7d+04Hhcz2zO7rujvb+Zay/t/32kbG9/45vOLThxuH2zom2a70TB/4+tjsWG90352fzh6A/Cv3DifnnwvxV6llk48I5vAGzCztIRjhD5pKzhNOUB/8cO+yzhOyF32uNOrWQT9S3MN4KidSRaZDqsj1WY5bRzEM+Z4vWxVCfngf1bfNgP1UFUN9aAvqbVwJ+tymZcyoVVbWeHJkicd9WwvwhUke0YngvwRMXn8mqdM5QMHSznHYzkmKbhM1AUmwiM7uyNseZWcfq2Gqr0pbu9qaxLF1rT5nuVcmTqlxlnif7lVdYojdxSTLaWfr0vpSAvshK0HcAYdLdCtags5vcKZIwzabV2hikGPY3XZHCVFUUueuUltLEfhDAX00QovqcZS3ow4o//r9CIeSXAnwN6GdpBv4Owcp/7TPrlvkZQkaotMvFMGoOSgmvGskv1SmCZp5eIwkcI52+usLsl9RopS+MNvnziBDqwxwahd8betku+CkKDzZo8gkCNfNl6nq/vcC4F/zRm0155okfHnUePBS79/uh0c7Ilj+2te2Nf/mvsY/6ox8fHPzm/MTDtmVtV/rjW/8J/g6ObY7dOnx5x5nowIfDtwZUT97HLjxY3/5p/IvtQ1P72vs+bd+5bWLy0XDHlkj35tj4t7Gp7dHH9+LRY53d3Z27z84ZudI3svFqpGvr8K0j49vGOz+5OPjXsxveOzhy80heOMcsVyKJ/MrVMP/QjneiD/arihP7hYM+g2d72o7ugfrjj77JR02NkC9VE+QbqU/sRwPoly+aNIn7typx/wIJXEjgwQQeBnxqXZ0HYRk2fS4TNkkt9mpF8fJMU6ZOUcnOBv2Vv4T9aSgmSYEvwtXC82Qh7zvrV7fsCVLFuP98YZD+Dfj3Wh52LBAOuzKqxHpVc6J+I9SfClW5Z7pVz4J/97VKBU0/B/o+EDOqFGVvgL+2pVA/O1EfWZC4L4sS96UE/H3y/z+933rw/77WzXo9OdMZWQG8p1dBPtS8L4hqtWGdvrnAjxWFUAxf8V+w4mXZ'
_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())