Ana Sayfa / Blog / AI & Otomasyon
AI & Otomasyon

Finansal Veri Entegrasyonu Rehberi: BIST 100 ve Küresel Endeksleri API ile Verimli Takip Etmek

Yazar: apibir Geliştirici Ekibi 4 dk okuma süresi

İçindekiler

  1. Endeks verisi ile hisse verisi farkı
  2. Endeksleri tek sorguda çekmek
  3. Seans saatlerini koda gömmeyin
  4. Endeks bileşenleri ve ağırlıklar
  5. Geçmiş seri ve getiri grafiği
  6. 30 saniyelik panel mimarisi
  7. Ekonomik takvim ve faiz bağlamı
  8. Türkçe sayı biçimlendirme
  9. Kredi bütçesi hesabı
  10. Sık yapılan hatalar
  11. Sık sorulan sorular

Özet: BIST 100'ü ekrana yazdırmak tek satırlık bir fetch çağrısıdır; asıl iş, seans saatlerini, kapanış verisini ve endeks bileşenlerini doğru modellemektir. Bu rehberde apibir Endeks Fiyatları API'sinin /indices ailesini kullanarak yerli ve küresel endeksleri tek sorguda çekiyor, marketStatus alanıyla seans mantığını koddan çıkarıyor ve 30 saniyede bir güncellenen bir portföy takip paneli kuruyoruz.

Endeks Verisi ile Hisse Verisi Aynı Şey Değildir

Portföy paneli kurmaya başlayan ekiplerin ilk kararı genellikle yanlış olur: her hisseyi ayrı ayrı sorgulayıp toplamı endeks sanmak. Endeks, bileşen hisselerin belirli bir ağırlıklandırma yöntemiyle (BIST 100'de fiili dolaşımdaki pay oranı ile düzeltilmiş piyasa değeri) hesaplanan tek bir puandır. Kendiniz hesaplamaya kalkarsanız hem ağırlık verisini sürekli güncel tutmak zorunda kalır hem de sermaye artırımı, bölünme ve endeksten çıkarma gibi olaylarda sapma üretirsiniz.

Pratik ayrım şudur:

  • Piyasanın genel yönünü göstermek istiyorsanız endeks verisi kullanın — tek çağrı, tek kredi, sabit alan şeması.
  • Kullanıcının kendi portföyünü değerlemek istiyorsanız hisse bazlı veri gerekir; endeksi yalnızca kıyas ölçütü (benchmark) olarak kullanın.
  • Sektörel dağılım analizi yapacaksanız endeks bileşenlerini ve ağırlıklarını /indices/{code}/components ucundan alın; bu veri günlük olarak yeterlidir, saniyelik değil.

1. Adım: XU100 ve Küresel Endeksleri Tek Sorguda Çekmek

Endeks servisi 126 endeksi 34 ülke kapsamında sunar. codes parametresine virgülle ayrılmış liste vererek hepsini tek istekte alırsınız — beş ayrı çağrı yapmak yerine bir kredi harcamanın en kolay yolu budur:

cURL
curl --request GET \
  --url "https://api.apibir.com/v1/indices?codes=XU100,XU030,SPX,NDX,DAX" \
  --header "authorization: apikey APIBIR-8f2c...9d41" \
  --header "accept: application/json"
Node.js (fetch)
const KODLAR = ["XU100", "XU030", "SPX", "NDX", "DAX"];

const url = new URL("https://api.apibir.com/v1/indices");
url.searchParams.set("codes", KODLAR.join(","));

const res = await fetch(url, {
  headers: { authorization: `apikey ${process.env.APIBIR_KEY}` }
});
if (!res.ok) throw new Error(`apibir ${res.status}`);

const { data } = await res.json();
const byCode = Object.fromEntries(data.map((d) => [d.code, d]));
console.log(byCode.XU100.value, byCode.XU100.changePercent);
Python (requests)
import os, requests

r = requests.get(
    "https://api.apibir.com/v1/indices",
    params={"codes": "XU100,XU030,SPX,NDX,DAX"},
    headers={"authorization": f"apikey {os.environ['APIBIR_KEY']}"},
    timeout=10,
)
r.raise_for_status()
endeksler = {d["code"]: d for d in r.json()["data"]}
print(endeksler["XU100"]["value"], endeksler["XU100"]["changePercent"])
Bölge bazlı sorgu
# codes yerine region kullanarak bir bölgenin tamamını çekin
curl --request GET \
  --url "https://api.apibir.com/v1/indices?region=tr" \
  --header "authorization: apikey APIBIR-8f2c...9d41"

# region değerleri: tr | us | eu | asia

Dönen yanıt her endeks için aynı şemayı taşır:

Örnek yanıt (kısaltılmış)
{
  "success": true,
  "creditsUsed": 1,
  "timestamp": "2026-08-20T10:42:52+03:00",
  "data": [
    {
      "code": "XU100",
      "name": "BIST 100",
      "country": "TR",
      "currency": "TRY",
      "value": 11482.36,
      "previousClose": 11395.80,
      "open": 11402.15,
      "change": 86.56,
      "changePercent": 0.76,
      "dayLow": 11380.44,
      "dayHigh": 11510.90,
      "yearToDatePercent": 18.42,
      "marketStatus": "open",
      "updatedAt": "2026-08-20T10:42:45+03:00"
    },
    {
      "code": "SPX",
      "name": "S&P 500",
      "country": "US",
      "currency": "USD",
      "value": 6284.11,
      "previousClose": 6301.55,
      "change": -17.44,
      "changePercent": -0.28,
      "marketStatus": "closed",
      "updatedAt": "2026-08-19T23:00:00+03:00"
    }
  ]
}

Kritik alan marketStatus. BIST seansı açıkken open, kapanışta closed, ABD borsalarında ise seans öncesi/sonrası işlemlerde pre ve after değerlerini alır. Bu alanı kullanmak, seans saatlerini uygulamanıza gömmekten çok daha dayanıklıdır.

2. Adım: Seans Saatlerini Koda Gömmeyin

"BIST 10:00–18:00 arası açıktır" varsayımıyla yazılmış her panel, yılda en az birkaç kez yanlış çalışır: yarım gün seanslar, resmi tatiller, yaz saati uygulaması nedeniyle kayan ABD seansı ve olağanüstü durumlarda seans iptalleri. marketStatus alanı bu kararı veri sağlayıcının sorumluluğuna devreder.

JavaScript — duruma göre periyot
const PERIYOT = {
  open:   30_000,        // seans açık: 30 saniye
  pre:    60_000,        // seans öncesi
  after:  60_000,        // seans sonrası
  closed: 15 * 60_000,   // kapalı: 15 dakika yeter
};

function sonrakiPeriyot(endeksler) {
  // Takip edilen endekslerden en az biri açıksa hızlı moda geç
  const durumlar = endeksler.map((e) => e.marketStatus);
  if (durumlar.includes("open")) return PERIYOT.open;
  if (durumlar.some((d) => d === "pre" || d === "after")) return PERIYOT.pre;
  return PERIYOT.closed;
}

function rozet(endeks) {
  return {
    open:   { metin: "Seans açık",   renk: "green" },
    pre:    { metin: "Açılış öncesi", renk: "amber" },
    after:  { metin: "Kapanış sonrası", renk: "amber" },
    closed: { metin: "Kapalı",        renk: "grey"  },
  }[endeks.marketStatus];
}
Python
PERIYOT = {"open": 30, "pre": 60, "after": 60, "closed": 900}

def sonraki_periyot(endeksler):
    durumlar = {e["marketStatus"] for e in endeksler}
    if "open" in durumlar:
        return PERIYOT["open"]
    if durumlar & {"pre", "after"}:
        return PERIYOT["pre"]
    return PERIYOT["closed"]

Tatil günlerinde panelinizin ne yapacağını da tanımlamanız gerekir. "Bugün BIST açık mı?" sorusunu API'ye sormadan yanıtlamak isterseniz apibir Resmi Tatiller & İş Günü API'si yıllık takvimi tek sorguda döner; kullanım detaylarını iş günü aritmetiği rehberinde anlattık. İkisini birleştirdiğinizde, kapalı günlerde gereksiz yere API çağırmayan ve kredi harcamayan bir zamanlayıcı kurabilirsiniz.

3. Adım: Endeks Bileşenleri ile Sektörel Dağılım

Bir portföyün BIST 100'e göre nerede durduğunu göstermenin en etkili yolu, kullanıcının hisse ağırlıklarını endeksin ağırlıklarıyla yan yana koymaktır. /indices/{code}/components ucu bileşenleri ağırlıklarıyla birlikte döner:

cURL
curl --request GET \
  --url "https://api.apibir.com/v1/indices/XU100/components" \
  --header "authorization: apikey APIBIR-8f2c...9d41"
Python — portföy vs endeks ağırlığı
import os, requests

r = requests.get(
    "https://api.apibir.com/v1/indices/XU100/components",
    headers={"authorization": f"apikey {os.environ['APIBIR_KEY']}"},
    timeout=15,
)
bilesenler = {b["symbol"]: b["weight"] for b in r.json()["data"]}

portfoy = {"THYAO": 22.0, "ASELS": 18.0, "GARAN": 10.0}   # yüzde ağırlıklar

for sembol, agirlik in portfoy.items():
    endeks_agirligi = bilesenler.get(sembol, 0.0)
    fark = agirlik - endeks_agirligi
    yon = "fazla ağırlık" if fark > 0 else "az ağırlık"
    print(f"{sembol}: portföy %{agirlik:.1f} · endeks %{endeks_agirligi:.2f} → {yon}")

Bileşen listesi endeks dönemsel gözden geçirmelerinde değişir; günde bir kez çekip önbelleğe almak yeterlidir. Her sayfa görüntülemesinde bu ucu çağırmak, kredi bütçenizin en hızlı tükenme yollarından biridir.

4. Adım: Geçmiş Seri ile Getiri Grafiği

Panelin altına yerleştireceğiniz "yılbaşından bugüne" grafiği için her gün ayrı sorgu atmayın. /indices/history ucu tek çağrıda tüm seriyi döner ve yearToDatePercent alanı zaten hazır bir özet sunar:

cURL
curl --request GET \
  --url "https://api.apibir.com/v1/indices/history?code=XU100&range=1y" \
  --header "authorization: apikey APIBIR-8f2c...9d41"
Node.js — Chart.js için seri hazırlama
const url = new URL("https://api.apibir.com/v1/indices/history");
url.searchParams.set("code", "XU100");
url.searchParams.set("range", "1y");

const { data } = await (await fetch(url, {
  headers: { authorization: `apikey ${process.env.APIBIR_KEY}` }
})).json();

// Chart.js'in beklediği {x, y} formatına dönüştür
const seri = data.map((g) => ({ x: g.date, y: g.close }));

// Endekslenmiş getiri (ilk gün = 100) — farklı endeksleri kıyaslamak için
const taban = data[0].close;
const normalize = data.map((g) => ({ x: g.date, y: (g.close / taban) * 100 }));

Farklı para birimlerindeki endeksleri aynı grafikte karşılaştırırken dikkatli olun: XU100'ün TL bazlı getirisi ile S&P 500'ün USD bazlı getirisini doğrudan yan yana koymak yanıltıcıdır. Adil bir karşılaştırma için convert parametresiyle her iki seriyi ortak bir para birimine çevirin; böylece kur etkisi ayrıştırılmış olur.

5. Adım: 30 Saniyelik Panel Mimarisi

Endeks servisi 30 saniyede bir güncellenir. Panel mimarisini bu ritme göre kurmak, hem kredi bütçesini hem de kullanıcı deneyimini birlikte optimize eder:

  • 1

    Tek çekici (poller), çok tüketici

    Sunucuda tek bir zamanlayıcı 30 saniyede bir apibir'i çağırsın; bağlı tüm tarayıcılar Server-Sent Events ile bu tek kaynaktan beslensin. 500 eşzamanlı kullanıcı, 500 kredi değil, saatte 120 kredi harcar.

  • 2

    Seans kapalıyken periyodu uzatın

    marketStatus === "closed" olduğunda 30 saniye yerine 15 dakikada bir çekmek yeterlidir. Bu tek değişiklik aylık kredi tüketimini yaklaşık üçte iki oranında düşürür.

  • 3

    Son bilinen değeri koruyun

    Geçici bir 429 veya 5xx yanıtında paneli boşaltmayın; son başarılı değeri updatedAt damgasıyla göstermeye devam edin ve görsel olarak "gecikmeli" işaretleyin.

Ön yüzde grafik çizerken de aynı disiplin geçerli: her SSE mesajında grafiği baştan çizmek yerine yalnızca son noktayı ekleyin. Chart.js kullanıyorsanız chart.data.datasets[0].data.push(...) ve chart.update("none") ikilisi, animasyon maliyetini de ortadan kaldırır. Yapay zeka destekli bir arayüzle hızlı prototip çıkarmak isterseniz Claude ve ChatGPT ile canlı finans panosu kurma yazımız hazır bir iskelet sunuyor.

Sayıya Bağlam Ekleyin: Ekonomik Takvim ve Faiz

Bir endeks panelinin kullanıcıya gerçekten değer kattığı an, sayının neden hareket ettiğini de gösterebildiği andır. Enflasyon verisi, faiz kararı ya da istihdam açıklaması gibi olaylar seans içi hareketlerin büyük kısmını açıklar. apibir Ekonomik Takvim API'si günün açıklamalarını saatiyle birlikte döndüğü için, panelin yan sütununa "bugün 10:00 — TÜFE, 14:00 — Fed faiz kararı" gibi bir şerit eklemek tek ek çağrıya mal olur ve günde bir kez çekilmesi yeterlidir.

Aynı mantık faiz tarafında da işler: Faiz Oranları API'sinden alınan politika faizi, endeks grafiğinin altına ikinci bir eksen olarak konduğunda kullanıcıya çok daha okunaklı bir hikâye anlatır. Bu tür bağlam katmanları günlük veriyle çalıştığı için kredi maliyetleri ihmal edilebilir düzeydedir; panelin algılanan kalitesine katkısı ise orantısız biçimde yüksektir.

Türkçe Sayı Biçimlendirme ve Küçük Detaylar

Teknik olarak doğru çalışan panellerin çoğu, biçimlendirme detaylarında tökezler. Türkiye'de binlik ayırıcı nokta, ondalık ayırıcı virgüldür; 11482.36 değerini olduğu gibi ekrana basmak amatör bir izlenim bırakır. Tarayıcıda Intl.NumberFormat("tr-TR") bu işi doğru yapar ve ek bir kütüphane gerektirmez.

Üç ayrıntıya daha dikkat edin. Birincisi, yüzde değişimlerde artı işaretini açıkça yazın — +0,76% ile 0,76% arasında okunabilirlik farkı vardır. İkincisi, renk körlüğü nedeniyle yalnızca kırmızı-yeşil ayrımına güvenmeyin; yön okunu veya artı/eksi işaretini de gösterin. Üçüncüsü, güncelleme saatini kullanıcının yerel saatinde gösterin: API zaman damgalarını +03:00 ofsetiyle döner, ancak yurt dışından bağlanan bir kullanıcı için tarayıcı yerelleştirmesi daha anlamlıdır.

Kredi Bütçesi: Panel Ayda Kaç Kredi Harcar?

Kredi hesabı, mimari kararlarınızın doğrudan çıktısıdır. Aynı paneli üç farklı şekilde kurduğunuzda tablo şöyle değişir:

Kurgu Yenileme Aylık istek (yaklaşık) Not
Her tarayıcı doğrudan API'yi çağırıyor (50 eşzamanlı kullanıcı) 30 sn ≈ 4.320.000 Anahtar istemcide görünür, kota anında tükenir
Tek sunucu poller, 7/24 sabit periyot 30 sn ≈ 86.400 Kabul edilebilir, ama kapalı seansta boşa çağrı
Tek sunucu poller, seans durumuna göre periyot 30 sn / 15 dk ≈ 25.000 Önerilen kurgu — kullanıcı deneyiminde fark yok

Üçüncü satır, ilkinden yaklaşık 65 kat daha ucuz olmasına rağmen kullanıcı deneyiminde neredeyse hiçbir fark yaratmaz — çünkü seans kapalıyken güncellenecek veri zaten yoktur. Plan seçenekleri ve kredi paketleri için fiyatlandırma sayfasına göz atabilirsiniz.

Endeks Entegrasyonunda Sık Yapılan Hatalar

Hata Sonucu Doğrusu
Her endeks için ayrı istek atmak 5 endeks = 5 kredi; kota beş kat hızlı biter. codes parametresine virgülle ayrılmış liste verin, tek kredi harcayın.
Seans saatlerini uygulamaya sabitlemek Yarım gün seanslarda ve yaz saati geçişlerinde panel yanlış durum gösterir. marketStatus alanını okuyun; saat mantığını veri sağlayıcıya bırakın.
Kapanış verisini canlı veri gibi göstermek Kullanıcı hafta sonu baktığında Cuma kapanışını anlık fiyat sanar. marketStatus ve updatedAt ile "son kapanış" etiketi gösterin.
Bileşen listesini her istekte çekmek 100 satırlık ağır bir yanıt, sayfa görüntülemesi başına 1 kredi. Günde bir kez çekip önbelleğe alın; bileşenler saniyelik değişmez.
Farklı para birimlerindeki endeksleri doğrudan karşılaştırmak TL bazlı getiri ile USD bazlı getiri yan yana konunca yanıltıcı sonuç çıkar. convert parametresiyle ortak para birimine çevirin veya kur etkisini ayrı gösterin.

Sık Sorulan Sorular

BIST 100 verisi API üzerinden gecikmeli mi geliyor?

Endeks servisi 30 saniyede bir güncellenir ve ortalama yanıt süresi yaklaşık 68 ms'dir. Yanıttaki updatedAt alanı verinin tam olarak hangi anı temsil ettiğini söyler; panelinizde bu damgayı göstermek, kullanıcıya tazelik konusunda net bilgi verir.

Kaç endeks kapsanıyor, sadece BIST mi var?

Servis 34 ülkeden 126 endeksi kapsar. BIST 100 (XU100) ve BIST 30 (XU030) yanında S&P 500, Nasdaq 100, DAX gibi küresel endeksler de aynı uçtan gelir. Bir bölgenin tamamını almak için region=tr, us, eu veya asia parametresini kullanabilirsiniz.

Endeks bileşenlerini ve ağırlıklarını alabilir miyim?

Evet. /indices/{code}/components ucu bileşen hisseleri ağırlıklarıyla birlikte döner. Bu veri dönemsel gözden geçirmelerde değiştiği için günde bir kez çekip önbelleğe almak yeterlidir.

Hisse senedi bazında veri de var mı?

Endeks servisi endeks puanlarını verir. ABD hisseleri için ayrı bir servis olan Amerikan Borsası API'si NASDAQ ve NYSE hisselerini temel oranlarıyla birlikte sunar; API kataloğundan inceleyebilirsiniz.

Geçmiş endeks verisine ne kadar geriye gidebilirim?

/indices/history ucu günlük kapanış serisini döner ve aralığı range parametresiyle belirlersiniz. Tek çağrıda tüm seriyi aldığınız için gün gün sorgu atmanıza gerek kalmaz; bu hem hız hem kredi açısından çok daha verimlidir.

Panelimi 500 kişi aynı anda açarsa kotam biter mi?

Tarayıcılar doğrudan API'yi çağırıyorsa evet. Doğru kurgu, sunucuda tek bir zamanlayıcının veriyi çekmesi ve tüm istemcilerin Server-Sent Events ya da WebSocket ile bu tek kaynaktan beslenmesidir; bu durumda kullanıcı sayısı kredi tüketimini hiç etkilemez.

Devamı: Endeks verisini faiz, döviz ve ekonomik takvim verileriyle birleştirip tek panelde toplamak isterseniz API kataloğundaki diğer finans servislerine ve hızlı başlangıç rehberine göz atın.

Ücretsiz API anahtarını 30 saniyede al

← Tüm Blog Yazılarına Dön Ücretsiz API Anahtarı Al