Blog

  • Sample Page
  • Hakkında
  • Kullanım
  • İletişim
  • Gizlilik
  • BorsaPin

Python Teknik Analiz Hazırlığı 1

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

Ağustos 1, 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.

[code lang=”js”]
"""
Borsapin StokData Yahoo Finans Üzerinden Kapanış Dataları indirme Scripti
www.kursatsenturk.com

"""

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

# Renkli yazı için colorama’yı başlatıyoruz
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()

[/code]

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.

Recent Posts

  • Kod gösterimleri ile ilgili sıkıntı
  • Borsapin EMA Sinyal Tablosu (Kısa, Orta, Uzun Vade)
  • Python BorsaPin Lineer Regresyon ve Pearson Analizi Betiği
  • Borsapin TradingView WT Sinyal Osilatör: Piyasa Dönüşlerini Tespit Etmede Güçlü Bir Araç
  • Python ile Borsa Verilerinden Wave Trend İndikatörü Sinyal Tarama Betiği

Recent Comments

  1. ateş - Pine Script ile Günlük, Haftalık, Aylık ve Yıllık Pivot Noktaları Gösteren Gelişmiş Tablo İndikatörü
  2. ateş - Pine Script ile Günlük, Haftalık, Aylık ve Yıllık Pivot Noktaları Gösteren Gelişmiş Tablo İndikatörü
  3. sdc - Pine Script ile Günlük, Haftalık, Aylık ve Yıllık Pivot Noktaları Gösteren Gelişmiş Tablo İndikatörü
  4. ateş - Pine Script ile Günlük, Haftalık, Aylık ve Yıllık Pivot Noktaları Gösteren Gelişmiş Tablo İndikatörü
  5. Borsapin :) - Pine Script ile Günlük, Haftalık, Aylık ve Yıllık Pivot Noktaları Gösteren Gelişmiş Tablo İndikatörü

Archives

  • 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

Categories

  • Anlık Tepkiler
  • Bilinçaltı Sayıklamaları
  • Bitmeyen Senfoni
  • Blog
  • BorsaPin
  • Bu nedir ?
  • Code is prority
  • Halet-i Ruhiye
  • İndikatör
  • Karma Karışık
  • Pine Script
  • Python
  • Teknik Analiz
  • Teknoloji
  • Trading View
  • Wordpress
Footer Sidebar 1

Drop a widget on "Footer Sidebar 1" sidebar at Appearance > Widgets page.

Footer Sidebar 2

Drop a widget on "Footer Sidebar 2" sidebar at Appearance > Widgets page.

Footer Sidebar 3

Drop a widget on "Footer Sidebar 3" sidebar at Appearance > Widgets page.

Footer Sidebar 4

Drop a widget on "Footer Sidebar 4" sidebar at Appearance > Widgets page.

2026 © Blog
Truemag theme by StrictThemes