В процессе загрузки ресурсов... загрузка...

Количественная стратегия торговли, основанная на двойном фильтре тренда

Автор:Чао Чжан, Дата: 2023-12-26 12:18:54
Тэги:

img

Обзор

Это количественная торговая стратегия, которая использует двойные трендовые фильтры. Стратегия сочетает в себе как глобальный трендовый фильтр, так и локальный трендовый фильтр, чтобы обеспечить вход в позиции только тогда, когда направление тренда является правильным. Кроме того, стратегия устанавливает несколько других фильтров, таких как фильтр RSI, фильтр цены, фильтр наклона и т. Д., Чтобы еще больше улучшить надежность торговых сигналов.

Логика стратегии

Основная логика этой стратегии основана на двойных трендовых фильтрах. Глобальный трендовый фильтр оценивает общую рыночную тенденцию на основе высокой периодической EMA, в то время как локальный трендовый фильтр оценивает местную тенденцию на основе низкой периодической EMA. Только когда оба фильтра предполагают одно и то же направление тренда, стратегия будет вводить позиции.

В частности, стратегия рассчитывает EMA BTCUSDT для определения того, находится ли общий рынок в восходящем или нисходящем тренде. Это глобальный трендовый фильтр. В то же время стратегия рассчитывает EMA базового контракта для определения местного тренда. Это локальный трендовый фильтр. Только когда оба фильтра согласны с одним и тем же направлением тренда, в сочетании с другими вспомогательными фильтрами, стратегия будет генерировать торговые сигналы и предустановлять стоп-лосс и принимать прибыльные цены для входа в позиции.

После определения торгуемого сигнала стратегия немедленно размещает ордера на вход в позиции. Между тем, цена остановки потери и цена получения прибыли предустановлены. Когда цена касается одной из них, стратегия автоматически выходит из позиций с остановкой потери или получением прибыли.

Анализ преимуществ

Это стабильная и надежная стратегия количественной торговли со следующими основными преимуществами:

  1. Принятие механизма двойной фильтрации трендов для фильтрации большинства ложных сигналов и повышения надежности торговых сигналов.

  2. Объединение нескольких вспомогательных фильтров, таких как фильтр RSI и фильтр цены, для дальнейшего улучшения качества сигнала.

  3. Автоматическое вычисление стоп-лосса и прибыли для снижения рисков торговли без ручного мониторинга.

  4. Настраиваемые параметры стратегии для адаптации большего количества торговых инструментов с лучшей адаптивностью.

  5. Ясная логика стратегии, легкая в понимании, и с большим потенциалом для оптимизации.

Анализ рисков

Несмотря на многочисленные преимущества, все еще существуют некоторые риски торговли, главным образом в:

  1. Двойные трендовые фильтры могут не определить точное время входа.

  2. Неточное установление стоп-лосса и цены на получение прибыли может привести к преждевременному выходу.

  3. Неправильный выбор торговых инструментов и временных рамок может сделать стратегию неэффективной.

  4. Для обеспечения надежности необходимо провести больше обратных испытаний в различных рыночных условиях.

Руководство по оптимизации

К основным направлениям оптимизации этой стратегии относятся:

  1. Настраивайте параметры двойных фильтров, чтобы найти оптимальную комбинацию.

  2. Проверьте и выберите лучшие вспомогательные фильтры.

  3. Оптимизируйте стоп-лосс и алгоритмы получения прибыли, чтобы сделать их более умными.

  4. Попробуйте ввести модели машинного обучения для динамической настройки параметров.

  5. Больше обратных испытаний на большем количестве инструментов и более длительные периоды для улучшения стабильности.

Заключение

В заключение, это общая стабильная, точная и легко оптимизируемая количественная стратегия торговли. Она производит торговые сигналы путем сочетания двойных трендовых фильтров и нескольких вспомогательных фильтров, фильтруя большую часть шума и генерируя более надежные сигналы. Кроме того, встроенное предопределение стоп-лосса и прибыли помогает снизить торговые риски. Это стратегия с большой практической ценностью. После оптимизации и проверки она может быть непосредственно применена для живой торговли. Кроме того, она имеет огромный потенциал для расширения и стоит глубокого исследования.


/*backtest
start: 2023-01-01 00:00:00
end: 2023-12-25 00:00:00
period: 1h
basePeriod: 15m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/


//@version=4

strategy(title = 'Cipher_B', overlay=true )

// PARAMETERS {

// WaveTrend
wtShow = input(true, title = 'Show WaveTrend', type = input.bool)
wtBuyShow = input(true, title = 'Show Buy dots', type = input.bool)
wtGoldShow = input(true, title = 'Show Gold dots', type = input.bool)
wtSellShow = input(true, title = 'Show Sell dots', type = input.bool)
wtDivShow = input(true, title = 'Show Div. dots', type = input.bool)
vwapShow = input(true, title = 'Show Fast WT', type = input.bool)
wtChannelLen = input(9, title = 'WT Channel Length', type = input.integer)
wtAverageLen = input(12, title = 'WT Average Length', type = input.integer)
wtMASource = input(hlc3, title = 'WT MA Source', type = input.source)
wtMALen = input(3, title = 'WT MA Length', type = input.integer)

// WaveTrend Overbought & Oversold lines
obLevel = input(53, title = 'WT Overbought Level 1', type = input.integer)
obLevel2 = input(60, title = 'WT Overbought Level 2', type = input.integer)
obLevel3 = input(100, title = 'WT Overbought Level 3', type = input.integer)
osLevel = input(-53, title = 'WT Oversold Level 1', type = input.integer)
osLevel2 = input(-60, title = 'WT Oversold Level 2', type = input.integer)
osLevel3 = input(-75, title = 'WT Oversold Level 3', type = input.integer)

// Divergence WT
wtShowDiv = input(true, title = 'Show WT Regular Divergences', type = input.bool)
wtShowHiddenDiv = input(false, title = 'Show WT Hidden Divergences', type = input.bool)
showHiddenDiv_nl = input(true, title = 'Not apply OB/OS Limits on Hidden Divergences', type = input.bool)
wtDivOBLevel = input(45, title = 'WT Bearish Divergence min', type = input.integer)
wtDivOSLevel = input(-65, title = 'WT Bullish Divergence min', type = input.integer)

// Divergence extra range
wtDivOBLevel_addshow = input(false, title = 'Show 2nd WT Regular Divergences', type = input.bool)
wtDivOBLevel_add = input(15, title = 'WT 2nd Bearish Divergence', type = input.integer)
wtDivOSLevel_add = input(-40, title = 'WT 2nd Bullish Divergence 15 min', type = input.integer)

// RSI+MFI
rsiMFIShow = input(true, title = 'Show MFI', type = input.bool)
rsiMFIperiod = input(60,title = 'MFI Period', type = input.integer)
rsiMFIMultiplier = input(150, title = 'MFI Area multiplier', type = input.float)
rsiMFIPosY = input(2.5, title = 'MFI Area Y Pos', type = input.float)

// RSI
rsiShow = input(false, title = 'Show RSI', type = input.bool)
rsiSRC = input(close, title = 'RSI Source', type = input.source)
rsiLen = input(14, title = 'RSI Length', type = input.integer)
rsiOversold = input(30, title = 'RSI Oversold', minval = 50, maxval = 100, type = input.integer)
rsiOverbought = input(60, title = 'RSI Overbought', minval = 0, maxval = 50, type = input.integer)

// Divergence RSI
rsiShowDiv = input(false, title = 'Show RSI Regular Divergences', type = input.bool)
rsiShowHiddenDiv = input(false, title = 'Show RSI Hidden Divergences', type = input.bool)
rsiDivOBLevel = input(60, title = 'RSI Bearish Divergence min', type = input.integer)
rsiDivOSLevel = input(30, title = 'RSI Bullish Divergence min', type = input.integer)

// RSI Stochastic
stochShow = input(true, title = 'Show Stochastic RSI', type = input.bool)
stochUseLog = input(true, title=' Use Log?', type = input.bool)
stochAvg = input(false, title='Use Average of both K & D', type = input.bool)
stochSRC = input(close, title = 'Stochastic RSI Source', type = input.source)
stochLen = input(14, title = 'Stochastic RSI Length', type = input.integer)
stochRsiLen = input(14, title = 'RSI Length ', type = input.integer)
stochKSmooth = input(3, title = 'Stochastic RSI K Smooth', type = input.integer)
stochDSmooth = input(3, title = 'Stochastic RSI D Smooth', type = input.integer)

// Divergence stoch
stochShowDiv = input(false, title = 'Show Stoch Regular Divergences', type = input.bool)
stochShowHiddenDiv = input(false, title = 'Show Stoch Hidden Divergences', type = input.bool)

// Schaff Trend Cycle
tcLine = input(false, title="Show Schaff TC line", type=input.bool)
tcSRC = input(close, title = 'Schaff TC Source', type = input.source)
tclength = input(10, title="Schaff TC", type=input.integer)
tcfastLength = input(23, title="Schaff TC Fast Lenght", type=input.integer)
tcslowLength = input(50, title="Schaff TC Slow Length", type=input.integer)
tcfactor = input(0.5, title="Schaff TC Factor", type=input.float)

// Sommi Flag
sommiFlagShow = input(false, title = 'Show Sommi flag', type = input.bool)
sommiShowVwap = input(false, title = 'Show Sommi F. Wave', type = input.bool)
sommiVwapTF = input('720', title = 'Sommi F. Wave timeframe', type = input.string)
sommiVwapBearLevel = input(0, title = 'F. Wave Bear Level (less than)', type = input.integer)
sommiVwapBullLevel = input(0, title = 'F. Wave Bull Level (more than)', type = input.integer)
soomiFlagWTBearLevel = input(0, title = 'WT Bear Level (more than)', type = input.integer) 
soomiFlagWTBullLevel = input(0, title = 'WT Bull Level (less than)', type = input.integer) 
soomiRSIMFIBearLevel = input(0, title = 'Money flow Bear Level (less than)', type = input.integer) 
soomiRSIMFIBullLevel = input(0, title = 'Money flow Bull Level (more than)', type = input.integer) 

// Sommi Diamond
sommiDiamondShow = input(false, title = 'Show Sommi diamond', type = input.bool)
sommiHTCRes = input('60', title = 'HTF Candle Res. 1', type = input.string)
sommiHTCRes2 = input('240', title = 'HTF Candle Res. 2', type = input.string)
soomiDiamondWTBearLevel = input(0, title = 'WT Bear Level (More than)', type = input.integer)
soomiDiamondWTBullLevel = input(0, title = 'WT Bull Level (Less than)', type = input.integer)

// macd Colors
macdWTColorsShow = input(false, title = 'Show MACD Colors', type = input.bool)
macdWTColorsTF = input('240', title = 'MACD Colors MACD TF', type = input.string)

darkMode = input(false, title = 'Dark mode', type = input.bool)


// Colors
colorRed = #ff0000
colorPurple = #e600e6
colorGreen = #3fff00
colorOrange = #e2a400
colorYellow = #ffe500
colorWhite = #ffffff
colorPink = #ff00f0
colorBluelight = #31c0ff

colorWT1 = #90caf9
colorWT2 = #0d47a1

colorWT2_ = #131722

colormacdWT1a = #4caf58
colormacdWT1b = #af4c4c
colormacdWT1c = #7ee57e
colormacdWT1d = #ff3535

colormacdWT2a = #305630
colormacdWT2b = #310101
colormacdWT2c = #132213
colormacdWT2d = #770000

// } PARAMETERS


// FUNCTIONS {
  
// Divergences 
f_top_fractal(src) => src[4] < src[2] and src[3] < src[2] and src[2] > src[1] and src[2] > src[0]
f_bot_fractal(src) => src[4] > src[2] and src[3] > src[2] and src[2] < src[1] and src[2] < src[0]
f_fractalize(src) => f_top_fractal(src) ? 1 : f_bot_fractal(src) ? -1 : 0

f_findDivs(src, topLimit, botLimit, useLimits) =>
    fractalTop = f_fractalize(src) > 0 and (useLimits ? src[2] >= topLimit : true) ? src[2] : na
    fractalBot = f_fractalize(src) < 0 and (useLimits ? src[2] <= botLimit : true) ? src[2] : na
    highPrev = valuewhen(fractalTop, src[2], 0)[2]
    highPrice = valuewhen(fractalTop, high[2], 0)[2]
    lowPrev = valuewhen(fractalBot, src[2], 0)[2]
    lowPrice = valuewhen(fractalBot, low[2], 0)[2]
    bearSignal = fractalTop and high[2] > highPrice and src[2] < highPrev
    bullSignal = fractalBot and low[2] < lowPrice and src[2] > lowPrev
    bearDivHidden = fractalTop and high[2] < highPrice and src[2] > highPrev
    bullDivHidden = fractalBot and low[2] > lowPrice and src[2] < lowPrev
    [fractalTop, fractalBot, lowPrev, bearSignal, bullSignal, bearDivHidden, bullDivHidden]
        
// RSI+MFI
f_rsimfi(_period, _multiplier, _tf) => security(syminfo.tickerid, _tf, sma(((close - open) / (high - low)) * _multiplier, _period) - rsiMFIPosY)
   
// WaveTrend
f_wavetrend(src, chlen, avg, malen, tf) =>
    tfsrc = security(syminfo.tickerid, tf, src)
    esa = ema(tfsrc, chlen)
    de = ema(abs(tfsrc - esa), chlen)
    ci = (tfsrc - esa) / (0.015 * de)
    wt1 = security(syminfo.tickerid, tf, ema(ci, avg))
    wt2 = security(syminfo.tickerid, tf, sma(wt1, malen))
    wtVwap = wt1 - wt2
    wtOversold = wt2 <= osLevel
    wtOverbought = wt2 >= obLevel
    wtCross = cross(wt1, wt2)
    wtCrossUp = wt2 - wt1 <= 0
    wtCrossDown = wt2 - wt1 >= 0
    wtCrosslast = cross(wt1[2], wt2[2])
    wtCrossUplast = wt2[2] - wt1[2] <= 0
    wtCrossDownlast = wt2[2] - wt1[2] >= 0
    [wt1, wt2, wtOversold, wtOverbought, wtCross, wtCrossUp, wtCrossDown, wtCrosslast, wtCrossUplast, wtCrossDownlast, wtVwap]

// Schaff Trend Cycle
f_tc(src, length, fastLength, slowLength) =>
    ema1 = ema(src, fastLength)
    ema2 = ema(src, slowLength)
    macdVal = ema1 - ema2	
    alpha = lowest(macdVal, length)
    beta = highest(macdVal, length) - alpha
    gamma = (macdVal - alpha) / beta * 100
    gamma := beta > 0 ? gamma : nz(gamma[1])
    delta = gamma
    delta := na(delta[1]) ? delta : delta[1] + tcfactor * (gamma - delta[1])
    epsilon = lowest(delta, length)
    zeta = highest(delta, length) - epsilon
    eta = (delta - epsilon) / zeta * 100
    eta := zeta > 0 ? eta : nz(eta[1])
    stcReturn = eta
    stcReturn := na(stcReturn[1]) ? stcReturn : stcReturn[1] + tcfactor * (eta - stcReturn[1])
    stcReturn

// Stochastic RSI
f_stochrsi(_src, _stochlen, _rsilen, _smoothk, _smoothd, _log, _avg) =>
    src = _log ? log(_src) : _src
    rsi = rsi(src, _rsilen)
    kk = sma(stoch(rsi, rsi, rsi, _stochlen), _smoothk)
    d1 = sma(kk, _smoothd)
    avg_1 = avg(kk, d1)
    k = _avg ? avg_1 : kk
    [k, d1]

// MACD
f_macd(src, fastlen, slowlen, sigsmooth, tf) =>
    fast_ma = security(syminfo.tickerid, tf, ema(src, fastlen))
    slow_ma = security(syminfo.tickerid, tf, ema(src, slowlen))
    macd = fast_ma - slow_ma,
    signal = security(syminfo.tickerid, tf, sma(macd, sigsmooth))
    hist = macd - signal
    [macd, signal, hist]
// MACD Colors on WT    
f_macdWTColors(tf) =>
    hrsimfi = f_rsimfi(rsiMFIperiod, rsiMFIMultiplier, tf)
    [macd, signal, hist] = f_macd(close, 28, 42, 9, macdWTColorsTF)
    macdup = macd >= signal
    macddown = macd <= signal
    macdWT1Color = macdup ? hrsimfi > 0 ? colormacdWT1c : colormacdWT1a : macddown ? hrsimfi < 0 ? colormacdWT1d : colormacdWT1b : na
    macdWT2Color = macdup ? hrsimfi < 0 ? colormacdWT2c : colormacdWT2a : macddown ? hrsimfi < 0 ? colormacdWT2d : colormacdWT2b : na 
    [macdWT1Color, macdWT2Color]
    
// Get higher timeframe candle
f_getTFCandle(_tf) => 
    _open  = security(heikinashi(syminfo.tickerid), _tf, open, barmerge.gaps_off, barmerge.lookahead_off)
    _close = security(heikinashi(syminfo.tickerid), _tf, close, barmerge.gaps_off, barmerge.lookahead_off)
    _high  = security(heikinashi(syminfo.tickerid), _tf, high, barmerge.gaps_off, barmerge.lookahead_off)
    _low   = security(heikinashi(syminfo.tickerid), _tf, low, barmerge.gaps_off, barmerge.lookahead_off)
    hl2   = (_high + _low) / 2.0
    newBar = change(_open)
    candleBodyDir = _close > _open
    [candleBodyDir, newBar]

// Sommi flag
f_findSommiFlag(tf, wt1, wt2, rsimfi, wtCross, wtCrossUp, wtCrossDown) =>    
    [hwt1, hwt2, hwtOversold, hwtOverbought, hwtCross, hwtCrossUp, hwtCrossDown, hwtCrosslast, hwtCrossUplast, hwtCrossDownlast, hwtVwap] = f_wavetrend(wtMASource, wtChannelLen, wtAverageLen, wtMALen, tf)      
    
    bearPattern = rsimfi < soomiRSIMFIBearLevel and
                   wt2 > soomiFlagWTBearLevel and 
                   wtCross and 
                   wtCrossDown and 
                   hwtVwap < sommiVwapBearLevel
                   
    bullPattern = rsimfi > soomiRSIMFIBullLevel and 
                   wt2 < soomiFlagWTBullLevel and 
                   wtCross and 
                   wtCrossUp and 
                   hwtVwap > sommiVwapBullLevel
    
    [bearPattern, bullPattern, hwtVwap]
    
f_findSommiDiamond(tf, tf2, wt1, wt2, wtCross, wtCrossUp, wtCrossDown) =>
    [candleBodyDir, newBar] = f_getTFCandle(tf)
    [candleBodyDir2, newBar2] = f_getTFCandle(tf2)
    bearPattern = wt2 >= soomiDiamondWTBearLevel and
                   wtCross and
                   wtCrossDown and
                   not candleBodyDir and
                   not candleBodyDir2                   
    bullPattern = wt2 <= soomiDiamondWTBullLevel and
                   wtCross and
                   wtCrossUp and
                   candleBodyDir and
                   candleBodyDir2 
    [bearPattern, bullPattern]
 
// } FUNCTIONS  

// CALCULATE INDICATORS {

// RSI
rsi = rsi(rsiSRC, rsiLen)
rsiColor = rsi <= rsiOversold ? colorGreen : rsi >= rsiOverbought ? colorRed : colorPurple

// RSI + MFI Area
rsiMFI = f_rsimfi(rsiMFIperiod, rsiMFIMultiplier, timeframe.period)
rsiMFIColor = rsiMFI > 0 ? #3ee145 : #ff3d2e

// Calculates WaveTrend
[wt1, wt2, wtOversold, wtOverbought, wtCross, wtCrossUp, wtCrossDown, wtCross_last, wtCrossUp_last, wtCrossDown_last, wtVwap] = f_wavetrend(wtMASource, wtChannelLen, wtAverageLen, wtMALen, timeframe.period)
 
// Stochastic RSI
[stochK, stochD] = f_stochrsi(stochSRC, stochLen, stochRsiLen, stochKSmooth, stochDSmooth, stochUseLog, stochAvg)

// Schaff Trend Cycle
tcVal = f_tc(tcSRC, tclength, tcfastLength, tcslowLength)

// Sommi flag
[sommiBearish, sommiBullish, hvwap] = f_findSommiFlag(sommiVwapTF, wt1, wt2, rsiMFI, wtCross,  wtCrossUp, wtCrossDown)

//Sommi diamond
[sommiBearishDiamond, sommiBullishDiamond] = f_findSommiDiamond(sommiHTCRes, sommiHTCRes2, wt1, wt2, wtCross, wtCrossUp, wtCrossDown)

// macd colors
[macdWT1Color, macdWT2Color] = f_macdWTColors(macdWTColorsTF)

// WT Divergences
[wtFractalTop, wtFractalBot, wtLow_prev, wtBearDiv, wtBullDiv, wtBearDivHidden, wtBullDivHidden] = f_findDivs(wt2, wtDivOBLevel, wtDivOSLevel, true)
    
[wtFractalTop_add, wtFractalBot_add, wtLow_prev_add, wtBearDiv_add, wtBullDiv_add, wtBearDivHidden_add, wtBullDivHidden_add] =  f_findDivs(wt2, wtDivOBLevel_add, wtDivOSLevel_add, true)
[wtFractalTop_nl, wtFractalBot_nl, wtLow_prev_nl, wtBearDiv_nl, wtBullDiv_nl, wtBearDivHidden_nl, wtBullDivHidden_nl] =  f_findDivs(wt2, 0, 0, false)

wtBearDivHidden_ = showHiddenDiv_nl ? wtBearDivHidden_nl : wtBearDivHidden
wtBullDivHidden_ = showHiddenDiv_nl ? wtBullDivHidden_nl : wtBullDivHidden

wtBearDivColor = (wtShowDiv and wtBearDiv) or (wtShowHiddenDiv and wtBearDivHidden_) ? colorRed : na
wtBullDivColor = (wtShowDiv and wtBullDiv) or (wtShowHiddenDiv and wtBullDivHidden_) ? colorGreen : na

wtBearDivColor_add = (wtShowDiv and (wtDivOBLevel_addshow and wtBearDiv_add)) or (wtShowHiddenDiv and (wtDivOBLevel_addshow and wtBearDivHidden_add)) ? #9a0202 : na
wtBullDivColor_add = (wtShowDiv and (wtDivOBLevel_addshow and wtBullDiv_add)) or (wtShowHiddenDiv and (wtDivOBLevel_addshow and wtBullDivHidden_add)) ? #1b5e20 : na

// RSI Divergences
[rsiFractalTop, rsiFractalBot, rsiLow_prev, rsiBearDiv, rsiBullDiv, rsiBearDivHidden, rsiBullDivHidden] = f_findDivs(rsi, rsiDivOBLevel, rsiDivOSLevel, true)
[rsiFractalTop_nl, rsiFractalBot_nl, rsiLow_prev_nl, rsiBearDiv_nl, rsiBullDiv_nl, rsiBearDivHidden_nl, rsiBullDivHidden_nl] = f_findDivs(rsi, 0, 0, false)

rsiBearDivHidden_ = showHiddenDiv_nl ? rsiBearDivHidden_nl : rsiBearDivHidden
rsiBullDivHidden_ = showHiddenDiv_nl ? rsiBullDivHidden_nl : rsiBullDivHidden

rsiBearDivColor = (rsiShowDiv and rsiBearDiv) or (rsiShowHiddenDiv and rsiBearDivHidden_) ? colorRed : na
rsiBullDivColor = (rsiShowDiv and rsiBullDiv) or (rsiShowHiddenDiv and rsiBullDivHidden_) ? colorGreen : na
 
// Stoch Divergences
[stochFractalTop, stochFractalBot, stochLow_prev, stochBearDiv, stochBullDiv, stochBearDivHidden, stochBullDivHidden] = f_findDivs(stochK, 0, 0, false)

stochBearDivColor = (stochShowDiv and stochBearDiv) or (stochShowHiddenDiv and stochBearDivHidden) ? colorRed : na
stochBullDivColor = (stochShowDiv and stochBullDiv) or (stochShowHiddenDiv and stochBullDivHidden) ? colorGreen : na


// Small Circles WT Cross
signalColor = wt2 - wt1 > 0 ? color.red : color.lime

// Buy signal.
buySignal = wtCross and wtCrossUp and wtOversold

buySignalDiv = (wtShowDiv and wtBullDiv) or 
               (wtShowDiv and wtBullDiv_add) or 
               (stochShowDiv and stochBullDiv) or 
               (rsiShowDiv and rsiBullDiv)
    
buySignalDiv_color = wtBullDiv ? colorGreen : 
                     wtBullDiv_add ? color.new(colorGreen, 60) : 
                     rsiShowDiv ? colorGreen : na

// Sell signal
sellSignal = wtCross and wtCrossDown and wtOverbought
             
sellSignalDiv = (wtShowDiv and wtBearDiv) or 
               (wtShowDiv and wtBearDiv_add) or
               (stochShowDiv and stochBearDiv) or
               (rsiShowDiv and rsiBearDiv)
                    
sellSignalDiv_color = wtBearDiv ? colorRed : 
                     wtBearDiv_add ? color.new(colorRed, 60) : 
                     rsiBearDiv ? colorRed : na

// Gold Buy 
lastRsi = valuewhen(wtFractalBot, rsi[2], 0)[2]
wtGoldBuy = ((wtShowDiv and wtBullDiv) or (rsiShowDiv and rsiBullDiv)) and
           wtLow_prev <= osLevel3 and
           wt2 > osLevel3 and
           wtLow_prev - wt2 <= -5 and
           lastRsi < 30           
          
// } CALCULATE INDICATORS


// DRAW {
bgcolor(darkMode ? color.new(#000000, 80) : na)
zLine = plot(0, color = color.new(colorWhite, 50))

//  MFI BAR 
rsiMfiBarTopLine = plot(rsiMFIShow ? -95 : na, title = 'MFI Bar TOP Line', transp = 100)
rsiMfiBarBottomLine = plot(rsiMFIShow ? -99 : na, title = 'MFI Bar BOTTOM Line', transp = 100)
fill(rsiMfiBarTopLine, rsiMfiBarBottomLine, title = 'MFI Bar Colors', color = rsiMFIColor, transp = 75)

Global=input(title="Use Global trend?", defval=true, type=input.bool,  group="Trend Settings")
regimeFilter_frame=input(title="Global trend timeframe", defval="5", options=['D','60','5'],  group="Trend Settings")
regimeFilter_length=input(title="Global trend length", defval=1700, type=input.integer,  group="Trend Settings")
localFilter_length=input(title="Local trend filter length", defval=20, type=input.integer,  group="Trend Settings")
localFilter_frame=input(title="Local trend filter timeframe", defval="60", options=['D','60', '5'],  group="Trend Settings")

Div_1=input(title="Only divergencies for long", defval=true, type=input.bool,  group="Trend Settings")
Div_2=input(title="Only divergencies for short", defval=true, type=input.bool,  group="Trend Settings")

sommi_diamond_on=input(title="Sommi diamond alerts", defval=false, type=input.bool,  group="Trend Settings")

Cancel_all=input(title="Cancel all positions if price crosses local sma? (yellow line)", defval=false, type=input.bool,  group="Trend Settings")

a_1=input(title="TP long", defval=0.95,step=0.5, type=input.float,  group="TP/SL Settings")

a_1_div=input(title="TP long div", defval=0.95,step=0.5, type=input.float,  group="TP/SL Settings")

a_2=input(title="TP short", defval=0.95,step=1, type=input.float,  group="TP/SL Settings")

b_1=input(title="SL long", defval=5,step=0.1, type=input.float,  group="TP/SL Settings")
b_2=input(title="SL short", defval=5,step=0.1, type=input.float,  group="TP/SL Settings")

RSI_filter_checkbox = input(title="RSI filter ON", defval=false, type=input.bool,  group="Trend Settings")
Price_filter_checkbox=input(title="Price filter ON", defval=false, type=input.bool,  group="Trend Settings")
Price_filter_1_long=input(title="Long Price filter from", defval=1000, type=input.integer,  group="Trend Settings")
Price_filter_2_long=input(title="Long Price filter to", defval=1200, type=input.integer,  group="Trend Settings")

Price_filter_1_short=input(title="Short Price filter from", defval=1000, type=input.integer,  group="Trend Settings")
Price_filter_2_short=input(title="Short Price filter to", defval=1200, type=input.integer,  group="Trend Settings")

Local_filter_checkbox=input(title="Use Local trend?", defval=true, type=input.bool,  group="Trend Settings")

slope_checkbox = input(title="Use Slope filter?", defval=false, type=input.bool,  group="Slope Settings")
slope_number_long = input(title="Slope number long", defval=-0.3,step=0.01, type=input.float,  group="Slope Settings")
slope_number_short = input(title="Slope number short", defval=0.16,step=0.01, type=input.float,  group="Slope Settings")
slope_period = input(title="Slope period", defval=300, type=input.integer,  group="Slope Settings")

long_on = input(title="Only long?", defval=true, type=input.bool,  group="Position Settings")
short_on = input(title="Only short?", defval=true, type=input.bool,  group="Position Settings")

volume_ETH_spot_checkbox = input(title="Volume filter?", defval=false, type=input.bool,  group="Volume Settings")
volume_ETH_spot_number_more = input(title="Volume no more than:", defval=3700, type=input.integer,  group="Volume Settings")
volume_ETH_spot_number_less = input(title="Volume no less than:", defval=600, type=input.integer,  group="Volume Settings")

limit_checkbox = input(title="Shift open position?", defval=false, type=input.bool,  group="Shift Settings")
limit_shift = input(title="How many % to shift?", defval=0.5,step=0.01, type=input.float,  group="Shift Settings")

cancel_in =  input(title="Cancel position in #bars?", defval=false, type=input.bool,  group="Cancel Settings")
cancel_in_num =  input(title="Number of bars", defval=96, type=input.integer,  group="Cancel Settings")
//Name of ticker
_str=tostring(syminfo.ticker)
_chars = str.split(_str, "")
int _len = array.size(_chars)
int _beg = max(0, _len - 4)
string[] _substr = array.new_string(0)
if _beg < _len
    _substr := array.slice(_chars, 0, _beg)
string _return = array.join(_substr, "")

//Hour sma
basis = security(syminfo.tickerid, localFilter_frame, ema(close, localFilter_length))
plot(basis, title="Local trend curve", color=color.yellow, style=plot.style_linebr)

//Trend calculation with EMA
f_sec(_market, _res, _exp) => security(_market, _res, _exp[barstate.isconfirmed ? 0 : 1])
ema = sma(close, regimeFilter_length) 
emaValue = f_sec("BTC_USDT:swap", regimeFilter_frame, ema)
marketPrice = f_sec("BTC_USDT:swap", regimeFilter_frame, close)
regimeFilter = Global?(marketPrice > emaValue or marketPrice[1] > emaValue[1]):true
reverse_regime=Global?(marketPrice < emaValue or marketPrice[1] < emaValue[1]):true
bgcolor(Global?regimeFilter ? color.green : color.red:color.yellow)

//Local trend
regimeFilter_local = Local_filter_checkbox ? close > basis: true //or close[1] > basis[1]
reverse_regime_local = Local_filter_checkbox ? close < basis: true //or close[1] < basis[1]

//RSI filter
up = rma(max(change(close), 0), 14)
down = rma(-min(change(close), 0), 14)
rsi_ = down == 0 ? 100 : up == 0 ? 0 : 100 - (100 / (1 + up / down))
rsiMA = ema(rsi_,12)

//local incline

sma =security(syminfo.tickerid, '60', ema(close, 15))
slope = (sma - sma[slope_period]) / slope_period
slope_filter_long = slope_checkbox? slope > slope_number_long : true
slope_filter_short = slope_checkbox? slope < slope_number_short : true


var long_check = true
var short_check = true
if RSI_filter_checkbox
    long_check:= rsiMA<40
    short_check:= rsiMA>60
//
validlow  =  Div_1 ? buySignalDiv or wtGoldBuy  :  buySignal or buySignalDiv or wtGoldBuy 
validhigh =   Div_2 ? sellSignalDiv  :  sellSignal or sellSignalDiv

//check volume of ETHUSDT
volume_ETH_spot = volume
volume_ETH_spot_filter = volume_ETH_spot_checkbox? volume_ETH_spot < volume_ETH_spot_number_more and volume_ETH_spot > volume_ETH_spot_number_less : true

// Check if we have confirmation for our setup
var Price_long = true
if Price_filter_checkbox
    Price_long:=close>Price_filter_1_long and close<Price_filter_2_long

var Price_short = true
if Price_filter_checkbox
    Price_short:=close>Price_filter_1_short and close<Price_filter_2_short


validlong = sommi_diamond_on  ? sommiBullishDiamond and strategy.position_size == 0 and barstate.isconfirmed and regimeFilter_local and regimeFilter  :  validlow and strategy.position_size == 0 and barstate.isconfirmed and regimeFilter_local and Price_long and long_check and slope_filter_long and volume_ETH_spot_filter
validshort = sommi_diamond_on ? sommiBearishDiamond and strategy.position_size == 0 and barstate.isconfirmed and reverse_regime_local and reverse_regime  :  validhigh and strategy.position_size == 0 and barstate.isconfirmed and reverse_regime_local and Price_short and short_check and slope_filter_short and volume_ETH_spot_filter


// Save trade stop & target & position size if a valid setup is detected
var tradeStopPrice = 0.0
var tradeTargetPrice = 0.0
var TP=0.0
var limit_price=0.0
//Detect valid long setups & trigger alert
if validlong 
    if buySignalDiv or wtGoldBuy
        limit_price:=limit_checkbox? close*(1-limit_shift*0.01) : close
        tradeStopPrice :=  limit_price*(1-b_1*0.01)
        tradeTargetPrice := limit_price*(1+a_1_div*0.01)
        TP:= a_1_div
    
    else
        limit_price:=limit_checkbox? close*(1-limit_shift*0.01) : close
        tradeStopPrice :=  limit_price*(1-b_1*0.01)
        tradeTargetPrice := limit_price*(1+a_1*0.01)
        TP:= a_1

// if validlong 
//     if buySignalDiv or wtGoldBuy
//         limit_price:=close 
//         tradeStopPrice :=  limit_price*(1-b_1*0.01)
//         tradeTargetPrice := limit_price*(1+a_1_div*0.01)
//         TP:= a_1_div
    
//     else
//         limit_price:=close
//         tradeStopPrice :=  limit_price*(1-b_1*0.01)
//         tradeTargetPrice := limit_price*(1+a_1*0.01)
//         TP:= a_1
// Detect valid short setups & trigger alert
if validshort 
    limit_price:=limit_checkbox? close*(1+limit_shift*0.01) : close
    tradeStopPrice :=  limit_price*(1+b_2*0.01)
    tradeTargetPrice  := limit_price*(1-a_2*0.01)
    TP:= a_2

// if validshort 
//     limit_price:= close
//     tradeStopPrice :=  limit_price*(1+b_2*0.01)
//     tradeTargetPrice  := limit_price*(1-a_2*0.01)
//     TP:= a_2

if cancel_in and barssince(validlong) == cancel_in_num or barssince(validshort) == cancel_in_num
    strategy.cancel_all()
if long_on 
    strategy.entry (id="Long", long=strategy.long, limit=limit_price, when=validlong, comment='{\n'    + '  "name": "",\n'    + '  "secret": "",\n'    + '  "side": "buy",\n'    + '  "symbol": '+'"'+_return+'"'+',\n'    + '  "positionSide": "long"\n'    + '}')
if short_on
    strategy.entry (id="Short", long=strategy.short, limit=limit_price, when=validshort,comment='{\n'    + '  "name": "",\n'    + '  "secret": "",\n'    + '  "side": "sell",\n'    + '  "symbol": '+'"'+_return+'"'+',\n'    + '  "positionSide": "short",\n'    + '  "sl": {\n'    + '    "enabled": true\n'    + '  }\n'    + '}')
//    condition:=true
// if Cancel_all and strategy.position_size > 0 and (reverse_regime_local or reverse_regime)
//     strategy.close_all(when=strategy.position_size != 0, comment='{\n'     + '  "name": "",\n'     + '  "secret": "",\n'     + '  "side": "sell",\n'     + '  "symbol": '+'"'+_return+'"'+',\n'     + '  "positionSide": "flat"\n'     + '}')




if Cancel_all and strategy.position_size > 0 and reverse_regime_local
    strategy.close_all(when=strategy.position_size != 0, comment='{\n'
     + '  "name": "",\n'
     + '  "secret": "",\n'
     + '  "side": "sell",\n'
     + '  "symbol": '+'"'+_return+'"'+',\n'
     + '  "positionSide": "flat"\n'
     + '}')

if Cancel_all and strategy.position_size < 0 and regimeFilter_local
    strategy.close_all(when=strategy.position_size != 0, comment='{\n'
     + '  "name": "",\n'
     + '  "secret": "",\n'
     + '  "side": "buy",\n'
     + '  "symbol": '+'"'+_return+'"'+',\n'
     + '  "positionSide": "flat"\n'
     + '}')
     
if cancel_in and strategy.position_size > 0 and barssince(validlong) > cancel_in_num
    strategy.close_all(when=strategy.position_size != 0, comment='{\n'
     + '  "name": "",\n'
     + '  "secret": "",\n'
     + '  "side": "sell",\n'
     + '  "symbol": '+'"'+_return+'"'+',\n'
     + '  "positionSide": "flat"\n'
     + '}')

if cancel_in and strategy.position_size < 0 and barssince(validshort) > cancel_in_num
    strategy.close_all(when=strategy.position_size != 0, comment='{\n'
     + '  "name": "",\n'
     + '  "secret": "",\n'
     + '  "side": "buy",\n'
     + '  "symbol": '+'"'+_return+'"'+',\n'
     + '  "positionSide": "flat"\n'
     + '}')

// Exit trades whenever our stop or target is hit
strategy.exit(id="Long Exit", from_entry="Long", limit=tradeTargetPrice, stop=tradeStopPrice, when=strategy.position_size > 0)
strategy.exit(id="Short Exit", from_entry="Short", limit=tradeTargetPrice,stop=tradeStopPrice, when=strategy.position_size < 0)

Больше