News Trader

Sep 18, 2017
4
4
3
31
Good day Enivid

I was inquiring about the EA NewsTrader

well to make things short, the mt4 version is perfect and does what it is supposed to do. But there is one limitation on mt4 which is that it is single-threaded. In this was it will be completely slower than mt5 by milliseconds and milliseconds can define a winning or loosing trade.

The mt5 version of the EA on the other hand was created in 2015. As at that point in time, mt5 didn't support having buy and sell trades of the same instrument at the same time. But this has changed now and seeing that mt5 is multi-threaded and has other advantages, it will be the most logical way to go.

I am not so much of a coder, but I know enough to deduce the logical process of a code when I see one. That is why I need help

This is the mt4 version of the code I am interested in.

"
MQL4:
.............
 
     GetPositionStates();
 
     // Adjust SL and TP of the current position
     if ((HaveLongPosition) || (HaveShortPosition)) ControlPosition();
   else
    {
      int time = (int)TimeCurrent();
      if ((news_time - time <= SecondsBefore) && (news_time > time))
      {
         if (Direction == Buy) fBuy();
         else if (Direction == Sell) fSell();
         else if (Direction == Both)
         {
            fBuy();
            fSell();
         }
         else if (Direction == Random)
         {
            MathSrand((uint)TimeCurrent());
            if (MathRand() % 2 == 1) fBuy();
            else fSell();
         }        
         if (ECN_Mode) ControlPosition();
      }
    }
 
    return(0);
}
 
//+------------------------------------------------------------------+
//| Check what positions are currently open.                                    |
//+------------------------------------------------------------------+
void GetPositionStates()
{
   int total = OrdersTotal();
   for (int cnt = 0; cnt < total; cnt++)
   {
      if (OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES) == false) continue;
      if (OrderMagicNumber() != Magic) continue;
      if (OrderSymbol() != Symbol()) continue;
 
      if (OrderType() == OP_BUY) HaveLongPosition = true;
      else if (OrderType() == OP_SELL) HaveShortPosition = true;
    }
}
 
//+------------------------------------------------------------------+
//| Add SL/TP, adjust SL/TP, set breakeven, close trade.                    |
//+------------------------------------------------------------------+
void ControlPosition()
{
   int total = OrdersTotal();
   for (int cnt = 0; cnt < total; cnt++)
   {
      if (OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES) == false) continue;
      if (OrderMagicNumber() != Magic) continue;
      if (OrderSymbol() != Symbol()) continue;
 
      if ((OrderType() == OP_BUY) || (OrderType() == OP_SELL))
        {
           RefreshRates();
 
         int time = (int)TimeCurrent();
         // Need to adjust or add SL/TP
         if (time < news_time)
         {
            double new_sl, new_tp;
            if (OrderType() == OP_BUY)
            {
               new_sl = NormalizeDouble(Ask - SL * Point, Digits);
 
...........


Now what this does is to first check if you have any pending order or active position, if true go to the ControlPosition class where it will either adjust the SL/TP or create SL/TP (on ecn account) if and only if the time of news have not been passed and if the current time is beyond the seconds before news.

if any of this conditions are not met, it will skip directly to the type of Trailing Stop used.


the mt5 version of the code

MQL5:
.......if (Direction == Both_Pending) ControlPending();
     // Adjust SL and TP of the current position
     if (PositionSelect(Symbol())) ControlPosition();
    else  
    {
      int time = (int)TimeCurrent();
      if ((news_time - time <= SecondsBefore) && (news_time > time))
      {
         if (Direction == Buy) fBuy();
         else if (Direction == Sell) fSell();
         else if ((Direction == Both_Pending) && ((!HaveBuyPending) || (!HaveSellPending)))
         {
            fBuy_Pending();
            fSell_Pending();
         }
         else if (Direction == Random)
         {
            MathSrand((uint)TimeCurrent());
            if (MathRand() % 2 == 1) fBuy();
            else fSell();
         }        
         if (ECN_Mode) ControlPosition();
      }
    }
}
 
//+------------------------------------------------------------------+
//| Add SL/TP, adjust SL/TP, set breakeven, close trade.                    |
//+------------------------------------------------------------------+
void ControlPosition()
{
   double Ask = SymbolInfoDouble(Symbol(), SYMBOL_ASK);
   double Bid = SymbolInfoDouble(Symbol(), SYMBOL_BID);
 
   int time = (int)TimeCurrent();
   // Need to adjust or add SL/TP
   if (time < news_time)
   {
      double new_sl, new_tp;
      if (PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY)
      {
         new_sl = NormalizeDouble(Ask - SL * Point(), Digits());
         new_tp = NormalizeDouble(Ask + TP * Point(), Digits());
      }
      else if (PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL)
      {
         new_sl = NormalizeDouble(Bid + SL * Point(), Digits());
         new_tp = NormalizeDouble(Bid - TP * Point(), Digits());
      }
        if ((((new_sl != NormalizeDouble(PositionGetDouble(POSITION_SL), Digits())) || (new_tp != NormalizeDouble(PositionGetDouble(POSITION_TP), Digits()))) && (PreAdjustSLTP)) ||
           (((PositionGetDouble(POSITION_SL) == 0) || (PositionGetDouble(POSITION_TP) == 0)) && (ECN_Mode)))
        {
           Print("Adjusting SL: ", new_sl, " and TP: ", new_tp, ".");
            for (int i = 0; i < 10; i++)
            {
              bool result = Trade.PositionModify(Symbol(), new_sl, new_tp);
              if (result) return;
              else Print("Error modifying position: ", GetLastError());
            }
        }
   }
   // Check for breakeven or trade time out.
   else
   {
      if /*(*/(TrailingStop == Breakeven).......


From what I see, what this does is to check if there is any pending order on that asset, if there is any, it will move to the ControlPending class which will adjust the SL/TP until after the news time is past. Since it is a pending order, in theory, only one order will be honoured and it also performs an OCO and then makes use of the type of trailing stop selected.

If there is no pending order, it should check if there is any active order, adjust the SL/TP appropriately and then utilize the kind of TrailingStop selected. This is bearing in mind that as at then, mt5 couldn't have both buy and sell positions of the same asset at the same time. So it will only be bothering about one position per asset

If there is no pending order and there is no active position, then the EA should establish positions in the market if the user selects buy or sell or create pending orders if the user selects Both_Pending.


Where am I going with all this long story and I am sorry making the story so long, it is just that I understand the logic behind the code but I don't know how to write the code. I am just using basic english and logic here....


Now that mt5 supports buy and sell positions at the same time, is there a way to make the code run like that of mt4.

I tried a bit modifying the code. I am also sorry if I breached any copyright stuff.... I was just using logic and english...This is what i modified it to...


MQL5:
.......
/*     if (Direction == Both_Pending) ControlPending();
     // Adjust SL and TP of the current position
     if (PositionSelect(Symbol())) ControlPosition();
    else  
    { */
      int time = (int)TimeCurrent();
      if ((news_time - time <= SecondsBefore) && (news_time > time))
      {
         if (Direction == Buy) fBuy();
         else if (Direction == Sell) fSell();
         else if ((Direction == Both_Pending) && ((!HaveBuyPending) || (!HaveSellPending)))
         {
            fSell();
            fBuy();
         }
         else if (Direction == Random)
         {
            MathSrand((uint)TimeCurrent());
            if (MathRand() % 2 == 1) fBuy();
            else fSell();
         }        
         if (ECN_Mode) ControlPosition();
      }
    //}
}
 
//+------------------------------------------------------------------+
//| Add SL/TP, adjust SL/TP, set breakeven, close trade.                    |
//+------------------------------------------------------------------+
void ControlPosition()
{
   double Ask = SymbolInfoDouble(Symbol(), SYMBOL_ASK);
   double Bid = SymbolInfoDouble(Symbol(), SYMBOL_BID);
 
   int total = OrdersTotal();
 
   for (int cnt = 0; cnt < total; cnt ++)
   {
  /* if (ORDER_MAGIC() != Magic) continue;
   if (ORDER_SYMBOL() != Symbol()) continue;
  */
   if  ((PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY) || (PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL))
   {
 
   int time = (int)TimeCurrent();
   // Need to adjust or add SL/TP
   if (time < news_time)
   {
      double new_sl, new_tp;
      if (PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY)
      {
         new_sl = NormalizeDouble(Ask - SL * Point(), Digits());
         new_tp = NormalizeDouble(Ask + TP * Point(), Digits());
      }
      else if (PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL)
      {
         new_sl = NormalizeDouble(Bid + SL * Point(), Digits());
         new_tp = NormalizeDouble(Bid - TP * Point(), Digits());
      }
        if ((((new_sl != NormalizeDouble(PositionGetDouble(POSITION_SL), Digits())) || (new_tp != NormalizeDouble(PositionGetDouble(POSITION_TP), Digits()))) && (PreAdjustSLTP)) ||
           (((PositionGetDouble(POSITION_SL) == 0) || (PositionGetDouble(POSITION_TP) == 0)) && (ECN_Mode)))
        {
           Print("Adjusting SL: ", new_sl, " and TP: ", new_tp, ".");
            for (int i = 0; i < 10; i++)
            {
              bool result = Trade.PositionModify(Symbol(), new_sl, new_tp);
              if (result) return;
              else Print("Error modifying position: ", GetLastError());
            }
        }
   }
   // Check for breakeven or trade time out.
   else
   {
      if /*(*/(TrailingStop == Breakeven)
 
...........


I just tried to copy the mt4 version of the code. I commented out the part where the EA had to check for any pending or active order since there will be no need for that. I assume that I will not have any positions at that point in time, so no need checking for any pending orders or active positions. and also if I had manually set a pending order, the EA wouldn't mess with it so much.

Then I also changed the fbuy_Pending and fsell_Pending to just fbuy and fsell. This will skip the Pending order classes and go straight to creating positions instead of pending orders (Just how the mt4 version works)

But the issue I ran into was the fact that after creating the positions, it will only modify the SL/TP or the buy position leaving the sell position the same.

i also tried adding a count.... this code right here I copied from the mt4 version of the EA. I had to go through the MQL5 documentation and see the substitutes for those codes...

MQL5:
.....
 
int total = OrdersTotal();
 
   for (int cnt = 0; cnt < total; cnt ++)
   {
  /* if (ORDER_MAGIC() != Magic) continue;
   if (ORDER_SYMBOL() != Symbol()) continue;
  */
   if  ((PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY) || (PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL))
......

So I introduced a count just like in the mt4, the ordermagic and ordersymbol seemed to be throwing errors during compilation so I commented that part out but i think that the vital code which is missing is this....


MQL4:
....
 
if (OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES) == false) continue;
 
....

because even after the modification, the EA runs well but it only modifies the buy orders as mentioned earlier. Then when I look at the journal and experts tab, i see that it modifies the buy position to the appropriate SL/TP and then still modifies the buy position again, which is null since the buy order has already been modified, so no need modifying to the same SL/TP, therefore the terminal just does nothing about it. For some reason, it is not recognizing the sell position.

i guess that what the EA does is look at the position book for buy and sell orders and then modify them accordingly just before the news. but the snippet of code is missing to make the EA recognize the buy and sell order separately.

Please help....

Sorry once again for making this so long... I just had to explain it in the way I was seeing it. I may be wrong and only the creator of the code knows how to fix it. Like I said.... I am no coder, I just use basic english and logic.

Thank you...
 
  • 👍
Reactions: mrsvak and Enivid
Sep 18, 2017
4
4
3
31
Thank you for reminding me about the fact that the MT5 version News Trader is incompatible with the hedging mode.

If you can wait 2-3 days, I will update the EA to work properly in MT5 in hedging mode.


Thank you Enivid. Or better still you could edit the code to the EA and have 3 versions for metatrader.

1. Metatrader 4 (which already has selection for ecn and non-ecn mode) <== This one is already available and perfect
2. Metatrader 5 without hedging mode <== This one is available and perfect but it is susceptible to slippage
3. Metatrader 5 with hedging mode... <== This is the one which the force would be with

or you could just copy and paste the adjusted code in the same mq5 code as the original mt5 EA and put it in a different class... kind of how you specified the ControlPending and ControlPosition so that one has to select the mode of operation and then the EA just jumps and utilizes the selected class codes..

Anything that works....

Thank you.
 
Sep 18, 2017
4
4
3
31
Also please on the EA meant for the cTrader, it seems to open trades earlier than specified.

For instance if I had a news by 13:30gmt broker time (which is the time the algo uses) andI set the seconds before to like say 10secs meaning I want the trades to be opened at 13:29:50 gmt, and click on the play button for the algo, it ends up opening the trade about 30-20secs. It will open the trade at let's say 13:29:32 gmt or some time like that which is not 13:29:50 gmt

Is there any fix to this? Every other thing seems to work well and ok. Please look into it.

Edit: It seems to buy and sell as soon as I click the Play button...
 
Last edited:
Sep 18, 2017
4
4
3
31
Also please on the EA meant for the cTrader, it seems to open trades earlier than specified.

For instance if I had a news by 13:30gmt broker time (which is the time the algo uses) andI set the seconds before to like say 10secs meaning I want the trades to be opened at 13:29:50 gmt, and click on the play button for the algo, it ends up opening the trade about 30-20secs. It will open the trade at let's say 13:29:32 gmt or some time like that which is not 13:29:50 gmt

Is there any fix to this? Every other thing seems to work well and ok. Please look into it.

Edit: It seems to buy and sell as soon as I click the Play button...


Ok I seem to have solved the issue. still using my basic knowledge of maths, english and logic

this is the original code



.........
// Check what position is currently open
GetPositionStates();

// Adjust SL and TP of the current position
if ((HaveLongPosition) || (HaveShortPosition))
ControlPosition();
else
{
TimeSpan difference = Time.Subtract(news_time).Negate();
if ((difference <= TimeSpan.FromSeconds(60)) && (difference > TimeSpan.FromMilliseconds(0)))
{
// Randomize entry.
if (Rnd)
{
Random r = new Random();
if (r.Next() % 2 == 1)
fBuy();
else
fSell();
}
else if ((Buy) && (Sell))
{
fBuy();
fSell();
}
else if (Buy)
fBuy();
else if (Sell)
fSell();
}
}
}

..........



Now the problem with this code was marked in red and bolded.

what that string would have probably meant is that as soon as the time is less than 60 seconds, then a position(s) should be established with the relative type of trailing stop selected.

So this does not give allowance for opening trades in a time frame that is less than 60 seconds. Assuming one wants to open a position(s) say 10secs to the news.

This will limit everyone to the 60 seconds window and it won't respect whatever seconds before you have set and if it is less 60 seconds, it will automatically open a trade(s)

now this is the edited code with the "possible" correction in blue.



.........

// Check what position is currently open
GetPositionStates();

// Adjust SL and TP of the current position
if ((HaveLongPosition) || (HaveShortPosition))
ControlPosition();
else
{
TimeSpan difference = Time.Subtract(news_time).Negate();
if ((difference <= TimeSpan.FromSeconds(SecondsBefore)) && (difference > TimeSpan.FromSeconds(1)))
{
// Randomize entry.
if (Rnd)
{
Random r = new Random();
if (r.Next() % 2 == 1)
fBuy();
else
fSell();
}
else if ((Buy) && (Sell))
{
fBuy();
fSell();
}
else if (Buy)
fBuy();
else if (Sell)
fSell();
}
}
}
..........



This "possible" correction sets the algo to respect the preferred SecondsBefore of the user...

basically what this means is that as soon as the time is lesser than the SecondsBefore and it is not 1 second to the news, then the positions can be opened...

After adjustment of the code, everything seems to respect whatever SecondsBefore I set

just my two tots....
 

clemmo

Trader
Aug 5, 2016
3
0
17
49
Is it possible to modify the EA with an option to leave (successful) trades open after the hour has elapsed?
 

Enivid

Administrator
Staff member
Nov 30, 2008
18,532
1,355
144
Odesa
www.earnforex.com
@Piotr Stebel, the answer to your question largely depends on which news events and currency pairs you are going to trade. It also depends a lot on your broker's trading conditions. For example, I have used 20/100 SL/TP with position opening @ 15 seconds before the news to trade the BoE interest rate decision and it went perfectly. But it was with InstaForex zero spread account and the trades could have gone a much different way if there were spreads involved.
 

Piotr Stebel

Newbie
Feb 10, 2018
12
0
2
54
I already have a few. The majority is set to 8 pips SL and it is Full of the Trailing Stop. I have a litter results from thosetransactions? Or turn off Trailing Stop?
I trade at red the news in the calendar ForexFactory
 
Last edited by a moderator:

Enivid

Administrator
Staff member
Nov 30, 2008
18,532
1,355
144
Odesa
www.earnforex.com
I would turn the Trailing Stop off, especially if your spreads tend to widen by a lot during the news.

Also, not all news reports marked red on ForexFactory are worth trading. In my experience, NZD and CAD reports work the best.