日志展示优化

This commit is contained in:
ddrwode
2026-02-10 16:03:14 +08:00
parent 51c53dceb9
commit a6df435c2f

View File

@@ -67,15 +67,13 @@ class BitmartFuturesTransaction:
# 策略优化参数
self.min_prev_entity_pct = 0.1 # 上一根K线实体涨幅%),仅当实体涨幅 > 此值才用作“上一根”
# 多仓止盈基于当前K线开盘价,涨 0.4% 后回调 0.3% 平仓,涨回 0.2% 同向开多
self.take_profit_rise_pct = 0.4 # 触发止盈的涨幅(%
self.take_profit_retrace_pct = 0.3 # 回调此幅度(%)则平
self.reentry_rise_pct = 0.2 # 平仓后涨回此幅度(%)则开多
self.take_profit_triggered_kline_id = None # 本K线内是否已出现过“涨 0.4%”
self.take_profit_reentry_threshold = None # 止盈平仓后,价格 >= 此值则开多(同向)
# 空仓止盈:跌 0.4% 后反弹 0.3% 平空,再跌到 0.2% 同向开空(复用上面三个百分比
self.take_profit_triggered_kline_id_short = None # 本K线内是否已出现过“跌 0.4%”
self.take_profit_reentry_threshold_short = None # 止盈平空后,价格 <= 此值则开空(同向)
# 自动止盈基于当前K线振幅四等分(多仓用 open~high空仓用 open~low
self.take_profit_close_quartile = 3 # 达到极值后,回到 3/4 位置平仓
self.take_profit_reentry_quartile = 2 # 止盈后,继续回到 2/4 位置同向再开
self.take_profit_triggered_kline_id = None # 多仓本K线内是否出现过 open~high 的极值触发
self.take_profit_reentry_threshold = None # 多仓止盈平仓后,价格 <= 此值则开多(同向)
self.take_profit_triggered_kline_id_short = None # 空仓本K线内是否出现过 open~low 的极值触发
self.take_profit_reentry_threshold_short = None # 空仓止盈平仓后,价格 >= 此值则开空(同向
self.optimized_params_file = Path(__file__).resolve().parent / "atr_best_params.json"
self.strategy_log_dir = Path(__file__).resolve().parent # 策略开仓日志目录
@@ -358,6 +356,52 @@ class BitmartFuturesTransaction:
'lower': min(kline['open'], kline['close']) # 实体下边
}
def calc_long_take_profit_levels(self, current_kline):
"""
多仓止盈阈值(自动四等分):
基于当前K线 open~high 计算:
- extreme: high4/4 极值)
- close: open + 3/4 * (high-open)
- reentry: open + 2/4 * (high-open)
"""
k_open = float(current_kline['open'])
k_high = float(current_kline['high'])
if k_high <= k_open:
return None
move = k_high - k_open
close_threshold = k_open + move * (self.take_profit_close_quartile / 4)
reentry_threshold = k_open + move * (self.take_profit_reentry_quartile / 4)
return {
"open": k_open,
"extreme": k_high,
"close_threshold": close_threshold,
"reentry_threshold": reentry_threshold
}
def calc_short_take_profit_levels(self, current_kline):
"""
空仓止盈阈值(自动四等分):
基于当前K线 open~low 计算:
- extreme: low4/4 极值)
- close: open - 3/4 * (open-low)
- reentry: open - 2/4 * (open-low)
"""
k_open = float(current_kline['open'])
k_low = float(current_kline['low'])
if k_low >= k_open:
return None
move = k_open - k_low
close_threshold = k_open - move * (self.take_profit_close_quartile / 4)
reentry_threshold = k_open - move * (self.take_profit_reentry_quartile / 4)
return {
"open": k_open,
"extreme": k_low,
"close_threshold": close_threshold,
"reentry_threshold": reentry_threshold
}
def check_signal(self, current_price, prev_kline, current_kline):
"""
检查交易信号
@@ -692,36 +736,39 @@ class BitmartFuturesTransaction:
logger.debug(f"当前持仓状态: {self.start} (0=无, 1=多, -1=空)")
kline_open = current_kline['open']
signal = None
# 3.5 多仓止盈当前K线涨 0.4% 后回调 0.3% 则平仓
# 3.5 多仓止盈自动四等分open~high 达到极值后,回到 3/4 平仓
if self.start == 1:
rise_threshold = kline_open * (1 + self.take_profit_rise_pct / 100)
retrace_close_threshold = kline_open * (1 + (self.take_profit_rise_pct - self.take_profit_retrace_pct) / 100)
if current_price >= rise_threshold:
self.take_profit_triggered_kline_id = current_kline_time
if (
self.take_profit_triggered_kline_id == current_kline_time
and current_price <= retrace_close_threshold
):
reason = (
f"当前K线开盘价={kline_open:.2f},曾涨至≥{rise_threshold:.2f}(+{self.take_profit_rise_pct}%)"
f"现价{current_price:.2f}已回调至≤{retrace_close_threshold:.2f}(+{self.take_profit_rise_pct - self.take_profit_retrace_pct}%),按规则止盈平多"
)
self._log_take_profit_action("止盈平多仓", reason)
self.平仓()
self.take_profit_reentry_threshold = kline_open * (1 + self.reentry_rise_pct / 100)
self.take_profit_triggered_kline_id = None
page_start = True
time.sleep(1)
long_levels = self.calc_long_take_profit_levels(current_kline)
if long_levels is not None:
retrace_close_threshold = long_levels["close_threshold"]
# 使用当前K线 high 判定是否已触发到 4/4 极值,避免依赖分钟收盘价漏判
if long_levels["extreme"] > long_levels["open"]:
self.take_profit_triggered_kline_id = current_kline_time
if (
self.take_profit_triggered_kline_id == current_kline_time
and current_price <= retrace_close_threshold
):
reason = (
f"当前K线开盘价={long_levels['open']:.2f},最高价={long_levels['extreme']:.2f}(4/4)"
f"现价{current_price:.2f}已回调至≤{retrace_close_threshold:.2f}(3/4),按规则止盈平多"
)
self._log_take_profit_action("止盈平多仓", reason)
self.平仓()
self.take_profit_reentry_threshold = long_levels["reentry_threshold"]
self.take_profit_triggered_kline_id = None
page_start = True
time.sleep(1)
else:
signal = self.check_signal(current_price, prev_kline, current_kline)
else:
signal = self.check_signal(current_price, prev_kline, current_kline)
# 3.6 止盈平多后:价格涨回 0.2% 则同向开多
# 3.6 止盈平多后:价格继续回调到 2/4 则同向开多
elif self.start == 0 and self.take_profit_reentry_threshold is not None:
if current_price >= self.take_profit_reentry_threshold:
if current_price <= self.take_profit_reentry_threshold:
reason = (
f"止盈平仓后价格涨回≥{self.take_profit_reentry_threshold:.2f}(相对当根K线开盘+{self.reentry_rise_pct}%),按规则同向开多"
f"止盈平仓后价格继续回调至≤{self.take_profit_reentry_threshold:.2f}(2/4),按规则同向开多"
)
self._log_take_profit_action("止盈后同向开多", reason)
self.开单(marketPriceLongOrder=1, size=self.default_order_size)
@@ -737,33 +784,37 @@ class BitmartFuturesTransaction:
self.take_profit_reentry_threshold = None
else:
signal = self.check_signal(current_price, prev_kline, current_kline)
# 3.7 空仓止盈当前K线跌 0.4% 后反弹 0.3% 则平空
# 3.7 空仓止盈自动四等分open~low 达到极值后,回到 3/4 平仓
elif self.start == -1:
drop_threshold = kline_open * (1 - self.take_profit_rise_pct / 100)
retrace_close_threshold_short = kline_open * (1 - (self.take_profit_rise_pct - self.take_profit_retrace_pct) / 100)
if current_price <= drop_threshold:
self.take_profit_triggered_kline_id_short = current_kline_time
if (
self.take_profit_triggered_kline_id_short == current_kline_time
and current_price >= retrace_close_threshold_short
):
reason = (
f"当前K线开盘价={kline_open:.2f},曾跌至≤{drop_threshold:.2f}(-{self.take_profit_rise_pct}%)"
f"现价{current_price:.2f}已反弹至≥{retrace_close_threshold_short:.2f}(-{self.take_profit_rise_pct - self.take_profit_retrace_pct}%),按规则止盈平空"
)
self._log_take_profit_action("止盈平空仓", reason)
self.平仓()
self.take_profit_reentry_threshold_short = kline_open * (1 - self.reentry_rise_pct / 100)
self.take_profit_triggered_kline_id_short = None
page_start = True
time.sleep(1)
short_levels = self.calc_short_take_profit_levels(current_kline)
if short_levels is not None:
retrace_close_threshold_short = short_levels["close_threshold"]
# 使用当前K线 low 判定是否已触发到 4/4 极值,避免依赖分钟收盘价漏判
if short_levels["extreme"] < short_levels["open"]:
self.take_profit_triggered_kline_id_short = current_kline_time
if (
self.take_profit_triggered_kline_id_short == current_kline_time
and current_price >= retrace_close_threshold_short
):
reason = (
f"当前K线开盘价={short_levels['open']:.2f},最低价={short_levels['extreme']:.2f}(4/4)"
f"现价{current_price:.2f}已反弹至≥{retrace_close_threshold_short:.2f}(3/4),按规则止盈平空"
)
self._log_take_profit_action("止盈平空仓", reason)
self.平仓()
self.take_profit_reentry_threshold_short = short_levels["reentry_threshold"]
self.take_profit_triggered_kline_id_short = None
page_start = True
time.sleep(1)
else:
signal = self.check_signal(current_price, prev_kline, current_kline)
else:
signal = self.check_signal(current_price, prev_kline, current_kline)
# 3.8 止盈平空后:价格再跌到 0.2% 则同向开空
# 3.8 止盈平空后:价格继续反弹到 2/4 则同向开空
elif self.start == 0 and self.take_profit_reentry_threshold_short is not None:
if current_price <= self.take_profit_reentry_threshold_short:
if current_price >= self.take_profit_reentry_threshold_short:
reason = (
f"止盈平空后价格再跌至≤{self.take_profit_reentry_threshold_short:.2f}(相对当根K线开盘-{self.reentry_rise_pct}%),按规则同向开空"
f"止盈平空后价格继续反弹至≥{self.take_profit_reentry_threshold_short:.2f}(2/4),按规则同向开空"
)
self._log_take_profit_action("止盈后同向开空", reason)
self.开单(marketPriceLongOrder=-1, size=self.default_order_size)