Author: Müller Peter
Orders Execution
Checks for the total of open orders
Miscellaneous
It issuies visual alerts to the screen
0 Views
0 Downloads
0 Favorites
FetchNews
ÿþ//+------------------------------------------------------------------+

//|                                                       NewsEA.mq5 |

//|                                  Copyright 2023, MetaQuotes Ltd. |

//|                                             https://www.mql5.com |

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

#property copyright "Müller Peter"

#property link      "https://www.mql5.com/en/users/mullerp04/seller"

#property version   "1.00"



#include <Trade\Trade.mqh>  // Include the standard trade library for trading operations



// Define an enum to specify what the expert advisor (EA) should do

enum e_Type {

   Trading = 0,  // Place trades based on news events

   Alerting = 1  // Only alert about important news events

};



// Input parameters for the EA

input e_Type Type = Alerting;   // The mode of operation (Trading or Alerting)

input int Magic = 1125021;      // Magic number to identify EA orders (relevant in trading mode)

input int TPPoints = 150;       // Take profit in points (relevant in trading mode)

input int SLPoints = 150;       // Stop loss in points (relevant in trading mode)

input double Volume = 0.1;      // Volume of orders (relevant in trading mode)



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

//| Initialization function                                          |

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

int OnInit()

{

   

   return(INIT_SUCCEEDED);  

}



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

//| Deinitialization function                                        |

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

void OnDeinit(const int reason)

{

}



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

//| Expert tick function                                             |

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

void OnTick()

{

   // Declare necessary variables

   MqlCalendarValue CalendarValues[];   // Array to hold calendar events

   MqlCalendarEvent CalendarEvent;      // Struct to hold specific event details

   MqlCalendarCountry CalendarCountry;  // Struct to hold country details



   // Static variables to maintain state between ticks

   static datetime LastRequest = TimeTradeServer(); // Last time news was fetched

   static CTrade trade;                             // Trade object for trading operations

   trade.SetExpertMagicNumber(Magic);               // Set the magic number for the EA's trades

   static datetime Expiry = 0;                      // Expiry time for pending orders



   // Retrieve calendar events from the last 50 seconds to the next 50 seconds

   CalendarValueHistory(CalendarValues, LastRequest, TimeTradeServer() + 50);



   // If new events are found, update the last request time

   if(ArraySize(CalendarValues) != 0)

      LastRequest = TimeTradeServer() + 50;



   // Loop through all retrieved events

   for(int i = 0; i < ArraySize(CalendarValues); i++)

   {

       // Fetch detailed information about the event and the country

       CalendarEventById(CalendarValues[i].event_id, CalendarEvent);

       CalendarCountryById(CalendarEvent.country_id, CalendarCountry);

       

       // Get the currency related to the event

       string currency = CalendarCountry.currency;



       // Check if the event is relevant to the current symbol

       if(currency == SymbolInfoString(_Symbol, SYMBOL_CURRENCY_BASE) || 

          currency == SymbolInfoString(_Symbol, SYMBOL_CURRENCY_PROFIT))

       {

         // If the event is high importance and the mode is Alerting, send an alert

         if(CalendarEvent.importance == CALENDAR_IMPORTANCE_MODERATE && Type == Alerting)

         {

            Alert("Upcoming important news event: " + CalendarEvent.name + 

                  " at " + TimeToString(CalendarValues[i].time));

         }



         // If the event relates to inflation or interest rate changes, place pending orders

         if((StringContains(CalendarEvent.name, "cpi") || 

            StringContains(CalendarEvent.name, "ppi") || 

            StringContains(CalendarEvent.name, "interest rate decision")) && Type == Trading)

         {

            // Skip if there are already active pending orders

            if(Expiry != 0)

               continue;



            // Retrieve current market prices

            double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);

            double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID);



            // Set expiry time for pending orders

            Expiry = TimeTradeServer() + 500;



            // Place buy stop and sell stop orders around the current price

            trade.BuyStop(Volume, ask + TPPoints * _Point, NULL, 

                          ask + TPPoints * _Point - SLPoints * _Point, 

                          ask + 2 * TPPoints * _Point);



            trade.SellStop(Volume, bid - TPPoints * _Point, NULL, 

                           bid - TPPoints * _Point + SLPoints * _Point, 

                           bid - 2 * TPPoints * _Point);

         }

       }       

   }



   // Delete pending orders if they have expired

   if(TimeTradeServer() > Expiry && Expiry != 0)

   {

      Expiry = 0;

      DeletePending();

   }

}



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

//| Function to delete pending orders                                |

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

void DeletePending()

{

   COrderInfo ordinfo;  // Order information object

   CTrade trade;        // Trade object



   // Loop through all orders and delete those with the EA's magic number

   for(int i = OrdersTotal() - 1; i >= 0; i--)

   {

      ordinfo.SelectByIndex(i);

      if(ordinfo.Magic() == Magic)

         trade.OrderDelete(ordinfo.Ticket());

   }

}



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

//| Helper function to check if a string contains another string     |

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

bool StringContains(string base, string containing, bool Cased = false)

{

   // If case-insensitive, convert both strings to lowercase

   if(!Cased)

   {

      StringToLower(base);

      StringToLower(containing);

   }



   int ct = 0; // Counter to track matching characters



   // Loop through the base string

   for(unsigned i = 0; i < base.Length(); i++)

   {

      if(base.GetChar(i) == containing.GetChar(ct))

         ct++;  // Increment counter if characters match

      else 

         ct = 0; // Reset counter if characters don't match



      // If the entire containing string matches, return true

      if(ct == containing.Length() - 1)

         return true;



      // If remaining base string is shorter than containing string, return false

      if(base.Length() - i < containing.Length() && !ct)

         return false;

   }

   return false; // Return false if no match is found

}

Comments