Sigurnost, full-history benchmark, offset sweep

2026-07-02 nalaz bug

Offset nije parametar nego šum — nijedan „najbolji pomeraj“ ne preživi permutacioni test (min p=0.41). Uz to kritičan import bug koji bi ugasio sve generatore na prvom čistom rebuild-u.

↑ Svi izveštaji ← PnL realnih live signala sa produkcije Produkcijski webhook i live-signal audit →

Datum: 2026-07-02/03 (računato na dev mašini; test/prod dobijaju samo rezultate) Radna kopija: E:\Work\AI\opencodeTest\crypto_scanner, master (daa1f1f5c34be1) Podaci: dev klines_cache.db (55.8 GB, pokrivenost do ~2026-06-11), dev crypto_scanner.db


TL;DR

  1. Sigurnost sređena (commit daa1f1f): fail-hard FLASK_SECRET_KEY, timing-safe poređenja tokena, Postgres kredencijali kroz .env, SESSION_COOKIE_SECURE flag. 412 testova prolazi.
  2. Kritičan latentan bug nađen i popravljen (commit 68d7be7): svi generatori i analitički alati importovali su module sa putanja koje ne postoje od reorganizacije 2026-06-17. Deployovani kontejneri rade samo zato što drže stare flat fajlove — prvi čist rebuild image-a bi ugasio sve generatore.
  3. Full-history benchmark (2017→2026-06): 18/24 generatora uspešno, 6 timeout (svi 1h/šablonski).
  4. Slot-portfolio šampioni (1200d, 2023-02→2026-06): compound N=1 → best_symbols_v3 +1197% (dd 52%, Sharpe 1.20); fixed N=1 → quality_cycle +351% (dd 40%). Najbolji risk-adjusted: bb_adx_combo_long N=1: +82% uz dd samo 23.6% (Sharpe 1.02).
  5. Offset sweep (48 ofseta × 8 generatora × 12 simbola): offset NIJE validan parametar — nijedan "najbolji ofset" ne preživljava permutacioni test (min p=0.41). Razlike među ofsetima su šum selekcije best-of-48.
  6. Revizija ranije preporuke: bollinger_band_pullback_long na 4h je preko 1200d negativan (−21% fixed N=1); njegov dobar majski rezultat bio je artefakt kraćeg prozora. Na 1d TF-u je pozitivan.

1. Sigurnosne popravke (commit daa1f1f)

#NalazFix
1FLASK_SECRET_KEY default 'change-me' → falsifikovanje superadmin session cookie-jacreate_app() odbija start bez pravog ključa (u debug-u efemerni ključ + warning); testovi dobijaju ključ u tests/conftest.py
2Postgres scanner_user:scanner_pass hardkodovan u docker-compose.yml${POSTGRES_USER:-...} / ${POSTGRES_PASSWORD:-...} iz .env; defaulti zadržani zbog kompatibilnosti — rotacija lozinke na serverima je i dalje TODO (traži ALTER USER u živom PG-u, env sam ne menja postojeći volume)
3Session cookie bez Secure flaga iza HTTPS-aSESSION_COOKIE_SECURE env flag (True na .207 iza nginx-a; False na .88 koji je čist HTTP)
4Tokeni poređeni sa == (timing napad)hmac.compare_digest kroz constant_time_equals() na sva 3 mesta

⚠ PRE SLEDEĆEG DEPLOY-A: u server .env (.88 i .207) mora postojati jak FLASK_SECRET_KEY, inače web kontejner neće startovati. Dev ključ deluje slabo („Lol1…") — rotirati na sve tri mašine. Generisanje: python -c "import secrets; print(secrets.token_hex(32))".

Već postojalo i potvrđeno: gunicorn, CSRFProtect, rate-limit na login/ingest, bcrypt-hešovani API ključevi sa scope-ovima, security headeri, .env van git-a.

2. Kritičan import bug (commit 68d7be7)

26 × signal_generators/*/generator.py + ~35 skripti u tools/** importovali su src.generator_lib, src.generator_profiles, src.feature_store, src.analyzer, src.database… — flat moduli koji od reorganizacije u pakete (2026-06-17) ne postoje. Na čistom checkout-u nijedan generator nije mogao da se učita (ModuleNotFoundError), a svi benchmark driveri su padali na importu. Testovi to nisu uhvatili jer importuju nove putanje direktno i mock-uju loader.

Posledica za servere: kontejneri trenutno rade na zaostalim flat fajlovima iz starih image-a / docker cp zakrpa. Fix je sada u master-u — sledeći deploy je bezbedan.

3. Full-history benchmark (2017-01-01 → 2026-06-01, --reset-state)

18/24 finished. Timeout (3h/gen): multi_timeframe_bias, dual_growth_liquidity, dual_growth_liquidity_cancel_test, donchian_volume_breakout, bollinger_volume_expansion, template_python — svi 1h TF (68 simbola × 9 godina × 1h je preskupo za 3h limit) ili šabloni. Njihove brojke tretirati kao nepotpune.

Событija po generatoru (izbor): growth_threshold_cycle 92,190; blacklist_cycle 21,338; dual_growth_trailing_stop 15,557; bollinger_band_pullback_long 11,416; ema_trend_pullback 8,910; quality_cycle 7,602; supertrend_long 6,677; v3 2,034; regime_cycle 1,696. high_conviction_combo, external_trend_confirmed_cycle, combinator_template = 0 (zahtevaju live kombinaciju / eksterne signale — očekivano).

Pun JSON: reports/full_history_benchmark_20260702.json.

4. Slot-portfolio poređenje (poslednjih 1200 dana, kapital $1000, fee 0.1%/strani)

Detaljne tabele: slot_portfolio_fixed_20260702.md / slot_portfolio_compound_20260702.md (+ JSON-ovi u reports/). Vrh:

COMPOUND, N=1:

GeneratorTFReturnMaxDDSharpeParova
best_symbols_cycle_v34h+1197%52.3%1.20634
quality_cycle4h+922%44.4%0.922106
best_symbols_cycle4h+402%54.2%0.901152
ema_cross_10_1004h+295%54.0%0.821612
supertrend_long4h+263%56.4%0.771781

FIXED, N=1: quality_cycle +351% (dd 39.6%); v3 +329% (dd 61.6%, Sharpe 0.91); ema_cross_10_100_pure +256%; best_symbols +251%; ema_trend_pullback +246%.

Risk-adjusted zvezda: bb_adx_combo_long N=1 fixed +82.4% uz MaxDD 23.6% (Sharpe 1.02) — ubedljivo najmirnija kriva; kandidat za auto-trading sa realnim novcem gde drawdown boli.

Supertrend na N=2: compound +559% (dd 75.8%) — njegov sweet spot je 2 slota; i dalje važi da mu TF sweep favorizuje 1d–1w za per-trade kvalitet.

Revizije / crvene zastavice:

5. Offset sweep — da li je pomeraj 4h grida validan parametar?

Pitanje: ako 4h sveće ne počinju na 00:00 UTC nego pomereno za X = n×5min (0–235 min), menja li se profitabilnost/kvalitet signala? Postoji li „najefikasniji pomeraj"?

Metod: 8 generatora × 48 ofseta × 12 simbola, 2023-01-01 → 2026-06-01, resample sa 5m baze (epoch-anchored, candle_resampler), in-memory backtest, FIFO pairing, fee 0.1%/strani. Runtime state izolovan po ofsetu (bez toga stale state guši ulaske — potvrđen efekat). Svi ofseti, uključujući 0, idu kroz identičan resample+recompute put (nema cache-vs-compute biasa). Statistika: max-statistic permutacioni test (obračunava best-of-48 selekciju), range test, Kruskal-Wallis (permutacioni p), split-half rank stabilnost, cross-generator slaganje. 2000 permutacija, seed 20260702.

Rezultati po generatoru (avg %/trade posle fee):

GeneratorBest ofsetBest avgOfset 0Rasponp(best)p(KW)Split-half ρ (p)
best_symbols_v3+165m0.4990.0200.5090.890.950.03 (0.42)
best_symbols_v2+165m0.318−0.0630.5620.800.210.23 (0.06)
best_symbols+165m0.420−0.0520.6740.410.090.20 (0.08)
bollinger_pullback+225m0.3020.0820.4090.970.560.45 (0.002)
bb_adx_combo+170m0.7020.1330.6600.950.280.47 (0.001)
supertrend+5m0.5990.4990.6621.001.00−0.14 (0.82)
ema_trend_pullback+80m0.5650.2360.5350.911.00−0.07 (0.68)
dual_growth_trailing+15m3.3123.0350.8290.930.98−0.02 (0.57)

(25k–58k trejdova po generatoru ukupno; ~500–1200 po ofsetu.)

Zaključci:

  1. Nijedan „najbolji ofset" nije statistički značajan — p(best) 0.41–1.00. Raspon per-ofset proseka (0.4–0.8 pp) je tačno ono što best-of-48 selekcija na razmenjivim trejdovima proizvodi slučajno. Kruskal-Wallis takođe ništa (min 0.09, pre korekcije za 8 testova).
  2. „Najefikasniji pomeraj" ne postoji kao stabilna veličina. Tri sibling quality generatora dele isti best (+165m), ali oni trguju praktično iste signale — to je zajednički šum, ne nezavisna potvrda. Između familija slaganje profila je slabo (prosek ρ=0.15), a supertrend je čak anti-korelisan sa quality familijom (ρ=−0.40). Univerzalni „dobar ofset" bi tražio pozitivno slaganje svuda.
  3. Jedina zanimljivost: BB par (bollinger_pullback, bb_adx) ima statistički stabilan oblik profila kroz vreme (split-half ρ≈0.45–0.47, p≈0.001) — neki fazni potpis BB mehanike verovatno postoji, ali mu je magnituda premala da preživi selekcioni test, tj. nije upotrebljiv za profit.
  4. Presuda: offset tretirati kao robustness parametar, ne kao optimizacioni. Vrednost sweep-a: pokazuje koliko je rezultat generatora osetljiv na fazu grida — npr. v3 na ofsetu 0 izgleda mršavo (0.02%/trade) a медijana преко ofseta mu je ~0.2–0.3% — dakle jedan fiksni grid potcenjuje/precenjuje generator za ±0.3 pp šuma. To je merilo nesigurnosti backtesta, ne dugme za štelovanje.

Podaci: reports/offset_sweep_osw{1..4}.json (sirovi trejdovi), analiza: offset_sweep_analysis.json.

6. Šta nije uspelo (pošteno)

7. Preporuke

Profitabilni generator (pitanje iz zadatka):

  1. growth_threshold_quality_best_symbols_cycle_v3 — compound N=1 +1197% / N=2 +281%, Sharpe 1.0–1.2, najviši Sharpe na skoro svakom N. Preporuka: enable sa slot count 1–2, compound sizing. (Trenutno disabled!)
  2. bb_adx_combo_long — za najmirniju krivu: +82% uz dd 23.6% (N=1 fixed). Najbolji kandidat za 3Commas webhook sa pravim parama.
  3. growth_threshold_quality_cycle — „radni konj": +351% fixed N=1 uz dd 39.6%, 2106 parova (velika statistička podrška).
  4. supertrend_long — drži N=2 (compound +559%); dugoročno razmisliti o 1d TF varijanti.
  5. Povući: preporuku za bollinger_band_pullback_long na 4h (negативан na 1200d); ako ostaje, prebaciti na 1d. dual_growth_trailing_stop ne dirati dok se slot-pairing artefakt ne razjasni.

Operativno:


Reprodukcija: tools/analysis/run_offset_sweep.py, analyze_offset_sweep.py, run_full_history_benchmark.py, build_monthly_generator_report.py, slot_portfolio_compare.py — sve pokretano .venv39 Python-om; logovi u database/*.log.

Izvor: crypto_scanner/reports/analysis/2026-07-02/FULL_REPORT_2026-07-02.md