加入精准回测数据

This commit is contained in:
27942
2026-02-02 00:16:35 +08:00
parent d8abb15304
commit 03e209f28a

View File

@@ -19,7 +19,7 @@ BitMart 五分之一回归策略交易(精准版)
4. 精准判断使用1分钟K线
- 当当前3分钟K线同时触及做多和做空价格时拉取该3分钟对应的3根1分钟K线判断哪个方向先被触发
"""
import random
import time
import datetime
from concurrent.futures import ThreadPoolExecutor
@@ -158,10 +158,18 @@ class BitmartOneFifthStrategy:
return 'short' if d_short < d_long else 'long'
return None
def check_realtime_trigger(self, kline_data):
def check_realtime_trigger(self, kline_data, current_position=0):
"""
实时检测当前3分钟K线是否触发信号
若多空都触发优先用1分钟K线判断先后否则用开盘价距离
参数:
kline_data: K线数据列表
current_position: 当前持仓状态 (1=多, -1=空, 0=无)
逻辑优化:
- 当已有持仓时,只关心反向信号(有多仓只看空信号,有空仓只看多信号)
- 无仓位时用1分钟K线判断先触发的方向
返回:(方向, 触发价格, 有效前一根K线, 当前K线) 或 (None, None, None, None)
"""
if len(kline_data) < 2:
@@ -187,25 +195,38 @@ class BitmartOneFifthStrategy:
direction = None
trigger_price = None
if long_triggered and short_triggered:
bars_1m = self.get_1m_bars_for_3m_bar(curr)
if bars_1m:
direction = self.determine_trigger_order_by_1m(
bars_1m, long_trigger, short_trigger
)
trigger_price = long_trigger if direction == 'long' else short_trigger
if direction is None:
c_open = float(curr['open'])
d_long = abs(long_trigger - c_open)
d_short = abs(short_trigger - c_open)
direction = 'short' if d_short <= d_long else 'long'
trigger_price = long_trigger if direction == 'long' else short_trigger
elif short_triggered:
direction = 'short'
trigger_price = short_trigger
elif long_triggered:
direction = 'long'
trigger_price = long_trigger
# 关键优化:根据当前持仓状态决定关注哪个方向的信号
if current_position == 1:
# 当前是多仓,只关心空信号(用于平多开空)
if short_triggered:
direction = 'short'
trigger_price = short_trigger
elif current_position == -1:
# 当前是空仓,只关心多信号(用于平空开多)
if long_triggered:
direction = 'long'
trigger_price = long_trigger
else:
# 无仓位,按原逻辑判断先触发的方向
if long_triggered and short_triggered:
bars_1m = self.get_1m_bars_for_3m_bar(curr)
if bars_1m:
direction = self.determine_trigger_order_by_1m(
bars_1m, long_trigger, short_trigger
)
trigger_price = long_trigger if direction == 'long' else short_trigger
if direction is None:
c_open = float(curr['open'])
d_long = abs(long_trigger - c_open)
d_short = abs(short_trigger - c_open)
direction = 'short' if d_short <= d_long else 'long'
trigger_price = long_trigger if direction == 'long' else short_trigger
elif short_triggered:
direction = 'short'
trigger_price = short_trigger
elif long_triggered:
direction = 'long'
trigger_price = long_trigger
if direction is None:
return None, None, None, None
@@ -383,7 +404,7 @@ class BitmartOneFifthStrategy:
"""
prefix = "❌五分之一策略:" if error else "🔔五分之一策略:"
full_msg = f"{prefix}{msg}"
if error:
logger.error(msg)
# 异步发送多条错误消息
@@ -393,7 +414,7 @@ class BitmartOneFifthStrategy:
logger.info(msg)
# 异步发送单条消息
ding_executor.submit(self._send_ding_safe, full_msg)
def _send_ding_safe(self, msg):
"""
安全发送钉钉消息,捕获异常防止线程崩溃
@@ -449,7 +470,15 @@ class BitmartOneFifthStrategy:
curr = kline_data[-1]
curr_time_str = datetime.datetime.fromtimestamp(curr['id']).strftime('%H:%M:%S')
direction, trigger_price, valid_prev, curr_kline = self.check_realtime_trigger(kline_data)
# 优化:先获取持仓状态,再检测信号(传入持仓状态以便只关注反向信号)
if not self.get_position_status():
logger.warning("获取仓位信息失败,使用缓存的持仓状态")
# 传入当前持仓状态,确保有持仓时只关注反向信号
direction, trigger_price, valid_prev, curr_kline = self.check_realtime_trigger(
kline_data, current_position=self.start
)
if direction:
curr_kline_id = curr_kline['id']
@@ -458,16 +487,15 @@ class BitmartOneFifthStrategy:
self.last_trigger_direction = direction
time.sleep(self.check_interval)
continue
if not self.get_position_status():
logger.warning("获取仓位信息失败")
time.sleep(self.check_interval)
continue
prev_time = datetime.datetime.fromtimestamp(valid_prev['id']).strftime('%H:%M')
prev_type = "阳线" if self.is_bullish(valid_prev) else "阴线"
prev_body = self.get_body_size(valid_prev)
# 由于 check_realtime_trigger 已经考虑了持仓状态,这里理论上不会出现同向信号
# 但保留这个检查作为安全措施
if (direction == "long" and self.start == 1) or (direction == "short" and self.start == -1):
logger.debug(f"同向信号被过滤: direction={direction}, position={self.start}")
self.last_trigger_kline_id = curr_kline_id
self.last_trigger_direction = direction
time.sleep(self.check_interval)
@@ -529,8 +557,10 @@ class BitmartOneFifthStrategy:
except Exception as e:
logger.error(f"主循环异常: {e}")
time.sleep(self.check_interval)
time.sleep(15)
self.page.close()
time.sleep(5)
if random.randint(1,10)>7:
self.page.close()
time.sleep(15)
def _send_position_message(self, latest_kline):