Help modify TP EA please

Hi,
can anyone help me, I have an EA, attached that handles partial close but I have 3 problems with it.
It only works on full lot size, not mini.
The EA does not preserve lots and just keeps on closing. I want to close half and keep half, but it will close half, then half again etc.
It does not handle 5 digit broker so you must close or set 30 for 3 pips. This is not huge problem but first 2 are hard to solve.

It is not a big bit of code and I have tried making changes but I cannot code to this level of understanding



//+--------------------------------------------------------+
//|                  e-Smart_Tralling                      |
//+--------------------------------------------------------+

extern   bool     UseOneAccount = true;
extern   bool     UseCloseOneThird = true;
extern   int      LevelProfit1 = 30;
extern   int      LevelMoving1 = 10;
extern   int      LevelProfit2 = 15;
extern   int      LevelMoving2 = 10;
extern   int      LevelProfit3 = 25;
extern   int      LevelMoving3 = 15;
extern   int      TrailingStop = 30;
extern   int      TrailingStep = 5;
extern   int      Slippage = 2;
extern   bool     ShowComment = true;
extern   bool     UseSound = true;
string   var_132 = "expert.wav";

//+------------------------------------------------------------------+

void deinit()
{
Comment("");
}

//+------------------------------------------------------------------+

void start()
{
double point;
int    digits;
string msg = "";

for (int i = 0; i < OrdersTotal(); i++)
   {
   if (OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
      {
      if (UseOneAccount || (OrderSymbol() == Symbol()))
         {
         ThreeLevelSystemOfOutput();
         digits = MarketInfo(OrderSymbol(),MODE_DIGITS);
         point = MarketInfo(OrderSymbol(),MODE_POINT);
         msg = msg + OrderSymbol() + "  Öåíà: " + DoubleToStr(OrderOpenPrice(),digits) + "  SL = " + DoubleToStr(OrderStopLoss(),digits) + " (" + StopLossInPoint() + ")
";
         }
      }
   }

if (ShowComment) Comment(msg);
}

//+------------------------------------------------------------------+

void ThreeLevelSystemOfOutput()
{
int profit = ProfitPosition();
int sl = StopLossInPoint();
int spread = MarketInfo(OrderSymbol(),MODE_SPREAD);

if ((profit > LevelProfit1) && (profit <= LevelProfit2) && (sl < LevelMoving1))
   {
   ModifyStopLossInPoint(LevelMoving1);
   if (UseCloseOneThird) CloseOneThird();
   }
if ((profit > LevelProfit2) && (profit <= LevelProfit3) && (sl < LevelMoving2)) ModifyStopLossInPoint(LevelMoving2);
if ((profit > LevelProfit3) && (sl < LevelMoving3)) ModifyStopLossInPoint(LevelMoving3);
if (profit > LevelMoving3 + TrailingStop + TrailingStep) TrailingPositions();
}

//+------------------------------------------------------------------+

[B]void CloseOneThird()
{
bool   result = false;
double lots = MathCeil(OrderLots() / 3.0 * 10.0) / 10.0;

if (lots > 0.0)
   {
   if (OrderType() == OP_BUY)
      {
      result = OrderClose(OrderTicket(),lots,Bid,Slippage,CLR_NONE);
      }
   if (OrderType() == OP_SELL)
      {
      result = OrderClose(OrderTicket(),lots,Ask,Slippage,CLR_NONE);
      }
   if (result && UseSound) PlaySound(var_132);
   }
}[/B]

//+------------------------------------------------------------------+

void TrailingPositions()
{
double bid;
double ask;
double point = MarketInfo(OrderSymbol(),MODE_POINT);

if (OrderType() == OP_BUY)
   {
   bid = MarketInfo(OrderSymbol(),MODE_BID);
   if (bid - OrderOpenPrice() > TrailingStop * point)
      {
      if (OrderStopLoss() < bid - (TrailingStop + TrailingStep - 1) * point)
         {
         ModifyStopLoss(bid - TrailingStop * point);
         return;
         }
      }
   }

if (OrderType() == OP_SELL)
   {
   ask = MarketInfo(OrderSymbol(),MODE_ASK);
   if (OrderOpenPrice() - ask > TrailingStop * point)
      {
      if ((OrderStopLoss() > ask + (TrailingStop + TrailingStep - 1) * point) || (OrderStopLoss() == 0))
         {
         ModifyStopLoss(ask + TrailingStop * point);
         }
      }
   }
}

//+------------------------------------------------------------------+

void ModifyStopLoss(double sl)
{
bool result = OrderModify(OrderTicket(),OrderOpenPrice(),sl,OrderTakeProfit(),0,CLR_NONE);
if (result && UseSound) PlaySound(var_132);
}

//+------------------------------------------------------------------+

void ModifyStopLossInPoint(int stoploss)
{
bool   result;
double sl = 0;
double point = MarketInfo(OrderSymbol(),MODE_POINT);

if (OrderType() == OP_BUY) sl = OrderOpenPrice() + stoploss * point;
if (OrderType() == OP_SELL) sl = OrderOpenPrice() - stoploss * point;

result = OrderModify(OrderTicket(),OrderOpenPrice(),sl,OrderTakeProfit(),0,CLR_NONE);
if (result && UseSound) PlaySound(var_132);
}

//+------------------------------------------------------------------+

int ProfitPosition()
{
double bid;
double ask;
double point = MarketInfo(OrderSymbol(),MODE_POINT);
double profit = 0;

if (OrderType() == OP_BUY)
   {
   bid = MarketInfo(OrderSymbol(),MODE_BID);
   profit = (bid - OrderOpenPrice()) / point;
   }
if (OrderType() == OP_SELL)
   {
   ask = MarketInfo(OrderSymbol(),MODE_ASK);
   profit = (OrderOpenPrice() - ask) / point;
   }
return(MathRound(profit));
}

//+------------------------------------------------------------------+

int StopLossInPoint()
{
double point = MarketInfo(OrderSymbol(),MODE_POINT);
double sl = 0;

if (OrderType() == OP_BUY) sl = (OrderStopLoss() - OrderOpenPrice()) / point;
if (OrderType() == OP_SELL) sl = (OrderOpenPrice() - OrderStopLoss()) / point;
if (OrderStopLoss() == 0.0) sl = -OrderOpenPrice() / point;
return(MathRound(sl));
}



Any help modifying this would be really helpful.

I made some updates in the code below (in bold) that may help you address issue #2 (“The EA does not preserve lots and just keeps on closing”). The main idea is to set a module level variable (closedHalf) that is checked to allow for closing 1/2 of the position and that resets when the position is closed. This only allows the code to close a fraction of the position once, rather than multiple times.
Note: these edits were not checked for syntax errors.

This is actually not that different from the logic of:
MQL4 - How To Create a Simple Forex MT4 Expert Advisor Template Using the RSI That Trades Once Per Bar

By the way, the code actually is set to close 1/3 not 1/2. (see red color in code)

It does not handle 5 digit broker so you must close or set 30 for 3 pips. This is not huge problem but first 2 are hard to solve.

Actually, that’s the way you handle a 5 digit broker. With a 4 digit broker you input pips. With a 5 digit broker you enter pippettes, so this is normal behavior.

From the code, I can’t tell why this wouldn’t work on a mini account as symbol names aren’t referenced (usually it’s because the code lacks a suffix like “m” at the end of the symbol name). Perhaps by changing all your inputs to pippettes on the 5 digit broker it will work as designed?

thats really great thank you, I will run it on my demo for a bit and report back how it goes, many thanks again
Kevin

Hi,

I’ve been running this EA but I can’t get it to manage all open trades unless I place it on each chart, which interferes with other EAs I want to run.
Is there any way this EA can be made to sit on any chart but manage ALL open positions, no magic numbers etc, just manage all positions in exactly the same way.

thanks
PG


//+--------------------------------------------------------+
//|                  close_half                      |
//+--------------------------------------------------------+

extern   bool     UseOneAccount = false;
extern   bool     UseCloseOneThird = true;
extern   int      LevelProfit1 = 100;
extern   int      LevelMoving1 = 11;
extern   int      LevelProfit2 = 150;
extern   int      LevelMoving2 = 50;
extern   int      LevelProfit3 = 250;
extern   int      LevelMoving3 = 150;
extern   int      TrailingStop = 300;
extern   int      TrailingStep = 50;
extern   int      Slippage = 2;
extern   bool     ShowComment = true;
extern   bool     UseSound = true;
string   var_132 = "email.wav";
bool   closedHalf = false;

//+------------------------------------------------------------------+

void deinit()
{
Comment("");
}

//+------------------------------------------------------------------+

void start()
{
double point;
int    digits;
string msg = "";
if (closedHalf == true && OrdersTotal() == 0) closedHalf = false;
for (int i = 0; i < OrdersTotal(); i++)
   {
   if (OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
      {
      if (UseOneAccount || (OrderSymbol() == Symbol()))
         {
         ThreeLevelSystemOfOutput();
         digits = MarketInfo(OrderSymbol(),MODE_DIGITS);
         point = MarketInfo(OrderSymbol(),MODE_POINT);
         msg = msg + OrderSymbol() + "  Öåíà: " + DoubleToStr(OrderOpenPrice(),digits) + "  SL = " + DoubleToStr(OrderStopLoss(),digits) + " (" + StopLossInPoint() + ")
";
         }
      }
   }

if (ShowComment) Comment(msg);
}

//+------------------------------------------------------------------+

void ThreeLevelSystemOfOutput()
{
int profit = ProfitPosition();
int sl = StopLossInPoint();
int spread = MarketInfo(OrderSymbol(),MODE_SPREAD);

if ((profit > LevelProfit1) && (profit <= LevelProfit2) && (sl < LevelMoving1))
   {
   ModifyStopLossInPoint(LevelMoving1);
   if (UseCloseOneThird && closedHalf == false) CloseOneThird();
   }
if ((profit > LevelProfit2) && (profit <= LevelProfit3) && (sl < LevelMoving2)) ModifyStopLossInPoint(LevelMoving2);
if ((profit > LevelProfit3) && (sl < LevelMoving3)) ModifyStopLossInPoint(LevelMoving3);
if (profit > LevelMoving3 + TrailingStop + TrailingStep) TrailingPositions();
}

//+------------------------------------------------------------------+

void CloseOneThird()
{
bool   result = false;

//2.0 is half, 3.0 is 1/3, 4.0 is a quarter and so on. Should only close out once.
double lots = MathCeil(OrderLots() / 2.0 * 10.0) / 10.0;

if (lots > 0.0)
   {
   if (OrderType() == OP_BUY)
      {
      result = OrderClose(OrderTicket(),lots,Bid,Slippage,CLR_NONE);
      }
   if (OrderType() == OP_SELL)
      {
      result = OrderClose(OrderTicket(),lots,Ask,Slippage,CLR_NONE);
      }
   if (result) {
      if (UseSound) PlaySound(var_132);
      closedHalf = true;
   }
   }
}

//+------------------------------------------------------------------+

void TrailingPositions()
{
double bid;
double ask;
double point = MarketInfo(OrderSymbol(),MODE_POINT);

if (OrderType() == OP_BUY)
   {
   bid = MarketInfo(OrderSymbol(),MODE_BID);
   if (bid - OrderOpenPrice() > TrailingStop * point)
      {
      if (OrderStopLoss() < bid - (TrailingStop + TrailingStep - 1) * point)
         {
         ModifyStopLoss(bid - TrailingStop * point);
         return;
         }
      }
   }

if (OrderType() == OP_SELL)
   {
   ask = MarketInfo(OrderSymbol(),MODE_ASK);
   if (OrderOpenPrice() - ask > TrailingStop * point)
      {
      if ((OrderStopLoss() > ask + (TrailingStop + TrailingStep - 1) * point) || (OrderStopLoss() == 0))
         {
         ModifyStopLoss(ask + TrailingStop * point);
         }
      }
   }
}

//+------------------------------------------------------------------+

void ModifyStopLoss(double sl)
{
bool result = OrderModify(OrderTicket(),OrderOpenPrice(),sl,OrderTakeProfit(),0,CLR_NONE);
if (result && UseSound) PlaySound(var_132);
}

//+------------------------------------------------------------------+

void ModifyStopLossInPoint(int stoploss)
{
bool   result;
double sl = 0;
double point = MarketInfo(OrderSymbol(),MODE_POINT);

if (OrderType() == OP_BUY) sl = OrderOpenPrice() + stoploss * point;
if (OrderType() == OP_SELL) sl = OrderOpenPrice() - stoploss * point;

result = OrderModify(OrderTicket(),OrderOpenPrice(),sl,OrderTakeProfit(),0,CLR_NONE);
if (result && UseSound) PlaySound(var_132);
}

//+------------------------------------------------------------------+

int ProfitPosition()
{
double bid;
double ask;
double point = MarketInfo(OrderSymbol(),MODE_POINT);
double profit = 0;

if (OrderType() == OP_BUY)
   {
   bid = MarketInfo(OrderSymbol(),MODE_BID);
   profit = (bid - OrderOpenPrice()) / point;
   }
if (OrderType() == OP_SELL)
   {
   ask = MarketInfo(OrderSymbol(),MODE_ASK);
   profit = (OrderOpenPrice() - ask) / point;
   }
return(MathRound(profit));
}

//+------------------------------------------------------------------+

int StopLossInPoint()
{
double point = MarketInfo(OrderSymbol(),MODE_POINT);
double sl = 0;

if (OrderType() == OP_BUY) sl = (OrderStopLoss() - OrderOpenPrice()) / point;
if (OrderType() == OP_SELL) sl = (OrderOpenPrice() - OrderStopLoss()) / point;
if (OrderStopLoss() == 0.0) sl = -OrderOpenPrice() / point;
return(MathRound(sl));
}


It is possible to do what you want. Just remove any restrictions on Magic Number and currency pair (Symbol()) when selecting orders to manage.

Hi,

I made Order Symbol == Order Symbol to nullify the effect of that line and get away from specifying symbol (other than the open orders.

It is cycling through the open orders and adjusting SL but it won’t close out half and I can’t figure out why.

I really thought I was making progress with all orders being updated but it was short lived :55:
The idea is to make it trail and partially close once on any/all open positions.


//+--------------------------------------------------------+
//|                  close_half                      |
//+--------------------------------------------------------+

extern   bool     UseOneAccount = true;
extern   bool     UseCloseOneThird = true;
extern   int      LevelProfit1 = -50;
extern   int      LevelMoving1 = -200;
extern   int      preserve_lots = 1.0;
extern   int      LevelProfit2 = 50;
extern   int      LevelMoving2 = -150;
extern   int      LevelProfit3 = 100;
extern   int      LevelMoving3 = -100;
extern   int      close_how_many_lots = 1.0;
extern   int      TrailingStop = 200;
extern   int      TrailingStep = 20;
extern   int      Slippage = 2;
extern   bool     ShowComment = true;
extern   bool     UseSound = true;
string   var_132 = "email.wav";
bool   closedHalf = false;

//+------------------------------------------------------------------+

void deinit()
{
Comment("");
}

//+------------------------------------------------------------------+

void start()
{
double point;
int    digits;
string msg = "";
if (closedHalf == true && OrdersTotal() == 0) closedHalf = false;
for (int i = 0; i < OrdersTotal(); i++)
   {
   if (OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
      {
      if (UseOneAccount || (OrderSymbol() == OrderSymbol()))
         {
         ThreeLevelSystemOfOutput();
         digits = MarketInfo(OrderSymbol(),MODE_DIGITS);
         point = MarketInfo(OrderSymbol(),MODE_POINT);
         msg = msg + OrderSymbol() + "  Open Price: " + DoubleToStr(OrderOpenPrice(),digits) + "  SL = " + DoubleToStr(OrderStopLoss(),digits) + " (" + StopLossInPoint() + ")
";
         }
      }
   }

if (ShowComment) Comment(msg);
}

//+------------------------------------------------------------------+

void ThreeLevelSystemOfOutput()
{
int profit = ProfitPosition();
int sl = StopLossInPoint();
int spread = MarketInfo(OrderSymbol(),MODE_SPREAD);

if ((profit > LevelProfit1) && (profit <= LevelProfit2) && (sl < LevelMoving1)) ModifyStopLossInPoint(LevelMoving1); 
if ((profit > LevelProfit2) && (profit <= LevelProfit3) && (sl < LevelMoving2)) ModifyStopLossInPoint(LevelMoving2); 
if ((profit > LevelProfit3) && (sl < LevelMoving3)) 
   {
   ModifyStopLossInPoint(LevelMoving3);
   if (UseCloseOneThird && closedHalf == false) CloseOneThird(); 
   Alert(" inside three level routine Closed Half ",Symbol()); 
   }

if (profit > LevelMoving3 + TrailingStop + TrailingStep) TrailingPositions();

}

//+------------------------------------------------------------------+

void CloseOneThird()
{
bool   result = false;

//2.0 is half, 3.0 is 1/3, 4.0 is a quarter and so on. Should only close out once.
double lots = MathCeil(OrderLots() / 2.0 * 10.0) / 10.0;

if (lots > preserve_lots)
   {
   if (OrderType() == OP_BUY)
      {
      result = OrderClose(OrderTicket(),close_how_many_lots,Bid,Slippage,CLR_NONE);
      }
   if (OrderType() == OP_SELL)
      {
      result = OrderClose(OrderTicket(),close_how_many_lots,Ask,Slippage,CLR_NONE);
      }
   if (result) {
      if (UseSound) PlaySound(var_132); Alert(" Closed Half ",Symbol());
      closedHalf = true; 
   }
   }
}

//+------------------------------------------------------------------+

void TrailingPositions()
{
double bid;
double ask;
double point = MarketInfo(OrderSymbol(),MODE_POINT);

if (OrderType() == OP_BUY)
   {
   bid = MarketInfo(OrderSymbol(),MODE_BID);
   if (bid - OrderOpenPrice() > TrailingStop * point)
      {
      if (OrderStopLoss() < bid - (TrailingStop + TrailingStep - 1) * point)
         {
         ModifyStopLoss(bid - TrailingStop * point);
         return;
         }
      }
   }

if (OrderType() == OP_SELL)
   {
   ask = MarketInfo(OrderSymbol(),MODE_ASK);
   if (OrderOpenPrice() - ask > TrailingStop * point)
      {
      if ((OrderStopLoss() > ask + (TrailingStop + TrailingStep - 1) * point) || (OrderStopLoss() == 0))
         {
         ModifyStopLoss(ask + TrailingStop * point);
         }
      }
   }
}

//+------------------------------------------------------------------+

void ModifyStopLoss(double sl)
{
bool result = OrderModify(OrderTicket(),OrderOpenPrice(),sl,OrderTakeProfit(),0,CLR_NONE);
if (result && UseSound) PlaySound(var_132);
}

//+------------------------------------------------------------------+

void ModifyStopLossInPoint(int stoploss)
{
bool   result;
double sl = 0;
double point = MarketInfo(OrderSymbol(),MODE_POINT);

if (OrderType() == OP_BUY) sl = OrderOpenPrice() + stoploss * point;
if (OrderType() == OP_SELL) sl = OrderOpenPrice() - stoploss * point;

result = OrderModify(OrderTicket(),OrderOpenPrice(),sl,OrderTakeProfit(),0,CLR_NONE);
if (result && UseSound) PlaySound(var_132);
}

//+------------------------------------------------------------------+

int ProfitPosition()
{
double bid;
double ask;
double point = MarketInfo(OrderSymbol(),MODE_POINT);
double profit = 0;

if (OrderType() == OP_BUY)
   {
   bid = MarketInfo(OrderSymbol(),MODE_BID);
   profit = (bid - OrderOpenPrice()) / point;
   }
if (OrderType() == OP_SELL)
   {
   ask = MarketInfo(OrderSymbol(),MODE_ASK);
   profit = (OrderOpenPrice() - ask) / point;
   }
return(MathRound(profit));
}

//+------------------------------------------------------------------+

int StopLossInPoint()
{
double point = MarketInfo(OrderSymbol(),MODE_POINT);
double sl = 0;

if (OrderType() == OP_BUY) sl = (OrderStopLoss() - OrderOpenPrice()) / point;
if (OrderType() == OP_SELL) sl = (OrderOpenPrice() - OrderStopLoss()) / point;
if (OrderStopLoss() == 0.0) sl = -OrderOpenPrice() / point;
return(MathRound(sl));
}


Thanks for any feedback, learning is slow,

PG