Source Code
This page contains the source code for my YouTube lessons.
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/ // © ZenAndTheArtOfTrading / www.PineScriptMastery.com // @version=5 indicator("Regime Filter") // Get user input res = input.timeframe(title="Timeframe", defval="D") len = input.int(title="EMA Length", defval=20) market = input.symbol(title="Market", defval="NASDAQ:NDX") // Define custom security function f_sec(_market, _res, _exp) => request.security(_market, _res, _exp[barstate.isconfirmed ? 0 : 1]) // Get EMA value ema = ta.ema(close, len) emaValue = f_sec(market, res, ema) // Check if price is above or below EMA filter marketPrice = f_sec(market, res, close) regimeFilter = marketPrice > emaValue or marketPrice[1] > emaValue[1] // Change background color bgcolor(regimeFilter ? color.green : color.red)
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/ // © ZenAndTheArtOfTrading / PineScriptMastery.com // @version=5 indicator("Auto-Fib", overlay=true) // Get user input var devTooltip = "Deviation is a multiplier that affects how much the price should deviate from the previous pivot in order for the bar to become a new pivot." var depthTooltip = "The minimum number of bars that will be taken into account when calculating the indicator." threshold_multiplier = input.float(title="Deviation", defval=3, minval=0, tooltip=devTooltip) depth = input.int(title="Depth", defval=10, minval=1, tooltip=depthTooltip) reverse = input.bool(title="Reverse", defval=false, tooltip="Flips the fibonacci levels around.") extendLeft = input.bool(title="Extend Left | Extend Right", defval=false, inline="Extend Lines") extendRight = input.bool(title="", defval=false, inline="Extend Lines") prices = input.bool(title="Show Prices", defval=false) deleteLastLine = input.bool(title="Delete Last Line", defval=true) levels = input.bool(title="Show Levels", defval=true, inline="Levels") levelsFormat = input.string(title="", defval="Values", options=["Values", "Percent"], inline="Levels") labelsPosition = input.string(title="Labels Position", defval="Left", options=["Left", "Right"]) backgroundTransparency = input.int(title="Background Transparency", defval=85, minval=0, maxval=100) // Check extending parameter var extending = extend.none if extendLeft and extendRight extending := extend.both if extendLeft and not extendRight extending := extend.left if not extendLeft and extendRight extending := extend.right // Calculate deviation threshold for identifying major swings dev_threshold = ta.atr(10) / close * 100 * threshold_multiplier // Prepare pivot variables var line lineLast = na var int iLast = 0 var int iPrev = 0 var float pLast = 0 var isHighLast = false // Otherwise the last pivot is a low pivot // Custom function for detecting pivot points pivots(src, length, isHigh) => l2 = length * 2 c = nz(src[length]) ok = true for i = 0 to l2 if isHigh and src[i] > c ok := false if not isHigh and src[i] < c ok := false if ok [bar_index[length], c] else [int(na), float(na)] // Get bar index & price high/low for current pivots [iH, pH] = pivots(high, depth / 2, true) [iL, pL] = pivots(low, depth / 2, false) // Custom function for calculating price deviation calc_dev(base_price, price) => 100 * (price - base_price) / price // Custom function for detecting pivots that meet our deviation criteria pivotFound(dev, isHigh, index, price) => if isHighLast == isHigh and not na(lineLast) // New pivot in same direction as last, so update line (ie. trend-continuation) if isHighLast ? price > pLast : price < pLast line.set_xy2(lineLast, index, price) [lineLast, isHighLast] else [line(na), bool(na)] // No valid pivot detected, return nothing else // Reverse the trend/pivot direction (or create the very first line if lineLast is na) if math.abs(dev) > dev_threshold // Price move is significant - create a new line between the pivot points id = line.new(iLast, pLast, index, price, color=color.gray, width=1, style=line.style_dashed) [id, isHigh] else [line(na), bool(na)] // If bar index for current pivot high is not NA (ie. we have a new pivot): if not na(iH) dev = calc_dev(pLast, pH) // Calculate the deviation from last pivot [id, isHigh] = pivotFound(dev, true, iH, pH) if not na(id) // If the line has been updated, update price values and delete previous line if id != lineLast and deleteLastLine line.delete(lineLast) lineLast := id isHighLast := isHigh iPrev := iLast iLast := iH pLast := pH else if not na(iL) // If bar index for current pivot low is not NA (ie. we have a new pivot): dev = calc_dev(pLast, pL) // Calculate the deviation from last pivot [id, isHigh] = pivotFound(dev, false, iL, pL) if not na(id) // If the line has been updated, update price values and delete previous line if id != lineLast and deleteLastLine line.delete(lineLast) lineLast := id isHighLast := isHigh iPrev := iLast iLast := iL pLast := pL // Draw fibonacci level as a line and return the line object ID draw_fib_line(price, col) => var id = line.new(iLast, price, bar_index, price, color=col, width=1, extend=extending) if not na(lineLast) line.set_xy1(id, line.get_x1(lineLast), price) line.set_xy2(id, line.get_x2(lineLast), price) id // Draw fibonacci labels draw_label(price, txt, txtColor) => x = labelsPosition == "Left" ? line.get_x1(lineLast) : not extendRight ? line.get_x2(lineLast) : bar_index labelStyle = labelsPosition == "Left" ? label.style_label_right : label.style_label_left align = labelsPosition == "Left" ? text.align_right : text.align_left labelsAlignStrLeft = txt + '\n \n' labelsAlignStrRight = ' ' + txt + '\n \n' labelsAlignStr = labelsPosition == "Left" ? labelsAlignStrLeft : labelsAlignStrRight var id = label.new(x=x, y=price, text=labelsAlignStr, textcolor=txtColor, style=labelStyle, textalign=align, color=#00000000) label.set_xy(id, x, price) label.set_text(id, labelsAlignStr) label.set_textcolor(id, txtColor) // Format the given string format(txt) => " (" + str.tostring(txt, "#.####") + ")" // Return the formatted label text for Fibonacci levels label_txt(level, price) => l = levelsFormat == "Values" ? str.tostring(level) : str.tostring(level * 100) + "%" (levels ? l : "") + (prices ? format(price) : "") // Returns true if price is crossing the given fib level crossing_level(price, fib) => (fib > price and fib < price[1]) or (fib < price and fib > price[1]) // Get starting and ending high/low price of the current pivot (for calculating fib levels) startPrice = reverse ? line.get_y1(lineLast) : pLast endPrice = reverse ? pLast : line.get_y1(lineLast) // Calculate price difference between high and low iHL = startPrice > endPrice diff = (iHL ? -1 : 1) * math.abs(startPrice - endPrice) // Process the given fib level (calculate fib, draw line & label, detect alerts, fill bgcolor between last fib) processLevel(show, value, colorL, lineIdOther) => if show fibPrice = startPrice + diff * value lineId = draw_fib_line(fibPrice, colorL) draw_label(fibPrice, label_txt(value, fibPrice), colorL) if crossing_level(close, fibPrice) // Trigger alert if price is crossing this fib level alert("Autofib: " + syminfo.ticker + " crossing level " + str.tostring(value)) if not na(lineIdOther) // Fill background color between each fib level linefill.new(lineId, lineIdOther, color=color.new(colorL, backgroundTransparency)) lineId else lineIdOther //{============================================================================= var g_fibs = "Fibonacci Levels" // Get Fibonacci level user inputs show_0 = input(true, "", inline = "Level0", group=g_fibs) value_0 = input(0, "", inline = "Level0", group=g_fibs) color_0 = input(#787b86, "", inline = "Level0", group=g_fibs) //------------------------------------------------------------------------------ show_0_236 = input(true, "", inline = "Level0", group=g_fibs) value_0_236 = input(0.236, "", inline = "Level0", group=g_fibs) color_0_236 = input(#f44336, "", inline = "Level0", group=g_fibs) //------------------------------------------------------------------------------ show_0_382 = input(true, "", inline = "Level1", group=g_fibs) value_0_382 = input(0.382, "", inline = "Level1", group=g_fibs) color_0_382 = input(#81c784, "", inline = "Level1", group=g_fibs) //------------------------------------------------------------------------------ show_0_5 = input(true, "", inline = "Level1", group=g_fibs) value_0_5 = input(0.5, "", inline = "Level1", group=g_fibs) color_0_5 = input(#4caf50, "", inline = "Level1", group=g_fibs) //------------------------------------------------------------------------------ show_0_618 = input(true, "", inline = "Level2", group=g_fibs) value_0_618 = input(0.618, "", inline = "Level2", group=g_fibs) color_0_618 = input(#009688, "", inline = "Level2", group=g_fibs) //------------------------------------------------------------------------------ show_0_65 = input(false, "", inline = "Level2", group=g_fibs) value_0_65 = input(0.65, "", inline = "Level2", group=g_fibs) color_0_65 = input(#009688, "", inline = "Level2", group=g_fibs) //------------------------------------------------------------------------------ show_0_786 = input(true, "", inline = "Level3", group=g_fibs) value_0_786 = input(0.786, "", inline = "Level3", group=g_fibs) color_0_786 = input(#64b5f6, "", inline = "Level3", group=g_fibs) //------------------------------------------------------------------------------ show_1 = input(true, "", inline = "Level3", group=g_fibs) value_1 = input(1, "", inline = "Level3", group=g_fibs) color_1 = input(#787b86, "", inline = "Level3", group=g_fibs) //------------------------------------------------------------------------------ show_1_272 = input(false, "", inline = "Level4", group=g_fibs) value_1_272 = input(1.272, "", inline = "Level4", group=g_fibs) color_1_272 = input(#81c784, "", inline = "Level4", group=g_fibs) //------------------------------------------------------------------------------ show_1_414 = input(false, "", inline = "Level4", group=g_fibs) value_1_414 = input(1.414, "", inline = "Level4", group=g_fibs) color_1_414 = input(#f44336, "", inline = "Level4", group=g_fibs) //------------------------------------------------------------------------------ show_1_618 = input(false, "", inline = "Level5", group=g_fibs) value_1_618 = input(1.618, "", inline = "Level5", group=g_fibs) color_1_618 = input(#2196f3, "", inline = "Level5", group=g_fibs) //------------------------------------------------------------------------------ show_1_65 = input(false, "", inline = "Level5", group=g_fibs) value_1_65 = input(1.65, "", inline = "Level5", group=g_fibs) color_1_65 = input(#2196f3, "", inline = "Level5", group=g_fibs) //------------------------------------------------------------------------------ show_2_618 = input(false, "", inline = "Level6", group=g_fibs) value_2_618 = input(2.618, "", inline = "Level6", group=g_fibs) color_2_618 = input(#f44336, "", inline = "Level6", group=g_fibs) //------------------------------------------------------------------------------ show_2_65 = input(false, "", inline = "Level6", group=g_fibs) value_2_65 = input(2.65, "", inline = "Level6", group=g_fibs) color_2_65 = input(#f44336, "", inline = "Level6", group=g_fibs) //------------------------------------------------------------------------------ show_3_618 = input(false, "", inline = "Level7", group=g_fibs) value_3_618 = input(3.618, "", inline = "Level7", group=g_fibs) color_3_618 = input(#9c27b0, "", inline = "Level7", group=g_fibs) //------------------------------------------------------------------------------ show_3_65 = input(false, "", inline = "Level7", group=g_fibs) value_3_65 = input(3.65, "", inline = "Level7", group=g_fibs) color_3_65 = input(#9c27b0, "", inline = "Level7", group=g_fibs) //------------------------------------------------------------------------------ show_4_236 = input(false, "", inline = "Level8", group=g_fibs) value_4_236 = input(4.236, "", inline = "Level8", group=g_fibs) color_4_236 = input(#e91e63, "", inline = "Level8", group=g_fibs) //------------------------------------------------------------------------------ show_4_618 = input(false, "", inline = "Level8", group=g_fibs) value_4_618 = input(4.618, "", inline = "Level8", group=g_fibs) color_4_618 = input(#81c784, "", inline = "Level8", group=g_fibs) //------------------------------------------------------------------------------ show_neg_0_236 = input(false, "", inline = "Level9", group=g_fibs) value_neg_0_236 = input(-0.236, "", inline = "Level9", group=g_fibs) color_neg_0_236 = input(#f44336, "", inline = "Level9", group=g_fibs) //------------------------------------------------------------------------------ show_neg_0_382 = input(false, "", inline = "Level9", group=g_fibs) value_neg_0_382 = input(-0.382, "", inline = "Level9", group=g_fibs) color_neg_0_382 = input(#81c784, "", inline = "Level9", group=g_fibs) //------------------------------------------------------------------------------ show_neg_0_618 = input(false, "", inline = "Level10", group=g_fibs) value_neg_0_618 = input(-0.618, "", inline = "Level10", group=g_fibs) color_neg_0_618 = input(#009688, "", inline = "Level10", group=g_fibs) //------------------------------------------------------------------------------ show_neg_0_65 = input(false, "", inline = "Level10", group=g_fibs) value_neg_0_65 = input(-0.65, "", inline = "Level10", group=g_fibs) color_neg_0_65 = input(#009688, "", inline = "Level10", group=g_fibs) //-----------------------------------------------------------------------------} //{============================================================================= // Process each fibonacci level //============================================================================== lineId0 = processLevel(show_neg_0_65, value_neg_0_65, color_neg_0_65, line(na)) lineId1 = processLevel(show_neg_0_618, value_neg_0_618, color_neg_0_618, lineId0) lineId2 = processLevel(show_neg_0_382, value_neg_0_382, color_neg_0_382, lineId1) lineId3 = processLevel(show_neg_0_236, value_neg_0_236, color_neg_0_236, lineId2) lineId4 = processLevel(show_0, value_0, color_0, lineId3) lineId5 = processLevel(show_0_236, value_0_236, color_0_236, lineId4) lineId6 = processLevel(show_0_382, value_0_382, color_0_382, lineId5) lineId7 = processLevel(show_0_5, value_0_5, color_0_5, lineId6) lineId8 = processLevel(show_0_618, value_0_618, color_0_618, lineId7) lineId9 = processLevel(show_0_65, value_0_65, color_0_65, lineId8) lineId10 = processLevel(show_0_786, value_0_786, color_0_786, lineId9) lineId11 = processLevel(show_1, value_1, color_1, lineId10) lineId12 = processLevel(show_1_272, value_1_272, color_1_272, lineId11) lineId13 = processLevel(show_1_414, value_1_414, color_1_414, lineId12) lineId14 = processLevel(show_1_618, value_1_618, color_1_618, lineId13) lineId15 = processLevel(show_1_65, value_1_65, color_1_65, lineId14) lineId16 = processLevel(show_2_618, value_2_618, color_2_618, lineId15) lineId17 = processLevel(show_2_65, value_2_65, color_2_65, lineId16) lineId18 = processLevel(show_3_618, value_3_618, color_3_618, lineId17) lineId19 = processLevel(show_3_65, value_3_65, color_3_65, lineId18) lineId20 = processLevel(show_4_236, value_4_236, color_4_236, lineId19) lineId21 = processLevel(show_4_618, value_4_618, color_4_618, lineId20) //-----------------------------------------------------------------------------}
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/ // © ZenAndTheArtOfTrading / PineScriptMastery.com // @version=5 indicator("Pivot Points", overlay=true) // Get user input var devTooltip = "Deviation is a multiplier that affects how much the price should deviate from the previous pivot in order for the bar to become a new pivot." var depthTooltip = "The minimum number of bars that will be taken into account when analyzing pivots." threshold_multiplier = input.float(title="Deviation", defval=2.5, minval=0, tooltip=devTooltip) depth = input.int(title="Depth", defval=10, minval=1, tooltip=depthTooltip) deleteLastLine = input.bool(title="Delete Last Line", defval=false) bgcolorChange = input.bool(title="Change BgColor", defval=false) // Calculate deviation threshold for identifying major swings dev_threshold = ta.atr(10) / close * 100 * threshold_multiplier // Prepare pivot variables var line lineLast = na var int iLast = 0 // Index last var int iPrev = 0 // Index previous var float pLast = 0 // Price last var isHighLast = false // If false then the last pivot was a pivot low // Custom function for detecting pivot points (and returning price + bar index) pivots(src, length, isHigh) => l2 = length * 2 c = nz(src[length]) ok = true for i = 0 to l2 if isHigh and src[i] > c // If isHigh, validate pivot high ok := false if not isHigh and src[i] < c // If not isHigh, validate pivot low ok := false if ok // If pivot is valid, return bar index + high price value [bar_index[length], c] else // If pivot is invalid, return na [int(na), float(na)] // Get bar index & price high/low for current pivots [iH, pH] = pivots(high, depth / 2, true) [iL, pL] = pivots(low, depth / 2, false) // Custom function for calculating price deviation for validating large moves calc_dev(base_price, price) => 100 * (price - base_price) / price // Custom function for detecting pivots that meet our deviation criteria pivotFound(dev, isHigh, index, price) => if isHighLast == isHigh and not na(lineLast) // Check bull/bear direction of new pivot // New pivot in same direction as last (a pivot high), so update line upwards (ie. trend-continuation) if isHighLast ? price > pLast : price < pLast // If new pivot is above last pivot, update line line.set_xy2(lineLast, index, price) [lineLast, isHighLast] else [line(na), bool(na)] // New pivot is not above last pivot, so don't update the line else // Reverse the trend/pivot direction (or create the very first line if lineLast is na) if math.abs(dev) > dev_threshold // Price move is significant - create a new line between the pivot points id = line.new(iLast, pLast, index, price, color=color.gray, width=1, style=line.style_dashed) [id, isHigh] else [line(na), bool(na)] // If bar index for current pivot high is not NA (ie. we have a new pivot): if not na(iH) dev = calc_dev(pLast, pH) // Calculate the deviation from last pivot [id, isHigh] = pivotFound(dev, true, iH, pH) // Pass the current pivot high into pivotFound() for validation & line update if not na(id) // If the line has been updated, update price & index values and delete previous line if id != lineLast and deleteLastLine line.delete(lineLast) lineLast := id isHighLast := isHigh iPrev := iLast iLast := iH pLast := pH else if not na(iL) // If bar index for current pivot low is not NA (ie. we have a new pivot): dev = calc_dev(pLast, pL) // Calculate the deviation from last pivot [id, isHigh] = pivotFound(dev, false, iL, pL) // Pass the current pivot low into pivotFound() for validation & line update if not na(id) // If the line has been updated, update price values and delete previous line if id != lineLast and deleteLastLine line.delete(lineLast) lineLast := id isHighLast := isHigh iPrev := iLast iLast := iL pLast := pL // Get starting and ending high/low price of the current pivot line startIndex = line.get_x1(lineLast) startPrice = line.get_y1(lineLast) endIndex = line.get_x2(lineLast) endPrice = line.get_y2(lineLast) // Draw top & bottom of impulsive move topLine = line.new(startIndex, startPrice, endIndex, startPrice, extend=extend.right, color=color.red) bottomline = line.new(startIndex, endPrice, endIndex, endPrice, extend=extend.right, color=color.green) line.delete(topLine[1]) line.delete(bottomline[1]) //plot(startPrice, color=color.green) //plot(endPrice, color=color.red) // Do what you like with these pivot values :) // Keep in mind there will be an X bar delay between pivot price values updating based on Depth setting dist = math.abs(startPrice - endPrice) plot(dist, color=color.new(color.purple,100)) bullish = endPrice > startPrice offsetBG = -(depth / 2) bgcolor(bgcolorChange ? bullish ? color.new(color.green,90) : color.new(color.red,90) : na, offset=offsetBG)
// PineScriptMastery.com // @version=5 indicator(title="Ichimoku Cloud", shorttitle="Ichimoku", overlay=true) // Get user input conversionPeriods = input.int(9, minval=1, title="Conversion Line Length") basePeriods = input.int(26, minval=1, title="Base Line Length") laggingSpan2Periods = input.int(52, minval=1, title="Leading Span B Length") displacement = input.int(26, minval=1, title="Lagging Span") donchian(len) => math.avg(ta.lowest(len), ta.highest(len)) conversionLine = donchian(conversionPeriods) baseLine = donchian(basePeriods) leadLine1 = math.avg(conversionLine, baseLine) leadLine2 = donchian(laggingSpan2Periods) // Draw cloud plot(conversionLine, color=#2962FF, title="Conversion Line", display=display.none) plot(baseLine, color=#B71C1C, title="Base Line", display=display.none) plot(close, offset = -displacement + 1, color=#43A047, title="Lagging Span", display=display.none) p1 = plot(leadLine1, offset = displacement - 1, color=#A5D6A7, title="Leading Span A", display=display.none) p2 = plot(leadLine2, offset = displacement - 1, color=#EF9A9A, title="Leading Span B", display=display.none) fill(p1, p2, color = leadLine1 > leadLine2 ? color.rgb(67, 160, 71, 90) : color.rgb(244, 67, 54, 90), display=display.none) // Track horizontal baseline var baseLineSaved = baseLine if baseLine != baseLine[1] baseLineSaved := na else baseLineSaved := baseLine // Draw baseline plot(baseLineSaved, color=color.purple, style=plot.style_linebr, title="Base Line Saved") // Track price trading above/below baseline isPriceAboveBaseLine = close > baseLineSaved priceTradingAboveBL = isPriceAboveBaseLine and not na(baseLineSaved) priceTradingBelowBL = not isPriceAboveBaseLine and not na(baseLineSaved) // Draw condition bgcolor(priceTradingAboveBL ? color.new(color.green,80) : na) bgcolor(priceTradingBelowBL ? color.new(color.red,80) : na) // Track candle pattern tests of baseline (example purposes - needs more conditions to be actually useful!) candlePatternBull = priceTradingAboveBL and priceTradingAboveBL[1] and low[1] < baseLineSaved and close > baseLineSaved candlePatternBear = priceTradingBelowBL and priceTradingBelowBL[1] and high[1] > baseLineSaved and close < baseLineSaved plotshape(candlePatternBull, style=shape.triangleup, color=color.green, location=location.belowbar) plotshape(candlePatternBear, style=shape.triangledown, color=color.red)
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/ // © ZenAndTheArtOfTrading / www.PineScriptMastery.com // @version=5 strategy("Simple Pullback Strategy", overlay=true, initial_capital=50000, default_qty_type=strategy.percent_of_equity, default_qty_value=100, // 100% of balance invested on each trade commission_type=strategy.commission.cash_per_contract, commission_value=0.005) // Interactive Brokers rate // Get user input i_ma1 = input.int(title="MA 1 Length", defval=200, step=10, group="Strategy Parameters", tooltip="Long-term MA") i_ma2 = input.int(title="MA 2 Length", defval=10, step=10, group="Strategy Parameters", tooltip="Short-term MA") i_stopPercent = input.float(title="Stop Loss Percent", defval=0.10, step=0.1, group="Strategy Parameters", tooltip="Failsafe Stop Loss Percent Decline") i_lowerClose = input.bool(title="Exit On Lower Close", defval=false, group="Strategy Parameters", tooltip="Wait for a lower-close before exiting above MA2") i_startTime = input.time(title="Start Filter", defval=timestamp("01 Jan 1995 13:30 +0000"), group="Time Filter", tooltip="Start date & time to begin searching for setups") i_endTime = input.time(title="End Filter", defval=timestamp("1 Jan 2099 19:30 +0000"), group="Time Filter", tooltip="End date & time to stop searching for setups") // Get indicator values ma1 = ta.sma(close, i_ma1) ma2 = ta.sma(close, i_ma2) // Check filter(s) f_dateFilter = time >= i_startTime and time <= i_endTime // Check buy/sell conditions var float buyPrice = 0 buyCondition = close > ma1 and close < ma2 and strategy.position_size == 0 and f_dateFilter sellCondition = close > ma2 and strategy.position_size > 0 and (not i_lowerClose or close < low[1]) stopDistance = strategy.position_size > 0 ? ((buyPrice - close) / close) : na stopPrice = strategy.position_size > 0 ? buyPrice - (buyPrice * i_stopPercent) : na stopCondition = strategy.position_size > 0 and stopDistance > i_stopPercent // Enter positions if buyCondition strategy.entry(id="Long", direction=strategy.long) if buyCondition[1] buyPrice := open // Exit positions if sellCondition or stopCondition strategy.close(id="Long", comment="Exit" + (stopCondition ? "SL=true" : "")) buyPrice := na // Draw pretty colors plot(buyPrice, color=color.lime, style=plot.style_linebr) plot(stopPrice, color=color.red, style=plot.style_linebr, offset=-1) plot(ma1, color=color.blue) plot(ma2, color=color.orange)
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/ // © ZenAndTheArtOfTrading / www.PineScriptMastery.com // // System Rules: // Indicators: MACD indicator (default values), ATR (14), EMA (200) // 1. Price must be trading above/below the 200 EMA // 2. Only 1 bar can close above/below the 200 EMA over the past 5 bars // 3. We take the FIRST MACD cross and ignore subsequent signals until TP/SL is hit // 4. Stop Loss = 0.5 ATR above/below the recent swing high/low (7 bars lookback) // 5. First take profit = 1:1 (25%) // 6. Second take profit = 2:1 (100%) // 7. Move stop loss to break-even after 1st target is hit // // @version=5 strategy("[2022] MACD Cross Strategy", overlay=true, currency="USD", calc_on_order_fills=true, use_bar_magnifier=true, initial_capital=10000, default_qty_type=strategy.percent_of_equity, default_qty_value=100, // 100% of balance invested on each trade commission_type=strategy.commission.cash_per_contract) //commission_value=0.005) // Interactive Brokers rate // Import ZenLibrary import ZenAndTheArtOfTrading/ZenLibrary/5 as zen // Get user input var g_system = "System Entry Settings" i_ema_filter = input.int(title="EMA Filter Length", defval=200, group=g_system) i_ema_filter2 = input.int(title="EMA Max Bars Above/Below", defval=1, group=g_system) i_stop_multi = input.float(title="Stop Loss Multiplier", defval=0.5, step=0.5, group=g_system) i_stop_lookback = input.int(title="Stop Loss Lookback", defval=7, group=g_system) var g_risk = "System Risk Settings" i_rr1 = input.float(title="Risk:Reward Target 1", defval=1.0, group=g_risk) i_rr2 = input.float(title="Risk:Reward Target 2", defval=2.0, group=g_risk) i_target1 = input.float(title="Profit % Target 1", defval=25, group=g_risk) i_riskPerTrade = input.float(title="Forex Risk Per Trade %", defval=1.0) var g_macd = "MACD Settings" i_price_src = input.source(title="Price Source", defval=close, group=g_macd) i_fast_length = input.int(title="Fast Length", defval=12, group=g_macd) i_slow_length = input.int(title="Slow Length", defval=26, group=g_macd) i_signal_length = input.int(title="Signal Smoothing", minval=1, maxval=50, defval=9, group=g_macd) i_sma_source = input.string(title="Oscillator MA Type", defval="EMA", options=["SMA", "EMA"], group=g_macd) i_sma_signal = input.string(title="Signal Line MA Type", defval="EMA", options=["SMA", "EMA"], group=g_macd) //------------- DETERMINE CURRENCY CONVERSION RATE -------------// // Check if our account currency is the same as the base or quote currency or neither (for risk $ conversion purposes) accountSameAsCounterCurrency = strategy.account_currency == syminfo.currency accountSameAsBaseCurrency = strategy.account_currency == syminfo.basecurrency accountNeitherCurrency = not accountSameAsCounterCurrency and not accountSameAsBaseCurrency // Get currency conversion rates if applicable conversionCurrencyPair = accountSameAsCounterCurrency ? syminfo.tickerid : strategy.account_currency + syminfo.currency conversionCurrencyRate = accountSameAsBaseCurrency or accountNeitherCurrency ? request.security(conversionCurrencyPair, "D", close, ignore_invalid_symbol=true) : 1.0 // Display the current conversion currency ticker (for debug purposes) if barstate.islastconfirmedhistory table t = table.new(position.top_right, 1, 2, color.black) table.cell(t, 0, 0, "Conversion: " + conversionCurrencyPair + " (" + str.tostring(conversionCurrencyRate) + ")", text_color=color.white, text_size=size.small) table.cell(t, 0, 1, "Account: $" + str.tostring(zen.truncate(strategy.equity)), text_color=color.white, text_size=size.small) //------------- END CURRENCY CONVERSION RATE CODE -------------// // Calculate MACD [macdLine, signalLine, histLine] = ta.macd(i_price_src, i_fast_length, i_slow_length, i_signal_length) // Get indicator values ema = ta.ema(close, i_ema_filter) atr = ta.atr(14) // Check for zero-point crosses crossUp = ta.crossover(signalLine, macdLine) crossDown = ta.crossunder(signalLine, macdLine) // Check general system filters tradeFilters = not na(ema) and not na(atr) // Check trend conditions upTrend = close > ema downTrend = close < ema // Check trade conditions longConditions = tradeFilters and macdLine[1] < 0 and signalLine[1] < 0 shortConditions = tradeFilters and macdLine[1] > 0 and signalLine[1] > 0 // Confirm long & short setups longSignal = longConditions and upTrend and crossDown shortSignal = shortConditions and downTrend and crossUp // Calculate stop loss longStop = ta.lowest(low, i_stop_lookback) - (atr * i_stop_multi) shortStop = ta.highest(high, i_stop_lookback) + (atr * i_stop_multi) // Save stops & targets var float tradeStop = na var float tradeTarget1 = na var float tradeTarget2 = na var float tradeSize = na // Count bars above/below MA int barsAboveMA = 0 int barsBelowMA = 0 for i = 1 to 5 if close[i] < ema[i] barsBelowMA += 1 if close[i] > ema[i] barsAboveMA += 1 // Combine signal filters longTrade = longSignal and barsBelowMA <= i_ema_filter2 and strategy.position_size == 0 shortTrade = shortSignal and barsAboveMA <= i_ema_filter2 and strategy.position_size == 0 // Handle long trade entry (enter position, reset stops & targets) if longTrade if syminfo.type == "forex" tradeStop := longStop stopDistance = close - tradeStop tradeTarget1 := close + (stopDistance * i_rr1) tradeTarget2 := close + (stopDistance * i_rr2) tradeSize := na positionSize = zen.av_getPositionSize(strategy.equity, i_riskPerTrade, zen.toWhole(stopDistance) * 10, conversionCurrencyRate) strategy.entry(id="Long", direction=strategy.long, qty=positionSize) else strategy.entry(id="Long", direction=strategy.long) tradeStop := na tradeTarget1 := na tradeTarget2 := na // Handle short trade entry (enter position, reset stops & targets) if shortTrade if syminfo.type == "forex" tradeStop := shortStop stopDistance = tradeStop - close tradeTarget1 := close - (stopDistance * i_rr1) tradeTarget2 := close - (stopDistance * i_rr2) tradeSize := na positionSize = zen.av_getPositionSize(strategy.equity, i_riskPerTrade, zen.toWhole(shortStop - close) * 10, conversionCurrencyRate) strategy.entry(id="Short", direction=strategy.short, qty=positionSize) else strategy.entry(id="Short", direction=strategy.short) tradeStop := na tradeTarget1 := na tradeTarget2 := na // Handle forex trade size tracking variable if syminfo.type == "forex" and strategy.position_size != 0 and na(tradeSize) tradeSize := strategy.position_size // Handle long stops & target calculation if strategy.position_size > 0 and na(tradeStop) and syminfo.type != "forex" tradeStop := longStop stopDistance = strategy.position_avg_price - tradeStop tradeTarget1 := strategy.position_avg_price + (stopDistance * i_rr1) tradeTarget2 := strategy.position_avg_price + (stopDistance * i_rr2) tradeSize := strategy.position_size // Handle short stops & target calculation if strategy.position_size < 0 and na(tradeStop) and syminfo.type != "forex" tradeStop := shortStop stopDistance = tradeStop - strategy.position_avg_price tradeTarget1 := strategy.position_avg_price - (stopDistance * i_rr1) tradeTarget2 := strategy.position_avg_price - (stopDistance * i_rr2) tradeSize := strategy.position_size // Handle trade exits strategy.exit(id="Long Exit #1", from_entry="Long", limit=tradeTarget1, stop=tradeStop, qty_percent=i_target1) strategy.exit(id="Long Exit #2", from_entry="Long", limit=tradeTarget2, stop=tradeStop, qty_percent=100) strategy.exit(id="Short Exit #1", from_entry="Short", limit=tradeTarget1, stop=tradeStop, qty_percent=i_target1) strategy.exit(id="Short Exit #2", from_entry="Short", limit=tradeTarget2, stop=tradeStop, qty_percent=100) // Handle both long & short trade break-even stops (do this AFTER first position has exited above ^) if strategy.position_size != tradeSize tradeStop := strategy.position_avg_price tradeTarget1 := na // Draw conditional data plot(ema, color=close > ema ? color.green : color.red, linewidth=2, title="EMA") plotshape(longTrade, style=shape.triangleup, color=color.green, location=location.belowbar, title="Long Setup") plotshape(shortTrade, style=shape.triangledown, color=color.red, location=location.abovebar, title="Short Setup") // Draw stops & targets plot(strategy.position_size != 0 ? tradeStop : na, color=color.red, style=plot.style_linebr, title="Stop Loss") plot(strategy.position_size != 0 ? tradeTarget1 : na, color=color.green, style=plot.style_linebr, title="Profit Target 1") plot(strategy.position_size != 0 ? tradeTarget2 : na, color=color.green, style=plot.style_linebr, title="Profit Target 2")
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/ // © ZenAndTheArtOfTrading / www.PineScriptMastery.com // // System Rules: // Indicators: MACD indicator (default values), ATR (14), EMA (200) // 1. Price must be trading above/below the 200 EMA // 2. Only 1 bar can close above/below the 200 EMA over the past 5 bars // 3. We take the FIRST MACD cross and ignore subsequent signals until TP/SL is hit // 4. Stop Loss = 0.5 ATR above/below the recent swing high/low (7 bars lookback) // 5. First take profit = 1:1 (25%) // 6. Second take profit = 2:1 (100%) // 7. Move stop loss to break-even after 1st target is hit // // @version=5 strategy("[2022] MACD Cross Strategy", overlay=true, currency="USD", calc_on_order_fills=true, use_bar_magnifier=true, initial_capital=10000, default_qty_type=strategy.percent_of_equity, default_qty_value=100, // 100% of balance invested on each trade commission_type=strategy.commission.cash_per_contract) //commission_value=0.005) // Interactive Brokers rate // Get user input var g_system = "System Entry Settings" i_ema_filter = input.int(title="EMA Filter Length", defval=200, group=g_system) i_ema_filter2 = input.int(title="EMA Max Bars Above/Below", defval=1, group=g_system) i_stop_multi = input.float(title="Stop Loss Multiplier", defval=0.5, step=0.5, group=g_system) i_stop_lookback = input.int(title="Stop Loss Lookback", defval=7, group=g_system) var g_risk = "System Risk Settings" i_rr1 = input.float(title="Risk:Reward Target 1", defval=1.0, group=g_risk) i_rr2 = input.float(title="Risk:Reward Target 2", defval=2.0, group=g_risk) i_target1 = input.float(title="Profit % Target 1", defval=25, group=g_risk) i_riskPerTrade = input.float(title="Forex Risk Per Trade %", defval=1.0) i_useLots = input.bool(title="Use Lots Instead Of Units", defval=false) var g_macd = "MACD Settings" i_price_src = input.source(title="Price Source", defval=close, group=g_macd) i_fast_length = input.int(title="Fast Length", defval=12, group=g_macd) i_slow_length = input.int(title="Slow Length", defval=26, group=g_macd) i_signal_length = input.int(title="Signal Smoothing", minval=1, maxval=50, defval=9, group=g_macd) i_sma_source = input.string(title="Oscillator MA Type", defval="EMA", options=["SMA", "EMA"], group=g_macd) i_sma_signal = input.string(title="Signal Line MA Type", defval="EMA", options=["SMA", "EMA"], group=g_macd) //------------- DETERMINE CURRENCY CONVERSION RATE ------------- { // // Import ZenLibrary import ZenAndTheArtOfTrading/ZenLibrary/5 as zen // Custom function for converting units into lot sizes unitsToLots(units) => float lots = units / 100000 lots := math.round(lots, 2) _return = lots * 100000 // Check if our account currency is the same as the base or quote currency or neither (for risk $ conversion purposes) accountSameAsCounterCurrency = strategy.account_currency == syminfo.currency accountSameAsBaseCurrency = strategy.account_currency == syminfo.basecurrency accountNeitherCurrency = not accountSameAsCounterCurrency and not accountSameAsBaseCurrency // Get currency conversion rates if applicable conversionCurrencyPair = accountSameAsCounterCurrency ? syminfo.tickerid : strategy.account_currency + syminfo.currency conversionCurrencyRate = accountSameAsBaseCurrency or accountNeitherCurrency ? request.security(conversionCurrencyPair, "D", close, ignore_invalid_symbol=true) : 1.0 // Display the current conversion currency ticker (for debug purposes) if barstate.islastconfirmedhistory table t = table.new(position.top_right, 1, 2, color.black) table.cell(t, 0, 0, "Conversion: " + conversionCurrencyPair + " (" + str.tostring(conversionCurrencyRate) + ")", text_color=color.white, text_size=size.small) table.cell(t, 0, 1, "Account: $" + str.tostring(zen.truncate(strategy.equity)), text_color=color.white, text_size=size.small) //------------- END CURRENCY CONVERSION RATE CODE ------------- }// // Calculate MACD [macdLine, signalLine, histLine] = ta.macd(i_price_src, i_fast_length, i_slow_length, i_signal_length) // Get indicator values ema = ta.ema(close, i_ema_filter) atr = ta.atr(14) // Check for zero-point crosses crossUp = ta.crossover(signalLine, macdLine) crossDown = ta.crossunder(signalLine, macdLine) // Check general system filters tradeFilters = not na(ema) and not na(atr) // Check trend conditions upTrend = close > ema downTrend = close < ema // Check trade conditions longConditions = tradeFilters and macdLine[1] < 0 and signalLine[1] < 0 shortConditions = tradeFilters and macdLine[1] > 0 and signalLine[1] > 0 // Confirm long & short setups longSignal = longConditions and upTrend and crossDown shortSignal = shortConditions and downTrend and crossUp // Calculate stop loss longStop = ta.lowest(low, i_stop_lookback) - (atr * i_stop_multi) shortStop = ta.highest(high, i_stop_lookback) + (atr * i_stop_multi) // Save stops & targets var float tradeStop = na var float tradeTarget1 = na var float tradeTarget2 = na var float tradeSize = na // Count bars above/below MA int barsAboveMA = 0 int barsBelowMA = 0 for i = 1 to 5 if close[i] < ema[i] barsBelowMA += 1 if close[i] > ema[i] barsAboveMA += 1 // Combine signal filters longTrade = longSignal and barsBelowMA <= i_ema_filter2 and strategy.position_size == 0 shortTrade = shortSignal and barsAboveMA <= i_ema_filter2 and strategy.position_size == 0 // Handle long trade entry (enter position, reset stops & targets) if longTrade if syminfo.type == "forex" tradeStop := longStop stopDistance = close - tradeStop tradeTarget1 := close + (stopDistance * i_rr1) tradeTarget2 := close + (stopDistance * i_rr2) tradeSize := na positionSize = zen.av_getPositionSize(strategy.equity, i_riskPerTrade, zen.toWhole(stopDistance) * 10, conversionCurrencyRate) strategy.entry(id="Long", direction=strategy.long, qty=i_useLots ? unitsToLots(positionSize) : positionSize) else strategy.entry(id="Long", direction=strategy.long) tradeStop := na tradeTarget1 := na tradeTarget2 := na // Handle short trade entry (enter position, reset stops & targets) if shortTrade if syminfo.type == "forex" tradeStop := shortStop stopDistance = tradeStop - close tradeTarget1 := close - (stopDistance * i_rr1) tradeTarget2 := close - (stopDistance * i_rr2) tradeSize := na positionSize = zen.av_getPositionSize(strategy.equity, i_riskPerTrade, zen.toWhole(shortStop - close) * 10, conversionCurrencyRate) strategy.entry(id="Short", direction=strategy.short, qty=i_useLots ? unitsToLots(positionSize) : positionSize) else strategy.entry(id="Short", direction=strategy.short) tradeStop := na tradeTarget1 := na tradeTarget2 := na // Handle forex trade size tracking variable if syminfo.type == "forex" and strategy.position_size != 0 and na(tradeSize) tradeSize := strategy.position_size // Handle long stops & target calculation if strategy.position_size > 0 and na(tradeStop) and syminfo.type != "forex" tradeStop := longStop stopDistance = strategy.position_avg_price - tradeStop tradeTarget1 := strategy.position_avg_price + (stopDistance * i_rr1) tradeTarget2 := strategy.position_avg_price + (stopDistance * i_rr2) tradeSize := strategy.position_size // Handle short stops & target calculation if strategy.position_size < 0 and na(tradeStop) and syminfo.type != "forex" tradeStop := shortStop stopDistance = tradeStop - strategy.position_avg_price tradeTarget1 := strategy.position_avg_price - (stopDistance * i_rr1) tradeTarget2 := strategy.position_avg_price - (stopDistance * i_rr2) tradeSize := strategy.position_size // Handle trade exits float exitPartialUnits = math.abs(strategy.position_size / (100 / i_target1)) float exitPartialLots = unitsToLots(exitPartialUnits) strategy.exit(id="Long Exit #1", from_entry="Long", limit=tradeTarget1, stop=tradeStop, qty=i_useLots ? exitPartialLots : exitPartialUnits) strategy.exit(id="Long Exit #2", from_entry="Long", limit=tradeTarget2, stop=tradeStop, qty_percent=100) strategy.exit(id="Short Exit #1", from_entry="Short", limit=tradeTarget1, stop=tradeStop, qty=i_useLots ? exitPartialLots : exitPartialUnits) strategy.exit(id="Short Exit #2", from_entry="Short", limit=tradeTarget2, stop=tradeStop, qty_percent=100) // Handle both long & short trade break-even stops (do this AFTER first position has exited above ^) if strategy.position_size != tradeSize tradeStop := strategy.position_avg_price tradeTarget1 := na // Draw conditional data plot(ema, color=close > ema ? color.green : color.red, linewidth=2, title="EMA") plotshape(longTrade, style=shape.triangleup, color=color.green, location=location.belowbar, title="Long Setup") plotshape(shortTrade, style=shape.triangledown, color=color.red, location=location.abovebar, title="Short Setup") // Draw stops & targets plot(strategy.position_size != 0 ? tradeStop : na, color=color.red, style=plot.style_linebr, title="Stop Loss") plot(strategy.position_size != 0 ? tradeTarget1 : na, color=color.green, style=plot.style_linebr, title="Profit Target 1") plot(strategy.position_size != 0 ? tradeTarget2 : na, color=color.green, style=plot.style_linebr, title="Profit Target 2")
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/ // © ZenAndTheArtOfTrading / www.PineScriptMastery.com // @version=5 strategy("ATR Reversion System", overlay=true, currency=currency.USD, initial_capital=100000, default_qty_type=strategy.percent_of_equity, default_qty_value=100, commission_type=strategy.commission.cash_per_order, commission_value=9.95) // Get user input i_EmaLongLength = input.int(title="Long-term EMA", defval=200) i_EmaShortLength = input.int(title="Short-term EMA Length", defval=20) i_ATRPeriod = input.int(title="ATR Period", defval=5) i_ATRBand = input.float(title="ATR Band Distance", defval=1) i_ATRStretch = input.float(title="ATR Buy Stretch", defval=1) i_SellBand = input.string(title="Sell At Band:", defval="Middle", options=["Top", "Middle", "Bottom"]) i_SellSrc = input.source(title="Sell Price Source", defval=high) // Get indicator values emaLongTerm = ta.ema(close, i_EmaLongLength) emaShortTerm = ta.ema(close, i_EmaShortLength) atrValue = ta.atr(i_ATRPeriod) // Get ATR bands atrBandTop = emaShortTerm + (atrValue * i_ATRBand) atrBandBot = emaShortTerm - (atrValue * i_ATRBand) // Define price stretch float buyLimitPrice = na // Check setup conditions = bar close is below ATR band, above long-term EMA setupCondition = close < atrBandBot and low > emaLongTerm // Clear any pending limit orders strategy.cancel_all() // Enter trades on next bar after setup condition is met if setupCondition buyLimitPrice := low - (atrValue * i_ATRStretch) strategy.entry("Long", strategy.long, limit=buyLimitPrice) // Get sell price sellPrice = switch i_SellBand "Top" => atrBandTop "Middle" => emaShortTerm "Bottom" => atrBandBot // Exit trades if i_SellSrc >= sellPrice or close < emaLongTerm strategy.close("Long", comment="Exit trade") // Draw data to chart plot(emaLongTerm, "EMA Filter", color.red, 2) plot(emaShortTerm, "ATR Band Middle", color.blue) plot(atrBandBot, "ATR Band Bottom", color=color.green) plot(atrBandTop, "ATR Band Top", color=color.new(color.gray, 75)) plot(setupCondition ? buyLimitPrice : na, "Buy Limit", color.lime, 1, plot.style_cross)
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/ // © ZenAndTheArtOfTrading // @version=5 indicator("PSMC - Lower Timeframe Dayta") // Get user input int i_Lookback = input.int(title="Lookback", defval=10) string i_Period = input.timeframe(title="Lower Timeframe", defval="D") // Define custom function for safely retrieving array values without index OOB errors getArrayValue(float[] array, int idx) => if array.size(array) > idx array.get(array, idx) else na // Get ATR value expression (for passing to security() function) float atrValue = ta.atr(14) plot(atrValue, color=color.new(color.purple, 100)) // Get lower timeframe dayta float[] LtfATR_Array = request.security_lower_tf(syminfo.tickerid, i_Period, atrValue) float[] LtfClosingPrice_Array = request.security_lower_tf(syminfo.tickerid, i_Period, close) // Define our merged ATR values array var float[] ATR_Array = array.new_float(i_Lookback, 0) var float[] ClosingPrice_Array = array.new_float(i_Lookback, 0) // If current timeframe is the reference timeframe, we don't need to reference LTF data if timeframe.period == i_Period for i = 0 to array.size(ATR_Array) - 1 array.set(ATR_Array, i, atrValue[i]) // Set each array index with the corresponding historical value array.set(ClosingPrice_Array, i, close[i]) array.reverse(ATR_Array) // Reverse array to be consistent with HTF array population handled below array.reverse(ClosingPrice_Array) else // Populate our ATR array if array.size(LtfATR_Array) > 0 for i = 0 to array.size(LtfATR_Array) - 1 array.shift(ATR_Array) // Remove the array's first element array.push(ATR_Array, array.get(LtfATR_Array, i)) // Insert a new array element (FIFO) array.shift(ClosingPrice_Array) array.push(ClosingPrice_Array, array.get(LtfClosingPrice_Array, i)) // Draw the past 10 days ATR values plot(getArrayValue(ATR_Array, 0)) plot(getArrayValue(ATR_Array, 1)) plot(getArrayValue(ATR_Array, 2)) plot(getArrayValue(ATR_Array, 3)) plot(getArrayValue(ATR_Array, 4)) plot(getArrayValue(ATR_Array, 5)) plot(getArrayValue(ATR_Array, 6)) plot(getArrayValue(ATR_Array, 7)) plot(getArrayValue(ATR_Array, 8)) plot(getArrayValue(ATR_Array, 9)) // For debug purposes string debugStr = "" for i = 0 to array.size(ClosingPrice_Array) - 1 debugStr := debugStr + str.tostring(getArrayValue(ClosingPrice_Array, i), "#.##") + ", " var table debugDisplay = table.new(position.top_right, 1, 1) if barstate.islast atrPercent = (getArrayValue(ATR_Array, array.size(ATR_Array) - 1) / getArrayValue(ClosingPrice_Array, array.size(ClosingPrice_Array) - 1)) * 100 table.cell(debugDisplay, 0, 0, str.tostring(atrPercent), text_color=color.lime) //table.cell(debugDisplay, 0, 0, debugStr, text_color=color.lime)
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/ // © ZenAndTheArtOfTrading / www.PineScriptMastery.com // @version=5 strategy("Bitcoin Regime Filter Strategy", overlay=true, initial_capital=10000, currency=currency.USDT, default_qty_type=strategy.percent_of_equity, default_qty_value=100, commission_type=strategy.commission.percent, commission_value=0.1) // Get user input res = input.timeframe(title="Timeframe", defval="W") len = input.int(title="EMA Length", defval=20) marketTF = input.timeframe(title="Market Timeframe", defval="D") useRsi = input.bool(title="Use RSI Momentum Filter", defval=false) rsiMom = input.int(title="RSI Momentum Threshold", defval=70) startTime = input.time(title="Start Filter", defval=timestamp("01 Jan 2000 13:30 +0000"), group="Time Filter", tooltip="Start date & time to begin searching for setups") endTime = input.time(title="End Filter", defval=timestamp("1 Jan 2099 19:30 +0000"), group="Time Filter", tooltip="End date & time to stop searching for setups") // Define custom security function f_sec(_market, _res, _exp) => request.security(_market, _res, _exp[barstate.isconfirmed ? 0 : 1]) // Define date filter dateFilter(int st, int et) => time >= st and time <= et // Get EMA value ema = ta.ema(close, len) htfEmaValue = f_sec(syminfo.tickerid, res, ema) // Get ATR value atrValue = ta.atr(5) // Check if price is above or below EMA filter marketPrice = f_sec(syminfo.tickerid, marketTF, close) regimeFilter = marketPrice > (htfEmaValue + (atrValue * 0.25)) // Calculate RSI rsiValue = ta.rsi(close, 7) // Get bullish momentum filter bullish = regimeFilter and (rsiValue > rsiMom or not useRsi) // Check for bearish volatility caution caution = bullish and ta.highest(high, 7) - low > (atrValue * 1.5) // Set momentum color bgCol = color.red if bullish[1] bgCol := color.green if caution[1] bgCol := color.orange // Change background color plotshape(1, color=bgCol, style=shape.square, location=location.bottom, size=size.auto, title="Momentum Strength") plot(htfEmaValue, color=close > htfEmaValue ? color.green : color.red, linewidth=2) // Store trailing ratchet stop loss var float trailStop = na // Handle strategy entry if bullish and strategy.position_size == 0 and dateFilter(startTime, endTime) and not caution strategy.entry(id="Buy", direction=strategy.long) trailStop := na // Handle trailing stop temp_trailStop = ta.highest(low, 7) - (caution[1] ? atrValue * 0.2 : atrValue) if strategy.position_size > 0 if temp_trailStop > trailStop or na(trailStop) trailStop := temp_trailStop // Handle strategy exit if (close < trailStop or close < htfEmaValue) strategy.close("Buy", comment="Sell") // Draw stop plot(strategy.position_size[1] > 0 ? trailStop : na, style=plot.style_linebr, color=color.red, title="Stop Loss")