Niestandardowe szablony alertów pozwalają kontrolować dokładnie, jakie informacje pojawiają się w wiadomościach Telegram, ładunkach webhook lub powiadomieniach email, gdy sygnał arbitrażowy spełnia kryteria alertu. Szablony używają prostej składni z placeholderami, pętlami i logiką warunkową — żadne doświadczenie programistyczne nie jest wymagane.
Jak Działają Szablony
Gdy sygnał spełnia filtry alertu, system pobiera zapisany tekst szablonu i zastępuje każdy placeholder rzeczywistą wartością sygnału przed wysłaniem powiadomienia.
- {variable} — zastąpiony pojedynczą wartością
- {% for %} — powtarza blok dla każdego kroku transakcji
- {% if %} — wyświetla różny tekst w zależności od warunku
Zmienne poziomu sygnału
| Placeholder | Opis | Przykład |
|---|---|---|
{signalId} | Unikalny numeryczny ID sygnału | 4821 |
{signalType} | Ex1 = wszystkie kroki na tej samej giełdzie · Ex2 = cross-exchange | Ex2 |
{coinType} | Cykl transakcji: A-B-A (2 pary) lub A-B-C-A (3 pary) | A-B-C-A |
{profitPercent} | Zysk brutto w procentach | 1.85 |
{feePercent} | Szacowana łączna prowizja w procentach | 0.30 |
{netProfit} | Zysk netto po prowizjach (profit − fee) | 1.55 |
{volume} | Wolumen pierwszego (głównego) kroku | 0.5 |
{lifetime} | Wiek sygnału w sekundach od utworzenia | 312 |
{createdAt} | Znacznik czasu pierwszego wykrycia sygnału | 2025-03-11 14:02:10 |
{updatedAt} | Znacznik czasu ostatniej aktualizacji sygnału | 2025-03-11 14:07:22 |
{freeSignal} | 1 jeśli jest to sygnał darmowy (publiczny), inaczej 0 | 0 |
| Placeholder | Opis | Przykład |
|---|---|---|
{coin_path} | Pełna ścieżka monety od quote do quote | USDT → BTC → ETH → USDT |
{symbol_steps} | Lista wszystkich par handlowych oddzielona przecinkami | BTCUSDT, ETHBTC, ETHUSDT |
{exchanges_list} | Unikalne giełdy biorące udział (oddzielone przecinkami) | Binance, KuCoin |
{signal_cards} | Wstępnie sformatowany blok podsumowania sygnału | (multi-line) |
| Placeholder | Opis | Przykład |
|---|---|---|
{exchanges[i]} | Nazwa giełdy dla kroku i | Binance |
{symbols[i]} | Pełny symbol pary handlowej dla kroku i | BTCUSDT |
{baseSymbols[i]} | Aktywo bazowe pary | BTC |
{quoteSymbols[i]} | Aktywo kwotowane pary | USDT |
{directions[i]} | Kierunek: 1 = Kupno, -1 = Sprzedaż | 1 |
{prices[i]} | Cena wykonania dla kroku i | 42318.57 |
{volumes[i]} | Wolumen transakcji dla kroku i | 0.01182 |
{i+1} | Numer kroku zaczynający od 1 (czytelny dla człowieka) | 1, 2, 3 |
| Placeholder | Opis |
|---|---|
{symbolStats[exchanges[i]+'_'+symbols[i]].minBid} | Najniższa cena bid w order booku |
{symbolStats[exchanges[i]+'_'+symbols[i]].maxBid} | Najwyższa cena bid w order booku |
{symbolStats[exchanges[i]+'_'+symbols[i]].minAsk} | Najniższa cena ask w order booku |
{symbolStats[exchanges[i]+'_'+symbols[i]].maxAsk} | Najwyższa cena ask w order booku |
{symbolStats[exchanges[i]+'_'+symbols[i]].bidQty} | Łączna ilość dostępna po stronie bid |
{symbolStats[exchanges[i]+'_'+symbols[i]].askQty} | Łączna ilość dostępna po stronie ask |
Składnia Szablonów
Sygnały mają 2 kroki (A-B-A) lub 3 kroki (A-B-C-A). Pętla uruchamia się automatycznie raz dla każdego kroku.
{% for i in 0..symbols.length-1 %}
Step {i+1}: {symbols[i]} on {exchanges[i]}
{% endfor %}
Wynik dla sygnału 3-krokowego:
Step 1: BTCUSDT on Binance
Step 2: ETHBTC on Binance
Step 3: ETHUSDT on KuCoin
Użyj {% if %}...{% else %}...{% endif %} aby wyświetlić różny tekst w zależności od wartości. Działa zarówno wewnątrz, jak i poza pętlami.
Kierunek Kupno/Sprzedaż:
{% if directions[i] == 1 %}BUY{% else %}SELL{% endif %}
Typ giełdy:
{% if signalType == 'Ex2' %}Cross-Exchange{% else %}Same-Exchange{% endif %}
Typ cyklu monet:
{% if coinType == 'A-B-C-A' %}Triangular{% else %}Simple{% endif %}
Odznaka sygnału darmowego:
{% if freeSignal == 1 %}🆓 Free Signal{% endif %}
| Placeholder | Opis | Przykład |
|---|---|---|
== | Równy | directions[i] == 1 |
!= | Różny od | signalType != 'Ex1' |
> | Większy niż | profitPercent > 2 |
< | Mniejszy niż | feePercent < 0.5 |
Gotowe Szablony
Są to te same szablony dostępne w menu rozwijalnym w oknie alertu. Użyj ich bezpośrednio lub jako punkt wyjścia dla własnego szablonu.
🚀 Arbitrage Alert [{signalType}] - {coinType}
📊 Profit: +{profitPercent}% | Fee: {feePercent}% | Net: +{netProfit}%
🔀 Path: {coin_path}
🏦 {exchanges_list}
⏱ Lifetime: {lifetime}
🚀 *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}
🚀 *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 %}
Zaawansowane Przykłady
Wyślij ustrukturyzowane dane do własnego endpointu lub aplikacji C#.
{
"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 %}
]
}
Dodaj wizualny znacznik, gdy zysk netto przekroczy próg.
{% 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 %}
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 %}
Wskazówki i Częste Błędy
- Zawsze zamykaj pętle i warunki. Każde
{% for %}wymaga odpowiadającego{% endfor %}, a każde{% if %}wymaga{% endif %}. - Zmienne order booku działają tylko wewnątrz pętli. Klucz
exchanges[i]+'_'+symbols[i]wymaga, abyibyło zdefiniowane przez blok{% for %}. - Porównania ciągów wymagają cudzysłowów. Użyj
signalType == 'Ex2'(z pojedynczymi cudzysłowami), niesignalType == Ex2. - Porównania numeryczne nie wymagają cudzysłowów. Użyj
directions[i] == 1lubnetProfit > 1.5. - Lifetime jest w sekundach. Wartość
312oznacza 5 minut i 12 sekund. Sformatuj ją w wiadomości jeśli potrzebne. - Pogrubienie Markdown Telegram. Otocz tekst
*gwiazdkami*dla pogrubienia w Telegramie (tryb parsowania MarkdownV1). - Nie używaj surowych nawiasów klamrowych
{}do niczego innego niż placeholdery — zostaną zinterpretowane jako tagi szablonu i mogą zepsuć renderowanie.
| Zmienna | Typ | Uwagi |
|---|---|---|
{signalId} | Integer | Bezpieczny do użycia w JSON bez cudzysłowów |
{profitPercent}, {feePercent}, {netProfit} | Decimal | Do 4 miejsc dziesiętnych |
{prices[i]}, {volumes[i]} | Decimal | Do 8 miejsc dziesiętnych |
{directions[i]} | Integer | 1 lub -1 |
{freeSignal} | Integer | 0 lub 1 |
{lifetime} | Integer | Sekundy (np. 312) |
{createdAt}, {updatedAt} | String | Format: RRRR-MM-DD GG:MM:SS |
| Zmienne ścieżki i podsumowania | String | Otocz cudzysłowami w ładunkach JSON |