Description
TrailBlazeArm Stop-Loss (TBASL)
Overview
The TrailBlazeArm Stop-Loss (TBASL) is an advanced trading script designed to help traders protect their positions by dynamically adjusting stop-loss levels based on market conditions. This script, originally authored by Giankam and modified by @Criptics, combines several market indicators to calculate and adjust trailing stop-loss levels for open positions, ensuring traders can minimize losses and lock in profits as the market moves.
Features
Dynamic Stop-Loss Adjustment: Automatically adjusts stop-loss levels based on the market's volatility and price action.
Customizable Parameters: Offers a range of input parameters for traders to customize the script according to their trading strategy and risk tolerance.
Support for Multiple Market Conditions: Utilizes indicators like ATR (Average True Range) and IQR (Interquartile Range) to adapt to changing market conditions.
Input Parameters
arm: Activation distance in percentage, determining when the trailing stop-loss is activated. Default is 1.5%.
atrLength: Length of the ATR indicator, defaulting to 8 bars.
atrMult: ATR Multiplier to adjust the sensitivity of the ATR indicator. Default is 1.
tslPercent: Percentage for trailing stop-loss. Default is 0 (not used).
triggerLength: Length for the trailing logic calculations. Default is 2.
centreLength: Length for midpoint adjustments. Default is 8.
iqrLength: Length for volatility adjustments using the IQR method. Default is 12.
iqrMult: Multiplier for the IQR value. Default is 0.
loMult: Multiplier for calculating the lower boundary. Default is 0.
hiMult: Multiplier for calculating the upper boundary. Default is 0.
filterSum: Boolean to determine the use of a summation filter on stop-level calculations. Default is false.
positionId: Optional parameter to specify a position ID.
direction: Optional parameter to specify the direction of the position (Long or Short).
Process Flow
Parameter Initialization: The script begins by initializing parameters based on user inputs or defaults.
Indicator Calculations:
Calculates various market indicators (ATR, IQR) based on the input parameters.
Uses these indicators to adjust the trailing stop-loss levels dynamically.
Trail Blaze Logic: Implements a sophisticated logic to determine the stop-loss levels based on the current trend, volatility, and user-defined parameters.
Position Management:
Monitors open positions and adjusts their stop-loss levels based on the calculated trailing stop values.
Supports dynamic adjustment for both long and short positions.
Plotting
The script plots the adjusted stop-loss levels on the chart, providing visual cues for traders. It uses different colors to indicate the direction of the adjustment (e.g., Aqua for upward adjustments, Purple for downward adjustments).
Output
The script outputs a boolean value indicating whether the adjusted stop-loss level has been successfully set for the current position.
Usage
This script is designed for traders looking for an advanced and dynamic way to manage stop-loss levels. It's particularly useful in volatile markets where static stop-loss levels might result in premature exits or unnecessary losses. By adjusting stop-loss levels dynamically, traders can better protect their capital while still capitalizing on profitable market movements.
HaasScript
-- [pshaiCmd] Trailing Arm Stop-Loss (TASL)
---- TrailBlaze Author: Giankam
--- modified TrailBlazeArmStopLoss by @Criptics
DefineCommand('TrailBlazeArmStopLoss', 'Educational TASL')
InputGroupHeader('TBA_StopLoss Settings ')
local arm = DefineParameter(NumberType, 'arm', 'Activation distance in percentage. Default is 0.2%.', false, Input('Arm', 1.5), 'Number')
local atrLength = DefineParameter(NumberType, 'atrLength', 'ATR Length. Default is 8 bars.', false, Input('AtrLength', 8), 'Number')
local atrMult = DefineParameter(NumberType, 'atrMult', 'ATR Multiplier. Default is 1.', false, Input('AtrMult', 1), 'Number')
local tslPercent = DefineParameter(NumberType, 'tslPercent', 'Trailing Percentage. Default is 0 (not used).', false, Input('TslPercent', 0), 'Number')
local triggerLength = DefineParameter(NumberType, 'triggerLength', 'Trigger Length for trailing logic calculations. Default is 2.', false, Input('TriggerLength', 2), 'Number')
local centreLength = DefineParameter(NumberType, 'centreLength', 'Centre Length for midpoint adjustments. Default is 8.', false, Input('CentreLength', 8), 'Number')
local iqrLength = DefineParameter(NumberType, 'iqrLength', 'IQR Length for volatility adjustments. Default is 12.', false, Input('IqrLength', 12), 'Number')
local iqrMult = DefineParameter(NumberType, 'iqrMult', 'IQR Multiplier. Default is 0.', false, Input('IqrMult', 0), 'Number')
local loMult = DefineParameter(NumberType, 'loMult', 'Low Multiplier for lower boundary calculation. Default is 0.', false, Input('LoMult', 0), 'Number')
local hiMult = DefineParameter(NumberType, 'hiMult', 'High Multiplier for upper boundary calculation. Default is 0.', false, Input('HiMult', 0), 'Number')
local filterSum = DefineParameter(BooleanType, 'filterSum', 'Determines use of summation filter on stop level calculations. Default is false.', false, Input('FilterSum', false), 'Boolean')
local positionId = DefineParameter(StringType, 'positionId', 'Optional position ID', false, '')
local direction = DefineParameter(EnumType, 'direction', 'Optional direction enum', false, NoPosition)
----------------------------------------------------------------------------------------------------------
--TrailBlaze
local function iqr_array(len, _h, _l , _hlc)
local function percentile_linear_interpolation(arr, percentile)
-- # sort the array in ascending order
local arr_sorted = ArraySort(arr)
--# determine the rank of the percentile value
local rank = (percentile / 100) * (#arr_sorted - 1)
--# determine the integer and fractional parts of the rank
local int_rank = Truncate(rank,0)
local frac_rank = rank - int_rank
--# interpolate between the values at int_rank and int_rank + 1
local lower_val = ArrayGet(arr_sorted,int_rank)
local upper_val = ArrayGet(arr_sorted,int_rank + 1)
local interpolated_val = lower_val + frac_rank * (upper_val - lower_val)
return interpolated_val
end
local hlArray = ArrayConcat(Grab(_h,0,len), Grab(_l,0,len))
local hlcmArray = ArrayConcat(hlArray, Grab(_hlc,0,len))
local q1 = percentile_linear_interpolation (hlcmArray, 25)
local q3 = percentile_linear_interpolation (hlcmArray, 75)
return (q3 - q1) / 2
end
local function trail_blaze (srct, srcc, lofac, hifac, _trendPrev, _histpPrev, _lostpPrev)
local lostop = 0
local histop = 0
local trend = 0
trend = srct >_histpPrev and 1 or (srct < _lostpPrev and -1 or _trendPrev)
local lostop00 = trend == 1 and _trendPrev == -1
local histop00 = trend == -1 and _trendPrev == 1
lostop = lostop00 and srcc - lofac or (srct[1] > _lostpPrev and Max(srcc - lofac, _lostpPrev) or srcc - lofac)
histop = histop00 and srcc + hifac or (srct[1] < _histpPrev and Min(srcc + hifac, _histpPrev) or srcc + hifac)
return {lostp = lostop, histp= histop, trnd = trend}
end
local c=ClosePrices()
local h = HighPrices()
local l = LowPrices()
local hlc= HLCPrices()
local triggerSource = HLPrices()
local centreSource = ClosePrices()
--// PROCESS
local trigger = EMA(c,4)
local centre = EMA(HLPrices(),atrLength)
local tslFactor = centre * tslPercent / 100
local atrFactor = atrMult * ATR (h, l, c, atrLength)
local iqrFactor = iqrMult * iqr_array (iqrLength, h, l, hlc)
local sumFactor = filterSum and WMA(WMA((tslFactor + atrFactor + iqrFactor),2),2) or atrFactor + iqrFactor + tslFactor
local loFactor = Max (sumFactor, 0) * loMult
local hiFactor = Max (sumFactor, 0) * hiMult
local trendPrev = Load('trendPrev',0)
local histpPrev = Load('histpPrev',0)
local lostpPrev = Load('lostpPrev',0)
local trend = trail_blaze (trigger, centre, loFactor, hiFactor, trendPrev, histpPrev, lostpPrev)
Save('trendPrev',trend.trnd)
Save('histpPrev',trend.histp)
Save('lostpPrev',trend.lostp)
if trend.trnd == 1 then
PlotShapes(
Plot(0, 'up', trend.lostp, {w = 1, c=Aqua(100), s=Smooth, id = NewGuid()}),
ShapeCircle,Aqua
)
elseif trend.trnd == -1 then
PlotShapes(
Plot(0, 'down', trend.histp, {w = 1, c=Purple(100), s=Smooth, id = NewGuid()}),
ShapeCircle, Purple
)
end
----------------------------------------------------------------------------------------------------------
-- Retrieve position information
local pos = PositionContainer(positionId)
if positionId == '' then positionId = pos.positionId end
-- Load trailing state and price for the position
local isTrailing = Load('tasl:it'..positionId, false)
local price = Load('tasl:p'..positionId, pos.enterPrice)
-- Current price information
local cp = CurrentPrice(pos.market)
local result = false
-- Calculate Trail Blaze Stop-Loss Levels
local c = ClosePrices()
local h = HighPrices()
local l = LowPrices()
local hlc = HLCPrices()
-- Update Trailing State Based on Trail Blaze Logic
if not isTrailing then
local armTarget = pos.isLong and AddPerc(pos.enterPrice, arm) or SubPerc(pos.enterPrice, arm)
if (pos.isLong and cp.high > armTarget) or (not pos.isLong and cp.low < armTarget) then
isTrailing = true
end
end
-- Use Trail Blaze for TASL Trailing Stop-Loss Levels
if isTrailing then
local stop
if pos.isLong then
price = Max(price, trend.lostp)
stop = price
result = stop > cp.bid
else
price = Min(price, trend.histp)
stop = price
result = stop < cp.ask
end
local plotColor = pos.isLong and Red or Green
Plot(0, 'Dynamic TASL Stop', stop, {color = plotColor, id = positionId})
end
-- Save trailing state and price
Save('tasl:it'..positionId, isTrailing)
Save('tasl:p'..positionId, price)
DefineOutput(BooleanType, result, '')
0 Comments
Sign in to leave a comment.
No comments yet. Be the first!