Kavramlar
Dört kavram var; hepsi bu sırayla bağlanır.
Provider — sen
API anahtarının sahibi. Bir provider birden çok algo yayınlayabilir. Kimliğin anahtardan gelir; gövdede provider göndermene gerek yok, gönderirsen yok sayılır.
Algo — ürünün
Kullanıcının panelde gördüğü isim (porty-ai, acme-trend-ai gibi). Skor, ghost karnesi, saat matrisi ve kazanç paylaşımı algo bazında tutulur.
Signal — tek karar
Bir coin için giriş fikri: yön, giriş (tek fiyat ya da bölge), stop, hedefler. Durumu vardır; aynı signal_id ile güncellenir.
Session — kullanıcının botu
Kullanıcı ya tek algo seçer ya da otonom çekirdeğe bırakır. Oturum senin sinyallerinle çalışır ve token harcar; bu tokenın %60'ı sana yazılır.
Hızlı başlangıç
Üç istek: algoyu kaydet, sandbox'ta bir sinyal gönder, karneyi oku.
# 1) Algonu kaydet (bir kez) curl -X POST https://signal.mety.dev/v1/algos \ -H "X-Mety-Key: pk_test_..." -H "Content-Type: application/json" \ -d '{"algo_id":"acme-trend-ai","name":"Acme Trend","timeframe":"1h", "description":{"tr":"Donchian kırılımı + hacim teyidi","en":"Donchian breakout + volume"}}' # 2) Sinyal gönder (imzalı) BODY='{"algo_id":"acme-trend-ai","signal_id":"BTC-LONG-20260923-01","pair":"BTCUSDT", "side":"LONG","issued_at":"2026-09-23T17:55:00Z","entry":{"type":"ZONE","low":62450,"high":62780}, "sl":61720,"tp":[{"price":63150,"close_pct":40},{"price":63850,"close_pct":30}, {"price":64900,"close_pct":20},{"price":66200,"close_pct":10}], "leverage":15,"margin":"ISOLATED","be_after":"TP1","valid_until":"2026-09-24T00:00:00Z"}' TS=$(date +%s) SIG=$(printf "%s.%s" "$TS" "$BODY" | openssl dgst -sha256 -hmac "$METY_SECRET" -hex | awk '{print $2}') curl -X POST https://signal.mety.dev/v1/signals \ -H "X-Mety-Key: pk_test_..." -H "X-Mety-Timestamp: $TS" -H "X-Mety-Signature: $SIG" \ -H "Content-Type: application/json" -d "$BODY" # 3) Karneni oku curl https://signal.mety.dev/v1/algos/acme-trend-ai/score -H "X-Mety-Key: pk_test_..."
import hmac, hashlib, json, time, requests
KEY, SECRET = "pk_live_...", "sk_live_..."
body = json.dumps({
"algo_id": "acme-trend-ai",
"signal_id": "BTC-LONG-20260923-01",
"pair": "BTCUSDT", "side": "LONG",
"issued_at": "2026-09-23T17:55:00Z",
"entry": {"type": "ZONE", "low": 62450, "high": 62780},
"sl": 61720, "tp": [{"price": 63150, "close_pct": 40}],
}, separators=(",", ":"))
ts = str(int(time.time()))
sig = hmac.new(SECRET.encode(), f"{ts}.{body}".encode(),
hashlib.sha256).hexdigest()
r = requests.post("https://signal.mety.dev/v1/signals",
data=body, headers={"X-Mety-Key": KEY, "X-Mety-Timestamp": ts,
"X-Mety-Signature": sig, "Content-Type": "application/json"})
print(r.status_code, r.json())import crypto from "node:crypto";
const KEY = "pk_live_...", SECRET = "sk_live_...";
const body = JSON.stringify({
algo_id: "acme-trend-ai",
signal_id: "BTC-LONG-20260923-01",
pair: "BTCUSDT", side: "LONG",
issued_at: new Date().toISOString(),
entry: { type: "MARKET" }, sl: 61720,
tp: [{ price: 63150 }],
});
const ts = Math.floor(Date.now() / 1000).toString();
const sig = crypto.createHmac("sha256", SECRET)
.update(`${ts}.${body}`).digest("hex");
const res = await fetch(
"https://signal.mety.dev/v1/signals",
{ method: "POST", body, headers: {
"X-Mety-Key": KEY, "X-Mety-Timestamp": ts,
"X-Mety-Signature": sig,
"Content-Type": "application/json" } });
console.log(res.status, await res.json());Kimlik ve imza
Anahtar kimliği, imza bütünlüğü sağlar. İkisi de zorunludur; imzasız istek 401 döner.
pk_test_… (sandbox) veya pk_live_… (canlı). Anahtar sahibi = provider.hex(HMAC_SHA256(secret, timestamp + "." + ham_gövde)). Gövde bayt bayt imzalanır — yeniden serileştirme imzayı bozar.application/json ya da text/plain (düz metin sinyal).- ✓Sandbox önce.
pk_test_anahtarı aynı doğrulamadan geçer, hiçbir şey yürütülmez, anında geri bildirim verir. Uyum testini geçmeden canlı anahtar verilmez. - ↻Anahtar döndürme. Panelden ikinci bir anahtar üretip eskisini 24 saat sonra kapatabilirsin; geçiş süresince ikisi de geçerlidir.
- !Secret bizde saklanmaz — yalnız türevi tutulur. Kaybedersen yenisini üretirsin, geri okunamaz.
Algo kaydı
Sinyal gönderebilmen için önce algo kaydı gerekir. Bir algo = bir karne = bir kazanç hattı.
{
"algo_id": "acme-trend-ai", // ^[a-z0-9-]{3,32}$ · sonradan değişmez
"name": "Acme Trend", // panelde görünen ad
"timeframe": "1h", // ana çalışma periyodun (bilgi amaçlı)
"markets": ["BINANCE:FUTURES"], // bu algonun sinyal ürettiği borsalar
"max_risk_level": 4, // 1-5: kullanıcı bunun üstünde risk seçemez
"description": {"tr": "Donchian kırılımı + hacim teyidi",
"en": "Donchian breakout + volume confirmation"},
"contact": "dev@acme.io"
}
Yanıt 201 ile algoyu ve durumunu döndürür: "status":"shadow" — gölge dönemi başlamıştır. algo_id mevcut bir algoyla (bizimkiler dahil) çakışırsa 409 alırsın.
{
"algo_id": "acme-trend-ai", "status": "shadow", // shadow | panel | paused
"shadow_days": 12, "signals": 318, "executed": 276,
"score_total": 2840, "provisional": true, // veri yetersizken true
"expectancy_pct": 0.041, "win_rate": 0.38, "max_dd_pct": 6.2,
"oos": {"window": "[now-60d, now-30d]", "expectancy_pct": 0.037, "t_stat": 2.4},
"hours_utc": {"best": [13,14,15,20], "worst": [2,3]},
"live_eligible": false, "blockers": ["gölge dönemi 30 güne tamamlanmadı"]
}Sinyal gönderme
Tek uç, üç kullanım: yeni sinyal, aynı signal_id ile güncelleme, toplu gönderim.
Zorunlu alanlar: algo_id, signal_id, pair, side, issued_at. Gerisi opsiyoneldir — eksik alanlar kullanıcının bot ayarından tamamlanır.
// 202 Accepted { "status": "accepted", "signal": {"id": "sig_01J8Z…", "signal_id": "BTC-LONG-20260923-01", "pair": "BTCUSDT", "side": "LONG", "state": "validated"}, "normalized": {"entry": {"type":"ZONE","low":62450,"high":62780}, "tp": [{"price":63150,"close_pct":40}, "…"]}, "warnings": [], "echo_unknown": ["my_custom_field"] // tanımadık ama sakladık }
Idempotency: anahtar (provider, algo_id, signal_id). Aynı gövde ikinci kez gelirse 200 ile aynı kayıt döner (çift kayıt yok). Gövde değişmişse güncelleme sayılır ve yeni bir revizyon yazılır.
{ "status": "CANCELLED" } // bekleyen girişler iptal
{ "sl": 62100 } // stop taşı
{ "tp": [{"price": 64000, "close_pct": 100}] } // hedefleri yeniden kur
Kapanmış bir sinyale giriş güncellemesi 409 ile reddedilir. Açık pozisyon varken CANCELLED göndermek pozisyonu kapatır; yalnız bekleyen emirleri düşürmek istiyorsan {"status":"EXPIRED"} kullan.
Tek istekte çok sinyal. Yanıt her satır için ayrı sonuç döndürür; bir satırın hatası diğerlerini düşürmez. Geçmiş veri aktarımı da bu uçtan yapılır (bkz. bölüm 09).
Kanonik kayıt + yürütme özeti: kaç oturum aldı, ortalama giriş, gerçekleşen sonuç, kapanış nedeni dağılımı.
Alan referansı
Kanonik model. Zorunlu beş alanın dışında hiçbir şey seni bağlamaz; gönderdiğin her ek alan yürütmeyi iyileştirir.
| Alan | Tip | Durum | Açıklama |
|---|---|---|---|
| algo_id | string | zorunlu | Kayıtlı algon. Bir provider birden çok algo yayınlayabilir. |
| signal_id | string | zorunlu | Algo içinde tekil. Aynı id = güncelleme. |
| pair | string | zorunlu | BTCUSDT · BTC/USDT · BTC-USDT · BTC (quote yoksa USDT). |
| side | enum | zorunlu | LONG / SHORT (BUY, SELL, L, S kabul). |
| issued_at | time | zorunlu | ISO-8601, unix sn veya ms. Canlı puanlamaya yalnız 60 sn içinde ulaşan sinyal girer; geç gelen saklanır ama puana girmez. |
| exchange · market | enum | zorunlu | Sinyalin borsası. BINANCE + FUTURES. Gövdede yoksa bu ikisi varsayılır ve yanıtta uyarı döner. Desteklenmeyen borsa (ör. OKX) kabul edilir ve saklanır ama şimdilik değerlendirilmez; destek açıldığında geriye dönük okunur. Güncel liste: GET /v1/venues. |
| entry.type | enum | opsiyonel | MARKET · LIMIT · ZONE. Verilmezse alanlardan türetilir. |
| entry.price / low / high | number | opsiyonel | Tek fiyat ya da bölge. "62450-62780" ve [62450,62780] da kabul. |
| sl | number | opsiyonel | Stop. Vermezsen risk seviyesinin ATR tabanlı stopu kullanılır — stopsuz pozisyon asla açılmaz. |
| tp[] | array | opsiyonel | [{price, close_pct}] · [63150,63850] · TP1..TPn + TP1_CLOSE…. Oran verilmezse eşit bölünür. |
| leverage · margin | number · enum | opsiyonel | İstek olarak alınır; kullanıcının paket tavanı ve borsa sınırı her zaman üsttedir. |
| be_after | enum | opsiyonel | TP1 / TP2 sonrası stop fee dahil başabaşa çekilir. |
| valid_until · expires_in | time · dur | opsiyonel | Süre dolunca bekleyen girişler iptal; açık pozisyon kendi SL/TP'siyle devam eder. |
| confidence | 0–1 | opsiyonel | Boyutlandırmaya girdi olur (düşük güven → küçük pozisyon). 72 gönderirsen 0.72 okunur. |
| risk_pct · timeframe · strategy | karışık | opsiyonel | Skorlama kırılımı: aynı algonun farklı setuplarını ayrı ayrı ölçeriz. |
| (diğer) | any | saklanır | Tanımadığımız her alan ham hâliyle saklanır ve yanıtta echo_unknown ile bildirilir. |
Takma adlar ve düz metin
Mevcut sinyal formatını değiştirmen gerekmiyor. Alan adların tanıdıksa çevirisini biz yaparız; mesaj metnini olduğu gibi de gönderebilirsin.
| Kanonik | Kabul edilen adlar | Tolerans |
|---|---|---|
| pair | symbol · ticker · coin · instrument | büyük/küçük harf, / - _, .P / PERP son ekleri |
| side | direction · position · action · type | BUY/SELL, L/S, AL/SAT |
| entry | entry_price · entry_zone · price · buy_between | "62450-62780", [62450,62780], $62,450 |
| tp[] | targets · take_profit · tps · TP1..TPn | dizi, nesne dizisi, numaralı alanlar, virgüllü liste |
| sl | stop · stop_loss · stoploss · invalidation | fiyat |
| leverage | lev · x | 15, "15x", "cross 15" (margin da okunur) |
| valid_until | expiry · expires_at · ttl · valid_for | ISO, unix, "24h", "2d" |
| issued_at | time · timestamp · created_at · ts | ISO, unix sn/ms, "2026-09-23 17:55" |
SIGNAL_ID: BTC-LONG-20260923-01 PAIR: BTCUSDT SIDE: LONG LEVERAGE: 15 ENTRY_LOW: 62450 ENTRY_HIGH: 62780 TP1: 63150 TP1_CLOSE: 40 TP2: 63850 TP2_CLOSE: 30 SL: 61720 MOVE_SL_TO_BE_AFTER: TP1 VALID_UNTIL: 2026-09-24T00:00:00Z TIME: 2026-09-23T17:55:00Z
- 1Satırlar
ANAHTAR: değerolarak okunur, takma adlar çevrilir. - 2Çözülemeyen satır atılmaz: ham hâliyle saklanır, yanıt
"partial": truedöner. - 3
algo_idmetinde yoksa query ile verilir:?algo_id=acme-trend-ai.
Sinyalin ömrü
Sinyal tek atımlık mesaj değil, durumu olan bir kayıttır. Her geçiş ayrı satıra yazılır; karnen bu defterden hesaplanır.
"Yürütülmedi" senin hatan değildir: coin o an başka bir motorda kilitli olabilir, kullanıcının kasası dolu olabilir, paket tavanı engelleyebilir. Bu sinyaller karnende nötrdür — ne ödül ne ceza.
Geçmiş veri aktarımı
Yeni algonun karnesi sıfırdan başlamak zorunda değil. Geçmiş sinyallerini mühürlü olarak içe aktarabilirsin; skor ve saat matrisi bunlardan hesaplanır.
{ "algo_id": "acme-trend-ai",
"seal": true, // mühür: bu aralık bir daha değiştirilemez
"range": {"from": "2025-09-23T00:00:00Z", "to": "2026-09-23T00:00:00Z"},
"signals": [ "… kanonik sinyaller, issued_at geçmişte …" ] }
Aktarılan sinyaller asla yürütülmez; motorumuzda kendi kline geçmişimize karşı yeniden oynatılır (aynı fee, aynı slippage, aynı kapılar). Sonuç senin iddian değil, bizim ölçümümüz olur.
- !Mühür kuralı. Bir aralık bir kez aktarılır ve kapanır. Sonradan sinyal eklemek, silmek ya da düzeltmek mümkün değildir — kaybedenleri ayıklayarak karne şişirmenin önü budur.
- ⏱Saat matrisi son 3 ayı okur. Otonom çekirdek "şu saatte hangi algo" derken yakın dönemin saat başarısına bakar; daha eski veri uzun pencere skorlarına (180g / 365g) girer.
- ≈Geçmiş tek başına yeterli değildir. Canlıya çıkış için ileriye dönük gölge dönemi de gerekir (bölüm 11). Geçmiş veri, gölge süresini kısaltmaz; güveni artırır.
- ✓Etiketlenir. Kullanıcıya gösterilen karnede geçmiş-aktarım ile canlı ölçüm ayrı satırlarda görünür. Karıştırmayız.
Yürütme kuralları
Sinyal niyeti söyler; boyut, kaldıraç tavanı, eşzamanlı pozisyon ve kasa koruması bizde kalır. Bu ayrımı bilerek tasarla.
| Gönderdiğin | Bizim yaptığımız |
|---|---|
| entry ZONE | bölgeye kademeli maker limit (varsayılan 2 kademe); dolmayan kademe süre sonunda iptal |
| tp[] + close_pct | kademeli kâr-al; toplam >100 ise oranlanır, tek TP'de 1R kademesi eklenir |
| be_after | stop fee dahil başabaşa çekilir (çıplak fiyat değil) |
| leverage | min(istek, kullanıcı paketi, canlı 50x, sembol braketi) |
| sl yok | risk seviyesinin ATR/swing stopu; stopsuz pozisyon yok |
| aynı coine ikinci sinyal | sembol tekeli: bir coinin aynı anda tek sahibi olur, ikincisi "yürütülmedi" yazılır |
| yüksek frekans | fee-edge kapısı: işlem başına brüt beklenti, fee'nin en az 3 katı olmalı — scalper tasarımlar bu rejimde elenir |
Kullanıcının günlük zarar kesicisi, drawdown yarı-boyutu ve sessiz-saat kapıları senin sinyallerinde de çalışır. Karnende bu yüzden "gönderilen" ile "yürütülen" sayısı farklı olur — normaldir.
Puanı dürüst tutan kurallar
Puan yalnız gerçekten iyi sinyalle kazanılabilsin diye şunlar zorunlu — hepsi otomatik uygulanır.
| Kural | Ne yapar |
|---|---|
| geç sinyal | Bize 60 sn içinde ulaşmayan sinyal puana girmez (geçmişe sinyal yazılamaz). |
| sonradan düzeltme | İlk fill'den sonra stop yalnız girişe doğru taşınabilir; uzağa taşıma 409. Kapanan sinyal değişmez. |
| sıklık | Algo başına günde ≤200 sinyal, sembol başına saatte ≤4, aynı (pair, side) 30 dk'da bir. Aşım 429. |
| çift yön | Aynı sembolde aynı anda LONG + SHORT puanlanmaz — ikisi de nötrlenir. |
| fee kapısı | Hedef, round-trip fee'nin 3 katından yakınsa o sinyalin puan ağırlığı sıfırdır. |
| likidite | Düşük hacimli paritelerde puan ağırlığı yarıya iner. |
| klon akış | Başka bir algonun sinyal akışını %80+ tekrarlayan algo terfi edemez. |
| tek işlem | En iyi %5 işlem çıkarıldığında beklentin negatife düşüyorsa terfi yok (jackpot koruması). |
| kendi kendine kazanç | Kendi hesabının oturumları kazanç payına girmez. |
Skor ve canlıya çıkış
Karne tek ölçüttür; "bence iyi" geçmez. Kendi algolarımız da bu kapıdan geçer, ayrıcalık yok.
Ölçü = expectancy
İşlem başına fee-net beklenti. Kazanma oranı tek başına anlamsızdır (R:R ile %69 WR bile başabaş olabilir).
Disjoint OOS
Skorlanan pencereyle örtüşmeyen bağımsız bir pencerede de pozitif olmalısın. Yakın dönem serabı bu kapıda elenir.
Gölge dönemi
En az 30 gün ve anlamlı işlem sayısı. Ayda ~40 pozisyon üreten bir algo tek aylık "+%10" ile terfi edemez.
İlk 3 çıtası
Skorun, o anki skorboardda ilk 3 algonun en düşüğünün altındaysa panele çıkmazsın; ghost'ta ölçülmeye devam edersin.
Otonom seçimi
Çekirdek "şu saatte hangi kaynak" diye sorar; saat matrisin ve skorun iyiyse filoya girersin. Kullanıcı istersen seni doğrudan da seçebilir.
Düşme
Karne bozulursa algo paused olur: sinyal almaya devam ederiz, yeni oturum açılmaz. Toparlarsan geri döner.
Kazanç paylaşımı
Algonu çalıştıran oturumların harcadığı tokenın %60'ı sana yazılır. Ödeme aylık kesinleşir.
Atıf
Her token hareketi, oturumu besleyen algoya etiketlenir. Otonom çekirdek gün içinde algo değiştirirse pay, o dilimde hangi algo çalıştıysa ona yazılır.
Defter
GET /v1/earnings — gün gün token, oturum sayısı, kesinleşen ve bekleyen tutar. Kapanmayan ay "bekliyor" görünür.
Ödeme
Ay kapanır, tutar kesinleşir, asgari eşiğin altındaysa bir sonraki aya devreder. Ödeme bilgisi panelden girilir.
Kötüye kullanım
Kendi hesabınla token yakarak pay üretmek (self-dealing), aynı coine dakikalık zıt sinyal yağdırmak ve geçmişe dönük düzeltme paydan düşülür. Sonuçlar bizim defterimizden okunur.
// GET /v1/earnings?month=2026-09 { "month": "2026-09", "status": "open", "tokens_attributed": 18420, "share_pct": 60, "tokens_earned": 11052, "sessions": 214, "users": 63, "by_algo": [{"algo_id":"acme-trend-ai","tokens_earned":11052}], "payout": {"state":"pending_month_close", "eta":"2026-10-05"} }
Hatalar ve limitler
Hata mesajı ne yapacağını söyler: hangi alan, neden, hangi adlar kabul ediliyor.
// 422 Unprocessable { "error": "validation_failed", "details": [ {"field":"issued_at", "message":"zorunlu — ISO-8601, unix sn veya ms", "accepts":["created_at","date","timestamp","ts"]}, {"field":"sl", "message":"LONG sinyalde stop girişin yanlış tarafında (giriş 62615, sl 63000)"} ] }
| Kod | Anlamı | Ne yapmalı |
|---|---|---|
| 200 / 201 / 202 | kabul (sırasıyla: aynı kayıt · oluşturuldu · alındı) | — |
| 400 | gövde okunamadı | JSON ya da text/plain gönder |
| 401 | anahtar/imza geçersiz | imzayı ham gövde üzerinden üret |
| 403 | algo sana ait değil / askıda | karneni kontrol et |
| 409 | çakışma (algo adı, kapanmış sinyale giriş, mühürlü aralık) | farklı id / yeni sinyal |
| 422 | doğrulama | details alanına bak |
| 429 | hız limiti | Retry-After kadar bekle |
v1 en az 6 ay yaşar.Webhook'lar
Sinyalinin başına ne geldiğini öğrenmek için bizi sorgulamana gerek yok.
| Olay | Ne zaman | Gövde |
|---|---|---|
| signal.executed | ilk oturum pozisyonu açtı | sinyal + oturum sayısı + ortalama giriş |
| signal.closed | son pozisyon kapandı | fee-net sonuç, kapanış nedeni dağılımı |
| signal.rejected | doğrulama/yürütme reddi | neden + alan |
| algo.status_changed | shadow → panel → paused | eski/yeni durum + gerekçe |
| payout.created | ay kapandı | token, tutar, dönem |
Her webhook X-Mety-Signature taşır (aynı HMAC şeması). 2xx dönmeyen uç 5 kez, artan aralıkla yeniden denenir.
Yayına çıkış kontrol listesi
Sandbox'tan canlıya geçmeden önce bunların hepsi yeşil olmalı.
- 1İmza doğru. Ham gövde üzerinden HMAC; yeniden serileştirme yok.
- 2Idempotency çalışıyor. Aynı
signal_id'yi iki kez göndermek çift kayıt üretmiyor. - 3Güncelleme akışı var. Stop taşıma ve iptal
PATCHile gönderiliyor. - 4Zaman doğru.
issued_atgerçek üretim anı; sunucu saatinle senkronsun. - 5Stop her sinyalde var (ya da bilinçli olarak bize bırakılıyor).
- 6Fee matematiği tutuyor. İşlem başına brüt beklentin round-trip fee'nin en az 3 katı.
- 7Geçmiş veri mühürlendi (aktaracaksan) ve tek seferde gönderildi.
- 8Webhook ucun 2xx dönüyor ve imzayı doğruluyor.
Takıldığın yerde dev@mety.dev — entegrasyon sorularına aynı gün dönüyoruz.