Ini adalah strategi perdagangan kuantitatif yang menggunakan filter tren ganda. Strategi ini menggabungkan filter tren global dan filter tren lokal untuk memastikan masuk posisi hanya ketika arah tren benar. Selain itu, strategi menetapkan beberapa filter lain seperti filter RSI, filter harga, filter kemiringan dll untuk meningkatkan keandalan sinyal perdagangan. Di sisi keluar, strategi ini menetapkan harga stop loss dan mengambil keuntungan. Secara keseluruhan, ini adalah strategi perdagangan kuantitatif yang stabil dan tepat.
Filter tren global menilai tren pasar secara keseluruhan berdasarkan EMA periode tinggi, sementara filter tren lokal menilai tren lokal berdasarkan EMA periode rendah. Hanya ketika kedua filter menunjukkan arah tren yang sama, strategi akan memasuki posisi.
Secara khusus, strategi menghitung EMA BTCUSDT
Setelah menentukan sinyal yang dapat diperdagangkan, strategi akan segera menempatkan pesanan untuk memasuki posisi. Sementara itu, harga stop loss dan harga take profit ditetapkan sebelumnya. Ketika harga menyentuh salah satu dari mereka, strategi akan secara otomatis keluar dari posisi dengan stop loss atau take profit.
Ini adalah strategi perdagangan kuantitatif yang stabil dan dapat diandalkan dengan keuntungan utama berikut:
Mengadopsi mekanisme penyaringan tren ganda untuk menyaring sebagian besar sinyal palsu dan membuat sinyal perdagangan lebih andal.
Menggabungkan beberapa filter tambahan seperti filter RSI dan filter harga untuk meningkatkan kualitas sinyal.
Menghitung stop loss secara otomatis dan mengambil harga keuntungan untuk menurunkan risiko perdagangan tanpa pemantauan manual.
Parameter strategi yang dapat disesuaikan untuk menyesuaikan lebih banyak instrumen perdagangan dengan kemampuan beradaptasi yang lebih baik.
Logika strategi yang jelas mudah dimengerti, dan dengan potensi yang lebih besar untuk optimasi.
Meskipun dengan banyak keuntungan, masih ada beberapa risiko perdagangan terutama di:
Filter tren ganda mungkin gagal menentukan waktu masuk yang akurat. Parameter dapat dioptimalkan.
Pengaturan harga stop loss dan take profit yang tidak akurat dapat menyebabkan keluar prematur.
Pemilihan instrumen perdagangan dan kerangka waktu yang tidak tepat dapat membuat strategi tidak efektif.
Ada beberapa risiko overfit. Lebih banyak backtesting dalam lingkungan pasar yang beragam diperlukan untuk memastikan ketahanan.
Arah utama untuk mengoptimalkan strategi ini meliputi:
Sesuaikan parameter filter ganda untuk menemukan kombinasi yang optimal.
Uji dan pilih filter tambahan terbaik.
Mengoptimalkan stop loss dan mengambil keuntungan algoritma untuk membuat mereka lebih cerdas.
Cobalah memperkenalkan model pembelajaran mesin untuk pengaturan parameter dinamis.
Lebih banyak backtest pada lebih banyak instrumen dan rentang waktu yang lebih lama untuk meningkatkan stabilitas.
Sebagai kesimpulan, ini adalah strategi perdagangan kuantitatif yang secara keseluruhan stabil, akurat dan mudah dioptimalkan. Ini menghasilkan sinyal perdagangan dengan menggabungkan filter tren ganda dan beberapa filter bantu, menyaring sebagian besar kebisingan dan menghasilkan sinyal yang lebih dapat diandalkan. Juga, pengaturan awal stop loss dan take profit yang built-in membantu menurunkan risiko perdagangan. Ini adalah strategi dengan nilai praktis yang besar. Setelah dioptimalkan dan divalidasi, ini dapat langsung diterapkan untuk perdagangan langsung. Selain itu, ini memiliki potensi besar untuk ekspansi dan layak untuk penelitian mendalam.
/*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)