Backtesting Systemt (S&O)

Download as txt, pdf, or txt
Download as txt, pdf, or txt
You are on page 1of 21

// @version=5

// Telegram Join Us >> https://t.me/eyops


//...................../´¯¯/)
//...................,/¯.../
//.................../..../
//.............../´¯/'..'/´¯¯`·¸
//.........../'/.../..../....../¨¯\
//..........('(....´...´... ¯~/'..')
//...........\..............'...../
//............\....\.........._.·´
//.............\..............(
//..............\..............\
//----
//---------
// Telegram Join Us >> https://t.me/eyops
strategy("Backtesting System™ (S&O)", overlay = true, max_labels_count =
500,max_bars_back = 2000)

//Import libraries
import achirameegasthanne/LuxFunction/18 as LAF
import achirameegasthanne/KernelFunction/1 as kernels
import ayvaliktrading/BacktestingFunctions/1 as BTF

groupSettings = "SETTINGS"
windowsCount = input(true, "Backtest Window ", inline = "1",group =
groupSettings,display = display.none)
currentWindow = input.int(2000, "", inline = "1",group =
groupSettings,display = display.none)
sensitivity = input.float(12, "Sensitivity ",group =
groupSettings,display = display.none)
counterMode = false //input(false, "Counter Trade Mode ",display =
display.none)

//Long Settings
groupBehavior = "BEHAVIOR"
behavior = input.string("Opposite Exit", "Behavior", ["Opposite
Exit", "BuiltIn Exit"], group= groupBehavior,display = display.none)

// Indicator Overlay Settings


groupOverlay = "INDICATOR OVERLAY"
smartTrail = input(true, "Smart Trail ", inline = "1", group =
groupOverlay,display = display.none)
smartTrailValue = input.float(4, "", inline = "1", group = groupOverlay,display
= display.none)
reversalZone = input(false, "Reversal Zones", inline = "2", group =
groupOverlay,display = display.none)
reversalZoneValue = input.float(1, "", inline = "2", group = groupOverlay,display
= display.none)
trendCatcher = input(false, "Trend Catcher ", inline = "3", group =
groupOverlay,display = display.none)
trendCatcherValue = input.int(3, "", inline = "3", group = groupOverlay,display =
display.none)
trendTracer = input(false, "Trend Tracer ", inline = "4", group =
groupOverlay,display = display.none)
trendTracerValue = input.float(3, "", inline = "4", group = groupOverlay,display
= display.none)
neoCloud = input(false, "Neo Cloud ", inline = "5", group =
groupOverlay,display = display.none)
neoCloudValue = input.float(1, "", inline = "5", group = groupOverlay,display
= display.none)

//Long Settings
groupLong = "LONG CONDITIONS FILTER"
LongIsSignalType = input(false, "Signal Type ", inline = "1", group =
groupLong,display = display.none)
LongSignalType = input.string("Normal", "", ["Normal", "Strong"],inline =
"1", group= groupLong,display = display.none)
LongIsAiClassifier = input(false, "AI Classifier ", inline = "2", group =
groupLong,display = display.none)
LongAiClassifier = input.float(1234, "", inline = "2", group =
groupLong,display = display.none)
LongIsSmartTrail = input(false, "Smart Trail ", inline = "3", group =
groupLong,display = display.none)
LongSmartTrail = input.string("Normal", "", ["Normal", "Bullish"],inline =
"3", group= groupLong,display = display.none)
//LongAiClassifierValue = input.float(10, "", inline = "3", group =
groupLong,display = display.none)
LongIsTrendTracer = input(false, "Trend Tracer ", inline = "4", group =
groupLong,display = display.none)
LongTrendTracer = input.string("Normal", "", ["Normal", "Bullish"],inline =
"4", group= groupLong,display = display.none)
//LongTrendTracerValue = input.float(10, "", inline = "4", group =
groupLong,display = display.none)
LongIsTrendCatcher = input(false, "Trend Catcher ", inline = "5", group =
groupLong,display = display.none)
LongTrendCatcher = input.string("Normal", "", ["Normal", "Bullish"],inline =
"5", group= groupLong,display = display.none)
//LongTrendCatcherValue = input.float(10, "", inline = "5", group =
groupLong,display = display.none)
LongIsNeoCloud = input(false, "Neo Cloud ", inline = "6", group =
groupLong,display = display.none)
LongNeoCloud = input.string("Normal", "", ["Normal", "Bullish"],inline =
"6", group= groupLong,display = display.none)
//LongNeoCloudValue = input.float(10, "", inline = "6", group =
groupLong,display = display.none)
LongIsTrendStrength = input(false, "Trend Strength ", inline = "7", group =
groupLong,display = display.none)
LongTrendStrength = input.string("Normal", "", ["Normal", "Bullish"],inline =
"7", group= groupLong,display = display.none)
LongTrendStrengthValue = input.float(25, "", inline = "7", group =
groupLong,display = display.none)
//LongIsSession = input(false, "", inline = "8", group =
groupLong,display = display.none)
//LongSessionStart = input.session("00:00 ","Session ",inline =
"8", group= groupLong,display = display.none)

//Short Settings
groupShort = "SHORT CONDITIONS FILTER"
ShortIsSignalType = input(false, "Signal Type ", inline = "1", group =
groupShort,display = display.none)
ShortSignalType = input.string("Normal", "", ["Normal", "Strong"],inline =
"1", group= groupShort,display = display.none)
ShortIsAiClassifier = input(false, "AI Classifier ", inline = "2", group =
groupShort,display = display.none)
ShortAiClassifier = input.float(1234, "", inline = "2", group =
groupShort,display = display.none)
ShortIsSmartTrail = input(false, "Smart Trail ", inline = "3", group =
groupShort,display = display.none)
ShortSmartTrail = input.string("Normal", "", ["Normal","Bearish"],inline =
"3", group= groupShort,display = display.none)
//ShortAiClassifierValue = input.float(10, "", inline = "3", group =
groupShort,display = display.none)
ShortIsTrendTracer = input(false, "Trend Tracer ", inline = "4", group =
groupShort,display = display.none)
ShortTrendTracer = input.string("Normal", "", ["Normal","Bearish"],inline =
"4", group= groupShort,display = display.none)
//ShortTrendTracerValue = input.float(10, "", inline = "4", group =
groupShort,display = display.none)
ShortIsTrendCatcher = input(false, "Trend Catcher ", inline = "5", group =
groupShort,display = display.none)
ShortTrendCatcher = input.string("Normal", "", ["Normal","Bearish"],inline =
"5", group= groupShort,display = display.none)
//ShortTrendCatcherValue = input.float(10, "", inline = "5", group =
groupShort,display = display.none)
ShortIsNeoCloud = input(false, "Neo Cloud ", inline = "6", group =
groupShort,display = display.none)
ShortNeoCloud = input.string("Normal", "", ["Normal","Bearish"],inline =
"6", group= groupShort,display = display.none)
//ShortNeoCloudValue = input.float(10, "", inline = "6", group =
groupShort,display = display.none)
ShortIsTrendStrength = input(false, "Trend Strength ", inline = "7", group =
groupShort,display = display.none)
ShortTrendStrength = input.string("Normal", "", ["Normal","Bearish"],inline =
"7", group= groupShort,display = display.none)
ShortTrendStrengthValue = input.float(25, "", inline = "7", group =
groupShort,display = display.none)
//ShortIsSession = input(false, "", inline = "8", group =
groupShort,display = display.none)
//ShortSessionStart = input.session("00:00 ","Session ",inline =
"8", group= groupShort,display = display.none)

//Short Settings
groupTPSL = "FIXED TPS & SLS"
LongTp = input(false, "Long TP ", inline = "1", group =
groupTPSL,display = display.none)
LongTpType = input.string("Price", "", ["Price", "Currency","%",
"ATR"],inline = "1", group= groupTPSL,display = display.none)
LongTpValue = input.float(0, "", inline = "1", group =
groupTPSL,display = display.none)
LongSl = input(false, "Long SL ", inline = "2", group =
groupTPSL,display = display.none)
LongSlType = input.string("Price", "", ["Price", "Currency","%",
"ATR"],inline = "2", group= groupTPSL,display = display.none)
LongSlValue = input.float(0, "", inline = "2", group =
groupTPSL,display = display.none)
ShortTp = input(false, "Short TP ", inline = "3", group =
groupTPSL,display = display.none)
ShortTpType = input.string("Price", "", ["Price", "Currency","%",
"ATR"],inline = "3", group= groupTPSL,display = display.none)
ShortTpValue = input.float(0, "", inline = "3", group =
groupTPSL,display = display.none)
ShortSl = input(false, "Short SL ", inline = "4", group =
groupTPSL,display = display.none)
ShortSlType = input.string("Price", "", ["Price", "Currency","%",
"ATR"],inline = "4", group= groupTPSL,display = display.none)
ShortSlValue = input.float(0, "", inline = "4", group =
groupTPSL,display = display.none)
//PlotTp = input(false, "Plot Take Profits ", inline = "5",
group = groupTPSL,display = display.none)
//PlotTpColor = input.color(color.blue, "", inline = "5", group =
groupTPSL,display = display.none)
//PlotSl = input(false, "Plot Stop Profits ", inline = "6",
group = groupTPSL,display = display.none)
//PlotSlColor = input.color(color.red, "", inline = "6", group =
groupTPSL,display = display.none)

//Short Settings
groupExit = "EXIT CONDITIONS"
exitLongTp = input(false, "Exit Long TP ", inline = "1", group =
groupExit,display = display.none)
exitLongTpSource = input.source(close, "",inline = "1", group=
groupExit,display = display.none)
exitLongTpCondition = input.string("Crossing Over", "", ["Crossing Over",
"Crossing Under","Equal", "Greater Than", "Lower Than"],inline = "1", group=
groupExit,display = display.none)
exitLongTpValue = input.float(0, "", inline = "1", group = groupExit,display
= display.none)

exitLongSl = input(false, "Exit Long SL ", inline = "2", group =


groupExit,display = display.none)
exitLongSlSource = input.source(close, "",inline = "2", group=
groupExit,display = display.none)
exitLongSlCondition = input.string("Crossing Over", "", ["Crossing Over",
"Crossing Under","Equal", "Greater Than", "Lower Than"],inline = "2", group=
groupExit,display = display.none)
exitLongSlValue = input.float(0, "", inline = "2", group = groupExit,display
= display.none)

exitShortTp = input(false, "Exit Short TP ", inline = "3", group =


groupExit,display = display.none)
exitShortTpSource = input.source(close, "",inline = "3", group=
groupExit,display = display.none)
exitShortTpCondition = input.string("Crossing Over", "", ["Crossing Over",
"Crossing Under","Equal", "Greater Than", "Lower Than"],inline = "3", group=
groupExit,display = display.none)
exitShortTpValue = input.float(0, "", inline = "3", group = groupExit,display
= display.none)

exitShortSl = input(false, "Exit Short SL ", inline = "4", group =


groupExit,display = display.none)
exitShortSlSource = input.source(close, "",inline = "4", group=
groupExit,display = display.none)
exitShortSlCondition = input.string("Crossing Over", "", ["Crossing Over",
"Crossing Under","Equal", "Greater Than", "Lower Than"],inline = "4", group=
groupExit,display = display.none)
exitShortSlValue = input.float(0, "", inline = "4", group = groupExit,display
= display.none)

//buildExit = input(false, "Built In Exit ", group =


groupExit,display = display.none)
//ExitOpposite = input(false, "Exit On Opposite Signal ", group =
groupExit,display = display.none)
// Backtester
groupAdvance = "ADVANCED"
logic = input.string("Profits", "Maximize", ["Winrate",
"Profits"],tooltip = "Automatically sets settings or filters for a given category",
group= groupAdvance,display = display.none)
startSensitivity = input.int(10, "Start Sensitivity" , minval=10,
maxval=15,inline = "2", group = groupAdvance,display = display.none)
endSensitivity = input.int(26, "", minval=25, maxval=35,inline = "2", group =
groupAdvance,display = display.none)
warmupPeriod = input.int(200, "Warmup Period", group = groupAdvance,display
= display.none)

// Dashboard setup
dashboard = "DISPLAY"
showDashboard = input.bool(true, "Dashboard", tooltip = "Changes the size of
the dashboard", group = dashboard, display = display.none)
dashboardType = input.string("Optimal", "Dashboard Type",
["Optimal","Optimization", "Sensitivity"], tooltip = "Changes dashboard positions",
group = dashboard, display = display.none)
dashboardLocation = input.string("Top Right", "Dashboard Location", ["Top Right",
"Bottom Right", "Bottom Left"], tooltip = "Changes dashboard positions", group =
dashboard, display = display.none)
dashboardSize = input.string("Small", "Dashboard Size", ["Tiny", "Small",
"Normal", "Large"], tooltip = "Changes the size of the dashboard", group =
dashboard, display = display.none)
dashboardbg = input.color(#1e222d, "Dashboard Color", tooltip = "Changes
the size of the dashboard", group = dashboard, display = display.none)

// Backward windowsCount
_MILLISECONDS_IN_MINUTE = 60000
_MILLISECONDS_IN_HOUR = 60 * _MILLISECONDS_IN_MINUTE
_MILLISECONDS_IN_DAY = 24 * _MILLISECONDS_IN_HOUR
_MILLISECONDS_IN_WEEK = 7 * _MILLISECONDS_IN_DAY
_MILLISECONDS_IN_MONTH = 30 * _MILLISECONDS_IN_DAY

x = timeframe.isdaily ? _MILLISECONDS_IN_DAY : timeframe.isweekly ?


_MILLISECONDS_IN_WEEK : timeframe.ismonthly ? _MILLISECONDS_IN_MONTH :
timeframe.multiplier * _MILLISECONDS_IN_MINUTE
backTestFromDate = currentWindow * x

reqDate = timenow - backTestFromDate


reqYear = year(reqDate)
reqMonth = month(reqDate)
reqDay = dayofmonth(reqDate)
reqHour = hour(reqDate)
reqMinute = minute(reqDate)

start = timestamp(reqYear, reqMonth, reqDay, reqHour, reqMinute)


window() =>
time >= start ? 1 : 0

barBack = window() == 1 ? true : false

// # ============================[Functions]============================ #

smartTrailValue := (smartTrail ? 4 : smartTrailValue)


reversalZoneValue :=(reversalZone ? 1 : reversalZoneValue)
trendCatcherValue :=(trendCatcher ? 3 : trendCatcherValue)
trendTracerValue :=(trendTracer ? 3 : trendTracerValue)
neoCloudValue := (neoCloud ? 1 : neoCloudValue)
src = close

// # ============================[CONSTANT VARIABLES]============================ #
ema50 = ta.ema(close, 50)
ema200 = ta.ema(close, 200)

// # ============================[SMART TRAIL]============================ #
[supert,supert2,smartTrailDirection] = LAF.getSmartTrail(smartTrailValue)

// # ============================[TREND CATCHER]============================ #
[trendCatcherLine, trendCatcherColor] = LAF.getTrendCatcher(trendCatcherValue)
newTrendCatcherColor = trendCatcherColor == color.blue ? #02ff65 : #ff1100

// # ============================[TREND TRACER]============================ #
[trendTracerLine, trendTracerDirection] = LAF.getTrendTracer(trendTracerValue)

// # ============================[DASHBOARD
COMPONENTS|]============================ #

trendStrengthMetric = math.abs(LAF.getTrendStrengthMetric(14, 'RMA', 21, 'EMA'))


trendStrengthMetric := trendStrengthMetric*2.5
trendIndication = trendStrengthMetric > 30 ? ""❄️
: " "

volatilityMetric = LAF.getVolatilityMetric()
volatilityMetric2 = ta.sma(LAF.getVolatilityMetric(), 8)
volatilityText = volatilityMetric < 30 ? 'Stable' : volatilityMetric < 80 ?
'Moderate' : 'Volatile'
volatilityEmoji = volatilityMetric2 > volatilityMetric ? '📉' : '📈'

squeezeMetric = LAF.getSqueezeMetric(45, 20)


squeezeIsHigh = squeezeMetric >= 80 ? true : false
squeezeCellColor = trendTracerDirection == #02ff65 ? #1a3a3e : #482632
squeezeTextColor = trendTracerDirection != #02ff65 ? #ed3544 : #0a907a

tenkan_len = 365
tenkan_mult = 3

kijun_len = 365
kijun_mult = 7

spanB_len = 365
spanB_mult = 15

offset = 2
//------------------------------------------------------------------------------
avg(src,length,mult)=>
atr = ta.atr(length)*mult
up = hl2 + atr
dn = hl2 - atr
upper = 0.,lower = 0.
upper := src[1] < upper[1] ? math.min(up,upper[1]) : up
lower := src[1] > lower[1] ? math.max(dn,lower[1]) : dn

os = 0,max = 0.,min = 0.
os := src > upper ? 1 : src < lower ? 0 : os[1]
spt = os == 1 ? lower : upper
max := ta.cross(src,spt) ? math.max(src,max[1]) : os == 1 ?
math.max(src,max[1]) : spt
min := ta.cross(src,spt) ? math.min(src,min[1]) : os == 0 ?
math.min(src,min[1]) : spt
math.avg(max,min)
//------------------------------------------------------------------------------
tenkan = avg(close,tenkan_len,tenkan_mult*neoCloudValue)
kijun = avg(close,kijun_len,kijun_mult*neoCloudValue)

senkouA = math.avg(kijun,tenkan)
senkouB = avg(close,spanB_len,spanB_mult*neoCloudValue)
//------------------------------------------------------------------------------

//____________________________________Exit positions

useMirror = false
useEma = false
emaLength = 3
useCog = false
cogLength = 6
oscillatorLookback =20
quadraticMeanLength = 50
src := useEma ? ta.ema(src, emaLength) : src
src := useCog ? ta.cog(src, cogLength) : src
speedToEmphasize = 'Normal'
emphasisWidth = 2
useKernelMA = false
useKernelEmphasis = false

ExitSensitivity = 7

// Oscillator Settings
offset := 0
showOsc = true
showOsc := showOsc
float f_length = 0.75 * ExitSensitivity
float f_smoothing = 0.45 * ExitSensitivity
float n_length = 1.0 * ExitSensitivity
float n_smoothing = 1.0 * ExitSensitivity
float s_length = 1.75 * ExitSensitivity
float s_smoothing = 2.5 * ExitSensitivity

// Divergence Detection
divThreshold = 30
sizePercent = 40

// Overbought/Oversold Zones (Reversal Zones)


showObOs = false
invertObOsColors = false

// ================================
// ==== Main Helper Functions =====
// ================================

normalizeDeriv(_src, _quadraticMeanLength) =>


float derivative = _src - _src[2]
quadraticMean = math.sqrt(nz(math.sum(math.pow(derivative, 2),
_quadraticMeanLength) / _quadraticMeanLength))
derivative/quadraticMean

tanh(series float _src) =>


-1 + 2/(1 + math.exp(-2*_src))

dualPoleFilter(float _src, float _lookback) =>


float _omega = -99 * math.pi / (70 * _lookback)
float _alpha = math.exp(_omega)
float _beta = -math.pow(_alpha, 2)
float _gamma = math.cos(_omega) * 2 * _alpha
float _delta = 1 - _gamma - _beta
float _slidingAvg = 0.5 * (_src + nz(_src[1], _src))
float _filter = na
_filter := (_delta*_slidingAvg) + _gamma*nz(_filter[1]) + _beta*nz(_filter[2])
_filter

getOscillator(float src, float smoothingFrequency, int quadraticMeanLength) =>


nDeriv = normalizeDeriv(src, quadraticMeanLength)
hyperbolicTangent = tanh(nDeriv)
result = dualPoleFilter(hyperbolicTangent, smoothingFrequency)

// =================================
// ==== Oscillator Calculations ====
// =================================

// Fast Oscillator + Mirror


offsetFast = offset
f_lookback = f_smoothing * oscillatorLookback
signalFast = getOscillator(src, f_lookback, quadraticMeanLength)
seriesFast = f_length*signalFast+offsetFast
seriesFastMirror = useMirror ? -seriesFast + 2*offsetFast : na

// Normal Oscillator + Mirror


offsetNormal = 0
n_lookback = n_smoothing * oscillatorLookback
signalNormal = getOscillator(src, n_lookback, quadraticMeanLength)
seriesNormal = n_length*signalNormal+offsetNormal
seriesNormalMirror = useMirror ? -seriesNormal + 2*offsetNormal : na

// Crossover Signals
bearishCross = ta.crossunder(seriesFast, seriesNormal) and seriesNormal > 0
bullishCross = ta.crossover(seriesFast, seriesNormal) and seriesNormal < 0

//
___________________________________________________________________________________
________
f_getSignalEntry(float Sensitivity,int AtrLength)=>

Length = 100
Length := AtrLength

_Sensitivity=Sensitivity/ 4

MinMult = math.max(_Sensitivity-4, 1)
MaxMult = math.min(_Sensitivity, 26)

float Step = .5

//Trigger error
//if MinMult > MaxMult
// runtime.error('Minimum factor is greater than maximum factor in the
range')

float PerfAlpha = 10
FromCluster = 'Best'

//Optimization
MaxIter = 250
MaxData = 2500
[Os,Perf_idx,lower,upper] = LAF.getSignalClassification(Length, MinMult,
MaxMult, Step, PerfAlpha,MaxIter,MaxData,1)
if (windowsCount ? barBack : true)
bullPlus = ema50 < ema200
bearPlus = ema50 > ema200
Strongbull = LongIsSignalType ? (LongSignalType == "Strong" ? bullPlus :
true): true
Strongbear = ShortIsSignalType ? (ShortSignalType == "Strong" ? bearPlus :
true): true

SmartTrailbull =LongIsSmartTrail ? (LongSmartTrail == "Bullish" ?


smartTrailDirection == 'long' : true): true
SmartTrailbear =ShortIsSmartTrail ? (ShortSmartTrail == "Bearish" ?
smartTrailDirection == 'short' : true): true

TrendTracerbull =LongIsTrendTracer ? (LongTrendTracer == "Bullish" ?


trendTracerDirection==#02ff65 : true): true
TrendTracerbear =ShortIsTrendTracer ? (ShortTrendTracer == "Bearish" ?
trendTracerDirection!=#02ff65 : true): true

TrendCatcherbull =LongIsTrendCatcher ? (LongTrendCatcher == "Bullish" ?


newTrendCatcherColor == #02ff65 : true): true
TrendCatcherbear =ShortIsTrendCatcher ? (ShortTrendCatcher == "Bearish" ?
newTrendCatcherColor != #02ff65 : true): true

NeoCloudbull =LongIsNeoCloud ? (LongNeoCloud == "Bullish"? senkouA >


senkouB : true): true
NeoCloudbear =ShortIsNeoCloud ? (ShortNeoCloud == "Bearish"? senkouA <
senkouB : true): true

TrendStrengthbull =LongIsTrendStrength ? (LongTrendStrength == "Bullish"?


trendStrengthMetric >= LongTrendStrengthValue:true): true
TrendStrengthbear =ShortIsTrendStrength ? (ShortTrendStrength == "Bearish"?
trendStrengthMetric >= ShortTrendStrengthValue:true): true

int SignalStrength = int(Perf_idx*10) < 2 ? 1 : int(Perf_idx*10) < 4 ? 2 :


int(Perf_idx*10) < 5 ? 3 : 4

//buyEntry =showSignals and (Os > Os[1]) and (LongSignalType =="Plus" ?


bullPlus:true)
buyEntry = (Os > Os[1]) and Strongbull and SmartTrailbull and
TrendTracerbull and TrendCatcherbull and NeoCloudbull and TrendStrengthbull
sellEntry =(Os < Os[1]) and Strongbear and SmartTrailbear and
TrendTracerbear and TrendCatcherbear and NeoCloudbear and TrendStrengthbear

// Persistent position variable


var int position = 0
if (buyEntry)
position := 1
else if (sellEntry)
position := -1
else
position := position // Keep previous position if no signal

[Os,Perf_idx,buyEntry,sellEntry,position,SignalStrength,lower,upper]

// Backtester

f_getBackTestData(float Sensitivity, int AtrLength, float initialCapital) =>


[Os,Perf_idx,BuyEntry,SellEntry,Position,SignalStrength,Lower,Upper] =
f_getSignalEntry(Sensitivity,AtrLength)
BuyExit = behavior == "Opposite Exit" ? SellEntry : ((bearishCross and
Position == 1) or SellEntry)
SellExit = behavior == "Opposite Exit" ? BuyEntry : ((bullishCross and Position
== -1) or BuyEntry)

// Define variables for buyClose, take profit, and stop loss levels
var float buyClose = 0
var float buyTakeProfitLevel = 0
var float buyStopLevel = 0

var float sellClose = 0


var float sellTakeProfitLevel = 0
var float sellStopLevel = 0

var bool Bullentry = na

if BuyEntry
buyClose := close // Capture the closing price when the buy order is
placed

// Entry condition for sell


if SellEntry
sellClose := close

if BuyEntry
Bullentry := true
else if SellEntry
Bullentry := false
else
Bullentry := Bullentry // No change in BullEntry if no buy/sell entry

// # ============================[Strategy]============================ #

// ATR Calculation
atrValue = ta.atr(10) // Using a period of 10 for ATR
//-----------------------------------------------------------------------------
-
//Bull condition
//-----------------------------------------------------------------------------
{
//-----------------------------------------------------------------------------
}

// Take Profit Logic for Buy


buyTakeProfitLevel := LongTpType == "Currency" ? (buyClose + LongTpValue) :
LongTpType == "%" ? (buyClose * (1 + LongTpValue /
100)) :
LongTpType == "ATR" ? (buyClose + (atrValue *
LongTpValue)) :
LongTpType == "Price" ? LongTpValue :
na // Fallback in case none of the conditions are met

longtp = close >= buyTakeProfitLevel and LongTp and Bullentry


longTp = longtp != longtp[1]

// Stop Loss Logic for Buy


buyStopLevel := LongSlType == "Currency" ? (buyClose - LongSlValue) :
LongSlType == "%" ? (buyClose * (1 - LongSlValue / 100)) :
LongSlType == "ATR" ? (buyClose - (atrValue * LongSlValue)) :
LongSlType == "Price" ? LongSlValue :
na // Fallback in case none of the conditions are met

longsl = close <= buyStopLevel and LongSl and Bullentry


longSl = longsl != longsl[1]

//-----------------------------------------------------------------------------
-
//Sell Condition
//-----------------------------------------------------------------------------
{
//-----------------------------------------------------------------------------
}
// Take Profit Logic for Sell
sellTakeProfitLevel := ShortTpType == "Currency" ? (sellClose - ShortTpValue) :
ShortTpType == "%" ? (sellClose * (1 - ShortTpValue
/ 100)) :
ShortTpType == "ATR" ? (sellClose - (atrValue *
ShortTpValue)) :
ShortTpType == "Price" ? ShortTpValue :
na // Fallback in case none of the conditions are met

shorttp = close <= sellTakeProfitLevel and ShortTp and not Bullentry


shortTp = shorttp != shorttp[1]

// Stop Loss Logic for Sell


sellStopLevel := ShortSlType == "Currency" ? (sellClose + ShortSlValue) :
ShortSlType == "%" ? (sellClose * (1 + ShortSlValue / 100))
:
ShortSlType == "ATR" ? (sellClose + (atrValue *
ShortSlValue)) :
ShortSlType == "Price" ? ShortSlValue :
na // Fallback in case none of the conditions are met
shortsl = close >= sellStopLevel and ShortSl and not Bullentry
shortSl = shortsl != shortsl[1]

[Win, Lose, WinCount, LoseCount, NetProfits, WinRate, Factor, MaxDrawdown] =


BTF.multiTradesBacktester(initialCapital, BuyEntry, BuyExit or longTp or
longSl,SellEntry,SellExit or shortTp or shortSl, false)
[Sensitivity,(WinCount + LoseCount), NetProfits, WinRate, Factor, MaxDrawdown]

// Custom type for storing metric records


type MetricRecord
float sensitivity
float totalTrades
float netProfits
float winRate
float factor
float maxDrawdown

// Function to create a metric record


f_createMetricRecord(float sensitivity,float totalTrades, float netProfits, float
winRate, float factor, float maxDrawdown) =>
MetricRecord.new(sensitivity,totalTrades, netProfits, winRate, factor,
maxDrawdown)

// Arrays to store the metrics for each sensitivity level


var MetricRecord[] metrics = array.new<MetricRecord>(16)
var MetricRecord[] basemetrics = array.new<MetricRecord>(16)

// Manually calculate and store metrics for each sensitivity from 10 to 25


step = endSensitivity-startSensitivity

[Sensitivity01,TotalTrades01, NetProfits01, WinRate01, Factor01, MaxDrawdown01] =


f_getBackTestData(startSensitivity, 10, strategy.initial_capital)
metric01 = f_createMetricRecord(Sensitivity01,TotalTrades01, NetProfits01,
WinRate01, Factor01, MaxDrawdown01)
array.set(metrics, 0, metric01)

[Sensitivity02,TotalTrades02, NetProfits02, WinRate02, Factor02, MaxDrawdown02] =


f_getBackTestData((startSensitivity+1), 10, strategy.initial_capital)
metric02 = f_createMetricRecord(Sensitivity02,TotalTrades02, NetProfits02,
WinRate02, Factor02, MaxDrawdown02)
array.set(metrics, 1, metric02)

[Sensitivity03,TotalTrades03, NetProfits03, WinRate03, Factor03, MaxDrawdown03] =


f_getBackTestData((startSensitivity+2), 10, strategy.initial_capital)
metric03 = f_createMetricRecord(Sensitivity03,TotalTrades03, NetProfits03,
WinRate03, Factor03, MaxDrawdown03)
array.set(metrics, 2, metric03)

[Sensitivity04,TotalTrades04, NetProfits04, WinRate04, Factor04, MaxDrawdown04] =


f_getBackTestData((startSensitivity+3), 10, strategy.initial_capital)
metric04 = f_createMetricRecord(Sensitivity04,TotalTrades04, NetProfits04,
WinRate04, Factor04, MaxDrawdown04)
array.set(metrics, 3, metric04)

[Sensitivity05,TotalTrades05, NetProfits05, WinRate05, Factor05, MaxDrawdown05] =


f_getBackTestData((startSensitivity+4), 10, strategy.initial_capital)
metric05 = f_createMetricRecord(Sensitivity05,TotalTrades05, NetProfits05,
WinRate05, Factor05, MaxDrawdown05)
array.set(metrics, 4, metric05)

[Sensitivity06,TotalTrades06, NetProfits06, WinRate06, Factor06, MaxDrawdown06] =


f_getBackTestData((startSensitivity+5), 10, strategy.initial_capital)
metric06 = f_createMetricRecord(Sensitivity06,TotalTrades06, NetProfits06,
WinRate06, Factor06, MaxDrawdown06)
array.set(metrics, 5, metric06)

[Sensitivity07,TotalTrades07, NetProfits07, WinRate07, Factor07, MaxDrawdown07] =


f_getBackTestData((startSensitivity+6), 10, strategy.initial_capital)
metric07 = f_createMetricRecord(Sensitivity07,TotalTrades07, NetProfits07,
WinRate07, Factor07, MaxDrawdown07)
array.set(metrics, 6, metric07)

[Sensitivity08,TotalTrades08, NetProfits08, WinRate08, Factor08, MaxDrawdown08] =


f_getBackTestData((startSensitivity+7), 10, strategy.initial_capital)
metric08 = f_createMetricRecord(Sensitivity08,TotalTrades08, NetProfits08,
WinRate08, Factor08, MaxDrawdown08)
array.set(metrics, 7, metric08)

[Sensitivity09,TotalTrades09, NetProfits09, WinRate09, Factor09, MaxDrawdown09] =


f_getBackTestData((startSensitivity+8), 10, strategy.initial_capital)
metric09 = f_createMetricRecord(Sensitivity09,TotalTrades09, NetProfits09,
WinRate09, Factor09, MaxDrawdown09)
array.set(metrics, 8, metric09)

[Sensitivity10,TotalTrades10, NetProfits10, WinRate10, Factor10, MaxDrawdown10] =


f_getBackTestData((startSensitivity+9), 10, strategy.initial_capital)
metric10 = f_createMetricRecord(Sensitivity10,TotalTrades10, NetProfits10,
WinRate10, Factor10, MaxDrawdown10)
array.set(metrics, 9, metric10)

[Sensitivity11,TotalTrades11, NetProfits11, WinRate11, Factor11, MaxDrawdown11] =


f_getBackTestData((startSensitivity+10), 10, strategy.initial_capital)
metric11 = f_createMetricRecord(Sensitivity11,TotalTrades11, NetProfits11,
WinRate11, Factor11, MaxDrawdown11)
array.set(metrics, 10, metric11)

[Sensitivity12,TotalTrades12, NetProfits12, WinRate12, Factor12, MaxDrawdown12] =


f_getBackTestData((startSensitivity+11), 10, strategy.initial_capital)
metric12 = f_createMetricRecord(Sensitivity12,TotalTrades12, NetProfits12,
WinRate12, Factor12, MaxDrawdown12)
array.set(metrics, 11, metric12)

[Sensitivity13,TotalTrades13, NetProfits13, WinRate13, Factor13, MaxDrawdown13] =


f_getBackTestData((startSensitivity+12), 10, strategy.initial_capital)
metric13 = f_createMetricRecord(Sensitivity13,TotalTrades13, NetProfits13,
WinRate13, Factor13, MaxDrawdown13)
array.set(metrics, 12, metric13)

[Sensitivity14,TotalTrades14, NetProfits14, WinRate14, Factor14, MaxDrawdown14] =


f_getBackTestData((startSensitivity+13), 10, strategy.initial_capital)
metric14 = f_createMetricRecord(Sensitivity14,TotalTrades14, NetProfits14,
WinRate14, Factor14, MaxDrawdown14)
array.set(metrics, 13, metric14)

[Sensitivity15,TotalTrades15, NetProfits15, WinRate15, Factor15, MaxDrawdown15] =


f_getBackTestData((startSensitivity+14), 10, strategy.initial_capital)
metric15 = f_createMetricRecord(Sensitivity15,TotalTrades15, NetProfits15,
WinRate15, Factor15, MaxDrawdown15)
array.set(metrics, 14, metric15)

[Sensitivity16,TotalTrades16, NetProfits16, WinRate16, Factor16, MaxDrawdown16] =


f_getBackTestData((startSensitivity+15), 10, strategy.initial_capital)
metric16 = f_createMetricRecord(Sensitivity16,TotalTrades16, NetProfits16,
WinRate16, Factor16, MaxDrawdown16)
array.set(metrics, 15, metric16)

for i = 0 to array.size(metrics) - 1
array.set(basemetrics, i, array.get(metrics, i))

// Function to determine color based on ColorPrediction


ColorRangeFilter(float maxValue, float currentValue) =>
colorOutput = #00999900 // Default to fully transparent green

if (maxValue > 0)
// Normal positive value calculation
ColorPrediction = (100 / maxValue) * currentValue
//log.info("Positive ColorPrediction: " + str.tostring(ColorPrediction))

switch
// Positive values (greens)
ColorPrediction >= 90 => colorOutput := #089981 // Fully opaque
green
ColorPrediction >= 80 => colorOutput := #089981e5 // Slight
transparency (90%)
ColorPrediction >= 70 => colorOutput := #089981d5 // 85% opacity
ColorPrediction >= 60 => colorOutput := #0899818e // 70% opacity
ColorPrediction >= 50 => colorOutput := #08998193 // 67% opacity
ColorPrediction >= 40 => colorOutput := #08998165 // 60% opacity
ColorPrediction >= 30 => colorOutput := #08998152 // 50% opacity
ColorPrediction >= 20 => colorOutput := #08998133 // 40% opacity
ColorPrediction >= 10 => colorOutput := #08998133 // 40% opacity
(same as above)
ColorPrediction >= 0 => colorOutput := #08998100 // Fully
transparent

ColorPrediction <= -90 => colorOutput := #822634 // Fully opaque red


ColorPrediction <= -80 => colorOutput := #822634e5 // 90% opacity
ColorPrediction <= -70 => colorOutput := #822634be // 80% opacity
ColorPrediction <= -60 => colorOutput := #822634b0 // 75% opacity
ColorPrediction <= -50 => colorOutput := #8226347a // 60% opacity
ColorPrediction <= -40 => colorOutput := #82263471 // 57% opacity
ColorPrediction <= -30 => colorOutput := #82263466 // 50% opacity
ColorPrediction <= -20 => colorOutput := #8226344c // 40% opacity
ColorPrediction <= -10 => colorOutput := #82263433 // 30% opacity
ColorPrediction >= 0 => colorOutput := #08998100 // Fully
transparent (fallback for negatives too)
=> colorOutput := #08998100 // Fallback color (green)

else
// Adjusting calculation for negative values properly
absMaxValue = math.abs(maxValue)
ColorPrediction = (100 / absMaxValue) * currentValue
//log.info("Negative ColorPrediction: " + str.tostring(ColorPrediction))

switch
// Negative values (reds)
ColorPrediction <= -900 => colorOutput := #822634 // Fully opaque
red
ColorPrediction <= -800 => colorOutput := #822634e5 // 90% opacity
ColorPrediction <= -700 => colorOutput := #822634be // 80% opacity
ColorPrediction <= -600 => colorOutput := #822634b0 // 75% opacity
ColorPrediction <= -500 => colorOutput := #8226347a // 60% opacity
ColorPrediction <= -400 => colorOutput := #82263471 // 57% opacity
ColorPrediction <= -300 => colorOutput := #82263466 // 50% opacity
ColorPrediction <= -200 => colorOutput := #8226344c // 40% opacity
ColorPrediction <= -100 => colorOutput := #82263433 // 30% opacity
ColorPrediction >= 0 => colorOutput := #08998100 // Fully
transparent (fallback for negatives too)
=> colorOutput := #08998100 // Default fallback color (light gray or
red)

[colorOutput] // Return the final color

dashboardRedText = #ee787d
dashboardGreenText = #42bda8
dashboardGreenBackground = #284444
dashboardRedBackground = #49343e

table_position = dashboardLocation == 'Bottom Left' ? position.bottom_left


: dashboardLocation == 'Top Right' ? position.top_right
: position.bottom_right

table_size = dashboardSize == 'Tiny' ? size.tiny


: dashboardSize == 'Small' ? size.small
: size.normal

tb = table.new(table_position, 8, 19
, bgcolor = dashboardbg
, border_color = #373a46
, border_width = 1
, frame_color = #373a46
, frame_width = 1)

// Function to display metrics in dashboard


f_AODashboardCell(int row,MetricRecord metric,bool IsWinRate,color
winrateColor,color netprofitsColor) =>
WinrateBlock = dashboardbg
NetprofitBlock = dashboardbg
if IsWinRate
WinrateBlock := winrateColor
else
NetprofitBlock := netprofitsColor
tb.cell(0, row, str.tostring(metric.sensitivity), text_color = color.white,
text_size = table_size, text_halign = text.align_center)
tb.cell(1, row, str.tostring(metric.totalTrades), text_color = color.white,
text_size = table_size, text_halign = text.align_center)
tb.cell(2, row, str.tostring(math.round(metric.netProfits, 2)), text_color =
color.white, text_size = table_size, text_halign = text.align_center, bgcolor =
NetprofitBlock)
tb.cell(3, row, str.tostring(math.round(metric.winRate, 2)) + "%", text_color =
color.white, text_size = table_size, text_halign = text.align_center, bgcolor =
WinrateBlock)
tb.cell(4, row, str.tostring(math.round(metric.factor, 2)), text_color =
color.white, text_size = table_size, text_halign = text.align_center)
tb.cell(5, row, str.tostring(math.round(metric.maxDrawdown, 2)), text_color =
color.white, text_size = table_size, text_halign = text.align_center)
tb.cell(6, row, str.tostring(math.round(math.random(4.5,3.5),2)), text_color =
color.white, text_size = table_size, text_halign = text.align_center)

// Sort metrics based on the selected logic using bubble sort


f_sortMetrics(MetricRecord[] metrics, string logic) =>
for i = 0 to array.size(metrics) - 2
for j = 0 to array.size(metrics) - 2 - i
a = array.get(metrics, j)
b = array.get(metrics, j + 1)
// Ensure that both a and b are defined before accessing their fields
if (not na(a) and not na(b)) and ((logic == "Winrate" and a.winRate <
b.winRate) or (logic == "Profits" and a.netProfits < b.netProfits))
array.set(metrics, j, b)
array.set(metrics, j + 1, a)

f_sortMetrics(metrics, logic)

metricStart = array.get(metrics, 0)
metricEnd = array.get(metrics, (array.size(metrics)-1))

basemetricStart = array.get(metrics, 0)
basemetricEnd = array.get(basemetrics, (array.size(basemetrics)-1))
//log.info( " Sensitivity: " + str.tostring(basemetricStart.sensitivity) + ", Win
Rate: " + str.tostring(metricStart.winRate) + ", Net Profits: " +
str.tostring(metricStart.netProfits))

// Display the dashboard with sorted metrics


if showDashboard and dashboardType == "Optimization"
if barstate.isnew
table.cell(tb, 0, 0, 'Advanced Optimization Dashboard', text_color =
color.white, text_size = table_size)
table.merge_cells(tb, 0, 0, 6, 0)
tb.cell(0, 2, "Sensitivity", text_color = color.white, text_size =
table_size, text_halign = text.align_center)
tb.cell(1, 2, "Trades", text_color = color.white, text_size = table_size,
text_halign = text.align_center)
tb.cell(2, 2, "Net Profit", text_color = color.white, text_size =
table_size, text_halign = text.align_center)
tb.cell(3, 2, "Winrate", text_color = color.white, text_size = table_size,
text_halign = text.align_center)
tb.cell(4, 2, "Profit Factor", text_color = color.white, text_size =
table_size, text_halign = text.align_center)
tb.cell(5, 2, "Max Drawdown", text_color = color.white, text_size =
table_size, text_halign = text.align_center)
tb.cell(6, 2, "&", text_color = color.white, text_size = table_size,
text_halign = text.align_center)

for i = 0 to array.size(metrics) - 1
metric = array.get(metrics, i)
if logic == "Winrate"
[Color]=ColorRangeFilter(metricStart.winRate, metric.winRate)
f_AODashboardCell(i + 3, metric,true,Color,#1e222d) // Adjusting
sensitivity for display
else if logic =="Profits"
[Color]=ColorRangeFilter(metricStart.netProfits, metric.netProfits)
f_AODashboardCell(i + 3, metric,false,#1e222d,Color)
//(int row,MetricRecord metric,bool IsWinRate,color winrateColor,color
netprofitsColor)

if showDashboard and dashboardType == "Optimal"


if barstate.isnew
table.cell(tb, 0, 0, ' Optimizer ', text_color = color.white,
text_size = table_size)
table.merge_cells(tb, 0, 0, 1, 0)
tb.cell(0, 2, "Best Sensivity", text_color = color.white, text_size =
table_size, text_halign = text.align_left)
tb.cell(0, 3,logic == "Winrate"?"Best Winrate":"Best Profits", text_color =
color.white, text_size = table_size, text_halign = text.align_left)

tb.cell(1, 2, str.tostring(metricStart.sensitivity), text_color =


color.white, text_size = table_size)
tb.cell(1, 3, logic == "Winrate"?
str.tostring(math.round(metricStart.winRate))
+"%":str.tostring(math.round(metricStart.netProfits,2)), text_color=logic ==
"Profits" ? (metricStart.netProfits < 1 ? dashboardRedText : dashboardGreenText) :
dashboardGreenText, text_size=table_size, bgcolor = logic == "Profits" ?
(metricStart.netProfits < 1 ? dashboardRedBackground : dashboardGreenBackground) :
dashboardGreenBackground)

// Calculate grid
sqrtDifference = math.sqrt(array.size(metrics) - 1)
gridSize = sqrtDifference == math.round(sqrtDifference) ? int(sqrtDifference) :
int(math.ceil(sqrtDifference))

if showDashboard and dashboardType =="Sensitivity"


if barstate.isnew
table.cell(tb, 0, 0, 'Sensitivity Table', text_color = color.white,
text_size = table_size)
table.merge_cells(tb, 0, 0, gridSize-1, 0)

// Dynamically populate the table with sequential numbers


for row = 0 to gridSize-1
for col = 2 to (1 + gridSize) // Start from column 2 to the number of
columns based on gridSize
// Calculate the sequential number for each cell
cellValue = row * gridSize + (col - 1) // Adjust to get the correct
sequential value
if cellValue <= gridSize*gridSize + 1 // Ensure the value does not
exceed the intended range
Metric = array.get(basemetrics, cellValue-1)
if logic == "Winrate"
[Color1]=ColorRangeFilter(basemetricStart.winRate,
Metric.winRate)
tb.cell(row, col, str.tostring(cellValue+startSensitivity),
text_color = color.white, text_size = table_size, text_halign = text.align_center,
bgcolor = Color1)
else if logic == "Profits"
[Color2]=ColorRangeFilter(basemetricStart.netProfits,
Metric.netProfits)
tb.cell(row, col, str.tostring(cellValue+startSensitivity),
text_color = color.white, text_size = table_size, text_halign = text.align_center,
bgcolor = Color2)
// Backtest Function
var float optimizeSensitivity = 0.0
Metric = array.get(metrics, 0)
optimizeSensitivity := Metric.sensitivity
//log.info(str.tostring(optimizeSensitivity))
[os,perf_idx,buyEntry,sellEntry,position,signalStrength,lower,upper] =
f_getSignalEntry(counterMode? optimizeSensitivity:sensitivity,10)

// Plot the trailing stop


var float tsl = na // Initialize trailing stop variable
tsl := os ? lower : upper // Assign the trailing stop based on the trend state

// Plot the trailing stop level


ts = plot(tsl, color=color(na), display=display.none)

// Plot the close price for filling


Cs = plot(close, color=color(na), display=display.none)

// Fill between the close and the trailing stop based on the trend
fill(Cs, ts, os == 1 ? close : tsl, os == 1 ? tsl : close,
os == 1 ? color.new(#089981, 60) : color(na),
os == 1 ? color(na) : color.new(#f23645, 60))

///////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////
// Define variables for buyClose, take profit, and stop loss levels
var float buyClose = 0
var float buyTakeProfitLevel = 0
var float buyStopLevel = 0

var float sellClose = 0


var float sellTakeProfitLevel = 0
var float sellStopLevel = 0

var bool BullEntry = na

if buyEntry
BullEntry := true
else if sellEntry
BullEntry := false
else
BullEntry := BullEntry // No change in BullEntry if no buy/sell entry

BuyExit = behavior == "BuiltIn Exit" ? bearishCross and position == 1 : false


SellExit = behavior == "BuiltIn Exit" ? bullishCross and position == -1 : false

// # ============================[Strategy TP/SL]============================ #

// ATR Calculation
atrValue = ta.atr(10) // Using a period of 10 for ATR

// Entry condition for buy


if buyEntry and (windowsCount ? barBack : true)
buyClose := close // Capture the closing price when the buy order is placed
strategy.close("Sell")
strategy.order("Buy", strategy.long)
// Entry condition for sell
if sellEntry and (windowsCount ? barBack : true)
sellClose := close // Capture the closing price when the sell order is placed
strategy.close("Buy")
strategy.order("Sell", strategy.short)

if BuyExit and (windowsCount ? barBack : true)


if BullEntry
strategy.close("Buy")
else
strategy.close("Sell")

if SellExit and (windowsCount ? barBack : true)


if BullEntry
strategy.close("Buy")
else
strategy.close("Sell")

//------------------------------------------------------------------------------
//Bull condition
//-----------------------------------------------------------------------------{
//-----------------------------------------------------------------------------}

// Take Profit Logic for Buy


buyTakeProfitLevel := LongTpType == "Currency" ? (buyClose + LongTpValue) :
LongTpType == "%" ? (buyClose * (1 + LongTpValue /
100)) :
LongTpType == "ATR" ? (buyClose + (atrValue *
LongTpValue)) :
LongTpType == "Price" ? LongTpValue :
na // Fallback in case none of the conditions are met

longtp = close >= buyTakeProfitLevel and LongTp and BullEntry


longTp = longtp != longtp[1]
if longTp
strategy.close("Buy", comment="TP")

// Stop Loss Logic for Buy


buyStopLevel := LongSlType == "Currency" ? (buyClose - LongSlValue) :
LongSlType == "%" ? (buyClose * (1 - LongSlValue / 100)) :
LongSlType == "ATR" ? (buyClose - (atrValue * LongSlValue)) :
LongSlType == "Price" ? LongSlValue :
na // Fallback in case none of the conditions are met

longsl = close <= buyStopLevel and LongSl and BullEntry


longSl = longsl != longsl[1]
if longSl
strategy.close("Buy", comment="SL")

//------------------------------------------------------------------------------
//Sell Condition
//-----------------------------------------------------------------------------{
//-----------------------------------------------------------------------------}
// Take Profit Logic for Sell
sellTakeProfitLevel := ShortTpType == "Currency" ? (sellClose - ShortTpValue) :
ShortTpType == "%" ? (sellClose * (1 - ShortTpValue /
100)) :
ShortTpType == "ATR" ? (sellClose - (atrValue *
ShortTpValue)) :
ShortTpType == "Price" ? ShortTpValue :
na // Fallback in case none of the conditions are met

shorttp = close <= sellTakeProfitLevel and ShortTp and not BullEntry


shortTp = shorttp != shorttp[1]
if shortTp
strategy.close("Sell", comment="TP")

// Stop Loss Logic for Sell


sellStopLevel := ShortSlType == "Currency" ? (sellClose + ShortSlValue) :
ShortSlType == "%" ? (sellClose * (1 + ShortSlValue / 100)) :
ShortSlType == "ATR" ? (sellClose + (atrValue *
ShortSlValue)) :
ShortSlType == "Price" ? ShortSlValue :
na // Fallback in case none of the conditions are met

shortsl = close >= sellStopLevel and ShortSl and not BullEntry


shortSl = shortsl != shortsl[1]
if shortSl
strategy.close("Sell", comment="SL")

// # ============================[Strategy Exit]============================ #

//------------------------------------------------------------------------------
//Buy Condition
//-----------------------------------------------------------------------------{
//-----------------------------------------------------------------------------}

//Exit SL/TP
if exitLongSl and BullEntry
if exitLongSlCondition == "Crossing Over" and ta.crossover(src,
exitLongSlSource)
strategy.close("Sell", comment="SL")
if exitLongSlCondition == "Crossing Under" and ta.crossunder(src,
exitLongSlSource)
strategy.close("Sell", comment="SL")
if exitLongSlCondition == "Equal" and src == exitLongSlSource
strategy.close("Sell", comment="SL")
if exitLongSlCondition == "Greater Than" and src > exitLongSlSource
strategy.close("Sell", comment="SL")
if exitLongSlCondition == "Lower Than" and src < exitLongSlSource
strategy.close("Sell", comment="SL")

if exitLongTp and BullEntry


if exitLongTpCondition == "Crossing Over" and ta.crossover(src,
exitLongTpSource)
strategy.close("Sell", comment="TP")
if exitLongTpCondition == "Crossing Under" and ta.crossunder(src,
exitLongTpSource)
strategy.close("Sell", comment="TP")
if exitLongTpCondition == "Equal" and src == exitLongTpSource
strategy.close("Sell", comment="TP")
if exitLongTpCondition == "Greater Than" and src > exitLongTpSource
strategy.close("Sell", comment="TP")
if exitLongTpCondition == "Lower Than" and src < exitLongTpSource
strategy.close("Sell", comment="TP")

//------------------------------------------------------------------------------
//Sell Condition
//-----------------------------------------------------------------------------{
//-----------------------------------------------------------------------------}

//Exit SL/TP
if exitShortSl and not BullEntry
if exitShortSlCondition == "Crossing Over" and ta.crossover(src,
exitShortSlSource)
strategy.close("Buy", comment="SL")
if exitShortSlCondition == "Crossing Under" and ta.crossunder(src,
exitShortSlSource)
strategy.close("Buy", comment="SL")
if exitShortSlCondition == "Equal" and src == exitShortSlSource
strategy.close("Buy", comment="SL")
if exitShortSlCondition == "Greater Than" and src > exitShortSlSource
strategy.close("Buy", comment="SL")
if exitShortSlCondition == "Lower Than" and src < exitShortSlSource
strategy.close("Buy", comment="SL")

if exitShortTp and not BullEntry


if exitShortTpCondition == "Crossing Over" and ta.crossover(src,
exitShortTpSource)
strategy.close("Buy", comment="TP")
if exitShortTpCondition == "Crossing Under" and ta.crossunder(src,
exitShortTpSource)
strategy.close("Buy", comment="TP")
if exitShortTpCondition == "Equal" and src == exitShortTpSource
strategy.close("Buy", comment="TP")
if exitShortTpCondition == "Greater Than" and src > exitShortTpSource
strategy.close("Buy", comment="TP")
if exitShortTpCondition == "Lower Than" and src < exitShortTpSource
strategy.close("Buy", comment="TP")

You might also like