Back to Projects

Tcmb Reserve Terminal

TCMB rezerv, swap, likidite ve altın hareketlerini EVDS 3'ten izleyen; müdahale sinyali üreten finansal istihbarat dashboard'u. Next.js + Fastify + PostgreSQL.

<div align="center">

TCMB Rezerv & Müdahale Terminali

Türkiye Cumhuriyet Merkez Bankası'nın piyasa davranışını tek ekrandan izleyen finansal istihbarat dashboard'u

Rezervler · Net rezerv · Swap · Likidite · Altın ayrıştırması · Müdahale sinyalleri · AI yorumu

Node TypeScript Next.js Fastify PostgreSQL Tests License

Ekran görüntüleri · AI yorum katmanı · Kurulum · EVDS tuzakları · Sinyal metodolojisi · API

</div>

⚠️ Önce bunu okuyun

TCMB'nin döviz ve altın işlemleri işlem bazında ve gerçek zamanlı olarak kamuya açıklanmamaktadır. Bu proje hiçbir koşulda tahmini bir işlemi kesin gerçek gibi göstermez.

Bu sistem demezBunun yerine der
❌ "TCMB bugün 750 milyon USD sattı"✅ "Döviz satış sinyali — güven 62/100"
❌ "Altın rezervi 40 ton azaldı"✅ "İma edilen altın miktarı −40 ton (fiyata bölünerek tahmin edildi)"

Her analitik çıktının altında kaynağı, yöntemi ve şu uyarı yer alır: "Bu gösterge doğrudan açıklanan TCMB işlem verisi değildir."

Yatırım tavsiyesi değildir. Bkz. Bilinen sınırlar.

<details> <summary><b>English summary</b></summary>

A financial-intelligence dashboard that tracks the Central Bank of the Republic of Türkiye (CBRT/TCMB) reserves, swap stock, TL liquidity operations and gold, and derives analytical intervention signals from published data.

The CBRT does not publish transaction-level FX or gold operations. This project therefore never claims an intervention happened — it produces explicitly labelled signals with a documented, config-driven confidence score, and shows the source, series code, observation date and native frequency behind every number.

Data comes from EVDS 3 (evds3.tcmb.gov.tr/igmevdsms-dis). All 48 series codes are verified against the live EVDS catalogue on every seed run.

</details>

📊 Ekran görüntüleri

AI yorumu — "grafiklerden bir şey anlamıyorum" diyenler için

Her ekranın başında, o ekrandaki verileri sade Türkçe ile açıklayan bir panel. Sayılar sistemden, cümleler dil modelinden — ve metindeki her sayı doğrulanmadan gösterilmez.

AI yorum paneli

Overview — "Şu anda TCMB piyasada ne yapıyor?"

Tek ekranda rezerv yönü, sinyaller, likidite yorumu ve kaynak/tazelik bilgisi.

Overview

<table> <tr> <td width="50%">

Rezervler

Brüt · döviz · altın · swap hariç net rezerv; değişimin kaynağına ayrıştırılması.

Rezervler

</td> <td width="50%">

Döviz

USD/TRY ile rezervin aynı eksende karşılaştırılması, kur–rezerv ayrışma kontrolü.

Döviz

</td> </tr> <tr> <td width="50%">

Altın

Değişimin fiyat etkisi ve miktar etkisi olarak ayrıştırılması, resmî ons verisiyle çapraz kontrol.

Altın

</td> <td width="50%">

Likidite

Net fonlama, bileşen kırılımı ve "TCMB bugün ne kadar TL verdi/çekti" yorumu.

Likidite

</td> </tr> <tr> <td width="50%">

TCMB İşlemleri

Repo/ters repo, döviz depo ihaleleri, swap stoku ve doğrulanmış işlem katmanı.

İşlemler

</td> <td width="50%">

Müdahale Sinyalleri

Sinyal geçmişi ve sinyallerin rezerv/kur grafiği üzerinde işaretlenmesi.

Sinyaller

</td> </tr> <tr> <td width="50%">

Timeline

Resmî duyurular, yayın takvimi ve veriden türetilen olaylar — ayrı etiketlerle.

Timeline

</td> <td width="50%">

Ayarlar

API anahtarları, kaynak sağlığı, seri kataloğu, alarm kuralları ve dışa aktarma.

Ayarlar

</td> </tr> </table>

✨ Öne çıkan özellikler

🎯 Sinyal değil, gerekçeHer sinyalin faktör kırılımı açılabilir: hangi faktör kaç puan kattı, neden. Ağırlıklar merkezî config'te.
📐 Yöntemi görünürNet rezerv ve altın ayrıştırması gibi hesaplanmış her metrik, yöntemini ve bilinen sınırlarını yanında taşır.
🕐 "LIVE" yalanı yokHaftalık veri "Haftalık veri" olarak etiketlenir. Her metrikte gözlem tarihi + son çekim zamanı gösterilir.
🚫 Eksik veri ≠ 0Veri yoksa null döner, ekranda "veri yok" yazar. Grafikte boşluk boşluk kalır.
🔍 Kaynak izlenebilirHer sayının altında EVDS seri kodu ve metaveri bağlantısı.
🛡️ Veri bütünlüğü korumasıEVDS'nin sessiz toplulaştırması tespit edilir ve bozuk veri yazılmaz (detay).
📉 Değerleme etkisi ayrıştırılırAltın fiyatı hareketi rezerv artışının ne kadarını açıklıyor? Sinyal skorunda ceza faktörü olarak kullanılır.
🔔 Alarm sistemiRezerv düşüşü, sinyal seviyesi, net fonlama eşiği. Telegram/e-posta/push için kanal soyutlaması hazır.
🤖 AI yorumu (doğrulamalı)Gemini verileri sade Türkçe ile açıklar; metindeki HER sayı ve tarih sistem verisiyle karşılaştırılır. Eşleşmeyen varsa metin gösterilmez.
🔑 Arayüzden anahtar girişiAPI anahtarları Ayarlar ekranından girilir; kaydedilmeden önce canlı test edilir, AES-256-GCM ile şifreli saklanır.
📤 ExportHer seri CSV/JSON; dosya başlığında veri modu belirtilir.
🧪 165 testToplulaştırma tespiti, ayrıştırma matematiği, sinyal skoru, eksik veri davranışı.

🚀 Kurulum

Gereksinimler: Node.js ≥ 20, Docker (PostgreSQL için), opsiyonel EVDS API anahtarı.

git clone https://github.com/<kullanici>/<repo>.git
cd <repo>
npm install

cp .env.example .env          # Windows: copy .env.example .env

npm run db:up                 # PostgreSQL 16 + Redis (docker compose)
npm run build -w @tcmb/shared
npm run migrate               # şema
npm run seed:series           # seri kataloğunu EVDS'den doğrula (ANAHTAR GEREKTİRMEZ)
npm run collect -- --full     # 5 yıllık geçmişi çek
npm run dev                   # API :4000 · Web :3000

Dashboard → http://localhost:3000

API anahtarı olmadan denemek

.env içinde DATA_MODE=mock bırakın. Sentetik veri üretilir ve ekranın üstünde kalıcı bir "MOCK VERİ" bandı çıkar; her metriğin kaynağı "MOCK ÜRETİCİ — GERÇEK VERİ DEĞİLDİR" olarak görünür, dışa aktarılan dosyaların başlığına da bu not düşülür.

Canlı veriye geçmek

  1. https://evds3.tcmb.gov.tr → üye ol → Profilim → API Key
  2. .env: EVDS_API_KEY=... ve DATA_MODE=live
  3. npm run evds:verify → servis tabanını ve anahtarı doğrular
  4. npm run collect -- --full

Güvenlik: EVDS_API_KEY yalnızca backend'de kullanılır. Hiçbir NEXT_PUBLIC_* değişkenine konmaz, API cevaplarında yer almaz, frontend TCMB'ye doğrudan istek yapmaz. .env ve .evds-endpoint.json .gitignore'dadır.

<details> <summary><b>Port çakışması / Docker'sız PostgreSQL / Next.js .env notu</b></summary>

Port: API_PORT varsayılanı 4000. Doluysa .env içinde hem API_PORT hem NEXT_PUBLIC_API_BASE_URL değerini birlikte değiştirin:

API_PORT=4010
NEXT_PUBLIC_API_BASE_URL=http://localhost:4010

PostgreSQL: docker-compose.yml PostgreSQL'i 5433 portunda yayımlar (yerel 5432 ile çakışmasın diye). Kendi sunucunuzu kullanacaksanız yalnızca DATABASE_URL yeterli.

Next.js: Next normalde sadece apps/web içindeki .env dosyalarını okur. Bu projede apps/web/next.config.mjs monorepo kökündeki .env'i yükler; tek dosya hem backend'i hem frontend'i besler.

Cannot find module './xxx.js' hatası: Dev sunucusu açıkken next build çalıştırıldıysa .next bozulmuştur. Çözüm: rm -rf apps/web/.next && npm run dev:web

</details>

🏗️ Mimari

Frontend TCMB'ye hiç gitmez. Toplama işleri zamanlanmış çalışır, veri PostgreSQL'de durur, analiz motoru üzerine hesaplar.

   TCMB EVDS 3  ──key: HTTP header──┐
                                     ▼
   ┌──────────────────────────────────────────┐
   │ Data collector      apps/api/collectors  │  katalog senk. · frekans koruması
   │                                          │  normalize · anomali tespiti
   └────────────────────┬─────────────────────┘
                        ▼
   ┌──────────────────────────────────────────┐
   │ PostgreSQL                               │  observations · indicators
   │                                          │  signals · timeline · alerts
   └────────────────────┬─────────────────────┘
                        ▼
   ┌──────────────────────────────────────────┐
   │ Analytics engine    apps/api/analytics   │  calculateNetReserves()
   │                                          │  decomposeGoldChange()
   │                                          │  InterventionAnalyzer
   └────────────────────┬─────────────────────┘
                        ▼
   ┌──────────────────────────────────────────┐
   │ AI katmanı          apps/api/ai          │  olgu özeti → Gemini
   │                                          │  → sayı/tarih/iddia doğrulaması
   └────────────────────┬─────────────────────┘
                        ▼
   ┌──────────────────────────────────────────┐
   │ REST API (Fastify)  →  Next.js dashboard │
   └──────────────────────────────────────────┘
packages/shared     Tipler · EVDS seri kayıt defteri · sinyal ağırlıkları · biçimlendirme
apps/api            Fastify API · collector'lar · analytics · scheduler · testler
apps/web            Next.js 15 App Router · Tailwind · Recharts
docs/screenshots    Arayüz görüntüleri
<details> <summary><b>Veritabanı şeması</b></summary>
TabloAmaç
data_sourcesKaynak sağlığı: son başarılı fetch, HTTP durumu, OK/DEGRADED/FAILED
economic_seriesSeri metaverisi: kod, veri grubu, birim, unit_confirmed, frekans
observationsGözlemler. value NULL = "veri yok", 0 değil. (series_id, date) tekil
observation_revisionsTCMB bir değeri revize ederse eski değer burada saklanır
calculated_indicatorsTüretilmiş seriler + yöntem + güven skoru
intervention_signalsSinyaller + faktör kırılımı (JSONB)
timeline_eventsOlaylar; derived alanı resmî/türetilmiş ayrımını taşır
alert_rules / alert_eventsAlarm kuralları ve tetiklenmeleri
collection_runsToplama denetim kaydı

Migration: bağımlısız SQL çalıştırıcı (npm run migrate), schema_migrations tablosu.

</details> <details> <summary><b>Scheduler — TCMB yayın saatlerine göre (TSİ)</b></summary>
CronNe zamanİş
15 9,12,16,18 * * 1-5Hafta içi gün içiİş günü serileri + analiz + alarm
35 14 * * 4Perşembe 14:35Haftalık rezerv yayını (yayın 14:30)
30 15 * * 4Perşembe 15:30Gecikmeli yayına karşı ikinci deneme
45 14 8-13 * *Ayın 8–13'üAylık IRFCL
0 3 * * 0Pazar 03:00Katalog senkronizasyonu (kod/birim değişiklikleri)
0 4 1 * *Ayın 1'i5 yıllık tam geçmiş tazeleme (revizyon yakalama)

Yatay ölçeklemede scheduler yalnızca tek örnekte açık olmalıdır (SCHEDULER_ENABLED=false).

</details>

🤖 AI yorum katmanı

"Bu grafikler iyi güzel de ben çok bir şey anlamıyorum."

Her ekranın başında, o ekrandaki verileri sade Türkçe ile açıklayan bir panel var. Ayrıca serbest soru sorulabilen bir kutu.

Temel ilke: sayılar sistemden, cümleler modelden

Dil modeli veri kaynağı değildir. Veri tabanına, EVDS'ye ya da internete erişmez. Yalnızca sistemin hesapladığı bir olgu özeti görür ve onu anlatır.

snapshot → olgu özeti (facts + bağlam) → Gemini → DOĞRULAMA → önbellek → arayüz
                                                     │
                                                     └─ geçemezse → kural tabanlı yedek

Üç katmanlı doğrulama

Model akıcı ama yanlış üretebilir. Bu yüzden çıktı, kullanıcıya ulaşmadan önce üç denetimden geçer:

DenetimNe yakalarCanlı testte yakalanan gerçek örnek
SayıOlgu kümesinde bulunmayan her sayıModelin kendi hesapladığı "bir hafta önce 164.448 milyon USD idi"
TarihSisteme verilmemiş her tarihModel "3 Eylül'de açıklanacak" dedi; gerçek yayın 20 Ağustostu
İddiaKesinlik bildiren ifadeler"TCMB 750 milyon USD sattı", "müdahale etti"

Sayı denetimi birim ölçeğini bilir: sistem 178366 milyon USD tutarken model "178,4 milyar USD" yazabilir — kabul edilir; "185 milyar" edilmez. Sıra sayıları ("33. Hafta"), gün sayıları ("son 7 günde") ve skor paydası ("70/100") veri sayılmaz; bunlar denetim dışıdır.

Doğrulamayı geçemeyen metin kullanıcıya gösterilmez. Yerine kural tabanlı (şablon) özet konur ve neden düşüldüğü ekranda yazar. Reddedilen metin denetim izi olarak saklanır ama önbellekten bir daha servis edilmez.

Kural tabanlı yedek

Anahtar yoksa, model çağrısı başarısızsa ya da doğrulama düşerse devreye giren tamamen deterministik özet. Daha az akıcıdır ama sayıları doğrudan sistemden alır — yani en kötü durumda kullanıcı daha sade bir metin görür, asla yanlış bir sayı görmez.

Maliyet kontrolü

Yorumlar veri durumunun parmak izine göre önbelleklenir: veri değişmediyse model tekrar çağrılmaz. Yeni haftalık rezerv verisi geldiğinde parmak izi değişir ve yorum kendiliğinden tazelenir.

Kurulum

Ayarlar ekranından ya da .env üzerinden:

GEMINI_API_KEY=...
GEMINI_MODEL=gemini-2.5-flash

Anahtar yoksa dashboard tam olarak çalışmaya devam eder; yalnızca yorumlar şablonla üretilir.


🔑 API anahtarlarının arayüzden yönetimi

API anahtarları

Ayarlar ekranından hem EVDS hem Gemini anahtarı girilebilir.

ÖnlemNasıl
Şifreli saklamaAES-256-GCM. Şifreleme anahtarı SETTINGS_SECRET ortam değişkeninden ya da .settings-key dosyasından gelir (gitignore'da). Veritabanı yedeği tek başına anahtarları açığa çıkarmaz.
Geri dönmezAPI ham anahtarı ASLA döndürmez; yalnızca son 4 karakteri maskelenmiş hâlde gösterilir.
Kaydetmeden önce testAnahtar önce gerçek servise sorulur (EVDS: seri isteği, Gemini: model listesi). Çalışmayan anahtar kaydedilmez.
Yazma korumasıADMIN_TOKEN tanımlıysa x-admin-token başlığı zorunlu. Tanımlı değilse yazma uçları yalnızca localhost'tan çalışır.

⚠️ API'yi dışarı açacaksanız ADMIN_TOKEN tanımlamanız zorunludur. Aksi hâlde anahtar yazma uçları uzak isteklere kapalı kalır (403 döner).

Öncelik sırası: Ayarlar ekranından girilen değer > .env dosyası. Hangi kaynağın aktif olduğu ekranda rozetle gösterilir.


⚠️ EVDS entegrasyonunda üç tuzak

Kendi EVDS entegrasyonunuzu yazacaksanız bu bölüm projenin en değerli kısmıdır. Üçü de canlı veriyle çalışırken yakalandı ve üçü de sessizce yanlış veri üretiyor.

1. EVDS 2 kapatıldı — internetteki tüm örnekler ölü

TCMB duyurusu #1006 (09.02.2026): EVDS 2, 20 Şubat 2026'da sonlandırıldı.

- https://evds2.tcmb.gov.tr/service/evds/...   → 302, JSON yerine HTML döner
+ https://evds3.tcmb.gov.tr/igmevdsms-dis/...  → güncel

Anahtar URL'de değil, key HTTP başlığında gönderilir (duyuru #195, Nisan 2024).

curl -H "key: $EVDS_API_KEY" \
  "https://evds3.tcmb.gov.tr/igmevdsms-dis/series=TP.AB.TOPLAM&startDate=01-01-2026&endDate=18-08-2026&type=json"

Anahtar gerektirmeyen uçlar (bu projede katalog ve timeline için kullanılır):

İçerik
/serieList/fe/type=json&code=<grup>Gruptaki seri kodları, adları, frekansları
/categories/withDatagroups/type=jsonVeri grubu metaverisi (birim, kaynak, metaveri linki)
/announcementsTCMB EVDS duyuruları
/calendar/yillikYayinlarResmî veri yayım takvimi (tarih + saat)

Bu projede eski URL hard-code edilmemiştir; npm run evds:verify aday tabanları gerçek anahtarla dener ve çalışanı kaydeder.

2. Farklı frekanslar aynı istekte → sessiz toplulaştırma

Tek istekte farklı frekanstaki seriler sorulduğunda EVDS cevabın tamamını en düşük frekansa indirger ve satırları dönem-sonu tarihiyle etiketler. Uyarı yok, cevapta bunu belirten bir alan yok.

İstenenAynı istekteki seriDönen veriSonuç
TP.APIFON3 (iş günü)TP.AB.TOPLAM (haftalık)Haftalık, Cuma etiketliSon gözlem 2026-08-21gelecek tarih
TP.DK.USD.S.YTL (günlük)TP.REZVARPD.* (aylık)Aylık, ay-sonu5 yılda 1826 yerine 61 gözlem
TP.ALTINPIYASA.KAP03 (iş günü)aynıAylıkAltın fiyatı iki rezerv gözlemi arasında hiç değişmedi

Son satırın etkisi kritikti: fiyat sabit görünürse altın rezervindeki tüm artış "miktar etkisi" sayılır ve sistem sahte bir ALTIN ALIM SİNYALİ üretir (güven 71/100). Frekans düzeltildikten sonra aynı dönem için doğru sonuç ALTIN SATIŞ SİNYALİ çıktı — yani toplulaştırma sinyalin yönünü ters çevirmişti.

3. 1000 satır tavanı — en eski uçtan sessizce keser

Tek cevapta azami 1000 satır döner; fazlası baştan kırpılır. 5 yıllık günlük seri istendiğinde son ~4 yıl gelir, gerisi sessizce kaybolur.

Bu projedeki üç katmanlı savunma

apps/api/src/collectors/frequency-guard.ts

  1. Frekansa göre gruplama — istekler yalnızca aynı frekanstaki serileri içerir.
  2. Zaman penceresi bölme — 1000 satır tavanına çarpılmaması için aralık frekansa göre pencerelere bölünür.
  3. Doğrulama — cevaptaki gözlem aralığı beklenenden 2 kat kabaysa veya bugünden ileri tarihli gözlem varsa veri yazılmaz, toplama hatası olarak raporlanır.
ÖncesiSonrası
5 yıllık toplama5.624 satır55.308 satır
Seri frekanslarıhaftalık/aylığa çökmüşher seri kendi doğal frekansında
Gelecek tarihli gözlemvaryok

📚 Veri serileri

48 seri kodunun tamamı canlı EVDS kataloğundan doğrulanmıştır. npm run seed:series her çalıştığında registry EVDS ile karşılaştırılır; bir kod bulunamazsa katalog uyumsuzluğu olarak raporlanır ve komut çıkış kodu 2 döner.

<details> <summary><b>Tam seri → metrik eşleme tablosu (48 seri)</b></summary>

Rezervler — bie_abres2 · haftalık (Cuma) · milyon USD · yayın Perşembe 14:30

Seri koduAdBeslediği metrik
TP.AB.TOPLAMToplam rezervBrüt rezerv, rezerv grafiği, net rezerv, FX sinyali
TP.AB.C2DövizDöviz rezervi kartı, döviz paneli, FX sinyali
TP.AB.C1AltınAltın rezervi kartı, altın paneli, altın sinyali

Swap — bie_swaptektarf · iş günü · milyon USD

Seri koduAd
TP.SWAPTEKTAR.TOTALSTOKALIMYONLUToplam swap stoku (alım yönlü) → swap hariç net rezerv
TP.SWAPTEKTAR.TOTALSTOKSATIMYONLUToplam swap stoku (satım yönlü)
TP.SWAPTEKTAR.SWAPKUSDTUTARDöviz karşılığı TL swap piyasası (günlük işlem)
TP.SWAPTEKTAR.SWAPKSTOKUSDTUTARAynı piyasa — stok
TP.SWAPTEKTAR.SWAPASTOKUSDTUTARTL karşılığı altın swap — stok
TP.SWAPTEKTAR.SWAPDSTOKUSDTUTARDöviz karşılığı altın swap — stok

Likidite / APİ — bie_apifon · iş günü · milyon TL

Seri koduAd
TP.APIFON3TCMB Net Fonlama (A−B)
TP.APIFON1.TOP / .IHA / .KOT.TToplam / ihale / kotasyon fonlaması
TP.APIFON1.KOT.ABİST O/N + kotasyon + PY repo → repo kartı
TP.APIFON1.KOT.B / .KOT.CTL depo / GLP depo-repo
TP.APIFON2.TOPToplam sterilizasyon → ters repo kartı
TP.APIFON2.IHA / .KOT / .LIKSterilizasyon kırılımı
TP.APIFON4Ağırlıklı ortalama fonlama maliyeti

Diğer

Seri koduVeri grubuAd
TP.RP01.MYRTP.RP04.MKTbie_rtrnrRepo / ters repo (müşteri + mali kuruluş)
TP.PPIBSM / TP.PPIGBTLbie_ppibsmBankalar serbest mevduatı / gün başı likidite
TP.FXSWAP0103bie_fxswapTL karşılığı döviz depo ihaleleri
TP.AB.A02 / A10 / A11 / A14 / A24 / A19bie_abanlbilAnalitik bilanço (TL)
TP.REZVARPD.K11bie_ulusdovlkdAltın — milyon saf troy ons (ton hesabı)
TP.REZVARPD.K10 / K1 / K2, TP.DOVVARNC.K14bie_ulusdovlkdIRFCL çapraz kontrol kalemleri
TP.DK.USD.S.YTL / .A.YTL, TP.DK.EUR.S.YTL, TP.DK.EUR.C.YTLbie_dkdovytlKurlar
TP.ALTINPIYASA.KAP03bie_altinbistbulAltın kapanış USD/ons (BİST)
TP.ALIM.USD / TP.SATIM.USDbie_dovefmudDoğrudan müdahaleler — ARŞİV
</details> <details> <summary><b>Birim kuralı — neden bazı birimlerin yanında <code>*</code> var?</b></summary>

EVDS'nin BIRIMI alanı seri değil, veri grubu birimidir ve gruptaki her seri için geçerli olmayabilir:

  • bie_apifon"milyon TL ve yüzde" (iki farklı birim bir arada)
  • bie_ulusdovlkd"milyon ABD doları" ama TP.REZVARPD.K11 ons cinsinden

Bu yüzden gösterilen birim her zaman seri bazlı registry birimidir; EVDS grup birimi yalnızca doğrulama için kullanılır. Eşleşmeyen seriler unit_confirmed = false ile işaretlenir ve arayüzde * ile gösterilir (48 serinin 11'i). Hiçbir seriye yanlış birim yapıştırılmaz.

</details>

🧮 Analytics

Net rezerv — iki yöntem, iki güven seviyesi

TCMB "net rezerv" diye tek bir seri yayımlamaz.

Yöntem 1 — gross_minus_swap (varsayılan, güven 85)

Swap Hariç Rezerv = TP.AB.TOPLAM − TP.SWAPTEKTAR.TOTALSTOKALIMYONLU

Her iki girdi de milyon USD → kur dönüşümü varsayımı yok. Swap iş günü, rezerv haftalık olduğundan swap değeri rezerv tarihine as-of hizalanır; swap verisi bulunamazsa gözlem null bırakılır (brüt değer "net" gibi gösterilmez).

Sınır: bankaların TCMB nezdindeki döviz mevduatı düşülmez — bu yüzden dar tanımlı NUR ile birebir aynı değildir. Metriğin adı bu yüzden "Swap Hariç Rezerv"dir.

Yöntem 2 — analytical_balance_sheet (deneysel, güven 45, varsayılan kapalı)

Yaklaşık Net Rezerv = (TP.AB.A02 − TP.AB.A10) ÷ USD/TRY

Analitik bilanço TL cinsindendir; tüm döviz kalemlerinin USD olduğu varsayılır — EUR, altın ve SDR nedeniyle sistematik sapma taşır. Seviye olarak değil, eğilim göstergesi olarak okunmalıdır.

Altın — fiyat mı, miktar mı?

Q_t = V_t / P_t                     (ima edilen miktar, milyon ons)
Fiyat etkisi  = Q₀ × (P₁ − P₀)
Miktar etkisi = (Q₁ − Q₀) × P₁
ΔV = Fiyat etkisi + Miktar etkisi   (tam olarak toplanır — testle doğrulanır)

Aylık resmî ons verisiyle çapraz kontrol edilir; sapmaya göre güven 85/75/60/40 olarak ayarlanır. Fiyat verisi yoksa ayrıştırma yapılmaz ve nedeni yazılır.


🎯 Müdahale sinyali nasıl hesaplanır

confidence = clamp( Σ ( maxWeight_i × f_i ) , 0 , 100 )
f_i = clamp( value_i / scale_i , 0 , 1 )

Ağırlıklar packages/shared/src/signal-config.ts içinde; analiz motorunda sabit sayı yoktur.

<details> <summary><b>Döviz satış sinyali faktörleri</b></summary>
FaktörAğırlıkTam puan eşiği
Doğrudan açıklanan TCMB satış verisi+401.000 mn USD
Döviz rezervindeki azalış+20−3.000 mn USD
Swap hariç net rezerv azalışı+15−2.500 mn USD
Swap stokundaki artış (maskeleme)+10+2.000 mn USD
USD/TRY yükselişi+10+%1,5
Net fonlama artışı (TL çekilmesi)+10+150.000 mn TL
Bankalar döviz mevduatındaki azalış+520 mr bin TL
Veri gecikmesi cezası−10beklenen gecikme + 14 gün
Değerleme etkisi cezası−10değişimin %100'ü fiyattan

Seviyeler: <25 NORMAL · 25–44 DİKKAT · 45–64 SİNYAL · ≥65 GÜÇLÜ SİNYAL

</details>

Güvenin yapısal üst sınırı — bilinçli bir tercih

direct_transaction faktörü yalnızca TCMB'nin doğrudan açıkladığı işlem verisi varsa puan üretir. Bu veri grubu (bie_dovefmud) arşiv durumunda olduğundan pratikte ulaşılabilir azami güven ~65'tir.

Doğrudan işlem verisi olmadan %90 güven iddia etmek kullanıcıyı yanıltmak olurdu. Veri gelirse sinyal otomatik olarak "DOĞRULANMIŞ İŞLEM VERİSİ" etiketine ve GÜÇLÜ seviyeye yükselir.

Altın sinyalinde de aynı ilke: miktar ölçülmediği (fiyata bölünerek ima edildiği) için −15 puanlık yapısal belirsizlik cezası her zaman uygulanır.


🔌 API endpointleri

Tüm cevaplar ortak zarf kullanır:

{
  "data": { /* ... */ },
  "meta": {
    "generatedAt": "2026-08-18T14:30:00.000Z",
    "dataMode": "live",
    "oldestObservationDate": "2025-08-18",
    "warnings": ["Veri güncellenemedi (TCMB EVDS) — son başarılı çekim: ..."]
  }
}

Her metrik value · unit · freshness (gözlem tarihi + frekans + etiket + bayat mı) · source (ad + seri kodu + veri grubu + metaveri linki) taşır.

EndpointAçıklama
GET /api/overviewTek ekran özeti
GET /api/reserves · /api/reserves/history?range=Rezervler + net rezerv yöntemi
GET /api/fx · /api/gold · /api/liquidity · /api/swaps · /api/operationsPanel verileri
GET /api/signals · /api/interventionsGüncel + geçmiş sinyaller
GET /api/timelineOlay zaman çizelgesi
GET /api/history?keys=&from=&to=Çoklu seri + sinyal işaretleri
GET /api/series/:keyTekil seri
GET /api/export?format=csv|json&keys=Dışa aktarma
GET /api/data-qualityKaynak sağlığı + seri kataloğu + toplama kayıtları
GET/POST/PATCH/DELETE /api/alertsAlarm kuralları
GET /api/ai/commentary?scope=Sade dille yorum (overview/reserves/gold/liquidity/signals)
POST /api/ai/askEkrandaki veriye serbest soru
GET /api/settings/keysAnahtar durumu (maskeli; ham değer dönmez)
PUT/DELETE /api/settings/keys/:key · POST .../testAnahtar kaydet / sil / test et
POST /api/admin/collectToplama zincirini elle tetikle

range: 1w · 1m · 3m · 6m · 1y · 3y · max


🧪 Testler

npm test

165 test / 9 dosya — vitest.

DosyaKapsam
evds/normalize.test.tsSayı/tarih ayrıştırma, eksik veri ≠ 0, aynı tarihin iki kez gelmesi, seri kodu değişikliği, anomali tespiti
collectors/frequency-guard.test.tsSessiz toplulaştırma tespiti, gelecek tarihli gözlem, 1000 satır tavanına göre pencere bölme
collectors/collector.test.tsURL sınırı bölme, frekans takvimi, mock determinizmi, arşiv serisinde veri uydurmama, birim doğrulama
analytics/reserves.test.tsAs-of hizalama, net rezerv (iki yöntem), eksik swapta null, rezerv atıfı
analytics/gold.test.tsFiyat + miktar etkisi toplamının değişime tam eşitliği, fiyat yokken hesaplamama, çapraz kontrol
analytics/intervention.test.tsStres/ayna senaryoları, skorun faktör toplamına eşitliği, gecikme/değerleme cezaları
ai/verifier.test.tsHalüsinasyon yakalama: uydurma sayı, modelin kendi hesapladığı türev, uydurma yayın tarihi, kesinlik iddiası; ölçek/sıra sayısı/skor paydası yanlış alarmları
ai/brief.test.tsOlgu özeti üretimi, parmak izi kararlılığı, gösterilmeyen tarihin izinli listeye girmemesi, yedek özetin kendi doğrulayıcısından geçmesi
routes/routes.test.tsUçtan uca API (DB taklitli): zarf yapısı, freshness'ın asla "LIVE" olmaması, eksik veride null

🚫 Bilinen sınırlar — ne HESAPLANAMAZ

SoruDurum
"TCMB bugün kaç dolar sattı?"Hesaplanamaz. İşlem bazlı veri açıklanmıyor; bie_dovefmud arşivde. Sistem yalnızca sinyal üretir.
"Rezervlerin USD/EUR kırılımı ne?"Hesaplanamaz. Haftalık para birimi kompozisyonu yayımlanmıyor. Dashboard bunun yerine EUR/USD parite etkisini gösterir.
"Altın rezervi kaç ton?" (haftalık)İma edilir, ölçülmez. Aylık resmî ons ile çapraz kontrol edilir, sapma gösterilir.
"Net uluslararası rezerv (dar tanım)"Kısmen. Varsayılan yöntem swap düzeltmesi yapar, banka döviz mevduatını düşmez.
"TCMB bugün gün içinde kaç TL fonladı?"Yaklaşık. Net fonlamadaki günlük değişim; gün içi brüt toplam ayrı yayımlanmaz.
"Bu sinyal kesin mi?"Hayır. Hiçbir sinyal kesin değildir.

Sistemin asla yapmadıkları

  • Eksik veriyi 0 kabul etmez → null döner, ekranda "veri yok" yazar
  • API hatasını veri gibi göstermez → eski veriyi gösterir + "Veri güncellenemedi" uyarısı
  • Haftalık veriyi "LIVE" diye etiketlemez → rozette "Haftalık veri" yazar
  • Tahmini müdahaleyi kesin işlem olarak sunmaz
  • Rezerv düşüşünü doğrudan "TCMB dolar sattı" diye yorumlamaz
  • Swap ve değerleme etkilerini yok saymaz — ikisi de sinyal skorunda ceza üretir

📄 Lisans

MIT

Veri kaynağı: TCMB EVDS ve Borsa İstanbul (EVDS üzerinden). Veriler ilgili kurumlara aittir; bu proje yalnızca kamuya açık veriyi işler ve görselleştirir.

⚖️ Sorumluluk reddi

Bu yazılım eğitim ve analiz amaçlıdır, yatırım tavsiyesi değildir. Üretilen tüm müdahale sinyalleri, yayımlanan verilerden hesaplanan analitik tahminlerdir ve TCMB'nin gerçekleştirdiği işlemleri temsil etmez. Kararlarınızın sorumluluğu size aittir.

Technologies

TypeScript
central-bank
evds
fastify
financial-data
fintech
nextjs
postgresql
tcmb
turkey
typescript

Details

Stars0
Forks0
LanguageTypeScript

Links

Source Code
Ask AI