この戦略は,二重トレンドフィルターを活用する定量的な取引戦略である.この戦略は,グローバルトレンドフィルターとローカルトレンドフィルタの両方を組み合わせ,トレンド方向が正しい場合にのみポジションに入ることを保証する.さらに,この戦略は,RSIフィルター,価格フィルター,傾斜フィルターなどの複数のフィルターを設定し,取引信号の信頼性をさらに向上させる.出口側では,戦略はストップ損失価格と利益価格をプリセットする.全体的に,これは安定的かつ正確な定量的な取引戦略である.
この戦略の基本論理は,二重トレンドフィルターに基づいています.グローバルトレンドフィルターは高期EMAに基づいて市場全体のトレンドを判断し,ローカルトレンドフィルターは低期EMAに基づいてローカルトレンドを判断します.両方のフィルターが同じトレンド方向を示唆した場合のみ,戦略はポジションに入ります.
戦略は,BTCUSDT
取引可能なシグナルが決定されると,戦略はすぐにポジションに入るオーダーを配置する.一方,ストップ損失価格と利益を得る価格は事前に設定されている.価格がいずれかに触れたとき,戦略は自動的にストップ損失または利益を得るポジションを退場する.
これは安定した信頼性の高い量的な取引戦略であり,以下の主な利点があります.
多重トレンドフィルタリングメカニズムを採用し,ほとんどの偽信号をフィルタリングし,取引信号をより信頼性のあるものにします.
RSIフィルターと価格フィルターのような複数の補助フィルターを組み合わせることで信号の質をさらに改善します
自動でストップ・ロストを計算し,手動監視なしで取引リスクを低減します.
調整可能な戦略パラメータにより多くの取引手段をより適性的に調整する.
明確な戦略論理は 理解しやすいし 最適化の可能性も高い
多くの利点があるにもかかわらず,主に以下のような取引リスクは依然としてある.
ダブルトレンドフィルターは,正確なエントリータイミングを決定できない場合があります.パラメータは最適化できます.
不正確なストップ・ロストとテイク・プロフィート価格設定は,早期出口につながる可能性があります.最適な値を見つけるために異なるパラメータセットをテストすることができます.
トレーディング・インスツルメントとタイムフレームの不適切な選択は,戦略を無効にすることがあります.パラメータの最適化とテストは,異なるトレーディング・インスツルメントに対して別々に提案されます.
過剰なフィットメントのリスクもあります. 安定性を確保するために,多様な市場環境でより多くのバックテストが必要です.
この戦略を最適化するための主な方向は以下の通りである.
最適な組み合わせを見つけるために 双フィルターのパラメータを調整します
最適な補助フィルターをテストして選択します
ストップ・ロスを最適化して 利潤アルゴリズムを活用して よりスマートにします
機械学習モデルを導入して 動的パラメータ調整をしてみてください
安定性を向上させるため より多くの楽器のバックテストと より長い時間帯
結論として,これは全体的に安定した,正確で簡単に最適化可能な定量的な取引戦略です. 双トレンドフィルターと複数の補助フィルターを組み合わせて取引信号を生成し,ほとんどのノイズをフィルタリングし,より信頼性の高い信号を生成します. また,内蔵ストップ損失と利益の事前設定は,取引リスクを低減するのに役立ちます. これは非常に実用的な価値を持つ戦略です. 最適化と検証の後,ライブ取引に直接適用できます. さらに,拡張の可能性が巨大で,深く調査に値します.
/*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)