
MQL5 Trading Toolkit (Part 5): Expanding the History Management EX5 Library with Position Functions
Introduction
In the previous article, we began developing the primary functions of the HistoryManager EX5 library, which forms the core engine responsible for retrieving, sorting, and categorizing historical data into various types, including orders, deals, pending orders, and positions. Most of these functions were designed to operate in the background, unnoticed by the library's users, and were not directly accessible. The only exportable functions were the print functions, which allowed users to output simple descriptive lists of orders, deals, pending orders, or positions to the MetaTrader 5 log.
In this article, we will expand the HistoryManager.mq5 source code by introducing additional user-accessible functions that build upon the foundational ones we created in the previous article. These new functions will allow library users to effortlessly query trade history data. Users will be able to retrieve key details, such as the trade duration in seconds, opening and closing deal tickets of the last closed position, whether the position was initiated by a pending order or a direct market entry, pip-based metrics like profit, stop loss, and take profit, as well as the net profit after accounting for expenses such as commissions and swaps. All of this will allow you to import the EX5 library in your MQL5 projects and be able to query various positions' history with minimal effort through straightforward function calls.
To get started, we will open the HistoryManager.mq5 file from the previous article and begin by creating the GetTotalDataInfoSize() function. The initial HistoryManager.mq5 source file is attached at the end of the previous article or can also be found at the end of this article (HistoryManager_Part1.mq5). We will continue adding new code below the PrintPendingOrdersHistory() function, which is where we left off previously.
Get Total Data Info Size Function
The GetTotalDataInfoSize() function is designed to retrieve and return the size of a specified historical data array. This function works in tandem with the FetchHistoryByCriteria() function, ensuring that we can dynamically determine the amount of data available in a specific data structure. Its primary role is to identify which dataset we are interested in—deals, orders, positions, or pending orders—and return the total number of elements in that dataset.
The GetTotalDataInfoSize() function will help streamline operations where dynamic access to various historical datasets is required. By passing the appropriate criteria as an argument, we will efficiently query the size of the relevant data structure.
We will start by defining the function signature. Since this function returns an integer representing the size of a specified data array, it uses an int return type. The input parameter or argument is an unsigned integer (uint), which will allow us to pass predefined constants to specify the type of data we are querying.
int GetTotalDataInfoSize(uint dataToGet) { //-- Our function's code will go here }
Next, we will declare a local variable, totalDataInfo, which will store the size of the requested dataset.
int totalDataInfo = 0;
We will use a switch statement to check the value of the dataToGet parameter. Depending on its value, we will identify the corresponding dataset and use the ArraySize() function to determine its size.
- Deals History Data: If dataToGet equals GET_DEALS_HISTORY_DATA, we will calculate the size of the dealInfo array and save it to totalDataInfo.
- Orders History Data: If dataToGet equals GET_ORDERS_HISTORY_DATA, we will calculate the size of the orderInfo array and save it to totalDataInfo.
- Positions History Data: For GET_POSITIONS_HISTORY_DATA, we will calculate the size of the positionInfo array and save it to totalDataInfo.
- Pending Orders Data: When dataToGet matches GET_PENDING_ORDERS_HISTORY_DATA, we will determine the size of the pendingOrderInfo array and save it to totalDataInfo.
- Default Case: If none of the predefined constants match, we will set totalDataInfo to 0 as a fallback.
Finally, we will return the value stored in totalDataInfo after we exit the switch. This will ensure that the function outputs the correct size for the specified data type or 0 if no valid data type is provided.
switch(dataToGet) { case GET_DEALS_HISTORY_DATA: totalDataInfo = ArraySize(dealInfo); break; case GET_ORDERS_HISTORY_DATA: totalDataInfo = ArraySize(orderInfo); break; case GET_POSITIONS_HISTORY_DATA: totalDataInfo = ArraySize(positionInfo); break; case GET_PENDING_ORDERS_HISTORY_DATA: totalDataInfo = ArraySize(pendingOrderInfo); break; default: totalDataInfo = 0; break; } return(totalDataInfo);
Below is the full implementation of the GetTotalDataInfoSize() function with all the code segments in their proper sequence.
int GetTotalDataInfoSize(uint dataToGet) { int totalDataInfo = 0; //- Saves the total elements of the specified history found switch(dataToGet) { case GET_DEALS_HISTORY_DATA: //- Check if we have any available deals history data totalDataInfo = ArraySize(dealInfo); //- Save the total deals found break; case GET_ORDERS_HISTORY_DATA: //- Check if we have any available orders history data totalDataInfo = ArraySize(orderInfo); //- Save the total orders found break; case GET_POSITIONS_HISTORY_DATA: //- Check if we have any available positions history data totalDataInfo = ArraySize(positionInfo); //- Save the total positions found break; case GET_PENDING_ORDERS_HISTORY_DATA: //- Check if we have any available pending orders history data totalDataInfo = ArraySize(pendingOrderInfo); //- Save the total pending orders found break; default: //-- Unknown entry totalDataInfo = 0; break; } return(totalDataInfo); }
Fetch History by Criteria Function
When querying recent history data with MQL5, such as retrieving the last five closed buy positions for a specific symbol, it is unnecessary to request the entire account history from the server, as this would waste valuable resources. Instead, you should adopt an optimal approach by first querying the most recent trade history, for example, within the current day. If the specific data you're looking for is not available within this period, you can then incrementally extend the time range until you find the targeted data. This method ensures efficiency and minimizes resource usage, providing the best performance while retrieving the necessary historical data.
The FetchHistoryByCriteria() function systematically retrieves historical data based on specific criteria, starting from the last 24 hours and expanding the retrieval period if necessary. It begins by checking the most recent data, and if no relevant history is found, it progressively scans older data—first by week, up to a year. If no data is found after scanning the entire year, it will attempt to retrieve all available account history.
The FetchHistoryByCriteria() function will serve as a key utility for fetching trade data from different periods and will allow the EX5 library to scan and retrieve history until the required data is found. If no relevant data is found, it will ensure the library can still attempt to retrieve older or complete account history.
Let us begin by defining the function signature. Since this function will be used internally by the library core modules, it will not be exportable.
bool FetchHistoryByCriteria(uint dataToGet) { //-- Our function's code will go here }
We will define the interval variable, which modulates the history retrieval period. Initially, this will be set to 1 to start with a 24-hour time range.
int interval = 1;
We will calculate the time range starting from 24 hours ago to the current time.
datetime fromDateTime = TimeCurrent() - 1 * (PeriodSeconds(PERIOD_D1) * interval); datetime toDateTime = TimeCurrent();
Next, we will use the GetHistoryData() function to fetch the data within the defined time range.
GetHistoryData(fromDateTime, toDateTime, dataToGet);
If no data is found in the last 24 hours, we will enter a loop where we increment the interval by one week at a time. We will continue this process until we scan up to a full year (53 weeks). During each iteration, the time range is updated to reflect the additional week.
while(GetTotalDataInfoSize(dataToGet) <= 0) { interval++; fromDateTime = TimeCurrent() - 1 * (PeriodSeconds(PERIOD_W1) * interval); toDateTime = TimeCurrent(); GetHistoryData(fromDateTime, toDateTime, dataToGet); if(interval > 53) { break; } }
If the data is still not found after scanning for a year, we will reset the time range to cover the entire account history (from the epoch to the current time). This ensures that all available history is checked.
fromDateTime = 0; toDateTime = TimeCurrent(); GetHistoryData(fromDateTime, toDateTime, dataToGet);
Finally, we will check if any history has been successfully retrieved. If no data is found after scanning the entire account history, we will log the failure and return false. If data is found, we will return true to indicate success.
if(GetTotalDataInfoSize(dataToGet) <= 0) { return(false); } else { return(true); }
Here is the full implementation of the FetchHistoryByCriteria() function with all the code segments included.
bool FetchHistoryByCriteria(uint dataToGet) { int interval = 1; //- Modulates the history period //- Save the history period for the last 24 hours datetime fromDateTime = TimeCurrent() - 1 * (PeriodSeconds(PERIOD_D1) * interval); datetime toDateTime = TimeCurrent(); //- Get the specified history GetHistoryData(fromDateTime, toDateTime, dataToGet); //- If we have no history in the last 24 hours we need to keep increasing the retrieval //- period by one week untill we scan a full year (53 weeks) while(GetTotalDataInfoSize(dataToGet) <= 0) { interval++; fromDateTime = TimeCurrent() - 1 * (PeriodSeconds(PERIOD_W1) * interval); toDateTime = TimeCurrent(); GetHistoryData(fromDateTime, toDateTime, dataToGet); //- If no history is found after a one year scanning period, we exit the while loop if(interval > 53) { break; } } //- If we have not found any trade history in the last year, we scan and cache the intire account history fromDateTime = 0; //-- 1970 (Epoch) toDateTime = TimeCurrent(); //-- Time now GetHistoryData(fromDateTime, toDateTime, dataToGet); //- If we still havent retrieved any history in the account, we log this info by //- printing it and exit the function by returning false if(GetTotalDataInfoSize(dataToGet) <= 0) { return(false); //- Specified history not found, exit and return false } else { return(true); //- Specified history found, exit and return true } }
Get The Last Closed Position Data Function
The GetLastClosedPositionData() function is responsible for retrieving the properties of the most recent closed position and storing this data in the provided lastClosedPositionInfo reference. This function will rely on the FetchHistoryByCriteria() function to fetch the relevant trading history data, ensuring that it has access to the necessary position information. If no closed positions are found, the function will log an error message and return false. If successful, it will retrieve the data and return true.
Let us begin by defining the function signature. Since this function is intended for external use, it is exported and can be imported by other MQL5 source files.
bool GetLastClosedPositionData(PositionData &lastClosedPositionInfo) export { //-- Our function's code will go here }
We will first attempt to fetch the available position history data by calling the FetchHistoryByCriteria() function with the GET_POSITIONS_HISTORY_DATA argument. This function call will search through available trading history to retrieve position-related data.
if(!FetchHistoryByCriteria(GET_POSITIONS_HISTORY_DATA)) { Print(__FUNCTION__, ": No trading history available. Last closed position can't be retrieved."); return(false); }
If no position history data is available (i.e., the FetchHistoryByCriteria() function returns false), we log an error message using the Print() function, which helps in debugging by providing useful information about the failure. The function then returns false, indicating that it could not retrieve the last closed position.
If position history data is successfully retrieved, we will then save the information for the last closed position in the lastClosedPositionInfo variable. This is done by assigning the first element in the positionInfo array to lastClosedPositionInfo, as this array contains the history of all positions, with the most recent closed position being at the start of the array. To conclude the function, we will return true to indicate that the last closed position data has been successfully retrieved and stored in the provided reference variable.
lastClosedPositionInfo = positionInfo[0]; return(true);
Here is the full implementation of the GetLastClosedPositionData() function, with all the code segments included.
bool GetLastClosedPositionData(PositionData &lastClosedPositionInfo) export { if(!FetchHistoryByCriteria(GET_POSITIONS_HISTORY_DATA)) { Print(__FUNCTION__, ": No trading history available. Last closed position can't be retrieved."); return(false); } //-- Save the last closed position data in the referenced lastClosedPositionInfo variable lastClosedPositionInfo = positionInfo[0]; return(true); }
Last Closed Position Type Function
The LastClosedPositionType() function will be responsible for determining the type of the most recently closed position in the trading account and storing it in the referenced variable lastClosedPositionType. This function is a logical extension of the GetLastClosedPositionData() function, leveraging its capability to retrieve the last closed position and extract its specific type.
The LastClosedPositionType() function is required for scenarios where you need to analyze the type of the most recent trade, such as distinguishing between buy and sell positions or identifying more complex strategies based on the position type.
Let us begin by defining the function signature. Since this function is intended for use by MQL5 files that import the EX5 library, we will mark it as exportable. This will ensure the function is accessible externally, enhancing both modularity and usability.
bool LastClosedPositionType(ENUM_POSITION_TYPE &lastClosedPositionType) export { //-- Our function's code will go here }
We begin by declaring a local variable lastClosedPositionInfo of type PositionData. This variable will temporarily store the details of the last closed position, which we will extract using the GetLastClosedPositionData() function.
PositionData lastClosedPositionInfo;
We invoke the GetLastClosedPositionData() function, passing lastClosedPositionInfo as an argument. If the function returns true, it means the data for the last closed position has been successfully retrieved.
if(GetLastClosedPositionData(lastClosedPositionInfo)) { //- Process the retrieved data }
If GetLastClosedPositionData() fails (returns false), this function immediately exits, returning false to indicate that the operation could not be completed.
Inside the if block, we extract the type property from lastClosedPositionInfo and assign it to the referenced variable lastClosedPositionType. This ensures that the calling code has access to the type of the last closed position. After successfully saving the type, we return true to indicate the operation was successful and exit the function.
lastClosedPositionType = lastClosedPositionInfo.type; return(true);
If the retrieval of the last closed position fails, the function skips the if block and directly returns false. This indicates that the position type could not be determined.
return(false);
Here is the complete implementation of the LastClosedPositionType() function with all the code segments in their correct order.
bool LastClosedPositionType(ENUM_POSITION_TYPE &lastClosedPositionType) export { PositionData lastClosedPositionInfo; if(GetLastClosedPositionData(lastClosedPositionInfo)) { lastClosedPositionType = lastClosedPositionInfo.type; return(true); } return(false); }
Last Closed Position Volume Function
The LastClosedPositionVolume() function is responsible for retrieving the volume of the most recently closed position in the trading history. It saves this volume into the referenced variable lastClosedPositionVolume. If the LastClosedPositionVolume() function successfully retrieves the data for the last closed position, it updates the lastClosedPositionVolume variable with the volume value and confirms the operation was successful by returning true. If it fails to retrieve the data, the lastClosedPositionVolume variable remains unchanged, and the function indicates the failure by returning false.
bool LastClosedPositionVolume(double &lastClosedPositionVolume) export { PositionData lastClosedPositionInfo; if(GetLastClosedPositionData(lastClosedPositionInfo)) { lastClosedPositionVolume = lastClosedPositionInfo.volume; return(true); } return(false); }
Last Closed Position Symbol Function
The LastClosedPositionSymbol() function is responsible for retrieving the symbol of the most recently closed position in the trading history. It saves this symbol into the referenced variable lastClosedPositionSymbol. If the LastClosedPositionSymbol() function successfully retrieves the data for the last closed position, it updates the lastClosedPositionSymbol variable with the symbol value and confirms the operation was successful by returning true. If it fails to retrieve the data, the lastClosedPositionSymbol variable remains unchanged, and the function indicates the failure by returning false.
bool LastClosedPositionSymbol(string &lastClosedPositionSymbol) export { PositionData lastClosedPositionInfo; if(GetLastClosedPositionData(lastClosedPositionInfo)) { lastClosedPositionSymbol = lastClosedPositionInfo.symbol; return(true); } return(false); }
Last Closed Position Ticket Function
The LastClosedPositionTicket() function is responsible for retrieving the ticket number of the most recently closed position in the trading history. It saves this ticket number into the referenced variable lastClosedPositionTicket. If the LastClosedPositionTicket() function successfully retrieves the data for the last closed position, it updates the lastClosedPositionTicket variable with the ticket number and confirms the operation was successful by returning true. If it fails to retrieve the data, the lastClosedPositionTicket variable remains unchanged, and the function indicates the failure by returning false.
bool LastClosedPositionTicket(ulong &lastClosedPositionTicket) export { PositionData lastClosedPositionInfo; if(GetLastClosedPositionData(lastClosedPositionInfo)) { lastClosedPositionTicket = lastClosedPositionInfo.ticket; return(true); } return(false); }
Last Closed Position Profit Function
The LastClosedPositionProfit() function is responsible for retrieving the profit of the most recently closed position in the trading history. It saves this profit into the referenced variable lastClosedPositionProfit. If the LastClosedPositionProfit() function successfully retrieves the data for the last closed position, it updates the lastClosedPositionProfit variable with the profit value and confirms the operation was successful by returning true. If it fails to retrieve the data, the lastClosedPositionProfit variable remains unchanged, and the function indicates the failure by returning false.
bool LastClosedPositionProfit(double &lastClosedPositionProfit) export { PositionData lastClosedPositionInfo; if(GetLastClosedPositionData(lastClosedPositionInfo)) { lastClosedPositionProfit = lastClosedPositionInfo.profit; return(true); } return(false); }
Last Closed Position Net Profit Function
The LastClosedPositionNetProfit() function is responsible for retrieving the net profit of the most recently closed position in the trading history. The position net profit is the final value after all charges like the commission and swaps have been deducted from the position profit. It saves this net profit into the referenced variable lastClosedPositionNetProfit. If the LastClosedPositionNetProfit() function successfully retrieves the data for the last closed position, it updates the lastClosedPositionNetProfit variable with the net profit value and confirms the operation was successful by returning true. If it fails to retrieve the data, the lastClosedPositionNetProfit variable remains unchanged, and the function indicates the failure by returning false.
bool LastClosedPositionNetProfit(double &lastClosedPositionNetProfit) export { PositionData lastClosedPositionInfo; if(GetLastClosedPositionData(lastClosedPositionInfo)) { lastClosedPositionNetProfit = lastClosedPositionInfo.netProfit; return(true); } return(false); }
Last Closed Position Pip (Point) Profit Function
The LastClosedPositionPipProfit() function is responsible for retrieving the pip profit of the most recently closed position in the trading history. It saves this pip profit into the referenced variable lastClosedPositionPipProfit. If the LastClosedPositionPipProfit() function successfully retrieves the data for the last closed position, it updates the lastClosedPositionPipProfit variable with the pip profit value and confirms the operation was successful by returning true. If it fails to retrieve the data, the lastClosedPositionPipProfit variable remains unchanged, and the function indicates the failure by returning false.
bool LastClosedPositionPipProfit(int &lastClosedPositionPipProfit) export { PositionData lastClosedPositionInfo; if(GetLastClosedPositionData(lastClosedPositionInfo)) { lastClosedPositionPipProfit = lastClosedPositionInfo.pipProfit; return(true); } return(false); }
Last Closed Position Close Price Function
The LastClosedPositionClosePrice() function is responsible for retrieving the closing price of the most recently closed position in the trading history. It saves this closing price into the referenced variable lastClosedPositionClosePrice. If the LastClosedPositionClosePrice() function successfully retrieves the data for the last closed position, it updates the lastClosedPositionClosePrice variable with the closing price value and confirms the operation was successful by returning true. If it fails to retrieve the data, the lastClosedPositionClosePrice variable remains unchanged, and the function indicates the failure by returning false.
bool LastClosedPositionClosePrice(double &lastClosedPositionClosePrice) export { PositionData lastClosedPositionInfo; if(GetLastClosedPositionData(lastClosedPositionInfo)) { lastClosedPositionClosePrice = lastClosedPositionInfo.closePrice; return(true); } return(false); }
Last Closed Position Open Price Function
The LastClosedPositionOpenPrice() function is responsible for retrieving the opening price of the most recently closed position in the trading history. It saves this opening price into the referenced variable lastClosedPositionOpenPrice. If the LastClosedPositionOpenPrice() function successfully retrieves the data for the last closed position, it updates the lastClosedPositionOpenPrice variable with the opening price value and confirms the operation was successful by returning true. If it fails to retrieve the data, the lastClosedPositionOpenPrice variable remains unchanged, and the function indicates the failure by returning false.
bool LastClosedPositionOpenPrice(double &lastClosedPositionOpenPrice) export { PositionData lastClosedPositionInfo; if(GetLastClosedPositionData(lastClosedPositionInfo)) { lastClosedPositionOpenPrice = lastClosedPositionInfo.openPrice; return(true); } return(false); }
Last Closed Position Stop Loss Price Function
The LastClosedPositionSlPrice() function is responsible for retrieving the stop loss price of the most recently closed position in the trading history. It saves this stop loss price into the referenced variable lastClosedPositionSlPrice. If the LastClosedPositionSlPrice() function successfully retrieves the data for the last closed position, it updates the lastClosedPositionSlPrice variable with the stop loss price value and confirms the operation was successful by returning true. If it fails to retrieve the data, the lastClosedPositionSlPrice variable remains unchanged, and the function indicates the failure by returning false.
bool LastClosedPositionSlPrice(double &lastClosedPositionSlPrice) export { PositionData lastClosedPositionInfo; if(GetLastClosedPositionData(lastClosedPositionInfo)) { lastClosedPositionSlPrice = lastClosedPositionInfo.slPrice; return(true); } return(false); }
Last Closed Position Take Profit Price Function
The LastClosedPositionTpPrice() function is responsible for retrieving the take profit price of the most recently closed position in the trading history. It saves this take profit price into the referenced variable lastClosedPositionTpPrice. If the LastClosedPositionTpPrice() function successfully retrieves the data for the last closed position, it updates the lastClosedPositionTpPrice variable with the take profit price value and confirms the operation was successful by returning true. If it fails to retrieve the data, the lastClosedPositionTpPrice variable remains unchanged, and the function indicates the failure by returning false.
bool LastClosedPositionTpPrice(double &lastClosedPositionTpPrice) export { PositionData lastClosedPositionInfo; if(GetLastClosedPositionData(lastClosedPositionInfo)) { lastClosedPositionTpPrice = lastClosedPositionInfo.tpPrice; return(true); } return(false); }
Last Closed Position Stop Loss Pips (Points) Function
The LastClosedPositionSlPips() function is responsible for retrieving the stop loss value of the most recently closed position in points (pips). It saves this stop loss value into the referenced variable lastClosedPositionSlPips. If the LastClosedPositionSlPips() function successfully retrieves the data for the last closed position, it updates the lastClosedPositionSlPips variable with the stop loss value in pips and confirms the operation was successful by returning true. If it fails to retrieve the data, the lastClosedPositionSlPips variable remains unchanged, and the function indicates the failure by returning false.
bool LastClosedPositionSlPips(int &lastClosedPositionSlPips) export { PositionData lastClosedPositionInfo; if(GetLastClosedPositionData(lastClosedPositionInfo)) { lastClosedPositionSlPips = lastClosedPositionInfo.slPips; return(true); } return(false); }
Last Closed Position Take Profit Pips (Points) Function
The LastClosedPositionTpPips() function is responsible for retrieving the take profit value of the most recently closed position in points (pips). It saves this take profit value into the referenced variable lastClosedPositionTpPips. If the LastClosedPositionTpPips() function successfully retrieves the data for the last closed position, it updates the lastClosedPositionTpPips variable with the take profit value in pips and confirms the operation was successful by returning true. If it fails to retrieve the data, the lastClosedPositionTpPips variable remains unchanged, and the function indicates the failure by returning false.
bool LastClosedPositionTpPips(int &lastClosedPositionTpPips) export { PositionData lastClosedPositionInfo; if(GetLastClosedPositionData(lastClosedPositionInfo)) { lastClosedPositionTpPips = lastClosedPositionInfo.tpPips; return(true); } return(false); }
Last Closed Position Open Time Function
The LastClosedPositionOpenTime() function is responsible for retrieving the open time of the most recently closed position. It saves this open time into the referenced variable lastClosedPositionOpenTime. If the LastClosedPositionOpenTime() function successfully retrieves the data for the last closed position, it updates the lastClosedPositionOpenTime variable with the open time value and confirms the operation was successful by returning true. If it fails to retrieve the data, the lastClosedPositionOpenTime variable remains unchanged, and the function indicates the failure by returning false.
bool LastClosedPositionOpenTime(datetime &lastClosedPositionOpenTime) export { PositionData lastClosedPositionInfo; if(GetLastClosedPositionData(lastClosedPositionInfo)) { lastClosedPositionOpenTime = lastClosedPositionInfo.openTime; return(true); } return(false); }
Last Closed Position Close Time Function
The LastClosedPositionCloseTime() function is responsible for retrieving the close time of the most recently closed position. It saves this close time into the referenced variable lastClosedPositionCloseTime. If the LastClosedPositionCloseTime() function successfully retrieves the data for the last closed position, it updates the lastClosedPositionCloseTime variable with the close time value and confirms the operation was successful by returning true. If it fails to retrieve the data, the lastClosedPositionCloseTime variable remains unchanged, and the function indicates the failure by returning false.
bool LastClosedPositionCloseTime(datetime &lastClosedPositionCloseTime) export { PositionData lastClosedPositionInfo; if(GetLastClosedPositionData(lastClosedPositionInfo)) { lastClosedPositionCloseTime = lastClosedPositionInfo.closeTime; return(true); } return(false); }
Last Closed Position Swap Function
The LastClosedPositionSwap() function is responsible for retrieving the swap value of the most recently closed position. It saves this swap value into the referenced variable lastClosedPositionSwap. If the LastClosedPositionSwap() function successfully retrieves the data for the last closed position, it updates the lastClosedPositionSwap variable with the swap value and confirms the operation was successful by returning true. If it fails to retrieve the data, the lastClosedPositionSwap variable remains unchanged, and the function indicates the failure by returning false.
bool LastClosedPositionSwap(double &lastClosedPositionSwap) export { PositionData lastClosedPositionInfo; if(GetLastClosedPositionData(lastClosedPositionInfo)) { lastClosedPositionSwap = lastClosedPositionInfo.swap; return(true); } return(false); }
Last Closed Position Commission Function
The LastClosedPositionCommission() function is responsible for retrieving the commission value of the most recently closed position. It saves this commission value into the referenced variable lastClosedPositionCommission. If the LastClosedPositionCommission() function successfully retrieves the data for the last closed position, it updates the lastClosedPositionCommission variable with the commission value and confirms the operation was successful by returning true. If it fails to retrieve the data, the lastClosedPositionCommission variable remains unchanged, and the function indicates the failure by returning false.
bool LastClosedPositionCommission(double &lastClosedPositionCommission) export { PositionData lastClosedPositionInfo; if(GetLastClosedPositionData(lastClosedPositionInfo)) { lastClosedPositionCommission = lastClosedPositionInfo.commission; return(true); } return(false); }
Last Closed Position Initiating Order Type Function
The LastClosedPositionInitiatingOrderType() function is responsible for retrieving the initiating order type of the most recently closed position. This enables us to know if the position was initiated by a pending order (Buy Stop, Buy Limit, Sell Stop, Sell Limit, Buy Stop Limit, or Sell Stop Limit) or a direct market entry order. It saves this initiating order type into the referenced variable lastClosedPositionInitiatingOrderType. If the LastClosedPositionInitiatingOrderType() function successfully retrieves the data for the last closed position, it updates the lastClosedPositionInitiatingOrderType variable with the initiating order type value and confirms the operation was successful by returning true. If it fails to retrieve the data, the lastClosedPositionInitiatingOrderType variable remains unchanged, and the function indicates the failure by returning false.
bool LastClosedPositionInitiatingOrderType(ENUM_ORDER_TYPE &lastClosedPositionInitiatingOrderType) export { PositionData lastClosedPositionInfo; if(GetLastClosedPositionData(lastClosedPositionInfo)) { lastClosedPositionInitiatingOrderType = lastClosedPositionInfo.initiatingOrderType; return(true); } return(false); }
Last Closed Position ID Function
The LastClosedPositionId() function is responsible for retrieving the ID of the most recently closed position. It saves this position ID into the referenced variable lastClosedPositionId. If the LastClosedPositionId() function successfully retrieves the data for the last closed position, it updates the lastClosedPositionId variable with the position ID value and confirms the operation was successful by returning true. If it fails to retrieve the data, the lastClosedPositionId variable remains unchanged, and the function indicates the failure by returning false.
bool LastClosedPositionId(ulong &lastClosedPositionId) export { PositionData lastClosedPositionInfo; if(GetLastClosedPositionData(lastClosedPositionInfo)) { lastClosedPositionId = lastClosedPositionInfo.positionId; return(true); } return(false); }
Last Closed Position Initiated by Pending Order Function
The LastClosedPositionInitiatedByPendingOrder() function is responsible for checking if the most recently closed position was initiated from a pending order. It saves this information into the referenced variable lastClosedPositionInitiatedByPendingOrder. If the LastClosedPositionInitiatedByPendingOrder() function successfully retrieves the data for the last closed position, it updates the lastClosedPositionInitiatedByPendingOrder variable with the result and confirms the operation was successful by returning true. If it fails to retrieve the data, the lastClosedPositionInitiatedByPendingOrder variable remains unchanged, and the function indicates the failure by returning false.
bool LastClosedPositionInitiatedByPendingOrder(bool &lastClosedPositionInitiatedByPendingOrder) export { PositionData lastClosedPositionInfo; if(GetLastClosedPositionData(lastClosedPositionInfo)) { lastClosedPositionInitiatedByPendingOrder = lastClosedPositionInfo.initiatedByPendingOrder; return(true); } return(false); }
Last Closed Position Opening Order Ticket Function
The LastClosedPositionOpeningOrderTicket() function is responsible for retrieving the ticket number of the opening order for the most recently closed position. It saves this ticket number into the referenced variable lastClosedPositionOpeningOrderTicket. If the LastClosedPositionOpeningOrderTicket() function successfully retrieves the data for the last closed position, it updates the lastClosedPositionOpeningOrderTicket variable with the ticket number and confirms the operation was successful by returning true. If it fails to retrieve the data, the lastClosedPositionOpeningOrderTicket variable remains unchanged, and the function indicates the failure by returning false.
bool LastClosedPositionOpeningOrderTicket(ulong &lastClosedPositionOpeningOrderTicket) export { PositionData lastClosedPositionInfo; if(GetLastClosedPositionData(lastClosedPositionInfo)) { lastClosedPositionOpeningOrderTicket = lastClosedPositionInfo.openingOrderTicket; return(true); } return(false); }
Last Closed Position Opening Deal Ticket Function
The LastClosedPositionOpeningDealTicket() function is responsible for retrieving the ticket number of the opening deal for the most recently closed position. It saves this deal ticket number into the referenced variable lastClosedPositionOpeningDealTicket. If the LastClosedPositionOpeningDealTicket() function successfully retrieves the data for the last closed position, it updates the lastClosedPositionOpeningDealTicket variable with the deal ticket number and confirms the operation was successful by returning true. If it fails to retrieve the data, the lastClosedPositionOpeningDealTicket variable remains unchanged, and the function indicates the failure by returning false.
bool LastClosedPositionOpeningDealTicket(ulong &lastClosedPositionOpeningDealTicket) export { PositionData lastClosedPositionInfo; if(GetLastClosedPositionData(lastClosedPositionInfo)) { lastClosedPositionOpeningDealTicket = lastClosedPositionInfo.openingDealTicket; return(true); } return(false); }
Last Closed Position Closing Deal Ticket Function
The LastClosedPositionClosingDealTicket() function is responsible for retrieving the ticket number of the closing deal for the most recently closed position. It saves this deal ticket number into the referenced variable lastClosedPositionClosingDealTicket. If the LastClosedPositionClosingDealTicket() function successfully retrieves the data for the last closed position, it updates the lastClosedPositionClosingDealTicket variable with the deal ticket number and confirms the operation was successful by returning true. If it fails to retrieve the data, the lastClosedPositionClosingDealTicket variable remains unchanged, and the function indicates the failure by returning false.
bool LastClosedPositionClosingDealTicket(ulong &lastClosedPositionClosingDealTicket) export { PositionData lastClosedPositionInfo; if(GetLastClosedPositionData(lastClosedPositionInfo)) { lastClosedPositionClosingDealTicket = lastClosedPositionInfo.closingDealTicket; return(true); } return(false); }
Last Closed Position Magic Function
The LastClosedPositionMagic() function is responsible for retrieving the magic number of the most recently closed position. It saves this magic number into the referenced variable lastClosedPositionMagic. If the LastClosedPositionMagic() function successfully retrieves the data for the last closed position, it updates the lastClosedPositionMagic variable with the magic number and confirms the operation was successful by returning true. If it fails to retrieve the data, the lastClosedPositionMagic variable remains unchanged, and the function indicates the failure by returning false.
bool LastClosedPositionMagic(ulong &lastClosedPositionMagic) export { PositionData lastClosedPositionInfo; if(GetLastClosedPositionData(lastClosedPositionInfo)) { lastClosedPositionMagic = lastClosedPositionInfo.magic; return(true); } return(false); }
Last Closed Position Comment Function
The LastClosedPositionComment() function is responsible for retrieving the comment associated with the most recently closed position. It saves this comment into the referenced variable lastClosedPositionComment. If the LastClosedPositionComment() function successfully retrieves the data for the last closed position, it updates the lastClosedPositionComment variable with the comment and confirms the operation was successful by returning true. If it fails to retrieve the data, the lastClosedPositionComment variable remains unchanged, and the function indicates the failure by returning false.
bool LastClosedPositionComment(string &lastClosedPositionComment) export { PositionData lastClosedPositionInfo; if(GetLastClosedPositionData(lastClosedPositionInfo)) { lastClosedPositionComment = lastClosedPositionInfo.comment; return(true); } return(false); }
Last Closed Position Duration Function
The LastClosedPositionDuration() function is responsible for retrieving the duration of the most recently closed position in seconds. It saves this duration into the referenced variable lastClosedPositionDuration. If the LastClosedPositionDuration() function successfully retrieves the data for the last closed position, it updates the lastClosedPositionDuration variable with the duration and confirms the operation was successful by returning true. If it fails to retrieve the data, the lastClosedPositionDuration variable remains unchanged, and the function indicates the failure by returning false.
bool LastClosedPositionDuration(long &lastClosedPositionDuration) export { PositionData lastClosedPositionInfo; if(GetLastClosedPositionData(lastClosedPositionInfo)) { lastClosedPositionDuration = lastClosedPositionInfo.duration; return(true); } return(false); }
Conclusion
In this article, you have learned how smaller, focused utility functions, such as those we have designed to retrieve specific properties of the last closed positions, can work together to accomplish targeted tasks while maintaining clarity and modularity within the EX5 library codebase. By isolating the logic for extracting various properties of positions, these functions streamline the process of gathering specific data clearly and efficiently.
To keep this article concise and focused, we will defer the creation of library functions that retrieve the various properties of the last filled and canceled pending orders to the next article. In that article, we will explore these functions in detail, ensuring they are well-integrated with the existing framework. Following that, we will move on to developing a set of analytical reporting functions, which will enable users to generate insightful summaries and detailed reports based on the historical trade data. This step-by-step approach will ensure clarity and allow us to cover each topic comprehensively without overwhelming you with so much information all at once.
At the end of this article, you will find the latest version of the HistoryManager.mq5 library source code, which includes all the functions created in this article as well as those introduced in the previous one. Thank you for following along, and I look forward to connecting with you again in the next article.





- Free trading apps
- Over 8,000 signals for copying
- Economic news for exploring financial markets
You agree to website policy and terms of use