Modificação de dois estágios de posições abertas
Introdução
O artigo nomeado T.DeMark's Approach to Technical Analysis" contém os coeficientes recomendados do comprimento de correção, particularmente 0,382 e 0,618. Usando esses coeficientes durante a abertura de posições, você pode evitar situações desnecessárias de fechamento e reabertura de posições em situações próximas à tendência. A função funciona bem, especialmente na situação de ocorrência de divergência.
Essa abordagem, contanto que o valor de lucro seja restabelecido, ajuda a detectar o surgimento de uma tendência "favorável". Por exemplo, como é mostrado na Fig. 1 e comparado à Fig. 2.
Algoritmo da função
A primeira modificação da ordem é realizada pelo valor específico de TrailingStop, as subsequentes configuram a StopLoss menor do que o nível de correção possível em 1 ou 2 pontos (nesse caso, o coeficiente de correção = 0,382 "Coeff_"). Aumente o valor de TakeProfit em cada passo em, por exemplo, metade do valor de TrailingStop (você pode escolher outro valor também). O valor de TakeProfit pode ser modificado também. Para esse fim, o valor zero da extern double March = 0; o operador deve ser configurado no início do programa.
Seria mais inteligente para traders que preferem que o suporte por análise de endereço de ações específicas de programa seja realizado diretamente durante o trading, transferir a variável do MagicNumber (número mágico) para o código do próprio Expert Advisor, onde a posição é aberta. Você pode ler informações mais detalhadas sobre o suporte de endereço específico no livro por S. Kovalyov publicado no website MQL4.com.
Vamos examinar o código sugerido da função em perspectiva no EA e os comentários sobre ele em detalhes:
//+------------------------------------------------------------------+ //| Two-stage variant of TrailingStop Modify_2step v5.mq4 | //| Orders modification: re-placing StopLoss and TakeProfit | //+------------------------------------------------------------------+ #property copyright "Copyright © 2008, GenKov" #property link Genkov@bk.ru //+------------------------------------------------------------------+ /* Magic=N
Magic=N - esse operador deveria ser inserido durante a abertura de posição logo depois do operador de controle de conformidade de condição no próprio programa (Expert Advisor) e na função! Não consegui criar um modificador universal, talvez em vista da imprevisibilidade do mercado, como parece para mim, então a função de tracking (movimento de S/L e T/P) e as condições de fechamento de posição deveriam ser escritas para cada tipo de condição de abertura de posição (por Magic=N).
extern double March = 1; // step of increasing TakeProfit // step 0 doesn't increase T/P.
S/L deve ser menor do que TrailingStop em 1 ponto para trazer a S/L para um nível seguro no primeiro triggering (acionamento). De tal forma, nos resguardamos de possíveis prejuízos (gerenciamento de capital).
extern double StopLoss = 15; extern double TrailingStop = 16; extern double TakeProfit = 60; // fitting with the tester //+------------------------------------------------------------------+ //void TrailingStop() int start() { //----------------------------------------------------------------+ int point = MarketInfo(Symbol(),MODE_POINT); // Point size int StopLev= MarketInfo(Symbol(),MODE_STOPLEVEL); double half_Trail = MathRound(TrailingStop/2);//half TrailingStop double Step = March*half_Trail; //value of TakeProfit increase if (TrailingStop<0) return; { for (int i=0; i<OrdersTotal(); i++) { if (OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==false) break; if (OrderSymbol()!=Symbol() || OrderMagicNumber()!=Magic) continue; if (OrderType()==OP_BUY) {
Primeiro estágio de modificação de posição BUY (Comprar)
if(OrderStopLoss()<OrderOpenPrice())//if S/L is less than the order open price { // and if the difference between the current price and the position opening price is greater than T/S if(Bid-OrderOpenPrice()>TrailingStop*Point) // && { // and if OrderStopLoss() is less than the difference between the current price and T/S if(OrderStopLoss()<Bid-TrailingStop*Point) { // calculate new T/P value double Now_T_P=(OrderTakeProfit()+Step*Point); { OrderModify(OrderTicket(),OrderOpenPrice(), OrderStopLoss()+TrailingStop*Point, OrderTakeProfit()+Step*Point,0,Aqua); // increasing T/P value return; } } } }
Entretanto, a seguinte situação pode ocorrer: a TakeProfit desviada se torna 2-3 pontos maior do que o nível de lucro planejado anteriormente, para e começa a diminuir vagarosamente.
Para evitar perder lucro, vamos inserir o operador de controle de situação que irá fechar a ordem no nível de lucro planejado. Se o preço continuar a crescer, então o desvio da StopLoss e TakeProfit vai continuar.
if(Bid-OrderOpenPrice()>=TakeProfit*Point && (Pr_Op_1-Pr_Op_0)>2*Point) { // Print(" Bid= ",Bid," >= ",OrderTakeProfit()," Magic= ",Magic); OrderClose(OrderTicket(),Lots,Bid,2,Red); }
// Second stage of BUY position modification
if(OrderStopLoss()>=OrderOpenPrice()) // StopLoss is on a lossless level { // calculate correction coefficient double Coeff_up = NormalizeDouble((Bid-OrderOpenPrice())*0.382,Digits); // and if the differnece between the current and the open price of the position is greater than corr. coefficient if(Bid-OrderOpenPrice()>Coeff_up) { // calculate the value of new StopLoss with the margin of 2 points double New_S_Loss = Bid-Coeff_up-2*Point; // and if the value of new StopLoss is higer than the current one if(New_S_Loss-OrderStopLoss()>3*Point) { // move S/L and T/P OrderModify(OrderTicket(),OrderOpenPrice(), New_S_Loss,OrderTakeProfit()+Step*Point,0,Yellow); } // Print(" Bid-OrderOpenPrice()= ",Bid-OrderOpenPrice()); // Print(" 2 Coeff_up= ",Coeff_up," Order_S_Los= ",New_S_Loss," Bid= ",Bid); return; } } }
A abordagem à posição curta é a mesma da descrita acima, então há menos comentários.
// ---------------------------- 1 stage of modification -----SELL-------------& else if(OrderType()==OP_SELL) { if(OrderStopLoss()>OrderOpenPrice())//if S/L is greater than order open price { if(OrderOpenPrice()-Ask>TrailingStop*Point && OrderStopLoss()>Ask+TrailingStop*Point) { OrderModify(OrderTicket(),OrderOpenPrice(), Ask+TrailingStop*Point,OrderTakeProfit()-Step*Point,0,SkyBlue); return; } } if(OrderOpenPrice()-Ask>=TakeProfit*Point && (Pr_Op_0-Pr_Op_1)>2*Point) { OrderClose(OrderTicket(),Lots,Bid,2,Red); } // ---------------------------- 2 stage of modification -----SELL-------------& if(OrderStopLoss()<=OrderOpenPrice()) // StopLoss is on a lossless level { // calculate correction coefficient double Coeff_down = NormalizeDouble((OrderOpenPrice()-Ask)*0.382,Digits); // and if the difference between the price of position opening and the current price is greater than corr. coefficient if(OrderOpenPrice()-Ask>Coeff_down) { // calculate the value of new StopLoss with the margin of 2 points New_S_Loss = Ask+Coeff_down+2*Point; // and if the value of new StopLoss is less than the current value if(New_S_Loss-OrderStopLoss()>3*Point) { // move S/L and T/P OrderModify(OrderTicket(),OrderOpenPrice(), New_S_Loss,OrderTakeProfit()-Step*Point,0,Khaki); return; } } } } } // -----------------------------------------------------------------------------------
Para transformar esse EA em uma função, é necessário comentar a função de início de int especial localizada no início do programa e substituir pela descrição descomentada da função de TrailingStop() localizada no início do programa. Descomentar a solicitação de função:
//TrailingStop();
no final do programa.
Se adicionarmos o bloco representado abaixo, então podemos verificar a função de forma eficiente usando-a como um EA no testador.
// -------------------------------------------------------------------------------- double Macd_m15_0= iMACD(NULL,PERIOD_M15,12,26,9,PRICE_CLOSE,MODE_MAIN,0); double Macd_m15_1= iMACD(NULL,PERIOD_M15,12,26,9,PRICE_CLOSE,MODE_MAIN,1); if(OrdersTotal()<2) { if(Macd_m15_0<Macd_m15_1) { OrderSend(Symbol(),OP_SELL,0.1,Bid,3,Ask+StopLoss*Point,Bid-TakeProfit*Point,"",Magic,0,Red); } if(Macd_m15_0>Macd_m15_1) { OrderSend(Symbol(),OP_BUY,0.1,Ask,3,Bid-StopLoss*Point,Ask+TakeProfit*Point,"",Magic,0,Blue); } return(0); } // -------------------------------------------------------------------------------- // TrailingStop(); } return(0); } // --- end --- &
Agora remova os comentários detalhados do texto código mencionado acima e o formule como uma função de execução: iremos obter o arquivo executável que é recomendado para ser armazenado no diretório terminal_folder\experts\include com a extensão .mqh ou no diretório terminal_folder\libraries com a extensão mq4.
//+------------------------------------------------------------------+ //| Modify_2_Step v5.mq4 | //| Copyright © 2008, GenKov | //| Genkov@bk.ru | //+------------------------------------------------------------------+ #property copyright "Copyright © 2008, GenKov" #property link "Genkov@bk.ru" extern double March = 1; // the step of TakeProfit increase // "0" step doesn't increase T/P. // S/L must be less than TrailingStop by 1 point to bring the S/L // on a safe level in the time of the very first triggering extern double StopLoss = 15; extern double TrailingStop = 16; extern double Lots = 0.1; extern double TakeProfit = 60; // fitting with the tester void TrailingStop() { int Magic=3090; // number of condition that opens position int point = MarketInfo(Symbol(),MODE_POINT); // Point size int StopLev= MarketInfo(Symbol(),MODE_STOPLEVEL); double half_Trail = MathRound(TrailingStop/2);//half TrailingStop double Step = March*half_Trail; //TakeProfit-а increase size if (TrailingStop<0) return; { for (int i=0; i<OrdersTotal(); i++) {//1 +cycle by orders search if (OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==false) break; if (OrderSymbol()!=Symbol() || OrderMagicNumber()!=Magic) continue; if (OrderType()==OP_BUY) { // --------------------------- 1 stage of modification -----BUY-------------& if(OrderStopLoss()<OrderOpenPrice())//if the S/L is less than the order open price { // and if the difference between the current and the open price is greater than T/S if(Bid-OrderOpenPrice()>TrailingStop*Point) // && { // and if OrderStopLoss() is less than the difference between current price andT/S if(OrderStopLoss()<Bid-TrailingStop*Point) { // calculate new T/P value double Now_T_P=(OrderTakeProfit()+Step*Point); { OrderModify(OrderTicket(),OrderOpenPrice(), OrderStopLoss()+TrailingStop*Point, OrderTakeProfit()+Step*Point,0,Aqua); // increase T/P value return; } } } } if(Bid-OrderOpenPrice()>=TakeProfit*Point) { OrderClose(OrderTicket(),Lots,Bid,2,Red); } //------------------------- 2 stage of modification -----BUY---------------& if(OrderStopLoss()>=OrderOpenPrice()) // StopLoss is on the lossless level { // calculate correction coefficient double Coeff_up = NormalizeDouble((Bid-OrderOpenPrice())*0.382,Digits); // and if the difference between the current and the position price is greater than correction coefficient if(Bid-OrderOpenPrice()>Coeff_up) { // clculate new StopLoss value with the margin of 6 points double New_S_Loss = Bid-Coeff_up-6*Point-StopLev*Point; // if the value of new StopLoss is greater than the current value if((New_S_Loss-OrderStopLoss())<2*Point) { // move S/L and T/P OrderModify(OrderTicket(),OrderOpenPrice(), OrderStopLoss(),OrderTakeProfit()+Step*Point/2,0,Yellow); } else { OrderModify(OrderTicket(),OrderOpenPrice(), New_S_Loss+1*Point,OrderTakeProfit()+Step*Point,0,Yellow); } return; } } } // ---------------------------- 1 stage of modification -----SELL-------------& else if(OrderType()==OP_SELL) { if(OrderStopLoss()>OrderOpenPrice())//if S/L is greater than the order open price { if(OrderOpenPrice()-Ask>TrailingStop*Point && OrderStopLoss()>Ask+TrailingStop*Point) { OrderModify(OrderTicket(),OrderOpenPrice(), Ask+TrailingStop*Point,OrderTakeProfit()-Step*Point,0,SkyBlue); return; } } if(OrderOpenPrice()-Ask>=TakeProfit*Point) { OrderClose(OrderTicket(),Lots,Bid,2,Red); } // ---------------------------- 2 stage of modification -----SELL-------------& if(OrderStopLoss()<=OrderOpenPrice()) // StopLoss is on the lossless level if(OrderOpenPrice()-Ask>=OrderTakeProfit()) OrderClose(OrderTicket(),Lots,Ask,2,Red); { // calculate correction coefficient double Coeff_down = NormalizeDouble((OrderOpenPrice()-Ask)*0.382,Digits); // and if the difference between the position open price and the current price is greater than corr. coefficient if(OrderOpenPrice()-Ask>Coeff_down) { // calculate the value of new StopLoss with the margin of 6 points New_S_Loss = Ask+Coeff_down+6*Point; // and if the value of new StopLoss is less than the current value if((OrderStopLoss()-New_S_Loss-StopLev*Point)>=10*Point) { // move S/L and T/P OrderModify(OrderTicket(),OrderOpenPrice(), New_S_Loss-5*Point,OrderTakeProfit()-Step*Point,0,Khaki); return; } } } } } return(0); } } // ---end----- void TrailingStop()--------------------------------& // this block is only for error controlling in the function code // int start() // { // if(25>26) TrailingStop(); // } // --------------------------------
Conclusão
Deveria ser dito que, se comparado com a "trailing stop exemplar" descrita no artigo "Trailing Stop padrão e saída de mercado" de Sergey Kravchuk, a versão sugerida é mais fácil de se entender e tem funcionado no meu EA (para dizer a verdade, em uma conta demo) e, como eu penso, se encaixa bem no trailing agressivo e moderado.
As versões em anexo:
v4 - com fechamento por S/L; v5 - com fechamento previsto por T/P; v6 - com um reflexo da previsão e do suporte de endereço pelo número mágico.
Traduzido do russo pela MetaQuotes Ltd.
Artigo original: https://www.mql5.com/ru/articles/1529
- Aplicativos de negociação gratuitos
- 8 000+ sinais para cópia
- Notícias econômicas para análise dos mercados financeiros
Você concorda com a política do site e com os termos de uso