888 BOT v4는 여러 지표가 결합되어 트렌드 판단과 거래 신호를 발산하는 자동 거래 전략이다. 그것은 평행선, 간격 필터, ADX, 패러폴리 라인 SAR, 리지드 RSI, MACD 및 브린 밴드 등 8가지 지표의 조합을 사용하여 더 신뢰할 수 있는 거래 신호를 발산한다.
Jurik 평균선 (JMA): Mark Jurik이 전문가들을 위해 설계한 신호 지연을 제거하는 평균선으로, 길이 파라미터가 잡음을 제거할 수 있고, 단계 과 파라미터가 지연과 오버포를 균형을 잡을 수 있다.
공간 필터: 한 기간 동안의 평균 가격 변동 범위를 계산하고 그 범위를 확대하여 시장 소음을 제거하여 단기 경향을 더 잘 판단한다.
평균 방향 지표 ((ADX): 와일더에 의해 만들어졌으며, 트렌드의 강도와 방향을 측정한다. ADX는 긍정적인 경사선이며, 하락값을 한동안 넘어서서, 가격 운동이 강하다는 것을 나타낸다.
패러블라인 상쇄 (SAR): 또 와일더가 만든 것인데, 동향을 판단하기 위해 지점을 배치하고, 가격이 지표에 닿을 때 가격의 다른 쪽으로 점프하여 패러폴리 라인 모양을 만든다.
RSI 주파수: 고전적인 RSI 기반의 거래량 변수를 추가하여 시장의 흐름을 더 정확하게 반영합니다.
MACD:Appel이 만든 급속한 평균선 차차 지표, 히스토그램은 평균선 교차를 미리 판단할 수 있다. MAC-Z가 가격을 표준화한 후 VWAP 계산에 포함한다.
거래량 조건: 필터링 거래량은 평균보다 낮은 신호, 다른 양 수준은 다른 레버리지를 대응한다.
브린 벨트존 볼링거의 파동폭 지표는 재입장 기회로 사용된다.
여덟 가지 지표의 상황에 따라 각각 빈 공간 조건이 결정된다.
다중 지표 확인 후 트레이드 신호를 생성하여 포지션에 들어갑니다.
포지션 수와 위험 변수에 따라 스톱 스톱 손실을 설정하십시오.
가격이 스톱 스톱로스 지점에 도달했을 때, 평점 포지션은 출발한다.
가격이 다시 브린에 도달하면, 입찰 가격을 개선할 수 있는 기회를 얻을 수 있다.
매번 평소된 후에 다시 지표 확인을 기다린 다음, 다시 새로운 포지션에 들어갈 수 있다.
888 BOT v4의 가장 큰 장점은 지표의 집합을 사용하는 데 있습니다. 서로 다른 지표는 서로 확인 할 수 있으며, 가짜 신호를 줄일 수 있습니다. 이것은 단일 지표 전략보다 더 신뢰할 수 있습니다. 또한, 더 많은 돈을 쫓을 수있는 입금 및 입금 가격을 개선 할 수 있습니다.
특히, 다음과 같은 장점이 있습니다:
JMA는 지연을 제거하고, 간격 필터는 소음을 제거하고, 신호 품질을 향상시킨다.
ADX는 트렌드 강도를 판단하고, 패러블 라인 SAR는 방향을 판단하여 진입을 더 정확하게 한다.
RSI와 MACD에 더 많은 시장 정보를 추가하여 여러 계층의 검증 신호를 제공합니다.
거래량 조건은 가짜 신호를 필터링할 수 있으며, 다른 양 수준은 레버리지를 대응한다.
스톱 손실 방식은 위험 스톱, ATR 스톱 또는 더블 스톱을 선택하여 하락 위험을 제어 할 수 있습니다.
부린을 통해 입찰 가격을 개선하고 더 큰 수익을 추구할 수 있습니다.
이자리를 분할할 수 있고, 이윤과 이윤 확률을 균형을 잡을 수 있다.
전략의 효과를 평가하기 위해 선택적으로 시간 분기 및 거래 쌍을 재검토할 수 있다.
888 BOT v4는 지표 조합과 변수 최적화를 통해 위험을 감소시키지만, 거래 전략에는 다음과 같은 위험이 있습니다.
지표가 잘못된 신호를 보내는 확률을 줄이기 위해 적절한 변수를 조정할 수 있다.
입금 후 손실이 확대되는 위험을 방지하기 위해 입금 가격 최적화를 낮출 수 있습니다.
부린 띠가 발동되지 않은 상태에서 손실이 확대되면, 트렌드 지표와 함께 부팅 시점을 판단할 수 있다.
너무 느슨하게 덮여 있는 위험을 막기 위해, 적절히 줄일 수 있다.
재검토 시간이 부족하여 재검토 주기를 확장하여 검증할 수 있다.
거래량이 부족해서 포지션 규모를 조정해야 합니다.
“특별한 상황에서는 효과가 없어서 위험 관리에 주의를 기울여야 한다”. 젠킨슨
888 BOT v4에는 몇 가지 개선 사항이 있습니다.
지표 변수를 조정하여 최적의 조합을 찾습니다.
KDJ, 진동 지표 등과 같은 다른 지표를 대체해 보세요.
최적화 입점 가격 최적화
정지 손실 알고리즘을 조정하십시오.
정지 후 손해배상보장
포지션 규모와 레버리지 크기를 최적화하십시오.
기계학습과 같은 방법을 사용해 자동적으로 최적화하십시오.
“이번 경기에서 더 많은 선수들이 출전할 수 있도록 해야 한다”고 강조했다.
크로스 마켓 중개로 시도해 보세요.
그래픽 인터페이스를 개발하여 사용 편의성을 향상시킵니다.
종합적으로, 888 BOT v4는 다중 지표 전략의 전형적인 대표자이며, 지표 포트폴리오 거래를 통해 수익 가능성을 크게 향상시킬 수 있다. 그러나 어떤 전략도 천하를 포장 할 수 없으며, 지속적인 테스트와 최적화, 위험 관리를 잘해야 지속적으로 수익을 올릴 수 있다.
/*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