Monday 23 October 2017

Oanda Forex Trading Api


OANDA plik cookie, plik cookie, plik cookie cookie firmy OANDA, plik cookie. ltiframe szerokość 1 wysokość 1 ramka ramki 0 styl wyświetlania brak mcestyle display none gt lt iframe gt. ANDA FIX OANDA FIX 4 2, 4 3 4 4.REST OANDA, OANDA, 20 v20. API, - OANDA, fxTrade API OANDA - API, API OANDA. fxTrade OANDA API - - API, API OANDA API. v20, 101-23423 fxTrade OANDA API - - API, API OANDA. API REST, OANDA. API OANDA v20.API REST-v20 v20.API OANDA, API. API REST 429. fxTrade API OANDA - API, API OANDA API. v20, 101-23423 -105, API v3 REST v20.API REST v20. , 252345, API v1.Forex Trading Diary 1 - Automatyczny handel walutowy z OANDA API. I wcześniej wspomniano w artykule QuantStart 2017 In Review, który chciałbym poświęcić trochę 2017 na pisanie o zautomatyzowanym handlu forex. badania na rynkach akcji i rynkach kontraktów terminowych, uważam, że byłoby zabawne i edukacyjne, aby pisać o swoich doświadczeniach z wejścia na rynek forex w stylu pamiętnika Każde wejście z dzienniczka będzie próbowało wykorzystać wszystkie te wcześniej, ale powinno być stosunkowo samozatrudnione, W tym pierwszym wpisie pamiętnika będę opisywać jak założyć nowe konto pośrednictwa w praktyce z OANDA oraz jak stworzyć podstawowy wielowątkowy silnik handlu zdarzeniami, który może automatycznie wykonywać transakcje zarówno w praktyce, jak i na żywo Pierwszy rok spędziliśmy dużo czasu, patrząc na backtester zdarzeń, głównie na akcje i ETF. Przedstawiony poniżej jest nastawiony na forex i może być używany zarówno do handlu papierami, jak i do życia tradi ng. I napisałem wszystkie poniższe instrukcje dla Ubuntu 14 04, ale powinny one łatwo przetłumaczyć na system Windows lub Mac OS X, używając dystrybucji Pythona, takiej jak Anaconda Jedyna dodatkowa biblioteka używana do silnika handlu Python jest biblioteką żądań, jest niezbędna do komunikacji z OANDA API. Poniżej przedstawiamy następujące zastrzeżenia. Od pierwszego ogłoszenia dotyczącego handlu walutowego, a przedstawiony poniżej kod może być prosto dostosowany do środowiska handlu emisyjnego. margines charakteryzuje się wysokim poziomem ryzyka i może nie być odpowiedni dla wszystkich inwestorów. Wyniki nie są wskazówką przyszłych wyników Wysoki stopień dźwigni może działać zarówno przed Tobą, jak i dla Ciebie Przed podjęciem decyzji o inwestowaniu w walutę obcą należy uważnie rozważyć cele inwestycyjne, poziom doświadczenia i apetyt na ryzyko Istnieje prawdopodobieństwo, że można by utrzymać stratę niektórych lub całych inwestycji początkowych a zatem nie należy inwestować pieniędzy, których nie stać na stracenie Należy mieć świadomość wszystkich zagrożeń związanych z obrotem dewizowym i zasięgnąć porady niezależnego doradcy finansowego, jeśli masz jakieś wątpliwości. Oprogramowanie jest dostarczane w takim stanie, w jakim jest i dowolne wyrażone lub domniemane gwarancje, w tym między innymi dorozumiane gwarancje dotyczące sprzedaży i przydatności do konkretnego celu są odrzucane. W żadnym wypadku regenci lub współautorzy nie ponoszą odpowiedzialności za szkody bezpośrednie, pośrednie, przypadkowe, specjalne, przykładowe lub wtórne w tym, ale bez ograniczania do tego, do zakupu towarów lub usług zastępczych utraty użytkowania, danych lub zysków lub przerwy w prowadzeniu działalności gospodarczej, niezależnie od tego, czy w umowie, odpowiedzialności ścisłej, czy tortu, w tym zaniedbania lub w inny sposób korzystanie z tego oprogramowania, nawet jeśli zostało poinformowane o możliwości takiej szkody. Ustanowienie konta w programie OANDA. Pierwsze pytanie, o które chodzi Dlaczego wybierzesz OANDA Po prostu trochę po Googlingu dla forex brokerów, który miał API, widziałem, że OANDA niedawno wydał odpowiedni REST API, który można łatwo komunikować się z prawie każdego języka w bardzo prosty sposób Po przeczytaniu ich twórcy Dokumentacja API postanowiłem spróbować, przynajmniej z kontem z praktyką. Jasne - nie mam wcześniejszego lub istniejącego związku z OANDA, a jedynie podanie tego zalecenia opiera się na moim ograniczonym doświadczeniu związanym z ich praktyką API i krótkimi użycie do pobierania danych rynkowych podczas pracy w funduszu wcześniej Jeśli ktoś natknę się na innych brokerów forex, które mają również podobny interfejs API, chętnie dam im spojrzenie. Przed użyciem interfejsu API konieczne jest zarejestrowanie się na koncie do ćwiczeń W tym celu przejdź do linku rejestracji Na ekranie pojawi się następujący ekran. Na ekranie rejestracji w witrynie programu CITYA będziesz mógł się zalogować za pomocą poświadczeń logowania. na karcie fxTradePrywice wybierz kartę fxTraderPractice z ekranu logowania. Na ekranie logowania użytkownika. Gdy będziesz musiał zanotować swój identyfikator konta, który znajduje się pod czarnym nagłówkiem My Funds (Moje kopie) obok Primary Mine (Kopalni pierwotne) to 7-cyfrowa numer Ponadto musisz także wygenerować osobisty token API Aby to zrobić, kliknij Zarządzaj dostępem API pod kartą Inne działania w lewym dolnym rogu. Na tym etapie będzie można wygenerować token API. Potrzebny będzie klucz do użycia później , więc upewnij się, że to również spisujesz. Teraz będziesz chciał uruchomić aplikację FXTrade Practice, która pozwoli nam zobaczyć zrealizowane zlecenia i naszą stratę w zyskach papierowych. Jeśli pracujesz w systemie Ubuntu, musisz zainstalować nieco inna wersja Javy W szczególności wersja Oracle Javy 8 Jeśli nie zrobisz tego, a następnie symulator ćwiczeń nie zostanie załadowany z przeglądarki, uruchomiłem te polecenia na moim systemie. Będziesz teraz mógł uruchomić środowisko handlowe praktyki Powrót do tablicy rozdzielczej OANDA i kliknij na zielony podświetlony link Launch FXTrade Practice Spowoduje wyświetlenie okna dialogowego Java z pytaniem, czy go uruchomić Kliknij przycisk Uruchom, a narzędzie fxTrade Practice załaduje Moje domyślnie do 15-minutowej świeczki w dolarach USD z panelem wyceny po lewej stronie. Odtychczasów jesteśmy gotowi, aby rozpocząć projektowanie i kodowanie naszego zautomatyzowanego systemu handlu forex przeciwko OANDA API. Omówienie architektury handlowej. Jeśli podążałeś za serią backtesterów zorientowanych na zdarzenia dla akcji i ETF, które stworzyłem w ubiegłym roku będziesz świadomy tego, jak funkcjonuje system handlu zdarzeniowego Dla tych, którzy są nowi w oprogramowaniu opartym na zdarzeniach, zdecydowanie polecam przeczytać artykuł, aby zrozumieć, jak one działają. W istocie , cały program jest wykonywany w pętli infinite, która kończy się tylko wtedy, gdy system handlu jest wyłączony Centralny mechanizm komunikacyjny programu jest przekazywany przez kolejkę zawierającą zdarzenia. Kolejką jest c regularnie sprawdzane w celu sprawdzenia nowych wydarzeń Po zdarzeniu wydarzenia na szczycie kolejki musi być obsługiwany przez odpowiedni składnik programu Dlatego kanał danych rynkowych może utworzyć TickEvent, które są umieszczane w kolejce, gdy nowa cena rynkowa przychodzi Obiekt generujący sygnał generuje linie OrderEvent, które mają zostać wysłane do pośrednictwa. Użyteczność tego systemu wynika z faktu, że nie ma znaczenia, jaki porządek lub typy zdarzeń są umieszczane w kolejce, zawsze będzie prawidłowo obsługiwane przez właściwy komponent programu. Ponadto różne części programu mogą być uruchamiane w odrębnych wątkach, co oznacza, że ​​nigdy nie trzeba czekać na konkretny składnik przed przetwarzaniem innych. Jest to bardzo przydatne w sytuacjach handlu algorytmicznego, gdzie dane na rynku i platformy generujące sygnały strategiczne mają bardzo różną charakterystykę wydajności. Główna pętla transakcyjna jest podana przez następujący kod pseudo - kodowy Pythona. powyżej kolejnego wiersza jest uruchamiany w nieskończonej pętli Po pierwsze kolejka jest odpytywana, aby pobrać nowe zdarzenie Jeśli kolejka jest pusta, pętla po prostu uruchamia się ponownie po krótkim okresie snu zwanym pulsu serca Jeśli zdarzenie zostanie odnalezione, jego typ zostanie oceniony i następnie przywołuje się odpowiedni moduł albo strategię albo wykonawcę wykonawczy, aby obsłużyć zdarzenie i ewentualnie wygenerować nowe, które wracają do kolejki. Podstawowymi składnikami, które utworzymy dla naszego systemu handlowego, są :.Streaming Price Handler - To będzie utrzymywać długotrwałe połączenie otwarte na serwerach OANDAs i przesyłać dane o kresach, tzn. zapytać o połączenie za wszelkie instrumenty, z którymi jesteśmy zainteresowani. Generator sygnałów strategicznych - potrwa sekwencję zdarzeń i użyje ich do generowania zamówień handlowych, które zostanie wykonany przez operatora obsługi. Handler realizacji - wykonuje zestaw zdarzeń zamówienia, a następnie ślepo je wykonuje z programem OANDA. Events - obiekty te stanowią przekazywane wiadomości na kolejce zdarzeń Potrzebujemy tylko dwóch dla tej implementacji, a mianowicie TickEvent i OrderEvent. Main Entry Point - główny punkt wejścia zawiera również pętlę handlową, która w sposób ciągły wyszukuje kolejkę komunikatów i wysyła wiadomości do poprawnego składnika. Jest to często znane jako pętli zdarzeń lub obsługi zdarzeń. Teraz omówimy szczegółowo implementację kodu. U dołu artykułu znajduje się pełna lista wszystkich plików kodu źródłowego. Jeśli umieścisz je w tym samym katalogu i uruchomisz Pythona, zaczniesz generować zlecenia, zakładając, że wypełniono identyfikator konta i tokenu uwierzytelniającego z implementacji OANDA. Python. Zła praktyka polega na przechowywaniu haseł lub kluczy uwierzytelniających w bazie kodu, ponieważ nigdy nie można przewidzieć, kto ostatecznie będzie miał dostęp do projektu W systemie produkcyjnym przechowywać te poświadczenia jako zmienne środowiskowe w systemie, a następnie kwerendy te envvars za każdym razem, gdy kod jest przesunięty na nowe. Zapewnia to, że hasła i aut h nie są nigdy przechowywane w systemie kontroli wersji. Jednakże ponieważ jesteśmy wyłącznie zainteresowani budowaniem systemu handlu zabawkami i nie zajmujemy się szczegółami produkcji w tym artykule, zamiast tego oddzielić te pliki tożsamości do pliku ustawień. po pliku konfiguracji mamy słownik zwany ŚRODOWISKI, które przechowują punkty końcowe interfejsu API dla zarówno API transakcji cenowych OANDA, jak i interfejsu API handlu Każdy słownik podrzędny zawiera trzy różne punkty końcowe interfejsu API API i sandbox. The sandbox API jest przeznaczony wyłącznie do testowania kodu i nie ma błędów lub błędów Nie ma gwarancji uptime w prawdziwych lub praktycznych interfejsach API praktyki, co do zasady zapewnia zdolność do handlu papierem To znaczy udostępnia wszystkie funkcje prawdziwego API na symulowanym koncie ćwiczeniowym Prawdziwe API to tylko to, że jest to handel na żywo Jeśli użyjesz tego punktu końcowego w swoim kodzie, będzie on handlował na Twoim koncie na żywo. Bądź ostrożny. w przeciwieństwie do praktyki API pamiętaj, że nie jest brany pod uwagę ważny koszt transakcji, a wpływ na rynek nie jest brany pod uwagę. Ponieważ transakcje nie są rzeczywiście wprowadzane do środowiska, koszt ten należy rozliczać w inny sposób gdzie indziej, używając modelu wpływu na rynek, jeśli chcesz realistycznie ocenić wydajność . Poniżej korzystamy z konta ćwiczeń podanego przez ustawienie DOMAIN Potrzebujemy dwóch oddzielnych słowników dla domen, po jednym dla komponentów API strumieniowego i handlowego. Wreszcie mamy ACCESSTOKEN i ACCOUNTID I wypełniłem poniższe dwie osobnymi identyfikatorami więc trzeba będzie korzystać z własnego, który można uzyskać na stronie konta OANDA. Innym krokiem jest zdefiniowanie zdarzeń, które kolejka będzie używana, aby pomóc wszystkimi poszczególnym komponentom komunikować się Potrzebujemy dwóch TickEvent i OrderEvent Pierwsze informacje o przechowywaniu o danych dotyczących rynków instrumentów, takich jak najlepsza oferta zlecenia i czas wymiany transakcji Druga jest wykorzystywana do przesyłania zamówień do operatora obsługi, a tym samym do kontraktu ns instrument, liczba jednostek handlowych, rynek typu zamówienia lub limit, a strona tj. kupno i sprzeda. Aby wyznaczyć na przyszłość nasz kod zdarzenia, utworzymy klasę bazową o nazwie Zdarzenie i wszystkie zdarzenia dziedziczą z tego kod jest podany poniżej. Następna klasa, którą utworzymy, obsłuży strategię handlową W tym demo zamierzamy stworzyć dość nonsensowną strategię, która po prostu otrzymuje wszystkie kleszcze rynkowe, a co 5-krotki losowo kupuje lub sprzedaje 10.000 jednostek z EUR USD. Jest to dość śmieszna strategia. Jest to jednak fantastyczna metoda testowania, ponieważ jest to łatwe do zrozumienia i zrozumienia. W przyszłych pamiętnikach zastąpimy to znacznie bardziej ekscytującymi informacjami, które mają nadzieję obrócić zysk. Plik może znajdziesz poniżej Let s pracy przez nią i zobaczyć, co się dzieje Po pierwsze, importujemy losową bibliotekę i obiekt OrderEvent z Potrzebujemy losowego lib w celu wybrania losowego zamówienia kupna lub sprzedaży Potrzebujemy OrderEv jako że obiekt strategiczny wysyła zlecenia do kolejki zdarzeń, która będzie później wykonywana przez operatora obsługi. Klasa TestRandomStrategy po prostu przyjmuje instrument w tym przypadku: EUR USD, liczba jednostek i kolejka zdarzeń jako zbiór Parametrów Tworzy się licznik kleszczy, który służy do określenia liczby wystąpień TickEvent. Większość prac powstaje w metodzie calculatesignals, która po prostu przyjmuje zdarzenie, określa, czy jest to TickEvent inaczej ignoruje i zwiększa licznik tick Następnie sprawdza, czy liczba jest podzielna na 5, a następnie losowo kupuje lub sprzedaje, z zamówieniem na rynek, określoną liczbę jednostek. To z pewnością nie jest największą strategią handlową na świecie, ale będzie to bardziej nadaje się dla naszej OANDA pośrednictwo w testowaniu interfejsów API. Następnym składnikiem jest instrukcja obsługi. Ta klasa ma za zadanie działać na instancje OrderEvent i składać wnioski do brokera w tym przypadku OANDA w głupi sposób. Oznacza to, że re jest żadnym zarządzaniem ryzykiem lub pokrywaniem konstrukcji potfolio Obsługa obsługi będzie po prostu wykonywała każde zlecenie, które zostało przekazane. Musimy przekazać wszystkie informacje uwierzytelniające do klasy Wykonanie, w tym praktykę domeny, prawdziwą lub sandbox, token dostępu i konto ID Następnie tworzymy bezpieczne połączenie z jednym z Pythonów zbudowanych w bibliotekach. Większość prac ma miejsce w wykonaniu. Metoda wymaga zdarzenia jako parametru. Następnie konstruktuje dwa słowniki - nagłówki i params. Te słowniki będą następnie prawidłowo zakodowane częściowo przez urllib innej bibliotece Pythona do wysłania jako żądanie POST do interfejsu API OANDAs. Przepuszczamy parametry nagłówka Content-Type i Authorization, które zawierają nasze informacje uwierzytelniające Ponadto kodujemy parametry, w tym instrument EUR USD, jednostki, typ zlecenia i side buy sell Wreszcie składamy wniosek i zapisujemy odpowiedź. Najbardziej skomplikowanym elementem systemu handlowego jest StreamingForexPrices obj ect, który obsługuje aktualizacje cen rynkowych z OANDA Istnieją dwie metody connecttostream i streamtoqueue. Pierwsza metoda wykorzystuje bibliotekę zapytań Pythona do łączenia się z gniazdem transmisji strumieniowej z odpowiednimi nagłówkami i parametrami. Parametry zawierają identyfikator konta i niezbędną listę instrumentów powinno być wysłuchane w przypadku aktualizacji w tym przypadku to tylko EUR USD Zanotuj poniższą linię. Powoduje, że połączenie ma być przesyłane strumieniowo, a tym samym pozostawione otwarte w długotrwały sposób. Druga metoda polega na próbie nawiązania połączenia z strumieniem odpowiedź nie powiedzie się, tzn. kod odpowiedzi nie jest 200, po prostu zwracamy i kończymy Jeśli uda się spróbować załadować pakiet JSON zwrócony do słownika Python Wreszcie konwertujemy słownik z Pythona na instrument, zapytaj o cenę i godzinę w TickEvent, który jest wysyłany do kolejki zdarzeń. Teraz mamy wszystkie najważniejsze składniki w miejscu Ostatnim krokiem jest zawarcie w całości tego, co dotychczas napisaliśmy do głównego programu Celem tego pliku jest stworzenie dwóch osobnych wątków, z których jedna uruchamia procedurę ustalania cen, a druga uruchamia handler transakcji. Dlaczego potrzebujemy dwóch oddzielnych wątków? Po prostu, wykonujemy dwa oddzielne kawałki kodu, z których oba są ciągle uruchamiane Jeśli utworzymy program niegwintowany, to gniazdo transmisji strumieniowej używane do aktualizacji cen nigdy nigdy nie powróci do głównej ścieżki kodu, a zatem nigdy byśmy nigdy nie prowadzili żadnego obrotu Podobnie , jeśli uruchomiliśmy pętlę handlową podaną poniżej, nigdy byśmy nigdy nie zawrócili ścieżki przepływu do gniazda strumieniowego transmisji danych. W związku z tym potrzebujemy wielu wątków, po jednym dla każdego składnika, dzięki czemu mogą one być przeprowadzane niezależnie. kolejki zdarzeń. Następnie przeanalizuj to trochę dalej Tworzymy dwa oddzielne wątki z następującymi wierszami. Przepuszczamy nazwę funkcji lub metody do docelowego słowa kluczowego, a następnie przekazujemy iterable takie jak lista lub krotka na args args argument, który następnie przekazuje te argumenty do rzeczywistej funkcji metody. Wreszcie zaczynamy oba wątki z następującymi wierszami. Jeśli jesteśmy w stanie uruchomić dwa, skutecznie nieskończone pętle, segmenty kodu niezależnie, które komunikują się za pośrednictwem kolejki zdarzeń Zauważ, że biblioteka gwintów Pythona nie generuje prawdziwego wielowątkowego środowiska wielordzeniowego ze względu na implementację Python'a i CPython Global Głębia interpreterów. Jeśli chcesz przeczytać więcej o wielowątkowości w Pythonie, zapoznaj się z tym artykułem. s przeanalizuj resztę kodu szczegółowo Po pierwsze importujemy wszystkie potrzebne biblioteki, w tym kolejkowanie wątków i czas Następnie importujemy wszystkie powyższe pliki kodów, które osobiście wolę wykorzystać wszelkie ustawienia konfiguracyjne, co jest zwyczajem, który podjąłem od pracy z Django. Następnie określamy funkcję handlową, która została wyjaśniona w Pythonie-pseudokodie powyżej Nieskończona pętla while jest wykonywana podczas gdy True, że ciągłość ously polls z kolejki zdarzeń i pomijając tylko pętlę, jeśli zostanie znaleziona pusta Jeśli zdarzenie zostanie znalezione, to jest to TickEvent lub OrderEvent, a następnie wywoływany jest odpowiedni składnik, aby go zrealizować W tym przypadku jest to strategia lub implementator obsługi Pętla wtedy po prostu śpi na sekundę bicia serca w tym przypadku 0 5 sekund i kontynuuje. Na koniec definiujemy główny punkt wejścia kodu w głównej funkcji Jest dobrze komentowane poniżej, ale podsumuję tutaj Istotnie, stwarzamy wystąpienia zdarzeń kolejka i definiowanie jednostek instrumentów Następnie tworzymy klasę strumieni cenowych StreamingForexPrices, a następnie wykonaj wykonawcę wykonawstwa Obydwa dane niezbędne do uwierzytelnienia podane przez firmę OANDA są tworzone przy tworzeniu konta. Następnie tworzymy instancję TestRandomStrategy Wreszcie definiujemy dwa wątki i a następnie uruchom je. Aby uruchomić kod, wystarczy umieścić wszystkie pliki w tym samym katalogu i zadzwonić do poniższych na terminalu. Zauważ, że aby zatrzymanie kodu na tym etapie wymaga ciężkiego zabicia procesu Pythona za pomocą Ctrl-Z lub odpowiednika Nie dodałem dodatkowego wątku, który by obsługił szukał tego, który byłby potrzebny do bezpiecznego zatrzymania kodu Potencjalny sposób na zatrzymanie kodu na Maszyna Ubuntu Linux ma zostać wpisana. Następnie należy przekazać dane wyjściowe tego numeru procesowi w następujący sposób: gdzie PROCESSID musi zostać zastąpiony przez wyjście z pgrep Należy zauważyć, że nie jest to szczególnie dobra praktyka. W późniejszych artykułach będziemy tworzyć bardziej wyrafinowane stop mechanizm startowy, który wykorzystuje nadzór nad procesem Ubuntu w celu uruchomienia systemu handlowego 24 7.Powinność po 30 sekundach, w zależności od pory dnia w stosunku do głównych godzin handlowych EUR USD, dla powyższego kodu , podano poniżej. Pierwsze pięć wierszy przedstawia dane z tickowania JSON zwrócone z OANDA z cenami zapytania ofertowego. Następnie można zobaczyć wynik wyjściowy realizacji zamówienia oraz odpowiedź JSON zwracaną przez firmę OANDA potwierdzającą otwarcie transakcji kupna f lub 10.000 jednostek w USD i cenę, którą osiągnięto. To będzie działało na czas nieokreślony do czasu zabicia programu przy użyciu polecenia Ctrl-Z lub podobnych. W późniejszych artykułach będziemy przeprowadzać wiele niezbędnych ulepszeń, w tym. Prawdziwe strategie - właściwe strategie forex, generujące zyskowne sygnały. Infrastruktura produkcyjna - zdalne wdrażanie serwera i system monitorowania z 24-miesięcznym monitoringiem, z możliwością stop startu. Zarządzanie portfelem i ryzykiem - Portfolio i nakładki ryzyka dla wszystkich sugerowanych zamówień ze strategii. Wielkie strategie - budowa portfel strategii wchodzących w skład nakładów na zarządzanie ryzykiem. W przypadku backtesteru opartego na zdarzeniach z udziałem kapitału, musimy również utworzyć moduł testowania transakcji forex, który umożliwi nam szybkie badania i ułatwi wdrażanie strategii. pamiętaj, aby zmienić ACCOUNTID i ACCESSTOKEN. Just zacząć z ilościowym handlem. OANDA plik cookie, plik cookie, cookie cookie OANDA, cookie. ltiframe szerokość 1 wysokość 1 frameborder 0 styl wyświetlania none mcestyle display none gt lt iframe gt,, iOS Android. METATRADER 4 ,, -, 4 iOS Android., 1 1 2017 OANDA v20, 4.1996 2017 OANDA Corporation OANDA, fxTrade fx OANDA Corporation - OANDA Europe Ltd,, 4 50 1. OANDA Europe Limited, 7110087, wieża 42, piętro 9a, 25 Old Broad St, Londyn EC2N 1HQ 542574.Andra Japan Co Ltd Kanto Lokalne Biuro Finansowe Kin-sho, 2137, 1571.

1 comment:

  1. Bardzo ciekawie napisane. Jestem pod wielkim wrażaniem.

    ReplyDelete