Sprawozdanie okresowe w sprawie rozwoju SI i optymalizacji działania kodu

Tytułowy obrazek historyczny

Bot pokerowy nie żyje, niech żyje BitSurfer! - Nie serio, co się stało?

PokerBot i Doradca Pokera to były dwa bardzo interesujące projekty, a od obu wiele się nauczyłem! PokerAdvisor odbiera karty z ekranu, automatycznie wprowadza je do SI i przewiduje wynik rozdania. Podczas gdy Pokerbot był zaplanowany do samodzielnej gry - wszystko było przygotowane, ale poker online był w zasadzie zabroniony w Szwajcarii.

Więc nadszedł czas, by ruszyć dalej. Ale co mogło być kolejnym wielkim wyzwaniem?

Wykres cen Bitcoinów

Natknąłem się na Coinbase'a, brokera kryptograficznego, gdzie interesował mnie głównie Bitcoin.

Posiadają one zgrabne API, przez które możesz podłączyć swoje ulubione oprogramowanie transakcyjne, takie jak Metatrader lub podobne. Ale nie.

Plan, oczywiście, nie polega na połączeniu z naszym ulubionym oprogramowaniem handlowym. Raczej moim pomysłem było zbudowanie od podstaw własnego interfejsu z myślą o moich potrzebach. Było to niewiarygodnie trudne i bardzo strome krzywe uczenia się, ale z pewnością było warte zachodu.

Pierwsza wersja alpha jest gotowa. Interfejs jest bardzo brzydki, ale forma podąża za funkcją. Mój pomysł na dobrze zaprojektowane oprogramowanie nie jest przede wszystkim fantazyjnym interfejsem użytkownika. Raczej chcę, żeby moje oprogramowanie po prostu robiło swoje. Absolutnie. W tle. Nic do zainstalowania, nic do siedzenia przed ekranem i powiedzieć programowi, co robić dalej. Po prostu uruchom go i patrz w fascynacji.

Interfejs zasadniczo składa się z wizualizacji danych rynkowych, jak również znormalizowanych danych wejściowych dla SI.

Czego się nauczyłem? Najpierw musiałem się połączyć z Coinbase. Dużo nauczyłem się o API i na szczęście z dostępnymi pakietami było to dość proste.

Wprowadzenie do aspektów wydajnościowych programowania

Musiałem się wiele nauczyć na temat strukturyzowania danych dla SI, a to w zasadzie wymagało dużej wiedzy na temat wydajności kodu. Do tego stopnia, że zupełnie oszalał. Głównie chodziło o to, że wciąż pracuję na mojej 7-letniej maszynie, którą odzyskałem ze szkolenia. Dobrze się starzeje, ale naprawdę można poczuć wiek.... Od mojego kolejnego komputera, który ma być wkrótce w użyciu, mogę spodziewać się około 10 razy większej wydajności dla moich przypadków użycia! Sam procesor jest około 400% szybszy, jeśli zużywa dużo wątków (co ja robię).

Znalazłem się w następującej sytuacji:

Mój kod potrzebuje około tygodnia na przetworzenie 8 lat danych (każdy punkt danych to 2s ~ 126,000,000 punktów cenowych). Tymczasem do następnej generacji procesorów i kart graficznych pozostało już tylko kilka miesięcy i jest to bardzo obiecujące.

Ilość danych do przetworzenia jest ogromna, dlatego też przystąpiłem do optymalizacji wydajności kodu. Miałem już pewne doświadczenie w pracy z pracownikami wielowątkowymi, którzy zajmowali się wieloma zadaniami jednocześnie. W rezultacie, miałem już trochę mniej niż 3,5x wydajność, ponieważ mój procesor ma 4 rdzenie. Przetworzenie danych o wartości 8 lat trwało dwa dni. To było jeszcze za dużo. Kiedy prowadzę testy wsteczne, chcę zobaczyć wyniki. I chcę je mieć szybko.

Musiałem przyjrzeć się bardziej optymalizacji wydajności i rozwinąłem własną abstrakcję pracowniczą w oparciu o zadanie w C#. Zasadniczo wdraża on metodę produkcji, której nauczyłam się podczas stażu w INA Lahr. To jak posiadanie maszyny (lub pracownika) z kolejką wejściową i wyjściową. Kolejka działa jak bufor i może pomóc każdemu rdzeniowi cpu w równomiernym rozłożeniu pracy. To jak modułowy, skalowalny rurociąg pracowniczy, w którym pracownicy mogą zabierać przedmioty z kolejki lub torby i przetwarzać je.

Dało to również duży wzrost wydajności. Byłem w stanie przetworzyć wszystkie dane mniej więcej w ciągu jednej nocy, ale postanowiłem powtórzyć je jeszcze bardziej, aby zobaczyć, jak daleko mogą się posunąć. Subskrybowałem rozszerzenie Visual Studio "dotTrace", które świetnie sprawdza się w znajdowaniu wąskich gardeł w kodzie. Możesz nagrać ślad, a następnie zobaczyć funkcja po funkcji, jak długo trwa jej wykonanie. Znalazłem cechę, której w ogóle się nie spodziewałem - konstruktor ciągu wyjściowego zdusił cały rurociąg. Możesz przeczytać więcej na ten temat wpytanie dotyczące przelewu kominowego

W sumie, proces jest dość prosty:

  1. Zidentyfikuj największe obciążenie mocy
  2. Wyeliminować go
  3. Nie przestawaj tego robić, dopóki nie uzyskasz rozsądnego rezultatu.

W powyższym przykładzie byłby to proces pracowniczy CLR z ID 10584. Brzmi to trochę myląco w tym momencie, ale JetBrains ma drzewo wywoływania po prawej stronie, gdzie możemy zobaczyć, która funkcja jest używana:

Wnioski i wyjścia

Wiem, że byłoby więcej władzy w tej dziedzinie, ale na razie jestem całkiem zadowolony z rezultatu.

W tej chwili 2 lata mijają w mniej niż 4 minuty, a ja zmieniłem biegi, jeśli działania mają być dokładniej obserwowane.

zrzut ekranu z backtestru

Zapisywana jest również linia kapitałowa oraz statystyki. Możliwe jest symulowanie / uruchamianie tylu kont i strategii, ile tylko chcesz, przy niewielkim spadku wydajności.

Próbowałem już różnych strategii ze wskaźnikami i tak dalej. Bez obiecujących rezultatów. W końcu znalazłem zwycięską strategię, która zamiast tego nie robi żadnej z tych rzeczy. Nie podąża za trendem, ani nie stawia przeciwko niemu zakładów. Nie próbuje niczego przewidzieć. Ani idealne wejście, ani idealne wyjście. To całkiem proste, ale nie będę zagłębiał się w szczegóły strategii. Pomyśl poza pudełkiem i może coś znajdziesz.

linia kapitałowa w górę

Roczna stopa zwrotu wynosi 20%. Szczerze mówiąc, zrobiłbym więcej miejsca w strategii "kupuj i trzymaj", ale z drugiej strony, nie przewiduję niczego, nie mamy tych szalonych kolców (i upadków).

Teraz mogę na tym budować i widzieć, co jest możliwe, a co nie. Pełna symulacja rynku w piaskownicy. Środowisko testowe z prawie nieograniczonymi możliwościami.

To wszystko na dzisiaj i mam nadzieję, że spodobał się wam wgląd w niektóre z moich bieżących projektów.