Add OKX trading-account USDC auto-swap and lock exit target while in position.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -2,6 +2,7 @@ from __future__ import annotations
|
||||
|
||||
import time
|
||||
from dataclasses import dataclass
|
||||
from typing import Any
|
||||
|
||||
EXIT_MODE_FIXED = "fixed_usdt"
|
||||
EXIT_MODE_PREMIUM = "premium_multiple"
|
||||
@@ -29,6 +30,62 @@ def resolve_exit_target(
|
||||
return float(net_profit_target), EXIT_MODE_FIXED
|
||||
|
||||
|
||||
def lock_trade_exit_target(
|
||||
db: Any,
|
||||
*,
|
||||
group_id: str,
|
||||
initial_premium: float,
|
||||
) -> float:
|
||||
"""
|
||||
开仓成交后锁定本组成交出场目标到 groups/positions。
|
||||
持仓期间盯盘与展示均用该值,不再跟随时价重算以损定仓/出场。
|
||||
"""
|
||||
from ..config import get_settings
|
||||
from ..sim.ledger import Ledger
|
||||
|
||||
s = get_settings()
|
||||
ledger = Ledger(db)
|
||||
exit_mode = ledger.get_setting_str("exit_mode", s.exit_mode) or EXIT_MODE_FIXED
|
||||
net_target = float(
|
||||
ledger.get_setting_float("net_profit_target", s.net_profit_target)
|
||||
or s.net_profit_target
|
||||
)
|
||||
prem_mult = float(
|
||||
ledger.get_setting_float("premium_exit_multiple", s.premium_exit_multiple)
|
||||
or s.premium_exit_multiple
|
||||
)
|
||||
target, _mode = resolve_exit_target(
|
||||
exit_mode=str(exit_mode),
|
||||
net_profit_target=net_target,
|
||||
premium_exit_multiple=prem_mult,
|
||||
initial_premium=float(initial_premium or 0),
|
||||
)
|
||||
target = float(target)
|
||||
db.execute(
|
||||
"UPDATE groups SET exit_target_usdt=? WHERE group_id=?",
|
||||
(target, group_id),
|
||||
)
|
||||
db.execute(
|
||||
"UPDATE positions SET exit_target_usdt=? WHERE id=1",
|
||||
(target,),
|
||||
)
|
||||
return target
|
||||
|
||||
|
||||
def read_locked_exit_target(pos: dict[str, Any] | None) -> float | None:
|
||||
"""持仓行上的锁定目标;无则 None(旧仓回退设置值)。"""
|
||||
if not pos:
|
||||
return None
|
||||
v = pos.get("exit_target_usdt")
|
||||
if v is None or v == "":
|
||||
return None
|
||||
try:
|
||||
f = float(v)
|
||||
except (TypeError, ValueError):
|
||||
return None
|
||||
return f if f > 0 else None
|
||||
|
||||
|
||||
def check_expiry_close(
|
||||
*,
|
||||
expiry_ms: int | None,
|
||||
@@ -50,14 +107,19 @@ def check_exits(
|
||||
net_profit_target: float,
|
||||
premium_exit_multiple: float,
|
||||
initial_premium: float,
|
||||
locked_exit_target: float | None = None,
|
||||
) -> ExitDecision:
|
||||
"""净盈利(预估全平后)≥ 所选模式目标则全平。"""
|
||||
target, mode = resolve_exit_target(
|
||||
exit_mode=exit_mode,
|
||||
net_profit_target=net_profit_target,
|
||||
premium_exit_multiple=premium_exit_multiple,
|
||||
initial_premium=initial_premium,
|
||||
)
|
||||
"""净盈利(预估全平后)≥ 所选模式目标则全平。持仓锁定目标优先。"""
|
||||
if locked_exit_target is not None and float(locked_exit_target) > 0:
|
||||
target = float(locked_exit_target)
|
||||
mode = EXIT_MODE_FIXED
|
||||
else:
|
||||
target, mode = resolve_exit_target(
|
||||
exit_mode=exit_mode,
|
||||
net_profit_target=net_profit_target,
|
||||
premium_exit_multiple=premium_exit_multiple,
|
||||
initial_premium=initial_premium,
|
||||
)
|
||||
if target > 0 and net_pnl + 1e-9 >= target:
|
||||
reason = "premium_multiple" if mode == EXIT_MODE_PREMIUM else "fixed_usdt"
|
||||
return ExitDecision(True, reason, target)
|
||||
|
||||
Reference in New Issue
Block a user