This Pine Script that will be provided in this article is designed to dynamically transform strategy parameters into a JSON format, enabling seamless integration with Wundertrading bots. The script allows you to customize and adjust key trading variables such as Take Profit, Stop Loss, Trailing Stop, and more for each individual trade. This flexibility ensures that every trade can be uniquely configured based on its specific requirements, making the strategy highly adaptable to changing market conditions and tailored trading preferences. Let's move step by step and explore the possibilities.
How to create Signal Bot using JSON
To begin setting up a Signal bot, navigate to the Signal bot tab on the left-hand side and select Create bot.
After opening the Signal bot settings window, you can start tailoring the settings to meet your specific needs.
General
1. Begin by configuring the bot's Name and Description.
2. Choose the Exchange and corresponding API.
You can choose up to 50 APIs simultaneously, all consolidated under a single strategy. To view the details, simply expand the strategy by clicking on the row.
3. Find your pair from the list or simply write it down in the search field.
You can choose up to 10 pairs, meaning that when an alert triggers a trade, a separate trade will be created for each selected pair.
4. Choose your desired Timeframe. This setting only changes the name of the Alert comments and allows you to filter your bots by Timeframes within your Signal bot list. It functions independently of the TradingView timeframe.
5. The Multiple entries option lets you scale into a position when you receive consecutive entry signals. Enable this setting if you wish to hold more than one open position per pair simultaneously.
6. The Swing trade feature enables switching trade directions using only Enter Short and Enter Long signals. When activated, it simplifies the Alert comments into three categories: Enter-Long, Enter-Short, and Exit-All. Please note that the Swing trade functionality is only available for Futures markets.
Entries
In the entries section of the form, you need to select the Source: TradingView and Bot settings format: JSON
When you switch your bot settings format to JSON, the alerts section on the right-hand side will update. This section provides a basic working strategy that can be copied into the TradingView Pine Editor to understand how the code functions. Let’s explore the code in detail.
The code has two main sections: STRATEGY LOGIC and WUNDERTRDAING EXECUTION
🔵 Strategy Example in Pine Script for TradingView
🔵 Strategy Example in Pine Script for TradingView
You can directly copy and paste this code into your TradingView PineScript, apply it to the chart, and observe how it functions as an example.
// This Pine Script™ code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © WunderTrading
//@version=6
strategy('Test Strategy', overlay = true, margin_long=0, margin_short=0)//, initial_capital = 10000, default_qty_type = strategy.fixed) //, commission_type = strategy.commission.percent, commission_value = 0.075)
// ――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――}
// 🔵 STRATEGY LOGIC
// ――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――{
// Inputs
capital = input.int(title = 'Capital $', defval = 1000, step = 1, minval=1, maxval=1000000, group="Risk and Money Management")
risk_per_trade = input.float(title = 'Risk per trade', defval = 2.0, step = 0.1,group="Risk and Money Management")
riskReward = input.float(title = 'Risk:Reward', defval = 1.0, step = 0.1, group="Risk and Money Management")
// Backtest period
testStartYear = input(2025, "Backtest Start Year", group="Backtest Starting period")
testStartMonth = input(1, "Backtest Start Month",group="Backtest Starting period")
testStartDay = input(26, "Backtest Start Day",group="Backtest Starting period")
testPeriodStart = timestamp(testStartYear,testStartMonth,testStartDay,0,0)
testPeriod() =>
time >= testPeriodStart
// Variables to store the value of the price when the condition will be met
var entry_price = 0.0
var stop = 0.0
var take1 = 0.0
var entry_amount = 0.0
longCondition = close > open[1]
// Logic of trade execution
if testPeriod()
if longCondition and strategy.position_size == 0 or (strategy.position_size == 0)[1]
entry_price := open
long_stop_prc = (entry_price - low[1]) / entry_price
long_stop_price = entry_price - (entry_price - low[1])
long_tp1_prc = long_stop_prc * riskReward
long_tp1_price = entry_price * (1 + (long_stop_prc * riskReward))
stop := long_stop_price
take1 := long_tp1_price
entry_amount := math.round(math.abs((capital * (risk_per_trade/100)) / long_stop_prc))
if longCondition and strategy.position_size ==0
strategy.entry('Long', strategy.long, qty = entry_amount )
if strategy.position_size > 0
strategy.exit(id = 'Long', from_entry = 'Long', limit = take1, stop=stop)
// Visual representation of your strategy
plot(strategy.position_size > 0 ? stop : na, style = plot.style_linebr, color = color.red, title = 'SL Long')
plot(strategy.position_size > 0 ? take1 : na, style = plot.style_linebr, color = color.green, title = 'TP1 Long')
// ――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――}
// 🔵 WUNDERTRADING EXECUTION
// ――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――{
// Comment inputs
enter_Long_Comment = input.string(defval = "CHANGE-THIS-ENTER-LONG-COMMENT", tooltip = "Your personal Enter signal from WunderTrading bot settings", group="Comment to WunderTrading Bot")
exit_Long_Comment = input.string(defval = "CHANGE-THIS-EXIT-LONG-COMMENT", tooltip = "Your personal Enter signal from WunderTrading bot settings", group="Comment to WunderTrading Bot")
enter_Short_Comment = input.string(defval = "CHANGE-THIS-ENTER-SHORT-COMMENT", tooltip = "Your personal Enter signal from WunderTrading bot settings", group="Comment to WunderTrading Bot")
exit_Short_Comment = input.string(defval = "CHANGE-THIS-EXIT-SHORT-COMMENT", tooltip = "Your personal Enter signal from WunderTrading bot settings", group="Comment to WunderTrading Bot")
exit_All_Comment = input.string(defval = "CHANGE-THIS-EXIT-ALL-COMMENT", tooltip = "Your personal Enter signal from WunderTrading bot settings", group="Comment to WunderTrading Bot")
// json custom alerts signal bot ----------------------------------------------------------------------------------------
// str : str
styleToJson(name, value) =>
'"' + str.tostring(name) + '"' + ': ' + '"' + str.tostring(value) + '"'
// str : int
styleToJson_num(name, value) =>
'"' + str.tostring(name) + '"' + ': ' + (na(value) ? '"NaN"' : str.tostring(value))
styleToJson_takeProfits(priceDeviation, portfolio) =>
'{' + styleToJson_num("price", priceDeviation) + ',' + styleToJson_num("portfolio", portfolio) + '}'
conditions_for_signal(comment) =>
alert_text = array.new_string()
// SETTINGS PARAMS
// Entry cooment code
entry_comment = '"code": ' + '"' + str.tostring(comment) + '"'
array.push(alert_text, entry_comment)
// Entry Parameters
order_type = styleToJson("orderType", "market")
amount_per_trade_type = styleToJson("amountPerTradeType", "quote")
amount_per_trade = styleToJson_num("amountPerTrade", entry_amount)
leverage = styleToJson_num("leverage", 1)
array.push(alert_text, order_type)
array.push(alert_text, amount_per_trade_type)
array.push(alert_text, amount_per_trade)
array.push(alert_text, leverage)
// Parameters for Limit Orders Only
// time_in_force = styleToJson_num("timeInForce", 1)
// price_deviation = '"priceDeviation": {' +
// styleToJson_num("deviation", 0.01) + ',' +
// styleToJson("deviationType", "percents") + ',' +
// styleToJson("priceType", "last") + '}'
// array.push(alert_text, time_in_force)
// array.push(alert_text, price_deviation)
// Take Profit
take_profits = '"takeProfits": [' +
// styleToJson_takeProfits(take1, 0.5) + ',' +
styleToJson_takeProfits(take1, 1) + ']'
array.push(alert_text, take_profits)
// Stop Loss
stop_loss = '"stopLoss": {' + styleToJson_num("price", stop) + '}'
array.push(alert_text, stop_loss)
// Move Stop Loss to breakeven
// move_to_breakeven = '"moveToBreakeven": {' + styleToJson_num("activationPriceDeviation", 0.05) + '}'
// array.push(alert_text, move_to_breakeven)
// Trailing Stop
// trailing_stop = '"trailingStop": {' +
// styleToJson_num("activation", 0.05) + ',' +
// styleToJson_num("execute", 0.005) + '}'
// array.push(alert_text, trailing_stop)
// Additional Parameters
// keep_position_open = styleToJson("keepPositionOpen", true)
reduce_only = styleToJson("reduceOnly", true)
place_conditional_orders = styleToJson("placeConditionalOrdersOnExchange", false)
// array.push(alert_text, keep_position_open)
array.push(alert_text, reduce_only)
array.push(alert_text, place_conditional_orders)
// DCA Parameters
// dca = '"dca": {' +
// styleToJson_num("extraOrderCount", 10) + ',' +
// styleToJson_num("extraOrderDeviation", 0.005) + ',' +
// styleToJson_num("extraOrderVolumeMultiplier", 1.1) + ',' +
// styleToJson_num("extraOrderDeviationMultiplier", 1.1) + ',' +
// styleToJson("takeProfitsBasedOn", "average_price") + ',' +
// styleToJson("stopLossBasedOn", "average_price") + '}'
// array.push(alert_text, dca)
// Pass Parameters
messageJson = "{" + array.join(alert_text, ', ') + "}"
//
// ALERT SIGNALS
signal_alert_long = conditions_for_signal(enter_Long_Comment)
signal_alert_short = conditions_for_signal(enter_Short_Comment)
signal_aler_exit_long = conditions_for_signal(exit_Long_Comment)
signal_aler_exit_short = conditions_for_signal(exit_Short_Comment)
signal_aler_exit_all = conditions_for_signal(exit_All_Comment)
if longCondition and strategy.position_size == 0
alert(signal_alert_long, alert.freq_once_per_bar_close)
Strategy logic section represents your custom approach to how the strategy should function. Here, you can define any strategy or conditions you envision. For instance, an entry could be triggered when two Simple Moving Averages cross, or when the RSI indicates overbought or oversold levels.
WunderTrading Execution section focuses on providing you with the code that will transform your alerts into the JSON type and is responsible for sending it to WunderTrading.
Single Pair Bot variables that you can pass in JSON format
Entry comment code
Field | Required | Type | Comments |
code | True | string | This is the entry comment code that will pass either the Enter Long or Enter Short signal from your comments. |
Entry Parameters
Field | Required | Type | Comments |
orderType | True | string | Possible value: "market", "limit" |
amountPerTradeType | True | string | Possible value: "quote", "percents", "contracts"
|
amountPerTrade | True | num | Range: (0; +Inf)
|
leverage | False | num | Range: [1, 125] Default: 1 |
Parameters for Limit Orders Only
Field | Required | Type | Comments |
timeInForce | False | num | Range: [5, 5000] Default: 5
Limit order time in force value in minutes. (Mandatory for `limit` order) |
price | False | num | Range: (0; +Inf) Strict price value. Mandatory for `limit` order when `priceDeviation` is not defined) |
priceDeviation | False | object | Price deviation settings. Mandatory for `limit` order when `price` is not defined |
deviation | True | num
| Range:
Price deviation value |
deviationType | False | string | Possible value: "percents" |
priceType | False | string
| Possible value: "bid", “ask”, “last” Default: “last”
Price type value from which to deviate |
Take Profit Parameters
Field | Required | Type | Comments |
takeProfits | False | array | Array Values type: object |
price | False | num | Range: (0; +Inf)
Strict price value. (Only for single pair bots)
|
priceDeviation | False
| num | Range:
Price deviation value in `percents ratio` (10% -> 0.1 `percents ratio`)'. (Cannot be empty for multiple pairs bot)
|
portfolio | False | num|null | Range: (0; 1]
Price deviation value in `percents ratio` (10% -> 0.1 `percents ratio`)'. (Cannot be empty for multiple pairs bot)
|
Stop Loss Parameters
Field | Required | Type | Comments |
stopLoss | False | object | Possible value: "price" or "priceDeviation" |
price | True | num | Range: (0; +Inf)
Strict price value. (Only for single pair bots)
|
priceDeviation | True
| num | Range:
Price deviation value in `percents ratio` (10% -> 0.1 `percents ratio`)'. (Cannot be empty for multiple pairs bot)
|
Move Stop Loss to breakeven
Field | Required | Type | Comments |
activationPrice | True
(for single pair)
| num | Range: (0; +Inf)
Strict price value. (Only for single pair bots)
|
activationPriceDeviation | True
(for multiple pair)
| num | Range:
Price deviation value in `percents ratio` (10% -> 0.1 `percents ratio`)'. (Cannot be empty for multiple pairs bot)
|
Trailing Stop
Field | Required | Type | Comments |
activation
| True | num | Range:
Price deviation value in `percents ratio` (10% -> 0.1 `percents ratio`)'.
|
execute | True | num | Range:
Price deviation value in `percents ratio` (10% -> 0.1 `percents ratio`)'.
|
Additional Parameters
Field | Required | Type | Comments |
keepPositionOpen | False | bool | Default: true
Keep my position open. (Effects only spot strategies with empty `takeProfits`, `stopLoss`, `moveToBreakeven`, `trailingStop`) |
reduceOnly | False | bool | Default: true
Reduce only for exits. (No effect for spot strategies) |
placeConditionalOrdersOnExchange | False | bool | Default: false
Place exit conditional orders on exchange. (Partially supported, ignored when DCA is enabled) |
DCA Parameters
Field | Required | Type | Comments |
dca | False | object |
|
extraOrderCount
| True | num | Range: [1; 30]
Entry order + extra DCA orders count sum. (In example value 5 means 1 entry order + 4 extra DCA orders) |
extraOrderDeviation
| True | num | Range: [0.001; 0.2]
Extra DCA order price deviation |
extraOrderVolumeMultiplier | True | num | Range: [1; 10]
Extra DCA order volume multiplier |
extraOrderDeviationMultiplier | False | num | When number: Range: [1; 10] Default: null
Extra DCA order price deviation multiplier |
takeProfitsBasedOn | False | string | Possible value: "average_price", "entry_order" Default: “average_price”
Take profits price based on specified condition |
stopLossBasedOn | False | string | Possible value: "average_price", "entry_order" Default: “entry_order”
Stop loss price based on specified condition |
How to create an alert in TradingView
First, update the strategy by clicking the button "Update on chart", and then Create the Alert by clicking the button "Alert".
Now let's set up the alert:
Select Strategy – Choose your strategy from the Condition dropdown.
Enable Alert Function Calls – Select "alert() function calls only" to trigger alerts based on script conditions.
Go to Notifications Tab – Navigate to the Notifications section.
Paste Webhook URL – Insert the Webhook URL from WunderTrading.
Click Create – Finalize the alert to automate trade execution.
That's it, wait for the entry alert and check if it all worked well. You can do that by going to the Signal bots list and click on the "logs" button of the specific signal bot you created, you will see if the alert was executed well without any errors. Finally, go to positions tab to see the opened position.
Bot Setup Confirmation
Once your bot alerts are set up, you will see a confirmation screen indicating that your bot has been successfully configured. At this stage, the bot will wait for an alert to trigger and open a position automatically.
If you prefer to enter a position immediately, click "Enter Position Now", where you can choose between a long or short trade linked to this bot.
You can edit bot settings anytime or check alert messages in your dashboard.