优化交易代码

This commit is contained in:
ddrwode
2026-02-02 11:00:45 +08:00
parent b398e1cac2
commit 8cfaf1d5e9
3 changed files with 39 additions and 25 deletions

View File

@@ -14,10 +14,12 @@
- 当前 K 线最高价 ≥ 做多触发价 → 做多信号 - 当前 K 线最高价 ≥ 做多触发价 → 做多信号
- 当前 K 线最低价 ≤ 做空触发价 → 做空信号 - 当前 K 线最低价 ≤ 做空触发价 → 做空信号
### 第一分钟反手(若已有持仓) ### 前1分30秒反手(若已有持仓)
- 3分钟K线的**前1分30秒**内若出现反手信号 → 平仓开反手
- **持空反手做多**:价格涨到 开仓价 + 前一根实体/5 - **持空反手做多**:价格涨到 开仓价 + 前一根实体/5
- **持多反手做空**:价格跌到 开仓价 - 前一根实体/5 - **持多反手做空**:价格跌到 开仓价 - 前一根实体/5
- 检测窗口使用前2根1分钟K线覆盖 0:00~2:00包含 0:00~1:30
### 与原始五分之一策略的区别 ### 与原始五分之一策略的区别

View File

@@ -29,5 +29,9 @@ RISK_PERCENT = 0.01 # 每次开仓占用可用余额的比例
# 反手信号价格容差(美元) # 反手信号价格容差(美元)
REVERSE_PRICE_TOLERANCE = 2.0 REVERSE_PRICE_TOLERANCE = 2.0
# 反手信号检测窗口3分钟K线的「前1分30秒」内出现反手信号则平仓反手
# 使用前2根1分钟K线近似覆盖 0:00~2:00包含 0:00~1:30
REVERSE_WINDOW_1M_BARS = 2
# 比特浏览器ID用于网页下单 # 比特浏览器ID用于网页下单
BIT_ID = "f2320f57e24c45529a009e1541e25961" BIT_ID = "f2320f57e24c45529a009e1541e25961"

View File

@@ -11,7 +11,8 @@ BitMart 基于开盘价的五分之一策略交易
- 当前K线最高价 >= 做多触发价 → 做多信号 - 当前K线最高价 >= 做多触发价 → 做多信号
- 当前K线最低价 <= 做空触发价 → 做空信号 - 当前K线最低价 <= 做空触发价 → 做空信号
3. 第一分钟反手(若已有持仓): 3. 前1分30秒反手(若已有持仓):
- 3分钟K线的前1分30秒内若出现反手信号则平仓开反手
- 持空反手做多:价格涨到 开仓价 + 前一根实体/5 - 持空反手做多:价格涨到 开仓价 + 前一根实体/5
- 持多反手做空:价格跌到 开仓价 - 前一根实体/5 - 持多反手做空:价格跌到 开仓价 - 前一根实体/5
@@ -50,6 +51,7 @@ from open_fifth_strategy.config import (
OPEN_TYPE, OPEN_TYPE,
RISK_PERCENT, RISK_PERCENT,
REVERSE_PRICE_TOLERANCE, REVERSE_PRICE_TOLERANCE,
REVERSE_WINDOW_1M_BARS,
BIT_ID, BIT_ID,
) )
@@ -82,6 +84,7 @@ class OpenBasedFifthStrategy:
self.open_type = OPEN_TYPE self.open_type = OPEN_TYPE
self.risk_percent = RISK_PERCENT self.risk_percent = RISK_PERCENT
self.reverse_price_tolerance = REVERSE_PRICE_TOLERANCE self.reverse_price_tolerance = REVERSE_PRICE_TOLERANCE
self.reverse_window_1m_bars = REVERSE_WINDOW_1M_BARS
self.last_trigger_kline_id = None self.last_trigger_kline_id = None
self.last_trigger_direction = None self.last_trigger_direction = None
@@ -89,7 +92,7 @@ class OpenBasedFifthStrategy:
self.entry_prev_body = None self.entry_prev_body = None
self.entry_price = None self.entry_price = None
self.entry_kline_id = None self.entry_kline_id = None
self.first_minute_reverse_executed = False self.early_reverse_executed = False
# ==================== 策略核心(基于开盘价)==================== # ==================== 策略核心(基于开盘价)====================
@@ -171,21 +174,23 @@ class OpenBasedFifthStrategy:
return "short" if d_short < d_long else "long" return "short" if d_short < d_long else "long"
return None return None
def check_first_minute_reverse_signal(self, curr_kline, kline_data): def check_early_reverse_signal(self, curr_kline, kline_data):
""" """
第一分钟反手检测与1111一致 前1分30秒反手检测与1111一致
- 3分钟K线的「前1分30秒」内若出现反手信号 → 平仓开反手
- 持空反手做多:价格涨到 开仓价 + 前一根实体/5 - 持空反手做多:价格涨到 开仓价 + 前一根实体/5
- 持多反手做空:价格跌到 开仓价 - 前一根实体/5 - 持多反手做空:价格跌到 开仓价 - 前一根实体/5
- 使用前 N 根1分钟K线近似REVERSE_WINDOW_1M_BARS=2 覆盖约 0:00~1:30
""" """
if self.start == 0: if self.start == 0:
return None, None return None, None
curr_kline_id = curr_kline["id"] curr_kline_id = curr_kline["id"]
if self.entry_kline_id != curr_kline_id: if self.entry_kline_id != curr_kline_id:
self.first_minute_reverse_executed = False self.early_reverse_executed = False
self.entry_kline_id = curr_kline_id self.entry_kline_id = curr_kline_id
if self.first_minute_reverse_executed: if self.early_reverse_executed:
return None, None return None, None
entry_price = self.entry_price entry_price = self.entry_price
@@ -203,25 +208,28 @@ class OpenBasedFifthStrategy:
reverse_offset = prev_body / 5 reverse_offset = prev_body / 5
bars_1m = self.get_1m_bars_for_3m_bar(curr_kline) bars_1m = self.get_1m_bars_for_3m_bar(curr_kline)
if not bars_1m or len(bars_1m) < 1: n_bars = min(self.reverse_window_1m_bars, len(bars_1m))
if n_bars < 1:
return None, None return None, None
first_1m = bars_1m[0] # 遍历前 N 根1分钟K线覆盖前1分30秒任一出现反手信号则触发
first_1m_high = float(first_1m["high"]) for i in range(n_bars):
first_1m_low = float(first_1m["low"]) bar = bars_1m[i]
first_1m_close = float(first_1m["close"]) bar_high = float(bar["high"])
bar_low = float(bar["low"])
bar_close = float(bar["close"])
if self.start == -1: if self.start == -1:
reverse_long_trigger = entry_price + reverse_offset reverse_long_trigger = entry_price + reverse_offset
if first_1m_high >= reverse_long_trigger: if bar_high >= reverse_long_trigger:
if first_1m_close >= reverse_long_trigger - self.reverse_price_tolerance: if bar_close >= reverse_long_trigger - self.reverse_price_tolerance:
return "long", reverse_long_trigger return "long", reverse_long_trigger
elif self.start == 1: elif self.start == 1:
reverse_short_trigger = entry_price - reverse_offset reverse_short_trigger = entry_price - reverse_offset
if first_1m_low <= reverse_short_trigger: if bar_low <= reverse_short_trigger:
if first_1m_close <= reverse_short_trigger + self.reverse_price_tolerance: if bar_close <= reverse_short_trigger + self.reverse_price_tolerance:
return "short", reverse_short_trigger return "short", reverse_short_trigger
return None, None return None, None
@@ -553,7 +561,7 @@ class OpenBasedFifthStrategy:
# 第一分钟反手 # 第一分钟反手
if self.start != 0: if self.start != 0:
first_dir, first_trigger = self.check_first_minute_reverse_signal( first_dir, first_trigger = self.check_early_reverse_signal(
curr, kline_data curr, kline_data
) )
if first_dir: if first_dir:
@@ -569,7 +577,7 @@ class OpenBasedFifthStrategy:
self.平仓() self.平仓()
time.sleep(1) time.sleep(1)
self.开单(marketPriceLongOrder=-1, size=trade_size) self.开单(marketPriceLongOrder=-1, size=trade_size)
self.first_minute_reverse_executed = True self.early_reverse_executed = True
self.last_trade_kline_id = curr_kline_id self.last_trade_kline_id = curr_kline_id
_, valid_prev = self.find_valid_prev_bar( _, valid_prev = self.find_valid_prev_bar(
kline_data, len(kline_data) - 1 kline_data, len(kline_data) - 1
@@ -634,7 +642,7 @@ class OpenBasedFifthStrategy:
self.entry_price = trigger_price self.entry_price = trigger_price
self.entry_prev_body = self.get_body_size(valid_prev) self.entry_prev_body = self.get_body_size(valid_prev)
self.entry_kline_id = curr_kline_id self.entry_kline_id = curr_kline_id
self.first_minute_reverse_executed = False self.early_reverse_executed = False
self.get_position_status() self.get_position_status()
self._send_position_message(curr_kline) self._send_position_message(curr_kline)
last_report_time = time.time() last_report_time = time.time()