50 lines
1.4 KiB
Python
50 lines
1.4 KiB
Python
"""
|
|
止损模块 - 固定止损 & 追踪止损
|
|
关羽 guanyu-dev
|
|
"""
|
|
|
|
from dataclasses import dataclass, field
|
|
|
|
|
|
@dataclass
|
|
class FixedStopLoss:
|
|
"""固定止损:价格跌破 stop_price 即触发。"""
|
|
stop_price: float
|
|
|
|
def check(self, current_price: float) -> bool:
|
|
"""返回 True 表示触发止损。"""
|
|
return current_price <= self.stop_price
|
|
|
|
|
|
@dataclass
|
|
class TrailingStopLoss:
|
|
"""
|
|
追踪止损:
|
|
- 价格涨到 activation_price 以上后激活
|
|
- 激活后按 trail_percent 回撤触发
|
|
"""
|
|
activation_price: float
|
|
trail_percent: float # e.g. 0.05 = 5%
|
|
_high_watermark: float = field(default=0.0, init=False)
|
|
_activated: bool = field(default=False, init=False)
|
|
|
|
@property
|
|
def stop_price(self) -> float:
|
|
"""当前止损价(未激活返回 NaN)。"""
|
|
if not self._activated:
|
|
return float("nan")
|
|
return self._high_watermark * (1 - self.trail_percent)
|
|
|
|
def update(self, current_price: float) -> None:
|
|
"""更新最高价和止损线。"""
|
|
if current_price >= self.activation_price:
|
|
self._activated = True
|
|
if self._activated and current_price > self._high_watermark:
|
|
self._high_watermark = current_price
|
|
|
|
def check(self, current_price: float) -> bool:
|
|
"""返回 True 表示触发止损。"""
|
|
if not self._activated:
|
|
return False
|
|
return current_price <= self.stop_price
|