📚 Dokumentation
📋 InnehĂ„llsförteckning

Teknisk systemdokumentation — Aktieanalys


Senast uppdaterad: 2026-08-16, dataflöden, körningar, datamodell och driftsÀtt.


1. Systemöversikt


Aktieanalys bestÄr av fem lager:


  1. DatainhÀmtning
  2. Dagliga priser, intraday-priser, makro och fundamenta hÀmtas frÄn externa kÀllor.

  3. BerÀkning
  4. Tekniska indikatorer, signaler, Fourier-cykler, backtester och neurala nÀtverk.

  5. Beslutslager
  6. Morning signals, NN-prediktioner, meta-signaler och paper trading-regler.

  7. Persistens
  8. MariaDB/PostgreSQL-tabeller för tidsserier, features, modeller och order/simuleringsdata.

  9. Presentation/Drift
  10. PHP-dashboard (VM 192.168.100.83, https://tegelwall.duckdns.org/aa/), nattliga jobb, intraday-jobb, loggar och statusfiler. Se §24 för fullstÀndig webbinfrastruktur.


    !Systemflöde


    !NN-arkitektur (signal_3class)


    1.1 Arkitekturdiagram (översikt)


    flowchart LR
        A[DatakÀllor<br/>Avanza/Yahoo/SCB/Riksbank] --> B[InhÀmtning<br/>fetch_*]
        B --> C[Databas<br/>prices/indicators/macro]
        C --> D[BerÀkning<br/>indicators/signals/fourier]
        C --> E[NN<br/>trÀning + inferens]
        D --> F[morning_signals]
        E --> F
        D --> G[backtest_results]
        E --> G
        F --> H[paper_trading_sim]
        C --> I[PHP-dashboard (/aa/)]
        D --> I
        E --> I
        H --> I
    

    1.2 Databasstruktur (förenklad bild)


    erDiagram
        TICKERS ||--o{ DAILY_PRICES : has
        TICKERS ||--o{ DAILY_INDICATORS : has
        TICKERS ||--o{ DAILY_SIGNALS : has
        TICKERS ||--o{ MORNING_SIGNALS : has
        TICKERS ||--o{ NN_PREDICTIONS : has
    
        NN_MODELS ||--o{ NN_PREDICTIONS : produces
        NN_MODELS ||--o{ NN_TRAINING_EPOCHS : logs
        NN_MODEL_REGISTRY }o--|| NN_MODELS : champion_model_id
    
        PAPER_ACCOUNTS ||--o{ PAPER_POSITIONS : owns
        PAPER_ACCOUNTS ||--o{ PAPER_ORDERS : owns
        PAPER_ACCOUNTS ||--o{ PAPER_EQUITY_SNAPSHOTS : tracks
    

    1.3 NN-struktur (trÀning + routing)


    flowchart TD
        A[daily_indicators + macro/fundamenta] --> B[neural_network.py]
        B --> C[nn_models]
        B --> D[nn_training_epochs]
        B --> E[nn_predictions]
        C --> F[nn_model_registry<br/>champion per target/ticker]
        F --> G[PHP-dashboard (/aa/)]
        F --> H[morning_signals join]
        F --> I[paper_trading_sim]
        E --> G
        E --> H
        E --> I
    

    2. Huvudflöden


    2.1 Nattlig batchpipeline (update_all.sh)


    Kör i följande ordning:


    1. fetch_yahoo_history.py (historik/fyll luckor)
    2. avanza_update_prices.py (senaste priser)
    3. fetch_fundamentals_avanza.py
    4. calculate_all_indicators.py
    5. calculate_indicators_v2.py
    6. analyze_fourier_cycles.py
    7. calculate_signals_py.py
    8. fetch_macro.py
    9. calculate_sector_performance.py
    10. backtest_engine.py
    11. pipeline_quality_check.py (--max-suspicious-sells 20)
    12. morning_signals.py

    13. Loggar till /shared/logs/aktieanalys/pipeline_*.log och status skrivs till /tmp/copilot/aktieanalys_status.md.


      Steg 7 (calculate_signals_py.py) och 12 (morning_signals.py) offloadar till bigrig-kön automatiskt nÀr QUEUE_OFFLOAD=1 Àr satt (se §21).


      pipeline_quality_check.py blockerar inte lĂ€ngre pipelinen pĂ„ legitima "misstĂ€nkta sells" sĂ„ lĂ€nge antalet Ă€r ≀ 20. Dessa definieras som sĂ€ljsignaler med t.ex. RSI < 50, stochastic < 35 och ADX < 22 — ovanliga men giltiga marknadslĂ€gen, inte nödvĂ€ndigtvis datafel. Tröskeln 0 blockerade data_pipeline (rc=2) frĂ„n 2026-07-17 tills den höjdes i commit d449cd9.


      2.2 NN nattjobb (run_nn_nightly.sh) — shardad körning


      Sedan 2026-08-06 körs nn_nightly som 6 parallella shards + en koordinator via jobbkön:


      nn_nightly_s0..s5   PREFER=bigrig_work733  NN_TICKER_SHARD_INDEX=0..5  NN_SKIP_FINALIZE=1
      nn_nightly          PREFER=bigrig_work733  DEPENDS=nn_nightly_s0,..,s5  NN_SKIP_PRETRAIN=1  NN_SKIP_MAIN_TRAIN=1
      

      Koordinatorn (nn_nightly) kör enbart finalize-steget (governance, meta-signaler, ensemble) efter att alla shards Ă€r klara. Downstream-jobb (paper_predict, morning_signals, nn_focused, oos_walkforward) beror pĂ„ nn_nightly och ser koordinatorn som sin dep — befintlig QUEUE_DEPENDS: nn_nightly fungerar oförĂ€ndrat.


      Lockfiler Àr per-shard: /tmp/aa_ai_nn_nightly_s${N}.lock. Koordinatorn anvÀnder /tmp/aa_ai_nn_nightly.lock. Shards blockerar aldrig varandra.


      Env-variabler:


      VariabelFörklaring
      NN_TICKER_SHARD_INDEX0–5, vilken shard
      NN_TICKER_SHARD_COUNTTotalt antal shards (6)
      NN_SKIP_FINALIZE1 = hoppa governance/meta/ensemble (shards)
      NN_SKIP_PRETRAIN1 = hoppa global pretrÀning (koordinator)
      NN_SKIP_MAIN_TRAIN1 = hoppa per-ticker trÀning (koordinator)

      Övriga egenskaper:

      • TrĂ€nar flera targets (signal_3class, ret_, prob_up_).
      • Profil för vardag/helg (epoker, folds, feature-selektion).
      • Per-ticker trĂ€ning, multicore workers, resume/warm-start.
      • Glidande trĂ€ningsfönster via _run_pretrain_window() (set +e + ${PIPESTATUS[0]}).
      • /mnt/raid detekteras via write-test (-w), ej bara listning — undviker Permission denied pĂ„ bigrig.

      Loggas till /shared/logs/aktieanalys/nn_nightly_*.log (en per körning).


      2.3 FFT nattjobb (run_fft_nightly.sh)


      • Kör analyze_fourier_cycles.py för hela tickeruniversum.
      • Parallelliserar per symbol via xargs -P.
      • Inkrementell recompute med --recompute-days.
      • NĂ€sta-dag-prediktion (tillagd 2026-08-13): fft_next_day_prediction() berĂ€knar förvĂ€ntad prisrörelse dag D+1 via
      • Δ = ÎŁ w_k × (cos(φ_k + 2π/T_k) − cos(φ_k))

        och skriver fft_next_day_direction (−1/0/+1) och fft_next_day_confidence [0,1] till fourier_features.

        Kolumnerna kopieras till nn_features_daily via _update_fft_cols() i materialize_nn_features.py.


      Loggas till /var/log/aktieanalys/fft_nightly_*.log.


      2.4 Intraday/paper trading (run_paper_daytrading.sh)


      Varje cykel:


      1. fetch_avanza_intraday_quotes.py (5m bars + intraday-indikatorer)
      2. Periodisk NN inferens (NN_PREDICT_ONLY=1, ingen retrÀning)
      3. paper_trading_sim.py daytrading-konton
      4. paper_trading_sim.py swing-konton

      5. Kör med lockfil för att undvika överlappande ordercykler.


        Kedjan driver nu bÄde swing- och daytrading-konton. Separata swing NN- och daytrading NN-konton planeras.


        2.5 Helgkedja (run_weekend_chain.sh)


        Körs varje lördag kl 00:30. Jobben startar direkt efter varandra utan tidsluckor:


        1. run_rank_weight_weekly.sh — viktkalibrering i fyra steg:
        2. - Fas 3b — LHS-sampling 25 000 iterationer med alpha-beta cutoff (pruna kandidater vars övre bound < bĂ€sta composite − 2 pp); se §16.3

          - Fas 4 — turnering + exhaustiv sökning runt topp-kandidater

          - Fas 5 — surrogate NN + Optuna för fin-kalibrering

          - signal_param_lhs — LHS-optimering av signalparametrar mot 5 OOS-horisonter, körs globalt + per sektor + per sektor×makroregim

          - apply_rank_weights.py — applicerar vinnande vikter → active_weights.json

          - backtest_engine.py — kör alla strategier direkt efter

          - combination_backtest.py — kör alla 2/3-kombinations-villkor

        3. db_housekeeping.py --apply — OPTIMIZE TABLE, rensning av förĂ„ldrad data
        4. cleanup_orphan_predictions.py — rensar nn_predictions för model_id som saknas i nn_models
        5. run_nn_focused.sh — djupare trĂ€ning (top 10 tickers, 8 folds, 75 epoker) pĂ„ starkaste signaler
        6. backtest_engine.py — andra passet med eventuellt uppdaterade NN-modeller
        7. combination_backtest.py — andra passet för 2/3-kombinations-villkor
        8. run_tests.sh — kör systemets nattliga hĂ€lsotester som sista verifieringssteg

        9. > OBS: backtest_engine och combination_backtest körs nu tvĂ„ gĂ„nger per helgkörning: en gĂ„ng i slutet av run_rank_weight_weekly.sh (med nya vikter) och en gĂ„ng i run_weekend_chain.sh steg 5–6 (efter nn_focused). Det andra passet anvĂ€nder eventuellt uppdaterade NN-modeller.


          OA-körning körs separat via run_rank_weight_sampling.sh oa som jÀmförelse (uppdaterar inte active_weights.json).


          Söndag Ă€r backup-dag — kör run_weekend_chain.sh manuellt om lördagskedjan misslyckades.


          3. Datamodell (centrala tabeller)


          3.1 Marknads- och featuredata


          • tickers
          • daily_prices
          • daily_indicators
          • daily_signals
          • fourier_features
          • macro_data
          • sector_performance
          • daily_fundamentals
          • ticker_universe — universum per scope med prioritet (se §17.5)

          3.2 Signal- och modellager


          • morning_signals
          • nn_models
          • nn_weights
          • nn_features_daily — dagligt NN-featurelager för trĂ€ning/inferens (~408 MB)
          • nn_feature_stats — feature-/scalerstatistik för daglig NN-trĂ€ning (~189 MB)
          • nn_predictions
          • nn_model_registry
          • nn_training_epochs

          3.3 Paper trading/intraday


          • intraday_quotes_5m — 5-minutersdata; nyckelkolumn: bar_time (DATE+TIME, inte timestamp); tĂ€cker from 2026-04-20; ~305–306 tickers per dag
          • intraday_indicators_5m — berĂ€knade indikatorer pĂ„ 5m-bars
          • paper_accounts
          • paper_positions
          • paper_orders
          • paper_equity_snapshots

          3.4 Backtesting och OOS


          • backtest_results — totalt per strategi/symbol (full historik)
          • backtest_results_by_period — per period (1m/2m/6m/1y/3y) med start_date; rensas efter 36 mĂ„nader
          • combo_backtest_results
          • oos_backtest_windows — rullande 36-veckors OOS-fönster per ticker/strategi; rensas efter 24 mĂ„nader
          • oos_walkforward_results — equity-kurvor och nyckeltal per strategi/ticker/fönster frĂ„n oos_walkforward_full.py

          3.5 Summerings- och hjÀlptabeller


          • nn_pred_summary (model_id PK, max_pred_date, n_preds, updated_at) — snabb lookup för senaste NN-prediktion per modell; uppdateras löpande i neural_network.py. Undviker full-scan av nn_predictions (35M rader, 4.5GB) i dashboard-vyerna. Rensades 2026-07-18 och behĂ„ller nu tvĂ„ modeller per target.
          • rank_weight_horizons (horizon_label, horizon_months, weights_json, result_1m..3y, composite_score, updated_at) — optimala vikter + backtest-resultat per investeringshorisont; uppdateras mĂ„nadsvis av rank_weight_monthly-jobbet
          • api_health (source, status, last_ok, last_fail, consecutive_fails, last_error, updated_at) — hĂ€lsotillstĂ„nd för externa datakĂ€llor; uppdateras via tools/api_health.py och visas pĂ„ /aa/status

          4. BerÀkningsmotorer


          4.1 IndikatorberÀkning


          • calculate_all_indicators.py berĂ€knar full uppsĂ€ttning features i ett pass.
          • Har C-acceleration via c_ext/indicators.so för kĂ€rnloopar (SMA/EMA/RSI/TR/ATR m.fl.).
          • calculate_indicators_v2.py kompletterar med extra features.

          4.2 Signalmotor


          • calculate_signals_py.py bygger regelbaserade köp/sĂ€ljscore.
          • Stöd för Cython-kĂ€rnor (cy_ext/signal_kernels) för utvalda villkor.
          • Fourier-signalstöd kan viktas in i score.

          4.3 Backtesting


          • backtest_engine.py kör strategier per symbol och lagrar i backtest_results och backtest_results_by_period.
          • Stöd för --start DATE och --period NAME för periodbaserade körningar (1m/2m/6m/1y/3y).
          • Multicore via workers/subprocess per symbol.
          • simulate() anvĂ€nder C-kĂ€rnan (c_ext/backtest.so → run_simulate()) som primĂ€r sanningskĂ€lla (sedan 2026-08-07). Python-loopen Ă€r fallback om .so saknas eller Ă€r inkompatibel.
          • - C-kĂ€rnan hanterar: nĂ€sta-bar-open-exekvering, slippage, positionsfraktioner (pos_fractions[]), courtage med min_fee_sek, Sharpe med konfigurerbar rf_daily, och trade-log (TradeRecord-struct).

            - Resultatet inkluderar simulation_backend: 'c_ext' eller 'python' för spÄrbarhet.

            - ARM32 (raspberrypi): .aarch64_32.so-suffix; matmul.so har fel ELF-klass (64-bit) → C-acceleration ej tillgĂ€nglig för NN pĂ„ pi.

          • Kombinationsbacktest (combination_backtest.py) anvĂ€nder c_ext/backtest.so.
          • OOS walk-forward: tools/simulate_stateful_oos_signals.py kör strikt OOS-simulering med state machine (FLAT→BUY→LONG→SELL), ATR-stops, trailing och weakness-exit. Resultat (3Ă„r): Regelstrategi +37.5%, NN +20.9%.
          • Full walk-forward-jobb: tools/oos_walkforward_full.py har fĂ„tt en sys.path-fix sĂ„ att bigrig kan köra scriptet direkt utan ModuleNotFoundError. shared/bin/submit_job.sh har ocksĂ„ ny jobtyp oos_walkforward_full som kör --years 3 och föredrar bigrig.
          • simulate_stateful_multi_c() (2026-08-13): Kör alla N strategier (8 med stop-loss + 8 utan = 16 totalt) i ett enda C-anrop till simulate_stateful.so. Prismatriser och indikatorer byggs en gĂ„ng med _build_price_indicator_arrays(); equity-kurvor returneras som (n_s × n_d) flat array.
          • FFT-strategier i OOS (2026-08-13): Fyra nya strategier i oos_walkforward_full.py — FFT-standalone, Ensemble FFT+Regel, Ensemble FFT+NN (med och utan stop-loss). Signaler hĂ€mtas via fetch_fft_signals().

          4.4 Neurala nÀtverk


          • neural_network.py trĂ€nar och predikterar flera targets.
          • Per-ticker-lĂ€ge, workers, sharding och fallback till global champion-modell.
          • NN_PREDICT_ONLY=1 möjliggör inferens utan trĂ€ning (anvĂ€nds intradag).
          • Hold-gating/confidence/margin hanteras i prediktionslogik.
          • Vikter sparas som komprimerade NPZ-filer i /shared/models/nn_weights/ (primĂ€rt) med DB-fallback för Ă€ldre LSTM-modeller. Migration via tools/migrate_weights_to_npz.py; efter klart: TRUNCATE TABLE nn_weights frigör ~12 GB.

          5. Paper trading-arkitektur


          paper_trading_sim.py Àr en paper-only exekveringsmotor:


          • LĂ€ser morning_signals + prisdata + intraday-indikatorer + NN-stöd.
          • Riskregler: positionsstorlek, ATR-baserade stops, break-even, trailing, daily DD-stop.
          • Router för strategi-scope (daytrading / swing) baserat pĂ„:
          • - horisont-edge (NN 1d/5d),

            - likviditet (turnover),

            - volatilitet (atr_pct, vol_ratio_20).

          • Daytrading kan flattena EOD; swing kan hĂ„llas över natt.
          • Courtagemodell parametriserad enligt Avanza-liknande max(rate*notional, min_fee).

          5.1 RĂ€ttad positionsstorleksbugg (2026-07-16)


          RÀttad bugg (2026-07-16): SHORT-positioner saknade cash-begrÀnsning (budget = notional_cap utan tak) och init_risk_abs saknade minimumgolv. Det resulterade i >2.5 MSEK SHORT-positioner pÄ BALD-B.ST i testkonton.


          Fix: budget = min(notional_cap, cash 0.95) för bÄde LONG och SHORT, plus max(..., px 0.005) pÄ init_risk_abs.


          PĂ„verkade konton: 127, 128, 130, 131, 132 — deaktiverade efter upptĂ€ckt.


          5.2 Portföljsimulator-fixes (2026-08-07)


          simulate_portfolio.py:

          • pending_buys: köpsignaler pĂ„ dag D exekveras pĂ„ dag D+1 öppningspris (look-ahead-fix)
          • load_intraday_confirmations: TIME <= '11:00:00' — endast morgonbekrĂ€ftelse
          • not confirmed behandlas korrekt som obekrĂ€ftad

          simulate_orb_portfolio.py:

          • pending_entries: ORB-breakout detekteras bar B, exekveras bar B+1 (look-ahead-fix)
          • DAY_END_TIME: 15:25 → 17:25 (korrekt XSTO-stĂ€ngningstid)
          • Connection-lĂ€cka i main() fixad med try/finally

          6. Parallellism och klusterstöd


          6.1 Tri-nod-kluster och jobbkö


          Sedan 2026-08-06 hanteras tunga batchjobb av ett fil-baserat NFS-kösystem (/shared/queue/):


          NodHÄrdvaraRoll
          bigrig (192.168.1.71)8 CPU, 15 GB RAM, GTX 1070 (SM 6.1)PrimÀr NN-trÀning, KVM-host (ubuntu24.10)
          work733 (192.168.1.72)2 CPU (AMD K8), 5.4 GB RAM, GT610MariaDB, API-server, cron/scheduler, OpenCL, KVM-host (webb-VM)
          raspberrypiPi 4B, 4 CPU, 7.6 GB RAM, aarch64INAKTIVERAD 2026-08-12 — flaggfil /shared/queue/worker_disabled_raspberrypi stoppar worker; reaktivera: ta bort flaggfil + reenable crontab

          PREFER-routing (definierat per jobb i submit_job.sh):


          PREFERPrioritetTypiska jobb
          gtx1070 / gpu / bigrigbigrig GTX1070-worker; accepterar Àven bigrig_work733-mÀrkta jobb sedan 2026-08-14NN-trÀning med GPU
          bigrig_work733bigrig(0s) → work733(3600s), pi aldrignn_nightly shards, paper_predict, nn_focused, oos_walkforward, data_pipeline, backtest
          pipi(0s) → bigrig(30s) → work733(600s)morning_signals, rank_weight_day, refresh_materialized, fft_nightly_s2 — OBS: pi inaktiverad 2026-08-12
          work733 / gt610work733(0s) → bigrig(300s) → pi(600s)OpenCL-jobb
          cpu / bigrig(0s) → pi(30s) → work733(120s)Generiska CPU-jobb — undvik för tunga jobb; pi kan ta dem

          Deps-hantering (deps_satisfied): Beroende-jobbet mĂ„ste ha done/-fil vars mtime ≄ QUEUE_SUBMITTED-epoch för aktuellt jobb (done_epoch >= job_epoch). Inga 72h-fönster — det gamla 72h-fallbacket tillĂ€t gĂ„rdagens shards att felaktigt uppfylla dagens koordinators beroenden och togs bort 2026-08-06.


          Atomisk claim: mv pending/ → running/ Ă€r atomisk pĂ„ NFS4 (POSIX rename). Korrekt worker-layout Ă€r bigrig: 8 cpu (@1–@8) + 1 gtx1070 (9 totalt), work733: 2 cpu + 1 gt610 (3 totalt), raspberrypi: 1 cpu (INAKTIVERAD 2026-08-12). GTX1070-workern accepterar bĂ„de gtx1070- och bigrig_work733-mĂ€rkta jobb (sedan 2026-08-14). nn_nightly-shards anvĂ€nder PREFER=bigrig_work733 sĂ„ alla workers kan ta dem.


          6.2 Skalbarhetsstöd i scripts


          Tunga batchsteg stödjer multicore/sharding via miljövariabler:


          • NN_TICKER_WORKERS, NN_TICKER_SHARD_INDEX, NN_TICKER_SHARD_COUNT
          • IND_WORKERS, IND_V2_WORKERS, SIGNAL_WORKERS, BACKTEST_WORKERS
          • JOB_SHARD_INDEX, JOB_SHARD_COUNT

          Designprincip:


          • Batch/analys: hög parallellism.
          • OrdernĂ€ra intraday-sim: lockad singelcykel per konto för determinism.

          7. Native-acceleration (C/Cython)


          7.1 C (c_ext/)


          • indicators.c → indicators.so
          • backtest.c → backtest.so
          • - run_backtest() / run_backtest_batch() — ursprungliga backtestfunktioner

            - run_simulate() (tillagd 2026-08-07) — fullstĂ€ndig simulering som primĂ€r sanningskĂ€lla för backtest_engine.simulate():

            - TradeRecord-struct: entry/exit-datum (yyyymmdd), priser, avkastning

            - NĂ€sta-bar-exekvering (next_opens[])

            - Slippage per köp/sÀlj

            - Positionsfraktioner per bar (pos_fractions[])

            - min_fee_sek absolut courtagetröskel

            - Sharpe med konfigurerbar rf_daily

            - Trade-log (pre-allokerad TradeRecord*, max n_rows/2+1)

          • simulate_stateful.c → simulate_stateful.so (tillagd 2026-08-13)
          • - simulate_stateful_multi(prices, n_t, n_d, signals_flat, n_s, atr, ema, macd, macs, capital, sl_pct, atr_stop, atr_trail, trail_act, max_hold, weak_days, no_stop, results_out, daily_equity_flat) — kör N strategier i ett anrop

            - Aktiv-positions-index: active_list[] underhÄlls via swap-with-last O(1)-borttagning; mark-to-market Àr O(n\_open) i stÀllet för O(n\_tickers)

            - daily_equity_flat (n\_s × n\_d) — equity-kurvor per strategi per dag (kan vara NULL)

            - Byggs med -march=athlon64 -mno-avx -mno-avx2 -ffast-math -fno-finite-math-only

            - Python-wrapper: simulate_stateful_multi_c() i tools/oos_walkforward_full.py

          • matmul.c och nn_train.c för NN-berĂ€kningar

          Wrapper: c_ext/init.py (ctypes, fallback till Python vid saknad .so).

          • pos_fractions=None → 1.0 för alla bars; 0.0-vĂ€rden hanteras korrekt (ej maskerade av or 1.0).

          7.2 Cython (cy_ext/)


          • signal_kernels.pyx för utvalda signalvillkor.
          • Build via cy_ext/setup.py och tools/build_cython.sh.

          7.3 OpenCL GPU-acceleration (c_ext/)


          Infrastruktur för GPU-acceleration via OpenCL (implementerad, aktiveras nÀr driver finns):


          FilSyfte
          c_ext/opencl_matmul_stub.cppTiled GEMM-kernel (matmul + NN-inferens)
          c_ext/opencl_backend.pyPython-bridge (ctypes), fallback till CPU vid saknad OpenCL
          c_ext/CL/cl.hOpenCL-headers
          tools/sim_c/opencl_sim.pyGPU-parallell portfölj-simulator (1287 viktkombinationer i ett kernel-anrop)
          tools/signal_param_opencl.pyOpenCL-kernel signal_param_sim för signal_param_lhs.py

          Prioriterade GPU-kandidater (speedup mot CPU):

          1. Parallell sim — 1 287 viktkombos i Phase 3b/4: 15–30×
          2. Surrogate NN batch-inferens i Phase 5: 4–8×
          3. Huvud-NN trĂ€ning: ~2×

          4. GT610-pipeline för signal_param_lhs:

            • en work-item per parameterkombination
            • input packas som flat array [n_dates × n_tickers × 4]
            • fem separata kernel-launches (en per horisont)
            • tools/signal_param_lhs.py försöker GPU först och faller tillbaka till CPU vid fel eller saknad OpenCL
            • uppmĂ€tt hastighetsvinst: ~5500× för ~6 000 kombinationer (ca 2,6 s pĂ„ GPU vs ~4 h pĂ„ CPU)
            • buffer-lĂ€ckor i OpenCL-bridge Ă€r fixade med try/finally för res_buf, flat_buf och params_buf (commit 553621e)

            Fallback: Om OpenCL saknas eller driver Àr inkompatibel anvÀnds CPU automatiskt.

            HĂ„rdvara (work733): GeForce GT 610 (Fermi, CC 2.1) — för gammal för CUDA men stöder OpenCL 1.1.


            8. Drift, loggar och observability


            Loggar (/shared/logs/aktieanalys/):


            • pipeline_*.log — data_pipeline körningar
            • nn_nightly_*.log — NN-natttrĂ€ning (en per körning, alla shards och koordinator)
            • queue_*.log — per jobbinstans + nod (t.ex. queue_10_nn_nightly_s0_20260806_145312_bigrig.log)
            • fft_nightly_*.log — FFT-cykelfeatures
            • paper_daytrading_*.log — intraday
            • alerts.log — kösystemets ERROR/WARN-notifieringar (copytruncate, 30 dagar)
            • scheduler.log — scheduler.sh körningar (var 5:e min)
            • watchdog_api_health.log — API-watchdog
            • rank_weight_monthly_.log, db_housekeeping_.log m.fl.

            Status och retention:


            • /tmp/copilot/aktieanalys_status.md (+ mĂ„nadsarkiv)
            • Logrotation: /etc/logrotate.d/aktieanalys — tĂ€cker alla log-typer med 7–90 dagars retention beroende pĂ„ typ; safety-net maxage 60 för engĂ„ngskörningar

            LÄsning:


            • Per-shard lockfiler i /tmp: aa_ai_nn_nightly_s${N}.lock (ej delade mellan shards)
            • Koordinator: aa_ai_nn_nightly.lock
            • aa_ai_nn_focused.lock för nn_focused
            • aa_update_all.lock — exklusivt flock-lĂ„s för update_all.sh (2026-08-13); förhindrar parallella pipeline-instanser frĂ„n requeue-loopar
            • Submit-locks i /shared/queue/.locks/ (mkdir-baserade, rensas av housekeeping om stale >6h)

            Housekeeping (housekeeping_work733.sh, kör 03:30 dagligen):


            • queue/done >7d, queue/failed >14d
            • Stale heartbeats (>1d NFS, >1d /tmp)
            • Stale submit-locks (>6h)
            • aa_ai_nn_*.lock i /tmp >1 dag
            • /tmp/aa_ai_batch/ >2 dagar
            • Loggar >60d (safety-net), .log.gz >90d
            • Kör logrotate

            8.1 RAID-status (verifierad 2026-08-16)


            /dev/md0 Àr en RAID10 om 4 diskar och kör degraderat pÄ 3 av 4 diskar:


            md0 : active raid10 sdd[2](F) sdc[1] sdb[0] sde[4]
                  5860268032 blocks super 1.2 512K chunks 2 near-copies [4/3] [UU_U]
                  bitmap: 37/44 pages [148KB], 65536KB chunk
            

            • /dev/sdd Ă€r markerad faulty (F) och rĂ€knas inte lĂ€ngre som medlem; SMART rapporterar "Health OK" men disken svarar inte pĂ„ full SMART-query, vilket behandlas som hĂ„rdvarufel
            • /dev/sda, /dev/sdb, /dev/sdc och /dev/sde rapporterar SMART PASSED
            • inga nya kernel-I/O-fel har observerats — driftlĂ€get bedöms som stabilt degraderat
            • RisknivĂ„: RAID10 med near-copies=2 överlever förlusten av sdd, men en ytterligare diskförlust i samma spegelpar innebĂ€r total dataförlust. Byte av sdd Ă€r dĂ€rför öppen kritisk driftĂ„tgĂ€rd (se devops-dokumentationen §10).

            8.2 Kerneloptimering (work733)


            work733 byggs med anpassad kernel 5.10.x-work733 optimerad för AMD Athlon 64 X2 5000+ (K8): MK8-kompilering, HZ=100, PREEMPT_NONE, NO_HZ_FULL, NR_CPUS=2. sysctl-profil: /etc/sysctl.d/99-work733-perf.conf (vm.swappiness=1, nr_hugepages=64) och /etc/sysctl.d/99-zz-network-final.conf (BBR+fq trumfar beowulf MPI cubic).


            Status 2026-08-16: 5.10.262-work733 Ă€r byggd och installerad (/boot/vmlinuz-5.10.262-work733), men inte aktiv. Noden kör fortfarande 5.10.0-46-amd64 — aktivering krĂ€ver omstart, vilken Ă€r uppskjuten sĂ„ lĂ€nge nn_wf_train-cyklerna kör.



            9. Driftmatris (jobb, frekvens, syfte)


            9.1 Jobbkedjor


            Alla jobb hanteras via fil-baserat NFS-kösystem (/shared/queue/). Scheduler.sh körs var 5:e minut och submittar nÀsta steg nÀr föregÄende Àr klart.


            Vardaglig kvĂ€llskedja (mĂ„n–fre, scheduler 18:00–23:00):


            data_pipeline          PREFER=work733    → update_all.sh: priser, indikatorer, signaler, backtest
            fft_nightly (s0–s2)    PREFER=bigrig/pi  → FFT-cykelfeatures (s2 kör pĂ„ pi)
            nn_all (s0–s5)         PREFER=bigrig  → NN-trĂ€ning alla tickers (alla shards pĂ„ bigrig, aldrig pi)
            calculate_signals      PREFER=gt610      → DEPENDS:data_pipeline
            morning_signals        PREFER=pi         → DEPENDS:nn_nightly
              ↓ (parallellt med calculate_signals)
            nn_nightly_s0..s5      PREFER=bigrig_work733  DEPENDS:data_pipeline  NN_SKIP_FINALIZE=1
            nn_nightly (koordinator) PREFER=bigrig_work733  DEPENDS:nn_nightly_s0..s5  → finalize: governance+ensemble
              ↓
            paper_predict_s0..s5   PREFER=bigrig_work733  DEPENDS:nn_nightly
            nn_focused             PREFER=bigrig_work733  DEPENDS:nn_nightly
            oos_walkforward        PREFER=bigrig_work733  DEPENDS:nn_nightly
            

            Helgkedja (scheduler lördag 00:00–03:00):

            run_rank_weight_weekly.sh      → LHS/OA-sampling + turnering + surrogate NN + signal LHS → vikter
            db_housekeeping.py --apply    → DB-optimering, rensning
            cleanup_orphan_predictions.py  → rensa orphan nn_predictions
            run_nn_focused.sh              → djupare trĂ€ning top-N tickers med helginstĂ€llningar
            backtest_engine.py             → andra passet efter focused NN
            combination_backtest.py        → kombinations-pass
            run_tests.sh                   → system-/hĂ€lsotester
            

            > Söndag Ă€r backup-dag — kör run_weekend_chain.sh manuellt om lördagskedjan misslyckades.


            9.2 Komplett cron-schema


            TidDagScriptSyfte
            @reboot +90s—run_reboot_recovery.shStartar om ej avklarade kedjer efter omstart
            @reboot +120s—apply_system_profile.sh daySĂ€krar dagsprofil efter boot
            */5MĂ„n–Fre 18–23run_reboot_recovery.shWatchdog: startar om kvĂ€llskedjan vid krasch
            */5MĂ„n–Fre 18–23scheduler.shSchemalĂ€gger nĂ€sta steg i kvĂ€llskedjan
            */5Lördag 00–03scheduler.shSchemalĂ€gger helgkedja-steg
            02:20Dagligenpartition_nn_predictions_shadow.pyPartitionering av NN-prediktioner
            03:00DagligenbackintimeSystembackup
            04:15MĂ„n–Frerun_tests.shKör 22 nattliga system-/hĂ€lsotester pĂ„ work733
            02:001:a varje mĂ„nadsubmit_job.sh rank_weight_monthlyKör fas 7 per horisont (6×5 000 trials) + importerar vikter till DB
            04:00Söndagsubmit_job.sh db_housekeepingDB-underhÄll: OPTIMIZE, rensning, tmp-artefakter
            08:55MĂ„n–Frerun_intraday_fetch.sh + run_paper_daytrading.shStartup intraday + paper-handel
            09:00–17:30MĂ„n–Frerun_intraday_fetch.sh + run_paper_daytrading.shVar 5:e min under handelsfönster (stĂ€nger 17:30)
            17:40MĂ„n–Freupdate_prices.py (Ă€ldre, stöds)EOD-priser
            18:30MĂ„n–Freupdate_all.sh QUEUE_OFFLOAD=1Huvudpipeline: data → indikatorer → signaler → backtest; steg 7+12 offloadar till bigrig
            01:00MĂ„n–Frescheduler.sh (fallback)Safety-fallback: kör scheduler om kvĂ€llens pipeline missade; submittar shardad nn_nightly om ej redan gjort
            00:30Lördagscheduler.sh → weekend_chain (kön)Helgkedja via queue: rank_weight → housekeeping → orphan-rensning → nn_focused → backtest-pass 2 → tester

            9.3 Driftmatris (per script)


            JobbScriptFrekvensSyfte
            Daglig huvudpipelineupdate_all.sh (QUEUE_OFFLOAD=1)mĂ„n–fre 18:30uppdatera priser, indikatorer, signaler, backtest och morning signals
            FFT nattjobb (3 shards)run_fft_nightly.shmĂ„n–fre kvĂ€ll (scheduler)FFT-cykelfeatures; s0–s1 bigrig, s2 pi (PREFER=pi)
            NN nattjobb (6 shards + koord)run_nn_nightly.sh via kömĂ„n–fre kvĂ€ll (scheduler)6 shards PREFER=bigrig_work733 + koordinator finalize; per-shard lock
            NN alla tickers (6 shards)neural_network.py via nn_allmĂ„n–fre kvĂ€llalla 6 shards pĂ„ bigrig (PREFER=bigrig), aldrig pi — NN_BACKEND=c_ext
            NN fokuseratrun_nn_focused.shmĂ„n–fre efter nn_nightly + lördagtop-N signaltickers DEPENDS:nn_nightly
            Paper predict (6 shards)kö-jobb paper_predict_s*mĂ„n–fre efter nn_nightlyNN-inferens för paper trading DEPENDS:nn_nightly PREFER=bigrig_work733
            Portföljsimuleringrolling_1month_sim, simulate_portfoliomĂ„n–fre efter paper_predictrullande 1m-sim + perioder 1m–3y, DEPENDS:paper_predict shards
            OOS walk-forwardoos_walkforward.pymĂ„n–fre efter nn_nightlyrullande OOS-validering DEPENDS:nn_nightly PREFER=bigrig_work733
            Paper daytrade-looprun_paper_daytrading.shvar 5:e minut 09:00–17:30intraday quotes, NN-inferens, paper-orderflöde
            Morning signalsmorning_signals kö-jobbmĂ„n–fre efter nn_nightlyrankade morgonsignaler DEPENDS:nn_nightly PREFER=pi
            Full testsvitrun_tests.shmĂ„n–fre 04:15 + lördag22 system-/hĂ€lsotester
            Helgkedjarun_weekend_chain.shlördag 00:30rank_weight → housekeeping → nn_focused → backtest-pass 2 → tester
            Rank-weight mĂ„nadsoptimeringsubmit_job.sh rank_weight_monthly1:a varje mĂ„nad 02:00fas 7 för 6 horisonter pĂ„ bigrig → rank_weight_horizons
            DB-housekeepingsubmit_job.sh db_housekeepingsöndag 04:00OPTIMIZE TABLE, rensning
            Nattlig stÀdninghousekeeping_work733.shdagligen 03:30kö-filer, loggar, stale locks, tmp-batchar + logrotate

            10. Dashboard-testtÀckning (innehÄll)


            Nya innehÄllstester verifierar att kritiska dashboard-sidor verkligen innehÄller avsedda sektioner/fÀlt:


            • tests/test_dashboard_overview_content_unittest.py
            • tests/test_dashboard_stock_content_unittest.py
            • tests/test_dashboard_settings_content_unittest.py
            • tests/test_dashboard_signals_content_unittest.py
            • tests/test_dashboard_backtest_content_unittest.py
            • tests/test_dashboard_macro_content_unittest.py
            • tests/test_dashboard_nn_content_unittest.py
            • tests/test_dashboard_morning_content_unittest.py
            • tests/test_dashboard_help_content_unittest.py

            11. Prestandaöversikt (teknisk)


            DelsystemDominerande kostnadNuvarande optimeringKvarvarande flaskhals
            NN-trÀning/inferensCPU (matmul/trÀningsloopar) + DB-upserts + RAMC-accel (matmul.so, nn_train.so), per-ticker workers, shard-stöd, batch inserts, float32-NumpyData (peak ~1057 MB), MALLOC_ARENA_MAX=2, gc per tickermodell-/prediktionsjoiner och total körtid vid stort universum
            IndikatorpipelineCPU (mĂ„nga tidsserieloopar)C-accel i kĂ€rnindikatorer (indicators.so), parallel workers/shards, ctypes-arrayer byggs 1× i stĂ€llet för 13× (−19 % körtid)fortfarande flera pure-Python-loopar
            FFT-cyklerCPU (FFT per ticker/fönster)parallel symbolkörning, inkrementell recomputeFFT-kÀrna Àr fortfarande pure Python
            BacktestingCPU + DB-write I/Oparallell symbolsplit, commit-batchning per ticker, C-backtest i kombinationsmotorhuvud-backtestmotorn anvÀnder Ànnu inte C-kÀrna
            Intraday/paperAPI-latens + DB-upsertslockad cykel, inkrementell indikator-lookback, periodisk NN inferensextern API-latens/formatÀndringar
            Rank-weight fas 5NN-trĂ€ning (CPU) + portfölj-simC-NN (nn.so 2.6×/epok), C-sim (_sim.so 190×), early stopping, ensemble 3— (~5 min, 19× snabbare Ă€n Python-original)
            API/statussidasubprocess-probar mot noder + loggscanningTTL-cache (@_ttl_cached) + keyed TTL-cache + bakgrundstrĂ„d för hĂ„rdvarudata: 24.7 s → 0.35 sförsta anropet efter TTL-utgĂ„ng betalar full kostnad
            DB-housekeepingRAM vid stora radmĂ€ngderanti-joins körs i databasen i stĂ€llet för att materialisera nyckelmĂ€ngder i Python—
            WF-trĂ€ning (nn_wf_train_s0/s1)DB-anslutningar per shard320 anslutningar/shard → 1 batchad query per cykel—

            12. FörbÀttringsförslag (prioriterad roadmap)


            PrioritetFörslagEffektRisk/komplexitet
            ✅ KlarGlobal NN-trĂ€ning OOM-fix: two-pass streaming med synthetic featureseliminerar prepared[]-lista; 85% RAM-besparing (commit 98d17db)—
            ✅ KlarFFT-optimering: handskriven Cooley-Tukey → numpy.fft.rfft~100x speedup; fft_nightly 17 min → ~2 min (commit fc2ebe9)—
            ✅ KlarIndikatorloopar O(N) → O(1) / O(N)v2: 10 running sums (commit 5066db2); extended: numpy stride_tricks (commit db66e93)—
            ✅ KlarBacktest parallellism: ProcessPoolExecutor~3-4x speedup via 4 processer; fas 1 DB, fas 2 CPU, fas 3 DB (commit 10d9741)—
            HögFlytta simulate() i backtest_engine.py till C-kÀrna (anvÀnd run_backtest_batch())ytterligare CPU-reduktion; krÀver att slippage/fractional/trade-log porteras till Chög
            HögOpenCL FFT-batch pĂ„ GPUGT610 ej lönsamt (1 SM Fermi, ingen gpyfft, PCIe-overhead = nollvinst)—
            MedelLÀgg replay-motor för historisk intraday paper-simuleringbÀttre utvÀrdering av daytrade-strategimedel
            MedelHMM-baserad regim-detektion som extra NN-featurese 12.2 nedanmedel/hög
            ✅ KlarMaterialiserad "latest prediction"-vy/tabell för NNlöst via nn_pred_summary-optimering och batchfrĂ„gor i morgon.php—
            ✅ KlarObservability: StepTimer i calculate_all_indicators.py + calculate_signals_py.pySTEP-timing + SUMMARY per körning—
            MedelLÀgg till Small Cap i _UNIVERSE_PRIORITY (efter MID_CAP)utökat tickeruniversumlÄg
            LÄgCentral konfigurationsprofil (dev/stage/prod)enklare driftstyrninglÄg
            LÄgDerivat-motor: Black-Scholes/Merton, optioner, warranter, hedgese 12.3 nedanhög

            12.1 Global NN-trÀning: minnesoptimering för 10+ Är och vÀxande tickeruniversum


            Krav: load_training_data() i neural_network.py ska klara 10 Ă„r × 500+ tickers utan OOM pĂ„ 6 GB RAM-system.


            NulÀge (problem): Global modell (signal_3class, universe=ALL) laddar hela trÀningsmatrisen i Python-minnet pÄ en gÄng:

            • 383 750 rader (307 tickers × 1 250 dagar) × ~100 features som Python-dicts = ~1.7 GB
            • Koden Ă€r redan optimerad (float32 X-matris, column-major extraktion, gc.collect, malloc_trim)
            • Bottleneck: _select_top_features(prepared[:train_cutoff]) krĂ€ver hela prepared-listan i minnet innan numpy-steget — cirkulĂ€rt beroende blockerar direkt streaming
            • TillfĂ€lligt workaround: NN_TRAIN_FROM=2021 (5 Ă„r) och watchdog-villkor RAM+swap kombinerat

            Prioriterade lösningsalternativ:


            AlternativTeknikRAM-besparingKomplexitet
            2-pass streaming (rekommenderas)Pass 1: stream sample (20k rader) → feature-selektion. Pass 2: COUNT→pre-allokera X float32→stream direkt in utan prepared-lista~85 %medel
            Chunk-baserad ticker-inlĂ€sningDela upp i ticker-batchar, trĂ€na med mini-epoch-ackumulering + global scaler pre-berĂ€knad~60–80 %medel/hög
            Rullande trÀningsfönsterBegrÀnsa fönster till 7 Är med tidsviktning (halvlife)~30 %lÄg
            Komprimerad DB-representationSpara features som float32 i DB, undvik Python-dict per rad~40 %medel

            Rekommenderad approach: 2-pass streaming — löser rot­orsaken utan att Ă€ndra modellarkitekturen.


            > EngĂ„ngskörning (nn_fullhistory): Detta Ă€r ett engĂ„ngsjobb som körs 2026-07-15/16 pĂ„ bigrig GPU med NN_TRAIN_FROM=3650 dagar, NN_RESUME=0, NN_BACKEND=pytorch (tvingad GPU). TĂ€cker OMX30→LARGE_CAP→MID_CAP sekventiellt. BerĂ€knad klar ~05:00.

            >

            > Löpande trĂ€ning: Nightly + helg kör alltid 5 Ă„r (1825 dagar) för bĂ„de global NN och per-ticker. Veckohelg-trĂ€ningen Ă€ndrades frĂ„n 3650 → 1825 i commit d7333c0 (run_nn_nightly.sh).


            12.2 HMM-baserad regim-detektion som extra NN-feature


            Bakgrund: Nuvarande arkitektur har implicit tillstÄndshantering (NN lÀr sig feature-korrelationer), ett binÀrt regime-filter i paper-trading (TREND_UP/DOWN/RANGE), och Phase7 som en global statisk viktning av 35 signaler. Ingen del av systemet modellerar explicit hur marknadsregimer övergÄr frÄn ett tillstÄnd till ett annat.


            Föreslagen förbĂ€ttring: TrĂ€na en Hidden Markov Model (HMM) per ticker (eller globalt) med 5–8 dolda tillstĂ„nd:

            TillstÄnd (exempel): LOW_VOL_RANGE, TREND_UP_STRONG, TREND_UP_WEAK,
                                 TREND_DOWN_STRONG, TREND_DOWN_WEAK, HIGH_VOL_CRASH, RECOVERY
            Emissioner: P(RSI, MACD, OBV, ATR, volatilitet | tillstÄnd)
            ÖvergĂ„ngar: P(state_t+1 | state_t) — trĂ€nas pĂ„ 10yr historik
            

            TillÀmpningar:

            1. Extra NN-features: Regime-posterior `P(state_tobservations)` (6–8 features) matas in i NN
            1. Konditionella Phase7-vikter: IstÀllet för globala vikter, optimera separata vikter per regime
            2. Paper-trading filter: ErsĂ€tt hĂ„rdkodat TREND_UP/DOWN/RANGE med HMM-posterior ≄ 0.7

            3. Implementering: hmmlearn-biblioteket (Gaussian HMM), trÀning i analyze_fourier_cycles.py eller separat compute_hmm_regimes.py, resultat i ny DB-tabell hmm_regime_features.


              Prioritet: LĂ„g/Medel — utvĂ€rdera efter att OOS-sim med nuvarande modeller visar att vi nĂ„tt tak med befintlig arkitektur. Uppskattad implementeringstid: 2 veckor.


              12.3 Derivat-motor: Black-Scholes/Merton, optioner, warranter och hedging


              Bakgrund: Systemet handlar idag endast aktier (lĂ„ng/kort). En derivat-motor möjliggör riskjusterade positioner, implicit volatilitetsanalys och hedgade strategier — vilket Ă€r nĂ€sta naturliga steg för att gĂ„ frĂ„n direktionell handel till riskminimering.


              Byggstenar:


              A. Black-Scholes/Merton-prissÀttning

              Europeiska call/put-optioner och warranter prissÀtts med BSM-formeln:

              C = S·N(d1) − K·e^(−rT)·N(d2)
              d1 = [ln(S/K) + (r + σÂČ/2)·T] / (σ·√T)
              d2 = d1 − σ·√T
              
              • Implicita volatiliteten (IV) löses numeriskt (Newton-Raphson eller Brent) per options-strike/löptid → implied_vol-tabell
              • Volatilitetsytan (IV per strike × löptid) ger IV-skew och term-struktur
              • Greeks: Delta (Δ), Gamma (Γ), Theta (Θ), Vega (Μ), Rho (ρ) för varje position

              B. Riskminimering

              MetodTillÀmpning
              Delta-hedgingNeutralisera Δ-exponering med motposition i underliggande
              Gamma-scalpingProfittera pÄ realiserad volatilitet > IV
              CVaR/ES-optimeringMinimera Conditional Value-at-Risk pÄ portföljnivÄ
              Kelly-kriterietOptimal positionsstorlek givet edge och varians
              Correlation-hedgingNeutralisera sektorrisk via indexkorgar (OMXS30 etc.)

              C. Warranter (svenska marknaden)

              • Bull/bear-certifikat och warranter pĂ„ NASDAQ OMX Nordic — prissĂ€tts som in-the-money calls/puts med hĂ€vstĂ„ng
              • FinansieringsrĂ€nta och knock-out-nivĂ„ integreras i BSM-justering
              • DatakĂ€lla: Nordnet warrant-feed eller Avanza API

              D. Integrering med befintligt system

              Ny komponent: tools/options_pricer.py
                - load_option_chain(ticker, expiry_date) → DB-tabell option_chains
                - compute_iv_surface(ticker) → iv_surface-tabell
                - compute_greeks(position_id) → uppdaterar paper_positions
                - suggest_hedge(ticker_id, nn_signal) → delta-hedge via index-ETF
              
              Ny DB-tabell: option_chains (ticker_id, strike, expiry, option_type, bid, ask, iv, delta, gamma, theta, vega)
              Ny DB-tabell: iv_surface (ticker_id, date, strike_pct, days_to_expiry, iv)
              

              E. Strategier att utvÀrdera

              • Covered call: Long aktie + short OTM call → inkomst vid sidledsmarknad
              • Protective put: Long aktie + long ATM put → begrĂ€nsar nedsida (NN-signal trigger)
              • Long straddle/strangle: Vid NN-osĂ€kerhet (lĂ„g confidence) + hög IV → volatilitetsbet
              • Calendar spread: Utnyttja IV-term-struktur (sĂ€songsvariationer i OMXS30)

              FörutsÀttningar: TillgÄng till options-data (Nordnet/Avanza API), margin-konto för short-options, realtids-IV-berÀkning (< 1s per strike). Börsdata för svenska warranter finns hos Avanza och Nordnet.


              Prioritet: LĂ„g — krĂ€ver ny datakĂ€lla och regulatorisk genomgĂ„ng. Estimerad implementeringstid: 4–6 veckor. PĂ„börja med IV-berĂ€kning och BSM-prissĂ€ttning (inga live-trades) som analytiskt verktyg.



              13. Felhantering och sÀkerhet


              • Bash-jobb kör set -euo pipefail.
              • trap on_error i nattjobb för tydlig felmarkering i logg/status.
              • Python-script anvĂ€nder explicita DB-commits och stĂ€nger anslutningar i finally.
              • calculate_signals_py.py vĂ€ntar pĂ„ eventuell pĂ„gĂ„ende ALTER TABLE nn_weights innan start (förhindrar I/O-konflikt och Lost Connection, inlagt 2026-07-22).

              13.1 TransaktionssÀkerhet (2026-08-07)


              db_pool.py sÀtter autocommit=True pÄ alla connections. commit()/rollback() Àr dÀrmed no-ops om inte en explicit transaktion startats med conn.begin(). Berörda moduler:


              • order_manager.py: sync_order_status() och _update_position_on_fill() startar explicit conn.begin() sĂ„ att live_orders-UPDATE och positions-INSERT/UPDATE Ă€r atomiska.
              • database.py: anvĂ€nder SQLAlchemy engine.begin() — atomisk transaktion för alla 4 tabeller (intraday_prices, daily_prices, daily_indicators, daily_signals).
              • Övriga moduler med enkla single-statement-operationer: autocommit Ă€r korrekt beteende.

              13.2 API-autentisering (2026-08-07)


              • Alla /aa/*-routes skyddas av _require_api_key (opt-in via API_KEY-miljövariabel i api.py).
              • /aktieanalys/status (kanonisk URL) Ă€r nu explicit skyddad — tidigare exponerades sidan utan auth.
              • PHP-frontend (aktie.php): rollBack() körs vid requeststart pĂ„ persistenta anslutningar för att rensa dirty state frĂ„n tidigare request.

              13.3 Watchdog — resursvĂ€ktare (watchdog.sh)


              Watchdog kör kontinuerligt och skyddar mot OOM och systemkrasch:


              TröskelVarningStopp av NN-trÀning
              Ledigt RAM< 600 MB< 300 MB
              Ledig swap< 1 500 MB< 600 MB
              Systemload> 6.0> 9.0

              Vid stop: kill_nn_training() skickar SIGTERM till alla neural_network.py / run_nn_retrain_clean / run_nn_nightly-processer; 8 s grace, sedan SIGKILL.


              Loggar hÀndelser till /tmp/copilot/nn_resource_kills.log. Skapar flaggfil /tmp/copilot/nn_killed_by_guard.flag för diagnostik. Watchdog-status (inkl. resurslÀge) uppdateras löpande i /tmp/copilot/watchdog_status.txt.


              14. KÀnda begrÀnsningar


              • Historisk replay av hela intraday-paperflödet krĂ€ver dedikerad replay-motor (nuvarande intraday-loop Ă€r live-cykelorienterad).
              • Vissa script Ă€r fortfarande CPU-intensiva i pure-Python-delar trots C-acceleration.
              • Externa API-format (framför allt quotes) kan Ă€ndras och krĂ€ver dĂ„ parserjustering.
              • ARM32 (raspberrypi): matmul.so Ă€r kompilerad för x86_64 → C-acceleration för NN ej tillgĂ€nglig. backtest.so (ARM32) fungerar.
              • backtest_engine.simulate() equity-serien har en konsekvent 1-dags presentation i equity-kurvan (trades Ă€r korrekta, Sharpe pĂ„verkas marginellt). GĂ€ller bĂ„da backends.
              • RAID10 degraderad (3/4 diskar) — sdd faulty. Ingen redundans kvar i det drabbade spegelparet. Diskbyte Ă€r öppen kritisk Ă„tgĂ€rd.
              • Kernel 5.10.262-work733 installerad men inte aktiv — krĂ€ver omstart av work733.
              • NN-trĂ€ningens minnesprofil ligger pĂ„ ~1057 MB peak per ticker (float32-dataset + float64-kopia för C-kĂ€rnan). Ett vĂ€sentligt större tickeruniversum eller fler features krĂ€ver chunkat X-bygge (medvetet ej genomfört, se §12.1).

              Ej fixade M-fynd (2026-08-07, öppna):

              • paper_trading_sim.py: qty_by_risk=0 faller tillbaka till budget-storlek → --risk-per-trade-pct Ă„sidosĂ€tts. Bör skippa trade (qty=0).
              • paper_trading_sim.py: fil-flock antar NFS-semantik; om nod monterar lokalt disk blir lĂ„set per-nod → DB advisory lock (GET_LOCK()) rekommenderas.
              • morning_signals.py, signal_executor.py, generate_day_signals.py: innehĂ„ller oanvĂ€nda lokala DB-dict med defaultlösenord (CHANGE_ME_DB_PASSWORD / user='maria'). Bör tas bort.

              ÅtgĂ€rdat sedan 2026-08-07: generate_day_signals.py OOM-risken (obegrĂ€nsad fetchall) hanteras nu via datum-/minnesbegrĂ€nsad laddning i samband med minnesoptimeringarna 2026-08-16 (se §44).


              15. Livehandelssystem (2026-08-07)


              Systemet har ett livehandelslager mot Nordnet som inte Àr aktivt i paper-mode:


              ModulSyfte
              nordnet_trader.pyREST-API-klient mot Nordnet: orderlÀggning, kontohantering, reconciliation
              order_manager.pyOrderlivscykel: sync_order_status, fill→position, stop-loss, daglig PnL
              risk_manager.pyRiskbegrÀnsningar: max daglig förlust, positionstak, drawdown-kill
              trading_killswitch.pyKill-switch och kretsbrytare: handelshorisont, helgdagar, circuit breaker

              Viktiga egenskaper:

              • trading_killswitch.py: check_market_hours() returnerar bool (INTE tuple). Fail-closed vid OSError.
              • Handelshorisont: XSTO 09:05–17:20 med helgdagar (PĂ„sk via Gauss-algoritm).
              - nordnet_trader.py: deterministisk `client_order_id = sha1(tickersidevolumetimestamp)[:16]` för idempotens.
              • Stop-loss: nollas i _update_position_on_fill (sĂ€lj-sidan) — inte omedelbart efter order-placement.
              • Atomic fill: live_orders-UPDATE och live_positions-INSERT/UPDATE sker i samma conn.begin()-transaktion.

              16. Tekniska nyckelfiler


              • update_all.sh
              • run_nn_nightly.sh
              • run_fft_nightly.sh
              • run_paper_daytrading.sh
              • neural_network.py
              • analyze_fourier_cycles.py
              • calculate_all_indicators.py
              • calculate_indicators_v2.py
              • calculate_signals_py.py
              • backtest_engine.py — backtestmotor; simulate() anvĂ€nder C-kĂ€rna (run_simulate()) som primĂ€r sanningskĂ€lla
              • paper_trading_sim.py
              • simulate_portfolio.py — portföljsimulator: pending_buys (D+1), morning-only-filter
              • simulate_orb_portfolio.py — ORB-simulator: pending_entries (nĂ€sta bar), DAY_END 17:25
              • nordnet_trader.py — Nordnet REST-klient; live orders mot riktigt konto
              • order_manager.py — orderlivscykel, atomic fill+position, stop-loss
              • risk_manager.py — riskgrĂ€nser och circuit breaker
              • trading_killswitch.py — kill-switch; check_market_hours() → bool
              • morning_signals.py — genererar köp/sĂ€lj-signaler varje morgon
              • signal_executor.py — exekverar signaler mot Nordnet API
              • database.py — DatabaseSaver; engine.begin() atomisk transaktion för 4 tabeller
              • db_pool.py — connection pool; autocommit=True; session_vars-whitelist
              • db_utils.py — execute_batch() returnerar (int, conn)-tuple
              • api.py — FastAPI REST API; alla /aa/*-routes autentiserade
              • fetch_avanza_intraday_quotes.py
              • db_creation_mariadb_complete.sql
              • db_creation_postgres.sql
              • run_rank_weight_weekly.sh
              • tools/rank_weight_sim_phase3b.py
              • tools/rank_weight_sim_phase4.py
              • tools/rank_weight_sim_phase5.py
              • tools/apply_rank_weights.py
              • tools/sim_c/sim.py + sim.c
              • tools/nn_c/cnn.py + nn.c
              • run_evening_chain.sh — (Ă€ldre) vardaglig jobbkedja; ersatt av scheduler.sh + NFS-kösystem sedan 2026-08
              • run_weekend_chain.sh — helgkedja (rank_weight → housekeeping → nn_focused)
              • shared/bin/submit_job.sh — submittar alla jobbtyper till NFS-kön; definierar PREFER/DEPENDS per jobb
              • shared/bin/scheduler.sh — dispatcher (var 5:e min); submittar nĂ€sta steg baserat pĂ„ körningslĂ€ge
              • shared/bin/queue_worker.sh — worker pĂ„ alla 3 noder; atomisk claim, heartbeat, orphan-recovery, PREFER-routing
              • housekeeping_work733.sh — nattlig stĂ€dning: kö-filer, loggar, stale locks, tmp-batchar
              • c_ext/backtest.c — C-backtest; run_simulate() med TradeRecord, slippage, pos_fractions
              • c_ext/init.py — ctypes-wrappers; TradeRecord; SIMULATE_AVAILABLE
              • c_ext/opencl_matmul_stub.cpp + c_ext/opencl_backend.py — OpenCL GPU-acceleration
              • tools/sim_c/opencl_sim.py — GPU-parallell simulator
              • tools/signal_param_opencl.py — OpenCL-kernel för signal_param_lhs
              • tools/signal_param_lhs.py — GPU→CPU-fallback för parameter-LHS
              • tools/db_housekeeping.py — DB-optimering och rensning
              • tools/oos_walkforward_full.py — full 3-Ă„rig walk-forward-körning för OOS



              17. Rank-weight optimeringspipeline


              Systemet optimerar dashboardens rankningsvikter automatiskt varje söndag via en 3-fas pipeline. FrÄn 2026-07-14 stöds fyra placeringshorisonter med separata viktsatser.


              16.1 MÄl


              Hitta multiplikatorer per rankningsgrupp (signals, trend, momentum, macd, volume, adx, bb, cycle) som maximerar composite-score:


              composite = 0.10 × 1mĂ„n% + 0.15 × 2mĂ„n% + 0.25 × 1Ă„r% + 0.50 × 3Ă„r%
              

              med straff:

              • −10 pp om 1mĂ„n% < −5%
              • −20 pp om 2mĂ„n% < −10%
              • −15 pp om 1Ă„r% < 0%

              Placeringshorisonter — separata viktsatser per horisont:


              HorisontSort-nyckelOutput-JSONPHP-dashboard
              Balanserad (composite)compositeactive_weights.json⚖ Balanserad
              LĂ„ng (1+ Ă„r)3Ă„ractive_weights_long.json📈 LĂ„ng
              Medel (3–12 mĂ„n)1Ă„ractive_weights_medium.json📊 Medel
              Kort (1–2 mĂ„n)2mĂ„nactive_weights_short.json⚡ Kort

              16.2 Pipeline-arkitektur


              flowchart LR
                  A[fas 3b\nLHS/OA/random\n25k iter, alpha-beta] --> B[fas 4\nTurnering\n+ exhaustiv sökning]
                  B --> C[fas 5\nSurrogat-NN\n+ 4×scipy DE]
                  C --> D[apply_rank_weights.py]
                  D --> E[active_weights*.json\n4 horisonter]
                  E --> F[PHP-dashboard (/aa/)\nlÀser active_weights*.json]
              

              16.3 Fas 3b — Sampling med alpha-beta cutoff


              Fil: tools/rank_weight_sim_phase3b.py


              • Drar 25 000 viktkombinationer ur SEARCH_SPACE med valbar samplingsmetod
              • Samplingsmetoder (styrs via RW_SAMPLING-env):
              • - lhs (default i weekly) — Latin Hypercube Sampling, garanterat jĂ€mn tĂ€ckning av parameterrummet

                - oa — Orthogonal Array (LHS strength=2), balans i alla dimensionspar — anvĂ€nds som jĂ€mförelse via run_rank_weight_sampling.sh oa

                - random — slumpmĂ€ssig sampling (ej lĂ€ngre default; LHS ger bĂ€ttre tĂ€ckning med samma N)

                - halton, sobol — quasi-random sekvenser (stöds via scipy.stats.qmc)

              • Simulerar perioder i stigande kostnad: 1mĂ„n → 2mĂ„n → 1Ă„r → 2Ă„r → 3Ă„r
              • Alpha-beta cutoff: om övre bound pĂ„ composite ≀ bĂ€sta sett hittills → pruna resterande perioder
              • Adaptiva bounds: MAX_3YR_BOUND och MAX_1YR_BOUND för konvergent cutoff
              • Sparar topp-50 (composite och 3Ă„r) + faktoranalys till rank_weight_phase3b_*.txt
              • Composite-score (4 perioder): 0.10×1mĂ„n + 0.15×2mĂ„n + 0.25×1Ă„r + 0.50×3Ă„r med straff
              • IndikatorvĂ€rden kontrolleras alltid med is not None (0.0 Ă€r ett giltigt vĂ€rde)
              • Typisk körtid: ~6 min (C-simulator), ~2.5 h (Python-fallback)

              16.4 Fas 4 — C++17-turneringseliminering + begrĂ€nsad exhaustiv sökning


              PrimĂ€r implementation: tools/rank_weight_sim_phase4.cpp → binĂ€r rank_weight_sim_phase4

              Byggscript: tools/build_phase4.sh


              Fas 4 Àr omskriven i C++17 för stabilare körning och lÀgre körtid. Python-versionen finns kvar som referens, men den binÀra C++-körningen Àr nu primÀr driftvÀg.


              Miljövariabler som lÀses vid körning:

              • DB_HOST
              • DB_MARIADB_PASSWORD
              • RW_END_DATE
              • RANK_WEIGHT_OUTPUT_DIR

              Turneringsfasen rangordnar de 8 grupperna deterministiskt:

              • Varje runda: varje kvarvarande grupp lyfts till HIGH_MULT=3.0, övriga hĂ„lls pĂ„ LOW_MULT=1.0
              • Gruppen med lĂ€gst composite nĂ€r förhöjd elimineras → sĂ€mst rangordnad
              • Upprepa tills 1 grupp kvar → fullstĂ€ndig ranking G[0] (bĂ€st) > ... > G[7] (sĂ€mst)

              BegrÀnsad sökning utnyttjar ranking-monotoni:

              • MULT_CHOICES = [0.0, 0.5, 1.0, ..., 4.5] (10 nivĂ„er)
              • Constraint: mult[G0] ≄ mult[G1] ≄ ... ≄ mult[G7]
              • C(17,8) = 24 310 kombinationer — globalt optimum i sökrymden
              • Sparar alla kombinationer till rank_weight_phase4_all.csv (trĂ€ningsdata för fas 5)
              • Sparar ranking till rank_weight_phase4_best.json (maskinlĂ€sbar, anvĂ€nds av fas 5)
              • Sparar per-horisont JSON: rank_weight_phase4_best.json, rank_weight_phase4_best_long.json, rank_weight_phase4_best_medium.json, rank_weight_phase4_best_short.json

              Högprioriterade buggar som rÀttats:

              1. Final-date rebalance bug — sista handelsdagen kunde trigga samma-bar köp + likvidering; fixat med is_last-guard.
              2. Universumbugg — simuleringen byggde tidigare universum endast frĂ„n daily_signals; nu inkluderas Ă€ven daily_prices sĂ„ hela investerbara universumet kommer med.

              3. PrestandaförbÀttringar:

                • binĂ€rsökning för datumfiltrering
                • förberĂ€knade datumserialer
                • inkrementell uppföljning av bĂ€sta resultat under sökning

                Typisk körtid: minuter snarare Àn Python-timmar pÄ samma hÄrdvara.


                16.5 Fas 5 — Surrogatmodell (NN) + scipy Differential Evolution


                Fil: tools/rank_weight_sim_phase5.py


                SurrogattrÀning


                TrÀnar fem ensemble-NN-surrogater (C-NN via nn.so, fallback numpy-NN):


                SurrogatTargetArkitektur
                surr_compcomposite8→64→32→1, Adam
                surr_1m1mĂ„n%8→64→32→1, Adam
                surr_2m2mĂ„n%8→64→32→1, Adam
                surr_1y1Ă„r%8→64→32→1, Adam
                surr_3y3Ă„r%8→64→32→1, Adam

                Ensemble-storlek: N_ENSEMBLE=3 (styrs via env RW_ENSEMBLE_SIZE).


                Ranking lĂ€ses frĂ„n rank_weight_phase4_best.json (maskinlĂ€sbar JSON, ej fri textparsning). Fas 5 crashar hĂ„rt om filen saknas — kör fas 4 först.


                2-pass early stopping (sedan 2026-07-13):


                Pass 1 – _find_best_chunks():
                  TrÀnar probe-modell pÄ train-split (80%) i 25-epokers-chunk
                  MĂ€ter val-RÂČ (20%) efter varje chunk
                  Stoppar nÀr 3 chunk utan förbÀttring (ES_PATIENCE=3, ES_MIN_DELTA=1e-3)
                  → returnerar best_chunks (typiskt 3–6 chunks = 75–150 epoker)
                
                Pass 2 – retrain:
                  Ny modell trĂ€nas exakt best_chunks × 25 epoker pĂ„ hela X
                  → returnerad modell har garanterat bĂ€sta vikter
                

                Tidigare: 5-fold CV × 150ep + 250ep = ~5.7M iterationer/target (~96 min total).

                Nu: 2-pass val-split, typiskt 75–150 epoker, ensemble 3 → ~5 min total (19× snabbare).


                Sökning


                • 4 separata scipy.differential_evolution-körningar — en per horisont (composite, lĂ„ng/3Ă„r, medel/1Ă„r, kort/2mĂ„n) — varje horisont optimeras mot rĂ€tt surrogat
                • 2 000 random multi-start med batch-framĂ„tspridning
                • Alla DE-resultat samlas och dedupliceras → topp-N valideras
                • Monotoni-constraint: mult[G0] ≄ mult[G1] ≄ ... (arv frĂ„n fas 4-ranking)
                • UCB-scoring: mean + 1.5×std vid sökning, mean vid validering

                Validering


                Topp-50 surrogatförslag valideras med faktisk portfölj-simulering:

                • C-simulator (_sim.so) anvĂ€nds om tillgĂ€nglig (190× snabbare Ă€n Python)
                • Python-simulate() som fallback

                Sparar:

                • rank_weight_phase5_best.json — composite (maskinlĂ€sbar, för apply_rank_weights.py)
                • rank_weight_phase5_best_long.json — optimerat för 3Ă„r
                • rank_weight_phase5_best_medium.json — optimerat för 1Ă„r
                • rank_weight_phase5_best_short.json — optimerat för 2mĂ„n
                • rank_weight_phase5_results.txt — lĂ€sbar rapport (topp-20)

                Stödjer --seed för reproducerbara körningar.


                OBS: Optuna TPE Ă€r O(nÂČ) per trial och ej anvĂ€ndbart pĂ„ AMD Athlon 64 — ersatt av scipy DE.


                16.6 Applicering: apply_rank_weights.py


                Fil: tools/apply_rank_weights.py


                Körs som steg 4 i run_rank_weight_weekly.sh:

                1. LÀser per-horisont JSON (fas 5 primÀr, fas 4 fallback) för composite, long, medium, short
                2. Anropar mults_to_weights(mults) → individuella vikter
                3. Skriver 4 JSON-filer till RANK_WEIGHT_OUTPUT_DIR:
                4. - active_weights.json (composite/balanserad)

                  - active_weights_long.json

                  - active_weights_medium.json

                  - active_weights_short.json

                5. Returnerar exit 0 endast om alla 4 horisonter lyckades (partiell deploy loggas men avbryter scriptet)

                6. 16.7 PHP-dashboard-integration


                  PHP-dashboarden (/aa/) lÀser active_weights*.json direkt frÄn rank-weight-outputen och anvÀnder samma fallback-kedja som tidigare webbvy:


                  - Horisontval: ⚖ Balanserad📈 LĂ„ng📊 Medel⚡ Kort
                  • Fallback per horisont: active_weights_{horizon}.json → active_weights.json → _DEFAULT_RANK_W
                  • active_weights*.json genereras fortsatt av tools/apply_rank_weights.py i weekly-pipelinen och Ă€r inte dashboard-specifika artefakter

                  16.8 C-accelererade kÀrnbibliotek


                  BibliotekKĂ€llaSyfteKompilering
                  _sim.sotools/sim_c/sim.cPortfölj-simulatorgcc -O3 -msse2 -march=athlon64 -shared -fPIC -o _sim.so sim.c -lm
                  nn.sotools/nn_c/nn.cFeedforward NN (Adam, SSE2, normalisering internt)gcc -O3 -msse2 -march=athlon64 -ffast-math -shared -fPIC -o nn.so nn.c -lm

                  Hastighetsvinst:

                  • _sim.so: ~190× snabbare Ă€n Python-simulatorn per körning
                  • nn.so: ~2.6× snabbare Ă€n numpy-NN per epok (SSE2-optimerad för Athlon64)

                  OBS _sim.so: Kompilera utan -ffast-math — C-koden anvĂ€nder x == x för NaN-detektion.

                  OBS nn.so: Wrapper tools/nn_c/cnn.py (CNN-klassen) hanterar normalisering internt — predict() tar rĂ„a X-vĂ€rden.

                  Minneshantering: SimHandle frigörs via close() eller exit; sim.c kopierar indata med memcpy (Python-buffertar kan kasseras efter sim_create()).

                  Fallback: Om .so saknas anvÀnds Python-implementationer automatiskt (numpy_nn.NumpyNN, simulate()).

                  handles_normalization = True pÄ CNN-klassen signalerar att surrogate_predict() kan anropa model.predict(X_raw) direkt.


                  16.9 Loggar och loggrotation


                  • Log: /shared/logs/aktieanalys/weekend_chain.log (helgkedja), /shared/logs/aktieanalys/rank_weight_monthly.log (mĂ„nadsjobb)
                  • Utdatafiler: /shared/logs/aktieanalys/rank_weight/ (JSON, CSV, txt)
                  • Lockfil: /tmp/aa_ai_rank_weight_weekly.lock, /tmp/aa_ai_rank_weight_monthly.lock, /tmp/aa_ai_weekend_chain.lock

                  Loggrotation — /etc/logrotate.d/aktieanalys


                  LogggruppMönsterFrekvensRetention
                  Pipeline/kedjeloggarpipeline.log, evening_chain.cron.log, nn_nightly.logdaily30 rotationer
                  NN datumstÀmpladenn_focused_.log, nn_nightly_.log, nn_detached_.log, nn_global_pretrain_.log, m.fl.daily14 dagar
                  Kedjeloggar datumstÀmpladeevening_chain.log, pipeline_.log, fft_nightly_.log, reboot_recovery.log, rank_weight_monthly_*.log, m.fl.daily7 dagar
                  Systemloggarsystem_alerts.log, system_profile.log, tests.cron.log, validate_prices.log, db_housekeeping*.log, m.fl.daily14 dagar
                  Rank-weight / multi-horizonrank_weight_lhs_.log, rank_weight_oa_.log, rank_weight_phase4_.log, rank_weight_multi_horizon_.logvid körning8 veckor
                  NN retrainrank_weight/nn_retrain_clean_*.logmonthly6 mÄnader
                  Intraday/simuleringsim_day_.log, sim_swing_.log, intraday_fetch_.log, oos_walkforward_full_.log, stateful_oos_*daily7 dagar
                  Strategy-experimentstrategy_v.log, arch_experiment.logvid körning8 veckor
                  aa-ai generella*.log i aa-ai/ och aa-ai/logs/weekly8 veckor
                  Trading-daemons/tmp/nordnet_*.log, /tmp/signal_executor.log, requeue_watch, nn_resource_kills, m.fl.daily (copytruncate)14 dagar

                  16.10 Multi-horisont viktsoptimering (rank_weight_multi_horizon.py)


                  Kör QMC-sampling (standard OA-LHS via scipy) och optimerar vikter separat per tidshorisont.


                  Horisonter: 1mÄn, 2mÄn, 6mÄn, 1Är, 3Är


                  Output:

                  • /tmp/copilot/rank_weight_multi_horizon_comparison.txt — jĂ€mförelsetabell
                  • /tmp/copilot/rank_weight_multi_horizon_{1m,2m,6m,1y,3y}.json — vikter per horisont

                  Sampling: RW_SAMPLING=oa (standard) — OA-LHS styrka 2 via scipy.stats.qmc.LatinHypercube(strength=2). Env RW_SAMPLING vĂ€ljer `oalhssobolhaltonrandom`.

                  Applicering:

                  • MĂ„nadsjobb rank_weight_monthly (fas 7, Optuna QMC Sobol, 5 000 trials/horisont) → rank_weight_horizons-tabellen → horisont.php
                  • 6mĂ„n-vikterna (bĂ€st balans: +18% pĂ„ 6mĂ„n, +19% pĂ„ 1Ă„r) → active_weights_medium.json

                  Resultat (2026-07-15):

                  Optimerat för1mÄn2mÄn6mÄn1Är3Är
                  1 mÄn+6.8%-6.3%-13.2%-3.1%+67.3%
                  2 mÄn-0.5%+6.7%-9.1%-3.2%+91.7%
                  6 mÄn-4.2%+1.1%+18.2%+19.0%+56.6%
                  1 Är-1.6%-0.4%+0.9%+31.7%+65.4%
                  3 Är-1.2%+2.3%-8.1%-1.1%+113.6%
                  Buy & Hold+0.4%-2.0%-4.3%-2.9%+28.7%

                  16.11 Fas 7 — Optuna med QMC (rank_weight_sim_phase7.py)


                  Fas 7 ersÀtter TPE random warm-start med QMCSampler(Sobol, scrambled=True).


                  Argument:

                  - `--sampler qmctpecmaes (standard qmc`)
                  - `--horizon composite1m2m6m1y3y (standard composite`)
                  • --trials N (standard 1 000)

                  Per-horisont vikter (_HORIZON_WEIGHTS):


                  Horisontw_1mw_2mw_6mw_1yw_3y
                  composite0.050.100.150.400.30
                  1m0.800.150.030.010.01
                  2m0.200.600.150.040.01
                  6m0.050.150.550.200.05
                  1y0.020.080.200.550.15
                  3y0.020.050.080.250.60

                  Optuna-studie namnges rw_phase7_{horizon} och output-JSON rank_weight_phase7_{horizon}.json. Fallback till TPESampler(n_startup_trials=200) om QMCSampler ej stöds av installerad Optuna-version.


                  17. NN-trÀning: dataintegritet och anti-leakage


                  Regler som mÄste upprÀtthÄllas för att NN-modellernas val_accuracy ska vara meningsfull:


                  17.1 Temporal split — alltid framĂ„t i tid


                  TrÀningsdata mÄste vara Àldre Àn valideringsdata. Fel att undvika:


                  RiskBeskrivningFix i koden
                  Resample-before-splitrandom.choices() med tidsvikter FÖRE split förstör tidsordningen → val-rader kan lĂ€cka in i trĂ€ningResampla efter split, endast pĂ„ trĂ€ningsdelen (NN_TIME_WEIGHT_HALFLIFE_DAYS)
                  Horizon-overlap (embargo=0)Sista h trĂ€ningsrader har labels frĂ„n LEAD(close, h) som faller i val-fönstretNN_WALKFORWARD_EMBARGO_ROWS ska sĂ€ttas ≄ target-horisont (h=5 för ret_5d, h=20 för ret_20d)
                  Feature/target-kollisionFeature ret_5d (trailing) och target ret_5d (leading) har samma namnEj leakage — SQL-queries skiljer dem korrekt

                  17.2 Scaler — berĂ€knas enbart pĂ„ trĂ€ningsdata


                  mean/std berÀknas pÄ X[:train_cutoff] och appliceras pÄ hela datasetet.

                  min/max berĂ€knas pĂ„ hela datasetet men anvĂ€nds ej för skalning — harmless.


                  17.3 Konfidenskalibrering


                  RÄ softmax-output Àr inte sannolikhet. Kalibrerad konfidens:


                  kalibrerad = val_accuracy × (softmax_max − 1/3) / (2/3)
                  

                  Regressionsmodeller (ret_5d, ret_20d) anvĂ€nder `sigmoid(rv× 10)` för att ge [0–1]-konfidens.

                  17.4 Survivorship bias


                  OOS-simuleringar filtrerar med p.date > nm.train_to (strikt framÄt) för att undvika att trÀna pÄ data som inte fanns vid prediktion.


                  17.5 nn_model_registry — integritet


                  nn_model_registry hÄller champion_model_id per (target, ticker_id). Registret kan komma ur synk med nn_models om modeller rensas ur DB utan att registret uppdateras (t.ex. efter DB-restore eller manuell rensning). Symptom: dashboarden visar nÀstan inga NN-signaler trots att nn_predictions har data.


                  Diagnos:

                  SELECT COUNT(*) FROM nn_model_registry r
                  LEFT JOIN nn_models m ON m.id = r.champion_model_id
                  WHERE r.target = 'signal_3class' AND m.id IS NULL;
                  

                  Korrigering — peka om till bĂ€sta tillgĂ€ngliga modell per ticker:

                  UPDATE nn_model_registry r
                  JOIN (
                    SELECT m.ticker_id, m.id AS best_id, m.val_accuracy
                    FROM nn_models m
                    JOIN (
                      SELECT ticker_id, MAX(train_to) AS max_to
                      FROM nn_models WHERE target = 'signal_3class' GROUP BY ticker_id
                    ) latest ON latest.ticker_id = m.ticker_id AND m.train_to = latest.max_to
                    WHERE m.target = 'signal_3class'
                  ) best ON best.ticker_id = r.ticker_id
                  LEFT JOIN nn_models bad ON bad.id = r.champion_model_id
                  SET r.champion_model_id = best.best_id
                  WHERE r.target = 'signal_3class' AND bad.id IS NULL;
                  

                  NN-jobbet skriver över dessa med korrekt champion allteftersom varje ticker trÀnas klart.


                  18. Tickeruniversum och deduplicering


                  18.1 Struktur


                  Tickers Àr grupperade i scopes via ticker_universe-tabellen:


                  ScopeAntalKĂ€lla
                  OMX3029Nasdaq Stockholm Large Cap-index, de mest omsatta
                  LARGE_CAP305Nasdaq Stockholm Large Cap (inkl. OMX30)
                  MID_CAP142Nasdaq Stockholm Mid Cap (alla 142 finns Àven i LARGE_CAP)

                  Totalt unika tickers: ~305.


                  > OBS (2026-07-27): Scope-uppdelningen anvÀnds inte lÀngre för NN-jobb. nn_all kör pÄ hela universumet utan scope-filter. ticker_universe-tabellen finns kvar för referens och potentiell framtida filtrering.


                  18.2 Bakgrund — varför scope-uppdelningen togs bort


                  Alla 142 MID_CAP-tickers överlappade med LARGE_CAP, vilket innebar att exkluderingslogiken gav 0 tickers för MID_CAP. Scopeuppdelningen ersattes med ett enda nn_all-jobb (2026-07-27). nn_omx30 och nn_mid_cap Àr kvar som alias till nn_all för bakÄtkompatibilitet.


                  19. Investeringshorisonter — webbsida (horisont.php)


                  Sidan /aa/horisont.php presenterar de mÄnadsvisa optimeringarna per investeringshorisont.


                  19.1 Funktion


                  - Radioknappar för att vÀlja horisont: `1m2m6m1y3ycomposite`
                  • Vikttabell (rank-score-komponenter och deras vikt i vald horisont)
                  • Backtest-resultat per horisont (frĂ„n rank_weight_horizons)
                  • Rankinglista — topp-aktier rankade med optimerade vikter för vald horisont
                  • Uppdateras automatiskt 1:a varje mĂ„nad via rank_weight_monthly-cron-jobbet

                  19.2 DB-koppning


                  Sidan lÀser frÄn rank_weight_horizons (horizon_label, horizon_months, weights_json, result_1m, result_2m, result_6m, result_1y, result_3y, composite_score, updated_at).


                  Om inga rader finns ger sidan ett informativt meddelande om att data vÀntar pÄ mÄnadsoptimering.


                  19.3 UnderhÄll


                  submit_job.sh rank_weight_monthly kör fas 7 för 6 horisonter (5 000 Optuna-trials/horisont, QMC Sobol) pÄ bigrig, sedan importerar inbyggt Python-script resultaten till rank_weight_horizons.




                  20. Stateful OOS-simulering (simulate_stateful_oos_signals.py)


                  Strikt out-of-sample simulering med state machine, realistiska stop-losses och ATR-baserade exits.


                  20.1 State machine


                  FLAT → BUY_SIGNAL → LONG → SELL_SIGNAL → FLAT


                  • FLAT: VĂ€ntar pĂ„ köpsignal (NN-konfidens ≄ tröskel)
                  • LONG: HĂ„ller position; ATR trailing stop, weakness-exit vid NN-signal < –0.3
                  • SELL_SIGNAL: VĂ€ntar pĂ„ bekrĂ€ftelse innan exit (anti-whipsaw)

                  20.2 Resultat (2026-07-15, 3 Är OOS)


                  PeriodNN-strategiRegelstrategi
                  1 Är+0.1%+2.0%
                  2 Ă„r–0.5%+1.8%
                  3 Är+20.9%+37.5%

                  Regelstrategin (rankningssignaler + OBV-trend + BB-percentil) övertrÀffar NN i samtliga perioder.


                  20.3 Poolad DB-anslutning


                  db_conn() ersattes med pool_connection() context manager (commit 1bc2f02) för att undvika att parallella simuleringsinstanser pÄ klustret tömmer max_connections.


                  20.4 Full OOS walk-forward via kön


                  shared/bin/submit_job.sh har ny jobtyp oos_walkforward_full som skickar tools/oos_walkforward_full.py --years 3 till kö-systemet med preferens för bigrig. Scriptet har en explicit sys.path-fix sÄ att körning frÄn queue-workern fungerar Àven nÀr arbetskatalogen inte ligger i projektroten.




                  21. Infrastruktur — bigrig-kluster och MariaDB-konfiguration


                  21.1 Bigrig queue-worker som systemd-tjÀnst


                  • Unit: aa-queue-worker@.service (WORKER_TYPE-template)
                  • Instanser per nod:
                  • - bigrig: @cpu (MAX_CONCURRENT_JOBS=6) + @gpu (MAX_CONCURRENT_JOBS=2) = 8 workers totalt

                    - work733: @cpu (MAX_CONCURRENT_JOBS=2) + @gt610 (MAX_CONCURRENT_JOBS=1)

                    - pi: @cpu (MAX_CONCURRENT_JOBS=1)

                  • Worker-script: /shared/bin/queue_worker.sh
                  • WORKER_TYPE-filtrering: gpu-workers tar bara jobb med QUEUE_PREFER: gpu; gt610 tar bara QUEUE_PREFER: gt610; cpu-workers hoppar över gpu/gt610-jobb
                  • Drop-in config: /etc/systemd/system/aa-queue-worker@<type>.service.d/local.conf sĂ€tter MAX_CONCURRENT_JOBS per nod och typ
                  • Loggar: /shared/logs/aktieanalys/queue_worker_<node>_<N>.log

                  Worker-antal (korrigerat 2026-08-09): Äldre dokumentation som nĂ€mnde "12 parallella workers pĂ„ bigrig, 4 pĂ„ work733" Ă€r fel. RĂ€tt antal Ă€r bigrig: 6 cpu + 2 gtx1070, work733: 2 cpu + 1 gt610, raspberrypi: 1 cpu.


                  Ny watchdog: /shared/bin/ensure_workers.sh Àr nu den primÀra övervakaren för worker-processer. Scriptet körs via crontab pÄ alla tre noder (@reboot sleep 60 && ... samt /5 * ...), ersÀtter de gamla direkta systemd-run --user-raderna och sÀkerstÀller exakt rÀtt antal workers per nod/typ. Scriptet dödar workers med okÀnd WORKER_TYPE, tar bort överskott (idle först, sedan nyast startad först) och startar saknade workers. Logg: /shared/logs/aktieanalys/ensure_workers.log.


                  queue_worker.sh-bugg fixad 2026-08-09: I huvudloopen kunde xargs -r grep -l "^# QUEUE_RAN_ON: $NODE" returnera exit-kod 123 nÀr inga trÀffar fanns. Med set -euo pipefail dödade detta workern tyst pÄ noder dÀr running/ innehöll gtx1070-jobb som körde pÄ annan nod. Pipelines som rÀknar körande jobb Àr nu wrappade med `{ ...true; }`, vilket förhindrar dessa falska worker-dödsfall.

                  Viktigt — orphan-recovery-duplicering: Om ett jobb kraschar upprepade gĂ„nger kan orphan-recovery-mekanismen Ă„terköa och starta om det flerfalt, vilket resulterar i att flera workers kör samma jobb parallellt med duplicerat DB-arbete. HĂ„ll koll pĂ„ failed/-katalogen och döda överflödiga processer manuellt vid behov.


                  Viktigt — workers lĂ€ser in script vid start: Bash laddar hela queue_worker.sh vid uppstart. Om scriptet uppdateras pĂ„ NFS mĂ„ste alla noder köra systemctl restart aa-queue-worker@* för att funktionsĂ€ndringar (t.ex. deps_satisfied) ska trĂ€da i kraft. Det rĂ€cker inte att scriptet uppdateras pĂ„ NFS — gamla workers har gammal kod i minnet.


                  21.2 MariaDB persistent konfiguration


                  Ny tuningfil: /etc/mysql/mariadb.conf.d/99-aktieanalys-tuning.cnf


                  [mysqld]
                  max_connections = 300
                  

                  Anledning: Med pipeline + NN-nightly + nn_large_cap + OOS-simulering parallellt nÄddes gamla grÀnsen (100) med ERROR 1040: Too many connections.


                  21.3 MariaDB binary logs — underhĂ„ll


                  • Konfiguration: expire_logs_days=7 i /etc/mysql/mariadb.conf.d/99-aktieanalys-replication.cnf
                  • Varning: Automatisk rensning sker bara medan MariaDB faktiskt kör. Om MariaDB stĂ„r still kan binlogs fortsĂ€tta ackumuleras pĂ„ disk utan att roteras bort.
                  • Manuell rensning vid diskkris:
                  • 1. Stoppa MariaDB

                    2. Kör ls -lh /var/log/mysql/

                    3. Ta bort alla mariadb-bin.* utom de 3 nyaste

                    4. Starta MariaDB igen


                  21.4 QUEUE_OFFLOAD-mekanism


                  update_all.sh accepterar QUEUE_OFFLOAD=1 (satt i cron):


                  • Steg 7 (calculate_signals_py.py) → skickas till bigrig-kön istĂ€llet för att köra lokalt
                  • Steg 12 (morning_signals.py) → skickas till bigrig-kön
                  • Övriga steg kör fortsatt pĂ„ work733 (koordinatormaskin)

                  Submit sker via bash /home/tege/work/python/aa-ai/submit_job.sh <job>.


                  21.5 indicators_backfill-jobb


                  Manuell backfill av daily_indicators för hela tickeruniversumet (308 tickers). Tillades i submit_job.sh 2026-07-18.


                  • Submit: bash submit_job.sh indicators_backfill
                  • QUEUE_PREFER: bigrig
                  • Workers: --workers 1 (generellt, oavsett maskin) — undviker duplicatarbete vid parallella körningar
                  • Logg: /shared/logs/aktieanalys/ind_backfill_YYYYMMDD.log
                  • Koordinatormaskin (work733): kör jobbet enbart som fallback om bigrig ej svarar; work733 ska inte belastas med tung berĂ€kning

                  Bakgrund: Tidigare körde jobbet --workers 4 pĂ„ bigrig, vilket kombinerat med orphan-recovery-duplicering resulterade i 4 parallella instanser × 4 workers = 16 duplicerade tickerberĂ€kningar. Ändrat till --workers 1 generellt (2026-07-18).


                  21.6 Queue-system — preferensordning och PREFER-typer (uppdaterad 2026-08-06)


                  PREFER-typOrdningDelaysJobb
                  bigrigbigrig(0s) → pi(300s) → work733(3600s)PrimĂ€r för GPU/tyngre CPU-jobbnn_nightly, nn_focused, backfill, fft_nightly, ind_backfill, strategy_v3/v4/v5, phase7, refresh_materialized, rank_weight_day, weekend_chain m.fl.
                  bigrig_work733bigrig(0s) → work733(3600s) — pi hoppas alltid avKrĂ€ver x86-venv (pi ARM-inkompatibelt)paper_predict s0–s5 (6 shards)
                  bigrig_onlybigrig(0s) — work733 och pi hopparJobb som enbart ska köra pĂ„ bigrig(reserv — inga aktiva jobb)
                  gt610work733(0s) → bigrig(300s) → pi(600s)OpenCL/GT610calculate_signals, data_pipeline
                  gpubigrig(0s) → pi(60s) → work733(600s)CUDA-exklusiv (legacy)(inga aktiva jobb för tillfĂ€llet)
                  cpubigrig(0s) → pi(30s) → work733(120s)Generisk CPUmorning_signals
                  home733/work733work733(0s) — andra hoppar—data_pipeline (NFS-beroende)

                  paper_predict (2026-08-06): Reducerat frĂ„n 8 till 6 shards (s0–s5) — matchar bigrigs 6 workers för maximal parallellism. PREFER=bigrig_work733 — pi exkluderas permanent (x86-venv ej kompatibelt med ARM), work733 som fallback efter 3600s. s6/s7 borttagna ur submit_job.sh och scheduler.sh.


                  Pi ARM-inkompatibilitet: venv pĂ„ /home/tege/work/python/aa-ai/venv/ Ă€r x86_64 (pĂ„ NFS). Pi nĂ„r den via source venv/bin/activate men binĂ€rerna körs inte pĂ„ ARM → ImportError: numpy trots att pi har numpy 1.19.5 i /usr/lib/python3/dist-packages. Löst med bigrig_work733 (pi hoppar dessa jobb).


                  QUEUE_SUBMITTED-header (fix 2026-08-05): # QUEUE_SUBMITTED: <epoch> injiceras pÄ rad 2 i varje jobbfil av submit_job.sh. deps_satisfied() i queue_worker.sh anvÀnder detta vÀrde (fallback till mtime) för att avgöra om beroenden Àr uppfyllda. PREFER-fördröjnings-Äldern rÀknas fortfarande pÄ mtime (= submissiontid för fÀrska jobb). Fixen löser konflikten dÀr gammal mtime (för Àldre jobb) felaktigt bypasade alla PREFER-delays.


                  QUEUE_STARTED_AT-header (fix 2026-08-06): # QUEUE_STARTED_AT: <epoch> skrivs av workern till jobbfilen i running/ direkt vid pickup — innan mtime-restore (som annars Ă„terstĂ€ller mtime till submission-tid). API:t lĂ€ser detta vĂ€rde som primĂ€r kĂ€lla för "Startad"-kolumnen i jobbkön. Utan QUEUE_STARTED_AT faller api.py tillbaka pĂ„ mtime, vilket ger felaktig tid (= submission-tid).


                  72h-fallback borttagen (fix 2026-08-06): deps_satisfied() anvĂ€nde tidigare `done_epoch >= job_epochdone_epoch >= (now-72h). Det 72h-fallbacket tillĂ€t gĂ„rdagens shards (t.ex. nn_nightly_s1–s5 frĂ„n igĂ„r) att uppfylla dagens koordinators beroenden, vilket fick koordinatorn att starta före alla dagens shards var klara. Fallbacket togs bort — nu gĂ€ller enbart done_epoch >= job_epoch`.

                  • Raspberry Pi (192.168.1.174) kör 1 cpu-worker och hĂ€mtar jobb frĂ„n /shared/queue/
                  • Alla köjobb körs med renice -n 10 + ionice -c2 -n7

                  22. Ändringar 2026-08-09


                  • Diskfull-kris Ă„terstĂ€lld: /var/log/mysql/ innehöll ~133 GB MariaDB binary logs (mariadb-bin.000174–000307). MariaDB stoppades, alla binlogs utom de 3 nyaste raderades och tjĂ€nsten startades om. Diskutrymmet gick frĂ„n 99% (213 GB av 228 GB) till 38%.
                  • WF-trĂ€ning Ă„terstartad: nn_wf_train_s0/nn_wf_train_s1 lades Ă„ter i kön med QUEUE_PREFER: gtx1070 och kör nu pĂ„ bigrig GPU 0+1. Resume-logiken (already_done_predict()) hoppar över redan fĂ€rdiga cykler.
                  - queue_worker.sh-bugg fixad: xargs-pipeline i huvudloopen kunde ge exit-kod 123 nÀr inga QUEUE_RAN_ON-trÀffar fanns, vilket dödade workers tyst under set -euo pipefail. Fixat med `{ ...true; }` runt alla tre berörda pipelines.
                  • Ny watchdog driftsatt: /shared/bin/ensure_workers.sh skapades för att hĂ„lla rĂ€tt worker-antal per nod och typ, med mutex-lĂ„s via mkdir och loggning till /shared/logs/aktieanalys/ensure_workers.log.
                  • Crontabs uppdaterade pĂ„ alla noder: gamla @reboot-rader och tidigare defekt watchdog-logik ersattes med ensure_workers.sh pĂ„ bigrig, work733 och raspberrypi.

                  22. Web-dashboard: förÀndringar och buggfixar (2026-07-18)


                  22.1 Papper.php — redesign


                  Pappershandelssidan omdesignades för att hantera 150+ paper-konton:


                  • Produktion-KPI-kort: Visar enbart PAPER_SWING_SEK och PAPER_DAYTRADING_SEK prominently
                  • A/B-konton: Samlad kollapserbar tabell (konton med A/B/COMPARE i namn)
                  • Experimentkonton: Sökbar/sorterbar kollapserbar tabell, sorterad pĂ„ P&L%
                  • PROD_ACCOUNTS-konstant styr vad som visas i KPI-korten
                  • Buggfixar: LIMIT ?-binding (PDO bindade som strĂ€ng → syntax error), O(nÂČ) P&L-loop → O(n) via $last_snap-lookup, load_open_positions() correlated subquery → derived table JOIN

                  22.2 Morgon.php — batch NN-queries


                  Problem: Sidan visade 0 KÖP / 0 SÄLJ trots att 169/138 signaler fanns i DB.

                  Rotorsak: 12 individuella queries + 6 subqueries mot nn_predictions (35M rader) överskred FPM max_execution_time.


                  Fix (commit c32c806):

                  • Query 1: HĂ€mtar senaste modell per target i EN query (nn_pred_summary JOIN nn_models)
                  • Query 2: HĂ€mtar alla NN-prediktioner för alla targets i EN query med OR-villkor
                  • Query 3: Morgonsignaler utan NN-subqueries
                  • NN-data slĂ„s ihop i PHP via array-lookup ($nn_by_ticker[$tid][$target])

                  22.3 NN.php — timeout-fix


                  Problem: Sidan gav 504 timeout.

                  Rotorsak: SELECT COUNT(*) FROM nn_pred_summary (full table scan) kördes 2× per sidladdning.


                  Fix (commit c32c806):

                  • BĂ„da COUNT(*)-anropen ersatta: alltid nn_pred_summary JOIN nn_models utan COUNT-kontroll
                  • Fallback-path till direkt scan pĂ„ nn_predictions (35M rader) borttagen

                  22.4 Backtest.php — flik-persistens


                  Problem: Fliken hoppade tillbaka till "StrategijÀmförelse" vid varje formulÀrsubmit.

                  Fix (commit c32c806):

                  • <input type="hidden" name="tab" value="..."> pĂ„ alla 3 formulĂ€r
                  • JS-aktivering via json_encode($active_tab) frĂ„n PHP istĂ€llet för URL-hash

                  22.5 Rapport.php — signalfixar


                  • load_signal_summary() anvĂ€nde CURDATE() som datum → alltid 0 signaler; Ă€ndrat till MAX(date) FROM daily_signals

                  22.6 Inkluderade filer — db.php


                  • PDO::ATTR_TIMEOUT ersatt med PDO::MYSQL_ATTR_CONNECT_TIMEOUT (med defined()-guard för PHP-miljöer utan pdo_mysql i CLI)
                  • rollBack() lades till i alla catch-block för att rensa persistenta PDO-anslutningar

                  22.7 aktie.php — Pris & volym-graf (commit 19b4674)


                  • "Pris & volym"-grafen filtrerar nu bort isolerade sĂ€ljsignaler som saknar föregĂ„ende köp
                  • filtreringen anvĂ€nder stateful direction tracking sĂ„ att signalvĂ€xlingarna blir visuellt konsekventa
                  • ultimate_sell visas alltid Ă€ven om ingen föregĂ„ende köpmarkering finns



                  23. DB-underhÄll och indexstrategi (2026-07-18)


                  23.1 Utförd cleanup


                  ÅtgĂ€rdEffekt
                  nn_weights: Raderade 61 000 rader för gamla modeller (behÄller 2 per target)~22 GB frigjorda
                  nn_pred_summary: Raderade 14 750 rader för gamla modellerSnabba PK-lookups, inga fler full-scans
                  Droppade 5 redundanta tabellerSe §23.2
                  Droppade 3 redundanta indexSe §23.3

                  Modeller som behölls per target (2 senaste med prediktioner):


                  TargetBehÄllna model_id
                  prob_up_1d16006, 16005
                  prob_up_2d16010, 16009
                  prob_up_3d16007, 16002
                  prob_up_4d16011, 16004
                  prob_up_5d16008, 15987
                  ret_20d16001, 16000
                  ret_5d15997, 15996
                  signal_3class15992, 15990

                  23.2 Droppade tabeller


                  TabellAnledning
                  fundamental_data0 rader; ersatt av daily_fundamentals + daily_fundamentals_asof
                  nn_training_log0 rader; ersatt av nn_training_epochs
                  ticker_universe_backup_20260715TemporÀr backup frÄn universumrensningen 2026-07-15
                  paper_ab_reports0 rader; aldrig populerad i produktion
                  dashboard_indicators_cache0 rader; tidigare dashboard-cache, nu avvecklad

                  BehÄllna tomma tabeller (planerad anvÀndning):

                  live_orders, live_positions, trading_capital, trading_audit_log, order_book_snapshots — behövs nĂ€r livehandel aktiveras.


                  23.3 Droppade redundanta index


                  TabellBorttaget indexBehÄllet överlappande index
                  nn_predictionsidx_nn_pred_ticker_model_dateidx_model_date_ticker (PRIMARY + detta rÀcker)
                  nn_predictionsidx_model_ticker_dateidx_model_date_ticker
                  daily_pricesidx_daily_prices_ticker_dateunique_ticker_date(ticker_id, date) tÀcker samma
                  daily_signalsidx_ticker_dateunique_ticker_date(ticker_id, date) tÀcker samma

                  23.4 nn_predictions — planerad cleanup


                  35M rader i nn_predictions; ca 33M rader tillhör modeller som nu Àr rensade ur nn_weights och nn_pred_summary. Cleanup via batch-DELETE (50k/batch, 2s paus) schemalÀggs utanför bigrig-trÀningsfönster (kör ej nÀr bigrig neural_network.py-processer Àr aktiva) för att undvika metadata lock-konflikter som blockerar trÀningsjobb.


                  Verktyg (tillagt 2026-07-18):

                  • run_nn_pred_cleanup.sh — vĂ€ntar automatiskt pĂ„ bigrig-idle, kör sedan tools/db_housekeeping.py --cleanup-nn-old-models --apply + OPTIMIZE TABLE
                  • submit_job.sh nn_pred_cleanup — köar jobbet via queue-systemet (kör pĂ„ work733, vĂ€ntar pĂ„ bigrig)
                  • tools/db_housekeeping.py --cleanup-nn-old-models — ny flagga för batch-rensning av predictions för borttagna modeller

                  23.5 nn_predictions — indexjustering (2026-07-24)


                  Det nyligen tillagda indexet idx_np_ticker_date (ticker_id, date) Àr nu droppat. Det tÀcktes redan funktionellt av PRIMARY KEY (ticker_id, date, model_id) och frigjorde cirka 700 MB utan att ta bort nödvÀndig ÄtkomstvÀg.




                  24. Webbinfrastruktur — nginx, PHP och API (2026-07-18)


                  24.1 Arkitekturöversikt


                  Internet
                    │
                    ▌
                  Router (port-forward 443 → 192.168.1.72:443)
                    │
                    ▌
                  iptables DNAT pÄ work733 (192.168.1.72)
                    │  443 → 192.168.100.83:443
                    ▌
                  nginx pĂ„ VM (192.168.100.83) — Let's Encrypt cert (tegelwall.duckdns.org)
                    ├── /aa/          → php7.4-fpm pĂ„ VM (PHP-dashboard)
                    └── /api/         → proxy → work733:8000  (REST-API)
                  

                  24.2 VM (192.168.100.83)


                  KomponentVersionDetaljer
                  OSDebian 11debian11-vm-733
                  nginxsystemd-tjÀnstLet's Encrypt, tegelwall.duckdns.org
                  php-fpmPHP 7.4.33 (php7.4-fpm.service)FastCGI via unix-socket /var/run/php/php7.4-fpm.sock

                  Aktiv nginx-konfig: /etc/nginx/conf.d/vm733.conf (laddas via nginx.conf → conf.d/*.conf).


                  PHP-filer: /var/www/html/aktieanalys/ pÄ VM:n.


                  24.3 PHP-dashboard (/aa/)


                  URL: https://tegelwall.duckdns.org/aa/


                  Filer pÄ VM /var/www/html/aktieanalys/:


                  FilFunktion
                  index.phpStartsida — aktietabell med signaler
                  aktie.phpDetaljsida per ticker (inkl. lÀnk till indikatoröversikt)
                  indikatorer.phpIndikatoröversikt per ticker — alla indikatorer med KÖP/AVVAKTA/SÄLJ + summering (tillagd 2026-08-02)
                  morgon.phpMorgonsignaler + NN-prediktioner
                  backtest.phpBacktestresultat och strategijÀmförelse
                  nn.phpNN-modeller, per-ticker prob_up-signaler (1d–5d) och signal_3class (prob_val-fix 2026-08-02)
                  papper.phpPaper trading — produktion + experiment
                  signaler.phpSignalöversikt
                  rapport.phpDaglig go/no-go-rapport
                  makro.phpMakrodata — rĂ€ntor, spread, KPIF, regimindikator, sektoröversikt, period-slider (2026-08-03)
                  hjalp.phpHjÀlpsida
                  db.phpPDO-databasanslutning (inkluderas av alla sidor)
                  includes/layout.phpGemensam header/footer (redigeras hÀr, inte i layout.php i rooten)
                  includes/Delade komponenter (config, db, layout)
                  assets/CSS, JS
                  api/Interna API-endpoints (se nedan)

                  PHP ansluter direkt till MariaDB pÄ 192.168.1.72 (work733). active_weights*.json lÀses ocksÄ av PHP-dashboarden som presentationsartefakter frÄn rank-weight-pipelinen.


                  Interna PHP API-endpoints (/aa/api/)


                  EndpointBeskrivningNyckeldata
                  macro_data.phpAll makrohistorik sedan 1987dates, repo_rate, rate_10y, kpif_yoy, spread, last_known, regime_changes
                  sector_data.phpSektorbredd — RSI, signaler, avkastningsectors[], as_of

                  macro_data.php — detaljer (uppdaterad 2026-08-03):

                  • Returnerar all tillgĂ€nglig data (ej begrĂ€nsad till 10 Ă„r) — anvĂ€nds av range-slider i makro.php
                  • last_known: sista icke-null-vĂ€rde per serie med datum — hanterar att KPIF Ă€r mĂ„nadsvis och att sista börsdagen ibland saknar 10Y
                  • regime_changes: konjunkturcykelbyten (spread byter tecken), filtrerade med 30-dagars minimivaraktighet + deduplicerade — ger ca 14 signifikanta förĂ€ndringar sedan 1987

                  24.3b Makro-sidan (makro.php) — implementeringsdetaljer


                  Chart.js-plugins registrerade globalt:

                  • regimePlugin (id: 'regimeLines') — ritar lodrĂ€ta linjer vid konjunkturcykelbyten via afterDatasetsDraw
                  • threshPlugin (id: 'thresholdLines') — ritar horisontella streckade linjer för recession/expansion-tröskel (−0.5 % / +0.5 %) via afterDraw

                  Range-slider (dubbel handtag):

                  • TvĂ„ <input type="range"> staplade ovanpĂ„ varandra med CSS (position: absolute, pointer-events: none pĂ„ track, pointer-events: all pĂ„ tummen via ::-webkit-slider-thumb)
                  • .rs-fill-div uppdateras med left/width i procent för att visa vald period
                  • Slider-vĂ€rden Ă€r index in i dates-arrayen — vid Ă€ndring sĂ€tts chart.options.scales.x.min/max och chart.update('none') (ingen animation)
                  • Period-knappar (1Y/3Y/5Y/10Y/Max) sĂ€tter slider-vĂ€rden via findIndex pĂ„ datumarrayer

                  DatahÀmtning: Parallel Promise.all([macro_data.php, sector_data.php]) vid sidladdning.


                  24.4 REST-API och systemstatussida (/api/, /aa/status)


                  FastAPI/uvicorn kör pÄ work733 port 8000. Nginx proxar:

                  • /api/ → http://192.168.1.72:8000/
                  • /aa/status → http://192.168.1.72:8000/aa/status

                  Systemstatussida


                  URL: https://tegelwall.duckdns.org/aa/status


                  Sidan uppdateras automatiskt var 30:e sekund och visar:


                  SektionInnehÄll
                  🔐 SessionsNordnet + Avanza login-status, BankID-knapp för förnyelse
                  đŸ©ș Externa datakĂ€llorapi_health för Avanza, Yahoo, makro och browser-session; visar ok/warn/error, senaste fel och fail-rĂ€knare
                  ⚙ ProcesserStatus för browser_session_daemon, FastAPI, paper daytrading, evening chain
                  đŸ’Ÿ RAID-statusRAID-array-hĂ€lsa (work733 /proc/mdstat)
                  📋 JobbköSlurm-jobb — pending/running/failed/done via squeue + sacct; visar jobbnamn, Slurm-ID, partition, nod och tid
                  📄 Senaste loggarDe 15 senaste loggfilerna i /var/log/aktieanalys/ med storlek och Ă€ndringsdatum

                  Jobbkö-implementering: api.py::_get_queue_status() kör squeue --format för aktiva jobb och sacct (24h bakÄt) för avklarade/misslyckade. Timeout 5s per anrop.


                  Åtkomst internt: http://192.168.1.72:8000/aa/status (utan TLS).


                  24.5 Intern Ätkomst (utan VPN/internet)


                  PHP-dashboarden kan ocksÄ nÄs direkt pÄ https://192.168.100.83/aa/ via det interna nÀtverket (self-signed cert, serveras av nginx default-server-block för 192.168.100.83).


                  24.6 TLS-certifikat


                  CertAnvÀnds förSökvÀg
                  Let's Encrypttegelwall.duckdns.org (extern)/etc/letsencrypt/live/tegelwall.duckdns.org/
                  Self-signed192.168.100.83 / localhost (intern)/etc/ssl/localcerts/vm733.{crt,key}



                  25. InfrastrukturförÀndringar 2026-07-21/22


                  25.1 Kluster — Raspberry Pi som Slurm-nod


                  Raspberry Pi (192.168.1.174, armhf 32-bit userspace, aarch64 kernel) Àr nu aktiv Slurm-nod.


                  Problem: Pi hade Slurm 20.11.4 (apt) men cluster kör 23.11.4 → NOT_RESPONDING.

                  Lösning: Kompilerat Slurm 23.11.4 frÄn kÀllkod pÄ Pi med --enable-deprecated (krÀvs för 32-bit).


                  ./configure --enable-deprecated --prefix=/usr/local --sysconfdir=/etc/slurm --with-munge
                  make -j4 && sudo make install
                  

                  systemd-override (/etc/systemd/system/slurmd.service.d/override.conf) pekar pÄ /usr/local/sbin/slurmd.


                  Pi Àr aktiv i partitionerna debug och pi. Slurm-nod: raspberrypi, status idle.


                  25.2 VM (debian12) — Ă„tgĂ€rdat efter omstart


                  VM:n startade inte automatiskt efter host-reboot. ÅtgĂ€rder:


                  ÅtgĂ€rdDetalj
                  virsh autostart debian12VM autostarter nu vid host-reboot
                  VM RAMSĂ€nkt frĂ„n 2 GB → 800 MB (tillrĂ€ckligt för nginx + php-fpm)
                  Custom kernel5.10.259-work733-work733 installerad (Äterskapad frÄn /shared/linux-image-5.10.259-work733-work733_5.10.259-work733-1_amd64.deb)
                  GUI-paket rensadegdm3, cups, avahi, bluez, gnome m.fl. avinstallerade — VM Ă€r terminal-only
                  Kernel-deb sparad/shared/linux-image-5.10.259-work733-work733_5.10.259-work733-1_amd64.deb

                  BrandvĂ€gg: iptables-regel saknade port 3306 frĂ„n VM (192.168.100.83) → PHP kunde inte nĂ„ MariaDB. Lagts till och sparats persistent:

                  iptables -I INPUT -s 192.168.100.83 -p tcp --dport 3306 -j ACCEPT
                  iptables-save > /etc/iptables/rules.v4
                  

                  Web-filer: PHP-filerna synkas med deploy_web.sh (rotmapp i projektet) via rsync frĂ„n /mnt/raid/tege/work/python/aa-ai/web/aktieanalys/ → VM /var/www/html/aa/. config.php laddar nu DB-lösenord frĂ„n gitignorerad web/aktieanalys/includes/db_secret.php, som genereras pĂ„ VM:n av deploy_web.sh via printf och sĂ€tts till lĂ€ge 0644. KrĂ€ver att rsync Ă€r installerat pĂ„ VM (installerat 2026-08-02: sudo apt install rsync). Filer i web/aktieanalys/includes/ innehĂ„ller delade funktioner (config, db, layout). Deploy-skript: deploy_web.sh. nginx-konfig versionshanteras: vm/nginx/vm733.conf.


                  nginx-konfig: Aktiv konfig finns i /etc/nginx/conf.d/vm733.conf pÄ VM:n (inte sites-enabled/). PHP-block för /aa/ lagts till manuellt efter att sidan saknades.


                  25.3 MariaDB — stabilisering


                  ProblemRotorsakÅtgĂ€rd
                  innodb_buffer_pool_size 512 MB trots 2 GB i configapply_system_profile.sh satte DAY_BP=512MB dynamiskt via SET GLOBALHöjt till 2 GB i bÄde DAY och TRAIN-profil (commit 645a892)
                  Lost connection vid calculate_signalsALTER TABLE pĂ„ 35 GB + GPU-bulk INSERT → I/O-kaos spinning diskcalculate_signals vĂ€ntar nu pĂ„ ALTER TABLE (submit_job.sh, commit 7a72963)
                  nn_weights 35 GB LONGTEXTweights_json/biases_json som text → omöjligt att cachaALTER TABLE → nullable + blob-migration pĂ„gĂ„r (zlib+float32 → ~3 GB)
                  Lock wait timeout exceeded (paper_predict)innodb_lock_wait_timeout=50 för kort vid parallella INSERT ON DUPLICATE KEY i nn_predictionsHöjt till 120s i /etc/mysql/mariadb.conf.d/99-aktieanalys-timeouts.cnf (2026-08-02)
                  Lost connection via SSCursor fetchmanynet_read_timeout=600 för kort vid stor streaming-query under predictHöjt till 900s i 99-aktieanalys-timeouts.cnf (2026-08-02)

                  Buffer pool: innodb_buffer_pool_size = 2G i /etc/mysql/mariadb.conf.d/99-aktieanalys-tuning.cnf och nu Àven korrekt i apply_system_profile.sh.


                  25.4 DB-index (2026-07-22)


                  Tillagda index (appliceras efter ALTER TABLE nn_weights):


                  TabellIndexSyfte
                  daily_signalsidx_ds_date_strength(date, signal_strength)Eliminerar filesort i signalsida ORDER BY
                  daily_signalsidx_ds_date_ultimate(date, ultimate_buy, ultimate_sell)TĂ€cker ultimate-signal queries
                  nn_predictionsidx_np_ticker_date(ticker_id, date)Snabb hÀmtning per ticker

                  > Uppdatering 2026-07-24: idx_np_ticker_date togs senare bort igen nÀr det bekrÀftades att PRIMARY KEY (ticker_id, date, model_id) redan tÀckte behovet. Utrymmesvinst: ~700 MB.


                  25.5 Kodfixar (commit 7a72963)


                  PrioritetFix
                  KRITISKcalculate_signals_py.py: GPU-bulk streamar med SSDictCursor, 1.2M rader laddas inte lÀngre i RAM
                  HÖGdb_pool.py: POOL_PREWARM 10→1 som default
                  HÖGnn_pytorch_trainer.py: validering batchvis (val-set laddades till GPU i ett block)
                  HÖGpaper_trading_sim.py: race condition i get_or_create_account() → UPSERT
                  MEDIUMCursor/connection-lÀckor i calculate_signals_py.py och tools/migrate_nn_weights_to_blob.py

                  26. InfrastrukturförÀndringar 2026-07-22 (session 2)


                  26.1 NN-vikter migrerade till disk (npz-filer)


                  Problem: nn_weights-tabellen innehöll 35 GB LONGTEXT (weights_json) + BLOB. load_model() lÀste

                  ~1 MB JSON per modell → 20 117 modeller × 73 s/modell = 6+ timmar per nattlig inferensrunda →

                  paper trading hade 0 trades sedan 2026-07-06.


                  Lösning: Vikterna sparas som numpy .npz-filer pÄ disk i /shared/models/nn_weights/{model_id}.npz.


                  EgenskapJSON (gammalt)npz (nytt)
                  Storlek/modell~1 MB~180 KB (5,9× komprimering)
                  Laddningstid73 s (DB-round-trip)<1 ms (mmap frÄn disk)
                  FormatJSON textfloat32 numpy-arrays W0,b0,W1,b1,


                  Implementering (neural_network.py):

                  • _NN_WEIGHTS_DIR (env NN_WEIGHTS_DIR, default /shared/models/nn_weights)
                  • _weights_path(model_id) — returnerar sökvĂ€g till .npz
                  • _save_weights_file(model_id, layers) — sparar som komprimerat npz
                  • _load_weights_file(model_id) — laddar, returnerar lager-dict
                  • load_model() — filprioritet: fil → DB blob → DB JSON (fallback)
                  • save_model() — sparar npz + bara metadata (n_in, n_out) i DB, inga vikter

                  DB-schemaÀndring: ALTER TABLE nn_weights gjort weights_json LONGTEXT NULL och

                  biases_json TEXT NULL (kör 2026-07-22 ~08:13 → ~11:10). Commit: 709f908.


                  Migreringsverktyg:

                  • tools/migrate_nn_weights_to_files.py --apply — batch-migrerar DB→npz, Ă„terupptagbar
                  • tools/cleanup_nn_weights_columns.py --apply — verifierar 100% tĂ€ckning, DROPpar viktskolumner

                  Status (uppdaterad 2026-08-16): Migreringen Ă€r helt klar. nn_weights truncerades 2026-08-15 och frigjorde 10.92 GB. Tabellen Ă€r nu ~0.1 MB / 1 236 rader och innehĂ„ller noll rader med weights_json — alla vikter ligger i NPZ-filer (~45 000 filer, ca 16 GB under /shared/models/nn_weights/). nn_weights_wf (~6.5 GB, 93 073 rader) hanteras separat och behĂ„ller sina metadatarader; WF-vikter skrivs likasĂ„ till NPZ (nn_models_wf_{id}.npz).


                  TillfÀllig fix (historik): PAPER_NN_PER_TICKER=0 i .env anvÀndes under migreringen (global modell = 6 inferenser i stÀllet för 1 848). Den Àr ÄterstÀlld till per-ticker-lÀge.



                  26.2 VM-disk sparsifiering


                  virsh destroy debian12
                  virt-sparsify --in-place /mnt/raid/tege/vms/debian12/vm1.qcow2
                  virsh start debian12
                  

                  Resultat: ls -lh 87 GB (virtuell storlek, oförĂ€ndrad) / du -sh 43 GB (faktisk disk = −44 GB).

                  virt-sparsify --in-place hĂ„lgĂ€ller (punches holes) — ls visar alltid virtuell storlek.


                  26.3 Housekeeping-komplettering (commit aebeae3)


                  tools/db_housekeeping.py utökad med:

                  • cleanup_orphan_npz_files() — tar bort .npz vars model_id inte finns i nn_models
                  • cleanup_stateful_oos_json() — tar bort gamla JSON-statusfiler för OOS-simuleringar
                  • cleanup_nn_weights_keep_n() — raderar nu Ă€ven .npz nĂ€r en modell tas bort frĂ„n DB
                  • OPTIMIZE TABLE körs nu Ă€ven nĂ€r DATA_FREE > 500 MB, Ă€ven om inget just raderades i samma pass

                  Intraday-retention: 90 → 210 dagar (commit cba7d81). Minst 6–7 mĂ„naders intraday-data

                  krÀvs för att NN-modeller för daytrading ska tÀcka tillrÀckligt med marknadsregimer.


                  /etc/logrotate.d/aktieanalys pÄ work733 tÀcker nu Àven:

                  gen_oos_worker_, wait_oos_, oos_walkforward_, oos_walkforward_full_,

                  nn_calibration_oos_, nn_conf_sweep_, nn_regime_oos_, nn_ensemble_oos_,

                  nn_pred_cleanup_, nn_rolling_, intraday_fetch_, ind_backfill_,

                  calculate_signals_rerun_, historical_training_rerun, sim_swing_*,

                  rank_weight_monthly_, rw_full_, migrate_nn_weights_, housekeeping_.txt,

                  requeue_watch, nn_resource_kills, nn_weights_reclaim_*.


                  26.4 Pi — logrotation installerad


                  /etc/logrotate.d/aktieanalys skapad pÄ Raspberry Pi (192.168.1.174).

                  OBS: /shared/ Ă€r NFS-monterat frĂ„n work733 — roteras inte pĂ„ Pi för att undvika dubbel-rotation.

                  Pi-lokala loggar som tÀcks:

                  • /home/tege/work/python/aa-ai/*.log (signal_executor, nordnet_trader m.fl.) — daily, rotate 14, copytruncate
                  • /home/tege/work/python/aa-ai/logs/*.log — weekly, rotate 8
                  • /var/log/slurm/*.log — weekly, rotate 8 (för framtida Slurm-loggar)

                  26.5 DB-stĂ€dning — orphan nn_predictions


                  tools/db_housekeeping.py --apply --cleanup-nn-old-models kördes 2026-07-22 ~11:31.

                  Raderar nn_predictions-rader för modeller som inte lÀngre finns i nn_models

                  (uppskattad volym: ~28 M rader / ~2,5 GB). Körs i batchar om 50 000 rader med 2 s paus.


                  26.6 MariaDB — innodb_io_capacity sĂ€nkt för spinning disk


                  Problem: MariaDB kraschade upprepade gÄnger (~var 45:e minut) under NPZ-migrationen.

                  Rotorsak: innodb_io_capacity=800 i 99-aktieanalys-tuning.cnf Àr alldeles för högt för

                  spinning disk RAID (rekommenderat: 200 IOPS). Bakgrundsflushing konkurrerade med

                  migrationens stora lÀsningar frÄn 35 GB nn_weights-tabellen.


                  Fix (dynamisk, 2026-07-22):

                  SET GLOBAL innodb_io_capacity = 200;
                  SET GLOBAL innodb_io_capacity_max = 400;
                  

                  Konfig (krÀver manuell sudo):

                  sudo cp /tmp/tuning_new.cnf /etc/mysql/mariadb.conf.d/99-aktieanalys-tuning.cnf
                  

                  InnehÄll: innodb_io_capacity = 200, innodb_io_capacity_max = 400.


                  Konfig-filen har ocksÄ 60-performance.cnf (innodb_io_capacity=600) som override:as av

                  99-aktieanalys-tuning.cnf (laddas sist). BÄda filer bör uppdateras för konsistens.


                  26.7 OOS 3-Ă„r simulering — triggad manuellt 2026-07-22


                  bigrig fÀrdigstÀllde OOS-prediktioner för 67 walk-forward-modeller kl 15:28.

                  stateful_oos-jobbet skickades till kön kl 16:41 och körs pÄ bigrig:


                  simulate_stateful_oos_signals.py --years 1,2,3 --universe ALL
                  --out-json /shared/logs/aktieanalys/stateful_oos_20260722.json
                  

                  Resultatet finns i /shared/logs/aktieanalys/stateful_oos_20260722.json nÀr det Àr klart.




                  27. Ändringar 2026-07-26


                  Senast uppdaterad: 2026-07-26


                  27.1 Kodinspektionsresultat (deep review)


                  FullstÀndig genomgÄng av api.py, neural_network.py, paper_trading_sim.py, calculate_signals_py.py, browser_session_daemon.py, db_pool.py. Viktigaste fynden:


                  FilRadKategoriAllvarStatus
                  calculate_signals_py.py44TREND_GATE=0 → falskt köp i nedtrendHÖGFIXAD
                  calculate_signals_py.py451-452buy_score floor 42 utan trendcheckHÖGFIXAD
                  aktie.php208a.name → a.account_name SQL-felHÖGFIXAD
                  api.py619+626write_text() ej atomisk för cookies/sessionMEDELFIXAD
                  paper_trading_sim.py1350-1394autocommit-race kring SELECT FOR UPDATEKRITISKÖppen
                  neural_network.py3802-4162DB-connection hĂ„lls öppen hela trĂ€ningHÖGÖppen
                  neural_network.py2532-2555deferred_rows.extend(part) peak-RAMHÖGÖppen

                  db_pool-kö: Befintlig semaforen rÀcker. En extra work-queue hjÀlper inte mellan subprocesser (calculate_signals, neural_network körs som separata processer). Rekommendation: minska DB_POOL_SIZE vid hög last istÀllet.


                  27.2 CAT-A.ST frozen buy-signal — rotorsak och fix


                  Rotorsak: broad_oversold_range (adx<22, rsi<50, stoch_k<35) aktiverades 2026-07-06 och forcerade buy_score = max(buy_score, 42.0) varje dag. Eftersom TREND_GATE=0 (av) tillÀmpades ingen MA-baserad broms trots att sma20 < sma50 < sma200.


                  Fix (commit 2950f3d):

                  1. TREND_GATE default: 0 → 1 (sma20<sma50 → buy_score=0)
                  2. buy_score-floor pÄ rad 452 backas nu av not (sma20 < sma50) guard

                  3. Kör calculate_signals om för att rÀkna om alla signaler med ny logik.


                    27.3 Logrotation och housekeeping — alla maskiner


                    MaskinStatusÅtgĂ€rd
                    work733✅ FullstĂ€ndig /etc/logrotate.d/aktieanalys—
                    bigrig✅ Skapad 2026-08-05—
                    VM (192.168.100.83)✅ nginx daily 14d + aktieanalys weekly—
                    Pi (192.168.1.174)✅ ÅtgĂ€rdat idagSe nedan

                    Pi — systemd journal 1.5 GB stĂ€dad:

                    sudo sed -i 's/^#*SystemMaxUse=.*/SystemMaxUse=200M/' /etc/systemd/journald.conf
                    sudo journalctl --vacuum-size=200M   # frigjorde 1.2 GB
                    

                    /etc/systemd/journald.conf innehÄller nu SystemMaxUse=200M.


                    housekeeping_host.sh utökat med:

                    • playwright_chromiumdev_profile-* i /tmp Ă€ldre Ă€n 2 dagar rensas
                    • /tmp/bankid_debug/ Ă€ldre Ă€n 3 dagar rensas

                    27.4 Aktie-dashboard grafförbÀttringar (commit d879522)


                    • MACD + Signal integrerade i prisgrafen som yMacd-axel (höger). Eliminerar x-axel-förskjutning helt (samma canvas/labels).
                    • RSI(14) Ă„terinförd som separat mini-chart under prisgrafen med referenslinjer vid 30 (översĂ„ld) och 70 (överköpt). Synkas med tidsvĂ€ljaren.

                    27.5 BankID-session cookies — atomisk write (commit 2950f3d)


                    api.py skriver nu .nordnet_cookies och nordnet_session.json via tempfil + os.replace() för att eliminera transient JSON-korruption vid lÀsning frÄn browser_session_daemon.


                    27.6 Walk-forward OOS — körschema


                    Söndagskörning (02:00) ska köra oos_walkforward_blankslate. Senaste lyckade körning: 2026-07-22. Kontrollera att queue_worker Àr aktiv inför kommande söndagar.


                    27.7 Kvarvarande öppna punkter


                    • paper_trading_sim.py: Explicit transaktion (autocommit=False + conn.begin() wrappa hela read-modify-write) för att eliminera race vid parallella körningar
                    • neural_network.py: StĂ€ng DB-connection efter dataladdning, öppna kortlivade connections för epoch-logging
                    • neural_network.py: Chunka deferred_rows/prepared-ackumulering för att minska peak-RAM
                    • calculate_signals: Kör om för att uppdatera alla tickers med TREND_GATE=1
                    • calculate_signals_py.py: Eliminera subprocess-per-ticker (~308 Python-omstarter); ersĂ€tt med shard-baserad in-process-körning eller --gpu-bulk

                    27.8 Ytterligare fixar 2026-07-26 (session 2)


                    paper_trading_sim.py — atomisk transaktion (commit 8c99781):

                    Hela main trade-loopen wrappas nu i conn.begin() 
 conn.commit() med rollback() vid fel.

                    Tidigare: varje open_position + log_order auto-committades separat (autocommit=True frÄn pool).

                    Risk eliminerad: position öppnad men cash ej uppdaterat vid krasch.


                    calculate_signals — TREND_GATE ej tillĂ€mpat pĂ„ existerande signaler:

                    --missing-flaggan i submit_job.sh skippar tickers som redan har signal för senaste handelsdagen.

                    CAT-A.ST kördes manuellt utan --missing → signal korrekt: buy_signal=0, signal_strength=0.00.

                    TREND_GATE=1 Àr nu default men pÄverkar bara nyberÀknade/uppdaterade signaler.


                    Öppet: NN DB-connection pool-starvation:

                    neural_network.py hÄller en lease_connection() öppen under hela trÀningen per target

                    (kan vara 30+ min). Med 15 pool-platser och parallella ticker-workers kan poolen ta slut.

                    Rekommenderad fix: stÀng connection efter dataladdning, öppna kortlivade connections för

                    epoch-logging. Ej akut eftersom NN körs seriellt per nod (file-mutex + subprocess).


                    27.9 SystemunderhÄll och kodfixar 2026-07-28 (session 3)


                    Pipeline-förenkling: nn_all


                    nn_omx30, nn_large_cap, nn_mid_cap ersatta av ett enda nn_all-jobb utan scope-filter.

                    • Rotorsak: alla 142 MID_CAP-tickers finns Ă€ven i LARGE_CAP → exkluderingslogik → 0 tickers → alla MID_CAP-jobb misslyckades
                    • scheduler.sh uppdaterad: nn_omx30 → nn_large_cap → nn_mid_cap → nn_all; nn_focused beror nu pĂ„ nn_all
                    • submit_job.sh uppdaterad: nn_omx30/nn_mid_cap kvar som alias till nn_all (bakĂ„tkompatibilitet)
                    • rank_weight_monthly formellt tillagd i submit_job.sh (fanns bara som ad-hoc-jobb)

                    Prioritering: alle berÀkningsjobb niceade


                    Samtliga tyngre jobb i submit_job.sh kör nu med ionice -c2 -n7 nice -n 10:

                    nn_nightly, nn_focused, backfill, fft_nightly, weekend_chain, data_pipeline, morning_signals, rank_weight_day, refresh_materialized


                    Logrotation — komplett pĂ„ alla maskiner


                    MaskinStatusDetaljer
                    work733✅ /etc/logrotate.d/aktieanalysTĂ€cker /var/log/aktieanalys/ (rank_weight-underdir + alla loggtyper) + /shared/logs/aktieanalys/
                    bigrig✅ Skapad 2026-08-05.log i aa-ai/ + /tmp/queue_worker_bigrig_.log
                    VM (192.168.100.83)✅ journald kappadSystemMaxUse=500M i /etc/systemd/journald.conf; systemctl restart systemd-journald + vacuum
                    Pi (192.168.1.174)✅ (tidigare session)daily rotate 14 för *.log i /home/tege/work/python/aa-ai/

                    XFCE-notifikationer maskade


                    systemctl --user mask xfce4-notifyd.service — eliminerar cannot open display: :1-fel som uppstod nattetid.


                    backfill_source-kolonn


                    rank_weight_history.backfill_source VARCHAR(40) DEFAULT 'weekly' tillagd. Backfill-jobb loggar nu ursprung.


                    Kodfixar (kod-granskning av extern AI)


                    morning_signals.py:

                    • Lokal _LeasedPoolConnection-klass borttagen — anvĂ€nde pool_connection() direkt och saknade RecursionError-skyddet i db_pool.py. Ersatt med from db_pool import LeasedPoolConnection
                    • conn.close() borttagen ur try-blocket (anropades dubbelt — var i both try och finally). StĂ€ngs nu bara i finally (cursor → conn)
                    • backtest_results-frĂ„gan filtrerar nu pĂ„ WHERE symbol IN (...) baserat pĂ„ aktuella rader — eliminerar full table scan (~alla historiska tickers)

                    neural_network.py:

                    • _upd-cursor i predict_all wrappas nu som with write_conn.cursor() as _upd: — garanterar att cursor stĂ€ngs Ă€ven vid exception

                    28. Infrastruktur- och pipeline-förÀndringar 2026-07-29


                    Senast uppdaterad: 2026-07-29


                    28.1 Avanza som primÀr datakÀlla (commit 03852b9)


                    update_all.sh omstrukturerat: Avanza primÀr, Yahoo fallback.


                    StegKĂ€llaKommentar
                    1avanza_update_prices.pyHÀmtar 5 Är för alla ~306 Avanza-mappade tickers
                    2fetch_yahoo_history.py --skip-avanza-mappedFyller bara tickers som saknar Avanza-mappning (~2 st)
                    2bvalidate_prices.py + avanza_update_prices.py --fix-frozenValiderar och ersÀtter fryst data

                    fetch_yahoo_history.py laddar avanza_ticker_map.json och hoppar över mappade tickers nÀr --skip-avanza-mapped Àr satt.


                    28.2 Scheduler och pipeline-beroenden fixade (commit 9e535e9)


                    Problemet: morning_signals enqueudes av scheduler sĂ„ snart calculate_signals var klart — men QUEUE_DEPENDS: nn_nightly i submit_job.sh höll den i kön tills nn_nightly ocksĂ„ var klart. Scheduler-kommentaren stĂ€mde inte med verkligheten.


                    Fix:

                    • scheduler.sh: morning_signals enqueuas nu bara om BÅDE calculate_signals och nn_nightly har status done
                    • Kommentaren i scheduler.sh visar nu korrekt beroendegraf

                    Korrekt pipeline-ordning (vardag):

                    data_pipeline (work733)
                      ├─ fft_nightly      (cpu, parallellt)
                      ├─ nn_all           (bigrig, parallellt)
                      ├─ calculate_signals (gt610, parallellt)
                      │     └─ + nn_nightly (gpu, ≄20:00)
                      │           → morning_signals (bigrig)
                      │               → refresh_materialized
                      │               → rank_weight_day
                      └─ nn_nightly → paper_predict
                           → nn_focused (efter nn_all, gpu)
                    

                    calculate_signals fick QUEUE_DEPENDS: data_pipeline (saknades tidigare).


                    28.3 Direktkörning av update_all.sh borttagen frÄn crontab


                    Cron-raden 30 18 1-5 QUEUE_OFFLOAD=1 update_all.sh körde parallellt med schedulerns data_pipeline-enqueue → risk för dubbel pipeline-körning. Raden Ă€r nu borttagen. Scheduler hanterar allt via queue.


                    data_pipeline har PREFER: home733 → plockas alltid upp av work733:s queue-worker.


                    28.4 Bigrig queue-workers 5–8 i crontab (permanent)


                    Workers 5–8 startades manuellt i en tidigare session. Nu permanenta i bigrig-crontab:


                    @reboot sleep 30 && /usr/bin/bash /shared/bin/queue_worker.sh >> .../queue_worker_5.log 2>&1 &
                    @reboot sleep 30 && /usr/bin/bash /shared/bin/queue_worker.sh >> .../queue_worker_6.log 2>&1 &
                    @reboot sleep 30 && /usr/bin/bash /shared/bin/queue_worker.sh >> .../queue_worker_7.log 2>&1 &
                    @reboot sleep 30 && /usr/bin/bash /shared/bin/queue_worker.sh >> .../queue_worker_8.log 2>&1 &
                    

                    Bigrig kör nu 8 parallella queue-workers (4 via systemd + 4 via cron @reboot).


                    28.5 Stale indikatorrader rensade


                    8 828 rader i daily_indicators hade inget matchande pris i daily_prices — stale data frĂ„n fryst/felaktig prispipeline. Raderade med:


                    DELETE di FROM daily_indicators di
                    LEFT JOIN daily_prices dp ON dp.ticker_id = di.ticker_id AND dp.date = di.date
                    WHERE dp.id IS NULL AND di.date >= '2020-01-01'
                    

                    Exempel: 2026-07-25 (lördag, ej handelsdag) hade 261 indikatorrader utan prisdata.


                    ind_backfill-jobb köat (2026-07-29 01:41) för att rÀkna om alla indikatorer.


                    28.6 Kodfixar


                    morning_signals.py (commit bb28188):

                    • LeasedPoolConnection() direkt → with db_pool.lease_connection() as conn: (context manager; explicit close ej nödvĂ€ndig)

                    db_pool.py (commit bb28188):

                    • Redundant ping(reconnect=True) vid Ă„terlĂ€mning till pool borttagen frĂ„n exit. Checkout-fasen validerar via _validated() Ă€ndĂ„ — sparar ett nĂ€tverks-RTT per connection-return.

                    28.7 Logrotate — saknade mönster (Ă„tgĂ€rdat)


                    /etc/logrotate.d/aktieanalys uppdaterad med sudo (pw: tommy166):


                    Tillagda mönster: api.log, uvicorn.log, browser_session_daemon.log, db_reclaim_*.log.


                    28.8 calculate_signals_py.py — subprocess→ThreadPoolExecutor (commit 761a20f)


                    workers > 1 spawnade tidigare ett separat Python-interpreterprocess per ticker (~308 st).

                    Ersatt med ThreadPoolExecutor som anropar _process_ticker_inproc() direkt i processen.

                    Varje trÄd öppnar sin egen lease_connection(). Eliminerar ~308 interpreter-omstarter per körning (~5 min).


                    28.9 queue_worker: per-jobb QUEUE_HEARTBEAT_STALE (commit b6031c9)


                    Problem: nn_nightly (GPU-trĂ€ning, 12+ h) fick heartbeat stale efter 1 h → orphan-recovery Ă„terlade jobbet till pending → plockades upp av ny worker → flera parallella trĂ€ningskörningar.


                    Fix: Ny funktion job_heartbeat_stale() i queue_worker.sh lÀser QUEUE_HEARTBEAT_STALE-metadag frÄn job-filen. recover_orphans() anvÀnder per-jobb tröskel istÀllet för globalt HEARTBEAT_STALE=3600.


                    Trösklar satta i submit_job.sh:


                    JobbQUEUE_HEARTBEAT_STALE
                    nn_nightly21600 s (6 h)
                    nn_focused14400 s (4 h)
                    rank_weight_monthly86400 s (24 h)

                    28.10 neural_network.py — stĂ€ng read_conn direkt efter dataladdning (commit d9fb17d)


                    predict_all() höll read_conn öppen under hela merge/commit-fasen (potentiellt timmar vid stor modell).

                    Fix: read_conn stÀngs direkt efter att while True: rows = cur.fetchmany(read_chunk) Àr klar.

                    Frigör DB pool-slot för övriga workers under den lÄnga skriv/commit-fasen.


                    28.11 paper_trading_sim.py — cross-node fil-mutex (commit d9fb17d)


                    Fil-mutex för parallellskyddlĂ„set lĂ„g i /tmp/aa_paper_trade_{account_id}.lock — LOCAL per nod, ingen cross-node effekt.

                    Flytt till /shared/queue/.locks/paper_trade_{account_id}.lock (NFS-delad sökvĂ€g) → serialiserar körningar oavsett vilken nod som plockar jobbet.


                    Katalog /shared/queue/.locks/ skapad (sticky-bit, alla noder kan skriva).


                    28.12 Backfill rank_weight_history (pÄgÄende 2026-07-29)


                    Backfill --from 2023-07-10 kör ~3 veckor/h. Status per 2026-07-29 12:30:

                    • Klar: 2023-09-11 → 2025-06-23 (95 distinkta veckor, 380 rader, 4 horisonter: composite/1m/6m/1y/3y)
                    • PĂ„gĂ„r: 2025-06-30 → 2026-07-07 (~52 veckor kvar, estimerat 26–50 h)
                    • valid_from Ă€r 8 veckor senare Ă€n trĂ€ningsveckan (warmup/validering)

                    28.13 Pi — systemd queue-workers aktiverade (2026-07-29)


                    tege-anvÀndaren pÄ raspi krÀver sudo-lösenord (tommy166) men stdin-pipe fungerar ej.


                    Lösning: pi-anvĂ€ndaren har NOPASSWD sudo → ssh pi@192.168.1.174 'sudo ...' fungerar utan lösenord.


                    aa-queue-worker@.service existerade redan (disabled). Aktiverat 6 instanser:


                    ssh pi@192.168.1.174 'sudo systemctl enable aa-queue-worker@{1,2,3,4,5,6}'
                    ssh pi@192.168.1.174 'sudo systemctl start  aa-queue-worker@{1,2,3,4,5,6}'
                    

                    Gamla @reboot-cron-rader för queue_worker.sh borttagna ur tege-crontab.

                    Kvar i tege-crontab: /5 * rsync ... (kod-sync frÄn work733).


                    Pi kör nu 6 systemd-hanterade queue-workers med automatisk Restart=on-failure.


                    28.14 Öppna punkter (2026-07-29)


                    • verify-backfill-result: Backfill pĂ„gĂ„r, verifiera fullstĂ€ndighet nĂ€r klart.

                    28.15 Alerting-system (2026-07-30)


                    Arkitektur

                    • queue_worker.sh: ny send_alert(level, msg) — skriver till /shared/logs/aktieanalys/alerts.log
                    • Format: [YYYY-MM-DD HH:MM:SS LEVEL nod] meddelande
                    • Triggers: FEL (rc≠0) → ERROR, ORPHAN-recovery → WARN
                    • Valfri push: sĂ€tt NTFY_TOPIC=aa-aktieanalys i /etc/environment för ntfy.sh push-notiser

                    API

                    • GET /aa/alerts?n=50 — returnerar senaste n alerts som JSON
                    • Visas som kort pĂ„ /aa/status statussidan
                    • Alert-logg: /shared/logs/aktieanalys/alerts.log (NFS-delad, alla noder skriver dit)

                    28.16 NN signal_3class klassbalansering (2026-07-30)


                    Problem

                    • val_accuracy för signal_3class: avg 37.4%, min 24.75% (ATT.ST, stoppar vid epoch 1)
                    • Orsak: klassimbalans — hold(0) Ă€r majoritetsklass, modellen lĂ€r sig prediktera majoritetsklassen
                    • Augmentering boost specifika mönster men balanserar inte övergripande fördelning

                    Lösning

                    • NN_SIGNAL3CLASS_BALANCE_RATIO=0.7 (default): oversamplar minoritetsklasser
                    • till 70% av majoritetsklassens storlek via random.choices()

                    • Loggar klassfördelning före/efter balansering
                    • PĂ„verkar bara trĂ€ningsdatan — val-setet behĂ„ller originalfördelning (korrekt)
                    • Kan stĂ€ngas av med NN_SIGNAL3CLASS_BALANCE_RATIO=0.0

                    FörvÀntat resultat

                    • Mer balanserade prediktioner (mindre dominans av majoritetsklassen)
                    • BĂ€ttre val_accuracy pĂ„ minoritetsklasser
                    • Testas vid nĂ€sta nn_nightly-körning

                    30. Ändringar 2026-07-30


                    30.1 ^OMX/^OMXSPI exkluderas frÄn NN-trÀning


                    _load_ticker_scope() i neural_network.py hÀmtade index-tickers (symbol LIKE ^%) till alla

                    trÀnings- och prediktionskörningar. ^OMX och ^OMXSPI saknar kurs-/feature-data och orsakade

                    RuntimeError: Parallell NN per-ticker-körning misslyckades i nn_all.


                    Fix (commit 34b634e): WHERE symbol NOT LIKE '^%' lagd i _load_ticker_scope().

                    Index-tickers (id 334–335) anvĂ€nds fortfarande för marknadsdata men trĂ€nas aldrig.


                    30.2 Paper trading — sĂ€nkta NN-konfidenstĂ€rskar


                    signal_3class Ă€r 3-klass softmax. Aktuella modeller ger max-confidence ~0.33–0.50.

                    Tidigare trösklar (0.58/0.52/0.65) blockerade 100 % av signalerna.


                    Nya vÀrden i .env (2026-07-30):


                    VariabelGammaltNytt
                    PAPER_NN_MIN_CONFIDENCE0.580.44
                    PAPER_SWING_NN_MIN_CONFIDENCE0.520.43
                    PAPER_SWING_NN_MIN_CONFIDENCE_STRICT0.650.46
                    PAPER_DAY_NN_MIN_CONFIDENCE0.500.44

                    30.3 OOS walk-forward — nn_prob_p0.55 (+251 % pĂ„ 3 Ă„r)


                    Kördes med tools/nn_trade_sim_strict.py över 3-Ärig OOS-period.


                    StrategiAvkastningSharpeAntal trades
                    nn_prob_p0.55 — prob_up_5d ≄ 0.55+251.1 %0.5831
                    nn_pure_c0.45 — signal_3class ≄ 0.45+2.4 %0.613
                    Strategier med confidence ≄ 0.550 trades—0

                    Nyckelinsikt: prob_up_5d Ă€r en regressionsoutput (0–1) och nĂ„r 0.55–1.0 för

                    PREF/D-aktier. signal_3class-confidence toppar vid ~0.495 och Àr oanvÀndbar

                    med gamla trösklar.


                    30.4 PREF/D-aktiers noggrannhetsmönster


                    Preference-aktier och D-aktier uppnĂ„r 65–88 % signal_3class-noggrannhet mot

                    snittet 39 % för universum. Orsak: lÄg volatilitet + utdelningsscheman ger

                    förutsÀgbara rörelsemönster.


                    Topp-5 (2026-07-30):


                    TickerAvg acc
                    VOLO-PREF.ST88.5 %
                    EMIL-PREF.ST80.8 %
                    BESQAB-PREF-B.ST73.1 %
                    NP3-PREF.ST66.6 %
                    INTEA-D.ST64.2 %

                    Extra trÀning (50 epoker, alla 3 targets) köad via run_nn_pref_boost.sh.


                    30.5 Nytt paper trading-konto: PAPER_PROB_UP5D_SEK


                    Implementerat i paper_trading_sim.py + run_paper_daytrading.sh:

                    • Argument --prob-up5d-direct 0.55 — bypasser morning_signals, anvĂ€nder prob_up_5d ≄ 0.55 direkt
                    • --nn-filter 0 — ingen confidence-gate (irrelevant för direkt regressionssignal)
                    • Max 5 positioner, 20 % positionsstorlek, ingen blankning
                    • OOS-bekrĂ€ftad: +251 % / 31 trades / 3 Ă„r / Sharpe 0.58

                    30.6 Exkludering av tickers med lÄg NN-noggrannhet


                    36 tickers med signal_3class avg < 35 % (sÀmre Àn slumpmÀssigt) exkluderas

                    frÄn regelbaserade paper trading-konton via PAPER_EXCLUDE_TICKERS i .env.


                    Dessa Àr stora likvida blue-chips (VOLV, SSAB, EVO, INDU, FAG m.fl.) dÀr

                    kortsiktiga rörelser domineras av makro/institutionella flöden — tekniska

                    mönster har begrÀnsad prediktiv kraft. prob_up5d_direct-kontot pÄverkas inte.


                    Framtida förbÀttringar för dessa tickers:

                    • Byt mĂ„l till ret_20d (lĂ€ngre horisont mer förutsĂ€gbar)
                    • Sektor-relativa features (prestation vs OMXS30/sektorindex)
                    • Multi-horisont-konsensus: prob_up_2d ∧ prob_up_3d ∧ prob_up_5d

                    30.7 prob_up_1d
4d — nulĂ€ge och plan


                    TargetAntal modellerAnvÀnds i paper trading
                    prob_up_1d2 019Dag-regime-filter (day_regime_min_prob_up_1d)
                    prob_up_2d2 005Ej
                    prob_up_3d2 022Ej
                    prob_up_4d2 016Ej
                    prob_up_5d2 014PrimÀr köpsignal (--prob-up5d-direct)

                    Plan: implementera multi-horisont-konsensus och exit-timing via prob_up_1d/prob_up_2d.



                    Sektion 31 — Uppdateringar 2026-07-31


                    31.1 Kritiska felrÀttningar


                    calculate_signals krasch (Unknown column 'sector_group'):

                    • Kolumnnamn i tickers-tabellen Ă€r sector, inte sector_group
                    • RĂ€ttad i calculate_signals_py.py och tools/signal_param_lhs.py (commit fcbaf87)

                    bigrig venv trasig (pyenv 3.11.8-symlink → inte installerad):

                    • ln -sf /usr/bin/python3 venv/bin/python3 → system Python 3.12.3
                    • pip install pymysql i venv (user-packages ej tillgĂ€ngliga inuti venv)
                    • slurm_dispatch_nn.sh har redan --exclude='venv/' i rsync — manuell rsync utan detta orsakade problemet

                    31.2 Makro-regime-arkitektur


                    Ny modul tools/macro_regime.py:

                    • Detekterar repo-rĂ€nte-trend (6 mĂ„naders förĂ€ndring vs ±0.25 pp)
                    • Detekterar marknadstrend (% tickers > SMA200 senaste 5 dagar, bull > 55 %, bear < 40 %)
                    - Returnerar strĂ€ng: `"{bullneutralbear}_{fallingstablerising}"` → 9 möjliga regimer
                    • Nuvarande: neutral_stable

                    Per-sektor × makro-regime LHS-parameterarkitektur i signal_param_lhs.py:

                    • RW_REGIME env-var → filtrerar trĂ€ningsdata till dagar med matchande regime
                    • Output: signal_param_lhs_best_{sector}_{regime}.json
                    • Fallback-kedja: {sector}_{regime} → {sector} → global

                    Sektornormalisering i DB: 16 tickers uppdaterade (Fastighet→Fastigheter, Bank&Finans→Finans, etc.)


                    31.3 nn_nightly-schema


                    Crontab Àndrad:

                    • Var: 0 1 2 (tisdag kl 01:00)
                    • Nu: 0 1 1-5 (varje vardag kl 01:00)

                    31.4 Multi-horisont-konsensus (paper trading)


                    build_prob_up5d_signals() i paper_trading_sim.py:

                    • Ny parameter min_prob_1d=0.0 — filtrerar bort köp om prob_up_1d < threshold
                    • Ny CLI-arg --prob-up5d-direct-min-1d / PAPER_PROB_UP5D_DIRECT_MIN_1D

                    PAPER_SWING_NN_SEK aktiverar konsensus:

                    • --prob-up5d-direct-min-1d 0.52 (via PAPER_SWING_NN_MIN_1D)
                    • KrĂ€ver nu: prob_up_5d ≄ 0.52 OCH prob_up_1d ≄ 0.52 för köp

                    31.5 Fredagsautomatik


                    update_all.sh steg 1 (Avanza-kurshÀmtning):

                    if [[ "$(date +%u)" == "5" ]]; then _avanza_force_flag="--force"; fi
                    $PYTHON avanza_update_prices.py ${_avanza_force_flag}
                    

                    Fredagar: --force flagga sÀkerstÀller att dagens slutkurser hÀmtas (annars skippas om igÄrdagens data finns).


                    31.6 OOS-riktighetsanalys (tools/eval_prob_up_oos.py)


                    Nytt verktyg: walk-forward OOS-riktighetsanalys för prob_up_Xd-modeller.

                    • Strikt walk-forward: för datum d anvĂ€nds bara modell med train_to < d
                    • BerĂ€knar faktisk riktning frĂ„n daily_prices.close (ej daily_forward_returns)
                    • Rapport: precision och lift per tröskelvĂ€rde 0.50–0.70

                    Resultat prob_up_1d (2025-07-30 → 2026-07-30, 2402 obs, basrate 51.5%):


                    TröskelvĂ€rdeKÖP nKÖP-riktighetLift
                    0.5071353.4 %+3.7 %
                    0.5255955.8 %+8.3 % ← nuvarande trösk
                    0.5445155.0 %+6.7 %
                    0.5639653.8 %+4.4 %
                    0.5834453.8 %+4.3 %
                    0.6030854.2 %+5.2 %

                    Slutsats: prob_up_1d ≄ 0.52 Ă€r validerat OOS med 55.8 % riktighet (+8.3 % lift vs basrate).

                    SĂ€lj-sidan (~49 %) Ă€r svagare — undvik short baserat enbart pĂ„ lĂ„g prob_up_1d.

                    Nuvarande tröskelvÀrde 0.52 Àr optimalt (bÀst balans lift/tÀckning).


                    Kör: python3 tools/eval_prob_up_oos.py --target prob_up_1d --years 1


                    31.7 OOS-riktighetsanalys prob_up_5d — varning bull-marknad


                    Resultat prob_up_5d (2025-07-30 → 2026-07-30, 3663 obs, basrate 57.7 %):


                    TröskelvĂ€rdeKÖP nKÖP-riktighetLift
                    0.501 26456.1 %−2.8 %
                    0.521 12055.9 %−3.1 %
                    0.55~870~56 %~−3 %
                    0.6063355.0 %−4.7 %

                    ⚠ Problem: Modellen underpresterar basraten under 2025-08–2026-07.

                    Basraten Ă€r 57.7 % (stark bull-marknad) — modellen vĂ€ljer ut aktier med 55-56 % uppgĂ„ng,

                    d.v.s. sÀmre Àn att bara slumpmÀssigt köpa.


                    Tolkning: prob_up_5d trÀnad pÄ mer balanserad data (50/50 upp/ner-fördelning)

                    kalibrerar inte om nÀr hela marknaden stiger. I en bull-marknad Àr "neutral" prediktion

                    (≈0.50) faktiskt ett dĂ„ligt urval eftersom alla aktier tenderar att stiga.


                    ÅtgĂ€rder:

                    1. SÀnk tröskelvÀrde till 0.48 vid bull-regime (bull = pct_above_sma200 > 55 %)
                    2. Kontrollera kalibrering: prob_up_5d-distribution bör reflektera aktuell marknadsriktning
                    3. Historisk OOS +251 % 3 Ă„r gĂ€ller — undvik panikĂ€ndringar, bull-marknader Ă€r temporĂ€ra
                    4. NĂ€sta NN-trĂ€ning (mĂ„ndag) inkluderar 2025-2026-data → förbĂ€ttrad kalibrering

                    5. JÀmförelse prob_up_1d vs prob_up_5d:

                      • prob_up_1d: +8.3 % lift ✅ — dagshandel-filtret fungerar vĂ€l
                      • prob_up_5d: −3 % lift ⚠ — bull-marknaden skapar kalibreringsproblem

                      31. Ändringar 2026-08-02


                      31.1 MariaDB — timeout-konfiguration


                      TvÄ MySQL-relaterade fel orsakade att paper_predict-jobbet kraschade (2026-07-31):


                      1. Lost connection during streaming query — SSCursor (streaming/server-side cursor) tappade anslutningen under fetchmany() pĂ„ stora frĂ„gor
                      2. Lock wait timeout — INSERT ON DUPLICATE KEY för prob_up_*-kolumner kraschade vid 50 s timeout

                      3. ÅtgĂ€rd: /etc/mysql/mariadb.conf.d/99-aktieanalys-timeouts.cnf skapad med:

                        innodb_lock_wait_timeout = 120
                        net_read_timeout = 900
                        net_write_timeout = 900
                        

                        MariaDB omstartades. Timeout SET GLOBAL verifierat. Nytt paper_predict-jobb skickat → rc=0 ✅.


                        31.2 nn.php — bugfix prob_up-kolumn och trösklar


                        load_prob_up_horizon() anvĂ€nde fel kolumn confidence AS prob_val → korrekt: pred_prob_up AS prob_val.

                        Trösklar Ă€ndrade till OOS-verifierade vĂ€rden: ≄0.65 = KÖP, ≀0.35 = SÄLJ (var ≄0.55/≀0.45).

                        Sortering Àndrad till pred_prob_up DESC (var confidence DESC).


                        31.3 Ny webbsida: indikatorer.php


                        Ny sida /aa/indikatorer.php skapad — per-ticker indikatoröversikt med 23 indikatorer i 9 kategorier:


                        KategoriIndikatorer
                        TrendSMA50, SMA200, Golden/Death Cross
                        MomentumRSI(14), MACD, Stochastic K/D, CCI(20)
                        VolatilitetBollinger %B, ATR(14)
                        TrendstyrkaADX(14)
                        IchimokuTK-Cross, Cloud position
                        SignalPSAR trend, VWAP-avstÄnd
                        FFT CyklerCycle bias score
                        NNprob_up_1d–5d (≄65%=KÖP, ≀35%=SÄLJ), signal_3class
                        MorgonsignalGap-up/down signal

                        Sidan visar en summeringsbar med #KÖP / #AVVAKTA / #SÄLJ och procentfylld bar.

                        LĂ€nkad frĂ„n navbaren (🔬 Indikatorer) och frĂ„n aktie.php detaljsida.

                        aktie.php har nu 🔬 Indikatoröversikt-lĂ€nk i subtitelraden.


                        31.4 Raspberry Pi — crontab-status verifierat


                        • pi-crontab: avsiktligt tom — queue workers körs via systemd (aa-queue-worker@{1-6}.service, enabled+active)
                        • tege-crontab pĂ„ raspi: /5 * rsync-kodsync frĂ„n work733 ✅
                        • slurmd aktiv, Pi i partitionerna debug och pi

                        31.5 VM — rsync installerat, deploy-flöde klart


                        rsync installerat pÄ VM (sudo apt install rsync). deploy_web.sh fungerar nu korrekt:

                        rsync -av --checksum web/aktieanalys/ tege@192.168.100.83:/var/www/html/aa/
                        

                        KrÀver att tege Àr med i www-data-gruppen (redan gjort via usermod -aG www-data tege) och att g+w Àr satt pÄ /var/www/html/aa/.


                        32. Ändringar 2026-08-02


                        32.1 MariaDB lösenordsrotation


                        • MariaDB-lösenordet roterades frĂ„n det tidigare vĂ€rdet till ett nytt sĂ€kert lösenord.
                        • web/aktieanalys/includes/config.php laddar nu hemligheten frĂ„n gitignorerad db_secret.php i stĂ€llet för att ha lösenordet inline i repo.
                        • deploy_web.sh genererar db_secret.php pĂ„ VM:n med printf och sĂ€tter filrĂ€ttigheter till 0644.
                        • Git-historiken sanerades med git-filter-repo för att ta bort det tidigare lösenordet ur historiken.

                        32.2 API-hÀlsospÄrning (api_health)


                        • Ny tabell api_health med kolumnerna source, status, last_ok, last_fail, consecutive_fails, last_error och updated_at.
                        • Ny hjĂ€lpmodul tools/api_health.py med report_ok(source) och report_fail(source, error_msg).
                        • Integrerad i browser_session_daemon.py, fetch_avanza_intraday.py, fetch_yahoo_5m.py och fetch_macro.py.
                        • Statussidan /aa/status visar nu sektionen đŸ©ș Externa datakĂ€llor baserad pĂ„ denna tabell.

                        32.3 Rensning av orphan nn_predictions


                        • Nytt verktyg tools/cleanup_orphan_predictions.py rensar prediktioner vars model_id saknas i nn_models.
                        • Kördes 2026-08-02 och raderade 7 486 orphan model_ids (cirka 20 miljoner rader).
                        • Verktyget körs nu som steg 3 i run_weekend_chain.sh.

                        32.4 Test-suite (tests/test_system_health.py, run_tests.sh)


                        • Systemets hĂ€lsosvit omfattar nu 22 tester i 8 testklasser: DB-anslutning, champion-aktualitet, queue-hĂ€lsa, intraday-data, daglig pipeline, disk/minne, webb-endpoints och cap_prob-logik.
                        • Sviten körs varje natt 04:15 pĂ„ work733 mĂ„ndag–fredag.
                        • Samma svit körs Ă€ven som steg 7 i run_weekend_chain.sh.

                        32.5 Kritiska felrÀttningar (commit 775e118)


                        • paper_trading_sim.py: SELECT ... FOR UPDATE ligger nu i explicit transaktion (autocommit=False + conn.begin()) för att eliminera race vid parallella körningar.
                        • neural_network.py: DB-anslutningen stĂ€ngs direkt efter dataladdning, epoch-loggning anvĂ€nder kortlivade anslutningar och deferred_rows chunkas i block om 10 000 rader för lĂ€gre peak-RAM.

                        32.6 Kommentarer och docstrings


                        Kommentarer/docstrings lades till i:

                        • db_pool.py
                        • api.py
                        • browser_session_daemon.py
                        • paper_trading_sim.py
                        • neural_network.py

                        32.7 Helgkedjan uppdaterad


                        run_weekend_chain.sh har nu 7 steg:

                        1. run_rank_weight_weekly.sh
                        2. db_housekeeping.py --apply
                        3. cleanup_orphan_predictions.py
                        4. run_nn_focused.sh
                        5. backtest_engine.py
                        6. combination_backtest.py
                        7. run_tests.sh

                        8. 32.8 Dokumenterad helgoptimering


                          §2.5 beskriver nu hela helgkedjan i detalj, inklusive fas 3b alpha-beta cutoff, signal_param_lhs per sektor×regime, apply_rank_weights.py och de dubbla backtest-passen.


                          33. Queue-system och cron-konsolidering 2026-08-05


                          Senast uppdaterad: 2026-08-05


                          33.1 QUEUE_SUBMITTED-header — separerar deps frĂ„n PREFER-delay


                          Problem: job_epoch = file_mtime anvĂ€ndes för BÅDE deps_satisfied()-kontrollen

                          OCH PREFER-fördröjningens ÄlderberÀkning. Om ett jobb hade gammal mtime (t.ex. för att

                          deps-checken krÀver att mtime sÀtts till nÀr jobbet submitterades) bypassade PREFER-delays

                          direkt, och pi/work733 hÀmtade bigrig-prefererade jobb omedelbart.


                          Fix:

                          • submit_job.sh injicerar # QUEUE_SUBMITTED: $(date +%s) pĂ„ rad 2 i varje jobbfil
                          • queue_worker.sh: ny funktion job_submitted() lĂ€ser headern (fallback: mtime)
                          • deps_satisfied() anvĂ€nder job_submitted() — inte mtime — för beroendekontrollen
                          • PREFER-delay-Ă„lder rĂ€knas fortfarande pĂ„ mtime (= nu för fĂ€rska jobb → liten Ă„lder → delays fungerar)

                          Commits: c07ca67, b2a343f, a660efb, c1b7bd0


                          33.2 PREFER-routing konsoliderad till bigrig


                          Alla GPU-trĂ€nings- och tyngre inferensjobb Ă€ndrade frĂ„n gpu/cpu → bigrig:


                          JobbFörutNu
                          nn_nightly, nn_focusedgpubigrig
                          paper_predictgpubigrig
                          backfill, fft_nightly, ind_backfillcpubigrig
                          strategy_v3/v4/v5, phase7cpubigrig
                          refresh_materializedcpubigrig

                          Effekt: bigrig-typen ger bigrig(0s)→pi(300s)→work733(3600s). Pi prövas som CPU-fallback

                          efter 5 min, work733 som sista utvÀg efter 1 timme.


                          33.3 Worker-antal justerade


                          NodFörutNuMetod
                          bigrig8 workers6 workersStoppade worker 7+8 manuellt; @reboot seq 1 6
                          pi4 workers2 workersWatchdog-tröskel 4→2, @reboot seq 1 2

                          33.4 Cron-konsolidering (work733)


                          Borttagna/ersatta cron-jobb:


                          BorttagetErsÀttningAnledning
                          slurm_dispatch_nn.sh nn_nightly (01:00 mĂ„n–fre)submit_job.sh nn_nightly (kö)Slurm Ă€r avvecklat; direktkörning bypassade kön
                          ssh bigrig "sbatch top_tickers" (01:00 fre)—Dead Slurm-artefakt
                          run_weekend_chain.sh (00:30 lör)scheduler.sh enqueuar weekend_chainDirektkörning bypassade kö och PREFER-routing
                          run_rank_weight_weekly.sh (00:30 sön)—Körs som steg 1 i run_weekend_chain.sh (via weekend_chain-jobbet)

                          Borttagna/ersatta cron-jobb pÄ bigrig och pi:

                          • bigrig: @reboot seq 1 8 → seq 1 6
                          • pi: dubblerad rsync-rad borttagen

                          33.5 Logrotate — kompletterat alla maskiner


                          MaskinStatusÄndringar
                          work733✅ Uppdateradcron_nn_nightly.log tillagd
                          bigrig✅ Skapad 2026-08-05TĂ€cker .log i aa-ai/ och /tmp/queue_worker_bigrig_.log
                          pi✅ UppdateradSlurm-stanza borttagen; /tmp/queue_worker_pi_*.log tillagd
                          vm✅ Uppdateradsu tege tege + compress + delaycompress tillagd

                          33.6 housekeeping_work733.sh — utökat


                          Tillagda steg:

                          • 2b: queue/failed — rensar jobbfiler Ă€ldre Ă€n 14 dagar
                          • 2c: Heartbeat-filer (.hb) i /shared/queue/.heartbeats/ och /tmp/ Ă€ldre Ă€n 1 dag

                          33.7 PÄgÄende (ej klart)


                          • Pi ARM-venv: pyenv 3.12.13 installeras pĂ„ pi (aarch64). NĂ€r klart: skapa lokal ARM-venv med numpy/scipy/torch
                          • work733 venv-rebuild: Python 3.11 → 3.12. requirements_rebuild.txt committad (d76a3a6). VĂ€ntar pĂ„ att paper_predict-körning avslutas

                          Sektion 34 — Uppdateringar 2026-08-06


                          34.1 ARM-vakt + TEMPFAIL-requeue (queue_worker.sh / run_nn_nightly.sh)


                          Problem: pi-noden plockade upp bigrig_work733-jobb trots PREFER-routing, pga workers startade före routing-driftsÀttning.


                          Lösning 1 — Arkitekturvakt (run_nn_nightly.sh):

                          if [[ "$(uname -m)" != "x86_64" ]]; then
                              echo "nn_nightly krĂ€ver x86_64 — exit 75 (TEMPFAIL → pending)"
                              exit 75
                          fi
                          

                          Lösning 2 — TEMPFAIL-requeue (queue_worker.sh):

                          • rc=0 → done/
                          • rc=75 (EX_TEMPFAIL) → pending/ (retry pĂ„ annan nod)
                          • rc=annat → failed/

                          Lösning 3 — QUEUE_RAN_ON overwrite:

                          sed -i "s/^QUEUE_RAN_ON=.*/QUEUE_RAN_ON=$(hostname)/" "$JOBFILE"
                          

                          SÀkerstÀller att loggfilnamn reflekterar körande nod, ej stale vÀrde frÄn föregÄende pickup.


                          34.2 ETA-berÀkning för nn_nightly-shards (api.py)


                          Problem: _estimate_eta() visade "–" för alla shard-jobb.


                          ÅtgĂ€rder:

                          1. _PROGRESS_PATTERNS utökad med nn_nightly_s0..s7 via loop
                          2. Fallback: shard utan historik → nn_nightly-historik Ă· 6 (parallella shards)
                          3. 1.5x-gate borttagen → visa >2h34m (+12% övertid) istĂ€llet för blank "–"
                          4. Starttid: sista "start"-raden anvÀnds (ej stale första körning frÄn pi)

                          5. 34.3 Jobbkö-label "senaste 10" → "senaste 15" (api.py)


                            Cap-variabeln var 15 men label sade 10. RĂ€ttat till senaste 15.


                            34.4 PYTHONPATH-fix för rolling_1month_sim (submit_job.sh)


                            python3 tools/script.py lÀgger till tools/ i sys.path, ej projektroten.

                            db_pool.py ligger i projektroten → ModuleNotFoundError.


                            Fix: export PYTHONPATH="/home/tege/work/python/aa-ai:..." i jobbdefinitionen.


                            34.5 Bull-regime kalibrering för prob_up_5d (paper_trading_sim.py)


                            Bakgrund: I bull-marknad (pct_above_sma200 > 55 %) Ă€r basraten ~57–58 % men modellen

                            selekterar 55–56 % → underpresterar basraten → för fĂ„ köpsignaler.


                            Implementering:

                            • _get_market_breadth(cur, asof_date) — mĂ€ter andel tickers med close_vs_sma200 > 0
                            • --bull-market-breadth (default 0.55) — tröskel för bull-regime
                            • --bull-prob-adj (default -0.04) — justeringsvĂ€rde för prob-trösklar
                            • Justerar: prob_up5d_direct, nn_prob_min_buy, day_regime_min_prob_up_5d
                            • Minimum: 0.40 (sĂ€kerhetsgolv)
                            • Loggas: paper_trade_bull_regime: breadth=61.2% > 55% → justerar prob-trösklar med -0.04

                            Env-vars: PAPER_BULL_MARKET_BREADTH, PAPER_BULL_PROB_ADJ


                            34.6 Observability — StepTimer (utils.py)


                            Ny kontexthanterare StepTimer i utils.py:


                            with StepTimer("preload sektor-data", logger=_log):
                                sector_all = load_sector_data(conn)
                            # Output: 16:38:59 STEP preload sektor-data               0.23s  1,850 rader  8,043 r/s
                            

                            Instrumenterade skript:

                            • calculate_all_indicators.py: preload (sektor/makro/benchmark/intraday/PE) + SUMMARY
                            • calculate_signals_py.py: init_macro_regime + SUMMARY

                            SUMMARY-format:

                            SUMMARY  tickers=308  DB-rader=3 542  loop=47.1s  total=52.3s  genomströmning=75 rader/s
                            

                            34.7 Roadmap-status


                            ItemStatusAnteckning
                            ARM-vakt + TEMPFAIL✅ Klarcommits 812fa9c, 1ecf9ec
                            ETA för shards✅ Klarcommit 1ecf9ec
                            "senaste 10" → 15✅ Klarcommit a9989e3
                            rolling_1month_sim PYTHONPATH✅ Klarcommit 7cc6a4a
                            Bull-regime kalibrering✅ Klarcommit 207125a
                            Multi-horisont-konsensus✅ Redan klar§31.4
                            Observability StepTimer✅ Klarcommit 025fc41
                            Small Cap _UNIVERSE_PRIORITY🔮 BlockeradKrĂ€ver nya tickers + data pipeline
                            Low-acc tickers ret_20d✅ Klarcommit 5ca00e4, se §35



                            35. SystemförÀndringar 2026-08-06


                            35.1 WORKER_TYPE — dedikerade GPU/CPU-workers


                            Workers uppdelades pÄ typbaserade systemd-instanser:


                            NodInstansMAXTar jobb
                            bigrig@cpu6Alla utom gpu/gt610
                            bigrig@gpu2Enbart QUEUE_PREFER: gpu
                            work733@cpu2Alla utom gpu/gt610
                            work733@gt6101Enbart QUEUE_PREFER: gt610
                            pi@cpu1Alla utom gpu/gt610

                            GPU-workers tar aldrig CPU-jobb; CPU-workers tar aldrig GPU/GT610-jobb. Konflikten dÀr stora NN-trÀningsjobb blockerade CPU-jobb (eller vice versa) Àr eliminerad.


                            35.2 deps_satisfied — 72h-fallback borttagen (commit fb140ea)


                            Det gamla villkoret `done_epoch >= job_epochdone_epoch >= (now-72h) tillĂ€t gĂ„rdagens shards att uppfylla dagens koordinators beroenden. Koordinatorn (nn_nightly`) startade dĂ„ medan s0–s3 fortfarande körde, anvĂ€nde ofĂ€rdiga modeller och genererade felaktiga prediktioner.

                            Fix: Enbart done_epoch >= job_epoch — done-filen mĂ„ste ha tillkommit efter att aktuellt jobb submitades.


                            Drift-notering: Om queue_worker.sh uppdateras pÄ NFS utan att workers startas om körs gamla funktioner kvar i minnet (bash lÀser hela scriptet vid start). Kör alltid systemctl restart aa-queue-worker@* pÄ alla 3 noder efter scriptÀndringar.


                            35.3 QUEUE_STARTED_AT — korrekt starttid i jobbkön (commit fb140ea)


                            queue_worker.sh skriver # QUEUE_STARTED_AT: <epoch> till jobbfilen i running/ vid pickup, innan mtime-restore. Utan detta visade API:t mtime (= submission-tid, t.ex. 14:33) som "Startad" trots att jobbet startades 20:23.


                            api.py _parse_job_file lĂ€ser QUEUE_STARTED_AT och _estimate_eta anvĂ€nder det som primĂ€r kĂ€lla. Fallback: mtime → filnamn-tidsstĂ€mpel.


                            35.4 save_model stats-metadata-guard (commit fb140ea)


                            save_model() itererar stats.items() och förvÀntar sig {mean, std, min, max}-dicts per feature. Commit abc333e lade till skalÀra metadata (_train_cutoff, _n_tickers) i samma dict, vilket orsakade TypeError: 'int' object is not subscriptable.


                            Fix: if isinstance(st, dict) and 'mean' in st guard i list comprehension.


                            35.5 Low-acc target switching (commit 5ca00e4)


                            För tickers dÀr signal_3class-champion understiger NN_LOW_ACC_THRESHOLD (default 0.48) byts trÀningens target automatiskt till NN_LOW_ACC_TARGET (default ret_20d):


                            [LOW-ACC] ATT.ST/signal_3class score=0.441 < 0.48 → trĂ€nar ret_20d istĂ€llet
                            

                            Ny hjÀlpfunktion get_champion_score(conn, target, ticker_id) hÀmtar champion_score ur nn_model_registry utan att ladda modellen. Env-variablerna lÀses en gÄng per ticker-batch (utanför inner-loopen). Inaktiveras tyst om NN_LOW_ACC_TARGET inte Àr ett giltigt target.


                            35.6 max_drawdown och Ulcer Index buggfixar (commit a700528)


                            • max_drawdown_63/252: berĂ€knade löpande drawdown frĂ„n rullande peak (ej peak-to-trough). Ny _max_drawdown_window(prices) hittar verkligt peak→trough-minimum.
                            • ulcer_idx14: anvĂ€nde max(window) som peak (lookahead). Ersatt med löpande peak per bar.

                            35.7 NN_SKIP_MAIN_TRAIN gav ingen effekt (commit 538a1b6)


                            run_nn_nightly.sh lĂ€ste in NN_SKIP_MAIN_TRAIN men anvĂ€nde aldrig variabeln för att gata Fas 2–4. Koordinatorjobbet (som sĂ€tter NN_SKIP_MAIN_TRAIN=1) körde dĂ€rmed full per-ticker-trĂ€ning istĂ€llet för predictions-only.


                            Fix: if [[ "${SKIP_MAIN_TRAIN:-0}" == "1" ]]; then wrapper runt hela Fas 2-4-blocket i for UNIVERSE-loopen. En informationslogg skrivs nÀr hopp sker: [SKIP_MAIN_TRAIN] Hoppar över Fas 2-4 för $UNIVERSE.


                            35.8 datetime.utcnow() deprecation (commit 538a1b6)


                            neural_network.py anvĂ€nde datetime.utcnow() pĂ„ 4 stĂ€llen (rad ~4134, 4135, 4390, 4490) — scheduled för removal i framtida Python. Ersatt med datetime.now(timezone.utc). timezone importeras nu explicit ur datetime-modulen.


                            35.9 Databasindex-optimering (commit dcf7e82, ~1.5 GB besparing)


                            Analys via EXPLAIN + query-patterns identifierade redundanta/oanvÀnda index:


                            TabellIndexÅtgĂ€rdMotivering
                            nn_predictionsidx_nn_pred_ticker_model_dateDROPOptimizer vĂ€ljer det aldrig — PRIMARY(ticker_id,date,model_id) + idx_model_date_ticker tĂ€cker alla mönster. Stod som borttaget i schema.sql sedan 2026-07-12 men hittades kvar i prod.
                            daily_signalsidx_ds_signal_dateDROPIngen query filtrerar (date,buy,sell)-kombinationen
                            daily_signalsidx_ds_date_ultimateDROPInga queries anvÀnder (date,ultimate_buy,sell)
                            daily_signalsidx_ds_buy_sellADDWHERE buy_signal=1 i main_simple.py scannnade 1.17M rader; nytt index fixar full scan
                            nn_training_epochsidx_target_ticker_createdDROPPrefix-subset av idx_target_ticker_status_created; alla queries filtrerar pÄ status

                            DROP INDEX pĂ„ nn_predictions (8.6 GB, ALGORITHM=INPLACE LOCK=NONE) tog 10 min. Zombie-connections (PID 14216/14217/14222, 4–5h gamla SELECT pĂ„ nn_predictions_strict_oos) blockerade metadata-lock och killades manuellt.


                            35.10 OPTIMIZE TABLE nn_predictions


                            Efter DROP INDEX + intensiv nattkörning hade nn_predictions ~1.6 GB fragmenterat utrymme (data_free). OPTIMIZE TABLE nn_predictions startades 2026-08-06 ~21:20 men avbröts efter 38 min (InnoDB ALTER TABLE-lock blockerade koordinatorns accuracy governance-steg). Schemalagd att köras igen 2026-08-07 kl 09:00 via cron pÄ work733 nÀr ingen trÀning Àr aktiv.


                            35.11 PREFER=pi borttaget ur submit_job.sh (commit 802b358)


                            Pi ska aldrig vara primĂ€r nod — fungerar som avlastningsfallback nĂ€r bigrig Ă€r full. Följande jobb hade felaktigt PREFER=pi:


                            • fft_nightly_s2, morning_signals, rank_weight_day, refresh_materialized → bigrig
                            • nn_all_s4, nn_all_s5 → bigrig (tidigare bigrig_work733, pi exkluderades)

                            Ordning för PREFER=bigrig: bigrig direkt → pi efter 300s → work733 efter 3600s. BehĂ„lls: nn_retrain_clean_pi (avsiktlig pi-körning).


                            35.12 PREFER work733/home733 ignorerades i case-sats (commit 7500aaf)


                            queue_worker.sh pre-filtret (rad 277) exkluderade korrekt icke-work733-noder för PREFER=work733, men case-satsen saknade en `work733home733) arm och föll igenom till *) (okĂ€nd token) → loggade varning och hoppade jobbet. Effekt: data_pipeline och alla jobb med PREFER=work733 körde aldrig. Fix: work733home733) ;;` tillagt.

                            35.13 Coordinator heartbeat-stale sĂ€nkt 7200 → 1800s


                            nn_nightly-koordinatorn (med NN_SKIP_MAIN_TRAIN=1) tar ~10–15 min. Det gamla vĂ€rdet 7200s (2h) innebar att en zombie-koordinator blockerade downstream-jobb i upp till 2h utan auto-recovery. Nytt vĂ€rde: 1800s (30 min).


                            35.14 api.py blocking I/O — async def konverterade till sync def


                            6 route handlers var deklarerade async def utan att anvĂ€nda await. FastAPI kör async def-handlers i event-loop-trĂ„den vilket blockerar alla andra requests under I/O (fillĂ€sning av jobbfiler, loggar). Konverterade till def (sync) — FastAPI/Starlette kör dem automatiskt i thread pool:


                            • login_start, login_status, login_cancel
                            • serve_log (lĂ€ser loggfiler — potentiellt stora)
                            • get_alerts
                            • status_page + system_status_page

                            35.15 run_job synkron — bigrig körde ett jobb i taget (commit 0190d08)


                            queue_worker.sh anropade run_job "$running_file" synkront i while-loopen. Loopen blockerade tills jobbet var klart innan nĂ€sta iteration. MAX_CONCURRENT_JOBS=6 var i praktiken oanvĂ€nt — varje worker-instans körde alltid exakt ett jobb Ă„t gĂ„ngen.


                            Fix: run_job "$running_file" & — jobbet bakgrundskörds. Loopen fortsĂ€tter omedelbart och plockar upp nĂ€sta jobb. Bashens EXIT-trap hanteras korrekt per bakgrundsbarn (varje child Ă€rver egna traps). Concurrency-rĂ€knaren (grep QUEUE_RAN_ON i running/-filer) fungerar som tidigare eftersom mv + header-skrivning sker innan run_job &.


                            Effekt: Bigrig kör nu upp till 6 jobb parallellt. Paper-predict-shardarna (s0–s5) plockas upp omedelbart istĂ€llet för sekventiellt.


                            35.16 FFT handskriven Cooley-Tukey → numpy.fft.rfft (commit fc2ebe9)


                            analyze_fourier_cycles.py implementerade Cooley-Tukey FFT i ren Python (fft_inplace). Byte till numpy.fft.rfft (C/pocketfft) ger ~100× speedup. detrend_log_segment() och spectrum_features_fft() fullt vektoriserade. valid_bins som np.ndarray(dtype=np.intp) för O(1) fancy indexing. fft_nightly: ~17 min → ~2 min.


                            35.17 calculate_indicators_v2: sum(buf[-N:]) → löpande summor O(1) (commit 5066db2)


                            10 globala löpande summavariabler (_csum20, _csum50, _csumsq20 m.fl.) ersÀtter alla sum(buf[-N:]) O(N)-anrop per rad. SMA20/50, TMA20/50, Vortex(14), Z-score (König-formeln), Mass Index(25), vol_spike optimerade. Testat pÄ ABB.ST.


                            35.18 NN two-pass streaming: need_syn=True orsakade OOM-fallback (commit 98d17db)


                            Gate and not need_syn (rad ~3355) tvingade _load_training_data_single_pass() nĂ€r NN_INCLUDE_SYNTHETIC=1 (default). Single-pass ackumulerar prepared=[] med alla rader som Python-dicts → OOM vid stora universum.


                            Fix: _load_training_data_two_pass() pre-laddar macro_map, omx30/lcap-universum och beta_map INNAN streaming. _enrich_rows_with_synthetic() körs per chunk i pass 1. Gaten borttagen — two-pass alltid aktiv oavsett synthetic features.


                            35.19 backtest_engine: ProcessPoolExecutor-parallellism (commit 10d9741)


                            run_all() var seriell: for symbol × strategy ~810 Python-loopanrop. TvĂ„fas arkitektur:

                            • Fas 1: ladda ticker-data sekventiellt (DB, kan ej pickle DB-connection)
                            • Fas 2: _worker_run_symbol() i ProcessPoolExecutor(workers=4) — rena CPU-berĂ€kningar
                            • Fas 3: spara resultat sekventiellt till DB
                            • FörvĂ€ntad speedup: ~3–4× (frĂ„n ~8 min → ~2 min). Override: BACKTEST_WORKERS=N.


                            35.20 calculate_indicators_extended: rolling O(NÂČ) → numpy stride_tricks O(N) (commit db66e93)


                            calculate_indicators_extended.py hade pure-Python rolling-funktioner (rolling_mean/std/max/min/sum, wma) med O(N×period)-komplexitet via fönsterslicing och sum(window) per rad.


                            Fix: Ersatt med np.lib.stride_tricks.sliding_window_view + numpy-reduktioner:

                            • rolling_mean → windows.mean(axis=1)
                            • rolling_std → windows.std(axis=1, ddof=0) (populations-stddev, matchar original)
                            • rolling_max/min → windows.max/min(axis=1)
                            • rolling_sum → windows.sum(axis=1)
                            • wma → (windows * weights).sum(axis=1) / denom

                            NaN propagerar automatiskt i IEEE-aritmetik — ingen explicit None-check per fönster behövs. _to_float_arr/_from_float_arr hanterar None↔NaN-konvertering.


                            Modulkommentar "no numpy/pandas – AVX not available" borttagen (numpy fungerar pĂ„ work733/bigrig).


                            paper_trading_sim._load_latest_nn_target(): dead code (raise NotImplementedError, inga kallare) borttagen.


                            35.21 calculate_indicators_extended: DECIMAL overflow-buggar (commit 16c0948)


                            Bugg: vol_roc_5 (DECIMAL(8,4), max 9999.9999) fick DataError 1264 "Out of range" vid volymspike (t.ex. 100x spike → 9900% ROC > 9999.9999).


                            Fix (3 kolumner):

                            • vol_roc_5: max(-9999.99, min(9999.99, v)) if math.isfinite(v) else None
                            • vol_ratio_20: klampar ±9999.99 (volym kan spike 10000x mot medel)
                            • bb_pct_b: rng > 1e-8 (numerisk stabilitet) + klampar ±9999.99

                            Hittad via real-ticker-test (ABB.ST, DataError rad 112 med 50M-volymspike).


                            35.22 Opus-5 code review: 4 kritiska buggar (commit bd6ff32)


                            Oberoende granskning av Claude Opus 5 hittade och fixade fyra kritiska buggar + minneslÀcka:


                            analyze_fourier_cycles.py — 100% trasigt sedan numpy-migrering:

                            • if not detr: och if not valid_bins: pĂ„ ndarray → ValueError: truth value ambiguous
                            • Skriptet kraschade vid varje start; aldrig kört utan fel sedan FFT-commit
                            • Fix: detr is None or detr.size == 0 resp. valid_bins.size == 0

                            backtest_engine.py — progressbar kraschade hela run_all():

                            • Index 6,7,10 istf rĂ€tt 4,5,8 → ValueError: Unknown format code 'd' utanför try/except
                            • Glidande fönster (BACKTEST_INFLIGHT): 163 MB → 53 MB peak RSS (308 tickers = 1,7 GB utan fix)
                            • conn.close() saknad i finally; cursor-lĂ€cka i period-grenen

                            neural_network.py — params i fel ordning + look-ahead bias + SSDictCursor-trunkering:

                            • _load_ticker_beta_map: params=[universe, ticker_id, lookback] men SQL: [universe, lookback, ticker_id] → ticker-scope betas alltid 0.0 (0 DB-rader matchade)
                            • Look-ahead bias: CURDATE() → end_date (train_to); 27/27 betas förĂ€ndrades
                            • _enrich_rows_with_synthetic: anropade _get_universe_ticker_set() per rad med öppen SSDictCursor → tyst trunkering (10k av 30k rader bearbetades utan varning)
                            • Single-pass: macro_map laddades med SSDictCursor öppen → tyst trunkering
                            • train_to=None → WHERE date <= NULL → 0 macro-rader (alla 8 features None)

                            Testresultat: 73 pytest passed, 5 skipped; fourier_features_upserted=580 mot riktig DB; 2-pass/single-pass ger samma 14 471 trÀningspar.


                            OBS: Beta-semantiken Ă€ndrades (DB-brett vs in-sample per chunk). Sparade modeller bör trĂ€nas om frĂ„n scratch — warm-start mot gamla vikter ger inkonsistent normaliseringsstatistik.


                            35.23 Opus-5 code review, runda 2 (commit 7eddbfa) — 9 buggar, 16 lĂ€ckor, 4 prestanda


                            TvÄ parallella Opus-5-agenter granskade 12 filer (9 070 rader). Alla fixes verifierade (52 pytest pass).


                            Pipeline-agent (calculate_all_indicators, paper_trading_sim, calculate_signals_py, oos_walkforward, order_manager, combination_backtest, simulate_portfolio):


                            Kritiska buggar:

                            • order_manager._get_db(): returnerade PooledConn utan .cursor()/.close() → AttributeError → lease_connection()
                            • calculate_signals_py: enkeltrĂ„dad vĂ€g injicerade inte prev_psar_trend → olika sell_percent beroende pĂ„ körvĂ€g
                            • simulate_portfolio: slutstĂ€ngning till entry_price vid icke-handelsdag → fel CAGR/slutvĂ€rde
                            • combination_backtest: C-vĂ€gen saknade years<0.5-spĂ€rr → inkonsistens mot Python-fallback
                            • order_manager: is_paper saknades i SELECT (alltid 1); cancel_order utanför try

                            MinneslÀckor: cursors aldrig stÀngda i oos_walkforward (3), calculate_all_indicators (4), paper_trading_sim._lock_fh, simulate_portfolio conn, combination_backtest._run


                            Prestanda: paper_trading_sim drog hem ~200k rader istf SQL-filter; simulate_portfolio O(kandidater×positioner)→inkrementell


                            Core-infra-agent (neural_network, backtest_engine, db_pool, api):


                            Kritiska buggar:

                            • backtest_engine: start_date i JOIN-villkor istf WHERE → hela historiken laddades alltid
                            • api: Any-annotation utan import → NameError vid FastAPI-uppstart
                            • backtest_engine._LeasedPoolConnection.getattr: oĂ€ndlig rekursion vid pool-init-fel
                            • neural_network.predict_all: read_conn lĂ€ckte + NameError i finally

                            MinneslÀckor:

                            • db_pool: atexit.register(close_pool) Ă€rvs av fork:ade workers → COM_QUIT pĂ„ förĂ€lderns sockets → fix: os.register_at_fork(after_in_child=_reset_after_fork)
                            • backtest_engine.run_all/print_summary: conn-lĂ€ckor vid exceptions
                            • api.serve_log/_get_alerts: read_text() lĂ€ste hundratals MB per anrop → tail-lĂ€sning (2 MB / 256 kB)
                            • api.login_cancel: frigjorde inte qr_b64 (helsides-PNG i base64 kvar tills nĂ€sta login)

                            Prestanda: backtest_engine O(NÂČ) as_completed-loop → wait(FIRST_COMPLETED)


                            35.24 SchemalÀggning: nn_all borttaget, mÄnadslig djupkörning (commit 7beac61)


                            Problem: nn_all (10 epochs, ingen pretrain-fas) körde varje vardagsnatt parallellt med nn_nightly (30 epochs, 7-Ă„rs pretrain). nn_nightly överskrev alltid nn_all:s modeller → nn_all var helt meningslöst i vardagspipelinen. Med 6 shards pĂ„ bigrig förbrukade det onödigt ca 1h klusterkapacitet per kvĂ€ll.


                            Ny schemalÀggningsstrategi:


                            SchemaJobbKonfiguration
                            MĂ„n–Fre natt ≄20:00nn_nightly (6 shards + koordinator)30 epochs, resume=1, 5-Ă„rs rullande fönster
                            Normala lördagar ≄20:00nn_nightly (helg-profil)30 epochs, alla targets inkl. prob_global
                            Första lördagen/mĂ„naden ≄20:00nn_nightly_monthly (6 shards + koordinator)50 epochs, resume=0 (tvingar omtrĂ€ning av alla tickers)
                            Manuellt (vid behov)nn_all10 epochs, ingen pretrain — kvar för: ny tom DB, kritisk bug-fix, ny server

                            Tekniska Àndringar:

                            • run_nn_nightly.sh: NN_DEEP_RETRAIN=1 → RESUME=0, EPOCHS=50, PROFILE=*-deep
                            • submit_job.sh: nn_nightly_monthly_s0..s5 + koordinator (42s stale=43200s)
                            - submit_job.sh: alla QUEUE_DEPENDS: nn_nightly → `nn_nightlynn_nightly_monthly` (OR-syntax)
                            - queue_worker.sh: ny OR-operator `` i DEPENDS-parsern (minst ett alternativ rÀcker)
                            • scheduler.sh: nn_all-shards borttagna; ny lördag-sektion + FIRST_SATURDAY-detektion (WEEKDAY=6 && DAY_OF_MONTH <= 7)

                            35.25 Open items §12 + Opus-5 runda 3 (commits bd26586, 470bcd7)


                            Implementerade open items (commit bd26586):


                            • oos_walkforward.py: load_ticker_window laddar nu oos_start-10d → oos_end istf 5 Ă„r (~20× mindre DB-IO). OOS-radfiltret rĂ€knar specifikt OOS-rader (< 30) för att exkludera nylistade tickers korrekt.
                            • paper_trading_sim.py: Borttagit brutet SELECT FOR UPDATE-block — NFS-flocken hindrar redan parallell Ă„tkomst per konto.
                            • combination_backtest.py: combo_id VARCHAR(120)→160, [:120]→[:160]. ALTER TABLE applicerat. 4 orphan-rader (truncerade 120-char nycklar) identifierade och raderade.
                            • neural_network.py: Pre-clip X_reordered till ±1e6 + stds_arr=0-skydd (felaktig initiell version, Ă„tgĂ€rdad i commit 470bcd7).
                            • calculate_all_indicators.py: STL sĂ€song O(N×365) Python-loop → O(N) collections.deque per veckodag.

                            nn-conn-open + deferred-ram (§27.1, §27.3): Inspekterade — bĂ„da redan Ă„tgĂ€rdade. Anslutning stĂ€ngs vid rad 4295 (innan trĂ€ningsloop); deferred_rows Ă€r begrĂ€nsad till ~20k rader via chunk-flush.


                            Opus-5 granskning runda 3 (commit 470bcd7) — kritiska och höga fynd:


                            FilAllvarFyndFix
                            neural_network.pyCRITICAL±1e6 clip förstörde obv/ad_line/pvt (~1e10 → konstant)Ändrat till ±1e15 (enbart inf-skydd)
                            neural_network.pyHIGHTrain/serve-skev: clip saknade i predict_allLagt till ±1e15-clip före normalisering i predict_all
                            oos_walkforward.pyHIGH3-dagars warmup tĂ€cker inte helgdagskluster (pĂ„sk/jul)Ändrat till 10 dagar
                            oos_walkforward.pyHIGHlen(rows)<5 accepterade nylistade tickers → CAGR=999999.99OOS-rĂ€kning specifik + threshold 30
                            neural_network.pyLOWnp.where(stds_arr>0) skyddar inte mot denormala stdsnp.maximum(stds_arr, 1e-9)
                            paper_trading_sim.pyMEDIUMDubbel SELECT (dead code) + no-op rollbackSELECT borttaget, rollback kommenterat

                            BekrÀftade korrekta av Opus-5:

                            • STL-deque: bit-identiska vĂ€rden mot original (A/B-test 800 börsdagar)
                            • X_reordered clip in-place Ă€r sĂ€kert (double fancy-index = kopia, ej view)
                            • VARCHAR(160) rĂ€cker (max verkligt length = 123)
                            • oos_walkforward prev_*-lookback: exakt 1 tidigare rad rĂ€cker

                            KvarstÄende medium-issues (ej akuta):

                            • NFS-flock pĂ„litlighet: verifiera att ingen nod monterar /shared med nolock (alternativ: MariaDB GET_LOCK())
                            • open(_lock_path, "w") → "a" + makedirs för robusthet pĂ„ ny nod
                            • neural_network.py:3223: naiv variansformel E[xÂČ]-E[x]ÂČ kan förlora precision för stora obv-vĂ€rden (float64, ~1e20); root cause bakom overflow-varningarna

                            35.26 Opus-5 indikatormatematik-granskning (commit fe6497a)


                            Opus-5 verifierade alla ~100 indikatorer mot standardreferenser (RSI/ADX bit-exact, A/B-test 400 barer). 2 kritiska C/Python-divergenser + 8 medium-buggar fixade.


                            Kritiska (C/Python-divergenser — vĂ€rden skilde sig beroende pĂ„ om indicators.so laddades):


                            IndikatorBuggFix
                            hist_vol_5/20/60C: population var /period; Python: sample /n-1)C Ă€ndrat till /(period-1)
                            keltner_upper/lowerC: ATR(20); Python-fallback: ATR(14) → 381/400 barer skildePython berĂ€knar nu atr20, fallback anvĂ€nder ATR(20)

                            Medium-buggar i Python:


                            IndikatorBuggFix
                            aroon_up/downC: 26-bars fönster (j<=period); Python: 25C Àndrat till j<period
                            psar_trend/psarEP uppdaterades FÖRE reversal-test → fel SAR-vĂ€rde pĂ„ utomstĂ„ende barerReversal check FÖRE EP-uppdatering (C + Python)
                            fisherAnvÀnde highs[i] istf median price (H+L)/2; saknade 0.33/0.67 EMA-glÀttningKorrigerat till Ehlers original
                            hurst_100Shadowing-bugg: var = sum(d*d for d in chunk) (E[xÂČ] ≠ variance)sum(d*d for d in dev)
                            cvar_5pct_63Off-by-one: _wr[:_idx] exkluderade VaR-observationen_wr[:_idx+1]
                            sortino_63Downside-std delade med len(_neg) istf len(_wr) → systematiskt för hög Sortino/ len(_wr)

                            BekrĂ€ftade korrekta: SMA/EMA/WMA/DEMA/TEMA/HMA/KAMA/VWMA, RSI (Wilder, bit-exact), MACD/PPO/TRIX/CMO, Bollinger (population std), ATR/TR (Wilder), ADX/+DI/-DI (Wilder, bit-exact), Supertrend, Vortex, OBV/AD/PVT/NVI/MFI/CMF/FI, Ichimoku, Pivot Points, Beta, RÂČ, Z-score m.fl.


                            Inte implementerade: Jensen's Alpha, Treynor Ratio, Psychological Line — saknas helt i koden.


                            VWAP: Kumulativ frĂ„n dataladdningens start (ingen dagsĂ„terstĂ€llning) — dokumenterat och kommenterat. Ändras ej (befintliga ML-modeller trĂ€nade pĂ„ dessa vĂ€rden).


                            ⚠ Konsekvens: IndikatorvĂ€rden för psar, hist_vol_, keltner_, aroon_*, fisher, hurst_100, cvar_5pct_63, sortino_63 Ă€ndras i daily_indicators. KrĂ€ver:

                            1. python3 calculate_all_indicators.py för alla tickers
                            2. ModelomtrÀning via nn_nightly_monthly

                            3. neural_network.py: var < 0-fallback förbÀttrad: std = feature_range/4 (uniform-estimat) istf std = 1.0 vid float64-cancellation pÄ kumulativa volymfeatures (~1e10-skala).


                              backtest-c-core (klart 2026-08-07): simulate() anvĂ€nder nu C-kĂ€rnan (run_simulate()) som primĂ€r sanningskĂ€lla — ej lĂ€ngre shadow-metrics. Se §15 Livehandelssystem och §4.3 Backtesting.




                              36. SystemförÀndringar 2026-08-07


                              Backtest C-kĂ€rna — primĂ€r sanningskĂ€lla


                              backtest_engine.simulate() anvÀnder nu run_simulate() i c_ext/backtest.so som primÀr motor. Python-loopen Àr fallback.


                              Ny funktionalitet i C:

                              • TradeRecord-struct (entry/exit-datum, priser, avkastning)
                              • NĂ€sta-bar-exekvering (next_opens[])
                              • Slippage per köp/sĂ€lj
                              • Positionsfraktioner (pos_fractions[]) — 0.0 hanteras korrekt (ej maskerat)
                              • min_fee_sek absolut courtagetröskel
                              • Sharpe med konfigurerbar rf_daily

                              TransaktionssÀkerhet (autocommit-fix)


                              db_pool.py kör autocommit=True. commit()/rollback() Àr no-ops utan conn.begin(). Fixat i:

                              • order_manager.py: sync_order_status() + _update_position_on_fill() — atomisk fill+position
                              • morning_signals.py: DELETE + INSERT i en transaktion — förhindrar signalförlust vid krasch
                              • signal_executor.py: conn.begin() aktiverar FOR UPDATE — förhindrar dubbelköp pĂ„ klustret

                              SĂ€kerhet


                              • api.py: /aktieanalys/status korrekt skyddad med _require_api_key
                              • db_pool.py: _ALLOWED_SESSION_VARS whitelist mot SQL-injektion i SET SESSION
                              • database.py: URL.create() för lösenordsmaskering i SQLAlchemy-URL

                              Live trading-modul


                              Komplett live-handelslager mot Nordnet implementerat och dokumenterat (§15):

                              • nordnet_trader.py, order_manager.py, risk_manager.py, trading_killswitch.py
                              • Stop-loss nollas vid fill (ej vid order-placement)
                              • filled utan fill_price → behĂ„ller status placed
                              - `client_order_id = sha1(tickersidevolumetimestamp)[:16]` med mikrosekunder

                              Signal executor


                              • FOR UPDATE aktiverat med conn.begin() — lĂ„s hĂ„ller under hela order-loopen
                              • available_cash -= volume * limit (ej referenspris) — korrekt kapitalbudget
                              • conn = None guard — förhindrar NameError vid pool-timeout

                              Övrigt


                              • database.py: NaN-guard (indicators/signals skrivs bara om kolumner finns), tz_convert(UTC) istf tz_localize
                              • db_utils.py: execute_batch() returnerar (0, conn) vid tom lista
                              • simulate_portfolio.py: pending_buys D+1, morning-only-filter
                              • simulate_orb_portfolio.py: pending_entries nĂ€sta bar, DAY_END 17:25
                              • materialize_nn_features.py: to_date = date.today() - timedelta(days=1) i both daily_update() och main()

                              Runda 11 — 2026-08-07


                              • morning_signals.py: Dead DB-dict borttagen
                              • signal_executor.py: Dead DB-dict borttagen
                              • generate_day_signals.py: Dead DB-dict borttagen; --days default Ă€ndrat None→30 (OOM-skydd); rows = None efter gruppering (RAM-frigöring)
                              • paper_trading_sim.py: qty_by_risk=0 → continue (skippar trade) — förhindrar att risk-cap-buget kringgĂ„s
                              • neural_network.py: _ping_reconnect() kallas var 5:e epoch — skyddar mot MariaDB wait_timeout vid lĂ„ng trĂ€ning
                              • nordnet_trader.py: Reconciliation matchar reference OR identifier+side (fallback för Ă€ldre ordrar)
                              • tests/test_backtest_engine_unittest.py: Mock-nycklar korrigerade (cagr ej cagr_pct); _simulate_with_c_fast mockas i fallback-tester

                              Runda 12 — 2026-08-07 (kritiska regressionsbuggar)


                              🔮 Kritisk regression C1 — signal_executor.py: _audit() anropade conn.commit() pĂ„ transaktions-conn (den som hĂ„ller FOR UPDATE-lĂ„s). Första audit-commit i signalloopen (vid risk-avslag, orderlĂ€ggning eller fel) frigav lĂ„sen pĂ„ alla Ă€nnu obehandlade signalrader → andra noder sĂ„g olĂ„sta signaler → dubbelköp. Fix: _audit() anvĂ€nder nu pool_connection() (separat anslutning, ingen commit() pĂ„ transaktions-conn).


                              🔮 Kritisk regression C2 — database.py: signal_cols definierades pĂ„ rad 194 men anvĂ€ndes pĂ„ rad 191 (present_sig = [c for c in signal_cols ...]). UnboundLocalError fĂ„ngades tyst av except → save_normalized_data() returnerade False för varje batch. All daglig pris/indikator/signal-ingest via DatabaseSaver var trasig sedan C2-fixen i runda 8. Fix: signal_cols-blocket flyttat före present_sig.


                              • morning_signals.py: _refresh_materialized_for_date() och INSERT sammanslagna i en conn.commit() (atomisk — förhindrar tom materialiserad tabell vid krasch)
                              • api.py: hmac.compare_digest() istf != för API-nyckeljĂ€mförelse (timing-sidokanal)
                              • c_ext/backtest.c: max_trades-parameter tillagd; bounds-check n_tr < max_trades före varje skriv till trades_out (skyddar mot heap-overflow)
                              • c_ext/Makefile: backtest.so lagd i all-target

                              Runda 13 — 2026-08-07 (NN RAM + NPZ)


                              neural_network.py — deferred_rows OOM eliminerad: _load_training_data_single_pass() ackumulerade tidigare alla trĂ€ningsrader i deferred_rows[] för att kunna berika med syntetiska features (beta, makro). Peak-RAM = O(alla rader). Fix: macro_map och beta_map förhĂ€mtas en gĂ„ng frĂ„n DB (_load_macro_asof_map + _load_ticker_beta_map(lookback_days=504)). Berikning sker direkt per chunk i streamingloopen → peak-RAM = O(fetch_chunk).


                              neural_network.py — checkpoint-format JSON→NPZ: save_checkpoint_file() och load_checkpoint_file() anvĂ€nder nu numpy.savez_compressed. MLP-vikter (W, b, mW, vW, mb, vb, best_W, best_b) sparas som float32 numpy-arrays → 3–15× komprimering mot JSON-text. BakĂ„tkompatibilitet: faller tillbaka pĂ„ .json om .npz saknas. checkpoint_path() returnerar nu .npz-suffix.


                              simulate_portfolio.py: getattr guard — if name in ('_cm', '_conn'): raise AttributeError(name) — förhindrar RecursionError vid partiellt misslyckad init.


                              NN-retrain och regelkörning — 2026-08-07


                              nn_models, nn_weights, nn_predictions truncatades och alla gamla .json-checkpoints raderades. Kedja submittat i /shared/bin/chain_rerun_all.sh (bakgrundsdemon):

                              1. ind_backfill — calculate_all_indicators.py --since 1999-01-01 (alla tickers, hela historiken)
                              2. calculate_signals — daily_signals för alla tickers
                              3. backtest — alla strategier för alla tickers
                              4. nn_all × 6 shards (parallell trĂ€ning med korrekt indikatordata)

                              5. Runda 14 — 2026-08-07


                                • simulate_portfolio.py M6: getattr guard — if name in ('_cm', '_conn'): raise AttributeError(name) — förhindrar RecursionError vid partiellt misslyckad init eller unpickling
                                • API omstartad (aktieanalys-api.service) — plockar upp runda 10–13 kodĂ€ndringar
                                • paper_trading_sim.py omstartad via run_paper_daytrading.sh
                                • /shared/bin/chain_rerun_all.sh startad som bakgrundsdemon (PID 711044)

                                Runda 15 — 2026-08-07 (simuleringsgranskning)


                                backtesting.py — PostgreSQL-prototyp, ej importerad i produktion:

                                • C1: capital -= position * price saknades vid entry → equity dubbelrĂ€knades (~2×) under öppen position → total_return, Sharpe och max drawdown var felaktiga
                                • M1: equity[:-1] → equity[1:] i plotten (off-by-one — sista datapunkten saknades, kurvan skiftad)
                                • M2: Sharpe berĂ€knades pĂ„ per-trade-returer med sqrt(252)-annualisering → meningslös siffra; nu berĂ€knat pĂ„ dagliga equity-returer (np.diff(equity)/equity[:-1])
                                • C2-varning: Queryn hĂ€mtar alla tickers i en blandad prisserie → entry-pris kan tillhöra ticker A och exit-pris ticker B. Dokumenterat som arkitekturfel i docstring. Korrekt backtest: se backtest_engine.py.

                                simulate_day_portfolio.py:

                                • H1: vid dagsslut (is_day_end) tvĂ„ngsstĂ€ngs nu position Ă€ven nĂ€r idx_now is None (illikvid aktie utan bar vid exakt klockslag) — förhindrar övernattpositioner mot daytrading-reglerna
                                • H2: conn = _lease_pool_connection() wrappas nu i try/finally med conn.close() — förhindrade connection-lĂ€cka vid exception i laddning/simulering
                                • M4: Dead DB-dict borttagen (anvĂ€ndes aldrig — allt gĂ„r via pool_connection)

                                Scheduler inaktiverad 2026-08-07 kvÀll


                                scheduler.sh stÀngdes av i crontab (3 rader kommenterade ut med #DISABLED_TONIGHT) för att förhindra att nn_nightly trÀnar pÄ tom nn_models-tabell (truncatad i samband med full omtrÀning). Backup: /tmp/crontab_backup_20260807_171809.txt. Aktiveras manuellt imorgon via crontab -e.


                                schema.sql synkad med live DB — 2026-08-07


                                schema.sql (skapar ny tom DB) var ofullstÀndig; 5 tabeller och 8 vyer fattades. Tillagda:


                                Tabeller:

                                • api_health — per-source hĂ€lsostatus (last_ok, last_fail, consecutive_fails, status)
                                • daily_fundamentals — dagliga fundamentaldata per ticker (pe_ratio, dividend_yield)
                                • nn_champion_history — historik om vilken modell var champion per snap_date+ticker+target
                                • queue_jobs — DB-spegel av NFS-jobbkö (synkas av worker, stödjer beroenden + prioritet)
                                • sim_horizon_results — simuleringsresultat per horisont/tröskelvĂ€rde

                                Vyer:

                                • v_active_tickers — aktiva tickers (ticker_universe.is_active = 1) med namn/sektor
                                • v_best_nn_model — senaste modell per target+ticker (max train_to, sedan max id)
                                • v_latest_indicators — senaste daily_indicators-rad per aktiv ticker
                                • v_latest_signals — senaste daily_signals-rad per ticker
                                • v_latest_nn_predictions — senaste prediction per ticker+target frĂ„n bĂ€sta modell med predictions
                                • v_morning_signals_live — morning_signals joinad med senaste NN-prediktioner (alla 6 targets)
                                • nn_predictions_strict_oos — predictions efter modellens train_to (riktig OOS, ej lĂ€ckage)
                                • nn_conf_calibration_3y — kalibreringsbins 0.0–1.0 (0.1-steg) för NN-confidence de senaste 3 Ă„ren

                                GT610-verifiering och gpu_accelerator-buggfix — 2026-08-07


                                GPU-implementationerna (commit 64d45cb) verifierades pĂ„ work733/GT610 — 18/19 tester gröna (1 CUDA-test skipped, vĂ€ntat).


                                Bugg funnen och fixad: _cpu_rule_scores i gpu_accelerator.py klampade inte fou_b till [-1, 1] som GPU-kerneln gör via align = clamp(fou_b, -1, 1). Vid `fou_b> 1 gav GPU och CPU-fallback olika resultat. Fix: np.clip(fou_b, -1.0, 1.0)` i CPU-fallbacken.

                                Prestandaresultat pÄ GT610:

                                • batch_rule_scores N=120: GPU 1.9ms vs CPU 0.9ms → GPU 2x lĂ„ngsammare för typisk pipelinestorlek
                                • batch_combo_eval 500 kombos: GPU 12ms vs CPU 29ms → +2.3x
                                • batch_combo_eval 5000 kombos: GPU 97ms vs CPU 306ms → +3.2x

                                combination_backtest.py testas hundratals–tusentals kombinationer → GT610 ger tydlig vinst.


                                weekend_chain PREFER Ă€ndrat: bigrig → gt610 — jobbet routas nu till work733/GT610 (primĂ€r), bigrig/GTX1070-OpenCL (300s fallback), pi/CPU (600s fallback).


                                browser_session_daemon + fetch_avanza — granskningsfynd fixade 2026-08-07


                                browser_session_daemon.py:

                                • M1: read_text() saknade encoding="utf-8" — kan ge korruption pĂ„ non-UTF8 locale
                                • M2: _touch_nordnet PUT saknade Content-Length: 0 — CDN kan returnera 411 Length Required

                                fetch_avanza_intraday_quotes.py:

                                • M3: conn.commit() (×2) Ă€r no-ops med autocommit=True utan conn.begin() — dokumenterade
                                • M4: ensure_schema() dokumenterad — kanonisk DDL finns i schema.sql (ska hĂ„llas synkade)
                                • M5: to_dt() anvĂ€nde systemets lokaltid istf explicit Europe/Stockholm — kan ge fel bar_time vid DST-skiften om system ej Ă€r Stockholm
                                • M6: .avanza_cookies bytte format pickle → JSON (save_avanza_session.py + fetch_avanza_intraday_quotes.py) — eliminerar RCE-risk via untrusted pickle-fil

                                tests/test_bug_fixes_unittest.py: test_urlexception_triggers_reconciliation mockade ej check_market_hours/is_trading_enabled → kraschade automatiskt efter börsstĂ€ngning kl 17:30. ÅtgĂ€rdat.


                                api.py ETA-fix för work733-jobb — 2026-08-07


                                _parse_log_ts() i api.py matchade ej work733:s loggformat Thu 06 Aug 2026 12:03:32 AM CEST (Swedish fĂ€ltordning men 12h AM/PM-suffix). Varken SV 24h-regex (nekar AM/PM via negativ lookahead) eller US-regex (fel fĂ€ltordning DD/MON) matchade → _historical_duration_secs() returnerade None → ETA visades som "–" för alla jobb körda pĂ„ work733 (data_pipeline, calculate_signals, morning_signals m.fl.). Fix: nytt _LOG_TS_RE_SV_12H-regex hanterar formatet. API omstartad.


                                Sektion 36 — Uppdateringar 2026-08-07 (natt) — NN retrain pipeline + logrotate


                                36.1 NN retrain pipeline — nn_all (full retrain)


                                FullstÀndig körning av nn_all (6 shards, alla tickers) kördes för första gÄngen pÄ ny infrastruktur. Flera kaskadfel hittades och fixades:


                                queue_worker.sh — odefinierade variabler (commit d4e7afa)


                                POLL_INTERVAL, HEARTBEAT_STALE, NFS_TIMEOUT anvÀndes men definierades aldrig. Med set -euo pipefail orsakade detta crash-loop (exit 1 vid varje start). Jobb pickades upp men startade aldrig. Fix: konstanter tillagda med defaults:


                                POLL_INTERVAL=10
                                HEARTBEAT_STALE=300
                                NFS_TIMEOUT=10
                                

                                neural_network.py — NoneType crash vid 0 datarader (commit d4e7afa)


                                _load_training_data_single_pass returnerade None nÀr 0 rader laddades. Fix: early return ([], {}, list(feature_cols)).


                                neural_network.py — SSDictCursor + conn-konflikt (commit 4c35b62, KRITISK)


                                Root cause: _load_macro_asof_map(conn) och _load_ticker_beta_map(conn) anropades EFTER att SSDictCursor öppnats men INNAN fetchmany(). ReguljĂ€ra cursors pĂ„ samma connection Ă„terstĂ€ller streaming-state tyst → 0 rader laddades för ALLA tickers.


                                Fix: Flytta alla förberedande data-laddningar TILL FÖRE conn.cursor(SSDictCursor).


                                Varningssignal: "Previous unbuffered result was left incomplete" i loggen.


                                neural_network.py — ValueError vid stale ticker avbröt hela shard (commit 17f01fd)


                                En enskild ticker med stale data (>10 dagar) höjde ValueError som bröt hela shard-loopen. Fix: try/except ValueError per ticker → SKIP + continue.


                                neural_network.py — INSERT IGNORE för nn_weights + nn_feature_stats (commit 7ced577)


                                IntegrityError: Duplicate entry uppstod vid retry/parallella shards. Fix: INSERT IGNORE pÄ bÄda tabellerna.


                                DB-schema — saknade kolumner i nn_weights


                                ALTER TABLE nn_weights
                                  ADD COLUMN weights_json LONGTEXT,
                                  ADD COLUMN biases_json  LONGTEXT;
                                

                                Python venv 3.11 → 3.12 (bigrig)


                                venv skapades med pyenv 3.11.8 (ej lÀngre installerat). venv/bin/python3 pekar nu pÄ system-Python 3.12. Paket i venv/lib/python3.11/site-packages/ Àr ej importerbara av 3.12.


                                Fix: venv/bin/pip install 'fastapi>=0.115' 'uvicorn[standard]' installerade nya 3.12-versioner. API omstartad.


                                api.py PREFER=bigrig visades som gpu (commit da60c8b)


                                _PART-dict visade "bigrig": "gpu" — fel, bigrig-CPU-workers hanterar ej GPU-jobb. Fix: "bigrig": "cpu", "bigrig_work733": "cpu".


                                36.2 CPU-parallellism för nn_all — utvĂ€rdering


                                Testat: s2–s5 kördes pĂ„ bigrig CPU (PREFER=bigrig) parallellt med s0+s1 pĂ„ GPU.


                                Resultat:

                                ScenarioGenomströmningTotal tid
                                2 GPU-shards~22 mod/minsekventiellt ~36 min/shard
                                2 GPU + 4 CPU~31 mod/min (+41%)CPU-shards ~178 min/shard — bottleneck

                                Slutsats: CPU-parallellism Àr inte effektivare för nn_all. GPU Àr ~5x snabbare per shard. 4 CPU-shards fördröjer slutförandet med +1,5h. CPU-shards avbröts, sekventiell GPU-körning Äterupptogs.


                                36.3 Ködiagnostik — stale running-filer blockerar GPU-slots


                                Problem: Manuell kill av CPU-processer utan att radera running-filer lĂ€mnade 2 stale running-filer med QUEUE_PREFER: gtx1070. GPU-workern rĂ€knar körande slots via grep -rl "^# QUEUE_PREFER: gtx1070" running/ — stale filer blockerade bĂ„da slots.


                                Symptom: 0 köpande processer, jobb fastnar i pending oavsett worker-status.


                                Fix: Ta bort stale running-filer manuellt. I framtiden: housekeeping fÄngar filer vars heartbeat Àr stale >HEARTBEAT_STALE.


                                36.4 deps_satisfied() — mtime-timing


                                deps_satisfied() krÀver done_file_mtime >= job_submission_epoch. Vid manuell touch av done-fil mÄste touch göras EFTER att jobbet submittats (ej före). Annars fastnar jobbet permanent i pending.


                                Workaround: touch /shared/queue/done/<dependency_file> efter varje ny submission-batch.


                                36.5 Logrotation och housekeeping — genomgĂ„ng alla noder (2026-08-07)


                                ÅtgĂ€rdade problem


                                ProblemNodFix
                                .log- stansa re-roterade redan roterade filer → *.log-DATUM-DATUM dubbelnamnbigrig/work733Stansen borttagen frĂ„n /etc/logrotate.d/aktieanalys
                                9 malformade dubbelnamn-filerbigrigRaderade direkt
                                test_results_YYYYMMDD.log saknade rotationallaLade till daily, rotate 14
                                /tmp/aa_queue_*.log saknade rotation pÄ PIpiLade till stans
                                /tmp/qw_pi_new_*.log saknade rotationpiLade till stans
                                VM saknade cron för logrotatevm0 3 * logrotate /etc/logrotate.d/aktieanalys
                                PI saknade daglig logrotate-cronpi0 3 * find /tmp + logrotate
                                housekeeping_work733.sh rensade ej test_resultsbigrigSteg 5c + 5d tillagda

                                Logrotate — aktuell tĂ€ckning per nod


                                NodKonfigKör viaTÀckning
                                bigrig/etc/logrotate.d/aktieanalyshousekeeping_work733.sh 03:30/shared/logs/, /var/log/aktieanalys/, /tmp/trading-daemons
                                work733/etc/logrotate.d/aktieanalyshousekeeping_work733.sh 03:30Identisk med bigrig
                                pi/etc/logrotate.d/aktieanalyscron 0 3 */home/tege/work/python/aa-ai/, /tmp/queue_worker_pi_.log, /tmp/aa_queue_.log
                                vm/etc/logrotate.d/aktieanalyscron 0 3 * (ny)/var/log/aktieanalys/

                                housekeeping_work733.sh — tillagda steg (commit cdd3a48)


                                • 5c: test_results_*.log >14 dagar
                                • 5d: Safety-net — raderar *.log-DATUM-DATUM-dubbelnamn i /var/log/aktieanalys/

                                deploy/-katalog


                                FilBeskrivning
                                deploy/aktieanalys.logrotateKÀlla för bigrig/work733/VM
                                deploy/aktieanalys_pi.logrotateKÀlla för PI (ny)
                                deploy/README.mdInstall-instruktioner

                                Commits: cdd3a48 (logrotate fixes + housekeeping), 74f0cd5 (PI logrotate till repo)


                                36.6 ensure_schema.py — pre-flight DB-schema-check (commit 606483f)


                                Bakgrund: Under nn_all-körningen 2026-08-07 saknades nn_weights.weights_json och biases_json i DB (försvann troligen vid DB-restore). Orsakade Unknown column-krasch.


                                Lösning: tools/ensure_schema.py — verifierar att alla kritiska kolumner finns:


                                python3 tools/ensure_schema.py           # dry-run — visar avvikelser
                                python3 tools/ensure_schema.py --apply   # applicerar ALTER TABLE
                                

                                Körs automatiskt som första steg i nn_all (shard 0) och nn_nightly_s0 via submit_job.sh. Vid avvikelse aborterar jobbet med tydligt felmeddelande.


                                TĂ€ckta tabeller: nn_weights, nn_models, nn_feature_stats, nn_predictions


                                36.7 simulate_portfolio + rolling_1month_sim efter paper_predict


                                Simuleringsjobbens QUEUE_DEPENDS Àr redan konfigurerade mot paper_predict,paper_predict_s1,..,s5. Submittas manuellt direkt efter nn_all (eller kan lÀggas i scheduler):


                                bash /shared/bin/submit_job.sh simulate_portfolio
                                bash /shared/bin/submit_job.sh rolling_1month_sim
                                

                                Kedja denna kvÀll:

                                nn_all s0–s5 (GPU) → paper_predict ×6 (GPU) → simulate_portfolio + rolling_1month_sim (bigrig_work733)
                                                                              → morning_signals (bigrig)
                                

                                36.8 nn_predictions_strict_oos — beteende direkt efter nn_all-retrĂ€ning


                                VIEW-definition: SELECT ... FROM nn_predictions np JOIN nn_models nm ON np.model_id=nm.id WHERE np.date > nm.train_to


                                Direkt efter en nn_all-körning Àr vyn tom eftersom:

                                • Alla nya modeller har train_to ≈ senaste handelsdagen
                                • nn_predictions innehĂ„ller bara in-sample-prediktioner (date ≀ train_to)
                                • Strikt OOS-prediktioner genereras av paper_predict frĂ„n nĂ€sta handelsdags prisdata

                                simulate_portfolio hanterar detta automatiskt (sedan dfa8042): om strict_oos Àr tom för perioden faller den tillbaka pÄ in-sample-prediktioner med tydlig VARNING i loggen. Strict OOS byggs upp organiskt efter varje handelsdags paper_predict-körning.


                                36.9 rolling_1month_sim — vikter och active_weights.json


                                run_rank_weight_weekly.sh sparar vikter i $RANK_WEIGHT_OUTPUT_DIR (default: /shared/logs/aktieanalys/rank_weight/). tools/rolling_1month_sim.py lĂ€ser nu samma env-variabel — bĂ„da pekar pĂ„ /shared/logs/aktieanalys/rank_weight/active_weights.json.


                                Tidigare fel: hardkodad sökvĂ€g /var/log/aktieanalys/rank_weight/ (lokal bigrig-disk, ej NFS) → FEL: vikter saknas. Fixat i dfa8042.


                                36.10 Queue-worker: mtime-deps efter manuell re-submission


                                Om jobb re-submittats manuellt (t.ex. efter felsökning) och beroende done-filer skapades före den nya submissionen, fastnar beroende-jobb i pending. Fix:


                                touch /shared/queue/done/<jobnamn>_*.job
                                

                                GÀller t.ex. nn_nightly-done-fil som morning_signals beror pÄ, eller paper_predict-done-filer som simulate_portfolio beror pÄ. Inkluderat i felsökningsrutinen.


                                37. Arkitektur- och driftuppdateringar 2026-08-10


                                37.1 Queue-system — deps_satisfied med 12h-fönster


                                Detta ersÀtter den Àldre beskrivningen i §35.2, §36.4 och §36.10 dÀr beroenden enbart kopplades till jobbets submission-tid.


                                • Gammal logik: cutoff = job_epoch - 60 — done-markören mĂ„ste i praktiken vara skapad efter att koordinatorjobbet submitades (med 60s slack).
                                • Problem: beroendejobb kan bli klara innan koordinatorn submitas, bĂ„de vid normal pipeline och vid manuell bootstrapping/re-submission.
                                • Ny logik i queue_worker.sh: cutoff = now - 12*3600 — en beroende-markör godkĂ€nns om den skapats inom de senaste 12 timmarna rĂ€knat frĂ„n nu.
                                • Varför 12h: nattliga jobb hinner normalt klart inom samma dygn, men gĂ„rdagens markörer blockeras fortfarande.
                                • Detta Ă€r inte en Ă„tergĂ„ng till det gamla 72h-fallbacket; fönstret Ă€r kortare och knutet till aktuell tid, inte till gĂ„rdagens coordinator-run.

                                37.2 Noder, GPU:er och PREFER-routing (korrigerad matris)


                                NodWorker-rollerKommentar
                                work733CPU-workers + 1 GT610-workerOpenCL/GT610-jobb körs hÀr primÀrt
                                bigrigCPU-workers + GTX1070-workersPrimÀr nod för GPU- och tyngre DB-jobb
                                raspberrypi1 CPU-worker endastIngen pymysql, ingen GPU

                                PREFER-vÀrden:


                                • bigrig_work733 = bigrig (0s) → work733 (3600s), raspberrypi hoppas alltid av.
                                • bigrig_only = enbart bigrig.
                                • Jobb som krĂ€ver pymysql (t.ex. nn_wf_oos_sim, oos_walkforward_full) ska routas med bigrig_work733.

                                Detta förtydligar varför Pi inte lÀngre anvÀnds som fallback för x86-/DB-beroende jobb trots att den fortfarande kan köra enklare CPU-arbete.


                                37.3 WF NN-pipeline (Walk-Forward Neural Network)


                                Persistenslager:

                                • Tabeller: nn_models_wf, nn_model_registry_wf, nn_predictions_wf, nn_weights_wf, nn_feature_stats_wf
                                • Vy: nn_predictions_wf_oos — filtrerar bort prediktioner som ligger i modellens trĂ€ningsfönster

                                Cykler:

                                • 9 cykler Ă  3 mĂ„nader
                                • TidsomfĂ„ng: aug 2023 → aug 2026
                                • Ny cykel öppnas varannan kvartal

                                Jobb i kedjan:

                                • nn_wf_train_s0
                                • nn_wf_train_s1
                                • nn_wf_predict_repair
                                • nn_wf_oos_sim

                                Bugfix 2026-08-10: predict-steget genererade in-sample-datum i stĂ€llet för predict-fönstret för cykel 5–9. ÅtgĂ€rd:

                                • 575k felaktiga prediktioner rensades bort
                                • nn_wf_predict_repair.sh uppdaterades sĂ„ att samtliga 7 repair-cykler tĂ€cks

                                37.4 GPU-validering i trÀningsloopen (neural_network.py)


                                MLP har nu en separat GPU-vÀg för validering via _validate_on_gpu().


                                • Returnerar summor, inte medelvĂ€rden: loss_sum, n, correct, ss_res, ss_tot
                                • Cache-nyckel: f"{run_id}:val{fold_idx}" — stabil inom samma körning
                                • Epoch-loopen provar GPU fast-path först och faller tillbaka till CPU om _torch_model is None
                                • Tillhörande runtime-fĂ€lt: _torch_val_X, _torch_val_Y, _torch_val_token
                                • Dessa rensas i clear_runtime_caches()

                                Syftet Àr att hÄlla valideringen pÄ GPU hela vÀgen nÀr Torch-backend anvÀnds, utan att förÀndra de aggregat som redan anvÀnds för metrics.


                                37.5 Dashboard — per-process CPU% i api.py


                                CPU-visningen pÄ status/dashboard-sidan har förtydligats:


                                • Gammal metod: ps -o comm trunkerade processnamn till ~15 tecken, vilket ofta bara gav python3
                                • Ny metod: _PS_AWK (samma modell som SSH-versionen) extraherar full command line
                                • _build_node_proc_cpu() matchar signaturer som slutar pĂ„ .py och summerar subtree-CPU% per script
                                • _node_cell() i status_page() lĂ€ser frĂ„n _proc_cpu_map.get(node, {}).get(cmd_sig)

                                Effekt: statussidan visar CPU-förbrukning per faktisk Python-process i stÀllet för generiska python3-rader.


                                37.6 schema.sql synkad med live DB — 2026-08-10


                                schema.sql Àr nu uppdaterad mot live-MariaDB och innehÄller 65 tabeller och 9 vyer.


                                Tillagt:

                                • nn_models_wf
                                • nn_model_registry_wf
                                • nn_predictions_wf
                                • nn_weights_wf
                                • nn_feature_stats_wf
                                • paper_ab_reports
                                • vyn nn_predictions_wf_oos

                                Borttaget:

                                • 2 duplikat-vyer med hĂ„rdkodat datum

                                37.7 schema_postgres.sql — PostgreSQL-kompatibelt schema


                                Ny fil: schema_postgres.sql.


                                • Synkad med MariaDB-versionen av schema.sql
                                • InnehĂ„ller 65 tabeller, 9 vyer och samtliga WF-objekt
                                • PostgreSQL-anpassningar: JSONB i stĂ€llet för JSON, SERIAL i stĂ€llet för AUTO_INCREMENT m.m.
                                • Applicerad pĂ„ analys-VM:n 2026-08-10

                                37.8 PostgreSQL pÄ ubuntu24.10-VM


                                • VM: ubuntu24.10 (virsh-namn), körs som KVM-gĂ€st pĂ„ bigrig
                                • IP: 192.168.122.87
                                • Version: PostgreSQL 16.14
                                • Databas: aktieanalys
                                • AnvĂ€ndare: maria / tommy167
                                • pgAdmin4 (snap): pgadmin4@pgadmin.org / tommy167
                                • Status: schema applicerat 2026-08-10
                                • PĂ„gĂ„ende arbete: migrering frĂ„n MariaDB via pgloader / mysqldump



                                38. Driftuppdateringar 2026-08-12


                                38.1 Raspberrypi worker inaktiverad


                                Pi orsakade upprepade failures och felrouting av NN-jobb (ARM-inkompatibel x86-venv, tog PREFER=cpu-jobb):


                                • Flaggfil /shared/queue/worker_disabled_raspberrypi skapad — queue_worker.sh kontrollerar denna vid start och avslutar omedelbart med exit 0.
                                • queue_worker.sh uppdaterad: ny check i toppen (if [[ -f "/shared/queue/worker_disabled_${NODE}" ]]; then exit 0; fi).
                                • Pi crontab uppdaterad: ensure_workers.sh-raderna (@reboot + */5) bortkommenterade.
                                • aa-queue-worker@cpu.service pĂ„ pi stoppad (mask lyckades inte pga saknad sudo — disable-flaggan Ă€r den effektiva mekanismen).

                                Reaktivering: rm /shared/queue/worker_disabled_raspberrypi + reenable crontab (crontab -e pÄ raspberrypi) + systemctl start aa-queue-worker@cpu.service.


                                38.2 PREFER-routing rÀttad i submit_job.sh


                                Alla jobbtypers PREFER korrigerade frÄn felaktiga vÀrden:


                                JobbtypGammalt PREFERNytt PREFERAnledning
                                nn_all_s0–s5gtx1070 / cpubigrigcpu-token tillĂ€t pi (30s vĂ€ntan); gtx1070 slösade GPU-slots
                                nn_nightly_s0–s5, koordgtx1070bigrig_work733pi exkluderas permanent
                                nn_nightly_monthlygtx1070bigrig_work733samma skÀl
                                paper_predict_s0–s5gtx1070bigrig_work733x86-venv, ARM-inkompatibelt
                                oos_walkforward, _blankslategtx1070bigrig_work733samma skÀl

                                nn_all anvĂ€nder NN_BACKEND=c_ext (CPU-trĂ€ning) — GTX1070 gav inget genomströmningslyft för dessa modellstorlekar ([96, 256, 128, 64, 3]).


                                38.3 npz-regression reparerad (commit fdf407c, 2026-08-07)


                                Commit fdf407c (2026-08-07) raderade av misstag 1368 rader ur neural_network.py inklusive hela npz-arkitekturen:


                                • _weights_path() — sökvĂ€g till .npz-fil per model_id
                                • _save_weights_file() / _load_weights_file() — atomisk npz-skrivning + JSON-fallback
                                • _MODEL_CACHE (LRU, 50 modeller) — förhindrar upprepad disklĂ€sning
                                • _sf() — feature-skalning med NaN/Inf-skydd
                                • _trim_process_memory(), _ensure_conn(), _merge_with_retry()

                                2273 .npz-filer i /shared/models/nn_weights/ var otillgÀngliga. Allt ÄterstÀlldes i commit 99baa71.


                                38.4 Bugfixar i neural_network.py (2026-08-12)


                                • INSERT IGNORE pĂ„ nn_feature_stats: förhindrar IntegrityError: Duplicate entry nĂ€r jobb körs om med befintliga stats (PRIMARY KEY: model_id + feature_name).
                                • save_model: isinstance(st, dict)-filter för metadata-nycklar i stat_rows.
                                • load_model: ValueError vid NULL weights_json (moderna modeller har vikter pĂ„ disk).
                                • predict_all: try/except sĂ„ korrupta modeller hoppas över utan att avbryta shard.
                                • datetime.utcnow() → datetime.now(timezone.utc) (4 platser, deprecation-fix).
                                • conn.ping(reconnect=True) → conn.ping() (2 platser).
                                • npz-namnkollision: nn_models_wf-modeller fĂ„r prefix i _weights_path för att undvika krock med nn_models.
                                • warm-start deepcopy: förhindrar att warm-start-vikter modifieras in-place under trĂ€ning.

                                38.5 Dashboard — per-jobb CPU% via /proc/PID/environ


                                api.py lÀser nu exakt CPU% per NN-shard (inte nod-aggregat):


                                1. queue_worker.sh skriver QUEUE_CHILD_PID: $BASHPID till jobbfilen vid pickup.
                                2. api.py._parse_job_file() lÀser QUEUE_CHILD_PID.
                                3. SSH-kommando _NN_SHARD_CMD lĂ€ser NN_TICKER_SHARD_INDEX frĂ„n /proc/<PID>/environ → identifierar rĂ€tt process per shard-index.
                                4. _build_node_proc_cpu() returnerar {_by_shard, _by_pid, _by_comm, _by_comm_count}.
                                5. _hw_cells(): prioritetsordning shard-idx → child_pid → comm/count → nod-nivĂ„.

                                6. 60s loggsynk bakgrundsprocess i queue_worker.sh heartbeat-loopen — ger live framsteg i dashboardens "BerĂ€knad klar"-kolumn.


                                  38.6 Ny handelsstrategi: macd_vol_trend


                                  Implementerad i backtest_engine.py och oos_walkforward.py:


                                  Signal: MACD-kors uppÄt (12/26/9) + SMA50 > SMA200 (trend) + ADX > 22 (styrka) + CMF > 0 (kapitalflöde) + RSI < 65 (ej överköpt)

                                  Exit: MACD-kors nedÄt ELLER RSI > 72 ELLER stop-loss 8%


                                  OOS-resultat (preliminĂ€rt, single-ticker VOLV-B.ST): Sharpe 0.24, CAGR 7.0% vs buy_hold Sharpe 0.22. Full-universum: Sharpe 0.10 (selektiv — behöver fullstĂ€ndig OOS walk-forward för slutsats).


                                  38.7 Dep-fönster utökat till 26h


                                  queue_worker.sh: beroende-fönster utökat frĂ„n 12h till 26h — fĂ„ngar nattjobb som börjar vid 22:00 och vars downstream-jobb körs sent nĂ€sta kvĂ€ll.


                                  38.8 save_checkpoint_file — FileNotFoundError — fixad (commit 960c028)


                                  Root cause: Om tvĂ„ shards trĂ€nar samma ticker+target-kombination (sker i extra-targets-steget), racear de pĂ„ identisk tmp-sökvĂ€g stem.npz.tmp.npz. Shard B skriver/byter namn pĂ„ filen innan Shard A:s os.replace körs → FileNotFoundError.


                                  Fix: tmp-filnamnet inkluderar nu os.getpid() → stem.tmp{PID}.npz — unikt per process. os.unlink av tmp-filen sker vid exception för att inte lĂ€mna skrĂ€p. Commit 960c028.





                                  §39 Regimklassificering och nya handelsstrategier (2026-08-12)


                                  39.1 5-dimensionell regimklassificering


                                  Ny tabell ticker_regime (skapas 2026-08-12) klassificerar varje ticker dagligen lÀngs fem dimensioner:


                                  DimensionKolumnTolkning
                                  ADX 20d snittavg_adx_20Trendstyrka
                                  ATR% 20d snittavg_atr_pctNormaliserad volatilitet
                                  Hurst-exponenthurstH>0.55=trend, H<0.45=mean-rev, H≈0.5=random
                                  Beta vs OMXSPIbeta_omxKorrelation/hÀvstÄng mot index
                                  BB-breddbbwKomprimering (lÄgt) vs expansion (högt)
                                  Autokorrelationautocorr_1dPositiv=momentum, negativ=mean-reversion

                                  Regimer (prioritetsordning):


                                  RegimeKriterierStrategiAntal tickers (2026-08-12)
                                  mean_revertingautocorr < -0.15 ELLER (H<0.45 & ac<0)mean_reversion_bounce67
                                  choppy_flatADX<15 & ATR%<1.5choppy_flat1
                                  momentum_high_betaH>0.55 & beta>1.2 & autocorr>0momentum_high_beta17
                                  breakoutADX>32 & ATR%>2.0 & H>0.50bb_squeeze_breakout21
                                  stable_trendADX>30 (ej breakout)macd_vol_trend15
                                  oscillatingADX<22macd_fast_reversal118
                                  mild_trendallt annat (ADX 22-32)macd_vol_trend62

                                  Skript: update_ticker_regime.py — körs dagligen via scheduler efter morning_signals.

                                  Hurst R/S-metod: Rescaled Range-analys, fönster 10–100 dagar, minst kvadrat-regression log(R/S) ~ H·log(n).

                                  Beta: Pearson-kovarians(ticker, OMXSPI) / Var(OMXSPI) pÄ 252 handelsdagar.


                                  39.2 Nya handelsstrategier


                                  Implementerade i backtest_engine.py (_STRATEGY_FNS, STRATEGIES) och oos_walkforward.py:


                                  mean_reversion_bounce (för regime=mean_reverting)

                                  RSI < 38 + pris ≀ BB-lower·1.03 → KÖP. RSI > 62 + pris ≄ BB-upper·0.97 → SÄLJ.

                                  Kompletterande: zscore < -1.8 → KÖP; zscore > 1.8 → SÄLJ.


                                  momentum_high_beta (för regime=momentum_high_beta)

                                  Gyllene kors (SMA50>SMA200) + volymbekrĂ€ftelse → KÖP/pullback. Dödskors → SÄLJ.


                                  bb_squeeze_breakout (för regime=breakout)

                                  Pris bryter BB-upper/lower med ADX>20 + vol_spike>1.3 → breakout-entry.


                                  choppy_flat (för regime=choppy_flat)

                                  RSI-bounce: KÖP vid RSI<35, SÄLJ vid RSI>65. Kompletterande BB-filter.


                                  macd_fast_reversal (förbĂ€ttrad — ADX≄18, SMA200-trendfilter, RSI 35-55 köp/>60 sĂ€lj)

                                  Histogram-vĂ€ndning + tightare filter. Uppgraderat frĂ„n ADX>12 till ADX≄18.


                                  39.3 regime_adaptive v2


                                  regime_adaptive i backtest_engine.py slÄr nu upp ticker_regime-tabellen (process-cachat, dagsfrisk) och delegerar till rÀtt strategi-funktion per regim. Fallback: rullande 20d ADX.


                                  Nyckelkod: _REGIME_TO_STRATEGY, _load_ticker_regime_cache(), _regime_from_cache().


                                  39.4 Infrastruktur


                                  • ticker_regime-tabell skapad med FK till tickers.id
                                  • update_ticker_regime.py — CLI: --ticker SYMBOL, --days N
                                  • submit_job.sh — nytt jobb update_ticker_regime (DEPENDS: morning_signals, PREFER: bigrig)
                                  • scheduler.sh — update_ticker_regime köas vid morning_signals=done (Steg 2e)
                                  • run_nn_nightly.sh — MALLOC_ARENA_MAX=2, MALLOC_TRIM_THRESHOLD_=67108864 (glibc-fragmentering)

                                  39.5 MinneslÀcksfixar (frÄn Claude Opus 4.8-granskning)


                                  FixFilBeskrivning
                                  A1neural_network.py_evict_model_from_cache() + clear_model_cache() — VRAM/np-cache frigörs vid vrĂ€kning
                                  A3neural_network.pypredict_all() finally: gc.collect() + _trim_process_memory()
                                  E3neural_network.pytempfile.mkstemp utan dir="/tmp" — respekterar TMPDIR/NN_TMPDIR
                                  C1backtest_engine.py_LeasedPoolConnection.init — pool-lease returneras korrekt vid enter-fel
                                  C3backtest_engine.pystrategy_signals — optimerad loop (lokal variabelbindning, undviker enumerate-overhead)
                                  B3run_nn_nightly.shMALLOC_ARENA_MAX=2 — fĂ€rre arenor, lĂ€gre fragmentering för 6 workers



                                  §40 rank_weight OOS walk-forward CV + IC-screening + NN strict-OOS fix (2026-08-XX)


                                  40.1 Problemanalys: IS-overfitting i rank_weight


                                  Grundproblemet (commit 84b874d): rank_weight_sim_phase7.py's evaluate() testade all data (_GLOBAL_PERIODS = 1m/2m/6m/1y/3y alla slutande idag) i optimeringsobjektivet. Med 35 fria parametrar × 3000+ Optuna-trials → ren IS-overfitting mot historiskt brus. LHS/OA/tournament förbĂ€ttrar sökhastighet men löser inte fel objektiv.


                                  Arkitekturella problem i NN (frÄn Claude Opus 4.8-granskning):

                                  • NN_PREDICT_STRICT_OOS defaultade till "0" → historiska prediktioner genererade med modell trĂ€nad pĂ„ ALL data inklusive framtida datum → lookahead-bias i backtest
                                  • get_oos_model_id_for_date() returnerade (None, None) om ingen strikt OOS-modell fanns → prediktioner hoppades → tomma daily_signals för historiska datum

                                  40.2 Implementerade lösningar


                                  IC-screening (compute_signal_ic)

                                  BerÀknar Information Coefficient per signal:

                                  • For signal K: sĂ€tt vikt=1.0, resten=0.0 → korrelera score_ticker()-vĂ€rde med nĂ€sta dags avkastning
                                  - `IC>= 0.02 krÀvs för att signalen ska delta i optimering (_ACTIVE_KEYS`)
                                  • Signaler med score==0 (ej aktiva) exkluderas frĂ„n pearsonr-berĂ€kningen
                                  • Resultattabell skrivs ut med ✓/✗ per signal

                                  Walk-forward CV (objective_wf, evaluate_wf, _make_wf_windows)

                                  OOS-exklusiv optimering:

                                  • 3 rullande fönster, var 18m trĂ€ning + 6m OOS-test (standard), konfigurerbart
                                  • Varje trial utvĂ€rderas enbart pĂ„ OOS-test-perioder — noll information frĂ„n trĂ€ningsdelen
                                  • Riskviktat mĂ„l: 0.60 × avg_OOS + 0.40 × worst_OOS → bestraffar strategier som Ă€r katastrofala i ett fönster
                                  • Fallback till IS-objektiv möjligt via --walk-forward=false (bakĂ„tkompatibelt)

                                  Regime-split

                                  • fetch_regime_tickers(conn, regime) hĂ€mtar ticker-IDs frĂ„n ticker_regime-tabellen
                                  • filter_data_by_tickers(data, ids) begrĂ€nsar data-dict in-memory (inga extra DB-queries)
                                  • Resultat: separata Optuna-studier per regime: phase7_oscillating_wf, phase7_trending_wf, phase7_mean_reverting_wf

                                  CLI-flaggor (nya)

                                  FlaggaDefaultBeskrivning
                                  --walk-forwardfalseAktivera OOS walk-forward CV som objektiv
                                  --regimeallFiltrera tickers: oscillating\trending\mean_reverting\...
                                  --ic-min0.02Minsta \IC\(0 = stÀng av IC-screening)
                                  --wf-folds3Antal WF-fönster
                                  --wf-train-months18TrÀningsmÄndads lÀngd per fold
                                  --wf-test-months6OOS-testmÄnadslÀngd per fold

                                  40.3 NN strict-OOS fix


                                  NN_PREDICT_STRICT_OOS default: "0" → "1"


                                  Historiska prediktioner anvÀnder nu alltid get_oos_model_id_for_date() som söker modell med train_to < prediktionsdatum. Eliminerar lookahead-bias i daily_signals-historik.


                                  Graceful fallback (ny beteende): Om ingen strikt OOS-modell finns loggas en WARNING och champion-modellen anvÀnds. Prediktionen körs (ej hoppas) men Àr ej OOS-garanterad. Backtest-kod kan filtrera pÄ detta om hÄrd OOS krÀvs.


                                  Viktigt: Om nn_models-tabellen saknar historiska modeller med train_to < datum, loggas WARNINGar men systemet fortsÀtter fungera. Kör NN_WALKFORWARD_FOLDS=3 vid nÀsta trÀning för att bygga upp historiska snap-shots.


                                  40.4 Scheduler-Ă€ndringar


                                  submit_job.sh: Ny case `rank_weight_oscillatingrank_weight_trendingrank_weight_mean_reverting → kör phase7 med --walk-forward --regime $REGIME --ic-min 0.02 --trials 5000`.

                                  scheduler.sh: Söndag ≄04:00 → köar de tre regime-specifika jobben (efter att update_ticker_regime körts under veckan).


                                  40.5 Filer Àndrade (commit 84b874d)


                                  FilFörÀndring
                                  tools/rank_weight_sim_phase7.py+350 rader: IC, WF-CV, regime-split, nya CLI-flaggor
                                  neural_network.pyNN_PREDICT_STRICT_OOS default 0→1; fallback i get_oos_model_id_for_date
                                  submit_job.sh3 nya regime-rank_weight-jobb
                                  shared/bin/submit_job.shSamma
                                  shared/bin/scheduler.shSöndagsschema för 3 regime-jobb



                                  §41 NN-kvalitetsförbÀttringar 2026-08-13


                                  Ändringarna i commit 09817e4 och c33ec9a adresserar tre Ă„terkommande NN-problem: kraftig klassobalans (hold dominerar), för svag feature-rankning för klassifikationsmĂ„l och för kort prediktionshorisont för signal_3class.


                                  41.1 Sammanfattning


                                  OmrÄdeFörÀndringEffekt
                                  KlassbalansDynamisk class-viktning i CrossEntropyLoss för signal_3classKöp/sĂ€lj-klasser fĂ„r större vikt nĂ€r hold dominerar 70–80 % av labels
                                  Feature-scoringmutual_info_classif ersÀtter Pearson för klassifikationsmÄlFÄngar icke-linjÀra samband bÀttre
                                  Target-designNy target signal_3class_20dBÀttre signal/brus-ratio Àn 5-dagarsvarianten
                                  TrÀningsstoppEarly stopping med patience 8 i vardagsprofilMindre overfitting i nattjobben
                                  Kalibreringnn_calibrate.py körd manuellt pĂ„ bigrig 2026-08-13FrĂ€schare sannolikheter efter Ă€ldre extrem slope (~5–6)

                                  41.2 FilÀndringar


                                  FilFörÀndring
                                  neural_network.py_train_epoch_torch() anvÀnder dynamiska class weights för signal_3class; auto-berÀkning frÄn trÀningsdata, manuell override via NN_CW_SELL, NN_CW_HOLD, NN_CW_BUY; hold-klassen kan cap:as via NN_CW_HOLD_CAP (koddefault 0.5)
                                  neural_network.py_score_features() anvĂ€nder mutual_info_classif för klassifikationsmĂ„l, med fallback till Pearson om sklearn saknas; minsta observationskrav (cnt) sĂ€nkt 50 → 20
                                  neural_network.py_select_top_features() sĂ€nker spĂ€rren för för smĂ„ dataset n<100 → n<30, vilket gör att fler tunna ticker-serier feature-prunas korrekt i stĂ€llet för att passera med svag selektion
                                  neural_network.pyNy target signal_3class_20d i _build_target_y_batch() och _build_target_y(); anvĂ€nder 20 handelsdagars horisont, dubbel tröskel 2×base_threshold_pct×vol_adj och golv 2.0%
                                  neural_network.pyrequired_h utökad sÄ att close_20d hÀmtas i SQL för signal_3class_20d; y_dtype satt till int8 Àven för denna target
                                  nn_pytorch_trainer.pyclass_weights rÀknas frÄn y_train via torch.bincount och invers frekvens; viktloggen skrivs som class_weights sÀlj=X hÄll=Y köp=Z
                                  run_nn_nightly.shVardagsprofil sÀtter NN_EARLY_STOP=8 som default och exporterar NN_CW_HOLD_CAP=0.4

                                  41.3 Detaljer: class-viktning


                                  För signal_3class har hold-klassen historiskt varit dominerande. Det gav modeller som ofta lÀrde sig att vara "för sÀkra" pÄ neutral klass och missade köp/sÀlj dÀr klassgrÀnsen var svag men relevant.


                                  Nu rÀknas klassvikter automatiskt frÄn trÀningsbatchens label-fördelning enligt invers frekvens. Hold-vikten begrÀnsas dessutom med NN_CW_HOLD_CAP för att undvika att neutral-klassen fortfarande blir för dominerande nÀr datat Àr extremt skevt. I nattprofilen exporteras 0.4, medan kodens generella default Àr 0.5.


                                  41.4 Detaljer: bÀttre feature-rankning och lÀngre target


                                  Pearson-korrelation fungerade acceptabelt för regressionsmÄl men var för grov för treklassificering. mutual_info_classif kan fÄnga icke-linjÀra beroenden mellan features och signal_3class, vilket Àr viktigare nÀr samma indikator kan vara bullish i ett regimlÀge och neutral i ett annat.


                                  Den nya targeten signal_3class_20d anvÀnder lÀngre horisont och hÄrdare tröskel för att minska brus. I praktiken betyder det fÀrre men mer meningsfulla labels Àn 5-dagarsvarianten, vilket gör targeten bÀttre lÀmpad för per-ticker-modeller med begrÀnsat dataunderlag.


                                  41.5 Recalibrering och nulÀge


                                  nn_calibrate.py kördes manuellt pĂ„ bigrig 2026-08-13 eftersom tidigare kalibrering frĂ„n 2026-07-19 hade extrem slope (~5–6). Recalibreringen Ă€ndrar inte klassetiketter i sig, men förbĂ€ttrar hur sannolikheter och confidence-vĂ€rden ska tolkas i dashboard, ranking och filter.


                                  Viktigt nulÀge: trots dessa förbÀttringar presterar NN fortfarande nÄgot svagare Àn regelstrategin i 3-Ärig OOS (+43.4% vs +45.8%). FörbÀttringarna ska dÀrför ses som kvalitetslyft och bias-reducering, inte som bevis pÄ att NN redan slagit regelmotorn.




                                  §42 OOS-ensemble och signal-overlap-analys (2026-08-13)


                                  Commit 7faccf1 lade till systematisk analys av hur NN-signaler och regelbaserade signaler överlappar, samt nya ensemblevarianter i den stateful OOS-simuleringen.


                                  42.1 Signal-overlap: vad som mÀttes


                                  MÄttUtfall
                                  NN-signaler52,092
                                  Regel-signaler14,473
                                  Enighet samma dag52.9%
                                  Forward return nÀr signalerna var eniga+0.16%
                                  Forward return nÀr signalerna var oense-0.40%

                                  Den initiala hypotesen var att enighet mellan NN och regelmotor skulle fungera som ett kvalitetsfilter: fÀrre signaler, men högre precision.


                                  42.2 Nya ensemblelÀgen


                                  tools/oos_walkforward_full.py har fÄtt funktionen build_ensemble_signals() med tre lÀgen:


                                  ModeLogik
                                  nn_confirmed_by_ruleNN-signal accepteras bara om regelmotor bekrÀftar inom ±3 dagar
                                  rule_confirmed_by_nnRegelsignal accepteras bara om NN bekrÀftar inom ±3 dagar
                                  union_agreeUnion/agreement-lÀge för att kombinera gemensamma eller nÀra signaler

                                  Dessa strategier testades i den stateful-simuleringen bÄde med och utan stop-loss.


                                  42.3 Resultat: fungerade inte bÀttre


                                  Den viktigaste negativa observationen var att ensemble-filtret inte förbÀttrade slutresultatet i helsimuleringen:


                                  Strategi3 Är OOS
                                  Regel+45.8%
                                  NN+43.4%
                                  Ensemble Regel+NN+28.4%

                                  Trots att samma-dag-enighet sÄg bÀttre ut i enkel forward-return-analys höll effekten inte nÀr signalerna kördes genom hela state machine-logiken med stop-loss, trailing och exits. Filtreringen tog bort mÄnga affÀrer, men de affÀrer som blev kvar var inte systematiskt de bÀsta.


                                  42.4 LĂ€rdom


                                  Den praktiska lÀrdomen Àr att signalreduktion inte automatiskt betyder signalförbÀttring. NÀr tvÄ modeller fÄngar delvis samma marknadsrörelser kan ett hÄrt bekrÀftelsefilter minska trade-frekvensen mer Àn det förbÀttrar trÀffsÀkerheten. I detta fall verkar interaktionen med stop-loss-logiken vara en viktig orsak till att ensemblet underpresterade.


                                  Detta dokumenteras uttryckligen som ett negativt fynd: ensemble mellan regelmotor och NN ska inte ses som default-förbÀttring i nuvarande arkitektur.




                                  §43 C-implementeringar — simulate_stateful + LSTM (2026-08-13)


                                  2026-08-13 tillkom tvÄ viktiga C-spÄr: en stateful simulator som speglar Python-logiken och en utökad LSTM-implementation i NN-trÀningskÀrnan. Python-integration Àr planerad men Ànnu inte fÀrdigkopplad som standardvÀg.


                                  43.1 c_ext/simulate_stateful.c


                                  Ny fil: c_ext/simulate_stateful.c


                                  Syfte: exakt spegling av Python-funktionen simulate_stateful_equity() i C för att flytta bort den tyngsta loopen frÄn Python.


                                  DelBeskrivning
                                  simulate_stateful()Kör en strategi över priser, signaler och indikatorer som platta 2D-arrayer
                                  simulate_stateful_multi()Kör flera strategier mot samma prisdata i ett anrop
                                  DatalayoutFlat 2D (n_tickers × n_dates) för priser, signaler och indikatorfĂ€lt
                                  ExitlogikATR-baserad stop-loss, ATR-trailing, weakness-exit (EMA20 + MACD), time-exit och signal-exit
                                  OutputDaglig mark-to-market equity-kurva

                                  FörvĂ€ntad hastighetsvinst Ă€r cirka 100× mot Python-loopen för storleksordningen 500 tickers × 750 dagar × 4 strategier (~1.5 miljoner Python-iterationer).


                                  Kompilering:


                                  gcc -O3 -march=athlon64 -mno-avx -mno-avx2 -ffast-math -fno-finite-math-only -shared -fPIC -o simulate_stateful.so simulate_stateful.c -lm
                                  

                                  43.2 c_ext/nn_train.c — LSTM-utökning


                                  c_ext/nn_train.c har utökats med en full LSTM-forward/backward-kedja för sekvensdata.


                                  FunktionRoll
                                  lstm_forward()LSTM-cell forward pass med fyra gates: forget, input, cell och output
                                  lstm_backward_step()BPTT-gradient för ett tidssteg
                                  train_epoch_lstm()Exporterad epoch-trÀning för sekvensdata (n_seq, seq_len, n_in) med Adam och class-weighted cross-entropy
                                  lstm_predict()Exporterad inferens som returnerar softmax-sannolikheter

                                  Viktformat:


                                  • Wih: (4h × n_in)
                                  • Whh: (4h × h)
                                  • bh: (4h)

                                  Implementationen innehÄller explicita malloc-kontroller och ska vara fri frÄn minneslÀckor enligt verifieringen som gjordes vid införandet.


                                  43.3 Byggstatus och integrationslÀge


                                  nn_train.so krÀver ingen Makefile-Àndring för LSTM-delen; den byggs som del av befintlig artefakt.


                                  Verifierad bygg:


                                  make -C c_ext nn_train.so
                                  

                                  Status:


                                  • nn_train.c LSTM-del: implementerad och verifierad
                                  • simulate_stateful.c: implementerad i C
                                  • Python-bindning/integration som standardbackend: planerad, inte klar

                                  Det betyder att dokumentationen nu behöver skilja mellan fĂ€rdig C-implementation och aktiverad produktionsintegration. SjĂ€lva C-koden finns och Ă€r verifierad, men hela Python→C-kedjan Ă€r Ă€nnu inte fullt inkopplad som ordinarie körvĂ€g.




                                  §44 Genomgripande kodgranskning och minnesoptimering (2026-08-15/16)


                                  Commits: ce637ed, 52109bd, a3fc44c, e46e7aa, 22f001c, a1cf7e1, 86ca787, 8efd1ca, 1d7a349.

                                  42 filer, ~3 700 tillagda / ~1 400 borttagna rader.


                                  44.1 Bakgrund


                                  Nightly NN-jobbet kraschade Äterkommande med OOM vid float64-konvertering av trÀnings­matrisen

                                  (408808, 226). Granskningen som följde utökades till hela kodbasen och omfattade minnesprofil,

                                  korrekthet i PnL-/backtestlogik, sÀkerhet och köinfrastruktur.


                                  44.2 Minnesprofil för NN-trÀning


                                  StegMinne
                                  NumpyData.X (float32, 408 808 × 226)352 MB
                                  shuffle-peak (gammal + ny array)352 + 352 = 704 MB
                                  trÀnings-peak (float32 + float64-kopia för C-kÀrnan)352 + 705 = ~1057 MB
                                  tidigare float64-lagring: shuffle-peak705 + 705 = 1410 MB → OOM

                                  ÅtgĂ€rder i neural_network.py / c_ext/neural_network.py:


                                  • NumpyData lagrar float32; float64 skapas först vid C-anropet via np.asarray
                                  • (behĂ„ller view-semantik nĂ€r dtype redan stĂ€mmer).

                                  • np.asarray i stĂ€llet för .astype i _train_epoch_c_classification,
                                  • evaluate_signal3class_balance, MLP.forward, valideringsvĂ€gen och

                                    _npz_reconstruct_accumulators.

                                  • np.fromiter vid X-/y-bygget i _load_training_data_single_pass (bort med tvĂ„ temporĂ€ra
                                  • Python-listor per kolumn), np.empty i stĂ€llet för np.full.

                                  • best_state snapshot/restore som numpy-kopior i stĂ€llet för nĂ€stlade Python-listor (~8× mindre RAM).
                                  • _sync_weights_from_torch behĂ„ller numpy-arrayer i self.W/self.b i stĂ€llet för .tolist()
                                  • varje epok (~125 k Python-floats per lager och epok).

                                  • NumpyData._uid — generationsrĂ€knare som bumpas vid shuffle()/setitem. Cache-nycklar
                                  • anvĂ€nder nu _dataset_cache_key() i stĂ€llet för id(data), som CPython kan Ă„teranvĂ€nda efter GC

                                    (latent bug med NN_C_TRAIN_STATIC_DATA=1).

                                  • train() river ned dataset-/torch-cachear och kör gc.collect() i finally;
                                  • nightly-loopen kör gc.collect() efter varje ticker och efter predict_all.

                                  • run_nn_nightly.sh: MALLOC_ARENA_MAX=2 och MALLOC_MMAP_THRESHOLD_=131072 exporteras i ett
                                  • enda block direkt efter set -euo pipefail, sĂ„ att alla barnprocesser Ă€rver instĂ€llningarna

                                    (commit a3fc44c — de sattes tidigare pĂ„ tvĂ„ stĂ€llen, varav ett för sent i filen).


                                  Medvetet ej genomfört: chunkat X-bygge utan prepared-mellanlager (B4). prepared behövs för

                                  augmentering, time-weighting, feature-selection och Python-fallbacken, och radantalet Àr inte kÀnt

                                  före augmentering.


                                  44.3 Kritiska buggar ÄtgÀrdade


                                  ModulBuggEffekt
                                  neural_network.pyensure_model_registry_table anropades ~103 000 ggr/natt via update_champion_challenger — DDL + commit varje gĂ„ngnu guardad med _SCHEMA_ENSURED; motsvarande guards för ensure_fundamentals_table, ensure_fundamentals_asof_table, ensure_epoch_log_table, ensure_nn_per_ticker_schema
                                  neural_network.pypredict_all lĂ€ste n_classes ur cfg — nyckeln finns inte i TARGETS, sĂ„ vĂ€rdet föll alltid tillbaka pĂ„ 3lĂ€ses nu ur cfg['n_out']; icke-3-klass-mĂ„l blev tidigare felaktigt tolkade
                                  neural_network.py_refresh_fundamentals_asof lÀmnade öppen transaktion vid tidiga returnscommit före early return + rollback vid undantag
                                  neural_network.pypredict_all lÀckte cursors vid undantagstÀngning flyttad till finally med None-init
                                  paper_trading_sim.pylook-ahead bias i ATR, market_profile och support/resistance vid intradag-asof; load_signals anvÀnde fel datumdaglig data trunkeras nu korrekt vid intradag-asof; simuleringsresultat före fixen Àr optimistiskt biased
                                  backtest_engine.pyfelaktig PnL-berÀkning; OOM vid stora universumrÀttad PnL, minnesbegrÀnsad körning
                                  oos_walkforward.pyPnL saknade courtage och slippage; task-fönstret gledPnL mot faktiskt insatt kapital inkl. köpcourtage; öppen position stÀngs vid OOS-slut med samma slippage/courtage som i loopen
                                  tools/nn_accuracy_governance.py--dry-run skrev skarpt till DBdry-run Àr nu lÀsning enbart
                                  tools/oos_walkforward_blankslate.pyuse-after-release av delad resurs; TypeError nÀr workers<=1bÄda rÀttade
                                  gpu_accelerator.pyOpenCL race condition vid kontextinit, int32-overflow vid stora index, OOM vid stora buffertarserialiserad init, int64-index, chunkade överföringar
                                  nn_pytorch_trainer.pyAMP-bugg (fp16 aktiverades inte korrekt), NaN-vikter, autograd-graf som inte slÀpptesfp16 fungerar nu pÄ GTX1070; NaN-skydd och korrekt detach mellan batchar
                                  queue_worker.shheartbeat registrerade $$ (förĂ€lderns PID) i subshell$BASHPID — orphan-recovery bedömer nu rĂ€tt process

                                  44.4 PrestandaförbÀttringar


                                  OmrÄdeFöreEfter
                                  IndikatorberĂ€kning (ctypes-arrayer byggdes 13× per körning, O(n·k))baslinje−19 % körtid (byggs 1×, O(n))
                                  API-statussida24.7 s0.35 s (TTL-cache, se arkitekturdok §9.3)
                                  tools/db_housekeeping.pymaterialiserade nyckelmÀngder i RAManti-joins körs i databasen
                                  nn_wf_train_s0/s1320 DB-uppkopplingar per shard1 batchad query per cykel

                                  44.5 SĂ€kerhetsfixar


                                  KomponentSĂ„rbarhetÅtgĂ€rd
                                  api.py — serve_log()path traversal via filnamnbasnamn + Path.resolve() och relative_to(_LOG_DIR.resolve())-kontroll
                                  api.py — statussidaXSS i loggnamn, alerts, jobbnamn och detaljfĂ€lthtml.escape() pĂ„ alla interpolerade vĂ€rden (quote=True för attribut)
                                  submit_job.shpath traversal via JOB_NAME (anvÀndes i LOCK_FILE, JOB_FILENAME, staging-sökvÀg)validering ^[A-Za-z0-9_]+$ innan namnet anvÀnds i nÄgon sökvÀg
                                  run_nn_nightly.shDB-lösenord synligt i ps-output (-p<lösen>)MYSQL_PWD i miljön i stÀllet för kommandoradsflagga
                                  housekeeping_*.shsamtidiga körningar; osÀker /tmp-purgeflock-lÄs + purge som bara raderar lockfiler ingen process hÄller

                                  44.6 Infrastrukturstatus vid dokumentationstillfÀllet


                                  PostStatus
                                  RAID /dev/md0degraderad [4/3] [UU_U], sdd faulty — byte krĂ€vs
                                  Kernel5.10.262-work733 installerad, ej aktiv (kör 5.10.0-46-amd64, vÀntar omstart)
                                  nn_weightstruncerad, 10.92 GB frigjort; alla vikter i NPZ
                                  nn_wf_train_s0 / s1kör, ~22 av 40 cykler
                                  nn_nightly_s4pending — vĂ€ntar pĂ„ ledig slot pĂ„ bigrig
                                  Koordinator + paper_predictvÀntar pÄ beroenden



                                  §45 Driftfelsökning och stabilitetsÄtgÀrder (2026-08-17)


                                  45.1 Bakgrund


                                  KvÀlls-session med fokus pÄ felsökning av pÄgÄende körningar och uppföljning av kvarstÄende problem frÄn granskningen i §44.


                                  45.2 Checkpoint-fel — rotorsak och utökad fix


                                  Symptom: ~36 FileNotFoundError per nattlig WF-körning (save_checkpoint_file), ~0.4 % av alla ticker/target-kombinationer. Alla var non-fatal (training fortsatte med fallback), men nn_all_s1 kraschade hÄrt (rc=1) nÀr felet uppstod under förutsÀgelsefasen.


                                  Rotorsak: /home/tege/work Ă€r en symlink till /mnt/raid/tege/work (lokal ext4 RAID). Med 8 parallella trĂ€ningsprocesser (2 workers × 4 shards) kan ext4:s directorycache bli inaktuell — os.path.exists(tmp_npz) returnerade False i upp till 5 s trots att filen skrivits.


                                  Fix (neural_network.py:save_checkpoint_file):

                                  • os.fsync() pĂ„ katalog-fd direkt efter np.savez_compressed — tvingar directorycachen att flödas ut.
                                  • Retry-fönster utökat frĂ„n 10 × 0.5 s = 5 s till 30 × 0.5 s = 15 s.
                                  • BekrĂ€ftat att os.fsync() löser problemet i isolerat test pĂ„ /mnt/raid.

                                  45.3 Stale champion-modell orsakar nn_all-krasch


                                  Symptom: nn_all (rc=1 kl 18:20) + nn_all_s1 (rc=1 kl 19:05) kraschade med:

                                  FileNotFoundError: load_model: npz-fil saknas för model_id=10505
                                  

                                  Rotorsak (rekonstruerad):

                                  1. Model 10505 var champion för CLA-B.ST/prob_up_2d sedan 2026-08-03.
                                  2. Idag (04:00) körde purge_old_nn_weights — modellen var >7 dagar gammal och inte lĂ€ngre refererad i nn_model_registry → raderades frĂ„n nn_models + nn_weights + .npz.
                                  3. nn_all_s1 (18:10) trĂ€nade CLA-B.ST — train() returnerade None (ticker skippades/fallbackade). get_champion_model_id hittade 10505 fortfarande som champion (registry Ă€nnu ej uppdaterat) och JOIN mot nn_models lyckades momentant.
                                  4. predict_all(10505) → load_model(10505) → fil saknas → FileNotFoundError → fĂ„ngades inte → hela processen kraschade.

                                  5. Fixar (neural_network.py):


                                    FunktionÅtgĂ€rd
                                    get_champion_model_idKontrollerar att .npz finns pÄ disk innan model_id returneras. Om filen saknas: loggar varning, nollstÀller champion_model_id i registry, returnerar None.
                                    predict_all-anropet (rad ~6741)FĂ„ngar FileNotFoundError + ValueError — loggar och hoppar vidare utan att krascha hela processen.

                                    ÅtgĂ€rd: nn_all_s1 re-köad manuellt till /shared/queue/pending/, körde klart.


                                    45.4 load_regime — SSDictCursor


                                    tools/nn_trade_sim.py:load_regime() anvĂ€nde conn.cursor() (buffrat) trots att alla övriga load_*-funktioner i samma fil anvĂ€nder pymysql.cursors.SSDictCursor (streaming). Fixat — resultatet itereras nu direkt utan att buffras klient-side.


                                    45.5 HĂ€ngande run_evening_chain (3 dagar)


                                    Symptom: reboot_recovery kör redan, skip. i schemalÀggar-loggen sedan 2026-08-14.


                                    Rotorsak: run_reboot_recovery.sh startade run_evening_chain.sh 2026-08-14, som körde klart alla steg utom submit_job.sh nn_focused --wait. Det --wait-anropet satt fast i polling-loop (sleep-baserad) och vĂ€ntade pĂ„ ett nn_focused-jobb som körde klart och om igen under tre dagar — men polling-loopen hittade aldrig "rĂ€tt" jobbinstans.


                                    Stdout/stderr hade raderats (/tmp/#9175060 (deleted)) vilket hindrade felloggning. flock-lÄset pÄ /tmp/aa_ai_reboot_recovery.lock hölls av PID 49882, vilket stoppade alla efterföljande cron-starter.


                                    ÅtgĂ€rd: ProcesstrĂ€ 49870 → 49882 → 50039 → 216007 dödades manuellt. LĂ„s frigjordes. reboot_recovery startar normalt vid nĂ€sta cron-trigger.


                                    45.6 Infrastrukturstatus 2026-08-17 23:00


                                    PostStatus
                                    nn_wf_train s0–s3🟡 >99 % klara (~2026-08-17 23:30 est.)
                                    nn_all s0, s2–s5✅ Klara
                                    nn_all_s1✅ Re-köad och klar
                                    nn_focused✅ Körde 20:00 (0 tickers — inga NN-signaler Ă€nnu)
                                    paper_predict alla shards✅ Klara
                                    Nordnet session🔮 UtgĂ„ngen — krĂ€ver ny inloggning
                                    Avanza session✅ OK
                                    run_evening_chain (gammal)✅ Dödad
                                    RAID /dev/md0⚠ Fortfarande degraderad (sdd faulty) — byte krĂ€vs



                                    §46 SimuleringsgenomgÄng och swing-uppdatering (2026-08-20)


                                    46.1 Bakgrund


                                    Manuell genomgÄng av alla pÄgÄende och avslutade simuleringsjobb. nn_wf_train_s0 och s1 körde klart (28h resp. 21h), nn_wf_predict_repair_s2 klar 22:38. Alla lÄs lediga.


                                    46.2 Jobb som kördes manuellt


                                    JobbStartResultat
                                    paper_replay (FROM_DATE=2026-07-02)08:36✅ 23 dagar simulerade, 4 konton
                                    oos_walkforward --resume08:36✅ Klar 08:38, W34/34 (9 884 redan rĂ€knade)
                                    oos_walkforward_full08:49✅ Klar 09:01
                                    db_housekeeping --apply09:05🟱 PĂ„gĂ„r (5,3M+ rader raderade ur nn_predictions)

                                    46.3 OOS Walk-forward — StrategijĂ€mförelse (2026-08-20)


                                    34 fönster × 308 aktier × 20 strategier. OOS-period 2023-08-20 → 2026-08-19.


                                    StrategiSharpeAvgRet%/fönsterBeatBnH%
                                    bb_rsi0.521.5056.1%
                                    mean_reversion_bounce0.521.5355.7%
                                    choppy_flat0.501.5555.4%
                                    rsi_only0.402.0955.9%
                                    channel_breakout-0.190.8734.1% ❌
                                    bb_squeeze_breakout-0.08-0.1940.2% ❌

                                    Alla strategier har negativt alpha mot B&H (marknaden stark 2023–2026).


                                    46.4 OOS Walk-forward Full (2026-08-20) — NN/Regel/FFT


                                    Period 2023-08-15 → 2026-08-19, 308 tickers, stateful simulering med stop-loss 3% + ATR-trailing.


                                    Strategi1m6m1Är3Är/Totalt
                                    NN global (sl3%)+5.5%+0.6%-7.2%+70.8%
                                    NN per-ticker (sl3%)+5.5%+0.5%-7.2%+70.7%
                                    Regel (no-stop)+3.6%+3.4%+2.2%+67.9%
                                    Regel (sl3%)+4.4%+2.6%+1.9%+62.1%
                                    Ensemble FFT+Regel (sl3%)+10.7%+25.9%+17.9%+9.1%
                                    Ensemble NN+Regel (sl3%)-1.0%-26.5%-42.2%-55.4% ❌

                                    Handelsdetaljer (3 Är):

                                    • Regel (no-stop): entries=7 209, hit=47.5%, avg=+0.263%/trade
                                    • NN global (sl3%): entries=2 674, hit=40.5%, avg=−0.126%/trade (hög total driven av fĂ„ stora vinnare)
                                    • Regelstrategin Ă€r konsekvent positiv pĂ„ alla tidshorisonter; NN starkt totalt men svagt pĂ„ 1-Ă„r

                                    JÀmförelse mot föregÄende körning (2026-07-19):

                                    • NN: +20% → +71% (+50 pp) tack vare ny trĂ€ningsdata frĂ„n nn_wf_train_s0/s1
                                    • Regel: +44% → +68% (+24 pp)

                                    Rapporter sparade: /tmp/copilot/oos_walkforward_full.txt och .json.


                                    46.5 Paper trading — Swing kör nu var 5:e minut


                                    Ändring: PAPER_SWING_INTERVAL_MIN=5 och PAPER_SWING_NN_INTERVAL_MIN=5 tillagda i .env.


                                    Tidigare körde swing-kontona med 15-minutersintervall. Nu körs alla 5 konton parallellt var 5:e minut under börsdagen:


                                    KontoStrategiIntervall
                                    PAPER_DAYTRADING_SEKDaytrading regelvar 5:e min
                                    PAPER_DAYTRADING_NN_SEKDaytrading NNvar 5:e min
                                    PAPER_SWING_SEKSwing regelvar 5:e min (Àndrat frÄn 15)
                                    PAPER_SWING_NN_SEKSwing NNvar 5:e min (Àndrat frÄn 15)
                                    PAPER_PROB_UP5D_SEKProb-up-5d directvar 5:e min

                                    Positioner, stop-loss och equity-snapshots uppdateras löpande i realtid för alla konton.


                                    46.6 NN-trÀningsöversikt


                                    ParameterVardagHelg
                                    TrÀningsfönster5 Är (1 825 dagar) rolling7 Är (2 555 dagar)
                                    Epoker30 (early stop vid 8 utan förbÀttring)30 + glidande förtrÀnning
                                    FörtrÀnningNej1-Äriga fönster, 6 mÄn steg, 7 Är bakÄt, warm-start
                                    Feature selectionTop 96 featuresAlla features
                                    Champion-gateval_AUC > befintlig championsamma
                                    Icke-champion rensasefter 7 dagarsamma
                                    PrediktionerInkrementellt (bara nya dagar)Inkrementellt
                                    WF-trĂ€ning (s0–s3)Manuellt (mĂ„nadsvis)—

                                    nn_wf_train (walk-forward per historiskt fönster) Àr separerat frÄn nightly och körs manuellt vid behov av uppdaterad OOS-analys.




                                    §47 Live-handel infrastruktur (2026-08-20)


                                    47.1 signal_executor.py — tre sessioner


                                    signal_executor.py refaktorerades för att stödja tre distinkta sessioner och

                                    separata strategy-scopes (daytrading, swing, both).


                                    SessionTidFunktion
                                    morning09:05Köpsignaler (daytrading + swing)
                                    intradayvar 5:e min 09:10–17:20Sync + stop-loss/trailing, inga köp
                                    eod17:05Flatten daytrading + order-timeouts

                                    Varför dessa tider:

                                    • 09:05 — NN-intradag körs 09:00; market-on-open-auktionen avvecklas ~09:03.
                                    • Stabil orderbok och uppdaterade kurser frĂ„n 09:05.

                                    • Var 5:e min — synkroniserat med run_paper_daytrading.sh (paper-cron).
                                    • Stop-loss och trailing hanteras löpande hela handelsdagen.

                                    • 17:05 — 25 min innan börsens stĂ€ngning (17:30). TillrĂ€ckligt för att
                                    • marknadsorder ska fyllas men nĂ€ra nog EOD för att undvika overnight-exposur.

                                      (afternoon Àr bakÄtkompatibelt alias för eod)


                                    47.2 Swing-signaler


                                    Ny funktion _fetch_swing_signals() lÀser daily_signals (regelbaserad

                                    köpsignal, max 5 dagar gammal) kombinerat med nn_predictions.prob_up_5d

                                    som konfidensmÄtt. TröskelvÀrden via env:


                                    • SIGNAL_SWING_MIN_PROB_UP5D (default 0.55)
                                    • MAX_SWING_POSITIONS (default 8)
                                    • MAX_SWING_POSITION_PCT (default 12%)

                                    Notis i live_orders.notes skiljer swing frÄn daytrading utan schemaÀndring.


                                    47.3 Aktivering av live-handel


                                    Live-handel Ă€r inte aktiverad — krĂ€ver:

                                    1. PAPER_TRADING=0 i .env
                                    2. Tre cron-rader avkommenteras (se kommenterade rader i crontab)
                                    3. Giltig Nordnet-session och giltiga API-credentials

                                    4. Cron-rader (avkommenterade för aktivering):

                                      # 5  9 * * 1-5  ... signal_executor.py --session morning
                                      # */5 9-17 * * 1-5  ... signal_executor.py --session intraday
                                      # 5  17 * * 1-5  ... signal_executor.py --session eod
                                      

                                      Kill-switch (fail-closed): TRADING_KILL_SWITCH=1 i env ELLER fil

                                      ~/.aktieanalys-state/trading_disabled. Även circuit-breaker-fil i samma mapp.