a
This commit is contained in:
parent
cf86c64296
commit
cb8b393550
|
|
@ -25,6 +25,8 @@ const KEY_LABELS = {
|
||||||
SYMBOL_LOSS_COOLDOWN_ENABLED: '连续亏损冷却',
|
SYMBOL_LOSS_COOLDOWN_ENABLED: '连续亏损冷却',
|
||||||
SYMBOL_MAX_CONSECUTIVE_LOSSES: '连续亏损次数阈值',
|
SYMBOL_MAX_CONSECUTIVE_LOSSES: '连续亏损次数阈值',
|
||||||
SYMBOL_LOSS_COOLDOWN_SEC: '冷却时间(秒)',
|
SYMBOL_LOSS_COOLDOWN_SEC: '冷却时间(秒)',
|
||||||
|
RSI_EXTREME_REVERSE_ENABLED: 'RSI 极端反向(超买反空/超卖反多)',
|
||||||
|
RSI_EXTREME_REVERSE_ONLY_NEUTRAL_4H: 'RSI 反向仅允许 4H 中性',
|
||||||
}
|
}
|
||||||
|
|
||||||
const ConfigItem = ({ label, config, onUpdate, disabled }) => {
|
const ConfigItem = ({ label, config, onUpdate, disabled }) => {
|
||||||
|
|
@ -481,6 +483,8 @@ const GlobalConfig = () => {
|
||||||
SYMBOL_LOSS_COOLDOWN_SEC: { value: 3600, type: 'number', category: 'strategy', description: '连续亏损后的冷却时间(秒),默认1小时。' },
|
SYMBOL_LOSS_COOLDOWN_SEC: { value: 3600, type: 'number', category: 'strategy', description: '连续亏损后的冷却时间(秒),默认1小时。' },
|
||||||
BETA_FILTER_ENABLED: { value: true, type: 'boolean', category: 'strategy', description: '大盘共振过滤:BTC/ETH 下跌时屏蔽多单。' },
|
BETA_FILTER_ENABLED: { value: true, type: 'boolean', category: 'strategy', description: '大盘共振过滤:BTC/ETH 下跌时屏蔽多单。' },
|
||||||
BETA_FILTER_THRESHOLD: { value: -0.005, type: 'number', category: 'strategy', description: '大盘共振阈值(比例,如 -0.005 表示 -0.5%)。' },
|
BETA_FILTER_THRESHOLD: { value: -0.005, type: 'number', category: 'strategy', description: '大盘共振阈值(比例,如 -0.005 表示 -0.5%)。' },
|
||||||
|
RSI_EXTREME_REVERSE_ENABLED: { value: false, type: 'boolean', category: 'strategy', description: '开启后:原信号做多但 RSI 超买(≥做多上限)时改为做空;原信号做空但 RSI 超卖(≤做空下限)时改为做多。属均值回归思路,可填补超买超卖时不下单的空置;默认关闭。' },
|
||||||
|
RSI_EXTREME_REVERSE_ONLY_NEUTRAL_4H: { value: true, type: 'boolean', category: 'strategy', description: '建议开启:仅在 4H 趋势为中性时允许 RSI 反向单,避免在强趋势里逆势抄底/摸顶,降低风险。关闭则反向可与 4H 同向(仍受“禁止逆4H趋势”约束)。' },
|
||||||
}
|
}
|
||||||
|
|
||||||
const loadConfigs = async () => {
|
const loadConfigs = async () => {
|
||||||
|
|
|
||||||
|
|
@ -472,12 +472,15 @@ class TradingStrategy:
|
||||||
pass
|
pass
|
||||||
should_trade = signal_strength >= min_signal_strength and direction is not None
|
should_trade = signal_strength >= min_signal_strength and direction is not None
|
||||||
|
|
||||||
# ===== RSI / 24h 涨跌幅过滤:做多不追高、做空不杀跌 =====
|
# ===== RSI / 24h 涨跌幅过滤:做多不追高、做空不杀跌;可选 RSI 极端反向(超买反空/超卖反多)=====
|
||||||
|
# 反向属于“逆短期超买超卖”的均值回归,在强趋势里逆势风险大;可选“仅4H中性时反向”以降低风险。
|
||||||
|
reversed_by_rsi = False
|
||||||
try:
|
try:
|
||||||
max_rsi_long = config.TRADING_CONFIG.get('MAX_RSI_FOR_LONG', 70)
|
max_rsi_long = config.TRADING_CONFIG.get('MAX_RSI_FOR_LONG', 70)
|
||||||
max_change_long = config.TRADING_CONFIG.get('MAX_CHANGE_PERCENT_FOR_LONG', 25)
|
max_change_long = config.TRADING_CONFIG.get('MAX_CHANGE_PERCENT_FOR_LONG', 25)
|
||||||
min_rsi_short = config.TRADING_CONFIG.get('MIN_RSI_FOR_SHORT', 30)
|
min_rsi_short = config.TRADING_CONFIG.get('MIN_RSI_FOR_SHORT', 30)
|
||||||
max_change_short = config.TRADING_CONFIG.get('MAX_CHANGE_PERCENT_FOR_SHORT', 10)
|
max_change_short = config.TRADING_CONFIG.get('MAX_CHANGE_PERCENT_FOR_SHORT', 10)
|
||||||
|
rsi_extreme_reverse = bool(config.TRADING_CONFIG.get('RSI_EXTREME_REVERSE_ENABLED', False))
|
||||||
change_pct = symbol_info.get('changePercent')
|
change_pct = symbol_info.get('changePercent')
|
||||||
if change_pct is not None and not isinstance(change_pct, (int, float)):
|
if change_pct is not None and not isinstance(change_pct, (int, float)):
|
||||||
change_pct = float(change_pct) if change_pct else None
|
change_pct = float(change_pct) if change_pct else None
|
||||||
|
|
@ -489,8 +492,13 @@ class TradingStrategy:
|
||||||
try:
|
try:
|
||||||
rsi_val = float(rsi)
|
rsi_val = float(rsi)
|
||||||
if rsi_val >= max_rsi_long:
|
if rsi_val >= max_rsi_long:
|
||||||
should_trade = False
|
if rsi_extreme_reverse:
|
||||||
reasons.append(f"❌ 做多RSI过滤:RSI={rsi_val:.1f}≥{max_rsi_long}(超买区不追多)")
|
direction = 'SELL'
|
||||||
|
reversed_by_rsi = True
|
||||||
|
reasons.append(f"RSI超买({rsi_val:.1f}≥{max_rsi_long})反向做空")
|
||||||
|
else:
|
||||||
|
should_trade = False
|
||||||
|
reasons.append(f"❌ 做多RSI过滤:RSI={rsi_val:.1f}≥{max_rsi_long}(超买区不追多)")
|
||||||
except (TypeError, ValueError):
|
except (TypeError, ValueError):
|
||||||
pass
|
pass
|
||||||
if should_trade and change_pct is not None and change_pct > max_change_long:
|
if should_trade and change_pct is not None and change_pct > max_change_long:
|
||||||
|
|
@ -502,16 +510,28 @@ class TradingStrategy:
|
||||||
try:
|
try:
|
||||||
rsi_val = float(rsi)
|
rsi_val = float(rsi)
|
||||||
if rsi_val <= min_rsi_short:
|
if rsi_val <= min_rsi_short:
|
||||||
should_trade = False
|
if rsi_extreme_reverse:
|
||||||
reasons.append(f"❌ 做空RSI过滤:RSI={rsi_val:.1f}≤{min_rsi_short}(超卖区不追空)")
|
direction = 'BUY'
|
||||||
|
reversed_by_rsi = True
|
||||||
|
reasons.append(f"RSI超卖({rsi_val:.1f}≤{min_rsi_short})反向做多")
|
||||||
|
else:
|
||||||
|
should_trade = False
|
||||||
|
reasons.append(f"❌ 做空RSI过滤:RSI={rsi_val:.1f}≤{min_rsi_short}(超卖区不追空)")
|
||||||
except (TypeError, ValueError):
|
except (TypeError, ValueError):
|
||||||
pass
|
pass
|
||||||
if should_trade and change_pct is not None and change_pct > max_change_short:
|
if should_trade and direction == 'SELL' and change_pct is not None and change_pct > max_change_short:
|
||||||
should_trade = False
|
should_trade = False
|
||||||
reasons.append(f"❌ 做空涨跌幅过滤:24h涨幅={change_pct:.1f}%>{max_change_short}%(24h仍大涨不做空)")
|
reasons.append(f"❌ 做空涨跌幅过滤:24h涨幅={change_pct:.1f}%>{max_change_short}%(24h仍大涨不做空)")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.debug(f"{symbol} RSI/涨跌幅过滤失败(忽略): {e}")
|
logger.debug(f"{symbol} RSI/涨跌幅过滤失败(忽略): {e}")
|
||||||
|
|
||||||
|
# 安全约束:RSI 反向仅允许在 4H 中性时执行(避免在强趋势里逆势抄底/摸顶)
|
||||||
|
if reversed_by_rsi and should_trade and direction:
|
||||||
|
only_neutral_4h = bool(config.TRADING_CONFIG.get('RSI_EXTREME_REVERSE_ONLY_NEUTRAL_4H', True))
|
||||||
|
if only_neutral_4h and trend_4h != 'neutral':
|
||||||
|
should_trade = False
|
||||||
|
reasons.append(f"❌ RSI反向仅允许4H中性时执行(当前4H={trend_4h or 'unknown'},避免逆势风险)")
|
||||||
|
|
||||||
# ===== 15m 短周期方向过滤:避免“上涨中做空 / 下跌中做多” =====
|
# ===== 15m 短周期方向过滤:避免“上涨中做空 / 下跌中做多” =====
|
||||||
# 思路:
|
# 思路:
|
||||||
# - 使用最近 N 根 15m K 线的总涨跌幅来确认短期方向
|
# - 使用最近 N 根 15m K 线的总涨跌幅来确认短期方向
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user