优化单根 k 线可以多次开仓
This commit is contained in:
@@ -36,12 +36,11 @@ class BitmartFuturesTransaction:
|
||||
# 开仓频率控制
|
||||
self.open_cooldown_seconds = 60 # 开仓冷却时间(秒),两次开仓至少间隔此时长
|
||||
self.last_open_time = None # 上次开仓时间
|
||||
self.last_open_kline_id = None # 上次开仓所在 K 线 id,同一根 K 线只允许开仓一次
|
||||
self.last_open_kline_id = None # 上次开仓所在 K 线 id(仅记录,不限制单 K 线开仓次数)
|
||||
|
||||
self.leverage = "100" # 高杠杆(全仓模式下可开更大仓位)
|
||||
self.open_type = "cross" # 全仓模式
|
||||
self.risk_percent = 0 # 未使用;若启用则可为每次开仓占可用余额的百分比
|
||||
self.take_profit_usd = 5 # 仓位盈利达到此金额(美元)时平仓止盈
|
||||
self.stop_loss_usd = -3 # 固定止损:亏损达到 3 美元平仓
|
||||
self.trailing_activation_usd = 2 # 盈利达到此金额后启动移动止损
|
||||
self.trailing_distance_usd = 1.5 # 从最高盈利回撤此金额则平仓
|
||||
@@ -54,9 +53,9 @@ class BitmartFuturesTransaction:
|
||||
self.retrace_ratio = 0.5 # 回撤系数,如 0.5 表示允许回撤涨幅的 50%(类似斐波那契 50% 回撤)
|
||||
self.min_rise_pct_to_activate = 0.02 # 至少涨/跌这么多才启用动态回撤,避免噪音
|
||||
self.min_drop_pct_from_high = 0.03 # 至少从最高点回撤这么多%才平仓(保底,避免过于敏感)
|
||||
# EMA(10) + EMA(20) / ATR(14) 平仓(多单优先):收盘跌破 EMA10 先平;或从最高价回撤 ≥ atr_multiplier×ATR(14) 平
|
||||
self.use_ema_atr_exit = True # 是否启用 EMA/ATR 平仓规则(多单)
|
||||
self.atr_multiplier = 1.1 # 追踪止盈:从最高价回撤 ≥ 此倍数 × ATR(14) 则平仓
|
||||
# EMA(10) + ATR(14) 平仓(多/空一致):多单跌破 EMA10 或从最高回撤≥ATR 平;空单涨破 EMA10 或从最低反弹≥ATR 平
|
||||
self.use_ema_atr_exit = True # 是否启用 EMA/ATR 平仓规则(多单+空单)
|
||||
self.atr_multiplier = 1.1 # 追踪止盈:从极值回撤/反弹 ≥ 此倍数 × ATR(14) 则平仓
|
||||
self._candle_high_seen = None # 当前K线内见过的最高价(多头用)
|
||||
self._candle_low_seen = None # 当前K线内见过的最低价(空头用)
|
||||
self._candle_id_for_high_low = None # 记录高低对应的K线 id,换线则重置
|
||||
@@ -461,11 +460,8 @@ class BitmartFuturesTransaction:
|
||||
return None
|
||||
|
||||
def can_open(self, current_kline_id):
|
||||
"""开仓前过滤:同一根 K 线只开一次 + 开仓冷却时间。仅用于 long/short 新开仓。"""
|
||||
"""开仓前过滤:仅开仓冷却时间。单根 K 线符合规则可多次开仓。"""
|
||||
now = time.time()
|
||||
if self.last_open_kline_id is not None and self.last_open_kline_id == current_kline_id:
|
||||
logger.info(f"开仓频率控制:本 K 线({current_kline_id})已开过仓,跳过")
|
||||
return False
|
||||
if self.last_open_time is not None and now - self.last_open_time < self.open_cooldown_seconds:
|
||||
remain = self.open_cooldown_seconds - (now - self.last_open_time)
|
||||
logger.info(f"开仓冷却中,剩余 {remain:.0f} 秒")
|
||||
@@ -710,7 +706,7 @@ class BitmartFuturesTransaction:
|
||||
elif self.start == -1:
|
||||
self._candle_low_seen = min(self._candle_low_seen or float('inf'), current_price)
|
||||
|
||||
# 多单优先:EMA(10) + ATR(14) 平仓 —— 收盘跌破 EMA10 先平;或从最高价回撤 ≥ 1.1×ATR 平
|
||||
# 多单:EMA(10) + ATR(14) 平仓 —— 收盘跌破 EMA10 先平;或从最高价回撤 ≥ 1.1×ATR 平
|
||||
if self.start == 1 and self.use_ema_atr_exit:
|
||||
kline_series = self.get_klines_series(35)
|
||||
ema10, ema20, atr14 = self.get_ema_atr_for_exit(kline_series)
|
||||
@@ -729,6 +725,25 @@ class BitmartFuturesTransaction:
|
||||
time.sleep(3)
|
||||
continue
|
||||
|
||||
# 空单:EMA(10) + ATR(14) 平仓 —— 收盘涨破 EMA10 先平;或从最低价反弹 ≥ 1.1×ATR 平
|
||||
if self.start == -1 and self.use_ema_atr_exit:
|
||||
kline_series = self.get_klines_series(35)
|
||||
ema10, ema20, atr14 = self.get_ema_atr_for_exit(kline_series)
|
||||
if ema10 is not None and current_price > ema10:
|
||||
logger.info(f"空单 EMA10 平仓:当前价 {current_price:.2f} 涨破 EMA10 {ema10:.2f}(能赚点是点)")
|
||||
self.平仓()
|
||||
self.max_unrealized_pnl_seen = None
|
||||
self._candle_low_seen = None
|
||||
time.sleep(3)
|
||||
continue
|
||||
if atr14 is not None and self._candle_low_seen and (current_price - self._candle_low_seen) >= self.atr_multiplier * atr14:
|
||||
logger.info(f"空单 ATR 追踪止盈:最低 {self._candle_low_seen:.2f},当前 {current_price:.2f},反弹 {(current_price - self._candle_low_seen):.2f} >= {self.atr_multiplier}×ATR(14)={atr14:.2f}")
|
||||
self.平仓()
|
||||
self.max_unrealized_pnl_seen = None
|
||||
self._candle_low_seen = None
|
||||
time.sleep(3)
|
||||
continue
|
||||
|
||||
use_fixed = self.drop_from_high_mode == 'fixed' and self.drop_from_high_to_close and self.drop_from_high_to_close > 0
|
||||
use_pct = self.drop_from_high_mode == 'pct_retrace'
|
||||
if use_fixed or use_pct:
|
||||
@@ -800,14 +815,6 @@ class BitmartFuturesTransaction:
|
||||
self.max_unrealized_pnl_seen = None
|
||||
time.sleep(3)
|
||||
continue
|
||||
# 止盈:盈利达到 take_profit_usd 平仓
|
||||
if pnl_usd >= self.take_profit_usd:
|
||||
logger.info(f"仓位盈利 {pnl_usd:.2f} 美元 >= {self.take_profit_usd} 美元,执行止盈平仓")
|
||||
self.平仓()
|
||||
self.max_unrealized_pnl_seen = None
|
||||
time.sleep(3)
|
||||
continue
|
||||
|
||||
# 4. 检查信号
|
||||
signal = self.check_signal(current_price, prev_kline, current_kline)
|
||||
|
||||
@@ -816,7 +823,7 @@ class BitmartFuturesTransaction:
|
||||
if not self.can_reverse(current_price, signal[1]):
|
||||
signal = None
|
||||
|
||||
# 5.5 开仓频率过滤:同一根 K 线只开一次 + 开仓冷却
|
||||
# 5.5 开仓频率过滤:仅冷却时间,单根 K 线符合规则可多次开仓
|
||||
if signal and signal[0] in ('long', 'short'):
|
||||
if not self.can_open(current_kline_time):
|
||||
signal = None
|
||||
|
||||
Reference in New Issue
Block a user