Quantitative Handelsstrategie basierend auf dem dualen Trendfilter


Erstellungsdatum: 2023-12-26 12:18:54 zuletzt geändert: 2023-12-26 12:18:54
Kopie: 2 Klicks: 684
1
konzentrieren Sie sich auf
1623
Anhänger

Quantitative Handelsstrategie basierend auf dem dualen Trendfilter

Überblick

Es handelt sich um eine Strategie, bei der Dual-Trend-Filter zum Quantifizieren des Handels verwendet werden. Die Strategie kombiniert gleichzeitig einen globalen Trendfilter und einen lokalen Trendfilter, um sicherzustellen, dass nur Positionen in der richtigen Trendrichtung eröffnet werden. Darüber hinaus werden in der Strategie weitere Filterbedingungen wie RSI-Filter, Preisfilter, Slip-Filter usw. eingesetzt, um die Zuverlässigkeit des Handelssignals weiter zu verbessern.

Strategieprinzip

Die Kernlogik der Strategie basiert auf einem doppelten Trendfilter. Der globale Trendfilter basiert auf einer hochperiodischen EMA, um die Gesamtbewegung des Marktes zu beurteilen, und der lokale Trendfilter basiert auf einer niedrigen EMA, um die lokale Bewegung zu beurteilen.

Insbesondere berechnet die Strategie die EMA-Linie für den BTCUSDT, um zu bestimmen, ob der Gesamtmarkt im Aufwärtstrend oder im Abwärtstrend ist, was der globale Trendfilter ist. Gleichzeitig berechnet die Strategie die EMA-Linie für diesen Kontrakt, um die Entwicklung des lokalen Marktes zu bestimmen, was ein lokaler Trendfilter ist. Wenn die beiden Trends übereinstimmen, erzeugt die Strategie ein Handelssignal und setzt die Stop-Loss-Preise ein.

Nach der Feststellung des Handelssignals eröffnet die Strategie sofort die Position. Gleichzeitig setzt die Strategie den Stop-Loss-Preis und den Stop-Loss-Preis im Voraus. Wenn der Preis einen Stop-Loss auslöst, wird die Strategie automatisch gestoppt oder gestoppt.

Analyse der Stärken

Es ist eine stabile und zuverlässige Quantitative Trading-Strategie mit folgenden Vorteilen:

  1. Die doppelte Trendfiltermechanik filtert die meisten Falschsignale und macht die Handelssignale zuverlässiger und genauer.

  2. In Kombination mit mehreren Hilfsfiltern wie RSI-Filter, Preisfilter usw. wird die Signalqualität weiter verbessert.

  3. Automatische Stop-Loss-Bewertung ohne manuelle Überwachung, reduziert das Handelsrisiko.

  4. Die Strategieparameter sind anpassungsfähig für mehrere Handelsarten und haben eine starke Anpassungsfähigkeit.

  5. Die Strategie ist klar und leicht verständlich, kann optimiert und verbessert werden, und es gibt viel Spielraum für Expansion.

Risikoanalyse

Obwohl diese Strategie viele Vorteile hat, besteht ein gewisses Handelsrisiko, das sich auf folgende Bereiche konzentriert:

  1. Die Doppeltrend-Filter sind nicht exakt, wenn es darum geht, den Einstiegspunkt zu bestimmen. Sie können optimiert werden, indem Sie die Filterparameter anpassen.

  2. Die Stop-Loss-Preise sind ungenau festgelegt und können zu früh gestoppt oder gestoppt werden. Verschiedene Parameterkombinationen können getestet werden, um die optimale Lösung zu finden.

  3. Die falsche Auswahl der Handelsarten und -perioden kann zu einer Strategie-Unwirksamkeit führen. Es wird empfohlen, die Parameter für die verschiedenen Handelsarten individuell zu optimieren und zu testen.

  4. Es besteht ein gewisses Überangebotsrisiko. Es ist notwendig, Rückmeldungen in mehreren Marktumgebungen durchzuführen, um die Strategie zu stabilisieren.

Optimierungsrichtung

Die Strategie kann vor allem in folgenden Bereichen optimiert werden:

  1. Anpassung der Parameter des Doppelfilters, um die optimale Kombination zu finden.

  2. Test und Auswahl der besten Hilfsfilter;

  3. Optimierung von Stop-Loss-Algorithmen, um sie intelligenter zu machen;

  4. Das Unternehmen hat sich dazu entschlossen, die Strategie zu erweitern, indem es Methoden wie maschinelles Lernen einführt.

  5. Es wird eine größere Anzahl von Handelsarten und eine längere Periode der Rückverfolgung durchgeführt, um die Stabilität der Strategie zu verbessern.

Zusammenfassen

Die Strategie als Ganzes ist eine stabile, präzise und leicht zu optimierende quantitative Handelsstrategie. Sie verwendet einen doppelten Trendfilter in Kombination mit mehreren Hilfsfiltern, um ein Handelssignal zu erzeugen, das den größten Teil des Geräusches filtert, um das Signal präziser und zuverlässiger zu machen. Die Strategie bietet auch eine integrierte Stop-Loss-Einstellung, die das Handelsrisiko verringert.

Strategiequellcode
/*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)