SDC

  • Menü
    • Teknik Analiz
    • BorsaPin
    • Bitmeyen Senfoni
    • Halet-i Ruhiye
    • Anlık Tepkiler
    • Teknoloji
    • Karma Karışık
  • Hakkında
  • İletişim
  • BorsaPin
  • Home
  • Menü
    • Teknik Analiz
    • BorsaPin
    • Bitmeyen Senfoni
    • Halet-i Ruhiye
    • Anlık Tepkiler
    • Teknoloji
    • Karma Karışık
  • Hakkında
  • İletişim
  • BorsaPin

İdeal EMA Dizilim (EMA ALIGNMENT) Trading View İndikatörü

03 Ağustos 2025 BorsaPin, İndikatör, Teknik Analiz, Trading Viewalgoritmik analiz, borsa teknik göstergeler, EMA alarm sinyali, Ema Alignment, EMA analiz, EMA destek direnç, EMA dizilim indikatörü, EMA sıralama mantığı, EMA stratejisi, EMA tablosu, EMA trend tespiti, ideal EMA sıralaması, Pine Script EMA, potansiyel trend oluşumu, Teknik Analiz, tradingview EMA indikatörü, tradingview strateji, Üstel Hareketli Ortalama, yatırım stratejileri

Trend takibi, finansal piyasalarda başarılı işlem stratejilerinin temelini oluşturur. Bu kapsamda, hareketli ortalamalar (MA) özellikle Exponential Moving Average (EMA), piyasa yönünü ve momentumunu belirlemede sıklıkla tercih edilen araçlardır. “Ideal EMA Dizilim” adlı bu özel gösterge, çoklu EMA’ların sıralanışını analiz ederek trendin gücünü ve netliğini ölçmeyi amaçlıyor. Önceki Makalelerde Python ile kapanış verilerini çektik, o verilerle Ema periyodlarını belirledik sonrasında ise Python ile İdeal Ema sinyallerini oluşturan  betiklede  bu sinyalleri Excele dökmüştük.

Ideal EMA Dizilim (EMA ALIGNMENT)

Kullanılan EMA Periyotları

Gösterge, aşağıdaki 10 adet üstel hareketli ortalamayı (EMA) hesaplar:

  • EMA 5, 8, 13, 21, 34, 55, 89, 144, 233, 370

Bu periyotlar kısa, orta ve uzun vadeli eğilimleri birlikte analiz etmeye olanak tanır.

Dizilim Mantığı

EMA dizilimleri büyükten küçüğe (azalan) veya küçükten büyüğe (artan) doğru sıralanabilir.

  • Fiyat, en büyük EMA’nın üzerindeyse ve EMA’lar azalan sıradaysa → İdeal EMA Yükseliş
  • Fiyat, en küçük EMA’nın altındaysa ve EMA’lar artan sıradaysa → İdeal EMA Düşüş
  • Diğer durumlarda → İdeal EMA Nötr
Dizilim kontrolü için array yapısı ve for döngüsü kullanılır.

Potansiyel Oluşum

Fiyat, en düşük ve en yüksek EMA arasında yer alıyorsa bu durum Potansiyel Oluşum olarak değerlendirilir. Trend dönüşü veya başlangıcı ihtimali yüksektir.

Grafiklerde Gösterim

  • EMA çizgileri renkli ve ayrı ayrı açılıp kapatılabilir.
  • Arka Plan Renkleri:
    • Yeşil: İdeal EMA Yükseliş
    • Kırmızı: İdeal EMA Düşüş
    • Sarı: Potansiyel oluşum
Tablo Gösterim
  • Mevcut EMA durumu
  • Son sinyalin tarihi ve kaç bar önce oluştuğu
  • Her EMA’nın değeri ve kapanış fiyatına göre fark oranı (%)
  • Tablo pozisyonu ve boyutu kullanıcı tarafından ayarlanabilir.

Bir Önceki Makaledeki Python idealEmaDizilim tarama çalışması dosyasıyla uyumlu çalışır.

Trading View Pine Script İdeal Ema Dizilim İndikatör Kodu

// Bu, Pine Script™ kodu Mozilla Kamu Lisansı 2.0 (MPL-2.0) altında lisanslandı
// © krstsntrk © BorsaPin codeispriority
// Saraylarda süremem, Dağlarda sürdüğümü. Bin cihana değişmem Şu öksüz Türk'lüğümü... Atsız
// @version=6

indicator("BorsaPin IdealEMA Dizilim (EMA ALIGNMENT) ", shorttitle="BorsaPin IdealEMA Dizilim (EMA ALIGNMENT)", overlay=true)

// Ayarlar
show_table = input.bool(true, "Tabloyu Göster", group="Görünüm")
table_position = input.string("Sağ Alt", "Tablo Konumu", options=["Sol Üst", "Orta Üst", "Sağ Üst", "Sol Orta", "Tam Orta", "Sağ Orta", "Sol Alt", "Orta Alt", "Sağ Alt"], group="Görünüm")
table_size = input.string("Küçük", "Tablo Boyutu", options=["Çok Küçük", "Küçük", "Normal", "Büyük"], group="Görünüm")
show_ema_lines = input.bool(true, "EMA Cizgilerini Goster", group="EMA Ayarlari")
show_background = input.bool(true, "Arka Plan Renklerini Goster", group="EMA Ayarlari")

// EMA gorunurluk ayarlari
show_ema5 = input.bool(true, "EMA 5", inline="ema1", group="EMA Cizgileri")
show_ema8 = input.bool(true, "EMA 8", inline="ema1", group="EMA Cizgileri")
show_ema13 = input.bool(true, "EMA 13", inline="ema2", group="EMA Cizgileri")
show_ema21 = input.bool(true, "EMA 21", inline="ema2", group="EMA Cizgileri")
show_ema34 = input.bool(true, "EMA 34", inline="ema3", group="EMA Cizgileri")
show_ema55 = input.bool(true, "EMA 55", inline="ema3", group="EMA Cizgileri")
show_ema89 = input.bool(true, "EMA 89", inline="ema4", group="EMA Cizgileri")
show_ema144 = input.bool(true, "EMA 144", inline="ema4", group="EMA Cizgileri")
show_ema233 = input.bool(true, "EMA 233", inline="ema5", group="EMA Cizgileri")
show_ema370 = input.bool(true, "EMA 370", inline="ema5", group="EMA Cizgileri")

// EMA Periyodları (Python kodundaki ile aynı)
ema5 = ta.ema(close, 5)
ema8 = ta.ema(close, 8)
ema13 = ta.ema(close, 13)
ema21 = ta.ema(close, 21)
ema34 = ta.ema(close, 34)
ema55 = ta.ema(close, 55)
ema89 = ta.ema(close, 89)
ema144 = ta.ema(close, 144)
ema233 = ta.ema(close, 233)
ema370 = ta.ema(close, 370)

// EMA'ları dizi olarak tanımlama
ema_values = array.new<float>()
array.push(ema_values, ema5)
array.push(ema_values, ema8)
array.push(ema_values, ema13)
array.push(ema_values, ema21)
array.push(ema_values, ema34)
array.push(ema_values, ema55)
array.push(ema_values, ema89)
array.push(ema_values, ema144)
array.push(ema_values, ema233)
array.push(ema_values, ema370)

ema_periods = array.new<int>()
array.push(ema_periods, 5)
array.push(ema_periods, 8)
array.push(ema_periods, 13)
array.push(ema_periods, 21)
array.push(ema_periods, 34)
array.push(ema_periods, 55)
array.push(ema_periods, 89)
array.push(ema_periods, 144)
array.push(ema_periods, 233)
array.push(ema_periods, 370)

// İdeal Ema Dizilim hesaplama

// Dizilimin sirali olup olmadigini kontrol etme fonksiyonu
is_descending_order(ema_array) =>
    size = array.size(ema_array)
    is_desc = true
    for i = 0 to size - 2
        if array.get(ema_array, i) < array.get(ema_array, i + 1)
            is_desc := false
            break
    is_desc

is_ascending_order(ema_array) =>
    size = array.size(ema_array)
    is_asc = true
    for i = 0 to size - 2
        if array.get(ema_array, i) > array.get(ema_array, i + 1)
            is_asc := false
            break
    is_asc

// Maximum ve minimum EMA değerlerini bulma
max_ema = math.max(ema5, math.max(ema8, math.max(ema13, math.max(ema21, math.max(ema34, math.max(ema55, math.max(ema89, math.max(ema144, math.max(ema233, ema370)))))))))
min_ema = math.min(ema5, math.min(ema8, math.min(ema13, math.min(ema21, math.min(ema34, math.min(ema55, math.min(ema89, math.min(ema144, math.min(ema233, ema370)))))))))

// Ideal EMA dizilim kontrolu (Python kodumuzdaki mantik)
ideal_ema_status = ""
if close > max_ema and is_descending_order(ema_values)
    ideal_ema_status := "Ideal EMA Yukselis"
else if close < min_ema and is_ascending_order(ema_values)
    ideal_ema_status := "Ideal EMA Dusus"
else
    ideal_ema_status := "Ideal EMA Notr"

// Potansiyel olusum kontrolu
is_potential = close > min_ema and close < max_ema

// Sinyal degisimi tespiti
var string prev_status = ""
var int signal_bar = 0
var string signal_date = ""

if ideal_ema_status != prev_status
    prev_status := ideal_ema_status
    signal_bar := bar_index
    signal_date := str.tostring(year) + "-" + str.tostring(month, "00") + "-" + str.tostring(dayofmonth, "00")

// Görseller

// EMA cizgileri - sadece secilenleri goster
plot(show_ema_lines and show_ema5 ? ema5 : na, "EMA 5", color=color.new(color.red, 0), linewidth=1)
plot(show_ema_lines and show_ema8 ? ema8 : na, "EMA 8", color=color.new(color.orange, 0), linewidth=1)
plot(show_ema_lines and show_ema13 ? ema13 : na, "EMA 13", color=color.new(color.yellow, 0), linewidth=1)
plot(show_ema_lines and show_ema21 ? ema21 : na, "EMA 21", color=color.new(color.green, 0), linewidth=1)
plot(show_ema_lines and show_ema34 ? ema34 : na, "EMA 34", color=color.new(color.blue, 0), linewidth=1)
plot(show_ema_lines and show_ema55 ? ema55 : na, "EMA 55", color=color.new(color.purple, 0), linewidth=1)
plot(show_ema_lines and show_ema89 ? ema89 : na, "EMA 89", color=color.new(color.gray, 0), linewidth=1)
plot(show_ema_lines and show_ema144 ? ema144 : na, "EMA 144", color=color.new(color.maroon, 0), linewidth=1)
plot(show_ema_lines and show_ema233 ? ema233 : na, "EMA 233", color=color.new(color.navy, 0), linewidth=1)
plot(show_ema_lines and show_ema370 ? ema370 : na, "EMA 370", color=color.new(color.black, 0), linewidth=2)

// Sinyal noktalarini isaretleme - sadece secildiginde goster
signal_color = show_background ? (ideal_ema_status == "Ideal EMA Yukselis" ? color.new(color.green, 90) : ideal_ema_status == "Ideal EMA Dusus" ? color.new(color.red, 90) :  is_potential ? color.new(color.yellow, 95) : na) : na

bgcolor(signal_color)

// Tablo
if show_table and barstate.islast
    // Tablo pozisyonunu dinamik olarak ayarlama
    table_pos = table_position == "Sol Üst" ? position.top_left : table_position == "Orta Üst" ? position.top_center : table_position == "Sağ Üst" ? position.top_right :  table_position == "Sol Orta" ? position.middle_left : table_position == "Tam Orta" ? position.middle_center : table_position == "Sağ Orta" ? position.middle_right :  table_position == "Sol Alt" ? position.bottom_left : table_position == "Orta Alt" ? position.bottom_center : position.bottom_right


    t_size = table_size == "Çok Küçük" ? size.tiny :  table_size == "Küçük" ? size.small : table_size == "Büyük" ? size.large :  size.normal
    
    // Ana tablo olusturma
    info_table = table.new(table_pos, 3, 15, bgcolor=color.new(color.white, 0), border_width=2, border_color=color.new(color.gray, 0))
    
    // Baslik satiri
    table.cell(info_table, 0, 0, "EMA DIZILIM ANALIZI", text_color=color.white, bgcolor=color.new(color.blue, 0), text_size=t_size)
    table.merge_cells(info_table, 0, 0, 2, 0)
    
    // Mevcut durum
    status_color = ideal_ema_status == "Ideal EMA Yukselis" ? color.new(color.green, 70) :
                   ideal_ema_status == "Ideal EMA Dusus" ? color.new(color.red, 70) :
                   color.new(color.gray, 70)
    
    table.cell(info_table, 0, 1, "Mevcut Durum:", text_color=color.black, bgcolor=color.new(color.silver, 70), text_size=t_size)
    table.cell(info_table, 1, 1, ideal_ema_status, text_color=color.black, bgcolor=status_color, text_size=t_size)
    table.cell(info_table, 2, 1, is_potential ? "Potansiyel ✓" : "", text_color=color.black, bgcolor=color.new(color.yellow, 80), text_size=t_size)
    
    // Son sinyal bilgisi
    table.cell(info_table, 0, 2, "Son Sinyal:", text_color=color.black, bgcolor=color.new(color.silver, 70), text_size=t_size)
    table.cell(info_table, 1, 2, signal_date, text_color=color.black, bgcolor=color.new(color.white, 50), text_size=t_size)
    table.cell(info_table, 2, 2, str.tostring(bar_index - signal_bar) + " bar once", text_color=color.black, bgcolor=color.new(color.white, 50), text_size=t_size)
    
    // EMA bilgileri baslik
    table.cell(info_table, 0, 3, "EMA", text_color=color.white, bgcolor=color.new(color.navy, 0), text_size=t_size)
    table.cell(info_table, 1, 3, "Deger", text_color=color.white, bgcolor=color.new(color.navy, 0), text_size=t_size)
    table.cell(info_table, 2, 3, "Kapanis Orani", text_color=color.white, bgcolor=color.new(color.navy, 0), text_size=t_size)
    
    // EMA degerleri ve oranlari
    ema_list = array.from(ema5, ema8, ema13, ema21, ema34, ema55, ema89, ema144, ema233, ema370)
    ema_names = array.from("EMA 5", "EMA 8", "EMA 13", "EMA 21", "EMA 34", "EMA 55", "EMA 89", "EMA 144", "EMA 233", "EMA 370")
    
    for i = 0 to 9
        row = i + 4
        ema_val = array.get(ema_list, i)
        ema_name = array.get(ema_names, i)
        ratio = (close / ema_val - 1) * 100
        
        // Renk belirleme (kapanis fiyatina gore) - pastel renkler
        cell_color = close > ema_val ? color.new(color.green, 80) : color.new(color.red, 80)
        
        table.cell(info_table, 0, row, ema_name, text_color=color.black, bgcolor=color.new(color.white, 70), text_size=t_size)
        table.cell(info_table, 1, row, str.tostring(math.round(ema_val, 2)), text_color=color.black, bgcolor=cell_color, text_size=t_size)
        table.cell(info_table, 2, row, str.tostring(math.round(ratio, 2)) + "%", text_color=color.black, bgcolor=cell_color, text_size=t_size)

// Sinyal degisimi icin alarm
alertcondition(ideal_ema_status != prev_status[1], "Ideal EMA Sinyal Degisimi", "Ideal EMA durumu degisti")
// Spesifik sinyaller icin alarm
alertcondition(ideal_ema_status == "Ideal EMA Yukselis" and prev_status[1] != "Ideal EMA Yukselis", "Ideal EMA Yukselis", "Ideal EMA Yukselis sinyali olustu!")
alertcondition(ideal_ema_status == "Ideal EMA Dusus" and prev_status[1] != "Ideal EMA Dusus", "Ideal EMA Dusus", "Ideal EMA Dusus sinyali olustu!")
// Potansiyel olusum alarmı
alertcondition(is_potential and not is_potential[1], "Potansiyel Olusim", "Ideal EMA potansiyel olusum tespit edildi!")

 

Python ile İdeal EMA ALIGNMENT Stratejisi Betiği

03 Ağustos 2025 BorsaPin, Python, Teknik Analizalgoritmik ticaret, borsa eğitimi, borsa robotu, borsa stratejileri, ema göstergesi, finansal analiz, hisse senedi alım satım, hisse senedi analizi, ideal ema nasıl kullanılır, ideal ema nedir, ideal ema stratejisi, kod otomasyonu, numpy, openpyxl, otomatik analiz, pandas, piyasa momentumu, programlama, Python, python ile borsa, python ile finans, python kodlama, python projeleri, Teknik Analiz, trend analizi, Üstel Hareketli Ortalama, yatırım stratejileri, yatırımcı rehberi


Hisse senedi piyasalarında başarılı olmak için doğru stratejileri belirlemek büyük önem taşır. Bu stratejilerden biri olan Üstel Hareketli Ortalama (Exponential Moving Average – EMA), fiyat hareketlerinin daha yumuşak ve tepkisel bir şekilde izlenmesini sağlar. Birden fazla EMA’nın bir araya getirilerek kullanıldığı İdeal EMA Stratejisi ise yatırımcılara trendin gücü, yönü ve olası dönüş noktaları hakkında kapsamlı bir bakış sunar. Bu yazıda stratejiyi Python kodları ile nasıl uygulayabileceğinizi ve analizlerinizi nasıl otomatikleştirebileceğinizi ele alacağız.

İdeal EMA Nedir?

İdeal EMA, belirli periyotlardaki üstel hareketli ortalamaların (örneğin 5, 8, 13, 21, 34, 55, 89…) birbirine göre dizilimini temel alan bir analiz yöntemidir. Bu stratejinin ana mantığı, bir hisse senedinin fiyatı ve EMA’larının belirli bir sırayla dizilmesi durumunda güçlü bir trendin varlığını işaret etmesidir.

  • İdeal EMA Yükseliş: Fiyat en kısa EMA’nın (örneğin 5 EMA) üzerinde, o da bir sonraki kısa EMA’nın (örneğin 8 EMA) üzerinde olacak şekilde, tüm EMA’lar büyükten küçüğe sıralandığında ve kapanış fiyatı tüm EMA’ların üzerindeyse bir yükseliş trendi sinyali üretir. Bu durum, piyasada alıcıların kontrolü ele aldığını ve güçlü bir yukarı yönlü momentumun oluştuğunu gösterir.
  • İdeal EMA Düşüş: Tersi durumda, kapanış fiyatı tüm EMA’ların altında kaldığında ve EMA’lar küçükten büyüğe sıralandığında bir düşüş trendi sinyali üretir. Bu, satıcıların piyasada baskın olduğunu ve fiyatların aşağı yönlü hareket etmeye devam edebileceğini gösterir.
  • Nötr veya Potansiyel Durum: Eğer EMA’lar birbirine karışık bir şekilde dizilmişse veya kapanış fiyatı EMA’lar arasında kalıyorsa, bu durum nötr bir piyasa yapısına veya potansiyel bir trend başlangıcına işaret edebilir.

 

Python ile İdeal EMA Stratejisi Nasıl Uygulanır?

Yazının devamında paylaşacağım Python kodu, bu stratejiyi otomatikleştirmek için tasarlanmıştır.
IdealEMACalculator adlı bir sınıf etrafında kurgulanan bu kod, birden fazla hisse senedi dosyasını analiz ederek İdeal EMA sinyallerini tespit eder ve sonuçları Excel dosyasına kaydeder.

1. Kodun Yapısı ve Kullanımı

  1. IdealEMACalculator sınıfı başlatılır. Bu sınıf, analiz edilecek EMA periyotlarını (ema_periods) ve sonuçları saklamak için gerekli listeleri (ideal_up, ideal_down vb.) içerir.
  2. main() metodu çağrıldığında, StokData/Emas/ klasöründeki tüm Excel dosyalarını (.xlsx) bulur. Her bir dosya, bir hisse senedine ait fiyat ve EMA verilerini içerir.
  3. process_single_file() metodu, her bir hisse senedi dosyası için EMA dizilimini kontrol eder. Bu kontrol, kapanış fiyatının EMA’lara göre konumunu ve EMA’ların kendi aralarındaki sıralamasını esas alır.
  4. Analiz sonucunda, hisse senedinin son durumu İdeal EMA Yükseliş, İdeal EMA  Düşüş veya Nötr olarak sınıflandırılır. Ayrıca, fiyat EMA’lar arasında sıkışmışsa bir “Potansiyel” durumun da raporlanır.
  5. Kod, sadece anlık durumu değil, aynı zamanda son İdeal EMA sinyalinin tarihini ve bu sinyalden sonraki en yüksek/en düşük fiyatları da hesaplar. Böylece, stratejinin performansını ölçmek için gerekli veriler toplanır.
  6. Tüm dosyalar işlendikten sonra save_results() metodu devreye girer. Bu metot, elde edilen sonuçları kategorilere ayırarak ayrı sekmelerde olmak üzere tek bir Excel dosyasına kaydeder. Hem ana bir çıktı dosyası (idealema_analiz.xlsx) hem de tarihli bir arşiv dosyası oluşturulur.
  7. Son olarak, kod başarılı ve başarısız dosyaların sayısını, tespit edilen sinyalleri ve son bir yıllık sinyallerin ortalama kazanç gibi istatistiklerini içeren bir özet raporunu konsola yazdırır.

 

2. Metotların Fonksiyonları ve Önemi

Kod, modüler bir yapıya sahip. Bu yapı sayesinde, her bir metot belirli bir işi yapar ve kodun anlaşılırlığı artar.

  • check_alignment(): Verilen hisse senedi satırındaki kapanış fiyatı ve EMA değerlerini kullanarak İdeal EMA dizilimini kontrol eden ana mantık motorudur.
  • calculate_gain(): Giriş ve çıkış fiyatlarına göre kazanç ve kazanç yüzdesini hesaplayan statik bir metottur.
  • find_max_price_after_signal() ve find_min_price_after_signal(): Bir sinyalden sonraki en yüksek veya en düşük fiyatı bulur. Bu metotlar, stratejinin potansiyel kazancını ölçmek için kritik öneme sahiptir.
  • process_single_file(): Her bir hisse senedi dosyasını okur, gerekli kontrolleri yapar ve sinyal verilerini toplar. Bu metot, kodun try…except blokları sayesinde dosya okuma veya veri hatalarına karşı oldukça dayanıklıdır.
  • write_sheet(): Pandas DataFrame’ini Excel sayfasına yazmak ve sütun genişlikleri, başlık biçimlendirmesi gibi temel görsel düzenlemeleri yapmak için kullanılır.
Bağımlı olduğu kütüphaneleri terminalde aşağıdaki komutla install edebilirsiniz.
pip install pandas numpy openpyxl colorama

Ema Alignment ( İdeal Ema Dizilim) Stratejisinin Değerlendirilmesi ve Potansiyeli

Python ile oluşturulan bu otomatize sistem, yatırımcılara manuel olarak yüzlerce hisse senedini tek tek inceleme zahmetinden kurtarır. Her gün yüzlerce veriyi otomatik olarak tarayarak potansiyel İdeal EMA  Dizilim sinyallerini anında tespit edebilir.

Yalnız unutmamak gerekir ki, hiçbir strateji her zaman kazanç sağlamaz. İdeal EMA stratejisi de tek başına yeterli olmayabilir. Genellikle hacim, diğer teknik göstergelerde ve temel analiz verileriyle birlikte kullanılması, sinyallerin güvenilirliğini artırır.

Bu Makale Daha önceki Makalelerin devamı niteliğinde olduğu için,  aşağıdaki makaleleri de incelemeniz büyük önem taşıyor.
Python ve PyCharm kurulumu
Gerekli kütüphanelerin kurulumu
Kapanış Datalarını çeken Script
Python ile Kapanış Fiyatlarından EMA Hesaplama Betiği
Çalışmaların tamamını içeren Google Drive Alanı

X_03_Borsapin_EmaDizilim.py Çalışmayı Bu isimde kayıt edebilirsiniz.
Python Kodları

import pandas as pd
import numpy as np
import os
from datetime import datetime, timedelta
from colorama import Fore, init
import glob
from openpyxl.styles import Font, PatternFill, Alignment
from openpyxl.utils import get_column_letter

"""
Borsapin StokData/Ema klasöründeki hisse datalarından EMA ALIGNMENT dizilimlerini hesaplar.
www.kursatsenturk.com

"""
init(autoreset=True)

class IdealEMACalculator:
def __init__(self):
self.ema_periods = [5, 8, 13, 21, 34, 55, 89, 144, 233, 370]
self.successful_files = []
self.failed_files = []

# Sonuç listeleri
self.ideal_up = []
self.ideal_down = []
self.neutral = []
self.potential = []
self.all_signals = []

def check_alignment(self, stock_row):
"""EMA dizilimi kontrolü"""
try:
ema_vals = [stock_row[f'EMA_{p}'] for p in self.ema_periods]
closing_price = stock_row['Kapanış']

# İdeal yükseliş: Kapanış &gt; tüm EMA'lar ve EMA'lar büyükten küçüğe sıralı
if closing_price &gt; max(ema_vals) and ema_vals == sorted(ema_vals, reverse=True):
return 'İdeal EMA Yükseliş'
# İdeal düşüş: Kapanış &lt; tüm EMA'lar ve EMA'lar küçükten büyüğe sıralı
elif closing_price &lt; min(ema_vals) and ema_vals == sorted(ema_vals):
return 'İdeal EMA Düşüş'
else:
return 'İdeal EMA Nötr'

except (KeyError, ValueError, TypeError) as e:
# Daha spesifik istisna yakalama
print(f"{Fore.RED}❌ EMA alignment kontrol hatası: {e}")
return 'İdeal EMA Nötr'

def check_potential(self, stock_row):
"""Potansiyel oluşum kontrolü"""
try:
ema_vals = [stock_row[f'EMA_{p}'] for p in self.ema_periods]
closing_price = stock_row['Kapanış']
return min(ema_vals) &lt; closing_price &lt; max(ema_vals)
except (KeyError, ValueError, TypeError):
# Basit durumlar için 'except:' kullanmak yerine 'except Exception' veya spesifik hataları kullanın
return False

def price_below_any_ema(self, stock_row):
"""Kapanış EMA'ların altına sarktı mı?"""
try:
return any(stock_row['Kapanış'] &lt; stock_row[f'EMA_{p}'] for p in self.ema_periods)
except (KeyError, ValueError, TypeError):
return False

@staticmethod
def calculate_gain(entry_price, exit_price):
"""Kazanç hesaplama fonksiyonu"""
if entry_price and exit_price and entry_price &gt; 0:
gain = exit_price - entry_price
gain_percent = (gain / entry_price) * 100
return gain, gain_percent
return 0, 0

@staticmethod
def find_max_price_after_signal(dataframe, signal_date):
"""Sinyal sonrası maksimum fiyat bulma"""
try:
future_data = dataframe[dataframe['Tarih'] &gt; signal_date]
if not future_data.empty:
max_price = future_data['Kapanış'].max()
max_date = future_data[future_data['Kapanış'] == max_price]['Tarih'].iloc[0]
return max_price, max_date
return None, None
except (KeyError, ValueError, IndexError):
return None, None

@staticmethod
def find_min_price_after_signal(dataframe, signal_date):
"""Sinyal sonrası minimum fiyat bulma"""
try:
future_data = dataframe[dataframe['Tarih'] &gt; signal_date]
if not future_data.empty:
min_price = future_data['Kapanış'].min()
min_date = future_data[future_data['Kapanış'] == min_price]['Tarih'].iloc[0]
return min_price, min_date
return None, None
except (KeyError, ValueError, IndexError):
return None, None

def find_latest_signal_date(self, dataframe, target_status):
"""İdeal EMA sinyalinin son oluştuğu tarihi bulma"""
try:
dataframe = dataframe.sort_values("Tarih").reset_index(drop=True)
last_status = None
latest_signal_date = None

for _, row in dataframe.iterrows():
current_status = self.check_alignment(row)
if current_status == target_status and last_status != target_status:
latest_signal_date = row['Tarih']
last_status = current_status

return latest_signal_date
except (KeyError, ValueError, IndexError):
return None

def process_single_file(self, file_path):
"""Tek dosya için İdeal EMA analizi"""
ticker_name = None # ticker_name değişkeni için başlangıç değeri atama
try:
# Dosya adından hisse adını alma
file_name = os.path.basename(file_path)
ticker_name = os.path.splitext(file_name)[0]

print(f"{Fore.YELLOW} İdeal EMA analizi: {ticker_name}...")

# Excel dosyasını okuma
df = pd.read_excel(file_path)

# Gerekli sütunların varlığını kontrol etme
required_columns = ['Tarih', 'Kapanış'] + [f'EMA_{p}' for p in self.ema_periods]
missing_columns = [col for col in required_columns if col not in df.columns]

if missing_columns:
raise ValueError(f"Eksik sütunlar: {missing_columns}")

# Veri kontrolü ve temizlik
df = df.dropna(subset=[f'EMA_{p}' for p in self.ema_periods])
if df.empty:
raise ValueError("EMA verileri boş")

# Tarih formatı ve sıralama
df['Tarih'] = pd.to_datetime(df['Tarih'])
df = df.sort_values('Tarih').reset_index(drop=True)

print(f"{Fore.CYAN} ⚡ EMA dizilim analizi yapılıyor...")

# Tüm sinyal değişimlerini takip et
last_status = None
signals_history = []

for _, row in df.iterrows():
status = self.check_alignment(row)
if status != last_status:
if last_status is not None: # İlk durumu kaydetme
signals_history.append({
'CODE': ticker_name,
'DATE': row["Tarih"],
'CLOSING_TL': row["Kapanış"],
'STATUS': status,
'PREV_STATUS': last_status
})
last_status = status

# Son durumu analiz et
if not df.empty:
last_row = df.iloc[-1]
last_status = self.check_alignment(last_row)

# Son sinyal tarihini bul
latest_signal_date = None
if last_status == "İdeal EMA Yükseliş":
latest_signal_date = self.find_latest_signal_date(df.copy(), "İdeal EMA Yükseliş")
elif last_status == "İdeal EMA Düşüş":
latest_signal_date = self.find_latest_signal_date(df.copy(), "İdeal EMA Düşüş")

# Sinyal sonrası kazanç hesapla
max_price, max_date = None, None
min_price, min_date = None, None
gain, gain_percent = 0, 0

if signals_history:
last_signal = signals_history[-1]
if last_signal['STATUS'] == 'İdeal EMA Yükseliş':
max_price, max_date = self.find_max_price_after_signal(df, last_signal['DATE'])
if max_price:
gain, gain_percent = self.calculate_gain(last_signal['CLOSING_TL'], max_price)
elif last_signal['STATUS'] == 'İdeal EMA Düşüş':
min_price, min_date = self.find_min_price_after_signal(df, last_signal['DATE'])
if min_price:
gain, gain_percent = self.calculate_gain(last_signal['CLOSING_TL'], min_price)

# Kayıt oluştur
record = {
"Hisse_Adi": ticker_name,
"Tarih": pd.to_datetime(last_row["Tarih"]).date(),
"Kapanış": last_row["Kapanış"],
"EMA_Dizilim": last_status,
"Son_Sinyal_Tarihi": latest_signal_date.date() if latest_signal_date else None,
"Bozulma": "Evet" if self.price_below_any_ema(last_row) else "Hayır",
"Sinyal_Sonrasi_Max_Fiyat": max_price,
"Max_Fiyat_Tarihi": max_date.date() if max_date else None,
"Sinyal_Sonrasi_Min_Fiyat": min_price,
"Min_Fiyat_Tarihi": min_date.date() if min_date else None,
"Kazanc_TL": round(gain, 2),
"Kazanc_Yuzde": round(gain_percent, 2)
}

# Kategorilere ayır
if last_status == "İdeal EMA Yükseliş":
self.ideal_up.append(record)
print(f"{Fore.GREEN} İdeal EMA Yükseliş tespit edildi!")
elif last_status == "İdeal EMA Düşüş":
self.ideal_down.append(record)
print(f"{Fore.RED} İdeal EMA Düşüş tespit edildi!")
else:
self.neutral.append(record)
print(f"{Fore.WHITE} ➖ Nötr durumda")

# Potansiyel kontrol
if self.check_potential(last_row):
potential_record = record.copy()
potential_record["EMA_Dizilim"] = "İdeal EMA Olabilir"
self.potential.append(potential_record)
print(f"{Fore.YELLOW} ⚡ Potansiyel oluşum tespit edildi!")

# Tüm sinyalleri kaydet
self.all_signals.extend(signals_history)

print(f"{Fore.GREEN}✅ {ticker_name} İdeal EMA analizi tamamlandı.")
self.successful_files.append(ticker_name)
return True

except FileNotFoundError:
print(f"{Fore.RED}❌ {ticker_name if ticker_name else file_path} dosyası bulunamadı.")
self.failed_files.append(os.path.basename(file_path))
return False
except pd.errors.EmptyDataError:
print(f"{Fore.RED}❌ {ticker_name if ticker_name else file_path} dosyası boş veya hatalı.")
self.failed_files.append(os.path.basename(file_path))
return False
except ValueError as e:
# Eksik sütun veya boş veri hatası için
print(f"{Fore.RED}❌ {ticker_name if ticker_name else file_path} için hata: {e}")
self.failed_files.append(os.path.basename(file_path))
return False
except Exception as e:
# Diğer tüm beklenmeyen hatalar için
print(f"{Fore.RED}❌ {ticker_name if ticker_name else file_path} için beklenmeyen hata: {e}")
self.failed_files.append(os.path.basename(file_path))
return False

@staticmethod
def find_input_files(input_folder="StokData/Emas/"):
"""Giriş dosyalarını bulma (EMA dosyalarından)"""
try:
pattern = os.path.join(input_folder, "*.xlsx")
files = glob.glob(pattern)

if not files:
print(f"{Fore.RED}❌ {input_folder} klasöründe Excel dosyası bulunamadı!")
return []

print(f"{Fore.BLUE} {len(files)} adet EMA dosyası bulundu.")
return files

except Exception as e:
print(f"{Fore.RED}❌ Dosya arama hatası: {e}")
return []

def calculate_statistics(self):
"""İstatistik hesaplama"""
try:
# Son 1 yılın verilerini filtrele
one_year_ago = datetime.now() - timedelta(days=365)
recent_signals = [signal for signal in self.all_signals if signal['DATE'] &gt;= one_year_ago]

# İdeal EMA UP sinyalleri için istatistikler
ideal_up_stats = []
for signal in recent_signals:
if signal['STATUS'] == 'İdeal EMA Yükseliş':
# Bu sinyalden sonra çıkış noktasını bul
exit_signals = [s for s in recent_signals if
s['CODE'] == signal['CODE'] and s['DATE'] &gt; signal['DATE']]
exit_signal = None
if exit_signals:
exit_signal = min(exit_signals, key=lambda x: x['DATE'])

if exit_signal:
gain, gain_percent = self.calculate_gain(signal['CLOSING_TL'], exit_signal['CLOSING_TL'])
ideal_up_stats.append({
'Hisse_Adi': signal['CODE'],
'Giris_Tarihi': signal['DATE'].date(),
'Giris_Fiyati': signal['CLOSING_TL'],
'Cikis_Tarihi': exit_signal['DATE'].date(),
'Cikis_Fiyati': exit_signal['CLOSING_TL'],
'Cikis_Sinyali': exit_signal['STATUS'],
'Kazanc_TL': round(gain, 2),
'Kazanc_Yuzde': round(gain_percent, 2),
'Gun_Sayisi': (exit_signal['DATE'] - signal['DATE']).days
})

return ideal_up_stats

except Exception as e:
print(f"{Fore.RED}❌ İstatistik hesaplama hatası: {e}")
return []

@staticmethod
def write_sheet(excel_writer, result_df, sheet_name, freeze_panes=None):
"""Excel sayfası yazma ve biçimlendirme"""
try:
if isinstance(result_df, list):
result_df = pd.DataFrame(result_df)

if result_df.empty:
result_df = pd.DataFrame([{"Mesaj": "Veri bulunamadı"}])

result_df.to_excel(excel_writer, sheet_name=sheet_name, index=False)
ws = excel_writer.sheets[sheet_name]

# Başlık biçimlendirme
header_fill = PatternFill(start_color='ADD8E6', end_color='ADD8E6', fill_type='solid')
for col_num, column in enumerate(result_df.columns, 1):
cell = ws.cell(row=1, column=col_num)
cell.font = Font(bold=True)
cell.fill = header_fill
cell.alignment = Alignment(horizontal='center')

# Sütun genişliklerini ayarla
if 'Tarih' in column:
ws.column_dimensions[get_column_letter(col_num)].width = 15
elif 'Hisse' in column:
ws.column_dimensions[get_column_letter(col_num)].width = 12
elif 'Kazanc' in column or 'Kapanış' in column or 'Fiyat' in column:
ws.column_dimensions[get_column_letter(col_num)].width = 18
else:
ws.column_dimensions[get_column_letter(col_num)].width = 20

# Freeze panes
if freeze_panes:
ws.freeze_panes = freeze_panes

# Sayısal verileri formatlama
for row_num in range(2, len(result_df) + 2):
for col_num in range(1, len(result_df.columns) + 1):
cell = ws.cell(row=row_num, column=col_num)
cell.alignment = Alignment(horizontal='center')

except Exception as e:
print(f"{Fore.RED}❌ Excel yazma hatası ({sheet_name}): {e}")

def save_results(self):
"""Sonuçları Excel'e kaydetme"""
try:
# Klasör oluşturma
output_folder = "StokData/IdealEma/"
os.makedirs(output_folder, exist_ok=True)

# Dosya isimleri
today = datetime.today().strftime('%Y-%m-%d')
main_file = os.path.join("StokData", "idealema_analiz.xlsx") # Ana dosya Stok klasörüne
archive_file = os.path.join(output_folder, f"idealema_analiz_{today}.xlsx") # Arşiv IdealEma klasörüne

# İstatistikleri hesapla
print(f"{Fore.CYAN} İstatistikler hesaplanıyor...")
ideal_up_stats = self.calculate_statistics()

# Özet istatistikler
summary_stats = pd.DataFrame({
'Kategori': ['Toplam İdeal EMA UP', 'Toplam İdeal EMA DOWN', 'Toplam Nötr', 'Toplam Potansiyel',
'Son 1 Yıl UP Sinyali', 'Son 1 Yıl Ortalama Kazanç %', 'Son 1 Yıl Ortalama Gün'],
'Deger': [len(self.ideal_up), len(self.ideal_down), len(self.neutral), len(self.potential),
len(ideal_up_stats),
round(np.mean([stat['Kazanc_Yuzde'] for stat in ideal_up_stats]) if ideal_up_stats else 0, 2),
round(np.mean([stat['Gun_Sayisi'] for stat in ideal_up_stats]) if ideal_up_stats else 0, 2)]
})

# Ana dosyayı kaydet
print(f"{Fore.GREEN} Ana dosya kaydediliyor: {main_file}")
with pd.ExcelWriter(main_file, engine='openpyxl') as excel_writer:
self.write_sheet(excel_writer, self.ideal_up, "IdealEMAUp", freeze_panes='A2')
self.write_sheet(excel_writer, self.ideal_down, "IdealEMADown", freeze_panes='A2')
self.write_sheet(excel_writer, self.neutral, "Neutral", freeze_panes='A2')
self.write_sheet(excel_writer, self.potential, "Potansiyel", freeze_panes='A2')
self.write_sheet(excel_writer, ideal_up_stats, "Son1Yil_IstatistikUp", freeze_panes='A2')
self.write_sheet(excel_writer, summary_stats, "Ozet_Istatistikler", freeze_panes='A2')

# Arşiv dosyasını kaydet
print(f"{Fore.BLUE} Arşiv dosyası kaydediliyor: {archive_file}")
with pd.ExcelWriter(archive_file, engine='openpyxl') as excel_writer:
self.write_sheet(excel_writer, self.ideal_up, "IdealEMAUp", freeze_panes='A2')
self.write_sheet(excel_writer, self.ideal_down, "IdealEMADown", freeze_panes='A2')
self.write_sheet(excel_writer, self.neutral, "Neutral", freeze_panes='A2')
self.write_sheet(excel_writer, self.potential, "Potansiyel", freeze_panes='A2')
self.write_sheet(excel_writer, ideal_up_stats, "Son1Yil_IstatistikUp", freeze_panes='A2')
self.write_sheet(excel_writer, summary_stats, "Ozet_Istatistikler", freeze_panes='A2')

return True, ideal_up_stats

except Exception as e:
print(f"{Fore.RED}❌ Sonuç kaydetme hatası: {e}")
return False, []

def print_summary(self, ideal_up_stats):
"""Özet rapor"""
total = len(self.successful_files) + len(self.failed_files)
success_rate = (len(self.successful_files) / total * 100) if total &gt; 0 else 0

print(f"\n{Fore.CYAN} ===== İDEAL EMA ANALİZ RAPORU =====")
print(f"{Fore.BLUE} EMA Periyodları: {', '.join(map(str, self.ema_periods))}")
print(f"{Fore.GREEN}✅ Başarılı: {len(self.successful_files)}")
print(f"{Fore.RED}❌ Başarısız: {len(self.failed_files)}")
print(f"{Fore.BLUE} Başarı oranı: {success_rate:.1f}%")

print(f"\n{Fore.MAGENTA} SONUÇLAR:")
print(f"{Fore.GREEN} İdeal EMA Yükseliş: {len(self.ideal_up)}")
print(f"{Fore.RED} İdeal EMA Düşüş: {len(self.ideal_down)}")
print(f"{Fore.WHITE} ➖ Nötr: {len(self.neutral)}")
print(f"{Fore.YELLOW} ⚡ Potansiyel: {len(self.potential)}")
print(f"{Fore.BLUE} Son 1 Yıl İstatistik: {len(ideal_up_stats)}")

if ideal_up_stats:
avg_gain = np.mean([stat['Kazanc_Yuzde'] for stat in ideal_up_stats])
avg_days = np.mean([stat['Gun_Sayisi'] for stat in ideal_up_stats])
print(f"{Fore.GREEN} Ortalama Kazanç: %{avg_gain:.2f}")
print(f"{Fore.BLUE} Ortalama Elde Tutma: {avg_days:.1f} gün")

def main(self):
"""Ana fonksiyon"""
print(f"{Fore.CYAN} İdeal EMA Dizilim Analizi Başlatılıyor...")
print(f"{Fore.BLUE} EMA Periyodları: {', '.join(map(str, self.ema_periods))}")

# Giriş dosyalarını bulma
input_files = self.find_input_files()

if not input_files:
return

print(f"{Fore.BLUE} Toplam işlenecek dosya: {len(input_files)}\n")

# Dosyaları işleme
for i, file_path in enumerate(input_files, 1):
print(f"\n{Fore.MAGENTA}[{i}/{len(input_files)}] İşleniyor...")
self.process_single_file(file_path)

# Sonuçları kaydetme ve raporlama
success, ideal_up_stats = self.save_results()

if success:
self.print_summary(ideal_up_stats)

print(f"\n{Fore.GREEN} İdeal EMA analizi tamamlandı!")
print(f"{Fore.BLUE} Ana dosya: Stok/idealema_analiz.xlsx")
print(f"{Fore.BLUE} Arşiv klasörü: Stok/IdealEma/")

# Kullanım
if __name__ == "__main__":
calculator = IdealEMACalculator()
calculator.main()

 

Bir sonraki yazıda Borsa İstanbul BIST Spot hisseleri için Wave Trend Osilatör sinyallerini tarama çalışması ve Trading View Wave Trend osilatör indikatörü ayrı ayrı ele alınacaktır.

Python ile Kapanış Fiyatlarından EMA Hesaplama Betiği

03 Ağustos 2025 BorsaPin, Python, Teknik Analizalım satım sinyali, borsa, Ema, Ema Alignment, Excel otomasyonu, finansal veri, hisse senedi, İdeal Ema, idealemadown, idealemanötr, idealemaup, kapanış fiyatları, otomatik hesaplama, Python, Python ile borsa analizi, Teknik Analiz, trade, trend analizi, Üstel Hareketli Ortalama

Finans piyasalarında, fiyat hareketlerini anlamak ve geleceğe yönelik tahminlerde bulunmak için teknik analiz araçları hayati önem taşır. Bu araçların en popülerlerinden biri, özellikle kısa ve orta vadeli trendleri belirlemede etkili olan Üstel Hareketli Ortalama (Exponential Moving Average – EMA)’dır.  EMA’nın ne olduğunu, neden bu kadar önemli olduğunu ve kendi borsa verileriniz üzerinde bu analizi otomatik olarak yapacak bir Python aracını nasıl kullanabileceğinizi ele alacağız.

EMA Nedir ve Neden Önemlidir?

Hareketli ortalamalar, belirli bir zaman dilimindeki fiyatların ortalamasını alarak fiyat dalgalanmalarını yumuşatan göstergelerdir. EMA, bu ortalama hesaplamasını yaparken son fiyatlara daha fazla ağırlık vererek, basit hareketli ortalamalardan (SMA) daha hızlı tepki verir. Bu özellik, yatırımcıların son piyasa değişikliklerini daha çabuk fark etmelerini sağlar.
EMA’nın temel mantığı, fiyatın EMA’nın üzerinde olması durumunda yükseliş trendinin devam ettiğini, altında olması durumunda ise düşüş trendinin hakim olduğunu gösterir. Farklı periyotlardaki EMA’ların birbiriyle kesişimi ise alım veya satım sinyali olarak yorumlanabilir.
Örneğin, kısa vadeli bir EMA’nın (örneğin EMA 8) uzun vadeli bir EMA’yı (örneğin EMA 21) yukarı yönlü kesmesi, güçlü bir alım sinyali olarak kabul edilebilir.

Kodun İşlevleri: EMACalculator Sınıfı

Python kodu, EMACalculator adında güçlü ve modüler bir sınıf yapısına sahiptir. Bu sınıf, borsa verilerinizi otomatik olarak okur, farklı periyotlarda EMA hesaplamaları yapar ve sonuçları düzenli bir şekilde kaydeder.

Kodun ana bölümleri

ema_periods: Kod, 5, 8, 13, 21, 34, 55, 89, 144, 233, 370 gibi finansal analizde sıkça kullanılan Fibonacci sayılarına dayalı EMA periyotlarını kullanır. Bu periyotlar, farklı zaman dilimlerindeki trendleri gözlemlemenize olanak tanır.

process_single_file: Bu metot, her bir hisse senedi için ayrı ayrı EMA’ları hesaplar. Girdi olarak alınan Excel dosyasından Tarih ve Kapanış verilerini okur ve her bir EMA periyodu için yeni sütunlar oluşturur.

find_input_files: StokData/Kapanis/ klasöründeki tüm Excel dosyalarını otomatik olarak bulur. Bu, yüzlerce hisse senedi verisini tek tek elle işlemek yerine toplu bir şekilde işlem yapmanızı sağlar.

main: Programın ana akışını yöneten metottur. Giriş dosyalarını bulur, her bir dosya için EMA hesaplamasını başlatır ve işlemin sonunda başarılı/başarısız dosyaların özetini gösteren bir rapor sunar.

Bu Makale Daha önceki Makalelerin devamı niteliğinde olduğu için,  aşağıdaki makaleleri de incelemeniz büyük önem taşıyor.
Python ve PyCharm kurulumu

Gerekli kütüphanelerin kurulumu

Kapanış Datalarını çeken Script

Çalışmaların tamamını içeren Google Drive Alanı

X_02_BorsaPin_Emas.py olarak dosyayı kayıt edebilirsiniz.
Python Kodu

import pandas as pd
import os
import numpy as np
from datetime import datetime
from colorama import Fore, init
import glob

"""
Borsapin StokData/Kapanis klasöründeki hisse kapanış datalarından EMA'larını hesaplar
www.kursatsenturk.com

"""
init(autoreset=True)

class EMACalculator:
def __init__(self):
self.ema_periods = [5, 8, 13, 21, 34, 55, 89, 144, 233, 370]
self.successful_files = []
self.failed_files = []

@staticmethod
def calculate_ema(data, period):
"""EMA hesaplama fonksiyonu"""
try:
return data.ewm(span=period, adjust=False).mean()
except Exception as e:
print(f"{Fore.RED}❌ EMA hesaplama hatası (Period {period}): {e}")
return pd.Series([np.nan] * len(data))

def process_single_file(self, file_path):
"""Tek dosya için EMA hesaplama"""
ticker_name = os.path.splitext(os.path.basename(file_path))[0]
try:
print(f"{Fore.YELLOW} EMA hesaplanıyor: {ticker_name}...")

df = pd.read_excel(file_path)

required_columns = ['Tarih', 'Kapanış']
missing_columns = [col for col in required_columns if col not in df.columns]

if missing_columns:
raise ValueError(f"Eksik sütunlar: {missing_columns}")

if df.empty or df['Kapanış'].isna().all():
raise ValueError("Kapanış verisi boş veya geçersiz")

df = df.sort_values('Tarih').reset_index(drop=True)

result_df = pd.DataFrame()
result_df['Hisse_Adi'] = [ticker_name] * len(df)
result_df['Tarih'] = df['Tarih']
result_df['Kapanış'] = df['Kapanış']

print(f"{Fore.CYAN} ⚡ EMA hesaplanıyor: ", end="")
for i, period in enumerate(self.ema_periods):
ema_column_name = f'EMA_{period}'
print(f"{period}", end="")

ema_values = self.calculate_ema(df['Kapanış'], period)
result_df[ema_column_name] = ema_values.round(4)

if i &lt; len(self.ema_periods) - 1:
print(", ", end="")
print()

output_folder = "StokData/Emas/"
os.makedirs(output_folder, exist_ok=True)

output_file = os.path.join(output_folder, f"{ticker_name}.xlsx")

result_df.to_excel(output_file, index=False)

print(f"{Fore.GREEN}✅ {ticker_name} EMA verileri başarıyla kaydedildi.")
print(f"{Fore.BLUE} Konum: {output_file}")
print(f"{Fore.BLUE} Toplam satır: {len(result_df)}")

self.successful_files.append(ticker_name)
return True

except Exception as e:
print(f"{Fore.RED}❌ {ticker_name} için hata: {e}")
self.failed_files.append(os.path.basename(file_path))
return False

@staticmethod
def find_input_files(input_folder="StokData/Kapanis/"):
"""Giriş dosyalarını bulma"""
try:
pattern = os.path.join(input_folder, "*.xlsx")
files = glob.glob(pattern)

if not files:
print(f"{Fore.RED}❌ {input_folder} klasöründe Excel dosyası bulunamadı!")
return []

print(f"{Fore.BLUE} {len(files)} adet Excel dosyası bulundu.")
return files

except Exception as e:
print(f"{Fore.RED}❌ Dosya arama hatası: {e}")
return []

@staticmethod
def validate_input_file(file_path):
"""Giriş dosyasını doğrulama"""
try:
df = pd.read_excel(file_path, nrows=1)
required_columns = ['Tarih', 'Kapanış']

if not all(col in df.columns for col in required_columns):
return False, f"Eksik sütunlar: {[col for col in required_columns if col not in df.columns]}"

return True, "OK"

except Exception as e:
return False, f"Dosya okuma hatası: {e}"

def print_summary(self):
"""Özet rapor"""
total = len(self.successful_files) + len(self.failed_files)
success_rate = (len(self.successful_files) / total * 100) if total &gt; 0 else 0

print(f"\n{Fore.CYAN} ===== EMA HESAPLAMA RAPORU =====")
print(f"{Fore.BLUE} EMA Periyodları: {', '.join(map(str, self.ema_periods))}")
print(f"{Fore.GREEN}✅ Başarılı: {len(self.successful_files)}")
print(f"{Fore.RED}❌ Başarısız: {len(self.failed_files)}")
print(f"{Fore.BLUE} Başarı oranı: {success_rate:.1f}%")

if self.successful_files:
print(f"{Fore.GREEN} Başarılı dosyalar: {', '.join(self.successful_files[:10])}")
if len(self.successful_files) &gt; 10:
print(f"{Fore.GREEN} ... ve {len(self.successful_files) - 10} dosya daha")

if self.failed_files:
print(f"{Fore.RED} Başarısız dosyalar: {', '.join(self.failed_files)}")

def save_failed_list(self, filename="basarisiz_ema_dosyalari.txt"):
"""Başarısız dosyaları kaydetme"""
if self.failed_files:
try:
with open(filename, 'w', encoding='utf-8') as f:
f.write("# Başarısız EMA hesaplama dosyaları\n")
f.write(f"# Tarih: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n\n")
for file_name in self.failed_files:
f.write(f"{file_name}\n")
print(f"{Fore.YELLOW} Başarısız dosyalar {filename} dosyasına kaydedildi.")
except Exception as e:
print(f"{Fore.RED}❌ Başarısız dosya listesi kaydetme hatası: {e}")

def create_sample_ema_analysis(self, ticker_name="SAMPLE"):
"""Örnek EMA analiz dosyası oluşturma"""
try:
dates = pd.date_range(start='2023-01-01', end='2024-01-01', freq='D')
np.random.seed(42)

base_price = 100
price_changes = np.random.normal(0, 2, len(dates))
prices = [base_price]

for change in price_changes[1:]:
new_price = prices[-1] * (1 + change / 100)
prices.append(max(new_price, 1))

df = pd.DataFrame({
'Tarih': dates,
'Kapanış': prices
})

result_df = pd.DataFrame()
result_df['Hisse_Adi'] = [ticker_name] * len(df)
result_df['Tarih'] = df['Tarih']
result_df['Kapanış'] = df['Kapanış']

for period in self.ema_periods:
ema_values = self.calculate_ema(df['Kapanış'], period)
result_df[f'EMA_{period}'] = ema_values.round(4)

output_folder = "StokData/Emas/"
os.makedirs(output_folder, exist_ok=True)
output_file = os.path.join(output_folder, f"{ticker_name}.xlsx")
result_df.to_excel(output_file, index=False)

print(f"{Fore.GREEN}✅ Örnek EMA dosyası oluşturuldu: {output_file}")
return True

except Exception as e:
print(f"{Fore.RED}❌ Örnek dosya oluşturma hatası: {e}")
return False

def main(self):
"""Ana fonksiyon"""
print(f"{Fore.CYAN} EMA Hesaplama Sistemi Başlatılıyor...")
print(f"{Fore.BLUE} EMA Periyodları: {', '.join(map(str, self.ema_periods))}")

input_files = self.find_input_files()

if not input_files:
print(f"{Fore.YELLOW}⚠️ Giriş dosyası bulunamadı. Örnek dosya oluşturuluyor...")
self.create_sample_ema_analysis()
return

print(f"{Fore.BLUE} Toplam işlenecek dosya: {len(input_files)}\n")

for i, file_path in enumerate(input_files, 1):
print(f"\n{Fore.MAGENTA}[{i}/{len(input_files)}] İşleniyor...")

is_valid, error_msg = self.validate_input_file(file_path)
if not is_valid:
print(f"{Fore.RED}❌ Geçersiz dosya: {os.path.basename(file_path)} - {error_msg}")
self.failed_files.append(os.path.basename(file_path))
continue

self.process_single_file(file_path)

self.save_failed_list()
self.print_summary()

print(f"\n{Fore.GREEN} EMA hesaplama işlemi tamamlandı!")
print(f"{Fore.BLUE} Çıktı klasörü: StokData/Emas/")

# Kullanım
if __name__ == "__main__":
calculator = EMACalculator()
calculator.main()

 

Bir sonraki makalede İdeal EMA dizilim (sıralama) yani Ema Alignment betiğini paylaşacağım.
Burada bütün hisseleri tarayıp belirli kurallara uyan hisseleri çalışma sayfalarında listeleteceğiz.
idealemaup, idealemadown,  idealemanötr, potansiyel taşıyan ve 1 yıllık istatistikleri gösteren çalışma sayfaları olacak.

Ben bu hayatta hiç var olmadım ki zaten…

01 Ağustos 2025 Anlık Tepkiler, Bilinçaltı Sayıklamaları, Halet-i Ruhiye


Ben bu hayatta hiç var olmadım ki zaten…
Ne birinin teninde ısındım,
Ne de bir kelimesinde yer bulabildim kendime.
Ne bir yürek beni anladı,
Ne bir ses adımı gerçekten söyledi.
Sanki bir rüyanın unutulan köşesiydim;
uyanıldığında hatırlanmayan,
bir hayalin eşiğinden bile geçemeyen silik bir iz.

Zaman aktı üzerimden,
ama ben hiçbir saate ait olmadım.
Bir gölgeydim belki;
ışık varsa varım, yoksa hiçim.
Hiçbir el tutmadı beni,
hiçbir bakışta kendimi bulamadım.

Bir gün gidecek olsam,
ardımdan ‘kimdi o?’ bile demez kimse.
Çünkü ben burada değildim aslında —
yalnızca yokluğumun yankısıydım sizin kalabalığınızda

Yazmazsam Unuturum…

Aşk siyahı beyaz görebilme körlüğüydü, biz siyahı hep beyaz gördük.”

01 Ağustos 2025 Anlık Tepkiler, Halet-i Ruhiye

 

Birlikte geçirdiğimiz kısa ama güzel anlar, dostluğunun ne kadar kıymetli olduğunu hep hatırlatacak bana. Sessizliğin artık çok daha derin, eksikliğin ise tarif edilemez…
Huzur içinde uyu, dostum. Seni hiç unutmayacağız.

Kitabında yer verdiğin cümlem içinde sonsuz teşekkürler..

“Aşk siyahı beyaz görebilme körlüğüydü,  biz siyahı hep beyaz gördük.”
O satırlarda ismimi anman, beni her zaman onurlandırdı..

Şiirlerin artık sensiz, sessiz ve sahipsiz…
Ama bil ki, her dizede seni yaşatmaya devam edeceğiz.
Hoşçakal Kel Adam..

 

Python ile Borsa İstanbul (BIST) Hisse Kapanış Verisi Çekme

01 Ağustos 2025 BorsaPin, Code is prority, PythonBIST hisse senedi verisi, BIST verisi otomatik çekme, borsa analiz otomasyonu, Excel'e hisse senedi yazdırma, pandas excel kaydetme, Python hisse senedi analizi, Python ile BIST verisi çekme, Python kapanış verisi indir, Python teknik analiz hazırlığı, yfinance Borsa İstanbul, yfinance Türk hisseleri

Finansal analiz ve algoritmik işlem geliştirmek isteyen herkesin ilk adımı, güvenilir hisse senedi kapanış verilerini elde etmektir. Bu veriler, teknik analizden sinyal üretimine kadar pek çok işlemin temelini oluşturur. Elinizdeki veriler ne kadar doğru ve güncelse, analizleriniz de o kadar isabetli olur.

Python ve yfinance kütüphanesi kullanılarak oluşturulmuş, Borsa İstanbul (BIST) hisselerine ait kapanış verilerini otomatik olarak indiren gelişmiş bir scripti detaylıca ele alacağız. Script, .xlsx formatında çıktılar üreterek analizlerinize doğrudan entegre edilebilir veriler sunar.

Kodun Amacı Nedir?

hisselistesi_txt.txt adlı dosyadan hisse senedi sembollerini okumak
Yahoo Finance üzerinden kapanış verilerini çekmek (yfinance)
Verileri işleyip Excel’e kaydetmek (pandas ve openpyxl)
Başarısız işlemleri tespit edip yeniden denemek
Kullanıcıya görsel ve metinsel özet rapor sunmak

Script’in öne çıkan teknik özellikler

Otomatik Hisse Formatlama
Yahoo Finance üzerinde işlem gören BIST hisseleri .IS uzantısına sahiptir.
Örneğin THYAO → THYAO.IS formatına otomatik olarak dönüştürülür.

Yeniden Deneme Mekanizması
Veri çekimi sırasında yaşanan geçici sorunlar için belirli aralıklarla otomatik yeniden deneme yapılır (max_retries, retry_delay).

 Excel Kaydı ve Türkçe Sütunlar
Çekilen veriler şu sütunlar ile .xlsx dosyasına kaydedilir:

Tarih  Açılış Yüksek Düşük Kapanış Hacim

Eksik Veri ve NaN Temizliği
İndirilen verilerdeki eksik veya bozuk kayıtlar otomatik olarak temizlenir. Bu sayede daha sağlıklı analizler yapılabilir.

Kullanıcı Dostu Konsol Çıktıları
colorama kütüphanesi sayesinde kullanıcıya renkli ve bilgilendirici çıktılar sunulur (örn. yeşil = başarı, kırmızı = hata).

Klasör Yapısı ve Çıktı
Kaydedilen dosyalar StokData/Kapanis/ klasörü altında saklanır. Her hisse senedi için ayrı bir Excel dosyası oluşturulur:
StokData/Kapanis/THYAO.xlsx gibi.

Kullanım Adımları
hisselistesi_txt.txt dosyasına BIST hisse sembollerini yazın (her satıra bir hisse, örn. AKBNK).
Temeli sağlam şirketleri listeleyebilirsiniz. Ya da belirli sektör yada endeks şirketlerin sembollerini de yazabilirsiniz. (XU100, XU030)

Scripti çalıştırdığınızda

Kapanış verileri indirilecek, işlenecek ve .xlsx olarak kaydedilecektir. Başarısız olan hisseler için sistem size yeniden deneme opsiyonu sunacaktır. Süreç sonunda konsolda özet rapor gösterilecektir.

Örnek Konsol Çıktısı

Veri çekiliyor: AKBNK (Deneme 1/3)…
✅ AKBNK verisi başarıyla kaydedildi.

Veri çekiliyor: THYAO (Deneme 1/3)…
❌ THYAO için hata (Deneme 1): Connection timed out.
⏳ 2 saniye bekleniyor…
…
===== ÖZET RAPOR =====
✅ Başarılı: 18
❌ Başarısız: 2
Başarı oranı: 90.0%
Başarısız hisseler: THYAO, TAVHL
Sonraki Adım

X_01_BorsaPin_StokData.py olarak kayıt edebilirsiniz.
Pyhon Kodumuz

import yfinance as yf
import os
import pandas as pd
from datetime import datetime, timedelta
from colorama import Fore, init
import time
from typing import List, Optional

"""
      Borsapin StokData Yahoo Finans Üzerinden Kapanış Datalarını çekmeye yarar
      www.kursatsenturk.com

      """
init(autoreset=True)


class StockDownloader:
    def __init__(self, max_retries: int = 3, retry_delay: int = 2):
        """
        Hisse senedi veri indirici sınıfı

        Args:
            max_retries: Maksimum yeniden deneme sayısı
            retry_delay: Denemeler arası bekleme süresi (saniye)
        """
        self.max_retries = max_retries
        self.retry_delay = retry_delay
        self.failed_tickers: List[str] = []
        self.successful_tickers: List[str] = []

    @staticmethod
    def read_tickers(file_path: str) -> List[str]:
        """Hisse kodlarını dosyadan okuma fonksiyonu"""
        try:
            with open(file_path, 'r', encoding='utf-8') as f:
                tickers = [line.strip() for line in f.readlines() if line.strip()]
            return tickers
        except FileNotFoundError:
            print(f"{Fore.RED}❌ {file_path} dosyası bulunamadı!")
            return []
        except Exception as e:
            print(f"{Fore.RED}❌ Dosya okuma hatası: {e}")
            return []

    @staticmethod
    def format_ticker(ticker: str) -> str:
        """Hisse sembolüne .IS eklemek"""
        if not ticker.endswith('.IS'):
            ticker = ticker + '.IS'
        return ticker

    @staticmethod
    def save_to_excel(data: pd.DataFrame, file_path: str) -> bool:
        """Veriyi Excel'e kaydetme fonksiyonu"""
        try:
            data.to_excel(file_path, index=False)
            return True
        except Exception as e:
            print(f"{Fore.RED}❌ Excel kaydetme hatası: {e}")
            return False

    def download_single_ticker(self, ticker: str, start_date: str, end_date: str, attempt: int = 1) -> bool:
        """Tek hisse için veri çekme fonksiyonu"""
        formatted_ticker = self.format_ticker(ticker)
        ticker_name = formatted_ticker.replace(".IS", "")

        print(f"{Fore.YELLOW} Veri çekiliyor: {ticker_name} (Deneme {attempt}/{self.max_retries})...")

        try:
            # Veri çekme
            stock_data = yf.download(
                formatted_ticker,
                start=start_date,
                end=end_date,
                progress=False,
                timeout=30,
                auto_adjust=True,  # Uyarıyı önlemek için explicit olarak True
                prepost=True,
                threads=True
            )

            if stock_data is None or stock_data.empty:
                raise ValueError("Veri boş veya None")

            # MultiIndex sütunlarını düzelt
            if isinstance(stock_data.columns, pd.MultiIndex):
                # MultiIndex'i tek seviyeye indir
                stock_data.columns = stock_data.columns.droplevel(1)

            # Sütun isimlerini temizle
            stock_data.columns = [str(col).strip() for col in stock_data.columns]

            # Veri işleme - sadece gerekli sütunları al
            required_columns = ['Open', 'High', 'Low', 'Close', 'Volume']
            available_columns = [col for col in required_columns if col in stock_data.columns]

            if not available_columns:
                raise ValueError("Gerekli sütunlar bulunamadı")

            stock_data = stock_data[available_columns]

            # Sayıları düzgün formatta işleme
            for column in stock_data.columns:
                if stock_data[column].dtype == 'object':
                    try:
                        stock_data[column] = pd.to_numeric(
                            stock_data[column].astype(str).str.replace(',', '.'),
                            errors='coerce'
                        )
                    except Exception:
                        continue

            # NaN değerleri temizle
            stock_data = stock_data.dropna()

            # Boş veri kontrolü
            if stock_data.empty:
                raise ValueError("İşlenen veri boş")

            # Dosya kaydetme
            folder_path = "StokData/Kapanis/"
            os.makedirs(folder_path, exist_ok=True)
            file_path = os.path.join(folder_path, f"{ticker_name}.xlsx")

            # Tarih formatı düzenleme
            stock_data_copy = stock_data.copy()

            # Index'i reset et ve tarih sütununu ekle
            stock_data_copy.reset_index(inplace=True)

            # Tarih sütunu varsa formatla
            if 'Date' in stock_data_copy.columns:
                stock_data_copy['Date'] = pd.to_datetime(stock_data_copy['Date']).dt.date
                stock_data_copy.rename(columns={"Date": "Tarih"}, inplace=True)

            # Sütun isimlerini Türkçeye çevirme
            column_mapping = {
                'Open': 'Açılış',
                'High': 'Yüksek',
                'Low': 'Düşük',
                'Close': 'Kapanış',
                'Volume': 'Hacim'
            }

            # Mevcut sütunları yeniden adlandır
            for eng_name, tr_name in column_mapping.items():
                if eng_name in stock_data_copy.columns:
                    stock_data_copy.rename(columns={eng_name: tr_name}, inplace=True)

            # Kaydetme
            if self.save_to_excel(stock_data_copy, file_path):
                print(f"{Fore.GREEN}✅ {ticker_name} verisi başarıyla kaydedildi.")
                return True
            else:
                raise Exception("Excel kaydetme başarısız")

        except Exception as e:
            print(f"{Fore.RED}❌ {ticker_name} için hata (Deneme {attempt}): {str(e)}")
            return False

    def download_with_retry(self, ticker: str, start_date: str, end_date: str) -> bool:
        """Yeniden deneme mekanizması ile veri çekme"""
        for attempt in range(1, self.max_retries + 1):
            if self.download_single_ticker(ticker, start_date, end_date, attempt):
                self.successful_tickers.append(ticker)
                return True

            if attempt < self.max_retries:
                print(f"{Fore.YELLOW}⏳ {self.retry_delay} saniye bekleniyor...")
                time.sleep(self.retry_delay)

        # Tüm denemeler başarısız
        self.failed_tickers.append(ticker)
        print(f"{Fore.RED} {ticker} için tüm denemeler başarısız!")
        return False

    def retry_failed_tickers(self, start_date: str, end_date: str) -> None:
        """Başarısız hisseleri tekrar deneme"""
        if not self.failed_tickers:
            print(f"{Fore.GREEN} Yeniden denenecek hisse yok!")
            return

        print(f"\n{Fore.CYAN} Başarısız {len(self.failed_tickers)} hisse tekrar deneniyor...")
        print(f"{Fore.CYAN}Başarısız hisseler: {', '.join(self.failed_tickers)}")

        retry_failed = []
        retry_successful = []

        # Başarısız hisselerin kopyasını al
        failed_copy = self.failed_tickers.copy()

        for ticker in failed_copy:
            print(f"\n{Fore.MAGENTA} Tekrar deneniyor: {ticker}")

            if self.download_with_retry(ticker, start_date, end_date):
                retry_successful.append(ticker)
                self.failed_tickers.remove(ticker)
            else:
                retry_failed.append(ticker)

        # Sonuçları yazdır
        if retry_successful:
            print(f"\n{Fore.GREEN}✅ Tekrar denemede başarılı: {', '.join(retry_successful)}")

        if retry_failed:
            print(f"\n{Fore.RED}❌ Hala başarısız: {', '.join(retry_failed)}")

    def save_failed_list(self, filename: str = "basarisiz_hisseler.txt") -> None:
        """Başarısız hisseleri dosyaya kaydet"""
        if self.failed_tickers:
            try:
                with open(filename, 'w', encoding='utf-8') as f:
                    f.write('\n'.join(self.failed_tickers))
                print(f"{Fore.YELLOW} Başarısız hisseler {filename} dosyasına kaydedildi.")
            except Exception as e:
                print(f"{Fore.RED}❌ Başarısız hisse listesi kaydetme hatası: {e}")

    def print_summary(self) -> None:
        """Özet rapor yazdır"""
        total = len(self.successful_tickers) + len(self.failed_tickers)
        success_rate = (len(self.successful_tickers) / total * 100) if total > 0 else 0

        print(f"\n{Fore.CYAN} ===== ÖZET RAPOR =====")
        print(f"{Fore.GREEN}✅ Başarılı: {len(self.successful_tickers)}")
        print(f"{Fore.RED}❌ Başarısız: {len(self.failed_tickers)}")
        print(f"{Fore.BLUE} Başarı oranı: {success_rate:.1f}%")

        if self.failed_tickers:
            print(f"{Fore.RED} Başarısız hisseler: {', '.join(self.failed_tickers)}")

    def main(self) -> None:
        """Ana fonksiyon"""
        print(f"{Fore.CYAN} Veri çekme başlıyor...")

        # Parametreler
        tickers = self.read_tickers("hisselistesi_txt.txt")
        if not tickers:
            print(f"{Fore.RED}❌ Hisse listesi okunamadı, işlem sonlandırılıyor.")
            return

        start_date = '2020-01-01'
        end_date = (datetime.today() + timedelta(days=1)).strftime('%Y-%m-%d')

        print(f"{Fore.BLUE} Tarih aralığı: {start_date} - {end_date}")
        print(f"{Fore.BLUE} Toplam hisse sayısı: {len(tickers)}")
        print(f"{Fore.BLUE} Maksimum deneme sayısı: {self.max_retries}")
        print(f"{Fore.BLUE}⏱️ Deneme arası bekleme: {self.retry_delay} saniye\n")

        # İlk deneme
        for i, ticker in enumerate(tickers, 1):
            print(f"\n{Fore.BLUE}[{i}/{len(tickers)}] İşleniyor...")
            self.download_with_retry(ticker, start_date, end_date)

        # Başarısız hisseleri tekrar deneme
        if self.failed_tickers:
            user_input = input(
                f"\n{Fore.YELLOW}❓ Başarısız {len(self.failed_tickers)} hisseyi tekrar denemek istiyor musunuz? (e/h): "
            ).lower().strip()

            if user_input in ['e', 'evet', 'y', 'yes']:
                self.retry_failed_tickers(start_date, end_date)

        # Sonuçları kaydet ve yazdır
        self.save_failed_list()
        self.print_summary()

        print(f"\n{Fore.GREEN} İşlem tamamlandı!")


# Kullanım
if __name__ == "__main__":
    # Özelleştirilebilir parametreler
    downloader = StockDownloader(
        max_retries=3,  # Maksimum deneme sayısı
        retry_delay=2  # Denemeler arası bekleme süresi (saniye)
    )

    downloader.main()

 

Bu script, ileri seviye analizlerin temelini oluşturur. Bir sonraki yazımızda, bu verileri kullanarak:

5 8 13 21 34 55 89 144 233 370  EMA  seviyelerini hesaplayan  EMAs script yayınlayacağım.

Ve yatırım kararları için Python tabanlı teknik analiz sistemleri geliştirmeye devam edeceğiz.

Python ile Borsa Verilerine Giriş: Gerekli Kütüphanelerin Otomatik Kurulumu

01 Ağustos 2025 BorsaPin, Python, Teknik AnalizBorsa İstanbul Python verisi, hisse senedi verisi çekme, openpyxl ile Excel yazma, pandas Excel işlemleri, Python borsa analizi, Python finans kütüphaneleri, Python finansal göstergeler, Python ile BIST verisi çekme, Python ile finansal veri analizi, Python otomatik kütüphane yükleme, Python teknik analiz, Python yatırım sinyalleri, teknik analiz Python scripti, yfinance ile hisse verisi çekme

Finansal analiz projelerinde Python, sunduğu zengin kütüphane ekosistemi ile güçlü bir araçtır. Borsa İstanbul (BIST) hisselerine ait kapanış verilerini çekmek ve bu veriler üzerinden teknik sinyaller üretmek için öncelikle bazı temel Python kütüphanelerine ihtiyaç duyarız.
Bu yazıda, gerekli kütüphanelerin sisteminizde yüklü olup olmadığını kontrol eden ve eksik olanları otomatik olarak kuran bir Python scriptini ele alacağız. Bu adım, ileri aşamalarda Borsa İstanbul Kapanış ve Hacim verilerini çekme ve analiz etme işlemleri için altyapı hazırlığı niteliğindedir.

Kullanılan Kütüphaneler

Aşağıdaki kütüphaneler, veri çekme ve analiz süreçlerinde kullanılacaktır:

pandas: Veri manipülasyonu ve analiz için temel kütüphane.
numpy: Sayısal hesaplamalar için kullanılır.
colorama: Konsolda renkli yazı yazmak için kullanılır (bilgilendirici çıktılar için).
yfinance: Yahoo Finance üzerinden hisse senedi verilerini çekmeye yarar.
openpyxl: Excel dosyaları oluşturmak ve düzenlemek için kullanılır.

Kod özetle şunları yapar:
1. Belirlenen `required_packages` listesinde yer alan kütüphanelerin sistemde kurulu olup olmadığını kontrol eder.
2. Eğer bir kütüphane yüklü değilse, `pip install` komutu ile yükler.
3. Her bir paket için yükleme durumu kullanıcıya yazdırılır.

GerekliKütüphaneler.py diye kayıt edebilirsiniz.

Python Kodu

import subprocess
import sys

# Gerekli kütüphaneler listesi
required_packages = [
"pandas",
"numpy",
"colorama",
"yfinance",
"openpyxl"
]

def install_missing_packages():
for package in required_packages:
try:
__import__(package)
print(f"{package} zaten yüklü.")
except ImportError:
print(f"{package} eksik, yükleniyor...")
subprocess.check_call([sys.executable, "-m", "pip", "install", package])

if __name__ == "__main__":
install_missing_packages()

 

Sonraki Adımlar
Eğer farklı bir kütüphaneye ihtiyaç duyduğumuzda bu betiğe ekleme yapacağız.
Şimdi bu temel kurulumu yaptıktan sonra, aşağıdaki adımlarla devam edeceğiz:

Borsa İstanbul Hisse Verilerinin Çekilmesi
yfinance kütüphanesini kullanarak BIST hisselerine ait günlük kapanış verilerini çekeceğiz. (2 Ocak 2020 tarihinden itibaren)

Verilerin Excel’e Aktarılması
pandas ve openpyxl kütüphaneleri sayesinde çekilen veriler .xlsx formatında saklanacak.

Teknik Göstergeler ve Sinyallerin Hesaplanması
EMA, EMA ALIGNMENT (İdeal Ema, Ema Sıralama), WaveTrend, Günlük Haftalık Aylık Yıllık Pivot, Lineer Regresyon kanalları gibi göstergeleri hesaplayıp, yatırım kararlarında kullanılabilecek potansiyel al/sat sinyallerinide analiz edeceğiz.

Sonuç olarak bu script, Python tabanlı finansal veri analizlerine başlamadan önce gerekli kütüphaneleri yükleyerek ortam hazırlığını otomatikleştirir. Böylece kullanıcılar doğrudan veri çekme ve analiz etme adımlarına geçebilirler.

Python ve PyCharm Kurulumu: Başlangıç Rehberi

01 Ağustos 2025 Code is prority, Python, Teknik AnalizBIST hisse verileri, Borsa analiz, Ema Alignment, EMA hesaplama, Excel borsa analiz, hisse senedi analizi, lineer regresyon kanalı, osilatör analizi, otomatik hisse tarama, Pearson korelasyonu, PyCharm, PyCharm kurulumu, Python, Python başlangıç rehberi, Python borsa verisi çekme, Python Excel çıktısı, Python kurulumu, teknik analiz Python, wave trend sinyali, Yahoo Finance Python

Python, günümüzün en popüler programlama dillerinden biridir. Veri bilimi, yapay zeka, web geliştirme, otomasyon ve daha birçok alanda yaygın olarak kullanılır. Bu makalede, Python’u bilgisayarınıza nasıl kuracağınızı ve PyCharm adlı güçlü bir geliştirme ortamını (IDE) nasıl kullanmaya başlayacağınızı adım adım öğreneceksiniz.

Python Nedir?
Python, okunabilirliği yüksek, öğrenmesi kolay ve güçlü bir programlama dilidir. Açık kaynaklıdır ve çok geniş bir kullanıcı topluluğuna sahiptir.

Python Kurulumu

Adım 1: Python Web Sitesine Gidin
Tarayıcınızda https://www.python.org adresine gidin.

Adım 2: Python Sürümünü İndirin

Ana sayfadaki “Download Python X.X.X” (örneğin 3.13.5) butonuna tıklayın. İşletim sisteminiz otomatik olarak algılanır (Windows, macOS veya Linux).

Adım 3: Kurulum Dosyasını Çalıştırın

İndirilen .exe dosyasını çalıştırın.

Kurulum ekranında mutlaka “Add Python to PATH” seçeneğini işaretleyin.

Ardından “Install Now” seçeneğine tıklayın.

Adım 4: Kurulumu Doğrulayın

Başlat Menüsü > Komut İstemi’ni (cmd) açın ve şu komutu yazın:

python –version
Python sürümünüzün yazıldığını görüyorsanız kurulum başarılıdır.

PyCharm Kurulumu

PyCharm Nedir?

PyCharm, Python için özel olarak geliştirilmiş bir IDE’dir. Kod yazmayı, çalıştırmayı, hata ayıklamayı ve projeleri yönetmeyi kolaylaştırır.

Adım 1: PyCharm Web Sitesine Gidin

https://www.jetbrains.com/pycharm adresini ziyaret edin.

Adım 2: Sürüm Seçimi

İki farklı sürüm vardır:

Community (Ücretsiz) – Başlangıç için yeterlidir.

Professional (Ücretli) – Web geliştirme, veri bilimi gibi ek özellikler içerir.

Community Edition’ı indirin.

Adım 3: Kurulumu Başlatın

İndirilen kurulum dosyasını açın ve yönergeleri takip ederek PyCharm’ı kurun.

Kurulum sırasında aşağıdaki seçenekleri işaretleyebilirsiniz:

64-bit launcher ekle

.py dosyalarını PyCharm ile ilişkilendirin

Adım 4: İlk Çalıştırma

Kurulum tamamlandıktan sonra PyCharm’ı başlatın ve tema (açık/koyu) gibi başlangıç ayarlarını yapın.

İlk Python Projeni Oluşturma

PyCharm’ı açın ve “New Project” seçeneğini seçin.

Projeye bir ad verin (örneğin: ilk_proje).

Python interpreter (yürütücü) olarak daha önce kurduğunuz Python sürümünü seçin.  (Mesela venv)

main.py adlı bir dosya oluşturun ve şu kodu yazın:

python

print(“Merhaba, Python dünyası!”)

Sağ üstteki yeşil “Run” (Çalıştır) butonuna tıklayarak kodunuzu çalıştırın.

Ek Tavsiyeler

PyCharm kısayollarına zamanla alışmak size büyük hız kazandırır.
Terminal kullanarak pip komutu ile paketler kurabilirsiniz.

Örneğin: pip install numpy
Virtual environment (sanallaştırılmış çalışma ortamı) kullanmak projelerinizi izole tutar ve karışıklığı önler.

Bir Sonraki Adımda Neler Var?

İzleyen makalelerde, Python kullanarak Yahoo Finance üzerinden BIST Spot hisse senetlerinin kapanış verilerini nasıl çekeceğimizi adım adım öğreneceğiz. Elde ettiğimiz bu verileri Excel formatında kaydederek, şu analizleri gerçekleştireceğiz:

Farklı periyotlara göre EMA (Üssel Hareketli Ortalama) hesaplamaları

Osilatör ve momentum göstergeleri

EMA Alignment analizi (ideal dizilim ve sapma durumları)

WaveTrend tabanlı sinyal üretimi

Belirli periyotlarda Doğrusal Regresyon (Linear Regression Channel) hesaplamaları

Her hisse için bu analizlerin Pearson korelasyon katsayısı ile değerlendirilmesi

Tüm bu analiz sonuçlarını Python ile  tasarlanmış Excel şablonlarına aktararak, hisse senetlerinin teknik durumlarını görsel olarak kolayca takip edebileceğiniz tarama dosyaları oluşturabileceksiniz.

Pine Script ile Günlük, Haftalık, Aylık ve Yıllık Pivot Noktaları Gösteren Gelişmiş Tablo İndikatörü

27 Temmuz 2025 BorsaPin, Code is prority, İndikatör, Pine Scriptgüncel destek direnç seviyeleri, klasik fibonacci woodie pivot hesaplama, pine script ile pivot indikatörü, pivot noktaları nasıl hesaplanır, teknik analiz destek direnç tablosu, tradingview pivot destek direnç göstergesi

 

Pivot noktaları, teknik analizde sıklıkla kullanılan ve bir varlığın olası destek ve direnç seviyelerini belirlemek için kullanılan matematiksel seviyelerdir. Bu seviyeler, yatırımcılara alım-satım kararlarında yardımcı olan önemli araçlardan biridir.

TradingView platformu üzerinde Pine Script ile geliştirilen ve grafik üzerinde çizim yapmadan sadece tablo formatında çalışan gelişmiş bir pivot analiz aracını tanıtacağız. Ayrıca kullanıcıların tercihlerine göre Klasik, Fibonacci veya Woodie pivot yöntemlerinden birini seçerek analiz yapabilmesi mümkün olacak. Youtubeda ki bir çok yayıncının yaptığı gibi bilgiyi para karşılığı satan bir zihniyette olmadığım için ücretsiz bir şekilde yararlanabilirsiniz.

İndikatörün Özellikleri

Zaman Dilimi Seçimi: Günlük, Haftalık, Aylık ve Yıllık pivot seviyeleri hesaplanır.

Yöntem Seçimi: Kullanıcı, Klasik, Fibonacci veya Woodie hesaplama yöntemlerinden birini tercih edebilir.

Tablo Üzerinden Görselleştirme: Pivot, 3 destek ve 3 direnç seviyesi; ilgili zaman dilimi ve yönteme göre tablo halinde görüntülenir.

Kapanış Bekleme Opsiyonu: Haftalık, aylık ve yıllık mum kapanışları henüz gerçekleşmediyse, bir önceki dönemin verileri kullanılır. Ancak kullanıcı, ayarlardan  Güncel veriyi kullanmak isterse bu seçeneği  pasifleştirerek o anki mum verileriyle hesaplama yapabilir.

Pivot Noktaları Nasıl Hesaplanır?

1. Klasik Pivot (Classic Pivot)

P = (High + Low + Close) / 3
R1 = (2 * P) – Low
S1 = (2 * P) – High
R2 = P + (High – Low)
S2 = P – (High – Low)
R3 = High + 2*(P – Low)
S3 = Low – 2*(High – P)

2. Fibonacci Pivot

P = (High + Low + Close) / 3
R1 = P + 0.382 * (High – Low)
R2 = P + 0.618 * (High – Low)
R3 = P + 1.000 * (High – Low)
S1 = P – 0.382 * (High – Low)
S2 = P – 0.618 * (High – Low)
S3 = P – 1.000 * (High – Low)

3. Woodie Pivot

P = (High + Low + 2 * Close) / 4
R1 = (2 * P) – Low
S1 = (2 * P) – High
R2 = P + (High – Low)
S2 = P – (High – Low)
R3 = High + 2*(P – Low)
S3 = Low – 2*(High – P)

Kullanım Şekli

TradingView’de yeni bir Pine Script oluşturun.

Kodunuzu yapıştırarak çalıştırın.

İndikatör, grafikte herhangi bir çizim yapmaz. Ancak ekranın sağ üst köşesinde pivot değerlerini detaylı bir şekilde gösteren bir tablo oluşturur.

Ayarlar kısmından:

Pivot türünü (Classic, Fibonacci, Woodie)

Zaman dilimini (Günlük, Haftalık , Aylık, Yıllık)

Text uzantılı dosya olarak indirmek isterseniz buraya tıklayın.

Trading View Günlük haftalık Aylık Yıllık PivotTablo Pine Script Kodu

// Bu, Pine Script™ kodu Mozilla Kamu Lisansı 2.0 (MPL-2.0) altında lisanslandı
// © krstsntrk © BorsaPin code is priority
//@version=5
indicator(title = 'BorsaPin Pivot Sistem', shorttitle = 'BorsaPin Pivot Sistem', overlay = true)

// === Kullanıcı Ayarları ===
pivotType = input.string("Woodie", title="Pivot Tipi", options=["Classic", "Fibonacci", "Woodie"])
useCurrentBar = input.bool(true, title="Kapanış Bekleme Opsiyonu (Açık mum yerine önceki kapanışı kullanır.)")
showDaily = input.bool(true, title="Günlük Pivot Göster")
showWeekly = input.bool(true, title="Haftalık Pivot Göster")
showMonthly = input.bool(true, title="Aylık Pivot Göster")
showYearly = input.bool(true, title="Yıllık Pivot Göster")

// === Zaman Aralığına Göre High/Low/Close ===
getHigh(_tf) => useCurrentBar ? request.security(syminfo.tickerid, _tf, high) : request.security(syminfo.tickerid, _tf, high[1])
getLow(_tf) => useCurrentBar ? request.security(syminfo.tickerid, _tf, low) : request.security(syminfo.tickerid, _tf, low[1])
getClose(_tf) => useCurrentBar ? request.security(syminfo.tickerid, _tf, close) : request.security(syminfo.tickerid, _tf, close[1])

// === Pivot Hesaplayıcı Fonksiyon ===
calcPivots(high_, low_, close_, _type) =>
    pivot = 0.0
    r1 = 0.0
    r2 = 0.0
    r3 = 0.0
    s1 = 0.0
    s2 = 0.0
    s3 = 0.0

    if _type == "Classic"
        pivot := (high_ + low_ + close_) / 3
        r1 := 2 * pivot - low_
        s1 := 2 * pivot - high_
        r2 := pivot + (high_ - low_)
        s2 := pivot - (high_ - low_)
        r3 := high_ + 2 * (pivot - low_)
        s3 := low_ - 2 * (high_ - pivot)

    else if _type == "Fibonacci"
        pivot := (high_ + low_ + close_) / 3
        r1 := pivot + 0.382 * (high_ - low_)
        r2 := pivot + 0.618 * (high_ - low_)
        r3 := pivot + 1.000 * (high_ - low_)
        s1 := pivot - 0.382 * (high_ - low_)
        s2 := pivot - 0.618 * (high_ - low_)
        s3 := pivot - 1.000 * (high_ - low_)

    else if _type == "Woodie"
        pivot := (high_ + low_ + 2 * close_) / 4
        r1 := (2 * pivot) - low_
        s1 := (2 * pivot) - high_
        r2 := pivot + (high_ - low_)
        s2 := pivot - (high_ - low_)
        r3 := high_ + 2 * (pivot - low_)
        s3 := low_ - 2 * (high_ - pivot)

    [pivot, r1, r2, r3, s1, s2, s3]

// === Her Zaman Dilimi İçin High / Low / Close Al ===
dH = getHigh("D")
dL = getLow("D")
dC = getClose("D")

wH = getHigh("W")
wL = getLow("W")
wC = getClose("W")

mH = getHigh("M")
mL = getLow("M")
mC = getClose("M")

yH = getHigh("12M")
yL = getLow("12M")
yC = getClose("12M")

// === Pivotları Hesapla ===
[dP, dR1, dR2, dR3, dS1, dS2, dS3] = calcPivots(dH, dL, dC, pivotType)
[wP, wR1, wR2, wR3, wS1, wS2, wS3] = calcPivots(wH, wL, wC, pivotType)
[mP, mR1, mR2, mR3, mS1, mS2, mS3] = calcPivots(mH, mL, mC, pivotType)
[yP, yR1, yR2, yR3, yS1, yS2, yS3] = calcPivots(yH, yL, yC, pivotType)

// === Tablo Oluştur ===
var table pivotTable = table.new(position.top_right, 8, 20, border_width=1)

// === Başlıklar ===
if bar_index % 10 == 0
    table.cell(pivotTable, 0, 0, "Zaman", text_color=color.black, bgcolor=color.gray)
    table.cell(pivotTable, 1, 0, "P", text_color=color.navy)
    table.cell(pivotTable, 2, 0, "R1", text_color=color.lime)
    table.cell(pivotTable, 3, 0, "R2", text_color=color.lime)
    table.cell(pivotTable, 4, 0, "R3", text_color=color.lime)
    table.cell(pivotTable, 5, 0, "S1", text_color=color.red)
    table.cell(pivotTable, 6, 0, "S2", text_color=color.red)
    table.cell(pivotTable, 7, 0, "S3", text_color=color.red)

// === Veri Satırı Ekleme Fonksiyonu ===
addRow(idx, label, p, r1, r2, r3, s1, s2, s3) =>
    table.cell(pivotTable, 0, idx, label, text_color=color.black)
    table.cell(pivotTable, 1, idx, str.tostring(p, format.mintick))
    table.cell(pivotTable, 2, idx, str.tostring(r1, format.mintick))
    table.cell(pivotTable, 3, idx, str.tostring(r2, format.mintick))
    table.cell(pivotTable, 4, idx, str.tostring(r3, format.mintick))
    table.cell(pivotTable, 5, idx, str.tostring(s1, format.mintick))
    table.cell(pivotTable, 6, idx, str.tostring(s2, format.mintick))
    table.cell(pivotTable, 7, idx, str.tostring(s3, format.mintick))

// === Tabloda Göster ===
row = 1
if showDaily
    addRow(row, "Günlük", dP, dR1, dR2, dR3, dS1, dS2, dS3)
    row += 1
if showWeekly
    addRow(row, "Haftalık", wP, wR1, wR2, wR3, wS1, wS2, wS3)
    row += 1
if showMonthly
    addRow(row, "Aylık", mP, mR1, mR2, mR3, mS1, mS2, mS3)
    row += 1
if showYearly
    addRow(row, "Yıllık", yP, yR1, yR2, yR3, yS1, yS2, yS3)

 

Bank of America (BoFA) gibi büyük finansal kurumların robotları nasıl çalışır.

22 Temmuz 2025 BorsaPinC++, Compliance, Data Ingestion, Java, KDB+/q, LSTM, Machine Learning ve AI, Python, PyTorch, Redis, Statistical Arbitrage, TensorFlow



Bank of America (BoFA) gibi büyük finansal kurumların robotları (otomatik alım-satım sistemleri, “trading bots”) çok katmanlı, yüksek teknolojiye dayalı ve sürekli güncellenen yapılarla çalışır. Aşağıda bu robotların nasıl çalıştığını ana başlıklarla özetleyeceğim.


1. Veri Toplama (Data Ingestion)

  • Gerçek zamanlı fiyat verisi (Level 1/2 order book, tick-by-tick).
  • Temel veriler: bilanço, gelir tablosu, makroekonomik göstergeler.
  • Haber akışı: Reuters, Bloomberg, sosyal medya sentiment analizi.
  • Alternatif veriler: uydu görüntüleri, lojistik verileri, tüketici verisi.

2. Algoritma Türleri

a. Statistical Arbitrage (StatArb)

  • Farklı piyasalardaki fiyat sapmalarından kar elde etmeye çalışır.
  • Cointegration, mean reversion, pairs trading gibi yöntemler kullanılır.

b. Market Making

  • Alım ve satım arasında sürekli fiyat teklifi verir.
  • Hızlı işlem (latency < 1 ms) ile küçük farklardan kâr sağlar.

c. Trend Following / Momentum

  • Teknik göstergeler (EMA, RSI, MACD) veya fiyat hareketleriyle pozisyon açar.
  • Genellikle daha uzun zaman dilimlerine dayanır.

d. Machine Learning ve AI

  • Derin öğrenme, reinforcement learning gibi tekniklerle karar verir.
  • Örn: LSTM ile zaman serisi tahmini, transformer ile haber analizi.

e. Execution Algoritmaları

  • VWAP, TWAP, POV gibi algoritmalar büyük emirleri piyasa etkisi yaratmadan parçalara bölerek işler.

3. Karar Alma ve Uygulama Süreci

  1. Sinyal üretimi: Model, al/sat/sus gibi kararlar üretir.
  2. Risk kontrolü: Pozisyon boyutu, kaldıraç, stop loss limitleri kontrol edilir.
  3. Order Routing: En uygun borsaya veya likidite sağlayıcısına yönlendirilir.
  4. Gerçek zamanlı izleme: Tüm sistem anlık olarak izlenir, anomaliler tespit edilir.

4. Yapısal Özellikler

  • Ultra düşük gecikme: New York–London arası fiber-optik hatlar veya mikrodalga iletişim.
  • Kolokasyon: Borsa sunucularına fiziksel olarak en yakın lokasyonlarda işlem yapılır.
  • Yüksek frekanslı işlem (HFT): Milyonlarca işlem/gün mümkün.

5. Denetim ve Uyum (Compliance)

  • Algoritmalar sürekli olarak düzenleyici kurallara uygunluk açısından izlenir.
  • Anormal davranışlar (manipülasyon, spoofing) algoritma tarafından engellenir.

6. Geliştirme Süreci

  • Kuant analistleri, yazılımcılar ve risk yöneticileri birlikte çalışır.
  • Algoritmalar önce backtest, sonra paper trading, en son da canlı işlem ortamına alınır.

Örnek Kullanılan Teknolojiler:

  • Python, C++, Java: Algoritma geliştirme
  • KDB+/q, Redis: Hızlı veri erişimi
  • TensorFlow, PyTorch: Yapay zeka modelleri
  • FIX protokolü: Emir iletimi
  • GPU/FPGA: Yüksek işlem gücü için
Page 2 of 27«12345...1020...»Last »
Etiketler
Teknik AnalizaşkPythonhisse senedi analiziEma AlignmentÜstel Hareketli OrtalamaPine Scripthayatalgoritmik tradingtrend analizipivotEmaallahteratrend takibiyatırım stratejisiBorsaPinotomatik analizpiyasa momentumuyatırım stratejileriborsa eğitimifinansal analizborsa stratejileriborsaPython ile BIST verisi çekmePython teknik analizPython borsa analiziPearson korelasyonuStop-Lossİdeal EmadirençdestekFibonacciİdeal Ema UpTrading ViewCem Sultansonbaharmuhsin yazıcıoğlukehanetözlemhayalmasalatatürkfiravunPhp Melody
Arşiv
  • Eylül 2026
  • Nisan 2026
  • Ağustos 2025
  • Temmuz 2025
  • Nisan 2025
  • Şubat 2025
  • Ocak 2025
  • Kasım 2024
  • Ekim 2024
  • Temmuz 2024
  • Mart 2024
  • Ocak 2023
  • Ağustos 2018
  • Temmuz 2016
  • Kasım 2015
  • Kasım 2014
  • Aralık 2013
  • Eylül 2013
  • Kasım 2012
  • Ekim 2012
  • Haziran 2011
  • Mart 2011
  • Şubat 2011
  • Ocak 2011
  • Aralık 2010
  • Kasım 2010
  • Eylül 2010
  • Ağustos 2010
  • Temmuz 2010
  • Haziran 2010
  • Mayıs 2010
  • Nisan 2010
  • Mart 2010
  • Şubat 2010
  • Ocak 2010
  • Aralık 2009
  • Kasım 2009
  • Ekim 2009
  • Eylül 2009
  • Ağustos 2009
  • Temmuz 2009
  • Haziran 2009
  • Mayıs 2009
  • Nisan 2009
  • Mart 2009
  • Şubat 2009
  • Ocak 2009
  • Aralık 2008
  • Kasım 2008
Sponsor Bağlantılar
Kategoriler
  • Anlık Tepkiler
  • Bilinçaltı Sayıklamaları
  • Bitmeyen Senfoni
  • Blog
  • Borsa
  • BorsaPin
  • Bu nedir ?
  • Code is prority
  • Halet-i Ruhiye
  • İndikatör
  • Karma Karışık
  • Pine Script
  • Python
  • Teknik Analiz
  • Teknoloji
  • Trading View
  • Wordpress
  • Telegram
  • YouTube
Son Yorumlar
  • Fonlarda Finansal Mühendislik, Sistemik Risk ve BIST 30 için Lagosbombai
  • PHP Mobil Cihazları yönlendirme için Azmi Güneş
  • Son bir hatıra için sdc
  • Arkadaşlık siteleri ve Tuzakları için can
  • Windows 7’de EasyPHP kurulumu (resimli anlatım) için mustafa


Borsapin Proje Google Drive

Sponsor Bağlantılar
Sponsor Bağlantılar
.

.

.

.

2026 © SDC