Strategy · Pine Script v4 · On the chart

ADX | DMI Trend

by hasnocool· code credited to millerrh

This price-chart strategy treats a rising ADX above a chosen key level as a trend and uses plus and minus DI to choose direction.

View on GitHub

GitHub stars106on the repository
Pine versionv4older, still runs
Lines of code122
Settings29inputs
LicenceGPL-3.0
Last update2 years ago18 Sep 2024

Add It to Your TradingView Chart

  1. 1Copy the scriptPress Copy script above, or the copy button on the code below.
  2. 2Open the Pine EditorOpen a TradingView chart and choose Pine Editor at the bottom of the screen.
  3. 3Paste over the templateCreate a new strategy, select all of the template text and paste. Press Save and give it a name.
  4. 4Add it to the chartPress Add to chart. The trades and results appear in the Strategy Tester tab; adjust the settings with the gear icon.

Source Code

122 lines of Pine Script v4 from ADX - DMI Trend Strategy.pine, published under GPL-3.0. Keep the author's credit and licence lines when you reuse it.

ADX - DMI Trend Strategy.pine
//@version=4
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © millerrh with inspiration from @9e52f12edd034d28bdd5544e7ff92e 
//The intent behind this study is to look at ADX when it has an increasing slope and is above a user-defined key level (23 default). 
//This is to identify when it is trending.
//It then looks at the DMI levels.  If D+ is above D- and the ADX is sloping upwards and above the key level, it triggers a buy condition.  Opposite for short.
//Can use a user-defined moving average to filter long/short if desried.
// NOTE: THIS IS MEANT TO BE USED IN CONJUNCTION WITH MY "ATX TRIGGER" INDICATOR FOR VISUALIZATION. MAKE SURE SETTINGS ARE THE SAME FOR BOTH.
strategy("ADX | DMI Trend", overlay=true, initial_capital=10000, currency='USD', 
   default_qty_type=strategy.percent_of_equity, default_qty_value=100, commission_type=strategy.commission.percent, commission_value=0.04)
// === BACKTEST RANGE ===
From_Year  = input(defval = 2019, title = "From Year")
From_Month = input(defval = 1, title = "From Month", minval = 1, maxval = 12)
From_Day   = input(defval = 1, title = "From Day", minval = 1, maxval = 31)
To_Year    = input(defval = 9999, title = "To Year")
To_Month   = input(defval = 1, title = "To Month", minval = 1, maxval = 12)
To_Day     = input(defval = 1, title = "To Day", minval = 1, maxval = 31)
Start  = timestamp(From_Year, From_Month, From_Day, 00, 00)  // backtest start window
Finish = timestamp(To_Year, To_Month, To_Day, 23, 59)        // backtest finish window
// == INPUTS ==
shortTrades = input(title = "Allow short trades?", type = input.bool, defval = true)
// ADX Info
adxlen = input(14, title="ADX Smoothing")
dilen = input(14, title="DI Period")
keyLevel = input(23, title="Keylevel for ADX")
adxLookbackEntry = input(3, title="Lookback Period for Slope (Entry)")
adxLookbackExit = input(1, title="Lookback Period for Slope (Exit)")
// == VOLUME FILTERING ==
// Inputs
volFilter = input(title = "Use Volume as Entry Filter?", type = input.bool, defval = true)
volType = input(defval="Multiplier * Average", options=["Multiplier * Average", "Manual", "Multiplier * Average AND Manual"], title = "Volume Filtering Method")
volMult = input(title = "Volume Trigger Multiplier", defval = 2, step = 0.1)
volSMA = input(title = "Volume Trigger Average Bars Back", defval = 20, step = 1)
volManual = input(20000, title="Manual Volume Value", step = 1000)
// Check that volume is high before entering trade
xVol = sma(volume, volSMA)
xVolMult = xVol * volMult
manualCompare = volManual > xVolMult
xVolManual = manualCompare == true ? volManual : xVolMult
volCheck = (volFilter == true and volType == "Multiplier * Average") ? xVolMult : (volFilter == true and volType == "Manual") ? volManual : (volFilter == true and volType == "Multiplier * Average AND Manual") ? xVolManual : 0
//     xVol * volMult
// else
//     0
// == MOVING AVERAGE FILTERING ==
// Inputs
useMaFilter = input(title = "Use MA for Entry Filtering?", type = input.bool, defval = true)
maType = input(defval="EMA", options=["EMA", "SMA"], title = "MA Type For Filtering")
maLength   = input(defval = 200, title = "MA Period for Filtering", minval = 1)
// Declare function to be able to swap out EMA/SMA
ma(maType, src, length) =>
    maType == "EMA" ? ema(src, length) : sma(src, length) //Ternary Operator (if maType equals EMA, then do ema calc, else do sma calc)
maFilter = ma(maType, close, maLength)
plot(maFilter, title = "Trend Filter MA", color = color.green, linewidth = 3, style = plot.style_line, transp = 50)
// Check to see if the useMaFilter check box is checked, this then inputs this conditional "maFilterCheck" variable into the strategy entry 
maFilterCheck = if useMaFilter == true
    maFilter
else
    close
    
// == ATR TRAILING STOPS ==
// Inputs
useATR = input(title = "Use ATR for Trailing Stop?", type = input.bool, defval = true)
atrLookback = input(defval=14,title="ATR Lookback Period",type=input.integer)
multiplier = input(defval=2,title="ATR Multiplier",type=input.float, step=0.1, minval=0.5, maxval=4)
trigInput = input(title = "Execute Trades On...", defval = "Wick", options=["Wick","Close"]) // Useful for comparing standing stop orders vs. waiting for candle closes prior to action
showInput = input(title="Show Trailing ATR", defval="Both", options=["Support","Resistance","Both"]) 
// Calculate the trailing ATR
atrValue = atr(atrLookback)
atrMultiplied = atrValue * multiplier
// Plot the price plus or minus the ATR
atrLow = low - atrMultiplied
atrHigh = high + atrMultiplied
// Calculate both the low and high trailing ATRs every time. The low one never goes down, and the high one never goes up
// Set them to something to start with
trailAtrLow = atrLow
trailAtrHigh = atrHigh
// If the ATR Low has gone up AND it has gone above the trail, the low trailing ATR should also go up. If the ATR Low has gone up or down, but not below the trail, the ATR trail stays where it is
trailAtrLow := na(trailAtrLow[1]) ? trailAtrLow : atrLow >= trailAtrLow[1] ? atrLow : trailAtrLow[1]
// Same for the High
trailAtrHigh := na(trailAtrHigh[1]) ? trailAtrHigh : atrHigh <= trailAtrHigh[1] ? atrHigh : trailAtrHigh[1]
// Trigger stop based on candle close or High/Low
trigResistance = trigInput == "Close" ? close : trigInput == "Wick" ? high : na
trigSupport = trigInput == "Close" ? close : trigInput == "Wick" ? low : na
// Determine if price is above resistance or below support
atrResistanceHit = trigResistance >= trailAtrHigh and useATR == true
atrSupportHit = trigSupport <= trailAtrLow and useATR == true
// If price is above resistance or below support, reset the trailing ATR
trailAtrLow := atrSupportHit ? atrLow : trailAtrLow
trailAtrHigh := atrResistanceHit ? atrHigh : trailAtrHigh
// Plot ATR Lines
plotLow = useATR == true and showInput == "Support" ? trailAtrLow : useATR == true and showInput == "Both" ? trailAtrLow : na
plotHigh = useATR == true and showInput == "Resistance" ? trailAtrHigh : useATR == true and showInput == "Both" ? trailAtrHigh : na
plot(plotLow, color=color.gray, style=plot.style_linebr, linewidth=1)
plot(plotHigh, color=color.gray, style=plot.style_linebr, linewidth=1)
// == LOOK AT PARABOLIC SAR AS AN EXIT OPTION ==
useSAR = input(title = "Use SAR for Trailing Stop?", type = input.bool, defval = true)
sarStart = input(0.02, "Start")
sarIncrement = input(0.02, "Increment")
sarMaximum = input(0.2, "Max Value")
sarOut = useSAR ? sar(sarStart, sarIncrement, sarMaximum) : na
plot(sarOut, "ParabolicSAR", style=plot.style_cross, color=#3A6CA8)
// Determine if price is above resistance or below support
sarResistanceHit = trigResistance >= sarOut and useSAR == true
sarSupportHit = trigSupport <= sarOut and useSAR == true
// == USE BUILT-IN DMI FUNCTION TO DETERMINE ADX AND BULL/BEAR STRENGTH
[diplus, diminus, adx] = dmi(dilen, adxlen)
buySignal = (adx[0]-adx[adxLookbackEntry] > 0) and adx > keyLevel and diplus > diminus and time > Start and time < Finish and close >= maFilterCheck and volume > volCheck
shortSignal = (adx[0]-adx[adxLookbackEntry] > 0) and adx > keyLevel and diplus < diminus and time > Start and time < Finish and close <= maFilterCheck and shortTrades and volume > volCheck
sellSignal = (adx[0]-adx[adxLookbackExit] < 0) or atrSupportHit or sarSupportHit
coverSignal = (adx[0]-adx[adxLookbackExit] < 0) or atrResistanceHit or sarResistanceHit
// == STRATEGY ENTRIES/EXITS == 
strategy.entry("Long", strategy.long, when = buySignal)
strategy.close("Long", when = sellSignal)
strategy.entry("Short", strategy.short, when = shortSignal)
strategy.close("Short", when = coverSignal)
    
// == ALERTS == 
alertcondition(buySignal, title='ADX | DMI Long', message='ADX | DMI Long')
alertcondition(shortSignal, title='ADX | DMI Short', message='ADX | DMI Short')
alertcondition(sellSignal, title='ADX | DMI Sell', message='ADX | DMI Sell')
alertcondition(coverSignal, title='ADX | DMI Cover', message='ADX | DMI Cover')
Expand (143 lines)

Overview

ADX | DMI Trend enters long when plus DI leads and short when minus DI leads, if short trades are allowed. Volume and an EMA or SMA can block entries, while lookback lengths change the ADX slope tests used for entry and exit. ATR and Parabolic SAR trailing-stop settings are present, but no stop loss is active by default. Each order uses a percentage of equity.

Details

Published by

hasnocool on GitHub

Code credit

millerrh, as written in the script's header

Type

Strategy, Pine Script v4

Draws

On the price chart

Category

Trend, Oscillators & momentum, Volatility & bands

Markets

Any symbol

Timeframes

Any timeframe

Risk Notes

  • The strategy enters trades without a stop loss

Topics

analysisbtcusdtcryptocurrencydatapandaspythonsimulationtradingtradingview

Settings

The inputs you can change from the gear icon on the chart. Defaults are the author's.

SettingTypeDefaultVariable
From Yearint2019From_Year
From Monthint1From_Month
From Dayint1From_Day
To Yearint9999To_Year
To Monthint1To_Month
To Dayint1To_Day
Allow short trades?booltrueshortTrades
ADX Smoothingint14adxlen
DI Periodint14dilen
Keylevel for ADXint23keyLevel
Lookback Period for Slope (Entry)int3adxLookbackEntry
Lookback Period for Slope (Exit)int1adxLookbackExit
Show all 29 settings
SettingTypeDefaultVariable
Use Volume as Entry Filter?booltruevolFilter
Volume Filtering MethodstringMultiplier * AveragevolType
Volume Trigger Multiplierint2volMult
Volume Trigger Average Bars Backint20volSMA
Manual Volume Valueint20000volManual
Use MA for Entry Filtering?booltrueuseMaFilter
MA Type For FilteringstringEMAmaType
MA Period for Filteringint200maLength
Use ATR for Trailing Stop?booltrueuseATR
ATR Lookback Periodint14atrLookback
ATR Multiplierfloat2multiplier
Execute Trades On...stringWicktrigInput
Show Trailing ATRstringBothshowInput
Use SAR for Trailing Stop?booltrueuseSAR
Startfloat0.02sarStart
Incrementfloat0.02sarIncrement
Max Valuefloat0.2sarMaximum
Third-party code. ForexR did not write, test or endorse this script, and the summary above was generated automatically from its code and README. Indicators describe the past, and a strategy's backtest can look better than live trading, especially when a script repaints. Check it in the Strategy Tester and on a demo account before you rely on it.

Similar Pine Scripts

Momentum Rider DAILY FINAL

by greenpeas007
58 stars

This strategy combines exponential moving averages (EMA 9, 21, 50), RSI, MACD, and Supertrend indicators to enter long positions. It triggers trades using six dynamic setups based on momentum breakouts, EMA crossovers, and pullbacks. Position sizing is compute

Strategy v6 TrendOscillators & momentum Repaints
Updated 4 months ago · Custom licence GitHub repository of Momentum Rider DAILY FINAL
57 stars

This strategy identifies trend reversals through market structure changes (CHoCH) filtered by MACD momentum. It initiates long positions on bullish structure breaks when MACD is positive and above its signal line, and short positions on bearish breaks when MAC

Strategy v6 SMC / ICT / price actionOscillators & momentum Repaints
Updated 1 year ago · Apache-2.0 GitHub repository of Market Structure MACD 4H + Trailing

CombinedBinHAndClucV6

by viktors1982
36 stars

CombinedBinHAndClucV6 is a trading strategy based on the popular BinHV45 and ClucMay72018 algorithms. It calculates dual Bollinger Bands, Exponential Moving Averages, Relative Strength Index, Average True Range, and volume metrics across primary and one-hour h

Strategy v4 Volatility & bandsOscillators & momentum Repaints
Updated 2 years ago · None stated GitHub repository of CombinedBinHAndClucV6
27 stars

LuxAlgo Hybrid Gold Scalper is a price-chart strategy aimed at gold. It stacks a fast, slow, trend and 200-period bias EMA to mark trend direction, then filters strength with RSI, ADX and an intraday VWAP. Swing highs and lows are marked from pivot length. Set

Strategy v5 TrendOscillators & momentum
Updated 5 months ago · None stated GitHub repository of LuxAlgo Hybrid Gold Scalper

Nueva_23-07

by santiagocanepa
27 stars

This multi-indicator modular strategy evaluates market entries by requiring consensus across a selectable suite of technical tools, including Absolute Strength, SSL Channel, Squeeze Momentum, and WaveTrend. Once conditions are met, it executes entries and scal

Strategy v5 Oscillators & momentumTrend
Updated 6 months ago · Custom licence GitHub repository of Nueva_23-07

More strategys

Trade Your Charts With a Regulated Broker

Compare brokers that connect to TradingView, with spreads, minimum deposits and leverage side by side.

Compare brokers