Skip to content

Справочник торговых команд

Все команды отправляются одним endpoint:

http
POST /api/v1/signals

Меняются поля platform, instanceId, type, cmd и payload. Endpoint требует Public API key со scope signals:write. Формат envelope, идемпотентность и ответ 202 Accepted подробно описаны в разделе Сигналы и статус исполнения.

Два уровня валидации

Backend проверяет envelope (v, signalId, ts, ttlMs, platform, type, cmd, payload), но не проверяет terminal-specific содержимое payload. Поэтому синтаксически корректный запрос может получить 202 Accepted, а затем быть отклонён terminal plugin. Окончательный результат всегда проверяйте через GET /api/v1/signals/{requestId}.

Матрица поддержки

Команда или возможностьNinjaTrader 8MetaTrader 5
system.pauseдада
system.resumeдада
system.infoдада
order.submit / marketдада
order.submit / limitдада
order.submit / stopдада
order.submit / stop_limitданет, terminal вернёт unsupported_execution_type
stopLoss, takeProfit как абсолютные ценыдада
stopLossTicks, takeProfitTicksдада
position.closeдада
position.reduceдада
position.protectдада
position.close_allдада
position.flatten_nowдада
risk.block_instrumentдада
risk.allow_instrumentдада
risk.flatten_nowдада

Для platform-specific команд не используйте platform=any: например, stop_limit будет направлен также в MT5 и завершится там отказом unsupported_execution_type.

atmStrategyName и другие неописанные дополнительные поля могут проходить через backend без HTTP-ошибки, но текущие tracked terminal plugins не обязаны их использовать. Они не входят в гарантированный Public API contract.

Общие вспомогательные функции

Следующие функции формируют актуальные ts, signalId и Idempotency-Key. Выполните подходящий helper один раз, затем используйте короткие вызовы из разделов ниже.

curl

Для helper нужны curl, jq и uuidgen. Переменная TMPRO_INSTANCE_ID может быть пустой: тогда поле instanceId не добавляется в signal body.

bash
export TMPRO_API_KEY='tmpro_api_REPLACE_ME'
export TMPRO_PLATFORM='ninjatrader'
export TMPRO_INSTANCE_ID='VPS-NT8-01'

send_signal() {
  local type="$1"
  local cmd="$2"
  local payload="$3"
  local ts
  local signal_id
  local idempotency_key
  local body

  ts=$(date +%s%3N)
  signal_id="api-$(uuidgen)"
  idempotency_key=$(uuidgen)

  body=$(
    jq -cn \
      --arg signalId "$signal_id" \
      --argjson ts "$ts" \
      --arg platform "$TMPRO_PLATFORM" \
      --arg instanceId "$TMPRO_INSTANCE_ID" \
      --arg type "$type" \
      --arg cmd "$cmd" \
      --argjson payload "$payload" \
      '{
        v: 1,
        signalId: $signalId,
        ts: $ts,
        ttlMs: 15000,
        platform: $platform,
        type: $type,
        cmd: $cmd,
        payload: $payload
      } + (
        if $instanceId == ""
        then {}
        else {instanceId: $instanceId}
        end
      )'
  )

  curl --request POST 'https://tradingmonitor.pro/api/v1/signals' \
    --header "Authorization: Bearer $TMPRO_API_KEY" \
    --header 'Content-Type: application/json' \
    --header "Idempotency-Key: $idempotency_key" \
    --data-binary "$body"
}

C#

csharp
using System.Net.Http.Headers;
using System.Net.Http.Json;

static async Task<string> SendSignalAsync(
    HttpClient http,
    string type,
    string cmd,
    object payload,
    string platform = "ninjatrader",
    string? instanceId = "VPS-NT8-01",
    CancellationToken cancellationToken = default)
{
    var body = new Dictionary<string, object?>
    {
        ["v"] = 1,
        ["signalId"] = $"api-{Guid.NewGuid():N}",
        ["ts"] = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(),
        ["ttlMs"] = 15_000,
        ["platform"] = platform,
        ["type"] = type,
        ["cmd"] = cmd,
        ["payload"] = payload
    };

    if (!string.IsNullOrWhiteSpace(instanceId))
    {
        body["instanceId"] = instanceId;
    }

    using var request = new HttpRequestMessage(HttpMethod.Post, "/api/v1/signals")
    {
        Content = JsonContent.Create(body)
    };
    request.Headers.Add("Idempotency-Key", Guid.NewGuid().ToString());

    using var response = await http.SendAsync(request, cancellationToken);
    var responseBody = await response.Content.ReadAsStringAsync(cancellationToken);
    Console.WriteLine($"{(int)response.StatusCode} {responseBody}");
    response.EnsureSuccessStatusCode();
    return responseBody;
}

using var http = new HttpClient
{
    BaseAddress = new Uri("https://tradingmonitor.pro")
};
http.DefaultRequestHeaders.Authorization =
    new AuthenticationHeaderValue("Bearer", "tmpro_api_REPLACE_ME");

Python

python
import time
import uuid

import requests

API_KEY = "tmpro_api_REPLACE_ME"


def send_signal(
    type_,
    cmd,
    payload,
    platform="ninjatrader",
    instance_id="VPS-NT8-01",
):
    body = {
        "v": 1,
        "signalId": f"api-{uuid.uuid4().hex}",
        "ts": int(time.time() * 1000),
        "ttlMs": 15_000,
        "platform": platform,
        "type": type_,
        "cmd": cmd,
        "payload": payload,
    }
    if instance_id:
        body["instanceId"] = instance_id

    response = requests.post(
        "https://tradingmonitor.pro/api/v1/signals",
        headers={
            "Authorization": f"Bearer {API_KEY}",
            "Idempotency-Key": str(uuid.uuid4()),
        },
        json=body,
        timeout=30,
    )
    print(response.status_code, response.text)
    response.raise_for_status()
    return response.json()

system.pause

Временно переводит выбранный terminal instance в paused state. Новые входы и обычные live-команды блокируются локально. Уже выставленные broker orders автоматически не отменяются, а открытые позиции не закрываются.

Payload:

json
{}
bash
send_signal system pause '{}'
csharp
await SendSignalAsync(http, "system", "pause", new { });
python
send_signal("system", "pause", {})

system.resume

Снимает локальный paused state и разрешает дальнейшее исполнение команд.

bash
send_signal system resume '{}'
csharp
await SendSignalAsync(http, "system", "resume", new { });
python
send_signal("system", "resume", {})

system.info

Показывает информационное сообщение в NinjaTrader 8 или MetaTrader 5. В NinjaTrader открывается окно TMPro; в MT5 сообщение выводится средствами plugin. Передавайте payload.info, блок рыночных данных или оба значения.

ПолеТипОписание
infostringтекст сообщения
DOHLCV.Dstringдата или метка периода
DOHLCV.Onumberopen
DOHLCV.Hnumberhigh
DOHLCV.Lnumberlow
DOHLCV.Cnumberclose
DOHLCV.Vnumbervolume

NinjaTrader также принимает legacy-блок OHLC с полями O, H, L, C. Имена DOHLCV и OHLC передавайте именно в верхнем регистре.

bash
TMPRO_PLATFORM='ninjatrader' TMPRO_INSTANCE_ID='VPS-NT8-01' \
  send_signal system info '{
    "info": "Проверка сигнала перед публикацией NFP",
    "DOHLCV": {
      "D": "2026-07-16",
      "O": 6300.25,
      "H": 6312.00,
      "L": 6294.50,
      "C": 6308.75,
      "V": 182450
    }
  }'
csharp
await SendSignalAsync(
    http,
    "system",
    "info",
    new
    {
        info = "Проверка сигнала перед публикацией NFP",
        DOHLCV = new
        {
            D = "2026-07-16",
            O = 6300.25,
            H = 6312.00,
            L = 6294.50,
            C = 6308.75,
            V = 182450
        }
    },
    platform: "ninjatrader",
    instanceId: "VPS-NT8-01");
python
send_signal(
    "system",
    "info",
    {
        "info": "Проверка сигнала перед публикацией NFP",
        "DOHLCV": {
            "D": "2026-07-16",
            "O": 6300.25,
            "H": 6312.00,
            "L": 6294.50,
            "C": 6308.75,
            "V": 182450,
        },
    },
    platform="ninjatrader",
    instance_id="VPS-NT8-01",
)

order.submit

Создаёт новый entry order. Только для этой команды backend формирует executions[].orderRef, который затем можно использовать для точной отмены.

Общие поля payload

ПолеТипОбязательноеОписание
instrumentstringдаточное имя инструмента в целевом terminal
sidestringдаbuy или sell
executionTypestringдаmarket, limit, stop, stop_limit
quantitynumberдазначение больше нуля до применения terminal multiplier
limitPricenumberзависит от типаобязательно для limit и stop_limit
stopPricenumberзависит от типаобязательно для stop и stop_limit
stopLossnumberнетабсолютная цена stop loss
takeProfitnumberнетабсолютная цена take profit
stopLossTicksnumberнетрасстояние stop loss в ticks/points terminal symbol
takeProfitTicksnumberнетрасстояние take profit в ticks/points terminal symbol

В NinjaTrader итоговый размер — quantity * QuantityMultiplier, нормализованный до количества contracts. В MT5 итоговый объём — quantity * Volume Multiplier, нормализованный по SYMBOL_VOLUME_MIN, SYMBOL_VOLUME_MAX и SYMBOL_VOLUME_STEP.

Если одновременно переданы абсолютная цена и tick-based значение одной защиты, оба terminal plugin используют абсолютную цену. В NinjaTrader расстояние рассчитывается от фактической Position.AveragePrice как ticks * TickSize, после чего цена округляется к tick size инструмента.

Market order

Market order не требует limitPrice или stopPrice.

bash
send_signal order submit '{
  "instrument": "ES 09-26",
  "side": "buy",
  "executionType": "market",
  "quantity": 1,
  "stopLoss": 6280.25,
  "takeProfit": 6310.25
}'
csharp
await SendSignalAsync(http, "order", "submit", new
{
    instrument = "ES 09-26",
    side = "buy",
    executionType = "market",
    quantity = 1,
    stopLoss = 6280.25,
    takeProfit = 6310.25
});
python
send_signal(
    "order",
    "submit",
    {
        "instrument": "ES 09-26",
        "side": "buy",
        "executionType": "market",
        "quantity": 1,
        "stopLoss": 6280.25,
        "takeProfit": 6310.25,
    },
)

Для MT5 symbol обычно имеет broker-specific имя, например EURUSD, EURUSD.a или XAUUSDm.

Limit order

limitPrice обязателен и должен быть допустим для выбранного symbol, side и текущего рынка.

bash
send_signal order submit '{
  "instrument": "NQ 09-26",
  "side": "buy",
  "executionType": "limit",
  "quantity": 1,
  "limitPrice": 23100.25
}'
csharp
await SendSignalAsync(http, "order", "submit", new
{
    instrument = "NQ 09-26",
    side = "buy",
    executionType = "limit",
    quantity = 1,
    limitPrice = 23100.25
});
python
send_signal(
    "order",
    "submit",
    {
        "instrument": "NQ 09-26",
        "side": "buy",
        "executionType": "limit",
        "quantity": 1,
        "limitPrice": 23100.25,
    },
)

Stop order

stopPrice задаёт trigger price.

bash
send_signal order submit '{
  "instrument": "NQ 09-26",
  "side": "buy",
  "executionType": "stop",
  "quantity": 1,
  "stopPrice": 23250.00
}'
csharp
await SendSignalAsync(http, "order", "submit", new
{
    instrument = "NQ 09-26",
    side = "buy",
    executionType = "stop",
    quantity = 1,
    stopPrice = 23250.00
});
python
send_signal(
    "order",
    "submit",
    {
        "instrument": "NQ 09-26",
        "side": "buy",
        "executionType": "stop",
        "quantity": 1,
        "stopPrice": 23250.00,
    },
)

Stop-limit order — только NinjaTrader 8

Требуются одновременно stopPrice и limitPrice. MT5 connector принимает общий JSON, но текущий MT5 Expert Advisor отклоняет live execution со status rejected и reasonCode=unsupported_execution_type.

bash
TMPRO_PLATFORM='ninjatrader' send_signal order submit '{
  "instrument": "NQ 09-26",
  "side": "sell",
  "executionType": "stop_limit",
  "quantity": 1,
  "stopPrice": 22990.00,
  "limitPrice": 22988.00
}'
csharp
await SendSignalAsync(
    http,
    "order",
    "submit",
    new
    {
        instrument = "NQ 09-26",
        side = "sell",
        executionType = "stop_limit",
        quantity = 1,
        stopPrice = 22990.00,
        limitPrice = 22988.00
    },
    platform: "ninjatrader",
    instanceId: "VPS-NT8-01");
python
send_signal(
    "order",
    "submit",
    {
        "instrument": "NQ 09-26",
        "side": "sell",
        "executionType": "stop_limit",
        "quantity": 1,
        "stopPrice": 22990.00,
        "limitPrice": 22988.00,
    },
    platform="ninjatrader",
    instance_id="VPS-NT8-01",
)

Protection в ticks

Для обоих terminal можно задать расстояния вместо абсолютных цен. В NinjaTrader защита применяется после появления позиции и рассчитывается от её фактической средней цены. В MT5 для pending order расстояние рассчитывается от entry price, а для market order — от фактической цены открытия.

bash
TMPRO_PLATFORM='mt5' TMPRO_INSTANCE_ID='MT5-DEMO-01' \
  send_signal order submit '{
    "instrument": "EURUSD",
    "side": "buy",
    "executionType": "market",
    "quantity": 0.10,
    "stopLossTicks": 200,
    "takeProfitTicks": 300
  }'
csharp
await SendSignalAsync(
    http,
    "order",
    "submit",
    new
    {
        instrument = "EURUSD",
        side = "buy",
        executionType = "market",
        quantity = 0.10,
        stopLossTicks = 200,
        takeProfitTicks = 300
    },
    platform: "mt5",
    instanceId: "MT5-DEMO-01");
python
send_signal(
    "order",
    "submit",
    {
        "instrument": "EURUSD",
        "side": "buy",
        "executionType": "market",
        "quantity": 0.10,
        "stopLossTicks": 200,
        "takeProfitTicks": 300,
    },
    platform="mt5",
    instance_id="MT5-DEMO-01",
)

position.close

Закрывает открытую позицию указанного инструмента. Команда не отменяет независимые pending orders этого инструмента; для одновременной отмены orders и закрытия position используйте position.flatten_now.

В MT5 статус terminal_completed отправляется только после подтверждения, что целевая позиция фактически отсутствует.

bash
send_signal position close '{"instrument":"ES 09-26"}'
csharp
await SendSignalAsync(
    http,
    "position",
    "close",
    new { instrument = "ES 09-26" });
python
send_signal("position", "close", {"instrument": "ES 09-26"})

position.reduce

Уменьшает текущую позицию на quantity до применения terminal multiplier. Если нормализованный объём не меньше текущего объёма позиции, terminal выполняет полное закрытие.

В MT5 операция завершается только после подтверждения уменьшенного фактического объёма.

bash
send_signal position reduce '{
  "instrument": "ES 09-26",
  "quantity": 1
}'
csharp
await SendSignalAsync(http, "position", "reduce", new
{
    instrument = "ES 09-26",
    quantity = 1
});
python
send_signal(
    "position",
    "reduce",
    {"instrument": "ES 09-26", "quantity": 1},
)

position.protect

Устанавливает или заменяет защиту открытой позиции. Требуется хотя бы одно поле stop loss или take profit.

ПоляNinjaTrader 8MetaTrader 5
stopLoss, takeProfitдада
stopLossTicks, takeProfitTicksдада

NinjaTrader создаёт protective orders для текущего размера позиции; tick-based цены рассчитываются от Position.AveragePrice. MT5 изменяет фактические SL/TP позиции. Если одновременно указаны абсолютное и tick-based значения одной защиты, используется абсолютная цена.

bash
send_signal position protect '{
  "instrument": "ES 09-26",
  "stopLoss": 6280.25,
  "takeProfit": 6310.25
}'
csharp
await SendSignalAsync(http, "position", "protect", new
{
    instrument = "ES 09-26",
    stopLoss = 6280.25,
    takeProfit = 6310.25
});
python
send_signal(
    "position",
    "protect",
    {
        "instrument": "ES 09-26",
        "stopLoss": 6280.25,
        "takeProfit": 6310.25,
    },
)

Вариант в ticks:

bash
TMPRO_PLATFORM='mt5' TMPRO_INSTANCE_ID='MT5-DEMO-01' \
  send_signal position protect '{
    "instrument": "EURUSD",
    "stopLossTicks": 150,
    "takeProfitTicks": 250
  }'
csharp
await SendSignalAsync(
    http,
    "position",
    "protect",
    new
    {
        instrument = "EURUSD",
        stopLossTicks = 150,
        takeProfitTicks = 250
    },
    platform: "mt5",
    instanceId: "MT5-DEMO-01");
python
send_signal(
    "position",
    "protect",
    {
        "instrument": "EURUSD",
        "stopLossTicks": 150,
        "takeProfitTicks": 250,
    },
    platform="mt5",
    instance_id="MT5-DEMO-01",
)

position.close_all

Закрывает все открытые позиции account, обслуживаемого выбранным terminal instance. Команда не является cancel-all для pending orders.

Payload пустой. В MT5 успешный итог подтверждается только после отсутствия всех захваченных целевых positions.

bash
send_signal position close_all '{}'
csharp
await SendSignalAsync(http, "position", "close_all", new { });
python
send_signal("position", "close_all", {})

position.flatten_now

Для одного instrument отменяет working/pending orders и закрывает открытую позицию. Используйте эту команду, когда нужно полностью убрать market exposure и ожидающие входы только по одному инструменту.

MT5 завершает operation после подтверждения отсутствия целевой позиции и целевых pending orders.

bash
send_signal position flatten_now '{"instrument":"ES 09-26"}'
csharp
await SendSignalAsync(
    http,
    "position",
    "flatten_now",
    new { instrument = "ES 09-26" });
python
send_signal(
    "position",
    "flatten_now",
    {"instrument": "ES 09-26"},
)

risk.block_instrument

Локально блокирует новые entry orders для указанного инструмента в выбранном terminal instance. Существующие orders и positions команда не изменяет.

Блокировка является локальным runtime state plugin и не должна рассматриваться как broker-side risk rule.

bash
send_signal risk block_instrument '{"instrument":"ES 09-26"}'
csharp
await SendSignalAsync(
    http,
    "risk",
    "block_instrument",
    new { instrument = "ES 09-26" });
python
send_signal(
    "risk",
    "block_instrument",
    {"instrument": "ES 09-26"},
)

risk.allow_instrument

Снимает локальную блокировку, созданную risk.block_instrument.

bash
send_signal risk allow_instrument '{"instrument":"ES 09-26"}'
csharp
await SendSignalAsync(
    http,
    "risk",
    "allow_instrument",
    new { instrument = "ES 09-26" });
python
send_signal(
    "risk",
    "allow_instrument",
    {"instrument": "ES 09-26"},
)

risk.flatten_now

Аварийная account-wide команда:

  1. переводит terminal plugin в paused state;
  2. отменяет working/pending orders account;
  3. отправляет закрытие всех открытых positions;
  4. требует последующего system.resume, если нужно продолжить обработку новых entry commands.

В MT5 terminal_completed отправляется только после подтверждения, что positions закрыты и целевые pending orders удалены.

Account-wide действие

risk.flatten_now действует на весь account выбранного terminal instance. Не путайте его с position.flatten_now, который ограничен одним инструментом.

bash
send_signal risk flatten_now '{}'
csharp
await SendSignalAsync(http, "risk", "flatten_now", new { });
python
send_signal("risk", "flatten_now", {})

Как интерпретировать результат

Для каждой команды сохраняйте requestId из 202 Accepted и читайте:

http
GET /api/v1/signals/{requestId}

Типичные результаты:

StatusЗначение
terminal_completednon-order команда подтверждена terminal state
broker_submittedentry order принят broker/adapter
partially_filledorder частично исполнен
filledorder полностью исполнен
rejectedterminal или broker отклонил команду; проверяйте reasonCode
not_executedкоманда не была выполнена
not_confirmedterminal confirmation не получено до timeout

Для order.submit результат broker_submitted ещё не является исполнением. Для position/risk-команд не считайте HTTP 202 подтверждением изменения account: ждите terminal_completed, а при not_confirmed проверяйте terminal и broker вручную.

Частые значения reasonCode:

CodeЗначение
pausedterminal instance находится в paused state
risk_blockedинструмент заблокирован risk.block_instrument
invalid_volumeобъём после multiplier/normalization недопустим
invalid_instrument или instrument_not_foundsymbol/instrument не найден или недоступен
no_tick_dataMT5 не получил актуальные bid/ask для market operation
broker_rejectedterminal trade request отклонён broker
position_not_foundцелевая открытая позиция отсутствует
position_or_order_not_foundдля instrument flatten нет позиции и pending orders
unsupported_execution_typeexecution type не поддерживается terminal, в частности MT5 stop_limit
target_mismatchtracked command адресован другому instance
expiredкоманда истекла до обработки terminal
terminal_timeoutbackend не получил terminal confirmation до execution timeout

Список не является закрытым: terminal plugins могут добавлять новые стабильные reason codes. Клиент должен сохранять неизвестное значение и показывать его оператору без аварийного завершения.

TradingMonitor.Pro documentation.