Backtest05.04.2026schedule3 min read

Transaction Cost Backtest'i Nasıl Bozar?

Komisyon ve slippage'ın kârlı görünen stratejileri nasıl batırdığını vectorbt ile sayısal olarak gösteriyoruz. BIST için gerçekçi maliyet modeli ve breakeven frekans hesabı.

En çok sevdiğim backtest hatasını anlatan bir anım var: günlük 4-5 işlem yapan bir strateji geliştirmiştim. Backtest'te yıllık %94 getiri. Komisyonu sıfır almıştım. Gerçekçi komisyon ekleyince getiri %12'ye düştü. Slippage ekleyince -%4. Aynı strateji, üç farklı sonuç.

Transaction Cost Analizi

Neden Transaction Cost Bu Kadar Önemli?

Çoğu backtest şu hesabı yapıyor: getiri = fiyat değişimi × pozisyon. Gerçek dünyada ise: getiri = fiyat değişimi × pozisyon − komisyon − slippage − spread.

Günde bir işlem, %0,1 komisyon — yılda yaklaşık %25 ek maliyet.

Komisyon: BIST'te genellikle %0,05-0,15 arası.

Slippage: Likit hisseler için %0,05-0,10, ince hisseler için %0,2-0,5 arası.

Adım 1: Temel Strateji ve Maliyet Senaryoları

!pip install vectorbt yfinance --quiet

import vectorbt as vbt
import yfinance as yf
import pandas as pd
import numpy as np

df = yf.download("THYAO.IS", start="2021-01-01", end="2025-01-01", progress=False)
if isinstance(df.columns, pd.MultiIndex):
    df.columns = df.columns.droplevel(1)
df = df[df["Volume"] > 0].ffill().dropna()
close = df["Close"]

# RSI hesapla
delta = close.diff()
kazanc = delta.clip(lower=0).ewm(alpha=1/14, adjust=False).mean()
kayip = (-delta).clip(lower=0).ewm(alpha=1/14, adjust=False).mean()
rsi = 100 - (100 / (1 + kazanc / kayip))

entries = (rsi < 35).shift(1).fillna(False)
exits = (rsi > 60).shift(1).fillna(False)

senaryolar = {
    "İdeal (0 maliyet)": dict(fees=0.000, slippage=0.000),
    "Çok düşük (%0.03+%0.03)": dict(fees=0.0003, slippage=0.0003),
    "Standart (%0.1+%0.05)": dict(fees=0.001, slippage=0.0005),
    "Gerçekçi (%0.15+%0.1)": dict(fees=0.0015, slippage=0.001),
    "Yüksek (%0.2+%0.2)": dict(fees=0.002, slippage=0.002),
}

Adım 2: Tüm Senaryoları Karşılaştır

sonuclar = {}

for isim, params in senaryolar.items():
    pf = vbt.Portfolio.from_signals(
        close, entries, exits,
        init_cash=100_000, freq="1D", **params
    )
    sonuclar[isim] = {
        "pf": pf,
        "getiri": pf.total_return() * 100,
        "sharpe": pf.sharpe_ratio(),
        "max_dd": pf.max_drawdown() * 100,
        "islem_say": pf.trades.count(),
    }

for isim, s in sonuclar.items():
    print(f"{isim:<30} %{s['getiri']:>6.1f}  Sharpe: {s['sharpe']:>7.2f}  İşlem: {s['islem_say']}")

Maliyet Etkisi Karşılaştırma

Adım 3: Breakeven Frekans Hesabı

def breakeven_islem_sayisi(yillik_getiri_pct, komisyon_oran, slippage_oran):
    tur_basi_maliyet = (komisyon_oran + slippage_oran) * 2
    yillik_beklenti = yillik_getiri_pct / 100
    maks_islem = yillik_beklenti / tur_basi_maliyet
    return int(maks_islem)

print("Breakeven İşlem Sayısı (yıllık)")
print(f"{'Yıllık Getiri':<18}", end="")

maliyet_seviyeleri = [0.001, 0.002, 0.003, 0.004]
for m in maliyet_seviyeleri:
    print(f"  Maliyet %{m*100:.1f}", end="")
print()

for getiri in [10, 20, 30, 50, 100]:
    print(f"  %{getiri:<15}", end="")
    for m in maliyet_seviyeleri:
        be = breakeven_islem_sayisi(getiri, m/2, m/2)
        print(f"  {be:>12}", end="")
    print()

Backtest Sonuçları

THYAO.IS, RSI mean-reversion stratejisi, 2021-2024:

Maliyet Senaryosu Getiri Sharpe Max DD
İdeal (0 maliyet) %84.2 1.31 %-18.4
Standart (%0.1+%0.05) %38.7 0.74 %-22.1
Gerçekçi (%0.15+%0.1) %17.4 0.41 %-25.8
Yüksek (%0.2+%0.2) %-8.3 -0.19 %-31.2

Bu sonuçlar geçmiş performansı gösterir, gelecek getiri garantisi vermez.

Aynı strateji: sıfır maliyette %84 getiri, gerçekçi maliyetle %17, yüksek maliyetle zarar.

Sonuç

  • Transaction cost ihmali en sık yapılan ve en pahalı backtest hatasıdır.
  • Yüksek frekanslı stratejiler maliyet hassasiyeti çok yüksek.
  • BIST'te aracı kurum seçimi gerçek anlamda önemli — %0.15 komisyon ile %0.05 komisyon arasında yüzlerce performans farkı yaratabiliyor.
  • Bu analizin sınırı: market impact modellemedik. Büyük pozisyonlar piyasayı hareket ettirir.

Bu yazıdaki kodlar eğitim amaçlıdır; yatırım tavsiyesi değildir.