Rajandran R Telecom Engineer turned Full-time Derivative Trader. Mostly Trading Nifty, Banknifty, USDINR and High Liquid Stock Derivatives. Trading the Markets Since 2006 onwards. Using Market Profile and Orderflow for more than a decade. Designed and published 100+ open source trading systems on various trading tools. Strongly believe that market understanding and robust trading frameworks are the key to the trading success. Writing about Markets, Trading System Design, Market Sentiment, Trading Softwares & Trading Nuances since 2007 onwards. Author of Marketcalls.in)

Dhan – Tradingview Webhook Automation – Long Short Trading Strategy Module

7 min read

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.

Rajandran R Telecom Engineer turned Full-time Derivative Trader. Mostly Trading Nifty, Banknifty, USDINR and High Liquid Stock Derivatives. Trading the Markets Since 2006 onwards. Using Market Profile and Orderflow for more than a decade. Designed and published 100+ open source trading systems on various trading tools. Strongly believe that market understanding and robust trading frameworks are the key to the trading success. Writing about Markets, Trading System Design, Market Sentiment, Trading Softwares & Trading Nuances since 2007 onwards. Author of Marketcalls.in)

Dive Into the TradingView Paper Trading Competition: A Chance…

Welcome to an exhilarating opportunity presented by TradingView – a paper trading competition that not only tests your trading acumen but also offers a...
Rajandran R
1 min read

Introducing PineGPT – To Build Better Tradingview Pinescript Codes

PineGPT is a customGPT for ChatGPT4 users designed to provide expert guidance on creating and understanding TradingView Pine Script indicators and trading strategies. PineGPT...
Rajandran R
1 min read

5Paisa – Tradingview Webhook Automation Module

In this tutorial, we will be learning how to use the 5Paisa – Tradingview Webhook feature for automating your Tradingview pinescript strategy. This Module...
Rajandran R
10 min read

Leave a Reply

Get Notifications, Alerts on Market Updates, Trading Tools, Automation & More