
AlphaTrend, piyasadaki trendin yönünü belirlemek için geliştirilen çoğu indikatörün aksine yüksek doğruluk oranı ve gelişmiş adaptasyon yeteneği sayesinde, hem ani piyasa dalgalanmalarını güvenilir şekilde tespit eder hem de uzun vadeli trend değişimlerini erken safhada öngörerek yatırımcılara stratejik avantajlar sunar. Ünlü Ekonomist Kıvanç Özbilgiç’in TradingView’de TypeScript ile ortaya koyduğu bu yapı, temel olarak aşağıda bahsedilen prensiplere dayanıyor.
Tam Kod
from binance import Client
import csv
import pandas as pd
from datetime import datetime
import pandas_ta as ta
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
from matplotlib.ticker import FuncFormatter
import os
import subprocess
client = Client(None, None)
def verileriGetir(sembol, periyot, baslangic, bitis):
mumlar = client.get_historical_klines(sembol, periyot, baslangic, bitis)
return mumlar
def csvOlustur(sembol, mumlar):
csvDosya = open(sembol + ".csv", 'w', newline='')
yazici = csv.writer(csvDosya, delimiter=',')
for mumverileri in mumlar:
yazici.writerow(mumverileri)
csvDosya.close()
def zamanHesapla(timestamp):
return datetime.fromtimestamp(timestamp / 1000)
def indikator(okunacakCsv):
basliklar = ['open_time', 'open', 'high', 'low', 'close', 'vol',
'close_time', 'qav', 'nat', 'tbbav', 'tbqav', 'ignore']
df = pd.read_csv(okunacakCsv, names=basliklar)
open_ = df['open'].astype(float)
close = df['close'].astype(float)
high = df['high'].astype(float)
low = df['low'].astype(float)
volume = df['vol'].astype(float)
ap = 14
tr = ta.true_range(high, low, close)
atr = ta.sma(tr, ap)
noVolumeData = False
coeff = 1
upt = []
downT = []
Trend = [0.0]
src = close
rsi = ta.rsi(src, ap)
mfi = ta.mfi(high, low, close, volume, ap)
for i in range(len(low)):
if pd.isna(atr[i]):
upt.append(0)
else:
upt.append(low[i] - (atr[i] * coeff))
for i in range(len(high)):
if pd.isna(atr[i]):
downT.append(0)
else:
downT.append(high[i] + (atr[i] * coeff))
for i in range(1, len(close)):
if noVolumeData and rsi[i] >= 50:
if upt[i] < Trend[i - 1]:
Trend.append(Trend[i - 1])
else:
Trend.append(upt[i])
elif not noVolumeData and mfi[i] >= 50:
if upt[i] < Trend[i - 1]:
Trend.append(Trend[i - 1])
else:
Trend.append(upt[i])
else:
if downT[i] > Trend[i - 1]:
Trend.append(Trend[i - 1])
else:
Trend.append(downT[i])
k1 = Trend
k2 = [0, 0] + Trend[:-2] # Trend'in 2 birim kaydırılmış hali
at = pd.DataFrame({'k1': k1, 'k2': k2})
return at
def BackTest(sembol, bakiye, baslangic_bakiye):
try:
cuzdan = bakiye
baslangic_cuzdan = baslangic_bakiye
alimSayisi = 0
satimSayisi = 0
toplamKoin = 0
komisyonOrani = 0.00075 # %0.075 komisyon oranı
komisyon = 0
csvName = sembol + ".csv"
basliklar = ['open_time', 'open', 'high', 'low', 'close', 'vol',
'close_time', 'qav', 'nat', 'tbbav', 'tbqav', 'ignore']
df = pd.read_csv(csvName, names=basliklar)
acilisZamani = df['open_time']
kapanis = df['close'].astype(float)
at = indikator(csvName)
k1 = at['k1']
k2 = at['k2']
sinyalSirasi = ['s']
alis_kapanis = []
satis_kapanis = []
alis_zaman = []
satis_zaman = []
output_file = open("Backtest_Sonuclari.txt", "w", encoding='utf-8')
for i in range(1, at.shape[0]):
# Alış sinyali
if k1[i - 1] <= k2[i - 1] and k1[i] > k2[i] and sinyalSirasi[-1] != 'a':
if cuzdan > 0:
alimSayisi += 1
alis_kapanis.append(kapanis[i])
alis_zaman.append(acilisZamani[i])
islem_tutari = cuzdan
komisyon_tutar = komisyonOrani * islem_tutari
komisyon += komisyon_tutar
net_bakiye = islem_tutari - komisyon_tutar
toplamKoin = net_bakiye / kapanis[i]
output_file.write(
f"{zamanHesapla(acilisZamani[i])} tarihinde "
f"{kapanis[i]} fiyatından {round(toplamKoin, 6)} "
f"adet {sembol} alındı\n"
)
sinyalSirasi.append('a')
cuzdan = 0
else:
sinyalSirasi.append('a')
# Satış sinyali
elif k1[i - 1] >= k2[i - 1] and k1[i] < k2[i] and sinyalSirasi[-1] != 's':
if toplamKoin > 0:
satimSayisi += 1
satis_kapanis.append(kapanis[i])
satis_zaman.append(acilisZamani[i])
islem_tutari = toplamKoin * kapanis[i]
komisyon_tutar = komisyonOrani * islem_tutari
komisyon += komisyon_tutar
net_tutar = islem_tutari - komisyon_tutar
cuzdan = net_tutar
output_file.write(
f"{zamanHesapla(acilisZamani[i])} tarihinde "
f"{kapanis[i]} fiyatından {round(toplamKoin, 6)} "
f"adet {sembol} satıldı\n"
)
sinyalSirasi.append('s')
toplamKoin = 0
else:
sinyalSirasi.append('s')
# Backtest sonucu
output_file.write("-----------------------------------\n")
output_file.write(f"Başlangıç Spot Cüzdan : ${round(baslangic_cuzdan, 2)}\n")
output_file.write(f"Toplam verilen Komisyon : ${round(komisyon, 2)}\n")
if toplamKoin > 0:
son_fiyat = kapanis.iloc[-1]
mevcut_deger = toplamKoin * son_fiyat
output_file.write(f"Son Cüzdan (Nakit): ${round(cuzdan, 2)}\n")
output_file.write(f"Kalan {sembol} miktarı : {round(toplamKoin, 6)} adet\n")
output_file.write(f"Kalan {sembol} değeri (Son fiyattan): ${round(mevcut_deger, 2)}\n")
output_file.write(f"Toplam Portföy Değeri: ${round(cuzdan + mevcut_deger, 2)}\n")
else:
output_file.write(f"Son Cüzdan : ${round(cuzdan, 2)}\n")
output_file.write(f"Toplam Portföy Değeri: ${round(cuzdan, 2)}\n")
output_file.write(f"Toplam Alım Sayısı : {alimSayisi}\n")
output_file.write(f"Toplam Satım Sayısı : {satimSayisi}\n")
output_file.write("-----------------------------------\n")
output_file.close()
sinyal_grafigi(acilisZamani, kapanis, alis_zaman, alis_kapanis,
satis_zaman, satis_kapanis, sembol)
except Exception as e:
print("Bir hata oluştu:", e)
def verigetirmefonksiyonu(sembol, tarih1, tarih2):
csvOlustur(sembol, verileriGetir(sembol, Client.KLINE_INTERVAL_1DAY, tarih1, tarih2))
print(sembol, "Veriler Getirildi.")
def sinyal_grafigi(acilisZamani, kapanis, alis_zaman, alis_kapanis,
satis_zaman, satis_kapanis, sembol):
acilisZamani = [zamanHesapla(zaman) for zaman in acilisZamani]
alis_zaman = [zamanHesapla(zaman) for zaman in alis_zaman]
satis_zaman = [zamanHesapla(zaman) for zaman in satis_zaman]
plt.figure(figsize=(16, 8), dpi=100)
plt.plot(acilisZamani, kapanis, color='black', linewidth=1.1, label='Kapanış Fiyatı')
plt.scatter(alis_zaman, alis_kapanis, color='green', marker='^', s=100, label='Alış Sinyali')
plt.scatter(satis_zaman, satis_kapanis, color='red', marker='v', s=100, label='Satış Sinyali')
plt.title(f'Alış ve Satış Sinyalleri - {sembol}', fontsize=16)
plt.xlabel('Tarih', fontsize=14)
plt.ylabel('Fiyat (USD)', fontsize=14)
ax = plt.gca()
date_format = mdates.DateFormatter('%d-%m-%Y')
ax.xaxis.set_major_formatter(date_format)
plt.xticks(rotation=45)
plt.grid(True, which='both', linestyle='--', linewidth=0.5, alpha=0.7)
def y_axis_format(y, pos):
return '${:,.0f}'.format(y)
ax.yaxis.set_major_formatter(FuncFormatter(y_axis_format))
plt.legend(fontsize=12)
plt.tight_layout()
plt.savefig('sinyal_grafigi.png')
plt.close()
# Parametreler
okunacakCsv = 'SOLUSDT.csv'
tarih_araligi_1 = '1 Jan 2020'
tarih_araligi_2 = '02 Dec 2024'
bakiye = 100
baslangic_bakiye = 100
sembol = okunacakCsv[:-4]
verigetirmefonksiyonu(sembol, tarih_araligi_1, tarih_araligi_2)
BackTest(sembol, bakiye, baslangic_bakiye)
def open_file(file_path):
try:
if os.name == 'nt':
os.system(f"start {file_path}")
elif os.name == 'posix':
subprocess.Popen(['open', file_path])
except Exception as e:
print(f"{file_path} dosyası açılamadı: {e}")
open_file('sinyal_grafigi.png')
open_file('Backtest_Sonuclari.txt')
1. Temel Yapı
ATR (Average True Range): Fiyatların oynaklığını ölçmek için yüksek, düşük ve kapanış fiyatları kullanılarak ATR hesaplanıyor. Bu değer, 14 periyotluk basit hareketli ortalama ile pürüzsüzleştiriliyor.
Trend Çizgileri (upt ve downT):
- upt: Düşük fiyattan ATR’nin katsayılı değeri çıkarılarak elde ediliyor
- downT: Yüksek fiyata ATR’nin katsayılı değeri eklenerek hesaplanıyor
Koşullu Güncelleme: RSI veya MFI gibi hacim ve momentum
göstergelerine bağlı olarak, piyasa koşullarına uyum sağlayan dinamik
bir trend çizgisi (k1) oluşturuluyor. Eğer MFI/RSI 50’nin üzerindeyse
destek hattı esas alınırken, aksi durumda direnç hattı kullanılıyor.
2. Python’a Adaptasyon ve Backtest Mantığı
a. Veri Çekimi ve CSV Oluşturma
Veri Çekimi: verileriGetir(sembol, periyot, baslangic, bitis)
fonksiyonu, Binance API’si üzerinden belirlenen tarih aralığındaki mum
(candlestick) verilerini getirir.
CSV Oluşturma: csvOlustur(sembol, mumlar) fonksiyonu, çekilen
verileri CSV dosyasına yazar. Bu, pandas kütüphanesiyle veri analizi
yapmayı kolaylaştırır.
b. AlphaTrend Hesaplamaları
Veri Hazırlığı: indikator(okunacakCsv) fonksiyonu, CSV’deki
verileri pandas DataFrame’e aktarır ve gerekli sütunları float tipine
çevirir.
Teknik Göstergeler:
- ATR Hesaplama:
pandas_takütüphanesi kullanılarak ATR hesaplanır ve 14 periyotluk ortalama alınır - RSI, MFI ve HLC3 Hesaplamaları: Bu göstergeler de aynı kütüphane yardımıyla elde edilir
Trend Hesaplaması: Her periyotta, upt ve downT dizileri
hesaplanır. Ardından, önceki periyodun trend değeriyle kıyas yapılarak,
mevcut periyodun trend değeri (k1) belirlenir. Bu basit koşul
ifadeleri, alım-satım sinyallerini oluşturmak için kullanılır.
c. Backtest İşlemi
BackTest(sembol, bakiye, baslangic_bakiye) fonksiyonu, stratejinin
geçmiş veriler üzerinde nasıl performans gösterdiğini test eder.
İşleyiş şu şekilde:
Başlangıç Ayarları: Cüzdan bakiyesi, başlangıç bakiyesi, işlem sayıları, toplam coin miktarı ve komisyon oranı (örneğin, %0.075) tanımlanır.
Veri ve Gösterge Entegrasyonu: Daha önce oluşturulan CSV dosyası
pandas ile okunur. indikator fonksiyonu ile hesaplanmış trend verileri
(k1 ve k2) elde edilir.
İşlem Sinyalleri Üretimi:
- Alım Sinyali: Eğer bir önceki periyotta
k1,k2’nin altında olup mevcut periyottak1,k2’yi yukarı keserse ve cüzdanda nakit varsa, tüm nakit ile alım yapılır - Satış Sinyali:
k1’in aşağı kesişi gerçekleştiğinde, eldeki coin’ler nakde çevrilir
İşlemler sırasında komisyon hesaplamaları titizlikle uygulanır.
Sonuçların Raporlanması: İşlem detayları
Backtest_Sonuclari.txt dosyasına yazılır. sinyal_grafigi fonksiyonu
ile matplotlib kullanılarak grafiksel rapor oluşturulur.
3. Gerekli Kütüphaneler
Projenin çalışması için aşağıdaki Python kütüphanelerine ihtiyaç var:
- python-binance: Binance API’sinden veri çekmek için
- pandas: Veri işleme ve analiz için
- pandas_ta: Teknik analiz göstergelerinin hesaplanması için
- matplotlib: Grafik oluşturma ve raporlama için
4. Projeyi Çalıştırma Adımları
1. Sanal Ortam Oluşturma:
python -m venv venv
Sanal ortamı aktive edin:
- Windows:
venv\Scripts\activate - macOS/Linux:
source venv/bin/activate
2. Kütüphanelerin Yüklenmesi:
pip install -r requirements.txt
3. Kodu Çalıştırma:
python backtest.py
4. Sonuçları İnceleyin:
Oluşturulan Backtest_Sonuclari.txt ve sinyal_grafigi.png dosyalarını
kontrol edin.
5. Sonuç
Bu yazıda, Kıvanç Özbilgiç’in geliştirdiği AlphaTrend göstergesinin temel prensiplerini ve Python’a adaptasyonunu profesyonel bir yaklaşımla ele aldık. İndikatörün hesaplama adımlarından backtest sürecine kadar her aşama, net ve sistematik bir biçimde detaylandırıldı.
Kıvanç Özbilgiç’in bu değerli katkısı, stratejik analiz süreçlerimizi önemli ölçüde optimize etmemize olanak sağlamış ve iş akışlarımızı sadeleştirmiştir. Bu bağlamda, kendisine samimi teşekkürlerimizi sunuyoruz.