日志展示优化
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import sys
|
||||
import time
|
||||
from datetime import datetime
|
||||
from collections import deque
|
||||
|
||||
from tqdm import tqdm
|
||||
from loguru import logger
|
||||
@@ -40,7 +41,7 @@ LOG_SYSTEM = _tag("系统", _M)
|
||||
|
||||
if not USE_RICH_DASHBOARD:
|
||||
logger.remove()
|
||||
logger.add(sys.stderr, format="\033[2m│\033[0m {message}", colorize=False)
|
||||
logger.add(sys.stderr, format="\033[2m│\033[0m {message}", colorize=False, level="INFO")
|
||||
|
||||
def log_kline_header(kline_id):
|
||||
"""新 K 线分块头(仅非 Rich 模式使用)"""
|
||||
@@ -81,7 +82,8 @@ def make_metrics_panel(state: dict) -> Panel:
|
||||
return Panel(t, title="[bold]价格 / 指标[/bold]", border_style="magenta")
|
||||
|
||||
def make_logs_panel(logs: list) -> Panel:
|
||||
body = "\n".join(logs[-12:]) if logs else "等待日志..."
|
||||
recent = list(logs)[-16:] if logs else []
|
||||
body = "\n".join(recent) if recent else "等待日志..."
|
||||
text = Text.from_ansi(body) if body else Text("等待日志...", style="dim")
|
||||
return Panel(text, title="[bold]状态 / 日志[/bold]", border_style="green")
|
||||
|
||||
@@ -166,8 +168,10 @@ class BitmartFuturesTransaction:
|
||||
self.current_open = None
|
||||
# Rich 仪表盘:状态与日志(供 build_dashboard_layout 使用)
|
||||
self._display_state = {}
|
||||
self._display_logs = []
|
||||
self._display_logs = deque(maxlen=120)
|
||||
self._display_triggers = {}
|
||||
self._last_signal_log_kline_id = None
|
||||
self._log_throttle_at = {}
|
||||
|
||||
def get_klines(self):
|
||||
"""获取最近2根K线(当前K线和上一根K线)"""
|
||||
@@ -424,6 +428,15 @@ class BitmartFuturesTransaction:
|
||||
else:
|
||||
logger.info(text)
|
||||
|
||||
def _log_throttled(self, key, text, interval=1.0, level="info"):
|
||||
"""同类日志限频,避免 0.1 秒循环刷屏。"""
|
||||
now = time.time()
|
||||
last = self._log_throttle_at.get(key, 0)
|
||||
if now - last < interval:
|
||||
return
|
||||
self._log_throttle_at[key] = now
|
||||
getattr(logger, level)(text)
|
||||
|
||||
def calculate_entity(self, kline):
|
||||
"""计算K线实体大小(绝对值)"""
|
||||
return abs(kline['close'] - kline['open'])
|
||||
@@ -458,12 +471,17 @@ class BitmartFuturesTransaction:
|
||||
检查交易信号
|
||||
返回: ('long', trigger_price) / ('short', trigger_price) / None
|
||||
"""
|
||||
current_kline_id = current_kline.get('id')
|
||||
should_log_snapshot = self._last_signal_log_kline_id != current_kline_id
|
||||
|
||||
# 计算上一根K线实体
|
||||
prev_entity = self.calculate_entity(prev_kline)
|
||||
|
||||
# 实体过小不交易(实体 < 0.1)
|
||||
if prev_entity < 0.1:
|
||||
logger.info(LOG_PRICE + f"上一根K线实体过小: {prev_entity:.4f},跳过信号检测")
|
||||
if should_log_snapshot:
|
||||
logger.info(LOG_PRICE + f"上一根K线实体过小: {prev_entity:.4f},跳过信号检测")
|
||||
self._last_signal_log_kline_id = current_kline_id
|
||||
return None
|
||||
|
||||
# 获取上一根K线的实体上下边
|
||||
@@ -504,17 +522,19 @@ class BitmartFuturesTransaction:
|
||||
current_is_bearish = current_kline['close'] < current_kline['open']
|
||||
skip_long_by_lower_third = prev_is_bullish and current_is_bearish
|
||||
|
||||
if use_current_open_as_base:
|
||||
if prev_is_bullish_for_calc and current_open_above_prev_close:
|
||||
logger.info(LOG_PRICE + f"上一根阳线且当前开盘价({current_kline['open']:.2f})>上一根收盘价({prev_kline['close']:.2f}),以当前开盘价为基准计算")
|
||||
else:
|
||||
logger.info(LOG_PRICE + f"上一根阴线且当前开盘价({current_kline['open']:.2f})<上一根收盘价({prev_kline['close']:.2f}),以当前开盘价为基准计算")
|
||||
logger.info(LOG_PRICE + f"当前价: {current_price:.2f} | 上一根实体: {prev_entity:.4f} | 实体上边: {prev_entity_upper:.2f} 下边: {prev_entity_lower:.2f}")
|
||||
logger.info(LOG_PRICE + f"做多触发(下1/4): {long_trigger:.2f} | 做空触发(上1/4): {short_trigger:.2f} | 突破做多: {long_breakout:.2f} | 突破做空: {short_breakout:.2f}")
|
||||
if skip_short_by_upper_third:
|
||||
logger.info(LOG_PRICE + "上一根阴+当前阳(做多形态),不按上1/4做空")
|
||||
if skip_long_by_lower_third:
|
||||
logger.info(LOG_PRICE + "上一根阳+当前阴(做空形态),不按下1/4做多")
|
||||
if should_log_snapshot:
|
||||
if use_current_open_as_base:
|
||||
if prev_is_bullish_for_calc and current_open_above_prev_close:
|
||||
logger.info(LOG_PRICE + f"上一根阳线且当前开盘价({current_kline['open']:.2f})>上一根收盘价({prev_kline['close']:.2f}),以当前开盘价为基准计算")
|
||||
else:
|
||||
logger.info(LOG_PRICE + f"上一根阴线且当前开盘价({current_kline['open']:.2f})<上一根收盘价({prev_kline['close']:.2f}),以当前开盘价为基准计算")
|
||||
logger.info(LOG_PRICE + f"当前价: {current_price:.2f} | 上一根实体: {prev_entity:.4f} | 实体上边: {prev_entity_upper:.2f} 下边: {prev_entity_lower:.2f}")
|
||||
logger.info(LOG_PRICE + f"做多触发(下1/4): {long_trigger:.2f} | 做空触发(上1/4): {short_trigger:.2f} | 突破做多: {long_breakout:.2f} | 突破做空: {short_breakout:.2f}")
|
||||
if skip_short_by_upper_third:
|
||||
logger.info(LOG_PRICE + "上一根阴+当前阳(做多形态),不按上1/4做空")
|
||||
if skip_long_by_lower_third:
|
||||
logger.info(LOG_PRICE + "上一根阳+当前阴(做空形态),不按下1/4做多")
|
||||
self._last_signal_log_kline_id = current_kline_id
|
||||
|
||||
self._display_triggers = {"long_trigger": long_trigger, "short_trigger": short_trigger, "long_breakout": long_breakout, "short_breakout": short_breakout}
|
||||
|
||||
@@ -553,7 +573,7 @@ class BitmartFuturesTransaction:
|
||||
now = time.time()
|
||||
if self.last_open_time is not None and now - self.last_open_time < self.open_cooldown_seconds:
|
||||
remain = self.open_cooldown_seconds - (now - self.last_open_time)
|
||||
logger.info(LOG_SYSTEM + f"开仓冷却中,剩余 {remain:.0f} 秒")
|
||||
self._log_throttled("open_cooldown", LOG_SYSTEM + f"开仓冷却中,剩余 {remain:.0f} 秒", interval=1.0)
|
||||
return False
|
||||
return True
|
||||
|
||||
@@ -562,13 +582,13 @@ class BitmartFuturesTransaction:
|
||||
now = time.time()
|
||||
if self.last_reverse_time and now - self.last_reverse_time < self.reverse_cooldown_seconds:
|
||||
remain = self.reverse_cooldown_seconds - (now - self.last_reverse_time)
|
||||
logger.info(LOG_SYSTEM + f"反手冷却中,剩余 {remain:.0f} 秒")
|
||||
self._log_throttled("reverse_cooldown", LOG_SYSTEM + f"反手冷却中,剩余 {remain:.0f} 秒", interval=1.0)
|
||||
return False
|
||||
|
||||
if trigger_price and trigger_price > 0:
|
||||
move_pct = abs(current_price - trigger_price) / trigger_price * 100
|
||||
if move_pct < self.reverse_min_move_pct:
|
||||
logger.info(LOG_SYSTEM + f"反手价差不足: {move_pct:.4f}% < {self.reverse_min_move_pct}%")
|
||||
self._log_throttled("reverse_move_small", LOG_SYSTEM + f"反手价差不足: {move_pct:.4f}% < {self.reverse_min_move_pct}%", interval=1.0)
|
||||
return False
|
||||
|
||||
return True
|
||||
@@ -733,13 +753,25 @@ class BitmartFuturesTransaction:
|
||||
|
||||
page_start = True
|
||||
if USE_RICH_DASHBOARD:
|
||||
self._display_logs = []
|
||||
self._display_logs.clear()
|
||||
logger.remove()
|
||||
level_color = {
|
||||
"DEBUG": "\033[2m",
|
||||
"INFO": "\033[36m",
|
||||
"SUCCESS": "\033[32m",
|
||||
"WARNING": "\033[33m",
|
||||
"ERROR": "\033[31m",
|
||||
"CRITICAL": "\033[35m",
|
||||
}
|
||||
|
||||
def _sink(msg):
|
||||
self._display_logs.append(msg.record["message"])
|
||||
if len(self._display_logs) > 50:
|
||||
self._display_logs.pop(0)
|
||||
logger.add(_sink, format="{message}")
|
||||
record = msg.record
|
||||
ts = record["time"].strftime("%H:%M:%S")
|
||||
level = record["level"].name
|
||||
color = level_color.get(level, "\033[37m")
|
||||
line = f"\033[2m{ts}\033[0m {color}{level:<7}\033[0m {record['message']}"
|
||||
self._display_logs.append(line)
|
||||
logger.add(_sink, format="{message}", level="INFO")
|
||||
|
||||
live = None
|
||||
if USE_RICH_DASHBOARD:
|
||||
@@ -783,8 +815,11 @@ class BitmartFuturesTransaction:
|
||||
current_kline_time = current_kline['id']
|
||||
if self.last_kline_time != current_kline_time:
|
||||
self.last_kline_time = current_kline_time
|
||||
logger.info("")
|
||||
log_kline_header(current_kline_time)
|
||||
if USE_RICH_DASHBOARD:
|
||||
logger.info(LOG_SYSTEM + f"进入新K线: {current_kline_time}")
|
||||
else:
|
||||
logger.info("")
|
||||
log_kline_header(current_kline_time)
|
||||
|
||||
# 2. 获取当前价格
|
||||
current_price = self.get_current_price()
|
||||
@@ -799,7 +834,12 @@ class BitmartFuturesTransaction:
|
||||
time.sleep(2)
|
||||
continue
|
||||
|
||||
logger.debug(f"当前持仓状态: {self.start} (0=无, 1=多, -1=空)")
|
||||
self._log_throttled(
|
||||
"position_state",
|
||||
f"当前持仓状态: {self.start} (0=无, 1=多, -1=空)",
|
||||
interval=2.0,
|
||||
level="debug",
|
||||
)
|
||||
|
||||
# 更新仪表盘左侧数据(供 Rich 展示)
|
||||
try:
|
||||
@@ -984,7 +1024,7 @@ class BitmartFuturesTransaction:
|
||||
|
||||
if USE_RICH_DASHBOARD:
|
||||
logger.remove()
|
||||
logger.add(sys.stderr, format="{message}")
|
||||
logger.add(sys.stderr, format="{message}", level="INFO")
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
Reference in New Issue
Block a user