日志展示优化

This commit is contained in:
ddrwode
2026-02-11 14:30:54 +08:00
parent 07fcab63e0
commit 53d27662e2
2 changed files with 74 additions and 66 deletions

11
1111
View File

@@ -25,12 +25,19 @@ bitmart\框架.py 读取这个代码文件夹
基础开仓逻辑
基于前一根有效 K 线(实体 ≥ 0.1
做多触发价 = 当前 k 线开盘价 + 上一根实体 / 4
做空触发价 = 当前 k 线开盘价 - 上一根实体 / 4
做多触发价 = 当前 k 线开盘价 + 上一根实体 / 3
做空触发价 = 当前 k 线开盘价 - 上一根实体 / 3
反手信号:
持空反手做多:价格涨到 当前k线开仓价 + 前一根实体 / 3
持多反手做空:价格跌到 当前k线开仓价 - 前一根实体 / 3
止盈:
如果当前开多,当前这根 5 分钟k 线开盘价到最高价涨幅大于 0.4%,然后就将这根 k 线分成 4等份回调到四分之三时止盈平仓回调到四分之 二时,开同向仓位
如果当前开空,当前这根 5 分钟k 线开盘价到最低价跌幅大于 0.4%,然后就将这根 k 线分成 4等份反弹到四分之三时止盈平仓反弹到四分之 二时,开同向仓位
持多反手做空:价格跌到 k 线的上阴线涨幅大于 0.01%当前这个根跌倒了上一根的k线的实体边平仓做空
持空反手做多:价格涨到 k 线的下阴线跌幅大于 0.01%当前这个根涨到了上一根的k线的实体边平仓做多

View File

@@ -408,49 +408,46 @@ class BitmartFuturesTransaction:
def check_signal(self, current_price, prev_kline, current_kline):
"""
检查交易信号
返回: ('long', trigger_price) / ('short', trigger_price) / None
检查交易信号(三分之一策略)
规则基于当前K线开盘价 ± 上一根K线实体的1/3
- 做多触发价 = 当前开盘价 + 上一根实体/3
- 做空触发价 = 当前开盘价 - 上一根实体/3
返回: ('long', trigger_price) / ('short', trigger_price) /
('reverse_long', trigger_price) / ('reverse_short', trigger_price) / None
"""
# 计算上一根K线实体主循环已保证所选 prev 实体涨幅 >= min_prev_entity_pct
prev_entity = self.calculate_entity(prev_kline)
# 基础规则始终以当前K线开盘价为基准
# 开仓与反手阈值统一为「当前开盘价 ± 上一根实体/3」
# 计算触发价当前K线开盘价 ± 上一根实体/3
base_open = current_kline['open']
long_trigger = base_open + prev_entity / 3
short_trigger = base_open - prev_entity / 3
long_breakout = long_trigger
short_breakout = short_trigger
logger.info(f"当前价格: {current_price:.2f}, 上一根实体: {prev_entity:.4f}")
logger.info(f"当前K线开盘价: {base_open:.2f}")
logger.info(f"做多触发价(开盘+实体1/3): {long_trigger:.2f}, 做空触发价(开盘-实体1/3): {short_trigger:.2f}")
logger.info(f"开仓做多价: {long_breakout:.2f}, 开仓做空价: {short_breakout:.2f}")
logger.info(f"做多触发价: {long_trigger:.2f}, 做空触发价: {short_trigger:.2f}")
# 无持仓时检查开仓信号
if self.start == 0:
if current_price >= long_breakout:
logger.info(
f"触发做多信号!价格 {current_price:.2f} >= 开仓做多价(开盘+实体1/3) {long_breakout:.2f}"
)
return ('long', long_breakout)
elif current_price <= short_breakout:
logger.info(
f"触发做空信号!价格 {current_price:.2f} <= 开仓做空价(开盘-实体1/3) {short_breakout:.2f}"
)
return ('short', short_breakout)
if current_price >= long_trigger:
logger.info(f"触发做多信号!价格 {current_price:.2f} >= 触发价 {long_trigger:.2f}")
return ('long', long_trigger)
elif current_price <= short_trigger:
logger.info(f"触发做空信号!价格 {current_price:.2f} <= 触发价 {short_trigger:.2f}")
return ('short', short_trigger)
# 持仓时检查反手信号
elif self.start == 1: # 持多仓
# 反手条件: 价格跌到 当前开盘价-上一根实体/3做空触发价
# 持仓时检查反手信号
elif self.start == 1:
if current_price <= short_trigger:
logger.info(f"持多反手做空!价格 {current_price:.2f} <= 触发价(开盘-实体1/3) {short_trigger:.2f}")
logger.info(f"持多反手做空!价格 {current_price:.2f} <= 触发价 {short_trigger:.2f}")
return ('reverse_short', short_trigger)
elif self.start == -1: # 持空仓
# 反手条件: 价格涨到 当前开盘价+上一根实体/3做多触发价
# 持空仓时检查反手信号
elif self.start == -1:
if current_price >= long_trigger:
logger.info(f"持空反手做多!价格 {current_price:.2f} >= 触发价(开盘+实体1/3) {long_trigger:.2f}")
logger.info(f"持空反手做多!价格 {current_price:.2f} >= 触发价 {long_trigger:.2f}")
return ('reverse_long', long_trigger)
return None
@@ -664,7 +661,8 @@ class BitmartFuturesTransaction:
page_start = False
try:
# 1. 获取K线数据当前K线=最后一根;上一根=从后往前第一根实体涨幅>=min_prev_entity_pct 的K线
# ========== 1. 获取K线数据 ==========
# 当前K线=最后一根;上一根=从后往前第一根实体涨幅>=min_prev_entity_pct 的K线
formatted = self.get_klines()
if not formatted or len(formatted) < 2:
logger.warning("获取K线失败等待重试...")
@@ -699,14 +697,15 @@ class BitmartFuturesTransaction:
if self.start == -1:
self.take_profit_triggered_kline_id_short = None
# 2. 获取当前价格
# ========== 2. 获取当前价格 ==========
current_price = self.get_current_price()
if not current_price:
logger.warning("获取价格失败,等待重试...")
time.sleep(2)
continue
# 3. 每次循环都通过SDK获取真实持仓状态避免状态不同步导致双向持仓
# ========== 3. 获取持仓状态 ==========
# 每次循环都通过SDK获取真实持仓状态避免状态不同步导致双向持仓
if not self.get_position_status():
logger.warning("获取持仓状态失败,等待重试...")
time.sleep(2)
@@ -714,9 +713,10 @@ class BitmartFuturesTransaction:
logger.debug(f"当前持仓状态: {self.start} (0=无, 1=多, -1=空)")
# ========== 4. 止盈逻辑(自动四等分) ==========
signal = None
# 3.5 多仓止盈(自动四等分)open~high 达到极值后,回到 3/4 平仓
# 4.1 多仓止盈open~high 达到极值后,回到 3/4 平仓
if self.start == 1:
# 同一根K线多仓只允许止盈一次避免“止盈->再开->再止盈”循环
if self.last_take_profit_kline_id == current_kline_time:
@@ -724,20 +724,20 @@ class BitmartFuturesTransaction:
else:
long_levels = self.calc_long_take_profit_levels(current_kline)
if long_levels is not None:
retrace_close_threshold = long_levels["close_threshold"]
min_gain_price_long = long_levels["open"] * (1 + self.take_profit_min_gain_pct_from_entry / 100)
min_gain_ok_long = long_levels["extreme"] > min_gain_price_long
# 止盈启动前提当前K线相对开盘价涨幅已超过 0.4%标记为已触发
if long_levels["extreme"] >= long_levels["open"] * (1 + self.take_profit_min_gain_pct_from_entry / 100):
# 计算涨幅百分比
gain_pct = (long_levels["extreme"] - long_levels["open"]) / long_levels["open"] * 100
# 止盈启动前提当前K线涨幅 > 0.4%,标记为已触发
if gain_pct > self.take_profit_min_gain_pct_from_entry:
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
and min_gain_ok_long
):
# 止盈执行条件:已触发 且 价格回调到3/4位置
if (self.take_profit_triggered_kline_id == current_kline_time
and current_price <= long_levels["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)且当根最高价相对当前K线开盘价{long_levels['open']:.2f}涨幅>{self.take_profit_min_gain_pct_from_entry:.2f}%,按规则止盈平多"
f"当前K线开盘价={long_levels['open']:.2f},最高价={long_levels['extreme']:.2f}(4/4)"
f"涨幅={gain_pct:.2f}%;现价{current_price:.2f}已回调至≤{long_levels['close_threshold']:.2f}(3/4)"
f"按规则止盈平多"
)
self._log_take_profit_action("止盈平多仓", reason)
self.平仓()
@@ -750,11 +750,11 @@ class BitmartFuturesTransaction:
signal = self.check_signal(current_price, prev_kline, current_kline)
else:
signal = self.check_signal(current_price, prev_kline, current_kline)
# 3.6 止盈平多后:价格继续回调并跌破 2/4 才同向开多
# 4.2 多仓止盈后再开仓:价格继续回调 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}(2/4),按规则同向开多"
f"止盈平仓后价格继续回调{self.take_profit_reentry_threshold:.2f}(2/4),按规则同向开多"
)
self._log_take_profit_action("止盈后同向开多", reason)
self.开单(marketPriceLongOrder=1, size=self.default_order_size)
@@ -770,7 +770,7 @@ class BitmartFuturesTransaction:
self.take_profit_reentry_threshold = None
else:
signal = self.check_signal(current_price, prev_kline, current_kline)
# 3.7 空仓止盈(自动四等分)open~low 达到极值后,回到 3/4 平仓
# 4.3 空仓止盈open~low 达到极值后,回到 3/4 平仓
elif self.start == -1:
# 同一根K线空仓只允许止盈一次避免“止盈->再开->再止盈”循环
if self.last_take_profit_kline_id == current_kline_time:
@@ -778,20 +778,20 @@ class BitmartFuturesTransaction:
else:
short_levels = self.calc_short_take_profit_levels(current_kline)
if short_levels is not None:
retrace_close_threshold_short = short_levels["close_threshold"]
min_gain_price_short = short_levels["open"] * (1 - self.take_profit_min_gain_pct_from_entry / 100)
min_gain_ok_short = short_levels["extreme"] < min_gain_price_short
# 止盈启动前提当前K线相对开盘价跌幅已超过 0.4%标记为已触发
if short_levels["extreme"] <= short_levels["open"] * (1 - self.take_profit_min_gain_pct_from_entry / 100):
# 计算跌幅百分比
drop_pct = (short_levels["open"] - short_levels["extreme"]) / short_levels["open"] * 100
# 止盈启动前提当前K线跌幅 > 0.4%,标记为已触发
if drop_pct > self.take_profit_min_gain_pct_from_entry:
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
and min_gain_ok_short
):
# 止盈执行条件:已触发 且 价格反弹到3/4位置
if (self.take_profit_triggered_kline_id_short == current_kline_time
and current_price >= short_levels["close_threshold"]):
reason = (
f"当前K线开盘价={short_levels['open']:.2f},最低价={short_levels['extreme']:.2f}(4/4)"
f"现价{current_price:.2f}已反弹至≥{retrace_close_threshold_short:.2f}(3/4)且当根最低价相对当前K线开盘价{short_levels['open']:.2f}跌幅>{self.take_profit_min_gain_pct_from_entry:.2f}%,按规则止盈平空"
f"当前K线开盘价={short_levels['open']:.2f},最低价={short_levels['extreme']:.2f}(4/4)"
f"跌幅={drop_pct:.2f}%;现价{current_price:.2f}已反弹至≥{short_levels['close_threshold']:.2f}(3/4)"
f"按规则止盈平空"
)
self._log_take_profit_action("止盈平空仓", reason)
self.平仓()
@@ -804,11 +804,11 @@ class BitmartFuturesTransaction:
signal = self.check_signal(current_price, prev_kline, current_kline)
else:
signal = self.check_signal(current_price, prev_kline, current_kline)
# 3.8 止盈平空后:价格回落并低于 2/4 才同向开空
# 4.4 空仓止盈后再开仓:价格反弹到 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}(2/4),按规则同向开空"
f"止盈平空后现价{current_price:.2f}反弹到{self.take_profit_reentry_threshold_short:.2f}(2/4),按规则同向开空"
)
self._log_take_profit_action("止盈后同向开空", reason)
self.开单(marketPriceLongOrder=-1, size=self.default_order_size)
@@ -825,22 +825,23 @@ class BitmartFuturesTransaction:
else:
signal = self.check_signal(current_price, prev_kline, current_kline)
else:
# 4. 检查信号
# 4.5 无止盈条件时,检查开仓/反手信号
signal = self.check_signal(current_price, prev_kline, current_kline)
# 6. 反手过滤:冷却时间
# ========== 5. 信号过滤(频率控制) ==========
# 5.1 反手过滤:冷却时间
if signal and signal[0].startswith('reverse_'):
if not self.can_reverse(current_kline_time):
signal = None
# 6.5 开仓频率过滤:同一根 K 线只开一次 + 开仓冷却
# 5.2 开仓频率过滤:同一根 K 线只开一次 + 开仓冷却
if signal and signal[0] in ('long', 'short'):
if not self.can_open(current_kline_time):
signal = None
else:
self._current_kline_id_for_open = current_kline_time # 供 execute_trade 成功后记录
# 7. 有信号则执行交易
# ========== 6. 执行交易 ==========
if signal:
trade_success = self.execute_trade(signal)
if trade_success: