Initialize crypto_monitor_user (user edition) from monitor codebase.
Retarget git remote, install path, and deploy docs from crypto_monitor to crypto_monitor_user. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,61 @@
|
||||
"""交易结果展示与入库时的语义归一化."""
|
||||
|
||||
_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
|
||||
Reference in New Issue
Block a user