auto_trade_sys/trading_system/trend_4h_cache.py
薇薇安 cddcf35481 feat(config): 添加4H趋势过滤配置以优化交易策略
在配置管理中新增 `BLOCK_SHORT_WHEN_4H_UP` 参数,允许在4H上涨时禁止开空,增强策略灵活性与风险控制。同时,更新前端组件以展示该配置,提升用户体验。此改动确保在不同市场条件下,策略能够更有效地避免逆势操作。
2026-02-22 22:51:36 +08:00

97 lines
2.6 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""
trend_4h 缓存模块
基于已有 WS K 线缓存,将计算得到的 trend_4hup/down/neutral写入 Redis
供 strategy、market_scanner 等复用,减少重复 EMA/MACD 计算。
Redis Key: trend_4h:{symbol}TTL 10 分钟。
"""
import logging
from typing import Optional, Dict, Any
logger = logging.getLogger(__name__)
KEY_PREFIX = "trend_4h:"
try:
from .redis_ttl import TTL_TREND_4H
except ImportError:
TTL_TREND_4H = 600 # 10 分钟
def _judge_trend_4h(
price_4h: float,
ema20_4h: Optional[float],
ema50_4h: Optional[float],
macd_4h: Optional[Dict],
) -> str:
"""
多指标投票判断 4H 趋势(与 strategy._judge_trend_4h 一致)。
Returns: 'up' | 'down' | 'neutral'
"""
if ema20_4h is None:
return 'neutral'
score = 0
if price_4h > ema20_4h:
score += 1
elif price_4h < ema20_4h:
score -= 1
if ema50_4h is not None:
if ema20_4h > ema50_4h:
score += 1
elif ema20_4h < ema50_4h:
score -= 1
if macd_4h and isinstance(macd_4h, dict):
macd_hist = macd_4h.get('histogram', 0)
if macd_hist > 0:
score += 1
elif macd_hist < 0:
score -= 1
if score >= 2:
return 'up'
if score <= -2:
return 'down'
return 'neutral'
async def get_trend_4h_cached(
redis_cache: Any,
symbol: str,
price_4h: float,
ema20_4h: Optional[float],
ema50_4h: Optional[float],
macd_4h: Optional[Dict],
ttl_sec: int = None,
) -> str:
"""
优先从 Redis 读取 trend_4h未命中则计算并写入缓存。
Args:
redis_cache: RedisCache 实例(可为 None则直接计算不缓存
symbol: 交易对
price_4h, ema20_4h, ema50_4h, macd_4h: 计算 trend_4h 所需输入
ttl_sec: 缓存 TTL默认使用 redis_ttl.TTL_TREND_4H10 分钟)
Returns:
'up' | 'down' | 'neutral'
"""
if ttl_sec is None:
ttl_sec = TTL_TREND_4H
key = f"{KEY_PREFIX}{symbol}"
if redis_cache:
try:
await redis_cache.connect()
cached = await redis_cache.get(key)
if cached and cached in ('up', 'down', 'neutral'):
return cached
except Exception as e:
logger.debug(f"trend_4h 缓存读取失败 {symbol}: {e}")
trend = _judge_trend_4h(price_4h, ema20_4h, ema50_4h, macd_4h)
if redis_cache:
try:
await redis_cache.set(key, trend, ttl=ttl_sec)
except Exception as e:
logger.debug(f"trend_4h 缓存写入失败 {symbol}: {e}")
return trend