You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Çalışma kuralı: Her faz tamamlandığında bu dosyaya tarihli bir kayıt eklenir
(ne yapıldı, commit, test sayısı, önemli kararlar/notlar) ve "Sıradaki İşler"
checklist'i güncellenir. Kapsamın tek yetkili kaynağı MVP_SCOPE.md'dir.
Config (config/settings.py): YAML + Pydantic, katmanlı yükleme
(base → mod overlay → strategies/.yaml), extra="forbid",
MVP kilitleri (leverage=1, short yasak, live onay şartı)
Loglama (monitoring/logging.py): run_id + mode + kategori formatı,
sabit kategori kümesi, günlük dosya + konsol
Test altyapısı: 57 unit test, pytest --basetemp=.pytest_tmp
(sistem TEMP'indeki bozuk ACL nedeniyle; bkz. pyproject.toml notu)
Faz 1 — Veri (tamamlandı, 2026-07-06)
Kararlar: veri kaynağı = Binance USDT-M Futures klines (fapi, public, API key
gerekmez; MVP_SCOPE.md güncellendi — futures yalnızca veri kaynağı, işlem tarafı
spot mantığıyla simüle); HTTP = doğrudan REST (requests, string fiyat → Decimal
kayıpsız); indikatörler = pandas/numpy (analitik değerler float, parasal alanlar
Decimal kalır)
Doğrulama: 103 test geçiyor (57 + 46 yeni, hepsi ağsız/mock); gerçek duman
testi: 7 günde 671 mum indi (kapanmamış son mum atıldı), 0 boşluk, taze; ikinci
çalıştırma artımlı (fetched=0 — son mumdan devam ettiği için duplicate bile
çekmiyor); DB'deki close değeri API'nin ham string'iyle birebir eşleşti
(Decimal kayıpsızlığı kanıtı); log satırları run_id | mode | DATA formatında
Faz 2 — Strateji (tamamlandı, 2026-07-06)
Arayüz:strategies/base.py — BaseStrategy (spec §9.2: name, version,
required_features(), validate_config() → ConfigError, generate_signal()
her zaman gerekçeli Signal döndürür, explain()) + StrategyContext
(frozen; candles yalnızca karar anına kadarki barlar — look-ahead yasağı §7.5,
dilimlemeyi motor yapar; bars_held() yardımcısı)
Feature çözümleyici:features.compute_features(df, names) — sma_{p} /
ema_{p} / rsi_{p} / atr_{p} / bollinger_{p}_{std} adlarını kolonlara çevirir;
strateji ihtiyacını adla bildirir, motor bir kez toptan hesaplar (O(n²) önlenir)
MeanReversionStrategy (mean_reversion, v1.0.0): parametreler iç Pydantic
modeliyle doğrulanır (extra=forbid, entry < exit). Giriş: close < alt bant VE
RSI < 30. Çıkış öncelik sırası: maks. tutma süresi → orta banda dönüş → RSI
normalleşmesi. Isınma NaN → "insufficient history" HOLD. Confidence: kalibre
edilmemiş doğrusal skor (sıralama amaçlı). Stop-loss/take-profit stratejide
DEĞİL (Faz 3/5'in işi); risk giriş engelleri Faz 5'te
Script:scripts/preview_signals.py — DB verisiyle pozisyonsuz sinyal
önizleme (backtest değil; Faz 3 gelince asıl akış motora geçer)
Doğrulama: 138 test geçiyor (103 + 35 yeni, sentetik veri); duman testi:
672 barda 5 BUY (30 Haziran düşüşünde, reason + RSI/bant değerleriyle),
son bar HOLD gerekçesi okunabilir; BUY metadata tutarlılığı REPL'de doğrulandı
(rsi < 30, close < bb_lower); look-ahead testi geçiyor; SIGNAL log formatı doğru
Faz 3 — Backtest (tamamlandı, 2026-07-06)
Motor (backtest/engine.py): kronolojik, bar-içi olay sırası look-ahead'i
imkânsız kılar — (1) açılışta önceki bar kapanışının bekleyen sinyali dolar,
(2) bar içinde SL/TP kontrolü (giriş barı dahil; aynı barda ikisi → kötümser: SL),
(3) kapanışta strateji yalnızca o ana kadarki dilimi görür. Muhasebe Decimal;
değişmez testle sabit: end = start − Σcommission + Σrealized_pnl.
Veri sonu → pozisyon end_of_data ile kapanır. DB'ye yazım YOK (deney kirletmez)
Fill modeli (backtest/execution.py, Faz 4 PaperBroker'la ortak): slippage
alışta yukarı/satışta aşağı; SL/TP fill'leri kötümser (seviyenin altı); komisyon
her iki bacakta. close_reason: stop_loss | take_profit | signal_exit |
max_holding | end_of_data (max_holding kuralı stratejide yaşar, motor reason'dan ayrıştırır)
Boyutlama (risk/sizing.py, Faz 5 risk motoru da kullanacak):
qty = equity×risk% / (entry×SL%); nakit sınırı komisyon dahil (1x, negatif nakit
imkânsız); 8 ondalığa AŞAĞI yuvarlama
Metrikler (backtest/metrics.py, spec §7.5'in tamamı): getiri, buy-and-hold
(aynı kötümser fill modeliyle — adil karşılaştırma), maks. drawdown, kazanma
oranı (NET pnl ile sınıflama), profit factor (zarar yoksa None), yıllıklaştırılmış
Sharpe, komisyon, ort. süre; 0 işlem kenar durumları None ile
Rapor (backtest/report.py): markdown tablo + close_reason dağılımı +
strateji-vs-B&H farkı; reports/ altına kayıt (gitignore'da);
render_comparison ile 15m vs 5m yan yana
Script'ler:run_backtest.py (--days/--start/--end, --timeframe, --compare);
download_market_data.py'a --timeframe bayrağı + backfill eklendi
(plan boşluğuydu: DB'de yeni veri varken geçmişe dönük indirme çalışmıyordu;
repository'ye earliest_timestamp eklendi). Windows konsolu için stdout UTF-8
Doğrulama: 180 test (42 yeni: sizing, execution, motor senaryoları —
bir-sonraki-bar-açılışı fill'i, kötümser SL/TP, giriş barında SL, look-ahead
kanıtı, muhasebe değişmezi — metrikler, rapor); gerçek veri: 365 gün 15m
(35.039 mum, backfill'le) + 5m (105.119 mum) boşluksuz; determinizm: aynı komut
iki kez → birebir aynı rapor. Sonuç (dürüst): bu dönemde strateji zarar
ediyor — 15m: −71.3% (B&H −41.7%, 349 işlem, komisyon 37.85 USD); 5m daha
kötü: −93.0% (868 işlem, komisyon 61.24 USD) → MVP_SCOPE'un "15m, işlem
sıklığı/komisyon dengesi" gerekçesi veriyle doğrulandı. Strateji parametre
ayarı MVP kapsamı dışı; motor kötümser ve doğru çalışıyor
Faz 4 — Paper Trading (tamamlandı, 2026-07-06)
Broker arayüzü (brokers/base.py): Broker(ABC) — update_market(candle),
submit_order(request), position/cash/realized_pnl; live broker aynı imzayı
fiyat parametresi olmadan uygulayabilir (MVP'de kodu yazılmadı, arayüz hazır)
PaperBroker (brokers/paper.py): sanal nakit + tek pozisyon; fill'ler
backtest/execution.py ile birebir (yeni fill kodu yazılmadı); SL/TP bar
high/low simülasyonu, aynı barda ikisi → kötümser SL önce; yetersiz nakit →
OrderError; restore() ile kurtarma; DB bilmez (kayıt servis katmanında)
Repository'ler (storage/repositories.py): signals / orders / trades /
portfolio_snapshots / system_events — market_data ile aynı saklama kuralları
(epoch ms + TEXT-Decimal); OrderRepository.exists(client_order_id) duplicate
koruması; TradeRepository.get_open() (exit_timestamp IS NULL)
Portföy (portfolio/service.py): PortfolioSnapshot + build_snapshot;
realized_pnl kümülatif NET (komisyon düşülmüş)
Servis döngüsü (services/paper_service.py, spec §12): artımlı veri çek →
tazelik kontrolü (bayat → tur biter, çökmez) → yeni barlar sırayla: SL/TP
simülasyonu → sinyal üret + kaydet → BUY/SELL icra + tam DB izi + snapshot.
Backtest'ten bilinçli fark: sinyal bar kapanışında icra edilir (sonraki bar
açılışı beklenmez — canlıda kapanış ≈ sonraki açılış). İşlenmiş bar işaretçisi
signals tablosudur (restart-güvenli); duplicate emir koruması deterministik
client_order_id (paper-{strateji}-{sembol}-{bar_ms}-{yön}). Faz 5 yuvaları
(risk motoru, bildirim) döngüde açık uç olarak işaretli
Restart kurtarma: açık pozisyon = trades'te açık satır, nakit = son
snapshot; çökme/Ctrl+C pozisyon kaybettirmez (testli)
Config:config/paper.yaml mod overlay'i (mekanizma Faz 0'dan hazırdı);
script --once (duman testi/cron) veya sürekli döngü
Doğrulama: 209 test (29 yeni: broker, repository'ler, servis senaryoları —
uçtan uca BUY→TP DB izi, duplicate, restart, bayat veri, DataError);
gerçek API duman testi: --once → PAPER banner + 1 bar işlendi + gerekçeli
HOLD sinyali DB'de; ikinci --once → no_new_bars, duplicate satır yok;
log formatı run_id | paper | SECURITY/SIGNAL/HEALTH doğru
Strateji iyileştirme — rejim filtresi + stop mesafesi (2026-07-06, Faz 5 öncesi)
Teşhis (365g 15m baseline, −71.3%): zararın kaynağı stop_loss işlemleri
(349 işlemin 149'u, toplam −102 USD; SL:TP tetiklenme oranı ~5:1) — strateji
düşüş sürerken giriyordu (falling knife). signal_exit işlemleri ~başabaş;
sorun çıkışta değil girişteydi. İkinci yük: işlem başına ~%0.3 gidiş-dönüş
maliyet × 349 işlem
Kabul edilen 1 — rejim filtresi (trend_sma_period: 200): kapanış SMA200
üstünde değilse giriş yok (çıkışlar etkilenmez; None = kapalı). Tek başına
−71.3% → −9.0%, maxDD %72 → %11, işlem 349 → 31. Gerekçe: mean reversion
güçlü düşüş trendinde çalışmaz; RSI<30 orada dönüş değil momentum sinyalidir
Kabul edilen 2 — SL/TP mesafe ölçeği ×2 (config: SL %1→%2, TP %1.5→%3,
R:R aynı): %1 stop bant-altı girişlerin doğal gürültüsü içindeydi (filtreli
koşuda bile SL ort. −1.19 USD ile ana yüktü). −9.0% → −4.4%, stop tetiklenmesi
11 → 3. Risk %1 sabit kaldığından pozisyon nominali yarıya indi (maliyet de)
Reddedilen — reclaim onayı (yazıdaki "sarkma + bandın üstünde kapanış"):
filtresiz −71.3% → −70.2% (PF 0.36 → 0.28), filtreliyle −9.0% → −11.0%.
Ayı trendinde bantlar da düştüğü için onay barları düşen trendin içinde
bolca oluşuyor; kod kaldırıldı, ders strateji docstring'ine yazıldı.
Ayrıca denendi: RSI çıkışını kapatmak (etkisi ihmal edilebilir, alınmadı)
Doğrulama: 214 test (5 yeni: filtre engeli/izni/ısınması, çıkışların
filtreden muaf olduğu, parametre doğrulama); determinist aralık
2025-07-06T08:00 → 2026-07-06T07:45. Sonuç 15m: −4.4% (B&H −41.7%,
30 işlem, maxDD %5.5, komisyon 2.89); 5m aynı parametrelerle −11.8%
(82 işlem — 15m tercihi yine doğrulandı); dönem yarıları H1 −3.9 / H2 −0.5
Dürüst değerlendirme: strateji hâlâ pozitif kenar ÜRETMİYOR — işlem
başına beklenti (−0.145 USD) ≈ işlem başına maliyet; brüt kenar ~sıfır.
Kazanım "az işlem + felaketi önleme": ayı yılında B&H'den 37 puan iyi,
maxDD %5.5. Pozitif kenar iddiası için boğa/yatay dönem verisiyle test
gerekir (mevcut 365 gün ayı ağırlıklı). Overfit riski düşük tutuldu:
2 kabul, 2 red, grid search yok; SMA200/2×ATR-benzeri değerler konvansiyon
Faz 5a — Risk motoru + kill switch (tamamlandı, 2026-07-06)
RiskEngine (risk/engine.py): her BUY sinyali emre dönüşmeden geçer
(spec §12 adım 6-7; paper_service.py'deki Faz 5 yuvası dolduruldu).
Kurallar sırayla, ilk ihlal reddeder (kötümser): kill_switch →
max_open_positions → daily_loss_limit → data_staleness → duplicate_signal
→ stop_loss_required → position_sizing. Karar = Faz 0'daki RiskDecision;
applied_rules değerlendirilen kuralları listeler. Motor durumsuzdur —
günlük limit dahil her şey DB'den hesaplanır (restart-güvenli).
Redler SECURITY loguna + system_events'e (risk_rejected) yazılır
Günlük zarar limiti: bugünkü (UTC) kapanmış işlemlerin NET PnL toplamı
≤ −%3 × gün-başı equity → gün sonuna dek giriş yok. Gün-başı equity =
gün öncesindeki son snapshot (yoksa starting_capital). Yeni repository
metodları: TradeRepository.realized_net_pnl_since,
PortfolioSnapshotRepository.latest_before (şema değişikliği YOK)
Kill switch (risk/kill_switch.py + scripts/kill_switch.py on|off|status):
dosya bayraklı (data/kill_switch), DB'den bağımsız, restart'a dayanıklı.
Aktifken giriş yok; çıkışlar (SL/TP, SELL) risk azaltıcı olduğundan asla
engellenmez; close_position_on_kill: true ise açık pozisyon sonraki barda
kill_switch gerekçesiyle kapatılır (spec §14.3'teki ayrı-config şartı)
Servis değişimi: duplicate + boyutlama kontrolleri servisten motora
taşındı (çift kod yok); _execute_exit artık close_reason'ı açık alır;
CycleResult.risk_rejections eklendi. Bilinçli sınır: risk motoru
backtest'e BAĞLANMAZ (günlük limit gibi durumsal kurallar deney sonuçlarını
değiştirir; doğrulandı — aynı aralıkta rapor birebir aynı: −4.37%, 30 işlem)
Doğrulama: 230 test (16 yeni: kural başına red/onay, UTC gün dönümü
sıfırlaması, snapshot tabanı, KillSwitch roundtrip; servis: kill switch
giriş engeli + config'li pozisyon kapatma + duplicate reddi uçtan uca);
gerçek API duman testi: normal tur ok, kill switch on → tur çökmeden
işliyor, off → normal; risk reddi=N script çıktısında
Faz 5b (kalan): Telegram bildirimleri — döngüdeki j yuvası açık
Faz 5b — Telegram bildirimleri (tamamlandı, 2026-07-07)
Modül (notifications/base.py + notifications/telegram.py): tek
generic Notifier.notify(event, message, metadata) arayüzü
(SystemEventRepository.insert ile aynı felsefe — 13-14 ayrı metot yok).
NotificationEvent enum'u spec §7.12'deki olayları kapsar; NEW_SIGNAL
enum'da var ama v1'de hiçbir yerden tetiklenmiyor (entry/exit/risk-reddi
zaten aynı bilgiyi veriyor, HOLD gürültüsü istenmedi — bilinçli karar).
TelegramNotifier: token/chat_id kurucuda ortam değişkeninden okunur
(config'de sadece değişken adı var, spec §14.1 — sır YAML'a girmez);
requests ile ham HTTP (sendMessage), kısa retry (backoff yok — bildirim
çekirdek döngüyü bloklamamalı); kontrat: notify() ASLA exception
fırlatmaz — ağ/HTTP hatası NOTIFICATION loguna yazılır ve yutulur.
Config:NotificationsConfig.telegram_enabled: bool → nested
TelegramConfig (rename, bilinçli kırılma): enabled, bot_token_env,
chat_id_env, request_timeout, max_retries. base.yaml'da kapalı
(backtest asla ağa çıkmaz), paper.yaml overlay'inde açık. .env yüklemesi
python-dotenv ile (scripts/run_paper_trading.py başında load_dotenv());
.env zaten gitignore'da.
Wiring (services/paper_service.py): PaperTradingService'e
notifier: Notifier | None = None parametresi (verilmezse settings'ten
TelegramNotifier kurulur — script değişmeden çalışır). Servis içinde
_notify() sarmalayıcısı (belt-and-suspenders: Notifier'ın kendi
kontratı ihlal edilse bile — ör. mesaj formatlama bug'ı — çekirdek
düşmez). 9 çağrı noktası: startup/shutdown, API/veri hatası, kill-switch
kapanışı, risk reddi (günlük limit ayrı event), giriş, çıkış (sinyal/
kill-switch), SL/TP tetiklenmesi. Her notify çağrısı mevcut/yeni
system_events insert'inin yanına eklendi (durable audit + best-effort
Telegram, aynı risk_rejected deseni). Eski # j. (Faz 5b yuvası) yorumu
kaldırıldı.
Doğrulama: 239 test (9 yeni: 8 TelegramNotifier — disabled/eksik env/
başarı/network hatası/4xx retry yok/429 retry var/token maskeleme/retry
sonrası başarı, hepsi sahte requests.Session ile ağsız; 1 FailingNotifier
enjekte edilmiş kritik senaryo — run_once() yine status="ok"
döndürüyor, çekirdek düşmüyor kanıtı).
Review düzeltmeleri: (1) requests hata mesajı isteğin URL'sini
içerdiğinden ağ hatası logu bot token'ı sızdırıyordu — _redact() ile
maskeleme eklendi; (2) kalıcı 4xx (bozuk token, yanlış chat_id) artık
retry edilmiyor — sadece ağ hatası, 429 ve 5xx yeniden denenir.
Gerçek bot duman testi: --once çalıştırıldı, TELEGRAM_BOT_TOKEN/
CHAT_ID.env'den okundu, NOTIFICATION kategorisinde hata yok, gerçek
Telegram sohbetine "🟢 Paper trading başladı..." mesajı ulaştı (kullanıcı
doğruladı). Not: sohbette paylaşılan token smoke test sonrası @BotFather
/revoke ile yenilenmeli.
Faz 6 — Terminal arayüzü (tamamlandı, 2026-07-07)
Mimari: salt-okunur üç katman — ui/queries.py (saf sorgular:
(Connection, Settings) → frozen dataclass, ham SQL yok, rich importu yok;
ileride FastAPI/React aynı fonksiyonları kullanır) → ui/render.py (yalnız
rich sunum) → scripts/dashboard.py (ince CLI). Yeni bağımlılık: rich>=13
(§20.1 gerekçesi pyproject yorumunda: renkli tablo/panel + titremeyen canlı
yenileme stdlib ile olmuyor).
Komutlar:dashboard.py [status|trades|events|backtest|settings]
(varsayılan status); status --watch [--interval N] rich Live ile canlı
yenileme — tek bağlantı, WAL sayesinde bot yazarken güvenle okur;
sqlite3.OperationalError yutulmaz, panelde gösterilir. backtest raporu
yeniden KOŞMAZ, en yeni reports/backtest_*.md'yi rich Markdown ile basar.
settings salt-okunur — arayüzden hiçbir yazma yolu yok (spec §7.13: live
mod tek tıkla açılamaz).
Yeni okuma metotları (ham SQL ui'a sızmasın diye repository'lere):
SignalRepository.latest(), SystemEventRow + SystemEventRepository .list_recent()/latest_of_types(), MarketDataRepository.latest_candle().
Toplam PnL için yeni metot GEREKMEDİ: realized_net_pnl_since(epoch)
(risk motorunun günlük limit kalıbıyla aynı hesap — tek doğruluk kaynağı).
Bot-aktif sezgiseli (heartbeat yok, bilinçli MVP kararı): son
service_started/stopped event'i + sinyal tazeliği (≤ 2×timeframe) →
running/stopped/stale/unknown; sınırları (çökmede stopped yazılmaz, --once
asimetrisi) docstring + bot_state_detail'de açıkça söylenir.
Dashboard create_database çağırmaz — connect() dosya yoksa boş DB
yaratırdı; önce is_file() kontrolü, yoksa yönlendirme mesajı + exit 1.
Windows cp1254: stdout.reconfigure(utf-8) rich Console'dan ÖNCE; ekranda
emoji yok (durum işaretleri rich markup).
Doğrulama: 255 test (16 yeni: 9 queries — boş/dolu DB, günlük-vs-toplam
PnL ayrımı, bot-state üçlemesi, kill switch, rapor sıralaması; 4 render
smoke Console(record=True); 3 repo okuma). Gerçek DB ile duman testi:
tüm alt komutlar + boş-DB mesajı + 8 sn --watch çalıştı.
MVP sonrası — Altyapı doğrulaması + smoke test aracı (2026-07-07)
Kullanıcının elle altyapı doğrulaması (13 madde, hepsi geçti): sürekli
paper döngüsü, yeni mum işleme (eski barlar tekrar işlenmiyor), sinyal +
gerekçe üretimi, dashboard (durum/bayat/PnL), Telegram (start/stop),
düzgün kapanış (Ctrl+C → state DB'de), restart kurtarması (yeni run_id,
no_new_bars, duplicate yok), kill switch (on/off + dashboard uyarısı),
internet kesintisi (3 retry → data_error, çökme yok), Telegram hatası
çekirdeği düşürmedi, bayat veri algısı, bağlantı gelince otomatik toparlanma
(kaçan mumlar topluca tamamlandı).
Eksik kalan zincir (mean reversion çok seyrek BUY ürettiği için kısa
testte görülemiyordu): BUY → risk motoru → emir → trade → snapshot →
dashboard'da açık pozisyon → Telegram giriş → SELL → kapanış → komisyon +
realized PnL → çıkış bildirimi. Çözüm: smoke_test stratejisi —
strategies/smoke_test.py (TEST ARACIDIR: pozisyon yoksa BUY, varsa SELL;
piyasa görüşü içermez), Timeframe.M1 (1m — dakikalar içinde tam tur),
config/smoke.yaml overlay'i (paper mod + 1m + ayrı DBdata/trading_smoke.db — gerçek paper geçmişi kirlenmez),
run_paper_trading.py --smoke ve dashboard.py --smoke bayrakları.
Strateji KALICI (Faz 7 live öncesi aynı smoke test live broker'a karşı da
gerekecek); canlı modda config kilidiyle yasak
(Settings validatörü: live + smoke_test → ConfigError).
Loader düzeltmesi (bu iş sırasında bulunan gerçek hata): mod overlay'i
strategy.name'i base'den farklı bir ada çektiğinde _deep_merge base'in
parametrelerini yeni stratejiye taşıyordu (mean_reversion parametreleri
smoke_test'in extra=forbid şemasında ConfigError üretirdi). Artık isim
değişiminde base parametreleri taşınmaz; aynı isimde merge davranışı
değişmedi (testle sabitlendi).
Doğrulama: 265 test (10 yeni: 4 smoke strateji, 4 config — isim
değişiminde parametre sıfırlama, aynı isimde koruma, live+smoke reddi,
gerçek smoke.yaml; 1 uçtan uca servis zinciri; 1 enum). Gerçek duman testi
(canlı Binance 1m verisi, 2× --smoke --once): 1. tur bootstrap 499 mum +
BUY (0.00079357 @ 63005.79, SL/TP kuruldu, Telegram giriş bildirimi); 2. tur
2 barı birden işledi — SELL (signal_exit, realized_pnl +0.0497,
komisyon 0.1000 = giriş+çıkış) ve yeni barda tekrar BUY; ayrıca yeni
run_id'nin pozisyonu DB'den kurtardığı görüldü. Orders 3× FILLED
(deterministik id), 3 snapshot, system_events zinciri tam, Telegram'da
0 hata, dashboard.py --smoke durum+işlem tablosunu doğru gösterdi.
Smoke DB'de bilinçli olarak açık bir trade bırakıldı — kullanıcının
sürekli --smoke turu ilk barda onu SELL ile kapatarak başlayacak.
Boşluk telafisi düzeltmesi (kullanıcının smoke turunun yakaladığı gerçek
davranış hatası): kesinti sonrası biriken eski barlar gerçek zamanlı karar
gibi replay ediliyordu — her eski barda strateji çağrılıyor, eski BUY'lar
risk motorunda bayatlıktan reddediliyor ve HER RED Telegram'a ayrı mesaj
atıyordu (kullanıcı sürekli --smoke turunu ~1,5 saatlik boşluktan sonra
başlatınca onlarca red mesajı gördü). Yeni davranış (paper_service.run_once):
telafi barları yalnızca DB/indikatör geçmişine ve açık pozisyonun SL/TP
simülasyonuna girer (kesintide fiyat SL'yi taradıysa tetiklenir — gerçek
borsada duran emir de çalışırdı); strateji + risk + emir yalnızca en yeni
kapanmış barda çalışır. Telafi tek catch_up system_event'i olarak
kaydedilir (bildirim spam'i yok). Sinyal işaretçisi (signals tablosu) en yeni
bara yazıldığı için telafi barları da kapsanır. 267 test (2 yeni: karar
yalnızca son barda + ara barda SL tetiklenmesi). Canlı doğrulama: 8 barlık
gerçek boşlukta Catch-up: 7 missed bars, tek SELL, 0 red, tek bildirim.
MVP sonrası — Dönem bazlı backtest / rejim analizi (2026-07-07)
Amaç: mean reversion + SMA200 rejim filtresi herhangi bir rejimde pozitif
beklenti üretiyor mu? Optimizasyon DEĞİL: parametreler sabit (son 365 günde
seçildi), diğer yıllar fiilen out-of-sample.
Altyapı:backtest/runner.py (run_window + calendar_year_periods) +
scripts/run_period_backtests.py (yıl yıl koşar, tek karşılaştırma raporu);
run_backtest.py aynı runner'ı kullanacak şekilde sadeleşti. 274 test.
Veri: 15m tüm Binance USDT-M geçmişi indirildi — 239.417 mum,
2019-09-08 → 2026-07-07, 0 boşluk.
Sonuç (rapor: reports/backtest_BTCUSDT_15m_periods_2026-07-07_161041.md):
Yıl
Strateji
B&H
İşlem
PF
Sharpe
2019 (Eyl'den)
−0.6%
−28.2%
4
0.50
−0.92
2020
+0.7%
+302.1%
23
1.12
0.24
2021
−4.8%
+59.4%
31
0.56
−1.17
2022
−8.2%
−64.3%
23
0.35
−2.35
2023
−9.7%
+155.5%
38
0.22
−2.50
2024
−2.1%
+120.8%
28
0.66
−0.72
2025
−5.7%
−6.5%
33
0.41
−1.84
2026 (Tem'e)
−0.3%
−27.2%
16
0.85
−0.21
Tüm veri
−27.4%
+538.1%
196
0.50
−1.35
Dürüst okuma: 9 pencerenin 8'inde zarar; tek pozitif yıl 2020 (+0.7%,
B&H +302 iken). Hiçbir rejimde kenar yok — boğada (2020/2023/2024) girişler
açılıyor ama PF 0.22–1.12 arası churn; ayıda (2022/2025/2026) rejim filtresi
zararı sınırlıyor ama kâr üretmiyor ("B&H'yi yenmek" para kazanmak değil).
Maliyet ayrıştırması: 7 yıllık net −27.4 USD'nin ~16.8'i komisyon, ~9.8'i
slippage → brüt sinyal kenarı ≈ −0.8 USD ≈ sıfır. Önceki 365g bulgusu
("beklenti ≈ −maliyet") tüm tarihe genelleniyor; sorun parametre ayarı değil,
sinyalin kendisinde bilgi yok. Kazanma oranı %47, ort. kazanç 0.30 <
ort. kayıp 0.53.
Çıkarım (sonraki adım kullanıcıyla konuşulacak): bu strateji ailesini
parametre oynayarak kurtarmaya çalışmak verimsiz (PF çoğu yıl <0.7, marj çok
büyük). Aday yollar: (a) farklı strateji ailesi — ör. trend-following/momentum
(BTC'nin uzun vadeli davranışıyla uyumlu; B&H +538 bunun işareti), kapsam
kararı gerektirir; (b) işlem maliyetini düşüren daha seyrek/uzun vadeli
varyant; (c) stratejisiz devam — altyapı doğrulandı, paper koşusu edge
aramaktan bağımsız sürebilir.
Karar (kullanıcı): mean reversion 7 yıllık rejim analizinde elendi (9 pencerenin
8'i zararda, brüt sinyal kenarı ≈ 0) → mean_reversion ve smoke_test silindi
(proje küçük kalsın; git geçmişinden geri getirilebilir), yerine trend-following
hipotezi aynı süzgeçten geçirildi. Hipotez: BTC'nin getirisi az sayıda büyük
yükseliş bacağında toplanır (B&H 7 yılda +519% bunun kanıtı); "düşüşte al"
yerine "trende bin" varlığın doğasına daha uygun.
Temizlik: MVP_SCOPE strateji satırı güncellendi (kapsam kuralı gereği önce);
silinen: strateji dosyaları + config'leri + testleri, iki script'teki --smoke
bayrağı, settings'teki smoke live-kilidi, Timeframe.M1; conftest/fixture'lar
trend_following'e geçti. Bilinçli kalanlar: boşluk telafisi ve loader
parametre-sıfırlama düzeltmeleri (çekirdek davranış, strateji değil).
Strateji (trend_following v1.0.0): Giriş = 20g Donchian kırılımı
(close > önceki 1920 barın zirvesi) VE EMA rejim filtresi (EMA480 > EMA1920 —
SMA200 dersinin devamı). Çıkış öncelik sırasıyla: 10g kanal kırılımı (Turtle
asimetrisi: geç gir, erken in) → EMA dönüşü → felaket stopu (config SL %8,
risk katmanının işi). TP yok (bilinçli): kâr hedefi trend stratejisinin
panzehiri; çıkış trailing mantığıyla. max_holding da yok. Bilinen zayıflık
docstring'de: yatay piyasada whipsaw, V-toparlanmada geç giriş.
Altyapı (küçük, hedefli): (1) features.py'a Donchian kanalları —
rolling.max/min().shift(1), kanal karar barını İÇERMEZ (yoksa kırılım hiç
tetiklenmezdi; testle sabitlendi); (2) take_profit_pct: Decimal | None —
null = TP kapalı (engine/paper/rapor/dashboard None-güvenli; broker zaten
korumalıydı); (3) BaseStrategy.required_history_bars() (taban 0) +
paper servis penceresi max(600, strateji ihtiyacı) — 600'lük sabit 1921
barlık kanalı besleyemezdi, strateji paper'da sessizce sakat kalırdı.
Doğrulama: 276 test (20 yeni: donchian referans/shift/look-ahead, strateji
karar matrisi + parametre doğrulama + required_history_bars, TP-None engine/
paper/config). Gerçek API --once: 1921 barlık pencere ısındı, gerekçeli HOLD
DB'de (close 61989.80 <= 1920-bar high 65597.20); dashboard gösteriyor;
30g backtest raporu üretildi (0 işlem — pencerenin 20 günü ısınma, kırılım yok).
Sonuç (rapor: reports/backtest_BTCUSDT_15m_periods_2026-07-08_091555.md;
MR = silinen mean reversion'ın aynı pencerelerdeki sonucu, yan yana):
Yıl
Trend F.
MR (elenen)
B&H
TF işlem
TF PF
TF Sharpe
2019 (Eyl'den)
0.0%
−0.6%
−28.2%
0
—
—
2020
+15.4%
+0.7%
+302.1%
7
8.45
2.09
2021
+3.6%
−4.8%
+59.4%
7
1.88
0.58
2022
−4.8%
−8.2%
−64.3%
7
0.03
−1.82
2023
+4.3%
−9.7%
+155.5%
6
3.32
1.04
2024
+8.4%
−2.1%
+120.8%
7
4.17
1.55
2025
+1.2%
−5.7%
−6.5%
5
1.75
0.54
2026 (Tem'e)
−0.4%
−0.3%
−29.3%
2
0.63
−0.37
Tüm veri
+36.6%
−27.4%
+519.0%
44
2.61
0.84
Dürüst okuma: İlk kez pozitif kenar var — 9 pencerenin 6'sı kârda (MR: 1),
tüm veri +36.6% (MR −27.4%), PF 2.61 (MR 0.50), maxDD %8.4. Az işlem hipotezi
doğrulandı: 7 yılda 44 işlem (MR 196), toplam komisyon 1.38 USD (MR 16.8) —
maliyet payı marjinal, kenar sinyalin kendisinden geliyor. Kazanma oranı %48
ama ort. kazanç (2.83) ≈ 2.9 × ort. kayıp (0.99) — klasik trend profili:
çok küçük kayıp, az büyük kazanç. Beklenen zayıflıklar aynen görüldü:
2022 ayısında whipsaw (PF 0.03, −4.8% — ama B&H −64.3), 2019 ayısında 0 işlem
(filtre doğru çalıştı: hiç oynamamak da bir karar).
B&H'nin hâlâ çok altında (+36.6 vs +519) — bağlam: pozisyon nominali öz
sermayenin ~%12.5'i (%1 risk / %8 SL boyutlaması, v1 muhafazakâr); tam
yatırılmış B&H ile mutlak getiri kıyası bu yüzden adil değil. Maruz kalınan
riske göre: TF maxDD %8.4 ile +36.6, B&H %77+ drawdown'larla +519. Yine de
mutlak getiri mütevazı; boyutlama/risk artışı ayrı bir kapsam kararıdır.
Sonraki adım (kullanıcı kararı): (a) paper'ı trend_following ile sürdür
(config geçti bile, mevcut durum bu); (b) parametre ailesini konuş — ör.
klasik Turtle 20/10 gün yerine 55/20, boyutlama; grid search MVP yasağı,
konuşarak tek tek denenir; (c) farklı/ek hipotez.
MVP sonrası — Çok varlıklı yapı + spot veriye geçiş (2026-07-10)
Karar (kullanıcı): trend_following tek sembolde pozitif kenar verdi ama çok
seyrek işliyordu (44 işlem / 7 yıl ≈ 6/yıl). Diversifiye trend following
literatürün standart çözümü — daha çok bağımsız trend fırsatı → daha çok işlem
daha düz equity. Ayrıca spot veriye geçiş: işlemi zaten spot mantığıyla
simüle ediyoruz, verinin de spot olması tutarlı (kaldıraç/short fazında
futures'a dönülür). 10 sembol: BTC, ETH, BNB, XRP, ADA, LINK, PAXG (altın —
tek gerçek çeşitlendirici), SOL, UNI, AVAX. Elenenler: ONDO (2024, geçmiş kısa),
MATIC/POL (migrasyon ticker'ı böldü).
Mimari: ayrı temiz DB (data/trading_spot.db) — spot/futures fiyatları
basis yüzünden farklı, karıştırmak sessiz bozulma olurdu; eski trading.db
futures arşivi olarak durur. MarketConfig.symbols: list[str]; market_type
{spot,futures} (varsayılan spot); create_provider fabrikası (BinanceSpot/
Futures ortak tabandan, spot limit 1000). Backtest sembol-bağımsız (her
sembole ayrı 100 USD — "kenar hangi varlıkta?" sorusu; paylaşımlı sermayeli
portföy backtest'i bilinçli kapsam dışı). Paper gerçek portföy: tek nakit
havuzu, sembol başına 1 pozisyon, eşzamanlı tavan max_open_positions: 5
(RiskEngine'e symbol_position kuralı + global sayım DB'den). Bir sembolün
bayat/hatalı verisi diğerlerini engellemez (PAXG gap riski BTC'yi durdurmaz).
Doğrulama: 294 test (18 yeni: çok varlıklı broker izolasyonu/paylaşımlı
nakit/restore, risk global tavan + aynı-sembol reddi, servis 2-sembol turu +
bayat izolasyonu, spot provider + fabrika, çoklu pozisyon dashboard görünümü).
Sonuç (rapor: reports/backtest_MULTI_15m_periods_2026-07-10_075326.md;
her sembol BAĞIMSIZ 100 USD, tüm-veri):
Sembol
Strateji
B&H
İşlem
PF
Sharpe
Kazanma
MaxDD
BTC/USDT
+29.8%
+620%
50
2.09
0.68
44%
10.0%
ETH/USDT
+69.3%
+552%
48
3.18
0.98
44%
7.6%
BNB/USDT
+75.5%
+1605%
53
2.97
0.68
38%
21.8%
XRP/USDT
+51.7%
+163%
50
2.39
0.56
30%
16.0%
ADA/USDT
+138.2%
+90%
47
3.51
0.90
28%
18.3%
LINK/USDT
+18.5%
+583%
68
1.32
0.28
26%
24.0%
PAXG/USDT
+3.9%
+112%
37
1.68
0.29
35%
4.4%
SOL/USDT
+131.3%
+2625%
53
3.34
0.99
34%
21.1%
UNI/USDT
+44.0%
+1028%
50
1.84
0.46
24%
25.1%
AVAX/USDT
+150.9%
+692%
45
3.19
0.86
22%
38.2%
Dürüst okuma:10/10 sembol tüm-veri pozitif (ortalama ~+71%/sembol),
hepsinde PF>1 (1.32 LINK zayıf ucu → 3.51 ADA). Kenar sinyalden geliyor:
toplam 501 işlem / 7 yıl ≈ 72/yıl (tek BTC ~6/yıl idi — sıklık sorunu
çözüldü), sembol başına komisyon 0.9–2.6 USD (maliyet payı ihmal edilebilir).
Kazanma oranı düşük (%22–44) ama trend profili gereği kazançlar kayıpların
katı — tüm sembollerde ortak. ADA tek başına B&H'yi yendi (+138 vs +90);
diğerlerinde B&H mutlak getiride hâlâ çok önde çünkü pozisyon nominali öz
sermayenin ~%12.5'i (v1 muhafazakâr) + trend takibi geç girer. Riske göre
bakınca tablo değişir: strateji maxDD %4–38, B&H drawdown'ları %60–90.
Yıllık desen (tüm sembollerde tutarlı): ayı yıllarında (2019/2022/2026)
tüm semboller küçük eksi ama B&H'den 30–80 puan iyi (rejim filtresi çalışıyor);
boğa yıllarında (2020/2021/2023/2024) pozitif ama B&H'nin çok altında (geç
giriş + muhafazakâr boyutlama). Beklenen davranış — sürpriz yok.
PAXG (çeşitlendirme testi): dürüst beklenti tuttu — altın gerçekten
farklı davrandı: en düşük maxDD (%4.4), az işlem (37), pozitif ama mütevazı
(+3.9%). Altcoin'ler BTC ile yüksek korelasyonlu ama trend zamanlamaları
idiyosinkratik olduğu için her biri ayrı kenar üretti + equity'yi düzleştirdi.
BTC spot vs futures tutarlılığı: spot +29.8% (50 işlem) vs futures +36.6%
(44 işlem) — aynı rejim, farklı fill/basis; makul yakın, veri kaynağı geçişi
sonucu bozmadı (sağlık kontrolü geçti).
Sonraki adım (kullanıcı kararı): (a) paper'ı 10 sembolle sürdür (config
hazır); (b) paylaşımlı sermayeli portföy backtest'ini gündeme al (per-symbol
umut verici — kronolojik çok-sembol birleştirme, ayrı iş); (c) boyutlama/risk
artışı (mutlak getiriyi B&H'ye yaklaştırmak — ayrı kapsam kararı); (d)
parametre ailesi (ör. Turtle 55/20). Faz 7 live, kenar kanıtı olmadan asla.
MVP sonrası — Paylaşımlı sermayeli portföy backtest + portföy risk motoru (2026-07-10)
Karar (kullanıcı): sembol-bağımsız analiz (her sembole ayrı 100 USD) iyi bir
ilk adım ama canlıya en yakın değil — gerçekte TEK 100 USD havuzu 10 sembol
arasında paylaşılır. Sorular: aynı anda kaç pozisyon, sermayenin ne kadarı
piyasada, çakışmada hangisi seçilir, coin başı/toplam risk, "6 altcoin long =
tek BTC bet mi?". Altcoinler BTC-korelasyonlu → portföy seviyesi risk motoru şart.
Kararlar (bana bırakıldı): boyutlama = coin başı %1, toplam mark-to-market
equity üzerinden (bileşik; tek-sembol %1 ile kıyas korunur); seçim kuralı =
config sırası (deterministik, kalibre confidence yok, optimizasyon yasağı);
portföy capleri = opsiyonel nullable (varsayılan kapalı → önce ham gerçek).
Altyapı:risk/portfolio.py saf allocator (slot + nakit + maruziyet-cap +
toplam-risk-cap kesişir; position_size reuse). backtest/portfolio_engine.py
kronolojik tek-havuz motor (bar-içi sıra tek-sembol engine ile birebir →
look-ahead güvenli; muhasebe değişmezi; concurrency/exposure/risk teşhis
serileri). backtest/portfolio_metrics.py (drawdown/sharpe reuse + eşit-ağırlık
B&H + ikili korelasyon ρ̄ + etkin bağımsız bahis N_eff). scripts/ run_portfolio_backtest.py (capsiz + caplı kıyas). Bu aşama backtest-only;
caplerin canlı paper'a bağlanması sonraki adım. 323 test (29 yeni).
Sonuç (rapor: reports/backtest_PORTFOLIO_15m_shared_2026-07-10_122228.md;
TEK 100 USD havuzu, 10 sembol, 2.3M mum, 7 yıl):
Metrik
Capsiz
Caplı (maruziyet %50 / risk %3)
Toplam getiri (bileşik)
+1044% ($100→$1144)
+343% ($443)
Eşit-ağırlık B&H
+820%
+820%
Getiri − B&H
+224 puan
−476 puan
Maks. drawdown
%39.0
%32.1
Sharpe (yıllık)
1.13
0.97
İşlem / PF
372 / 1.73
365 / 1.80
Komisyon
$66.75
$20.12
Kullanıcının 6 sorusu — sayılarla (capsiz):
Kaç eşzamanlı pozisyon? maks 5 (tavan), ort 2.12; tavan zamanın
%22.3'ünde dolu (dağılım: %29.5 boş, %21.5 tek, … %22.3 beş).
Sermayenin ne kadarı piyasada? maruziyet maks %91.7, ort %29.7
(çoğu zaman ~1/3, boğada %90+).
Çakışmada hangisi? config sırası (BTC önce); kitap doluyken 2335
giriş sinyali atlandı → çakışma SIK, seçim kuralı önemli (not edildi).
Coin başı risk? equity'nin %1'i (SL %8'de gerçekleşen kayıp).
Toplam portföy riski? naif toplam-risk maks %5.21 (5×~%1) — AMA
gerçek risk bundan büyük: maxDD %39 (korelasyonlu pozisyonlar birlikte
düşünce %8 SL'ler birikiyor). "5×%1=%5" naif hesabı gerçek drawdown'u
olduğundan AZ gösteriyor — kullanıcının tam da uyardığı nokta.
6 altcoin = tek BTC bet mi? ort ikili korelasyon ρ̄=0.50, etkin
bağımsız bahis N_eff=1.82 → 10 sembol aslında ~1.8 bağımsız bahse iniyor.
Sezgi doğrulandı (çeşitlendirme sınırlı) ama ρ̄ 0.8 değil 0.5 (erken yıllarda
bazı coinler yoktu/decorrele idi; boğada korelasyon daha yüksek çıkar).
Dürüst okuma: Paylaşımlı havuz + bileşik güçlü — tek 100 USD ile 7 yılda
+1044%, eşit-ağırlık B&H'yi (+820) 224 puan GEÇTİ. Bileşik + 10 varlıkta trend
takibi tek havuzda çalışıyor (kazananlar birbirini besliyor). AMA korelasyon
bedeli gerçek: maxDD %39 (tek pozisyonun %8 SL'ine karşı) çünkü pozisyonlar
kümeleniyor (N_eff 1.8). Capler (maruziyet %50 / risk %3) DD'yi %39→%32'ye
indiriyor ama getiriyi %1044→%343'e düşürüyor — takas kullanıcının risk iştahı
kararı. Uyarı: +1044 bileşik boyutlamaya duyarlı (equity büyüdükçe pozisyon
büyür); maxDD %39 dürüst karşı ağırlıktır. Sembol katkısı: ADA +$245, ETH +$217,
SOL +$209, BTC +$145, AVAX +$132 taşıdı; UNI −$75, BNB −$2 sürükledi.
Not (sembol-bağımsız analizle fark): önceki matris 10× ayrı 100 USD'de
ortalama +71%/sembol veriyordu (çapraz bileşik yok). Paylaşımlı havuz kazananları
bileştirdiği için TEK 100 USD'de +1044% — daha gerçekçi ve daha yüksek tablo.
Sonraki adım (kullanıcı kararı): (a) portföy caplerini canlı paper döngüsüne
bağla (tutarlılık); (b) risk iştahına göre cap ayarı (maxDD %39 kabul mü?);
(c) korelasyon-ayarlı boyutlama (N_eff'e göre ölçekle); (d) seçim kuralını
kırılım-gücüyle dene (2335 atlanan sinyal var). Faz 7 live, kenar kanıtı+risk
netliği olmadan asla.
MVP sonrası — Portföy capleri canlı paper'da + hata düzeltmeleri (2026-07-13)
Karar (kullanıcı): açık uçlardan (a) uygulandı — portföy capleri canlı
paper döngüsüne bağlandı; cap DEĞERLERİ config'te null kaldı (altyapı bağlı,
davranış değişmez; açmak tek satır). Ayrıca hata avı: 1 gerçek tutarsızlık +
2 kenar durum düzeltildi; çürütülenler (gap-down SL, aynı-bar SL+TP sırası,
YAML→Decimal, Sharpe katsayısı, eşit-ağırlık B&H, muhasebe değişmezi) temiz çıktı.
Refactor (davranışsız):risk/portfolio.py:size_with_caps — cap matematiği
allocate() iç döngüsünden bit-bit aynı çıkarıldı; tek doğruluk kaynağı artık
hem portföy backtest allocator'ı hem RiskEngine kullanır. Parite kanıtı:
refactor sonrası run_portfolio_backtest.py çıktısı raporla birebir
(capsiz $1144.17 / 372 işlem / 2335 skip; caplı $443.20 / 365 / 2348).
A1 (gerçek tutarsızlık) — boyutlama tabanı: paper'daki RiskEngine
position_size(equity=cash) ile KALAN NAKİT üzerinden boyutluyordu; backtest
allocator'ı toplam mark-to-market equity kullanır → pozisyon açıldıkça paper
sistematik küçük boyut üretir, defter backtest'ten sapardı. Düzeltme:
evaluate_entry imzası cash → PortfolioState (equity/cash/exposure/
total_risk; build_portfolio_state broker'dan kurar, değerleme kuralı
build_snapshot ile ortak). Boyutlama tabanı artık equity, nakit sınırı cash.
Yeni kurallar:portfolio_exposure ve total_risk (stop_loss_required
sonrası, sizing öncesi — allocate içi sırayla aynı model). Null cap = kural
applied_rules'ta görünür ama geçer. Sıfır miktarda gerekçe binding'e göre:
insufficient cash / exposure budget too small / risk budget too small.
Restart-güvenli: pozisyonlar SL'leriyle DB'den kurtarıldığı için cap girdileri
restart sonrası aynı (testli).
A2 (orta-düşük) — 1 bar bayat değerleme: snapshot yalnız broker'ın son
mumunu kullanıyordu; sıralı sembol işleme + bayat-atlanan sembolün DB'ye
yazılıp broker'a girmeyen mumları değerlemeyi geride bırakıyordu. Düzeltme:
_freshest_prices() — broker mumu ile DB'deki en yeni mumdan tazesi alınır
(snapshot + cap kararları); broker'a mum BESLENMEZ (SL/TP çifte tetikleme yok).
A3 (düşük) — uzun kesinti: okuma penceresi sabit 600 bardı; kesinti daha
uzunsa boşluğun başındaki barlar catch-up SL/TP simülasyonuna girmiyordu
(boşlukta taranan stop kaçardı). Pencere başlangıcı artık işaretçiyi kapsar;
karar yine yalnız en yeni barda. A4: Sharpe'ın veri boşluğunda eşit-aralık
varsayımı docstring'e bilinen-sınır olarak yazıldı (düzeltme değil).
Doğrulama: 339 test (16 yeni: allocator parite/binding ×6, engine cap
red/kırpma/null-geçiş/equity-taban ×6, servis canlı yol + restart + taze fiyat
uzun kesinti ×4). Gerçek API duman (capler null): --once → 10/10 sembol
ok, 3020 bar telafi, 0 risk reddi, davranış eskisiyle aynı. Caplı duman
(geçici %50/%3 overlay): config yüklendi, tur temiz; canlı cap red yolu servis
unit testleriyle kapsandı (o turda yeni bar/BUY oluşmadı). Portföy backtest
paritesi yukarıda.
Kalan açık uçlar (değişmedi): (b) risk iştahına göre cap değeri seçimi,
(c) korelasyon-ayarlı boyutlama (N_eff), (d) seçim kuralı (kırılım gücü).
MVP sonrası — Seçim kuralı deneyi: kırılım gücü (2026-07-13)
Soru (açık uç d): kitap doluyken 2335 giriş atlanıyor ve seçim keyfî config
sırası (BTC önce). Kırılım gücü, hangi trende binileceği konusunda bilgi taşıyor mu?
Tasarım (önceden sabit, parametresiz — optimizasyon yasağı korundu): güç =
(close − donchian_high) / donchian_high, sinyal barındaki yüzde aşım; sinyal
metadata'sından okunur (yeni feature/parametre yok). Adaylar güce göre azalan
sıralanır, eşitlikte config sırası (stable sort). ATR-normalize varyantı bilinçli
DENENMEDİ (ikinci varyant = optimizasyon kokusu). Motor selection paramı alır;
varsayılan config_order (mevcut davranış). Karar kriteri önceden yazıldı:
getiri/maxDD/Sharpe'ta anlamlı iyileşme yoksa config sırasında kalınır.
Sonuç (rapor: reports/backtest_PORTFOLIO_15m_shared_2026-07-13_163756.md;
2 seçim kuralı × 2 cap ayarı, aynı 10 sembol / 7 yıl):
Metrik
Config sırası (capsiz)
Kırılım gücü (capsiz)
Config (caplı)
Kırılım gücü (caplı)
Toplam getiri
+1041.9%
+1109.9%
+340.1%
+335.3%
Maks. drawdown
%39.0
%37.3
%32.1
%32.0
Sharpe
1.13
1.14
0.96
0.95
İşlem / PF
372 / 1.72
373 / 1.74
366 / 1.79
369 / 1.78
Kapasite reddi
2335
2287
2348
2306
Dürüst okuma — kural KABUL EDİLMEDİ (kriter karşılanmadı): capsiz koşuda
getiri +68 puan (+%6.5 göreli) ve maxDD −1.7 puan iyi görünüyor, AMA
risk-ayarlı ölçüde iyileşme yok: Sharpe 1.13 → 1.14 (gürültü), kazanma oranı
ve PF neredeyse aynı (1.72 → 1.74), işlem sayısı aynı. Daha kritik: caplı
koşuda işaret DÖNÜYOR — kırılım gücü hafif daha KÖTÜ (+335.3 vs +340.1,
Sharpe 0.95 vs 0.96). Aynı sinyalin iki cap ayarında zıt yönde çıkması, kazancın
kuralın taşıdığı bilgiden değil tek yolun yol-bağımlılığından (hangi işlem hangi
sermayeyle bileşti) geldiğini gösterir. Sembol kırılımı da bunu doğruluyor:
fark tek bir yerde toplanmış (ADA +245 → +335, SOL +204 → +244) ama BTC
+145 → +87 düşmüş; kural "daha iyi seçmiyor", farklı seçiyor.
Karar: config sırası korunuyor (varsayılan zaten o). Kod KALIYOR (motor
selection paramı + 4'lü kıyas raporu): deneyi tekrar üretilebilir kılıyor ve
gelecekte farklı bir metrik denenirse altyapı hazır. Paper'a bağlama (tur içinde
BUY niyetlerini toplayıp sıralama — orta boy değişiklik) YAPILMADI, gerek yok.
Not (temel koşu sayısı kaydı): capsiz config-sırası getirisi 1044.17% →
1041.88%, eşit-ağırlık B&H 819.69% → 808.93% değişti — sebep kodda değil veride:
aradaki paper duman testi DB'ye 4 günlük yeni mum ekledi (2026-07-09 → 07-13).
Refactor paritesi ayrıca aynı veriyle birebir doğrulanmıştı.
Doğrulama: 344 test (5 yeni: güç metriği + savunma, güçlünün tek slotu
kapması (aynı veride config kuralı BTC'yi seçiyor — kural gerçekten fark
yaratıyor), eşitlikte config sırasına düşüş, determinizm, bilinmeyen kural reddi).
Kalan açık uçlar: (b) risk iştahına göre cap değeri, (c) korelasyon-ayarlı
boyutlama (N_eff) — asıl sorun burada: maxDD %39'un kaynağı seçim değil,
pozisyonların korelasyonlu kümelenmesi.
MVP sonrası — Deney (c): korelasyon-ayarlı boyutlama (2026-07-14)
Hipotez (açık uç c): maxDD %39'un kaynağı seçim değil birlikte düşme
(ρ̄=0.50, N_eff=1.82). Yeni girişin riskini kitabın korelasyonuna göre
ölçeklemek DD'yi caplerden daha az getiri feda ederek düşürebilir mi?
Tasarım (önceden sabit, kalibre yok): risk_scale = 1/√(1+(N−1)·ρ̄₊);
N = açık + aday, ρ̄₊ negatifse 0 (ödüle çevrilmez, ölçek ≤ 1). Ölçüm: 30g
pencere, 1h getiriler, çift başına min 100 nokta — koda sabit; config'e
yalnız risk.correlation_sizing: bool (varsayılan false). Veri yetersizse
tam boyut (erken yıllar cezalandırılmaz). Yalnız yeni giriş; rebalance yok.
Karar kriteri önceden yazıldı: (1) maxDD ≥5 puan düşer VE (2) getiri
eşit-ağırlık B&H üstünde kalır VE (3) Sharpe kötüleşmez — üçü birden.
Altyapı:risk/correlation.py (saf modül + CorrelationCache),
Candidate.risk_scale (varsayılan 1 — parite testli), motor koşu başında
saatlik serileri bir kez üretir; script 2 boyutlama × 2 cap koşar, karar
tablosu rapora gömülü (EVET/HAYIR — eşik sonradan oynatılamaz). 368 test.
Uygulamanın yakaladığı 2 gerçek sorun: (1) look-ahead: pandas
resample("1h") kovayı sola etiketler — [00:00,01:00) kovası 00:45 barını
içerir ama 00:00'a yazılır; aday fill barında değerlendirildiği için yarı
açık dilim henüz oluşmamış barı sızdırıyordu. İndeks kova sonuna kaydırıldı
(motor + birim testiyle sabit). (2) performans: caplerde sıfıra
yuvarlanan giriş her barda yeniden aday olur → korelasyon her seferinde
yeniden hesaplanıyordu (ilk koşu 3 saatte 7 yılın 2'sine gelebildi, iptal).
Matris artık saat başına bir kez (CorrelationCache, kronolojik yürüyüş →
tek girişlik önbellek; searchsorted dilimleme) — 4 koşu ~30 dk.
Sonuç (rapor: reports/backtest_PORTFOLIO_15m_shared_2026-07-14_151132.md):
Metrik
Düz %1 (capsiz)
Korelasyon (capsiz)
Düz %1 (caplı %50/%3)
Korelasyon (caplı)
Toplam getiri
+1041.9%
+476.0%
+340.1%
+352.4%
Maks. drawdown
%39.0
%31.1
%32.1
%30.7
Sharpe
1.13
1.07
0.96
1.02
Profit factor
1.72
1.83
1.79
1.88
Ort./maks. maruziyet
%29.7 / %91.7
%22.1 / %72.8
%21.0 / %73.4
%20.0 / %64.1
Karar — kural KABUL EDİLMEDİ (kriter 1/3): maxDD −7.9 puan (%39.0→%31.1,
eşik geçti) AMA getiri +476 < B&H +809 (kaldı) ve Sharpe 1.13→1.07 (kaldı).
Mekanizma iddia edildiği gibi çalışıyor (maruziyet ve toplam risk serileri
düştü, işlem sayısı/kazanma oranı aynı — yalnız boyut küçülüyor) ama bileşik
büyümeden vazgeçilen pay riskin azalttığından büyük: risk-ayarlı getiri bile
iyileşmedi. correlation_sizing: false kalıyor; kod deney altyapısı olarak
duruyor (tek satırla açılır).
Kayda değer yan bulgu (açık uç b'ye girdi): korelasyon-ayarlı boyutlama
tek başına, %50/%3 caplerini HER eksende domine ediyor — getiri +476 vs +340,
maxDD %31.1 vs %32.1, Sharpe 1.07 vs 0.96. "DD'yi düşürmek istiyorum" kararı
verilirse doğru kol cap değil bu kural olabilir; ayrıca caplı+korelasyonlu
kombinasyon caplı-düz'den de iyi (+352/%30.7/1.02). Bu bir öneri değil
gözlemdir — kriter capsiz kıyasta koyulmuştu ve geçilemedi; cap/DD iştahı
ayrı kullanıcı kararı olarak duruyor.
Bilinen sınır (docstring'de de): aynı barda birlikte giren adaylar
birbirini görmez (hiçbiri henüz pozisyonda değil → hepsi N=açık+1 ile
ölçeklenir). Kırılımlar kümelendiğinde ölçek olması gerekenden büyük kalır;
"bar içi önceki adayları say" varyantı istenirse ayrı deneydir.
Kalan açık uç: (b) risk iştahı / DD hedefi kararı — artık iki ölçülmüş
kol var: capler (kaba, ucuz) vs korelasyon ölçeği (hedefli, capsizde bileşiği
törpülüyor). (d) seçim kuralı ve (c) korelasyon boyutlaması denendi ve
kapatıldı.
MVP sonrası — Genel temizlik (2026-07-14)
Karar (kullanıcı): proje küçük ve düzgün kalsın — reddedilen deneylerin
kodu silindi (sonuçlar bu dosyada yazılı, git geçmişinden geri getirilebilir:
kırılım gücü 20a6719, korelasyon boyutlama 7f07d12…fe8c54b). Silinen:
risk/correlation.py + testleri, Candidate.risk_scale,
RiskConfig.correlation_sizing, motorun selection parametresi;
run_portfolio_backtest.py capsiz/caplı 2-koşuya döndü. Parite kanıtı:
silme sonrası koşu birebir aynı (capsiz $1141.88 / 372 işlem / 2335 skip;
caplı $440.10 / 366 / 2348).
Bug düzeltmesi:preview_signals.py mean_reversion döneminden kalma
confidence:.2f (trend_following'de None → TypeError) ve meta['bb_middle']
(artık yok → KeyError) kullanıyordu — herhangi bir BUY sinyalinde çöküyordu.
Artık yalnız gerekçe satırı basılır (tüm sayısal bağlam zaten orada); gerçek
veride doğrulandı (ADA 3000 barda 5 BUY listelendi).
Bayat doküman düzeltmeleri: README çalıştırma bölümüne eksik script'ler
eklendi (period/portfolio backtest, preview); run_period_backtests.py
rapor notundaki "paylaşımlı portföy kapsam dışı" ifadesi script referansına
çevrildi. Bilinçli KORUNAN: features.py'daki RSI/Bollinger/ATR —
trend_following kullanmıyor ama MVP_SCOPE Faz 1'in kilitli teslimatı olan
genel indikatör katmanı (testli altyapı, strateji kodu değil).
Veri temizliği: eski loglar, .pytest_tmp, PROGRESS'te referansı olmayan
eski raporlar ve data/trading.db (35MB futures arşivi — spot geçişinden
beri kullanılmıyor, gerekirse download_market_data.py ile yeniden inebilir)
silindi. Kalan tek veri: data/trading_spot.db (kanonik, 279MB).
Restart regression ve atomik paper state (2026-09-16)
Regression önce kırıldı: aynı barda BTC + ETH BUY, iki eşit timestamp'li
snapshot ve yeni bağlantıyla restart. Nakit 74.9773467629185 yerine
87.4875001236235 oluyordu; eski sorgu ilk snapshot'ı seçiyordu.
Düzeltme: snapshot state_sequence ile kalıcı yazım sırasını taşır;
restart olay zamanından bağımsız son durumu yükler. Eski şema rowid sırasıyla
veri kaybetmeden migrate edilir. Son mumlar SL/TP çalıştırmadan yüklenir;
değişmeyen veride cash/positions/equity ve giriş komisyonları birebir korunur.
Transaction kararı: sembolün catch-up çıkışları + son bar kararı +
orders/trades/snapshots/system_events + signals cursor'u tek COMMIT.
Market data ayrı commit; başarısız işlem SQLite ve broker belleğinde rollback;
bildirimler commit sonrası. BTC tamamlanmışsa ETH hatası BTC'yi geri almaz.
Ayrıntılar ve sınırlar: paper durum sözleşmesi.
Doğrulama: önceki 339 + 22 yeni = 361 test geçti (9.26 sn, ağ kapalı).
Yazım/COMMIT hatası, aynı süreçte/yeni broker ile retry, SELL/SL/TP rollback,
geriye tarihli catch-up, migration ve bildirim görünürlüğü test edildi.
JUnit kanıtı: data/regression-validation/pytest-results.xml.
Veri koruması: kanonik SQLite'a migration uygulanmadı; yalnız geçici test
DB'leri kullanıldı. Mevcut veri/rapor arşivi korunuyor. Git commit oluşturulmadı.
Gap-stop ve EMA parity regression'ları (2026-09-16)
Önce kırılan iki regression: SL=92, O/H/L/C=80/82/78/81 için eski fill
91.954; aynı bar için uzun geçmiş/paper pencere EMA farkı.
Gap-stop düzeltmesi: üç execution yolu ortak min(SL, open) + satış
slippage'ını kullanır; örnek fill 79.96. Toparlanan gap barı ve muhasebe
değişmezleri de test edildi.
EMA kararı: incremental state yerine seed ağırlığı ≤1e-12 sağlayan warm-up.
EMA1920 için 26.527 gözlem; gerçek mum sayısıyla pencere seçimi; paper'da
yetersiz geçmiş için HOLD, SL/TP ve kill-switch çıkışları çalışmaya devam eder.
Sabit örnek: 2025-12-31 23:45 UTC BTC/USDT 15m, 231.180 mum referansında
EMA1920 farkı 167.766157546 → 2.59024e-9; EMA480 farkı 0.529434048 → 0.
Script: scripts/check_ema_parity.py; karar/sınırlar: ENGINE_PARITY.md.
Doğrulama: önceki 361 + 11 yeni = 372 test geçti (9.06 sn, ağ kapalı).
JUnit: data/regression-validation/gap-ema-pytest-results.xml.
Sabit 2025 backtest tekrarlandı: 5 trade, +%1.1843914422, son equity
101.184391442201243200000; önceki baseline ile birebir, muhasebe hatası 0.
Kanıt: data/regression-validation/btc2025-after-gap-ema.json.
Sonraki oturum:NEXT_SESSION.md — restart muhasebesi,
atomik state ve backtest–paper tutarlılığı; yeni strateji/live entegrasyonu yok.
Trusted baseline v2 + T05 (2026-09-17)
Git baseline:ca45075 — fix: establish trusted baseline v2, annotated
tag trusted-baseline-v2. Önce 372 test ve sabit BTC 2025 sonucu tekrar
doğrulandı; ortam/kanıt referansları docs/TRUSTED_BASELINE_V2.md içinde.
T05: zorunlu paper account_id, hesap/timeframe/strateji namespace'i, DB
sahipliği ve işlem config fingerprint'i; yanlış config/legacy state reddi.
Default paper DB OneDrive dışında LOCALAPPDATA altında; araştırma DB'si korunur.
Kilit: migration/provider/notification öncesi DB-path + namespace OS kilidi;
Windows ortak ProgramData lock kökü, msvcrt tanıtıcı kilidi, çakışmada exit 2.
Aynı namespace'in farklı DB kopyaları da eşzamanlı çalışamaz. Dashboard read-only.
Emir anahtarı: ayrı client_order_id, deterministic namespace/symbol/bar/
side/purpose anahtarı, SQL UNIQUE + paper NOT NULL/blank trigger'ları.
Gerçek constraint hatasında broker/state/cursor rollback testi eklendi.
Recovery: gerçek worker PID'sini commit öncesi/sonrası kill eden testler;
lock release, session interrupted kaydı, Decimal cash/positions/equity/fees
eşitliği ve tek seferlik retry doğrulandı. Session_id log run_id ile eşlendi.
Son doğrulama:400 test geçti (372 + 28 yeni, 29.28 sn); JUnit
data/regression-validation/t05-final-results.xml. T05 sonrası BTC 2025
yine 5 trade / 101.184391442201243200000 equity, muhasebe hatası sıfır.
Asıl SQLite + yedi rapor ve arşiv hash'leri aynı; kanonik DB migrate edilmedi.
Ayrıntı: docs/T05_PAPER_ISOLATION.md. T05 ayrı commit'te; push yapılmadı.
Execution A/B/C ve forward gözlem bu teslimde başlatılmadı; kabul edilmiş
devam kapsamı docs/NEXT_SESSION.md içinde.