Как сохранить разрыв в 10 пипсов между стоп-лоссом и текущей ценой при увеличении прибыли - PullRequest
4 голосов
/ 17 мая 2019

Я пытаюсь добавить еще одно условие к решению в этой записи . Я хочу, чтобы стоп-лосс двигался на 10 пипсов, когда сделка приносит прибыль в 10 пипсов. Точнее сказать, я установил отложенный ордер на покупку, а стоп-лосс на 10 пунктов ниже цены открытия, а тейк-профит - на 50 пунктов. Если прибыль составляет 10 пипсов, то стоп-лосс переместится на 10 пипсов вверх, если прибыль переместится на 20 пипсов, то стоп-лосс переместится еще на 10 пипсов вверх, и то же самое произойдет для 30 и 40 пипсов. прибыль до достижения тейк-профита в 50 пипсов. Идея здесь заключается в том, что стоп-лосс увеличивается на 10 пунктов, а прибыль увеличивается на 10 пунктов, но стоп-лосс не падает. Таким образом, если стоп-лосс находится в прибыли на 10 пипсов, а цена - на 23 пипса, и он внезапно уменьшается, он выйдет из сделки со стоп-лоссом в 10 пипсов.

Настройка вышеуказанного условия кажется мне довольно сложной. Я не смог этого сделать.

Ниже приведена соответствующая часть кода, которую я пытаюсь решить (обратите внимание, что остальная часть кода совпадает с приведенным выше решением для связанного вопроса).

//=========================================================
    //CLOSE EXPIRED STOP/EXECUTED ORDERS
    //---------------------------------------------------------
    for( int i=OrdersTotal()-1; i>=0; i-- ) {
        if(OrderSelect( i, SELECT_BY_POS, MODE_TRADES ))
            if( OrderSymbol() == Symbol() )
                if( OrderMagicNumber() == viMagicId) {
                    if( (OrderType() == OP_BUYSTOP) || (OrderType() == OP_SELLSTOP) )
                        if((TimeCurrent()-OrderOpenTime()) >= viDeleteStopOrderAfterInSec)
                            OrderDelete(OrderTicket());

                    if( (OrderType() == OP_BUY) || (OrderType() == OP_SELL) )
                        if((TimeCurrent()-OrderOpenTime()) >= viDeleteOpenOrderAfterInSec) {
                            // For executed orders, need to close them
                            double closePrice = 0;
                            RefreshRates();
                            if(OrderType() == OP_BUY)
                                closePrice  = Bid;
                            if(OrderType() == OP_SELL)
                                closePrice  = Ask;
                            OrderClose(OrderTicket(), OrderLots(), closePrice, int(viMaxSlippageInPip*viPipsToPoint), clrWhite);
                        }

                        // WORKING ON 10 pip Gap for to increase stop loss by 10 pips as profits increase by 10 pips
                        int incomePips = (int) ((OrderProfit() - OrderSwap() - OrderCommission()) / OrderLots());

                        if (incomePips >= 10)   {
                           if(OrderType() == OP_BUY)
                              OrderModify(OrderTicket(), 0, OrderStopLoss() + 10*Point, OrderTakeProfit(), 0);
                           if(OrderType() == OP_SELL)
                              OrderModify(OrderTicket(), 0, OrderStopLoss() - 10*Point, OrderTakeProfit(), 0);
                        }

                }
    }

1 Ответ

3 голосов
/ 17 мая 2019

БЛОК-TRAILING То, что вы ищете, называется Block-Trailing. В отличие от обычного трейлинг-стопа, поставляемого с MT4, вам необходимо:

  1. Старт-трейлинг только на прибыли x-pip.
  2. Размер блока в пипсах (прыжок SL только после каждого движения блока).
  3. Каждая настройка SL должна двигаться в x-пунктах.

Примечание : Распространенная проблема, возникающая при этом, заключается в том, что трейдер устанавливает трейл слишком близко / близко к текущему рынку. MT4 не является платформой HFT. Не скальпируйте это слишком близко. Большинство брокеров имеют минимальное расстояние Freeze и StopLoss. Если вы установите его слишком близко к границе цены, вы получите ошибку «ОШИБКА 130 Invalid Stop». Проверьте настройки вашего брокера в спецификации контракта на наличие символа.


Параметры

vsTicketIdsInCSV : список ОТКРЫТЫХ идентификаторов Ticket для обработки (например, 123, 124, 123123, 1231, 1)

viProfitToActivateBlockTrailInPip : трейлинг начнется только после OrderProfit> этого пункта.

viTrailShiftProfitBlockInPip : SL будет увеличиваться при каждом увеличении прибыли на это количество пунктов.

viTrailShiftOnProfitInPip : Увеличить SL на это количество пунктов.


Пример:

viProfitToActivateBlockTrailInPip = 100, viTrailShiftProfitBlockInPip = 30, viTrailShiftOnProfitInPip = 20.

Блок-трейлинг начнется, когда ордер с плавающей прибылью составит 130 пунктов (100 + 30). SL будет гарантированно получать прибыль в 20 пунктов.

Когда плавающая прибыль достигает 160 пунктов (100 + 30 + 30), SL будет установлен на гарантию 40 пунктов (2x20 пунктов).


Я добавил это в GitHub: https://github.com/fhlee74/mql4-BlockTrailer Вклад ETH или BTC приветствуется.

Вот полный код для этого:

//+------------------------------------------------------------------+
//|                                                   SO56177003.mq4 |
//|                Copyright 2019, Joseph Lee, TELEGRAM @JosephLee74 |
//|                                             http://www.fs.com.my |
//+------------------------------------------------------------------+
#property copyright "Copyright 2019, Joseph Lee, TELEGRAM @JosephLee74"
#property link      "http://www.fs.com.my"
#property version   "1.00"
#property strict

#include <stderror.mqh> 
#include <stdlib.mqh> 

//-------------------------------------------------------------------
// APPLICABLE PARAMETERS
//-------------------------------------------------------------------
extern string       vsEAComment1                                = "Telegram @JosephLee74";      // Ego trip
extern string       vsTicketIdsInCSV                            = "123 , 124, 125 ,126 ";       // List of OPENED TicketIDs to process.
extern int          viProfitToActivateBlockTrailInPip   = 10;                                   // Order must be in profit by this to activate BlockTrail
extern int          viTrailShiftProfitBlockInPip            = 15;                                   // For every pip in profit (Profit Block), shift the SL
extern int          viTrailShiftOnProfitInPip               = 10;                                   // by this much
extern int          viMaxSlippageInPip                      = 2;                                    // Max Slippage (pip)


//-------------------------------------------------------------------
// System Variables
//-------------------------------------------------------------------
double  viPipsToPrice               = 0.0001;
double  viPipsToPoint               = 1;
int     vaiTicketIds[];
string  vsDisplay                   = "";

//-------------------------------------------------------------------



//+------------------------------------------------------------------+
//| EA Initialization function
//+------------------------------------------------------------------+
int init() {
    ObjectsDeleteAll(); Comment("");
    // Caclulate PipsToPrice & PipsToPoints (old sytle, but works)
    if((Digits == 2) || (Digits == 3)) {viPipsToPrice=0.01;}
    if((Digits == 3) || (Digits == 5)) {viPipsToPoint=10;}

    // ---------------------------------
    // Transcribe the list of TicketIDs from CSV (comma separated string) to an Int array.
    string vasTickets[];
    StringSplit(vsTicketIdsInCSV, StringGetCharacter(",", 0), vasTickets);
    ArrayResize(vaiTicketIds, ArraySize(vasTickets));
    for(int i=0; i<ArraySize(vasTickets); i++) {
        vaiTicketIds[i] = StringToInteger(StringTrimLeft(StringTrimRight(vasTickets[i])));
    }
    // ---------------------------------
    start();
    return(0);
}
//+------------------------------------------------------------------+
//| EA Stand-Down function
//+------------------------------------------------------------------+
int deinit() {
    ObjectsDeleteAll();
    return(0);
}


//============================================================
// MAIN EA ROUTINE
//============================================================
int start() {

    // ========================================
    // Process all the tickets in the list
    vsDisplay                   = "BLOCK-TRAILER v1.1 (Please note the Minimum Freeze/StopLoss level in Contract Specification to AVOID error 130 Invalid Stop when trailing).\n";
    double  viPrice         = 0;
    for(int i=0; i<ArraySize(vaiTicketIds); i++) {
        if(OrderSelect( vaiTicketIds[i], SELECT_BY_TICKET, MODE_TRADES ))
            if(OrderCloseTime() == 0 ) {
                // Only work on Active orders
                if(OrderType() == OP_BUY) {
                    RefreshRates();
                    double  viCurrentProfitInPip        = (Bid-OrderOpenPrice()) / viPipsToPrice;
                    double  viNewSLinPip                = ((viCurrentProfitInPip - viProfitToActivateBlockTrailInPip)/viTrailShiftProfitBlockInPip) * viTrailShiftOnProfitInPip;
                    double  viSLinPrice                 = NormalizeDouble(OrderOpenPrice() + (viNewSLinPip * viPipsToPrice), Digits);
                    double  viNewSLFromCurrentPrice = NormalizeDouble((Bid-viSLinPrice)/viPipsToPrice, 1);
                    vsDisplay   =   vsDisplay 
                                        + "\n[" + IntegerToString(OrderTicket()) 
                                        + "] BUY: Open@ " + DoubleToStr(OrderOpenPrice(), Digits) 
                                        + " | P/L: $" + DoubleToStr(OrderProfit(), 2) 
                                        + " / " + DoubleToStr(viCurrentProfitInPip, 1) + "pips.";
                    if(viCurrentProfitInPip < (viProfitToActivateBlockTrailInPip+viTrailShiftProfitBlockInPip))
                        vsDisplay   = vsDisplay + " " + int(((viProfitToActivateBlockTrailInPip+viTrailShiftProfitBlockInPip))-viCurrentProfitInPip) + " pips to start Trail.";
                    if(viCurrentProfitInPip >= (viProfitToActivateBlockTrailInPip+viTrailShiftProfitBlockInPip)) {
                        ResetLastError();
                        vsDisplay   = vsDisplay + " TRAILING to [" + DoubleToStr(viSLinPrice, Digits) + " which is " + DoubleToStr(viNewSLFromCurrentPrice, 1) + " pips from Bid]";
                        if((viSLinPrice > OrderStopLoss()) || (OrderStopLoss() == 0))
                            if(OrderModify(OrderTicket(), OrderOpenPrice(), viSLinPrice, OrderTakeProfit(), OrderExpiration())) {
                                vsDisplay = vsDisplay + " --Trailed SL to " + DoubleToStr(viSLinPrice, Digits);
                            }
                            else {
                                int errCode = GetLastError();
                                Print(" --ERROR Trailing " + IntegerToString(OrderTicket()) + " to " + DoubleToStr(viSLinPrice, Digits) + ". [" + errCode + "]: " + ErrorDescription(errCode));
                                vsDisplay = vsDisplay + " --ERROR Trailing to " + DoubleToStr(viSLinPrice, Digits);
                                vsDisplay = vsDisplay + " [" + errCode + "]: " + ErrorDescription(errCode);
                            }
                    }
                }
                if(OrderType() == OP_SELL) {
                    RefreshRates();
                    double  viCurrentProfitInPip    = (OrderOpenPrice()-Ask) / viPipsToPrice;
                    double  viNewSLinPip                = int((viCurrentProfitInPip - viProfitToActivateBlockTrailInPip)/viTrailShiftProfitBlockInPip) * viTrailShiftOnProfitInPip;
                    double  viSLinPrice                 = NormalizeDouble(OrderOpenPrice() - (viNewSLinPip * viPipsToPrice), Digits);
                    double  viNewSLFromCurrentPrice = NormalizeDouble((viSLinPrice-Ask)/viPipsToPrice, 1);
                    vsDisplay   =   vsDisplay 
                                        + "\n[" + IntegerToString(OrderTicket()) 
                                        + "] SELL: Open@ " + DoubleToStr(OrderOpenPrice(), Digits) 
                                        + " | P/L: $" + DoubleToStr(OrderProfit(), 2) 
                                        + " / " + DoubleToStr(viCurrentProfitInPip, 1) + "pips.";
                    if(viCurrentProfitInPip < (viProfitToActivateBlockTrailInPip+viTrailShiftProfitBlockInPip))
                        vsDisplay   = vsDisplay + " " + int(((viProfitToActivateBlockTrailInPip+viTrailShiftProfitBlockInPip))-viCurrentProfitInPip) + " pips to start Trail.";
                    if(viCurrentProfitInPip >= (viProfitToActivateBlockTrailInPip+viTrailShiftProfitBlockInPip)) {
                        ResetLastError();
                        vsDisplay   = vsDisplay + " TRAILING to [" + DoubleToStr(viSLinPrice, Digits) + " which is " + DoubleToStr(viNewSLFromCurrentPrice, 1) + " pips from Ask]";
                        if((viSLinPrice < OrderStopLoss()) || (OrderStopLoss()==0) )
                            if(OrderModify(OrderTicket(), OrderOpenPrice(), viSLinPrice, OrderTakeProfit(), OrderExpiration())) {
                                vsDisplay = vsDisplay + " --Trailed SL to " + DoubleToStr(viSLinPrice, Digits);
                            }
                            else {
                                int errCode = GetLastError();
                                Print(" --ERROR Trailing " + IntegerToString(OrderTicket()) + " to " + DoubleToStr(viSLinPrice, Digits) + ". [" + errCode + "]: " + ErrorDescription(errCode));
                                vsDisplay = vsDisplay + " --ERROR Trailing to " + DoubleToStr(viSLinPrice, Digits);
                                vsDisplay = vsDisplay + " [" + errCode + "]: " + ErrorDescription(errCode);
                            }
                    }
                }
            }
    }
    Comment(vsDisplay);
    return(0);
}

А вот скриншоты, показывающие, как это работает: enter image description here

...