This commit is contained in:
aaron 2026-05-20 15:55:14 +08:00
parent ec9ec9f3cc
commit f6ae9c4ed6

View File

@ -35,28 +35,33 @@ def paper_trading_enabled() -> bool:
return bool(paper_trading_config().get("enabled", True))
def default_account_equity_usdt() -> float:
return max(1.0, _safe_float(paper_trading_config().get("account_equity_usdt"), 20000.0))
def _paper_cfg(config: dict | None = None) -> dict:
return config if isinstance(config, dict) else paper_trading_config()
def default_leverage() -> float:
return max(1.0, _safe_float(paper_trading_config().get("trade_leverage"), 5.0))
def default_account_equity_usdt(config: dict | None = None) -> float:
return max(1.0, _safe_float(_paper_cfg(config).get("account_equity_usdt"), 20000.0))
def default_notional_usdt() -> float:
return max(1.0, _safe_float(paper_trading_config().get("trade_notional_usdt"), 5000.0))
def default_leverage(config: dict | None = None) -> float:
return max(1.0, _safe_float(_paper_cfg(config).get("trade_leverage"), 5.0))
def default_margin_usdt() -> float:
return round(default_notional_usdt() / default_leverage(), 8)
def default_notional_usdt(config: dict | None = None) -> float:
return max(1.0, _safe_float(_paper_cfg(config).get("trade_notional_usdt"), 5000.0))
def default_fee_rate() -> float:
return max(0.0, _safe_float(paper_trading_config().get("fee_rate"), 0.001))
def default_margin_usdt(config: dict | None = None) -> float:
cfg = _paper_cfg(config)
return round(default_notional_usdt(cfg) / default_leverage(cfg), 8)
def default_slippage_pct() -> float:
return max(0.0, _safe_float(paper_trading_config().get("slippage_pct"), 0.05))
def default_fee_rate(config: dict | None = None) -> float:
return max(0.0, _safe_float(_paper_cfg(config).get("fee_rate"), 0.001))
def default_slippage_pct(config: dict | None = None) -> float:
return max(0.0, _safe_float(_paper_cfg(config).get("slippage_pct"), 0.05))
def _trailing_config() -> dict:
@ -100,12 +105,12 @@ def _entry_plan(rec: dict) -> dict:
return _loads_json(rec.get("entry_plan_json"), {})
def _open_price(current_price: float) -> float:
return round(current_price * (1 + default_slippage_pct() / 100), 12)
def _open_price(current_price: float, config: dict | None = None) -> float:
return round(current_price * (1 + default_slippage_pct(config) / 100), 12)
def _close_price(current_price: float) -> float:
return round(current_price * (1 - default_slippage_pct() / 100), 12)
def _close_price(current_price: float, config: dict | None = None) -> float:
return round(current_price * (1 - default_slippage_pct(config) / 100), 12)
def _trade_pnl_pct(entry_price: float, current_price: float) -> float:
@ -114,29 +119,30 @@ def _trade_pnl_pct(entry_price: float, current_price: float) -> float:
return round((current_price / entry_price - 1) * 100, 4)
def _account_return_pct(pnl_usdt: float, account_equity: float | None = None) -> float:
equity = max(1.0, _safe_float(account_equity, default_account_equity_usdt()))
def _account_return_pct(pnl_usdt: float, account_equity: float | None = None, config: dict | None = None) -> float:
equity = max(1.0, _safe_float(account_equity, default_account_equity_usdt(config)))
return round(_safe_float(pnl_usdt) / equity * 100, 4)
def _margin_roi_pct(pnl_usdt: float, margin_usdt: float) -> float:
margin = max(1.0, _safe_float(margin_usdt, default_margin_usdt()))
def _margin_roi_pct(pnl_usdt: float, margin_usdt: float, config: dict | None = None) -> float:
margin = max(1.0, _safe_float(margin_usdt, default_margin_usdt(config)))
return round(_safe_float(pnl_usdt) / margin * 100, 4)
def _trade_margin(trade: dict) -> float:
def _trade_margin(trade: dict, config: dict | None = None) -> float:
margin = _safe_float(trade.get("margin_usdt"))
if margin > 0:
return margin
leverage = max(1.0, _safe_float(trade.get("leverage"), default_leverage()))
leverage = max(1.0, _safe_float(trade.get("leverage"), default_leverage(config)))
return round(_safe_float(trade.get("notional_usdt")) / leverage, 8)
def _decorate_trade(trade: dict) -> dict:
def _decorate_trade(trade: dict, config: dict | None = None) -> dict:
cfg = _paper_cfg(config)
item = dict(trade)
notional = _safe_float(item.get("notional_usdt"), default_notional_usdt())
leverage = max(1.0, _safe_float(item.get("leverage"), default_leverage()))
margin = _trade_margin({"margin_usdt": item.get("margin_usdt"), "notional_usdt": notional, "leverage": leverage})
notional = _safe_float(item.get("notional_usdt"), default_notional_usdt(cfg))
leverage = max(1.0, _safe_float(item.get("leverage"), default_leverage(cfg)))
margin = _trade_margin({"margin_usdt": item.get("margin_usdt"), "notional_usdt": notional, "leverage": leverage}, cfg)
unrealized = round(notional * _safe_float(item.get("pnl_pct")) / 100, 8)
realized = _safe_float(item.get("realized_pnl_usdt"))
effective_pnl = realized if item.get("status") == "closed" else unrealized
@ -144,9 +150,9 @@ def _decorate_trade(trade: dict) -> dict:
item["leverage"] = leverage
item["margin_usdt"] = margin
item["unrealized_pnl_usdt"] = unrealized
item["margin_roi_pct"] = _margin_roi_pct(effective_pnl, margin)
item["account_return_pct"] = _account_return_pct(effective_pnl)
item["account_equity_usdt"] = default_account_equity_usdt()
item["margin_roi_pct"] = _margin_roi_pct(effective_pnl, margin, cfg)
item["account_return_pct"] = _account_return_pct(effective_pnl, config=cfg)
item["account_equity_usdt"] = default_account_equity_usdt(cfg)
latest_market = _safe_float(item.get("latest_market_price"))
item["latest_price"] = latest_market if latest_market > 0 else _safe_float(item.get("current_price"))
item["latest_price_updated_at"] = item.get("latest_market_price_updated_at") or item.get("updated_at") or ""
@ -507,7 +513,8 @@ def get_paper_trading_summary(days: int = 30) -> dict:
).fetchall()
finally:
conn.close()
items = [_decorate_trade(dict(r)) for r in rows]
cfg = paper_trading_config()
items = [_decorate_trade(dict(r), cfg) for r in rows]
open_items = [x for x in items if x.get("status") == "open"]
closed_items = [x for x in items if x.get("status") == "closed"]
wins = [x for x in closed_items if _safe_float(x.get("realized_pnl_pct")) > 0]
@ -518,7 +525,7 @@ def get_paper_trading_summary(days: int = 30) -> dict:
total_pnl = round(total_realized + open_unrealized, 4)
allocated_margin = round(sum(_safe_float(x.get("margin_usdt")) for x in open_items), 4)
open_position_value = round(sum(_safe_float(x.get("notional_usdt")) for x in open_items), 4)
initial_equity = default_account_equity_usdt()
initial_equity = default_account_equity_usdt(cfg)
current_balance = round(initial_equity + total_pnl, 4)
cumulative_leverage = round(open_position_value / current_balance, 4) if current_balance > 0 else 0
return {
@ -543,11 +550,11 @@ def get_paper_trading_summary(days: int = 30) -> dict:
"open_position_value_usdt": open_position_value,
"cumulative_leverage": cumulative_leverage,
"available_equity_usdt": round(current_balance - allocated_margin, 4),
"margin_usdt": default_margin_usdt(),
"leverage": default_leverage(),
"notional_usdt": default_notional_usdt(),
"fee_rate": default_fee_rate(),
"slippage_pct": default_slippage_pct(),
"margin_usdt": default_margin_usdt(cfg),
"leverage": default_leverage(cfg),
"notional_usdt": default_notional_usdt(cfg),
"fee_rate": default_fee_rate(cfg),
"slippage_pct": default_slippage_pct(cfg),
}
@ -576,8 +583,9 @@ def list_paper_trades(limit: int = 50, offset: int = 0, status: str = "") -> dic
).fetchall()
finally:
conn.close()
cfg = paper_trading_config()
return {
"items": [_decorate_trade(dict(r)) for r in rows],
"items": [_decorate_trade(dict(r), cfg) for r in rows],
"total": int(total or 0),
"limit": limit,
"offset": offset,