Gerçek Zamanlı Akışlar
SignalR WebSocket protokolü üzerinden bağlanarak hesabınızdaki emir değişikliklerini ve anlık portföy verisini saniyeler içinde alın.
Genel Bakış
TradeWise Gerçek Zamanlı Akışları, Microsoft SignalR tabanlı bir WebSocket bağlantısı kullanır. Aynı hub üzerinden hem emir değişikliklerini hem de anlık portföy verisini alabilirsiniz. Her abonelik türü bağımsız olup birini veya her ikisini birden aktifleştirebilirsiniz.
Protokol
SignalR (WebSocket)
Portföy Güncelleme Sıklığı
Her 1 saniye
Abonelik TTL
2 saat (heartbeat ile uzatılır)
ReceiveOrderChanges
Hesapta yeni emir oluştuğunda veya mevcut bir emrin durumu değiştiğinde tetiklenir. Abonelik: SubscribeToPositions
ReceivePortfolio
Her saniye çekilen anlık portföy verisi (bakiye, pozisyonlar, k/z). Abonelik: SubscribeToPortfolio
Önemli: Akışlar yalnızca haftaiçi borsa saatleri (09:30–18:15 Türkiye saati) arasında aktiftir. Bu saatler dışında bağlantı kurabilirsiniz ancak mesaj gelmez.
Kimlik Doğrulama
WebSocket bağlantısı, standart HTTP Bearer token kimlik doğrulamasını desteklemez.
Bu nedenle JWT token'ınızı bağlantı URL'sinin access_token sorgu parametresi olarak geçirmeniz gerekir.
JWT token'ınızı Kimlik Doğrulama sayfasında anlatıldığı şekilde POST /oauth/token
endpoint'inden API anahtarınızı kullanarak alabilirsiniz. Access token geçerlilik süresi 24 saattir; süresi dolmadan önce refresh token ile yenileyebilirsiniz.
https://devapi.tradewise.com.tr/hubs/positions?access_token=YOUR_JWT_TOKEN
SignalR istemci kütüphaneleri, token'ı otomatik olarak sorgu parametresine ekleyebilir. Aşağıdaki örneklere bakın.
Token yenileme: Heartbeat OAuth token yenilemesi değildir. Uygulamanız expires_in değerine göre access token'ı refresh token ile yenilemeli; bağlantı yeniden kurulursa yeni JWT ile bağlanıp abonelikleri tekrar göndermelidir.
Bağlantı Kurma
Hub adresi değişmez; tüm broker hesapları için aynı endpoint üzerinden bağlanılır.
Hangi hesabı dinleyeceğinizi bağlantı sonrasında SubscribeToPositions metoduyla bildirirsiniz.
| Parametre | Değer |
|---|---|
| Hub URL | https://devapi.tradewise.com.tr/hubs/positions |
| Token parametresi | ?access_token=<JWT> |
| Transport | WebSockets (tercih edilir), Server-Sent Events, Long Polling |
Negotiate endpoint (SignalR istemcisi otomatik çağırır)
POST https://devapi.tradewise.com.tr/hubs/positions/negotiate?negotiateVersion=1
Authorization: Bearer <JWT>
Abonelik — Emir Akışı
Bağlantı kurulduktan sonra, hangi broker hesabının emir değişikliklerini almak istediğinizi sunucuya bildirmeniz gerekir. Birden fazla hesaba ayrı ayrı abone olabilirsiniz.
HUB METODU SubscribeToPositions
Belirtilen broker hesabı için emir değişikliği akışına abone olur. true dönerse abone olundu, false dönerse reddedildi demektir.
| Parametre | Tip | Açıklama |
|---|---|---|
| brokerageCode | string | Aracı kurum kodu (örn. "TradeWiseYatirim"). Hesap listeleme API'sinden (brokerageCode alanı) öğrenebilirsiniz. |
| accountNumber | string | Aracı kurumdaki hesap numarası. |
Güvenlik: Sunucu, yalnızca JWT token'ında kimliği doğrulanmış kullanıcıya ait hesaplara abone olmaya izin verir.
Başkasının hesabına abone olmaya çalışırsanız abonelik reddedilir ve Error olayı tetiklenir.
Dönüş değeri: bool
true→ Abonelik başarılı, emir akışı başlar.false→ Reddedildi. Hesap size ait değil ya da geçersiz parametre.
HUB METODU UnsubscribeFromPositions
Belirtilen hesap için emir aboneliğini iptal eder. Bağlantı kesildiğinde tüm abonelikler otomatik olarak iptal edilir.
| Parametre | Tip | Açıklama |
|---|---|---|
| brokerageCode | string | Aracı kurum kimlik numarası |
| accountNumber | string | Hesap numarası |
Abonelik — Portföy Akışı
Emir akışından bağımsız olarak anlık portföy verisine abone olabilirsiniz.
Sunucu, her 1 saniyede bir GetPortfolioAsync çağrısı yaparak güncel portföyü
ReceivePortfolio olayıyla iletir.
HUB METODU SubscribeToPortfolio
Belirtilen broker hesabı için anlık portföy akışına abone olur. true dönerse akış başladı demektir.
| Parametre | Tip | Açıklama |
|---|---|---|
| brokerageCode | string | Aracı kurum kimlik numarası. |
| accountNumber | string | Aracı kurumdaki hesap numarası. |
Dönüş değeri: bool
true→ Abonelik başarılı, portföy akışı saniyede bir gelmeye başlar.false→ Reddedildi. Hesap size ait değil ya da geçersiz parametre.
HUB METODU UnsubscribeFromPortfolio
Belirtilen hesap için portföy aboneliğini iptal eder. Bağlantı kesildiğinde otomatik olarak iptal edilir.
| Parametre | Tip | Açıklama |
|---|---|---|
| brokerageCode | string | Aracı kurum kimlik numarası |
| accountNumber | string | Hesap numarası |
Gelen Olaylar
Aboneliğe göre sunucu aşağıdaki olayları gönderir. Her olay ilgili handler fonksiyonunuza otomatik olarak iletilir.
OLAY ReceiveOrderChanges
SubscribeToPositions aboneliğine gelir.
Hesapta yeni bir emir iletildiğinde veya mevcut bir emrin durumu değiştiğinde tetiklenir.
Mesaj, değişen emirlerin listesini içerir.
Ne zaman gelir?
• Hesapta yeni bir emir oluştuğunda (changeType: "New")
• Mevcut bir emrin durumu değiştiğinde — örneğin Bekliyor → Tamamlandı, Bekliyor → İptal (changeType: "Completed", "Cancelled", "Updated")
Payload tipi: OrderChangeDto[]
OLAY ReceivePortfolio
SubscribeToPortfolio aboneliğine gelir.
Sunucu her 1 saniyede bir hesabın güncel portföyünü çekerek bu olayla iletir.
Oturum içindeki her güncelleme (bakiye, pozisyon k/z vb.) anlık olarak yansır.
Payload tipi: PortfolioDto (tekil nesne)
OLAY Error
Sunucu tarafında bir hata oluştuğunda veya abonelik reddedildiğinde tetiklenir.
Payload tipi: string (hata mesajı).
Veri Şeması — OrderChangeDto
ReceiveOrderChanges olayıyla gelen her eleman aşağıdaki alanları içerir.
| Alan | Tip | Açıklama |
|---|---|---|
| orderId | string | Aracı kurumdaki emir numarası. İlgili emri tanımlamak için kullanın. |
| symbol | string | İşlem gören sembol kodu (örn: THYAO, EREGL). |
| side | string | "BUY" (Alış) veya "SELL" (Satış). |
| quantity | number | Emir miktarı (lot). |
| status | string |
Emirin güncel durumu:
Pending (Bekliyor),
Completed (Tamamlandı),
Canceled (İptal),
Waiting,
Rejected (Reddedildi).
|
| changeType | string |
Değişiklik türü:
New (yeni emir),
Completed,
Cancelled,
Updated (diğer durum değişiklikleri).
|
| previousStatus | string | Değişiklikten önceki durum. Yeni emirlerde boş string ("") gelir. |
| changedAt | string (ISO 8601) | Değişikliğin tespit edildiği UTC zaman damgası. |
Örnek Payload
[
{
"orderId": "305344701",
"symbol": "THYAO",
"side": "BUY",
"quantity": 100,
"status": "Pending",
"changeType": "New",
"previousStatus": "",
"changedAt": "2026-03-06T09:35:12.483Z"
},
{
"orderId": "305344695",
"symbol": "EREGL",
"side": "SELL",
"quantity": 50,
"status": "Completed",
"changeType": "Completed",
"previousStatus": "Pending",
"changedAt": "2026-03-06T09:36:01.120Z"
}
]
Veri Şeması — PortfolioDto
ReceivePortfolio olayıyla gelen tekil nesnenin alanları aşağıda açıklanmıştır.
Portföy (üst nesne)
| Alan | Tip | Açıklama |
|---|---|---|
| accountNumber | string | Hesap numarası. |
| dateTime | string (ISO 8601) | Portföyün alındığı UTC zaman damgası. |
| accountBalance | number | Hesap bakiyesi (TL). |
| cashAmount | number | Nakit miktar (TL). |
| t1NetCashAmount | number | T+1 net nakit miktarı. |
| t2NetCashAmount | number | T+2 net nakit miktarı. |
| overall | number | Toplam portföy değeri (nakit + hisse, TL). |
| stockOverall | number | Toplam hisse senedi değeri (TL). |
| totalProfit | number | Toplam kar/zarar (TL). |
| positions | PositionDto[] | Açık pozisyonların listesi. Aşağıya bakın. |
Pozisyon (positions dizisi)
| Alan | Tip | Açıklama |
|---|---|---|
| symbol | string | Sembol kodu (örn: THYAO). |
| lot | number (int) | Toplam lot adedi. |
| sellable | number (int) | Satılabilir lot adedi. |
| profitRate | number | Kar/zarar oranı (%). Pozitif = kârda, negatif = zararda. |
Örnek Payload
{
"accountNumber": "123456",
"dateTime": "2026-04-08T10:15:32.000Z",
"accountBalance": 250000.00,
"cashAmount": 50000.00,
"t1NetCashAmount": 48000.00,
"t2NetCashAmount": 47500.00,
"overall": 245000.00,
"stockOverall": 195000.00,
"totalProfit": 12500.00,
"positions": [
{
"symbol": "THYAO",
"lot": 500,
"sellable": 500,
"profitRate": 8.45
},
{
"symbol": "EREGL",
"lot": 200,
"sellable": 150,
"profitRate": -2.10
}
]
}
Heartbeat (Canlılık Sinyali)
Sunucu, abonelikleri otomatik olarak temizler. Uygulamanızın çalışmaya devam ettiğini bildirmek için
25 dakikada bir önerilen, en geç 30 dakikada bir Heartbeat metodunu çağırmanız gerekir.
Heartbeat Mekanizması
- • Sunucu, her abonelik için 2 saatlik bir TTL (yaşam süresi) tutar.
- • Her
Heartbeatçağrısı bu TTL'i yeniler. - • Heartbeat, JWT access token veya refresh token süresini uzatmaz; sadece abonelik TTL'ini yeniler.
- • 2 saat boyunca heartbeat gelmezse abonelik otomatik olarak sona erer ve emir/portföy akışı durur.
- • Tüm aktif abonelikleriniz için tek bir Heartbeat çağrısı yeterlidir.
| Özellik | Değer |
|---|---|
| Hub metodu | Heartbeat() |
| Önerilen aralık | 30 dakika |
| Maksimum sessizlik | 2 saat (sonrası abonelik otomatik iptal) |
| Parametre | Yok |
| Dönüş değeri | Yok |
Öneri: Bağlantı kesilip yeniden kurulduğunda, aktif aboneliklerinizi (SubscribeToPositions ve/veya SubscribeToPortfolio) tekrar çağırın ve ardından hemen bir Heartbeat gönderin.
Tek bir Heartbeat çağrısı hem emir hem portföy aboneliklerini yeniler.
Hata Olayları
Sunucu, belirli durumlarda Error olayını tetikler.
Bu olayı dinleyerek uygulamanızda uygun aksiyon alabilirsiniz.
| Hata Mesajı | Neden | Yapılacak |
|---|---|---|
| Unauthorized | JWT token eksik, geçersiz veya süresi dolmuş. | Access token'ı refresh token ile yenileyip yeni JWT ile tekrar bağlanın. |
| Account not found or access denied | Hesap size ait değil veya mevcut değil. | Hesap listelerinizi kontrol edin. |
| brokerageCode and accountNumber required | Parametreler boş ya da eksik gönderildi. | Her iki parametreyi de doldurun. |
| Unknown brokerage | Gönderilen brokerageCode geçersiz veya tanımlı değil. | Hesap listeleme API'sinden doğru brokerageCode değerini alın. |
| Account validation failed, try again | Sunucu tarafında geçici hata. | Birkaç saniye bekleyip tekrar deneyin. |
C# / .NET Örneği
Bağımlılık
dotnet add package Microsoft.AspNetCore.SignalR.Client
Tam Örnek
using Microsoft.AspNetCore.SignalR.Client;
var jwtToken = "YOUR_JWT_TOKEN"; // POST /oauth/token ile alın (bkz. Kimlik Doğrulama)
var brokerageCode = "TradeWiseYatirim"; // hesap listesinden alın
var accountNumber = "123456";
var hubEndpoint = "https://devapi.tradewise.com.tr/hubs/positions";
var connection = new HubConnectionBuilder()
.WithUrl(hubEndpoint, opts =>
opts.AccessTokenProvider = () => Task.FromResult<string?>(jwtToken))
.WithAutomaticReconnect([
TimeSpan.Zero,
TimeSpan.FromSeconds(2),
TimeSpan.FromSeconds(5),
TimeSpan.FromSeconds(10)])
.Build();
// ── Mesaj handler'ları ────────────────────────────────────────────────────────
connection.On<List<OrderChangeDto>>("ReceiveOrderChanges", changes =>
{
foreach (var c in changes)
{
Console.WriteLine($"[{c.ChangeType}] {c.Symbol} {c.Side} {c.Quantity} lot");
if (!string.IsNullOrEmpty(c.PreviousStatus))
Console.WriteLine($" Durum: {c.PreviousStatus} → {c.Status}");
Console.WriteLine($" Emir No: {c.OrderId} Zaman: {c.ChangedAt:HH:mm:ss}");
}
});
connection.On<PortfolioDto>("ReceivePortfolio", portfolio =>
{
Console.WriteLine($"Portföy | Bakiye: {portfolio.AccountBalance:N0} ₺ Toplam: {portfolio.Overall:N0} ₺ K/Z: {portfolio.TotalProfit:+N0;-N0} ₺");
foreach (var p in portfolio.Positions)
Console.WriteLine($" {p.Symbol,-8} lot:{p.Lot,6} satılabilir:{p.Sellable,6} k/z: {p.ProfitRate:+0.00;-0.00}%");
});
connection.On<string>("Error", msg =>
Console.WriteLine($"Sunucu hatası: {msg}"));
// ── Bağlantı event'leri ───────────────────────────────────────────────────────
connection.Reconnecting += ex =>
{
Console.WriteLine($"Yeniden bağlanılıyor... ({ex?.Message})");
return Task.CompletedTask;
};
connection.Reconnected += async _ =>
{
Console.WriteLine("Yeniden bağlandı, abonelik yenileniyor...");
await SubscribeAsync(connection, brokerageCode, accountNumber);
await SubscribePortfolioAsync(connection, brokerageCode, accountNumber);
await SendHeartbeatAsync(connection);
};
connection.Closed += ex =>
{
Console.WriteLine($"Bağlantı kapandı: {ex?.Message}");
return Task.CompletedTask;
};
// ── Bağlan & abone ol ────────────────────────────────────────────────────────
await connection.StartAsync();
Console.WriteLine($"Bağlandı → {hubEndpoint}");
// Emir akışına abone ol (zorunlu)
var subscribed = await SubscribeAsync(connection, brokerageCode, accountNumber);
if (!subscribed)
{
Console.WriteLine("Emir aboneliği reddedildi. Bağlantı kapatılıyor.");
await connection.DisposeAsync();
return;
}
// Portföy akışına abone ol (isteğe bağlı)
await SubscribePortfolioAsync(connection, brokerageCode, accountNumber);
// ── Heartbeat (25 dakikada bir; en geç 30 dakikada bir) ──────────────────────
using var cts = new CancellationTokenSource();
Console.CancelKeyPress += (_, e) => { e.Cancel = true; cts.Cancel(); };
using var heartbeatTimer = new PeriodicTimer(TimeSpan.FromMinutes(25));
try
{
while (await heartbeatTimer.WaitForNextTickAsync(cts.Token))
{
if (connection.State == HubConnectionState.Connected)
await SendHeartbeatAsync(connection);
}
}
catch (OperationCanceledException) { }
// ── Temizlik ─────────────────────────────────────────────────────────────────
try
{
await connection.InvokeAsync("UnsubscribeFromPositions", brokerageCode, accountNumber);
await connection.InvokeAsync("UnsubscribeFromPortfolio", brokerageCode, accountNumber);
}
catch { }
await connection.DisposeAsync();
Console.WriteLine("Bağlantı kapatıldı.");
// ── Yardımcı metodlar ────────────────────────────────────────────────────────
static async Task<bool> SubscribeAsync(HubConnection conn, string brokerageCode, string accountNumber)
{
try
{
var accepted = await conn.InvokeAsync<bool>("SubscribeToPositions", brokerageCode, accountNumber);
Console.WriteLine(accepted ? "Emir aboneliği başarılı." : "Emir aboneliği reddedildi.");
return accepted;
}
catch (Exception ex)
{
Console.WriteLine($"Abonelik hatası: {ex.Message}");
return false;
}
}
static async Task SubscribePortfolioAsync(HubConnection conn, string brokerageCode, string accountNumber)
{
try
{
var accepted = await conn.InvokeAsync<bool>("SubscribeToPortfolio", brokerageCode, accountNumber);
Console.WriteLine(accepted ? "Portföy aboneliği başarılı." : "Portföy aboneliği reddedildi.");
}
catch (Exception ex)
{
Console.WriteLine($"Portföy abonelik hatası: {ex.Message}");
}
}
static async Task SendHeartbeatAsync(HubConnection conn)
{
try
{
await conn.InvokeAsync("Heartbeat");
Console.WriteLine($"Heartbeat gönderildi → {DateTime.Now:HH:mm:ss}");
}
catch (Exception ex)
{
Console.WriteLine($"Heartbeat gönderilemedi: {ex.Message}");
}
}
// ── DTO'lar ───────────────────────────────────────────────────────────────────
record OrderChangeDto(
string OrderId,
string Symbol,
string Side, // "BUY" veya "SELL"
int Quantity,
string Status,
string ChangeType, // "New" | "Updated" | "Cancelled" | "Completed"
string PreviousStatus,
DateTime ChangedAt);
record PortfolioDto(
string AccountNumber,
DateTime DateTime,
decimal AccountBalance,
decimal CashAmount,
decimal T1NetCashAmount,
decimal T2NetCashAmount,
decimal Overall,
decimal StockOverall,
decimal TotalProfit,
List<PositionDto> Positions);
record PositionDto(
string Symbol,
int Lot,
int Sellable,
decimal ProfitRate);
JavaScript Örneği
Bağımlılık
npm install @microsoft/signalr
Tam Örnek
import * as signalR from "@microsoft/signalr";
const jwtToken = "YOUR_JWT_TOKEN"; // POST /oauth/token ile alın (bkz. Kimlik Doğrulama)
const brokerageCode = "TradeWiseYatirim"; // hesap listesinden alın
const accountNumber = "123456";
const connection = new signalR.HubConnectionBuilder()
.withUrl("https://devapi.tradewise.com.tr/hubs/positions", {
// Token query string olarak eklenir (WebSocket için zorunlu)
accessTokenFactory: () => jwtToken
})
.withAutomaticReconnect()
.build();
// Emir değişikliği olayı
connection.on("ReceiveOrderChanges", (changes) => {
changes.forEach(c => {
console.log(`[${c.changeType}] ${c.symbol} ${c.side} ${c.quantity} lot`);
if (c.previousStatus) {
console.log(` Durum: ${c.previousStatus} → ${c.status}`);
}
console.log(` Emir No: ${c.orderId} Zaman: ${c.changedAt}`);
});
});
// Anlık portföy olayı (saniyede bir)
connection.on("ReceivePortfolio", (portfolio) => {
console.log(`Portföy | Bakiye: ${portfolio.accountBalance.toFixed(2)} ₺ Toplam: ${portfolio.overall.toFixed(2)} ₺`);
portfolio.positions.forEach(p => {
const sign = p.profitRate >= 0 ? "+" : "";
console.log(` ${p.symbol.padEnd(8)} lot:${p.lot} satılabilir:${p.sellable} k/z: ${sign}${p.profitRate.toFixed(2)}%`);
});
});
// Hata olayı
connection.on("Error", (message) => {
console.error("Sunucu hatası:", message);
});
// Yeniden bağlanınca abonelikleri yenile
connection.onreconnected(async () => {
await subscribeOrders();
await subscribePortfolio();
});
async function subscribeOrders() {
const result = await connection.invoke("SubscribeToPositions", brokerageCode, accountNumber);
console.log(result ? "Emir aboneliği başarılı." : "Emir aboneliği reddedildi.");
return result;
}
async function subscribePortfolio() {
const result = await connection.invoke("SubscribeToPortfolio", brokerageCode, accountNumber);
console.log(result ? "Portföy aboneliği başarılı." : "Portföy aboneliği reddedildi.");
}
async function main() {
await connection.start();
console.log("Bağlandı.");
const subscribed = await subscribeOrders();
if (!subscribed) {
await connection.stop();
return;
}
// Portföy akışını da başlat (isteğe bağlı)
await subscribePortfolio();
// 25 dakikada bir heartbeat gönder (hem emir hem portföy TTL'i yenilenir)
setInterval(async () => {
try {
await connection.invoke("Heartbeat");
} catch (e) {
console.warn("Heartbeat gönderilemedi:", e.message);
}
}, 25 * 60 * 1000);
}
main().catch(console.error);
Python Örneği
Bağımlılık
pip install signalrcore
Tam Örnek
import threading
from signalrcore.hub_connection_builder import HubConnectionBuilder
jwt_token = "YOUR_JWT_TOKEN" # POST /oauth/token ile alın (bkz. Kimlik Doğrulama)
brokerage_code = "TradeWiseYatirim" # hesap listesinden alın
account_number = "123456"
hub_url = (
"https://devapi.tradewise.com.tr/hubs/positions"
f"?access_token={jwt_token}"
)
connection = (
HubConnectionBuilder()
.with_url(hub_url)
.with_automatic_reconnect({"type": "raw", "keep_alive_interval": 10, "reconnect_interval": 5})
.build()
)
def on_order_changes(changes):
for c in changes:
print(f"[{c['changeType']}] {c['symbol']} {c['side']} {c['quantity']} lot")
if c.get("previousStatus"):
print(f" Durum: {c['previousStatus']} → {c['status']}")
print(f" Emir No: {c['orderId']} Zaman: {c['changedAt']}")
def on_portfolio(portfolio):
print(f"Portföy | Bakiye: {portfolio['accountBalance']:.2f} ₺ Toplam: {portfolio['overall']:.2f} ₺")
for p in portfolio.get("positions", []):
sign = "+" if p["profitRate"] >= 0 else ""
print(f" {p['symbol']:<8} lot:{p['lot']} satılabilir:{p['sellable']} k/z: {sign}{p['profitRate']:.2f}%")
def on_error(message):
print(f"Sunucu hatası: {message}")
def subscribe_orders():
result = connection.send("SubscribeToPositions", [brokerage_code, account_number])
print("Emir aboneliği başarılı." if result else "Emir aboneliği reddedildi.")
def subscribe_portfolio():
result = connection.send("SubscribeToPortfolio", [brokerage_code, account_number])
print("Portföy aboneliği başarılı." if result else "Portföy aboneliği reddedildi.")
def send_heartbeat():
"""25 dakikada bir heartbeat gönderir (hem emir hem portföy TTL'i yenilenir)"""
while True:
threading.Event().wait(25 * 60)
try:
connection.send("Heartbeat", [])
except Exception as e:
print(f"Heartbeat hatası: {e}")
connection.on("ReceiveOrderChanges", on_order_changes)
connection.on("ReceivePortfolio", on_portfolio)
connection.on("Error", on_error)
def on_connected():
print("Bağlandı.")
subscribe_orders()
subscribe_portfolio()
connection.on_open(on_connected)
connection.on_reconnect(lambda: (subscribe_orders(), subscribe_portfolio()))
connection.start()
# Heartbeat thread başlat
threading.Thread(target=send_heartbeat, daemon=True).start()
input("Çıkmak için Enter'a basın...\n")
connection.stop()
Hızlı Başvuru
| Adım | Yapılacak |
|---|---|
| 1 | Kimlik Doğrulama sayfasındaki adımları izleyerek POST /oauth/token ile JWT alın. |
| 2 | JWT'yi access_token parametresiyle hub URL'sine ekleyerek bağlanın. |
| 3 | SubscribeToPositions(brokerageCode, accountNumber) çağırın — emir değişikliği akışı başlar. |
| 4 | (İsteğe bağlı) SubscribeToPortfolio(brokerageCode, accountNumber) çağırın — saniyede bir portföy gelmeye başlar. |
| 5 | ReceiveOrderChanges ve/veya ReceivePortfolio olaylarını dinleyin. |
| 6 | 25 dakikada bir Heartbeat() çağırın — hem emir hem portföy abonelikleri yenilenir. Bu çağrı OAuth token süresini uzatmaz. |
| 7 | Bağlantı kopunca 3–4. adımları + Heartbeat'i tekrarlayın. |
Sorunuz mu Var?
Teknik destek için ekibimize ulaşın.