ArbiScans
Alert Template Guide

Custom alert templates let you control exactly what information appears in your Telegram messages, webhook payloads, or email notifications when an arbitrage signal matches your alert criteria. Templates use a simple placeholder syntax mixed with loop and conditional logic — no programming experience required.

How Templates Work

When a signal matches your alert filters, the system takes your saved template text and replaces every placeholder with the actual signal value before sending the notification.

  • {variable} — replaced with a single value
  • {% for %} — repeats a block for each trading step
  • {% if %} — shows different text based on a condition
Note: Templates must be between 50 and 10,000 characters. Use the Simple preset as a starting point if you need a minimal template.
Signal-level variables
Signal-level variables
Placeholder Description Example
{signalId}Unique numeric ID of the signal4821
{signalType}Ex1 = all steps on the same exchange · Ex2 = cross-exchangeEx2
{coinType}Trading cycle: A-B-A (2 pairs) or A-B-C-A (3 pairs)A-B-C-A
{profitPercent}Gross profit in percent1.85
{feePercent}Estimated total fee in percent0.30
{netProfit}Net profit after fees (profit − fee)1.55
{volume}Volume of the first (primary) step0.5
{lifetime}Signal age in seconds since creation312
{createdAt}Timestamp when the signal was first detected2025-03-11 14:02:10
{updatedAt}Timestamp of the last signal update2025-03-11 14:07:22
{freeSignal}1 if this is a free (public) signal, otherwise 00
Path & summary variables
Placeholder Description Example
{coin_path}Full coin journey from quote to quoteUSDT → BTC → ETH → USDT
{symbol_steps}Comma-separated list of all trading pairsBTCUSDT, ETHBTC, ETHUSDT
{exchanges_list}Unique exchanges involved (comma-separated)Binance, KuCoin
{signal_cards}Pre-formatted summary block of the signal(multi-line)
Per-step variables — use inside {% for i %} loops
Placeholder Description Example
{exchanges[i]}Exchange name for step iBinance
{symbols[i]}Full trading pair symbol for step iBTCUSDT
{baseSymbols[i]}Base asset of the pairBTC
{quoteSymbols[i]}Quote asset of the pairUSDT
{directions[i]}Trade direction: 1 = Buy, -1 = Sell1
{prices[i]}Execution price for step i42318.57
{volumes[i]}Volume traded at step i0.01182
{i+1}Step number starting from 1 (human-readable)1, 2, 3
Order book variables — use inside {% for i %} loops
Placeholder Description
{symbolStats[exchanges[i]+'_'+symbols[i]].minBid}Lowest bid price in the order book
{symbolStats[exchanges[i]+'_'+symbols[i]].maxBid}Highest bid price in the order book
{symbolStats[exchanges[i]+'_'+symbols[i]].minAsk}Lowest ask price in the order book
{symbolStats[exchanges[i]+'_'+symbols[i]].maxAsk}Highest ask price in the order book
{symbolStats[exchanges[i]+'_'+symbols[i]].bidQty}Total quantity available on the bid side
{symbolStats[exchanges[i]+'_'+symbols[i]].askQty}Total quantity available on the ask side
Template Syntax
For loop — iterate over trading steps

Signals have 2 steps (A-B-A) or 3 steps (A-B-C-A). The loop runs once for each step automatically.

{% for i in 0..symbols.length-1 %}
  Step {i+1}: {symbols[i]} on {exchanges[i]}
{% endfor %}

Output for a 3-step signal:

  Step 1: BTCUSDT on Binance
  Step 2: ETHBTC on Binance
  Step 3: ETHUSDT on KuCoin
If / else — conditional text

Use {% if %}...{% else %}...{% endif %} to show different text depending on a value. Works both inside and outside loops.

Buy/Sell direction:

{% if directions[i] == 1 %}BUY{% else %}SELL{% endif %}

Exchange type:

{% if signalType == 'Ex2' %}Cross-Exchange{% else %}Same-Exchange{% endif %}

Coin cycle type:

{% if coinType == 'A-B-C-A' %}Triangular{% else %}Simple{% endif %}

Free signal badge:

{% if freeSignal == 1 %}🆓 Free Signal{% endif %}
Supported operators in conditions
PlaceholderDescriptionExample
==Equal todirections[i] == 1
!=Not equal tosignalType != 'Ex1'
>Greater thanprofitPercent > 2
<Less thanfeePercent < 0.5
Ready-Made Templates

These are the same templates available in the dropdown inside the alert modal. Use them as-is or as a starting point for your custom template.

Simple 5 lines · best for high-volume channels
🚀 Arbitrage Alert [{signalType}] - {coinType}
📊 Profit: +{profitPercent}% | Fee: {feePercent}% | Net: +{netProfit}%
🔀 Path: {coin_path}
🏦 {exchanges_list}
⏱ Lifetime: {lifetime}
Standard recommended default
🚀 *Arbitrage Signal* [{signalType} | {coinType}]
━━━━━━━━━━━━━━━━━━━━

💰 *Profit:* +{profitPercent}%
💸 *Fee:* {feePercent}%
📈 *Net:* +{netProfit}%
📦 *Volume:* {volume}

🔀 *Path:* {coin_path}
🏦 *Exchanges:* {exchanges_list}

📋 *Steps:*
{% for i in 0..symbols.length-1 %}
  [{i+1}] {exchanges[i]} | {symbols[i]}
      ↳ {% if directions[i] == 1 %}🟢 Buy{% else %}🔴 Sell{% endif %} @ {prices[i]}
      ↳ Vol: {volumes[i]}
{% endfor %}

⏱ *Lifetime:* {lifetime}
🕐 *Updated:* {updatedAt}
Full all data · ideal for webhooks / C# apps
🚀 *Arbitrage Signal* #️⃣{signalId}
━━━━━━━━━━━━━━━━━━━━
📌 *Type:* {signalType} ({coinType})
{% if signalType == 'Ex2' %}🔁 *Cross-Exchange*{% else %}🔄 *Same-Exchange*{% endif %}

💰 *Profit:*     +{profitPercent}%
💸 *Fee:*        -{feePercent}%
📈 *Net Profit:* +{netProfit}%
📦 *Volume:*     {volume}

🔀 *Coin Path:* {coin_path}
📍 *Symbols:*   {symbol_steps}
🏦 *Exchanges:* {exchanges_list}

━━━━━━━━━━━━━━━━━━━━
📋 *STEP DETAILS*
━━━━━━━━━━━━━━━━━━━━
{% for i in 0..symbols.length-1 %}
[STEP {i+1}]
  Exchange:  {exchanges[i]}
  Pair:      {symbols[i]} ({baseSymbols[i]}/{quoteSymbols[i]})
  Action:    {% if directions[i] == 1 %}🟢 BUY{% else %}🔴 SELL{% endif %}
  Price:     {prices[i]}
  Volume:    {volumes[i]}
  Order Book:
    Bid → min: {symbolStats[exchanges[i]+'_'+symbols[i]].minBid}  max: {symbolStats[exchanges[i]+'_'+symbols[i]].maxBid}  qty: {symbolStats[exchanges[i]+'_'+symbols[i]].bidQty}
    Ask → min: {symbolStats[exchanges[i]+'_'+symbols[i]].minAsk}  max: {symbolStats[exchanges[i]+'_'+symbols[i]].maxAsk}  qty: {symbolStats[exchanges[i]+'_'+symbols[i]].askQty}
{% endfor %}

━━━━━━━━━━━━━━━━━━━━
⏱ Lifetime:  {lifetime}
🕐 Created:  {createdAt}
🔄 Updated:  {updatedAt}
{% if freeSignal == 1 %}🆓 Free Signal{% endif %}
Advanced Examples
Webhook JSON payload

Send structured data to your own endpoint or C# application.

{
  "id": {signalId},
  "type": "{signalType}",
  "coinType": "{coinType}",
  "profit": {profitPercent},
  "fee": {feePercent},
  "netProfit": {netProfit},
  "volume": {volume},
  "path": "{coin_path}",
  "exchanges": "{exchanges_list}",
  "lifetime": {lifetime},
  "createdAt": "{createdAt}",
  "steps": [
    {% for i in 0..symbols.length-1 %}
    {
      "step": {i+1},
      "exchange": "{exchanges[i]}",
      "symbol": "{symbols[i]}",
      "base": "{baseSymbols[i]}",
      "quote": "{quoteSymbols[i]}",
      "direction": {% if directions[i] == 1 %}"buy"{% else %}"sell"{% endif %},
      "price": {prices[i]},
      "volume": {volumes[i]},
      "orderBook": {
        "minBid": {symbolStats[exchanges[i]+'_'+symbols[i]].minBid},
        "maxBid": {symbolStats[exchanges[i]+'_'+symbols[i]].maxBid},
        "minAsk": {symbolStats[exchanges[i]+'_'+symbols[i]].minAsk},
        "maxAsk": {symbolStats[exchanges[i]+'_'+symbols[i]].maxAsk},
        "bidQty": {symbolStats[exchanges[i]+'_'+symbols[i]].bidQty},
        "askQty": {symbolStats[exchanges[i]+'_'+symbols[i]].askQty}
      }
    }{% endfor %}
  ]
}
Highlight high-profit signals

Add a visual marker when net profit exceeds a threshold.

{% if netProfit > 1.5 %}🔥 HIGH PROFIT{% else %}🚀 Signal{% endif %} [{signalType}] {coinType}
Net: +{netProfit}% | Path: {coin_path}
{% if signalType == 'Ex2' %}⚡ Cross-exchange — check transfer fees!{% endif %}
Order book summary per step
Signal #{signalId} — {coinType} — Net +{netProfit}%

{% for i in 0..symbols.length-1 %}
▸ Step {i+1} · {exchanges[i]} · {symbols[i]}
  {% if directions[i] == 1 %}BUY{% else %}SELL{% endif %} @ {prices[i]} (vol: {volumes[i]})
  Bid  {symbolStats[exchanges[i]+'_'+symbols[i]].minBid} – {symbolStats[exchanges[i]+'_'+symbols[i]].maxBid}  qty {symbolStats[exchanges[i]+'_'+symbols[i]].bidQty}
  Ask  {symbolStats[exchanges[i]+'_'+symbols[i]].minAsk} – {symbolStats[exchanges[i]+'_'+symbols[i]].maxAsk}  qty {symbolStats[exchanges[i]+'_'+symbols[i]].askQty}
{% endfor %}
Tips & Common Mistakes
  • Always close loops and conditions. Every {% for %} needs a matching {% endfor %} and every {% if %} needs a matching {% endif %}.
  • Order book variables only work inside a loop. The key exchanges[i]+'_'+symbols[i] requires i to be defined by a {% for %} block.
  • String comparisons need quotes. Use signalType == 'Ex2' (with single quotes), not signalType == Ex2.
  • Numeric comparisons do not need quotes. Use directions[i] == 1 or netProfit > 1.5.
  • Lifetime is in seconds. A value of 312 means 5 minutes and 12 seconds. Format it in your message if needed.
  • Telegram Markdown bold. Wrap text with *asterisks* for bold in Telegram (MarkdownV1 parse mode).
  • Do not use raw {} braces for anything other than placeholders — they will be interpreted as template tags and may break rendering.
Data types quick reference
Variable Type Notes
{signalId}IntegerSafe to use in JSON without quotes
{profitPercent}, {feePercent}, {netProfit}DecimalUp to 4 decimal places
{prices[i]}, {volumes[i]}DecimalUp to 8 decimal places
{directions[i]}Integer1 or -1
{freeSignal}Integer0 or 1
{lifetime}IntegerSeconds (e.g. 312)
{createdAt}, {updatedAt}StringFormat: YYYY-MM-DD HH:MM:SS
Path & summary variablesStringWrap in quotes in JSON payloads

Documentation