In this tutorial, we will be learning how to use the Dhan – Tradingview Webhook feature for automating your Tradingview pinescript strategy. This Module discusses configuring a long/short trading system with stoploss/target/trailing stoploss controls
Tradingview Automation Requirements
1)Dhan Trading Account
2)Tradingview Paid Subscription (Essential, Plus or Premium Plans)
3)Tradingview Pinescript Strategy
Steps to Set Up Automated Trading with Dhan and TradingView Webhook
Below is an overview of how to set up automated trading using Dhan through the TradingView webhook.
Steps to Set Up Automated Trading with Dhan and TradingView Webhook
1.Log in to Dhan: Access your broker portal by logging in to Dhan.
2Dhan.Webhook Configuration:
- Navigate to the Orders tab.
- Select the Webhooks tab and manage your webhooks.
- Create a new webhook with the desired validity by clicking on the ‘Generate Webhook’ button.
3.Trading Instrument Selection:
- Click on the ‘Add Scrip’ button.
- Choose the trading instrument you wish to trade.
4.JSON Generation:
- Generate the JSON for order execution by clicking on the ‘Generate JSON’ button.
- Copy the JSON object that’s generated.
Generated Sample JSON
Here is the unique sample JSON Generated from Dhan portal and it varies from user to user
{
"secret": "iF4yz",
"alertType": "multi_leg_order",
"order_legs": [
{
"transactionType": "B",
"orderType": "MKT",
"quantity": "1",
"exchange": "NSE",
"symbol": "NIFTY1!",
"instrument": "FUT",
"productType": "M",
"sort_order": "1",
"price": "0"
}
]
}
Convert to Tradingview Alerts JSON Message with Dynamic Action and Quantity
Convert the copied JSON into a format that can be used by TradingView’s webhook. Use Strategy placeholders like {{strategy.order.alert_message}}
and {{strategy.order.contracts}}
to insert dynamic buy/sell actions and quantities as part of the trading strategy alerts. Here is the modified response
{
"secret": "iF4yz",
"alertType": "multi_leg_order",
"order_legs": [
{
"transactionType": "{{strategy.order.alert_message}}",
"orderType": "MKT",
"quantity": "{{strategy.order.contracts}}",
"exchange": "NSE",
"symbol": "NIFTY1!",
"instrument": "FUT",
"productType": "M",
"sort_order": "1",
"price": "0"
}
]
}
Tradingview Pinescript Strategy
Apply your trading strategy script on TradingView. The script should include blocks for backtesting controls, strategy logic, intraday functions, and strategy execution. Here is a sample supertrend trading system with various configurable blocks with intraday, stoploss, target and trailing stoploss controls which fits the stop and reversal trading strategy
////////////////////////////////////////////////////////////////////////////////////////////////////////////
//Trading Block Description
//Module Name : Long/Short Module
//Coded by Rajandran R (Founder - www.marketcalls.in)
//Version : v1.0
//Coded Date : 20th Dec 2023
//Block 1 : Backtesting Controls & Target and Stoploss Controls
//Block 2 : Trading Strategy and Controls (write your trading strategy in the block
//Block 3 : Intraday Function and Buy and Sell Signal Mapping (Signal Mapping is required)
//Block 4 : Strategy Execution Module
//Block 5 : Strategy Stoploss, Target and Trailing Stoploss Execution Module
///////////////////////////////////////////////////////////////////////////////////////////////////////////
//@version=5
strategy('SuperTrend Trading Strategy with Target/Stoploss/TrailingStoploss', shorttitle='Supertrend Strategy', overlay=true,process_orders_on_close=true)
//Block 1 : Backtesting Controls & Target Stoploss Controls
FromDay = input.int(defval=1, title='From Day', minval=1, maxval=31, group='Backtesting')
FromMonth = input.int(defval=1, title='From Month', minval=1, maxval=12, group='Backtesting')
FromYear = input.int(defval=2018, title='From Year', minval=999, group='Backtesting')
ToDay = input.int(defval=1, title='To Day', minval=1, maxval=31, group='Backtesting')
ToMonth = input.int(defval=1, title='To Month', minval=1, maxval=12, group='Backtesting')
ToYear = input.int(defval=9999, title='To Year', minval=999, group='Backtesting')
start = timestamp(FromYear, FromMonth, FromDay, 00, 00)
finish = timestamp(ToYear, ToMonth, ToDay, 23, 59)
window() =>
time >= start and time <= finish ? true : false
Mode = input.string(title='Algo Mode', defval='ENABLE', options=['ENABLE', 'LONGONLY', 'SHORTONLY'], group='Backtesting')
highlighting = input.bool(title='Highlighter On/Off ?', defval=true, group='Intraday Controls')
barcoloring = input.bool(title='Bar Coloring On/Off ?', defval=true, group='Intraday Controls')
intraday = input.bool(title='Intraday On/Off ?', defval=false, group='Intraday Controls')
marketSession = input.session(title='Market session', defval='0930-1500', confirm=false, group='Intraday Controls')
risk = input.bool(title='Stoploss/Target On/Off', defval=false, group='Stoploss/Target Controls')
type = input.string(title='Type', defval='FIXED', options=['FIXED', 'PERCENTAGE', 'VOLATILITY'], group='Stoploss/Target Controls')
stoploss = input.float(defval=10.0, title='Stoploss', group='Stoploss/Target Controls')
target = input.float(defval=20.0, title='Target', group='Stoploss/Target Controls')
TickSz = input.float(defval=0.05, title='TickSize', group='Stoploss/Target Controls')
ATRMultiplier = input.float(title='ATR Multiplier', step=0.1, defval=1.5, group='Stoploss/Target Controls')
ATRLength = input.int(title='ATR Period', defval=20, group='Stoploss/Target Controls')
iATR = ta.atr(ATRLength)
trail = input.bool(title='Trailing Stoploss On/Off', defval=false, group='Trailstop Controls')
longTrailPerc = input.float(title='Trail Long Stop (%)', minval=0.01, maxval=50.0, step=0.01, defval=1, group='Trailstop Controls') * 0.01
shortTrailPerc = input.float(title='Trail Short Stop (%)', minval=0.01, maxval=50.0, step=0.01, defval=1, group='Trailstop Controls') * 0.01
var longCondition = false
var shortCondition = false
//Tradingview alert_message
string alert_buy = 'B'
string alert_sell = 'S'
////////////////////////////////////////Block 1 Module Ends////////////////////////////////////////////////////////////////////////
//Block 2 : Trading Strategy
//inputs
src = input(hl2, title='Source', group='Supertrend Controls')
Multiplier = input.float(title='ATR Multiplier', step=0.1, defval=3.0, group='Supertrend Controls')
Periods = input.int(title='ATR Period', defval=10, group='Supertrend Controls')
changeATR = input.bool(title='Change ATR Calculation Method ?', defval=true, group='Supertrend Controls')
showsignals = input.bool(title='Show Buy/Sell Signals ?', defval=true, group='Supertrend Controls')
atr2 = ta.sma(ta.tr, Periods)
atr = changeATR ? ta.atr(Periods) : atr2
up = src - Multiplier * atr
up1 = nz(up[1], up)
up := close[1] > up1 ? math.max(up, up1) : up
dn = src + Multiplier * atr
dn1 = nz(dn[1], dn)
dn := close[1] < dn1 ? math.min(dn, dn1) : dn
trend = 1
trend := nz(trend[1], trend)
trend := trend == -1 and close > dn1 ? 1 : trend == 1 and close < up1 ? -1 : trend
//Plots
upPlot = plot(trend == 1 ? up : na, title='Up Trend', style=plot.style_linebr, linewidth=2, color=color.new(color.green, 0))
buySignal = trend == 1 and trend[1] == -1
plotshape(buySignal ? up : na, title='UpTrend Begins', location=location.absolute, style=shape.circle, size=size.tiny, color=color.new(color.green, 0))
//plotshape(buySignal and showsignals ? up : na, title='Buy', text='Buy', location=location.absolute, style=shape.labelup, size=size.tiny, color=color.new(color.green, 0), textcolor=color.new(color.white, 0))
dnPlot = plot(trend == 1 ? na : dn, title='Down Trend', style=plot.style_linebr, linewidth=2, color=color.new(color.red, 0))
sellSignal = trend == -1 and trend[1] == 1
plotshape(sellSignal ? dn : na, title='DownTrend Begins', location=location.absolute, style=shape.circle, size=size.tiny, color=color.new(color.red, 0))
//plotshape(sellSignal and showsignals ? dn : na, title='Sell', text='Sell', location=location.absolute, style=shape.labeldown, size=size.tiny, color=color.new(color.red, 0), textcolor=color.new(color.white, 0))
mPlot = plot(ohlc4, title='', style=plot.style_circles, linewidth=0)
longFillColor = highlighting ? trend == 1 ? color.new(color.green,90) : na : na
shortFillColor = highlighting ? trend == -1 ? color.new(color.red,90) : na : na
fill(mPlot, upPlot, title='UpTrend Highligter', color=longFillColor)
fill(mPlot, dnPlot, title='DownTrend Highligter', color=shortFillColor)
////////////////////////////////////////Block 2 Module Ends////////////////////////////////////////////////////////////////////////
//Block 3 : Intraday Function and Buy and Sell Signal Mapping
//Remove the comments to do the long/short signal mapping
//buySignal = enterLong
//sellSignal = enterShort
barInSession(sess) =>
time(timeframe.period, sess) != 0
bool intradaySession = barInSession(marketSession)
buy = buySignal
sell = sellSignal
buy1 = buy[1]
sell1 = sell[1]
//assign signals
if(not intraday)
longCondition := buySignal
shortCondition := sellSignal
if(intraday)
longCondition := buySignal and intradaySession
shortCondition := sellSignal and intradaySession
////////////////////////////////////////Block 3 Module Ends////////////////////////////////////////////////////////////////////////
//Block 4 : Execution Controls
if(Mode=="ENABLE")
if longCondition and strategy.position_size == 0 and window()
strategy.entry('BUY', strategy.long, comment='BUY',alert_message = alert_buy)
if longCondition and strategy.position_size < 0 and window()
strategy.entry('BUY', strategy.long, comment='BUY',alert_message = alert_buy)
if shortCondition and strategy.position_size == 0 and window()
strategy.entry('SELL', strategy.short, comment='SELL',alert_message = alert_sell)
if shortCondition and strategy.position_size > 0 and window()
strategy.entry('SELL', strategy.short, comment='SELL',alert_message = alert_sell)
if(Mode=="LONGONLY")
if longCondition and strategy.position_size == 0 and window()
strategy.entry('BUY', strategy.long,comment='BUY',alert_message = alert_buy)
if shortCondition and strategy.position_size > 0 and window()
strategy.close('BUY', comment='BUY EXIT',alert_message = alert_sell)
if(Mode=="SHORTONLY")
if shortCondition and strategy.position_size == 0 and window()
strategy.entry('SELL', strategy.short, comment='SHORT',alert_message = alert_sell)
if longCondition and strategy.position_size < 0 and window()
strategy.close('SELL',comment='SHORT EXIT',alert_message = alert_buy)
if(intraday)
longsquareOff = not intradaySession and strategy.position_size > 0
if(longsquareOff)
strategy.close(id='BUY', comment='Square-off',alert_message = alert_sell)
shortsquareOff = not intradaySession and strategy.position_size < 0
if(shortsquareOff)
strategy.close(id='SELL', comment='Square-off',alert_message = alert_buy)
////////////////////////////////////////Block 4 Module Ends////////////////////////////////////////////////////////////////////////
//Block5 - Stoploss, Target and Trailingstoploss Execution Module
buycount = ta.barssince(buySignal)
sellcount = ta.barssince(sellSignal)
color1 = buycount[1] < sellcount[1] ? color.green : buycount[1] > sellcount[1] ? color.red : na
barcolor(barcoloring ? color1 : na)
long_stop_level = ta.valuewhen(strategy.position_size>0 and strategy.position_size[1]<=0, open - stoploss, 0)
long_profit_level = ta.valuewhen(strategy.position_size>0 and strategy.position_size[1]<=0, open + target, 0)
short_stop_level = ta.valuewhen(strategy.position_size<0 and strategy.position_size[1]>=0, open + stoploss, 0)
short_profit_level = ta.valuewhen(strategy.position_size<0 and strategy.position_size[1]>=0, open - target, 0)
if(type=="PERCENTAGE")
long_stop_level := ta.valuewhen(strategy.position_size>0 and strategy.position_size[1]<=0, open, 0) * (100-stoploss)/100
long_profit_level := ta.valuewhen(strategy.position_size>0 and strategy.position_size[1]<=0, open, 0) * (100+target)/100
long_stop_level := TickSz * math.round(long_stop_level/TickSz)
long_profit_level := TickSz * math.round(long_profit_level/TickSz)
short_stop_level := ta.valuewhen(strategy.position_size<0 and strategy.position_size[1]>=0, open, 0) * (100+stoploss)/100
short_profit_level := ta.valuewhen(strategy.position_size<0 and strategy.position_size[1]>=0, open, 0) * (100-target)/100
short_stop_level := TickSz * math.round(short_stop_level/TickSz)
short_profit_level := TickSz * math.round(short_profit_level/TickSz)
if(type=="VOLATILITY")
long_stop_level := ta.valuewhen(strategy.position_size>0 and strategy.position_size[1]<=0, open - iATR*ATRMultiplier, 0)
long_profit_level := ta.valuewhen(strategy.position_size>0 and strategy.position_size[1]<=0, open + iATR*ATRMultiplier, 0)
short_stop_level := ta.valuewhen(strategy.position_size<0 and strategy.position_size[1]>=0, open + iATR*ATRMultiplier, 0)
short_profit_level := ta.valuewhen(strategy.position_size<0 and strategy.position_size[1]>=0, open - iATR*ATRMultiplier, 0)
//Sending Target/Stoploss Orders
if(risk)
if(strategy.position_size>0)
strategy.exit('TP/SL', 'BUY', stop=long_stop_level, limit=long_profit_level,alert_message = alert_sell)
if(strategy.position_size<0)
strategy.exit('TP/SL', 'SELL', stop=short_stop_level, limit=short_profit_level,alert_message = alert_buy)
plot(strategy.position_size <= 0 or not risk ? na : long_stop_level, color=color.new(color.red, 0), style=plot.style_circles, linewidth=2)
plot(strategy.position_size <= 0 or not risk ? na : long_profit_level, color=color.new(color.green, 0), style=plot.style_circles, linewidth=2)
plot(strategy.position_size >= 0 or not risk ? na : short_stop_level, color=color.new(color.red, 0), style=plot.style_circles, linewidth=2)
plot(strategy.position_size >= 0 or not risk ? na : short_profit_level, color=color.new(color.green, 0), style=plot.style_circles, linewidth=2)
//Initialization of Long Stop Price and Short Stop Price
longStopPrice = 0.0
shortStopPrice = 0.0
//Sending Trailing Stoploss Orders
if(trail)
// Determine trail stop loss prices
longStopPrice := if strategy.position_size > 0
stopValue = close * (1 - longTrailPerc)
math.max(stopValue, longStopPrice[1])
else
0
shortStopPrice := if strategy.position_size < 0
stopValue = close * (1 + shortTrailPerc)
math.min(stopValue, shortStopPrice[1])
else
999999
// Submit exit orders for trail stop loss price
if strategy.position_size > 0
strategy.exit(id='TRAIL HIT', stop=longStopPrice,alert_message = 'S')
if strategy.position_size < 0
strategy.exit(id='TRAIL HIT', stop=shortStopPrice,alert_message = 'B')
// Plot stop loss values for confirmation
plot(series=strategy.position_size > 0 and trail ? longStopPrice : na, color=color.new(color.fuchsia, 0), style=plot.style_cross, linewidth=2, title='Long Trail Stop')
plot(series=strategy.position_size < 0 and trail ? shortStopPrice : na, color=color.new(color.fuchsia, 0), style=plot.style_cross, linewidth=2, title='Short Trail Stop')
Alert Configuration on TradingView:
1.After applying the strategy to the charts, create a strategy alert.
2.Enter the strategy name and the configured TradingView alert message.
3.In the alert box, go to the Notifications tab, enable webhook, and enter the Dhan webhook URL.
Trade Execution
Once configured, TradingView will send automated orders to Dhan based on the alerts set up by your trading strategy.
Automating trading strategies via webhooks can be a powerful tool for traders who use technical analysis to inform their trading decisions. By automating the trading process, traders can execute trades faster and more efficiently, often leading to better entry and exit points and overall improved trading performance.