Pine v4 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 //@version=4 study("PSMC - Bar Wick & Border Color", overlay=true) bullCandle = close > open plotcandle(bullCandle ? open : na, bullCandle ? high : na, bullCandle ? low : na, bullCandle ? close : na, color=color.green, wickcolor=color.blue, bordercolor=color.lime) plotcandle(bullCandle ? na : open, bullCandle ? na : high, bullCandle ? na : low, bullCandle ? na : close, color=color.maroon, wickcolor=color.orange, bordercolor=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 //@version=4 study("PSMC - Drawing Variable Values", overlay=true) // Calculate difference between 50 EMA and 100 EMA variableValue = (ema(close, 100) - ema(close, 50)) / syminfo.mintick // Create a label labelText = tostring(variableValue) ourLabel = label.new(x=bar_index, y=na, text=labelText, yloc=yloc.belowbar, color=color.green, textcolor=color.white, style=label.style_label_up, size=size.normal) label.delete(ourLabel[1])
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/ // © ZenAndTheArtOfTrading //@version=4 study("PSMC - How To Split Alerts", overlay=true) // Get user input longAlerts = input(title="Trigger Long Alerts", type=input.bool, defval=true) shortAlerts = input(title="Trigger Short Alerts", type=input.bool, defval=true) // Detect candle patterns bullishCandle = close > open bearishCandle = close < open plotshape(bullishCandle, color=color.green, style=shape.arrowup, location=location.belowbar) plotshape(bearishCandle, color=color.red, style=shape.arrowdown, location=location.abovebar) // Trigger alerts alertcondition((bullishCandle and longAlerts) or (bearishCandle and shortAlerts), title="Alert!", message="Alert for {{ticker}}")
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/ // © ZenAndTheArtOfTrading //@version=4 study("PSMC - Alerts & Afterhours", overlay=true) // Get user input preMarket = input(title="Pre-market", type=input.session, defval="0400-0930") afterMarket = input(title="After-market", type=input.session, defval="1600-2000") // Create function for detecting if current bar falls within specified time period InSession(sess) => na(time(timeframe.period, sess)) == false // Check if the current bar falls within pre-market or after-market hours isAfterClose = InSession(afterMarket) isPreOpen = InSession(preMarket) isAfterHours = isAfterClose or isPreOpen // Change bar color if bar falls within after hours time barcolor(isAfterHours ? color.black : na) // Trigger alert ONLY IF bar is outside of after hours time alertTrigger = close >= open alertcondition(alertTrigger and not isAfterHours, title="Alert title", message="Alert message")
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/ // © ZenAndTheArtOfTrading //@version=4 study("PSMC - Alerts & Time Session", overlay=true) // Get user input session = input(title="Time session", type=input.session, defval="0930-1030") // Create function for detecting if current bar falls within specified time period InSession(sess) => na(time(timeframe.period, sess)) == false // Check if the current bar falls within our session isInSession = InSession(session) // Change bar color if bar falls within session barcolor(isInSession ? color.black : na) // Trigger alert ONLY IF bar is within session alertTrigger = close >= open alertcondition(alertTrigger and isInSession, title="Alert title", message="Alert message")
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/ // © ZenAndTheArtOfTrading //@version=4 study("PSMC - Stochastic & RSI") // Get user input kInput = input(title="K Length", type=input.integer, defval=14) dInput = input(title="D Length", type=input.integer, defval=3) rsiLength = input(title="RSI Length", type=input.integer, defval=14) obLevel = input(title="Overbought Threshold", type=input.float, defval=80) osLevel = input(title="Oversold Threshold", type=input.float, defval=20) // Calculate our stochastic rsi = rsi(close, rsiLength) k = 100 * ((close - lowest(low, kInput)) / (highest(high, kInput) - lowest(low, kInput))) d = sma(k, dInput) // Draw data to chart plot(obLevel, color=color.red, linewidth=2, title="Overbought") plot(osLevel, color=color.green, linewidth=2, title="Oversold") plot(rsi, color=rsi > obLevel ? color.red : rsi < osLevel ? color.green : color.black, linewidth=2) plot(k, color=color.purple, title="K") plot(d, color=color.orange, title="D")
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/ // © ZenAndTheArtOfTrading //@version=4 study("PSMC - EMA Confluence Filter", overlay=true) // Get user input emaLength1 = input(title="EMA 1 Length", type=input.integer, defval=50) emaLength2 = input(title="EMA 2 Length", type=input.integer, defval=100) emaLookback = input(title="EMA Lookback", type=input.integer, defval=3) maxBarsBeyondEMA = input(title="Max Bars Beyond EMA", type=input.integer, defval=1) // Get EMAs ema1 = ema(close, emaLength1) ema2 = ema(close, emaLength2 == 0 ? 1 : emaLength2) // EMA Breach Check barsAboveEMA = 0 barsBelowEMA = 0 // Count candles beyond the EMA for i = 0 to emaLookback if close[i] > ema1 barsAboveEMA := barsAboveEMA + 1 if close[i] < ema1 barsBelowEMA := barsBelowEMA + 1 // Get Filters longFilter = close > ema1 and (ema1 > ema2 or emaLength2 == 0) and barsBelowEMA <= maxBarsBeyondEMA shortFilter = close < ema1 and (ema1 < ema2 or emaLength2 == 0) and barsAboveEMA <= maxBarsBeyondEMA // Detect entry reasons longEntry = longFilter and close >= open[1] and close[1] <= open[1] shortEntry = shortFilter and close <= open[1] and close[1] >= open[1] // Plot EMAs plot(ema1, color=close > ema1 ? color.green : color.red, linewidth=2) plot(emaLength2 == 0 ? na : ema2, color=color.blue, linewidth=3) // Plot Entry Signals plotshape(longEntry ? 1 : na, style=shape.arrowup, color=color.green, location=location.belowbar) plotshape(shortEntry ? 1 : na, style=shape.arrowdown, 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 //@version=4 study(title="PSMC - Setup Detection", shorttitle="www.pinescriptmastery.com", overlay=true) // Get user input rsiLength = input(title="RSI Length", type=input.integer, defval=14) rsiOB = input(title="RSI Overbought", type=input.float, defval=70.0) rsiOS = input(title="RSI Oversold", type=input.float, defval=30.0) // Get RSI values & check condition rsi = rsi(close, rsiLength) rsiBullish = rsi <= rsiOS or rsi[1] <= rsiOS rsiBearish = rsi >= rsiOB or rsi[1] >= rsiOB // Detect candlestick pattern bullishEngulfing = close >= open[1] and close[1] <= open[1] bearishEngulfing = close <= open[1] and close[1] >= open[1] // Detect trading setups bullishSetup = rsiBullish and bullishEngulfing bearishSetup = rsiBearish and bearishEngulfing // Draw data to chart plotshape(bullishSetup ? 1 : na, style=shape.arrowup, color=color.green, location=location.belowbar, title="Bullish Signal") plotshape(bearishSetup ? 1 : na, style=shape.arrowdown, color=color.red, location=location.abovebar, title="Bearish Signal") // Trigger alerts alertcondition(condition=bullishSetup or bearishSetup, title="RSI Setup Alert!", message="RSI Trading Setup Detected For: {{ticker}}")
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/ // © ZenAndTheArtOfTrading // @version=4 study("PSMC - Hammer & Shooting Stars", overlay=true) // Get user input fibLevel = input(title="Fib Level", type=input.float, defval=0.333) colorFilter = input(title="Color Must Match", type=input.bool, defval=false) // Calculate fibonacci level for current candle bullFib = (low - high) * fibLevel + high bearFib = (high - low) * fibLevel + low // Determine which price source closes or opens highest/lowest lowestBody = close < open ? close : open highestBody = close > open ? close : open // Determine if we have a valid hammer or shooting star hammerCandle = lowestBody >= bullFib and (not colorFilter or close > open) starCandle = highestBody <= bearFib and (not colorFilter or close < open) // Plot the signals to the chart plotshape(hammerCandle, style=shape.arrowup, location=location.belowbar, color=color.green) plotshape(starCandle, style=shape.arrowdown, location=location.abovebar, color=color.red) // Trigger alerts alertcondition(hammerCandle or starCandle, title="Hammer or Shooting Star Alert", message="{{ticker}}")
// 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 // Last Updated: 24th November, 2020 // @version=4 study("PSMC - Piercing Cloud", overlay=true) // Get user input rsiLength = input(title="RSI Length", type=input.integer, defval=7) rsiOB = input(title="RSI OB", type=input.float, defval=70.0) rsiOS = input(title="RSI OS", type=input.float, defval=30.0) margin = input(title="Pip Margin", type=input.float, defval=0.0) // Get current RSI value rsi = rsi(close, rsiLength) // Detect bullish piercing line bpc = open < close[1] and close > close[1] and close < open[1] and close[1] < open[1] // Detect bearish dark cloud cover dcc = open > close[1] and close > open[1] and close < close[1] and close[1] > open[1] // Check pip distance between the candle bodies bpcMargin = close[1] - open dccMargin = open - close[1] // Piercing line filter piercingLine = (low[1] - high[1]) * 0.5 + high[1] longPierce = close >= piercingLine shortPierce = close <= piercingLine // Determine if the current bar meets our conditions longSignal = rsi[1] <= rsiOS and bpc and bpcMargin >= margin and longPierce shortSignal = rsi[1] >= rsiOB and dcc and dccMargin >= margin and shortPierce // Draw signals plotshape(longSignal, style=shape.triangleup, location=location.belowbar, color=color.green, text="Long", title="Long") plotshape(shortSignal, style=shape.triangledown, location=location.abovebar, color=color.red, text="Short", title="Short")
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/ // Positive Bars Oscillator v1.0 / Last Modified: 25th January, 2021 // © ZenAndTheArtOfTrading / www.PineScriptMastery.com // @version=4 study("Positive Bars %", overlay=false, precision=0) // Get user input lookback = input(title="Lookback", type=input.integer, defval=10) // Get user input upperLimit = input(title="Upper Limit", type=input.integer, defval=80) lowerLimit = input(title="Lower Limit", type=input.integer, defval=20) // Count past X positive bars (X = lookback) positiveBars = 0 for i = (lookback - 1) to 0 if close[i] > open[i] positiveBars := positiveBars + 1 // Plot limits to chart hline(upperLimit, color=color.orange, title="Upper Limit") hline(lowerLimit, color=color.orange, title="Lower Limit") // Draw positive bars as % positiveBarsPercent = (positiveBars / lookback) * 100 plot(positiveBarsPercent, color=color.blue, title="Positive Bars") // Draw top & bottom of oscillator plot(100, color=color.black, editable=false, title="Top") plot(0, color=color.black, editable=false, title="Bottom") // Trigger alerts alertcondition(positiveBarsPercent >= upperLimit, title="PB(+) Alert", message="Positive bars has exceeded upper limit: {{plot_0}}%") alertcondition(positiveBarsPercent <= lowerLimit, title="PB(-) Alert", message="Positive bars has exceeded lower limit: {{plot_0}}%")
// 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 // This script calculates the covariance and correlation coefficient between two array data sets // @version=4 study("PSMC - Correlation Meter", overlay=false) // Get user input lookback = input(title="Lookback", type=input.integer, defval=20) source = input(title="Source", type=input.source, defval=close) reference = input(title="Reference Market", type=input.string, defval="OANDA:SPX500USD") // Get % change of reference data source referenceData = security(symbol=reference, resolution=timeframe.period, expression=source) referenceChange = ((referenceData - referenceData[1]) / referenceData[1]) * 100 // Get % change of current market currentData = source currentChange = ((currentData - currentData[1]) / currentData[1]) * 100 // Declare arrays var referenceArray = array.new_float(lookback) var currentArray = array.new_float(lookback) // Shift (remove) the last (first entered) value from our arrays (FIFO) array.shift(referenceArray) array.shift(currentArray) // Add the current values to our arrays array.push(referenceArray, referenceChange) array.push(currentArray, currentChange) // Determine & plot our covariance relationship covariance = array.covariance(currentArray, referenceArray) plot(covariance, color=color.purple, style=plot.style_area, transp=0, title="Covariance") // Plot our reference data plot(referenceChange, color=color.red, style=plot.style_columns, transp=10, title="Reference Market") plot(currentChange, color=color.blue, style=plot.style_histogram, linewidth=4, title="Current Market") // Determine the standard deviation of our arrays referenceDev = array.stdev(referenceArray) currentDev = array.stdev(currentArray) correlation = covariance / (referenceDev * currentDev) plot(correlation, color=color.black, linewidth=2, style=plot.style_stepline, title="Correlation Strength") // Plot reference lines //hline(price=1.0) //hline(price=-1.0) //hline(price=0.0)
// 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=4 study("Tick Counter") // Prepare tick counter variables (varip makes them persistent on real-time bar) varip ticks = 0 varip volumeChanges = 0 varip lastPrice = close // Check if price has changed (price tick) if barstate.isrealtime and lastPrice != close ticks := ticks + 1 lastPrice := close // Check if volume has changed (trade executed at current price) if barstate.isrealtime and lastPrice == close volumeChanges := volumeChanges + 1 // Reset counters on each new bar if barstate.isnew ticks := 0 volumeChanges := 0 lastPrice := close // Draw data to chart plot(ticks, style=plot.style_columns, title="Price Ticks") plot(volumeChanges, style=plot.style_histogram, color=color.purple, title="Volume Ticks")
// 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=4 study("Forex Position Size Calculator", overlay=true) // Get user input accountBalance = input(title="Account Balance", type=input.float, defval=10000.0, step=100, group="AutoView Oanda Settings", tooltip="Your Oanda account balance (optional - used for automation through AutoView plugin)") accountCurrency = input(title="Account Currency", type=input.string, defval="USD", options=["AUD", "CAD", "CHF", "EUR", "GBP", "JPY", "NZD", "USD"], group="AutoView Oanda Settings", tooltip="Your Oanda account currency (optional - used for automation through AutoView plugin)") riskPerTrade = input(title="Risk Per Trade %", type=input.float, defval=1.0, step=0.5, group="AutoView Oanda Settings", tooltip="Your risk per trade as a % of your account balance (optional - used for automation through AutoView plugin)") // Get current ATR atr = atr(14) // Custom function to convert pips into whole numbers toWhole(number) => return = atr < 1.0 ? (number / syminfo.mintick) / (10 / syminfo.pointvalue) : number return := atr >= 1.0 and atr < 100.0 and syminfo.currency == "JPY" ? return * 100 : return //------------- DETERMINE POSITION SIZE -------------// // Check if our account currency is the same as the base or quote currency (for risk $ conversion purposes) accountSameAsCounterCurrency = accountCurrency == syminfo.currency accountSameAsBaseCurrency = accountCurrency == syminfo.basecurrency // Check if our account currency is neither the base or quote currency (for risk $ conversion purposes) accountNeitherCurrency = not accountSameAsCounterCurrency and not accountSameAsBaseCurrency // Get currency conversion rates if applicable conversionCurrencyPair = accountSameAsCounterCurrency ? syminfo.tickerid : accountNeitherCurrency ? accountCurrency + syminfo.currency : accountCurrency + syminfo.currency conversionCurrencyRate = security(symbol=syminfo.type == "forex" ? conversionCurrencyPair : "AUDUSD", resolution="D", expression=close) // Calculate position size getPositionSize(stopLossSizePoints) => riskAmount = (accountBalance * (riskPerTrade / 100)) * (accountSameAsBaseCurrency or accountNeitherCurrency ? conversionCurrencyRate : 1.0) riskPerPoint = (stopLossSizePoints * syminfo.pointvalue) positionSize = syminfo.type == "forex" ? ((riskAmount / riskPerPoint) / syminfo.mintick) : 0 round(positionSize) //------------- END POSITION SIZE CODE -------------// // Detect setup var inLongTrade = false var riskReward = 1.0 var tradeStop = 0.0 var tradeStopDistance = 0.0 var tradeTarget = 0.0 var tradeSize = 0 longSetup = low == lowest(low, 15) and close >= open[1] and close[1] < open[1] and open >= low[1] // Calculate stops & targets if longSetup and not inLongTrade tradeStop := low - atr tradeStopDistance := close - tradeStop tradeTarget := close + (tradeStopDistance * riskReward) tradeSize := getPositionSize(toWhole(tradeStopDistance) * 10) inLongTrade := true // Exit trade when appropriate if inLongTrade and (high >= tradeTarget or low <= tradeStop) inLongTrade := false // Draw setup info plotshape(longSetup, color=color.green, style=shape.triangleup, location=location.belowbar, title="Long Setup") plot(inLongTrade ? tradeStop : na, color=color.red, style=plot.style_linebr, title="Trade Stop") plot(inLongTrade ? tradeTarget : na, color=color.green, style=plot.style_linebr, title="Trade Target") // Draw position size plot(inLongTrade ? tradeStopDistance : na, color=color.gray, transp=100, title="Trade Stop Distance") plot(inLongTrade ? tradeSize : na, color=color.purple, transp=100, title="Position Size")
// 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 // Last Updated: 26th May, 2021 // @version=4 strategy("Hammers & Stars Strategy YouTube", shorttitle="HSS", overlay=true) // Get user input stopMultiplier = input(title="Stop Loss ATR", type=input.float, defval=1.0, tooltip="Stop loss multiplier (x ATR)", group="Strategy Settings") rr = input(title="R:R", type=input.float, defval=1.0, tooltip="Risk:Reward profile", group="Strategy Settings") fibLevel = input(title="Fib Level", type=input.float, defval=0.333, tooltip="Used to calculate upper/lower third of candle. (For example, setting it to 0.5 will mean hammers must close >= 50% mark of the total candle size)", group="Strategy Settings") oandaDemo = input(title="Use Oanda Demo?", type=input.bool, defval=false, tooltip="If turned on then oandapractice broker prefix will be used for AutoView alerts (demo account). If turned off then live account will be used", group="AutoView Oanda Settings") limitOrder = input(title="Use Limit Order?", type=input.bool, defval=true, tooltip="If turned on then AutoView will use limit orders. If turned off then market orders will be used", group="AutoView Oanda Settings") gtdOrder = input(title="Days To Leave Limit Order", type=input.integer, minval=0, defval=2, tooltip="This is your GTD setting (good til day)", group="AutoView Oanda Settings") accountBalance = input(title="Account Balance", type=input.float, defval=1000.0, step=100, tooltip="Your account balance (used for calculating position size)", group="AutoView Oanda Settings") accountCurrency = input(title="Account Currency", type=input.string, defval="USD", options=["AUD", "CAD", "CHF", "EUR", "GBP", "JPY", "NZD", "USD"], tooltip="Your account balance currency (used for calculating position size)", group="AutoView Oanda Settings") riskPerTrade = input(title="Risk Per Trade %", type=input.float, defval=2.0, step=0.5, tooltip="Your risk per trade as a % of your account balance", group="AutoView Oanda Settings") // Filter Settings // ATR Filter atrMinFilterSize = input(title=">= ATR Filter", type=input.float, defval=0.0, minval=0.0, tooltip="Minimum size of entry candle compared to ATR", group="Filters") atrMaxFilterSize = input(title="<= ATR Filter", type=input.float, defval=3.0, minval=0.0, tooltip="Maximum size of entry candle compared to ATR", group="Filters") // EMA Filter emaFilterLength = input(title="EMA Filter Length", type=input.integer, defval=0, tooltip="EMA Length for filtering trades (set to zero to disable)", group="Filters") // Date Filter startTime = input(title="Start Date Filter", defval=timestamp("01 Jan 1000 13:30 +0000"), type=input.time, tooltip="Date & time to begin trading from", group="Filters") endTime = input(title="End Date Filter", defval=timestamp("1 Jan 2099 19:30 +0000"), type=input.time, tooltip="Date & time to stop trading", group="Filters") // Time Filter timeSession = input(title="Time Session To Ignore Trades", type=input.session, defval="0600-0915", group="Filters", tooltip="Time session to ignore trades") useTimeFilter = input(title="Use Time Session Filter", type=input.bool, defval=false, group="Filters", tooltip="Turns on/off time session filter") // Get ATR atr = atr(14) // Check ATR Filter atrMinFilter = high - low >= (atrMinFilterSize * atr) or atrMinFilterSize == 0.0 atrMaxFilter = high - low <= (atrMaxFilterSize * atr) or atrMaxFilterSize == 0.0 atrFilter = atrMinFilter and atrMaxFilter // Check EMA Filter ema = emaFilterLength == 0 ? na : ema(close, emaFilterLength) emaLongFilter = emaFilterLength == 0 or (close > ema and not na(ema)) emaShortFilter = emaFilterLength == 0 or (close < ema and not na(ema)) // Check Date Filter dateFilter = time >= startTime and time <= endTime // Check Time Filter isInSession(sess) => na(time(timeframe.period, sess)) == false timeFilter = (useTimeFilter and not isInSession(timeSession)) or not useTimeFilter // Merge Filters longFilters = atrFilter and emaLongFilter and dateFilter and timeFilter shortFilters = atrFilter and emaShortFilter and dateFilter and timeFilter bgcolor(color=(useTimeFilter and isInSession(timeSession)) or not dateFilter or not atrFilter ? color.red : na, transp=70, title="Filter Colorr") // Calculate the 33.3% fibonacci level for current candle bullFib = (low - high) * fibLevel + high bearFib = (high - low) * fibLevel + low // Determine which price source closes or opens highest/lowest lowestBody = close < open ? close : open highestBody = close > open ? close : open // Determine if we have a valid setup validHammer = lowestBody >= bullFib and close != open and not na(atr) and longFilters validStar = highestBody <= bearFib and close != open and not na(atr) and shortFilters // Check if we have confirmation for our setup validLong = validHammer and strategy.position_size == 0 and barstate.isconfirmed validShort = validStar and strategy.position_size == 0 and barstate.isconfirmed //------------- DETERMINE POSITION SIZE -------------// // Get account inputs var broker = oandaDemo ? "oandapractice" : "oanda" var tradePositionSize = 0.0 var pair = syminfo.basecurrency + "/" + syminfo.currency // Check if our account currency is the same as the base or quote currency (for risk $ conversion purposes) accountSameAsCounterCurrency = accountCurrency == syminfo.currency accountSameAsBaseCurrency = accountCurrency == syminfo.basecurrency // Check if our account currency is neither the base or quote currency (for risk $ conversion purposes) accountNeitherCurrency = not accountSameAsCounterCurrency and not accountSameAsBaseCurrency // Get currency conversion rates if applicable conversionCurrencyPair = accountSameAsCounterCurrency ? syminfo.tickerid : accountNeitherCurrency ? accountCurrency + syminfo.currency : accountCurrency + syminfo.currency conversionCurrencyRate = security(symbol=syminfo.type == "forex" ? conversionCurrencyPair : "AUDUSD", resolution="D", expression=close) // Calculate position size getPositionSize(stopLossSizePoints) => riskAmount = (accountBalance * (riskPerTrade / 100)) * (accountSameAsBaseCurrency or accountNeitherCurrency ? conversionCurrencyRate : 1.0) riskPerPoint = (stopLossSizePoints * syminfo.pointvalue) positionSize = syminfo.type == "forex" ? ((riskAmount / riskPerPoint) / syminfo.mintick) : 0 round(positionSize) // Custom function to convert pips into whole numbers toWhole(number) => return = atr(14) < 1.0 ? (number / syminfo.mintick) / (10 / syminfo.pointvalue) : number return := atr(14) >= 1.0 and atr(14) < 100.0 and syminfo.currency == "JPY" ? return * 100 : return //------------- END POSITION SIZE CODE -------------// // Set up our GTD (good-til-date) order info gtdTime = time + (gtdOrder * 1440 * 60 * 1000) // 86,400,000ms per day gtdYear = year(gtdTime) gtdMonth = month(gtdTime) gtdDay = dayofmonth(gtdTime) gtdString = " dt=" + tostring(gtdYear) + "-" + tostring(gtdMonth) + "-" + tostring(gtdDay) // Calculate our stops & targets stopSize = atr * stopMultiplier longStopPrice = low < low[1] ? low - stopSize : low[1] - stopSize longStopDistance = close - longStopPrice longTargetPrice = close + (longStopDistance * rr) shortStopPrice = high > high[1] ? high + stopSize : high[1] + stopSize shortStopDistance = shortStopPrice - close shortTargetPrice = close - (shortStopDistance * rr) // Save stops & targets for the current trade var tradeStopPrice = 0.0 var tradeTargetPrice = 0.0 // Detect valid long setups & trigger alerts if validLong tradeStopPrice := longStopPrice tradeTargetPrice := longTargetPrice tradePositionSize := getPositionSize(toWhole(longStopDistance) * 10) // Trigger AutoView long alert alert(message="e=" + broker + " b=long" + " q=" + tostring(tradePositionSize) + " s=" + pair + " t=" + (limitOrder ? "limit fp=" + tostring(close) : "market") + " fsl=" + tostring(tradeStopPrice) + " ftp=" + tostring(tradeTargetPrice) + (gtdOrder != 0 and limitOrder ? gtdString : ""), freq=alert.freq_once_per_bar_close) // Detect valid short setups & trigger alerts if validShort tradeStopPrice := shortStopPrice tradeTargetPrice := shortTargetPrice tradePositionSize := getPositionSize(toWhole(shortStopDistance) * 10) // Trigger AutoView short alert alert(message="e=" + broker + " b=short" + " q=" + tostring(tradePositionSize) + " s=" + pair + " t=" + (limitOrder ? "limit fp=" + tostring(close) : "market") + " fsl=" + tostring(tradeStopPrice) + " ftp=" + tostring(tradeTargetPrice) + (gtdOrder != 0 and limitOrder ? gtdString : ""), freq=alert.freq_once_per_bar_close) // Enter trades whenever a valid setup is detected strategy.entry(id="Long", long=strategy.long, when=validLong) strategy.entry(id="Short", long=strategy.short, when=validShort) // Exit trades whenever our stop or target is hit strategy.exit(id="Long Exit", from_entry="Long", limit=tradeTargetPrice, stop=tradeStopPrice, when=strategy.position_size > 0) strategy.exit(id="Short Exit", from_entry="Short", limit=tradeTargetPrice, stop=tradeStopPrice, when=strategy.position_size < 0) // Draw trade data plot(emaFilterLength == 0 ? na : ema, color=close > ema ? color.green : color.red, title="EMA Filter") plot(strategy.position_size != 0 or validLong or validShort ? tradeStopPrice : na, title="Trade Stop Price", color=color.red, style=plot.style_linebr, transp=0) plot(strategy.position_size != 0 or validLong or validShort ? tradeTargetPrice : na, title="Trade Target Price", color=color.green, style=plot.style_linebr, transp=0) //plot(strategy.position_size != 0 or validLong or validShort ? tradePositionSize : na, title="Trade Position Size", color=color.purple, style=plot.style_linebr, transp=100) // Draw price action setup arrows plotshape(validLong ? 1 : na, style=shape.triangleup, location=location.belowbar, color=color.green, title="Bullish Setup") plotshape(validShort ? 1 : na, style=shape.triangledown, location=location.abovebar, color=color.red, title="Bearish Setup")
// 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=4 strategy("PineConnector Strategy Test", overlay=true) // PineConnector Settings pc_id = input(title="License ID", defval="1234567890123", type=input.string, group="PineConnector Settings", tooltip="This is your PineConnector license ID") pc_risk = input(title="Risk Per Trade", defval=1, step=0.5, type=input.float, group="PineConnector Settings", tooltip="This is how much to risk per trade (if set to %, use whole numbers)") pc_prefix = input(title="MetaTrader Prefix", defval="", type=input.string, group="PineConnector Settings", tooltip="This is your broker's MetaTrader symbol prefix") pc_suffix = input(title="MetaTrader Suffix", defval="", type=input.string, group="PineConnector Settings", tooltip="This is your broker's MetaTrader symbol suffix") pc_limit = input(title="Use Limit Order?", defval=true, type=input.bool, group="PineConnector Settings", tooltip="If true a limit order will be used, if false a market order will be used") // Generate PineConnector alert string var symbol = pc_prefix + syminfo.ticker + pc_suffix var limit = pc_limit ? "limit" : "" price = pc_limit ? "price=" + tostring(close) + "," : "" pc_entry_alert(direction, price, sl, tp) => pc_id + "," + direction + "," + symbol + "," + price + "sl=" + tostring(sl) + ",tp=" + tostring(tp) + ",risk=" + tostring(pc_risk) // See if this bar's time happened on/after start date (to stop script taking too many trades) afterStartDateFilter = time >= timestamp(syminfo.timezone, 2021, 7, 1, 0, 0) // Test long command longCondition = close > high[1] and afterStartDateFilter var longStop = 0.0 var longTarget = 0.0 if longCondition and barstate.isconfirmed and strategy.position_size == 0 longStop := low longTarget := close + syminfo.mintick * 100 alert_string = pc_entry_alert("buy" + limit, price, longStop, longTarget) alert(alert_string, alert.freq_once_per_bar_close) strategy.entry("Long", strategy.long, comment=alert_string) // Test short command shortCondition = close < low[1] and afterStartDateFilter var shortStop = 0.0 var shortTarget = 0.0 if shortCondition and barstate.isconfirmed and strategy.position_size == 0 shortStop := high shortTarget := close - syminfo.mintick * 100 alert_string = pc_entry_alert("sell" + limit, price, shortStop, shortTarget) alert(alert_string, alert.freq_once_per_bar_close) strategy.entry("Short", strategy.short, comment=alert_string) // Exit mock trades strategy.exit(id="Long Exit", from_entry="Long", limit=longTarget, stop=longStop, when=strategy.position_size > 0) strategy.exit(id="Short Exit", from_entry="Short", limit=shortTarget, stop=shortStop, when=strategy.position_size < 0)
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/ // © ZenAndTheArtOfTrading / PineScriptMastery // FTB Strategy (PineConnector Version) // Last Updated: 21st July, 2021 // @version=4 strategy("[2021] FTB Strategy", shorttitle="FTB", overlay=true, calc_on_order_fills=true, initial_capital=10000, default_qty_value=100000) // Risk Settings var g_risk = "Risk Settings" pips = input(title="Stop Pips", type=input.float, defval=2.0, group=g_risk, tooltip="How many pips above high to put stop loss") rr = input(title="Risk:Reward", type=input.float, defval=1.0, group=g_risk, tooltip="This determines the risk:reward profile of the setup") // Filters var g_filter = "Filter Settings" timezone = input(title="Timezone", type=input.session, defval="0200-0700", group=g_filter, tooltip="Which timezone to search for FTB signals in") days = input(title="Days To Trade", defval="13457", group=g_filter, tooltip="Which days to trade this strategy on (Monday & Friday disabled by default)") useRsiFilter = input(title="RSI OB/OS?", type=input.bool, defval=true, group=g_filter, tooltip="If true then the RSI must be considered overbought before a signal is valid") useCloseFilter = input(title="Previous Bar Must Be Bullish?", type=input.bool, defval=false, group=g_filter, tooltip="If true then the previous bar must have closed bullish") useHighFilter = input(title="High Filter", type=input.bool, defval=false, group=g_filter, tooltip="If true then the signal bar must be the highest bar over X bars") highLookback = input(title="High Lookback", type=input.integer, defval=10, group=g_filter, tooltip="This is for setting the High Filter lookback distance") fib = input(title="Candle Close %", defval=0.5, group=g_filter, tooltip="For identifying shooting star candles (0.5 = must close <= 50% mark of candle size)") rsiLen = input(title="RSI Length", type=input.integer, defval=3, group=g_filter, tooltip="RSI length") rsiOB = input(title="RSI OB", type=input.float, defval=70.0, group=g_filter, tooltip="RSI overbought threshold") // PineConnector Settings var g_pc = "PineConnector Settings" pc_id = input(title="License ID", defval="YOUR_ID", type=input.string, group=g_pc, tooltip="This is your PineConnector license ID") pc_risk = input(title="Risk Per Trade", defval=1, step=0.5, type=input.float, group=g_pc, tooltip="This is how much to risk per trade (% of balance or lots)") pc_prefix = input(title="MetaTrader Prefix", defval="", type=input.string, group=g_pc, tooltip="This is your broker's MetaTrader symbol prefix") pc_suffix = input(title="MetaTrader Suffix", defval="", type=input.string, group=g_pc, tooltip="This is your broker's MetaTrader symbol suffix") pc_spread = input(title="Spread", defval=0.5, type=input.float, group=g_pc, tooltip="Enter your average spread for this pair (used for offsetting limit order)") pc_limit = input(title="Use Limit Order?", defval=true, type=input.bool, group=g_pc, tooltip="If true a limit order will be used, if false a market order will be used") // Generate PineConnector alert string var symbol = pc_prefix + syminfo.ticker + pc_suffix var limit = pc_limit ? "limit" : "" pc_entry_alert(direction, sl, tp) => price = pc_limit ? "price=" + tostring(pc_spread) + "," : "" pc_id + "," + direction + limit + "," + symbol + "," + price + "sl=" + tostring(sl) + ",tp=" + tostring(tp) + ",risk=" + tostring(pc_risk) // Get RSI filter rsiValue = rsi(close, rsiLen) rsiFilter = not useRsiFilter or rsiValue >= rsiOB // Check high & close filter highFilter = not useHighFilter or high == highest(high, highLookback) closeFilter = not useCloseFilter or close[1] > open[1] // InSession() determines if a price bar falls inside the specified session inSession(sess) => na(time(timeframe.period, sess + ":" + days)) == false // Calculate 50% mark of candle size bearFib = (high - low) * fib + low // Check filters filters = inSession(timezone) and closeFilter and high > high[1] and rsiFilter and highFilter and open != close // Detect valid shooting star pinbar pattern var takenTradeAlready = false star = filters and close < bearFib and open < bearFib and not takenTradeAlready // Calculate stops & targets shortStopPrice = high + (syminfo.mintick * pips * 10) shortStopDistance = shortStopPrice - close shortTargetPrice = close - (shortStopDistance * rr) // Save stops & targets for the current trade var tradeStopPrice = 0.0 var tradeTargetPrice = 0.0 // If we detect a valid shooting star, save our stops & targets, enter short and generate alert if star and barstate.isconfirmed tradeStopPrice := shortStopPrice tradeTargetPrice := shortTargetPrice takenTradeAlready := true alertString = pc_entry_alert("sell", tradeStopPrice, tradeTargetPrice) alert(alertString, alert.freq_once_per_bar_close) strategy.entry(id="Short", long=strategy.short, when=strategy.position_size == 0, comment=alertString) // If we have exited the FTB session then reset our takenTradeAlready flag for the next session if not inSession(timezone) and inSession(timezone)[1] takenTradeAlready := false // If price has exceeded target then cancel limit order if it's still active if pc_limit and low <= tradeTargetPrice and strategy.position_size == 0 alert(pc_id + ",cancelshort," + symbol) tradeTargetPrice := na // Draw stops & targets plot(star ? tradeStopPrice : na, color=color.red, style=plot.style_linebr, title="SL") plot(star ? shortTargetPrice : na, color=color.green, style=plot.style_linebr, title="TP") // Draw short signals plotshape(star ? 1 : na, style=shape.triangledown, color=color.red) // Change background color to highlight detection zone bgcolor(color=inSession(timezone) ? color.new(color.red,80) : na, title="Session") // Exit trade whenever our stop or target is hit strategy.exit(id="Short Exit", from_entry="Short", limit=tradeTargetPrice, stop=tradeStopPrice, when=strategy.position_size != 0)
// 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 // Last Updated: 27th July, 2021 // @version=4 strategy("Hammers & Stars Strategy [Automated]", shorttitle="HSS", overlay=true) // Get Strategy Settings var g_strategy = "Strategy Settings" stopMultiplier = input(title="Stop Loss ATR", type=input.float, defval=1.0, tooltip="Stop loss multiplier (x ATR)", group=g_strategy) rr = input(title="R:R", type=input.float, defval=1.0, tooltip="Risk:Reward profile", group=g_strategy) fibLevel = input(title="Fib Level", type=input.float, defval=0.333, tooltip="Used to calculate upper/lower third of candle. (For example, setting it to 0.5 will mean hammers must close >= 50% mark of the total candle size)", group=g_strategy) // Filter Settings var g_filters = "Filter Settings" // ATR Filter atrMinFilterSize = input(title=">= ATR Filter", type=input.float, defval=0.0, minval=0.0, tooltip="Minimum size of entry candle compared to ATR", group=g_filters) atrMaxFilterSize = input(title="<= ATR Filter", type=input.float, defval=3.0, minval=0.0, tooltip="Maximum size of entry candle compared to ATR", group=g_filters) // EMA Filter emaFilterLength = input(title="EMA Filter Length", type=input.integer, defval=20, tooltip="EMA Length for filtering trades (set to zero to disable)", group=g_filters) emaTouchFilter = input(title="EMA Touch Filter", type=input.bool, defval=false, tooltip="Price must touch EMA", group=g_filters) // Date Filter startTime = input(title="Start Date Filter", defval=timestamp("01 Jan 1000 13:30 +0000"), type=input.time, tooltip="Date & time to begin trading from", group=g_filters) endTime = input(title="End Date Filter", defval=timestamp("1 Jan 2099 19:30 +0000"), type=input.time, tooltip="Date & time to stop trading", group=g_filters) // Time Filter timeSession = input(title="Time Session To Ignore Trades", type=input.session, defval="0600-0915", tooltip="Time session to ignore trades", group=g_filters) useTimeFilter = input(title="Use Time Session Filter", type=input.bool, defval=false, tooltip="Turns on/off time session filter", group=g_filters) // Get AutoView Settings var g_av = "AutoView Oanda Settings" autoview = input(title="Use AutoView?", type=input.bool, defval=false, tooltip="Turn this on to use AutoView alerts", group=g_av) oandaDemo = input(title="Use Oanda Demo?", type=input.bool, defval=false, tooltip="If turned on then oandapractice broker prefix will be used for AutoView alerts (demo account). If turned off then live account will be used", group=g_av) limitOrder = input(title="Use Limit Order?", type=input.bool, defval=true, tooltip="If turned on then AutoView will use limit orders. If turned off then market orders will be used", group=g_av) gtdOrder = input(title="Days To Leave Limit Order", type=input.integer, minval=0, defval=2, tooltip="This is your GTD setting (good til day)", group=g_av) accountBalance = input(title="Account Balance", type=input.float, defval=1000.0, step=100, tooltip="Your account balance (used for calculating position size)", group=g_av) accountCurrency = input(title="Account Currency", type=input.string, defval="USD", options=["AUD", "CAD", "CHF", "EUR", "GBP", "JPY", "NZD", "USD"], tooltip="Your account balance currency (used for calculating position size)", group=g_av) riskPerTrade = input(title="Risk Per Trade %", type=input.float, defval=2.0, step=0.5, tooltip="Your risk per trade as a % of your account balance", group=g_av) // PineConnector Settings var g_pc = "PineConnector Settings" pineconnector = input(title="Use PineConnector?", type=input.bool, defval=false, tooltip="Turn this on to use PineConnector alerts", group=g_pc) pc_id = input(title="License ID", defval="YOUR_ID", type=input.string, group=g_pc, tooltip="This is your PineConnector license ID") pc_risk = input(title="Risk Per Trade", defval=1, step=0.5, type=input.float, group=g_pc, tooltip="This is how much to risk per trade (% of balance or lots)") pc_prefix = input(title="MetaTrader Prefix", defval="", type=input.string, group=g_pc, tooltip="This is your broker's MetaTrader symbol prefix") pc_suffix = input(title="MetaTrader Suffix", defval="", type=input.string, group=g_pc, tooltip="This is your broker's MetaTrader symbol suffix") pc_spread = input(title="Spread", defval=0.5, type=input.float, group=g_pc, tooltip="Enter your average spread for this pair (used for offsetting limit order)") pc_limit = input(title="Use Limit Order?", defval=true, type=input.bool, group=g_pc, tooltip="If true a limit order will be used, if false a market order will be used") // Generate PineConnector alert string var symbol = pc_prefix + syminfo.ticker + pc_suffix var limit = pc_limit ? "limit" : "" pc_entry_alert(direction, sl, tp) => price = pc_limit ? "price=" + tostring(pc_spread) + "," : "" pc_id + "," + direction + limit + "," + symbol + "," + price + "sl=" + tostring(sl) + ",tp=" + tostring(tp) + ",risk=" + tostring(pc_risk) // Get ATR atr = atr(14) // Check ATR Filter atrMinFilter = high - low >= (atrMinFilterSize * atr) or atrMinFilterSize == 0.0 atrMaxFilter = high - low <= (atrMaxFilterSize * atr) or atrMaxFilterSize == 0.0 atrFilter = atrMinFilter and atrMaxFilter // Check EMA Filter ema = emaFilterLength == 0 ? na : ema(close, emaFilterLength) emaLongFilter = emaFilterLength == 0 or (close > ema and not na(ema)) emaShortFilter = emaFilterLength == 0 or (close < ema and not na(ema)) emaTouchFilterLong = (low <= ema and emaTouchFilter and close[1] > ema) or not emaTouchFilter emaTouchFilterShort = (high >= ema and emaTouchFilter and close[1] < ema) or not emaTouchFilter // Check Date Filter dateFilter = time >= startTime and time <= endTime // Check Time Filter isInSession(sess) => na(time(timeframe.period, sess)) == false timeFilter = (useTimeFilter and not isInSession(timeSession)) or not useTimeFilter // Merge Filters longFilters = atrFilter and emaLongFilter and dateFilter and timeFilter and emaTouchFilterLong shortFilters = atrFilter and emaShortFilter and dateFilter and timeFilter and emaTouchFilterShort bgcolor(color=(useTimeFilter and isInSession(timeSession)) or not dateFilter or not atrFilter ? color.new(color.red,70) : na, title="Filter Color") // Calculate the 33.3% fibonacci level for current candle bullFib = (low - high) * fibLevel + high bearFib = (high - low) * fibLevel + low // Determine which price source closes or opens highest/lowest lowestBody = close < open ? close : open highestBody = close > open ? close : open // Determine if we have a valid setup validHammer = lowestBody >= bullFib and close != open and not na(atr) and longFilters validStar = highestBody <= bearFib and close != open and not na(atr) and shortFilters // Check if we have confirmation for our setup validLong = validHammer and strategy.position_size == 0 and barstate.isconfirmed validShort = validStar and strategy.position_size == 0 and barstate.isconfirmed //------------- DETERMINE POSITION SIZE -------------// // Get account inputs var broker = oandaDemo ? "oandapractice" : "oanda" var tradePositionSize = 0.0 var pair = syminfo.basecurrency + "/" + syminfo.currency // Check if our account currency is the same as the base or quote currency (for risk $ conversion purposes) accountSameAsCounterCurrency = accountCurrency == syminfo.currency accountSameAsBaseCurrency = accountCurrency == syminfo.basecurrency // Check if our account currency is neither the base or quote currency (for risk $ conversion purposes) accountNeitherCurrency = not accountSameAsCounterCurrency and not accountSameAsBaseCurrency // Get currency conversion rates if applicable conversionCurrencyPair = accountSameAsCounterCurrency ? syminfo.tickerid : accountNeitherCurrency ? accountCurrency + syminfo.currency : accountCurrency + syminfo.currency conversionCurrencyRate = security(symbol=syminfo.type == "forex" ? conversionCurrencyPair : "AUDUSD", resolution="D", expression=close) // Calculate position size getPositionSize(stopLossSizePoints) => riskAmount = (accountBalance * (riskPerTrade / 100)) * (accountSameAsBaseCurrency or accountNeitherCurrency ? conversionCurrencyRate : 1.0) riskPerPoint = (stopLossSizePoints * syminfo.pointvalue) positionSize = syminfo.type == "forex" ? ((riskAmount / riskPerPoint) / syminfo.mintick) : 0 round(positionSize) // Custom function to convert pips into whole numbers toWhole(number) => return = atr(14) < 1.0 ? (number / syminfo.mintick) / (10 / syminfo.pointvalue) : number return := atr(14) >= 1.0 and atr(14) < 100.0 and syminfo.currency == "JPY" ? return * 100 : return //------------- END POSITION SIZE CODE -------------// // Set up our GTD (good-til-date) order info gtdTime = time + (gtdOrder * 1440 * 60 * 1000) // 86,400,000ms per day gtdYear = year(gtdTime) gtdMonth = month(gtdTime) gtdDay = dayofmonth(gtdTime) gtdString = " dt=" + tostring(gtdYear) + "-" + tostring(gtdMonth) + "-" + tostring(gtdDay) // Calculate our stops & targets stopSize = atr * stopMultiplier longStopPrice = low < low[1] ? low - stopSize : low[1] - stopSize longStopDistance = close - longStopPrice longTargetPrice = close + (longStopDistance * rr) shortStopPrice = high > high[1] ? high + stopSize : high[1] + stopSize shortStopDistance = shortStopPrice - close shortTargetPrice = close - (shortStopDistance * rr) // Save stops & targets for the current trade var tradeStopPrice = 0.0 var tradeTargetPrice = 0.0 // Detect valid long setups & trigger alerts temp_positionSize = getPositionSize(toWhole(longStopDistance) * 10) if validLong tradeStopPrice := longStopPrice tradeTargetPrice := longTargetPrice tradePositionSize := temp_positionSize // Generate PineConnector alert syntax pc_alert = pc_entry_alert("buy", tradeStopPrice, tradeTargetPrice) // Generate AutoView alert syntax av_alert = "e=" + broker + " b=long" + " q=" + tostring(tradePositionSize) + " s=" + pair + " t=" + (limitOrder ? "limit fp=" + tostring(close) : "market") + " fsl=" + tostring(tradeStopPrice) + " ftp=" + tostring(tradeTargetPrice) + (gtdOrder != 0 and limitOrder ? gtdString : "") // Send alert to webhook alert(message=autoview ? av_alert : pineconnector ? pc_alert : "HSS Long Alert", freq=alert.freq_once_per_bar_close) // Detect valid short setups & trigger alerts temp_positionSize := getPositionSize(toWhole(shortStopDistance) * 10) if validShort tradeStopPrice := shortStopPrice tradeTargetPrice := shortTargetPrice tradePositionSize := temp_positionSize // Generate PineConnector alert syntax pc_alert = pc_entry_alert("sell", tradeStopPrice, tradeTargetPrice) // Generate AutoView alert syntax av_alert = "e=" + broker + " b=short" + " q=" + tostring(tradePositionSize) + " s=" + pair + " t=" + (limitOrder ? "limit fp=" + tostring(close) : "market") + " fsl=" + tostring(tradeStopPrice) + " ftp=" + tostring(tradeTargetPrice) + (gtdOrder != 0 and limitOrder ? gtdString : "") // Send alert to webhook alert(message=autoview ? av_alert : pineconnector ? pc_alert : "HSS Short Alert", freq=alert.freq_once_per_bar_close) // Enter trades whenever a valid setup is detected strategy.entry(id="Long", long=strategy.long, when=validLong) strategy.entry(id="Short", long=strategy.short, when=validShort) // Exit trades whenever our stop or target is hit strategy.exit(id="Long Exit", from_entry="Long", limit=tradeTargetPrice, stop=tradeStopPrice, when=strategy.position_size > 0) strategy.exit(id="Short Exit", from_entry="Short", limit=tradeTargetPrice, stop=tradeStopPrice, when=strategy.position_size < 0) // Draw trade data plot(emaFilterLength == 0 ? na : ema, color=close > ema ? color.green : color.red, title="EMA Filter") plot(strategy.position_size != 0 or validLong or validShort ? tradeStopPrice : na, title="Trade Stop Price", color=color.new(color.red,0), style=plot.style_linebr) plot(strategy.position_size != 0 or validLong or validShort ? tradeTargetPrice : na, title="Trade Target Price", color=color.new(color.green,0), style=plot.style_linebr) //plot(strategy.position_size != 0 or validLong or validShort ? tradePositionSize : na, title="Trade Position Size", color=color.purple, style=plot.style_linebr, transp=100) // Draw price action setup arrows plotshape(validLong ? 1 : na, style=shape.triangleup, location=location.belowbar, color=color.green, title="Bullish Setup") plotshape(validShort ? 1 : na, style=shape.triangledown, location=location.abovebar, color=color.red, title="Bearish Setup")
// 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=4 strategy("Daily Breakout Strategy", overlay=true, default_qty_value=1000000) // Get user input entryPips = input(title="Entry Pips", defval=3.0, type=input.float, tooltip="How many pips above high to place entry order") stopPips = input(title="Stop Pips", defval=5.0, type=input.float, tooltip="Fixed pip stop loss distance") targetPips = input(title="Target Pips", defval=10.0, type=input.float, tooltip="Fixed pip profit target distance") // Get highs and lows dailyHigh = security(syminfo.tickerid, "D", high) dailyLow = security(syminfo.tickerid, "D", low) // Determine buy & sell point (default 3 pips/30 points above/below high/low) buyPoint = dailyHigh + (entryPips * 10 * syminfo.mintick) sellPoint = dailyLow - (entryPips * 10 * syminfo.mintick) // Determine stop loss (default 5 pips/50 points above/below buy/sell point) stopLossLong = buyPoint - (stopPips * 10 * syminfo.mintick) stopLossShort = sellPoint + (stopPips * 10 * syminfo.mintick) // Determine take profit (default 10 pips/100 points above/below buy/sell point) takeProfitLong = buyPoint + (targetPips * 10 * syminfo.mintick) takeProfitShort = sellPoint - (targetPips * 10 * syminfo.mintick) // If a new day has started and we're flat, place a buy stop & sell stop var stopLossLongSaved = 0.0 var takeProfitLongSaved = 0.0 var stopLossShortSaved = 0.0 var takeProfitShortSaved = 0.0 newDay = change(time("D")) if newDay if strategy.position_size == 0 stopLossLongSaved := stopLossLong takeProfitLongSaved := takeProfitLong strategy.entry(id="Long", long=strategy.long, stop=buyPoint, oca_name="x", oca_type=strategy.oca.cancel) stopLossShortSaved := stopLossShort takeProfitShortSaved := takeProfitShort strategy.entry(id="Short", long=strategy.short, stop=sellPoint, oca_name="x", oca_type=strategy.oca.cancel) // Exit our trade if our stop loss or take profit is hit strategy.exit(id="Long Exit", from_entry="Long", limit=takeProfitLongSaved, stop=stopLossLongSaved) strategy.exit(id="Short Exit", from_entry="Short", limit=takeProfitShortSaved, stop=stopLossShortSaved) // Draw data to the chart plot(dailyHigh, color=color.blue, linewidth=2, title="Daily High") plot(dailyLow, color=color.blue, linewidth=2, title="Daily Low") plot(buyPoint, color=color.purple, title="Buy Stop") plot(stopLossLong, color=color.red, title="Long Stop Loss") plot(takeProfitLong, color=color.green, title="Long Profit Target") plot(sellPoint, color=color.purple, title="Sell Stop") plot(stopLossShort, color=color.red, title="Short Stop Loss") plot(takeProfitShort, color=color.green, title="Short Profit Target")
// 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=4 study("Discord Alerts") // Get user input botName = input(title="Bot Name", type=input.string, defval="TradingView", tooltip="The display name for this webhook bot") avatarURL = input(title="Avatar URL", type=input.string, defval="https://pbs.twimg.com/profile_images/1418656582888525833/p4fZd3KR.jpg", tooltip="Your preferred Avatar image URL") iconURL = input(title="Icon URL", type=input.string, defval="https://theartoftrading.com/files/discord/zentradingcircle.png", tooltip="Your preferred message icon image URL") titleURL = input(title="Title URL", type=input.string, defval="https://www.tradingview.com/chart/", tooltip="Where you want the title of the message to link to") message = input(title="Message", type=input.string, defval="", tooltip="Optional message to add before the role tag & embed info") role = input(title="Role ID", type=input.string, defval="", tooltip="The role ID you want to ping when this message is sent to discord (optional)") embedColor = input(title="Embed Color", type=input.string, defval="", tooltip="Your embed color (decimal color only - not HEX or RGB!)") volatility = input(title="Volatility Alerts?", type=input.bool, defval=true, tooltip="Turns on/off intraday volatility alerts") // Declare constant variables var ROLE_ID = role == "" ? "" : " (<@&" + role + ">)" var ICON1_URL = syminfo.type == "forex" ? ("https://theartoftrading.com/files/discord/flags/" + syminfo.basecurrency + ".png") : iconURL var ICON2_URL = syminfo.type == "forex" ? ("https://theartoftrading.com/files/discord/flags/" + syminfo.currency + ".png") : "" var MARKET = syminfo.type == "forex" or syminfo.type == "crypto" ? syminfo.basecurrency : syminfo.ticker // Get market data to send to discord mktChange = (change(close) / close[1]) * 100 mktRSI = rsi(close, 14) // Custom function to truncate (cut) excess decimal places truncate(_number, _decimalPlaces) => _factor = pow(10, _decimalPlaces) int(_number * _factor) / _factor // Custom function to convert pips into whole numbers atr = atr(14) toWhole(_number) => _return = atr < 1.0 ? (_number / syminfo.mintick) / (10 / syminfo.pointvalue) : _number _return := atr >= 1.0 and atr < 100.0 and syminfo.currency == "JPY" ? _return * 100 : _return // Generate discord embed JSON getDiscordEmbedJSON(_color, _author, _title, _url, _icon_url, _icon2_url, _footer, _description) => botTxt = "\"username\":\"" + botName + "\",\"avatar_url\":\"" + avatarURL + "\"," tagTxt = message == "" and role == "" ? "" : ("\"content\":\"" + (message == "" ? "" : message + " ") + ROLE_ID + "\",") returnString = "{" + botTxt + tagTxt + "\"embeds\":[{\"title\":\""+_title+"\",\"url\":\""+_url+"\",\"color\":"+ _color+",\"description\":\""+_description+"\",\"author\":{\"name\":\""+_author+ "\",\"url\":\""+_url+"\",\"icon_url\":\""+_icon_url+"\"},\"footer\":{\"text\":\""+_footer+"\",\"icon_url\":\""+_icon2_url+"\"}}]}" // Determine if we have a new bar starting - if so, send our Discord webhook alert if barstate.isconfirmed timeframe = (timeframe.isintraday ? timeframe.period + " minute" : timeframe.isdaily ? "Daily" : timeframe.isweekly ? "Weekly" : timeframe.ismonthly ? "Monthly" : timeframe.period) + " timeframe" update = syminfo.ticker + " ended " + (mktChange > 0 ? "up +" : "down ") + tostring(truncate(mktChange,2)) + "% on " + timeframe + " (RSI = " + tostring(truncate(mktRSI,2)) + ")" gainLoss = toWhole(open - close) footer = "Price: " + tostring(close) + " (" + (gainLoss > 0 ? "+" : "") + tostring(gainLoss) + " pips)" gainColor = (embedColor != "" ? embedColor : (mktChange > 0 ? "65280" : "16711680")) content = getDiscordEmbedJSON(gainColor, "Market Update", syminfo.ticker, titleURL, ICON1_URL, ICON2_URL, footer, update) alert(content, alert.freq_once_per_bar) // Check if we have high intraday volatility - if so, send our Discord webhook alert if abs(mktChange) >= 10 and volatility timeframe = (timeframe.isintraday ? timeframe.period + " minute" : timeframe.isdaily ? "Daily" : timeframe.isweekly ? "Weekly" : timeframe.ismonthly ? "Monthly" : timeframe.period) + " timeframe" update = syminfo.ticker + " is " + (mktChange > 0 ? "up +" : "down ") + tostring(truncate(mktChange,2)) + "% [" + tostring(close) + "] on " + timeframe + " (RSI = " + tostring(truncate(mktRSI,2)) + ")" gainLoss = toWhole(open - close) footer = "Price: " + tostring(close) + " (" + (gainLoss > 0 ? "+" : "") + tostring(gainLoss) + " pips)" gainColor = (embedColor != "" ? embedColor : (mktChange > 0 ? "65280" : "16711680")) content = getDiscordEmbedJSON(gainColor, "High Volatility Alert", syminfo.ticker, titleURL, ICON1_URL, ICON2_URL, footer, update) alert(content, alert.freq_once_per_bar) // Prepare table var table myTable = table.new(position.middle_right, 1, 1, border_width=1) f_fillCell(_table, _column, _row, _title, _value, _bgcolor, _txtcolor) => _cellText = _title + "\n" + _value table.cell(_table, _column, _row, _cellText, bgcolor=_bgcolor, text_color=_txtcolor) // Draw table if barstate.islast f_fillCell(myTable, 0, 0, "Market:", MARKET + " (" + syminfo.type + ")", color.new(color.black,0), color.white)
// 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=4 study("Tables", overlay=true) // Custom function to truncate (cut) excess decimal places truncate(_number, _decimalPlaces) => _factor = pow(10, _decimalPlaces) int(_number * _factor) / _factor // Get display data ema = ema(close,50) rsi = rsi(close,14) mktChange = (change(close) / close[1]) * 100 // Create table var table myTable = table.new(position.top_right, 5, 2, border_width=1) // Update table if barstate.islast txt1 = "Closing Price\n" + tostring(close) txt2 = "Opening Price\n" + tostring(open) txt3 = "Pip Gain/Loss\n" + tostring(close - open) txt4 = "50-EMA Value\n" + tostring(truncate(ema,2)) txt5 = "RSI Value\n" + tostring(truncate(rsi,2)) txt6 = "Percent Change\n" + tostring(truncate(mktChange,2)) + "%" table.cell(myTable, 0, 0, text=txt1, bgcolor=color.black, text_color=color.white) table.cell(myTable, 0, 1, text=txt2, bgcolor=color.black, text_color=color.white) table.cell(myTable, 1, 0, text=txt3, bgcolor=color.black, text_color=color.white) table.cell(myTable, 1, 1, text=txt4, bgcolor=color.black, text_color=color.white) table.cell(myTable, 2, 0, text=txt5, bgcolor=color.black, text_color=color.white) table.cell(myTable, 2, 1, text=txt6, bgcolor=(mktChange > 0 ? color.green : color.red), text_color=color.white)