đ InnehĂ„llsförteckning
- Teknisk systemdokumentation â Aktieanalys
- 1. Systemöversikt
- 2. Huvudflöden
- 3. Datamodell (centrala tabeller)
- 4. BerÀkningsmotorer
- 5. Paper trading-arkitektur
- 6. Parallellism och klusterstöd
- 7. Native-acceleration (C/Cython)
- 8. Drift, loggar och observability
- 9. Driftmatris (jobb, frekvens, syfte)
- 10. Dashboard-testtÀckning (innehÄll)
- 11. Prestandaöversikt (teknisk)
- 12. FörbÀttringsförslag (prioriterad roadmap)
- 13. Felhantering och sÀkerhet
- 14. KÀnda begrÀnsningar
- 15. Livehandelssystem (2026-08-07)
- 16. Tekniska nyckelfiler
- 17. Rank-weight optimeringspipeline
- 17. NN-trÀning: dataintegritet och anti-leakage
- 18. Tickeruniversum och deduplicering
- 19. Investeringshorisonter â webbsida (`horisont.php`)
- 20. Stateful OOS-simulering (`simulate_stateful_oos_signals.py`)
- 21. Infrastruktur â bigrig-kluster och MariaDB-konfiguration
- 22. Ăndringar 2026-08-09
- 22. Web-dashboard: förÀndringar och buggfixar (2026-07-18)
- 23. DB-underhÄll och indexstrategi (2026-07-18)
- 24. Webbinfrastruktur â nginx, PHP och API (2026-07-18)
- 25. InfrastrukturförÀndringar 2026-07-21/22
- 26. InfrastrukturförÀndringar 2026-07-22 (session 2)
- 27. Ăndringar 2026-07-26
- 28. Infrastruktur- och pipeline-förÀndringar 2026-07-29
- 28.15 Alerting-system (2026-07-30)
- 28.16 NN signal_3class klassbalansering (2026-07-30)
- 30. Ăndringar 2026-07-30
- Sektion 31 â Uppdateringar 2026-07-31
- 31. Ăndringar 2026-08-02
- 32. Ăndringar 2026-08-02
- 33. Queue-system och cron-konsolidering 2026-08-05
- Sektion 34 â Uppdateringar 2026-08-06
- Output: 16:38:59 STEP preload sektor-data 0.23s 1,850 rader 8,043 r/s
- 35. SystemförÀndringar 2026-08-06
- 36. SystemförÀndringar 2026-08-07
- Sektion 36 â Uppdateringar 2026-08-07 (natt) â NN retrain pipeline + logrotate
- 37. Arkitektur- och driftuppdateringar 2026-08-10
- 38. Driftuppdateringar 2026-08-12
- §39 Regimklassificering och nya handelsstrategier (2026-08-12)
- §40 rank_weight OOS walk-forward CV + IC-screening + NN strict-OOS fix (2026-08-XX)
- §41 NN-kvalitetsförbÀttringar 2026-08-13
- §42 OOS-ensemble och signal-overlap-analys (2026-08-13)
- §43 C-implementeringar â `simulate_stateful` + LSTM (2026-08-13)
- §44 Genomgripande kodgranskning och minnesoptimering (2026-08-15/16)
- §45 Driftfelsökning och stabilitetsÄtgÀrder (2026-08-17)
- §46 SimuleringsgenomgÄng och swing-uppdatering (2026-08-20)
- §47 Live-handel infrastruktur (2026-08-20)
- 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
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:
- DatainhÀmtning
- BerÀkning
- Beslutslager
- Persistens
- Presentation/Drift
fetch_yahoo_history.py(historik/fyll luckor)avanza_update_prices.py(senaste priser)fetch_fundamentals_avanza.pycalculate_all_indicators.pycalculate_indicators_v2.pyanalyze_fourier_cycles.pycalculate_signals_py.pyfetch_macro.pycalculate_sector_performance.pybacktest_engine.pypipeline_quality_check.py(--max-suspicious-sells 20)morning_signals.py- 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/raiddetekteras via write-test (-w), ej bara listning â undviker Permission denied pĂ„ bigrig.- Kör
analyze_fourier_cycles.pyfö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 fetch_avanza_intraday_quotes.py(5m bars + intraday-indikatorer)- Periodisk NN inferens (
NN_PREDICT_ONLY=1, ingen retrĂ€ning) paper_trading_sim.pydaytrading-kontonpaper_trading_sim.pyswing-kontonrun_rank_weight_weekly.shâ viktkalibrering i fyra steg:db_housekeeping.py --applyâ OPTIMIZE TABLE, rensning av förĂ„ldrad datacleanup_orphan_predictions.pyâ rensarnn_predictionsförmodel_idsom saknas inn_modelsrun_nn_focused.shâ djupare trĂ€ning (top 10 tickers, 8 folds, 75 epoker) pĂ„ starkaste signalerbacktest_engine.pyâ andra passet med eventuellt uppdaterade NN-modellercombination_backtest.pyâ andra passet för 2/3-kombinations-villkorrun_tests.shâ kör systemets nattliga hĂ€lsotester som sista verifieringsstegtickersdaily_pricesdaily_indicatorsdaily_signalsfourier_featuresmacro_datasector_performancedaily_fundamentalsticker_universeâ universum per scope med prioritet (se §17.5)morning_signalsnn_modelsnn_weightsnn_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_predictionsnn_model_registrynn_training_epochsintraday_quotes_5mâ 5-minutersdata; nyckelkolumn:bar_time(DATE+TIME, intetimestamp); tĂ€cker from 2026-04-20; ~305â306 tickers per dagintraday_indicators_5mâ berĂ€knade indikatorer pĂ„ 5m-barspaper_accountspaper_positionspaper_orderspaper_equity_snapshotsbacktest_resultsâ totalt per strategi/symbol (full historik)backtest_results_by_periodâ per period (1m/2m/6m/1y/3y) medstart_date; rensas efter 36 mĂ„nadercombo_backtest_resultsoos_backtest_windowsâ rullande 36-veckors OOS-fönster per ticker/strategi; rensas efter 24 mĂ„naderoos_walkforward_resultsâ equity-kurvor och nyckeltal per strategi/ticker/fönster frĂ„noos_walkforward_full.pynn_pred_summary (model_id PK, max_pred_date, n_preds, updated_at)â snabb lookup för senaste NN-prediktion per modell; uppdateras löpande ineural_network.py. Undviker full-scan avnn_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 avrank_weight_monthly-jobbetapi_health (source, status, last_ok, last_fail, consecutive_fails, last_error, updated_at)â hĂ€lsotillstĂ„nd för externa datakĂ€llor; uppdateras viatools/api_health.pyoch visas pĂ„/aa/statuscalculate_all_indicators.pyberĂ€knar full uppsĂ€ttning features i ett pass.- Har C-acceleration via
c_ext/indicators.soför kÀrnloopar (SMA/EMA/RSI/TR/ATR m.fl.). calculate_indicators_v2.pykompletterar med extra features.calculate_signals_py.pybygger 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.
backtest_engine.pykör strategier per symbol och lagrar ibacktest_resultsochbacktest_results_by_period.- Stöd för
--start DATEoch--period NAMEfö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.sosaknas eller Ă€r inkompatibel.- Kombinationsbacktest (
combination_backtest.py) anvÀnderc_ext/backtest.so. - OOS walk-forward:
tools/simulate_stateful_oos_signals.pykö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.pyhar fÄtt ensys.path-fix sÄ att bigrig kan köra scriptet direkt utanModuleNotFoundError.shared/bin/submit_job.shhar ocksÄ ny jobtypoos_walkforward_fullsom kör--years 3och 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 tillsimulate_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 viafetch_fft_signals(). neural_network.pytrĂ€nar och predikterar flera targets.- Per-ticker-lĂ€ge, workers, sharding och fallback till global champion-modell.
NN_PREDICT_ONLY=1mö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 viatools/migrate_weights_to_npz.py; efter klart:TRUNCATE TABLE nn_weightsfrigör ~12 GB. - 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Ä: - Daytrading kan flattena EOD; swing kan hÄllas över natt.
- Courtagemodell parametriserad enligt Avanza-liknande
max(rate*notional, min_fee). 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Ă€ftelsenot confirmedbehandlas korrekt som obekrĂ€ftadpending_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 medtry/finally NN_TICKER_WORKERS,NN_TICKER_SHARD_INDEX,NN_TICKER_SHARD_COUNTIND_WORKERS,IND_V2_WORKERS,SIGNAL_WORKERS,BACKTEST_WORKERSJOB_SHARD_INDEX,JOB_SHARD_COUNT- Batch/analys: hög parallellism.
- OrdernÀra intraday-sim: lockad singelcykel per konto för determinism.
indicators.câindicators.sobacktest.câbacktest.sosimulate_stateful.câsimulate_stateful.so(tillagd 2026-08-13)matmul.cochnn_train.cför NN-berĂ€kningarpos_fractions=Noneâ 1.0 för alla bars;0.0-vĂ€rden hanteras korrekt (ej maskerade avor 1.0).signal_kernels.pyxför utvalda signalvillkor.- Build via
cy_ext/setup.pyochtools/build_cython.sh. - Parallell sim â 1 287 viktkombos i Phase 3b/4: 15â30Ă
- Surrogate NN batch-inferens i Phase 5: 4â8Ă
- Huvud-NN trĂ€ning: ~2Ă
- 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.pyfö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/finallyförres_buf,flat_bufochparams_buf(commit553621e) pipeline_*.logâ data_pipeline körningarnn_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-cykelfeaturespaper_daytrading_*.logâ intradayalerts.logâ kösystemets ERROR/WARN-notifieringar (copytruncate, 30 dagar)scheduler.logâ scheduler.sh körningar (var 5:e min)watchdog_api_health.logâ API-watchdogrank_weight_monthly_.log,db_housekeeping_.logm.fl./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-netmaxage 60för engĂ„ngskörningar - 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.lockför nn_focusedaa_update_all.lockâ exklusivt flock-lĂ„s förupdate_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) queue/done>7d,queue/failed>14d- Stale heartbeats (>1d NFS, >1d /tmp)
- Stale submit-locks (>6h)
aa_ai_nn_*.locki /tmp >1 dag/tmp/aa_ai_batch/>2 dagar- Loggar >60d (safety-net),
.log.gz>90d - Kör logrotate
/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/sdcoch/dev/sderapporterar 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 avsddÀr dÀrför öppen kritisk driftÄtgÀrd (se devops-dokumentationen §10). tests/test_dashboard_overview_content_unittest.pytests/test_dashboard_stock_content_unittest.pytests/test_dashboard_settings_content_unittest.pytests/test_dashboard_signals_content_unittest.pytests/test_dashboard_backtest_content_unittest.pytests/test_dashboard_macro_content_unittest.pytests/test_dashboard_nn_content_unittest.pytests/test_dashboard_morning_content_unittest.pytests/test_dashboard_help_content_unittest.py- 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 helaprepared-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 - Konditionella Phase7-vikter: IstÀllet för globala vikter, optimera separata vikter per regime
- Paper-trading filter: ErsÀtt hÄrdkodat TREND_UP/DOWN/RANGE med HMM-posterior ℠0.7
- 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
- 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
- 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)
- Bash-jobb kör
set -euo pipefail. trap on_errori nattjobb för tydlig felmarkering i logg/status.- Python-script anvÀnder explicita DB-commits och stÀnger anslutningar i
finally. calculate_signals_py.pyvĂ€ntar pĂ„ eventuell pĂ„gĂ„endeALTER TABLE nn_weightsinnan start (förhindrar I/O-konflikt och Lost Connection, inlagt 2026-07-22).order_manager.py:sync_order_status()och_update_position_on_fill()startar explicitconn.begin()sĂ„ att live_orders-UPDATE och positions-INSERT/UPDATE Ă€r atomiska.database.py: anvĂ€nder SQLAlchemyengine.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.
- Alla
/aa/*-routes skyddas av_require_api_key(opt-in viaAPI_KEY-miljövariabel iapi.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. - 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) â
sddfaulty. Ingen redundans kvar i det drabbade spegelparet. Diskbyte Àr öppen kritisk ÄtgÀrd. - Kernel
5.10.262-work733installerad 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).
paper_trading_sim.py:qty_by_risk=0faller 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 lokalaDB-dict med defaultlösenord (CHANGE_ME_DB_PASSWORD/user='maria'). Bör tas bort.trading_killswitch.py:check_market_hours()returnerarbool(INTE tuple). Fail-closed vid OSError.- Handelshorisont: XSTO 09:05â17:20 med helgdagar (PĂ„sk via Gauss-algoritm).
- 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. update_all.shrun_nn_nightly.shrun_fft_nightly.shrun_paper_daytrading.shneural_network.pyanalyze_fourier_cycles.pycalculate_all_indicators.pycalculate_indicators_v2.pycalculate_signals_py.pybacktest_engine.pyâ backtestmotor;simulate()anvĂ€nder C-kĂ€rna (run_simulate()) som primĂ€r sanningskĂ€llapaper_trading_sim.pysimulate_portfolio.pyâ portföljsimulator: pending_buys (D+1), morning-only-filtersimulate_orb_portfolio.pyâ ORB-simulator: pending_entries (nĂ€sta bar), DAY_END 17:25nordnet_trader.pyâ Nordnet REST-klient; live orders mot riktigt kontoorder_manager.pyâ orderlivscykel, atomic fill+position, stop-lossrisk_manager.pyâ riskgrĂ€nser och circuit breakertrading_killswitch.pyâ kill-switch;check_market_hours()â boolmorning_signals.pyâ genererar köp/sĂ€lj-signaler varje morgonsignal_executor.pyâ exekverar signaler mot Nordnet APIdatabase.pyâ DatabaseSaver; engine.begin() atomisk transaktion för 4 tabellerdb_pool.pyâ connection pool; autocommit=True; session_vars-whitelistdb_utils.pyâ execute_batch() returnerar (int, conn)-tupleapi.pyâ FastAPI REST API; alla /aa/*-routes autentiseradefetch_avanza_intraday_quotes.pydb_creation_mariadb_complete.sqldb_creation_postgres.sqlrun_rank_weight_weekly.shtools/rank_weight_sim_phase3b.pytools/rank_weight_sim_phase4.pytools/rank_weight_sim_phase5.pytools/apply_rank_weights.pytools/sim_c/sim.py+sim.ctools/nn_c/cnn.py+nn.crun_evening_chain.shâ (Ă€ldre) vardaglig jobbkedja; ersatt av scheduler.sh + NFS-kösystem sedan 2026-08run_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 jobbshared/bin/scheduler.shâ dispatcher (var 5:e min); submittar nĂ€sta steg baserat pĂ„ körningslĂ€geshared/bin/queue_worker.shâ worker pĂ„ alla 3 noder; atomisk claim, heartbeat, orphan-recovery, PREFER-routinghousekeeping_work733.shâ nattlig stĂ€dning: kö-filer, loggar, stale locks, tmp-batcharc_ext/backtest.câ C-backtest;run_simulate()med TradeRecord, slippage, pos_fractionsc_ext/init.pyâ ctypes-wrappers; TradeRecord; SIMULATE_AVAILABLEc_ext/opencl_matmul_stub.cpp+c_ext/opencl_backend.pyâ OpenCL GPU-accelerationtools/sim_c/opencl_sim.pyâ GPU-parallell simulatortools/signal_param_opencl.pyâ OpenCL-kernel försignal_param_lhstools/signal_param_lhs.pyâ GPUâCPU-fallback för parameter-LHStools/db_housekeeping.pyâ DB-optimering och rensningtools/oos_walkforward_full.pyâ full 3-Ă„rig walk-forward-körning för OOS- â10 pp om 1mĂ„n% < â5%
- â20 pp om 2mĂ„n% < â10%
- â15 pp om 1Ă„r% < 0%
- Drar 25 000 viktkombinationer ur
SEARCH_SPACEmed valbar samplingsmetod - Samplingsmetoder (styrs via
RW_SAMPLING-env): - 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_BOUNDochMAX_1YR_BOUNDfö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Ă„rmed 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)
DB_HOSTDB_MARIADB_PASSWORDRW_END_DATERANK_WEIGHT_OUTPUT_DIR- 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) MULT_CHOICES = [0.0, 0.5, 1.0, ..., 4.5](10 nivÄer)- Constraint:
mult[G0] â„ mult[G1] â„ ... â„ mult[G7] C(17,8) = 24 310kombinationer â 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 - Final-date rebalance bug â sista handelsdagen kunde trigga samma-bar köp + likvidering; fixat med
is_last-guard. - Universumbugg â simuleringen byggde tidigare universum endast frĂ„n
daily_signals; nu inkluderas Àvendaily_pricessÄ hela investerbara universumet kommer med. - binÀrsökning för datumfiltrering
- förberÀknade datumserialer
- inkrementell uppföljning av bÀsta resultat under 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Ăstdvid sökning,meanvid validering - C-simulator (
_sim.so) anvÀnds om tillgÀnglig (190à snabbare Àn Python) - Python-
simulate()som fallback rank_weight_phase5_best.jsonâ composite (maskinlĂ€sbar, förapply_rank_weights.py)rank_weight_phase5_best_long.jsonâ optimerat för 3Ă„rrank_weight_phase5_best_medium.jsonâ optimerat för 1Ă„rrank_weight_phase5_best_short.jsonâ optimerat för 2mĂ„nrank_weight_phase5_results.txtâ lĂ€sbar rapport (topp-20)- LĂ€ser per-horisont JSON (fas 5 primĂ€r, fas 4 fallback) för composite, long, medium, short
- Anropar
mults_to_weights(mults)â individuella vikter - Skriver 4 JSON-filer till
RANK_WEIGHT_OUTPUT_DIR: - Returnerar exit 0 endast om alla 4 horisonter lyckades (partiell deploy loggas men avbryter scriptet)
- Fallback per horisont:
active_weights_{horizon}.json â active_weights.json â _DEFAULT_RANK_W active_weights*.jsongenereras fortsatt avtools/apply_rank_weights.pyi weekly-pipelinen och Ă€r inte dashboard-specifika artefakter_sim.so: ~190Ă snabbare Ă€n Python-simulatorn per körningnn.so: ~2.6Ă snabbare Ă€n numpy-NN per epok (SSE2-optimerad för Athlon64)- 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 /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- 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 --trials N(standard 1 000)- 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 - 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)
- Unit:
aa-queue-worker@.service(WORKER_TYPE-template) - Instanser per nod:
- Worker-script:
/shared/bin/queue_worker.sh - WORKER_TYPE-filtrering:
gpu-workers tar bara jobb medQUEUE_PREFER: gpu;gt610tar baraQUEUE_PREFER: gt610;cpu-workers hoppar övergpu/gt610-jobb - Drop-in config:
/etc/systemd/system/aa-queue-worker@<type>.service.d/local.confsÀtterMAX_CONCURRENT_JOBSper nod och typ - Loggar:
/shared/logs/aktieanalys/queue_worker_<node>_<N>.log - Konfiguration:
expire_logs_days=7i/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:
- 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:
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
- 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 - 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_s1lades Äter i kön medQUEUE_PREFER: gtx1070och kör nu pÄ bigrig GPU 0+1. Resume-logiken (already_done_predict()) hoppar över redan fÀrdiga cykler. - Ny watchdog driftsatt:
/shared/bin/ensure_workers.shskapades för att hÄlla rÀtt worker-antal per nod och typ, med mutex-lÄs viamkdiroch loggning till/shared/logs/aktieanalys/ensure_workers.log. - Crontabs uppdaterade pÄ alla noder: gamla
@reboot-rader och tidigare defekt watchdog-logik ersattes medensure_workers.shpÄ bigrig, work733 och raspberrypi. - Produktion-KPI-kort: Visar enbart
PAPER_SWING_SEKochPAPER_DAYTRADING_SEKprominently - A/B-konton: Samlad kollapserbar tabell (konton med
A/B/COMPAREi 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 - 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]) - BÄda
COUNT(*)-anropen ersatta: alltidnn_pred_summary JOIN nn_modelsutan COUNT-kontroll - Fallback-path till direkt scan pÄ
nn_predictions(35M rader) borttagen <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 load_signal_summary()anvĂ€ndeCURDATE()som datum â alltid 0 signaler; Ă€ndrat tillMAX(date) FROM daily_signalsPDO::ATTR_TIMEOUTersatt medPDO::MYSQL_ATTR_CONNECT_TIMEOUT(meddefined()-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- "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_sellvisas alltid Ă€ven om ingen föregĂ„ende köpmarkering finnsrun_nn_pred_cleanup.shâ vĂ€ntar automatiskt pĂ„ bigrig-idle, kör sedantools/db_housekeeping.py --cleanup-nn-old-models --apply+OPTIMIZE TABLEsubmit_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- 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 10Yregime_changes: konjunkturcykelbyten (spread byter tecken), filtrerade med 30-dagars minimivaraktighet + deduplicerade â ger ca 14 signifikanta förĂ€ndringar sedan 1987regimePlugin(id: 'regimeLines') â ritar lodrĂ€ta linjer vid konjunkturcykelbyten viaafterDatasetsDrawthreshPlugin(id: 'thresholdLines') â ritar horisontella streckade linjer för recession/expansion-tröskel (â0.5 % / +0.5 %) viaafterDraw- TvĂ„
<input type="range">staplade ovanpÄ varandra med CSS (position: absolute,pointer-events: nonepÄ track,pointer-events: allpÄ tummen via::-webkit-slider-thumb) .rs-fill-div uppdateras medleft/widthi procent för att visa vald period- Slider-vÀrden Àr index in i
dates-arrayen â vid Ă€ndring sĂ€ttschart.options.scales.x.min/maxochchart.update('none')(ingen animation) - Period-knappar (1Y/3Y/5Y/10Y/Max) sĂ€tter slider-vĂ€rden via
findIndexpĂ„ datumarrayer /api/âhttp://192.168.1.72:8000//aa/statusâhttp://192.168.1.72:8000/aa/status_NN_WEIGHTS_DIR(envNN_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-dictload_model()â filprioritet: fil â DB blob â DB JSON (fallback)save_model()â sparar npz + bara metadata (n_in, n_out) i DB, inga viktertools/migrate_nn_weights_to_files.py --applyâ batch-migrerar DBânpz, Ă„terupptagbartools/cleanup_nn_weights_columns.py --applyâ verifierar 100% tĂ€ckning, DROPpar viktskolumnercleanup_orphan_npz_files()â tar bort.npzvarsmodel_idinte finns inn_modelscleanup_stateful_oos_json()â tar bort gamla JSON-statusfiler för OOS-simuleringarcleanup_nn_weights_keep_n()â raderar nu Ă€ven.npznĂ€r en modell tas bort frĂ„n DBOPTIMIZE TABLEkörs nu Ă€ven nĂ€rDATA_FREE > 500 MB, Ă€ven om inget just raderades i samma pass/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)TREND_GATEdefault:0â1(sma20<sma50 â buy_score=0)buy_score-floor pĂ„ rad 452 backas nu avnot (sma20 < sma50)guardplaywright_chromiumdev_profile-*i/tmpĂ€ldre Ă€n 2 dagar rensas/tmp/bankid_debug/Ă€ldre Ă€n 3 dagar rensas- 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.
paper_trading_sim.py: Explicit transaktion (autocommit=False + conn.begin() wrappa hela read-modify-write) för att eliminera race vid parallella körningarneural_network.py: StĂ€ng DB-connection efter dataladdning, öppna kortlivade connections för epoch-loggingneural_network.py: Chunkadeferred_rows/prepared-ackumulering för att minska peak-RAMcalculate_signals: Kör om för att uppdatera alla tickers med TREND_GATE=1calculate_signals_py.py: Eliminera subprocess-per-ticker (~308 Python-omstarter); ersĂ€tt med shard-baserad in-process-körning eller--gpu-bulk- Rotorsak: alla 142 MID_CAP-tickers finns Ă€ven i LARGE_CAP â exkluderingslogik â 0 tickers â alla MID_CAP-jobb misslyckades
scheduler.shuppdaterad:nn_omx30 â nn_large_cap â nn_mid_capânn_all;nn_focusedberor nu pĂ„nn_allsubmit_job.shuppdaterad:nn_omx30/nn_mid_capkvar som alias tillnn_all(bakĂ„tkompatibilitet)rank_weight_monthlyformellt tillagd isubmit_job.sh(fanns bara som ad-hoc-jobb)- Lokal
_LeasedPoolConnection-klass borttagen â anvĂ€ndepool_connection()direkt och saknade RecursionError-skyddet i db_pool.py. Ersatt medfrom 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)_upd-cursor ipredict_allwrappas nu somwith write_conn.cursor() as _upd:â garanterar att cursor stĂ€ngs Ă€ven vid exceptionscheduler.sh:morning_signalsenqueuas nu bara om BĂ DEcalculate_signalsochnn_nightlyhar statusdone- Kommentaren i scheduler.sh visar nu korrekt beroendegraf
LeasedPoolConnection()direkt âwith db_pool.lease_connection() as conn:(context manager; explicit close ej nödvĂ€ndig)- Redundant
ping(reconnect=True)vid Ă„terlĂ€mning till pool borttagen frĂ„nexit. Checkout-fasen validerar via_validated()Ă€ndĂ„ â sparar ett nĂ€tverks-RTT per connection-return. - 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)verify-backfill-result: Backfill pĂ„gĂ„r, verifiera fullstĂ€ndighet nĂ€r klart.queue_worker.sh: nysend_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-aktieanalysi/etc/environmentför ntfy.sh push-notiser GET /aa/alerts?n=50â returnerar senaste n alerts som JSON- Visas som kort pĂ„
/aa/statusstatussidan - Alert-logg:
/shared/logs/aktieanalys/alerts.log(NFS-delad, alla noder skriver dit) val_accuracyfö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
NN_SIGNAL3CLASS_BALANCE_RATIO=0.7(default): oversamplar minoritetsklasser- 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 - Mer balanserade prediktioner (mindre dominans av majoritetsklassen)
- BĂ€ttre
val_accuracypÄ minoritetsklasser - Testas vid nÀsta
nn_nightly-körning - Argument
--prob-up5d-direct 0.55â bypassermorning_signals, anvĂ€nderprob_up_5d â„ 0.55direkt --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
- 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 - Kolumnnamn i
tickers-tabellen Àrsector, intesector_group - RÀttad i
calculate_signals_py.pyochtools/signal_param_lhs.py(commitfcbaf87) ln -sf /usr/bin/python3 venv/bin/python3â system Python 3.12.3pip install pymysqli venv (user-packages ej tillgĂ€ngliga inuti venv)slurm_dispatch_nn.shhar redan--exclude='venv/'i rsync â manuell rsync utan detta orsakade problemet- 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 %)
- Nuvarande:
neutral_stable RW_REGIMEenv-var â filtrerar trĂ€ningsdata till dagar med matchande regime- Output:
signal_param_lhs_best_{sector}_{regime}.json - Fallback-kedja:
{sector}_{regime}â{sector}â global - Var:
0 1 2(tisdag kl 01:00) - Nu:
0 1 1-5(varje vardag kl 01:00) - Ny parameter
min_prob_1d=0.0â filtrerar bort köp omprob_up_1d < threshold - Ny CLI-arg
--prob-up5d-direct-min-1d/PAPER_PROB_UP5D_DIRECT_MIN_1D --prob-up5d-direct-min-1d 0.52(viaPAPER_SWING_NN_MIN_1D)- KrÀver nu:
prob_up_5d ℠0.52 OCH prob_up_1d ℠0.52för köp - Strikt walk-forward: för datum
danvÀnds bara modell medtrain_to < d - BerÀknar faktisk riktning frÄn
daily_prices.close(ejdaily_forward_returns) - Rapport: precision och lift per tröskelvĂ€rde 0.50â0.70
- SÀnk tröskelvÀrde till 0.48 vid bull-regime (bull = pct_above_sma200 > 55 %)
- Kontrollera kalibrering:
prob_up_5d-distribution bör reflektera aktuell marknadsriktning - Historisk OOS +251 % 3 Ă„r gĂ€ller â undvik panikĂ€ndringar, bull-marknader Ă€r temporĂ€ra
- NĂ€sta NN-trĂ€ning (mĂ„ndag) inkluderar 2025-2026-data â förbĂ€ttrad kalibrering
prob_up_1d: +8.3 % lift â â dagshandel-filtret fungerar vĂ€lprob_up_5d: â3 % lift â ïž â bull-marknaden skapar kalibreringsproblem- Lost connection during streaming query â SSCursor (streaming/server-side cursor) tappade anslutningen under
fetchmany()pĂ„ stora frĂ„gor - Lock wait timeout â INSERT ON DUPLICATE KEY för
prob_up_*-kolumner kraschade vid 50 s timeout 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 âslurmdaktiv, Pi i partitionernadebugochpi- MariaDB-lösenordet roterades frĂ„n det tidigare vĂ€rdet till ett nytt sĂ€kert lösenord.
web/aktieanalys/includes/config.phpladdar nu hemligheten frÄn gitignoreraddb_secret.phpi stÀllet för att ha lösenordet inline i repo.deploy_web.shgenererardb_secret.phppÄ VM:n medprintfoch sÀtter filrÀttigheter till0644.- Git-historiken sanerades med
git-filter-repoför att ta bort det tidigare lösenordet ur historiken. - Ny tabell
api_healthmed kolumnernasource,status,last_ok,last_fail,consecutive_fails,last_errorochupdated_at. - Ny hjÀlpmodul
tools/api_health.pymedreport_ok(source)ochreport_fail(source, error_msg). - Integrerad i
browser_session_daemon.py,fetch_avanza_intraday.py,fetch_yahoo_5m.pyochfetch_macro.py. - Statussidan
/aa/statusvisar nu sektionen đ©ș Externa datakĂ€llor baserad pĂ„ denna tabell. - Nytt verktyg
tools/cleanup_orphan_predictions.pyrensar prediktioner varsmodel_idsaknas inn_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. - 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. paper_trading_sim.py:SELECT ... FOR UPDATEligger 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 ochdeferred_rowschunkas i block om 10 000 rader för lĂ€gre peak-RAM.db_pool.pyapi.pybrowser_session_daemon.pypaper_trading_sim.pyneural_network.pyrun_rank_weight_weekly.shdb_housekeeping.py --applycleanup_orphan_predictions.pyrun_nn_focused.shbacktest_engine.pycombination_backtest.pyrun_tests.shsubmit_job.shinjicerar# QUEUE_SUBMITTED: $(date +%s)pĂ„ rad 2 i varje jobbfilqueue_worker.sh: ny funktionjob_submitted()lĂ€ser headern (fallback: mtime)deps_satisfied()anvĂ€nderjob_submitted()â inte mtime â för beroendekontrollen- PREFER-delay-Ă„lder rĂ€knas fortfarande pĂ„ mtime (= nu för fĂ€rska jobb â liten Ă„lder â delays fungerar)
- bigrig: @reboot
seq 1 8âseq 1 6 - pi: dubblerad rsync-rad borttagen
- 2b:
queue/failedâ rensar jobbfiler Ă€ldre Ă€n 14 dagar - 2c: Heartbeat-filer (
.hb) i/shared/queue/.heartbeats/och/tmp/Àldre Àn 1 dag - 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.txtcommittad (d76a3a6). VĂ€ntar pĂ„ att paper_predict-körning avslutas rc=0âdone/rc=75(EX_TEMPFAIL) âpending/(retry pĂ„ annan nod)rc=annatâfailed/_PROGRESS_PATTERNSutökad mednn_nightly_s0..s7via loop- Fallback: shard utan historik â
nn_nightly-historik Ă· 6 (parallella shards) - 1.5x-gate borttagen â visa
>2h34m (+12% övertid)istĂ€llet för blank "â" - Starttid: sista "start"-raden anvĂ€nds (ej stale första körning frĂ„n pi)
_get_market_breadth(cur, asof_date)â mĂ€ter andel tickers medclose_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 calculate_all_indicators.py: preload (sektor/makro/benchmark/intraday/PE) + SUMMARYcalculate_signals_py.py: init_macro_regime + SUMMARYmax_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Ă€ndemax(window)som peak (lookahead). Ersatt med löpande peak per bar.fft_nightly_s2,morning_signals,rank_weight_day,refresh_materializedâbigrignn_all_s4,nn_all_s5âbigrig(tidigarebigrig_work733, pi exkluderades)login_start,login_status,login_cancelserve_log(lĂ€ser loggfiler â potentiellt stora)get_alertsstatus_page+system_status_page- Fas 1: ladda ticker-data sekventiellt (DB, kan ej pickle DB-connection)
- Fas 2:
_worker_run_symbol()iProcessPoolExecutor(workers=4)â rena CPU-berĂ€kningar - Fas 3: spara resultat sekventiellt till DB
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) / denomvol_roc_5:max(-9999.99, min(9999.99, v)) if math.isfinite(v) else Nonevol_ratio_20: klampar ±9999.99 (volym kan spike 10000x mot medel)bb_pct_b:rng > 1e-8(numerisk stabilitet) + klampar ±9999.99if not detr:ochif 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 == 0resp.valid_bins.size == 0 - 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_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)order_manager._get_db(): returneradePooledConnutan.cursor()/.close()â AttributeError âlease_connection()calculate_signals_py: enkeltrĂ„dad vĂ€g injicerade inteprev_psar_trendâ olikasell_percentberoende pĂ„ körvĂ€gsimulate_portfolio: slutstĂ€ngning tillentry_pricevid icke-handelsdag â fel CAGR/slutvĂ€rdecombination_backtest: C-vĂ€gen saknadeyears<0.5-spĂ€rr â inkonsistens mot Python-fallbackorder_manager:is_papersaknades i SELECT (alltid 1);cancel_orderutanför trybacktest_engine:start_datei JOIN-villkor istf WHERE â hela historiken laddades alltidapi:Any-annotation utan import âNameErrorvid FastAPI-uppstartbacktest_engine._LeasedPoolConnection.getattr: oĂ€ndlig rekursion vid pool-init-felneural_network.predict_all:read_connlĂ€ckte +NameErrori finallydb_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 exceptionsapi.serve_log/_get_alerts:read_text()lĂ€ste hundratals MB per anrop â tail-lĂ€sning (2 MB / 256 kB)api.login_cancel: frigjorde inteqr_b64(helsides-PNG i base64 kvar tills nĂ€sta login)run_nn_nightly.sh:NN_DEEP_RETRAIN=1âRESUME=0,EPOCHS=50,PROFILE=*-deepsubmit_job.sh:nn_nightly_monthly_s0..s5+ koordinator (42s stale=43200s)scheduler.sh:nn_all-shards borttagna; ny lördag-sektion +FIRST_SATURDAY-detektion (WEEKDAY=6 && DAY_OF_MONTH <= 7)oos_walkforward.py:load_ticker_windowladdar nuoos_start-10d â oos_endistf 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 brutetSELECT FOR UPDATE-block â NFS-flocken hindrar redan parallell Ă„tkomst per konto.combination_backtest.py:combo_id VARCHAR(120)â160,[:120]â[:160].ALTER TABLEapplicerat. 4 orphan-rader (truncerade 120-char nycklar) identifierade och raderade.neural_network.py: Pre-clipX_reorderedtill ±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.dequeper veckodag.- STL-deque: bit-identiska vĂ€rden mot original (A/B-test 800 börsdagar)
X_reorderedclip in-place Àr sÀkert (double fancy-index = kopia, ej view)VARCHAR(160)rÀcker (max verkligt length = 123)oos_walkforwardprev_*-lookback: exakt 1 tidigare rad rÀcker- NFS-flock pÄlitlighet: verifiera att ingen nod monterar
/sharedmednolock(alternativ: MariaDBGET_LOCK()) open(_lock_path, "w")â"a"+makedirsför robusthet pĂ„ ny nodneural_network.py:3223: naiv variansformelE[xÂČ]-E[x]ÂČkan förlora precision för stora obv-vĂ€rden (float64, ~1e20); root cause bakom overflow-varningarnapython3 calculate_all_indicators.pyför alla tickers- ModelomtrĂ€ning via
nn_nightly_monthly TradeRecord-struct (entry/exit-datum, priser, avkastning)- NĂ€sta-bar-exekvering (
next_opens[]) - Slippage per köp/sÀlj
- Positionsfraktioner (
pos_fractions[]) â0.0hanteras korrekt (ej maskerat) min_fee_sekabsolut courtagetröskel- Sharpe med konfigurerbar
rf_daily order_manager.py:sync_order_status()+_update_position_on_fill()â atomisk fill+positionmorning_signals.py: DELETE + INSERT i en transaktion â förhindrar signalförlust vid kraschsignal_executor.py:conn.begin()aktiverarFOR UPDATEâ förhindrar dubbelköp pĂ„ klustretapi.py:/aktieanalys/statuskorrekt skyddad med_require_api_keydb_pool.py:_ALLOWED_SESSION_VARSwhitelist mot SQL-injektion iSET SESSIONdatabase.py:URL.create()för lösenordsmaskering i SQLAlchemy-URLnordnet_trader.py,order_manager.py,risk_manager.py,trading_killswitch.py- Stop-loss nollas vid fill (ej vid order-placement)
filledutan fill_price â behĂ„ller statusplacedFOR UPDATEaktiverat medconn.begin()â lĂ„s hĂ„ller under hela order-loopenavailable_cash -= volume * limit(ej referenspris) â korrekt kapitalbudgetconn = Noneguard â förhindrarNameErrorvid pool-timeoutdatabase.py: NaN-guard (indicators/signals skrivs bara om kolumner finns), tz_convert(UTC) istf tz_localizedb_utils.py:execute_batch()returnerar(0, conn)vid tom listasimulate_portfolio.py: pending_buys D+1, morning-only-filtersimulate_orb_portfolio.py: pending_entries nĂ€sta bar, DAY_END 17:25materialize_nn_features.py:to_date = date.today() - timedelta(days=1)i bothdaily_update()ochmain()morning_signals.py: Dead DB-dict borttagensignal_executor.py: Dead DB-dict borttagengenerate_day_signals.py: Dead DB-dict borttagen;--daysdefault Ă€ndratNoneâ30(OOM-skydd);rows = Noneefter gruppering (RAM-frigöring)paper_trading_sim.py:qty_by_risk=0âcontinue(skippar trade) â förhindrar att risk-cap-buget kringgĂ„sneural_network.py:_ping_reconnect()kallas var 5:e epoch â skyddar mot MariaDBwait_timeoutvid lĂ„ng trĂ€ningnordnet_trader.py: Reconciliation matcharreference OR identifier+side(fallback för Ă€ldre ordrar)tests/test_backtest_engine_unittest.py: Mock-nycklar korrigerade (cagrejcagr_pct);_simulate_with_c_fastmockas i fallback-testermorning_signals.py:_refresh_materialized_for_date()och INSERT sammanslagna i enconn.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-checkn_tr < max_tradesföre varje skriv tilltrades_out(skyddar mot heap-overflow)c_ext/Makefile:backtest.solagd iall-targetind_backfillâcalculate_all_indicators.py --since 1999-01-01(alla tickers, hela historiken)calculate_signalsâdaily_signalsför alla tickersbacktestâ alla strategier för alla tickersnn_allĂ 6 shards (parallell trĂ€ning med korrekt indikatordata)simulate_portfolio.pyM6:getattrguard âif name in ('_cm', '_conn'): raise AttributeError(name)â förhindrarRecursionErrorvid partiellt misslyckadiniteller unpickling- API omstartad (
aktieanalys-api.service) â plockar upp runda 10â13 kodĂ€ndringar paper_trading_sim.pyomstartad viarun_paper_daytrading.sh/shared/bin/chain_rerun_all.shstartad som bakgrundsdemon (PID 711044)- C1:
capital -= position * pricesaknades 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. - H1: vid dagsslut (
is_day_end) tvĂ„ngsstĂ€ngs nu position Ă€ven nĂ€ridx_now is None(illikvid aktie utan bar vid exakt klockslag) â förhindrar övernattpositioner mot daytrading-reglerna - H2:
conn = _lease_pool_connection()wrappas nu itry/finallymedconn.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) 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+targetqueue_jobsâ DB-spegel av NFS-jobbkö (synkas av worker, stödjer beroenden + prioritet)sim_horizon_resultsâ simuleringsresultat per horisont/tröskelvĂ€rdev_active_tickersâ aktiva tickers (ticker_universe.is_active = 1) med namn/sektorv_best_nn_modelâ senaste modell per target+ticker (max train_to, sedan max id)v_latest_indicatorsâ senastedaily_indicators-rad per aktiv tickerv_latest_signalsâ senastedaily_signals-rad per tickerv_latest_nn_predictionsâ senaste prediction per ticker+target frĂ„n bĂ€sta modell med predictionsv_morning_signals_liveâmorning_signalsjoinad med senaste NN-prediktioner (alla 6 targets)nn_predictions_strict_oosâ predictions efter modellenstrain_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 Ă„renbatch_rule_scoresN=120: GPU 1.9ms vs CPU 0.9ms â GPU 2x lĂ„ngsammare för typisk pipelinestorlekbatch_combo_eval500 kombos: GPU 12ms vs CPU 29ms â +2.3xbatch_combo_eval5000 kombos: GPU 97ms vs CPU 306ms â +3.2x- M1:
read_text()saknadeencoding="utf-8"â kan ge korruption pĂ„ non-UTF8 locale - M2:
_touch_nordnetPUT saknadeContent-Length: 0â CDN kan returnera411 Length Required - M3:
conn.commit()(Ă2) Ă€r no-ops medautocommit=Trueutanconn.begin()â dokumenterade - M4:
ensure_schema()dokumenterad â kanonisk DDL finns ischema.sql(ska hĂ„llas synkade) - M5:
to_dt()anvĂ€nde systemets lokaltid istf explicitEurope/Stockholmâ kan ge fel bar_time vid DST-skiften om system ej Ă€r Stockholm - M6:
.avanza_cookiesbytte format pickle â JSON (save_avanza_session.py+fetch_avanza_intraday_quotes.py) â eliminerar RCE-risk via untrusted pickle-fil - 5c:
test_results_*.log>14 dagar - 5d: Safety-net â raderar
*.log-DATUM-DATUM-dubbelnamn i/var/log/aktieanalys/ - Alla nya modeller har
train_to â senaste handelsdagen nn_predictionsinnehĂ„ller bara in-sample-prediktioner (date †train_to)- Strikt OOS-prediktioner genereras av
paper_predictfrÄn nÀsta handelsdags prisdata - 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.
bigrig_work733= bigrig (0s) â work733 (3600s),raspberrypihoppas alltid av.bigrig_only= enbart bigrig.- Jobb som krĂ€ver
pymysql(t.ex.nn_wf_oos_sim,oos_walkforward_full) ska routas medbigrig_work733. - 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 - 9 cykler Ă 3 mĂ„nader
- TidsomfĂ„ng: aug 2023 â aug 2026
- Ny cykel öppnas varannan kvartal
nn_wf_train_s0nn_wf_train_s1nn_wf_predict_repairnn_wf_oos_sim- 575k felaktiga prediktioner rensades bort
nn_wf_predict_repair.shuppdaterades sÄ att samtliga 7 repair-cykler tÀcks- 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() - Gammal metod:
ps -o commtrunkerade processnamn till ~15 tecken, vilket ofta bara gavpython3 - Ny metod:
_PS_AWK(samma modell som SSH-versionen) extraherar full command line _build_node_proc_cpu()matchar signaturer som slutar pÄ.pyoch summerar subtree-CPU% per script_node_cell()istatus_page()lÀser frÄn_proc_cpu_map.get(node, {}).get(cmd_sig)nn_models_wfnn_model_registry_wfnn_predictions_wfnn_weights_wfnn_feature_stats_wfpaper_ab_reports- vyn
nn_predictions_wf_oos - 2 duplikat-vyer med hÄrdkodat datum
- Synkad med MariaDB-versionen av
schema.sql - InnehÄller 65 tabeller, 9 vyer och samtliga WF-objekt
- PostgreSQL-anpassningar:
JSONBi stÀllet förJSON,SERIALi stÀllet förAUTO_INCREMENTm.m. - Applicerad pÄ analys-VM:n 2026-08-10
- 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 - Flaggfil
/shared/queue/worker_disabled_raspberrypiskapad âqueue_worker.shkontrollerar 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.servicepĂ„ pi stoppad (mask lyckades inte pga saknad sudo â disable-flaggan Ă€r den effektiva mekanismen)._weights_path()â sökvĂ€g till.npz-fil permodel_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()- INSERT IGNORE pĂ„
nn_feature_stats: förhindrarIntegrityError: Duplicate entrynĂ€r jobb körs om med befintliga stats (PRIMARY KEY: model_id + feature_name). save_model:isinstance(st, dict)-filter för metadata-nycklar istat_rows.load_model:ValueErrorvidNULL weights_json(moderna modeller har vikter pĂ„ disk).predict_all:try/exceptsĂ„ 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_pathför att undvika krock mednn_models. - warm-start deepcopy: förhindrar att warm-start-vikter modifieras in-place under trÀning.
queue_worker.shskriverQUEUE_CHILD_PID: $BASHPIDtill jobbfilen vid pickup.api.py._parse_job_file()lÀser QUEUE_CHILD_PID.- SSH-kommando
_NN_SHARD_CMDlĂ€serNN_TICKER_SHARD_INDEXfrĂ„n/proc/<PID>/environâ identifierar rĂ€tt process per shard-index. _build_node_proc_cpu()returnerar{_by_shard, _by_pid, _by_comm, _by_comm_count}._hw_cells(): prioritetsordning shard-idx â child_pid â comm/count â nod-nivĂ„.ticker_regime-tabell skapad med FK tilltickers.idupdate_ticker_regime.pyâ CLI:--ticker SYMBOL,--days Nsubmit_job.shâ nytt jobbupdate_ticker_regime(DEPENDS: morning_signals, PREFER: bigrig)scheduler.shâupdate_ticker_regimeköas vidmorning_signals=done(Steg 2e)run_nn_nightly.shâMALLOC_ARENA_MAX=2,MALLOC_TRIM_THRESHOLD_=67108864(glibc-fragmentering)NN_PREDICT_STRICT_OOSdefaultade till"0"â historiska prediktioner genererade med modell trĂ€nad pĂ„ ALL data inklusive framtida datum â lookahead-bias i backtestget_oos_model_id_for_date()returnerade(None, None)om ingen strikt OOS-modell fanns â prediktioner hoppades â tommadaily_signalsför historiska datum- For signal K: sĂ€tt vikt=1.0, resten=0.0 â korrelera
score_ticker()-vÀrde med nÀsta dags avkastning - Signaler med
score==0(ej aktiva) exkluderas frĂ„n pearsonr-berĂ€kningen - Resultattabell skrivs ut med â/â per signal
- 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) fetch_regime_tickers(conn, regime)hÀmtar ticker-IDs frÄnticker_regime-tabellenfilter_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 Wih:(4h Ă n_in)Whh:(4h Ă h)bh:(4h)nn_train.cLSTM-del: implementerad och verifieradsimulate_stateful.c: implementerad i C- Python-bindning/integration som standardbackend: planerad, inte klar
NumpyDatalagrar float32; float64 skapas först vid C-anropet vianp.asarraynp.asarrayi stĂ€llet för.astypei_train_epoch_c_classification,np.fromitervid X-/y-bygget i_load_training_data_single_pass(bort med tvĂ„ temporĂ€rabest_statesnapshot/restore som numpy-kopior i stĂ€llet för nĂ€stlade Python-listor (~8Ă mindre RAM)._sync_weights_from_torchbehĂ„ller numpy-arrayer iself.W/self.bi stĂ€llet för.tolist()NumpyData._uidâ generationsrĂ€knare som bumpas vidshuffle()/setitem. Cache-nycklartrain()river ned dataset-/torch-cachear och körgc.collect()ifinally;run_nn_nightly.sh:MALLOC_ARENA_MAX=2ochMALLOC_MMAP_THRESHOLD_=131072exporteras i ettos.fsync()pĂ„ katalog-fd direkt efternp.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. - Model 10505 var champion för CLA-B.ST/
prob_up_2dsedan 2026-08-03. - Idag (04:00) körde
purge_old_nn_weightsâ modellen var >7 dagar gammal och inte lĂ€ngre refererad inn_model_registryâ raderades frĂ„nnn_models+nn_weights+.npz. nn_all_s1(18:10) trĂ€nade CLA-B.ST âtrain()returneradeNone(ticker skippades/fallbackade).get_champion_model_idhittade 10505 fortfarande som champion (registry Ă€nnu ej uppdaterat) och JOIN motnn_modelslyckades momentant.predict_all(10505)âload_model(10505)â fil saknas âFileNotFoundErrorâ fĂ„ngades inte â hela processen kraschade.- 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
- NN: +20% â +71% (+50 pp) tack vare ny trĂ€ningsdata frĂ„n
nn_wf_train_s0/s1 - Regel: +44% â +68% (+24 pp)
- 09:05 â NN-intradag körs 09:00; market-on-open-auktionen avvecklas ~09:03.
- Var 5:e min â synkroniserat med run_paper_daytrading.sh (paper-cron).
- 17:05 â 25 min innan börsens stĂ€ngning (17:30). TillrĂ€ckligt för att
SIGNAL_SWING_MIN_PROB_UP5D(default 0.55)MAX_SWING_POSITIONS(default 8)MAX_SWING_POSITION_PCT(default 12%)PAPER_TRADING=0i.env- Tre cron-rader avkommenteras (se kommenterade rader i crontab)
- Giltig Nordnet-session och giltiga API-credentials
Dagliga priser, intraday-priser, makro och fundamenta hÀmtas frÄn externa kÀllor.
Tekniska indikatorer, signaler, Fourier-cykler, backtester och neurala nÀtverk.
Morning signals, NN-prediktioner, meta-signaler och paper trading-regler.
MariaDB/PostgreSQL-tabeller för tidsserier, features, modeller och order/simuleringsdata.
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.
!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:
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:
| Variabel | Förklaring |
|---|---|
NN_TICKER_SHARD_INDEX | 0â5, vilken shard |
NN_TICKER_SHARD_COUNT | Totalt antal shards (6) |
NN_SKIP_FINALIZE | 1 = hoppa governance/meta/ensemble (shards) |
NN_SKIP_PRETRAIN | 1 = hoppa global pretrÀning (koordinator) |
NN_SKIP_MAIN_TRAIN | 1 = hoppa per-ticker trÀning (koordinator) |
Ăvriga egenskaper:
Loggas till /shared/logs/aktieanalys/nn_nightly_*.log (en per körning).
2.3 FFT nattjobb (run_fft_nightly.sh)
Î = ÎŁ 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:
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:
- 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
> 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
3.2 Signal- och modellager
3.3 Paper trading/intraday
3.4 Backtesting och OOS
3.5 Summerings- och hjÀlptabeller
4. BerÀkningsmotorer
4.1 IndikatorberÀkning
4.2 Signalmotor
4.3 Backtesting
- 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.
4.4 Neurala nÀtverk
5. Paper trading-arkitektur
paper_trading_sim.py Àr en paper-only exekveringsmotor:
- horisont-edge (NN 1d/5d),
- likviditet (turnover),
- volatilitet (atr_pct, vol_ratio_20).
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:
simulate_orb_portfolio.py:
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/):
| Nod | HÄrdvara | Roll |
|---|---|---|
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, GT610 | MariaDB, API-server, cron/scheduler, OpenCL, KVM-host (webb-VM) |
raspberrypi | Pi 4B, 4 CPU, 7.6 GB RAM, aarch64 | INAKTIVERAD 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):
| PREFER | Prioritet | Typiska jobb |
|---|---|---|
gtx1070 / gpu / bigrig | bigrig GTX1070-worker; accepterar Àven bigrig_work733-mÀrkta jobb sedan 2026-08-14 | NN-trÀning med GPU |
bigrig_work733 | bigrig(0s) â work733(3600s), pi aldrig | nn_nightly shards, paper_predict, nn_focused, oos_walkforward, data_pipeline, backtest |
pi | pi(0s) â bigrig(30s) â work733(600s) | morning_signals, rank_weight_day, refresh_materialized, fft_nightly_s2 â OBS: pi inaktiverad 2026-08-12 |
work733 / gt610 | work733(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:
Designprincip:
7. Native-acceleration (C/Cython)
7.1 C (c_ext/)
- 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_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
Wrapper: c_ext/init.py (ctypes, fallback till Python vid saknad .so).
7.2 Cython (cy_ext/)
7.3 OpenCL GPU-acceleration (c_ext/)
Infrastruktur för GPU-acceleration via OpenCL (implementerad, aktiveras nÀr driver finns):
| Fil | Syfte |
|---|---|
c_ext/opencl_matmul_stub.cpp | Tiled GEMM-kernel (matmul + NN-inferens) |
c_ext/opencl_backend.py | Python-bridge (ctypes), fallback till CPU vid saknad OpenCL |
c_ext/CL/cl.h | OpenCL-headers |
tools/sim_c/opencl_sim.py | GPU-parallell portfölj-simulator (1287 viktkombinationer i ett kernel-anrop) |
tools/signal_param_opencl.py | OpenCL-kernel signal_param_sim för signal_param_lhs.py |
Prioriterade GPU-kandidater (speedup mot CPU):
GT610-pipeline för signal_param_lhs:
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/):
Status och retention:
LÄsning:
Housekeeping (housekeeping_work733.sh, kör 03:30 dagligen):
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
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
| Tid | Dag | Script | Syfte |
|---|---|---|---|
| @reboot +90s | â | run_reboot_recovery.sh | Startar om ej avklarade kedjer efter omstart |
| @reboot +120s | â | apply_system_profile.sh day | SĂ€krar dagsprofil efter boot |
| */5 | MĂ„nâFre 18â23 | run_reboot_recovery.sh | Watchdog: startar om kvĂ€llskedjan vid krasch |
| */5 | MĂ„nâFre 18â23 | scheduler.sh | SchemalĂ€gger nĂ€sta steg i kvĂ€llskedjan |
| */5 | Lördag 00â03 | scheduler.sh | SchemalĂ€gger helgkedja-steg |
| 02:20 | Dagligen | partition_nn_predictions_shadow.py | Partitionering av NN-prediktioner |
| 03:00 | Dagligen | backintime | Systembackup |
| 04:15 | MĂ„nâFre | run_tests.sh | Kör 22 nattliga system-/hĂ€lsotester pĂ„ work733 |
| 02:00 | 1:a varje mĂ„nad | submit_job.sh rank_weight_monthly | Kör fas 7 per horisont (6Ă5 000 trials) + importerar vikter till DB |
| 04:00 | Söndag | submit_job.sh db_housekeeping | DB-underhÄll: OPTIMIZE, rensning, tmp-artefakter |
| 08:55 | MĂ„nâFre | run_intraday_fetch.sh + run_paper_daytrading.sh | Startup intraday + paper-handel |
| 09:00â17:30 | MĂ„nâFre | run_intraday_fetch.sh + run_paper_daytrading.sh | Var 5:e min under handelsfönster (stĂ€nger 17:30) |
| 17:40 | MĂ„nâFre | update_prices.py (Ă€ldre, stöds) | EOD-priser |
| 18:30 | MĂ„nâFre | update_all.sh QUEUE_OFFLOAD=1 | Huvudpipeline: data â indikatorer â signaler â backtest; steg 7+12 offloadar till bigrig |
| 01:00 | MĂ„nâFre | scheduler.sh (fallback) | Safety-fallback: kör scheduler om kvĂ€llens pipeline missade; submittar shardad nn_nightly om ej redan gjort |
| 00:30 | Lördag | scheduler.sh â weekend_chain (kön) | Helgkedja via queue: rank_weight â housekeeping â orphan-rensning â nn_focused â backtest-pass 2 â tester |
9.3 Driftmatris (per script)
| Jobb | Script | Frekvens | Syfte |
|---|---|---|---|
| Daglig huvudpipeline | update_all.sh (QUEUE_OFFLOAD=1) | mĂ„nâfre 18:30 | uppdatera priser, indikatorer, signaler, backtest och morning signals |
| FFT nattjobb (3 shards) | run_fft_nightly.sh | mĂ„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_all | mĂ„nâfre kvĂ€ll | alla 6 shards pĂ„ bigrig (PREFER=bigrig), aldrig pi â NN_BACKEND=c_ext |
| NN fokuserat | run_nn_focused.sh | mĂ„nâfre efter nn_nightly + lördag | top-N signaltickers DEPENDS:nn_nightly |
| Paper predict (6 shards) | kö-jobb paper_predict_s* | mĂ„nâfre efter nn_nightly | NN-inferens för paper trading DEPENDS:nn_nightly PREFER=bigrig_work733 |
| Portföljsimulering | rolling_1month_sim, simulate_portfolio | mĂ„nâfre efter paper_predict | rullande 1m-sim + perioder 1mâ3y, DEPENDS:paper_predict shards |
| OOS walk-forward | oos_walkforward.py | mĂ„nâfre efter nn_nightly | rullande OOS-validering DEPENDS:nn_nightly PREFER=bigrig_work733 |
| Paper daytrade-loop | run_paper_daytrading.sh | var 5:e minut 09:00â17:30 | intraday quotes, NN-inferens, paper-orderflöde |
| Morning signals | morning_signals kö-jobb | mĂ„nâfre efter nn_nightly | rankade morgonsignaler DEPENDS:nn_nightly PREFER=pi |
| Full testsvit | run_tests.sh | mĂ„nâfre 04:15 + lördag | 22 system-/hĂ€lsotester |
| Helgkedja | run_weekend_chain.sh | lördag 00:30 | rank_weight â housekeeping â nn_focused â backtest-pass 2 â tester |
| Rank-weight mĂ„nadsoptimering | submit_job.sh rank_weight_monthly | 1:a varje mĂ„nad 02:00 | fas 7 för 6 horisonter pĂ„ bigrig â rank_weight_horizons |
| DB-housekeeping | submit_job.sh db_housekeeping | söndag 04:00 | OPTIMIZE TABLE, rensning |
| Nattlig stÀdning | housekeeping_work733.sh | dagligen 03:30 | kö-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:
11. Prestandaöversikt (teknisk)
| Delsystem | Dominerande kostnad | Nuvarande optimering | Kvarvarande flaskhals |
|---|---|---|---|
| NN-trÀning/inferens | CPU (matmul/trÀningsloopar) + DB-upserts + RAM | C-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 ticker | modell-/prediktionsjoiner och total körtid vid stort universum |
| Indikatorpipeline | CPU (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-cykler | CPU (FFT per ticker/fönster) | parallel symbolkörning, inkrementell recompute | FFT-kÀrna Àr fortfarande pure Python |
| Backtesting | CPU + DB-write I/O | parallell symbolsplit, commit-batchning per ticker, C-backtest i kombinationsmotor | huvud-backtestmotorn anvÀnder Ànnu inte C-kÀrna |
| Intraday/paper | API-latens + DB-upserts | lockad cykel, inkrementell indikator-lookback, periodisk NN inferens | extern API-latens/formatÀndringar |
| Rank-weight fas 5 | NN-trĂ€ning (CPU) + portfölj-sim | C-NN (nn.so 2.6Ă/epok), C-sim (_sim.so 190Ă), early stopping, ensemble 3 | â (~5 min, 19Ă snabbare Ă€n Python-original) |
| API/statussida | subprocess-probar mot noder + loggscanning | TTL-cache (@_ttl_cached) + keyed TTL-cache + bakgrundstrĂ„d för hĂ„rdvarudata: 24.7 s â 0.35 s | första anropet efter TTL-utgĂ„ng betalar full kostnad |
| DB-housekeeping | RAM vid stora radmĂ€ngder | anti-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 shard | 320 anslutningar/shard â 1 batchad query per cykel | â |
12. FörbÀttringsförslag (prioriterad roadmap)
| Prioritet | Förslag | Effekt | Risk/komplexitet |
|---|---|---|---|
| â Klar | Global NN-trĂ€ning OOM-fix: two-pass streaming med synthetic features | eliminerar prepared[]-lista; 85% RAM-besparing (commit 98d17db) | â |
| â Klar | FFT-optimering: handskriven Cooley-Tukey â numpy.fft.rfft | ~100x speedup; fft_nightly 17 min â ~2 min (commit fc2ebe9) | â |
| â Klar | Indikatorloopar O(N) â O(1) / O(N) | v2: 10 running sums (commit 5066db2); extended: numpy stride_tricks (commit db66e93) | â |
| â Klar | Backtest parallellism: ProcessPoolExecutor | ~3-4x speedup via 4 processer; fas 1 DB, fas 2 CPU, fas 3 DB (commit 10d9741) | â |
| Hög | Flytta 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 C | hög |
| Hög | OpenCL FFT-batch pĂ„ GPU | GT610 ej lönsamt (1 SM Fermi, ingen gpyfft, PCIe-overhead = nollvinst) | â |
| Medel | LÀgg replay-motor för historisk intraday paper-simulering | bÀttre utvÀrdering av daytrade-strategi | medel |
| Medel | HMM-baserad regim-detektion som extra NN-feature | se 12.2 nedan | medel/hög |
| â Klar | Materialiserad "latest prediction"-vy/tabell för NN | löst via nn_pred_summary-optimering och batchfrĂ„gor i morgon.php | â |
| â Klar | Observability: StepTimer i calculate_all_indicators.py + calculate_signals_py.py | STEP-timing + SUMMARY per körning | â |
| Medel | LÀgg till Small Cap i _UNIVERSE_PRIORITY (efter MID_CAP) | utökat tickeruniversum | lÄg |
| LÄg | Central konfigurationsprofil (dev/stage/prod) | enklare driftstyrning | lÄg |
| LÄg | Derivat-motor: Black-Scholes/Merton, optioner, warranter, hedge | se 12.3 nedan | hö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:
Prioriterade lösningsalternativ:
| Alternativ | Teknik | RAM-besparing | Komplexitet |
|---|---|---|---|
| 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Ă€sning | Dela upp i ticker-batchar, trĂ€na med mini-epoch-ackumulering + global scaler pre-berĂ€knad | ~60â80 % | medel/hög |
| Rullande trÀningsfönster | BegrÀnsa fönster till 7 Är med tidsviktning (halvlife) | ~30 % | lÄg |
| Komprimerad DB-representation | Spara 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_t | observations)` (6â8 features) matas in i NN |
|---|
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
B. Riskminimering
| Metod | TillÀmpning |
|---|---|
| Delta-hedging | Neutralisera Î-exponering med motposition i underliggande |
| Gamma-scalping | Profittera pÄ realiserad volatilitet > IV |
| CVaR/ES-optimering | Minimera Conditional Value-at-Risk pÄ portföljnivÄ |
| Kelly-kriteriet | Optimal positionsstorlek givet edge och varians |
| Correlation-hedging | Neutralisera sektorrisk via indexkorgar (OMXS30 etc.) |
C. Warranter (svenska marknaden)
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
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
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:
13.2 API-autentisering (2026-08-07)
13.3 Watchdog â resursvĂ€ktare (watchdog.sh)
Watchdog kör kontinuerligt och skyddar mot OOM och systemkrasch:
| Tröskel | Varning | Stopp 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
Ej fixade M-fynd (2026-08-07, öppna):
Ă
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:
| Modul | Syfte |
|---|---|
nordnet_trader.py | REST-API-klient mot Nordnet: orderlÀggning, kontohantering, reconciliation |
order_manager.py | Orderlivscykel: sync_order_status, fillâposition, stop-loss, daglig PnL |
risk_manager.py | RiskbegrÀnsningar: max daglig förlust, positionstak, drawdown-kill |
trading_killswitch.py | Kill-switch och kretsbrytare: handelshorisont, helgdagar, circuit breaker |
Viktiga egenskaper:
- nordnet_trader.py: deterministisk `client_order_id = sha1(ticker | side | volume | timestamp)[:16]` för idempotens. |
|---|
16. Tekniska nyckelfiler
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:
Placeringshorisonter â separata viktsatser per horisont:
| Horisont | Sort-nyckel | Output-JSON | PHP-dashboard |
|---|---|---|---|
| Balanserad (composite) | composite | active_weights.json | âïž Balanserad |
| LĂ„ng (1+ Ă„r) | 3Ă„r | active_weights_long.json | đ LĂ„ng |
| Medel (3â12 mĂ„n) | 1Ă„r | active_weights_medium.json | đ Medel |
| Kort (1â2 mĂ„n) | 2mĂ„n | active_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
- 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)
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:
Turneringsfasen rangordnar de 8 grupperna deterministiskt:
BegrÀnsad sökning utnyttjar ranking-monotoni:
Högprioriterade buggar som rÀttats:
PrestandaförbÀttringar:
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):
| Surrogat | Target | Arkitektur |
|---|---|---|
surr_comp | composite | 8â64â32â1, Adam |
surr_1m | 1mĂ„n% | 8â64â32â1, Adam |
surr_2m | 2mĂ„n% | 8â64â32â1, Adam |
surr_1y | 1Ă„r% | 8â64â32â1, Adam |
surr_3y | 3Ă„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
Validering
Topp-50 surrogatförslag valideras med faktisk portfölj-simulering:
Sparar:
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:
- active_weights.json (composite/balanserad)
- active_weights_long.json
- active_weights_medium.json
- active_weights_short.json
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 |
|---|
16.8 C-accelererade kÀrnbibliotek
| Bibliotek | KĂ€lla | Syfte | Kompilering |
|---|---|---|---|
_sim.so | tools/sim_c/sim.c | Portfölj-simulator | gcc -O3 -msse2 -march=athlon64 -shared -fPIC -o _sim.so sim.c -lm |
nn.so | tools/nn_c/nn.c | Feedforward NN (Adam, SSE2, normalisering internt) | gcc -O3 -msse2 -march=athlon64 -ffast-math -shared -fPIC -o nn.so nn.c -lm |
Hastighetsvinst:
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
Loggrotation â /etc/logrotate.d/aktieanalys
| Logggrupp | Mönster | Frekvens | Retention |
|---|---|---|---|
| Pipeline/kedjeloggar | pipeline.log, evening_chain.cron.log, nn_nightly.log | daily | 30 rotationer |
| NN datumstÀmplade | nn_focused_.log, nn_nightly_.log, nn_detached_.log, nn_global_pretrain_.log, m.fl. | daily | 14 dagar |
| Kedjeloggar datumstÀmplade | evening_chain.log, pipeline_.log, fft_nightly_.log, reboot_recovery.log, rank_weight_monthly_*.log, m.fl. | daily | 7 dagar |
| Systemloggar | system_alerts.log, system_profile.log, tests.cron.log, validate_prices.log, db_housekeeping*.log, m.fl. | daily | 14 dagar |
| Rank-weight / multi-horizon | rank_weight_lhs_.log, rank_weight_oa_.log, rank_weight_phase4_.log, rank_weight_multi_horizon_.log | vid körning | 8 veckor |
| NN retrain | rank_weight/nn_retrain_clean_*.log | monthly | 6 mÄnader |
| Intraday/simulering | sim_day_.log, sim_swing_.log, intraday_fetch_.log, oos_walkforward_full_.log, stateful_oos_* | daily | 7 dagar |
| Strategy-experiment | strategy_v.log, arch_experiment.log | vid körning | 8 veckor |
| aa-ai generella | *.log i aa-ai/ och aa-ai/logs/ | weekly | 8 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:
Sampling: RW_SAMPLING=oa (standard) â OA-LHS styrka 2 via scipy.stats.qmc.LatinHypercube(strength=2). Env RW_SAMPLING vĂ€ljer `oa | lhs | sobol | halton | random`. |
|---|
Applicering:
Resultat (2026-07-15):
| Optimerat för | 1mÄn | 2mÄn | 6mÄn | 1Är | 3Ä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 qmc | tpe | cmaes (standard qmc`) | |||
|---|---|---|---|---|---|
| - `--horizon composite | 1m | 2m | 6m | 1y | 3y (standard composite`) |
Per-horisont vikter (_HORIZON_WEIGHTS):
| Horisont | w_1m | w_2m | w_6m | w_1y | w_3y |
|---|---|---|---|---|---|
| composite | 0.05 | 0.10 | 0.15 | 0.40 | 0.30 |
| 1m | 0.80 | 0.15 | 0.03 | 0.01 | 0.01 |
| 2m | 0.20 | 0.60 | 0.15 | 0.04 | 0.01 |
| 6m | 0.05 | 0.15 | 0.55 | 0.20 | 0.05 |
| 1y | 0.02 | 0.08 | 0.20 | 0.55 | 0.15 |
| 3y | 0.02 | 0.05 | 0.08 | 0.25 | 0.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:
| Risk | Beskrivning | Fix i koden |
|---|---|---|
| Resample-before-split | random.choices() med tidsvikter FĂRE split förstör tidsordningen â val-rader kan lĂ€cka in i trĂ€ning | Resampla 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önstret | NN_WALKFORWARD_EMBARGO_ROWS ska sÀttas ℠target-horisont (h=5 för ret_5d, h=20 för ret_20d) |
| Feature/target-kollision | Feature ret_5d (trailing) och target ret_5d (leading) har samma namn | Ej 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:
| Scope | Antal | KĂ€lla |
|---|---|---|
| OMX30 | 29 | Nasdaq Stockholm Large Cap-index, de mest omsatta |
| LARGE_CAP | 305 | Nasdaq Stockholm Large Cap (inkl. OMX30) |
| MID_CAP | 142 | Nasdaq 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: `1m | 2m | 6m | 1y | 3y | composite` |
|---|
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
20.2 Resultat (2026-07-15, 3 Är OOS)
| Period | NN-strategi | Regelstrategi |
|---|---|---|
| 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
- 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-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
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):
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.
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-typ | Ordning | Delays | Jobb |
|---|---|---|---|
bigrig | bigrig(0s) â pi(300s) â work733(3600s) | PrimĂ€r för GPU/tyngre CPU-jobb | nn_nightly, nn_focused, backfill, fft_nightly, ind_backfill, strategy_v3/v4/v5, phase7, refresh_materialized, rank_weight_day, weekend_chain m.fl. |
bigrig_work733 | bigrig(0s) â work733(3600s) â pi hoppas alltid av | KrĂ€ver x86-venv (pi ARM-inkompatibelt) | paper_predict s0âs5 (6 shards) |
bigrig_only | bigrig(0s) â work733 och pi hoppar | Jobb som enbart ska köra pĂ„ bigrig | (reserv â inga aktiva jobb) |
gt610 | work733(0s) â bigrig(300s) â pi(600s) | OpenCL/GT610 | calculate_signals, data_pipeline |
gpu | bigrig(0s) â pi(60s) â work733(600s) | CUDA-exklusiv (legacy) | (inga aktiva jobb för tillfĂ€llet) |
cpu | bigrig(0s) â pi(30s) â work733(120s) | Generisk CPU | morning_signals |
home733/work733 | work733(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_epoch | done_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`. |
|---|
22. Ăndringar 2026-08-09
- 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. |
|---|
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:
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):
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):
22.4 Backtest.php â flik-persistens
Problem: Fliken hoppade tillbaka till "StrategijÀmförelse" vid varje formulÀrsubmit.
Fix (commit c32c806):
22.5 Rapport.php â signalfixar
22.6 Inkluderade filer â db.php
22.7 aktie.php â Pris & volym-graf (commit 19b4674)
23. DB-underhÄll och indexstrategi (2026-07-18)
23.1 Utförd cleanup
| à tgÀrd | Effekt |
|---|---|
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 modeller | Snabba PK-lookups, inga fler full-scans |
| Droppade 5 redundanta tabeller | Se §23.2 |
| Droppade 3 redundanta index | Se §23.3 |
Modeller som behölls per target (2 senaste med prediktioner):
| Target | BehÄllna model_id |
|---|---|
| prob_up_1d | 16006, 16005 |
| prob_up_2d | 16010, 16009 |
| prob_up_3d | 16007, 16002 |
| prob_up_4d | 16011, 16004 |
| prob_up_5d | 16008, 15987 |
| ret_20d | 16001, 16000 |
| ret_5d | 15997, 15996 |
| signal_3class | 15992, 15990 |
23.2 Droppade tabeller
| Tabell | Anledning |
|---|---|
fundamental_data | 0 rader; ersatt av daily_fundamentals + daily_fundamentals_asof |
nn_training_log | 0 rader; ersatt av nn_training_epochs |
ticker_universe_backup_20260715 | TemporÀr backup frÄn universumrensningen 2026-07-15 |
paper_ab_reports | 0 rader; aldrig populerad i produktion |
dashboard_indicators_cache | 0 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
| Tabell | Borttaget index | BehÄllet överlappande index |
|---|---|---|
nn_predictions | idx_nn_pred_ticker_model_date | idx_model_date_ticker (PRIMARY + detta rÀcker) |
nn_predictions | idx_model_ticker_date | idx_model_date_ticker |
daily_prices | idx_daily_prices_ticker_date | unique_ticker_date(ticker_id, date) tÀcker samma |
daily_signals | idx_ticker_date | unique_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):
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)
| Komponent | Version | Detaljer |
|---|---|---|
| OS | Debian 11 | debian11-vm-733 |
| nginx | systemd-tjÀnst | Let's Encrypt, tegelwall.duckdns.org |
| php-fpm | PHP 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/:
| Fil | Funktion |
|---|---|
index.php | Startsida â aktietabell med signaler |
aktie.php | Detaljsida per ticker (inkl. lÀnk till indikatoröversikt) |
indikatorer.php | Indikatoröversikt per ticker â alla indikatorer med KĂP/AVVAKTA/SĂLJ + summering (tillagd 2026-08-02) |
morgon.php | Morgonsignaler + NN-prediktioner |
backtest.php | Backtestresultat och strategijÀmförelse |
nn.php | NN-modeller, per-ticker prob_up-signaler (1dâ5d) och signal_3class (prob_val-fix 2026-08-02) |
papper.php | Paper trading â produktion + experiment |
signaler.php | Signalöversikt |
rapport.php | Daglig go/no-go-rapport |
makro.php | Makrodata â rĂ€ntor, spread, KPIF, regimindikator, sektoröversikt, period-slider (2026-08-03) |
hjalp.php | HjÀlpsida |
db.php | PDO-databasanslutning (inkluderas av alla sidor) |
includes/layout.php | Gemensam 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/)
| Endpoint | Beskrivning | Nyckeldata |
|---|---|---|
macro_data.php | All makrohistorik sedan 1987 | dates, repo_rate, rate_10y, kpif_yoy, spread, last_known, regime_changes |
sector_data.php | Sektorbredd â RSI, signaler, avkastning | sectors[], as_of |
macro_data.php â detaljer (uppdaterad 2026-08-03):
24.3b Makro-sidan (makro.php) â implementeringsdetaljer
Chart.js-plugins registrerade globalt:
Range-slider (dubbel handtag):
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:
Systemstatussida
URL: https://tegelwall.duckdns.org/aa/status
Sidan uppdateras automatiskt var 30:e sekund och visar:
| Sektion | InnehÄll |
|---|---|
| đ Sessions | Nordnet + Avanza login-status, BankID-knapp för förnyelse |
| đ©ș Externa datakĂ€llor | api_health för Avanza, Yahoo, makro och browser-session; visar ok/warn/error, senaste fel och fail-rĂ€knare |
| âïž Processer | Status för browser_session_daemon, FastAPI, paper daytrading, evening chain |
| đŸ RAID-status | RAID-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 loggar | De 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
| Cert | AnvÀnds för | SökvÀg |
|---|---|---|
| Let's Encrypt | tegelwall.duckdns.org (extern) | /etc/letsencrypt/live/tegelwall.duckdns.org/ |
| Self-signed | 192.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Àrd | Detalj |
|---|---|
virsh autostart debian12 | VM autostarter nu vid host-reboot |
| VM RAM | SĂ€nkt frĂ„n 2 GB â 800 MB (tillrĂ€ckligt för nginx + php-fpm) |
| Custom kernel | 5.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 rensade | gdm3, 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
| Problem | Rotorsak | à tgÀrd |
|---|---|---|
innodb_buffer_pool_size 512 MB trots 2 GB i config | apply_system_profile.sh satte DAY_BP=512MB dynamiskt via SET GLOBAL | Höjt till 2 GB i bÄde DAY och TRAIN-profil (commit 645a892) |
Lost connection vid calculate_signals | ALTER TABLE pĂ„ 35 GB + GPU-bulk INSERT â I/O-kaos spinning disk | calculate_signals vĂ€ntar nu pĂ„ ALTER TABLE (submit_job.sh, commit 7a72963) |
| nn_weights 35 GB LONGTEXT | weights_json/biases_json som text â omöjligt att cacha | ALTER 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_predictions | Höjt till 120s i /etc/mysql/mariadb.conf.d/99-aktieanalys-timeouts.cnf (2026-08-02) |
Lost connection via SSCursor fetchmany | net_read_timeout=600 för kort vid stor streaming-query under predict | Hö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):
| Tabell | Index | Syfte |
|---|---|---|
daily_signals | idx_ds_date_strength(date, signal_strength) | Eliminerar filesort i signalsida ORDER BY |
daily_signals | idx_ds_date_ultimate(date, ultimate_buy, ultimate_sell) | TĂ€cker ultimate-signal queries |
nn_predictions | idx_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)
| Prioritet | Fix |
|---|---|
| KRITISK | calculate_signals_py.py: GPU-bulk streamar med SSDictCursor, 1.2M rader laddas inte lÀngre i RAM |
| HĂG | db_pool.py: POOL_PREWARM 10â1 som default |
| HĂG | nn_pytorch_trainer.py: validering batchvis (val-set laddades till GPU i ett block) |
| HĂG | paper_trading_sim.py: race condition i get_or_create_account() â UPSERT |
| MEDIUM | Cursor/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.
| Egenskap | JSON (gammalt) | npz (nytt) |
|---|---|---|
| Storlek/modell | ~1 MB | ~180 KB (5,9Ă komprimering) |
| Laddningstid | 73 s (DB-round-trip) | <1 ms (mmap frÄn disk) |
| Format | JSON text | float32 numpy-arrays W0,b0,W1,b1,⊠|
Implementering (neural_network.py):
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:
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:
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:
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:
| Fil | Rad | Kategori | Allvar | Status |
|---|---|---|---|---|
calculate_signals_py.py | 44 | TREND_GATE=0 â falskt köp i nedtrend | HĂG | FIXAD |
calculate_signals_py.py | 451-452 | buy_score floor 42 utan trendcheck | HĂG | FIXAD |
aktie.php | 208 | a.name â a.account_name SQL-fel | HĂG | FIXAD |
api.py | 619+626 | write_text() ej atomisk för cookies/session | MEDEL | FIXAD |
paper_trading_sim.py | 1350-1394 | autocommit-race kring SELECT FOR UPDATE | KRITISK | Ăppen |
neural_network.py | 3802-4162 | DB-connection hĂ„lls öppen hela trĂ€ning | HĂG | Ăppen |
neural_network.py | 2532-2555 | deferred_rows.extend(part) peak-RAM | HĂ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):
Kör calculate_signals om för att rÀkna om alla signaler med ny logik.
27.3 Logrotation och housekeeping â alla maskiner
| Maskin | Status | à 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 idag | Se 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:
27.4 Aktie-dashboard grafförbÀttringar (commit d879522)
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
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.
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
| Maskin | Status | Detaljer |
|---|---|---|
| work733 | â
/etc/logrotate.d/aktieanalys | TĂ€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 kappad | SystemMaxUse=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:
neural_network.py:
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.
| Steg | KĂ€lla | Kommentar |
|---|---|---|
| 1 | avanza_update_prices.py | HÀmtar 5 Är för alla ~306 Avanza-mappade tickers |
| 2 | fetch_yahoo_history.py --skip-avanza-mapped | Fyller bara tickers som saknar Avanza-mappning (~2 st) |
| 2b | validate_prices.py + avanza_update_prices.py --fix-frozen | Validerar 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:
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):
db_pool.py (commit bb28188):
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:
| Jobb | QUEUE_HEARTBEAT_STALE |
|---|---|
nn_nightly | 21600 s (6 h) |
nn_focused | 14400 s (4 h) |
rank_weight_monthly | 86400 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:
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)
28.15 Alerting-system (2026-07-30)
Arkitektur
API
28.16 NN signal_3class klassbalansering (2026-07-30)
Problem
Lösning
till 70% av majoritetsklassens storlek via random.choices()
FörvÀntat resultat
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):
| Variabel | Gammalt | Nytt |
|---|---|---|
PAPER_NN_MIN_CONFIDENCE | 0.58 | 0.44 |
PAPER_SWING_NN_MIN_CONFIDENCE | 0.52 | 0.43 |
PAPER_SWING_NN_MIN_CONFIDENCE_STRICT | 0.65 | 0.46 |
PAPER_DAY_NN_MIN_CONFIDENCE | 0.50 | 0.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.
| Strategi | Avkastning | Sharpe | Antal trades |
|---|---|---|---|
nn_prob_p0.55 â prob_up_5d â„ 0.55 | +251.1 % | 0.58 | 31 |
nn_pure_c0.45 â signal_3class â„ 0.45 | +2.4 % | 0.61 | 3 |
| Strategier med confidence â„ 0.55 | 0 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):
| Ticker | Avg acc |
|---|---|
| VOLO-PREF.ST | 88.5 % |
| EMIL-PREF.ST | 80.8 % |
| BESQAB-PREF-B.ST | 73.1 % |
| NP3-PREF.ST | 66.6 % |
| INTEA-D.ST | 64.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:
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:
30.7 prob_up_1dâŠ4d â nulĂ€ge och plan
| Target | Antal modeller | AnvÀnds i paper trading |
|---|---|---|
prob_up_1d | 2 019 | Dag-regime-filter (day_regime_min_prob_up_1d) |
prob_up_2d | 2 005 | Ej |
prob_up_3d | 2 022 | Ej |
prob_up_4d | 2 016 | Ej |
prob_up_5d | 2 014 | PrimÀ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'):
bigrig venv trasig (pyenv 3.11.8-symlink â inte installerad):
31.2 Makro-regime-arkitektur
Ny modul tools/macro_regime.py:
| - Returnerar strĂ€ng: `"{bull | neutral | bear}_{falling | stable | rising}"` â 9 möjliga regimer |
|---|
Per-sektor Ă makro-regime LHS-parameterarkitektur i signal_param_lhs.py:
Sektornormalisering i DB: 16 tickers uppdaterade (FastighetâFastigheter, Bank&FinansâFinans, etc.)
31.3 nn_nightly-schema
Crontab Àndrad:
31.4 Multi-horisont-konsensus (paper trading)
build_prob_up5d_signals() i paper_trading_sim.py:
PAPER_SWING_NN_SEK aktiverar konsensus:
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.
Resultat prob_up_1d (2025-07-30 â 2026-07-30, 2402 obs, basrate 51.5%):
| TröskelvĂ€rde | KĂP n | KĂP-riktighet | Lift |
|---|---|---|---|
| 0.50 | 713 | 53.4 % | +3.7 % |
| 0.52 | 559 | 55.8 % | +8.3 % â nuvarande trösk |
| 0.54 | 451 | 55.0 % | +6.7 % |
| 0.56 | 396 | 53.8 % | +4.4 % |
| 0.58 | 344 | 53.8 % | +4.3 % |
| 0.60 | 308 | 54.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Ă€rde | KĂP n | KĂP-riktighet | Lift |
|---|---|---|---|
| 0.50 | 1 264 | 56.1 % | â2.8 % |
| 0.52 | 1 120 | 55.9 % | â3.1 % |
| 0.55 | ~870 | ~56 % | ~â3 % |
| 0.60 | 633 | 55.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:
JÀmförelse prob_up_1d vs prob_up_5d:
31. Ăndringar 2026-08-02
31.1 MariaDB â timeout-konfiguration
TvÄ MySQL-relaterade fel orsakade att paper_predict-jobbet kraschade (2026-07-31):
Ă
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:
| Kategori | Indikatorer |
|---|---|
| Trend | SMA50, SMA200, Golden/Death Cross |
| Momentum | RSI(14), MACD, Stochastic K/D, CCI(20) |
| Volatilitet | Bollinger %B, ATR(14) |
| Trendstyrka | ADX(14) |
| Ichimoku | TK-Cross, Cloud position |
| Signal | PSAR trend, VWAP-avstÄnd |
| FFT Cykler | Cycle bias score |
| NN | prob_up_1dâ5d (â„65%=KĂP, â€35%=SĂLJ), signal_3class |
| Morgonsignal | Gap-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
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
32.2 API-hÀlsospÄrning (api_health)
32.3 Rensning av orphan nn_predictions
32.4 Test-suite (tests/test_system_health.py, run_tests.sh)
32.5 Kritiska felrÀttningar (commit 775e118)
32.6 Kommentarer och docstrings
Kommentarer/docstrings lades till i:
32.7 Helgkedjan uppdaterad
run_weekend_chain.sh har nu 7 steg:
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:
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:
| Jobb | Förut | Nu |
|---|---|---|
| nn_nightly, nn_focused | gpu | bigrig |
| paper_predict | gpu | bigrig |
| backfill, fft_nightly, ind_backfill | cpu | bigrig |
| strategy_v3/v4/v5, phase7 | cpu | bigrig |
| refresh_materialized | cpu | bigrig |
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
| Nod | Förut | Nu | Metod |
|---|---|---|---|
| bigrig | 8 workers | 6 workers | Stoppade worker 7+8 manuellt; @reboot seq 1 6 |
| pi | 4 workers | 2 workers | Watchdog-tröskel 4â2, @reboot seq 1 2 |
33.4 Cron-konsolidering (work733)
Borttagna/ersatta cron-jobb:
| Borttaget | ErsÀttning | Anledning |
|---|---|---|
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_chain | Direktkö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:
33.5 Logrotate â kompletterat alla maskiner
| Maskin | Status | Ăndringar |
|---|---|---|
| work733 | â Uppdaterad | cron_nn_nightly.log tillagd |
| bigrig | â Skapad 2026-08-05 | TĂ€cker .log i aa-ai/ och /tmp/queue_worker_bigrig_.log |
| pi | â Uppdaterad | Slurm-stanza borttagen; /tmp/queue_worker_pi_*.log tillagd |
| vm | â Uppdaterad | su tege tege + compress + delaycompress tillagd |
33.6 housekeeping_work733.sh â utökat
Tillagda steg:
33.7 PÄgÄende (ej klart)
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):
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:
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:
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:
SUMMARY-format:
SUMMARY tickers=308 DB-rader=3 542 loop=47.1s total=52.3s genomströmning=75 rader/s
34.7 Roadmap-status
| Item | Status | Anteckning |
|---|---|---|
| ARM-vakt + TEMPFAIL | â Klar | commits 812fa9c, 1ecf9ec |
| ETA för shards | â Klar | commit 1ecf9ec |
| "senaste 10" â 15 | â Klar | commit a9989e3 |
| rolling_1month_sim PYTHONPATH | â Klar | commit 7cc6a4a |
| Bull-regime kalibrering | â Klar | commit 207125a |
| Multi-horisont-konsensus | â Redan klar | §31.4 |
| Observability StepTimer | â Klar | commit 025fc41 |
Small Cap _UNIVERSE_PRIORITY | đŽ Blockerad | KrĂ€ver nya tickers + data pipeline |
| Low-acc tickers ret_20d | â Klar | commit 5ca00e4, se §35 |
35. SystemförÀndringar 2026-08-06
35.1 WORKER_TYPE â dedikerade GPU/CPU-workers
Workers uppdelades pÄ typbaserade systemd-instanser:
| Nod | Instans | MAX | Tar jobb |
|---|---|---|---|
| bigrig | @cpu | 6 | Alla utom gpu/gt610 |
| bigrig | @gpu | 2 | Enbart QUEUE_PREFER: gpu |
| work733 | @cpu | 2 | Alla utom gpu/gt610 |
| work733 | @gt610 | 1 | Enbart QUEUE_PREFER: gt610 |
| pi | @cpu | 1 | Alla 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_epoch | done_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)
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:
| Tabell | Index | à tgÀrd | Motivering |
|---|---|---|---|
nn_predictions | idx_nn_pred_ticker_model_date | DROP | Optimizer 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_signals | idx_ds_signal_date | DROP | Ingen query filtrerar (date,buy,sell)-kombinationen |
daily_signals | idx_ds_date_ultimate | DROP | Inga queries anvÀnder (date,ultimate_buy,sell) |
daily_signals | idx_ds_buy_sell | ADD | WHERE buy_signal=1 i main_simple.py scannnade 1.17M rader; nytt index fixar full scan |
nn_training_epochs | idx_target_ticker_created | DROP | Prefix-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:
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 `work733 | home733) 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: work733 | home733) ;;` 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:
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:
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:
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):
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:
backtest_engine.py â progressbar kraschade hela run_all():
neural_network.py â params i fel ordning + look-ahead bias + SSDictCursor-trunkering:
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:
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:
MinneslÀckor:
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:
| Schema | Jobb | Konfiguration |
|---|---|---|
| MĂ„nâFre natt â„20:00 | nn_nightly (6 shards + koordinator) | 30 epochs, resume=1, 5-Ă„rs rullande fönster |
| Normala lördagar â„20:00 | nn_nightly (helg-profil) | 30 epochs, alla targets inkl. prob_global |
| Första lördagen/mĂ„naden â„20:00 | nn_nightly_monthly (6 shards + koordinator) | 50 epochs, resume=0 (tvingar omtrĂ€ning av alla tickers) |
| Manuellt (vid behov) | nn_all | 10 epochs, ingen pretrain â kvar för: ny tom DB, kritisk bug-fix, ny server |
Tekniska Àndringar:
- submit_job.sh: alla QUEUE_DEPENDS: nn_nightly â `nn_nightly | nn_nightly_monthly` (OR-syntax) |
|---|---|
- queue_worker.sh: ny OR-operator ` | ` i DEPENDS-parsern (minst ett alternativ rÀcker) |
35.25 Open items §12 + Opus-5 runda 3 (commits bd26586, 470bcd7)
Implementerade open items (commit bd26586):
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:
| Fil | Allvar | Fynd | Fix |
|---|---|---|---|
neural_network.py | CRITICAL | ±1e6 clip förstörde obv/ad_line/pvt (~1e10 â konstant) | Ăndrat till ±1e15 (enbart inf-skydd) |
neural_network.py | HIGH | Train/serve-skev: clip saknade i predict_all | Lagt till ±1e15-clip före normalisering i predict_all |
oos_walkforward.py | HIGH | 3-dagars warmup tĂ€cker inte helgdagskluster (pĂ„sk/jul) | Ăndrat till 10 dagar |
oos_walkforward.py | HIGH | len(rows)<5 accepterade nylistade tickers â CAGR=999999.99 | OOS-rĂ€kning specifik + threshold 30 |
neural_network.py | LOW | np.where(stds_arr>0) skyddar inte mot denormala stds | np.maximum(stds_arr, 1e-9) |
paper_trading_sim.py | MEDIUM | Dubbel SELECT (dead code) + no-op rollback | SELECT borttaget, rollback kommenterat |
BekrÀftade korrekta av Opus-5:
KvarstÄende medium-issues (ej akuta):
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):
| Indikator | Bugg | Fix |
|---|---|---|
hist_vol_5/20/60 | C: population var /period; Python: sample /ïŒn-1) | C Ă€ndrat till /(period-1) |
keltner_upper/lower | C: ATR(20); Python-fallback: ATR(14) â 381/400 barer skilde | Python berĂ€knar nu atr20, fallback anvĂ€nder ATR(20) |
Medium-buggar i Python:
| Indikator | Bugg | Fix |
|---|---|---|
aroon_up/down | C: 26-bars fönster (j<=period); Python: 25 | C Àndrat till j<period |
psar_trend/psar | EP uppdaterades FĂRE reversal-test â fel SAR-vĂ€rde pĂ„ utomstĂ„ende barer | Reversal check FĂRE EP-uppdatering (C + Python) |
fisher | AnvÀnde highs[i] istf median price (H+L)/2; saknade 0.33/0.67 EMA-glÀttning | Korrigerat till Ehlers original |
hurst_100 | Shadowing-bugg: var = sum(d*d for d in chunk) (E[xÂČ] â variance) | sum(d*d for d in dev) |
cvar_5pct_63 | Off-by-one: _wr[:_idx] exkluderade VaR-observationen | _wr[:_idx+1] |
sortino_63 | Downside-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:
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:
TransaktionssÀkerhet (autocommit-fix)
db_pool.py kör autocommit=True. commit()/rollback() Àr no-ops utan conn.begin(). Fixat i:
SĂ€kerhet
Live trading-modul
Komplett live-handelslager mot Nordnet implementerat och dokumenterat (§15):
| - `client_order_id = sha1(ticker | side | volume | timestamp)[:16]` med mikrosekunder |
|---|
Signal executor
Ăvrigt
Runda 11 â 2026-08-07
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.
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):
Runda 14 â 2026-08-07
Runda 15 â 2026-08-07 (simuleringsgranskning)
backtesting.py â PostgreSQL-prototyp, ej importerad i produktion:
simulate_day_portfolio.py:
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:
Vyer:
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:
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:
fetch_avanza_intraday_quotes.py:
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:
| Scenario | Genomströmning | Total tid |
|---|---|---|
| 2 GPU-shards | ~22 mod/min | sekventiellt ~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
| Problem | Nod | Fix |
|---|---|---|
.log- stansa re-roterade redan roterade filer â *.log-DATUM-DATUM dubbelnamn | bigrig/work733 | Stansen borttagen frĂ„n /etc/logrotate.d/aktieanalys |
| 9 malformade dubbelnamn-filer | bigrig | Raderade direkt |
test_results_YYYYMMDD.log saknade rotation | alla | Lade till daily, rotate 14 |
/tmp/aa_queue_*.log saknade rotation pÄ PI | pi | Lade till stans |
/tmp/qw_pi_new_*.log saknade rotation | pi | Lade till stans |
| VM saknade cron för logrotate | vm | 0 3 * logrotate /etc/logrotate.d/aktieanalys |
| PI saknade daglig logrotate-cron | pi | 0 3 * find /tmp + logrotate |
housekeeping_work733.sh rensade ej test_results | bigrig | Steg 5c + 5d tillagda |
Logrotate â aktuell tĂ€ckning per nod
| Nod | Konfig | Kör via | TÀckning |
|---|---|---|---|
| bigrig | /etc/logrotate.d/aktieanalys | housekeeping_work733.sh 03:30 | /shared/logs/, /var/log/aktieanalys/, /tmp/trading-daemons |
| work733 | /etc/logrotate.d/aktieanalys | housekeeping_work733.sh 03:30 | Identisk med bigrig |
| pi | /etc/logrotate.d/aktieanalys | cron 0 3 * | /home/tege/work/python/aa-ai/, /tmp/queue_worker_pi_.log, /tmp/aa_queue_.log |
| vm | /etc/logrotate.d/aktieanalys | cron 0 3 * (ny) | /var/log/aktieanalys/ |
housekeeping_work733.sh â tillagda steg (commit cdd3a48)
deploy/-katalog
| Fil | Beskrivning |
|---|---|
deploy/aktieanalys.logrotate | KÀlla för bigrig/work733/VM |
deploy/aktieanalys_pi.logrotate | KÀlla för PI (ny) |
deploy/README.md | Install-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:
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.
37.2 Noder, GPU:er och PREFER-routing (korrigerad matris)
| Nod | Worker-roller | Kommentar |
|---|---|---|
work733 | CPU-workers + 1 GT610-worker | OpenCL/GT610-jobb körs hÀr primÀrt |
bigrig | CPU-workers + GTX1070-workers | PrimÀr nod för GPU- och tyngre DB-jobb |
raspberrypi | 1 CPU-worker endast | Ingen pymysql, ingen GPU |
PREFER-vÀrden:
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:
Cykler:
Jobb i kedjan:
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:
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().
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:
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:
Borttaget:
37.7 schema_postgres.sql â PostgreSQL-kompatibelt schema
Ny fil: schema_postgres.sql.
37.8 PostgreSQL pÄ ubuntu24.10-VM
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):
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:
| Jobbtyp | Gammalt PREFER | Nytt PREFER | Anledning |
|---|---|---|---|
nn_all_s0âs5 | gtx1070 / cpu | bigrig | cpu-token tillĂ€t pi (30s vĂ€ntan); gtx1070 slösade GPU-slots |
nn_nightly_s0âs5, koord | gtx1070 | bigrig_work733 | pi exkluderas permanent |
nn_nightly_monthly | gtx1070 | bigrig_work733 | samma skÀl |
paper_predict_s0âs5 | gtx1070 | bigrig_work733 | x86-venv, ARM-inkompatibelt |
oos_walkforward, _blankslate | gtx1070 | bigrig_work733 | samma 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:
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)
38.5 Dashboard â per-jobb CPU% via /proc/PID/environ
api.py lÀser nu exakt CPU% per NN-shard (inte nod-aggregat):
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:
| Dimension | Kolumn | Tolkning |
|---|---|---|
| ADX 20d snitt | avg_adx_20 | Trendstyrka |
| ATR% 20d snitt | avg_atr_pct | Normaliserad volatilitet |
| Hurst-exponent | hurst | H>0.55=trend, H<0.45=mean-rev, Hâ0.5=random |
| Beta vs OMXSPI | beta_omx | Korrelation/hÀvstÄng mot index |
| BB-bredd | bbw | Komprimering (lÄgt) vs expansion (högt) |
| Autokorrelation | autocorr_1d | Positiv=momentum, negativ=mean-reversion |
Regimer (prioritetsordning):
| Regime | Kriterier | Strategi | Antal tickers (2026-08-12) |
|---|---|---|---|
mean_reverting | autocorr < -0.15 ELLER (H<0.45 & ac<0) | mean_reversion_bounce | 67 |
choppy_flat | ADX<15 & ATR%<1.5 | choppy_flat | 1 |
momentum_high_beta | H>0.55 & beta>1.2 & autocorr>0 | momentum_high_beta | 17 |
breakout | ADX>32 & ATR%>2.0 & H>0.50 | bb_squeeze_breakout | 21 |
stable_trend | ADX>30 (ej breakout) | macd_vol_trend | 15 |
oscillating | ADX<22 | macd_fast_reversal | 118 |
mild_trend | allt annat (ADX 22-32) | macd_vol_trend | 62 |
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
39.5 MinneslÀcksfixar (frÄn Claude Opus 4.8-granskning)
| Fix | Fil | Beskrivning |
|---|---|---|
| A1 | neural_network.py | _evict_model_from_cache() + clear_model_cache() â VRAM/np-cache frigörs vid vrĂ€kning |
| A3 | neural_network.py | predict_all() finally: gc.collect() + _trim_process_memory() |
| E3 | neural_network.py | tempfile.mkstemp utan dir="/tmp" â respekterar TMPDIR/NN_TMPDIR |
| C1 | backtest_engine.py | _LeasedPoolConnection.init â pool-lease returneras korrekt vid enter-fel |
| C3 | backtest_engine.py | strategy_signals â optimerad loop (lokal variabelbindning, undviker enumerate-overhead) |
| B3 | run_nn_nightly.sh | MALLOC_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):
40.2 Implementerade lösningar
IC-screening (compute_signal_ic)
BerÀknar Information Coefficient per signal:
| - ` | IC | >= 0.02 krÀvs för att signalen ska delta i optimering (_ACTIVE_KEYS`) |
|---|
Walk-forward CV (objective_wf, evaluate_wf, _make_wf_windows)
OOS-exklusiv optimering:
Regime-split
CLI-flaggor (nya)
| Flagga | Default | Beskrivning | |||
|---|---|---|---|---|---|
--walk-forward | false | Aktivera OOS walk-forward CV som objektiv | |||
--regime | all | Filtrera tickers: oscillating\ | trending\ | mean_reverting\ | ... |
--ic-min | 0.02 | Minsta \ | IC\ | (0 = stÀng av IC-screening) | |
--wf-folds | 3 | Antal WF-fönster | |||
--wf-train-months | 18 | TrÀningsmÄndads lÀngd per fold | |||
--wf-test-months | 6 | OOS-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_oscillating | rank_weight_trending | rank_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)
| Fil | FörÀndring |
|---|---|
tools/rank_weight_sim_phase7.py | +350 rader: IC, WF-CV, regime-split, nya CLI-flaggor |
neural_network.py | NN_PREDICT_STRICT_OOS default 0â1; fallback i get_oos_model_id_for_date |
submit_job.sh | 3 nya regime-rank_weight-jobb |
shared/bin/submit_job.sh | Samma |
shared/bin/scheduler.sh | Sö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Äde | FörÀndring | Effekt |
|---|---|---|
| Klassbalans | Dynamisk class-viktning i CrossEntropyLoss för signal_3class | Köp/sĂ€lj-klasser fĂ„r större vikt nĂ€r hold dominerar 70â80 % av labels |
| Feature-scoring | mutual_info_classif ersÀtter Pearson för klassifikationsmÄl | FÄngar icke-linjÀra samband bÀttre |
| Target-design | Ny target signal_3class_20d | BÀttre signal/brus-ratio Àn 5-dagarsvarianten |
| TrÀningsstopp | Early stopping med patience 8 i vardagsprofil | Mindre overfitting i nattjobben |
| Kalibrering | nn_calibrate.py körd manuellt pĂ„ bigrig 2026-08-13 | FrĂ€schare sannolikheter efter Ă€ldre extrem slope (~5â6) |
41.2 FilÀndringar
| Fil | Fö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.py | Ny 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.py | required_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.py | class_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.sh | Vardagsprofil 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Ätt | Utfall |
|---|---|
| NN-signaler | 52,092 |
| Regel-signaler | 14,473 |
| Enighet samma dag | 52.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:
| Mode | Logik |
|---|---|
nn_confirmed_by_rule | NN-signal accepteras bara om regelmotor bekrÀftar inom ±3 dagar |
rule_confirmed_by_nn | Regelsignal accepteras bara om NN bekrÀftar inom ±3 dagar |
union_agree | Union/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:
| Strategi | 3 Ä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.
| Del | Beskrivning |
|---|---|
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 |
| Datalayout | Flat 2D (n_tickers à n_dates) för priser, signaler och indikatorfÀlt |
| Exitlogik | ATR-baserad stop-loss, ATR-trailing, weakness-exit (EMA20 + MACD), time-exit och signal-exit |
| Output | Daglig 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.
| Funktion | Roll |
|---|---|
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:
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:
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
| Steg | Minne |
|---|---|
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-peak | 705 + 705 = 1410 MB â OOM |
Ă
tgÀrder i neural_network.py / c_ext/neural_network.py:
(behÄller view-semantik nÀr dtype redan stÀmmer).
evaluate_signal3class_balance, MLP.forward, valideringsvÀgen och
_npz_reconstruct_accumulators.
Python-listor per kolumn), np.empty i stÀllet för np.full.
varje epok (~125 k Python-floats per lager och epok).
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).
nightly-loopen kör gc.collect() efter varje ticker och efter predict_all.
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
| Modul | Bugg | Effekt |
|---|---|---|
neural_network.py | ensure_model_registry_table anropades ~103 000 ggr/natt via update_champion_challenger â DDL + commit varje gĂ„ng | nu 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.py | predict_all lĂ€ste n_classes ur cfg â nyckeln finns inte i TARGETS, sĂ„ vĂ€rdet föll alltid tillbaka pĂ„ 3 | lĂ€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 returns | commit före early return + rollback vid undantag |
neural_network.py | predict_all lÀckte cursors vid undantag | stÀngning flyttad till finally med None-init |
paper_trading_sim.py | look-ahead bias i ATR, market_profile och support/resistance vid intradag-asof; load_signals anvÀnde fel datum | daglig data trunkeras nu korrekt vid intradag-asof; simuleringsresultat före fixen Àr optimistiskt biased |
backtest_engine.py | felaktig PnL-berÀkning; OOM vid stora universum | rÀttad PnL, minnesbegrÀnsad körning |
oos_walkforward.py | PnL saknade courtage och slippage; task-fönstret gled | PnL 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 DB | dry-run Àr nu lÀsning enbart |
tools/oos_walkforward_blankslate.py | use-after-release av delad resurs; TypeError nÀr workers<=1 | bÄda rÀttade |
gpu_accelerator.py | OpenCL race condition vid kontextinit, int32-overflow vid stora index, OOM vid stora buffertar | serialiserad init, int64-index, chunkade överföringar |
nn_pytorch_trainer.py | AMP-bugg (fp16 aktiverades inte korrekt), NaN-vikter, autograd-graf som inte slÀpptes | fp16 fungerar nu pÄ GTX1070; NaN-skydd och korrekt detach mellan batchar |
queue_worker.sh | heartbeat registrerade $$ (förĂ€lderns PID) i subshell | $BASHPID â orphan-recovery bedömer nu rĂ€tt process |
44.4 PrestandaförbÀttringar
| OmrÄde | Före | Efter |
|---|---|---|
| IndikatorberĂ€kning (ctypes-arrayer byggdes 13Ă per körning, O(n·k)) | baslinje | â19 % körtid (byggs 1Ă, O(n)) |
| API-statussida | 24.7 s | 0.35 s (TTL-cache, se arkitekturdok §9.3) |
tools/db_housekeeping.py | materialiserade nyckelmÀngder i RAM | anti-joins körs i databasen |
nn_wf_train_s0/s1 | 320 DB-uppkopplingar per shard | 1 batchad query per cykel |
44.5 SĂ€kerhetsfixar
| Komponent | SÄrbarhet | à tgÀrd |
|---|---|---|
api.py â serve_log() | path traversal via filnamn | basnamn + Path.resolve() och relative_to(_LOG_DIR.resolve())-kontroll |
api.py â statussida | XSS i loggnamn, alerts, jobbnamn och detaljfĂ€lt | html.escape() pĂ„ alla interpolerade vĂ€rden (quote=True för attribut) |
submit_job.sh | path 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.sh | DB-lösenord synligt i ps-output (-p<lösen>) | MYSQL_PWD i miljön i stÀllet för kommandoradsflagga |
housekeeping_*.sh | samtidiga körningar; osÀker /tmp-purge | flock-lÄs + purge som bara raderar lockfiler ingen process hÄller |
44.6 Infrastrukturstatus vid dokumentationstillfÀllet
| Post | Status |
|---|---|
RAID /dev/md0 | degraderad [4/3] [UU_U], sdd faulty â byte krĂ€vs |
| Kernel | 5.10.262-work733 installerad, ej aktiv (kör 5.10.0-46-amd64, vÀntar omstart) |
nn_weights | truncerad, 10.92 GB frigjort; alla vikter i NPZ |
nn_wf_train_s0 / s1 | kör, ~22 av 40 cykler |
nn_nightly_s4 | pending â vĂ€ntar pĂ„ ledig slot pĂ„ bigrig |
Koordinator + paper_predict | vÀ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):
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):
Fixar (neural_network.py):
| Funktion | à tgÀrd |
|---|---|
get_champion_model_id | Kontrollerar 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
| Post | Status |
|---|---|
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
| Jobb | Start | Resultat |
|---|---|---|
paper_replay (FROM_DATE=2026-07-02) | 08:36 | â 23 dagar simulerade, 4 konton |
oos_walkforward --resume | 08:36 | â Klar 08:38, W34/34 (9 884 redan rĂ€knade) |
oos_walkforward_full | 08:49 | â Klar 09:01 |
db_housekeeping --apply | 09: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.
| Strategi | Sharpe | AvgRet%/fönster | BeatBnH% |
|---|---|---|---|
bb_rsi | 0.52 | 1.50 | 56.1% |
mean_reversion_bounce | 0.52 | 1.53 | 55.7% |
choppy_flat | 0.50 | 1.55 | 55.4% |
rsi_only | 0.40 | 2.09 | 55.9% |
channel_breakout | -0.19 | 0.87 | 34.1% â |
bb_squeeze_breakout | -0.08 | -0.19 | 40.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.
| Strategi | 1m | 6m | 1Är | 3Ä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):
JÀmförelse mot föregÄende körning (2026-07-19):
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:
| Konto | Strategi | Intervall |
|---|---|---|
PAPER_DAYTRADING_SEK | Daytrading regel | var 5:e min |
PAPER_DAYTRADING_NN_SEK | Daytrading NN | var 5:e min |
PAPER_SWING_SEK | Swing regel | var 5:e min (Àndrat frÄn 15) |
PAPER_SWING_NN_SEK | Swing NN | var 5:e min (Àndrat frÄn 15) |
PAPER_PROB_UP5D_SEK | Prob-up-5d direct | var 5:e min |
Positioner, stop-loss och equity-snapshots uppdateras löpande i realtid för alla konton.
46.6 NN-trÀningsöversikt
| Parameter | Vardag | Helg |
|---|---|---|
| TrÀningsfönster | 5 Är (1 825 dagar) rolling | 7 Är (2 555 dagar) |
| Epoker | 30 (early stop vid 8 utan förbÀttring) | 30 + glidande förtrÀnning |
| FörtrÀnning | Nej | 1-Äriga fönster, 6 mÄn steg, 7 Är bakÄt, warm-start |
| Feature selection | Top 96 features | Alla features |
| Champion-gate | val_AUC > befintlig champion | samma |
| Icke-champion rensas | efter 7 dagar | samma |
| Prediktioner | Inkrementellt (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).
| Session | Tid | Funktion |
|---|---|---|
morning | 09:05 | Köpsignaler (daytrading + swing) |
intraday | var 5:e min 09:10â17:20 | Sync + stop-loss/trailing, inga köp |
eod | 17:05 | Flatten daytrading + order-timeouts |
Varför dessa tider:
Stabil orderbok och uppdaterade kurser frÄn 09:05.
Stop-loss och trailing hanteras löpande hela handelsdagen.
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:
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:
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.