// This Pine Script® code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/ // © gilanns //@version=6 strategy('BTCUSDTPERP BOT', overlay = true, pyramiding = 1, initial_capital = 10000, default_qty_type = strategy.percent_of_equity, default_qty_value = 100, calc_on_order_fills = false, slippage = 0, commission_type = strategy.commission.percent, commission_value = 0) //SOURCE ================================================================================================================================================================================================================================================================== src = input(ohlc4) // INPUTS ================================================================================================================================================================================================================================================================== //ADX ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Act_ADX = input(true, title = 'AVERAGE DIRECTIONAL INDEX') ADX_options = input.string('MASANAKAMURA', title = 'ADX OPTION', options = ['CLASSIC', 'MASANAKAMURA']) ADX_len = input.int(11, title = 'ADX LENGTH', minval = 1) th = input.float(12, title = 'ADX THRESHOLD', minval = 0, step = 0.5) //Range Filter---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- length0 = input(13, title = 'Range Filter lenght') mult = input(1, title = 'Range Filter mult') //SAR------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- start = input.float(title = 'SAR Start', step = 0.001, defval = 0) increment = input.float(title = 'SAR Increment', step = 0.001, defval = 0.006) maximum = input.float(title = 'SAR Maximum', step = 0.01, defval = 1) width = input.int(title = 'SAR Point Width', minval = 1, defval = 1) //RSI--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- len_3 = input.int(70, minval = 1, title = 'RSI lenght') src_3 = input(close, 'RSI Source') //TWAP Trend -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- smoothing = input(title = 'TWAP Smoothing', defval = 10) resolution = input('0', 'TWAP Timeframe') //JMA------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ inp = input(title = 'JMA Source', defval = close) reso = input.timeframe(title = 'JMA Resolution', defval = '') rep = input(title = 'JMA Allow Repainting?', defval = false) src0 = request.security(syminfo.tickerid, reso, inp[rep ? 0 : barstate.isrealtime ? 1 : 0])[rep ? 0 : barstate.isrealtime ? 0 : 1] lengths = input.int(title = 'JMA Length', defval = 4, minval = 1) //MACD------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ fast_length = input(title = 'MACD Fast Length', defval = 25) slow_length = input(title = 'MACD Slow Length', defval = 50) signal_length = input.int(title = 'MACD Signal Smoothing', minval = 1, maxval = 50, defval = 9) //Volume Delta ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- periodMa = input.int(title = 'Delta Length', minval = 1, defval = 45) //Volume weight------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ maLength = input.int(title = 'Volume Weight Length', defval = 100, minval = 1) maType = input.string(title = 'Volume Weight Type', defval = 'SMA', options = ['EMA', 'SMA', 'HMA', 'WMA', 'DEMA']) rvolTrigger = input.float(title = 'Volume To Trigger Signal', defval = 1.5, step = 0.1, minval = 0.1) //MA---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- length = input.int(51, minval = 1, title = 'MA Length') matype = input.int(5, minval = 1, maxval = 5, title = 'AvgType') //Momentum------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ tmolength = input(45, title = 'Momentum Length') calcLength = input(12, title = 'Momentum Calc length') smoothLength = input(9, title = 'Momentum Smooth length') //INDICATORS ============================================================================================================================================================================================================================================================== //ADX---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- calcADX(_len) => up = ta.change(high) down = -ta.change(low) plusDM = na(up) ? na : up > down and up > 0 ? up : 0 minusDM = na(down) ? na : down > up and down > 0 ? down : 0 truerange = ta.rma(ta.tr, _len) _plus = fixnan(100 * ta.rma(plusDM, _len) / truerange) _minus = fixnan(100 * ta.rma(minusDM, _len) / truerange) sum = _plus + _minus _adx = 100 * ta.rma(math.abs(_plus - _minus) / (sum == 0 ? 1 : sum), _len) [_plus, _minus, _adx] calcADX_Masanakamura(_len) => SmoothedTrueRange = 0.0 SmoothedDirectionalMovementPlus = 0.0 SmoothedDirectionalMovementMinus = 0.0 TrueRange = math.max(math.max(high - low, math.abs(high - nz(close[1]))), math.abs(low - nz(close[1]))) DirectionalMovementPlus = high - nz(high[1]) > nz(low[1]) - low ? math.max(high - nz(high[1]), 0) : 0 DirectionalMovementMinus = nz(low[1]) - low > high - nz(high[1]) ? math.max(nz(low[1]) - low, 0) : 0 SmoothedTrueRange := nz(SmoothedTrueRange[1]) - nz(SmoothedTrueRange[1]) / _len + TrueRange SmoothedDirectionalMovementPlus := nz(SmoothedDirectionalMovementPlus[1]) - nz(SmoothedDirectionalMovementPlus[1]) / _len + DirectionalMovementPlus SmoothedDirectionalMovementMinus := nz(SmoothedDirectionalMovementMinus[1]) - nz(SmoothedDirectionalMovementMinus[1]) / _len + DirectionalMovementMinus DIP = SmoothedDirectionalMovementPlus / SmoothedTrueRange * 100 DIM = SmoothedDirectionalMovementMinus / SmoothedTrueRange * 100 DX = math.abs(DIP - DIM) / (DIP + DIM) * 100 adx = ta.sma(DX, _len) [DIP, DIM, adx] [DIPlusC, DIMinusC, ADXC] = calcADX(ADX_len) [DIPlusM, DIMinusM, ADXM] = calcADX_Masanakamura(ADX_len) DIPlus = ADX_options == 'CLASSIC' ? DIPlusC : DIPlusM DIMinus = ADX_options == 'CLASSIC' ? DIMinusC : DIMinusM ADX = ADX_options == 'CLASSIC' ? ADXC : ADXM ADX_color = DIPlus > DIMinus and ADX > th ? color.green : DIPlus < DIMinus and ADX > th ? color.red : color.orange barcolor(color = Act_ADX ? ADX_color : na, title = 'ADX') //Range Filter--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- out = 0. cma = 0. cts = 0. Var = ta.variance(src, length0) * mult sma = ta.sma(src, length0) secma = math.pow(nz(sma - cma[1]), 2) sects = math.pow(nz(src - cts[1]), 2) ka = Var < secma ? 1 - Var / secma : 0 kb = Var < sects ? 1 - Var / sects : 0 cma := ka * sma + (1 - ka) * nz(cma[1], src) cts := kb * src + (1 - kb) * nz(cts[1], src) css = cts > cma ? color.green : color.red a = plot(cts, 'CTS', color.new(color.red, 0), 2) b = plot(cma, 'CMA', color.new(color.green, 0), 2) fill(a, b, color = css) rangegood = cts > cma rangebad = cts < cma //SAR------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- psar = ta.sar(start, increment, maximum) dir = psar < close ? 1 : -1 psarColor = dir == 1 ? color.green : color.red psarPlot = plot(psar, title = 'PSAR', style = plot.style_circles, linewidth = math.max(1, width), color = psarColor) var color longColor = color.green var color shortColor = color.red sargood = dir == 1 sarbad = dir == -1 //RSI--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- up_3 = ta.rma(math.max(ta.change(src_3), 0), len_3) down_3 = ta.rma(-math.min(ta.change(src_3), 0), len_3) rsi_3 = down_3 == 0 ? 100 : up_3 == 0 ? 0 : 100 - 100 / (1 + up_3 / down_3) rsiob = rsi_3 < 70 rsios = rsi_3 > 30 //TWAP Trend -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- res = resolution != '0' ? resolution : timeframe.period weight = ta.barssince(bool(ta.change(request.security(syminfo.tickerid, res, time, lookahead = barmerge.lookahead_on)))) price = 0. price := weight == 0 ? src : src + nz(price[1]) twap = price / (weight + 1) ma_ = smoothing < 2 ? twap : ta.sma(twap, smoothing) bullish = smoothing < 2 ? src >= ma_ : src > ma_ disposition = bullish ? color.lime : color.red basis = plot(src, 'OHLC4', disposition, linewidth = 1) work = plot(ma_, 'TWAP', disposition, linewidth = 2) fill(basis, work, disposition) //JMA------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ jsa = (src0 + src0[lengths]) / 2 sig = src0 > jsa ? 1 : src0 < jsa ? -1 : 0 jsaColor = sig > 0 ? color.lime : sig < 0 ? color.red : color.orange plot(jsa, color = jsaColor, linewidth = 2) jmagood = sig > 0 jmabad = sig < 0 //MACD------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ fast_ma = ta.ema(src, fast_length) slow_ma = ta.ema(src, slow_length) macd = fast_ma - slow_ma signal = ta.sma(macd, signal_length) macdgood = macd > signal macdbad = macd < signal //Volume Delta ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- iff_1 = close[1] < open ? math.max(high - close[1], close - low) : math.max(high - open, close - low) iff_2 = close[1] > open ? high - low : math.max(open - close[1], high - low) iff_3 = close[1] < open ? math.max(high - close[1], close - low) : high - open iff_4 = close[1] > open ? high - low : math.max(open - close[1], high - low) iff_5 = close[1] < open ? math.max(open - close[1], high - low) : high - low iff_6 = close[1] > open ? math.max(high - open, close - low) : iff_5 iff_7 = high - close < close - low ? iff_4 : iff_6 iff_8 = high - close > close - low ? iff_3 : iff_7 iff_9 = close > open ? iff_2 : iff_8 bullPower = close < open ? iff_1 : iff_9 iff_10 = close[1] > open ? math.max(close[1] - open, high - low) : high - low iff_11 = close[1] > open ? math.max(close[1] - low, high - close) : math.max(open - low, high - close) iff_12 = close[1] > open ? math.max(close[1] - open, high - low) : high - low iff_13 = close[1] > open ? math.max(close[1] - low, high - close) : open - low iff_14 = close[1] < open ? math.max(open - low, high - close) : high - low iff_15 = close[1] > open ? math.max(close[1] - open, high - low) : iff_14 iff_16 = high - close < close - low ? iff_13 : iff_15 iff_17 = high - close > close - low ? iff_12 : iff_16 iff_18 = close > open ? iff_11 : iff_17 bearPower = close < open ? iff_10 : iff_18 bullVolume = bullPower / (bullPower + bearPower) * volume bearVolume = bearPower / (bullPower + bearPower) * volume delta = bullVolume - bearVolume cvd = ta.cum(delta) cvdMa = ta.sma(cvd, periodMa) deltagood = cvd > cvdMa deltabad = cvd < cvdMa //Volume weight------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ getMA0(length) => maPrice = ta.ema(volume, length) if maType == 'SMA' maPrice := ta.sma(volume, length) maPrice if maType == 'HMA' maPrice := ta.hma(volume, length) maPrice if maType == 'WMA' maPrice := ta.wma(volume, length) maPrice if maType == 'DEMA' e1 = ta.ema(volume, length) e2 = ta.ema(e1, length) maPrice := 2 * e1 - e2 maPrice maPrice ma = getMA0(maLength) rvol = volume / ma volumegood = volume > rvolTrigger * ma //MA---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ma5 = ta.sma(close, 5) ma10 = ta.sma(close, 10) ma30 = ta.sma(close, 30) magood = ma5 > ma30 mabad = ma5 < ma30 simplema = ta.sma(src, length) exponentialma = ta.ema(src, length) hullma = ta.wma(2 * ta.wma(src, length / 2) - ta.wma(src, length), math.round(math.sqrt(length))) weightedma = ta.wma(src, length) volweightedma = ta.vwma(src, length) avgval = matype == 1 ? simplema : matype == 2 ? exponentialma : matype == 3 ? hullma : matype == 4 ? weightedma : matype == 5 ? volweightedma : na MA_speed = (avgval / avgval[1] - 1) * 100 masgood = MA_speed > 0 masbad = MA_speed < 0 //Momentum----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- data = 0 for i = 1 to tmolength - 1 by 1 if close > open[i] data := data + 1 data if close < open[i] data := data - 1 data EMA5 = ta.ema(data, calcLength) Main = ta.ema(EMA5, smoothLength) Signal = ta.ema(Main, smoothLength) momentumgood = Main > Signal momentumbad = Main < Signal //STRATEGY=============================================================================================================================================================================================================================================================== Long = DIPlus > DIMinus and ADX > th and volumegood and sargood and rsiob and macdgood and deltagood and magood and masgood and bullish and jmagood and rangegood and momentumgood Short = DIPlus < DIMinus and ADX > th and volumegood and sarbad and rsios and macdbad and deltabad and mabad and masbad and jmabad and rangebad and momentumbad //BACKTESTING========================================================================================================================================================================================================================== // ————— Backtest input Act_BT = input(true, title = 'BACKTEST') backtest_time = input.int(180, title = 'BACKTEST DAYS', minval = 1) * 24 * 60 * 60 * 1000 entry_Type = input.string('% EQUITY', title = 'ENTRY TYPE', options = ['CONTRACTS', 'CASH', '% EQUITY']) et_Factor = entry_Type == 'CONTRACTS' ? 1 : entry_Type == '% EQUITY' ? 100 / (strategy.equity / close) : close //Signals---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- // SL AND TP----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- stopPer = input(3.6, title = 'Stop Loss % [plotshape]') / 100 takePer = input(0.8, title = 'Take Profit % [plotshape]') / 100 long_short = 0 long_last = Long and (nz(long_short[1]) == 0 or nz(long_short[1]) == -1) short_last = Short and (nz(long_short[1]) == 0 or nz(long_short[1]) == 1) long_short := long_last ? 1 : short_last ? -1 : long_short[1] longPrice = ta.valuewhen(long_last, close, 0) shortPrice = ta.valuewhen(short_last, close, 0) longStop = longPrice * (1 - stopPer) shortStop = shortPrice * (1 + stopPer) longTake = longPrice * (1 + takePer) shortTake = shortPrice * (1 - takePer) //plot lines --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- plotshape(long_short == 1 ? longTake : na, style = shape.cross, color = color.new(color.gray, 0), location = location.absolute) plotshape(long_short == -1 ? shortTake : na, style = shape.cross, color = color.new(color.gray, 0), location = location.absolute) longBar1 = ta.barssince(long_last) longBar2 = longBar1 >= 1 ? true : false shortBar1 = ta.barssince(short_last) shortBar2 = shortBar1 >= 1 ? true : false Long_SL = long_short == 1 and longBar2 and low < longStop Short_SL = long_short == -1 and shortBar2 and high > shortStop Long_TP = long_short == 1 and longBar2 and high > longTake Short_TP = long_short == -1 and shortBar2 and low < shortTake long_short := (long_short == 1 or long_short == 0) and longBar2 and (Long_SL or Long_TP) ? 0 : (long_short == -1 or long_short == 0) and shortBar2 and (Short_SL or Short_TP) ? 0 : long_short last_long_cond = Long and long_last last_short_cond = Short and short_last //plotshapes--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- plotshape(last_long_cond, title = 'Long x1', color = color.new(color.blue, 1), style = shape.triangleup, location = location.belowbar, size = size.small, textcolor = color.new(color.white, 1), text = 'Long') plotshape(last_short_cond, title = 'Short x1', color = color.new(color.red, 1), style = shape.triangledown, location = location.abovebar, size = size.tiny, textcolor = color.new(color.white, 1), text = 'Short') plotshape(Long_SL, location = location.belowbar, color = color.new(color.black, 0), size = size.tiny, text = 'SL', textcolor = color.new(color.fuchsia, 0)) plotshape(Short_SL, location = location.abovebar, color = color.new(color.black, 0), size = size.tiny, text = 'SL', textcolor = color.new(color.fuchsia, 0)) plotshape(Long_TP, style = shape.triangledown, location = location.abovebar, color = color.new(color.gray, 0), size = size.tiny, text = 'TP', textcolor = color.new(color.red, 0)) plotshape(Short_TP, style = shape.triangleup, location = location.belowbar, color = color.new(color.gray, 0), size = size.tiny, text = 'TP', textcolor = color.new(color.green, 0)) if last_long_cond and Act_BT strategy.entry('L', strategy.long) if last_short_cond and Act_BT strategy.entry('S', strategy.short) per(pcnt) => strategy.position_size != 0 ? math.round(pcnt / 100 * strategy.position_avg_price / syminfo.mintick) : float(na) stoploss = input.float(title = ' stop loss [BT]', defval = 3.6, minval = 0.01) los = per(stoploss) q = input.int(title = ' qty percent', defval = 100, minval = 1) tp = input.float(title = ' Take profit [BT]', defval = 0.8, minval = 0.01) strategy.exit('tp', qty_percent = q, profit = per(tp), loss = los) //