Projekt Giełdowych Analiz Dodawacz (GAD) będzie aplikacją umożliwiającą gromadzenie rekomendacji danych giełdowych oraz ich wymianę pomiędzy użytkownikami serwisu. Program będzie udostępniany klientom poprzez interfejs www.
Produkt zainteresować może w szczególności osoby mające więcej wspólnego z analizą danych giełdowych, np. czynnych graczy. Dodatkowo, będzie on przydatnym narzędziem dla tych, którzy zaczynają swoją przygodę z tym tematem – pozwoli zapoznać się z mechanizmami rządzącymi giełdą oraz umożliwi sprawdzenie się w roli potencjalnego inwestora.
Użytkownicy aplikacji korzystać będą z fikcyjnej waluty, której środki pozyskiwane będą w konsekwencji udanych (trafnych) przewidywań zachowań rynku giełdowego. W określonych warunkach, zgromadzone środki podlegać będą wymianie na prawdziwe pieniądze. Dla doświadczonych inwestorów stać więc może źródłem pozyskiwania realnych funduszy, natomiast dla pozostałych – serwisem pomocnym przy alokowaniu pieniędzy w akcje konkretnych spółek.
Możemy wyróżnić szereg serwisów internetowych udostępniających rekomendacje giełdowe zarówno płatnie jak i darmowo. Serwisy darmowe działają zwykle z opóźnieniem – nawet kilkudniowym – co bardzo często ogranicza możliwości wykorzystania rekomendacji. Serwisy płatne, zwykle opierające się na stałym abonamencie, zwykle udostępniają wytworzone przez siebie rekomendacje wszystkim abonentom w tym samym momencie czasu – na stronie lub drogą e-mailową.
Metod prognozowania jest bardzo wiele, niektóre opierają się na różnych wskaźnikach giełdowych i ich porównywaniu, inne na skomplikowanych algorytmach statystycznych, biorących pod uwagę dane krótko lub długookresowe, jednak nie spotkaliśmy się z serwisem działającym na bazie sieci neuronowej.
Warto również wspomnieć o istniejących programach mających wspomagać granie na giełdzie. Tu również można wyróżnić darmowe i płatne wersje, jednak większość z nich oferuje jedynie swego rodzaju segregację danych i różnego typu wykresy statystyczne, które mogą stanowić podstawę do rekomendacji.
Wszystkie rozwiązania skierowane są pod graczy giełdowych o różnym stopniu zaawansowania.
Nasze rozwiązanie jest innowacyjne na skalę kraju. Główną zaletą będzie możliwość interaktywnego tworzenia i dobierania danych do sieci neuronowej, co nie zostało wprowadzone na rynek przez nikogo. Kolejnym atutem jest łączenie w sobie możliwości serwisu płatnego jak i darmowego, pozwalającego tworzyć i udostępniać rekomendacje, jak również sieci neuronowe wykorzystywane do analizy danych, a nawet uzyskanie na tym pewnego dochodu – użytkownik, którego rekomendacje są dobre i często wykorzystywane będzie w stanie na tym zarobić.
W projekcie wyróżnia się dwa rozdaje użytkowników: Zalogowany Użytkownik (zwany dalej Użytkownikiem) oraz Gość.
Funkcja rejestrująca użytkownika w systemie; wymaga podania loginu, hasła oraz adresu e-mail, na który (w przypadku rejestracji zakończonej sukcesem) przesłany zostanie mail z linkiem aktywacyjnym.
Funkcja autoryzacyjna, pozwalająca na logowanie z wykorzystaniem loginu oraz hasła, przekazanych w procesie rejestracji; funkcja sprawdza poprawność wprowadzonej pary login-hasło z danymi znajdującymi się w bazie. Hasło sprawdzane jest w formie zaszyfrowanej.
Funkcja realizująca zakończenie aktualnie trwającej sesji użytkownika; w przypadku poprawnego wylogowania z systemu, użytkownik przekierowywany jest na stronę główną aplikacji.
W sytuacji, gdy użytkownik nie jest w stanie zalogować się do systemu, może skorzystać z opcji przypomnienia (a właściwie: odzyskiwania) hasła; polega to na przesłaniu na powiązany z kontem adres e-mail linka, pod którym możliwe jest wprowadzenie nowego hasła dla danego użytkownika.
Funkcja pozwalająca na wprowadzanie zmian w profilu użytkownika zarejestrowanego; edycji podlegają hasło, adres e-mail i informacje dodatkowe; w przypadku zmiany hasła, wymagane jest wprowadzenie hasła aktualnego oraz dwukrotnie nowego; zmiana adresu mailowego wymaga jego aktywacji poprzez e-mail aktywacyjny.
Funkcja umożliwia pobranie z bazy wartości indeksów giełdowych jednej lub więcej spółek dla zadanego przedziału czasowego.
Funkcja umożliwia wyciągnięcie z bazy informacji o rekomendacjach użytkownika zalogowanego (o ile istnieje) oraz rekomendacji osób, których ustawienia prywatności na to pozwalają (rekomendacje publiczne/dla zalogowanych).
Funkcja umożliwiająca wprowadzenie do bazy rekomendacji; wymaga podania wartości indeksu, identyfikatora spółki, której rekomendacja dotyczy oraz dnia, na który stan przewidujemy.
Funkcja realizująca dodanie rekomendacji opartej o sieć neuronową, z przekazanym zestawem parametrów dla tej sieci; sieć taka będzie mieć za zadanie, na podstawie analiz danych historycznych określonych spółek dokonywać estymacji wskaźników giełdowych.
Funkcja umożliwiająca zmianę dostępności rekomendacji dla innych użytkowników systemu. Dopuszczalne opcje:
Funkcja obliczająca na ile zbieżne są wartości przewidziane do rzeczywistych, występujących w danym dniu.
Nazwa klucza | Tabela nadrzędna | Tabela zależna | Kolumna nadrzędna | Kolumna zależna | Typ relacji | ON DELETE | ON UPDATE |
---|---|---|---|---|---|---|---|
fk_neural_networks_neurons_f_neurons | neurons | neural_networks_neurons | neuron_id | neuron_id_from | 1 : 1, m | NO ACTION | CASCADE |
fk_neural_networks_neurons_t_neurons | neurons | neural_networks_neurons | neuron_id | neuron_id_to | 1 : 1, m | NO ACTION | CASCADE |
fk_neurons_neural_networks | neural_networks | neurons | network_id | network_id | 1 : 1, m | NO ACTION | CASCADE |
fk_recommendations_access_levels | access_levels | recommendations | access_level_id | access_level_id | 1 : 1, m | NO ACTION | CASCADE |
fk_recommendations_companies | companies | recommendations | company_code | company_code | 1 : 1, m | NO ACTION | CASCADE |
fk_recommendations_neural_networks | neural_networks | recommendations | network_id | network_id | 1 : 0, 1, m | NO ACTION | CASCADE |
fk_recommendations_users | users | recommendations | user_id | owner_id | 1 : 1, m | NO ACTION | CASCADE |
fk_stock_values_companies | companies | stock_values | company_code | company_code | 1 : 1, m | NO ACTION | CASCADE |
fk_users_roles | roles | users | role_id | role_id | 1 : 1, m | NO ACTION | CASCADE |
SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO"; CREATE TABLE IF NOT EXISTS `access_levels` ( `access_level_id` int(10) unsigned NOT NULL AUTO_INCREMENT, `description_short` varchar(45) COLLATE utf8_polish_ci NOT NULL, `description_long` varchar(200) COLLATE utf8_polish_ci NOT NULL, PRIMARY KEY (`access_level_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_polish_ci AUTO_INCREMENT=1 ; CREATE TABLE IF NOT EXISTS `companies` ( `company_code` varchar(10) COLLATE utf8_polish_ci NOT NULL, `company_name` varchar(45) COLLATE utf8_polish_ci NOT NULL, PRIMARY KEY (`company_code`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_polish_ci; CREATE TABLE IF NOT EXISTS `neural_networks` ( `network_id` int(10) unsigned NOT NULL AUTO_INCREMENT, `name` varchar(45) COLLATE utf8_polish_ci NOT NULL, `inputs_no` int(10) unsigned NOT NULL DEFAULT '0', `outputs_no` int(10) unsigned NOT NULL DEFAULT '0', PRIMARY KEY (`network_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_polish_ci AUTO_INCREMENT=1 ; CREATE TABLE IF NOT EXISTS `neural_networks_neurons` ( `neuron_id_from` int(10) unsigned NOT NULL, `neuron_id_to` int(10) unsigned NOT NULL, `weight` double unsigned NOT NULL, PRIMARY KEY (`neuron_id_from`,`neuron_id_to`), KEY `fk_neural_networks_neurons_t_neurons` (`neuron_id_to`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_polish_ci; CREATE TABLE IF NOT EXISTS `neurons` ( `neuron_id` int(10) unsigned NOT NULL AUTO_INCREMENT, `network_id` int(10) unsigned NOT NULL, `bias` double NOT NULL, PRIMARY KEY (`neuron_id`), KEY `fk_neurons_neural_networks` (`network_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_polish_ci AUTO_INCREMENT=1 ; CREATE TABLE IF NOT EXISTS `recommendations` ( `recommendation_id` int(10) unsigned NOT NULL AUTO_INCREMENT, `owner_id` int(10) unsigned NOT NULL, `company_code` varchar(10) COLLATE utf8_polish_ci NOT NULL, `predicted_value` decimal(10,2) unsigned NOT NULL, `prediction_day` date NOT NULL, `network_id` int(10) unsigned DEFAULT NULL, `access_level_id` int(10) unsigned NOT NULL, PRIMARY KEY (`recommendation_id`), KEY `recommendations_company_code_Idx` (`company_code`), KEY `recommendations_owner_id_Idx` (`owner_id`), KEY `recommendations_prediction_day_Idx` (`prediction_day`), KEY `fk_recommendations_access_levels` (`access_level_id`), KEY `fk_recommendations_neural_networks` (`network_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_polish_ci AUTO_INCREMENT=1 ; CREATE TABLE IF NOT EXISTS `stock_values` ( `company_code` varchar(10) COLLATE utf8_polish_ci NOT NULL, `date` date NOT NULL, `value` decimal(10,2) NOT NULL, PRIMARY KEY (`company_code`,`date`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_polish_ci; CREATE TABLE IF NOT EXISTS `users` ( `user_id` int(10) unsigned NOT NULL AUTO_INCREMENT, `login` varchar(45) COLLATE utf8_polish_ci NOT NULL, `email` varchar(45) COLLATE utf8_polish_ci NOT NULL, `password` varchar(32) COLLATE utf8_polish_ci NOT NULL, `registration_time` datetime NOT NULL, `last_login_time` datetime NOT NULL, `is_active` tinyint(3) unsigned NOT NULL DEFAULT '0', `role_id` int(10) unsigned NOT NULL DEFAULT '1', PRIMARY KEY (`user_id`), KEY `fk_users_user_roles` (`role_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_polish_ci AUTO_INCREMENT=1 ; CREATE TABLE IF NOT EXISTS `user_roles` ( `role_id` int(10) unsigned NOT NULL AUTO_INCREMENT, `description` varchar(45) COLLATE utf8_polish_ci NOT NULL, PRIMARY KEY (`role_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_polish_ci AUTO_INCREMENT=1 ; INSERT INTO `user_roles` (`role_id`, `description`) VALUES (1, 'Użytkownik'); ALTER TABLE `neural_networks_neurons` ADD CONSTRAINT `fk_neural_networks_neurons_t_neurons` FOREIGN KEY (`neuron_id_to`) REFERENCES `neurons` (`neuron_id`) ON DELETE NO ACTION ON UPDATE CASCADE, ADD CONSTRAINT `fk_neural_networks_neurons_f_neurons` FOREIGN KEY (`neuron_id_from`) REFERENCES `neurons` (`neuron_id`) ON DELETE NO ACTION ON UPDATE CASCADE; ALTER TABLE `neurons` ADD CONSTRAINT `fk_neurons_neural_networks` FOREIGN KEY (`network_id`) REFERENCES `neural_networks` (`network_id`) ON DELETE NO ACTION ON UPDATE CASCADE; ALTER TABLE `recommendations` ADD CONSTRAINT `fk_recommendations_users` FOREIGN KEY (`owner_id`) REFERENCES `users` (`user_id`) ON DELETE NO ACTION ON UPDATE CASCADE, ADD CONSTRAINT `fk_recommendations_access_levels` FOREIGN KEY (`access_level_id`) REFERENCES `access_levels` (`access_level_id`) ON DELETE NO ACTION ON UPDATE CASCADE, ADD CONSTRAINT `fk_recommendations_companies` FOREIGN KEY (`company_code`) REFERENCES `companies` (`company_code`) ON DELETE NO ACTION ON UPDATE CASCADE, ADD CONSTRAINT `fk_recommendations_neural_networks` FOREIGN KEY (`network_id`) REFERENCES `neural_networks` (`network_id`) ON DELETE NO ACTION ON UPDATE CASCADE; ALTER TABLE `stock_values` ADD CONSTRAINT `fk_stock_values_companies` FOREIGN KEY (`company_code`) REFERENCES `companies` (`company_code`) ON DELETE NO ACTION ON UPDATE CASCADE; ALTER TABLE `users` ADD CONSTRAINT `fk_users_user_roles` FOREIGN KEY (`role_id`) REFERENCES `user_roles` (`role_id`) ON DELETE NO ACTION ON UPDATE CASCADE;
Wymagania:
Przedstawiana baza jest 1NF.
Wymagania:
Przedstawiana baza jest 2NF.
Wymagania:
Przedstawiana baza jest 3NF.
Rejestracja użytkownika
INSERT INTO users (login, email, password, registration_time) VALUES ('justin', 'justin@domain.com', '61c81371ae4404d7100202d90bee987e', NOW())
Sprawdzenie, czy nie istnieją użytkownicy o podanym e-mailu/loginie (jeśli zwrócona wartość != 0, istnieją)
SELECT COUNT(1) FROM users WHERE login='justin' OR email='justinmail@domain.com'
Modyfikacja danych użytkownika
UPDATE users SET (login, email) VALUES ('harry', 'harry@domain.com')
Dodanie nowej spółki
INSERT INTO companies (company_code, company_name) VALUES ('NS', 'Nowa spółka')
Pobranie danych historycznych wybranych spółek
SELECT company_code, date, value FROM stock_values WHERE company_code IN ('XXX', 'YYY', 'ZZZ') AND date BETWEEN 2011-03-04 AND 2011-05-21
Dodanie dziennego ratingu dla spółki
INSERT INTO stock_values (company_code, date, value) VALUES ('NS', DATE(NOW()), 123)
Pobranie rekomendacji użytkownika zalogowanego oraz tych, które są dla niego widoczne
SELECT * FROM recommendations INNER JOIN access_levels ON access_levels.access_level_id=recommendations.access_level_id WHERE owner_id={{id_uzytkownika_zalogowanego}} OR access_levels.description_short IN ('publiczny', 'dla_zalogowanych')
Dodanie rekomendacji dla wybranej spółki, przewidywanego kursu oraz dnia, którego prognoza ma dotyczyć - wraz z ustaleniem poziomu dostępu
INSERT INTO recommendations (owner_id, company_code, predicted_value, prediction_day, access_level_id) VALUES ({{id_uzytkownika_zalogowanego}}, 'NS', 444, '2011-10-10', ( SELECT access_level_id FROM access_levels WHERE description_short='publiczny') )
Dodanie rekomendacji dla wybranej spółki, z wykorzystaniem parametryzowanej sieci neuronowej
W oparciu o powyższy diagram ERD, utworzono pustą bazę danych na silniku MySQL o strukturze zaprezentowanej na poniższym listingu:
SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO"; CREATE TABLE IF NOT EXISTS `access_levels` ( `access_level_id` int(10) unsigned NOT NULL AUTO_INCREMENT, `description_short` varchar(45) COLLATE utf8_polish_ci NOT NULL, `description_long` varchar(200) COLLATE utf8_polish_ci NOT NULL, PRIMARY KEY (`access_level_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_polish_ci AUTO_INCREMENT=1 ; CREATE TABLE IF NOT EXISTS `companies` ( `company_code` varchar(10) COLLATE utf8_polish_ci NOT NULL, `company_name` varchar(45) COLLATE utf8_polish_ci NOT NULL, PRIMARY KEY (`company_code`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_polish_ci; CREATE TABLE IF NOT EXISTS `neural_networks` ( `network_id` int(10) unsigned NOT NULL AUTO_INCREMENT, `name` varchar(45) COLLATE utf8_polish_ci NOT NULL, `inputs_no` int(10) unsigned NOT NULL DEFAULT '0', `outputs_no` int(10) unsigned NOT NULL DEFAULT '0', PRIMARY KEY (`network_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_polish_ci AUTO_INCREMENT=1 ; CREATE TABLE IF NOT EXISTS `neural_networks_neurons` ( `neuron_id_from` int(10) unsigned NOT NULL, `neuron_id_to` int(10) unsigned NOT NULL, `weight` double unsigned NOT NULL, PRIMARY KEY (`neuron_id_from`,`neuron_id_to`), KEY `fk_neural_networks_neurons_t_neurons` (`neuron_id_to`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_polish_ci; CREATE TABLE IF NOT EXISTS `neurons` ( `neuron_id` int(10) unsigned NOT NULL AUTO_INCREMENT, `network_id` int(10) unsigned NOT NULL, `bias` double NOT NULL, PRIMARY KEY (`neuron_id`), KEY `fk_neurons_neural_networks` (`network_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_polish_ci AUTO_INCREMENT=1 ; CREATE TABLE IF NOT EXISTS `recommendations` ( `recommendation_id` int(10) unsigned NOT NULL AUTO_INCREMENT, `owner_id` int(10) unsigned NOT NULL, `company_code` varchar(10) COLLATE utf8_polish_ci NOT NULL, `predicted_value` decimal(10,2) unsigned NOT NULL, `prediction_day` date NOT NULL, `network_id` int(10) unsigned DEFAULT NULL, `access_level_id` int(10) unsigned NOT NULL, PRIMARY KEY (`recommendation_id`), KEY `recommendations_company_code_Idx` (`company_code`), KEY `recommendations_owner_id_Idx` (`owner_id`), KEY `recommendations_prediction_day_Idx` (`prediction_day`), KEY `fk_recommendations_access_levels` (`access_level_id`), KEY `fk_recommendations_neural_networks` (`network_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_polish_ci AUTO_INCREMENT=1 ; CREATE TABLE IF NOT EXISTS `stock_values` ( `company_code` varchar(10) COLLATE utf8_polish_ci NOT NULL, `date` date NOT NULL, `value` decimal(10,2) NOT NULL, PRIMARY KEY (`company_code`,`date`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_polish_ci; CREATE TABLE IF NOT EXISTS `users` ( `user_id` int(10) unsigned NOT NULL AUTO_INCREMENT, `login` varchar(45) COLLATE utf8_polish_ci NOT NULL, `email` varchar(45) COLLATE utf8_polish_ci NOT NULL, `password` varchar(32) COLLATE utf8_polish_ci NOT NULL, `registration_time` datetime NOT NULL, `last_login_time` datetime NOT NULL, `is_active` tinyint(3) unsigned NOT NULL DEFAULT '0', `role_id` int(10) unsigned NOT NULL DEFAULT '1', PRIMARY KEY (`user_id`), KEY `fk_users_user_roles` (`role_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_polish_ci AUTO_INCREMENT=1 ; CREATE TABLE IF NOT EXISTS `user_roles` ( `role_id` int(10) unsigned NOT NULL AUTO_INCREMENT, `description` varchar(45) COLLATE utf8_polish_ci NOT NULL, PRIMARY KEY (`role_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_polish_ci AUTO_INCREMENT=1 ; INSERT INTO `user_roles` (`role_id`, `description`) VALUES (1, 'Użytkownik'); ALTER TABLE `neural_networks_neurons` ADD CONSTRAINT `fk_neural_networks_neurons_t_neurons` FOREIGN KEY (`neuron_id_to`) REFERENCES `neurons` (`neuron_id`) ON DELETE NO ACTION ON UPDATE CASCADE, ADD CONSTRAINT `fk_neural_networks_neurons_f_neurons` FOREIGN KEY (`neuron_id_from`) REFERENCES `neurons` (`neuron_id`) ON DELETE NO ACTION ON UPDATE CASCADE; ALTER TABLE `neurons` ADD CONSTRAINT `fk_neurons_neural_networks` FOREIGN KEY (`network_id`) REFERENCES `neural_networks` (`network_id`) ON DELETE NO ACTION ON UPDATE CASCADE; ALTER TABLE `recommendations` ADD CONSTRAINT `fk_recommendations_users` FOREIGN KEY (`owner_id`) REFERENCES `users` (`user_id`) ON DELETE NO ACTION ON UPDATE CASCADE, ADD CONSTRAINT `fk_recommendations_access_levels` FOREIGN KEY (`access_level_id`) REFERENCES `access_levels` (`access_level_id`) ON DELETE NO ACTION ON UPDATE CASCADE, ADD CONSTRAINT `fk_recommendations_companies` FOREIGN KEY (`company_code`) REFERENCES `companies` (`company_code`) ON DELETE NO ACTION ON UPDATE CASCADE, ADD CONSTRAINT `fk_recommendations_neural_networks` FOREIGN KEY (`network_id`) REFERENCES `neural_networks` (`network_id`) ON DELETE NO ACTION ON UPDATE CASCADE; ALTER TABLE `stock_values` ADD CONSTRAINT `fk_stock_values_companies` FOREIGN KEY (`company_code`) REFERENCES `companies` (`company_code`) ON DELETE NO ACTION ON UPDATE CASCADE; ALTER TABLE `users` ADD CONSTRAINT `fk_users_user_roles` FOREIGN KEY (`role_id`) REFERENCES `user_roles` (`role_id`) ON DELETE NO ACTION ON UPDATE CASCADE;
Strona startowa
Ekran logowania
Ekran rejestracji nowego użytkownika
Ekran dodawania sieci neuronowej
Ekran wyświetlający rekomendacje
Ekran dodawania nowej rekomendacji
Aplikacja nie używa dokumentów do prezentacji danych. Jedynym dokumentem wykorzystywanym jest plik .csv, pobierany za pośrednictwem API, zawierający dane giełdowe.
Na tym etapie rozwoju aplikacja nie wymagała stworzenia panelu sterowania.
Typowe operacje na bazie danych wykonywane są przy pomocy frameworka do realizacji warstwy dostępu do danych Hibernate. Pełni on funkcję mapera obiektowo-relacyjnego (ORM) i wykonuje podstawowe zapytania do bazy danych.
Z wielu dostępnych narzędzi tego typu, powyższe zostało wybrane z racji dojrzałości projektu, jak i dostarczonej do niego dokumentacji.
Aplikacja uruchamiana oraz testowana była na lokalnych środowiskach jej twórców. Poszczególne komponenty i funkcjonalności były regularnie testowane w miarę rozwoju projektu, w celu możliwie szybkiego wyeliminowania ewentualnych niepoprawnych zachowań i innych sytuacji nieporządanych.
System opiera swe działanie o dane dostarczane przez serwis Charts - Yahoo! Finance za pośrednictwem API http://finance.yahoo.com/charts.
Fragment kodu (w języku Java), budujący adres uri dla danych do pobrania:
StringBuilder uri = new StringBuilder(); uri.append("http://ichart.finance.yahoo.com/table.csv"); uri.append("?s=").append(company.getSymbol()); uri.append("&a=").append(start.getMonth()); uri.append("&b=").append(start.getDay()); uri.append("&c=").append(start.getYear() + 1900); uri.append("&d=").append(end.getMonth()); uri.append("&e=").append(end.getDay()); uri.append("&f=").append(end.getYear() + 1900); uri.append("&g=d");
Aplikacja „odpytuje” API poprzez (zbudowane z powyższego) żądanie HTTP GET do Yahoo!, a serwis zwraca oczekiwane wartości (lub komunikat o błędzie, w przypadku przekazania niepoprawnych parametrów).
Tym sposobem otrzymujemy wartości dzienne danego, sprecyzowanego wskaźnika z określonego przedziału czasowego.
Na potrzeby implementacji oraz weryfikacji działania, aplikacja pozwala na import informacji o cenach złota, ropy oraz wartości indeksu Dow Jones. Na chwilę obecną import przeprowadzany jest ręcznie, docelowo wykonywane będzie to automatycznie.
W celu uruchomienia aplikacji na nowej maszynie produkcyjnej, należy wykonać następujące czynności:
Aplikacja nie jest bardzo skomplikowana, a interfejs w miarę intuicyjny. Korzystanie z niej nie powinno sprawić problemów użytkownikom systemu.
Jedyną rzeczą jaką dobrzy byłoby dostarczyć użytkownikom aplikacji są podstawowe informacje o sieciach neuronowych oraz sposobie ich konstruowania i wykorzystania do przewidzenia danych giełdowych.
Obsługa aplikacji po wdrożeniu to zarówno kontrola poprawności działania aplikacji i bazy danych jak również moderacja zawartości. Autorzy powinni umożliwić i reagować na feedback od użytkowników. Ważne jest także skalowalność czyli przygotowanie bazy, serwera jak i aplikacji do znacznego wzrostu obciążenia w przypadku zwiększenia liczby użytkowników.
Podstawowym kierunkiem dalszego rozwoju aplikacji powinno być dodanie obsługi większej ilości spółek.
Kolejnym dobrym pomysłem będzie dodanie większej ilości parametrów do modułu tworzenia sieci neuronowych w celu umożliwienia dokładniejszych obliczeń.
Dodanie szaty graficznej znacznie wpłynęło by na komfort i wrażenia wizualne użytkowników.
Realizacja omawianego projektu wiązała się z koniecznością poznania nieużywanych przez nas do tej pory technologii i rozwiązań. Przede wszystkim dotyczy to frameworków Google Web Toolkit (GWT) oraz Hibernate.
O ile same w sobie są raczej przyjazne dla developerów, wykorzystanie ich razem - w jednym projekcie - nastręczyło nam dość sporych trudności i było znaczącą przyczyną opóźnienia dalszych prac. Niestety na chwilę obecną brakuje wyczerpujących dokumentacji dotyczących podpinania Hibernate'a do aplikacji tworzonej w GWT, dlatego też nie obyło się bez „eksperymentowania”, którego normalnie bylibyśmy w stanie uniknąć.
Google Web Toolkit dla twórców aplikacji internetowych jest niewątpliwie ciekawym rozwiązaniem. Pozwala on na tworzenie serwisów AJAXowych z wykorzystaniem języka Java. Jest to możliwe poprzez mechanizmy przeprowadzające kompilację kodu Javowego stanowiącego część kliencką aplikacji do JavaScriptu, HTMLa i CSSa.
Hibernate natomiast, niezwykle upraszcza i przyspiesza wykonywanie operacji na strukturach bazodanowych. Pełni on funkcję mapera obiektowo-relacyjnego, co w konsekwencji pozwala na budowanie zapytań do bazy w oparciu o struktury obiektowe. Przy korzystaniu z tego typu rozwiązań, pod rozwagę należy wziąć kwestie wydajnościowe. Mapowanie obiektowo-relacyjne niewątpliwie jest wygodne (i atrakcyjne), w szczególności z punktu widzenia programisty nieobytego w językach SQLowych. Bez praktycznej znajomości SQLa można swobodnie wykonywać większość operacji bazodanowych. Jednak należy pamiętać, że „odpytywanie” bazy w taki sposób wymaga więcej zasobów, z racji samej natury translacji O-R. Dlatego też, w sytuacjach, gdzie wydajność staje się czynnikiem krytycznym, nieraz bardziej odpowiednie okaże się korzystanie ze „standardowych” zapytań.