Стратегия биполярного сглаженного осциллятора

SMA stdev EMA CROSSOVER CROSSUNDER
Дата создания: 2025-10-17 15:20:53 Последнее изменение: 2025-10-17 15:20:53
Копировать: 0 Количество просмотров: 262
2
Подписаться
323
Подписчики

Стратегия биполярного сглаженного осциллятора Стратегия биполярного сглаженного осциллятора

Что это за план Сен-Сен?

Вы знаете? Эта стратегия как будто настраивает на рынок “чувственный детектор”! Он чувствует “радость и горесть” рынка с помощью двуполярного плавного колебателя, и посылает торговый сигнал, когда рынок слишком возбужден (перекупает) или слишком расстроен (перепродает).

Как работают масла

Представьте, что эта стратегия похожа на сверхчувствительный “торговый термометр”. Во-первых, она рассчитывает, насколько цены отклоняются от средней линии в 25 циклов, а затем проводит стандартизацию (как если бы люди с разным ростом были пересчитаны в пропорции к стандартному росту).

Это суперспособности этой стратегии.

Вот вам руководство по избежанию ям! Самая сильная часть этой стратегии - это ее механизм “облигации обратного сигнала” - как если бы вы видели красный свет и сразу остановили машину, когда вы едете!

Опасность не может быть меньше

Хотя эта стратегия хороша, она не является универсальной. На рынках с сильными тенденциями колебатели могут “потеряться”, как и использование городской навигации на шоссе.

Исходный код стратегии
/*backtest
start: 2025-01-01 00:00:00
end: 2025-10-15 08:00:00
period: 1h
basePeriod: 1h
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT","balance":500000}]
*/

//@version=6
strategy("Two-Pole Threshold Entries + Opposite-Signal & Stop Exits + Stats",
     overlay=true,
     max_labels_count=500)

// === Inputs ===
length       = input.int(20,    minval=1,    title="Filter Length")
buyTrig      = input.float(-0.8,             title="Buy Threshold (osc ↑)")
sellTrig     = input.float( 0.8,             title="Sell Threshold (osc ↓)")
stopLossPts  = input.int(10,    minval=1,    title="Stop Loss (pts)")

// === Two-Pole Oscillator ===
sma25 = ta.sma(close, 25)
dev   = (close - sma25) - ta.sma(close - sma25, 25)
norm  = dev / ta.stdev(close - sma25, 25)
alpha = 2.0 / (length + 1)

var float s1 = na
var float s2 = na
s1 := na(s1) ? norm : (1 - alpha) * s1 + alpha * norm
s2 := na(s2) ? s1   : (1 - alpha) * s2 + alpha * s1

osc     = s2
prevOsc = osc[4]

// === Trigger Cross Signals ===
isLongSig  = ta.crossover(osc, buyTrig)  and barstate.isconfirmed
isShortSig = ta.crossunder(osc, sellTrig) and barstate.isconfirmed

// === State & Stats Vars ===
var int   tradeDir    = 0      //  1=long, -1=short, 0=flat
var float entryPrice = na
var int   entryBar   = na

var int   buyTotal    = 0
var int   buyFailed   = 0
var float sumMoveB    = 0.0
var int   cntMoveB    = 0
var float sumPLptsB   = 0.0

var int   sellTotal   = 0
var int   sellFailed  = 0
var float sumMoveS    = 0.0
var int   cntMoveS    = 0
var float sumPLptsS   = 0.0

// === Exit Marker Flags ===
var bool longStopHit  = false
var bool shortStopHit = false
var bool longSigExit  = false
var bool shortSigExit = false

longStopHit  := false
shortStopHit := false
longSigExit  := false
shortSigExit := false

// === 1) Opposite-Signal Exit ===
if tradeDir == 1 and isShortSig
    float ptsL = close - entryPrice
    sumMoveB  += ptsL
    sumPLptsB += ptsL
    cntMoveB  += 1
    strategy.close("Long")
    longSigExit := true
    tradeDir    := 0

if tradeDir == -1 and isLongSig
    float ptsS = entryPrice - close
    sumMoveS  += ptsS
    sumPLptsS += ptsS
    cntMoveS  += 1
    strategy.close("Short")
    shortSigExit := true
    tradeDir     := 0

// === 2) 5-Bar, Bar-Close 10-pt Stop Exit ===
inWindow       = (tradeDir != 0) and (bar_index <= entryBar + 5)
longStopPrice  = entryPrice - stopLossPts
shortStopPrice = entryPrice + stopLossPts

if tradeDir == 1 and inWindow and close <= longStopPrice
    buyFailed   += 1
    sumPLptsB   -= stopLossPts
    strategy.close("Long")
    longStopHit := true
    tradeDir    := 0

if tradeDir == -1 and inWindow and close >= shortStopPrice
    sellFailed   += 1
    sumPLptsS    -= stopLossPts
    strategy.close("Short")
    shortStopHit := true
    tradeDir     := 0

// === 3) New Entries (only when flat) ===
if tradeDir == 0 and isLongSig
    buyTotal   += 1
    entryPrice := close
    entryBar   := bar_index
    strategy.entry("Long", strategy.long)
    tradeDir   := 1

if tradeDir == 0 and isShortSig
    sellTotal  += 1
    entryPrice := close
    entryBar   := bar_index
    strategy.entry("Short", strategy.short)
    tradeDir   := -1

// === Stats Computation ===
float avgMoveB    = cntMoveB  > 0 ? sumMoveB  / cntMoveB  : na
float successPctB = buyTotal   > 0 ? (buyTotal - buyFailed) / buyTotal  * 100 : na
float pnlUSD_B    = sumPLptsB * 50.0

float avgMoveS    = cntMoveS  > 0 ? sumMoveS  / cntMoveS  : na
float successPctS = sellTotal  > 0 ? (sellTotal - sellFailed) / sellTotal * 100 : na
float pnlUSD_S    = sumPLptsS * 50.0

string tf = timeframe.period



// === On-Chart Markers ===
plotshape(isLongSig,  title="Long Entry",      style=shape.triangleup,   location=location.belowbar, color=color.green,  size=size.tiny)
plotshape(isShortSig, title="Short Entry",     style=shape.triangledown, location=location.abovebar, color=color.red,    size=size.tiny)
plotshape(longSigExit,  title="Exit on Sell Sig", style=shape.xcross, location=location.abovebar, color=color.orange, size=size.tiny)
plotshape(shortSigExit, title="Exit on Buy Sig",  style=shape.xcross, location=location.belowbar, color=color.orange, size=size.tiny)
plotshape(longStopHit,  title="Stop Exit Long",  style=shape.xcross, location=location.abovebar, color=color.purple, size=size.tiny)
plotshape(shortStopHit, title="Stop Exit Short", style=shape.xcross, location=location.belowbar, color=color.purple, size=size.tiny)