Różne TrailingStop'y :)

O jezykach programowania w platformach i nie tylko.
Awatar użytkownika
Ykee
Gaduła
Gaduła
Posty: 198
Rejestracja: 15 lip 2008, 22:12

Różne TrailingStop'y :)

Nieprzeczytany post autor: Ykee »

Przedstawiam poniżej różne TS'y jak ktoś bardzo potrzebuje...

// -- TS zwykły

Kod: Zaznacz cały

int TS_Distance = 15;            // --- SL podąża za ceną w odległości 15pipsów
int TS_ActivatedLevel = 10;   // --- poziom od którego TS zaczyna działać. Standardowo zaczyna działać po przekroczeniu ceny otwarcia zlecenia

if( (OrderType() == OP_BUY) && (Bid > (OrderOpenPrice() + TS_ActivatedLevel*Point)) && (OrderStopLoss() < (Bid - TS_Distance*Point))) { 
     if(!OrderModify(OrderTicket(), OrderOpenPrice(), (Bid - TS_Distance*Point), OrderTakeProfit(), OrderExpiration(), Gold)) {
          Print(ErrorDescription(GetLastError())); return(0);
     }
}
if((OrderType() == OP_SELL) && (Ask < (OrderOpenPrice() - TS_ActivatedLevel*Point)) && (OrderStopLoss() > (Ask + TS_Distance*Point))) {
      if(!OrderModify(OrderTicket(), OrderOpenPrice(), (Ask + TS_Distance*Point), OrderTakeProfit(), OrderExpiration(), Gold)) {
          Print(ErrorDescription(GetLastError())); return(0);
      }
}
UWAGA !
Ponieważ w wielu TS będą się powtarzać pewne sytuacje, więc zapodaję wyjaśnienie ogólne, a jeśli będzie trzeba pod TS'ami będą dodatkowe.

Warunek sprawdzający składa się z trzech części:
1. sprawdza typ zlecenia (czy BUY, czy SELL) np.: OrderType() == OP_SELL
2. sprawdza czy cena przebiła poziom po którym TS ma zacząć działać np.: Ask < (OrderOpenPrice() - TS_ActivatedLevel*Point).
Jeśli chcemy żeby TS zadziałał od razu, to 2 część można wyciąć.
3. sprawdza konkretny warunek, w powyższym kodzie - czy cena jest w odległości większej niż zadana odległość 15pipsów od ostatniego znanego poziomu SL:
OrderStopLoss() > (Ask + TS_Distance*Point)

żeby TS zadziałał wszystkie trzy warunki muszą być spełnione!
a więc, jeśli było zlecenie BUY, to cena (Bid - dla SELL najlepiej Ask) musi przekroczy cenę otwarcia zlecenia (OrderOpenPrice()) + poziom 'aktywacji' (w przykladzie 10pipsów) - jeśli cena nie przekroczy tego progu SL nie będzie przesuwany, Trzeci warunek wtedy nie będzie sprawdzany, bo drugi nie został spełniony.
Dajmy na to kupiliśmy EURUSD po 1.400 ze SL = 15pipsów = 1.385, jeśli więc cena (Bid) przekroczy próg 1.400 + 10 = 1.410 nasz TS zacznie działać.
Wtedy sprawdzi czy cena (Bid) jest dalej od SL niż te 15pipsów, ponieważ osiągnęła poziom 1.411 to oczywiście warunek trzeci został spełniony i nasz SL zostanie przesunięty na poziom wyżej z zachowanie odległości TS_DIstance = 15p, czyli 1.396.
Jeśli cena pójdzie dalej np 1.420, to oczywiście nasz SL także 1.405. Ale jeśli teraz się cofnie na 1.415 to nie spełni się warunek trzecie i SL nie zostanie przesunięty, zostanie na poziomie 1.405.

UWAGA !
W powyższym kodzie (nie będzie tego poniżej, żeby nie zaciemniać) zlecenie OrderModify(...) jest zamknięte w funkcji warunkowej if(...) - to oznacza, że jeśli nie uda się zlecenie
!OrderModify(...), to zostanie wydrukowany w zakładce Dziennik (albo Strategie... nie pamiętam :) ) nr i opis błędu. Żeby jednak to się wydrukowało na samym początku naszego EA musimy includować następujące pliki:

Kod: Zaznacz cały

#include <stderror.mqh>
#include <stdlib.mqh>
I jeszcze jedna ważna rzecz!
Oczywiście żeby warunki w ogóle były sprawdzane musimy je zamknąć w pętli:

Kod: Zaznacz cały

int TS_Distance = 15;            // --- SL podąża za ceną w odległości 15pipsów
int TS_ActivatedLevel = 10;   // --- poziom od którego TS zaczyna działać. 

for(int i=0; i<OrdersTotal(); i++) {
     if(OrderSelect(i,SELECT_BY_POS, MODE_TRADES) && (OrderSymbol() == Symbol())) {
          ...
          [tutaj kod TS'a  -- warunki]
          ...
     }
}


Dodano po 17 minutach:

// --- TrailingStop skaczący

Kod: Zaznacz cały

int TS_Distance = 25;            // --- SL podąża za ceną w odległości 15pipsów 
int TS_ActivatedLevel = 10;   // --- poziom od którego TS zaczyna działać. Standardowo zaczyna działać po przekroczeniu ceny 
int TS_JumpingLevel = 10;   // --- odległość którą cena musi przejść, aby SL został przesunięty z zachowaniem TS_Distance
...

if((OrderType() == OP_BUY) && (Bid > (OrderOpenPrice() + TS_ActivatedLevel*Point)) && (OrderStopLoss() < (Bid - TS_JumpingLevels*Point - TS_Distance*Point))) {
     OrderModify(OrderTicket(), OrderOpenPrice(), (Bid - TS_Distance*Point), OrderTakeProfit(), OrderExpiration(), Gold)
}
if((OrderType() == OP_SELL) && (ask < (OrderOpenPrice() - TS_ActivatedLevel*Point)) && (OrderStopLoss() > (Ask + TS_JumpingLevel*Point + TS_Distance*Point))) {
      OrderModify(OrderTicket(), OrderOpenPrice(), (Ask + TS_Distance*Point), OrderTakeProfit(), OrderExpiration(), Gold)
}
W powyższym kodzie cena musi przejść nieco większy dystans niż tylko TS_Distance. Tutaj akurat odległość musi wynosić TS_JumpingLevel + TS_Distance = 35pipsów.
czyli jak kupimy po 1.400 to cena musi oddalić się od SL o 35p czyli dojść do 1.435, aby SL został przesunięty na 1.410. Od teraz cena musi znów oddalić się o 10 pipsów (TS_JumpingLevel)
żeby SL został przesunięty.
Od ceny (Bid) odjąłem TS_JumpingLevel oraz TS_Distance, ale można sam TS_JumpingLevel, byle był większy od TS_Distance, w przeciwnym wypadku SL może być przesuwany w górę i w dół.

Dodano po 21 minutach:

// --- TrailingStop idący po średniej kroczącej

Kod: Zaznacz cały

int TS_Distance = 25;            // --- SL podąża za ceną w odległości 15pipsów 
int TS_ActivatedLevel = 10;   // --- poziom od którego TS zaczyna działać. Standardowo zaczyna działać po przekroczeniu ceny 

double TS_MALevel = iMA(OrderSymbol(), 0, MAPeriod, MAShift, MAMethod, MAApliedPrice, 0); // -- nie mnożymy przez Point, bo już mamy wartość jako cenę
...
if((OrderType() == OP_BUY) && (Bid > (OrderOpenPrice() + TS_ActivatedLevel*Point)) && (OrderStopLoss() < TS_MALevel)) {
     OrderModify(OrderTicket(), OrderOpenPrice(), TS_MALevel, OrderTakeProfit(), OrderExpiration(), Gold);
}
if((OrderType() == OP_SELL) && (ask < (OrderOpenPrice() - TS_ActivatedLevel*Point)) && (OrderStopLoss() > TS_MALevel)) {
     OrderModify(OrderTicket(), OrderOpenPrice(), TS_MALevel, OrderTakeProfit(), OrderExpiration(), Gold);
}
UWAGA !
Ponieważ w większości sytuacji nie można ustawić SL bliżej ceny niż 15pipsów (zależy chyba od brokera), należy sprawdzić czy TS_MALevel nie jest bliżej ceny niż te 15p - zanim sprawdzimy warunek.

MAPeriod, MAShift, MAMethod, MAApliedPrice - to wartości które chcemy ustalić dla średniej kroczącej. Fajnie sprawdza się MAPeriod = 10, MAShift = 4, MAMethod = MODE_SMA (SimpleMovingAverage), MAApliedPrice = PRICE_CLOSE

W tym TS nasz SL może skakać w górę i w dół w zależności od tego jak się zmienia cena zamknięcia. Tzn, zanim świeczka się zbuduje

Innym wariantem (tutaj tych wariantów może być wiele) jest wyliczenie MA dla poprzedniej świeczki itp

Dodano po 16 minutach:

// --- TrailingStop kroczący po wartościach z poprzedniej (lub kilku) świecach

Kod: Zaznacz cały

int TS_ActivatedLevel = 10;   // --- poziom od którego TS zaczyna działać. Standardowo zaczyna działać po przekroczeniu ceny otwarcia zlecenia 
...
int n_bar = 3; // --- która świeczka
int spread=MarketInfo(OrderSymbol(),MODE_SPREAD); // --- spread dla danego symbolu

if( (OrderType() == OP_BUY) && (Bid > (OrderOpenPrice() + TS_ActivatedLevel*Point)) && (OrderStopLoss() < Low[n_bar])) {
     OrderModify(OrderTicket(), OrderOpenPrice(), Low[n_bar] - spread*Point, OrderTakeProfit(), OrderExpiration(), Gold);
} 
if( (OrderType() == OP_SELL) && (Ask < (OrderOpenPrice() - TS_ActivatedLevel*Point)) && (OrderStopLoss() > High[n_bar])) {
     OrderModify(OrderTicket(), OrderOpenPrice(), High[n_bar] + spread*Point, OrderTakeProfit(), OrderExpiration(), Gold);
}
Dla zlecenia BUY szukam najniższej wartości (Low) dla n-tej świeczki i sprawdzam czy SL nie jest dalej... a dla SELL, sprawdzam najwyższe wartości dla danej świeczki...
UWAGA !
TS BARDZO wrażliwy na zmianę TF, jak sprawdzamy na H1, to SL będzie ustawiony na n=tej świeczce w TS godzinowym ale, jeśli sobie tylko zerkniemy na M15 np, to nagle nasz SL przesunie się na n-tą świeczkę w TF 15-minutowym.
Dlatego albo nie przełączamy się między TF'ami, albo...

...albo korzystamy z iLow( string symbol, int timeframe, int shift) (lub iHigh(...) )

Kod: Zaznacz cały

OrderStopLoss() < iLow(OrderSymbol(), PERIOD_H1, n_bar)
- sprawdzamy ceną Low dla n-tej świeczki godzinowej... (dla zlecenia BUY)

innym wariantem może być wyszukanie najniższej wartości Low z n ostatnich świeczek (lub najwyższej High) np.:

Kod: Zaznacz cały

MathMin( iLow(OrderSymbol(), PERIOD_H1, 1), iLow(OrderSymbol(), PERIOD_H1, 2), iLow(OrderSymbol(), PERIOD_H1, 3)) 
tutaj najniższa wartość Low z trzech ostatnich świeczek godzinowych... implementację właściwą zostawiam zainteresowanym. :D

Jak ktoś wpadnie na jakiś inny TS to niech się dopisuje...
Pozdrawiam

StudenTM84
Stały bywalec
Stały bywalec
Posty: 53
Rejestracja: 07 maja 2009, 21:08

Nieprzeczytany post autor: StudenTM84 »

Cóż mogę powiedzieć... miło, że niektórzy się tak angażują dla innych :)
Niby wolontariat nie jest w modzie ale mam nadzieję, że kiedyś będę mógł się jakoś odwdzięczyć :D Na początek dałbym plusika ale chyba mi się już skończyły :/
Pozdrawiam!
Pewnych rzeczy nie można odkryć;
lecz tego nie stwierdzisz odgadywaniem ani snuciem domysłów;
nie, musisz być cierpliwy i przeprowadzić doświadczenia,
aż odkryjesz, że nie możesz czegoś poznać.
Mark Twain :)

Awatar użytkownika
Ykee
Gaduła
Gaduła
Posty: 198
Rejestracja: 15 lip 2008, 22:12

Nieprzeczytany post autor: Ykee »

// --- TrailingStop procentowy
(w odpowiedzi na http://www.forex.nawigator.biz/dyskusje ... php?t=8325 )

Kod: Zaznacz cały

...

if((OrderType() == OP_BUY) && (Bid > (OrderOpenPrice() + TS_ActivatedLevel*Point))){
     double exec_perc = ((High[0] - OrderOpenPrice()))/(OrderTakeProfit()-OrderOpenPrice());  // --- stosunek ceny (Bid) do TP
     double ts_lev = NormalizeDouble((OrderOpenPrice() + ((High[0] - OrderOpenPrice())*exec_perc),MarketInfo(OrderSymbol(),MODE_DIGITS); // -- stosunek ceny (Bid) do Ceny otwarcia...
     if(OrderStopLoss() < ts_lev){  
          OrderModify(OrderTicket(), OrderOpenPrice(), ts_lev, OrderTakeProfit(), OrderExpiration(), Gold);
     }
}
if((OrderType() == OP_SELL) && (Ask < (OrderOpenPrice() - TS_ActivatedLevel*Point))){
     double exec_perc = ((OrderOpenPrice() - Low[0]))/(OrderOpenPrice() - OrderTakeProfit()); 
     double ts_lev = NormalizeDouble((OrderOpenPrice() - ((OrderOpenPrice()-Low[0])*exec_perc),MarketInfo(OrderSymbol(),MODE_DIGITS);
     if(OrderStopLoss() > ts_lev){  
          OrderModify(OrderTicket(), OrderOpenPrice(), ts_lev, OrderTakeProfit(), OrderExpiration(), Gold);
     }  
}
Oczywiście musimy do czegoś ten procent wyliczyć, więc w złożonym zleceniu otwarcia musi być jakiś TP...

Awatar użytkownika
sam58
Bywalec
Bywalec
Posty: 20
Rejestracja: 02 sie 2007, 12:21

Nieprzeczytany post autor: sam58 »

Witam wszystkich serdecznie po dłuuuzzszej przerwie.
Mam prośbę o wyjaśnie pojęć zawartych w tym Trailingstopie w celu ustawienia odpowiednich parametrów z gory dzieki za pomoc

extern string SL_TP_Trail_Options="--------------------------";
extern int StopLoss.Pips=30;
extern int TakeProfit.Pips=160;
extern int Trail.Pips=15;
extern bool Trail.Starts.After.BreakEven=true;
extern int Move.To.BreakEven.at.pips=11;
extern int Move.To.BreakEven.Lock.pips=7;
extern int Move.Trail.Every.xx.Pips=0;
extern bool Use.ADR.for.SL.pips=false;
extern double tsl.divisor=0.40;
Nie masz wymaganych uprawnień, aby zobaczyć pliki załączone do tego posta.

Awatar użytkownika
Ykee
Gaduła
Gaduła
Posty: 198
Rejestracja: 15 lip 2008, 22:12

Nieprzeczytany post autor: Ykee »

...wiesz - nie lubię tak. Szczególnie, że w kodzie masz wyjaśnienie - po angielsku, ale jest http://translate.google.pl/#
a tak czuję się jak frajer, bo nie wiem, czy Ci się nie chce, czy faktycznie nie umiesz.

po kolej:

Kod: Zaznacz cały

extern string SL_TP_Trail_Options="--------------------------";  
// BEZ ZNACZENIA

extern int StopLoss.Pips=30;     
// STOP LOSS NA SZTYWNO

extern int TakeProfit.Pips=160;   
// TAKE PROFIT NA SZTYWNO

extern int Trail.Pips=15;            
// ODLEGŁOŚĆ W PIPSACH w jakiej ma być przesuwany SL za ceną 
// (nie jest używany, jeśli ustawisz Use.ADR.for.SL.pips na TRUE, lub gdy wpiszesz 0)

extern bool Trail.Starts.After.BreakEven=true;   
//   TRAILINGSTOP startuje, gdy przekroczy BreakEven

extern int Move.To.BreakEven.at.pips=11;    
//    Odległość w pipsach od ceny otwarcia zlecenia, po przekroczeniu której 
//   SL jest przestawiany na wartość Move.To.BreakEven.Lock.pips

extern int Move.To.BreakEven.Lock.pips=7; 
// Czyli w jakiej odległość od ceny otwarcia ma być przestawiony 
//SL po przekroczeniu Move.To.BreakEven.at.pips

extern int Move.Trail.Every.xx.Pips=0;   
// coś jak TS Jumping, przesuwa SL po każdym pokonaniu xx pipsów, na odległość Trail.Pips od aktualnej ceny

extern bool Use.ADR.for.SL.pips=false;  
//  używaj ŚredniDziennyZasięg do ustawiania SL.

extern double tsl.divisor=0.40; 
// jak powyższe masz na TRUE, to ADR jest dzielone przez ten dzielnik i tak wyliczany jest sztywny SL dla zlecenia
...mam nadzieję, że pomogłem. Pozdrawiam
More practice, more luck!

Awatar użytkownika
sam58
Bywalec
Bywalec
Posty: 20
Rejestracja: 02 sie 2007, 12:21

Podziękowanie

Nieprzeczytany post autor: sam58 »

Korzystałem z translatora , ale fachowych zwrotów nie da się tam wyjaśnić a mój niemłody już umysł nie wszystko rozumie.Wielkie dzięki za wyjaśnienia.
Pozdrawiam

Awatar użytkownika
Asia
Gaduła
Gaduła
Posty: 319
Rejestracja: 09 gru 2009, 02:00

wizualizacja

Nieprzeczytany post autor: Asia »

odnośnie TSów

jak zrobic żeby wymienione wyżej SLy pokazały sie na wykresie
jako linia z podaniem nazwy SL i aktualnej wartości SL

oraz aby tą linię można było przeciagać ręcznie po wykresie góra/dół
w celu "poprawienia" SL w zleceniu bez otwierania zlecenia

rozumiem, że "ręczna poprawka" pozwalałaby jedynie na "zmniejszenie" SL
bo w przeciwnym razie SL automatycznie zostanie "podciągnięty" do wartości wyliczonej z kodów podanych wyżej

green7
Maniak
Maniak
Posty: 2060
Rejestracja: 16 sty 2008, 18:44

Nieprzeczytany post autor: green7 »

Tak na szybki rzut okiem to widzę, że nie uwzględniasz w orderach typu SELL sytuacji gdy order nie ma początkowego SL (SL=0). Wtedy Twój trailing nie zadziała.

Awatar użytkownika
Ykee
Gaduła
Gaduła
Posty: 198
Rejestracja: 15 lip 2008, 22:12

Nieprzeczytany post autor: Ykee »

Witam
Asia pisze:jak zrobic żeby wymienione wyżej SLy pokazały sie na wykresie
jako linia z podaniem nazwy SL i aktualnej wartości SL [...]
Trailing Stopy przedstawione wyżej, są tylko propozycją dla programistów, do zakodowania, jak ktoś chce i potrzebuje jakiejś bazy... Jeśli chcesz Asiu aby można było przestawiać SL to musisz skorzystać z np.:
green7 pisze:Tak na szybki rzut okiem to widzę, że nie uwzględniasz w orderach typu SELL sytuacji gdy order nie ma początkowego SL (SL=0). Wtedy Twój trailing nie zadziała.
Możliwe. Nie sprawdzałem bez SL. Korzystając z rad doświadczonych Traderów, dążymy do sytuacji, gdzie każde zlecenie BUY/SELL będzie miało ustawiony SL, lub SL zostanie ustawiony przez aplikacje wspomagające (takie jak wyżej np.) ZAWSZE... wtedy problem, o którym wspomniałeś, nie istnieje... :)

Z drugiej strony takie zabezpieczenie nie było by trudne do napisanie, trzeba by tylko sprawdzać dodatkowo, czy SL != 0, jeśli tak to...
More practice, more luck!

green7
Maniak
Maniak
Posty: 2060
Rejestracja: 16 sty 2008, 18:44

Nieprzeczytany post autor: green7 »

Możliwe. Nie sprawdzałem bez SL. Korzystając z rad doświadczonych Traderów, dążymy do sytuacji, gdzie każde zlecenie BUY/SELL będzie miało ustawiony SL, lub SL zostanie ustawiony przez aplikacje wspomagające (takie jak wyżej np.) ZAWSZE... wtedy problem, o którym wspomniałeś, nie istnieje..
Istnieje istnieje - bo coraz więcej broków używa zleceń "market" - gdzie nie można od razu wysłać zlecenia z ustawionym SL. Trzeba to zrobić w 2 krokach: najpierw zlecenie z SL/TP=0, następnie zmiana SL/TP.
Green
Obrazek
Obrazek

ODPOWIEDZ