Skip to content

Latest commit

 

History

History
858 lines (799 loc) · 59.9 KB

File metadata and controls

858 lines (799 loc) · 59.9 KB

Proje İlerleme Kaydı

Ç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.

Yapılanlar

Faz 0 — İskelet (tamamlandı, commit e20feb0)

  • Paket yapısı: src/trading_platform/ (core, config, monitoring), tests/, config/
  • Domain modelleri (core/models.py): MarketCandle, Signal, OrderRequest, Position, RiskDecision — frozen dataclass, parasal alanlar Decimal, UTC-aware timestamp zorunlu, kuruluşta kendi tutarlılık doğrulaması
  • Enum'lar (core/enums.py): SignalAction, OrderSide, OrderType, OrderStatus, PositionSide (long-only), TradingMode, Timeframe — string değerler testle sabitlendi
  • İstisna hiyerarşisi (core/exceptions.py): TradingPlatformError tabanı; ConfigError, DataError/StaleDataError, RiskViolationError, OrderError
  • 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)
  • Provider: data/providers/base.py (MarketDataProvider ABC) + data/providers/binance.py (BinanceFuturesProvider) — sayfalama (limit=1500), yalnızca kapanmış mumlar (look-ahead koruması), 429/418 Retry-After + 5xx üstel backoff, sembol eşleme BTC/USDT ↔ BTCUSDT
  • SQLite: storage/database.py — spec §7.11'deki 6 tablonun tamamı kuruldu (market_data, signals, orders, trades, portfolio_snapshots, system_events); WAL modu; timestamp = epoch ms INTEGER, fiyat/hacim = TEXT (Decimal kayıpsız); market_data UNIQUE(symbol, timeframe, timestamp)
  • Repository: data/repository.py — upsert_candles (INSERT OR IGNORE, duplicate'ler DB seviyesinde atlanır), get_candles (kronolojik, Decimal gidiş-dönüş), latest_timestamp, count
  • Kalite: data/quality.py — find_gaps (boşluk = rapor + WARNING, hata değil), check_freshness (yaş > multiplier × timeframe → StaleDataError), build_report
  • İndikatörler: data/features.py — SMA, EMA, RSI (Wilder), Bollinger (ddof=0), ATR (Wilder); ısınma NaN bırakılır; look-ahead yok (testle doğrulandı)
  • Config: data: bölümü (DataConfig) — market_type MVP kilidiyle yalnızca futures, db_path, history_days, staleness_multiplier; Timeframe.duration eklendi
  • Script: scripts/download_market_data.py — artımlı indirme (DB'deki son mumdan devam), kalite raporu, özet
  • 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ı)
  • Registry: strategies/registry.py — @register dekoratörü (duplicate ad → hata, sessiz ezme yok), create_strategy(name, params) (bilinmeyen ad → mevcutları listeleyen ConfigError); modül import'ları strategies/__init__.py'de
  • 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ı DB data/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.

MVP sonrası — Temizlik + trend_following (Donchian + EMA) + rejim analizi (2026-07-08)

  • 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).
  • Veri: 10 sembol spot 15m indirildi — 2.315.611 mum, 2019-05-27 → 2026-07-09 (SOL/UNI/AVAX/PAXG 2020'den, geç listelendikleri için).
  • 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):
    1. 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ş).
    2. Sermayenin ne kadarı piyasada? maruziyet maks %91.7, ort %29.7 (çoğu zaman ~1/3, boğada %90+).
    3. Çakışmada hangisi? config sırası (BTC önce); kitap doluyken 2335 giriş sinyali atlandı → çakışma SIK, seçim kuralı önemli (not edildi).
    4. Coin başı risk? equity'nin %1'i (SL %8'de gerçekleşen kayıp).
    5. 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. 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.

Sıradaki İşler (MVP_SCOPE.md sırasıyla)

Güncel öncelik ve kabul kriterleri: sonraki oturum kapsamı.

  • Faz 1 — Veri: Binance OHLCV çekme (USDT-M Futures klines), SQLite kayıt, duplicate/eksik mum kontrolü, veri güncellik kontrolü, indikatörler (RSI, SMA, EMA, Bollinger, ATR)
  • Faz 2 — Strateji: BaseStrategy arayüzü, mean reversion stratejisi, Signal + gerekçe üretimi, config'den parametre
  • Faz 3 — Backtest: kronolojik motor, look-ahead bias yok, komisyon + slippage, stop-loss/take-profit/maks. pozisyon süresi, metrikler, buy-and-hold karşılaştırması, 15m vs 5m testi
  • Faz 4 — Paper trading: PaperBroker, sanal nakit/pozisyon, PnL takibi, işlemlerin SQLite'a kaydı
  • Faz 5a — Risk: risk motoru (tek pozisyon, günlük limit, pozisyon boyutu, veri bayatlığı, duplicate sinyal engeli), kill switch
  • Faz 5b — Bildirim: Telegram bildirimleri (hata bildirimde çekirdek çökmez)
  • Faz 6 — Terminal arayüzü: durum/pozisyon/PnL/işlem geçmişi, backtest raporu
  • Restart güvenilirliği: aynı bar çoklu BUY regression'ı, kalıcı snapshot sırası ve portföy/sinyal cursor'unun atomik commit'i
  • Gap-stop ve EMA: ortak gap fill modeli, yeterli warm-up ve parity fixture'ı
  • T05: process-kill recovery, tek-yazıcı kilidi, DB namespace/config sahipliği, session kayıtları ve unique client order key
  • Execution A/B/C: zaman alanları, backtest ön geçmişi, ortak SELL→BUY, quote fill, kalıcı niyet, daily-loss ve cycle valuation parity (NEXT_SESSION.md)
  • Forward: tam manifest, ayrı DB + güncel veri, 28 günlük sabit-parametre gözlem