uperTrend Trailing Stop-Loss with Enhanced Features (Integration of Trail_Blaze)
stableDescription
This script represents a dynamic approach to managing trailing stop-loss orders in trading. It is a culmination of strategic methodologies originally inspired by "pshai's" SuperTrend Stop-Loss strategy, with an integration of the "Trail Blaze" function from "Giankam".
How It Works
Dynamic Trailing Stop-Loss Calculation: At its core, the script computes trailing stop-loss levels by amalgamating the Average True Range (ATR), Interquartile Range (IQR), and other market factors like NQK values. This blend of statistical measures offers a nuanced view of market volatility and price movement.
Real-Time Updates: The stop-loss levels are not static; they are recalibrated in real-time responding to the market's fluctuating conditions. This dynamism aims to strike a balance between capitalizing on profitable trends and curtailing potential losses.
Trail Blaze Function: Borrowed from Giankam's innovative approach, this function is pivotal to the script. It methodically assesses the market's direction and momentum, adjusting the stop positions accordingly. This component is instrumental in enhancing the script's responsiveness to market changes.
Parameter Management: The script ensures operational consistency and accuracy through intelligent management of parameters. It resets and saves key data points whenever there's a change in the position, maintaining the integrity of its trading logic.
HaasScript
-- Author: tedo
-- SuperTrend Trailing Stop-Loss with Enhanced Features (Integration of Trail_Blaze)
DefineCommand('STTSLXL', 'SuperTrend Trailing Stop-Loss Enhanced EXTRA')
-- Parameters
local atr_len = DefineParameter(NumberType, 'atr_len', 'ATR Period length', true, 20)
local atr_mult = DefineParameter(NumberType, 'atr_mult', 'ATR Multiplier', true, 2)
local interval = DefineParameter(NumberType, 'interval', 'Interval for data', false, 0, 'InputInterval, Number')
local position_id = DefineParameter(StringType, 'position_id', 'Position identifier', false, '', 'PositionContainer')
local market_id = DefineParameter(StringType, 'market_id', 'Market identifier', false, PriceMarket(), 'PriceMarket, InputAccountMarket, InputMarket, CreateMarket')
local tslPercent = DefineParameter(NumberType, 'Trailing %', 'Trailing %', true, 0)
local iqrLength = DefineParameter(NumberType, 'iqrLength', 'IQR Period length', true, 12)
local iqrMult = DefineParameter(NumberType, 'iqrMult', 'IQR Multiplier', true, 0)
local loMult = DefineParameter(NumberType, 'loMult', 'Low Multiplier', true, 1)
local hiMult = DefineParameter(NumberType, 'hiMult', 'High Multiplier', true, 1)
local triggerLength = DefineParameter(NumberType, 'triggerLength', 'Trigger Length', true, 2)
local centreLength = DefineParameter(NumberType, 'centreLength', 'Centre Length', true, 8)
local filterSum = DefineParameter(BooleanType, 'filterSum', 'Combine Factors', false, false)
-- Initialize position and market data
local position = PositionContainer(position_id)
local direction = GetPositionDirection()
local prev_id = Load('pid', position.positionId)
local result = false
-- High-speed prices integration
local hsp = CC_HighSpeedPrices(1)
local h = hsp.high
local l = hsp.low
local c = hsp.close
local hlc = hsp.hlc
local hl = hsp.hl
-- NQK Parameters
local alpha = 2
local nearFactor = 1.5
local farFactor = 8
local atr_length = 60
local relative_weight = 8
local lookback_w = 8
-- Initialize NQK with high-speed price data
local nqk = CC_NQK(alpha, nearFactor, farFactor, atr_length, relative_weight, lookback_w)
-- Enhanced IQR calculation (from Trail_Blaze)
local function iqr_array(len, _h, _l, _hlc)
local function percentile_linear_interpolation(arr, percentile)
local arr_sorted = ArraySort(arr)
local rank = (percentile / 100) * (#arr_sorted - 1)
local int_rank = Truncate(rank, 0)
local frac_rank = rank - int_rank
local lower_val = ArrayGet(arr_sorted, int_rank)
local upper_val = ArrayGet(arr_sorted, int_rank + 1)
return lower_val + frac_rank * (upper_val - lower_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
-- Trail Blaze Function
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
-- Reset upper and lower lines if position changes
if position.positionId != prev_id then
Save('upper', -1)
Save('lower', -1)
end
-- Main logic for trailing stop-loss
if direction != NoPosition then
local atr = atr_mult * ATR(h, l, c, atr_len)
local iqrValue = iqrMult * iqr_array(iqrLength, h, l, hlc)
-- Calculate factors
-- Use NQK values in the trailing stop logic
local trigger = nqk.kernel_avg -- or use bounds for different logic
local centre = nqk.kernel_avg -- or nqk.up_avg / nqk.low_avg based on position direction
local tslFactor = centre * tslPercent / 100
local atrFactor = atr
local iqrFactor = iqrValue
-- Combine factors based on filterSum
local sumFactor
if filterSum then
sumFactor = CC_SMMA(CC_SMMA((tslFactor + atrFactor + iqrFactor), 2), 2)
else
sumFactor = tslFactor + atrFactor + iqrFactor
end
local loFactor = Max(sumFactor, 0) * loMult
local hiFactor = Max(sumFactor, 0) * hiMult
-- Trail Blaze Logic
local trend = trail_blaze(trigger, centre, loFactor, hiFactor, Load('trendPrev', 0), Load('histpPrev', 0), Load('lostpPrev', 0))
Save('trendPrev', trend.trnd)
Save('histpPrev', trend.histp)
Save('lostpPrev', trend.lostp)
-- Update and plot positions
local finalStop = (direction == PositionLong and trend.lostp) or (direction == PositionShort and trend.histp)
Plot(0, 'Stop', finalStop, {c = direction == PositionLong and 'Red' or 'Green', id = position.positionId})
result = (direction == PositionLong and c <= finalStop) or (direction == PositionShort and c >= finalStop)
end
-- Save current position ID and define output
Save('pid', position.positionId)
DefineOutput(BooleanType, result, 'Returns true if stop was triggered')
0 Comments
Sign in to leave a comment.
No comments yet. Be the first!