888 BOT v4 adalah strategi perdagangan otomatis yang menggabungkan beberapa indikator untuk membuat penilaian tren dan mengirimkan sinyal perdagangan. Ini menggunakan kombinasi dari 8 indikator, seperti rata-rata, filter interval, ADX, SAR parallax, RSI, MACD, dan Brin band, untuk mengirimkan sinyal perdagangan yang lebih andal.
Jalur rata-rata Jurik (JMA): Sebuah garis rata yang dirancang oleh Mark Jurik untuk para profesional untuk menghilangkan lag sinyal, dengan panjang lambung lambung parameter yang dapat dikontrol untuk menghilangkan kebisingan, lambung fase lambung dan lambung parameter yang dapat menyeimbangkan lag dan overflow.
Filter spasialDengan menghitung rentang fluktuasi harga rata-rata dalam jangka waktu tertentu, dan memperbesar rentang tersebut, untuk menghilangkan kebisingan pasar, lebih baik menilai tren jangka pendek.
Indikator arah rata-rata ((ADX)Dibuat oleh Wilder, ADX mengukur kekuatan dan arah tren. ADX memiliki kemiringan positif dan telah melampaui penurunan selama beberapa waktu, menunjukkan pergerakan harga yang kuat.
Hentikan Kerugian Garis Parabola (SAR): juga diciptakan oleh Wilder, menempatkan titik untuk menilai tren, ketika harga menyentuh indikator akan melompat ke sisi lain dari harga, membentuk bentuk garis paralel.
RSI Berjangka: Menambahkan parameter volume perdagangan berdasarkan RSI klasik, sehingga lebih akurat mencerminkan tren pasar.
MACDSebuah histogram dapat memprediksi persilangan garis rata-rata. MAC-Z menambahkan VWAP setelah standarisasi harga.
Kondisi volume transaksi: Filter volume transaksi di bawah sinyal rata-rata, dengan tingkat volume yang berbeda sesuai dengan leverage yang berbeda.
BeringinIndikator pita gelombang John Bollinger dapat digunakan sebagai peluang untuk masuk kembali.
Berdasarkan delapan indikator, masing-masing menentukan kondisi ruang kosong.
Setelah beberapa indikator dikonfirmasi, sinyal perdagangan dihasilkan, masuk ke posisi.
Set Stop Loss berdasarkan jumlah posisi dan parameter risiko.
Bila harga mencapai titik stop loss, maka posisi kosong akan keluar.
Ketika harga kembali menyentuh Brin Belt, ada kesempatan untuk mengambil posisi dan memperbaiki harga masuk.
Setelah setiap posisi kosong menunggu konfirmasi indikator, Anda dapat memasuki posisi baru lagi.
Keuntungan terbesar dari 888 BOT v4 adalah penggunaan kombinasi indikator, indikator yang berbeda dapat diverifikasi satu sama lain, mengurangi sinyal palsu, yang lebih andal daripada strategi indikator tunggal. Selain itu, memungkinkan penambahan posisi dan peningkatan harga masuk, dapat mengejar lebih banyak uang.
Secara khusus, ini adalah keuntungan:
JMA menghilangkan lag, filter spasial untuk menghilangkan kebisingan, meningkatkan kualitas sinyal.
ADX menilai intensitas tren, dan SAR menilai arah parabola, sehingga masuk lebih akurat.
RSI dan MACD menambahkan lebih banyak informasi pasar, sinyal verifikasi multi-lapisan.
Kondisi volume transaksi dapat memfilter sinyal palsu, dengan tingkat volume yang berbeda sesuai dengan leverage.
Stop loss dapat dipilih dari stop loss, stop loss ATR, atau double stop loss, untuk mengendalikan risiko penurunan.
Hal ini memungkinkan untuk meningkatkan harga masuk melalui Bollinger Bands, untuk mendapatkan keuntungan yang lebih besar.
Anda dapat memilih untuk membagi stop loss, keseimbangan profit dan probabilitas profit.
Anda dapat memilih periode dan pasangan perdagangan untuk melakukan pengujian ulang dan mengevaluasi efektivitas strategi.
Meskipun 888 BOT v4 mengurangi risiko melalui kombinasi indikator dan optimasi parameter, ada risiko tertentu dalam strategi perdagangan apa pun, terutama termasuk:
Probabilitas indikator mengirimkan sinyal yang salah, parameter dapat disesuaikan dengan tepat untuk mengurangi.
Untuk menghindari risiko kerugian yang lebih besar setelah menginvestasikan, optimasi harga masuk dapat dikurangi.
Peningkatan kerugian bila BRI tidak dipicu, dapat bekerja sama dengan indikator tren untuk menentukan kapan harus menaikkan posisi.
Stop loss adalah risiko yang terlalu longgar, dan dapat dikurangi sesuai dengan stop loss.
Waktu pengembalian tidak cukup, dapat diperluas siklus pengembalian untuk verifikasi.
Tidak cukup volume transaksi, penyesuaian ukuran posisi.
Jenkinson: Manajemen risiko yang baik diperlukan dalam situasi khusus yang tidak efektif
888 BOT v4 juga memiliki ruang untuk optimasi:
Menyesuaikan parameter indikator untuk mencari kombinasi optimal.
Cobalah untuk menggantikan indikator lain, seperti KDJ, indikator getaran, dll.
Optimalkan harga tiket masuk.
Adaptasi algoritma Stop Loss.
Setel Stop Stop dan Hentikan Kerugian.
Optimalkan ukuran posisi dan ukuran leverage.
Cobalah untuk mengoptimalkan metode seperti pembelajaran mesin.
Meningkatkan kondisi absensi, menghindari situasi tertentu.
Cobalah Arbitrage lintas pasar.
Mengembangkan antarmuka grafis untuk meningkatkan kemudahan penggunaan.
Secara keseluruhan, 888 BOT v4 adalah contoh dari strategi multi-indikator, yang secara signifikan meningkatkan probabilitas keuntungan melalui perdagangan kombinasi indikator. Namun, tidak ada strategi yang dapat mengemas dunia, perlu terus-menerus diuji dan dioptimalkan, melakukan manajemen risiko yang baik, agar tetap menguntungkan.
/*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