Pokazywanie postów oznaczonych etykietą Programowanie. Pokaż wszystkie posty
Pokazywanie postów oznaczonych etykietą Programowanie. Pokaż wszystkie posty

sobota, 14 kwietnia 2012

# Zanim zaczniesz pisać, tworzyć forexowego robota - sprawdź się!

Zanim zaczniesz pisać, tworzyć forexowego robota - sprawdź się!

Automatyczna samokontrola

Temat cieszy się pewnym zainteresowaniem:
Jak napisać własnego robota pod Metatradera na forex?
 
Zanim utoniecie w programowaniu proponuję przeprowadzić prosty test. Czy będziecie w stanie grać stworzonym automatem w realu? Wbrew pozorom nie jest to łatwe. Bo jak nie macie ku temu predyspozycji - próżny Wasz trud - szkoda czasu.

Test stróża

 
Weźcie jakąś strategię, którą da się prowadzić ręcznie w perspektywie jednego dnia i która w Waszej ocenie może być "profitowa". Może coś w tym stylu: sygnał otwarcia - zmknięcie na TP lub SL. Obstawiacie na koncie rzeczywistym jakimiś drobnymi stawkami. Ot tyle aby poczuć "emocje".

I teraz najtrudniejsze. Przez miesiąc - dzień po dniu - bez względu na narastające wyniki: wstajecie, otwieracie zlecenie, ustawiacie parametry i zamykacie platformę - zapominacie o pozycji, czas wolny !!! Przed snem sprawdzacie czy coś się "złapało" czy jeszcze nie.
 
Jak nie dacie rady tak żyć przez miesiąc to po co Wam robot? Szukacie posady stróża? Chcecie stale kontrolować robota i może jeszcze go "poprawiać" z ręki? Nie lepiej od razu poszukać posady stróża (w tym nocnego) niż tworzyć robota? Pieniądz pewniejszy, a stres mniejszy.

Pomijając wszelkie inne aspekty robotyki to jest chyba  największa bariera z jaką trzeba sobie poradzić. Bariera zaufania do algorytmu. W praktyce bariera zaufanie do własnej osoby. Być może wystarczy Wam półautomat (zmiana parametrów zleceń bezpośrednio z wykresu) np:
 
AutoGraf 4 - robot do wspierania handlu na forexie

poniedziałek, 6 lutego 2012

# Kryterium Kelly - zapomniana funkcja Metatradera - hazard w służbie forexu

Kryterium Kelly - zapomniana funkcja Metatradera - hazard w służbie forexu

Sposób na stawkowanie

 
Kryterium Kelly'ego jest dobrze opisane na polskich stronach dotyczących hazardu więc nie ma co się rozpisywać. Oni tam nawet nie cofają się przed używaniem zwrotu "giełda" zakładów sportowych. Jest też dobrze znane części graczy z rynku futures warszawskiej giełdy na kontrakty terminowe. Wiecie to taki twardy giełdowy hazard gdzie można stracić więcej niż się postawiło. Przebitka stawkowania do 1:10, więc przy Forexie to i tak kontrakty wyglądają na bardzo łagodny hazard. Na Forexie maxymalne przebitki sięgają 1:100 czy 1:500, a są i tacy brokerzy co pozwalają na jeszcze wyższe stawkowanie. W powiązaniu z niskimi wymogami kapitałowymi do otwarcia zakładu powstaje mieszanka wybuchowa rozsadzająca portfele najtwardszych (najmłodszych) graczy. Nawet niewielka niekorzystna zmiana kursu wyrzuca niedokapitalizowanych graczy z gry.
 
Oryginalny text z 1956 roku:
http://www.racing.saratoga.ny.us/kelly.pdf
Angielska Wikipedia:
http://en.wikipedia.org/wiki/Kelly_criterion

Niżej pocztówka z 1957 roku z widokiem na tor wyścigów konnych:

Saratoga Race Course
Saratoga Race Course

Ten temat jakoś w forexowych kręgach jest pomijany. Może chodzi o to aby ludzie tracili szybko? Moja próba zainicjowania dyskusji na pewnym forum nie wzbudziła zainteresowania. Niestety na forexie mało kto myśli co stanie się z jego kontem za miesiąc. Gra na ile broker pozwala.
 
Paul Wilmott on Quantitative Finance, Chapter 17, Kelly criterion


O co chodzi, że nie wychodzi


Chodzi o pieniądze. Przy pomocy kryterium maxsymalizujemy wartość oczekiwaną gry - spodziewany wynik. Gra jest tak prowadzona aby maxymalizować geometryczną stopę zwrotu. Gra ma tylko jedno optymalne rozwiązanie. Filozofia jest tu inna niż przykładowo w metodzie portfelowej, w której możemy wybierać pomiędzy wieloma równoważnymi rozwiązaniami. Stosując kryterium mamy trzy w jednym: optymalizujemy stawkę zakładu, minimalizujemy prawdopodobieństwo bankructwa oraz maxymalizujemy tempo wzrostu naszych zysków. Krótko mówiąc wyliczamy ile procent posiadanego kapitału postawić na zdarzenie aby zmaksymalizować zysk i zminimalizować stratę.
 

Założenia - jak zwykle najsłabsze ogniwo

 
 Poprawne zastosowanie kryterium wymaga spełnienia warunku:
  • musimy posiadać przewagę statystyczną - zarabiającą strategię
Bułka z masłem.
Strategia większego jelenia (idioty) - klucz do sukcesu na Forexie
Jak nie zarabiamy to stosowanie kryterium nic nam nie pomoże - szkoda na nie czasu - stan rachunku szybciej czy wolniej będzie i tak zmierzał do zera. Generalnie ilość pieniędzy jaką zarabiamy musi być większa od ilości pieniędzy jaką tracimy (może coś takiego: ilość zleceń zyskownych razy średni zysk > ilości zleceń stratnych razy średnia strata albo prawdopodobieństwa wygranej razy średnia wygrana > prawdopodobieństwa porażki razy średnia strata). W przeciwnym wypadku kryterium da wynik: nie obstawiaj - w sensie prawdopodobieństwa: obstaw zdarzenie przeciwne. Ze względu na koszty (spread) w praktyce nie da się otworzyć zakładu przeciwnego (to odpowiada na pytanie: dlaczego nie chcą działać strategie przeciwne do przegrywających).

Wspomnę o jeszcze jednym warunku - stawka wyliczana z kryterium powinna dawać dzielić się w nieskończoność. Przy odpowiednio dużym stanie konta warunek ten można zlekceważyć. W przypadku zakładów bukmacherskich warunki zapisywane są zwykle jako: prawdopodobieństwo wygranej wg. naszej oceny większe od 0,5 oraz prawdopodobieństwo wygranej wg. naszej oceny razy kurs zdarzenia wg. buka większe od 1. Przykładowo kurs zdarzenia 1,85 odpowiada prawdopodobieństwu 54% (1/1,85) czyli nasza ocena prawdopodobieństwa musi być wyższa - przewaga nad bukiem - dla 0,55x1,85>1.

Ale to wredne

 
Kryterium ma swoje maximum. Widać to dobrze pod koniec klipu wyżej, albo na grafice niżej. Co to znaczy? Nie można bezkarnie zwiększać stawki zakładu. Dalsze zwiększanie stawki ponad maximum wyliczone z kryterium do niczego dobrego nie prowadzi. Skutek jest wręcz odwrotny - zyski z gry spadają. Można mieć bardzo dobry system, ale można go bardzo łatwo położyć przeholowaną stawką. Nie ma sensu dalsze zwiększanie stawki. Matematycznie wygląda to tak, że przy stawkach zmierzających do podwojenia ponad optimum tempo wzrostu kapitału zmierza do zera.

Tempo przyrostu naszych zysków powiązane jest ze skutecznością systemu i wielkością ryzykowanej stawki. No nie jest to informacja warta reklamowania przez brokerów. Być może dlatego kryterium jest "zapomniane" na forexie - niech ludziska stawiają na ile broker pozwala - szybciej/więcej przegrają. Po co mają wiedzieć, że śrubowanie stawki może ich jedynie doprowadzić do MC niezależnie od zastosowanej strategii. Po coś ten "lewar" jest. Nie wszyscy muszą wiedzieć, że stawka zmienia się liniowo, a ryzyko geometrycznie.
 
Nie jest to też dobra informacja dla "producentów" wszelkiego rodzaju systemów zarabiających podobno niewiarygodne ilości pipsów. Można oszacować skuteczność takiej metody, zestawić z proponowaną stawką i sprawdzić czy to w ogóle jest możliwe w dłuższym horyzoncie. Ocenić w jakim stopniu podawane informacje mogą być wiarygodne.

Wykres funkcji
Wykres funkcji

The Kelly Criterion has applications in gambling and stocks. This video explains  the concept and how to use it in a variety of situations. There are 4 examples,  including coin flipping, stock investing, football betting, and lotteries.

Understanding Kelly Criterion


Jak z tego skorzystać


Całą naszą dotychczasową grę na forexie potraktujemy jako jeden zakład. Kasę straconą dodajemy do zarobionej i liczymy ile % stanowi kasa zarobiona. Przykładowo niech to będzie 52% - wygrana jest większa od przegranej, system zarabia. Ile w takim razie należy postawić w kolejnym zakładzie?

Liczymy: 52% to inaczej 0,52 podwajamy i odejmujemy 1. Zostaje 0,04 czyli kwotę jaką mamy przeznaczoną na grę mnożymy przez 0,04 (4%) i już wiemy ile można maxsymalnie postawić kwotowo (odległość SL) w kolejnym zakładzie. Po każdym zagraniu aktualizujemy: stan konta, skuteczność strategii i wyliczamy stawkę na kolejny zakład.
 
Krótko mówiąc nie należy nigdy ryzykować więcej niż wynosi nasza statystyczna przewaga nad organizatorem zakładów (brokerem). Jakie to proste. Chyba za proste aby to zamieszczać w literaturze przedmiotu czy "uczyć" na forexowych szkoleniach. Wystarczy zapamiętać ten "uproszczony" sposób liczenia i przed postawieniem kolejnego zakładu na forexie zastanowić się: czy aby nie za dużo stawiam?
 
Jeśli - posiadając bardzo dobrą strategię o skuteczności 52% (już po kosztach) - zaczniecie stawiać z 8% na zakład to MC macie pewne jak w banku. Myślicie, że skuteczność 52% to "kiepściocha"? 4% przewagi? Pomyślcie: kasyna z europejską ruletką mają mniejszą przewagę, i to przed kosztami, a i tak "jakoś" sobie radzą - robią z właścicieli milionerów. Jak mało potrzeba do "szczęścia".

Do porównania:
Zarządzanie pieniędzmi - Asia Forex System
Skuteczność systemu transakcyjnego na forexie

Blaski i cienie

 
Kryterium Kelly'ego nie jest lekiem na całe zło. Zastosowanie kryterium mówi jedynie o tym, że prawdopodobieństwo podwojenia kapitału jest większe od prawdopodobieństwa utraty połowy kapitału. Nadal jednak prawdopodobieństwo wcześniejszej utraty połowy kapitału niż jego podwojenia jest bardzo znaczne: 1:3. Z tego powodu w praktyce zaleca się stosować co najwyżej 1/2 Kelly, 1/3 Kelly lub 1/4 Kelly, a przy większej przewadze nie więcej niż 1/15. Ma to swoje matematyczne uzasadnienie w tym, że stopa zwrotu przy tej metodzie spada wolniej niż stawka zakładu. Zmniejszenie stawki o połowę nie spowoduje spadku zysków o połowę.

Chyba najsłabszym ogniwem w tej metodzie jest potrzeba zgromadzenie wartościowego materiału statystycznego potrzebnego do poprawnego wyznaczenia skuteczności stosowanej strategii. Błąd w szacowaniu skuteczności może mieć tu opłakane skutki (nadstawkowanie). Jak pamiętamy stosowanie kryterium ma tylko wtedy sens gdy dysponujemy wygrywającą strategią - więcej zarabia niż traci. Wtedy resztę "roboty" wykona za nas Pani Statystyka. Niestety na forexie króluje gra na "widzi mi się".

Podstawowe pytanie: czy naprawdę posiadamy zarabiającą strategię? Czy jej dodatnia skuteczność została stwierdzona w oparciu o odpowiednio duży materiał statystyczny zebrany na rzeczywistym rynku? Kryterium Kelly jest metodą, której siła opiera się na statystyce - konsekwentnym powtarzaniu tak strategii jak i obliczeń po każdym zagraniu. Zbiór przypadkowych danych z gry "na czuja" czy podobny mix zleceń to za mało do jej praktycznego wykorzystania. Pomiar skuteczności nie może być dziełem przypadku, 51% czy 52% czy 53% robi sporą różnicę i może zdecydować o naszym być albo nie być. Trzeba pamiętać, że w klasycznym hazardzie teoretyczny rozkład prawdopodobieństwa jest z góry znany. Na forexie nie mamy takich luxusów. Nie znamy wszystkich możliwych wyników i nie będziemy znać.
 
CZŁOWIEK ROZSĄDNY NIE GRA W GRY O NIEJASNYCH REGUŁACH.

Kolejne schody pojawią się gdy będziemy utrzymywać więcej niż jedno otwarte zlecenie. Błąd szacowania wzrośnie z powodu niezamkniętych zleceń. Z kolei niedokapitalizowani uczestnicy będą zmuszeni do znacznego zaokrąglania wyników aby "wpasować" się w dopuszczalny rozmiar kwotowy zleceń. Dla bezpieczeństwa należy zaokrąglać wyłącznie w dół. Czyli uogólniając w celach praktycznych - nigdy nie stawiamy więcej niż... Kryterium jest jak ściana, do której nie należy się nigdy zbliżać aby nie rozbić się o MC.

Jest to metoda dla ludzi, którzy potrafią konsekwentnie stosować daną strategię w długim terminie (setki zleceń). Pieniądze przychodzą tu z "czasem". Dla wygładzenia zmienności wyników zaleca się stosować kryterium na zdywersyfikowanym portfelu instrumentów finansowych. Pamiętajcie: kryterium stanowi optimum w sensie statystycznym.

... będę z Tobą (Kelly)

Blue Affair & Sasha Dith


Gotowa funkcja


... najważniejsze. Po lewej macie link MQL4/KJK, a pod nim do pobrania podręcznik. Pod sam koniec podręcznika (173 strona)  jest gotowa funcja kryterium, którą można "dokręcić" do robota.
[strona nie istnieje, próba dostępu kwiecień 2021]
 
Funkcja oblicza stosunek transakcji wygrywających do wszystkich transakcji o niezerowym saldzie oraz stosunek średniej wygranej do średniej straty i na tej podstawie wyznacza kryterium. Komu nie wystarcza zapamiętać aby nigdy nie stawiać więcej niż wynosi jego przewaga nad brokerem oraz ma zacięcie matematyczne może przeanalizować podaną funkcję i coś niecoś sobie ulepszyć...
 
Stosunek średniej straty do średniego zysku obliczany jest w ujęciu kwotowym. Proponuję rozważyć obliczanie w ujęciu procentowym. Czyli średni przyrost procentowy do średniego spadku procentowego. Przejaskrawiony przykład: przyrost o 1% ze 100$ wyniesie 1$, przyrost o 1% przy 1000$ wyniesie 10$. Skok 10x, ale procentowo ciągle jest to to samo. Pamiętacie: wynik kryterium jest podawany w procentach, a nie kwotowo.

Idealna strategia


Idealną strategią do zastosowania kryterium będzie zarabiająca strategia (pozytywna wartość oczekiwana) o stabilnych w czasie parametrach - powtarzalność, prawdopodobieństwo, średnia wygrana, średnia strata. Kryterium wykorzystuje średnie - im mniejszy rozrzut pojedynczych wyników tym lepiej. Natomiast idealny użytkownik to ktoś z bardzo grubym portfelem - niestety bez pieniędzy znacznie trudniej zarobić pieniądze. Przykładowo: przy małym kapitale będzie nas stać na grę na jednym instrumencie. W takim przypadku maksymalizując stopę zwrotu (dopuszczalną stawkę zakładu) łatwo możemy rozbić się o MC. Przy dużym kapitale możemy grać na ile Kelly pozwala na wielu instrumentach. Część rynków zamknie się zapewne na MC, ale sumaryczna stopa zwrotu dla całego portfela zostanie zmaksymalizowana, a ryzyko zminimalizowane - korzyści z dywersyfikacji. Z powodu jak wcześniej ktoś kto gra małym kapitałem - bez dywersyfikacji - musi grać ostrożniej jeśli nie chce skończyć na MC tym samym jego stopa zwrotu będzie niższa niż kogoś kto może sobie pozwolić na grę zdywersyfikowaną. Na forexie łatwo rozpoznacie tych co nie mają pieniędzy, wbrew matematyce grają najagresywniej.

Kto z tego korzysta

 
Tacy jak: Warren Buffett, Bill Gross czy Simons Jim.
Strategia uśredniania w dół - zarządzanie pieniędzmi na sposób Warrena Buffetta
 

Kelly na wyścigach konnych


Gra na forexie to prosta gra wygrał-przegrał. W przypadku wyścigów konnych jest trudniej bo startuje wiele zakładów na raz. Ile należy postawić na dowolnego konia oblicza się w 4 etapach. Pamiętajcie, że jak przyjmują zakład 1:15 to tak naprawdę szanse na zwycięstwo konia oceniają na 1:16. Dywersyfikacja w celu poprawy wyników polega w tym przypadku na obstawianiu więcej niż jednego konia w danym wyścigu. Jest to jednak ułomna dywersyfikacja ponieważ nie mamy do czynienia ze zdarzeniami niezależnymi.
 
Podobno Kelly nigdy nie wykorzystał swojej formuły w praktyce. Zmarł w 1965 roku w wieku 41 lat. Dopadł go udar na ulicy.

Wzorek

 
No i chyba nie uda się bez wzoru:
Kelly% = W - [(1 - W) / R]

W odniesieniu do forexiku może tak:

  • W - prawdopodobieństwo - w tym przypadku liczone jako trafność czyli % wygranych zleceń,  obliczamy stosunek zleceń wygranych do sumy zleceń wygranych i przegranych
  • R - w tym przypadku liczone jako skuteczność czyli wskaźnik średniego zysku % z transakcji wygranych do średniej straty % z transakcji przegranych, zastosowanie ujęcia % pozwala nam ujednolicić różne stawki kwotowe
Przykładowo:

Na sto zleceń były 52 wygrane czyli prawdopodobieństwo (trafność) 52/100= 0,52. Średni przyrost kapitału po każdym zleceniu wygranym był 1,1% natomiast średni spadek kapitału po każdym zleceniu przegranym był 1%. Skuteczność 1,1/1=1,1.
Kelly% = 0,52 - [(1 - 0,52) / 1,1]
 

I co z tego


Cholercia. Badania na historycznych danych finansowych pokazały, że wyliczane stawki są prawie identyczne jak stawki wyliczane na podstawie danych losowych.  Sporo roboty w to włożył Ed Thorp (pogrzebcie w internecie, nie mylić z Tharp'em). Profesor matematyki, a jednocześnie hazardzista. Zasłynął książką z 1962, w której wykazał, że licząc karty w blackjack'u można pokonać kasyno. Sprawdził to w praktyce grając w kasynach uzbrojony w system liczenia kart i system stawkowania. Był też pionierem wykorzystania komputerów podczas gry w kasynach. Domyślacie się jak kasyna go polubiły. Musiał się bawić w przebieranki i inne cuda na kiju. Impas pomiędzy graczami w blackjack'a i kasynami skończył się w ten sposób, że kasyna wprowadziły grę 4ema taliami zamiast jednej. Natomiast Thorp wszedł do panteonu sław związanych z blackjack'iem.

Według wyliczeń Thorp'a majątek Warrena Buffetta rozrastał się zgodnie z zasadami kryterium. Sam Thorp chwali się 20% wieloletnią stopą zwrotu (dodam tylko, że jego fundusz hedgingowy był oskarżany o nielegalne praktyki i został zlikwidowany). Wykręcanie wyższych zwrotów okazuje się matematyczną niemożliwością lub zwykłym szczęściem ?

Strona domowa:
www.edwardthorp.com
[strona nie istnieje, próba dostępu kwiecień 2021]
Znajdziecie na niej i to całkowicie za darmo takie pozycje jak:
THE KELLY CRITERION IN BLACKJACK, SPORTS
BETTING, AND THE STOCK MARKET czy
BEAT THE MARKET
Przy okazji porównajcie czym się różni strona kogoś co coś potrafi od setek stron ludzi, którzy raczej nic nie potrafią, a jedynie próbują Wam sprzedać prawie wszystko.
 
Formuła Kelly bazuje na błądzeniu losowym i tak wracamy do korzeni:
Hipoteza błądzenia losowego na forexie

Edward Thorp - Beat the dealer
Edward Thorp - Beat the dealer

Na koniec wypada wspomnieć o "ulepszonej" wersji Kelly. Kiedy nasza przewaga w grze wynosi 10%, 20% albo i ze 30% stawka wyliczana z kryterium rośnie do "astronomicznych" rozmiarów w stosunku do posiadanego kapitału. W takich przypadkach kilka stratnych transakcji z rzędu może doprowadzić do finansowej demolki. Chłopaki sprawdźcie sami. Z tego powodu zaleca się przy takiej przewadze nie stawiać więcej niż 1/15 wyliczonej stawki. Z tym problemem zmierzył się:


Ralph Vince - sztuka poprawiania

 
Do przejrzenia blog:
http://www.dailyspeculations.com
A to strona Ralpha:
http://ralphvince.com
 

Ralph Vince experyment

 
Experyment zaproponowany przez Ralpha polegał na rozegraniu 100 prób w grze, w której prawdopodobieństwo wygranej wynosi 60%, a pula startowa 1000$. Wygrywamy stawkę lub przegrywamy stawkę. O wielkości stawki decyduje gracz.  Proste - na sto zagrań wygramy jakieś 60 razy - przewaga po naszej stronie. Trudno nie zarobić. A jednak zaledwie 2 osoby na 40 kończyło grę z wynikiem dodatnim. Jak to możliwe? Co ciekawe Vince do experymentu zaprosił ludzi z doktoratami z tym, że odrzucił tych co mieli doktorat ze statystyki.
 

Usprawnienie

 
Optimal F czyli optymalna frakcja czyli optymalna część kapitału jaką można postawić. Usprawnienie polega na tym, że Ralph wielkość stawki uzależnia od największej historycznej procentowej straty (największa seria strat w ujęciu procentowym). Efekt jaki otrzymuje to generalizując wolniejszy wzrost stawki przy rosnącej przewadze w porównaniu do kryterium Kelly. Facet napisał kilka książek, więc bez problemu wyguglujecie sporo oryginalnego materiału z internetu jak i sam wzór.

Moje trzy grosze (konie)


Do czego mogę się przyczepić. Stawka uzależniona jest od pojedynczego zdarzenia - największej procentowej straty. Zależność stawki od dużej "wtopy". Teraz pytanie czy trafimy na nią na początku "kariery" czy później. Albo stawka będzie "przeszacowana" albo "niedoszacowana", ale w zasadzie nigdy optymalna. Teoretycznie wzór będzie "lepszy" dopóki nie trafimy na jeszcze większą stratę. Przy odrobinie szczęścia nie stanowi to problemu.
 
Problemem jest wiara w istnienie strategii o wysokiej przewadze. Niestety mnie jej brak. Po prostu nie wierzę w możliwość działania w realu strategii o znacznie większej przewadze niż ma kasyno czy broker. Jak ktoś pokazuje takie "coś" to najprawdopodobniej coś z "tym" jest nie tak - albo oszustwo, albo jakiś błąd w algorytmie. Nie zajmuję się takim "wodotryskami" ignorującymi siłę procentu składanego. W takim razie pozostaje pytanie czy "ulepszania" kryterium Kelly jest pragmatycznie uzasadnione czy to raczej sztuka dla wodotryskowego kiczu.

Rzeczywistość kontra reklamowe stopy zwrotu:
Procent składany czyli składanie (pochwała) ludzkiej głupoty - Lof der zotheid
Dlaczego nie widać wysokich stóp zwrotu:
Jak nie dać się oszukać na Forexie?
Ile pozwala zarobić przewaga brokera:
100 najbogatszych Polaków 2011. Czy grających na forexie?
 
Drobna przewaga jaką posiada broker wystarczyła głównemu współwłaścicielowi XTB wejść do 100ti najbogatszych ludzi w Polsce.

WDFX Marzec 09, 2017, 09:50:26 am -----

Witam,

mam pytanie odnośnie R bo nie mogę dojść do ładu i czasem wychodzą kosmiczne wartości np. 47%

Win/loss wychodzi mi 0.5322
a AvgWin/AvgLoss  wychodzi 0.5268

WinRate = 108/(108+50)=0,68

Kelly %= WinRate - ((1- WinRate) / (AvgWin/AvgLoss));

wydaje mi się, że źle liczę średni zysk/stratę
czy R to (zysk/ilość zyskownych) / (strata / ilość stratnych)

Jak ten wskaźnik średniego zysku/straty % powinienem policzyć?

Marzec 12, 2017, 09:56:23 pm -----

Przy dużej przewadze mogą wychodzić "kosmiczne wartości". Zostało to zasygnalizowane wyżej ... i jak sobie z tym radzić też.

Jak nie zarabiasz na forexie to nie musisz sobie KK zawracać głowy. Ogólna zasada jest taka aby zwiększać stawkę po wygranej i zmniejszać po przegranej czyli przykładowo stawka jako procent posiadanego kapitału gdzie ów procent bazuje na wielkości oczekiwanej. Po każdej zmianie kapitału ustalasz stawkę na nowo. Oczywiści dotyczy to gry jednym zleceniem. Przy dwóch trzeba stawkę podzielić przez dwa, a przy kolejnych odpowiednio przez ich ilość.

Przypomnę: beneficjentami stosowania KK będą gracze zarabiający, posiadający duży kapitał i dużą próbę statystyczną dla stosowanej strategii. Po więcej odsyłam do popularnej wyszukiwarki. Wystarczy wpisać "Kelly criterion pdf".

wtorek, 10 stycznia 2012

# AutoGraf 4 - robot do wspierania handlu na forexie

AutoGraf 4 - robot do wspierania handlu na forexie

AutoGraf 4

Rewelacyjny darmowy ukraiński produkt.
 
Strona domowa: http://autograf.dp.ua
Do pobrania wersja: rosyjska i angielska.
 
Najlepiej pobrać bezpośrednio ze strony (linki wyżej). Z innych źródeł (od brokerów) może mieć blokady. Najlepiej zainstalować na czystej instalce MT4 (nic się nie będzie "gryzło"). Program ma tyle opcji, że na dobrą sprawę nic więcej nie jest potrzebne do handlu półautomatycznego (można też podpiąć pod niego pełne automaty). Robot wymiata wszystkie inne "wynalazki". Ilość opcji może w pierwszej chwili przytłoczyć - trzeba opanować za co, która ikona odpowiada. Do wygodnej obsługi dobrze jest mieć mysz - "pocieranie" może być za wolne. Jedyna rzecz do jakiej mogę się przyczepić to brak prowadzenia zleceń po krzywych. Po prostych działa bez problemu. W przypadku zmiany ich położenia na wykresie robot automatycznie uwzględnia zmianę.

AutoGraf 4
AutoGraf 4

Komercjalizacja


Niestety produkt od czasu powstania wpisu w 2012 roku przeszedł proces komercjalizacji. Nie wiem czy można go uzyskać bezpłatnie w wersji "pełnosprawnej". Jak macie konto u jednego z "preferowanych" brokerów to pewnie bez problemu. Lista "preferowanych" jest na stronie AutoGrafa.

Uwagi


W języku MQL nie da się zaprogramować "przycisków", na które można najechać myszką i uruchomić klikając. W języku MQL "uruchomienie" realizowane jest przez "przeciągnięcie" obiektu w inne dowolne miejsce na wykresie. Czyli nie klikamy myszą tylko "łapiemy" i przesuwamy obiekt graficzny na inne miejsce - wtedy następuje wykonanie zapisanego "pod nim" polecenia.

Z AutoGraf'em 4 możecie spędzić wiele "niezapomnianych" nocy.
Dziewczyna w piosence obiecuje dać (tylko) sto nocy...

Злата Огневич - Ангелы

wtorek, 26 lipca 2011

# Dr Alexander Elder - szkolenie z MetaStock'a (angielski)

Dr Alexander Elder - szkolenie z MetaStock'a (angielski)

MetaStock

Originally presented on June 14, 2011, this webinar is presented by Dr. Alexander Elder.
Godzinka z Alexandrem Elderem, poznajcie jego umiejętności w roli prowadzącego, a przy okazji posmakujcie konkurencyjny produkt do MetaTrader'a - program MetaStock. Programowanie w Metastock'u jest znacznie łatwiejsze, testowanie znacznie wygodniejsze, baza gotowych wskaźników i strategii znacznie bogatsza - niestety program sporo kosztuje. Nie wiem czy jakiś broker forexowy oferuje konta z nim. Program ma moduł do podpięcia danych zewnętrznych, a to praktyka niemile widziana na detalicznym forexie.

Alexander Elder w Polsce - radziecki sposób na giełdowe straty

Trading Room Approach to Current Markets presented by Dr Alexander Elder

sobota, 18 czerwca 2011

# Jak napisać własnego robota pod MetaTradera na forex?

Wprowadzenie
 
No właśnie. Nie zawsze znacie język, nie zawsze macie chęci czy zdolności. Jak to zrobić nie mając o tym za dużo pojęcia?
 
Skorzystamy z:
Expert Advisor Builder for MetaTrader 4
działającego w przeglądarce.
 
Przy jego pomocy możecie zbudować robota do handlu automatycznego (zwanego też: "expert advisor" lub w skrócie "ea") w pół godziny. Gotowy projekt zapisujecie bezpośrednio z przeglądarki poleceniem na dole "Complete!" i już możecie testować/handlować. Proste i wygodne i co ważne całkowicie darmowe. Licencja umożliwia wykorzystanie stworzonych przy pomocy strony robotów w celach niekomercyjnych - nie można ich sprzedawać.   

Tu jest wyjaśnienie gdzie zapisać plik na własnym komputerze:
Jak to uruchomić - poradnik MetaTrader skrypty, wskaźniki, roboty 
 
Przy pomocy Expert Advisor'a może nie zbudujecie super skomplikowanej strategii, ale przeciętna strategia jest znacznie mniej rozbudowana niż możliwości apletu działającego na stronie. Stronę możecie też używać jako edytora do pisania kawałków kodu do wstawienia w inne projekty.
 
Pomocne materiały 

  • Biblioteka - ogromny zbiór gotowych skryptów, wskaźników, robotów do wykorzystania (rosyjski, angielski),
  • Dokumentacja - podręcznik programowania MQL (rosyjski, angielski),
  • Expert Advisor - link do strony z omawianym apletem to tworzenia strategii,
  • Język C - podręcznik języka C bardzo podobnego do języka MQL4, warto chociaż zerknąć jak działają pętle (polski),
  • KJK - podręcznik języka MQL po polsku - niestety strona już nie istnieje. Wielka szkoda. Link usunięty. Nie pamiętam jak się chłopak nazywał, ale wielkie podziękowania dla niego za ogrom bezinteresownej pracy.
 
Uwagi

Proszę zwrócić uwagę, że to opracowanie było pisane w 2011 roku. Nie mam zielonego pojęcia w jakim stopniu aplet uwzględnił zmiany jakie zaszły od tamtego czasu. Od dawna z niego nie korzystam.

To  co mogę podpowiedzieć. W razie problemów z apletem proszę zmienić przeglądarkę i spróbować ponownie.

Sądzę, że text niżej warto przeczytać bo zawiera też pewne moje doświadczenia "ponadczasowe" związane z programowaniem MQL. Mogą zaoszczędzić czasu.

piątek, 7 stycznia 2011

# Robot do stawiania siatki zleceń można użyć do stawiania piramid

Robot do stawiania siatki zleceń można użyć do stawiania piramid

Automat do stawiania siatki zleceń


Instrukcja oraz kod robota (EA) o nazwie "MakeGrid193" do stawiania siatki zleceń [1].

Instrukcja

Following on numerous mails, I would like to point out that this is NOT a trading system and a straight implementation of MakeGrid on any currency pair is bound to blow your account - sooner or later - unless you are very rich and patient.

Risk

As a simple exercise, try calculating the drawdown on your account for 1k lots on a 6 pip grid over a range of 3000 pips (this is typical of an annual move).
It comes out to something like 60'000 $ depending on the pair you trade. That is a lot of money for something like 300 pips a day.

Other than that, I found it to be a super tool to learn the different ways of trading grids and the variants that people in the boards were mentioning and trying.

After back and forward testing it with a lot of variants, I really changed my way of looking at grids. It is a really strange beast to trade.

Before trying this with real money, please do your maths. Your account chould be able to handle a 3000 pip drop in a few days without being near a margin call. Personally, I use 50 pip grids and count 4 - 6000 $ of Equity per currency traded per 1000 lot size. Also, watch out for rollover interest / charges as, depending on the broker, this can really mess you up. Having lots of GBP/JPY short positions is not a good idea!


What the EA does

The basic program does the following: Every few minutes ( determined by UpdateInterval ), it will calculate the first entry price at current price minus gridsize * gridsteps / 2.

ex. if we are at 1.2000, gridsize is 50, gridsteps is 12, 50 x 12 /2 = 300.
The first order would be placed at 1.2000 - .0300 = 1.1700 and the last order at 1.2300. This gives 12 orders at 50 pip intervals. Note that orders are placed at round numbers : 100, 150, 200 etc for a 50 pip grid, 10, 20, 30, 40 etc for a 10 pip grid.

Before placing orders, the EA looks to see if we either have a position or an existing order near the relevant price. By 'near' I mean within 9/10th of the grid size. i.e. for a 50 pip grid, the EA will look to see if we have an existing order or position 45pips above or 45 pips below the required price.
This looks a bit extreme but is a simple way to reduce the risk of duplicate positions.

If an order / position does not exist at the slot, it will create one (stop or limit) with the TP and SL as specified. TP is necessary, SL is optional.

There are many flage to determine whether the order should be placed. They are discussed below.

Once it has placed orders, it can do some housekeeping. For example, it can delete orders that are too far out ( in out example, orders that are more than 300pips away from the current price) so as to limit the server load. It can also delete orders after a specified number or hours.


Parameters

There are lots of different flags that allow you to test variants :

Lots - the lot size you want to trade.
GridSize - the interval between orders, in pips
GridSteps - the number of open orders the EA will try to set above and below the current price
TakeProfit - the TP in pips
StopLoss - If you want a stoploss, specify in pips. 0 means no stoploss.
wantLongs - if you want longs to be opened. ex. eur/huf, you may not want longs
wantShorts - if u want short positions opened.
- if both are true, both longs and shorts will be opened

Some people wanted to open positions only if 'with the trend' (i.e. for longs, above the current price ) and others only against the trend (i.e. if longs, only below the current price).

wantBreakout - sets orders above the price for longs and below the current price for shorts
wantCounter - sets long orders below the current price, shorts above current price.

GridMaxOpen - will make sure that no more than this number of positions is open at any one time. This is a way of limiting drawdown risk.

minFromPrice - this is the minumum distance, in pips, from the current price, that one can place a trade. For example, we only want a breakout of at least 30 pips from the current price. This can be used in conjunction with wantBreakout and wantCounter.

All the above parameters will work on ANY time frame chart and give exactly the same results. The parameters below are time frame dependent. I have mostly used them on 5 min charts but lots of people have tried on longer time frames.

It is possible to limit long orders only if they are above an EMA and shorts below. The EMA period is set by the EMAPeriod flag and the flag is limitEMA. If true, it will test this condition. The housekeeping routine will remove orders that end up on the wrong side of the EMA.

UseMACD and useOSMA are similar. If true, only longs will be placed if the MACD (OsMA) signal is above zero. All short orders will be cancelled.
The opposite is true for MACD below zero. All the MACD parameters are specifiable (fast and slow ema, signal period), including the chart time frame (timeFrame).
When either of these signals is true, it is possible to have the EA close open positions (whether gain or loss) that are on the wrong side. i.e. if MACD crosses up, all short orders are cancelled but if CloseOpenPositions is true, all short open positions are closed. The new grid is setup as a long grid.

These flage work in conjunction with wantLongs and wantShorts.
Hence it is possible to setup a grid of longs only, above the 34 EMA, above the current price plus 20 pips (minFromPrice) and only if MACD is positive.

With a bit of simple programming, you can change either of these to use your favourite index.


Future direction

I regularly add in suggestions other traders have found useful. I have not read this whole thread so if someone can summarise the variants that are needed, I may try to program them in.

However, as a good contribution to the advancement of grid trading, if someone has an effective way of limiting drawdown, I will be very happy to hear it.

Other than MACD and OsMA, I have not found that the other methods are useful in improving the system. These can limit the drawdown by up to about 50%.

In particular, I have found that any stoploss, time limit or CloseOpenPositions lead to losing strategies.

For real trading, the main direction I have moved in is trading a group of selected currency pairs. This is impossible to backtest properly on MetaTrader so I have an API as well as some custom programs and tons of tick data.


Conclusion

I hope this short tutorial on MakeGrid helps better understand how it works and the risks inherant in grid trading. If we can come up with ways to reduce drawdown, then we can have a good simple automated trading system that would be accessible to the normal retail trader.

Dream on!


Kod robota


//+------------------------------------------------------------------+
//|                                                  MakeGrid193.mq4 |
//|                                            Copyright © 2005, hdb |
//|                                       http://www.dubois1.net/hdb |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2005, hdb"
#property link      "http://www.dubois1.net/hdb"
//#property version      "1.93"
// DISCLAIMER ***** IMPORTANT NOTE ***** READ BEFORE USING *****
// This expert advisor can open and close real positions and hence do real trades and lose real money.
// This is not a 'trading system' but a simple robot that places trades according to fixed rules.
// The author has no pretentions as to the profitability of this system and does not suggest the use
// of this EA other than for testing purposes in demo accounts.
// Use of this system is free - but u may not resell it - and is without any garantee as to its
// suitability for any purpose.
// By using this program you implicitly acknowledge that you understand what it does and agree that
// the author bears no responsibility for any losses.
// Before using, please also check with your broker that his systems are adapted for the frequest trades
// associated with this expert.
// 1.8 changes
// made wantLongs and wantShorts into local variables. Previously, if u set UseMACD to true,
//       it did longs and shorts and simply ignored the wantLongs and wantShorts flags.
//       Now, these flags are not ignored.
// added a loop to check if there are 'illicit' open orders above or below the EMA when the limitEMA34
//       flag is used. These accumulate over time and are never removed and is due to the EMA moving.
// removed the switch instruction as they dont seem to work - replaced with if statements
// made the EMA period variable
//
// 1.9 changes - as per kind suggestions of Gideon
// Added a routine to delete orders and positions if they are older than keepOpenTimeLimit hours.
// Added OsMA as a possible filter. Acts exactly like MACD.
// Added 4 parameters for MACD or OsMA so that we can optimise
// Also cleaned up the code a bit.
// 1.92 changes by dave
// added function openPOsitions to count the number of open positions
// modified the order logic so that openPOsitions is not > GridMaxOpen
// 1.93 added long term direction indicator
// Added tradeForMinutes  - will only trade for this time then stop till EA is reset.
//
// modified by cori. Using OrderMagicNumber to identify the trades of the grid
extern int    uniqueGridMagic = 9999; // Magic number of the trades. must be unique to identify
                                       // the trades of one grid   
extern double Lots = 0.1;              //
extern double GridSize = 10;            // pips between orders - grid or mesh size
extern double GridSteps = 10;          // total number of orders to place
extern double TakeProfit = 10;         // number of ticks to take profit. normally is = grid size but u can override
extern double StopLoss = 0;            // if u want to add a stop loss. normal grids dont use stop losses
extern int    trailStop = 0;           // will trail if > 0
extern double UpdateInterval = 0.1;    // update orders every x minutes
extern bool   wantLongs = true;       // do we want long positions
extern bool   wantShorts = true;       // do we want short positions
extern bool   wantBreakout = true;    // do we want longs above price, shorts below price
extern bool   wantCounter = true;      // do we want longs below price, shorts above price
extern bool   limitEMA = false;        // do we want longs above ema only, shorts below ema only
extern int    EMAperiod = 34;          // the length of the EMA.. was previously fixed at 34
extern double GridMaxOpen = 0;         // maximum number of open positions : implemented in v1.92
extern bool   UseMACD = false;         // if true, will use macd >0 for longs only, macd <0 for shorts only
                                       // on crossover, will cancel all pending orders. Works in conjunction with wantLongs and wantShorts.
extern bool   UseOsMA = false;         // if true, will use OSMA > 0 for longs only, OSMA <0 for shorts only. used in same way as MACD.
                                       // If both UseMACD and UseOSMA atr true, OSMA is taken.
extern bool CloseOpenPositions = false;// if UseMACD, do we also close open positions with a loss?
extern bool   doHouseKeeping = true;   // this will remove long orders below the 34 ema and vv if limitEMA flag is true
extern double keepOpenTimeLimit = 0;   // in hours - if > 0, all open orders or positions will be closed after this period. fractions are permitted
extern int    emaFast = 12;            // parameters for MACD and OSMA
extern int    emaSlow = 26;            // parameters for MACD and OSMA
extern int    signalPeriod = 9;        // parameters for MACD and OSMA
extern int    timeFrame = 0;           // parameters for MACD and OSMA
extern int    minFromPrice = 0;        // minimum distance from price to place trades.
extern int    tradeForMinutes=0;       // will trade for this number of minutes after being initialised.
                                       // add/readd the EA before news and it will trade for these minutes then close out all positions at end
extern int    gridOffset = 0;          // positions are opened at price modulo GridSize and offset with this parameter.
                                       // used essentially to enter at non round numbers
// the following flags set bounds on the prices at which orders may be placed
// this code was developed for and is kindly made public by Exc_ite2

extern double longGridCenter = 0;      // defines the center point of a fixed width long grid                                      
extern double shortGridCenter = 0;     // defines the center point of a fixed width short grid                                      

extern double longGridLow = 0;         // defines the bottom of a fixed width long grid
extern double longGridHigh = 0;        // defines the top of a fixed width long grid

extern double shortGridLow = 0;         // defines the bottom of a fixed width short grid
extern double shortGridHigh = 0;        // defines the top of a fixed width short grid

extern double profitTarget = 99999;     // if > 0, will close out all positions once the $ target has been met

extern bool   suspendGrid = false;       // if set to true, will close all unfilled Orders
extern bool   shutdownGrid = false;      // if set to true, will close all orders and positions.
                                      
// modified by cori. internal variables only
string   GridName = "Grid";              // identifies the grid. allows for several co-existing grids - old variable.. shold not use any more
double   LastUpdate = 0;                 // counter used to note time of last update
double   startTime = 0;                  // counter to note trade start time.
double   closedProfit = 0;               // counts closed p&l
double   openProfit = 0;                 // counts open p&l
double   accumulatedProfit = 0;          // for back testing only
bool     haveHitTarget = false;          //  if there is a target, this flag says we have hit it
int      openLongs = 0;                  //  how many longs are open
int      openShorts = 0;                 // how many shorts are open
bool     gridActive = true;              // is the grid active
bool     gridOneShot = false;       // is this a one shot? if so, it stops after the profitTarget has been reached

//+------------------------------------------------------------------+
//| expert initialization function                                   |
//+------------------------------------------------------------------+
int init()
  {
//----
 #property show_inputs                  // shows the parameters - thanks Slawa...   
//----
   GridName = StringConcatenate( "Grid-", Symbol(),"-",uniqueGridMagic );
   return(0);
  }
//+------------------------------------------------------------------------+
//| tests if there is an open position or order in the region of atRate    |
//|     will check for longs if checkLongs is true, else will check        |
//|     for shorts                                                         |
//+------------------------------------------------------------------------+

bool IsPosition(double atRate, double inRange, bool checkLongs )
  {
     int totalorders = OrdersTotal();
     for(int i=0;i<totalorders;i++)                                // scan all orders and positions...
      {
        OrderSelect(i, SELECT_BY_POS);
// modified by cori. Using OrderMagicNumber to identify the trades of the grid // hdb added or gridname for compatibility
        if ( OrderSymbol()==Symbol() && ( (OrderMagicNumber() == uniqueGridMagic) || (OrderComment() == GridName)) )  // only look if mygrid and symbol...
         {  int type = OrderType();
            if (MathAbs( OrderOpenPrice() - atRate ) < (inRange*0.9)) // dont look for exact price but price proximity (less than gridsize) - added 0.9 because of floating point errors
              { if ( ( checkLongs && ( type == OP_BUY || type == OP_BUYLIMIT  || type == OP_BUYSTOP ) )  || (!checkLongs && ( type == OP_SELL || type == OP_SELLLIMIT  || type == OP_SELLSTOP ) ) )
                 {
                    return(true);
                 }
              }
         }
      }
   return(false);
  }

//+------------------------------------------------------------------+
//| Delete order after x hours                                     |
//+------------------------------------------------------------------+
void DeleteAfter( double xHours )    // delete pending orders or open positions after x hours
  {
  int totalorders = OrdersTotal();
  for(int i=totalorders-1;i>=0;i--)
     OrderSelect(i, SELECT_BY_POS, MODE_TRADES);
// we use iTime so it works in backtesting
     if ( OrderSymbol()==Symbol() && ( (OrderMagicNumber() == uniqueGridMagic) || (OrderComment() == GridName)) )  // only look if mygrid and symbol...
        {
            if (( MathAbs(iTime(Symbol(),5,0)-OrderOpenTime()) >= xHours*60*60 ) && (iTime(Symbol(),5,0)>0))
            {  bool result = false;
               //Close opened long position
               if ( OrderType() == OP_BUY )  result = OrderClose( OrderTicket(), OrderLots(), MarketInfo(OrderSymbol(), MODE_BID), 5, Red );
               //Close opened short position
               if ( OrderType() == OP_SELL )  result = OrderClose( OrderTicket(), OrderLots(), MarketInfo(OrderSymbol(), MODE_ASK), 5, Red );
               //Close pending order
               if ( OrderType() > 1 ) result = OrderDelete( OrderTicket() );
           }
        }
     
  } // proc DeleteAfter()


//+------------------------------------------------------------------------+
//| cancells all pending orders                                      |
//+------------------------------------------------------------------------+

void CloseAllPendingOrders( )
  {
     int totalorders = OrdersTotal();
     for(int i=totalorders-1;i>=0;i--)                                // scan all orders and positions...
      {
        OrderSelect(i, SELECT_BY_POS);
// modified as per cori. Using OrderMagicNumber to identify the trades of the grid // hdb added or gridname for compatibility
        if ( OrderSymbol()==Symbol() && ( (OrderMagicNumber() == uniqueGridMagic) || (OrderComment() == GridName)) )  // only look if mygrid and symbol...
         { 
          if ( OrderType() > 1 ) bool result = OrderDelete( OrderTicket() );
         }
      }
   return;
  }
//+------------------------------------------------------------------------+
//| cancells all pending orders    and closes open positions               |
//+------------------------------------------------------------------------+

void ClosePendingOrdersAndPositions()
{
  int totalorders = OrdersTotal();
  for(int i=totalorders-1;i>=0;i--)
 {
    OrderSelect(i, SELECT_BY_POS);
    bool result = false;
// modified by cori. Using OrderMagicNumber to identify the trades of the grid // hdb added or gridname for compatibility
    if ( OrderSymbol()==Symbol() && ( (OrderMagicNumber() == uniqueGridMagic) || (OrderComment() == GridName)) )  // only look if mygrid and symbol...
     {
           //Close opened long positions
           if ( OrderType() == OP_BUY )  result = OrderClose( OrderTicket(), OrderLots(), MarketInfo(OrderSymbol(), MODE_BID), 5, Red );
           //Close opened short positions
           if ( OrderType() == OP_SELL )  result = OrderClose( OrderTicket(), OrderLots(), MarketInfo(OrderSymbol(), MODE_ASK), 5, Red );
           //Close pending orders
           if ( OrderType() > 1 ) result = OrderDelete( OrderTicket() );
      }
  }
  return;
}

//+------------------------------------------------------------------------+
//| cancells all open orders which fall on the wrong side of the EMA                                     |
//+------------------------------------------------------------------------+

void CloseOrdersfromEMA( double theEMAValue )
  {
     int totalorders = OrdersTotal();
     for(int i=totalorders-1;i>=0;i--)                                // scan all orders and positions...
      {
        OrderSelect(i, SELECT_BY_POS);
        if ( OrderSymbol()==Symbol() && ( (OrderMagicNumber() == uniqueGridMagic) || (OrderComment() == GridName)) )  // only look if mygrid and symbol...
         { 
          int type = OrderType();
          bool result = false;
//if (type > 1) Print(type,"  ",theEMAValue,"  ",OrderOpenPrice());
          if ( type == OP_BUYLIMIT && OrderOpenPrice() <= theEMAValue ) result = OrderDelete( OrderTicket() );
          if ( type == OP_BUYSTOP && OrderOpenPrice() <= theEMAValue ) result = OrderDelete( OrderTicket() );
          if ( type == OP_SELLLIMIT && OrderOpenPrice() >= theEMAValue ) result = OrderDelete( OrderTicket() );
          if ( type == OP_SELLSTOP && OrderOpenPrice() >= theEMAValue ) result = OrderDelete( OrderTicket() );
         }
      }
   return;
  }

//+------------------------------------------------------------------------+
//| counts the number of open positions                                    |
//+------------------------------------------------------------------------+

int openPositions(  )
  {  int op =0;
     int totalorders = OrdersTotal();
     for(int i=totalorders-1;i>=0;i--)                                // scan all orders and positions...
      {
        OrderSelect(i, SELECT_BY_POS);
        if ( OrderSymbol()==Symbol() && ( (OrderMagicNumber() == uniqueGridMagic) || (OrderComment() == GridName)) )  // only look if mygrid and symbol...
         { 
          int type = OrderType();
          if ( type == OP_BUY ) {op=op+1;}
          if ( type == OP_SELL ) {op=op+1;}
         }
      }
   return(op);
  }

//+------------------------------------------------------------------+
//| Close on profit target                                           |
//+------------------------------------------------------------------+
void TestForProfit( int forMagic, double profittarget, bool testOpen, bool testHistory )                   // based on trailing stop code from MT site... but modified as per Hiro
  {
    if (profittarget > 0 )
     {
         closedProfit = 0;                // counts closed p&l

         if (testHistory == true) {
            int total = HistoryTotal();
            for(int i=0;i<total;i++)                                // scan all closed / cancelled transactions
              {
              OrderSelect(i, SELECT_BY_POS, MODE_HISTORY );
              if ( OrderSymbol() == Symbol() && OrderMagicNumber() == forMagic )  // only look if mygrid and symbol...
                {
                 closedProfit = closedProfit + OrderProfit();
               }
              }
          } else {
             accumulatedProfit =0;
          }
         
         openProfit = 0;                  // counts open p&l

         if (testOpen == true) {
            total = OrdersTotal();
            openLongs = 0;
            openShorts = 0;
            for(i=0;i<total;i++)                                // scan all open orders and positions
              {
              OrderSelect(i, SELECT_BY_POS );
              if ( OrderSymbol() == Symbol() && OrderMagicNumber() == forMagic )  // only look if mygrid and symbol...
                {
                  openProfit = openProfit + OrderProfit();
                  int type = OrderType();
                  if ( type == OP_BUY ) {openLongs=openLongs+1;}
                  if ( type == OP_SELL ) {openShorts=openShorts+1;}
                }
              }
           }
         if ( ( closedProfit + openProfit) >= (profittarget + accumulatedProfit) )
            {
               Print("Closing grid due to profit target");
               ClosePendingOrdersAndPositions();
               accumulatedProfit = accumulatedProfit + closedProfit + openProfit;
               haveHitTarget = true;
               if (gridOneShot==true) { gridActive = false; }
            }
     }
  }


//+------------------------------------------------------------------+
//| Trailing stop procedure                                          |
//+------------------------------------------------------------------+
void TrailIt( int byPips )                   // based on trailing stop code from MT site... thanks MT!
  {
  if (byPips >=5)
  {
  for (int i = 0; i < OrdersTotal(); i++) {
     OrderSelect(i, SELECT_BY_POS, MODE_TRADES);
     if ( OrderSymbol()==Symbol() && ( (OrderMagicNumber() == uniqueGridMagic) || (OrderComment() == GridName)) )  // only look if mygrid and symbol...
        {
            if (OrderType() == OP_BUY) {
               //if (Bid > (OrderValue(cnt,VAL_OPENPRICE) + TrailingStop * Point)) {
               //   OrderClose(OrderTicket(), OrderLots(), Bid, 3, Violet);
               //   break;
               //}
               if (Bid - OrderOpenPrice() > byPips * MarketInfo(OrderSymbol(), MODE_POINT)) {
                  if (OrderStopLoss() < Bid - byPips * MarketInfo(OrderSymbol(), MODE_POINT)) {
                     OrderModify(OrderTicket(), OrderOpenPrice(), Bid - byPips * MarketInfo(OrderSymbol(), MODE_POINT), OrderTakeProfit(), Red);
                  }
               }
            } else if (OrderType() == OP_SELL) {
               if (OrderOpenPrice() - Ask > byPips * MarketInfo(OrderSymbol(), MODE_POINT)) {
                  if ((OrderStopLoss() > Ask + byPips * MarketInfo(OrderSymbol(), MODE_POINT)) ||
                        (OrderStopLoss() == 0)) {
                     OrderModify(OrderTicket(), OrderOpenPrice(),
                        Ask + byPips * MarketInfo(OrderSymbol(), MODE_POINT), OrderTakeProfit(), Red);
                  }
               }
            }
        }
      }
      }

  } // proc TrailIt()


//+------------------------------------------------------------------+
//| script program start function                                    |
//+------------------------------------------------------------------+
int start()
  {
//----
   int    i, j,k, ticket, entermode, totalorders;
   bool   doit;
   double point, startrate, traderate, temp;
//---- setup parameters

 if ( TakeProfit <= 0 )                 //
   { TakeProfit = GridSize; }

 bool myWantLongs = wantLongs;
 bool myWantShorts = wantShorts;

//---- test if we want to shutdown or suspend
   if (suspendGrid == true) {       // close unfilled orders and then test if profit target
      CloseAllPendingOrders();
   }
   if (shutdownGrid == true) {      // close all positions and orders. then exit.. there is nothing more to do
      ClosePendingOrdersAndPositions();
      return(0);
   }
   if (haveHitTarget == true) {     // in case we hit target and there are still some open orders and positions
      ClosePendingOrdersAndPositions();
      if (gridOneShot==true) { gridActive = false; }
   }
//----
   if (gridActive == false) {       // if grid not active, do nothing.
     return(0);
   }

//----

  if (MathAbs(CurTime()-LastUpdate)> UpdateInterval*60)           // we update the first time it is called and every UpdateInterval minutes
   {
  
   if (profitTarget >0)
      {
        TestForProfit(uniqueGridMagic, profitTarget, true, false );
        if (!IsTesting()) {
            Comment(" v 1.93  "," Server time is ",TimeToStr(CurTime( )),
               "\n",
//               "\n","                  Closed p&l  = ",closedProfit,
               "\n","                  Open p&l    = ",openProfit,
//               "\n","                  Total p&l   = ",closedProfit + openProfit, 
               "\n","                  Long, Short = ",openLongs,"  ",openShorts,
               "\n","                  Net pos     = ",openLongs-openShorts,
               "\n",
               "\n","                  Balance     = ",AccountBalance(),
               "\n","                  Equity      = ",AccountEquity(),
               "\n","                  Margin      = ",AccountMargin(),
               "\n","                  Free mrg    = ",AccountFreeMargin(),
               ());
            }
      }

  
  
   LastUpdate = CurTime();
   point = MarketInfo(Symbol(),MODE_POINT);
   startrate = ( Ask + point*GridSize/2 ) / point / GridSize;    // round to a number of ticks divisible by GridSize
   k = startrate ;
   k = k * GridSize ;
   startrate = k * point - GridSize*GridSteps/2*point ;          // calculate the lowest entry point
   double myEMA=iMA(NULL,0,EMAperiod,0,MODE_EMA,PRICE_CLOSE,0);
   int currentOpen = 0;
   if ( GridMaxOpen > 0 ) {
      currentOpen = openPositions();
      if (currentOpen >= GridMaxOpen) {CloseAllPendingOrders(); }
   }
  
   if (limitEMA) { if (doHouseKeeping) CloseOrdersfromEMA(myEMA);}
   if (keepOpenTimeLimit > 0) DeleteAfter(keepOpenTimeLimit);
   if (trailStop >0) TrailIt(trailStop);
   if ( UseMACD || UseOsMA) 
     {
      if ( UseMACD )
        {
            double Trigger0=iMACD(NULL,timeFrame,emaFast,emaSlow,signalPeriod,PRICE_CLOSE,MODE_MAIN,0);
            double Trigger1=iMACD(NULL,timeFrame,emaFast,emaSlow,signalPeriod,PRICE_CLOSE,MODE_MAIN,1);
            double Trigger2=iMACD(NULL,timeFrame,emaFast,emaSlow,signalPeriod,PRICE_CLOSE,MODE_MAIN,2);
        }
      if ( UseOsMA )
        {
             Trigger0=iOsMA(NULL,timeFrame,emaFast,emaSlow,signalPeriod,PRICE_CLOSE,0);
             Trigger1=iOsMA(NULL,timeFrame,emaFast,emaSlow,signalPeriod,PRICE_CLOSE,1);
             Trigger2=iOsMA(NULL,timeFrame,emaFast,emaSlow,signalPeriod,PRICE_CLOSE,2);
        }

   
       if( (Trigger0 > 0) && (Trigger1 > 0)  &&  (Trigger2 < 0 ))     // cross up
        {
         CloseAllPendingOrders();
         if ( CloseOpenPositions == true ) { ClosePendingOrdersAndPositions(); }
        }
       if( (Trigger0<0) && (Trigger1<0)  &&  (Trigger2>0))     // cross down
        {
         CloseAllPendingOrders();
         if ( CloseOpenPositions == true ) { ClosePendingOrdersAndPositions(); }
        }
       myWantLongs = false;
       myWantShorts = false;
       if( (Trigger0>0) && (Trigger1>0)  &&  (Trigger2>0) && (wantLongs==true) )     // is well above zero
        {
         myWantLongs = true;
        }
       if( (Trigger0<0) && (Trigger1<0)  &&  (Trigger2<0) && (wantShorts== true) )     // is well below zero
        {
         myWantShorts = true;
        }
   }
   int myGridSteps = GridSteps;
   if (( GridMaxOpen > 0 ) && (currentOpen >= GridMaxOpen)) {
      myGridSteps = 0;
   }
  
    if (suspendGrid == true) {       //profit target and exit conditions tested so finished
      return(0);
   }

//   Print("Trigs ",    Trigger0,"  ",Trigger1,"  ",Trigger2,"  ",myWantLongs,"  ",myWantShorts,"  ",myGridSteps," ema ",myEMA," price ",Bid );

   //Print("start  1 ",startrate);    

   for( i=0;i<myGridSteps;i++) {

     startrate = ( Ask + point*GridSize/2 ) / point / GridSize;    // round to a number of ticks divisible by GridSize
     k = startrate ;
     k = k * GridSize ;
     startrate = k * point - GridSize*GridSteps/2*point ;          // calculate the lowest entry point
     traderate = startrate + i*point*GridSize + gridOffset*point;

     if (myWantLongs && (!limitEMA || traderate > myEMA)) {
          if (longGridCenter > point) {
               temp = GridSteps / 2;
               k = temp;
               startrate = longGridCenter - k * GridSize * point;
          }
          else {
               startrate = ( Ask + point*GridSize/2 ) / point / GridSize;    // round to a number of ticks divisible by GridSize
               k = startrate ;
               k = k * GridSize ;
               startrate = k * point - GridSize*GridSteps/2*point ;          // calculate the lowest entry point
          }

          traderate = startrate + i*point*GridSize + gridOffset*point;
          // now test if traderate within limits
          doit = true;
          if (traderate < longGridLow) {
                doit = false;
          }
          if ((traderate > longGridHigh) && (longGridHigh > point)) {
                doit = false;
          }
        
          if (( IsPosition(traderate,point*GridSize,true) == false ) && (doit == true)) {  // test if i have no open orders close to my price: if so, put one on

               double myStopLoss = 0;
               if ( StopLoss > 0 ) {
                    myStopLoss = traderate-point*StopLoss ;
               }
               if ( traderate > Ask ) {
               Print("BUY STOP",i);
                     entermode = OP_BUYSTOP;
               }
               else {
               Print("BUY LIMIT",i);
                     entermode = OP_BUYLIMIT ;
               }
               if ( ((traderate > (Ask +minFromPrice*Point) ) && (wantBreakout)) || ((traderate <= (Ask-minFromPrice*Point) ) && (wantCounter)) ) {
                     // modified by cori. Using OrderMagicNumber to identify the trades of the grid
                     ticket=OrderSend(Symbol(),entermode,Lots,traderate,0,myStopLoss,traderate+point*TakeProfit,GridName,uniqueGridMagic,0,Green);
               }
          }
      }
      if ( myWantShorts && (!limitEMA || traderate < myEMA)) {
          if (shortGridCenter > point) {
               temp = GridSteps / 2;
               k = temp;
               startrate = shortGridCenter - k * GridSize * point ;
          }
          else {
               startrate = ( Ask + point*GridSize/2 ) / point / GridSize;    // round to a number of ticks divisible by GridSize
               k = startrate ;
               k = k * GridSize ;
               startrate = k * point - GridSize*GridSteps/2*point ;          // calculate the lowest entry point
          }
    
          traderate = startrate + i*point*GridSize + gridOffset*point;
          // now test if traderate within limits
          doit = true;
    
          if (traderate < shortGridLow) {
              doit = false;
          }
          if ((traderate > shortGridHigh) && (shortGridHigh > point)) {
              doit = false;
          }

          if ((IsPosition(traderate,point*GridSize,false)== false ) && (doit == true)) {  // test if i have no open orders close to my price: if so, put one on
               myStopLoss = 0;
               if ( StopLoss > 0 ) {
                  myStopLoss = traderate+point*StopLoss ;
               }
               if ( traderate < Bid ) {
                  Print("SELL STOP",i);
                  entermode = OP_SELLSTOP;
               }
               else {
                  Print("SELL LIMIT",i);
                  entermode = OP_SELLLIMIT;
               }
               if ( ((traderate < (Bid -minFromPrice*Point) ) && (wantBreakout)) || ((traderate >= (Bid+minFromPrice*Point) ) && (wantCounter)) ) {
                // modified by cori. Using OrderMagicNumber to identify the trades of the grid
                ticket=OrderSend(Symbol(),entermode,Lots,traderate,0,myStopLoss,traderate-point*TakeProfit,GridName,uniqueGridMagic,0,Red);
               }
          }
       }
     }
   }
   return(0);
  }
//+------------------------------------------------------------------+


Temat wydzielony z:
Piramida użyta w forex konkursie BOSSY
------------------------------------------
[1] Robot napisany dla platformy MetaTrader4 (MT4), do znalezienia w popularnych wyszukiwarkach na hasło : "MakeGrid193".

Popularne posty