Webhook json help

Help me to configure correct json
Below code is not firing order, although getting alert on trading view.

Note : I have a premium trading view account.
The web hook url is used correctly.
I have also pasted {{strategy.order.alert_message}} on Tradingview message

// === Quantity & Dhan JSON ===
lot_size = 75
qty = lot_size

dhan_json(tx, symbol, qty, opt_type, strike, expiry) =>
‘{“secret”:“sUmtC”,“alertType”:“multi_leg_order”,“order_legs”:[{“transactionType”:"’ + (tx == “BUY” ? “B” : “S”) + ‘“,“orderType”:“MKT”,“quantity”:”’ + str.tostring(qty) + ‘“,“exchange”:“NSE”,“symbol”:”’ + symbol + ‘“,“instrument”:“OPT”,“productType”:“I”,“sort_order”:“1”,“price”:“0”,“option_type”:”’ + opt_type + ‘“,“strike_price”:”’ + str.tostring(strike, “#.0”) + ‘“,“expiry_date”:”’ + expiry + ‘"}]}’

send_alert(tx, opt_type, strike) =>
if enableWebhook
alert(dhan_json(tx, “NIFTY”, qty, opt_type, strike, expiry_dt), alert.freq_once_per_bar)

// === Strategy & Alerts ===
if long_entry and inDateRange
strategy.entry(“Long”, strategy.long)
send_alert(“BUY”, “CE”, ce_strike)

if short_entry and inDateRange
strategy.entry(“Short”, strategy.short)
send_alert(“BUY”, “PE”, pe_strike)

if use_ema_exit and inDateRange
if long_exit
strategy.close(“Long”, comment=“EMA Exit”)
send_alert(“SELL”, “CE”, ce_strike)
if short_exit
strategy.close(“Short”, comment=“EMA Exit”)
send_alert(“SELL”, “PE”, pe_strike)

if not use_ema_exit and inDateRange
tp_long = strategy.position_avg_price + tp_pts
tp_short = strategy.position_avg_price - tp_pts
strategy.exit(“TP Long”, from_entry=“Long”, limit=tp_long)
strategy.exit(“TP Short”, from_entry=“Short”, limit=tp_short)
if close >= tp_long
send_alert(“SELL”, “CE”, ce_strike)
if close <= tp_short
send_alert(“SELL”, “PE”, pe_strike)

if inDateRange
sl_long = strategy.position_avg_price - sl_pts
sl_short = strategy.position_avg_price + sl_pts
strategy.exit(“SL/Trail Long”, from_entry=“Long”, stop=sl_long, trail_points=trail_sl, trail_offset=trail_offset)
strategy.exit(“SL/Trail Short”, from_entry=“Short”, stop=sl_short, trail_points=trail_sl, trail_offset=trail_offset)
if close <= sl_long
send_alert(“SELL”, “CE”, ce_strike)
if close >= sl_short
send_alert(“SELL”, “PE”, pe_strike)

@RajeshK

first debug step would be to check the tv alert log and see whether the alert json generated from your code is exactly like what Dhan server expects.

1 Like

Dhan server expects - request you to pls post some working sample, i might be missing something.

You can get a sample code here

1 Like

Still not working I am trying this

//@version=6
strategy(“EMA Crossover Strategy with Dhan Webhook”, overlay=true, default_qty_type=strategy.cash, default_qty_value=100000)

// === Global Automation Toggle ===
enableWebhook = input.bool(true, “Enable Webhook Alerts”, inline=“tog”, group=“Automation”)

// === EMA Controls (1m TF) ===
groupEMA = “EMA (1m)”
ema_tf = input.timeframe(“1”, “Timeframe”, group=groupEMA)
ema_fast_len = input.int(3, “Fast EMA Length”, minval=1, group=groupEMA)
ema_slow_len = input.int(21, “Slow EMA Length”, minval=1, group=groupEMA)
ema_src = input.source(close, “Source”, group=groupEMA)

// === Price Series ===
ema_fast = request.security(syminfo.tickerid, ema_tf, ta.ema(ema_src, ema_fast_len))
ema_slow = request.security(syminfo.tickerid, ema_tf, ta.ema(ema_src, ema_slow_len))

// === Entry Conditions ===
long_entry = ta.crossover(ema_fast, ema_slow)
short_entry = ta.crossunder(ema_fast, ema_slow)
long_exit = ta.crossunder(ema_fast, ema_slow)
short_exit = ta.crossover(ema_fast, ema_slow)

// === Strike Calculation (ATM) ===
round_strike(x) => math.round(x / 100) * 100
atm_strike = round_strike(close)
ce_strike = atm_strike
pe_strike = atm_strike

// === Expiry Calculation (Next Thursday) ===
get_expiry_date() =>
d = dayofweek
curr = timestamp(“GMT+5:30”, year, month, dayofmonth, 0, 0)
exp_day = d <= dayofweek.wednesday ? curr + (dayofweek.thursday - d) * 86400000 : curr + (7 - d + dayofweek.thursday) * 86400000
year_str = str.tostring(year(exp_day))
month_str = str.tostring(month(exp_day), “00”)
day_str = str.tostring(dayofmonth(exp_day), “00”)
year_str + “-” + month_str + “-” + day_str
expiry_dt = get_expiry_date()

// === Quantity ===
lot_size = 75
qty = lot_size

// === Prebuilt JSON Alerts ===
make_json(tx, opt_type, strike) =>
‘{“secret”:“sUmtC”,“alertType”:“multi_leg_order”,“order_legs”:[{“transactionType”:"’ + (tx == “BUY” ? “B” : “S”) + ‘“,“orderType”:“MKT”,“quantity”:”’ + str.tostring(qty) + ‘“,“exchange”:“NSE”,“symbol”:“NIFTY”,“instrument”:“OPT”,“productType”:“I”,“sort_order”:“1”,“price”:“0”,“option_type”:”’ + opt_type + ‘“,“strike_price”:”’ + str.tostring(strike, “#.0”) + ‘“,“expiry_date”:”’ + expiry_dt + ‘"}]}’

long_entry_msg = make_json(“BUY”, “CE”, ce_strike)
short_entry_msg = make_json(“BUY”, “PE”, pe_strike)
long_exit_msg = make_json(“SELL”, “CE”, ce_strike)
short_exit_msg = make_json(“SELL”, “PE”, pe_strike)

// === SL/TP Controls ===
groupSLTP = “Exit / SL / TP Controls”
use_stoch_exit = input.bool(true, “Use EMA Exit (else TP Exit)”, group=groupSLTP)
sl_pts = input.float(7.0, “Stop Loss (Pts)”, group=groupSLTP)
tp_pts = input.float(150.0, “Target Profit (Pts)”, group=groupSLTP)
trail_sl = input.float(9.0, “Trailing Stop (Pts)”, group=groupSLTP)
trail_offset = input.float(3.0, “Trailing Threshold (Pts)”, group=groupSLTP)

// === Strategy Entries with Webhook ===
if long_entry
strategy.entry(“Long”, strategy.long, alert_message=enableWebhook ? long_entry_msg : “”)
if short_entry
strategy.entry(“Short”, strategy.short, alert_message=enableWebhook ? short_entry_msg : “”)

// === EMA-based Exit
if use_stoch_exit
if long_exit
strategy.close(“Long”, comment=“EMA Exit”, alert_message=enableWebhook ? long_exit_msg : “”)
if short_exit
strategy.close(“Short”, comment=“EMA Exit”, alert_message=enableWebhook ? short_exit_msg : “”)

// === TP-based Exit
if not use_stoch_exit
tp_long = strategy.position_avg_price + tp_pts
tp_short = strategy.position_avg_price - tp_pts
strategy.exit(“TP Long”, from_entry=“Long”, limit=tp_long, alert_message=enableWebhook ? long_exit_msg : “”)
strategy.exit(“TP Short”, from_entry=“Short”, limit=tp_short, alert_message=enableWebhook ? short_exit_msg : “”)

// === SL + Trailing Exit (Always Active)
sl_long = strategy.position_avg_price - sl_pts
sl_short = strategy.position_avg_price + sl_pts
strategy.exit(“SL/Trail Long”, from_entry=“Long”, stop=sl_long, trail_points=trail_sl, trail_offset=trail_offset, alert_message=enableWebhook ? long_exit_msg : “”)
strategy.exit(“SL/Trail Short”, from_entry=“Short”, stop=sl_short, trail_points=trail_sl, trail_offset=trail_offset, alert_message=enableWebhook ? short_exit_msg : “”)

The sample code works. It has been tested. I request you to follow this step and debug at your end.

1 Like

I am trying to pull option strike dynamically close + round 100 for put and vice-versa for call .

Looks like that causing issues.

But if that is not possible then option buying can not me made fully unattended automed.

In future you can , but not in option buying.

This is possible in pine script and if you are passing the correct string to the JSON generator call in your code it should work.

1 Like

trying few methods

1 Like

@t7support you need to make a video on option buying all dynamic.

Strike Selection based on Nifty close
Quantity based on availability of funds 50%, 100% etc.

Conditional entry, exit, tp,sl, trailing sl

This will solve a lot of headache for a lot of people :folded_hands::sweat_smile:

Hi Syam, Pls help with this Log, why is this 1st and 4 row blank alert has been fired?
Also, pls take a look at entry,exit, sl and trailing sl triggers.

Alert ID Ticker Name Description Time
2517406004 NSE:NIFTY, 5m 2025-06-24T08:00:06Z
2517406004 NSE:NIFTY, 5m {“secret”:“sUmtC”,“alertType”:“multi_leg_order”,“order_legs”:[{“transactionType”:“B”,“orderType”:“MKT”,“quantity”:“1”,“exchange”:“NSE”,“symbol”:“NIFTY”,“instrument”:“OPT”,“productType”:“I”,“sort_order”:“1”,“price”:“0”,“option_type”:“PE”,“strike_price”:“25100.0”,“expiry_date”:“2025-06-26”}]} 2025-06-24T08:00:03Z
2517406004 NSE:NIFTY, 5m {“secret”:“sUmtC”,“alertType”:“multi_leg_order”,“order_legs”:[{“transactionType”:“S”,“orderType”:“MKT”,“quantity”:“1”,“exchange”:“NSE”,“symbol”:“NIFTY”,“instrument”:“OPT”,“productType”:“I”,“sort_order”:“1”,“price”:“0”,“option_type”:“CE”,“strike_price”:“25100.0”,“expiry_date”:“2025-06-26”}]} 2025-06-24T08:00:03Z
2517406004 NSE:NIFTY, 5m 2025-06-24T08:00:03Z

Here is my code

//@version=6

strategy(“s12 1 min 24June EMA Crossover Strategy with Dhan Webhook + Toggle”, overlay=true, default_qty_type=strategy.cash, default_qty_value=100000)

// === GLOBAL TOGGLE ===

enableWebhook = input.bool(true, “Enable Webhook Alerts”, inline=“tog”, group=“Automation”)

// === Date Range ===

groupDate = “Date Range”

fromDate = input.time(timestamp(“2025-06-24 09:15 +0530”), “From Date”, group=groupDate)

toDate = input.time(timestamp(“2025-12-31 15:30 +0530”), “To Date”, group=groupDate)

inDateRange = time >= fromDate and time <= toDate

// === EMA 1m ===

group1m = “EMA Crossover (1m)”

ema1_tf = input.timeframe(“1”, “Timeframe”, group=group1m)

ema1_fast_len = input.int(3, “Fast EMA Length”, group=group1m)

ema1_slow_len = input.int(21, “Slow EMA Length”, group=group1m)

src1 = input.source(open, “Source”, group=group1m)

ema1_fast = request.security(syminfo.tickerid, ema1_tf, ta.ema(src1, ema1_fast_len))

ema1_slow = request.security(syminfo.tickerid, ema1_tf, ta.ema(src1, ema1_slow_len))

// === EMA 5m ===

group5m = “EMA Crossover (5m)”

ema5_tf = input.timeframe(“5”, “Timeframe”, group=group5m)

ema5_fast_len = input.int(3, “Fast EMA Length”, group=group5m)

ema5_slow_len = input.int(21, “Slow EMA Length”, group=group5m)

src5 = input.source(open, “Source”, group=group5m)

ema5_fast = request.security(syminfo.tickerid, ema5_tf, ta.ema(src5, ema5_fast_len))

ema5_slow = request.security(syminfo.tickerid, ema5_tf, ta.ema(src5, ema5_slow_len))

// === SL/TP ===

groupSLTP = “Exit / SL / TP Controls”

use_ema_exit = input.bool(true, “Use EMA Exit (else TP Exit)”, group=groupSLTP)

sl_pts = input.float(7.0, “Stop Loss (Pts)”, group=groupSLTP)

tp_pts = input.float(150.0, “Target Profit (Pts)”, group=groupSLTP)

trail_sl = input.float(9.0, “Trailing Stop (Pts)”, group=groupSLTP)

trail_offset = input.float(3.0, “Trailing Threshold (Pts)”, group=groupSLTP)

// === Entry/Exit Logic ===

long_entry = ema5_fast > ema5_slow and ema1_fast > ema1_slow

short_entry = ema5_fast < ema5_slow and ema1_fast < ema1_slow

long_exit = ema1_fast < ema1_slow

short_exit = ema1_fast > ema1_slow

// === Strike Offset ===

Strike_offset = input.float(-100, step=100, title=“Strike Offset”, group=group5m)

// === Strike Calculation ===

round_strike(x) => math.floor(x / 100) * 100

ce_strike = round_strike(close) - Strike_offset

pe_strike = round_strike(close) + Strike_offset

// === Weekly Expiry Auto-Detect ===

get_expiry_date() =>

d = dayofweek

curr = timestamp(“GMT+5:30”, year, month, dayofmonth, 0, 0)

exp_day = d <= dayofweek.wednesday ? curr + (dayofweek.thursday - d) * 86400000 : curr + (7 - d + dayofweek.thursday) * 86400000

year_str = str.tostring(year(exp_day))

month_str = str.tostring(month(exp_day), “00”)

day_str = str.tostring(dayofmonth(exp_day), “00”)

year_str + “-” + month_str + “-” + day_str

expiry_dt = get_expiry_date()

// === Quantity & Dhan JSON ===

lot_size = 1

qty = lot_size

dhan_json(tx, symbol, qty, opt_type, strike, expiry) =>

‘{“secret”:“sUmtC”,“alertType”:“multi_leg_order”,“order_legs”:[{“transactionType”:"’ + (tx == “BUY” ? “B” : “S”) + ‘“,“orderType”:“MKT”,“quantity”:”’ + str.tostring(qty) + ‘“,“exchange”:“NSE”,“symbol”:”’ + symbol + ‘“,“instrument”:“OPT”,“productType”:“I”,“sort_order”:“1”,“price”:“0”,“option_type”:”’ + opt_type + ‘“,“strike_price”:”’ + str.tostring(strike, “#.0”) + ‘“,“expiry_date”:”’ + expiry + ‘"}]}’

send_alert(tx, opt_type, strike) =>

if enableWebhook

alert(dhan_json(tx, “NIFTY”, qty, opt_type, strike, expiry_dt), alert.freq_once_per_bar)

// === Strategy & Alerts ===

if long_entry and inDateRange

strategy.entry(“Long”, strategy.long)

send_alert(“BUY”, “CE”, ce_strike)

if short_entry and inDateRange

strategy.entry(“Short”, strategy.short)

send_alert(“BUY”, “PE”, pe_strike)

if use_ema_exit and inDateRange

if long_exit

strategy.close(“Long”, comment=“EMA Exit”)

send_alert(“SELL”, “CE”, ce_strike)

if short_exit

strategy.close(“Short”, comment=“EMA Exit”)

send_alert(“SELL”, “PE”, pe_strike)

if not use_ema_exit and inDateRange

tp_long = strategy.position_avg_price + tp_pts

tp_short = strategy.position_avg_price - tp_pts

strategy.exit(“TP Long”, from_entry=“Long”, limit=tp_long)

strategy.exit(“TP Short”, from_entry=“Short”, limit=tp_short)

if close >= tp_long

send_alert(“SELL”, “CE”, ce_strike)

if close <= tp_short

send_alert(“SELL”, “PE”, pe_strike)

if inDateRange

sl_long = strategy.position_avg_price - sl_pts

sl_short = strategy.position_avg_price + sl_pts

strategy.exit(“SL/Trail Long”, from_entry=“Long”, stop=sl_long, trail_points=trail_sl, trail_offset=trail_offset)

strategy.exit(“SL/Trail Short”, from_entry=“Short”, stop=sl_short, trail_points=trail_sl, trail_offset=trail_offset)

if close <= sl_long

send_alert(“SELL”, “CE”, ce_strike)

if close >= sl_short

send_alert(“SELL”, “PE”, pe_strike)

Please go through the sample code shared. It has strike selection based on close, target, stop loss etc.

Then keep this code as base and improvise step by step and at each incremental step check whether your modified code is working.

Kindly note that your code is a radical departure from the base code and you are doing things very differently. This needs you to put significant debug effort to get it fixed.

ok will try that,
in your sample code, I am confused about trailing SL and trailing threshold.

Something like this.

Can you share a code snippet for just this.

There is only fixed stop and target stop in the sample code. For trailing stop you can refer this link for an example

https://www.tradingcode.net/tradingview/percentage-trail/

1 Like

thankyou, will look into it.

1 Like

Now alerts are going through,
A new issue - buy sell instruments mismatch
Since I am using dynamic strike Selection, and if Market move away after say call bought 24500 then this should get exit as a sell call 24500

But for some reason it is getting sold as CE 25600 which is not matching from buy hence fail to close the trade.

Any help would be appreciated.
@Dhan @t7support

You should note the close price of the candle before the signal generation candle and then use that to choose u r strike while buying and selling.

this is resolved , now multiple entry exit are being sent to dhan for same condition met on 1 in candle chart

Anita vikas valvi