К основному содержимому

Сигнальный Бот: Полное руководство по JSON

Изучите пошаговое руководство по созданию JSON-кода для сигнального бота и получите четкое представление о работе каждой функции.

Автор: Jacob

Pine Script, представленный в данной статье, предназначен для динамического преобразования параметров стратегии в формат JSON, что позволяет легко интегрировать его с ботами WunderTrading. Скрипт дает возможность настраивать и изменять ключевые переменные торговли, такие как Take Profit, Stop Loss, Trailing Stop и другие, для каждой отдельной сделки.
Такая гибкость позволяет уникально конфигурировать каждую сделку в соответствии с ее конкретными требованиями, делая стратегию максимально адаптивной к изменяющимся рыночным условиям и индивидуальным торговым предпочтениям.
Давайте разберемся во всем шаг за шагом и изучим возможные варианты.

Как создать сигнального бота с использованием JSON

Чтобы создать сигнального бота, перейдите на вкладку Сигнальный бот в левом меню и выберите Создать бота.

После открытия окна настроек Сигнального бота вы можете настроить параметры в соответствии с вашими требованиями.

Общие настройки

  1. Начните с указания названия бота.

  2. Условие запуска бота – источник сигнала. В настоящее время JSON совместим с TradingView Indicator, API-запросами и Other – для других инструментов автоматизации, таких как Make, IFTTT, Zapier, n8n и т. д. Доступные функции зависят от источника.

    После включения JSON раздел алертов обновится. В нём будет представлена базовая рабочая стратегия, которую можно скопировать в Pine Editor на TradingView, чтобы разобраться в принципах работы кода. Рассмотрим его подробнее.

  3. Выберите биржу и соответствующий API.
    Можно выбрать до 50 API одновременно, объединенных в единую стратегию.

    Чтобы выбрать демо-аккаунт, включите режим DEMO.

  4. Выберите торговую пару из списка для каждого API либо введите её напрямую в поле поиска.
    Расширенные настройки позволяют отдельно задать кредитное плечо для каждой пары, а также API-множители. Это даёт больше гибкости при управлении несколькими API в рамках одного бота.

    Для каждого профиля API можно выбрать до 10 различных пар. Когда сигнал инициирует сделку, для каждой выбранной пары будет создана отдельная сделка.

  5. Выберите желаемый таймфрейм. Этот параметр влияет только на название комментариев в сигналах и фильтрацию списка ботов по таймфрейму. Он не влияет на таймфрейм в TradingView.

  6. Функция Множественные входы позволяет постепенно увеличивать позицию при получении нескольких последовательных сигналов на вход. Включите, если хотите одновременно иметь более одной открытой позиции по каждой торговой паре.

  7. Свинг-трейдинг позволяет менять направление сделки, используя только сигналы Enter Short и Enter Long. При включении этой функции комментарии к алертам объединяются в пять категорий: Enter-Long, Enter-Short, Exit-All, Partial Exit Long и Partial Exit Short. Функция доступна только для фьючерсных рынков.

🔵 Пример стратегии на Pine Script для TradingView

Вы можете напрямую скопировать и вставить этот код в свой TradingView PineScript, применить его к графику и посмотреть, как он работает, в качестве примера. Это базовый пример, который поможет создать собственную стратегию и интегрировать её с WunderTrading.

// 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 (ЛОГИКА СТРАТЕГИИ) и WUNDERTRADING EXECUTION (ИСПОЛНЕНИЕ WUNDERTRADING).

Раздел логики стратегии представляет ваш собственный подход к тому, как должна функционировать стратегия. Здесь вы можете определить любую стратегию или условия, которые считаете нужными. Например, вход может срабатывать при пересечении двух простых скользящих средних или когда RSI указывает на перекупленность или перепроданность.

Раздел исполнения WunderTrading фокусируется на предоставлении кода, который преобразует ваши алерты в формат JSON и отвечает за их отправку в WunderTrading.

Переменные бота для одной торговой пары, передаваемые в JSON-формате

Код комментария для входа

Поле

Обязательно

Тип

Описание

code

True

string

Код комментария для входа, передающий сигнал Enter Long или Enter Short из ваших комментариев.

Параметры входа

Поле

Обязательно

Тип

Описание

orderType

True

string

Возможные значения: "market", "limit".

amountPerTradeType

True

string

Возможные значения: "quote", "percents", "contracts", "base".

  • Для спотовых пар: "quote", "base", "percents".

  • Для деривативов: "quote", "contracts", "percents", "base".

amountPerTrade

True

num

Диапазон: (0; +Inf).

  • Если amountPerTradeType равен "percents", то значение amountPerTrade должно быть в десятичном формате (например, 10% → 0.1).

leverage

False

num

Диапазон: [1, 125].

По умолчанию: 1.

Параметры только для лимитных ордеров

Поле

Обязательно

Тип

Описание

timeInForce

False

num

Диапазон: [5, 20160].

По умолчанию: 5.

Время действия лимитного ордера в минутах (обязательно для "limit" ордеров).

price

False

num

Диапазон: (0; +Inf).

Фиксированное значение цены.

Обязательно для "limit" ордеров, если priceDeviation не задан.

priceDeviation

False

object

Настройки отклонения цены Обязательно для "limit" ордеров, если "price" не задан.

deviation

True

num

Диапазон:

  • deviationType="percents"

  • LONG: (0.001; 1)

  • SHORT: (0.001; +Inf)

Значение отклонения цены

deviationType

False

string

Возможное значение: "percents".

priceType

False

string

Возможные значения: "bid", "ask", "last".

По умолчанию: "last".

Значение типа цены, от которого следует отклоняться.

Параметры Take Profit

Поле

Обязательно

Тип

Описание

takeProfits

False

array

Массив объектов с параметрами Take Profit.

price

False

num

Диапазон: (0; +Inf).

Фиксированное значение цены (только для ботов с одной торговой парой).

priceDeviation

False

num

Диапазон:

  • LONG (0.001; +Inf)

  • SHORT (0.001; 1)

Отклонение цены в процентах (например, 10% → 0.1).
(Поле обязательно для бота с несколькими торговыми парами).

portfolio

False

num | null

Диапазон: (0; 1].

Отклонение цены в процентах (например, 10% → 0.1).
(Поле обязательно для бота с несколькими торговыми парами).

Параметры Stop Loss

Поле

Обязательно

Тип

Описание

stopLoss

False

object

Возможные значения: "price" или "priceDeviation".

price

True

num

Диапазон: (0; +Inf).

Фиксированное значение цены (для ботов с одной торговой парой).

priceDeviation

True

num

Диапазон:

  • SHORT (0.001; +Inf)

  • LONG (0.001; 1)

Отклонение цены в процентах (например, 10% → 0.1).
(Поле обязательно для бота с несколькими торговыми парами).

Перенос Stop Loss в безубыток

Поле

Обязательно

Тип

Описание

activationPrice

True

(для одной торговой пары)

num

Диапазон: (0; +Inf)

Фиксированное значение цены

executePrice

False

(для одной торговой пары)

num|null

Диапазон: (0; +Inf)
По умолчанию: null (равняется цене входа)

Строгое ценовое значение.

activationPriceDeviation

True

(для одной и нескольких торговых пар)

num

Диапазон:

  • LONG (0.001; +Inf)

  • SHORT (0.001; 1)

Отклонение цены в процентах (например, 10% → 0.1).
(Поле обязательно для бота с несколькими торговыми парами).

executePriceDeviation

True

(для одной и нескольких торговых пар)

num

Диапазон: (-1; activationPriceDeviation)

Отклонение цены в процентах (например, 10% → 0.1).
(Поле обязательно для бота с несколькими торговыми парами).

Trailing Stop

Поле

Обязательно

Тип

Описание

activation

True

num

Диапазон:

  • LONG (0.0001; +Inf)

  • SHORT (0.0001; 1)

Отклонение цены в процентах (например, 10% → 0.1).

execute

True

num

Диапазон:

  • LONG (0.0001; 1)

  • SHORT (0.0001; +Inf)

Отклонение цены в процентах (например, 10% → 0.1).

Дополнительные параметры

Поле

Обязательно

Тип

Описание

keepPositionOpen

False

bool

По умолчанию: true.

Оставлять позицию открытой (влияет только на спотовые стратегии без Take Profit, Stop Loss, Move to Breakeven, Trailing Stop).

reduceOnly

False

bool

По умолчанию: true.

Уменьшать позиции только при выходе.
(Не влияет на спотовые стратегии.)

placeConditionalOrdersOnExchange

False

bool

По умолчанию: false.

Размещение условных ордеров на бирже (частично поддерживается, игнорируется, если включен DCA).

Параметры DCA

Поле

Обязательно

Тип

Описание

dca

False

object

Параметры усреднения (DCA).

extraOrderCount

True

num

Диапазон: [1; 30].

Сумма ордеров входа, включая первоначальный ордер и дополнительные DCA-ордера (например, 5 означает 1 вход + 4 DCA ордера).

extraOrderDeviation

True

num

Диапазон: [0.001; 0.2].

Отклонение цены для DCA ордеров.

extraOrderVolumeMultiplier

True

num

Диапазон: [1; 10].

Множитель объема для дополнительных DCA ордеров.

extraOrderDeviationMultiplier

False

num

Диапазон: [1; 10].

По умолчанию: null. Множитель отклонения цены для DCA ордеров.

takeProfitsBasedOn

False

string

Возможные значения: "average_price", "entry_order".

По умолчанию: "average_price".

Основа для расчета Take Profit.

stopLossBasedOn

False

string

Возможные значения: "average_price", "entry_order". По умолчанию: "entry_order".

Основа для расчета Stop Loss.

Как создать алерт в TradingView

Сначала обновите стратегию, нажав кнопку "Update on chart", затем создайте алерт, нажав кнопку "Alert".

Теперь настроим алерт:

  1. Выбор стратегии – В выпадающем списке Condition выберите свою стратегию.

  2. Включение вызовов функций алертов – Выберите "alert() function calls only", чтобы алерты срабатывали на основе условий скрипта.

  3. Переход во вкладку "Notifications" – Откройте раздел "Notifications".

  4. Вставка Webhook URL – Вставьте Webhook URL из WunderTrading.

  5. Создание алерта – Нажмите "Create", чтобы завершить настройку и автоматизировать исполнение сделок.

Вот и все! Теперь остается дождаться входного сигнала и проверить, все ли работает корректно. Для этого перейдите в список сигнальных ботов и нажмите кнопку "Logs" у нужного бота. Здесь вы сможете увидеть, был ли успешно выполнен алерт без ошибок. Затем откройте вкладку "Positions", чтобы просмотреть открытую позицию.

Подтверждение настройки бота

После настройки алертов вы увидите экран подтверждения, указывающий на то, что ваш бот успешно настроен. На этом этапе бот будет ожидать поступления сигнала для автоматического открытия позиции.

Если вы предпочитаете войти в позицию немедленно, нажмите "Enter Position Now", где вы можете выбрать между длинной или короткой сделкой, связанной с этим ботом.

Вы можете в любой момент изменить настройки бота или проверить сообщения алертов в личном кабинете.

Нашли ответ на свой вопрос?