
Идея заключается в том, что если мы будем продолжать развивать эту стратегию, то мы сможем достичь успеха в этом направлении.Полюсная доходностьПроведение плавной обработки АЛМА, а не непосредственного действия на цены. Комбинация 30-циклической краткосрочной АЛМА vs 250-циклической долгосрочной АЛМА, совмещенная с 0.95 смещением и параметрами 4.0 сигма, создает более чувствительную, но менее шумную сигнальную систему, чем традиционная подвижная средняя.
Ключевые данные: стратегическое использованиеМинимальная кросс-тенденция 0.0002Для фильтрации ложных прорывов, этот показатель был оптимизирован, чтобы эффективно уменьшить неэффективные сигналы в шокирующем рынке. 200-циклическая EMA используется в качестве фильтра макро-трендов, чтобы гарантировать, что позиции открываются только в условиях бычьего рынка.
В конце концов, это была очень серьезная оборона:
Эта конструкция более надежна, чем простая стратегия золотых винтов. Опрос показал, что механизм трехфильтрации может повысить вероятность победы на 15-20%, но пропустит некоторые возможности для быстрого разворота.
Главная особенность стратегии заключается в том, чтоПолюсная доходностьИспользование формулыlogReturn = math.log(close / close[1])Преобразование ценовых изменений в последовательность комбинированных доходов имеет два преимущества:
Экспериментальные данные: задержка сигнала после обработки рентабельности по логике на 1-2 цикла меньше, чем при прямой ценовой ALMA, при этом шум снижается примерно на 30%.
Настройка на 0,95 смещения ALMA близка к максимальному значению 1,0, что означает, что большое внимание уделяется недавним данным. В сочетании с значением сигма 4,0 создается кривая, которая является чувствительной и гладкой.
Сравнение результатов:
250-циклическая долгосрочная ALMA служит базовой линией, которая может точно улавливать изменения среднесрочных и долгосрочных тенденций, избегая заблуждения от краткосрочных колебаний.
“Строго вводим, широко выводим” - так называемая стратегия:
Логика такого асимметричного дизайна заключается в следующем: лучше упустить возможность, чем брать на себя ненужный риск. В реальном режиме средний период хранения позиций составляет 15-25 торговых циклов, что соответствует характеристикам стратегии слежения за среднесрочными тенденциями.
Оптимальная среда:
Определенные ограничения:
Сообщения о рискеИсторический отсчет не является индикатором будущего дохода, существует риск непрерывного убытка, рекомендуется использовать стратегию в сочетании со строгим управлением капиталом.
/*backtest
start: 2024-10-23 00:00:00
end: 2025-10-21 08:00:00
period: 1d
basePeriod: 1d
exchanges: [{"eid":"Futures_Binance","currency":"XRP_USDT","balance":5000}]
*/
//@version=5
strategy("Hermes Strategy", overlay=false, initial_capital=10000, default_qty_type=strategy.percent_of_equity, default_qty_value=100, pyramiding=20)
// ============================================================================
// ALMA FILTER PARAMETERS (optimized for Giovanni-style macro trend capture)
// ============================================================================
shortPeriod = input.int(30, "Short Period", minval=10, maxval=200)
longPeriod = input.int(250, "Long Period", minval=50, maxval=400)
almaOffset = input.float(0.95, "ALMA Offset", minval=0.0, maxval=1.0, step=0.01)
almaSigma = input.float(4, "ALMA Sigma", minval=1.0, maxval=10.0, step=0.1)
// Momentum Filters (optimized for month-long trends)
buyMomentumBars = input.int(6, "Buy Lookback", minval=1)
sellMomentumBars = input.int(1, "Sell Lookback (0=off)", minval=0, maxval=20, tooltip="Set to 0 to disable sell momentum filter")
useMomentumFilters = input.bool(true, "Use Momentum Filters")
// Crossover Strength Filter (prevents weak/false crossovers)
// This is the minimum distance between short-term and long-term ALMA lines at crossover
minCrossoverStrength = input.float(0.0002, "Min Crossover Strength", step=0.0001, minval=0.0001, maxval=0.001)
useCrossoverStrengthFilter = input.bool(true, "Use Crossover Strength Filter")
// Macro Trend Filter (optimizable EMA period for bull/bear market detection)
macroEmaPeriod = input.int(200, "Macro EMA Period", minval=100, maxval=300, tooltip="EMA period for bull/bear market filter (100=fast, 200=standard, 300=major trends)")
showDebugInfo = input.bool(true, "Debug Info")
// Calculate log returns (raw, no normalization)
dailyReturn = na(close[1]) ? 1.0 : close / close[1]
logReturn = math.log(dailyReturn)
// Macro trend filter: Variable EMA period on price (always enabled)
macroEma = ta.ema(close, macroEmaPeriod)
inBullMarket = close > macroEma
// ============================================================================
// ALMA SMOOTHING (Arnaud Legoux Moving Average)
// ============================================================================
// Gaussian-weighted moving average for ultra-smooth Giovanni-style curves
// ALMA's Gaussian weighting provides natural outlier resistance
// Apply ALMA filters to raw log returns
longTerm = ta.alma(logReturn, longPeriod, almaOffset, almaSigma)
shortTerm = ta.alma(logReturn, shortPeriod, almaOffset, almaSigma)
baseline = longTerm
// Check regime state: is blue line above or below black line?
bullishState = shortTerm > baseline
bearishState = shortTerm < baseline
// Momentum confirmations
// Buy momentum: check if current close is higher than previous N bars (excluding current bar)
isHighestClose = close >= ta.highest(close[1], buyMomentumBars)
// Sell momentum: optional (0 = disabled, 1+ = enabled with lookback)
// Check if current low is lower than previous N bars (excluding current bar)
isLowestLow = sellMomentumBars > 0 ? low <= ta.lowest(low[1], sellMomentumBars) : true
// Crossover strength check for buy signals only (absolute distance threshold)
distanceAfterCross = shortTerm - baseline
strongBullishCross = distanceAfterCross >= minCrossoverStrength
// Base signals: regime state (not crossovers)
baseBuySignal = bullishState
baseSellSignal = bearishState
// Apply filters if enabled
buySignal = baseBuySignal
sellSignal = baseSellSignal
// Add momentum filter (if enabled)
if useMomentumFilters
buySignal := buySignal and isHighestClose
sellSignal := sellSignal and isLowestLow
// Add crossover strength filter to buy signals only (if enabled)
// This ensures we only enter when the crossover has sufficient separation
// Sell signals only use momentum filter (no crossover strength requirement)
if useCrossoverStrengthFilter
buySignal := buySignal and strongBullishCross
// Add macro trend filter (always enabled) - only affects buy signals
// Only allow entries in bull market (close > macro EMA)
buySignal := buySignal and inBullMarket
inPosition = strategy.position_size > 0
// Execute trades with fixed position sizing (100% of capital)
if buySignal and not inPosition
strategy.entry("Long", strategy.long)
if sellSignal and inPosition
strategy.close("Long")
// Plot lines
plot(shortTerm, color=color.blue, linewidth=2, title="Short-Term Signal")
plot(baseline, color=color.black, linewidth=2, title="Long-Term Baseline")
hline(0, "Zero", color=color.gray, linestyle=hline.style_dotted)
// Visual feedback
bgcolor(inPosition ? color.new(color.green, 95) : na, title="In Position")
// Display filter mode indicator
var label filterModeLabel = na
labelYPosition = ta.highest(shortTerm, 100)
if barstate.islast
labelText = "📊 ALMA FILTER"
labelColor = color.new(color.blue, 80)
if na(filterModeLabel)
filterModeLabel := label.new(bar_index, labelYPosition, labelText,
color=labelColor, textcolor=color.white,
style=label.style_label_down, size=size.small)
else
label.set_xy(filterModeLabel, bar_index, labelYPosition)
label.set_text(filterModeLabel, labelText)
label.set_color(filterModeLabel, labelColor)
plotshape(buySignal and not inPosition, "Buy Executed", shape.triangleup, location.bottom, color.green, size=size.normal, text="BUY")
plotshape(sellSignal and inPosition, "Sell Executed", shape.triangledown, location.top, color.red, size=size.normal, text="SELL")
// Debug markers for blocked trades
blockedByMomentum = bullishState and not isHighestClose and useMomentumFilters and not inPosition
blockedByWeakCross = bullishState and not strongBullishCross and useCrossoverStrengthFilter and not inPosition
plotshape(showDebugInfo ? blockedByMomentum : na, "Blocked by Momentum", shape.xcross, location.bottom, color.orange, size=size.tiny, text="M")
plotshape(showDebugInfo ? blockedByWeakCross : na, "Blocked by Weak Crossover", shape.xcross, location.bottom, color.purple, size=size.tiny, text="W")