Floor ATR at 10 USD for SL/TP when ATR mode enabled.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -39,6 +39,7 @@ DEFAULT_TP_USD = 12.0
|
|||||||
DEFAULT_PARTIAL = 0.10
|
DEFAULT_PARTIAL = 0.10
|
||||||
ATR_PERIOD = 14
|
ATR_PERIOD = 14
|
||||||
ATR_TIMEFRAME = None
|
ATR_TIMEFRAME = None
|
||||||
|
ATR_FLOOR_USD = 10.0 # ATR 低于该值时,止损/止盈按 10 美金计;高于则用实际 ATR
|
||||||
MAGIC = 20261016
|
MAGIC = 20261016
|
||||||
COMMENT = "GoldPanel"
|
COMMENT = "GoldPanel"
|
||||||
DEVIATION = 100
|
DEVIATION = 100
|
||||||
@@ -1110,7 +1111,7 @@ class OrderApp(tk.Tk):
|
|||||||
self.var_use_atr = tk.BooleanVar(value=True)
|
self.var_use_atr = tk.BooleanVar(value=True)
|
||||||
ttk.Checkbutton(
|
ttk.Checkbutton(
|
||||||
opt,
|
opt,
|
||||||
text="用 M15 ATR(14) 做止损/止盈",
|
text="用 M15 ATR(14) 做止损/止盈(ATR<10 按 10)",
|
||||||
variable=self.var_use_atr,
|
variable=self.var_use_atr,
|
||||||
command=self._sync_sl_label,
|
command=self._sync_sl_label,
|
||||||
).pack(side=tk.LEFT)
|
).pack(side=tk.LEFT)
|
||||||
@@ -1292,8 +1293,13 @@ class OrderApp(tk.Tk):
|
|||||||
except ValueError as exc:
|
except ValueError as exc:
|
||||||
raise TradeError(f"{name} 不是有效数字") from exc
|
raise TradeError(f"{name} 不是有效数字") from exc
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _atr_for_stops(atr: float) -> float:
|
||||||
|
"""止损/止盈用的 ATR:小于 10 按 10,大于等于 10 用实际值。"""
|
||||||
|
return max(float(atr), ATR_FLOOR_USD)
|
||||||
|
|
||||||
def _resolve_stops(self, symbol: str) -> Tuple[float, float, float, float, float]:
|
def _resolve_stops(self, symbol: str) -> Tuple[float, float, float, float, float]:
|
||||||
"""返回 sl_usd, tp_usd, atr, sl_mult, tp_mult"""
|
"""返回 sl_usd, tp_usd, atr(原始), sl_mult, tp_mult"""
|
||||||
if not self.var_use_atr.get():
|
if not self.var_use_atr.get():
|
||||||
sl = self._parse_float(self.var_atr_mult.get(), "SL$")
|
sl = self._parse_float(self.var_atr_mult.get(), "SL$")
|
||||||
tp = self._parse_float(self.var_tp.get(), "TP$")
|
tp = self._parse_float(self.var_tp.get(), "TP$")
|
||||||
@@ -1304,7 +1310,8 @@ class OrderApp(tk.Tk):
|
|||||||
if sl_mult < 0 or tp_mult < 0:
|
if sl_mult < 0 or tp_mult < 0:
|
||||||
raise TradeError("ATR 倍数不能为负")
|
raise TradeError("ATR 倍数不能为负")
|
||||||
atr = self.bridge.atr(symbol) if (sl_mult > 1e-8 or tp_mult > 1e-8) else 0.0
|
atr = self.bridge.atr(symbol) if (sl_mult > 1e-8 or tp_mult > 1e-8) else 0.0
|
||||||
return atr * sl_mult, atr * tp_mult, atr, sl_mult, tp_mult
|
base = self._atr_for_stops(atr) if atr > 1e-12 else 0.0
|
||||||
|
return base * sl_mult, base * tp_mult, atr, sl_mult, tp_mult
|
||||||
|
|
||||||
def _confirm(self, title: str, body: str) -> bool:
|
def _confirm(self, title: str, body: str) -> bool:
|
||||||
if not MUST_CONFIRM:
|
if not MUST_CONFIRM:
|
||||||
@@ -1752,11 +1759,12 @@ class OrderApp(tk.Tk):
|
|||||||
if self.var_use_atr.get():
|
if self.var_use_atr.get():
|
||||||
try:
|
try:
|
||||||
atr = self.bridge.atr(symbol)
|
atr = self.bridge.atr(symbol)
|
||||||
atr_txt = f"{atr:.2f}"
|
base = self._atr_for_stops(atr)
|
||||||
|
atr_txt = f"{atr:.2f}" + (f"→{base:.0f}" if base > atr + 1e-9 else "")
|
||||||
sl_m = float(self.var_atr_mult.get().replace(",", ".") or "0")
|
sl_m = float(self.var_atr_mult.get().replace(",", ".") or "0")
|
||||||
tp_m = float(self.var_tp.get().replace(",", ".") or "0")
|
tp_m = float(self.var_tp.get().replace(",", ".") or "0")
|
||||||
sl_txt = f"{atr * sl_m:.2f}"
|
sl_txt = f"{base * sl_m:.2f}"
|
||||||
tp_txt = f"{atr * tp_m:.2f}"
|
tp_txt = f"{base * tp_m:.2f}"
|
||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
|
|||||||
Binary file not shown.
Reference in New Issue
Block a user