Skip to content

Poprawki pomiaru equity: sesja w symulacji (A-2), IC per sygnał (A-3), bez shortów na akcjach (A-5) - #39

Merged
mbeczynski merged 3 commits into
mainfrom
trader/poprawki-pomiaru-equity
Oct 18, 2026
Merged

mbeczynski merged 3 commits into
mainfrom
trader/poprawki-pomiaru-equity

Conversation

@mbeczynski

@mbeczynski mbeczynski commented Oct 18, 2026 •

Copy link
Copy Markdown
Contributor

Poprawki pomiaru w torze equity, wskazane przez niezależną analizę przebiegu trenera z 18.10. Każdą sprawdziłem w kodzie przed zmianą. Krypto nie zmienia wyniku (dowód niżej).

A-2: brak decyzji poza sesją giełdy (tzw. widma)

Wada. Symulacja decydowała na każdej świecy panelu equity, także na świecach przed- i posesyjnych Alpaki oraz na ostatniej świecy sesji. Decyzja z tej świecy zapada o 16:00 czasu Nowego Jorku, a zlecenie wychodzi o 16:20. Pętla takiej decyzji nie podejmuje (BRAMKA 1 w loop.py, /v2/clock). W symulacji takie zlecenie liczyło się jako niewypełnione z braku świecy 1h: brak_swiec_1h: 890 z 4061 zleceń. Niewypełnione wyjście trzymało pozycję przez lukę otwarcia, której produkcja nie ma.

Poprawka.

  • sesja.sesja_historyczna(kind) stosuje tę samą regułę co pętla: rynek ciągły decyduje zawsze, a rynek z sesją tylko przy otwartej sesji. Zegara giełdy w historii nie ma (ref.session_calendar jest pusta), dlatego używam kalendarza sesji regularnej NYSE (9:30–16:00 America/New_York, pon.–pt.) dla stock/etf. Dla krypto wynik to None.
  • portfolio.okno_wykonania (czysta funkcja, reguły jak w loop.py):
    • decyzja w sesji i wysyłka w sesji: zlecenie normalne;
    • decyzja 15:00 NY (świeca 18:00Z latem, wysyłka 15:20): okno wypełnienia modelu pesymistycznego to reszta godziny wysyłki do zamknięcia. Świeca 1h tej godziny obejmuje też ~20 min przed wysyłką, więc okno jest lekko łaskawsze niż w rzeczywistości;
    • świeca przedsesyjna (12:00Z latem, decyzja w pierwszym cyklu po otwarciu): wyjście tak (wysyłka otwarcie + opóźnienie), wejście nie (decyzja_przeterminowana);
    • decyzja 16:00 NY i wcześniejsze świece nocne: zlecenie nie powstaje.
  • Liczniki poza_sesja_wejscia / poza_sesja_wyjscia liczą zlecenia: jedno na ciąg świec poza sesją dla instrumentu albo pozycji, nie każdą świecę. Do wypełnialności nie wchodzą.
  • IC per sygnał na rynku z sesją liczy się tylko ze świec, z których symulacja może wejść.
  • Trener wypisuje linię „Zlecenia NIEZŁOŻONE poza sesją” (tylko gdy > 0), a PODSUMOWANIE_JSON ma klucz poza_sesja.

Czego kalendarz nie zna: świąt (w święto nie ma świec, więc i tak nie ma decyzji) i sesji skróconych do 13:00 (ok. 3 dni w roku, po 13:00 symulacja może tam jeszcze decydować). Strefa America/New_York jest w przypiętym obrazie python:3.12-slim@sha256:2f17… (sprawdzone docker run).

A-3: IC per sygnał w logu trenera

Po walk-forwardzie trener wypisuje tabelę: sygnał × (razem, reżimy). Każda komórka to średnia IC z okien testowych oraz liczba okien z IC > 0 na liczbę okien z IC. To czysta diagnostyka: liczy się z cache_te po wyborze wag i nie trafia do żadnej decyzji ani zapisu. Zbieranie par wydzieliłem do _pary_ic, wspólnego z _wagi_z_ic, bez zmiany zachowania. Podaję średnią po oknach zamiast jednej korelacji po panelu, bo etykiety sąsiednich świec nachodzą na siebie o H-1 świec.

A-5: bez nogi krótkiej na akcjach

Wada. Dla CENNIK["stock"] było krotka_pozycja=True, a kosztu pożyczki papieru nie liczyła ani symulacja, ani Alpaca paper. Wynik shortów był więc fikcją w obu miejscach.

Poprawka (korekta pomiaru). Ustawiłem krotka_pozycja=False dla stock i etf. Trener liczy SPY w torze --kind stock, a pętla czyta rodzaj z ref.instrument (SPY = etf). Przy różnych flagach produkcja grałaby shorty SPY, których symulacja nie zna. To samo pole czytają:

  • symulacja: wejście ze score < 0 jest pomijane (pominiete_shorty),
  • pętla: enter_short daje hold z powodem short_niewykonalny (loop.py),
  • trener: strona_uczenia("stock") == "dluga" (H-6), czyli progi i IC liczone ze strony długiej,
  • karta: składnik „koszt pozyczki papieru” znika razem z nogą, której dotyczył,
  • evaluate_limits: brak max_leverage przestaje blokować stock (reguła dotyczy tylko instrumentów z nogą krótką).

Skutek dla modelu. params toru equity dostają klucz strona: "dluga". zmiana_struktury zgłasza +strona, więc nowa wersja zostaje candidate i jest nową konfiguracją w N deflacji (N+1). Silnik equity na demo chodzi z --model-status candidate, więc po pierwszym przebiegu trenera po wdrożeniu zacznie grać tę wersję. Otwarte shorty (jeśli są) zamykają się normalnie, bo flaga blokuje tylko wejścia.

Jak cofnąć: revert tego commita. Flagi wracają na True, params tracą strona, to znów zmiana struktury, więc kolejna wersja będzie candidate. Powrót do shortów na stałe wymaga zmierzonej stawki pożyczki naliczanej w simulate_portfolio.

Testy

  • Cały zestaw: python -B -m pytest: 3674 passed, 148 skipped (przed zmianą 3623/148). ruff check czysty.
  • Nowe: tests/test_sesja_w_symulacji.py (granice sesji EDT/EST, weekend; brak decyzji wejścia i wyjścia poza sesją przy świecach 1h o każdej godzinie; kanarek bez kalendarza; krypto spot/spot_eu/perp identyczne co do transakcji, krzywej i liczników) oraz tests/test_ic_sygnalow.py.
  • Zmienione: test_runda_w_zwrocie.py, gdzie test pilnujący krotka_pozycja=True odwróciłem świadomie i dodałem test braku shortów w symulacji na stock. W test_trener_cde.py H-6 obejmuje teraz stock → dluga.
  • Regresja: z wyłączoną bramką sesji i z flagami z powrotem na True pada 9 testów (sesja, A-5, H-6).
  • Krypto bez zmian: zrzut trener_rownowaznosc.json przegenerowałem. Przed zapisem sprawdziłem 7 wariantów krypto wobec zrzutu z 11.10: JSON bez poza_sesja (także w przesuniecia) przechodzi _bliskie, a wydruk bez tabeli IC jest identyczny linia po linii. Wariant ic_stock zastąpiłem ic_perp, bo panel syntetyczny 24/7 daje na akcjach jedną decyzję w sesji dziennie, czyli 0 okien.

Ryzyka / czego to nie robi

  • Progi wejścia (proby_wynikow) i wagi IC equity nadal liczą się ze wszystkich świec panelu, łącznie z przed- i posesyjnymi, na których produkcja nie decyduje. To osobna korekta (rozkład, z którego idzie p88), poza zakresem tego PR.
  • Do sesji skróconych i świąt potrzebny byłby kalendarz giełdy. Skala jest opisana wyżej.
  • A-2 i A-5 zmieniają wynik equity w kolejnym przebiegu trenera, więc liczby equity sprzed i po wdrożeniu nie są porównywalne.

🤖 Generated with Claude Code

https://claude.ai/code/session_017S4D5yYFQmJsfcLx14gnjE

mbeczynski added a commit that referenced this pull request Oct 18, 2026
…ń, IC w sesji

- `portfolio.okno_wykonania` (czysta funkcja) zastępuje regułę w domknięciu:
  decyzja 15:00 NY przy modelu pesymistycznym nie jest odrzucana - okno
  wypełnienia to reszta godziny wysyłki do zamknięcia (`do_zamkniecia`,
  świeca godziny wysyłki w `wycena_wysylki`); świeca przedsesyjna dostaje
  decyzję w pierwszym cyklu po otwarciu - wyjście tak (wysyłka otwarcie +
  opóźnienie), wejście nie (`decyzja_przeterminowana` w pętli).
- `poza_sesja` liczy zlecenia, nie świece: raz na ciąg świec poza sesją dla
  pozycji (`poza_sesja_wyjscia`) albo instrumentu (`poza_sesja_wejscia`).
- IC per sygnał na rynku z sesją tylko ze świec, z których symulacja może
  wejść (`swieca_wejscia`); wagi bez zmian.
- `sesja.KalendarzSesji` (otwarta + otwarcie dnia), `NYSE_REGULARNA`.

Krypto bez zmian: zrzut równoważności przechodzi bez przegenerowania.
`test_przebicie_nie_dotyczy_wyjsc` liczy flagę tylko przy `zlecenie_z_limitem`.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017S4D5yYFQmJsfcLx14gnjE
mbeczynski added a commit that referenced this pull request Oct 18, 2026
…ń, IC w sesji

- `portfolio.okno_wykonania` (czysta funkcja) zastępuje regułę w domknięciu:
  decyzja 15:00 NY przy modelu pesymistycznym nie jest odrzucana - okno
  wypełnienia to reszta godziny wysyłki do zamknięcia (`do_zamkniecia`,
  świeca godziny wysyłki w `wycena_wysylki`); świeca przedsesyjna dostaje
  decyzję w pierwszym cyklu po otwarciu - wyjście tak (wysyłka otwarcie +
  opóźnienie), wejście nie (`decyzja_przeterminowana` w pętli).
- `poza_sesja` liczy zlecenia, nie świece: raz na ciąg świec poza sesją dla
  pozycji (`poza_sesja_wyjscia`) albo instrumentu (`poza_sesja_wejscia`).
- IC per sygnał na rynku z sesją tylko ze świec, z których symulacja może
  wejść (`swieca_wejscia`); wagi bez zmian.
- `sesja.KalendarzSesji` (otwarta + otwarcie dnia), `NYSE_REGULARNA`.

Krypto bez zmian: zrzut równoważności przechodzi bez przegenerowania.
`test_przebicie_nie_dotyczy_wyjsc` liczy flagę tylko przy `zlecenie_z_limitem`.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017S4D5yYFQmJsfcLx14gnjE
@mbeczynski
mbeczynski force-pushed the trader/poprawki-pomiaru-equity branch from c0dc2be to 98ac08d Compare October 18, 2026 11:55
mbeczynski and others added 3 commits October 18, 2026 14:03
… shortów na akcjach

A-2: symulacja nie składa zleceń, których pętla nie złoży, bo giełda jest
zamknięta. `sesja.sesja_historyczna(kind)` - sesja regularna NYSE 9:30-16:00
czasu Nowego Jorku dla `stock`/`etf`, None (rynek ciągły) dla krypto.
`simulate_portfolio` sprawdza chwilę decyzji, wysyłki i - w modelu
pesymistycznym - godzinę wypełnienia; pominięte zlecenia liczy
`PortfolioResult.poza_sesja` (poza wypełnialnością). Przebieg 18.10 miał
890 z 4061 zleceń equity "bez świecy 1h" z decyzji na ostatniej świecy sesji.

A-3: tabela IC per sygnał (razem i per reżim) na oknach testowych, średnia
i okna z IC > 0 - wyłącznie wydruk, po wyborze wag. Zbieranie par IC
wydzielone do `_pary_ic`, wspólne z `_wagi_z_ic` (bez zmiany zachowania).

A-5: `krotka_pozycja=False` dla `stock` i `etf` - koszt pożyczki papieru
nie był liczony ani w symulacji, ani na Alpaca paper. Ta sama flaga czyta
symulacja (`pominiete_shorty`), pętla (`short_niewykonalny`) i trener
(`strona_uczenia` -> `strona: dluga`, zmiana struktury -> candidate).

Zrzut `trener_rownowaznosc.json` przegenerowany: siedem wariantów krypto
sprawdzone wobec zrzutu z 11.10 - JSON bez `poza_sesja` i wydruk bez tabeli
IC identyczne. `ic_stock` zastąpiony `ic_perp` (opis w docstringu testu).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017S4D5yYFQmJsfcLx14gnjE
…ń, IC w sesji

- `portfolio.okno_wykonania` (czysta funkcja) zastępuje regułę w domknięciu:
  decyzja 15:00 NY przy modelu pesymistycznym nie jest odrzucana - okno
  wypełnienia to reszta godziny wysyłki do zamknięcia (`do_zamkniecia`,
  świeca godziny wysyłki w `wycena_wysylki`); świeca przedsesyjna dostaje
  decyzję w pierwszym cyklu po otwarciu - wyjście tak (wysyłka otwarcie +
  opóźnienie), wejście nie (`decyzja_przeterminowana` w pętli).
- `poza_sesja` liczy zlecenia, nie świece: raz na ciąg świec poza sesją dla
  pozycji (`poza_sesja_wyjscia`) albo instrumentu (`poza_sesja_wejscia`).
- IC per sygnał na rynku z sesją tylko ze świec, z których symulacja może
  wejść (`swieca_wejscia`); wagi bez zmian.
- `sesja.KalendarzSesji` (otwarta + otwarcie dnia), `NYSE_REGULARNA`.

Krypto bez zmian: zrzut równoważności przechodzi bez przegenerowania.
`test_przebicie_nie_dotyczy_wyjsc` liczy flagę tylko przy `zlecenie_z_limitem`.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017S4D5yYFQmJsfcLx14gnjE
`sesja_regularna_nyse` i `KalendarzSesji` używają `STREFA_US`
i `otwarcie_sesji_us` z #38 - tej samej funkcji, której pętla używa
w `StanSesji.swieca_przed_otwarciem`. Usunięte zdublowane `NYSE`,
`OTWARCIE_NYSE` i `otwarcie_nyse`. Świeca przedsesyjna w symulacji opisana
jako `swieca_przed_sesja` (wejścia nie, wyjścia tak) - jak w pętli.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017S4D5yYFQmJsfcLx14gnjE
@mbeczynski
mbeczynski force-pushed the trader/poprawki-pomiaru-equity branch from 98ac08d to ae0a659 Compare October 18, 2026 12:03
@mbeczynski
mbeczynski merged commit 8a7e7ba into main Oct 18, 2026
1 check passed
@mbeczynski
mbeczynski deleted the trader/poprawki-pomiaru-equity branch October 18, 2026 12:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant