如何随着利润的增加在止损和当前价格之间保持10点的利润差距

时间:2019-05-16 21:46:14

标签: mql4 trading algorithmic-trading metatrader4

我正在尝试向this post中的解决方案添加另一个条件。我希望当交易获利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);
                        }

                }
    }

2 个答案:

答案 0 :(得分:2)

区块跟踪 您正在寻找的被称为“块尾”。与MT4随附的普通Trailing-Stop不同,您(将)需要:

  1. 仅以x点利润开始追踪。
  2. 块大小(以点为单位)(每次块移动后才跳SL)。
  3. 每次SL调整都需要按x点移动。

注意随之而来的一个常见问题是,交易员将跟踪设置为与当前市场过于紧密/紧密。 MT4不是HFT平台。不要头皮太近。大多数经纪人的最小冻结和止损距离。如果您将其设置在价格边缘附近,则会收到“ ERROR 130 Invalid Stop”错误。在合同规范中检查您的经纪人设置的符号。


参数

vsTicketIdsInCSV :要处理的已打开的TicketID列表(例如123、124、123123、1231、1)

viProfitToActivateBlockTrailInPip :跟踪只会在OrderProfit>此点之后开始。

viTrailShiftProfitBlockInPip :每次利润增加此点数时,SL都会跳转。

viTrailShiftOnProfitInPip :按此点数增加SL。


示例:

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

当订单以130点(100 + 30)的点差浮动盈利时,将开始大宗追踪。 SL将设置为保证20点的利润。

当浮动利润达到160pips(100 + 30 + 30)时,SL将设置为保证40pips(2x20pips)。


我已将此添加到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

答案 1 :(得分:0)

赏金索赔

道歉完全忘记了这一点:'( 我在https://github.com/fhlee74/mql4-EventTrader处扩展了原始EventTrader,以合并此Block-Trailer。但是,如果有人可以对其进行适当的测试,那就太好了。这是我的初始测试结果:在初始10pips触发后,每15pips利润便从原始的50pips SL变为40pips(此参数)。

要退出此线程的测试,请致电@ JosephLee74与我联系 确认后,我们将在这里更新。

enter image description here