// -- 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);
}
}
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

Kod: Zaznacz cały
#include <stderror.mqh>
#include <stdlib.mqh>
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)
}
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);
}
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);
}
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)
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))

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