OCO Emirleri
One-Cancels-the-Other — 1 Stop-Loss ve kademeli Take-Profit emirleri ile pozisyonunuzu yönetin. SL tetiklendiğinde tüm TP emirleri otomatik iptal edilir; her TP tetiklendiğinde diğerleri izlemeye devam eder.
Genel Bakış
OCO (One-Cancels-the-Other) emri, bir pozisyon için aynı anda hem kademeli Take Profit hem de tek bir Stop Loss seviyesi tanımlamanızı sağlar.
Grup Modeli
Her OCO grubu bir Stop Loss (SL) ve bir veya daha fazla
Take Profit (TP) emrinden oluşur. SL emrinin id değeri tüm gruptaki emirlerin
groupId'si olur.
| id | groupId | orderType | price | quantity |
|---|---|---|---|---|
| 101 | 101 | 2 (StopLoss) | 21,00 | 100 |
| 102 | 101 | 1 (TakeProfit) | 22,20 | 40 |
| 103 | 101 | 1 (TakeProfit) | 23,00 | 40 |
| 104 | 101 | 1 (TakeProfit) | 24,00 | 20 |
2. Gruptaki tüm aktif TP emirleri otomatik Cancelled yapılır.
3. Grup izlemeden çıkarılır.
BIST Fiyat Kademeleri
Tüm price değerleri BIST kademe kurallarına uygun olmalıdır.
Geçersiz kademede fiyat gönderildiğinde API 400 Bad Request döner.
OCO Emir Grubu Oluştur
1 Stop-Loss ve istediğiniz kadar kademeli Take-Profit emrini tek çağrıyla oluşturur.
curl -X POST https://devapi.tradewise.com.tr/api/v1/oco-orders \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"brokerageCode": "TradeWiseYatirim",
"accountNumber": "123456",
"symbol": "EREGL",
"stopLossPrice": 21.00,
"stopLossQuantity": 100,
"takeProfitItems": [
{ "price": 22.20, "quantity": 40 },
{ "price": 23.00, "quantity": 40 },
{ "price": 24.00, "quantity": 20 }
],
"dueDate": "2026-06-30T23:59:59Z",
"notes": "Kademeli kâr al + zarar kes"
}'
{
"success": true,
"message": "OCO emir grubu başarıyla oluşturuldu.",
"data": {
"id": 101,
"groupId": 101,
"userId": 42,
"accountNumber": "123456",
"symbol": "EREGL",
"orderType": 2,
"quantity": 100,
"price": 21.00,
"status": 1,
"triggeredPrice": null,
"triggeredDate": null,
"dueDate": "2026-06-30T23:59:59Z",
"notes": "Kademeli kâr al + zarar kes",
"triggerErrorMessage": null,
"createdDate": "2026-04-09T08:00:00Z",
"updatedDate": null
}
}
{
"success": false,
"message": "EREGL için zaten aktif bir OCO grubunuz var. Önce mevcut emri iptal edin."
}
Broker Emrine Bağlı OCO (Pending OCO)
Önce broker'a normal alış emri verirsiniz, sonra dönen brokerOrderNo ile bu endpoint'i çağırırsınız.
Broker emri Completed olunca gerçekleşme fiyatı üzerinden SL/TP fiyatları
otomatik hesaplanır, BIST kademesine yuvarlanır ve klasik OCO grubu oluşturulur. Broker emri iptal edilirse
bağlantı da düşer; siz hiçbir şey yapmazsınız.
POST /api/v1/oco-orders emirleri anında oluşturur ve
tüm SL/TP fiyatlarını sabit ister. Pending OCO ise broker emri gerçekleşene kadar bekler ve seviyeleri
yüzde olarak da kabul eder — gerçekleşme fiyatınızı önceden bilmediğiniz senaryolar için idealdir.
curl -X POST https://devapi.tradewise.com.tr/api/v1/oco-orders/register-pending \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"brokerageCode": "TradeWiseYatirim",
"accountNumber": "123456",
"brokerOrderNo": "ORDER-9876",
"symbol": "EREGL",
"stopLossQuantity": 100,
"stopLossPercent": 3,
"takeProfitItems": [
{ "quantity": 40, "percent": 4.5 },
{ "quantity": 40, "price": 23.00 },
{ "quantity": 20, "percent": 8 }
],
"dueDate": "2026-06-30T23:59:59Z",
"notes": "Gerçekleşmesini bekliyorum"
}'
curl -X POST https://devapi.tradewise.com.tr/api/v1/oco-orders/register-pending \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"brokerageCode": "TradeWiseYatirim",
"accountNumber": "123456",
"brokerOrderNo": "ORDER-9876",
"symbol": "EREGL",
"stopLossQuantity": 100,
"stopLossPrice": 21.00,
"takeProfitItems": [
{ "quantity": 40, "price": 22.20 },
{ "quantity": 40, "price": 23.00 },
{ "quantity": 20, "price": 24.00 }
]
}'
data alanı bağlantı kaydının setupId değeridir (integer).
{
"success": true,
"message": "Bekleyen OCO bağlantısı kaydedildi. Emir gerçekleşince otomatik OCO oluşturulur.",
"data": 4217
}
{
"success": false,
"message": "Stop-Loss için yüzde ve fiyat birlikte verilemez; sadece birini girin.",
"data": 0
}
• SL için
stopLossPercent veya stopLossPrice'tan tam olarak biri girilmelidir.• Her TP için
percent veya price'tan tam olarak biri girilmelidir.• Fiyat girilirse BIST kademe aralığına uygun olmalı; yüzde girilen alanlar gerçekleşme sonrası otomatik yuvarlanır.
• Aynı
brokerOrderNo için ikinci bir pending kayıt açılamaz.• Şu an yalnızca long pozisyon (alış emri) destekleniyor — yüzdeler "yukarı" yönde uygulanır.
OCO Emir Satırlarını Listele
Belirtilen hesaba ait tüm OCO emir satırlarını döner. Her satır ya bir TP ya da bir SL emridir;
groupId ile birbirine bağlıdır.
curl -X GET "https://devapi.tradewise.com.tr/api/v1/oco-orders?brokerageCode=TradeWiseYatirim&accountNumber=123456" \
-H "Authorization: Bearer YOUR_JWT_TOKEN"
{
"success": true,
"message": "İşlem Başarılı",
"data": [
{ "id": 101, "groupId": 101, "accountNumber": "123456", "symbol": "EREGL",
"orderType": 2, "quantity": 100, "price": 21.00, "status": 1,
"triggeredPrice": null, "triggeredDate": null, "createdDate": "2026-04-09T08:00:00Z" },
{ "id": 102, "groupId": 101, "accountNumber": "123456", "symbol": "EREGL",
"orderType": 1, "quantity": 40, "price": 22.20, "status": 1,
"triggeredPrice": null, "triggeredDate": null, "createdDate": "2026-04-09T08:00:00Z" },
{ "id": 103, "groupId": 101, "accountNumber": "123456", "symbol": "EREGL",
"orderType": 1, "quantity": 40, "price": 23.00, "status": 1,
"triggeredPrice": null, "triggeredDate": null, "createdDate": "2026-04-09T08:00:00Z" },
{ "id": 104, "groupId": 101, "accountNumber": "123456", "symbol": "EREGL",
"orderType": 1, "quantity": 20, "price": 24.00, "status": 2,
"triggeredPrice": 24.05, "triggeredDate": "2026-04-10T09:14:32Z", "createdDate": "2026-04-09T08:00:00Z" }
]
}
OCO Emir Grubunu İptal Et
Belirtilen emrin ait olduğu tüm gruptaki aktif emirleri iptal eder.
Sadece status: 1 (Aktif) emirler iptal edilebilir.
curl -X DELETE "https://devapi.tradewise.com.tr/api/v1/oco-orders/101?brokerageCode=TradeWiseYatirim" \
-H "Authorization: Bearer YOUR_JWT_TOKEN"
{
"success": true,
"message": "OCO emir grubu iptal edildi.",
"data": true
}
Emir Durum Kodları
Her OCO emir satırının status (integer) ve orderType (integer) alanı bulunur.
Kod Örnekleri
Popüler dillerde tam OCO emir akışı — grup oluştur, listele, iptal et.
const JWT_TOKEN = 'YOUR_JWT_TOKEN';
const BASE_URL = 'https://devapi.tradewise.com.tr';
const headers = { Authorization: `Bearer ${JWT_TOKEN}`, 'Content-Type': 'application/json' };
// OCO grup oluştur
async function createOcoGroup({ brokerageCode, accountNumber, symbol,
stopLossPrice, stopLossQuantity, takeProfitItems, dueDate, notes }) {
const res = await fetch(`${BASE_URL}/api/v1/oco-orders`, {
method: 'POST',
headers,
body: JSON.stringify({ brokerageCode, accountNumber, symbol,
stopLossPrice, stopLossQuantity, takeProfitItems, dueDate, notes })
});
if (!res.ok) throw new Error(`HTTP ${res.status}`);
return res.json();
}
// Listele
async function listOcoOrders(brokerageCode, accountNumber) {
const params = new URLSearchParams({ brokerageCode, accountNumber });
const res = await fetch(`${BASE_URL}/api/v1/oco-orders?${params}`, { headers });
if (!res.ok) throw new Error(`HTTP ${res.status}`);
return res.json();
}
// İptal et
async function cancelOcoGroup(id, brokerageCode) {
const res = await fetch(`${BASE_URL}/api/v1/oco-orders/${id}?brokerageCode=${brokerageCode}`, {
method: 'DELETE', headers
});
if (!res.ok) throw new Error(`HTTP ${res.status}`);
return res.json();
}
// Kullanım
const group = await createOcoGroup({
brokerageCode: 'TradeWiseYatirim',
accountNumber: '123456',
symbol: 'EREGL',
stopLossPrice: 21.00,
stopLossQuantity: 100,
takeProfitItems: [
{ price: 22.20, quantity: 40 },
{ price: 23.00, quantity: 40 },
{ price: 24.00, quantity: 20 }
]
});
console.log(`Grup oluşturuldu: GroupId=${group.data.id}`);
import requests
JWT_TOKEN = 'YOUR_JWT_TOKEN'
BASE_URL = 'https://devapi.tradewise.com.tr'
HEADERS = {'Authorization': f'Bearer {JWT_TOKEN}', 'Content-Type': 'application/json'}
def create_oco_group(brokerage_id, account_number, symbol,
stop_loss_price, stop_loss_qty, take_profit_items,
due_date=None, notes=None):
payload = {
'brokerageCode': brokerage_id,
'accountNumber': account_number,
'symbol': symbol,
'stopLossPrice': stop_loss_price,
'stopLossQuantity': stop_loss_qty,
'takeProfitItems': take_profit_items,
}
if due_date: payload['dueDate'] = due_date
if notes: payload['notes'] = notes
r = requests.post(f'{BASE_URL}/api/v1/oco-orders', json=payload, headers=HEADERS)
r.raise_for_status()
return r.json()
def list_oco_orders(brokerage_id, account_number):
r = requests.get(f'{BASE_URL}/api/v1/oco-orders',
params={'brokerageCode': brokerage_id, 'accountNumber': account_number},
headers=HEADERS)
r.raise_for_status()
return r.json()
def cancel_oco_group(order_id, brokerage_id):
r = requests.delete(f'{BASE_URL}/api/v1/oco-orders/{order_id}',
params={'brokerageCode': brokerage_id},
headers=HEADERS)
r.raise_for_status()
return r.json()
# Kullanım
result = create_oco_group(
'TradeWiseYatirim', '123456', 'EREGL',
stop_loss_price=21.00, stop_loss_qty=100,
take_profit_items=[
{'price': 22.20, 'quantity': 40},
{'price': 23.00, 'quantity': 40},
{'price': 24.00, 'quantity': 20},
]
)
print(f"Grup oluşturuldu: GroupId={result['data']['id']}")
using System.Net.Http.Json;
public record TakeProfitItem(decimal Price, int Quantity);
public record CreateOcoGroupRequest(
string BrokerageCode,
string AccountNumber,
string Symbol,
decimal StopLossPrice,
int StopLossQuantity,
List<TakeProfitItem> TakeProfitItems,
DateTime? DueDate = null,
string? Notes = null);
public class OcoOrderClient(string accessToken, string baseUrl = "https://devapi.tradewise.com.tr")
{
private readonly HttpClient _http = new();
private HttpRequestMessage NewRequest(HttpMethod method, string path)
{
var req = new HttpRequestMessage(method, $"{baseUrl}{path}");
req.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", accessToken);
return req;
}
public async Task<T?> PostAsync<T>(string path, object body)
{
var req = NewRequest(HttpMethod.Post, path);
req.Content = JsonContent.Create(body);
var res = (await _http.SendAsync(req)).EnsureSuccessStatusCode();
return await res.Content.ReadFromJsonAsync<T>();
}
public async Task<T?> GetAsync<T>(string path)
{
var req = NewRequest(HttpMethod.Get, path);
var res = (await _http.SendAsync(req)).EnsureSuccessStatusCode();
return await res.Content.ReadFromJsonAsync<T>();
}
public async Task<T?> DeleteAsync<T>(string path)
{
var req = NewRequest(HttpMethod.Delete, path);
var res = (await _http.SendAsync(req)).EnsureSuccessStatusCode();
return await res.Content.ReadFromJsonAsync<T>();
}
}
// Kullanım
var client = new OcoOrderClient("tw_live_your_api_key_here");
var group = await client.PostAsync<ApiResponse<OcoOrderDto>>(
"/api/v1/oco-orders",
new CreateOcoGroupRequest(
"TradeWiseYatirim", "123456", "EREGL",
StopLossPrice: 21.00m,
StopLossQuantity: 100,
TakeProfitItems: [
new(22.20m, 40),
new(23.00m, 40),
new(24.00m, 20)
]));
Console.WriteLine($"Grup oluşturuldu: GroupId={group!.Data.Id}");
var orders = await client.GetAsync<ApiResponse<List<OcoOrderDto>>>(
"/api/v1/oco-orders?brokerageCode=TradeWiseYatirim&accountNumber=123456");
// Grupları grupId'ye göre organize et
var groups = orders!.Data.GroupBy(o => o.GroupId);
foreach (var g in groups)
{
var sl = g.First(o => o.OrderType == 2);
var tps = g.Where(o => o.OrderType == 1).ToList();
Console.WriteLine($"Grup {g.Key}: SL={sl.Price}, TP'ler={string.Join(", ", tps.Select(t => t.Price))}");
}