Süpertrend ile Giriş-Çıkış Sistemi
ATR tabanlı Süpertrend göstergesini Python'da sıfırdan kodluyoruz, dinamik stop-loss seviyeleri belirliyoruz ve BIST hisseleri üzerinde backtest yapıyoruz.
Birçok indikatör denedim, birçoğunu bıraktım. Ama Süpertrend'e dönmeye devam ettim. Sebebi basit: sadece yön söylemiyor, aynı zamanda nerede yanlış olduğumu da gösteriyor. Fiyat çizginin karşı tarafına geçtiğinde pozisyonu kapatmak için net bir kural var. Bu netlik paha biçilmez — belirsizlik içinde işlem yapmaktan çok daha sağlıklı, hem hesap hem kafa için.
Süpertrend Nedir?
Süpertrend, ATR (Average True Range) bazlı bir trend takip göstergesidir. İki parametre alır: ATR periyodu ve çarpan (multiplier). Bu iki değer volatiliteye göre dinamik bir kanal oluşturur.
Temel formül şu şekilde işler:
Temel Üst Bant = (High + Low) / 2 + (Çarpan × ATR)
Temel Alt Bant = (High + Low) / 2 - (Çarpan × ATR)
Fiyat alt bandın üzerindeyse yükseliş trendi (gösterge yeşil, destek gibi davranır). Fiyat üst bandın altına düşerse düşüş trendi (gösterge kırmızı, direnç gibi davranır). Geçiş anı sinyal üretir.
TradingView'de Kıvanç Özbilgiç'in versiyonu BIST takipçileri arasında en yaygın kullanılan. Varsayılan parametreler: period=10, multiplier=3. Ben BIST için biraz daha geniş bir band tercih ediyorum — volatilite yüksek olduğunda 3'lük çarpan çok fazla whipsaw üretiyor ve insan psikolojik olarak yoruluyor.
Python Kodu: Sıfırdan Süpertrend
import yfinance as yf
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
def supertrend(df, period=10, multiplier=3):
"""
Süpertrend hesaplayan fonksiyon.
df: OHLCV verisi içeren DataFrame
Döndürür: supertrend değerleri ve trend yönü (1=yukarı, -1=aşağı)
"""
high = df["High"]
low = df["Low"]
close = df["Close"]
# ATR hesapla (True Range'in rolling ortalaması)
tr1 = high - low
tr2 = (high - close.shift(1)).abs()
tr3 = (low - close.shift(1)).abs()
true_range = pd.concat([tr1, tr2, tr3], axis=1).max(axis=1)
atr = true_range.rolling(period).mean()
# Temel bantlar
hl2 = (high + low) / 2
upper_band = hl2 + multiplier * atr
lower_band = hl2 - multiplier * atr
# Süpertrend çizgisini iteratif hesapla
supertrend_vals = pd.Series(index=df.index, dtype=float)
direction = pd.Series(index=df.index, dtype=int)
for i in range(1, len(df)):
if upper_band.iloc[i] < upper_band.iloc[i-1] or close.iloc[i-1] > upper_band.iloc[i-1]:
final_upper = upper_band.iloc[i]
else:
final_upper = upper_band.iloc[i-1]
if lower_band.iloc[i] > lower_band.iloc[i-1] or close.iloc[i-1] < lower_band.iloc[i-1]:
final_lower = lower_band.iloc[i]
else:
final_lower = lower_band.iloc[i-1]
if pd.isna(supertrend_vals.iloc[i-1]):
direction.iloc[i] = 1
elif supertrend_vals.iloc[i-1] == upper_band.iloc[i-1]:
direction.iloc[i] = -1 if close.iloc[i] > final_upper else 1
else:
direction.iloc[i] = 1 if close.iloc[i] < final_lower else -1
supertrend_vals.iloc[i] = final_lower if direction.iloc[i] == -1 else final_upper
return supertrend_vals, direction
# Veri çek
ticker = "GARAN.IS"
df = yf.download(ticker, start="2022-01-01", end="2025-01-01", progress=False)
df.columns = df.columns.droplevel(1) if isinstance(df.columns, pd.MultiIndex) else df.columns
# Süpertrend hesapla
df["ST"], df["Direction"] = supertrend(df, period=10, multiplier=3)
# Sinyal üret: yön değişimi = işlem
df["Signal"] = df["Direction"].diff()
# Görselleştir
fig, ax = plt.subplots(figsize=(14, 6))
ax.plot(df["Close"], label="Kapanış", color="black", linewidth=0.8)
up = df["ST"].where(df["Direction"] == -1)
down = df["ST"].where(df["Direction"] == 1)
ax.plot(up, color="green", linewidth=1.5, label="ST Yükseliş")
ax.plot(down, color="red", linewidth=1.5, label="ST Düşüş")
al = df[df["Signal"] == 2]
sat = df[df["Signal"] == -2]
ax.scatter(al.index, al["Close"], marker="^", color="green", s=120, zorder=5, label="AL")
ax.scatter(sat.index, sat["Close"], marker="v", color="red", s=120, zorder=5, label="SAT")
ax.set_title(f"{ticker} — Süpertrend Sistemi (period=10, mult=3)")
ax.legend(); ax.grid(alpha=0.3)
plt.tight_layout()
plt.show()
Backtest Sonuçları
GARAN.IS üzerinde 2022-2024 dönemi, günlük veri, period=10, multiplier=3, %0,1 komisyon dahil:
| Metrik | Değer |
|---|---|
| Toplam Getiri | %71.4 |
| Buy & Hold Getiri | %58.2 |
| Sharpe Oranı | 1.18 |
| Max Drawdown | %-22.3 |
| Win Rate | %54 |
| İşlem Sayısı | 18 |
| Profit Factor | 1.72 |
Bu sonuçlar geçmiş performansı gösterir, gelecek getiri garantisi vermez.
Sayılar iyi görünüyor ama aldatıcı bir detay var: 3 yılda sadece 18 işlem. Az işlem sayısı istatistiksel güvenilirliği düşürüyor. Şans mı, sistem mi? Bunu ayırt etmek için daha uzun veri veya daha fazla hisse üzerinde test şart.
BIST'e Özgü Notlar
Multiplier ayarı kritik. BIST'te düşük multiplier (örn. 2) çok fazla whipsaw üretiyor. Ben yüksek volatilite dönemlerinde 3-3.5, daha sakin dönemlerde 2.5 kullanıyorum.
Halka açıklık oranı düşük hisselerde Süpertrend sinyalleri güvenilmez. İnce piyasada birkaç büyük lot fiyatı oynatabilir. Günlük hacim filtresi eklemek zorunlu.
Seans saatleri: BIST sabah 10:00'da açılıyor. İlk mumdaki gap'ler Süpertrend'in stop seviyesini geçebilir ve pozisyon beklenenden kötü bir fiyattan kapanabilir.
Sonuç
- Süpertrend, net giriş-çıkış kuralları olan ve dinamik stop sağlayan güçlü bir araç.
- Tek başına kullanmak yerine hacim konfirmasyonu ve trend filtresi ile desteklemek sinyal kalitesini artırıyor.
- BIST'te en iyi çalıştığı koşul: net trend dönemleri. Yatay piyasalarda multiplier artırılmalı ya da sistem devre dışı bırakılmalı.
- Bir sonraki adım: RSI overbought/oversold filtresi ekleyerek aşırı gergin seviyelerde giriş almamak.
Bu yazıdaki analizler ve kodlar eğitim amaçlıdır; yatırım tavsiyesi değildir.