I am trying to add another condition to the solution in this post. I want the stop loss to move by 10 pips when a trade is in 10 pips profit. To be more specific, say I've set a pending buy order and the stop loss is 10 pips below the open price and the take profit is 50 pips. If the trade is 10 pips in profit, then the stop loss would move 10 pips upwards, if the trade moves to 20 pips in profit then the stop loss would move another 10 pips upwards, and the same would occur for 30 and 40 pips in profit till the 50 pips take profit is reached. The idea here is the stop loss increases by 10 pips as profit increases by 10 pips, but the stop loss doesn't go down. So if the stop loss is at 10 pips in profit whiles the price is at 23 pips in profits and it suddenly decreases, it would exit the trade at the 10 pip profit stop loss.
Setting up the above condition seems quite complex for me. I haven't been able to get it done.
Below is the relevant part of the code I'm trying to solve (please note that the rest of the code is the same as the above linked question solution).
//=========================================================
//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);
}
}
}
A day trader may want to use a 10% ATR stop, meaning that the stop is placed 10% x ATR pips from the entry price. In this instance, the stop would be anywhere from 11 pips to 14 pips from your entry price. A swing trader might use 50% or 100% of ATR as a stop.
In general, the best ratio is 1:3, so the profit should be 3 times bigger than the loss. For example, if your Stop Loss equals 50 pips, the Take Profit should be 150 pips. In some cases, other Risk/Reward ratios are possible.
The problem is that using the default sell order options; you can only set 1 sell order at a time. This means you have to either place a “take profit” OR a “stop-loss” order. If you want to set both “take profit” and “stop-loss” orders simultaneously, you have to use the OCO option.
BLOCK-TRAILING What you are looking for is called a Block-Trailing. Unlike a normal Trailing-Stop that comes with MT4, you (will) need:
Note: A common problem that comes with this is when trader set the trail to be too close/tight to the current market. MT4 is not a HFT platform. Do not scalp it too close. Most brokers have a minimum Freeze and StopLoss distance. If you set it too near the price-edge, you will receive an "ERROR 130 Invalid Stop" error. Check your broker's setting in the Contract-Specification for the symbol.
Parameters
vsTicketIdsInCSV: List of OPENED TicketIDs to process (eg 123, 124, 123123, 1231 , 1)
viProfitToActivateBlockTrailInPip: Trailing will only start after OrderProfit > this pips.
viTrailShiftProfitBlockInPip: SL will jump each time profit increase by this number of pips.
viTrailShiftOnProfitInPip: Increase the SL by this number of pips.
Example:
viProfitToActivateBlockTrailInPip=100, viTrailShiftProfitBlockInPip=30, viTrailShiftOnProfitInPip=20.
The Block-Trailing will start when order is floating-profit by 130 pips (100+30). SL will be set to guarantee 20pip profit.
When floating-profit reach 160pips (100+30+30), SL will be set to guarantee 40pips (2x20pips).
I have added this to GitHub: https://github.com/fhlee74/mql4-BlockTrailer An ETH or BTC contribution will be appreciated.
Here is the full code for it:
//+------------------------------------------------------------------+
//| 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);
}
And here is the screen shots showing how it works:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With