Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //████████╗ █████╗ ███╗ ██╗██╗ ██╗███████╗███████╗
- //╚══██╔══╝██╔══██╗████╗ ██║██║ ██║██╔════╝██╔════╝
- // ██║ ███████║██╔██╗██║███████║█████╗ █████╗
- // ██║ ██╔══██║██║╚████║██╔══██║██╔══╝ ██╔══╝
- // ██║ ██║ ██║██║ ╚███║██║ ██║███████╗██║
- // ╚═╝ ╚═╝ ╚═╝╚═╝ ╚══╝╚═╝ ╚═╝╚══════╝╚═╝
- //@version=5
- indicator(title='Limit Order + ATR Stop-Loss', shorttitle='Limit + ATR Stop-Loss', overlay=true)
- //TOOLTIPS
- var string tt_Hide = "If selected, this indicator will only be visible on the enterred ticker.\n\nAn error ❗ will display beside indicator title when when hidden."
- var string tt_Interact = "Click location for ATR Trailing Stoploss entry on next price cross (Long by default). Drag 🟢 to modify afterwards."
- var string tt_entryType = "Entry Type Long or Short.\n\nLong Limit: Buy after cross down.\nLong Stop-Limit: Buy after cross above.\nShort Limit: Sell after cross up.\nShort Stop-Limit: Sell after cross below."
- var string tt_PriceTarget = "Profit target can be set on the opposite side of price in compared to the trailing stoploss.\n\nR:R = Risk/Reward Target\nPrice = Price Target\n\nStop At Target = If Target hit, Trailing Stoploss stops."
- var string tt_updateStop = "Select frequency of Stoploss updates.\n\n\nAlways = update continuously.\n\nBar Open = update bar from prior bar close.\n\nEntry Bar Open, then Always = update bar from prior bar close for entry bar, then every bar after updates continuously."
- var string tt_settingsATR = "The Average True Range (ATR) is a volatility indicator that measures price fluctuations. Higher calculated ATR values mean more volatility. This ATR result is aplied to the stoploss."
- var string tt_src = "Source of ATR Stoploss placement. Note that using a different source may result in unexpected results due to limitations of how this indicator was created.\n\nSources: \n Entry = 'non-trailing' from entry price (start point) \n Open = open \n High = high \n Low = low \n Close = close \n OC2 = (open + close)/2 \n HL2 = (high + low)/2 \n HLC3 = (high + low + close)/3 \n OHLC4 = (open + high + low + close)/4 \n HLCC4 = (high + low + close + close)/4"
- var string tt_srcEntry = "Only applies to the first bar of an entry for the ATR Stoploss placement."
- var string tt_Trigger = "Criteria used to determine if entry, stop-loss, or target has been hit.\n\nWick: low/high wicks outside. \nClose: close outside."
- var string tt_estimate = "Smooth the estimated stoploss prior to the active entry begins. This will affect the estimated target to be smoothed."
- var string tt_Interactive = "Display ATR Trailing Position"
- var string tt_Label = "Label including Positions Levels and Status\n\nCurrent = Label location is at current price bar \nTrailing = Label location is at trailing stoploss"
- var string tt_Table = "Table including Position Levels, Stoploss Settings, Target Settings, and Trigger Settings"
- var string tt_TargetFill = 'Display Target Fill, Target Fill Color, Target Line Color'
- var string tt_StopFill = 'Display Stoploss Fill, Stoploss Fill Color, Stoploss Line Color'
- var string tt_UpperBand = "Display Normal ATR Upper Band\nUses all settings from 'ATR Settings'"
- var string tt_LowerBand = "Display Normal ATR Lower Band\nUses all settings from 'ATR Settings'"
- var string tt_alert = "\n\nCheck alerts to use. Go to 'Create Alert' and set the condition to 'Limit Order + ATR Stoploss', select create. \n\nDetails can be added using words in Curly Brackets:\n {{trail}} = ATR trailing stop-loss (price) \n {{target}} = Profit Target (price) \n {{type}} = Long or Short stop-loss (word) \n {{traildistance}} = Trailing Distance (%) \n {{targetdistance}} = Target Distance (%) \n {{starttime}} = Start time of position (day:hr:min) \n {{target}} = Price target (price) \n {{maxdrawdown}} = max loss \n {{maxprofit}} = max profit \n {{update}} = stoploss update frequency (input) \n {{entrysource}} = entry as 1st bar source (yes/no) \n {{triggerentry}} = Wick/Close Trigger entry input\n {{triggerexit}} = Wick/Close Trigger exit input\n {{triggertarget}} = Wick/Close Trigger target input\n {{atrlength}} = ATR length input \n {{atrmultiplier}} = ATR multiplier input \n {{atrtype}} = ATR type input \n {{ticker}} = Ticker of chart (word) \n {{exchange}} = Exchange of chart (word) \n {{description}} = Description of ticker (words) \n {{close}} = Bar close (price) \n {{open}} = Bar open (price) \n {{high}} = Bar high (price) \n {{low}} = Bar low (price) \n {{hl2}} = Bar HL2 (price) \n {{volume}} = Bar volume (value) \n {{time}} = Current time (day:hr:min) \n {{interval}} = Chart timeframe \n {{newline}} = New line for text"
- var string tt_alertEntry = "Entry: alert when new entry begins."
- var string tt_alertEntryEx = "\n\nExample Alert Message Input: \n New {{type}} Entry with ATR Trailing Stoploss {{newline}}{{interval}} {{ticker}}\n\nExample Alert Message Output: \n New Long Entry with ATR Trailing Stoploss\n 4h BTCUSD"
- var string tt_alertTrailHit= "Trailing Hit: alert trailing ATR Stoploss hit."
- var string tt_alertTrailEx = "\n\nExample Alert Message Input: \n {{band}} ATR Trailing Stop Hit at {{trail}} ({{type}}){{newline}}{{interval}} {{ticker}}\n\nExample Alert Message Output: \n Lower ATR Trailing Stop Hit at 25 (Long)\n 4h BTCUSD"
- var string tt_alertTarget = "Target Hit: alert target hit (while trailing not hit)."
- var string tt_alertTargetEx= "\n\nExample Alert Message Input: \n Price crossing target of {{target}} ({{type}}){{newline}}{{interval}} {{ticker}} ATR Trailing Stop Not Hit\n\nExample Alert Message Output: \n Price crossing target of 100 (Long)\n 4h BTCUSD ATR Trailing Stop Not Hit"
- var string tt_alertInvalid = "Overlapping ATR Failed Entry, which only occurs on entry bar if the ATR settings cause the ATR Stoploss to be hit on the open bar."
- //OPTIONS
- var string o_Long = '🟢Long' //Entry Type
- var string o_Short = '🔴Short' //Entry Type
- var string o_RR = 'R:R' //Target Type
- var string o_Price = 'Price' //Target Type
- var string o_Every = 'Always' //Stoploss Update Frequency
- var string o_BarOpen = 'Bar Open' //Stoploss Update Frequency
- var string o_EntryBarOpen = 'Entry Bar Open, then Always' //Stoploss Update Frequency
- var string o_entry = "New {{type}} Entry with ATR Trailing Stoploss {{newline}}{{interval}} {{ticker}}" //Alert Message
- var string o_trailing = "{{band}} ATR Trailing Stop Hit at {{trail}} ({{type}}){{newline}}{{interval}} {{ticker}}" //Alert Message
- var string o_target = "Price crossing target of {{target}} ({{type}}){{newline}}{{interval}} {{ticker}} ATR Trailing Stop Not Hit" //Alert Message
- var string o_inavlidEntry = "Overlapping ATR and Bar" //Alert Message
- //COLORS
- var color c_colStoploss = color.new(color.blue,0) //Line - Stoploss
- var color c_colTarget = color.new(color.blue,0) //Line - Target
- var color c_colLossFill = color.new(color.red,20) //Fill - Stoploss
- var color c_colProfitFill = color.new(color.lime,20) //Fill - Target
- var color c_colBandUpper = color.new(color.purple,20) //Line - Normal Upper ATR Band
- var color c_colBandLower = color.new(color.teal,20) //Line - Normal Upper ATR Band
- var color colClear = color.new(color.blue,100) //Transparent
- //VARIABLES
- var timeLabel = time(na) //Time saved for placement of label
- var bool startNow = false //Start Plotting TrailingStop Loss
- var bool waitFirstTargetHit= true //Prevents multiple hits of profit target
- var bool overlappingATR = false //Check if ATR is overlapping price bar on entry
- var bool waitingTrailing = true //Waiting to enter Position
- var bool currentlyTrailing = false //Active Position
- var bool limitOrder = true //Limit Order or Stop-Limit Order
- var float upperTrailing = 0.0 //Set during active short
- var float lowerTrailing = 0.0 //Set during active long
- var float targetPrice = float(na) //For price target value (from either R:R or Price input)
- var float exitPrice = float(na) //For exit price value
- var float estimatedStoploss= float(na) //Estimated Stoploss (smoothed)
- var string limitTypeText = '' //Limit or Stop-Limit
- var int startMinute = int(na) //Start minute (for alerts)
- var int startHour = int(na) //Start hour (for alerts)
- var int startDay = int(na) //Start day (for alerts)
- //INPUTS - Show only on certain ticker
- hideUnlessSelected = input(false, title='Show only on ticker', inline='sec', tooltip=tt_Hide)
- hideUnlessSelectedVAL = input.symbol("", title="", inline='sec')
- if hideUnlessSelected
- if syminfo.ticker(hideUnlessSelectedVAL) != syminfo.ticker and hideUnlessSelectedVAL != '' //Checks symbol (exludes exchange check)
- runtime.error('Selected to show only on ' + syminfo.ticker(hideUnlessSelectedVAL))
- //INPUTS - Interactive
- entryType = input.string(o_Long, title="Entry Type", inline='Entry', group='Interactive Position', tooltip=tt_entryType, options=[o_Long,o_Short])
- yBarPrice = input.price(0.0, title='Start Point', inline='Start', group='Interactive Position', confirm=true)
- xBarTime = input.time(0, title='', inline='Start', group='Interactive Position', tooltip=tt_Interact, confirm=true)
- var isLong = entryType == o_Long ? true : false //Position Direction
- var col_isLong = isLong ? color.lime : color.red //Position Direction (Color)
- var entryPrice = yBarPrice //For entry price value
- var invalidStart= xBarTime == 0 or yBarPrice == 0 ? true : false
- //Check Starting Bar to Search for Entry
- xBarTime_Now = xBarTime == time ? true : false //First valid bar
- xBarTime_Valid = xBarTime <= time ? true : false //All valid bars
- //Limit or Stoplimit order
- if xBarTime == time
- if isLong //Long
- limitOrder := yBarPrice < hl2 ? true : false
- else //Short
- limitOrder := yBarPrice > hl2 ? true : false
- limitTypeText := limitOrder ? 'Limit' : 'Stop-Limit'
- //DESCRIPTIONS - Stop-limit orders and limit orders
- var string descLongStopLimit = "Long stop limit order: A buy order that is triggered only after the price reaches a specific level, and is executed at a set price or better."
- var string descShortStopLimit = "Short stop limit order: A sell order that is triggered only after the price reaches a specific level, and is executed at a set price or better."
- var string descLongLimit = "Long limit order: A buy order that is executed at a set price or better, without any trigger condition."
- var string descShortLimit = "Short limit order: A sell order that is executed at a set price or better, without any trigger condition."
- var string selectedDesc = isLong and limitOrder ? descLongLimit :
- isLong and limitOrder == false ? descLongStopLimit :
- isLong == false and limitOrder ? descShortLimit :
- descShortStopLimit
- //INPUTS - Stoploss Update
- updateStopVAL = input.string(o_Every, title="Update Frequency", inline="ATR", group="Interactive Position", options=[o_Every,o_BarOpen,o_EntryBarOpen], tooltip=tt_updateStop)
- updateOnce = updateStopVAL == o_BarOpen ? true : false
- updateEntryOnce = updateStopVAL == o_EntryBarOpen ? true : false
- //INPUTS - Price Target
- useDisplayTarget= input(false, title="Profit Target", inline="Target", group="Interactive Position", tooltip=tt_PriceTarget)
- targetType = input.string(o_RR, title="", inline='Target', group="Interactive Position", options=[o_RR,o_Price])
- targetMult = input.float(1.5, title="", inline="Target", group="Interactive Position", step=0.1)
- stopAtTarget = input(true, title="Stop at Target", inline="Target", group="Interactive Position")
- var targetTypeRR= targetType == o_RR ? true : false
- var entryTypeText= isLong ? 'Long ' : 'Short '
- //INPUTS - ATR Settings
- length = input.int(14, minval=1, title='Length', inline="ATR", group="ATR Settings")
- multiplier = input.float(3.0,step=0.5,title='Multiplier', inline="ATR", group="ATR Settings")
- maTypeInput = input.string("RMA", title="Type", inline="ATR", group="ATR Settings", options=["SMA", "EMA", "RMA", "WMA", "VWMA"])
- //OPTIONS - Sources
- var string o_src_entry = 'Entry'
- var string o_src_open = 'Open'
- var string o_src_high = 'High'
- var string o_src_low = 'Low'
- var string o_src_close = 'Close'
- var string o_src_oc2 = 'OC2'
- var string o_src_hl2 = 'HL2'
- var string o_src_hlc3 = 'HLC3'
- var string o_src_ohlc4 = 'OHLC4'
- var string o_src_hlcc4 = 'HLCC4'
- //INPUTS - ATR Sources
- srcUpperVAL = input.string(o_src_high, title='Source Upper', inline="ATR1", group="ATR Settings", options=[o_src_entry,o_src_open,o_src_high,o_src_low,o_src_close,o_src_oc2,o_src_hl2,o_src_hlc3,o_src_ohlc4,o_src_hlcc4],tooltip=tt_src)
- srcLowerVAL = input.string(o_src_low, title='Source Lower', inline="ATR2", group="ATR Settings", options=[o_src_entry,o_src_open,o_src_high,o_src_low,o_src_close,o_src_oc2,o_src_hl2,o_src_hlc3,o_src_ohlc4,o_src_hlcc4])
- srcUseEntry = input(false, title='Entry as Entry Bar Source (1st bar)', inline="ATR3", group="ATR Settings", tooltip=tt_srcEntry)
- //INPUTS - Triggers
- entryTrigger = input.string("Wick", title="Entry", inline='Trigger',group="Trigger Settings", options=["Wick","Close"])
- stopTrigger = input.string("Wick", title="Stoploss", inline='Trigger',group="Trigger Settings", options=["Wick","Close"])
- targetTrigger = input.string("Wick", title="Target", inline='Trigger',group="Trigger Settings", options=["Wick","Close"], tooltip=tt_Trigger)
- var entry_Wick = entryTrigger == "Wick" ? true : false
- var stop_Wick = stopTrigger == "Wick" ? true : false
- var target_Wick = targetTrigger == "Wick" ? true : false
- //INPUTS - MA Settings for Estimate
- useSmoother = input(true, title='Smooth Estimate', inline="EST", group="Estimate Smoothing", tooltip=tt_estimate)
- maTypeInputEST = input.string("RMA", title=" - Type", inline="EST", group="Estimate Smoothing", options=["SMA", "EMA", "RMA", "WMA", "VWMA"])
- lengthEST = input.int(5, minval=1, title='Length', inline="EST", group="Estimate Smoothing")
- //INPUTS - Display Settings
- displayTrailATR = input(true, title="Display ATR Trailing (Position)", inline='Trail', group="Display", tooltip=tt_Interactive)
- fillProfitArea = input(true, title="Fill Target (Position) ", inline='Stop', group="Display")
- colLossFill = input(c_colLossFill, title='', inline='Stop', group="Display")
- colStoploss = input(c_colStoploss, title='Line', inline='Stop', group="Display", tooltip=tt_TargetFill)
- fillLossArea = input(true, title="Fill Stoploss (Position)", inline='Target', group="Display")
- colProfitFill = input(c_colProfitFill, title='', inline='Target', group="Display")
- colTarget = input(c_colTarget, title='Line', inline='Target', group="Display", tooltip=tt_TargetFill)
- displayUpperATR = input(false, title="Display Normal ATR Upper Band", inline='Band1', group="Display")
- colBandUpper = input(c_colBandUpper, title='', inline='Band1', group="Display", tooltip=tt_UpperBand)
- displayLowerATR = input(false, title="Display Normal ATR Lower Band", inline='Band2', group="Display")
- colBandLower = input(c_colBandLower, title='', inline='Band2', group="Display", tooltip=tt_LowerBand)
- displayLabel = input(true, title='Label', inline='Label', group="Display", tooltip=tt_Label)
- labelSize = input.string(size.normal,title="", inline="Label", group="Display", options=[size.auto, size.tiny, size.small, size.normal, size.large, size.huge])
- labelPos = input.string('Trailing', title="Position", inline="Label", group="Display", options=['Current','Trailing'])
- displayTable = input(true, title='Table', inline='Table', group="Display", tooltip=tt_Table)
- tableSize = input.string(size.small, title="", inline="Table", group="Display", options=[size.auto, size.tiny, size.small, size.normal, size.large, size.huge])
- tablePos1 = input.string("bottom", title="Position", inline="Table", group="Display", options=["top","middle","bottom"])
- tablePos2 = input.string("right", title="", inline="Table", group="Display", options=["left","center","right"])
- //CALCULATE - Source
- getSource(_val) =>
- srcUpper = _val == o_src_entry ? entryPrice :
- _val == o_src_open ? open :
- _val == o_src_high ? high :
- _val == o_src_low ? low :
- _val == o_src_close ? close :
- _val == o_src_oc2 ? (open+close)/2 :
- _val == o_src_hl2 ? hl2 :
- _val == o_src_hlc3 ? hlc3 :
- _val == o_src_ohlc4 ? ohlc4 :
- _val == o_src_hlcc4 ? hlcc4 :
- close
- srcUpper = getSource(srcUpperVAL)
- srcLower = getSource(srcLowerVAL)
- //CALCULATE - MA
- calcMA(source, length, type) =>
- switch type
- "RMA" => ta.rma(source, length)
- "SMA" => ta.sma(source, length)
- "EMA" => ta.ema(source, length)
- "WMA" => ta.wma(source, length)
- "VWMA"=> ta.vwma(source, length)
- atr = calcMA(ta.tr(true), length, maTypeInput) * multiplier
- upper = atr + srcUpper
- lower = srcLower - atr
- //CALCULATE - Trailing ATR
- //Check first bar of trailing stoploss, also if short or long stoploss
- if xBarTime_Valid
- if entry_Wick //entryTrigger == "Wick"
- if limitOrder //Limit Order
- if (low < yBarPrice and isLong) or (high > yBarPrice and isLong == false) //New Limit Order (Wick Trigger)
- startNow := true
- startMinute := minute, startHour := hour, startDay := dayofmonth
- else //Stop-Limit Order
- if (high > yBarPrice and isLong) or (low < yBarPrice and isLong == false) //New Stop-Limit Order (Wick Trigger)
- startNow := true
- startMinute := minute, startHour := hour, startDay := dayofmonth
- else
- if ta.cross(yBarPrice,close) //New Limit or Stop-Limit Order (Close Trigger)
- startNow := true
- startMinute := minute, startHour := hour, startDay := dayofmonth
- //Start stoploss and set trailing value
- if startNow and startNow[1] == false
- //Stoploss
- if srcUseEntry
- upperTrailing := atr + entryPrice //Stoploss (Short)
- lowerTrailing := entryPrice - atr //Stoploss (Long)
- else if updateEntryOnce or updateOnce
- upperTrailing := upper[1] //Stoploss (Short)
- lowerTrailing := lower[1] //Stoploss (Long)
- else
- upperTrailing := upper //Stoploss (Short)
- lowerTrailing := lower //Stoploss (Long)
- //Entry Price
- entryPrice := entry_Wick ? math.round_to_mintick(yBarPrice) : close //entryTrigger == "Wick"
- //Price Target
- targetPrice := targetTypeRR == false ? targetMult : ( isLong ? entryPrice+((entryPrice-lowerTrailing)*targetMult) : entryPrice-((upperTrailing-entryPrice)*targetMult) ) //targetType == o_Price
- //Warning that an entry did not occur due ATR being within the price bar on the opening bar (this only occurs if the ATR Stoploss settings are to tight to the price bar)
- if isLong
- if lowerTrailing > low
- labelATR = label.new(bar_index, isLong ? low : high, text='🚨\nOverlapping\nATR and Bar', textalign = text.align_center, color=color.new(color.red,90), textcolor=color.blue, xloc=xloc.bar_index, yloc=yloc.price,size=labelSize, tooltip='Either place on another bar or modify ATR Settings')
- label.set_style(labelATR, isLong ? label.style_label_up : label.style_label_down)
- overlappingATR := true
- else
- if upperTrailing < high
- labelATR = label.new(bar_index, isLong ? low : high, text='🚨\nOverlapping\nATR and Bar', textalign = text.align_center, color=color.new(color.red,90), textcolor=color.blue, xloc=xloc.bar_index, yloc=yloc.price,size=labelSize, tooltip='Either place on another bar or modify ATR Settings')
- label.set_style(labelATR, isLong ? label.style_label_up : label.style_label_down)
- overlappingATR := true
- //Overlapping - Prevent position from starting if price bar overlapping with ATR
- if overlappingATR == false
- currentlyTrailing := true //True during active position
- waitingTrailing := false //True if no position occurred yet
- //Update ATR Trailing Stop Value
- if updateOnce == false or (updateEntryOnce and startNow and startNow[1] == false) //Updates Continuously
- if currentlyTrailing and currentlyTrailing[1]
- if isLong
- lowerTrailing := lowerTrailing < lower ? lower : lowerTrailing
- else
- upperTrailing := upperTrailing > upper ? upper : upperTrailing
- else //Updates on bar open
- if currentlyTrailing and currentlyTrailing[1]
- if isLong
- lowerTrailing := lowerTrailing < lower[1] ? lower[1] : lowerTrailing
- else
- upperTrailing := upperTrailing > upper[1] ? upper[1] : upperTrailing
- //PLOT - Draggable Start Point
- plot(xBarTime_Now ? yBarPrice : na,style=plot.style_circles, color=col_isLong, linewidth=5, title="🟢/🔴 Start Point (Draggable Circle)")
- //CALCULATE - Estimated Stoploss
- estimatedStoploss := isLong ? entryPrice-atr : entryPrice+atr //Calculate Estimated Stoploss
- estimatedStoplossSmooth = calcMA(estimatedStoploss, lengthEST, maTypeInputEST) //Calculate Estimated Stoploss (Smoothed)
- estimatedStoploss := useSmoother ? estimatedStoplossSmooth : estimatedStoploss //Choose normal estimate or smoothed
- //CALCULATE - Estimated Profit Target & Check if Profit Target Valid
- var displayTarget = useDisplayTarget //Hide target if invalid
- var estimatedProfitTarget = targetMult //Profit Target
- if useDisplayTarget
- if targetTypeRR //targetType == o_RR
- estimatedProfitTarget := isLong ? yBarPrice+((yBarPrice-estimatedStoploss)*targetMult) : yBarPrice-((estimatedStoploss-yBarPrice)*targetMult)
- else if useDisplayTarget
- if isLong
- displayTarget := targetMult > yBarPrice ? true : false
- else
- displayTarget := targetMult < yBarPrice ? true : false
- //Label - Price of for entry trigger
- if xBarTime_Now
- tt_TargetType = targetTypeRR ? 'Calculated from current ATR to price difference' : 'Profit Target' //targetType == o_RR
- entryText = entryTypeText+limitTypeText+' '+str.tostring(math.round_to_mintick(yBarPrice)) + '➔'
- label.new(bar_index, yBarPrice, style=label.style_label_right, text=entryText, textalign = text.align_center, color=colClear, textcolor=color.blue, xloc=xloc.bar_index, yloc=yloc.price,size=labelSize, tooltip=entryTypeText+limitTypeText)
- label.new(bar_index, estimatedStoploss, style=label.style_label_right, text='⚠️➔', textalign = text.align_center, color=colClear, textcolor=color.new(color.blue,50), xloc=xloc.bar_index, yloc=yloc.price,size=labelSize, tooltip='Estimated ATR Stoploss')
- label.new(displayTarget ? bar_index : na, estimatedProfitTarget, style=label.style_label_right, text='🎯➔', textalign = text.align_center, color=colClear, textcolor=color.new(color.blue,50), xloc=xloc.bar_index, yloc=yloc.price,size=labelSize, tooltip=tt_TargetType)
- //Common requirement for plotting
- checkPlot = xBarTime_Valid and startNow[1] == false and invalidStart == false ? true : false
- //PLOT - Entry price line
- plot(checkPlot ? yBarPrice : na, linewidth=1, title="Entry Price Line", color=col_isLong)
- //PLOT - Estimated Stoploss
- plot(checkPlot ? estimatedStoploss : na, linewidth=1, title="Estimated Stoploss", color=color.new(color.blue,50), style= plot.style_circles)
- //PLOT - Estimated Profit Target
- plot(checkPlot and displayTarget ? estimatedProfitTarget : na, linewidth=1, title="Estimated Profit Target", color=color.new(color.blue,50), style= plot.style_circles)
- //PLOT - Trailing Stop-loss
- plotUpperTrailing = plot(displayTrailATR and currentlyTrailing and isLong == false ? upperTrailing : na, title="Upper Trailing Stoploss (Short)", color=colStoploss) //Upper Trail (Short)
- plotLowerTrailing = plot(displayTrailATR and currentlyTrailing and isLong ? lowerTrailing : na, title="Lower Trailing Stoploss (Long)", color=colStoploss) //Lower Trail (Long)
- placeholder = plot(currentlyTrailing ? hlc3 : na, title="Placeholder", editable=false, color=colClear) //Placeholder
- profitHit = false //Profit Target Hit
- stopHit = false //Stoploss Hit
- //CHECK - Stoploss Hit
- if currentlyTrailing
- if stop_Wick //stopTrigger == "Wick"
- if high > upperTrailing and isLong == false //Wick Stoploss (Short)
- currentlyTrailing := false
- exitPrice := upperTrailing
- stopHit := true
- if low < lowerTrailing and isLong //Wick Stoploss (Long)
- currentlyTrailing := false
- exitPrice := lowerTrailing
- stopHit := true
- else //stopTrigger == "Close"
- if close[1] > upperTrailing and isLong == false //Close Stoploss (Short)
- currentlyTrailing := false
- exitPrice := close[1]
- stopHit := true
- if close[1] < lowerTrailing and isLong //Close Stoploss (Long)
- currentlyTrailing := false
- exitPrice := close[1]
- stopHit := true
- //CHECK - Profit Target Hit
- if displayTarget //Require profit target to be displayed
- if currentlyTrailing
- if target_Wick //targetTrigger == "Wick"
- if (ta.cross(high,targetPrice) or ta.cross(low,targetPrice)) //Wick Target
- waitFirstTargetHit := false
- profitHit := true
- exitPrice := targetPrice
- currentlyTrailing := stopAtTarget ? false : true
- else //targetTrigger == "Close"
- if (ta.cross(close,targetPrice)) //Close Target
- waitFirstTargetHit := false
- profitHit := true
- exitPrice := close
- currentlyTrailing := stopAtTarget ? false : true
- //PLOT - Stoploss Fill (only while active, removes after exit)
- fill(plotUpperTrailing,placeholder,color=close < upperTrailing ? color.new(colLossFill,80) : na,display=fillLossArea ? display.all : display.none)
- fill(plotLowerTrailing,placeholder,color=close > lowerTrailing ? color.new(colLossFill,80) : na,display=fillLossArea ? display.all : display.none)
- //PLOT - Price Target and Fill Target
- plotTarget = plot(displayTarget and (currentlyTrailing or currentlyTrailing[1]) and waitFirstTargetHit[1] ? targetPrice : na, title="Profit Target", color=colTarget)
- fill(placeholder, plotTarget, color=waitFirstTargetHit[1] ? color.new(colProfitFill,80) : na,display=fillProfitArea ? display.all : display.none)
- //PLOT - Shape (Stoploss Hit)
- plotchar(displayTrailATR and isLong and stopHit, title="Symbol - Long Stop", char='⚠️', location=location.belowbar, size=size.small)
- plotchar(displayTrailATR and isLong == false and stopHit, title="Symbol - Short Stop", char='⚠️', location=location.abovebar, size=size.small)
- //PLOT - Shape (Target Hit)
- plotchar(displayTrailATR and isLong and displayTarget and profitHit and waitFirstTargetHit[1], title="Symbol - Long Profit", char='🎯', location=location.abovebar, size=size.small)
- plotchar(displayTrailATR and isLong == false and displayTarget and profitHit and waitFirstTargetHit[1], title="Symbol - Short Profit", char='🎯', location=location.belowbar, size=size.small)
- //PLOT - Normal ATR Bands
- plotUpper = plot(displayUpperATR ? atr + srcUpper : na, title='ATR Normal Band - Upper', color=colBandUpper)
- plotLower = plot(displayLowerATR ? srcLower - atr : na, title='ATR Normal Band - Lower', color=colBandLower)
- //CALCULATE - Percent Distance
- getLongPercentText(_entry,_exit) => ((_exit-_entry)/_entry)*100
- getShortPercentText(_entry,_exit) => ((_entry-_exit)/_entry)*100
- //CALCULATE - Percentage Distance (Text)
- percentFromEntry() => isLong ? str.tostring(getLongPercentText(entryPrice,close),'#.##') : str.tostring(getShortPercentText(entryPrice,close),'#.##')
- percentPositionResult() => isLong ? str.tostring(getLongPercentText(entryPrice,exitPrice),'#.##') : str.tostring(getShortPercentText(entryPrice,close),'#.##')
- percentMaxDrawdownEST() => isLong ? str.tostring(getLongPercentText(yBarPrice,estimatedStoploss),'#.##') : str.tostring(getShortPercentText(yBarPrice,estimatedStoploss),'#.##')
- percentMaxProfitEST() => isLong ? str.tostring(getLongPercentText(yBarPrice,estimatedProfitTarget),'#.##') : str.tostring(getShortPercentText(yBarPrice,estimatedProfitTarget),'#.##')
- percentMaxDrawdown() => isLong ? str.tostring(getLongPercentText(entryPrice,lowerTrailing),'#.##') : str.tostring(getShortPercentText(entryPrice,upperTrailing),'#.##')
- percentMaxProfit() => isLong ? str.tostring(getLongPercentText(entryPrice,targetPrice),'#.##') : str.tostring(getShortPercentText(entryPrice,targetPrice),'#.##')
- //CALCULATE - Timeframe text for alert ('fixes' letter consistancy between different timeframes)
- calcTimeframeText(_src) =>
- result = _src
- if str.contains(_src,'S')
- result := str.replace(_src,'S','s',0)
- else if str.contains(_src,'D') or str.contains(_src,'W') or str.contains(_src,'M')
- result := _src
- else
- result := str.tonumber(_src) < 60 ? _src + 'm' : str.tostring(str.tonumber(_src)/60) + 'h'
- //CALCULATE - Curly brackets text into current data
- //One reason this code was added due to the preference of using alert() instead of alertcondition() which requires additional selection when setting up alerts.
- //This function allows for alert() to return messages with retreived values via curly brackets, that alertcondition() can do by default.
- //Additional indicator specific values can also be retreived, such as {{trail}} , {{band}} , {{type}} , {{target}} , {{newline}} , and more.
- checkAlertText(_text) =>
- result = _text
- result := str.replace(result, '{{trail}}', str.tostring(math.round_to_mintick(isLong ? lowerTrailing : upperTrailing)))
- result := str.replace(result, '{{target}}', str.tostring(math.round_to_mintick(targetPrice)))
- result := str.replace(result, '{{type}}', isLong ? 'Long' : 'Short')
- result := str.replace(result, '{{traildistance}}', isLong ? str.tostring(((lowerTrailing/close)-1)*100,'#.###') + '%' : str.tostring(((upperTrailing/close)-1)*100,'#.###') + '%')
- result := str.replace(result, '{{targetdistance}}', isLong ? str.tostring(((targetPrice/close)-1)*100,'#.###') + '%' : str.tostring(((targetPrice/close)-1)*100,'#.###') + '%')
- result := str.replace(result, '{{starttime}}', str.tostring(startDay,'#') + ':' + str.tostring(startHour,'#') + ':' + str.tostring(startMinute,'#'))
- result := str.replace(result, '{{maxdrawdown}}', percentMaxDrawdown())
- result := str.replace(result, '{{maxprofit}}', percentMaxProfit())
- result := str.replace(result, '{{update}}', updateStopVAL)
- result := str.replace(result, '{{entrysource}}', srcUseEntry ? 'Yes' : 'No')
- result := str.replace(result, '{{triggerentry}}', entryTrigger)
- result := str.replace(result, '{{triggerstop}}', stopTrigger)
- result := str.replace(result, '{{triggertarget}}', targetTrigger)
- result := str.replace(result, '{{atrlength}}', str.tostring(length,'#'))
- result := str.replace(result, '{{atrmultiplier}}', str.tostring(multiplier,'#'))
- result := str.replace(result, '{{atrtype}}', maTypeInput)
- result := str.replace(result, '{{ticker}}', syminfo.ticker)
- result := str.replace(result, '{{exchange}}', syminfo.prefix(syminfo.tickerid))
- result := str.replace(result, '{{description}}', syminfo.description)
- result := str.replace(result, '{{close}}', str.tostring(math.round_to_mintick(close)))
- result := str.replace(result, '{{open}}', str.tostring(math.round_to_mintick(open)))
- result := str.replace(result, '{{high}}', str.tostring(math.round_to_mintick(high)))
- result := str.replace(result, '{{low}}', str.tostring(math.round_to_mintick(low)))
- result := str.replace(result, '{{hl2}}', str.tostring(math.round_to_mintick(hl2)))
- result := str.replace(result, '{{volume}}', str.tostring(math.round_to_mintick(volume)))
- result := str.replace(result, '{{time}}', str.tostring(dayofmonth,'#') + ':' + str.tostring(hour,'#') + ':' + str.tostring(minute,'#'))
- result := str.replace(result, '{{interval}}', calcTimeframeText(timeframe.period))
- result := str.replace(result, '{{newline}}', '\n')
- //INPUTS - Alerts
- Alert_Entry = input(true, title="Alert Entry", inline='AlertEntry', group="Alert", tooltip=tt_alertEntry + tt_alert + tt_alertEntryEx)
- Alert_EntryText = input.string(o_entry, title='', inline='AlertEntry', group="Alert")
- Alert_TrailingHit = input(true, title="Alert Trailing Stop Hit", inline='AlertTrailingHit', group="Alert", tooltip=tt_alertTrailHit + tt_alert + tt_alertTrailEx)
- Alert_TrailingHitText = input.string(o_trailing, title='', inline='AlertTrailingHit', group="Alert")
- Alert_PriceTarget = input(true, title="Alert Profit Target Hit", inline='AlertProfitHit', group="Alert", tooltip=tt_alertTarget + tt_alert + tt_alertTargetEx)
- Alert_PriceTargetText = input.string(o_target, title='', inline='AlertProfitHit', group="Alert")
- Alert_InvalidEntry = input(true, title="Alert Failed Entry (ATR Overlap)", inline='AlertInvalidEntry', group="Alert", tooltip=tt_alertInvalid + tt_alert)
- Alert_InvalidEntryText= input.string(o_inavlidEntry,title='', inline='AlertInvalidEntry', group="Alert")
- //CALCULATE - ALERTS
- if Alert_Entry
- if startNow
- alert(checkAlertText(Alert_EntryText),alert.freq_once_per_bar)
- if Alert_TrailingHit
- if stopHit
- alert(checkAlertText(Alert_TrailingHitText),alert.freq_once_per_bar)
- if Alert_PriceTarget
- if profitHit
- alert(checkAlertText(Alert_PriceTargetText),alert.freq_once_per_bar)
- if Alert_InvalidEntry
- if overlappingATR
- alert(checkAlertText(Alert_InvalidEntryText),alert.freq_once_per_bar)
- //Label checks
- var resultSymbol = ''
- if stopHit
- resultSymbol := '⚠️'
- if profitHit
- resultSymbol := '🎯'
- var labelText = ""
- var labelATR = label.new(na, na, '', textalign = text.align_left, xloc=xloc.bar_time, yloc=yloc.price,size=labelSize)
- //Set time location for displaying label
- if currentlyTrailing[1] or (waitingTrailing and xBarTime_Valid)
- timeLabel := time
- if barstate.islast //Compile script faster
- //Exit Entry
- if resultSymbol != '' and overlappingATR == false //resultSymbol != resultSymbol[1] //waitFirstTargetHit == false
- labelText := ''
- if isLong
- labelText := resultSymbol + (exitPrice > entryPrice ? 'Win: ' : (exitPrice < entryPrice ? 'Loss: ' : 'Draw: ')) //Win or Loss (Long)
- else
- labelText := resultSymbol + (exitPrice < entryPrice ? 'Win: ' : (exitPrice > entryPrice ? 'Loss: ' : 'Draw: ')) //Win or Loss (Short)
- labelText := labelText + percentPositionResult() + '%\nEntry: ' + str.tostring(math.round_to_mintick(entryPrice)) + //Entry Price
- '\nExit: ' + str.tostring(math.round_to_mintick(exitPrice)) //Exit Price
- labelText := (useDisplayTarget and displayTarget == false ? labelText + '\n\n🚨Target Invalid🚨' : labelText) //Target Invalid
- //Waiting Entry
- if xBarTime_Valid and waitingTrailing and overlappingATR == false //xBarTime_Valid (xBarTime <= time , each bar after initial click) //waitingTrailing (prior to entry)
- labelText := ''
- labelText := labelText + 'Waiting ' + entryTypeText + 'Entry...\n\n' +
- (displayTarget ? ('🎯Profit Target: ' + str.tostring(math.round_to_mintick(estimatedProfitTarget)) + //Target Price
- (targetTypeRR ? ' (Estimate)\n' : '\n')) : '') + //Target Estimate ?
- '⏳' + entryTypeText + limitTypeText + ': ' + str.tostring(math.round_to_mintick(yBarPrice)) + //Entry Price
- '\n⚠️Stoploss: ' + str.tostring(math.round_to_mintick(estimatedStoploss)) + ' (Estimate)' + //Stoploss Price
- '\n\nMax Drawdown: ' + percentMaxDrawdownEST() + '% (Estimate)' + //Max Drawdown Percent
- (displayTarget ? '\nMax Profit: ' + percentMaxProfitEST() + '% (Estimate)' : '') + //Max Profit Percent
- (useDisplayTarget and displayTarget == false ? '\n\n🚨Target Invalid🚨' : '') //Target Invalid
- //Active Entry
- if waitingTrailing == false and currentlyTrailing
- labelText := ''
- labelText := labelText + 'Active Position: ' + percentFromEntry() + //Active Position Percent
- '%\n\n' + (displayTarget ? '🎯Profit Target: ' + str.tostring(math.round_to_mintick(targetPrice)) + '\n' : '') + //Profit Target Price
- '✔️Entry: ' + str.tostring(math.round_to_mintick(entryPrice)) + //Entry Price
- '\n⚠️Stoploss: ' + str.tostring(math.round_to_mintick(isLong ? lowerTrailing : upperTrailing)) + //Stoploss Price
- (displayTarget ? '\n\nMax Profit: ' + percentMaxProfit() + '%' : '\n') + //Max Profit Percent
- '\nMax Drawdown: ' + percentMaxDrawdown() + '%' //Max Drawdown Percent
- //LABEL - Check Label
- labelTextcolor = color.blue
- labelColor = isLong ? colProfitFill : colLossFill
- labelTooltip = selectedDesc
- if invalidStart //xBarTime == 0 or yBarPrice == 0
- labelText := '🚨Modify Start Point or Re-add to chart🚨'
- labelTooltip := "Start Point is currently zero or date is invalid. Modify the start point within settings or re-add this indicator to the chart."
- labelTextcolor := color.yellow
- labelColor := color.blue
- //LABEL - Display
- if labelText != ''
- label.set_textcolor(labelATR, overlappingATR ? color.yellow : labelTextcolor)
- label.set_color(labelATR, overlappingATR ? color.blue : labelColor)
- label.set_text(labelATR, labelText)
- label.set_tooltip(labelATR, labelTooltip)
- if labelPos == 'Trailing'
- label.set_xy(labelATR, displayTrailATR and displayLabel ? timeLabel+1 : na, isLong ? (lowerTrailing == 0 ? close[1] : lowerTrailing) : (upperTrailing == 0 ? close[1] : upperTrailing))
- label.set_style(labelATR, isLong ? label.style_label_upper_left : label.style_label_lower_left)
- else
- label.set_xy(labelATR, displayTrailATR and displayLabel ? time+1 : na, close[1])
- label.set_style(labelATR, label.style_label_left)
- //TABLE - Settings of this indicator
- if displayTable
- col_T = color.white //Text Color
- col_H = color.rgb(25, 0, 255) //Heading Color
- col_W = color.rgb(189, 0, 0) //Warning Color
- infobox = table.new(tablePos1 + "_" + tablePos2, 2, 20, bgcolor=color.rgb(0, 0, 0), frame_color=col_H, frame_width=1)
- //Warning
- if invalidStart //xBarTime == 0 or yBarPrice == 0
- warningTT = "Start Point is currently zero or date is invalid. Modify the start point within settings or re-add this indicator to the chart."
- warningText = '🚨Modify Start Point🚨\nOr\n🚨Re-add to chart🚨'
- table.cell(infobox, 0, 1, warningText, text_color=col_T, text_halign=text.align_center, text_size=tableSize, tooltip=warningTT, bgcolor=col_W)
- table.merge_cells(infobox, 0, 1, 1, 1)
- else if useDisplayTarget and displayTarget == false
- warningTT = 'Target entered is invalid'
- table.cell(infobox, 0, 1, '\n🚨Target Invalid🚨\n', text_color=col_T, text_halign=text.align_center, text_size=tableSize, tooltip=warningTT, bgcolor=col_W)
- table.merge_cells(infobox, 0, 1, 1, 1)
- //Gap
- table.cell(infobox, 0, 2, 'Position', text_color=col_T, text_halign=text.align_center, text_size=size.tiny, tooltip='Position', bgcolor=col_H)
- table.merge_cells(infobox, 0, 2, 1, 2)
- //Entry
- directionLimitText = (isLong ? '🟢' : '🔴') + limitTypeText + ':'
- priceText = str.tostring(math.round_to_mintick(yBarPrice))
- table.cell(infobox, 0, 3, directionLimitText, text_color=col_T, text_halign=text.align_left, text_size=tableSize, tooltip=selectedDesc)
- table.cell(infobox, 1, 3, priceText, text_color=col_T, text_halign=text.align_center, text_size=tableSize, tooltip=selectedDesc)
- //Entry Stoploss
- if invalidStart == false
- stopText = waitingTrailing ? '⚠️Estimated Stoploss:':'⚠️Stoploss:'
- table.cell(infobox, 0, 4, stopText, text_color=col_T, text_halign=text.align_left, text_size=tableSize)
- stoplossText = waitingTrailing ? str.tostring(math.round_to_mintick(estimatedStoploss)) : str.tostring(math.round_to_mintick( isLong ? lowerTrailing : upperTrailing ))
- table.cell(infobox, 1, 4, stoplossText, text_color=col_T, text_halign=text.align_center, text_size=tableSize)
- //Entry Target
- if displayTarget and invalidStart == false
- targetText = waitingTrailing ? '🎯Estimated Target:':'🎯Target'
- profitText = waitingTrailing ? str.tostring(math.round_to_mintick(estimatedProfitTarget)) : str.tostring(math.round_to_mintick(targetPrice))
- table.cell(infobox, 0, 5, targetText, text_color=col_T, text_halign=text.align_left, text_size=tableSize)
- table.cell(infobox, 1, 5, profitText, text_color=col_T, text_halign=text.align_center, text_size=tableSize)
- //Gap
- table.cell(infobox, 0, 6, 'ATR Settings', text_color=col_T, text_halign=text.align_center, text_size=size.tiny, tooltip="ATR Settings", bgcolor=col_H)
- table.merge_cells(infobox, 0, 6, 1, 6)
- //ATR Settings
- table.cell(infobox, 0, 7, 'Length:', text_color=col_T, text_halign=text.align_left, text_size=tableSize)
- table.cell(infobox, 1, 7, str.tostring(length), text_color=col_T, text_halign=text.align_center, text_size=tableSize)
- table.cell(infobox, 0, 8, 'Multiplier:', text_color=col_T, text_halign=text.align_left, text_size=tableSize)
- table.cell(infobox, 1, 8, str.tostring(multiplier), text_color=col_T, text_halign=text.align_center, text_size=tableSize)
- table.cell(infobox, 0, 9, 'Type:', text_color=col_T, text_halign=text.align_left, text_size=tableSize)
- table.cell(infobox, 1, 9, str.tostring(maTypeInput), text_color=col_T, text_halign=text.align_center, text_size=tableSize)
- table.cell(infobox, 0,10, 'Source:', text_color=col_T, text_halign=text.align_left, text_size=tableSize, tooltip='Source for ATR Stoploss placement')
- table.cell(infobox, 1,10, isLong ? srcLowerVAL : srcUpperVAL, text_color=col_T, text_halign=text.align_center, text_size=tableSize, tooltip='Source for ATR Stoploss placement')
- if srcUseEntry
- table.cell(infobox, 0,11, '(1st bar = Entry)', text_color=col_T, text_halign=text.align_right, text_size=tableSize)
- table.merge_cells(infobox, 0, 11, 1, 11)
- updateText = updateOnce ? 'Bar Open' :
- updateEntryOnce ? 'Entry Open, Always' :
- 'Always'
- updateTT = updateOnce ? "Update Trailing Stoploss only once per bar on open, referencing prior bar's close." :
- updateEntryOnce ? "Update Trailing Stoploss only once on open bar, referencing prior bar's close. After, update Trailing Stoploss continuously." :
- "Update Trailing Stoploss continuously."
- table.cell(infobox, 0,12, 'Update:', text_color=col_T, text_halign=text.align_left, text_size=tableSize, tooltip='Frequency of updating ATR Trailing Stoploss')
- table.cell(infobox, 1,12, updateText, text_color=col_T, text_halign=text.align_center, text_size=tableSize, tooltip=updateTT)
- //Target
- if displayTarget
- //Gap
- table.cell(infobox, 0,13, 'Target Setting', text_color=col_T, text_halign=text.align_center, text_size=size.tiny, tooltip="Target Setting", bgcolor=col_H)
- table.merge_cells(infobox, 0, 13, 1, 13)
- //Target
- targetText = targetTypeRR ? '1 : ' + str.tostring(targetMult) : str.tostring(targetMult)
- targetTitleText = targetTypeRR ? 'Target (R:R):' : 'Target (Price):'
- table.cell(infobox, 0,14, targetTitleText, text_color=col_T, text_halign=text.align_left, text_size=tableSize)
- table.cell(infobox, 1,14, targetText, text_color=col_T, text_halign=text.align_center, text_size=tableSize)
- if targetTypeRR
- percentBreakEvenEST = str.tostring( 100 - (( 1 / ( 1 + (1/targetMult)) ) * 100) ,'#.#')
- table.cell(infobox, 0,15, 'Break Even:', text_color=col_T, text_halign=text.align_left, text_size=tableSize, tooltip='Break Even Winrate Percent')
- table.cell(infobox, 1,15, percentBreakEvenEST + '%', text_color=col_T, text_halign=text.align_center, text_size=tableSize, tooltip='Break Even Winrate Percent')
- //Gap
- table.cell(infobox, 0,16, 'Trigger Settings', text_color=col_T, text_halign=text.align_center, text_size=size.tiny, tooltip="Trigger Settings", bgcolor=col_H)
- table.merge_cells(infobox, 0, 16, 1, 16)
- //Triggers - Add this way to have the table take up less space on chart
- if displayTarget
- if entryTrigger == stopTrigger and stopTrigger == targetTrigger
- triggerText = 'Entry,Stop,Target: ' + entryTrigger
- table.cell(infobox, 0,17, triggerText, text_color=col_T, text_halign=text.align_left, text_size=tableSize)
- table.merge_cells(infobox, 0, 17, 1, 17)
- else
- table.cell(infobox, 0,17, 'Entry:', text_color=col_T, text_halign=text.align_left, text_size=tableSize)
- table.cell(infobox, 1,17, entryTrigger, text_color=col_T, text_halign=text.align_center, text_size=tableSize)
- table.cell(infobox, 0,18, 'Stop:', text_color=col_T, text_halign=text.align_left, text_size=tableSize)
- table.cell(infobox, 1,18, stopTrigger, text_color=col_T, text_halign=text.align_center, text_size=tableSize)
- table.cell(infobox, 0,19, 'Target:', text_color=col_T, text_halign=text.align_left, text_size=tableSize)
- table.cell(infobox, 1,19, targetTrigger, text_color=col_T, text_halign=text.align_center, text_size=tableSize)
- else
- if entryTrigger == stopTrigger
- table.cell(infobox, 0,17, 'Entry, Stop: ', text_color=col_T, text_halign=text.align_left, text_size=tableSize)
- table.cell(infobox, 1,17, entryTrigger, text_color=col_T, text_halign=text.align_left, text_size=tableSize)
- else
- table.cell(infobox, 0,17, 'Entry:', text_color=col_T, text_halign=text.align_left, text_size=tableSize)
- table.cell(infobox, 1,17, entryTrigger, text_color=col_T, text_halign=text.align_center, text_size=tableSize)
- table.cell(infobox, 0,18, 'Stop:', text_color=col_T, text_halign=text.align_left, text_size=tableSize)
- table.cell(infobox, 1,18, stopTrigger, text_color=col_T, text_halign=text.align_center, text_size=tableSize)
Advertisement
Add Comment
Please, Sign In to add comment