Spis treści

Projekt konceptualny

1. Sformułowanie zadania projektowego

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.

2. Analiza stanu wyjściowego

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ć.

3. Analiza wymagań użytkownika (wstępna)

W projekcie wyróżnia się dwa rozdaje użytkowników: Zalogowany Użytkownik (zwany dalej Użytkownikiem) oraz Gość.

Wymagania Użytkownika

  1. Konieczne (Must):
    • Przeglądania historycznych danych o kursach akcji
    • Dodanie własnych rekomendacji, nie wynikających z wyników sieci neuronowej, a z jego własnej wiedzy i doświadczenia
    • Wygenerowania sieci neuronowej, uczącej się na podstawie podzbioru historycznych danych giełdowych, według zdefiniowanych przez użytkownika parametrów
    • Zdefiniowania poziomu dostępności do rekomendacji swojej sieci. (minimalnie: dostępne dla wszystkich, dostępne dla zalogowanych, prywatne)
    • Przeglądanie wyników własnej sieci, wyników sieci ogólnodostępnych oraz globalnych statystyk (minimalnie: najczęściej rekomendowane, najlepsze rekomendacje ostatniego dnia, najlepsze rekomendacje ostatniego tygodnia)
  2. Powinny się pojawić (Should):
    • Użytkownik będzie posiadał „konto” z wirtualnymi pieniędzmi za które będzie mógł kupować dostęp do niektórych części serwisu
    • Ustawienie poziomu dostępu do rekomendacji na „za opłatą” oraz ustalenie wysokości opłaty
  3. Opcjonalne (Could):
    • Przeglądanie analizy technicznej
    • Możliwość wykorzystania wyników analizy technicznej jako wejście sieci neuronowej
    • Otrzymywanie powiadomień mailowych o nowych rekomendacjach własnej sieci
    • Możliwość „zapisania się” na otrzymywanie powiadomień mailowych o rekomendacjach konkretnych użytkowników

Wymagania Gościa

  • Zarejestrowanie się oraz późniejsze zalogowanie przy użyciu loginu oraz hasła – Gość staje się Użytkownikiem
  • Przeglądania historycznych danych o kursach akcji
  • Przeglądanie wyników wyników sieci ogólnodostępnych oraz globalnych statystyk (minimalnie: najczęściej rekomendowane, najlepsze rekomendacje ostatniego dnia, najlepsze rekomendacje ostatniego tygodnia)

4. Określenie scenariuszy użycia

Rejestracja

  1. Użytkownik wprowadza pożądany login, posiadany adres e-mail oraz hasło (opcjonalnie imię i nazwisko, dane adresowe itp. - do przemyślenia + może system weryfikacji z obrazka)
  2. Jeśli w bazie użytkowników nie ma użytkownika o takim samym loginie, bądź adresie e-mail tworzone jest nowe konto użytkownika, w przeciwnym wypadku użytkownik informowany jest o konflikcie
  3. (Weryfikacja adresu e-mail?)

Logowanie

  1. Użytkownik wprowadza login i hasło
  2. Jeśli dane odpowiadają danym w bazie to ładowana jest strona startowa użytkownika, zawierającą przeznaczone dla niego rekomendacje, w przeciwnym wypadku użytkownik jest informowany o błędzie

Odzyskiwanie hasła

  1. Użytkownik wprowadza adres e-mail powiązany z jego kontem
  2. Jeśli w bazie danych jest przechowywana informacja o użytkowniku z takim adresem mailowym, na adres ten wysłany zostaje e-mail m.in. z loginem oraz linkiem, pod którym możliwe będzie wprowadzenie nowego hasła
  3. Użytkownik dwukrotnie wprowadza nowe hasło; po wysłaniu zwalidowanego formularza hasło użytkownika zostaje zmienione na to nowo wprowadzone

Tworzenie sieci neuronowej

  1. Użytkownik ze swojej strony głównej wybiera odnośnik „Dodaj nową sieć”
  2. Pojawia się formularz pozwalający na wybranie parametrów sieci, takich jak:
    • Typ sieci
    • Ilość warstw/neuronów
    • Algorytmu uczenia sieci
  3. Następny formularz pozwala na ustawienie danych wejściowych, takich jak:
    • Wybór indeksu (WIG, WIG20, MIDWIG, itp.)
    • Wybór akcji
    • Wybór typu danych branych pod uwagę (kurs otwarcia/zamknięcia, wolumin, kurs średni)
    • Dane analizy technicznej
  4. Formularz finalizacyjny pozwalający na:
    • Nadanie sieci nazwy
    • Ustawienie dostępności sieci (publiczna/prywatna)
    • Ustawienia dotyczące powiadomień

Dodawanie rekomendacji

  1. Użytkownik ze swojej strony głównej wybiera odnośnik „Dodaj nową rekomendację”
  2. Użytkownik wypełnia odpowiednie pola formularza:
    • Nazwę rekomendacji
    • Spółkę
    • Przewidywany kurs
    • Dzień na który aktualna będzie rekomendacja
    • Opcjonalne: Pole z opisem na czym bazuje swoje wnioski

Przegląd danych historycznych

  1. Użytkownik ze swojej strony głównej wybiera odnośnik „Kursy”

Przegląd statystyk

  1. Użytkownik ze swojej strony głównej wybiera odnośnik „Statystyki”
  2. Pojawia się strona z różnego rodzaju statystykami:
    • Najlepsze rekomendacje tygodnia/miesiąca/roku
    • Najlepiej rekomendujący użytkownicy tygodnia/miesiąca/roku
    • Najlepiej przewidujące sieci tygodnia/miesiąca/roku (Może być trudne w ocenie?)

Przegląd rekomendacji własnych oraz obserwowanych

  1. Lista będzie dostępna na stronie głównej użytkownika, wraz ze źródłami pochodzenia

Przegląd rekomendacji cudzych

  1. Użytkownik ze swojej strony głównej wybiera odnośnik „Dostępne rekomendacje”
  2. Pojawia się lista dostępnych rekomendacji wraz z odnośnikami do dodawania do obserwowanych oraz rekomendującego. Dodatkowo dostępne są różne opcje filtrowania (kiedy dodana, czego dotyczy (indeksy/spółki))

5. Identyfikacja funkcji

Rejestracja

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.

Logowanie

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.

Wylogowanie

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.

Odzyskiwanie/zmiana hasła

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.

Modyfikacja danych 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.

Pobranie danych

Funkcja umożliwia pobranie z bazy wartości indeksów giełdowych jednej lub więcej spółek dla zadanego przedziału czasowego.

Pobranie rekomendacji

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).

Dodanie rekomendacji zwykłej

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.

Dodanie rekomendacji opartej o sieć neuronową

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.

Edycja poziomu dostępności rekomendacji

Funkcja umożliwiająca zmianę dostępności rekomendacji dla innych użytkowników systemu. Dopuszczalne opcje:

  • rekomendacja publiczna (każdy może ją widzieć)
  • tylko zalogowanych
  • rekomendacja prywatna (dostępna tylko dla użytkownika, który ją utworzył)

Funkcja oceniająca

Funkcja obliczająca na ile zbieżne są wartości przewidziane do rzeczywistych, występujących w danym dniu.

6. Analiza hierarchii funkcji projektowanej aplikacji (FHD – Functional Hierarchy Diagram)

Funkcje obsługi kont użytkowników

  • obsługa nowych użytkowników
    • rejestracja nowego użytkownika (minimalnie login, e-mail, hasło)
      • funkcja sprawdzająca, czy podany login/e-mail nie istnieje w bazie
      • właściwa rejestracja (dodanie konta do bazy)
    • powiadomienie mailowe o rejestracji
      • funkcja generująca link do aktywacji konta (potwierdzenia adresu e-mail)
      • funkcja wysyłająca odpowiedni e-mail
    • aktywacja konta
  • obsługa użytkowników zarejestrowanych
    • funkcja odpowiadająca za logowanie do serwisu
    • funkcja odpowiadająca za opcję przypominania hasła

Funkcje obsługi rekomendacji

  • dodanie rekomendacji dla wybranej spółki, przewidywanego kursu oraz dnia, którego prognoza ma dotyczyć
  • dodanie rekomendacji w oparciu o sieć neuronową
    • ustawienie parametrów sieci
  • sprawdzenie, czy rekomendacja dla tej spółki w podanym dniu nie została wcześniej zdefiniowana przez tego samego użytkownika (przeciwdziałanie zwiększeniu szansy na trafną prognozę poprzez wprowadzanie wielu kursów)
  • weryfikacja trafności rekomendacji

Funkcje obsługi danych historycznych oraz statystyk

  • wyświetlanie danych historycznych dla konkretnej spółki (spółek) z zadanego przedziału czasowego
  • (ocena rekomendacji, oceny trafności?)

7. Diagram przepływu danych (DFD - Data Flow Diagram)

8. Wybór encji (obiektów) i ich atrybutów

Użytkownik

  • id
  • login
  • hasło (zakodowane)
  • e-mail
  • data rejestracji
  • data ostatniego logowania
  • flaga aktywności
  • rola

Spółka

  • id spółki
  • nazwa
  • indeks (WIG, WIG20, midWIG itp.)

Rekomendacja

  • id rekomendacji
  • nazwa rekomendacji
  • id spółki
  • id (właściciel rekomendacji)
  • dzień na który przewidujemy
  • przewidywana wartość
  • dostępność rekomendacji
  • opis/komentarz do rekomendacji
  • id sieci neuronowej (jeśli dotyczy)

Sieć neuronowa

  • id sieci neuronowej
  • nazwa sieci
  • id (właściciela sieci)
  • typ sieci
  • zestaw parametrów opisujących sieć (warstwy/liczby neuronów/wagi neuronów)
  • (czy dane z których uczymy nie będą dotyczyły tylko sieci z rekomendacjami? To pozwoli na wielokrotne wykorzystanie?)

9. Powiązania pomiędzy encjami (ERD - Entity-Relationship Diagram)

10. Diagramy przejść między stanami (STD - State Transition Diagram)

Projekt logiczny

1. Projektowanie tabel, kluczy, kluczy obcych, powiązań między tabelami, indeksów, etc. w oparciu o zdefiniowany diagram ERD

Zaprojektowane klucze obce i powiązania między tabelami

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

Nałożone indeksy

  • recommendations_company_code_Idx - dot. kolumny company_code w tabeli recommendations
  • recommendations_owner_id_Idx - dot. kolumny owner_id w tabeli recommendations
  • recommendations_prediction_day_Idx - dot. kolumny prediction_day w tabeli recommendations

Kompletny kod w języku MySQL tworzący strukturę bazodanową

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;

2. Słowniki danych

  1. roles: tabela słownikowa przechowująca identyfikatory poszczególnych ról użytkowników systemu (administrator, zwykły użytkownik itp.)
    • role_id (id roli; klucz główny, wartość unikalna) - INT UNSIGNED NOT NULL AUTO_INCREMENT,
    • description (określenie roli) - VARCHAR(45) NOT NULL.
  2. users: tabela przechowująca informacje o użytkownikach systemu
    • user_id (id użytkownika; klucz główny, wartość unikalna) - INT UNSIGNED NOT NULL AUTO_INCREMENT,
    • login (nazwa użytkownika) - VARCHAR(45) NOT NULL,
    • email (adres e-mail) - VARCHAR(45) NOT NULL,
    • password (hasło użytkownika, zaszyfrowane algorytmem md5) - VARCHAR(32) NOT NULL,
    • registration_time (data rejestracji w systemie) - DATETIME NOT NULL,
    • last_login_time (data ostatniego zalogowania) - DATETIME NOT NULL,
    • is_active (flaga określająca, czy użytkownik jest aktywny) - TINYINT(1) NOT NULL DEFAULT 0,
    • role_id (id roli z tabeli roles) - INT NOT NULL DEFAULT 1.
  3. recommendations: tabela, w której przechowywane są rekomendacje (przewidywane wartości na konkretne terminy) spółek, wprowadzane przez użytkowników systemu
    • recommendation_id (unikalny identyfikator rekomendacji, klucz główny) - INT UNSIGNED NOT NULL AUTO_INCREMENT,
    • owner_id (identyfikator autora/właściciela z tabeli users) - INT UNSIGNED NOT NULL,
    • company_code (identyfikator firmy z tabeli companies) - VARCHAR(10) NOT NULL,
    • predicted_value (przewidywana wartość akcji na konkretną datę) - DECIMAL NOT NULL,
    • predicted_day (dzień, którego dotyczy szacowanie wartości) - DATE NOT NULL,
    • access_level (poziom dostępu, z tabeli access_levels) - INT NOT NULL,
    • network_id (opcjonalny identyfikator sieci neuronowej, która wyznaczyła rekomendację) - INT UNSIGNED NULL DEFAULT NULL.
  4. companies: tabela z identyfikatorami firm
    • company_code (unikalny kod spółki, klucz główny) - VARCHAR(10) NOT NULL,
    • company_name (pełna nazwa spółki) - VARCHAR(45) NOT NULL,
    • index_id
  5. stock_values: tabela z faktycznymi wartościami spółek w konkretnych dniach
    • company_code (kod spółki, z tabeli companies) - VARCHAR(10) NOT NULL,
    • date (data zanotowania wartości wskaźnika) - DATE NOT NULL,
    • value (wartość spółki w określonym dniu) - DECIMAL NOT NULL.
  6. access_levels: tabela słownikowa dla opisów poszczególnych ustawień prywatności
    • access_level_id (unikalny identyfiaktor poziomu dostępu, klucz główny) - INT UNSIGNED NOT NULL AUTO_INCREMENT,
    • description_short (krótki opis poziomu dostępu) - VARCHAR(45) NOT NULL,
    • description_long (pełny opis poziomu dostępu) - VARCHAR(200) NOT NULL.
  7. neural_networks: tabela określająca podstawowe parametry sieci neuronowych (nazwę, liczbę wejść i wyjść)
    • network_id (unikalny identyfikator sieci neuronowej, klucz główny) - INT UNSIGNED NOT NULL AUTO_INCREMENT,
    • name (nazwa sieci neuronowej) - VARCHAR(45) NOT NULL,
    • inputs (liczba wejść) - INT NOT NULL DEFAULT 0,
    • outputs (liczba wyjść) - INT NOT NULL DEFAULT 0.
  8. neurons: tabela precyzująca parametr 'bias' każdego neuronu
    • neuron_id (unikalny identyfikator neuronu, klucz główny) - INT UNSIGNED NOT NULL AUTO_INCREMENT,
    • network_id (identyfikator sieci neuronowej z tabeli neural_networks) - INT NOT NULL,
    • bias (parametr 'bias' konkretnego neuronu) - DOUBLE NOT NULL.
  9. neural_networks_neurons: tabela definiująca połączenia między poszczególnymi neuronami w ramach sieci neuronowej
    • neuron_id_from (identyfikator neuronu, od którego wychodzi połączenie, element złożonego klucza głównego) - INT UNSIGNED NOT NULL,
    • neuron_id_to (identufikator neuronu, do którego wchodzi połączenie, element złożonego klucza głównego) - INT UNSIGNED NOT NULL,
    • weight (waga połączenia między neuronami) - DOUBLE NOT NULL.

3. Analiza zależności funkcyjnych i normalizacja tabel (dekompozycja do 3NF, BCNF, 4NF, 5NF)

Analiza zależności funkcyjnych

Pierwsza postać normalna (1NF)

Wymagania:

  • wartości atrybutów we wszystkich tabelach są atomiczne (niepodzielne),
  • każda tabela posiada klucz główny,
  • znaczenie danych nie zależy od kolejności rekordów.

Przedstawiana baza jest 1NF.

Druga postać normalna (2NF)

Wymagania:

  • zachodzą warunki na 1NF,
  • każda kolumna jest funkcyjnie zależna od całego klucza głównego.

Przedstawiana baza jest 2NF.

Trzecia postać normalna (3NF)

Wymagania:

  • zachodzą warunki na 2NF,
  • wszystkie pola, które nie wchodzą w skład klucza głównego są od niego zależne bezpośrednio.

Przedstawiana baza jest 3NF.

4. Projektowanie operacji na danych - przykładowe zapytania

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



Raport końcowy

1. Implementacja bazy danych

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;

2. Zdefiniowanie interfejsów do prezentacji, edycji i obsługi danych

Strona startowa

Ekran logowania

Ekran rejestracji nowego użytkownika

Ekran dodawania sieci neuronowej

Ekran wyświetlający rekomendacje

Ekran dodawania nowej rekomendacji

3. Zdefiniowanie dokumentów do przetwarzania i prezentacji danych

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.

4. Zdefiniowanie panelu sterowania aplikacji

Na tym etapie rozwoju aplikacja nie wymagała stworzenia panelu sterowania.

5. Zdefiniowanie makropoleceń dla realizacji typowych operacji

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.

6. Uruchamianie i testowanie aplikacji

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.

7. Wprowadzanie 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.

8. Wdrażanie systemu do użytkowania

W celu uruchomienia aplikacji na nowej maszynie produkcyjnej, należy wykonać następujące czynności:

  • zaimportować strukturę bazodanową do docelowego serwera MySQL,
  • zaktualizować sekcję dotyczącą parametrów bazy w pliku konfiguracyjnym projektu,
  • uruchomić kontener servletów TomCat,
  • wdrożyć projekt na serwer produkcyjny,

9. Przeprowadzenie szkolenia użytkowników

Aplikacja nie jest bardzo skomplikowana, a interfejs w miarę intuicyjny. Korzystanie z niej nie powinno sprawić problemów użytkownikom systemu.

10. Zapewnienie dokumentacji technicznej i użytkowej

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.

11. Zapewnienie obsługiwania systemu po wdrożeniu

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.

12. Rozwijanie i modyfikowanie aplikacji

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.

13. Opracowanie doświadczeń wynikających z realizacji projektu

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ń.

14. Wykaz literatury, linki i załączniki

pl/dydaktyka/ztb/2011/projekty/gielda/start.txt · ostatnio zmienione: 2019/06/27 15:50 (edycja zewnętrzna)
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0