diff --git a/crypto_monitor_binance/app.py b/crypto_monitor_binance/app.py
index 82c38cb..82a6cc8 100644
--- a/crypto_monitor_binance/app.py
+++ b/crypto_monitor_binance/app.py
@@ -193,6 +193,7 @@ from history_window_lib import (
utc_window_to_bj_sql_strings,
utc_window_to_utc_sql_strings,
)
+from trade_result_lib import normalize_result_with_pnl
def load_env_file(path):
if not os.path.exists(path):
@@ -2132,6 +2133,10 @@ def to_effective_trade_dict(row):
item["display_pnl_source"] = "reviewed"
else:
item["display_pnl_source"] = "local"
+ item["effective_result"] = normalize_result_with_pnl(
+ item.get("effective_result"),
+ item.get("effective_pnl_amount"),
+ )
return item
@@ -2573,19 +2578,6 @@ def calc_actual_rr(pnl_amount, risk_amount):
return None
-def normalize_result_with_pnl(result, pnl_amount):
- """
- 触发“止损”但实际已盈利时,归类为保本止盈,避免语义混淆。
- """
- if result == "止损":
- try:
- if float(pnl_amount or 0) > 0:
- return "保本止盈"
- except Exception:
- pass
- return result
-
-
def calc_breakeven_stop(direction, entry_price, risk_fraction, locked_r, offset_pct):
"""
按“已锁定R”计算目标止损位:
@@ -4352,7 +4344,7 @@ def resolve_synced_flat_close(row, opened_at_str, opened_at_ms=None):
closed_at_ms=close_ms,
)
return (
- guessed,
+ normalize_result_with_pnl(guessed, pnl2),
pnl2,
closed_at_str,
"未能拉取成交明细,按当前市价与止盈/止损位近似归类(建议核对交易所账单)",
@@ -4367,7 +4359,7 @@ def resolve_synced_flat_close(row, opened_at_str, opened_at_ms=None):
result = classify_exit_by_levels(direction, trigger_price, stop_loss, take_profit, exit_px)
if result:
return (
- result,
+ normalize_result_with_pnl(result, pnl),
pnl,
closed_at_str,
"按交易所成交/流水同步为止盈/止损平仓",
@@ -6288,7 +6280,7 @@ def check_order_monitors():
hold_seconds = calc_hold_seconds(opened_at, now)
pnl_amount = calc_pnl(direction, trigger_price, p, margin_capital, leverage)
if res == "止损" and float(pnl_amount or 0) > 0:
- res = "移动止盈" if breakeven_armed else "保本止盈"
+ res = normalize_result_with_pnl("止损", pnl_amount)
else:
res = normalize_result_with_pnl(res, pnl_amount)
close_order_id = ""
@@ -6320,7 +6312,7 @@ def check_order_monitors():
guessed_res = classify_exit_by_levels(direction, trigger_price, stop_loss, take_profit, exit_p)
if guessed_res:
if guessed_res == "止损" and float(pnl_amount or 0) > 0:
- res = "移动止盈" if breakeven_armed else "保本止盈"
+ res = normalize_result_with_pnl("止损", pnl_amount)
else:
res = normalize_result_with_pnl(guessed_res, pnl_amount)
else:
@@ -6351,7 +6343,7 @@ def check_order_monitors():
guessed_res = classify_exit_by_levels(direction, trigger_price, stop_loss, take_profit, exit_p)
if guessed_res:
if guessed_res == "止损" and float(pnl_amount or 0) > 0:
- res = "移动止盈" if breakeven_armed else "保本止盈"
+ res = normalize_result_with_pnl("止损", pnl_amount)
else:
res = normalize_result_with_pnl(guessed_res, pnl_amount)
else:
diff --git a/crypto_monitor_gate/app.py b/crypto_monitor_gate/app.py
index 11bfdf3..d06a926 100644
--- a/crypto_monitor_gate/app.py
+++ b/crypto_monitor_gate/app.py
@@ -193,6 +193,7 @@ from history_window_lib import (
utc_window_to_bj_sql_strings,
utc_window_to_utc_sql_strings,
)
+from trade_result_lib import normalize_result_with_pnl
def load_env_file(path):
@@ -2089,6 +2090,10 @@ def to_effective_trade_dict(row):
item["display_pnl_source"] = "reviewed"
else:
item["display_pnl_source"] = "local"
+ item["effective_result"] = normalize_result_with_pnl(
+ item.get("effective_result"),
+ item.get("effective_pnl_amount"),
+ )
return item
@@ -2287,19 +2292,6 @@ def calc_actual_rr(pnl_amount, risk_amount):
return None
-def normalize_result_with_pnl(result, pnl_amount):
- """
- 触发“止损”但实际已盈利时,归类为保本止盈,避免语义混淆。
- """
- if result == "止损":
- try:
- if float(pnl_amount or 0) > 0:
- return "保本止盈"
- except Exception:
- pass
- return result
-
-
def calc_breakeven_stop(direction, entry_price, risk_fraction, locked_r, offset_pct):
"""
按“已锁定R”计算目标止损位:
@@ -3992,7 +3984,7 @@ def resolve_synced_flat_close(row, opened_at_str, opened_at_ms=None, *, prefer_m
if guessed:
pnl = calc_pnl(direction, trigger_price, p, margin_capital, leverage)
return (
- guessed,
+ normalize_result_with_pnl(guessed, pnl),
pnl,
closed_at_str,
"未能拉取成交明细,按当前市价与止盈/止损位近似归类(建议核对交易所账单)",
@@ -4015,7 +4007,7 @@ def resolve_synced_flat_close(row, opened_at_str, opened_at_ms=None, *, prefer_m
)
if result:
return (
- result,
+ normalize_result_with_pnl(result, pnl),
pnl,
closed_at_str,
"按交易所成交记录同步为止盈/止损平仓",
@@ -6047,7 +6039,7 @@ def check_order_monitors():
hold_seconds = calc_hold_seconds(opened_at, now)
pnl_amount = calc_pnl(direction, trigger_price, p, margin_capital, leverage)
if res == "止损" and float(pnl_amount or 0) > 0:
- res = "移动止盈" if breakeven_armed else "保本止盈"
+ res = normalize_result_with_pnl("止损", pnl_amount)
else:
res = normalize_result_with_pnl(res, pnl_amount)
close_order_id = ""
@@ -6078,7 +6070,7 @@ def check_order_monitors():
guessed_res = classify_exit_by_levels(direction, trigger_price, stop_loss, take_profit, exit_p)
if guessed_res:
if guessed_res == "止损" and float(pnl_amount or 0) > 0:
- res = "移动止盈" if breakeven_armed else "保本止盈"
+ res = normalize_result_with_pnl("止损", pnl_amount)
else:
res = normalize_result_with_pnl(guessed_res, pnl_amount)
else:
@@ -6109,7 +6101,7 @@ def check_order_monitors():
guessed_res = classify_exit_by_levels(direction, trigger_price, stop_loss, take_profit, exit_p)
if guessed_res:
if guessed_res == "止损" and float(pnl_amount or 0) > 0:
- res = "移动止盈" if breakeven_armed else "保本止盈"
+ res = normalize_result_with_pnl("止损", pnl_amount)
else:
res = normalize_result_with_pnl(guessed_res, pnl_amount)
else:
diff --git a/crypto_monitor_gate_bot/app.py b/crypto_monitor_gate_bot/app.py
index 9789716..2d8bc5e 100644
--- a/crypto_monitor_gate_bot/app.py
+++ b/crypto_monitor_gate_bot/app.py
@@ -193,6 +193,7 @@ from history_window_lib import (
utc_window_to_bj_sql_strings,
utc_window_to_utc_sql_strings,
)
+from trade_result_lib import normalize_result_with_pnl
def load_env_file(path):
@@ -2089,6 +2090,10 @@ def to_effective_trade_dict(row):
item["display_pnl_source"] = "reviewed"
else:
item["display_pnl_source"] = "local"
+ item["effective_result"] = normalize_result_with_pnl(
+ item.get("effective_result"),
+ item.get("effective_pnl_amount"),
+ )
return item
@@ -2287,19 +2292,6 @@ def calc_actual_rr(pnl_amount, risk_amount):
return None
-def normalize_result_with_pnl(result, pnl_amount):
- """
- 触发“止损”但实际已盈利时,归类为保本止盈,避免语义混淆。
- """
- if result == "止损":
- try:
- if float(pnl_amount or 0) > 0:
- return "保本止盈"
- except Exception:
- pass
- return result
-
-
def calc_breakeven_stop(direction, entry_price, risk_fraction, locked_r, offset_pct):
"""
按“已锁定R”计算目标止损位:
@@ -3992,7 +3984,7 @@ def resolve_synced_flat_close(row, opened_at_str, opened_at_ms=None, *, prefer_m
if guessed:
pnl = calc_pnl(direction, trigger_price, p, margin_capital, leverage)
return (
- guessed,
+ normalize_result_with_pnl(guessed, pnl),
pnl,
closed_at_str,
"未能拉取成交明细,按当前市价与止盈/止损位近似归类(建议核对交易所账单)",
@@ -4015,7 +4007,7 @@ def resolve_synced_flat_close(row, opened_at_str, opened_at_ms=None, *, prefer_m
)
if result:
return (
- result,
+ normalize_result_with_pnl(result, pnl),
pnl,
closed_at_str,
"按交易所成交记录同步为止盈/止损平仓",
@@ -6047,7 +6039,7 @@ def check_order_monitors():
hold_seconds = calc_hold_seconds(opened_at, now)
pnl_amount = calc_pnl(direction, trigger_price, p, margin_capital, leverage)
if res == "止损" and float(pnl_amount or 0) > 0:
- res = "移动止盈" if breakeven_armed else "保本止盈"
+ res = normalize_result_with_pnl("止损", pnl_amount)
else:
res = normalize_result_with_pnl(res, pnl_amount)
close_order_id = ""
@@ -6078,7 +6070,7 @@ def check_order_monitors():
guessed_res = classify_exit_by_levels(direction, trigger_price, stop_loss, take_profit, exit_p)
if guessed_res:
if guessed_res == "止损" and float(pnl_amount or 0) > 0:
- res = "移动止盈" if breakeven_armed else "保本止盈"
+ res = normalize_result_with_pnl("止损", pnl_amount)
else:
res = normalize_result_with_pnl(guessed_res, pnl_amount)
else:
@@ -6109,7 +6101,7 @@ def check_order_monitors():
guessed_res = classify_exit_by_levels(direction, trigger_price, stop_loss, take_profit, exit_p)
if guessed_res:
if guessed_res == "止损" and float(pnl_amount or 0) > 0:
- res = "移动止盈" if breakeven_armed else "保本止盈"
+ res = normalize_result_with_pnl("止损", pnl_amount)
else:
res = normalize_result_with_pnl(guessed_res, pnl_amount)
else:
diff --git a/crypto_monitor_okx/app.py b/crypto_monitor_okx/app.py
index 7f8d77f..a0dff1f 100644
--- a/crypto_monitor_okx/app.py
+++ b/crypto_monitor_okx/app.py
@@ -192,6 +192,7 @@ from history_window_lib import (
utc_window_to_bj_sql_strings,
utc_window_to_utc_sql_strings,
)
+from trade_result_lib import normalize_result_with_pnl
def load_env_file(path):
@@ -2038,6 +2039,10 @@ def to_effective_trade_dict(row):
item["display_pnl_source"] = "reviewed"
else:
item["display_pnl_source"] = "local"
+ item["effective_result"] = normalize_result_with_pnl(
+ item.get("effective_result"),
+ item.get("effective_pnl_amount"),
+ )
return item
@@ -2183,19 +2188,6 @@ def calc_actual_rr(pnl_amount, risk_amount):
return None
-def normalize_result_with_pnl(result, pnl_amount):
- """
- 触发“止损”但实际已盈利时,归类为保本止盈,避免语义混淆。
- """
- if result == "止损":
- try:
- if float(pnl_amount or 0) > 0:
- return "保本止盈"
- except Exception:
- pass
- return result
-
-
def calc_breakeven_stop(direction, entry_price, risk_fraction, locked_r, offset_pct):
"""
按“已锁定R”计算目标止损位:
@@ -3448,7 +3440,7 @@ def resolve_synced_flat_close(row, opened_at_str, opened_at_ms=None):
if guessed:
pnl = calc_pnl(direction, trigger_price, p, margin_capital, leverage)
return (
- guessed,
+ normalize_result_with_pnl(guessed, pnl),
pnl,
closed_at_str,
"未能拉取成交明细,按当前市价与止盈/止损位近似归类(建议核对交易所账单)",
@@ -3464,7 +3456,7 @@ def resolve_synced_flat_close(row, opened_at_str, opened_at_ms=None):
pnl = calc_pnl(direction, trigger_price, exit_px, margin_capital, leverage)
if result:
return (
- result,
+ normalize_result_with_pnl(result, pnl),
pnl,
closed_at_str,
"按交易所成交记录同步为止盈/止损平仓",
@@ -5796,7 +5788,7 @@ def check_order_monitors():
hold_seconds = calc_hold_seconds(opened_at, now)
pnl_amount = calc_pnl(direction, trigger_price, p, margin_capital, leverage)
if res == "止损" and float(pnl_amount or 0) > 0:
- res = "移动止盈" if breakeven_armed else "保本止盈"
+ res = normalize_result_with_pnl("止损", pnl_amount)
else:
res = normalize_result_with_pnl(res, pnl_amount)
close_order_id = ""
@@ -5827,7 +5819,7 @@ def check_order_monitors():
guessed_res = classify_exit_by_levels(direction, trigger_price, stop_loss, take_profit, exit_p)
if guessed_res:
if guessed_res == "止损" and float(pnl_amount or 0) > 0:
- res = "移动止盈" if breakeven_armed else "保本止盈"
+ res = normalize_result_with_pnl("止损", pnl_amount)
else:
res = normalize_result_with_pnl(guessed_res, pnl_amount)
else:
@@ -5857,7 +5849,7 @@ def check_order_monitors():
guessed_res = classify_exit_by_levels(direction, trigger_price, stop_loss, take_profit, exit_p)
if guessed_res:
if guessed_res == "止损" and float(pnl_amount or 0) > 0:
- res = "移动止盈" if breakeven_armed else "保本止盈"
+ res = normalize_result_with_pnl("止损", pnl_amount)
else:
res = normalize_result_with_pnl(guessed_res, pnl_amount)
else:
diff --git a/embed_templates/embed_boot_scripts.html b/embed_templates/embed_boot_scripts.html
index 8e83b57..ead5c0d 100644
--- a/embed_templates/embed_boot_scripts.html
+++ b/embed_templates/embed_boot_scripts.html
@@ -684,8 +684,21 @@ function toggleStatsCard(){
btn.innerText = collapsed ? "展开" : "折叠";
}
+function bindListWindowDateAutoCustom(){
+ const preset = document.getElementById("win-preset-select");
+ const fromEl = document.getElementById("win-from-utc");
+ const toEl = document.getElementById("win-to-utc");
+ function toCustom(){
+ if(preset) preset.value = "custom";
+ toggleListWindowCustom();
+ }
+ if(fromEl) fromEl.addEventListener("change", toCustom);
+ if(toEl) toEl.addEventListener("change", toCustom);
+}
+
attachListWindowToExports();
toggleListWindowCustom();
+bindListWindowDateAutoCustom();
initStatsSegmentFromUrl();
if(document.getElementById("journal-list")) loadJournals();
if(document.getElementById("review-list")) loadReviews();
diff --git a/embed_templates/embed_shell.html b/embed_templates/embed_shell.html
index bc2c254..0977200 100644
--- a/embed_templates/embed_shell.html
+++ b/embed_templates/embed_shell.html
@@ -115,6 +115,6 @@
{% include 'embed_boot_scripts.html' %}
-
+