ARCHbartosz@archengineering.dev:~/pl/blog/building-an-llm-trading-bot.md
← cd ..

cat building-an-llm-trading-bot.md

Wszyscy nagle budują boty tradingowe na LLM-ach

· 6 min czytania · Bartosz Szczepanik

#ai#llm#trading

Spis treści7 ▾
  1. Czym właściwie jest większość tych botów
  2. Do czego model naprawdę się nadaje
  3. Jak bym to złożył
  4. Co zaskoczyło mnie najbardziej
  5. Co się stało, gdy modele handlowały prawdziwymi pieniędzmi
  6. Jeśli naprawdę chcesz takiego bota uruchomić
  7. Na czym stanąłem

Od kilku miesięcy wszędzie natykam się na to samo. Ktoś na meetupie wspomina o bocie, którego puścił na małym koncie. Znajomy podsyła mi screenshot wykresu, który idzie tylko w górę. Na moim feedzie przybywa wątków o tym, żeby oddać zarządzanie portfelem modelowi językowemu. W końcu zaciekawiło mnie to na tyle, że przestałem scrollować i przyjrzałem się temu porządnie. Ten wpis to zapis tego, czego się dowiedziałem. Spisałem to głównie po to, żeby przestać opowiadać w kółko to samo przy kawie.

Od razu zaznaczam: jestem inżynierem, a do zawodowego tradera bardzo mi daleko. Nic tu nie jest poradą finansową, a jeśli masz zapamiętać z tego tekstu tylko jedną rzecz, to chyba tę, że na tym bardzo łatwo szybko stracić pieniądze.

Czym właściwie jest większość tych botów

Gdy spojrzeć poza screenshoty, okazuje się, że spora część tych projektów to zwykła pętla. Co kilka minut skrypt pobiera ostatnie notowania i ewentualnie kilka nagłówków, wkleja je do promptu, pyta model, czy kupić, czy sprzedać i ile, po czym wysyła na giełdę to, co dostanie w odpowiedzi. Fajny projekt na weekend i rozumiem, czemu ludzie go budują. Tyle że jedyny element systemu, który może wyczyścić konto, oddaje się w ten sposób temu, który najgorzej radzi sobie z liczbami.

Im więcej czytałem, tym bardziej miałem wrażenie, że sensowna wersja tego pomysłu wygląda zupełnie inaczej.

Do czego model naprawdę się nadaje

Modele językowe dobrze czytają. Sprawozdania spółek, transkrypcje konferencji wynikowych, komunikaty banków centralnych i niekończący się strumień newsów to wszystko tekst. W przerabianiu go na coś, z czego może skorzystać program, te modele wyraźnie wygrywają ze starszymi narzędziami opartymi na regułach. Pytanie, czy dany komunikat prasowy zmienia perspektywy spółki, jak nerwowo brzmią wypowiedzi na konferencji albo której z obserwowanych przez ciebie spółek naprawdę dotyczy nagłówek, to moim zdaniem rozsądne zadania dla modelu.

Gorzej jest z arytmetyką, prawdopodobieństwem i powtarzalnością. Ten sam prompt potrafi z dnia na dzień dawać różne odpowiedzi, model nie ma wyczucia prowizji ani poślizgu, dopóki mu ich wprost nie rozpiszesz, i bez wahania zaproponuje wielkość pozycji, która nie ma żadnego sensu przy koncie, na które akurat patrzy.

Dlatego architektura, do której ciągle wracałem, daje się opisać bardzo prosto. Model czyta i opisuje, a wszystko, co dotyka pieniędzy, zostaje w zwykłym kodzie, który za każdym razem działa tak samo.

Jak bym to złożył

Gdybym budował to porządnie, model siedziałby w środku pipeline'u, z dala od jego brzegów. Z jednej strony wpływałyby dane rynkowe i źródła tekstowe. Model zamieniałby tekst na mały, stały zestaw sygnałów, na przykład ocenę sentymentu, typ zdarzenia i listę tickerów, których ono dotyczy. Każdy taki wynik zapisywałbym razem z promptem i wersją modelu, z której pochodzi. O tym, co trzymać w portfelu, decydowałaby na podstawie tych sygnałów i cen strategia napisana w zwykłym kodzie. Osobny moduł kontroli ryzyka, też zwykły kod, sprawdzałby każde zlecenie pod kątem limitów wielkości pozycji, łącznej ekspozycji i dziennej straty. Miałby też prawo powiedzieć „nie”. Dopiero potem cokolwiek trafiałoby do brokera.

W takim podziale podoba mi się to, że każdy element da się przetestować osobno. Możesz przepuścić przez model newsy z zeszłego tygodnia i po prostu obejrzeć sygnały, które z nich wyciągnął. Możesz zasypywać moduł ryzyka absurdalnymi zleceniami i sprawdzać, czy wszystkie odrzuca. A gdy coś pójdzie nie tak, łatwo ustalić, czy to model źle odczytał newsa, czy strategia podjęła złą decyzję mimo poprawnego odczytu.

Chciałbym też mieć jeden wyłącznik zatrzymujący cały handel, sprawdzany przed każdym zleceniem, oraz mechanizm, który sam go uruchamia, gdy straty, błędy albo czasy odpowiedzi zaczynają odbiegać od normy.

Co zaskoczyło mnie najbardziej

To właśnie zmieniło moje spojrzenie na każdy efektowny wykres, jaki ktoś mi podesłał. Gdy testujesz zwykłą strategię tradingową na danych sprzed kilku lat, strategia nie ma pojęcia, co działo się potem. Gdy w ten sam sposób testujesz model językowy, model najpewniej już podczas treningu czytał o tym, co działo się potem. Widział newsy, komentarze, a często nawet same ceny.

Backtest strategii opartej na LLM-ie na okresie, który model zna z treningu, może więc wyglądać genialnie z powodu, który nie ma nic wspólnego z umiejętnościami. Z tego, co udało mi się znaleźć, sporo opublikowanych wyników w tej dziedzinie rozsypuje się, gdy testuje się je wyłącznie na datach po training cutoffie modelu, a wiele wypada wtedy nie lepiej niż losowy wybór. Ta lektura mocno mnie otrzeźwiła.

Uczciwym rozwiązaniem wydaje się testowanie wyłącznie na danych z okresu po cutoffie, a w przypadku świeżego modelu to niewiele historii. Potem trzeba długo prowadzić paper trading na danych na żywo, zanim wejdą jakiekolwiek prawdziwe pieniądze.

Co się stało, gdy modele handlowały prawdziwymi pieniędzmi

Zeszłej jesieni głośno było o publicznym eksperymencie. Sześć dużych modeli dostało po dziesięć tysięcy dolarów na kilka tygodni handlu kontraktami futures na kryptowaluty. Jeden skończył mniej więcej dwadzieścia procent na plusie, kilka straciło około czterdziestu procent, a jeden był w pewnym momencie jakieś pięćdziesiąt procent do przodu, po czym oddał większość zysku.

Nagłówki były świetne, ale nie sądzę, żeby to wiele mówiło o tym, który model jest lepszym traderem. Kilka tygodni handlu krypto z dźwignią mierzy głównie to, ile ryzyka każdy z nich akurat podjął na bardzo rozchwianym rynku, a w innych dwóch tygodniach kolejność mogłaby się całkiem odwrócić. Ja wyciągnąłem z tego inną lekcję. Model, który sam ustala wielkość swoich pozycji, potrafi bardzo szybko przepalić sporą część konta. Właśnie dlatego trzymałbym go z dala od tej decyzji.

Trafiłem też na parę staranniejszych setupów, w których kilka instancji modelu gra różne role: jest paru analityków, ktoś broni scenariusza wzrostowego, ktoś spadkowego, a przed transakcjami stoi risk manager. Bardzo podoba mi się taki układ. Wyniki, które ludzie dla niego podają, obejmują jednak wciąż krótkie okresy i mają ten sam problem z danymi treningowymi, więc na razie traktuję to jako ciekawą architekturę i niewiele więcej.

Jeśli naprawdę chcesz takiego bota uruchomić

Reszta to ta mniej efektowna część. Przypnij konkretną wersję modelu, bo cicha aktualizacja po stronie dostawcy potrafi z dnia na dzień zmienić sygnały. Loguj każdy prompt i każdą odpowiedź razem ze zleceniami, do których doprowadziły, bo później będziesz chciał zrozumieć dawne decyzje. Pilnuj kosztów API, jeśli przepuszczasz przez model dużo newsów, i pogódź się z tym, że wszystko, co musi reagować szybciej niż w sekundę czy dwie, jest poza zasięgiem.

A jeśli pomysł kiedyś rozrośnie się do zarządzania cudzymi pieniędzmi, jak najwcześniej porozmawiaj z prawnikiem. W Europie to działalność regulowana i lepiej nie przekonywać się o tym za późno.

Na czym stanąłem

Po tym całym grzebaniu pomysł interesuje mnie bardziej niż na początku. Model językowy, który czyta wszystko i przekazuje czyste, ustrukturyzowane sygnały do rygorystycznego i dość nudnego systemu, wydaje mi się naprawdę przydatny. Właśnie taką wersję zbudowałbym, gdybym kiedyś sam się za to zabrał.

Jeśli budujesz coś podobnego i chcesz wymienić się doświadczeniami, odezwij się, chętnie pogadam.