PRACA MAGISTERSKA
Opracowanie systemu informatycznego z automatycznym
zawieraniem transakcji na rynku walutowym
2
Spis treści
Wstęp ................................................................................................................................3
Cel i zakres pracy ............................................................................................................4
1. Giełda walutowa – pojęcia podstawowe..................................................................5
2. Techniki ułatwiające dokonywanie właściwych transakcji na rynku walutowym
...........................................................................................................................................8
2.1. Analiza fundamentalna.........................................................................................8
2.2. Analiza techniczna .............................................................................................10
2.3. Aspekt psychologiczny przy zawieraniu transakcji ...........................................15
3. Etapy tworzenia systemu informatycznego do automatycznego podejmowania
decyzji.............................................................................................................................17
3.1. Wybór rynku i odpowiednich narzędzi odwzorowujących trendy rynkowe .....20
3.2. Wypracowanie i zaadoptowanie metody do zbioru obiektywnych zasad..........21
3.3. Testowanie i ocena wyników .............................................................................22
3.4. Nadzorowanie i optymalizacja systemu.............................................................23
4. Opracowanie, implementacja i użytkowanie platformy JST ..............................24
4.1. Wymagania funkcjonalne i niefunkcjonalne......................................................25
4.1.1. Wymagania funkcjonalne............................................................................25
4.1.2. Wymagania niefunkcjonalne.......................................................................27
4.2. Projektowanie systemu informatycznego ..........................................................28
4.3. Implementacja systemu informatycznego..........................................................36
4.4. Główne problemy implementacyjne ..................................................................49
5. Użytkowanie, testowanie, optymalizacja oraz ocena uzyskanych wyników ......52
6. Wnioski.....................................................................................................................57
Dodatek A ......................................................................................................................59
Instrukcja postępowania przy wzbogacaniu kodu o nowe wskaźniki lub systemy
transakcyjne.................................................................................................................59
Dodatek B.......................................................................................................................60
Ważniejsze funkcje systemu informatycznego ...........................................................60
Bibliografia ....................................................................................................................66
3
Wstęp
Rozwój komputeryzacji w handlu uprościł do minimum zawieranie
wszelkiego rodzaju transakcji. Kupno lub Sprzedaż określonych towarów sprowadza się
obecnie do kilku kliknięć myszką – oczywiście na odpowiednio zbudowanych
platformach i różnych aplikacjach ułatwiających takie operacje. Również rynek
papierów wartościowych podlega tym trendom. Obecnie istnieje bardzo wiele platform,
jak np. Wealth Lab, Metastock, Metatrader, Deal Book, TradeStation, i inne, które
umożliwiają przeprowadzanie odpowiednich operacji rynkowych bez potrzeby
wychodzenia z domu. Łącza internetowe pozwalają na bieżące śledzenie kursów
wszelkich papierów wartościowych
Dzięki wykorzystaniu funkcji z rodziny API, możliwe jest zbudowanie
własnej aplikacji, która może w pełni odzwierciedlać wymagania użytkownika – gracza.
Budując taki system informatyczny starałem się rozszerzyć pewne funkcjonalności,
które posiadają obecne na rynku platformy, aby pomogły one przyszłym użytkownikom
wykorzystanie mocy obliczeniowej ich komputerów oraz ich własnych możliwości.
Dzięki zastosowaniu języka programowania Java możliwe było zaimplementowanie
automatycznego
systemu
transakcyjnego,
czyli
odpowiedniego
systemu
komputerowego, który wspomaga decyzje gracza lub w pełni przejmuje kontrole nad
kapitałem gracza i inwestuje jego pieniądze.
4
Cel i zakres pracy
Celem
tej
pracy
jest
opracowanie
systemu
informatycznego
wspomagającego zawieranie transakcji na giełdzie walutowej, która poza
standardowymi transakcjami zawieranymi ręcznie przez gracza, zawiera jak już
wspomniałem automatyczny system transakcyjny. System ten, umożliwia również
budowę własnych wskaźników analizy technicznej oraz implementacje własnych
systemów. Każda nowo stworzona koncepcja gry może zostać przetestowana i
zoptymalizowana zanim gracz zdecyduje się na wykorzystanie jej w czasie
rzeczywistym.
Rozdział pierwszy jest opisem podstawowych pojęć używanych w
dziedzinie rynków towarowych, walutowych, papierów wartościowych i innych.
Wyjaśniona jest też nietypowa budowa rynku walutowego.
Rozdział
drugi
jest
przedstawieniem
podstawowych
technik,
wykorzystywanych przez grono inwestorów giełdowych, które ułatwiają podejmowanie
decyzji transakcyjnych.
Trzeci punkt to omówienie podstawowych zasad, jakimi należy kierować
się podczas budowy własnego systemu informatycznego.
Rozdział czwarty, to opis funkcjonalności zbudowanej platformy oraz etapy
implementacji klas składowych.
Przedostatni
rozdział
jest
opisem
właściwego
korzystania
z zaprogramowanych właściwości gotowego systemu informatycznego.
Ponadto zostały umieszczone dwa dodatki: pierwszy, to swego rodzaju
instrukcja postępowania w przypadku rozbudowy platformy o nową funkcjonalność lub
wskaźniki. W drugim dodatku zostały umieszczone kody ważniejszych funkcji
zbudowanej aplikacji.
5
1. Giełda walutowa – pojęcia podstawowe
Rynek walutowy potocznie zwany Forex’em (Foreign Exchange – wymiana
międzynarodowa) w formie jaką znamy ukształtował się jakieś 30 lat temu, a w ciągu
ostatnich 10 lat przeżywa swój największy rozkwit. Podobnie jak rynek papierów
wartościowych rynek walutowy jest dostępny dla każdego, kto tylko zdecyduje się aby
w nim uczestniczyć.
Handel pieniędzmi sięga średniowiecza, kiedy to ówcześni kupcy wymyślili
różnego rodzaju kwity wymiany umożliwiające handel międzynarodowy. Współczesny
rynek walutowy uformował się dopiero w XX wieku, a w połowie lat trzydziestych tego
wieku Londyn stał się centrum wymiany walutowej, a funt brytyjski zyskał miano
bardzo silnej waluty. Niestety druga wojna światowa zachwiała pozycją Wielkiej
Brytanii w sferze ekonomicznej, a Stany Zjednoczone nie zniszczone wojną wzmocniły
swoją pozycję ekonomiczną na świecie. Na mocy porozumienia z Bretton
Woods z 1944 roku, zawartego pomiędzy Wielką Brytanią, Francją i Stanami
Zjednoczonymi, dolar amerykański stał się bazową walutą krajów kapitalistycznych.
Pozostałe waluty zostały powiązane z dolarem, on zaś został powiązany ze złotem przy
kursie $35 za uncję. W latach 70-tych kursy walut zostały uwolnione od cen złota. Ich
zmienność od tego momentu była zależna od podaży i popytu. Każdy mógł wymieniać
dowolne ilości walut na inne. Ta sytuacja dała początek rynkowi walutowemu w postaci
jaką mamy dziś. Od momentu uwolnienia cen, kursy zmieniają się względem siebie.
Przez kolejne lata obroty na rynku Forex zwiększały się w astronomicznym tempie:
1977 r. – dzienny obrót wynosił 5 miliardów USD, 1987 r. – 600 miliardów USD, 2000
r. – 1,5 tryliona.
Rozwój i wykorzystanie Internetu oraz komputerów w handlu sprawiło, że obecnie
obrót ten wynosi ok. 1,9 tryliona USD i jest największym rynkiem finansowym na
świecie, który nie ma określonego miejsca usytuowania (rynek pozagiełdowy – Over
the Counter), który składa się z sieci połączonych ze sobą za pomocą łączy
telefonicznych i innych elektronicznych systemów obrotu banków, brokerów,
przedsiębiorstw oraz inwestorów indywidualnych. Brak określonego miejsca fizycznej
lokalizacji rynku walutowego umożliwia mu funkcjonowanie 24 godziny na dobę przez
6
5 dni w tygodniu. Rynek ten obejmuje swym zasięgiem większość krajów świata a do
największych centrów transakcji walutowych należą Londyn, Nowy Jork i Tokio.
Obecnie na rynku Forex najczęściej wymienianymi walutami są:
USD – Dolar amerykański (United States Dollar)
EUR – Euro
GBP – Funt brytyjski (Great Britan Pound)
JPY – Japoński jen (Japanese Yen)
CHF – Frank szwajcarski (Swiss Franc)
AUD – Dolar australijski (Austalian Dollar)
NZD – Dolar nowozelandzki (New Zeland Dollar)
Rynek ten jest w zasadzie bardzo podobny do innych rynków, kupujemy
taniej aby sprzedać drożej i odwrotnie. Giełda walutowa jest rynkiem dwustronnym
dlatego możemy zarabiać zarówno na wzroście jak i na spadku kursu. Wynika to ze
specyficznej budowy tego rynku. Instrumentami finansowymi są tu pary walutowe np.
EUR/USD, USD/CHF, EUR/GBP. Kursem waluty będzie tu stosunek jednej waluty do
drugiej. Pierwsza w parze to waluta bazowa, druga to waluta kwotowana – innymi
słowy kurs o wartości np. 180 pary GBP/JPY mówi nam że za 1- go funta brytyjskiego
dostaniemy 180 jenów japońskich. Kupując tą parę walutową wykonujemy tzw.
transakcję „długą” – oznacza to, że inwestujemy w walutę bazową w tym wypadku
GBP, i zakładamy że mamy wzrost kursu do 200 i zamykamy naszą transakcję.
Oznacza to że dzięki tej operacji zarobiliśmy na różnicy cen między funtem brytyjskim
a jenem japońskim, ponieważ kupiliśmy walutę bazową kiedy miała mniejszą wartość
w stosunku do waluty kwotowanej – za każdego kupionego funta dostaniemy nie 180
a 200 jenów (oczywiście zysk ten może być zdeponowany przez nas w dowolnej
walucie). Sprzedając z kolei naszą parę po kursie 200 wykonujemy tzw. transakcję
„krótką” – oznacza to, że inwestujemy w walutę kwotowaną tj. JPY. Ponownie
zakładamy korzystne dla nas notowanie np. 180 i zamykamy pozycję „krótką”. W tym
przypadku za kupione przez nas jeny japońskie możemy dostać więcej funtów
brytyjskich, ponieważ ich kurs obniżył się w stosunku do jena.
Zarabianie pieniędzy na rynku walutowym sprowadza się de facto do tego,
aby kupić walutę tanio i sprzedać ją po wyższym kursie, lub sprzedać drogo i odkupić
7
po kursie niższym. W rzeczywistości nie jest to jednak takie proste, bo trzeba wiedzieć
kiedy kurs jest niski a kiedy wysoki, czy będzie rósł czy spadał. W tym celu przez
inwestorów stosowane są dwa rodzaje analiz inwestycyjnych:
• Analiza fundamentalna – metoda przewidywania przyszłych ruchów cen
instrumentu finansowego na podstawie czynników i danych ekonomicznych,
politycznych i środowiskowych, które w jakikolwiek sposób mogą wpłynąć na
poziom podaży i popytu na dany instrument,
• Analiza techniczna – metoda przewidywania ruchów cen i przyszłych trendów
rynkowych na podstawie wykresów, oscylatorów i innych wskaźników
zbudowanych na bazie historycznych danych o kursach walutowych i obrotach
na rynku.
W praktyce inwestorzy wykorzystują najczęściej narzędzia i techniki
należące do obu rodzaju analiz.
Analiza fundamentalna
Na rynku walutowym analiza fundamentalna opiera się na obserwowaniu
sytuacji makroekonomicznej w danym kraju i na świecie, oraz analizie zmian
zachodzących w gospodarce, które wpływają na popyt i podaż danej waluty, a co za
tym idzie na jej kurs. Trzeba więc na bieżąco śledzić wydarzenia polityczne,
ekonomiczne, społeczne oraz obserwować wskaźniki makroekonomiczne świadczące
o stanie gospodarki danego kraju
1
. Publikacja danych makroekonomicznych znacznie
ułatwia inwestorom śledzenie sytuacji ekonomicznej różnych krajów oraz czynników
makroekonomicznych wpływających na rynek walutowy.
Duże znaczenie z punktu widzenie analizy fundamentalnej ma również
znaczenie prowadzona przez banki centralne polityka pieniężna. Ustalany przez nie
poziom stóp procentowych, operacje otwartego rynku czy interwencje walutowe nie
pozostają bez wpływu na sytuację na rynku walutowym i są przedmiotem uważnych
obserwacji analityków finansowych.
1
„Makro i Mikro Ekonomia …”, Rozdział 22.
8
Wpływ na rynek mają również te najbardziej tragiczne wydarzenia np.
wojny, katastrofy, ataki terrorystyczne.
Analiza techniczna
Analiza techniczna zajmuje się badaniem tego co już się wydarzyło na
rynku, a nie tym, co powinno się wydarzyć. Analityk techniczny bada poziom cen i
obrotów danego instrumentu finansowego w przeszłości, a z zebranych danych poprzez
analizę wykresu tworzy możliwą prognozę dalszych zmian kursów. Nie interesują go
dane makro ani wydarzenia polityczne - koncentruje się wyłącznie na wykresie,
odzwierciedlającym zachowania wszystkich inwestorów – trendy i tendencje
Analiza techniczna to ocena i próba prognozowania przyszłych trendów na
podstawie zachowania się cen w przeszłości. Ceny rysowane na wykresach tworzą
różne kształty i formacje. Według analityków technicznych formacje te powtarzają się
regularnie i prowadzą do podobnych zachowań rynku. Niektóre z nich zapowiadają
spadki cen, inne wzrosty. Na podstawie niektórych można próbować ocenić jak duże
będą ewentualne wzrosty lub spadki. W odróżnieniu od analizy fundamentalnej,
oceniającej ogólną sytuację na rynku, analiza techniczna stosowana jest do wyznaczania
momentów zawierania transakcji.
2. Techniki ułatwiające dokonywanie właściwych transakcji na rynku walutowym
2.1. Analiza fundamentalna
Do najważniejszych wskaźników makroekonomicznych które wpływają na
notowania walut, a tym samym mogą pomagać inwestorom w podejmowaniu decyzji -
zaliczamy:
• Produkt krajowy brutto – czyli sumaryczna wartość dóbr i usług wytworzonych
na terenie danego kraju. Rynki finansowe uważnie analizują publikowane co
kwartał zmiany poziomu produktu krajowego brutto w ujęciu rocznym. Większa
9
od oczekiwań dynamika rozwoju gospodarki danego kraju może przyczynić się
do umocnienia jego waluty na rynku międzynarodowym.
• Wskaźnik cen produktów i usług (Consumer Price Index CPI) - wyraża cenę
stałego koszyka dóbr konsumpcyjnych skorygowanych o czynnik sezonowy.
Rynki finansowe wykazują tendencję do odwrotu od walut krajów o rosnącej
inflacji. Wzrost wskaźnika prowadzi do wzrostu stóp procentowych, co oznacza
spadek cen na rynku papierów dłużnych, nominowanych w danej walucie,
• Produkcja przemysłowa (Industrial Production) - określa tempo przyrostu
zagregowanego, fizycznego poziomu produkcji gospodarczej. Wysoka
dynamika produkcji wskazuje na dobrą kondycję gospodarki i może prowadzić
do umocnienia waluty na rynku. Niska dynamika jest natomiast symptomem
niekorzystnej sytuacji ekonomicznej, prowadząc do ucieczki inwestorów od
danej waluty,
• Stopa bezrobocia (Unemployment Rate) - poziom stopy bezrobocia stanowi
jeden z najważniejszych wskaźników mówiących o kondycji danej gospodarki,
Publikowany poziom bezrobocia obejmuje zarówno bezrobocie naturalne –
dobrowolne, jak i bezrobocie rzeczywiste – wynikające z niedopasowania
kwalifikacji siły roboczej do potrzeb rynku pracy, braku popytu oraz bezrobocie
frykcyjne. Stały wzrost poziomu bezrobocia stanowi przejaw pogarszającej się
sytuacji gospodarczej kraju, negatywnie odbierany przez rynki finansowe jako
sygnał odwrotu od danej waluty,
• Rachunek obrotów bieżących (Current Account) - obejmuje wszelkie przepływy
kapitału z i do danego kraju. Dodatnie saldo na rachunku obrotów bieżących
oznacza, że do danego kraju napływa kapitał. Sytuacja taka może się przyczynić
do wzmocnienia waluty krajowej.
Publikacje tych oraz wielu innych wskaźników makroekonomicznych
znacznie ułatwia graczom giełdowym opierającym swoje decyzje na analizie
fundamentalnej podejmowanie właściwych decyzji na rynkach walutowych.
Niekorzystna wartość jednego lub dwóch z tych wskaźników nie oznacza jeszcze, że
pewna waluta zmieni swoje notowania. W praktyce bowiem okazuje się, że każdy
wskaźnik ma swoje znaczenie, które przybiera na wadze w zależności od sytuacji
ekonomicznej w jakiej znajduję się państwo. Zawieranie transakcji na giełdzie
10
walutowej w oparciu o analizę fundamentalną jest dosyć skomplikowane i wymaga od
gracza dużego doświadczenia. Przewidzenie jak na daną sytuacje makroekonomiczna
zareaguje rynek pozwala na obfite zyski. Drugim aspektem przemawiającym za
użyciem analizy fundamentalnej jest to, że jeśli nie mamy żadnych nowych wieści
makroekonomicznych, nie podejmujemy gry na giełdzie. Pozwala to nam uniknąć
inwestowania podczas, gdy rynek nie podlega żadnym trendom – znajduje się wówczas
w tak zwanym trendzie horyzontalnym lub pobocznym. Jest to częsta sytuacja na
giełdzie powodowana najczęściej wyczekiwaniem na nowe wiadomości w sferze
ekonomicznej.
2.2. Analiza techniczna
Aby łatwiej zrozumieć zasady inwestowania na podstawie tej analizy należy
zapoznać się najpierw na trzech podstawowych założeniach, na których się ona opiera:
• Rynek dyskontuje wszystko – to twierdzenie można uznać za kamień węgielny
analizy technicznej. Zwolennicy analizy technicznej uważają, że wszystkie
czynniki, które mogą oddziaływać na rynkową cenę „towaru” w kontrakcie
terminowym – fundamentalne, polityczne, psychologiczne bądź jeszcze inne –
już są uwzględnione w cenie tego „towaru”. Z założenia tego wynika zatem, że
badanie zachowań cen jest podejściem całkowicie samowystarczalnym,
• Ceny podlegają trendom – zasadniczym celem badania wykresów cen jest
wychwycenie trendów w ich wczesnej fazie, co pozwala na dokonywanie
transakcji zgodnie z kierunkiem owych trendów (trend – kierunek, w którym
podążają ceny)
• Historia się powtarza – analiza techniczna zachowań rynku w znacznej mierze
wiąże się z badaniem ludzkiej psychiki. Formacje cenowe, znane już od ponad
stu lat, są na przykład odzwierciedleniem pewnych kształtów, jakie pojawiają
się na wykresach, oznajmiając o dominującej na rynku hossie lub bessie.
Ponieważ formacje sprawdziły się w przeszłości, zakłada się, że znajdą
potwierdzenie również i w przyszłości. Opierają się one na badaniu psychiki
ludzkiej, która raczej się nie zmienia. Założenie mówiące, że historia się
11
powtarza, można przedstawić również jako tezę, według której kluczem do
zrozumienia przyszłości jest badanie przeszłości
2
.
Mając na uwadze powyższe założenia można wskazać na metody, które
pozwolą nam na zawieranie właściwych transakcji na rynku Forex. Wspomniane
metody to: wskaźniki analizy technicznej i formacje cenowe.
Wskaźniki analizy technicznej
Przykładami wskaźników analizy technicznej są np. średnia krocząca, RSI,
ADX, oscylator stochastyczny i wiele innych. Służą one głównie do wyznaczania
kierunków trendu, jego siły (tempa w jakim się porusza w górę lub w dół) jak również
innych cech rynku np. ilości zawieranych transakcji. Od strony matematycznej
wskaźniki są z reguły bardzo proste np. średnia krocząca jest jak sama nazwa wskazuje
średnią arytmetyczną liczoną z ostatnich notowań pary walutowej. Najczęściej używa
się kombinacji dwóch średnich kroczących o różnych okresach dzięki czemu uzyskuje
się dwa wykresy tych wskaźników, które przecinając się wzajemnie wskazują na
miejsca zawierania transakcji. Graczowi giełdowemu wystarcza wiedza w jaki sposób
wykorzystać dany wskaźnik. Każdy inwestor posługuje się również zbiorem
wskaźników, które on sam uważna za najlepsze.
Opierając się na drugim założeniu analizy technicznej należy jednak
pamiętać, że zawierane transakcje powinny być zawsze zgodne z trendem. Pojawia się
jednak pytanie. Zgodnie z którym trendem? Według teorii Downa na rynkach występują
trzy rodzaje trendów. Są to trendy główne (primary trends), wtórne (secondary trends) i
mniejsze (minor trends). W praktyce trendy główne trwają od kilkunastu miesięcy do
kilku lat i zmieniają ceny rynku o 20 procent lub więcej. Trend wtórny jest tylko
zakłóceniem trendu głównego.
2
John J. Murphy – „Analiza techniczna …”
12
Rys. 2.1. Trend wtórny i trend mniejszy wychwycone za pomocą średniej kroczącej,
punkty 1, 2, 3, 4 to dogodne miejsca do zawarcia transakcji zgodnie
z trendem wtórnym „skorygowane” o wskazania trendu mniejszego.
Trwają one od trzech tygodni do kilkunastu miesięcy i „korygują” trend główny, który
tymczasowo posunął się „za daleko i za szybko”. Trendy mniejsze trwają od kilku
godzin do kilku tygodni i nie mają większego wpływu na decyzje większości graczy
giełdowych
3
.
Większość graczy i systemów opierających się na analizie trendów
koncentruje się na badaniu trendów wtórnych. Trendy mniejsze służą wówczas do
wyznaczania momentów wyznaczania transakcji (rys. 2.1).
Do wyznaczania trendów można wykorzystać również inne metody.
Przykładem innych sposobów jest łączenie linią prostą ekstremów cenowych –
minimów dla wyznaczenia trendu rosnącego i maksimów dla wyznaczania trendu
malejącego (rys. 2.2).
Informacje płynące z takiego wyznaczania linii trendów są bardzo znaczące
i przydatne inwestorom. Po kącie nachylenia linii wyznaczającej trend można określić
jego siłę oraz czas, w którym nastąpi odwrócenie trendu, a tym samym da nam znać o
momencie zamknięcia dotychczasowej pozycji (transakcji) i otwarciu przeciwnej.
Sygnałem świadczącym o zmianie tego trendu jest przecięcie linii trendu przez wykres
odzwierciedlający ceny instrumentu.
3
Zenon Komar – „Sztuka …”
13
a)
b)
c)
c)
14
Rys. 2.2. Linie trendu: a) zwyżkujący, b) zniżkujący, c) horyzontalny
Formacje cenowe
Analizując wykresy cenowe można zauważyć, że oprócz wyraźnych
trendów ceny układają się czasami w specyficzny sposób, tworząc tzw. formacje. Takie
w pełni ukształtowane formacje informują nas o kontynuacji danego trendu bądź o
momencie odwrócenia trendu. Formacje te są wywoływane zachowaniem graczy
rynkowych i wynikają z trzeciego założenia analizy technicznej, że historia się
powtarza.
Rys. 2.3. Formacje cenowe: a) trójkąt (chorągiewka), b) chorągiewka, c) głowa
ramiona, d) spodeczek (dno), e) formacja oporu
Podczas kształtowania się tych zjawisk, możemy przewidzieć określone
zachowania rynku. Przykładowe takie formacje pokazane są na rysunku 2.3. Oprócz
tych istnieje jeszcze wiele innych jak np. podwójne dno, podwójny szczyt, formacja
15
wsparcia, formacja V, formacja V z platformą, formacja bazy, kliny, prostokąty,
diamenty, luki w cenach, wyspy. Prawie każda z nich jest podwójna tzn., że oprócz
spodka istnieje jeszcze odwrócony spodek itd.. Część tych formacji zapowiada
kontynuację trendu (chorągiewka, flaga, klin) pozostałe zaś jego odwrócenie (głowa
ramiona, podwójne dno, podwójny szczyt). Dla właściwego oddziaływania tych
formacji na sytuację na giełdzie musi być spełnionych kilka warunków. Jeżeli kształtuje
się formacja np. chorągiewki, która najczęściej jest wiarygodnym zwiastunem
kontynuacji trendu, to oczywistym jest to aby uformowana była ona na trendzie
rosnącym bądź malejącym. Sytuacja ta dotyczy też pozostałych formacji. Wnikliwe
obserwowanie i rozpoznawanie powtarzających się schematów pozwoli na zawieranie
właściwych transakcji. Warto przy tym wspomnieć, że im dana formacja jest większa
tym większy potencjał przyszłego trendu zapowiada, czy to odwrotnego czy będącego
kontynuacją obecnego. Rynek nie jest jednak do końca przewidywalny. Często
występują pułapki, czyli tzw. fałszywe ruchy, które często są przyczyną bankructwa
drobnych inwestorów. Po ukształtowaniu się pewnych form (np. bazy bądź prostokąta)
następuje wybicie cen poza linie wsparcia lub oporu i porusza się w chwile w tym
kierunku, a następnie zmienia się podążając w przeciwną stronę. Z większością formacji
wiążą się również określone metody pomiaru pomagające analitykowi w wyznaczaniu
minimalnego zasięgu przyszłego ruchu cen. Są to wprawdzie tylko wielkości
przybliżone, ale pomagają się zorientować, jak wygląda stosunek potencjalnych zysków
do związanego z ich osiągnięciem ryzyka
4
.
Obok tego istnieje jeszcze cała gama formacji tworzonych przez ceny
instrumentów jak choćby świece japońskie, które służą do prezentacji cen, ale
jednocześnie są doskonałym narzędziem do prognozowania przyszłych zachowań
rynków. Kształty i zestawienia tych świec są bardzo różne i jest i bardzo wiele. Każdy
ma swoją specyficzną nazwę i znaczenie. Są one najczęściej stosowane przez graczy
krajów azjatyckich, gdzie zrodził się ten specyficzny rodzaj prezentacji cen.
2.3. Aspekt psychologiczny przy zawieraniu transakcji
Większość uczestników rynku ma wypracowaną strategię inwestycyjną. Nie
jest ważne jakie ma ona podstawy, lecz w większości przypadków jest ona przemyślana
4
John J. Murphy - op cit.
16
i usytuowana na mocnych fundamentach. Najwięcej trudności, jak się okazuje sprawia
graczom, korzystanie z tej strategii.
Przyczyną takich zachowań jest ludzka psychika, dla tego też jednym z
najważniejszych czynników warunkujących odniesienie sukcesu na rynku walutowym
jest psychologiczne przygotowanie inwestora do przyjmowania ryzyka oraz
umiejętność podejmowania decyzji inwestycyjnych pod wpływem stresu. Inwestor
walutowy, podobnie jak inni uczestnicy rynku terminowego, powinien posiadać
umiejętność selektywnego myślenia, zaakceptowania określonego poziomu straty oraz
unikania presji otoczenia rynkowego [6]. Najczęstszą bolączką graczy giełdowych jest
właśnie brak akceptacji niewielkich strat. Mając zawartą taką niekorzystną transakcję,
nie zamykają jej w nadziei na odwrócenie się trendu, zazwyczaj jednak pogłębia się ich
strata
5
.
Bardzo ważnym czynnikiem, sprzyjającym graczom giełdowym jest
dyscyplina. Pozwala ona opanować nerwy i działać zawsze według ustalonego planu.
Ciekawostką jest to, że np. wojskowi odnoszą znacznie większe sukcesy w spekulacji
niż jakakolwiek inna grupa zawodowa. Zawód ten ponad wszystko wymaga dyscypliny.
Ich siła polega na tym, że mają zdolność kontrolowania emocji, strachu i chciwości,
która niejednokrotnie bywa przyczyna zguby licznych spekulantów. Chcąc odrobić
poniesione straty, starają się w następnej transakcji odrobić te straty ryzykując
większym kapitałem.
5
Koppel R. – „Wewnetrzna gra …”
17
Rys. 2.4. Emocje i ich wpływ na decyzje gracza giełdowego
6
.
Ludzie poddają się zachowaniom zbiorowym, a niektóre działania
społeczności rynkowej mogą być bardzo irracjonalne i niewytłumaczalne.
Potwierdzeniem tej tezy jest krach na giełdzie amerykańskiej w 1987 r., który według
oceny wielu ekonomistów nie doczekał się jak dotąd wyczerpującego i przede
wszystkim racjonalnego wyjaśnienia. Od lat siedemdziesiątych ubiegłego wieku
rozwija się dziedzina nauki zwana behawioryzmem finansowym, zajmująca się
badaniem i przewidywaniem zachowań inwestorów w oparciu o wiedzę dotyczącą
poznawczych i emocjonalnych procesów funkcjonowania umysłu człowieka. Rozwój
tej dziedziny jest uzasadniony tym, że z szeregu przeprowadzonych badań wynika, że
psychologiczne podstawy procesu decyzyjnego u inwestora giełdowego są bardzo
złożone. Zdiagnozowanie tych zachowań być może w niedalekiej przyszłości pozwoli
na łatwiejsze przewidywanie tych zachowań i zapobieganie niepożądanym zjawiskom.
Na rysunku 2.4 przedstawiono wpływ emocji na zachowanie się tradera.
3. Etapy tworzenia systemu informatycznego do automatycznego podejmowania
decyzji
Komputerowe systemy transakcyjne pojawiły się na początku lat
dziewięćdziesiątych dwudziestego wieku. Rozwój technik informatycznych sprawił, że
stały się one bardzo popularne wśród społeczności giełdowej. Komputer dawał nowe
możliwości, jeśli chodzi o budowanie skomplikowanych rozwiązań z zakresu analizy
technicznej. Powstawały zaawansowane teorie rynkowe oparte o sieci neuronowe.
Rozszerzające się możliwości obliczeniowe sprawiły, że nawet bardzo skomplikowane
modele można było zaimplementować. Obecnie postęp w tej dziedzinie jest tak duży, że
w używa się nawet teorii logiki rozmytej, systemów wielokryterialnych i inne
6
Plummert T. – „Psychologia rynków…”
18
rozwiązania, które mogą zostać stworzone i testowane nawet na domowych
komputerach.
Wzrost
popularności
komputerowych
systemów
transakcyjnych
spowodował to, że uczestnicy rynku zauważyli możliwości komputera nie tylko przy
obliczaniu skomplikowanych formułek analizy technicznej, ale również przy
podejmowaniu decyzji kupna i sprzedaży.
Systemy mechaniczne jako dość nowe rozwiązanie znalazło już bardzo dużo
zwolenników. Wiele rzeczy stało się dużo prostsze i łatwiejsze w analizie. Rynek
również stał się przedmiotem analizy niezliczonych rzeszy informatyków. Chociaż
niektóre platformy transakcyjne oferują gotowe systemy transakcyjne, to trudno
przekonać do nich graczy giełdowych, którzy woleli by aby takie systemy działały
według ich określonej strategii. I w tym przypadku firmy oferujące takie
oprogramowanie, wyszły naprzeciw tym wymogom i umieściły w swych platformach
edytory kodu, które pozwalają budować własne systemy transakcyjne lub wskaźniki.
Jednak języki używane implementacji tych narzędzi są z reguły bardzo proste i
ograniczone.
Stworzenie aplikacji na bazie języka C++, C# lub platformy Java z
możliwością implementacji własnych wskaźników i systemów pozwalałoby na
budowanie skomplikowanych i opartych o różne kryteria narzędzi wychwytujących
trendy rynkowe i skuteczne wykorzystywanie tych informacji. Zbudowana platforma
JST ma takie możliwości. Jest to modułowa aplikacja open source. Jeżeli uczestnik
rynku ma opracowaną pewną strategię w podejmowaniu decyzji transakcyjnych, to
zaimplementowanie systemu, który realizowałby wszelkie założenia tej strategii, nie
powinno sprawić mu większego problemu. Koniecznością w tym wypadku, jest chociaż
minimalna znajomość języka programowania Java.
Bardzo istotną przeszkodą w budowaniu takiego systemu może się okazać
trudność wykorzystania analizy fundamentalnej w implementacji tych systemów. Nawet
nie cała analiza techniczna może być w pełni wykorzystana. Trudno bowiem byłoby w
notowaniach instrumentów znaleźć niektóre bardziej skomplikowane formacje np.
głowa – ramiona czy spodek. Budowany system należy więc oprzeć na wskaźnikach
wbudowanych bądź też, zaimplementować własne.
Pomimo tych ograniczeń jest bardzo wiele zalet które przemawiają za
stosowaniem tego typu rozwiązań w powiększaniu swojego kapitału np.
a) eliminowane są emocje,
19
b) osiąga się dyscyplinę,
c) możliwa staje się większa konsekwencja,
d) transakcje są dokonywane zgodnie z kierunkiem trendu,
e) praktycznie gwarantowane jest uczestnictwo w każdym istotnym trendzie,
f) zyski mogą rosnąć,
g) straty są minimalizowane.
Do wad systemów transakcyjnych zaliczamy:
a) większość z nich podąża za trendem,
b) systemy podążające za trendem potrzebują wyraźnych trendów, aby przynosić
zyski,
c) systemy zależne od trendów nie przynoszą na ogół zysków, kiedy na rynku nie
ma wyraźnego trendu,
d) okresy bez wyraźnego trendu bywają bardzo długie, co utrudnia stosowanie tego
podejścia
7
.
Celowo opisane są psychologiczne aspekty inwestowania w podpunkcie
trzecim bieżącego rozdziału, ponieważ jak się okazuje jedną z zalet systemów
transakcyjnych jest eliminowanie tych zachowań, które jak wcześniej zaznaczyłem,
mają ogromny wpływ na decyzje gracza giełdowego.
Dyscyplina i konsekwencja to oczywiste cechy jakie posiadał będzie
jakikolwiek zbudowany system. Zaimplementowane akcje decyzyjne zawsze
wykonywać się będą według ustalonego algorytmu i niemożliwym jest, aby pominęły
jakiekolwiek okazje do zajmowania pozycji – oczywiście pod warunkiem że
zbudowany system nie będzie zawierał błędów merytorycznych. Oprócz wymienionych
zalet można jeszcze zwrócić uwagę na oszczędność czasu i zawieranie większej liczby
transakcji (zaleta, jeśli są to prawidłowe transakcje). Zyskując czas możemy poświęcić
go na badanie nowych, bardziej płynnych rynków.
Jeżeli chodzi o wady takich rozwiązań, to jestem jak najbardziej zgodny z
powyższymi punktami. Niemniej jednak dotyczą one głównie jednego problemu, a
mianowicie trendów horyzontalnych. Najlepszym rozwiązaniem wydaje być się w
takiej sytuacji unikanie gry podczas takich zastojów rynku, bądź też szukanie innych
7
John J. Murphy op. cit.
20
bardziej dynamicznych instrumentów finansowych. Zasady na jakich należy opierać
budowane systemy są opisane w kolejnych podrozdziałach.
3.1. Wybór rynku i odpowiednich narzędzi odwzorowujących trendy rynkowe
Pierwszym krokiem jaki powinno się podjąć podczas budowania systemu
transakcyjnego, jest określenie zbioru instrumentów finansowych, czyli par
walutowych, które są najbardziej odpowiednie. Wybierając je, należy pamiętać o ich
płynności. Testujemy różne rynki pod względem szybkości zawierania transakcji (czy
musimy długo czekać na realizację naszych zleceń) oraz wahań cen w zależności od
naszych zleceń, jeśli takie wahania mają miejsce to należy zrezygnować z udziału w
grze na danej walucie, gdyż oznacza to małe zainteresowanie wśród społeczności
giełdowej tym instrumentem, a wówczas analizowanie trendów w takiej sytuacji może
się okazać bardzo skomplikowane. Nie należy podejmować gry na instrumentach, dla
których jest bardzo duża różnica między ceną oferowaną i żądaną (bid i ask), jednym
słowem na walutach, za które opłaty dla brokerów są wysokie. Każda transakcja wiąże
się wówczas z taką opłatą. Oczywistym w takiej sytuacji, jest to, że zdecydowanie
powinniśmy unikać inwestowania w na stosunkowo nowych rynkach, które najczęściej
cechują się wysokim spread’em (opłata brokerska) i szalonymi wahaniami
8
. Szukając
odpowiednich instrumentów musimy przede wszystkim zwrócić uwagę na wolumen,
który świadczy o dużej liczbie inwestorów i o dużym potencjale pary walutowej.
Po wybraniu odpowiedniego rynku nie można poprzestać na badaniu go,
ponieważ może zdarzyć się, że pewne czynniki spowodują odwrócenie się inwestorów
od danego instrumentu i handel może okazać się już nieopłacalny. Dobrze jest śledzić
kilka rynków i inwestować kapitał na więcej niż jednym.
Dobór narzędzi do analizy kierunku rynku walutowego, jest kolejnym
bardzo ważnym czynnikiem przy budowie systemu. Podstawowym zadaniem jakie musi
spełnić wskaźnik, to odzwierciedlenie trendu, bądź jego siły. Jest opracowanych
obecnie dużo takich narzędzi zarówno do wyznaczania kierunków ruchu cen jak i siły
tych ruchów. Budowę naszego systemu możemy oprzeć na wskazaniach tych prostych
wskaźników lub też zaprojektować własne, które będą reprezentować nasz punkt
myślenia.
8
Dawis W. Lukas – „Komputerowa analiza …”
21
3.2. Wypracowanie i zaadoptowanie metody do zbioru obiektywnych zasad
Jeśli inwestor ma już jasno sprecyzowane rynki, na których chce
inwestować oraz narzędzia jakich będzie używał, to musi opracować metodę, którą
będzie stosował do zawierania odpowiednich transakcji. Gracz musi być zdecydowany,
czy będzie śledził wszystkie najdrobniejsze wahania rynku, czy też będzie inwestował
w dłuższej perspektywie czasowej. Jest to ważna kwestia związana z optymalizacją
zbudowanego systemu, która zostanie opisana w kolejnych punktach tego rozdziału.
Kolejnym ważnym elementem w budowie systemu jest określenie dopuszczalnego
poziomu strat jakie może przynieść jedna transakcja. Oczywiste jest, że na rynku mogą
pojawić się sytuacje w których nasz system może przynieść pewne straty. Najlepszym
wyjściem z takiej sytuacji byłoby wyeliminowanie takich zachowań, ale w praktyce nie
zawsze się to udaje dlatego w trosce o zmniejszenie strat powinno się pamiętać o
zleceniach obronnych, które są pełnią funkcję składki w polisie ubezpieczeniowej
i związane z nimi koszta należy traktować jako koszta prowadzenia każdego innego
biznesu
9
.
Przechodzimy teraz do kolejnym problemów: otwarcie i zamknięcie
pozycji. Należy jasno sprecyzować kiedy wchodzimy na rynek, a kiedy z niego
wychodzimy. Możliwa jest oczywiście ciągła gra, bo przecież zamykając pozycję długą,
czyli transakcję kupna, spodziewamy się najczęściej zmian na rynku, które pozwalają
na zawarcie pozycji krótkiej (sprzedaż). Nie zaleca się jednak takich rozwiązań.
Inwestor powinien mieć jasno określone zasady wchodzenia i wychodzenia z rynku. Po
zamknięciu pozycji, czekać na sygnał do włączenia się do gry.
Najczęściej do wyznaczania takich momentów używa się wskaźników.
Kombinacja dwóch średnich kroczących dobrze wyznacza te przedziały czasowe, ale
ich użycie staje się bezużyteczne jeśli na rynku mamy do czynienia z trendem
horyzontalnym. Na tym przykładzie widać, że nie ma idealnego i prostego rozwiązania,
którego zazwyczaj poszukują projektanci systemów. Nie można zbudować wskaźnika,
który będzie sygnalizował odpowiednie momenty do otwarcia lub zamknięcia pozycji
oraz zmiany trendów. Powinno się raczej wyodrębnić i zbadać poszczególne problemy,
a następnie rozwiązać je kolejno posługując się za każdym razem odpowiednim
9
Dawis W. Lukas - op. cit.
22
narzędziem. Dzięki takiemu podejściu będziemy mogli projektować elastyczne
i dynamiczne systemy, które będą mogły przetrwać w konfrontacji ze zmieniającym się
nieustannie rynkiem
10
.
Istnieje również przekonanie, że drogą do sukcesu jest zamykanie pozycji
w odpowiednim czasie, a nie wchodzenie na rynek. Istnieje wiele sposobów
realizowania zysków z transakcji. Jednym z nich jest założenie określonego poziomu
wyjścia. Jak każde rozwiązanie posiada swoje zalety i wady. Do innych rozwiązań
należą między innymi zlecenia obronne ruchome. Jeśli mamy otwartą pozycję która
przynosi nam zysk, to aby go zmaksymalizować ustalamy ruchomą linię obronną.
Jesteśmy wtedy zabezpieczeni przed nagłym zwrotem rynku i mamy pewność, że zysk
będzie w miarę maksymalny. Należy tylko ustalić prawidłowy poziom tej obrony, aby
chwilowe korekcje trendu nie zaprzepaściły naszej szansy na wysoki profit.
Gdy mamy już określone wszelkie zasady, które ma realizować nasz
system, musimy dotrzeć do ich matematycznego podłoża, dzięki czemu implementacja
będzie już ostatnim krokiem przed pierwszym testowaniem.
3.3. Testowanie i ocena wyników
Przed testowaniem systemu należy sprawdzić wizualnie na wykresie, czy
zbudowany system zawiera transakcje według określonych przez nas zasad. Oczywiście
najłatwiej sprawdzić to na danych historycznych. Jeżeli założenia programowe są
realizowane w prawidłowy sposób, to możemy przystąpić to wyliczenia potencjalnych
zysków. System powinien być przetestowanych w różnych aspektach:
• Różne zestawy parametrów – zazwyczaj w projektowanych rozwiązaniach
używa się kilku zmiennych warunkujących podejmowanie decyzji. Ważnym jest
aby przetestować system pod kątem odpowiednich wartości tych zmiennych i
wybrać taki zestaw, aby bilans zysków był jak największy,
• Różne okresy – systemy zasadniczo powinny sprawdzać się w różnych
okresach. Jeśli przykładowo daje dobre rezultaty na notowaniach EUR/USD w
latach 1995 – 2000, to powinien dawać je również w latach 2000 – 2005.
10
Dawis W. Lukas - op. cit.
23
• Wiele różnych rynków – generalnie zbudowane systemy powinny być
przenośne, tzn. dawać równie dobre rezultaty na różnych instrumentach
(dotyczy to par walutowych o podobnej kondycji ekonomicznej).
Jeśli wykazane zyski okazuję się małe lub nie ma ich wcale, wówczas
musimy dokonać poprawek w kodzie lub w procesie decyzyjnym i ponownie
przeprowadzić testy. W praktyce bardzo niewiele koncepcji pozytywnie przechodzi
testy, zwykle mniej niż 5 procent. Często też, okazuje się, że z różnych powodów te
„udane” koncepcje nie zawsze nadają się do wykorzystania w praktyce. Aby nasz
system mógł być użyty w czasie rzeczywistym musi spełniać jeszcze dużo wymogów.
Ile czasu zajmuje mu wychodzenie z przegrywającej transakcji? Czy przetrwamy
obsunięcia kapitału? Na te pytania można udzielić odpowiedzi wyznaczając kilka
kluczowych elementów:
• Współczynnik zysku – zysk z transakcji udanych w stosunku do strat z
transakcji nieudanych. Satysfakcjonującą wartością jest co najmniej 2.
• Średni zysk z transakcji – wielkość ta powinna być na tyle duża, aby pokryć
koszty transakcji (prowizje i poślizgi); w innym przypadku będziemy narażeni
na straty.
• Maksymalne obsunięcie kapitału – spadek kapitału przypadający na najbardziej
nieudaną transakcję
11
.
Jednakże, podczas testowania należy pamiętać nie tylko o bilansie zysków i
strat, ale również o ilości trafnych decyzji. Wyobraźmy sobie sytuację, w której nasz
system przetestowany na okresie ostatniego miesiąca przyniósł pewne, aczkolwiek małe
zyski, przeprowadzając tym samym kilkanaście transakcji. Przy bliższej analizie,
okazuje się, że tylko dwie były udane i pokryły straty z pozostałych transakcji. Jak się
okazuje, analizowanie tylko i wyłącznie bilansu zysków i strat jest niebezpieczne.
Istnieje potrzeba analizowania działania systemu nawet, gdy przynosi on wymierne
korzyści.
3.4. Nadzorowanie i optymalizacja systemu
11
John J. Murphy op. cit.
24
Jak powszechnie wiadomo rynki się zmieniają oraz warunki na nich
panujące. Można spekulować na temat tego, czy wszystkie systemy tracą po pewnym
czasie swą pierwotną wartość. Lepiej jest założyć, że pomimo wszelkich starań
dołożonych, aby nasz system był odporny na nieoczekiwane zmiany, może on stracić
skuteczność (objawami może być powiększająca się strata kapitału). Należy w takim
wypadku nauczyć się wcześnie rozpoznawać symptomy świadczące o starzeniu się
naszego systemu
12
.
Najlepszą metodą oceny bieżącej skuteczności systemu byłoby gromadzenie
danych na ten temat już w czasie testowania go na danych historycznych, które
następnie służyłyby jako punkt odniesienia dla porównań jego bieżącego
funkcjonowania.
W procesie nadzorowania systemu bardzo ważne jest rozpoznanie źródeł
pojawiających się problemów. Utrzymywanie bazy danych na temat historycznej
skuteczności systemu na różnych rynkach jest pomocne, gdy trzeba wyodrębnić różne
rodzaje jego braków
13
. Z danych historycznych, czy bieżących danych możemy
wyliczać pewne wartości, które przy analizie pozwolą nam na wczesne zdefiniowanie
problemu w naszej koncepcji. Jest to, jak wspomniałem już wcześniej, liczba udanych
transakcji w stosunku do tych nieudanych. Najczęściej wyraża się ją w procentach.
Innymi używanymi wartościami są: średni zysk z udanej transakcji, średnia strata z
udanej transakcji, czas potrzebny do odrobienia największego obsunięcia kapitału itp.
Nadzorowanie jest ostatnim elementem zdyscyplinowanej strategii
budowania systemów. Jeżeli stworzony przez nas system transakcyjny przeszedł
zadowalająco testy i jest gotowy do zastosowania do gry na danych rzeczywistych, to
pozostaje nam analiza zysków i transakcji w celu optymalizacji, a nie przebudowy
podstaw naszej koncepcji. Zmienność rynku nie jest na tyle gwałtowna, aby nasz
system stał się zawodny z dnia na dzień. Stałe nadzorowanie pozwala na utrzymanie
naszego systemu w dobrej kondycji, przez co ewentualne poprawki i optymalizowanie
może przebiegać znacznie szybciej.
4. Opracowanie, implementacja i użytkowanie platformy JST
12
Dawis W. Lukas – op. cit.
13
Dawis W. Lukas - op. cit.
25
4.1. Wymagania funkcjonalne i niefunkcjonalne
Interfejs użytkownika jest zasadniczą częścią zbudowanego systemu
informatycznego, dlatego też wszelkie wymagania funkcjonalne dotyczą sposobu
prezentacji danych dotyczących notowań oraz transakcji zawieranych na bieżąco przez
użytkownika oraz historii tych zleceń. Z uwagi na charakter budowanej platformy (open
source) wymagania niefunkcjonalne będą miały znaczenie dla użytkowników, którzy
będą rozbudowywać aplikacje o nowe systemy transakcyjne bądź wskaźniki.
4.1.1. Wymagania funkcjonalne
Zasadniczą rolą aplikacji jest pobieranie danych z serwera i obrazowanie ich
na wykresach (notowania walut) lub w tabelach (dane dotyczące konta i historia jego
transakcji). Dla działającego systemu transakcyjnego taki interfejs nie jest konieczny,
ale biorąc pod uwagę konieczność nadzorowania takich mechanicznych rozwiązań, to
wizualizacja podejmowanych decyzji przez ten mechanizm, może być wykorzystana do
jego weryfikacji i walidacji. Poniżej przedstawiono najważniejsze wymagania
funkcjonalne.
Zarządzanie systemem informatycznym
Plik
Nowy
Załadowanie wykresu dla nowej pary walut
Ustalenie okresowości
Ustalenie charakteru reprezentacji danych
Dodanie wskaźnika
26
Wybór wskaźnika
Wybór parametrów
Otwórz
Otwarcie danych z pliku w celu prezentacji na wykresie
Zapisz
Zapis danych z bieżącej prezentacji do pliku
Opcje
Nowe zlecenie
Ustalenie wielkości transakcji
Ustalenie progów zabezpieczających transakcję
Modyfikuj zlecenie
Zmiana progów zabezpieczających
Zamknij zlecenie
Sfinalizowanie transakcji
Systemy mechaniczne
Modyfikuj wskaźnik
Zmiana parametrów wskaźnika
27
4.1.2. Wymagania niefunkcjonalne
Wymagania niefunkcjonalne jak już wcześniej wspomniano, dotyczą
głównie sposobu prezentacji wszelkich danych oraz podręcznego opisu dla łatwiejszego
rozbudowania aplikacji. Do wymagań tych można zaliczyć:
• rozbudowana prezentacja kursów – wizualizacja wskaźników bezpośrednio na
notowaniach i pod modułem wykresowym, możliwość skalowania wykresów i
prezentacji w różnych dywersyfikacjach czasowych,
Testowanie
Sprawdzanie merytorycznej poprawności
systemów oraz bilansu transakcji
Optymalizacja
Dobieranie odpowiednich parametrów do
zaimplementowanych systemów
Uruchomienie
Włączenie systemu do udziału w spekulacji
rynkowej
Zatrzymanie
Odłączenie systemu od gry na rynku
Raporty
Graficzna i liczbowa prezentacja przychodów, ilości transakcji itp.
28
• wizualizacja notowań najważniejszych par walutowych – możliwość ciągłego
obserwowania kilku instrumentów finansowych,
• wizualizacja parametrów konta, zawieranych transakcji bez względu, czy są
zawarte przez system czy przez gracza, możliwość sprawdzenia historii
zamkniętych zleceń,
• szybki dostęp do najpotrzebniejszych i najczęściej używanych funkcji np.
zawierania i zamykania transakcji, przeładowywanie wykresów i inne (prawy
klawisz myszy lub skróty klawiszowe),
• zapamiętywanie ustawień użytkownika, takich jak login i hasło, aby nie
wpisywać ich każdorazowo przy logowaniu do systemu,
• zaznaczenie miejsc w kodzie źródłowym, w których projektanci własnych
systemów i wskaźników będą mogli poszerzyć funkcjonalność aplikacji.
4.2. Projektowanie systemu informatycznego
Pełna funkcjonalność platformy jest możliwa dzięki zastosowaniu funkcji
z rodziny API zamkniętych w bibliotece dll, które zapewniają komunikację z serwerem
(podłączenie do serwera), pobieranie aktualnych cen walut, zawieranie transakcji kupna
i sprzedaży, modyfikowanie transakcji poprzez zmianę ich wartości zabezpieczających,
czyli StopLoss i TakeProfit oraz pobieranie historii zamkniętych zleceń. Zbiór tych
funkcji jest udostępniony przez amerykańską firmę Visual Trade. Serwer, z którego
pobierane są wszelkie informacje dotyczące notowań, również należy do tej firmy.
Aplikacja JST jest tak zbudowana aby w pełni korzystać możliwości powyższych
funkcji. Dla potrzeb identyfikacji konta użytkownika, kursów walut czy otwartych
transakcji zostały stworzone specjalne klasy przechowujące odpowiednie informacje.
Do obiektów tych należą miedzy innymi:
IAccount – jest to klasa przechowująca informacje o użytkowniku konta, jej
ważniejszymi atrybutami są:
• Id : String, Index : int – identyfikator konta,
• Owner : String – nazwa właściciela konta,
• Balance : double – wartość kapitału przed transakcją ,
• Equity : double – wartość kapitału łącznie z bieżącą transakcją (jeśli aktualnie
gracz nie ma żadnej otwartej pozycji ta wartość jest taka sama jak Balance,
• NetPL : double – łączna wartość otwartych pozycji.
29
Do metod tej klasy należą funkcje dostępu do poszczególnych atrybutów.
IInstrument – jest to klasa zawierająca informacje o notowaniach pary walutowej:
• Currency1 : String – nazwa pierwszej waluty w parze,
• Currency2 : String – nazwa drugiej waluty w parze,
• Id : String, Index : int – identyfikator instrumentu,
• Bid : double – ostatnia cena sprzedaży,
• Ask : double – ostatnia cena kupna,
• points : int – liczba miejsc po przecinku.
Oprócz funkcji dostępu klasa posiada metody takie jak:
• GetHistory() – pobranie historii notowania waluty.
IPosition – klasa zawierająca informacje o otwartej transakcji:
• Account : IAccount – informacje o koncie użytkownika
• Instrument : IInstrument – informacje o parze walutowej związanej z transakcją,
• LimitOrder : IConditionalOrder – informacje o zabezpieczeniu transakcji
TakeProfit,
• StopOrder : IConditionalOrder – informacje o zabezpieczeniu transakcji
zleceniem obronnym StopLoss,
• BuySell : boolean – zmienna informująca o rodzaju zawartej transakcji: true –
sell, false – buy,
• Id : String, Index : int – identyfikator transakcji,
• Amount : double – wielkość transakcji (Lot),
• NetPL : double – zysk lub strata w danej transakcji,
• Time : Date – czas zawarcia transakcji,
• OpenRate : double – cena instrumentu podczas zawierania transakcji,
• CloseRate : double – obecna cena instrumentu.
Podobnie jak powyższe klasy posiada funkcje dostępu oraz:
• Close() – funkcja służąca do zamknięcia pozycji,
• CreateLimitOrder() – zabezpieczenie transakcji zleceniem TakeProfit,
• CreateStopOrder() – zabezpieczenie transakcji zleceniem obronnym StopLoss.
IConditionalOrder – klasa przechowująca informacje o zabezpieczeniach transakcji,
jej atrybuty to:
• Account : IAccount – informacje o koncie użytkownika,
30
• Instrument : IInstrument – informacje o instrumencie, którego zlecenie obronne
dotyczy,
• Id : String, Index : int – identyfikator,
• Rate : double – wartość przy którym zlecenie należy zamknąć.
Do metod klasy należą:
• Change() – zmiana wartości zlecenia obronnego,
• Remove() – usunięcie ograniczenia transakcji.
IServerMessage – klasa przechowująca informacje o komunikatach przesyłanych do i z
serwera. Do atrybutów należą:
• Id : String, Index : int – identyfikator wiadomości,
• Time : Date – czas odbioru wiadomości,
• Level : int – poziom wiadomości,
• Kind : int – typ wiadomości,
• Text : String – treść wiadomości.
Ważniejszymi funkcjami zawartymi w bibliotece dll i najczęściej używanymi, są:
• Login() – funkcja pozwala na połączenie się z serwerem. Jako parametry
przyjmuje: nazwę użytkownika, hasło i numer serwera (0 – wersja demo, 1 –
wersja real);
• Logout() – wylogowanie się z serwera;
• Finalize() – usuwa obiekty, wylogowanie użytkownika, jeśli był zalogowany,
• GetInstrumentByIndex() – pobranie informacji o instrumencie na podstawie
parametru, którym jest index pary walutowej,
• GetInsturmentByCurrency() – podobnie jak w przypadku powyższej funkcji, ale
jako parametr przyjmuje nazwę waluty,
• GetOpenPositionCount() – funkcja zwraca ilość otwartych transakcji,
• GetOpenPositionById() – pobranie informacji o transakcji, której identyfikator
podany jest jako parametr,
• GetMessageByIndex() – pobranie wiadomości,
• SendCreateOrder() – zawarcie transakcji kupna lub sprzedaży,
• SendClosePosiotion() – zamknięcie transakcji,
• SendSetStopForOpenPosition() – ustawienie zabezpieczenia transakcji dla
otwartej pozycji zleceniem obronnym StopLoss,
31
• SendSetLimitForOpenPosition() – podobnie jak powyższa funkcja, tyle że
zabezpieczenie następuje poprzez zlecenie TakeProfit,
• SendChangeStopForOpenPosition() – zmiana wartości zlecenia obronnego,
• SendChangeLimitForOpenPosition() – podobnie jak powyżej,
• SendRemoveStopForOpenPosition() – usunięcie zabezpieczenia obronnego,
• SendRemoveLimitForOpenPosition() – podobnie jak powyżej,
• GetClosedPositions() – pobranie historii zamkniętych zleceń,
Ponadto moduł ten jest wzbogacony o obsługę zdarzeń, możliwe jest dzięki
temu zredukowanie do minimum ruchu na serwerze. Poszczególne funkcje i ich
wykorzystanie zostały omówione poniżej:
• OnNewServerMessage ( int MsID ) – zdarzenie wykorzystywane do śledzenia
ruchu na serwerze. Parametr MsID, to typ wiadomości.
• OnPositionChange ( String PosiotionID, int Action ) – zdarzenie wywoływane
gry zmieniają się parametry zawartej transakcji, np. zlecenia obronne (StopLoss,
TakeProfit), bądź też zysk lub ewentualna strata z takiej transakcji. Jako
parametr funkcji przekazywany jest identyfikator pozycji PositionID, dzięki
czemu łatwo jest odszukać tą pozycję w tabeli prezentującej zawarte transakcje i
uaktualnić ją. Dodatkowo w identyfikacji rodzaju zmiany pozycji pomaga drugi
parametr przekazywany przez funkcję, czyli Action,
• OnAccountChange ( String AccountID, int Action) – podobnie jak w przypadku
poprzedniego zdarzenia, zostaje wywołane z dwoma parametrami. Pierwszy
dotyczy konta użytkownika, na którym pojawia się pewna zmiana, drugi zaś
dotyczy rodzaju tej zmiany – najczęściej jest to zmiana dotycząca wielkości
kapitału gracza,
• OnInstrumentChange ( String InstrumentID ) – zdarzenie jest wywoływane
kiedy zmienia się cena zamknięcia (Bid i Ask),
• OnConnectionLost() – zdarzenie jest wywoływane gdy połączenie z serwerem
zostaje przerwane.
Istnieje jeszcze kilka zdarzeń zdefiniowanych we wspomnianej bibliotece,
ale nie będą tu opisane gdyż nie są wykorzystywane w aplikacji. Warto jednak
wspomnieć o rodzajach wiadomości jakie zwracają powyższe funkcje lub jakie
przekazują zdarzenia i tak numeracja przykładowych błędów wygląda następująco:
32
• NO_ERROR = 0,
• UNKNOWN_ERROR = 1,
• HTTP_ERROR = 2,
• PARSE_ERROR = 3,
• TIMEOUT_ERROR = 4,
• ALREADY_LOGGED_ERROR = 6,
• NOT_LOGGED_ERROR = 7,
• WRONG_PASSWORD = 12,
• INVALID_INSTRUMENT = 17,
• NOT_IMPLEMENTED = 27,
• INVALID_ACCOUNT = 31,
• INVALID_POSITION = 32.
Typy wiadomości dotyczące otwartych pozycji to np.:
• MT_NEW_POSITION = 0,
• MT_CLOSE_POSITION = 1,
• MT_CREATE_STOP = 2,
• MT_CREATE_LIMIT = 3,
• MT_UPDATE_STOP = 5,
• MT_UPDATE_LIMIT = 6,
• MT_REMOVE_STOP = 8,
• MT_REMOVE_LIMIT = 9,
• MT_ERROR = 11.
Typy wiadomości odnoszące się do konta użytkownika to:
• A_ACCOUNT_UPDATE = 0,
• A_EQUTIY_CALL = 2,
• A_ACCOUNT_RATE_UPDATE = 8.
Platforma JST zapewnia właściwe wykorzystanie wszelkich funkcji poprzez
wizualizację notowań walut, wyświetlanie aktualnych cen kupna i sprzedaży
najpopularniejszych dziesięciu par walutowych, informacji dotyczących konta
użytkownika oraz transakcji przez niego zawartych. W tym celu zostały zbudowane
odpowiednie klasy odpowiedzialne za przekształcanie ciągu liczb w wykresy lub tabele.
33
Chart – to klasa, która jest odpowiedzialna za odpowiednie wyskalowanie
i wyświetlenie kursów walut lub akcji oraz wskaźników analizy technicznej
naniesionych na notowania bądź dodanych pod oknem wykresu. Na wykresach tych
naniesione są również informacje dotyczące cen otwarcia, zamknięcia, najwyższe,
najniższe oraz daty związane z notowaniami. Ważniejsze zmienne składowe tej klasy
to:
• count : int – ilość „barów” czyli wartości opisujących notowanie instrumentu w
danej chwili czasowej,
• min, max, step, value, scale, width : int – zmienne wykorzystywane do
rysowania,
• fIndicator, sIndicator : String – nazwy wskaźników, które są wizualizowane pod
wykresem notowania,
• closeData, highData, openData, lowData : double – dane o notowaniach
instrumentu,
• timeStamps : Date – daty notowań,
• numberOfIndicators – ilość wskaźników.
Metody tej klasy to:
• drawChart() – funkcja rysujaca,
• update() – funkcja zmieniająca ciąg danych przeznaczonych do wizualizacji,
• range() – funkcja odpowiedzialna za wyznaczenie wartości pomocnych przy
rysowaniu (odstępy między kolejnymi barami, słupkami, jednostka itp.),
• min_max() – wyznaczanie minimalnej i maksymalnej wartości notowania,
• indMin() – wyznaczanie minimalnej wartości wskaźnika,
• indMax() – wyznaczanie maksymalnej wartości wskaźnika,
• refresh() – odświeżenie wykresu (np. po zmianie koloru wskaźnika),
• addIndicator() – dodanie nowego wskaźnika,
• computeIndicators() – obliczenie wskaźników.
Ponadto klasa zawiera szereg funkcji wyznaczających wbudowane wskaźniki np.
średnią kroczącą (movAvg1() i movAvg2()), wstęgę Bollingera (band()) i inne.
Poniżej opisane klasy, to interfejsy realizujące zadania jakie może
wykonywać użytkownik. Ze względu na to ze aplikacja JST jest przystosowana również
34
dla potrzeb graczy preferujących manualny tryb zawierania transakcji konieczne było
zaimplementowanie odpowiednich formatek umożliwiających wszelkie operacje, tj.
zawieranie transakcji, modyfikowanie zawartych zleceń, wizualizacja wskaźników oraz
możliwość ich modyfikacji.
ModifyOrder – klasa umożliwiająca użytkownikowi zmianę zabezpieczeń transakcji.
Login – klasa umożliwia użytkownikowi zalogowanie się do serwera po podaniu
niezbędnych informacji tj. nazwy użytkownika w systemie, hasła i serwera, na który
użytkownik chce się zalogować.
New – interfejs umożliwiający dodawanie nowych wskaźników bądź zmianę
wizualizowanych notowań.
Indicators – klasa pozwala użytkownikowi na dobieranie odpowiednich parametrów
takich jak kolor na wykresie czy okres dla nowych wskaźników bądź tych parametrów
dla już istniejących.
Transaction – ta klasa umożliwia zawieranie transakcji. Użytkownik ma możliwość
wybrania wielkości transakcji, rodzaju zawieranej transakcji oraz ustalenia
zabezpieczeń.
Dla potrzeb użytkowników budujących własne systemy transakcyjne zostały
również zbudowane odpowiednie klasy umożliwiające ich testowanie i wprowadzanie
w życie.
ASystem – klasa umożliwiająca uruchamianie, testowanie i optymalizację budowanych
systemów.
SystemRun
–
klasa
realizująca
działanie
zaimplementowanych
systemów
transakcyjnych.
Report – jest to klasa w zasadzie podobna do klasy Chart, ponieważ podobnie jak ona
zajmuje się rysowaniem, tyle ze nie wizualizuje notowań ale wyniki testowanych
systemów transakcyjnych. Atrybuty to:
35
• testedSystem : double – tablica wartości kapitału po kolejnych transakcjach
testowanego systemu,
• currentSystem : double – tablica wartości kapitału na podstawie zamkniętych
pozycji,
• min, max : double – maksymalna i minimalna wartość kapitału w testowanym
bądź bieżącym systemie – wykorzystywane do skalowania wykresu krzywej
kapitału,
• step : int – odległość w pikselach pomiędzy kolejnymi transakcjami na krzywej
kapitału,
• name : String – nazwa systemu, na podstawie którego jest aktualnie narysowana
krzywa kapitału.
Metody:
• min_max() – wyznaczanie minimalnej i maksymalnej wartości kapitału,
• paint() – rysowanie wykresu odzwierciedlającego krzywą kapitału,
• setData() – ustalenie danych przeznaczonych do wizualizacji,
• findScale() – ustalenie skali do rysowania.
Klasa główna systemu informatycznego, to JST, która jest głównym interfejsem
umożliwiającym sterowanie funkcjonalnością wszystkich klas składowych oraz funkcji
pobranych z biblioteki dll. Atrybuty tej klasy to standardowe komponenty wizualne
Javy oraz inne zmienne np.:
• hasFinishedInitialization : boolean – zmienna informująca o tym, czy
zakończono już inicjalizację elementów w funkcji initComponets(),
• api : VT_API – obiekt klasy dostarczonej z biblioteki dll, umożliwiający
odwołanie się do funkcji zamkniętych w tejże bibliotece.
• highData, closeData, lowData, openData : double – tablice przechowujące
informacje o notowaniach walut,
• highDataZ, closeDataZ, lowDataZ, openDataZ : double – pomocnicze tablice
przechowujące dane przeznaczone do powiększania rozdzielczości wykresu,
• timeStamps, timeStampsZ : Data – daty notowań,
• ticketName, oldTicketName : String – zmienne przechowujące ostatnią i bieżącą
nazwę wyświetlanej akcji,
36
• oldInd1, oldInd2 : String – nazwy aktualnych wskaźników wybranych do
wizualizacji,
• hist : String – zmianna przechowująca bieżące notowanie pary walutowej lub
ostatnio wizualizowane. Zmienna ta jest wykorzystywana w funkcji save(),
Natomiast najważniejsze metody to:
• getData() – wczytanie kursu akcji,
• initComponents() – inicjowanie komponentów wizualnych i wczytanie danych
domyślnych,
• getClosedHistory() – pobranie historii zamkniętych zleceń i umieszczenie w
tabeli,
• getHistory() – pobranie historii notowań bieżącego instrumentu,
• getResultTest() – pobranie wyników testu systemu i przekazanie do
wizualizacji,
• save() – zapisanie notowania pary walutowej, która jest wyświetlana bądź
ostatnio była,
• open() – otwarcie ostatniego notowania pary walutowej,
• refreshReport() – uaktualnienie danych raportu,
• setIndicator() – ustawienie właściwości nowego wskaźnika,
• zoomIn() – powiększenie wykresu,
• zoomOut() – pomniejszenie wykresu.
Poza tym klasa posiada szereg funkcji wizualizujących interfejsy klas składowych jak
Login, Transaction, ModifyOrder, Indicators i inne.
4.3. Implementacja systemu informatycznego
Aplikacja JST jest w całości napisana w języku Java. Jak wiadomo ten język
programowania ma wiele zalet jak chociażby przenośność na wszystkie platformy,
stabilność, bogaty zasób komponentów. Tak i w przypadku tego systemu
informatycznego jest możliwe uruchomienie go na platformach na bazie Unixa. Jednak
funkcjonalność programu będzie tam już nieco ograniczona ze względu na brak
odpowiedniej biblioteki dedykowanej tym systemom. Jednakże aplikacja została tak
zaimplementowana, aby w przypadku pozyskania odpowiedniego modułu, ograniczyć
konieczne do wykonania operacje (zmiana kilku linijek kodu). Przy tworzeniu systemu
37
informatycznego użyto modelu kaskadowego. Był to najbardziej odpowiedni model z
uwagi na charakter budowanego programu. Budowanie funkcjonalnych części aplikacji
JST pozwoliło na łatwe testowanie i sprawdzanie ich poprawności. Pojawiające się
błędy były łatwe do usunięcia, a ich detekcja przebiegała sprawnie, zwłaszcza dzięki
użytemu modelowi programowania.
Jako pierwsza została stworzona główna klasa projektu tj. Jst. Jest ona
podzielona na trzy zasadnicze części. Jedna służy do wizualizacji notowań akcji i par
walutowych. W drugiej są umieszczone dwie tabele, pierwsza zawiera informacje o
koncie użytkownika i jego ewentualnych transakcjach. Druga to zestawienie
zamkniętych pozycji. W trzeciej części znajduje się tabela zawierająca notowania
najpopularniejszych instrumentów finansowych giełdy walutowej oraz grupy
komponentów ułatwiających sterowanie aplikacją. Grupa ta była ciągle rozszerzana o
nowe komponenty wraz z pojawiającymi się wymaganiami dotyczącymi zwłaszcza
potrzeb graczy preferujących manualne zawieranie transakcji. Po zaimplementowaniu
ogólnego interfejsu aplikacji została stworzona klasa Login jako okno umożliwiające
przeprowadzenie podłączenia się do serwera. Na poniższym rysunku przedstawiono
wygląd tej klasy.
Rys. 4.1. Logowanie do serwera
Wszystkie pola są wypełnione domyślnymi wartościami, a dokładniej rzecz ujmując są
to parametry ostatnio zalogowanego użytkownika. Jak widać na rysunku, jest
38
możliwość także wylogowania się, czyli rozłączenia z serwerem. W obu przypadkach
działań dane są pobierane z pól tekstowych i przekazywane funkcjom z rodziny API.
Dzięki obsłudze zdarzeń przechwytujących wiadomości płynące do i z serwera możemy
śledzić przepływ komunikatów dotyczących ewentualnych błędów podczas tych
operacji. Zostały podjęte specjalne środki zabezpieczające niepowodzenia we wszelkich
działaniach prowadzonych przez użytkowników aplikacji, i tak w przypadku logowania,
podczas nieudanego połączenia się do serwera, następuje ponowne jego nawiązywanie.
Jeżeli operacja się nie powiedzie, działanie zostaje przerwane po piątej próbie.
Mając możliwość podłączenia się do serwera, można było zbudować klasy
pozwalające na wykonywanie pierwszych operacji na instrumentach. Wcześniej jednak
została stworzona tabela prezentująca notowania popularnych par walutowych. Na
rysunku poniżej mamy przedstawiony widok tego interfejsu.
Rys. 4.2. Ceny Bid i Ask wybranych instrumentów.
Umieszczenie tych informacji w tabeli pozwala na badanie rynku
walutowego. Możemy obserwować zmieniające się ceny kilku instrumentów
finansowych oraz przekonać się o ich sile i znaczeniu na arenie międzynarodowej. Jak
widać na powyższym rysunku istnieją istotne różnice pomiędzy spread’ami
poszczególnych walut, czyli wielkościami jakie powstają po odjęciu ceny Ask od ceny
Bid. Jest to tak zwana opłata brokerska i jej wartość jest tym większa im jedna waluta z
pary jest silniejsza od drugiej. Siłą w tym przypadku może być sytuacja ekonomiczna
czy poziom rozwoju gospodarczego kraju. I tak w przypadku pary EUR/USD opłata ta
wynosi 0,0003 od transakcji, a w parze EUR/PLN sięga 0,0140 (informacja dotycząca
39
pary EUR/PLN została zaczerpnięta z polskiej platformy X-Trader 4 XTB, gdyż na
serwerze, z którego aplikacja JSP pobiera wszelkie dane, ta para walutowa nie jest
uwzględniona). Jest to wielkość, na którą należy zwracać uwagę podczas wybierania
rodzaju instrumentu, na którym będziemy chcieli podjąć grę. Ceny Bid i Ask są na
bieżąco aktualizowane dzięki obsłudze zdarzenia OnInstumentChange() a tabela jako
komponent został wzbogacony o obsługę zdarzenia polegającą na tym, że po kliknięciu
na wybrany instrument finansowy (wiersz tabeli), pojawia się automatycznie okno
(obiekt klasy Transaction) i możemy wówczas przeprowadzić dowolną transakcję na tej
parze (rys. 4.3).
Rys. 4.3. Okno transakcji.
Mamy tu możliwość wybrania wielkości transakcji oraz ustawienia
zabezpieczeń transakcji w momencie jej zawierania. Do zawarcia transakcji
potrzebujemy jeszcze nazwy pary oraz określenia rodzaju przedsięwzięcia. Jeśli
zajmiemy pozycję długą (kupno), wówczas automatycznie zlenienie zostanie zawarte
po cenie Ask, natomiast w przypadku pozycji krótkiej (sprzedaż) – po cenie Bid.
Ponadto ten sam interfejs pozwala na zamykanie transakcji już otwartych i tu też
podajemy jedynie identyfikator transakcji przeznaczonej do zamknięcia i oczekujemy
na potwierdzenie ze strony serwera.
Wszelkie zawarte transakcje, te zamknięte i bieżące oraz informacje o
koncie użytkownika, są wyświetlane w dwóch tabelach umieszczonych na komponencie
z biblioteki javax.swing JTabbedPane, który umożliwia przełączanie się pomiędzy nimi.
40
Wszelkie zmieniające się informacje dotyczące pozycji lub konta gracza są
aktualizowane
przy
pomocy
obsługi
zdarzeń
OnAccountChange()
oraz
OnPositionChange().
Rys. 4.4. Dane o koncie użytkownika: a) zawarte transakcje i ogólny bilans,
b) historia zleceń.
Z uwagi na potrzeby zmiany zabezpieczeń transakcji została stworzona
kolejna klasa realizująca takie wymagania – ModifyOrder. Na poniższym rysunku
możemy zobaczyć, że poza możliwością modyfikowania zleceń zabezpieczających
istnieje również opcja usunięcia tego zlecenia.
a)
b)
41
Rys. 4.5. Ustawianie i usuwanie zabezpieczeń transakcji.
Klasa Indicators, to okno pozwalające na wybór odpowiednich parametrów
do wskaźników analizy technicznej. Jak widać na rysunku poniżej, mamy możliwość
wyboru dwóch kolorów, związanych z danym wskaźnikiem oraz okresu, czyli pewnego
rodzaju przedziału, z którego będą wyliczane wartości. Ten sam interfejs służy również
do zmiany ich właściwości, wykorzystywane jest wówczas pole wyboru Which
indicator, które pozwala zastosować zmiany do wybranego wskaźnika.
Rys. 4.5. Wprowadzanie parametrów wskaźników
Następnie w celu umożliwienia wizualizacji wskaźników oraz notowań
walut czy akcji została zaimplementowana klasa Chart. Wykresy są nanoszone na
komponent BufferedImage, który jest umieszczony w specjalnym widoku JScrollPane,
42
dzięki czemu duże wymiary rysunku mogą być oglądane bez problemu z użyciem
suwaków zmieniających okno widoku.
Jak widać na rysunku 4.6 wykres daje użytkownikowi bardzo wiele informacji o
ruchach cenowych każdego instrumentu w dowolnych przedziałach czasowych. Są
oznaczone godziny notowań oraz wartości zarówno samych par jak i wskaźników.
Zmiana instrumentu giełdowego powoduje automatyczne przeliczenie wskaźników.
Użycie komponentu BufferedImage znacznie przyspieszyło działanie aplikacji, przez
ograniczenie odświeżania i przerysowywania wykresów wchodzących w skład klasy
Chart.
Rys. 4.6. Wizualizacja notowania wybranego instrumentu oraz kilku
wskaźników analizy technicznej.
Dla szybszego dostępu do podstawowych właściwości wykresu został stworzony
specjalny komponent JPopupMenu, dzięki któremu użytkownik klikając na okno
wykresu prawym przyciskiem myszy może szybko dodać nowy wskaźnik, zmienić
skalę, zapisać notowanie do pliku wszystko to ma wpływ na to, że gracz ma szersze
pole działania jeżeli chodzi o analizę formacji cenowych oraz trendów. Jednym z tych
pól jest Save, taka sama opcja jest również dostępna w menu głównym programu, a
dokładnie w zakładce File. Jest tam również opcja Open. Rozszerzenie funkcjonalności
43
aplikacji o powyższe metody (zapis do pliku i odczyt z pliku), pozwalają na analizę
historii notowań dowolnych instrumentów finansowych w przypadkach kiedy nie
można nawiązać połączenia z serwerem, bądź też w czasie kiedy handel na rynku
walutowym jest wstrzymany (okres od 24:00 w piątek do 24:00 w niedzielę). W tym
czasie użytkownik może się zalogować na swoje konto, sprawdzić jego stan, lecz nie
może pobierać notowań kursów i zawierać oczywiście transakcji. Analiza formacji i
trendów na danych historycznych może posłużyć jako przygotowanie do wejścia na
rynek wraz z rozpoczęciem się handlu. Na rysunku 4.7 mamy widok komponentu za
pośrednictwem, którego możemy zapisywać i odczytywać notowania par walutowych.
Rys. 4.7. Otwieranie historii notowania z pliku.
Użytym typem z pakietu Swinga jest JFileChooser, który jednocześnie umożliwia
zapisywanie i otwieranie dowolnych plików. W celu uniknięcia wczytania plików o
niepoprawnym formacie, jest przeprowadzane sprawdzanie rozszerzeń (filtrowanie).
Przy zapisywaniu plików rozszerzenie dodawane jest automatycznie. Jak było już
wielokrotnie wcześniej wspominane aplikacja umożliwia również wizualizację kursów
akcji. Pliki z danymi o notowaniach akcji mają rozszerzenie .mst i są pobierane ze
strony http://bossa.pl/notowania/daneatech/metastock/ . Takie rozwiązanie było
konieczne ze względu na to, że w tej chwili nie ma darmowych wersji funkcji z rodziny
44
API, które umożliwiłyby ciągły dostęp do najnowszych danych, jak i pozwoliły by na
zawieranie transakcji na giełdzie papierów wartościowych.
Następnie została stworzona klasa Report, której zadaniem jest wyznaczanie
krzywej odzwierciedlającej wahania wartości kapitału. Zmiany środków pieniężnych na
koncie użytkownika są zebrane w tabeli umieszczonej poniżej modułu z wykresem, ale
ich wizualizacja umożliwia ich lepszą analizę. Poza tym, klasa może również
wizualizować osiągnięcia systemów transakcyjnych, które są testowane w klasie
ASystem, a ich wyniki są przekazywane do zobrazowania.
Rys. 4.8. Wykres przedstawiający zmianę wartości kapitału bieżącego systemu
transakcyjnego (historia zamkniętych pozycji).
Klasa ASystem (AutomaticSystem), jest interfejsem pozwalającym na
testowanie, optymalizację, uruchamianie i zatrzymywanie automatycznych systemów
transakcyjnych.
45
Rys. 4.9. Interfejs do automatycznych systemów transakcyjnych.
Jak widać na rysunku 4.9 użytkownik ma do wyboru dużo opcji związanych z
testowaniem i optymalizacją systemów zaimplementowanych oraz tych, które może
sam zbudować. W obecnej chwili są zaimplementowane dwa systemy do gry. Obydwa
są oparte o wskaźniki, ich metoda podejmowania decyzji transakcyjnych zostanie
opisana w kolejnym rozdziale. Podczas testowania, można wybrać instrument giełdowe
na których doświadczenie zostanie przeprowadzone, wielkości transakcji oraz rodzaju
dywersyfikacji czasowej. Cztery pola tekstowe na dole interfejsu to miejsca na
parametry dla testowanych czy uruchamianych systemów. Jeżeli są puste podczas
testowania są wykorzystywane parametry domyśle, natomiast wpisanie wartości
powoduje
automatyczne
ich
użycie
w
przeprowadzanym
doświadczeniu.
Optymalizacja, z kolei opiera się na wielokrotnym testowaniu z odpowiednim doborem
tych parametrów. Wartości parametrów są zapamiętywane w specjalnej klasie Settings i
wyświetlone ostatecznie te, przy których wyniki są najlepsze. Sam bilans oraz ilość
operacji nie jest pokazywany. W sytuacji gdy pojawią się już najlepsze zmienne dla
naszego modelu transakcyjnego, powinniśmy je przetestować, dzięki temu
automatycznie dokonana zostanie wizualizacja oraz w lewym górnym rogu obiektu
klasy Report ukaże się liczba transakcji. Podczas uruchamiania systemów, należy
wpisywać parametry do odpowiednich pól tekstowych tj. komponentów JTextField
(najlepiej tych zoptymalizowanych), w przeciwnym razie zostanie zgłoszony błąd
o niepoprawności formatu danych. Dla zaimplementowanych systemów, w momencie
zgłoszenia tego wyjątku parametry te są ustawiane na wartości domyślne (przy budowie
nowych systemów należy pamiętać o tym, aby zdefiniować własne ich wartości).
46
Na
rysunku
4.10
mamy
przedstawiony
schemat
algorytmu
odzwierciedlającego kroki jakie podejmuje 2 MOV System, kiedy zostaje uruchomiony
za pomocą interfejsu opartego o komponenty użyte przy budowie klasy ASystem.
Znacznik „A” naniesiony na algorytm określa miejsce, w którym klasa RunSystem
przejmuje sterowanie i przelicza odpowiednie wskaźniki. Sygnały są generowane z
funkcji OnInstrumentChange(), która rejestruje zmiany wszystkich instrumentów i jeśli
nastąpiła zmiana pary walutowej, która jest przedmiotem analizy systemu
transakcyjnego, zostaje wysłane powiadomienie o zajściu tego zdarzenia.
START
optymalizowanie
Wprowadź parametry:
p1, p2, p3, p4
N
Wprowadz: system,
interval, lot, instrument
Ilość transakcji == 0
T
T
N
avg1 > avg2
buy()
T
N
sell()
czy buy
avg1 > avg2
T
T
sell()
N
avg1 < avg2
T
A
getHistory()
movingAvg(p1)
movingAvg(p2)
47
Rys. 4.10. Schemat blokowy 2 MOV System.
Rys. 4.11. Java System Trading – wygląd ogólny
49
Finalna postać aplikacji może ulec jeszcze zmianom (rozszerzenia przez
użytkowników), ale interfejs jako narzędzie komunikacji z użytkownikiem nie powinien
się zmienić. Na chwilę obecną wygląd głównego okna komunikacji jest przedstawiony
na rysunku 4.11.
4.4. Główne problemy implementacyjne
Aby zbudowane systemy działały poprawnie, podczas ich implementacji
należy zwrócić szczególną uwagę na kilka detali związanych z budową rynku
walutowego, które mogą negatywnie wpływać na funkcjonowanie systemu
informatycznego do automatycznego podejmowania decyzji transakcyjnych. Na
rysunku poniżej mamy przedstawiony fragment notowania.
Rys. 4.12.
Jest to przykład sytuacji, w której może dojść do dwóch lub więcej zupełnie nie
potrzebnych transakcji. Kurs notowania znajduje się w trendzie rosnącym, ale następują
sytuacje , w których dochodzi do zbliżenia się do siebie wykresu dwóch średnich
kroczących. W powiększeniu widać jednak, że nie dochodzi do bezpośredniego
przecięcia. Jednak ze względu na charakter reprezentacji danych dotyczących kursów
50
walut dochodzi do utraty pewnych informacji. Na rysunku 4.13 jest przedstawiony inny
aspekt tego samego problemu, a konkretnie moment zamykania pozycji.
Rys. 4.13.
Również i w tym przypadku nie widać pewnych istotnych informacji „zakodowanych”
w świecach czy barach. Opisywana w tych dwu przypadkach kłopotliwa sytuacja
wynika z tego, że ostateczny kształt (przebieg) średnich wyliczany jest zazwyczaj na
podstawie wartości „close” (najbardziej reprezentatywnej), czyli ostatniego notowania
instrumentu odnoszącego się do danego baru. Dla danych historycznych nie ma to
większego znaczenia, jednak w przypadku bieżącego analizowania zachowania się tych
wskaźników należy liczyć się ze zjawiskiem, że wzajemne położenie wykresów się za
każdym razem, gdy tylko zmieni się notowanie pary walutowej. Oczywiście sytuacja
nie zawsze jest kłopotliwa. Ma ona największe znaczenie w dwóch przedstawionych
powyżej sytuacjach – zbliżeń krzywych oraz przecięć. Dlatego też, analizując dane
uzyskane z testowania systemu opartego na średnich kroczących, czy też innych
rozwiązań - należy się zastanowić na jakie koszty możemy być narażeni w wyniku
ukrytych informacji. Istnieją jednak liczne rozwiązania zapobiegające lub ułatwiające
podejmowanie odpowiednich decyzji przez graczy lub systemy transakcyjne.
Na kolejnym rysunku 4.14 mamy przedstawione dwa fragmenty notowań.
Obydwa reprezentują ten sam przedział czasowy, ale są przedstawione w innych
dywersyfikacjach czasowych. W przypadku a), jest to fragment notowania pary
walutowej EURJPY (30.03.06) i jest to wykres godzinowy (1 H). Jak można łatwo
51
policzyć fragment ten składa się z ok. 16 barów. W przypadku b), ten sam okres
czasowy jest zdywersyfikowany przedziałem dziesięciominutowym (10 MIN), dlatego
też każdemu barowi z przypadku a) odpowiada 6 w przypadku drugim czyli b) (1h –
60 min). Przy takiej reprezentacji łatwiej jest zauważyć, że notowania ciągle podlegają
wahaniom okresowym. Dla użytkowników preferujących manualne wykorzystanie
funkcjonalności platformy JST, możliwość przedstawiania w mniejszych przedziałach
czasowych danych o notowaniach może być doskonałym narzędziem do wczesnego
rozpoznawania trendów oraz zmiany ich kierunków. W przypadku systemów
transakcyjnych należy podjąć zdecydowanie inne środki zaradcze.
Rys. 4.14.
Do najprostszych zaliczyć można budowanie wskaźników, opartych na wartościach nie
podlegających wahaniom np. wartości „high” i „low”, jeżeli wykorzystujemy
informacje niesione przez bary lub „volumenu”, czyli ilości inwestycji (największe
zastosowanie na rynku papierów wartościowych).
52
5. Użytkowanie, testowanie, optymalizacja oraz ocena uzyskanych wyników
Użytkowanie platformy JST, biorąc pod uwagę manualny tryb gry, jest
bardzo proste. Wykorzystanie zaimplementowanych systemów transakcyjnych, też nie
nastręcza wielu problemów, ponieważ ogranicza się do paru kliknięć na odpowiednich
okienkach. Samo testowanie czy optymalizacja tych systemów, również są operacjami
łatwymi do przeprowadzenia, pozostaje jedynie kwestia dotycząca interpretacji
uzyskanych wyników (w celu przeprowadzenia tych operacji konieczne jest
zalogowanie się do serwera, aby móc pobierać dane do tych doświadczeń). Jak już było
wspomniane w rozdziale poprzednim, wizualizacja wyników testów pozwala na
łatwiejsze ich analizowanie. Na rysunku 5.1 mamy dwa wyniki testów. Działanie obu
systemów jest zależne od wartości wskaźników analizy technicznej. Pierwszy, bardzo
prosty system, swoje decyzje transakcyjne podejmuje na podstawie zachowania się
dwóch średnich kroczących, których okresy domyślnie ustawione są na 16 i 8. Drugi
system opiera się o wskaźnik SovietStochSgl, który jest wyznaczany na podstawie
analizy przedziałowej z zastosowaniem logiki rozmytej. Jego wykres składa się
z dwóch linii przecinających się wzajemnie – podobnie jak dwie średnie kroczące, i tak
samo jak w ich przypadku momentami decyzyjnymi są właśnie te punkty przecięcia.
a)
b)
53
Rys. 5.1. Krzywe wartości kapitału dla dwóch systemów
a) StochSgl System, b) 2 MOV System
Testowanie było przeprowadzone w jednakowych warunkach tj. na tym samym
instrumencie GBPUSD, przy dywersyfikacji czasowej 2H (jeden bar reprezentuje
zmiany notowania w ciągu dwóch godzin), natomiast zakres notowania obejmował
1000 ostatnich barów. Jak widać oba systemy przyniosły zyski, ale znacznie lepsze
osiągnięcia miał pierwszy. Kolejnym istotnym elementem różniącym, jest charakter
osiągania zysków. Jak widać pierwszy system sukcesywnie pomnaża kapitał i rzadko
podejmuje błędne decyzje. Drugi natomiast ma więcej błędnych operacji i są one
bardziej dotkliwsze dla wartości kapitału niż w przypadku pierwszego. Tą wadę
rekompensują za to duże zyski z trafnych transakcji. Istnieje jeszcze jeden aspekt
bardzo istotny w analizie działania tych mechanizmów transakcyjnych, a mianowicie
ilość operacji. StochSgl System swoją końcową wartość kapitału osiągnął po 42
operacjach, natomiast 2 MOV System po 78. Jak już wcześniej była mowa, każda
operacja wiąże się z opłatą brokerską, więc użytkownik mając do wyboru te dwa
systemy, będzie raczej skłonny do użycia tego pierwszego. Abstrahując jednak od
wartości kapitału jaką uzyskały poszczególne testy oraz od ilości operacji, a skupiając
się jedynie na kształcie krzywej odzwierciedlającej drogę naszego kapitału do
osiągnięcia ostatecznej wartości, trzeba przypomnieć o aspekcie psychologicznym w
grze na rynku walutowym. Jak już było wspomniane w rozdziale pierwszym
54
zastosowanie informatycznych rozwiązań w celu wyeliminowania stresu związanego z
inwestowaniem pieniędzy przez samego gracza, jest zrozumiałe i wyjaśnia chęć
budowania ciągle nowych rozwiązań zapewniających realizację metod transakcyjnych
graczy. Mając jednak przed sobą dwa systemy osiągające jednakowe zyski, ale różniące
się tym, że jeden systematycznie powiększa kapitał nieznacznie odchylając się od linii
aproksymującej, a drugi dochodzi do tego samego końcowego bilansu, ale wahania
kapitału są duże i znacznie odbiegają od linii aproksymacji, użytkownik wybierze ten
mniej agresywny, który mniej ryzykuje i charakteryzuje się mniejszym obsunięciem
kapitału przypadającym na jedną transakcję.
Istotnym elementem w budowaniu i określaniu skuteczności jego działania
jest optymalizacja. Jak już wspominałem, polega ona na optymalnym dobieraniu
parametrów używanych w decyzjach transakcyjnych. Oczywiście użytkownik może
samodzielnie dojść do najbardziej korzystnych wartości tych zmiennych za pomocą
kilkukrotnego testowania i podawania za każdym razem nowych parametrów, aż
wyniki, które uzyska będą satysfakcjonujące. Od razu widać pewną niedoskonałość
takiej metody, ponieważ zawsze mogą być jeszcze lepsze wyniki. Uruchamiając
wbudowany mechanizm optymalizacji można być pewnym, że testy zostały
przeprowadzone wielokrotnie i uzyskane parametry będą tymi, które gwarantują
maksymalne zyski. Trzeba jednak pogodzić się z czasochłonnym procesem sprawdzania
nowych kombinacji zmiennych wchodzących w skład optymalizowanego systemu.
Na rysunku 5.2 mamy dwa wyniki testowania. Pierwszy, to wynik jaki został uzyskany
przy standardowych ustawieniach parametrów, drugi to wynik otrzymany po
zoptymalizowaniu.
a)
55
b)
Rys. 5.2. Testy systemu 2 MOV: a) ustawienia standardowe, b) ustawienia
zoptymalizowane.
Przy ustawieniach 16 i 8, czyli standardowych parametrach systemu opierającego się o
wskazania średnich ruchomych o podanych okresach, uzyskano ok. 16% przy
pięćdziesięciu dwóch transakcjach. Optymalizacja wskazała na parametry 16 i 4 jako
najodpowiedniejsze. Przy tych ustawieniach zysk był większy i wyniósł ok. 41% przy
56
62 operacjach rynkowych. Jak widać, poza osiągnięciem większych zysków ulepszony
system wykonał o 12 transakcji więcej. W tym wypadku nie jest to tak bardzo istotna
różnica i śmiało można stwierdzić, że wynik jest zadowalający. Wynik ten nie wpłynie
znacząco na ostateczny bilans zysków i strat. Na rysunku przedstawiającym te dwa
przypadki widzimy dzięki czemu udało się poprawić wyniki. W przykładzie a) krzywa
obrazująca przyrost kapitału charakteryzuje się okresami szybkiego wzrostu i okresami
przestoju, w których bilans pozostaje bez zmian lub nawet traci. Stagnacja ta jest
spowodowana trendem horyzontalnym, podczas którego w ogóle system nie powinien
grać. Wersja zoptymalizowana nie ma już tych wad. Wyznaczone w wyniku
optymalizacji nowe wartości średnich – 16 i 4, pozwoliły na ograniczenie ilości
transakcji, zwłaszcza w momencie trwania trendów horyzontalnych. Na poniższym
rysunku mamy przedstawiony fragment notowania wraz z dwoma wskaźnikami.
Rys. 5.3. Fragment notowania pozostający w trendzie horyzontalnym
Wskaźniki te to średnie kroczące. W zaznaczonym przedziale przecinają się one
wzajemnie ok. 10 razy. 2 MOV System zbudowany na ich podstawie zawrze więc w
tych okresie, również dziesięć operacji. Nietrudno zatem zauważyć, że tylko jedna tak
naprawdę może przynieść pewne korzyści. Jest bardzo istotną sprawą, aby przy
budowie własnych systemów pamiętać o tym, aby poświęcić dużo uwagi na
wyeliminowanie lub chociaż ograniczenie gry podczas tych niekorzystnych okresów na
rynku. Możliwe jest również zatrzymywanie uruchomionych systemów, jeśli gracz sam
stwierdzi taką potrzebę lub gdy zauważy że nastąpiła krótsza czy dłuższa stagnacja.
57
O ile testowanie nie powinno przynieść traderowi żadnych problemów, o
tyle w przypadku uruchomienia wybranego modelu transakcyjnego, musi on pamiętać o
kilku podstawowych zasadach. Przede wszystkim, wizualizacja notowania instrumentu
finansowego powinna odpowiadać instrumentowi, na którym uczestnik rynku
zdecydował się zastosować system. Pozwoli to na szybkie reagowanie na zmieniające
się zachowania rynku, które w skrajnych przypadkach mogą prowadzić do obniżenia
funkcjonalności metody zastosowanej w rozwiązaniu automatycznym albo nawet do
utraty większości kapitału. Poza tym należy również pamiętać o nanoszeniu
odpowiednich wskaźników analizy technicznej, które uruchomiony system
wykorzystuje, to także wpłynie szybsze wychwycenie ewentualnych błędów
merytorycznych czy implementacyjnych. Przeprowadzenie testów nigdy nie daje
stuprocentowej pewności, że po wprowadzeniu go w życie wyniki nadal będą tak
zadowalające jak w czasie przeprowadzania doświadczeń na danych historycznych,
dlatego aplikacja jest tak napisana, aby przyszli użytkownicy mogli z powodzeniem
wykrywać wszelkie usterki. Umieszczone są specjalne bloki przechwytujące możliwe
wyjątki, które mogą się pojawić, np. podczas wykonywania operacji na niewłaściwych
danych. Jest możliwość wizualizacji wszelkich wskaźników, które wykorzystują
zaimplementowane systemy i zaleca się użytkownikom, zwłaszcza tym, którzy myślą
o rozbudowie aplikacji o nowe systemy do automatycznego podejmowania decyzji, aby
wszelkie wykorzystywane w nich wskaźniki również zaimplementować w klasie Chart,
w celu możliwości ich wizualizacji.
6. Wnioski
Celem pracy było zaprojektowanie i zaimplementowanie platformy,
realizującej transakcje na rynkach walutowych. Dzięki udostępnieniu modułu ze
zbiorem odpowiednich funkcji, możliwe było zaprogramowanie wszelkich funkcji
zezwalających na wykonywanie dowolnych operacji na koncie gracza – tradera.
Charakter dostępu do tego modułu (poprzez bibliotekę dynamiczną) pozwolił na
oddzielenie funkcjonalności aplikacji oraz interfejsu od narzędzi oferowanych przez
firmę VisualTrade. Ewentualna zmiana biblioteki (lub dodanie nowych funkcji do
istniejącej) nie powinna spowodować trudności w zaadoptowaniu jej do potrzeb
systemu informatycznego.
58
Główne zadanie polegało na zaprojektowaniu interfejsu dla przyszłych
użytkowników Java System Trading. Była to jednocześnie okazja do zaznajomienia się
z wzorcami projektowymi (Design Patterns) – czyli zespołem zasad jakie każdy
projektant aplikacji użytkowych powinien stosować. Nabycie tej umiejętności jest
niezwykle ważne, gdyż jest to nieodłączny aspekt programowania we wszelkiego
rodzaju firmach informatycznych.
Bardzo ważnym elementem aplikacji, jest możliwość wdrażania
automatycznych systemów transakcyjnych. Interfejs umożliwia testowanie oraz ich
optymalizację. Dzięki tym możliwościom możliwe jest również zbadanie rynku
dowolnych instrumentów. Przeprowadzenie testów na systemie 2 MOV System
umożliwia bowiem, tak naprawdę sprawdzenie kierunków trendów. Jak wykazują
badania, około 70 % graczy używa zestawu dwóch średnich kroczących do analizy
sytuacji rynkowej
14
. Tak prosty system może okazać się dobrym narzędziem do
poznania charakterystyki rynku zanim podejmiemy prawdziwą grę.
Ponadto użytkownicy platformy, którym podstawowa wiedza z podstaw
programowania języka Java nie jest obca mogą dowolnie rozszerzać funkcjonalność
produktu, zwłaszcza o nowe mechanizmy automatyzujące podejmowanie decyzji oraz
wskaźników. Wiele aplikacji oferowanych na rynku przez różne firmy, również posiada
takie możliwości, ale jest to zdecydowana mniejszość. Edytory umożliwiające te
platformy są jednak bardzo ograniczone: brak możliwości programowania obiektowego,
mały zestaw wbudowanych funkcji. JST, jako open source umożliwia skorzystanie
z bogatego zestawu funkcji i komponentów jednego z najbardziej popularnych języków
programowania.
14
Piotr Surdel – ”Wprowadzenie ..”
59
Dodatek A
Instrukcja postępowania przy wzbogacaniu kodu o nowe wskaźniki lub systemy
transakcyjne.
Osobom zainteresowanym rozbudową kodu źródłowego zapewnie nie
będzie trudno zapoznać się z mechanizmem w jaki sposób organizowana jest
komunikacja aplikacji z serwerem oraz jej poszczególnych części pomiędzy sobą.
Ponadto w plikach, w których ewentualna rozbudowa może mieć miejsce zostały
umieszczone specjalne znaczniki ułatwiające rozszerzenie funkcjonalności platformy.
Dodanie nowych wskaźników analizy technicznej:
1. W pliku odpowiedzialnym za rysowanie wykresów, tj. Chart.java:
a. Dodać klasę opisującą dane nowego wskaźnika,
b. Dodać metodę wyznaczającą dane dla wskaźnika,
c. W metodzie computeIndicators(String name,Color c1, Color c2, int
period) – dodać warunek sprawdzający czy nowym wskaźnikiem
dodawanym do wykresu jest definiowany przez użytkownika (podobnie
w metodzie computeIndicators()),
d. W metodzie drawChart() umieścić kod odpowiedzialny za rysowanie – w
zależności od charakteru nowego wskaźnika może on być umieszczony
w sekcji gdzie znajdują się dane notowań lub też pod nią.
2. W głównym pliku aplikacji Jst.java:
a. W metodzie initComponents(boolean closeOnExit) dodać nazwę
wyświetlaną dla naszego wskaźnika to listy „indicators”
Dodanie nowego automatycznego systemu transakcyjnego:
1. W pliku SystemRun.java:
a. Dodać w metodzie run() w instrukcji switch() przypadek (case)
określający zachowanie się systemu w przypadku wybrania nowego
systemu,
2. W pliku ASystem.java:
a. W konstruktorze klasy dodać nazwę nowego systemu do modelu
reprezentującego dostępne systemy transakcyjne (JComboBox),
60
b. W metodach run(), stop(), test(), optymize() – zdefiniować zachowanie
się nowego systemu,
c. Opcjonalnie zdefiniować dodatkowe metody pozwalające na
podejmowanie transakcji decyzyjnych przez system.
Dodatek B
Ważniejsze funkcje systemu informatycznego.
Funkcja z klasy ASystem przeprowadzająca test wybranego systemu dla
bieżących parametrów – domyślnych bądź ustawionych przez użytkownika – rezultaty
są przekazywane do klasy reprezentującej uzyskane rezultaty w formie graficznej –
Reports.java
public void test()
{
testResult.removeAllElements();
double lotv = Double.parseDouble(((ListItem)lot.getSelectedItem()).getKey());
int nrs = Integer.parseInt(((ListItem)sname.getSelectedItem()).getKey());
int suma = 0;
getHistory();
double close_ost = closeD[20];
boolean buy = true;
boolean sell = true;
int ilosc_op = 0;
String st1 = p1.getText();
String st2 = p2.getText();
double dif = 0.1;
switch(nrs)
{
case 0:
if(st1.equals(""))
{
avg1 = movingAvg(16);
avg2 = movingAvg(8);
}
else
{
try
{
avg1 = movingAvg((int)Double.parseDouble(st1));
avg2 = movingAvg((int)Double.parseDouble(st2));
61
}catch(Exception e)
{System.out.println("Bad format");};
}
int s;
int i;
for(i=20; i<closeD.length; ++i)
{
if(sell)
if(avg1[i] > avg2[i])
{
sell = false;
buy = true;
suma += (closeD[i] - close_ost)*coma;
s = (int)((closeD[i] - close_ost)*coma);
close_ost = closeD[i];
ilosc_op += 1;
testResult.addElement(new Double(s*lotv*10));
}
if(buy)
if(avg1[i] < avg2[i])
{
buy = false;
sell = true;
suma += (close_ost - closeD[i])*coma;
s = (int)((close_ost - closeD[i])*coma);
close_ost = closeD[i];
ilosc_op += 1;
testResult.addElement(new Double(s*lotv*10));
}
}
System.out.println("Zysk w pipsach - "+suma+" Ilosc operacji - "+ilosc_op);
break;
case 1:
//get parameters from p1 .. p4
if(st1.equals(""))
SovietStochSgl(10);
else
{
SovietStochSgl((int)Double.parseDouble(st1));
dif = Double.parseDouble(p2.getText());
}
int s1;
int i1;
for(i1=20; i1<closeD.length; ++i1)
{
62
if(sell)
if(stochSgl_b[i1] - stochSgl_s[i1] > dif)
{
sell = false;
buy = true;
suma += (closeD[i1] - close_ost)*coma;
s1 = (int)((closeD[i1] - close_ost)*coma);
close_ost = closeD[i1];
ilosc_op += 1;
testResult.addElement(new Double(s1*lotv*10));
}
if(buy)
if(stochSgl_s[i1] - stochSgl_b[i1] > dif)
{
buy = false;
sell = true;
suma += (close_ost - closeD[i1])*coma;
s1 = (int)((close_ost - closeD[i1])*coma);
close_ost = closeD[i1];
ilosc_op += 1;
testResult.addElement(new Double(s1*lotv*10));
}
}
System.out.println("Zysk w pipsach - "+suma+" Ilosc operacji - "+ilosc_op);
break;
case 2:
//others systems
break;
case 3:
//others systems
break;
}
double [] tmp1 = new double[testResult.size()+1];
tmp1[0] = 10000;
for(int x=1; x<testResult.size()+1; ++x)
tmp1[x] = tmp1[x-1] + Double.parseDouble(String.valueOf(testResult.elementAt(x-1)));
Jts.getTestResult(tmp1);
}
Kolejna metoda z klasy ASystem. Tworzy obiekt klasy SystemRun, który
przejmuje sterowanie nad zawieraniem transakcji. Obiekt jest inicjalizowany
odpowiednimi parametrami, które pomogą w identyfikacji systemu oraz parametrów z
jakimi ma zostać uruchomiony
63
public void run()
{
///pair
String p = ((ListItem)pair.getSelectedItem()).getKey();
//lot
double l = Double.parseDouble(((ListItem)lot.getSelectedItem()).getKey());
//which system
int nrs = Integer.parseInt(((ListItem)sname.getSelectedItem()).getKey());
//interval
int itv = Integer.parseInt(((ListItem)Interval.getSelectedItem()).getKey());
double pa1=1,pa2=1;
try{
pa1 = Double.parseDouble(p1.getText());
pa2 = Double.parseDouble(p2.getText());
}catch(Exception e){System.out.println("Bad format");
if(nrs == 0)
{
pa2 = 8;
pa1 = 16;
}
if(nrs == 1)
{
pa1 = 10;
pa2 = 0.1;
}};
if(nrs == 0)
wtksys = new SystemRun(p,l,itv,nrs,pa1,pa2,0,0);
if(nrs == 1)
wtksys = new SystemRun(p,l,itv,nrs,pa1,pa2,0,0);
wtksys.run();
}
Metoda klasy ASystem run() – przeprowadzająca rzeczywiste transakcje na
rynku Forex. Funkcja ta powinna zawierać implementacje wszystkich systemów
transakcyjnych.
public void run()
{
int i,err=0;
IPosition pozycja;
if(!lock)
{
lock = true;
System.out.println("Checking dependences");
64
switch(system_id)
{
case 0:
getHistory(30);
avg2 = movingAvg((int)p2); //8
avg1 = movingAvg((int)p1); //16
i = Jts.getApi().GetOpenPositionCount();
if(i == 0)
{
Jts.cond = 1;
if(avg2[avg2.length - 1] > avg1[avg1.length - 1]) //buy
err = Jts.getApi().SendCreateOrder(
account_id,para_id,true,0,false,0,lot,
false,true);
if(avg2[avg2.length - 1] < avg1[avg1.length - 1]) //sell
err = Jts.getApi().SendCreateOrder(
account_id,para_id,true,0,true,0,lot,
false,true);
}
else
{
pozycja = Jts.getApi().GetOpenPositionByIndex(0);
if(pozycja.get_BuySell())
{
if(avg2[avg2.length - 1] > avg1[avg1.length - 1])
//buy
{
Jts.cond = 0;
err = Jts.getApi().SendCreateOrder(
account_id,para_id,true,0,false,0,lot,
false,true);
}
}
else
{
if(avg2[avg2.length -1] < avg1[avg1.length - 1])
/sell
{
Jts.cond = 0;
err = Jts.getApi().SendCreateOrder(
account_id,para_id,true,0,true,0,lot,
false,true);
}
}
}
break;
case 1:
getHistory(30);
65
SovietStochSgl((int)p1);
i = Jts.getApi().GetOpenPositionCount();
if(i == 0)
{
Jts.cond = 1;
if(stochSgl_s[stochSgl_s.length - 1] - stochSgl_b[stochSgl_b.length - 1] > p2) //buy
err = Jts.getApi().SendCreateOrder(
account_id,para_id,true,0,false,0,lot,false,true);
if(stochSgl_b[stochSgl_b.length - 1] - stochSgl_s[stochSgl_s.length - 1] > p2) //sell
err = Jts.getApi().SendCreateOrder(
account_id,para_id,true,0,true,0,lot,false,true);
}
else
{
pozycja = Jts.getApi().GetOpenPositionByIndex(0);
if(pozycja.get_BuySell())
{
if(stochSgl_s[stochSgl_s.length - 1] - stochSgl_b
[stochSgl_b.length - 1] > p2) //buy
{
Jts.cond = 0;
err = Jts.getApi().SendCreateOrder(
account_id,para_id,true,0,
false,0,lot,false,true);
}
}
else
{
if(stochSgl_b[stochSgl_b.length - 1] - stochSgl_s
[stochSgl_s.length - 1] > p2) //sell
{
Jts.cond = 0;
err = Jts.getApi().SendCreateOrder(
account_id,para_id,true,0,
true,0,lot,false,true);
}
}
}
break;
case 2:
///others systems
break;
case 3:
///others systems
break;
}
lock = false;
}
}
66
Metoda getHistory() z głównej klasy projektu zajmuje się ściąganiem
notowań instrumentów z serwera oraz przekształca format ich reprezentacji na
łatwiejszy do graficznej wizualizacji. Dane z postaci XML, są konwertowane do tablic,
które są przekazywane do klasy Chart.
public void getHistory()
{
int interval = Integer.parseInt(((ListItem)Interval.getSelectedItem()).getKey());
int count = Integer.parseInt(((ListItem)Count.getSelectedItem()).getKey());
int wal = Integer.parseInt(((ListItem)Pair.getSelectedItem()).getKey());
IInstrument para = api.GetInstrumentByIndex(wal);
hist = para.GetHistory(interval,true,count);
if(para.get_points() == 4)
chart.coma = 10000;
if(para.get_points() == 2)
chart.coma = 100;
try
{
SAXBuilder builder = new SAXBuilder(false);
Document document = builder.build(new StringReader(hist));
java.util.List candles = document.getRootElement().getChildren();
openData = new double[candles.size()];
lowData = new double[candles.size()];
highData = new double[candles.size()];
closeData= new double[candles.size()];
volData = new double[candles.size()];
timeStamps = new Date[candles.size()];
String t,o,l,c,h;
Calendar cal = Calendar.getInstance();
int i=0;
for (Iterator iter = candles.iterator(); iter.hasNext();i++)
{
Element candle = (Element) iter.next();
t = candle.getAttributeValue("endtime");
o = candle.getAttributeValue("open");
o = o.replace(',','.');
l = candle.getAttributeValue("min");
l = l.replace(',','.');
h = candle.getAttributeValue("max");
h = h.replace(',','.');
c = candle.getAttributeValue("last");
c = c.replace(',','.');
67
openData[i] = Double.parseDouble(o);
lowData[i] = Double.parseDouble(l);
highData[i] = Double.parseDouble(h);
closeData[i]= Double.parseDouble(c);
volData[i]= Double.parseDouble(candle.getAttributeValue("vol"));
cal.set(Integer.parseInt(t.substring(0,4))+1900,
Integer.parseInt(t.substring(5,7))-
1,Integer.parseInt(t.substring(8,10)),Integer.parseIn
t(t.substring(11,13)),Integer.parseInt(t.substring(14
,16)));
timeStamps[i] = cal.getTime();
}
} catch (java.io.IOException e){
} catch (org.jdom.JDOMException e){
}
timeStampsZ = timeStamps;
openDataZ = openData;
closeDataZ = closeData;
lowDataZ = lowData;
highDataZ = highData;
volDataZ = volData;
chart.update(timeStampsZ,highDataZ,lowDataZ,openDataZ,closeDataZ,highDataZ.length);
}
Bibliografia
[1] „Makro i Mikro Ekonomia – Podstawowe problemy” – Rozdział 22,
[2] Grzegorz Białek – „Podstawy zarządzania pieniądzem w Banku Komercyjnym” -
Warszawa 1994,
[3] Peter Schaal – „Pieniądz i polityka pieniężna” – PWE 1996 Warszawa,
[4] Zenon Komar – „Sztuka spekulacji” – PRET S.A. Warszawa 1993,
[5] Koppel R., Abell H. – „Wewnętrzna gra. Kształtowanie psychiki gracza
giełdowego”., WIG-PRESS, Warszawa 1997,
[6] Plummert T., „Psychologia rynków finansowych u źródeł analizy technicznej”
WIG-PRESS, Warszawa 1993,
[7] John J. Murphy – „Analiza techniczna rynków finansowych (
Technical Analysis of the
Financial Markets
)” – WIG-PRESS Warszawa 1999,
[8] Charles LeBeau, Dawis W. Lukas – „Komputerowa Analiza Rynków
Terminowych” – WIG-PRESS Warszawa 1998,
[9] Marcin Kaczmarski, Michał Gronowski, Pawel Sewastianow, "Automatyczne
68
systemy transakcyjne, od teorii do praktyki"
[10] Piotr Surdel – „Wprowadzenie do gry na Giełdzie Walutowej „Forex”” –
http://ebooki4u.boo.pl.
[11] http://www.sun.com
[12] http://www.vtsystems.com
[13] http://bossa.pl/notowania/daneatech/metastock/