This commit is contained in:
27942
2026-01-28 18:17:11 +08:00
parent 55afde2691
commit 70aa29c820
5 changed files with 169 additions and 57 deletions

View File

@@ -4,10 +4,8 @@ BitMart 三分之一回归策略交易(双向触发版)
策略规则:
1. 触发价格计算基于有效的前一根K线实体>=0.1
- 实体上边界 = max(开盘价, 收盘价)
- 实体下边界 = min(开盘价, 收盘价)
- 做多触发价格 = 实体上边界 - 实体/3进入实体上部1/3区域做多
- 做空触发价格 = 实体下边界 + 实体/3进入实体下部1/3区域做空
- 做多触发价格 = 收盘价 + 实体/3从收盘价往上涨1/3
- 做空触发价格 = 收盘价 - 实体/3从收盘价往下跌1/3
2. 信号触发条件:
- 当前K线最高价 >= 做多触发价格 → 做多信号
@@ -16,12 +14,17 @@ BitMart 三分之一回归策略交易(双向触发版)
3. 执行逻辑:
- 做多时遇到做空信号 -> 平多并反手开空
- 做空时遇到做多信号 -> 平空并反手开多
- 如果同时触发两个方向,以距离开盘价更近的方向优先
- 同一根K线内只交易一次防止频繁反手
示例(阳线):
示例1(阳线):
前一根K线开盘3000收盘3100阳线实体=100
- 做多触发价格 = 3100 - 33.33 = 3066.67(价格涨到这里做多)
- 做空触发价格 = 3000 + 33.33 = 3033.33(价格跌到这里做空
- 做多触发价格 = 3100 + 33 = 3133继续上涨做多)
- 做空触发价格 = 3100 - 33 = 3067回调做空←当前跌到这里做空
示例2阴线
前一根K线开盘3100收盘3000阴线实体=100
- 做多触发价格 = 3000 + 33 = 3033反弹做多
- 做空触发价格 = 3000 - 33 = 2967继续下跌做空
"""
import time
@@ -75,6 +78,7 @@ class BitmartOneThirdStrategy:
self.check_interval = 3 # 检测间隔(秒)
self.last_trigger_kline_id = None # 记录上次触发信号的K线ID避免同一K线重复触发
self.last_trigger_direction = None # 记录上次触发的方向
self.last_trade_kline_id = None # 记录上次实际交易的K线ID防止同一K线内频繁反手
# ========================= 三分之一策略核心函数 =========================
@@ -111,23 +115,30 @@ class BitmartOneThirdStrategy:
计算前一根K线实体的 1/3 双向触发价格
返回:(做多触发价格, 做空触发价格)
基于实体的上下边界计算
- 做多触发价格 = 实体上边界 - 实体/3进入实体上部1/3区域做多
- 做空触发价格 = 实体下边界 + 实体/3进入实体下部1/3区域做空
基于收盘价计算(无论阴线阳线)
- 做多触发价格 = 收盘价 + 实体/3从收盘价往上涨1/3实体
- 做空触发价格 = 收盘价 - 实体/3从收盘价往下跌1/3实体
示例:
阳线 open=3000, close=3100, 实体=100
- 做多触发 = 3100 + 33 = 3133继续涨
- 做空触发 = 3100 - 33 = 3067回调
阴线 open=3100, close=3000, 实体=100
- 做多触发 = 3000 + 33 = 3033反弹
- 做空触发 = 3000 - 33 = 2967继续跌
"""
p_open = float(prev['open'])
p_close = float(prev['close'])
body_high = max(p_open, p_close) # 实体上边界
body_low = min(p_open, p_close) # 实体下边界
body = body_high - body_low
body = abs(p_open - p_close)
if body < 0.001: # 十字星,忽略
return None, None
# 基于实体边界的双向触发价格
long_trigger = body_high - body / 3 # 进入实体上部1/3区域触发做多
short_trigger = body_low + body / 3 # 进入实体下部1/3区域触发做空
# 基于收盘价的双向触发价格
long_trigger = p_close + body / 3 # 从收盘价往上涨1/3触发做多
short_trigger = p_close - body / 3 # 从收盘价往下跌1/3触发做空
return long_trigger, short_trigger
@@ -520,6 +531,17 @@ class BitmartOneThirdStrategy:
direction, trigger_price, valid_prev, curr_kline = self.check_realtime_trigger(kline_data)
if direction:
curr_kline_id = curr_kline['id']
# 检查是否在同一K线内已经交易过防止频繁反手
if self.last_trade_kline_id == curr_kline_id:
logger.debug(f"同一K线内已交易跳过本次{direction}信号")
# 更新触发记录,避免重复日志
self.last_trigger_kline_id = curr_kline_id
self.last_trigger_direction = direction
time.sleep(self.check_interval)
continue
# 获取持仓状态
if not self.get_position_status():
logger.warning("获取仓位信息失败")
@@ -530,6 +552,14 @@ class BitmartOneThirdStrategy:
prev_type = "阳线" if self.is_bullish(valid_prev) else "阴线"
prev_body = self.get_body_size(valid_prev)
# 检查信号与持仓是否同向(避免重复日志)
if (direction == "long" and self.start == 1) or (direction == "short" and self.start == -1):
# 信号与持仓同向,静默忽略
self.last_trigger_kline_id = curr_kline_id
self.last_trigger_direction = direction
time.sleep(self.check_interval)
continue
logger.info(f"{'='*50}")
logger.info(f"🚨 检测到{direction}信号!触发价格: {trigger_price:.2f}")
logger.info(f" 有效前一根[{prev_time}]: {prev_type} 实体={prev_body:.2f} O={valid_prev['open']:.2f} C={valid_prev['close']:.2f}")
@@ -554,8 +584,6 @@ class BitmartOneThirdStrategy:
logger.info("📈 无仓位,开多")
self.开单(marketPriceLongOrder=1, size=trade_size)
executed = True
else:
logger.info("已有多仓,忽略做多信号")
elif direction == "short":
if self.start == 1: # 当前多仓,平多开空
@@ -568,13 +596,14 @@ class BitmartOneThirdStrategy:
logger.info("📉 无仓位,开空")
self.开单(marketPriceLongOrder=-1, size=trade_size)
executed = True
else:
logger.info("已有空仓,忽略做空信号")
# 记录本次触发避免同一K线重复触发
# 记录本次触发
self.last_trigger_kline_id = curr_kline_id
self.last_trigger_direction = direction
if executed:
self.last_trigger_kline_id = curr_kline['id']
self.last_trigger_direction = direction
# 记录交易K线防止同一K线内频繁反手
self.last_trade_kline_id = curr_kline_id
# 交易后立即发送持仓信息
self.get_position_status()
self._send_position_message(curr_kline)