优化日志展示
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
import sys
|
||||
import time
|
||||
|
||||
from tqdm import tqdm
|
||||
@@ -8,6 +9,39 @@ from DrissionPage import ChromiumOptions
|
||||
|
||||
from bitmart.api_contract import APIContract
|
||||
|
||||
# Claude 风格控制台:左侧竖线 + 仅消息(无时间戳),颜色由下方 LOG_* 控制
|
||||
logger.remove()
|
||||
logger.add(sys.stderr, format="\033[2m│\033[0m {message}", colorize=False)
|
||||
|
||||
# 颜色标签 + 分块边框
|
||||
_R = "\033[0m" # reset
|
||||
_B = "\033[1m" # bold
|
||||
_D = "\033[2m" # dim
|
||||
_C = "\033[36m" # cyan - 价格/数据
|
||||
_Y = "\033[33m" # yellow - 信号
|
||||
_G = "\033[32m" # green - 仓位/操作
|
||||
_M = "\033[90m" # gray - 系统
|
||||
_W = "\033[97m" # white - 高亮
|
||||
|
||||
def _tag(t: str, color: str) -> str:
|
||||
return color + "[" + t + "]" + _R + " "
|
||||
|
||||
LOG_PRICE = _tag("价格", _C)
|
||||
LOG_SIGNAL = _tag("信号", _Y)
|
||||
LOG_POSITION = _tag("仓位", _G)
|
||||
LOG_SYSTEM = _tag("系统", _M)
|
||||
|
||||
def log_kline_header(kline_id):
|
||||
"""新 K 线分块头(Claude 风格面板)"""
|
||||
s = f" K 线 {kline_id} "
|
||||
width = max(52, len(s) + 4)
|
||||
line = "─" * (width - 2)
|
||||
pad_left = (width - 2 - len(s)) // 2
|
||||
pad_right = width - 2 - len(s) - pad_left
|
||||
logger.info(_M + "╭" + line + "╮" + _R)
|
||||
logger.info(_M + "│" + _R + " " * pad_left + _B + _W + s + _R + " " * pad_right + _M + "│" + _R)
|
||||
logger.info(_M + "╰" + line + "╯" + _R)
|
||||
|
||||
|
||||
class BitmartFuturesTransaction:
|
||||
def __init__(self, bit_id):
|
||||
@@ -366,7 +400,7 @@ class BitmartFuturesTransaction:
|
||||
|
||||
# 实体过小不交易(实体 < 0.1)
|
||||
if prev_entity < 0.1:
|
||||
logger.info(f"上一根K线实体过小: {prev_entity:.4f},跳过信号检测")
|
||||
logger.info(LOG_PRICE + f"上一根K线实体过小: {prev_entity:.4f},跳过信号检测")
|
||||
return None
|
||||
|
||||
# 获取上一根K线的实体上下边
|
||||
@@ -409,52 +443,42 @@ class BitmartFuturesTransaction:
|
||||
|
||||
if use_current_open_as_base:
|
||||
if prev_is_bullish_for_calc and current_open_above_prev_close:
|
||||
logger.info(f"上一根阳线且当前开盘价({current_kline['open']:.2f})>上一根收盘价({prev_kline['close']:.2f}),以当前开盘价为基准计算")
|
||||
logger.info(LOG_PRICE + f"上一根阳线且当前开盘价({current_kline['open']:.2f})>上一根收盘价({prev_kline['close']:.2f}),以当前开盘价为基准计算")
|
||||
else:
|
||||
logger.info(f"上一根阴线且当前开盘价({current_kline['open']:.2f})<上一根收盘价({prev_kline['close']:.2f}),以当前开盘价为基准计算")
|
||||
logger.info(f"当前价格: {current_price:.2f}, 上一根实体: {prev_entity:.4f}")
|
||||
logger.info(f"上一根实体上边: {prev_entity_upper:.2f}, 下边: {prev_entity_lower:.2f}")
|
||||
logger.info(f"做多触发价(下1/4): {long_trigger:.2f}, 做空触发价(上1/4): {short_trigger:.2f}")
|
||||
logger.info(f"突破做多价(上1/4外): {long_breakout:.2f}, 突破做空价(下1/4外): {short_breakout:.2f}")
|
||||
logger.info(LOG_PRICE + f"上一根阴线且当前开盘价({current_kline['open']:.2f})<上一根收盘价({prev_kline['close']:.2f}),以当前开盘价为基准计算")
|
||||
logger.info(LOG_PRICE + f"当前价: {current_price:.2f} | 上一根实体: {prev_entity:.4f} | 实体上边: {prev_entity_upper:.2f} 下边: {prev_entity_lower:.2f}")
|
||||
logger.info(LOG_PRICE + f"做多触发(下1/4): {long_trigger:.2f} | 做空触发(上1/4): {short_trigger:.2f} | 突破做多: {long_breakout:.2f} | 突破做空: {short_breakout:.2f}")
|
||||
if skip_short_by_upper_third:
|
||||
logger.info("上一根阴线+当前阳线(做多形态),不按上四分之一做空")
|
||||
logger.info(LOG_PRICE + "上一根阴+当前阳(做多形态),不按上1/4做空")
|
||||
if skip_long_by_lower_third:
|
||||
logger.info("上一根阳线+当前阴线(做空形态),不按下四分之一做多")
|
||||
logger.info(LOG_PRICE + "上一根阳+当前阴(做空形态),不按下1/4做多")
|
||||
|
||||
# 无持仓时检查开仓信号
|
||||
if self.start == 0:
|
||||
if current_price >= long_breakout and not skip_long_by_lower_third:
|
||||
logger.info(f"触发做多信号!价格 {current_price:.2f} >= 突破价(上1/4外) {long_breakout:.2f}")
|
||||
logger.info(LOG_SIGNAL + f"触发做多 | 价 {current_price:.2f} >= 突破价 {long_breakout:.2f}")
|
||||
return ('long', long_breakout)
|
||||
elif current_price <= short_breakout and not skip_short_by_upper_third:
|
||||
logger.info(f"触发做空信号!价格 {current_price:.2f} <= 突破价(下1/4外) {short_breakout:.2f}")
|
||||
logger.info(LOG_SIGNAL + f"触发做空 | 价 {current_price:.2f} <= 突破价 {short_breakout:.2f}")
|
||||
return ('short', short_breakout)
|
||||
|
||||
# 持仓时检查反手信号
|
||||
elif self.start == 1: # 持多仓
|
||||
# 反手条件1: 价格跌到上一根K线的上三分之一处(做空触发价);上一根阴线+当前阳线做多时跳过
|
||||
if current_price <= short_trigger and not skip_short_by_upper_third:
|
||||
logger.info(f"持多反手做空!价格 {current_price:.2f} <= 触发价(上1/4) {short_trigger:.2f}")
|
||||
logger.info(LOG_SIGNAL + f"持多→反手做空 | 价 {current_price:.2f} <= 触发价 {short_trigger:.2f}")
|
||||
return ('reverse_short', short_trigger)
|
||||
|
||||
# 反手条件2: 上一根K线上阴线涨幅>0.01%,当前跌到上一根实体下边
|
||||
upper_shadow_pct = self.calculate_upper_shadow(prev_kline)
|
||||
if upper_shadow_pct > 0.01 and current_price <= prev_entity_lower:
|
||||
logger.info(f"持多反手做空!上阴线涨幅 {upper_shadow_pct:.4f}% > 0.01%,"
|
||||
f"价格 {current_price:.2f} <= 实体下边 {prev_entity_lower:.2f}")
|
||||
logger.info(LOG_SIGNAL + f"持多→反手做空 | 上阴线 {upper_shadow_pct:.4f}% 价<=实体下边 {prev_entity_lower:.2f}")
|
||||
return ('reverse_short', prev_entity_lower)
|
||||
|
||||
elif self.start == -1: # 持空仓
|
||||
# 反手条件1: 价格涨到上一根K线的下三分之一处(做多触发价);上一根阳线+当前阴线做空时跳过
|
||||
if current_price >= long_trigger and not skip_long_by_lower_third:
|
||||
logger.info(f"持空反手做多!价格 {current_price:.2f} >= 触发价(下1/4) {long_trigger:.2f}")
|
||||
logger.info(LOG_SIGNAL + f"持空→反手做多 | 价 {current_price:.2f} >= 触发价 {long_trigger:.2f}")
|
||||
return ('reverse_long', long_trigger)
|
||||
|
||||
# 反手条件2: 上一根K线下阴线跌幅>0.01%,当前涨到上一根实体上边
|
||||
lower_shadow_pct = self.calculate_lower_shadow(prev_kline)
|
||||
if lower_shadow_pct > 0.01 and current_price >= prev_entity_upper:
|
||||
logger.info(f"持空反手做多!下阴线跌幅 {lower_shadow_pct:.4f}% > 0.01%,"
|
||||
f"价格 {current_price:.2f} >= 实体上边 {prev_entity_upper:.2f}")
|
||||
logger.info(LOG_SIGNAL + f"持空→反手做多 | 下阴线 {lower_shadow_pct:.4f}% 价>=实体上边 {prev_entity_upper:.2f}")
|
||||
return ('reverse_long', prev_entity_upper)
|
||||
|
||||
return None
|
||||
@@ -464,7 +488,7 @@ class BitmartFuturesTransaction:
|
||||
now = time.time()
|
||||
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} 秒")
|
||||
logger.info(LOG_SYSTEM + f"开仓冷却中,剩余 {remain:.0f} 秒")
|
||||
return False
|
||||
return True
|
||||
|
||||
@@ -473,13 +497,13 @@ class BitmartFuturesTransaction:
|
||||
now = time.time()
|
||||
if self.last_reverse_time and now - self.last_reverse_time < self.reverse_cooldown_seconds:
|
||||
remain = self.reverse_cooldown_seconds - (now - self.last_reverse_time)
|
||||
logger.info(f"反手冷却中,剩余 {remain:.0f} 秒")
|
||||
logger.info(LOG_SYSTEM + f"反手冷却中,剩余 {remain:.0f} 秒")
|
||||
return False
|
||||
|
||||
if trigger_price and trigger_price > 0:
|
||||
move_pct = abs(current_price - trigger_price) / trigger_price * 100
|
||||
if move_pct < self.reverse_min_move_pct:
|
||||
logger.info(f"反手价差不足: {move_pct:.4f}% < {self.reverse_min_move_pct}%")
|
||||
logger.info(LOG_SYSTEM + f"反手价差不足: {move_pct:.4f}% < {self.reverse_min_move_pct}%")
|
||||
return False
|
||||
|
||||
return True
|
||||
@@ -492,7 +516,7 @@ class BitmartFuturesTransaction:
|
||||
for i in range(max_retries):
|
||||
if self.get_position_status():
|
||||
if self.start == 0:
|
||||
logger.info(f"确认无持仓,可以开仓")
|
||||
logger.info(LOG_POSITION + "确认无持仓,可以开仓")
|
||||
return True
|
||||
else:
|
||||
logger.warning(
|
||||
@@ -513,7 +537,7 @@ class BitmartFuturesTransaction:
|
||||
"""
|
||||
if self.get_position_status():
|
||||
if self.start == expected_direction:
|
||||
logger.info(f"持仓方向验证成功: {self.start}")
|
||||
logger.info(LOG_POSITION + f"持仓方向验证成功: {self.start}")
|
||||
return True
|
||||
else:
|
||||
logger.warning(f"持仓方向不符: 期望 {expected_direction}, 实际 {self.start}")
|
||||
@@ -529,7 +553,7 @@ class BitmartFuturesTransaction:
|
||||
|
||||
if signal_type == 'long':
|
||||
# 开多前先确认无持仓
|
||||
logger.info(f"准备开多,触发价: {trigger_price:.2f}")
|
||||
logger.info(LOG_POSITION + f"准备开多,触发价: {trigger_price:.2f}")
|
||||
if not self.get_position_status():
|
||||
logger.error("开仓前查询持仓状态失败,放弃开仓")
|
||||
return False
|
||||
@@ -537,7 +561,7 @@ class BitmartFuturesTransaction:
|
||||
logger.warning(f"开多前发现已有持仓 (方向: {self.start}),放弃开仓避免双向持仓")
|
||||
return False
|
||||
|
||||
logger.info(f"确认无持仓,执行开多")
|
||||
logger.info(LOG_POSITION + "确认无持仓,执行开多")
|
||||
self.开单(marketPriceLongOrder=1, size=size)
|
||||
time.sleep(3) # 等待订单执行
|
||||
|
||||
@@ -546,7 +570,7 @@ class BitmartFuturesTransaction:
|
||||
self.max_unrealized_pnl_seen = None # 新仓位重置移动止损记录
|
||||
self.last_open_time = time.time()
|
||||
self.last_open_kline_id = getattr(self, "_current_kline_id_for_open", None)
|
||||
logger.success("开多成功")
|
||||
logger.success(LOG_POSITION + "开多成功")
|
||||
return True
|
||||
else:
|
||||
logger.error("开多后持仓验证失败")
|
||||
@@ -554,7 +578,7 @@ class BitmartFuturesTransaction:
|
||||
|
||||
elif signal_type == 'short':
|
||||
# 开空前先确认无持仓
|
||||
logger.info(f"准备开空,触发价: {trigger_price:.2f}")
|
||||
logger.info(LOG_POSITION + f"准备开空,触发价: {trigger_price:.2f}")
|
||||
if not self.get_position_status():
|
||||
logger.error("开仓前查询持仓状态失败,放弃开仓")
|
||||
return False
|
||||
@@ -562,7 +586,7 @@ class BitmartFuturesTransaction:
|
||||
logger.warning(f"开空前发现已有持仓 (方向: {self.start}),放弃开仓避免双向持仓")
|
||||
return False
|
||||
|
||||
logger.info(f"确认无持仓,执行开空")
|
||||
logger.info(LOG_POSITION + "确认无持仓,执行开空")
|
||||
self.开单(marketPriceLongOrder=-1, size=size)
|
||||
time.sleep(3) # 等待订单执行
|
||||
|
||||
@@ -571,7 +595,7 @@ class BitmartFuturesTransaction:
|
||||
self.max_unrealized_pnl_seen = None # 新仓位重置移动止损记录
|
||||
self.last_open_time = time.time()
|
||||
self.last_open_kline_id = getattr(self, "_current_kline_id_for_open", None)
|
||||
logger.success("开空成功")
|
||||
logger.success(LOG_POSITION + "开空成功")
|
||||
return True
|
||||
else:
|
||||
logger.error("开空后持仓验证失败")
|
||||
@@ -579,7 +603,7 @@ class BitmartFuturesTransaction:
|
||||
|
||||
elif signal_type == 'reverse_long':
|
||||
# 平空 + 开多(反手做多):先平仓,确认无仓后再开多,避免双向持仓
|
||||
logger.info(f"执行反手做多,触发价: {trigger_price:.2f}")
|
||||
logger.info(LOG_POSITION + f"执行反手做多,触发价: {trigger_price:.2f}")
|
||||
self.平仓()
|
||||
time.sleep(1) # 给交易所处理平仓的时间
|
||||
# 轮询确认已无持仓再开多(最多等约 10 秒)
|
||||
@@ -590,13 +614,13 @@ class BitmartFuturesTransaction:
|
||||
if self.start != 0:
|
||||
logger.warning("反手做多:平仓后仍有持仓,放弃本次开多")
|
||||
return False
|
||||
logger.info("已确认无持仓,执行开多")
|
||||
logger.info(LOG_POSITION + "已确认无持仓,执行开多")
|
||||
self.开单(marketPriceLongOrder=1, size=size)
|
||||
time.sleep(3)
|
||||
|
||||
if self.verify_position_direction(1):
|
||||
self.max_unrealized_pnl_seen = None
|
||||
logger.success("反手做多成功")
|
||||
logger.success(LOG_POSITION + "反手做多成功")
|
||||
self.last_reverse_time = time.time()
|
||||
time.sleep(20)
|
||||
return True
|
||||
@@ -606,7 +630,7 @@ class BitmartFuturesTransaction:
|
||||
|
||||
elif signal_type == 'reverse_short':
|
||||
# 平多 + 开空(反手做空):先平仓,确认无仓后再开空
|
||||
logger.info(f"执行反手做空,触发价: {trigger_price:.2f}")
|
||||
logger.info(LOG_POSITION + f"执行反手做空,触发价: {trigger_price:.2f}")
|
||||
self.平仓()
|
||||
time.sleep(1)
|
||||
for _ in range(10):
|
||||
@@ -616,13 +640,13 @@ class BitmartFuturesTransaction:
|
||||
if self.start != 0:
|
||||
logger.warning("反手做空:平仓后仍有持仓,放弃本次开空")
|
||||
return False
|
||||
logger.info("已确认无持仓,执行开空")
|
||||
logger.info(LOG_POSITION + "已确认无持仓,执行开空")
|
||||
self.开单(marketPriceLongOrder=-1, size=size)
|
||||
time.sleep(3)
|
||||
|
||||
if self.verify_position_direction(-1):
|
||||
self.max_unrealized_pnl_seen = None
|
||||
logger.success("反手做空成功")
|
||||
logger.success(LOG_POSITION + "反手做空成功")
|
||||
self.last_reverse_time = time.time()
|
||||
time.sleep(20)
|
||||
return True
|
||||
@@ -635,7 +659,7 @@ class BitmartFuturesTransaction:
|
||||
def action(self):
|
||||
"""主循环"""
|
||||
|
||||
logger.info("开始运行四分之一策略交易...")
|
||||
logger.info(LOG_SYSTEM + "开始运行四分之一策略交易...")
|
||||
|
||||
# 启动时设置全仓高杠杆
|
||||
if not self.set_leverage():
|
||||
@@ -650,7 +674,7 @@ class BitmartFuturesTransaction:
|
||||
# 打开浏览器
|
||||
for i in range(5):
|
||||
if self.openBrowser():
|
||||
logger.info("浏览器打开成功")
|
||||
logger.info(LOG_SYSTEM + "浏览器打开成功")
|
||||
break
|
||||
else:
|
||||
self.ding("打开浏览器失败!", error=True)
|
||||
@@ -668,26 +692,27 @@ class BitmartFuturesTransaction:
|
||||
# 1. 获取K线数据(当前K线和上一根K线)
|
||||
prev_kline, current_kline = self.get_klines()
|
||||
if not prev_kline or not current_kline:
|
||||
logger.warning("获取K线失败,等待重试...")
|
||||
logger.warning(LOG_SYSTEM + "获取K线失败,等待重试...")
|
||||
time.sleep(5)
|
||||
continue
|
||||
|
||||
# 记录进入新的K线
|
||||
# 记录进入新的K线(分块分隔,便于阅读)
|
||||
current_kline_time = current_kline['id']
|
||||
if self.last_kline_time != current_kline_time:
|
||||
self.last_kline_time = current_kline_time
|
||||
logger.info(f"进入新K线: {current_kline_time}")
|
||||
logger.info("")
|
||||
log_kline_header(current_kline_time)
|
||||
|
||||
# 2. 获取当前价格
|
||||
current_price = self.get_current_price()
|
||||
if not current_price:
|
||||
logger.warning("获取价格失败,等待重试...")
|
||||
logger.warning(LOG_SYSTEM + "获取价格失败,等待重试...")
|
||||
time.sleep(2)
|
||||
continue
|
||||
|
||||
# 3. 每次循环都通过SDK获取真实持仓状态(避免状态不同步导致双向持仓)
|
||||
if not self.get_position_status():
|
||||
logger.warning("获取持仓状态失败,等待重试...")
|
||||
logger.warning(LOG_SYSTEM + "获取持仓状态失败,等待重试...")
|
||||
time.sleep(2)
|
||||
continue
|
||||
|
||||
@@ -711,14 +736,14 @@ class BitmartFuturesTransaction:
|
||||
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}(能赚点是点)")
|
||||
logger.info(LOG_POSITION + f"多单 EMA10 平仓 | 价 {current_price:.2f} 跌破 EMA10 {ema10:.2f}")
|
||||
self.平仓()
|
||||
self.max_unrealized_pnl_seen = None
|
||||
self._candle_high_seen = None
|
||||
time.sleep(3)
|
||||
continue
|
||||
if atr14 is not None and self._candle_high_seen and (self._candle_high_seen - current_price) >= self.atr_multiplier * atr14:
|
||||
logger.info(f"多单 ATR 追踪止盈:最高 {self._candle_high_seen:.2f},当前 {current_price:.2f},回撤 {(self._candle_high_seen - current_price):.2f} >= {self.atr_multiplier}×ATR(14)={atr14:.2f}")
|
||||
logger.info(LOG_POSITION + f"多单 ATR 追踪止盈 | 最高 {self._candle_high_seen:.2f} 当前 {current_price:.2f} 回撤≥{self.atr_multiplier}×ATR={atr14:.2f}")
|
||||
self.平仓()
|
||||
self.max_unrealized_pnl_seen = None
|
||||
self._candle_high_seen = None
|
||||
@@ -730,14 +755,14 @@ class BitmartFuturesTransaction:
|
||||
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}(能赚点是点)")
|
||||
logger.info(LOG_POSITION + 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}")
|
||||
logger.info(LOG_POSITION + f"空单 ATR 追踪止盈 | 最低 {self._candle_low_seen:.2f} 当前 {current_price:.2f} 反弹≥{self.atr_multiplier}×ATR={atr14:.2f}")
|
||||
self.平仓()
|
||||
self.max_unrealized_pnl_seen = None
|
||||
self._candle_low_seen = None
|
||||
@@ -764,7 +789,7 @@ class BitmartFuturesTransaction:
|
||||
else:
|
||||
pass # 涨幅不足,不启用动态回撤
|
||||
if do_close:
|
||||
logger.info(f"当前K线从最高点回落平仓:最高 {self._candle_high_seen:.2f},当前 {current_price:.2f},{reason}")
|
||||
logger.info(LOG_POSITION + f"多单K线回落平仓 | 最高 {self._candle_high_seen:.2f} 当前 {current_price:.2f} | {reason}")
|
||||
self.平仓()
|
||||
self.max_unrealized_pnl_seen = None
|
||||
self._candle_high_seen = None
|
||||
@@ -786,7 +811,7 @@ class BitmartFuturesTransaction:
|
||||
do_close = True
|
||||
reason = f"跌幅 {rise_pct:.3f}% → 允许反弹 {drop_trigger_pct:.3f}%,实际反弹 {bounce_pct:.3f}%"
|
||||
if do_close:
|
||||
logger.info(f"当前K线从最低点反弹平仓:最低 {self._candle_low_seen:.2f},当前 {current_price:.2f},{reason}")
|
||||
logger.info(LOG_POSITION + f"空单K线反弹平仓 | 最低 {self._candle_low_seen:.2f} 当前 {current_price:.2f} | {reason}")
|
||||
self.平仓()
|
||||
self.max_unrealized_pnl_seen = None
|
||||
self._candle_low_seen = None
|
||||
@@ -797,7 +822,7 @@ class BitmartFuturesTransaction:
|
||||
if pnl_usd is not None:
|
||||
# 固定止损:亏损达到 3 美元平仓
|
||||
if pnl_usd <= self.stop_loss_usd:
|
||||
logger.info(f"仓位亏损 {pnl_usd:.2f} 美元 <= 止损 {self.stop_loss_usd} 美元,执行止损平仓")
|
||||
logger.info(LOG_POSITION + f"固定止损平仓 | 亏损 {pnl_usd:.2f} 美元")
|
||||
self.平仓()
|
||||
self.max_unrealized_pnl_seen = None
|
||||
time.sleep(3)
|
||||
@@ -810,7 +835,7 @@ class BitmartFuturesTransaction:
|
||||
# 移动止损:盈利曾达到 activation 后,从最高盈利回撤 trailing_distance 则平仓
|
||||
if self.max_unrealized_pnl_seen >= self.trailing_activation_usd:
|
||||
if pnl_usd < self.max_unrealized_pnl_seen - self.trailing_distance_usd:
|
||||
logger.info(f"移动止损:当前盈利 {pnl_usd:.2f} 从最高 {self.max_unrealized_pnl_seen:.2f} 回撤 >= {self.trailing_distance_usd} 美元,平仓")
|
||||
logger.info(LOG_POSITION + f"移动止损平仓 | 盈利 {pnl_usd:.2f} 从最高 {self.max_unrealized_pnl_seen:.2f} 回撤≥{self.trailing_distance_usd}$")
|
||||
self.平仓()
|
||||
self.max_unrealized_pnl_seen = None
|
||||
time.sleep(3)
|
||||
@@ -834,7 +859,7 @@ class BitmartFuturesTransaction:
|
||||
if signal:
|
||||
trade_success = self.execute_trade(signal)
|
||||
if trade_success:
|
||||
logger.success(f"交易执行完成: {signal[0]}, 当前持仓状态: {self.start}")
|
||||
logger.success(LOG_POSITION + f"交易执行完成: {signal[0]} | 当前持仓: {self.start}")
|
||||
page_start = True
|
||||
else:
|
||||
logger.warning(f"交易执行失败或被阻止: {signal[0]}")
|
||||
@@ -847,7 +872,7 @@ class BitmartFuturesTransaction:
|
||||
time.sleep(5)
|
||||
|
||||
except KeyboardInterrupt:
|
||||
logger.info("用户中断,程序退出")
|
||||
logger.info(LOG_SYSTEM + "用户中断,程序退出")
|
||||
break
|
||||
except Exception as e:
|
||||
logger.error(f"主循环异常: {e}")
|
||||
|
||||
Reference in New Issue
Block a user