加入一个回测,

This commit is contained in:
ddrwode
2026-03-05 15:44:55 +08:00
parent 5530a008b3
commit 3a6678089c
2 changed files with 18275 additions and 31 deletions

View File

@@ -293,7 +293,7 @@ class BBDelayReversalTrader:
self.delay_reverse_type = reverse_type
self.delay_reverse_price = trigger_price
self.delay_reverse_kline_id = kline_id
logger.info(f"触发延迟反转: {reverse_type} @ {trigger_price:.2f}")
logger.warning(f"⚠️ 延迟反转触发: {reverse_type} @ {trigger_price:.2f} | K线ID: {kline_id}")
def clear_delay_reversal(self):
"""清除延迟反转状态"""
@@ -301,40 +301,82 @@ class BBDelayReversalTrader:
self.delay_reverse_type = None
self.delay_reverse_kline_id = None
def check_delay_reversal(self, current_kline, prev_kline, kline_index) -> tuple | None:
"""检查延迟反转确认"""
def check_delay_reversal(self, current_kline, prev_kline, prev_upper, prev_lower) -> tuple | None:
"""
检查延迟反转确认
根据回测代码的逻辑:
1. 次K确认触轨后的下一根K线回调/反弹到记录价格
2. 持续追踪追踪上一根K线的触轨情况或实体
"""
if self.position == 0 or self.delay_reverse_price is None:
return None
if self.delay_reverse_kline_id is None:
return None
offset = kline_index - self.delay_reverse_kline_id
current_kline_id = current_kline['id']
trigger_kline_id = self.delay_reverse_kline_id
# 计算K线偏移5分钟 = 300000ms
offset = (current_kline_id - trigger_kline_id) // 300000
if offset <= 0:
return None
high = current_kline['high']
low = current_kline['low']
logger.debug(f"延迟反转检查: offset={offset} | 当前K线 H={high:.2f} L={low:.2f}")
if self.delay_reverse_type == 'long_to_short':
# 多转空: 回调到记录价格
if offset == 1 and low <= self.delay_reverse_price:
return 'short', self.delay_reverse_price, "次K回调确认"
# 多转空: 需要价格回调
if offset == 1:
# 次K确认回调到记录的上轨价格
if low <= self.delay_reverse_price:
logger.success(f"✓ 延迟反转确认(次K): 回调到 {self.delay_reverse_price:.2f}")
return 'short', self.delay_reverse_price, "次K回调确认"
if offset >= 2 and prev_kline:
prev_body_low = min(prev_kline['open'], prev_kline['close'])
if low <= prev_body_low:
return 'short', prev_body_low, "跌破上一根实体"
elif offset >= 2 and prev_kline and prev_upper:
# 持续追踪上一根K线
prev_high = prev_kline['high']
prev_touch_upper = prev_high >= prev_upper
if prev_touch_upper:
# 上一根触上轨当前K回调到上一根上轨价
if low <= prev_upper:
logger.success(f"✓ 延迟反转确认(追踪): 上一根触上轨后回调到 {prev_upper:.2f}")
return 'short', prev_upper, "上一根触上轨后回调确认"
else:
# 上一根未触轨,跌破上一根实体
prev_body_low = min(prev_kline['open'], prev_kline['close'])
if low <= prev_body_low:
logger.success(f"✓ 延迟反转确认(追踪): 跌破上一根实体 {prev_body_low:.2f}")
return 'short', prev_body_low, "跌破上一根实体确认"
elif self.delay_reverse_type == 'short_to_long':
# 空转多: 反弹到记录价格
if offset == 1 and high >= self.delay_reverse_price:
return 'long', self.delay_reverse_price, "次K反弹确认"
# 空转多: 需要价格反弹
if offset == 1:
# 次K确认反弹到记录的下轨价格
if high >= self.delay_reverse_price:
logger.success(f"✓ 延迟反转确认(次K): 反弹到 {self.delay_reverse_price:.2f}")
return 'long', self.delay_reverse_price, "次K反弹确认"
if offset >= 2 and prev_kline:
prev_body_high = max(prev_kline['open'], prev_kline['close'])
if high >= prev_body_high:
return 'long', prev_body_high, "突破上一根实体"
elif offset >= 2 and prev_kline and prev_lower:
# 持续追踪上一根K线
prev_low = prev_kline['low']
prev_touch_lower = prev_low <= prev_lower
if prev_touch_lower:
# 上一根触下轨当前K反弹到上一根下轨价
if high >= prev_lower:
logger.success(f"✓ 延迟反转确认(追踪): 上一根触下轨后反弹到 {prev_lower:.2f}")
return 'long', prev_lower, "上一根触下轨后反弹确认"
else:
# 上一根未触轨,突破上一根实体
prev_body_high = max(prev_kline['open'], prev_kline['close'])
if high >= prev_body_high:
logger.success(f"✓ 延迟反转确认(追踪): 突破上一根实体 {prev_body_high:.2f}")
return 'long', prev_body_high, "突破上一根实体确认"
return None
@@ -361,7 +403,9 @@ class BBDelayReversalTrader:
logger.info(f"初始持仓: {self.position}")
page_start = True
kline_history = []
kline_history = [] # 保存历史K线
prev_bb_upper = None # 保存上一根K线的上轨
prev_bb_lower = None # 保存上一根K线的下轨
while True:
try:
@@ -430,11 +474,16 @@ class BBDelayReversalTrader:
touched_lower = cur_low <= bb_lower
touched_middle = cur_low <= bb_mid <= cur_high
# 延迟反转状态显示
delay_status = ""
if self.delay_reverse_price is not None:
delay_status = f" | 🔄延迟反转中: {self.delay_reverse_type} @ {self.delay_reverse_price:.2f}"
logger.info(
f"价格={current_price:.2f} | "
f"BB: {bb_lower:.2f}/{bb_mid:.2f}/{bb_upper:.2f} | "
f"触上={touched_upper} 触下={touched_lower} 触中={touched_middle} | "
f"仓位={self.position}"
f"仓位={self.position}{delay_status}"
)
# 同步持仓
@@ -447,29 +496,31 @@ class BBDelayReversalTrader:
time.sleep(self.cfg.POLL_INTERVAL)
continue
# ===== 延迟反转确认 =====
if self.delay_reverse_price is not None and len(kline_history) > 0:
# ===== 延迟反转确认(优先级最高)=====
if self.delay_reverse_price is not None:
prev_kline = kline_history[-1] if len(kline_history) > 0 else None
reversal = self.check_delay_reversal(
current_kline, prev_kline, len(kline_history)
current_kline, prev_kline, prev_bb_upper, prev_bb_lower
)
if reversal:
new_direction, reversal_price, reason = reversal
logger.info(f"延迟反转确认: {reason} @ {reversal_price:.2f}")
logger.warning(f"🔄 延迟反转确认: {reason} @ {reversal_price:.2f}")
# 平仓
logger.info("执行平仓...")
self.browser_close_position(1.0)
time.sleep(2)
time.sleep(3)
self.get_position_status()
if self.position == 0:
# 反向开仓
logger.info(f"执行反向开{'' if new_direction == 'long' else ''}...")
balance = self.get_balance()
if balance:
usdt_amount = round(balance * self.cfg.MARGIN_PCT, 2)
self.browser_open_position(new_direction, usdt_amount)
time.sleep(2)
time.sleep(3)
self.get_position_status()
if self.position != 0:
@@ -477,7 +528,14 @@ class BBDelayReversalTrader:
self.mid_closed_half = False
self.clear_delay_reversal()
self.last_kline_id = kline_id
logger.success(f"✓ 延迟反转完成!")
else:
logger.error(f"平仓后仍有持仓: {self.position}")
# 更新历史
kline_history.append(current_kline)
prev_bb_upper = bb_upper
prev_bb_lower = bb_lower
continue
# ===== 中轨平仓 =====
@@ -549,13 +607,13 @@ class BBDelayReversalTrader:
# ===== 延迟反转触发 =====
elif self.position > 0 and touched_upper:
logger.info("多仓触上轨,标记延迟反转")
self.mark_delay_reversal('long_to_short', bb_upper, len(kline_history))
logger.warning("⚠️ 多仓触上轨,标记延迟反转")
self.mark_delay_reversal('long_to_short', bb_upper, kline_id)
self.last_kline_id = kline_id
elif self.position < 0 and touched_lower:
logger.info("空仓触下轨,标记延迟反转")
self.mark_delay_reversal('short_to_long', bb_lower, len(kline_history))
logger.warning("⚠️ 空仓触下轨,标记延迟反转")
self.mark_delay_reversal('short_to_long', bb_lower, kline_id)
self.last_kline_id = kline_id
# ===== 加仓 =====
@@ -582,11 +640,14 @@ class BBDelayReversalTrader:
self.position_count = 2
self.last_kline_id = kline_id
# 更新K线历史
# 更新K线历史和布林带历史
kline_history.append(current_kline)
if len(kline_history) > 100:
kline_history = kline_history[-100:]
prev_bb_upper = bb_upper
prev_bb_lower = bb_lower
time.sleep(self.cfg.POLL_INTERVAL)
except KeyboardInterrupt:

File diff suppressed because it is too large Load Diff