888 BOT v4 adalah strategi perdagangan automatik yang menggabungkan pelbagai penunjuk untuk menentukan trend dan menghasilkan isyarat perdagangan. Ia menggunakan gabungan 8 penunjuk termasuk purata bergerak, penapis julat, ADX, SAR parabolik, RSI dengan jumlah, MACD dan pita Bollinger untuk menghasilkan isyarat perdagangan yang lebih boleh dipercayai.
Jurik Moving Average (JMA): Purata bergerak yang direka oleh Mark Jurik untuk profesional yang menghapuskan kelewatan isyarat.
Penapis Julat: Mengira julat harga purata dalam tempoh dan memperkuatnya untuk menapis bunyi bising dan menentukan lebih baik trend jangka pendek.
Indeks Arah Purata (ADX): Dicipta oleh Wilder untuk mengukur kekuatan trend dan arah.
SAR Parabolik: Juga oleh Wilder, meletakkan titik untuk menentukan arah trend. SAR membalik ke sisi lain harga apabila disentuh membentuk bentuk parabola.
RSI dengan Volume: Menambah parameter jumlah kepada RSI klasik untuk menjadikannya lebih responsif kepada pergerakan pasaran.
MACD: Perbezaan konvergensi purata bergerak oleh Appel. Histogram menjangkakan persilangan purata bergerak. MAC-Z standardkan harga sebelum pengiraan VWAP.
Keadaan Volume: Menapis isyarat dengan jumlah di bawah purata, leverage yang berbeza untuk tahap yang berbeza.
Bollinger Bands: John Bollinger
Menentukan keadaan panjang/pendek berdasarkan penunjuk.
Menghasilkan isyarat perdagangan apabila disahkan dari pelbagai penunjuk dan masukkan kedudukan.
Tetapkan tahap mengambil keuntungan dan menghentikan kerugian berdasarkan saiz kedudukan dan parameter risiko.
Tutup kedudukan apabila mengambil keuntungan atau hentikan kerugian.
Peluang untuk menambah kedudukan di pintu masuk yang lebih baik apabila Bollinger Bands dipukul lagi.
Tunggu pengesahan penunjuk sekali lagi selepas setiap kedudukan ditutup untuk entri baru.
Kelebihan terbesar 888 BOT v4 adalah penggunaan gabungan beberapa penunjuk untuk pengesahan yang lebih boleh dipercayai daripada strategi penunjuk tunggal.
Khususnya, kelebihan termasuk:
JMA menghapuskan kelewatan, penapis julat mengurangkan bunyi bising untuk isyarat berkualiti tinggi.
ADX mengukur kekuatan trend manakala SAR menentukan arah untuk entri yang lebih tepat.
RSI dan MACD berwajaran jumlah menggabungkan lebih banyak data pasaran untuk mengesahkan isyarat secara berbilang pihak.
Keadaan volum menapis isyarat palsu dan sepadan leverage ke tahap.
Pilihan SL peratusan tetap, ATR atau kedua-duanya mengawal risiko penurunan.
Bounce Bollinger membolehkan penambahan untuk meningkatkan harga kemasukan untuk keuntungan yang lebih besar.
Pilihan untuk membahagikan TP untuk keseimbangan antara keuntungan dan kadar kemenangan.
Backtestable merentasi jangka masa dan simbol untuk penilaian strategi.
Walaupun risiko yang dikurangkan daripada kombinasi penunjuk dan penyesuaian parameter, semua strategi membawa beberapa risiko termasuk:
Kemungkinan isyarat palsu penunjuk boleh dikurangkan dengan menyesuaikan parameter.
Risiko kerugian yang diperbesar apabila menambah kedudukan yang kehilangan dapat dicegah dengan mengehadkan besarnya pengoptimuman.
Risiko penarikan yang dilanjutkan sebelum Bollinger Band hit boleh dinilai dengan penunjuk trend untuk menambah masa.
Risiko SL yang terlalu luas boleh dikurangkan dengan ukuran julat SL yang sesuai.
Tempoh backtest yang tidak mencukupi boleh ditangani dengan memperluaskan jangka masa ujian.
Masalah jumlah yang rendah boleh diselesaikan dengan menyesuaikan saiz kedudukan.
Kegagalan dalam keadaan pasaran khas memerlukan pengurusan risiko dan kesediaan.
Beberapa bidang 888 BOT v4 masih boleh ditingkatkan:
Sesuaikan parameter penunjuk untuk kombinasi yang ideal.
Cuba menggantikan penunjuk dengan yang lain e.g. KDJ, osilator dan lain-lain.
Mengoptimumkan tahap optimum kemasukan yang lebih baik.
Memperbaiki algoritma TP dan SL.
Melaksanakan break-even SL selepas TP.
Mengoptimumkan saiz kedudukan dan leverage.
meneroka pembelajaran mesin untuk pengoptimuman automatik.
Tambah syarat keluar untuk mengelakkan keadaan pasaran tertentu.
Uji arbitrage rentas pasaran.
Membangunkan antara muka grafik untuk kemudahan penggunaan.
Kesimpulannya, 888 BOT v4 merupakan contoh strategi pelbagai penunjuk yang dapat meningkatkan keuntungan dengan ketara melalui kombinasi penunjuk.
/*backtest start: 2023-09-20 00:00:00 end: 2023-09-27 00:00:00 period: 10m basePeriod: 1m exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}] */ // This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/ // Β© Xaviz //@version=4 strategy(title = "888 BOT #backtest", shorttitle = "888πΉ", overlay = true, initial_capital = 10000, pyramiding = 10, currency = "USD", default_qty_type = strategy.percent_of_equity, default_qty_value = 0, commission_value = 0.04) // -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- // // ββββββββββββββββββββ Inputs // -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- // // βββββ Source input src = input(hlc3, title = "ββSOURCE", type = input.source) // βββββ JMA inputs Act_JMA = input(true, title = "JURIK MOVING AVERAGE", type = input.bool) JMA_length = input(30, title = "ββJMA LENGTH", type = input.integer, minval = 0) phase = input(40, title = "ββJMA PHASE", type = input.integer, minval = 0) power = input(2.5, title = "ββJMA POWER", type = input.float, minval = 0, step = 0.5) // βββββ Range Filter inputs Act_RF = input(true, title = "RANGE FILTER", type = input.bool) per = input(20, title = "ββSAMPLING PERIOD", type = input.integer, minval = 1) mult = input(1.7, title = "ββRANGE MULTIPLIER", type = input.float, minval = 0.1, step = 0.1) // βββββ ADX inputs Act_ADX = input(true, title = "AVERAGE DIRECTIONAL INDEX", type = input.bool) ADX_options = input("CLASSIC", title = "ββADX OPTION", options = ["CLASSIC", "MASANAKAMURA"]) ADX_len = input(22, title = "ββADX LENGTH", type = input.integer, minval = 1) th = input(20, title = "ββADX THRESHOLD", type = input.float, minval = 0, step = 0.5) // βββββ SAR inputs Act_SAR = input(true, title = "PARABOLIC SAR", type = input.bool) Sst = input (0.25, title = "ββSAR STAR", type = input.float, minval = 0.01, step = 0.01) Sinc = input (0.25, title = "ββSAR INC", type = input.float, minval = 0.01, step = 0.01) Smax = input (0.13, title = "ββSAR MAX", type = input.float, minval = 0.01, step = 0.01) // βββββ RSI with volume inputs Act_RSI = input(true, title = "RSI VOLUME WEIGHTED", type = input.bool) RSI_len = input(34, title = "ββRSI LENGHT", type = input.integer, minval = 1) RSI_obos = input(45, title = "ββRSI CENTER LINE", type = input.integer, minval = 1) // βββββ MACD / MAC-Z inputs Act_MACD = input(true, title = "MA CONVERGENCE/DIVERGENCE", type = input.bool) MACD_options = input("MAC-Z", title = "ββMACD OPTION", options = ["MACD", "MAC-Z"]) fastLength = input(45, title = "ββMACD FAST MA LENGTH", type = input.integer, minval = 1) slowLength = input(47, title = "ββMACD SLOW MA LENGTH", type = input.integer, minval = 1) signalLength = input(13, title = "ββMACD SIGNAL LENGTH", type = input.integer, minval = 1) lengthz = input(9, title = "ββZ-VWAP LENGTH", type = input.integer, minval = 1) lengthStdev = input(14, title = "ββSTDEV LENGTH", type = input.integer, minval = 1) // βββββ Volume inputs for entries condition and for calculate quantities later Act_Vol = input(true, title = "VOLUME CONDITION", type = input.bool) volume_f = input(1.4, title = "ββVOLUME FACTOR", type = input.float, minval = 0, step = 0.1) sma_length = input(61, title = "ββSMA VOLUME LENGTH", type = input.integer, minval = 1) // βββββ First take profit input tp_long0 = input(1.7, title = "ββTAKE PROFIT LONG %", type = input.float, minval = 0, step = 0.1) tp_short0 = input(1.8, title = "ββTAKE PROFIT SHORT %", type = input.float, minval = 0, step = 0.1) // βββββ Stop Loss input Act_sl = input(true, title = "ACTIVATE STOP LOSS π§»", type = input.bool) SL_options = input("NORMAL", title = "ββSTOP LOSS OPTION", options = ["NORMAL", "ATR", "BOTH"]) sl0 = input(3.7, title = "ββSTOP LOSS %", type = input.float, minval = 0, step = 0.1) // βββββ ATR Inputs atrPeriod = input(13, title = "ββATR SL PERIOD", type = input.integer, minval = 0) multiplierPeriod = input(7.0, title = "ββATR SL MULTIPLIER", type = input.float, minval = 0, step = 0.1) // βββββ Risk input Risk = input(3.5, title = "ββ% RISK ALLOWED", type = input.float, minval = 0, step = 0.5) // βββββ Confirmed Stop loss Act_Conf_SL = input(false, title = "STOP LOSS CONFIRMED", type = input.bool) // βββββ Bollinger Bands inputs Act_BB = input(true, title = "ACTIVATE BOLLINGER BANDS RE-ENTRY π", type = input.bool) BB_length = input(20, title = "ββBB LENGTH", type = input.integer, minval = 1) BB_mult = input(1.9, title = "ββBB MULTIPLIER", type = input.float, minval = 0.001, step = 0.1) bbBetterPrice = input(0.5, title = "ββ% MINIMUM BETTER PRICE", type = input.float, minval = 0.1, step = 0.1) Act_divide = input(false, title = "ACTIVATE DIVIDE TP", type = input.bool) // βββββ Backtest input Act_BT = input(true, title = "BACKTEST πΉ", type = input.bool) backtest_time = input(180, title = "ββBACKTEST DAYS", type = input.integer, minval = 1)*24*60*60*1000 entry_Type = input("% EQUITY", title = "ββENTRY TYPE", options = ["CONTRACTS","CASH","% EQUITY"]) et_Factor = (entry_Type == "CONTRACTS") ? 1 : (entry_Type == "% EQUITY") ? (100/(strategy.equity/close)) : close quanTity = input(8.0, title = "ββQUANTITY (LEVERAGE 1X)", type = input.float, minval = 0, step = 0.5) / et_Factor Max_Lev = input(8, title = "ββMAXIMUM LEVERAGE", type = input.integer, minval = 1, maxval = 8) // -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- // // ββββββββββββββββββββ Variables // -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- // // βββββ Long/Short var bool longCond = na, var bool shortCond = na var int CondIni_long = 0, var int CondIni_short = 0 var bool _Final_longCondition = na, var bool _Final_shortCondition = na var float last_open_longCondition = na, var float last_open_shortCondition = na var float last_dynamic_Leverage_long = na, var float last_dynamic_Leverage_short = na var int last_longCondition = na, var int last_shortCondition = na var int last_Final_longCondition = na, var int last_Final_shortCondition = na var int nLongs = na, var int nShorts = na // βββββ Take profit var bool long_tp = na, var bool short_tp = na var int last_long_tp = na, var int last_short_tp = na var bool Final_Long_tp = na, var bool Final_Short_tp = na // βββββ Stop Loss var int CondIni_long_sl = 0, var int CondIni_short_sl = 0 var bool Final_Long_sl0 = na, var bool Final_Short_sl0 = na var bool Final_Long_sl = na, var bool Final_Short_sl = na var int last_long_sl = na, var int last_short_sl = na // βββββ Indicators var bool JMA_longCond = na, var bool JMA_shortCond = na var bool RF_longCond = na, var bool RF_shortCond = na var bool ADX_longCond = na, var bool ADX_shortCond = na var bool SAR_longCond = na, var bool SAR_shortCond = na var bool RSI_longCond = na, var bool RSI_shortCond = na var bool MACD_longCond = na, var bool MACD_shortCond = na var bool VOL_longCond = na, var bool VOL_shortCond = na var bool JMA_XlongCond = na, var bool JMA_XshortCond = na var bool RF_XlongCond = na, var bool RF_XshortCond = na var bool ADX_XlongCond = na, var bool ADX_XshortCond = na var bool SAR_XlongCond = na, var bool SAR_XshortCond = na var int CondIni_long_BB = 0, var int CondIni_short_BB = 0 var bool Final_long_BB = na, var bool Final_short_BB = na var int last_long_BB = na, var int last_short_BB = na // βββββ Average Price var float sum_long = 0.0, var float sum_short = 0.0 var float Position_Price = 0.0 // -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- // // ββββββββββββββββββββ Jurik Moving Average // -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- // // βββββ JMA calculation JMA(_JMA_length, _phase, _power, _src) => phaseRatio = _phase < -100 ? 0.5 : _phase > 100 ? 2.5 : _phase / 100 + 1.5 beta = 0.45 * (_JMA_length - 1) / (0.45 * (_JMA_length - 1) + 2) alpha = pow(beta, _power) jma = 0.0 e0 = 0.0 e0 := (1 - alpha) * _src + alpha * nz(e0[1]) e1 = 0.0 e1 := (_src - e0) * (1 - beta) + beta * nz(e1[1]) e2 = 0.0 e2 := (e0 + phaseRatio * e1 - nz(jma[1])) * pow(1 - alpha, 2) + pow(alpha, 2) * nz(e2[1]) jma := e2 + nz(jma[1]) // βββββ Defining JMA trend JMA_Rising = JMA(JMA_length, phase, power, src) > JMA(JMA_length, phase, power, src)[1] JMA_Falling = JMA(JMA_length, phase, power, src) < JMA(JMA_length, phase, power, src)[1] // βββββ JMA Plotting JMA_color = JMA_Rising ? color.lime : JMA_Falling ? #e91e63 : color.orange plot(Act_JMA ? JMA(JMA_length, phase, power, src) : na, color=JMA_color, linewidth = 2, title= "JMA") // -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- // // ββββββββββββββββββββ Range Filter // -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- // // βββββ Range Filter calculation Range_filter(_src, _per, _mult) => float _upward = 0.0 float _downward = 0.0 wper = (_per*2) - 1 avrng = ema(abs(_src - _src[1]), _per) _smoothrng = ema(avrng, wper) * _mult _filt = _src _filt := _src > nz(_filt[1]) ? ((_src-_smoothrng) < nz(_filt[1]) ? nz(_filt[1]) : (_src-_smoothrng)) : ((_src+_smoothrng) > nz(_filt[1]) ? nz(_filt[1]) : (_src+_smoothrng)) _upward := _filt > _filt[1] ? nz(_upward[1]) + 1 : _filt < _filt[1] ? 0 : nz(_upward[1]) _downward := _filt < _filt[1] ? nz(_downward[1]) + 1 : _filt > _filt[1] ? 0 : nz(_downward[1]) [_smoothrng,_filt,_upward,_downward] // βββββ Defining variables for include in future conditions [smoothrng, filt, upward, downward] = Range_filter(src, per, mult) // βββββ Defining high and low bands hband = filt + smoothrng lband = filt - smoothrng // βββββ Range Filter Plotting filtcolor = upward > 0 ? color.lime : downward > 0 ? color.red : color.orange filtplot = plot(Act_RF ? filt : na, color = filtcolor, linewidth = 1, title = "RF") hbandplot = plot(Act_RF ? hband : na, color = filtcolor, transp = 50, title = "RF High Target") lbandplot = plot(Act_RF ? lband : na, color = filtcolor, transp = 50, title = "RF Low Target") fill(hbandplot, lbandplot, color = filtcolor, title = "RF Target Range") // -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- // // ββββββββββββββββββββ ADX // -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- // // βββββ Classic ADX calculating calcADX(_len) => up = change(high) down = -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 = rma(tr, _len) _plus = fixnan(100 * rma(plusDM, _len) / truerange) _minus = fixnan(100 * rma(minusDM, _len) / truerange) sum = _plus + _minus _adx = 100 * rma(abs(_plus - _minus) / (sum == 0 ? 1 : sum), _len) [_plus,_minus,_adx] // βββββ Masanakamura ADX calculating calcADX_Masanakamura(_len) => SmoothedTrueRange = 0.0 SmoothedDirectionalMovementPlus = 0.0 SmoothedDirectionalMovementMinus = 0.0 TrueRange = max(max(high - low, abs(high - nz(close[1]))), abs(low - nz(close[1]))) DirectionalMovementPlus = high - nz(high[1]) > nz(low[1]) - low ? max(high - nz(high[1]), 0) : 0 DirectionalMovementMinus = nz(low[1]) - low > high - nz(high[1]) ? 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 = abs(DIP-DIM) / (DIP+DIM)*100 adx = sma(DX, _len) [DIP,DIM,adx] // βββββ Defining variables for include in future conditions [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 // βββββ Plotting ADX bar colors 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") // -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- // // ββββββββββββββββββββ SAR // -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- // // βββββ SAR calculation from TV SAR = sar(Sst, Sinc, Smax) // βββββ SAR Plotting plot(Act_SAR ? SAR : na, color = ADX_color, style = plot.style_circles, title = "SAR") // -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- // // ββββββββββββββββββββ RSI with Volume // -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- // // βββββ RSI with volume calculation WiMA(_src, W_length) => var float MA_s = 0.0 MA_s :=(_src + nz(MA_s[1] * (W_length-1)))/W_length MA_s RSI_Volume(fv, _length) => up = iff(fv > fv[1], abs(fv - fv[1]) * volume, 0) dn = iff(fv < fv[1], abs(fv - fv[1]) * volume, 0) upt = WiMA(up,_length) dnt = WiMA(dn,_length) 100 * (upt / (upt + dnt)) // βββββ Defining variable for include in conditions RSI_V = RSI_Volume(src, RSI_len) // -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- // // ββββββββββββββββββββ MACD // -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- // // βββββ MAC-Z calculation calc_zvwap(pds) => mean = sum(volume * close, pds) / sum(volume, pds) vwapsd = sqrt(sma(pow(close - mean, 2), pds)) (close - mean ) / vwapsd zscore = calc_zvwap(lengthz) fastMA = sma(src, fastLength) slowMA = sma(src, slowLength) macd = fastMA - slowMA macz = zscore + macd / stdev(src, lengthStdev) signal = sma(macz, signalLength) histmacz = macz - signal // βββββ MACD calculation [_,_,histmacd] = macd(src, fastLength, slowLength, signalLength) hist = MACD_options == "MACD" ? histmacd : histmacz // -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- // // ββββββββββββββββββββ Strategy // -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- // // βββββ All indicators with long conditions and enable/disable option JMA_longCond := (Act_JMA ? (JMA_Rising) : VOL_longCond) RF_longCond := (Act_RF ? (high > hband and upward > 0) : JMA_longCond) ADX_longCond := (Act_ADX ? (DIPlus > DIMinus and ADX > th) : RF_longCond) SAR_longCond := (Act_SAR ? (SAR < close) : ADX_longCond) RSI_longCond := (Act_RSI ? (RSI_V > RSI_obos) : SAR_longCond) MACD_longCond := (Act_MACD ? (hist > 0) : RSI_longCond) VOL_longCond := (Act_Vol ? (volume > sma(volume,sma_length) * volume_f) : MACD_longCond) // βββββ All indicators with short conditions and enable/disable option JMA_shortCond := (Act_JMA ? (JMA_Falling) : VOL_shortCond) RF_shortCond := (Act_RF ? (low < lband and downward > 0) : JMA_shortCond) ADX_shortCond := (Act_ADX ? (DIPlus < DIMinus and ADX > th) : RF_shortCond) SAR_shortCond := (Act_SAR ? (SAR > close) : ADX_shortCond) RSI_shortCond := (Act_RSI ? (RSI_V < RSI_obos) : SAR_shortCond) MACD_shortCond := (Act_MACD ? (hist < 0) : RSI_shortCond) VOL_shortCond := (Act_Vol ? (volume > sma(volume,sma_length) * volume_f) : MACD_shortCond) // βββββ Defining long/short condition from indicators + volume longCond := JMA_longCond and RF_longCond and ADX_longCond and SAR_longCond and RSI_longCond and MACD_longCond and VOL_longCond shortCond := JMA_shortCond and RF_shortCond and ADX_shortCond and SAR_shortCond and RSI_shortCond and MACD_shortCond and VOL_shortCond // βββββ Avoiding confirmed long/short simultaneity CondIni_long := longCond[1] ? 1 : shortCond[1] ? -1 : nz(CondIni_long[1]) CondIni_short := longCond[1] ? 1 : shortCond[1] ? -1 : nz(CondIni_short[1]) // βββββ Confirmed long/short conditions longCondition = (longCond[1] and nz(CondIni_long[1]) == -1) shortCondition = (shortCond[1] and nz(CondIni_short[1]) == 1) // -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- // // ββββββββββββββββββββ Position Price // -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- // // βββββ Last opened long/short price on unconfirmed/confirmed conditions last_open_longCondition := longCondition or Final_long_BB[1] ? close[1] : nz(last_open_longCondition[1]) last_open_shortCondition := shortCondition or Final_short_BB[1] ? close[1] : nz(last_open_shortCondition[1]) // βββββ Check if your last position was a confirmed long or a short last_longCondition := longCondition or Final_long_BB[1] ? time : nz(last_longCondition[1]) last_shortCondition := shortCondition or Final_short_BB[1] ? time : nz(last_shortCondition[1]) in_longCondition = last_longCondition > last_shortCondition in_shortCondition = last_shortCondition > last_longCondition // βββββ Check if your last position was a confirmed final long or short without BB last_Final_longCondition := longCondition ? time : nz(last_Final_longCondition[1]) last_Final_shortCondition := shortCondition ? time : nz(last_Final_shortCondition[1]) // βββββ Counting long & short iterations nLongs := nz(nLongs[1]) nShorts := nz(nShorts[1]) // βββββ Longs Counter if longCondition or Final_long_BB nLongs := nLongs + 1 nShorts := 0 sum_long := nz(last_open_longCondition) + nz(sum_long[1]) sum_short := 0.0 // βββββ Shorts Counter if shortCondition or Final_short_BB nLongs := 0 nShorts := nShorts + 1 sum_short := nz(last_open_shortCondition) + nz(sum_short[1]) sum_long := 0.0 // βββββ Calculating and Plotting the price average Position_Price := nz(Position_Price[1]) Position_Price := longCondition or Final_long_BB ? sum_long/nLongs : shortCondition or Final_short_BB ? sum_short/nShorts : na plot((nLongs > 1) or (nShorts > 1) ? Position_Price : na, title = "Average Price", color = in_longCondition ? color.aqua : color.orange, linewidth = 2, style = plot.style_cross) // -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- // // ββββββββββββββββββββ Take Profit // -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- // // βββββ Take Profit divided by n entries tp_long = (Act_divide and (nLongs > 1) ? tp_long0 / nLongs : tp_long0) / 100 tp_short = (Act_divide and (nShorts > 1) ? tp_short0 / nShorts : tp_short0) / 100 // βββββ First TP Conditions long_tp := high > (fixnan(Position_Price) * (1 + tp_long)) and in_longCondition short_tp := low < (fixnan(Position_Price) * (1 - tp_short)) and in_shortCondition // βββββ Get the time of the last tp close last_long_tp := long_tp ? time : nz(last_long_tp[1]) last_short_tp := short_tp ? time : nz(last_short_tp[1]) // βββββ Final Take profit condition (never after the stop loss) Final_Long_tp := (long_tp and last_longCondition > nz(last_long_tp[1]) and last_longCondition > nz(last_long_sl[1])) Final_Short_tp := (short_tp and last_shortCondition > nz(last_short_tp[1]) and last_shortCondition > nz(last_short_sl[1])) // -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- // // ββββββββββββββββββββ Stop Loss // -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- // // βββββ Stop Loss ATR calculation ATR_SL_Long = low - atr(atrPeriod) * multiplierPeriod ATR_SL_Short = high + atr(atrPeriod) * multiplierPeriod longStopPrev = nz(ATR_SL_Long[1], ATR_SL_Long) shortStopPrev = nz(ATR_SL_Short[1], ATR_SL_Short) ATR_SL_Long := close[1] > longStopPrev ? max(ATR_SL_Long, longStopPrev) : ATR_SL_Long ATR_SL_Short := close[1] < shortStopPrev ? min(ATR_SL_Short, shortStopPrev) : ATR_SL_Short // βββββ Calculating Sl according Risk and Initial Capital sl = in_longCondition ? min(sl0, (((Risk / (100 / (strategy.equity / close)))*100) / (quanTity * max(1, last_dynamic_Leverage_long) * max(1, nLongs)))) : min(sl0, (((Risk / (100 / (strategy.equity / close)))*100) / (quanTity * max(1, last_dynamic_Leverage_short) * max(1, nShorts)))) // βββββ Stop Loss long conditions Normal_long_sl = Act_Conf_SL ? ((SL_options == "NORMAL") ? ((Act_sl and in_longCondition and close <= ((1 - (sl / 100)) * (fixnan(Position_Price))))) : na) : ((SL_options == "NORMAL") ? ((Act_sl and in_longCondition and low <= ((1 - (sl / 100)) * (fixnan(Position_Price))))) : na) ATR_long_sl = Act_Conf_SL ? ((SL_options == "ATR") ? ((Act_sl and in_longCondition and close <= (ATR_SL_Long))) : na) : ((SL_options == "ATR") ? ((Act_sl and in_longCondition and low <= (ATR_SL_Long))) : na) Both_long_sl = Act_Conf_SL ? ((SL_options == "BOTH") ? ((Act_sl and in_longCondition and close <= ((1 - (sl / 100)) * (fixnan(Position_Price)))) or ((Act_sl and in_longCondition and close <= (ATR_SL_Long)))) : na) : ((SL_options == "BOTH") ? ((Act_sl and in_longCondition and low <= ((1 - (sl / 100)) * (fixnan(Position_Price)))) or ((Act_sl and in_longCondition and low <= (ATR_SL_Long)))) : na) // βββββ Stop Loss short conditions Normal_short_sl = Act_Conf_SL ? ((SL_options == "NORMAL") ? ((Act_sl and in_shortCondition and close >= ((1 + (sl / 100)) * (fixnan(Position_Price))))) : na) : ((SL_options == "NORMAL") ? ((Act_sl and in_shortCondition and high >= ((1 + (sl / 100)) * (fixnan(Position_Price))))) : na) ATR_short_sl = Act_Conf_SL ? ((SL_options == "ATR") ? ((Act_sl and in_shortCondition and close >= (ATR_SL_Short))) : na) : ((SL_options == "ATR") ? ((Act_sl and in_shortCondition and high >= (ATR_SL_Short))) : na) Both_short_sl = Act_Conf_SL ? ((SL_options == "BOTH") ? ((Act_sl and in_shortCondition and close >= ((1 + (sl/100)) * (fixnan(Position_Price)))) or ((Act_sl and in_shortCondition and close >= (ATR_SL_Short)))) : na) : ((SL_options == "BOTH") ? ((Act_sl and in_shortCondition and high >= ((1 + (sl/100)) * (fixnan(Position_Price)))) or ((Act_sl and in_shortCondition and high >= (ATR_SL_Short)))) : na) // βββββ Get the time of the last sl close last_long_sl := Normal_long_sl or ATR_long_sl or Both_long_sl ? time : nz(last_long_sl[1]) last_short_sl := Normal_short_sl or ATR_short_sl or Both_short_sl ? time : nz(last_short_sl[1]) // βββββ Final Stop Loss condition Final_Long_sl := (Normal_long_sl or ATR_long_sl or Both_long_sl) and last_longCondition > nz(last_long_sl[1]) and last_longCondition > nz(last_long_tp[1]) and not Final_Long_tp Final_Short_sl := (Normal_short_sl or ATR_short_sl or Both_short_sl) and last_shortCondition > nz(last_short_sl[1]) and last_shortCondition > nz(last_short_tp[1]) and not Final_Short_tp //Plottin ATR SL plot(Act_sl and (SL_options != "NORMAL") ? in_longCondition ? ATR_SL_Long[1] : ATR_SL_Short[1] : na, title = "ATR SL", color = color.purple) // -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- // // ββββββββββββββββββββ Bollinger Bands Re-entry // -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- // BB_basis = sma(src, BB_length) BB_dev = BB_mult * stdev(src, BB_length) BB_upper = BB_basis + BB_dev BB_lower = BB_basis - BB_dev u_BB = plot(Act_BB ? BB_upper : na, title = "Upper Bollinger Band", color = #009688, linewidth = 2) l_BB = plot(Act_BB ? BB_lower : na, title = "Lower Bollinger Band", color = #f06292, linewidth = 2) fill(u_BB, l_BB, title = "Bollinger Band Background", color = in_longCondition ? #009688 : #f06292, transp = 95) // βββββ Initial Bollinger Bands conditions BB_long = Act_BB and in_longCondition and not (DIPlus < DIMinus and ADX > th) and (close <= BB_lower) and (close < last_open_longCondition * (1 - (bbBetterPrice / 100))) BB_short = Act_BB and in_shortCondition and not (DIPlus > DIMinus and ADX > th) and (close >= BB_upper) and (close > last_open_shortCondition * (1 + (bbBetterPrice / 100))) // βββββ Get the time of the last BB close last_long_BB := BB_long ? time : nz(last_long_BB[1]) last_short_BB := BB_short ? time : nz(last_short_BB[1]) // βββββ Final Bollinger Bands condition for long Final_long_BB := BB_long and last_Final_longCondition > nz(last_long_BB[1]) and last_longCondition > nz(last_long_tp[1]) and last_longCondition > nz(last_long_sl[1]) and not Final_Long_sl // βββββ Final Bollinger Bands condition for short Final_short_BB := BB_short and last_Final_shortCondition > nz(last_short_BB[1]) and last_shortCondition > nz(last_short_tp[1]) and last_shortCondition > nz(last_short_sl[1]) and not Final_Short_sl // βββββ Final confirmed Re-entries on long & short conditions Final_Long_BB = Final_long_BB[1] Final_Short_BB = Final_short_BB[1] // -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- // // ββββββββββββββββββββ Signal Plotting // -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- // // βββββ TP Long Levels tplLevel = (in_longCondition and (last_longCondition > nz(last_long_tp[1])) and (last_longCondition > nz(last_long_sl[1])) and not Final_Long_sl[1]) ? (nLongs > 1) ? (fixnan(Position_Price) * (1 + tp_long)) : (last_open_longCondition * (1 + tp_long)) : na plot(tplLevel, title = "Long TP Level", style = plot.style_circles, color = color.lime, linewidth = 2) tpsLevel = (in_shortCondition and (last_shortCondition > nz(last_short_tp[1])) and (last_shortCondition > nz(last_short_sl[1])) and not Final_Short_sl[1]) ? (nShorts > 1) ? (fixnan(Position_Price) * (1 - tp_short)) : (last_open_shortCondition * (1 - tp_short)) : na plot(tpsLevel, title = "Short TP Level", style = plot.style_circles, color = color.red, linewidth = 2) // βββββ Weekend W_color = (dayofweek == dayofweek.sunday or dayofweek == dayofweek.saturday) ? color.white : na bgcolor(W_color, title = "Weekend", transp = 95) // -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- // // ββββββββββββββββββββ Re-entry Conditions // -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- // // βββββ Re-entry on long after tp, sl or Xlong if Final_Long_tp or Final_Long_sl CondIni_long := -1 sum_long := 0.0 nLongs := na // βββββ Re-entry on short after tp, sl or Xshort if Final_Short_tp or Final_Short_sl CondIni_short := 1 sum_short := 0.0 nShorts := na // -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- // // ββββββββββββββββββββ Backtest // -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- // // βββββ Defining new final unconfirmed long conditions _longCondition = (longCond and not in_longCondition) or (longCond and Final_Long_tp) or (longCond and Final_Long_sl) or (longCond and not longCondition and (last_long_tp >= nz(last_longCondition))) or (longCond and not longCondition and (last_long_sl >= nz(last_longCondition))) // βββββ Defining new final unconfirmed short conditions _shortCondition = (shortCond and not in_shortCondition) or (shortCond and Final_Short_tp) or (shortCond and Final_Short_sl) or (shortCond and not shortCondition and (last_short_tp >= nz(last_shortCondition))) or (shortCond and not shortCondition and (last_short_sl >= nz(last_shortCondition))) // βββββ Test period declaration testPeriod = time >= timenow - backtest_time // βββββ Volume Factor for determine quantities Volume_Factor_Leverage = min(Max_Lev, max(1, round(volume / sma(volume, sma_length)))) last_dynamic_Leverage_long := _longCondition ? Volume_Factor_Leverage : nz(last_dynamic_Leverage_long[1]) last_dynamic_Leverage_short := _shortCondition ? Volume_Factor_Leverage : nz(last_dynamic_Leverage_short[1]) // βββββ Entering long positions if (_longCondition) strategy.entry("long", strategy.long, qty = Volume_Factor_Leverage * quanTity, when = Act_BT and testPeriod) if (Final_long_BB) strategy.entry("long", strategy.long, qty = last_dynamic_Leverage_long * quanTity, when = Act_BT and testPeriod) // βββββ Entering short positions if (_shortCondition) strategy.entry("short", strategy.short, qty = Volume_Factor_Leverage * quanTity, when = Act_BT and testPeriod) if (Final_short_BB) strategy.entry("short", strategy.short, qty = last_dynamic_Leverage_short * quanTity, when = Act_BT and testPeriod) // βββββ Closing positions with first long TP strategy.exit("Tpl", "long", profit = (abs((last_open_longCondition * (1 + tp_long)) - last_open_longCondition) / syminfo.mintick), limit = nLongs >= 1 ? strategy.position_avg_price * (1 + tp_long) : na, loss = Act_Conf_SL == false ? (iff(Act_sl and (SL_options == "NORMAL"), (abs((last_open_longCondition*(1-(sl/100)))-last_open_longCondition)/syminfo.mintick), iff(Act_sl and (SL_options == "ATR"), (abs(ATR_SL_Long-last_open_longCondition)/syminfo.mintick), iff(Act_sl and (SL_options == "BOTH") and ((abs((last_open_longCondition*(1-(sl/100)))-last_open_longCondition)/syminfo.mintick) < (abs(ATR_SL_Long-last_open_longCondition)/syminfo.mintick)), (abs((last_open_longCondition*(1-(sl/100)))-last_open_longCondition)/syminfo.mintick), iff(Act_sl and (SL_options == "BOTH") and ((abs((last_open_longCondition*(1-(sl/100)))-last_open_longCondition)/syminfo.mintick) > (abs(ATR_SL_Long-last_open_longCondition)/syminfo.mintick)), (abs(ATR_SL_Long-last_open_longCondition)/syminfo.mintick), na))))) : na, stop = Act_Conf_SL == false and nLongs >= 1 ? (iff(Act_sl and (SL_options == "NORMAL"), ((1-(sl/100))*strategy.position_avg_price), iff(Act_sl and (SL_options == "ATR"), ATR_SL_Long, iff(Act_sl and (SL_options == "BOTH") and (((1-(sl/100))*strategy.position_avg_price) > ATR_SL_Long), ((1-(sl/100))*strategy.position_avg_price), iff(Act_sl and (SL_options == "BOTH") and (((1-(sl/100))*strategy.position_avg_price) < ATR_SL_Long), ATR_SL_Long, na))))) : na) // Canceling long exit orders to avoid simultaneity with re-entry strategy.cancel("Tpl", when = Final_long_BB) // βββββ Closing positions with first short TP strategy.exit("Tps", "short", profit = (abs((last_open_shortCondition * (1 - tp_short)) - last_open_shortCondition) / syminfo.mintick), limit = nShorts >= 1 ? strategy.position_avg_price*(1-(tp_short)) : na, loss = Act_Conf_SL == false ? (iff(Act_sl and (SL_options == "NORMAL"), (abs((last_open_shortCondition*(1+(sl/100)))-last_open_shortCondition)/syminfo.mintick), iff(Act_sl and (SL_options == "ATR"), (abs(ATR_SL_Short-last_open_shortCondition)/syminfo.mintick), iff(Act_sl and (SL_options == "BOTH") and ((abs((last_open_shortCondition*(1+(sl/100)))-last_open_shortCondition)/syminfo.mintick) < (abs(ATR_SL_Short-last_open_shortCondition)/syminfo.mintick)), (abs((last_open_shortCondition*(1+(sl/100)))-last_open_shortCondition)/syminfo.mintick), iff(Act_sl and (SL_options == "BOTH") and ((abs((last_open_shortCondition*(1+(sl/100)))-last_open_shortCondition)/syminfo.mintick) > (abs(ATR_SL_Short-last_open_shortCondition)/syminfo.mintick)), (abs(ATR_SL_Short-last_open_shortCondition)/syminfo.mintick), na))))) : na, stop = Act_Conf_SL == false and nShorts >= 1 ? (iff(Act_sl and (SL_options == "NORMAL"), ((1+(sl/100))*strategy.position_avg_price), iff(Act_sl and (SL_options == "ATR"), ATR_SL_Short, iff(Act_sl and (SL_options == "BOTH") and (((1+(sl/100))*strategy.position_avg_price) < ATR_SL_Short), ((1+(sl/100))*strategy.position_avg_price), iff(Act_sl and (SL_options == "BOTH") and (((1+(sl/100))*strategy.position_avg_price) > ATR_SL_Short), ATR_SL_Short, na))))) : na) // Canceling short exit orders to avoid simultaneity with re-entry strategy.cancel("Tps", when = Final_short_BB) // βββββ Closing all positions with Xlong/Xshort strategy.close_all(when = (Final_Long_sl and Act_Conf_SL) or (Final_Short_sl and Act_Conf_SL)) // -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- // // ββββββββββββββββββββ by Xaviz