日志展示优化
This commit is contained in:
11
1111
11
1111
@@ -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线的实体边,平仓做多
|
||||
|
||||
|
||||
129
bitmart/交易.py
129
bitmart/交易.py
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user