How to Handle Deal Entry in and Out in MQL5?

What are Deals in MQL5?

In MQL5, a deal represents the actual execution of a trade. It’s distinct from an order, which is a request to buy or sell an asset. A single order can result in multiple deals if it’s partially filled. Deals store granular information about each executed trade, including price, volume, time, entry/exit type, and more. Understanding deals is crucial for analyzing trading performance, implementing sophisticated risk management, and building robust trading strategies.

Importance of Tracking Deal Entry and Exit

Knowing how a deal entered and exited the market provides essential context for evaluating trading decisions. This information allows traders to:

  • Analyze strategy effectiveness: Determine if a strategy performs better on specific entry types (e.g., limit orders vs. market orders).
  • Identify slippage: Compare the requested order price with the actual execution price to quantify slippage.
  • Implement advanced risk management: Adjust position sizes or stop-loss levels based on the deal’s entry type.
  • Debug trading logic: Understand the exact circumstances under which a trade was executed, aiding in identifying and fixing errors in the code.

Entry and Exit as ‘Entry’ and ‘InOut’ Deal Properties

The entry and exit nature of a deal is represented by the DEAL_ENTRY property. This property indicates whether a deal was an entry into the market (buying or selling), an exit from the market (closing a position), or a reversal (closing and opening a position simultaneously). In addition, deals also can have DEAL_INOUT property, which also shows the direction of a trade.

Accessing Deal Entry and Exit Information Using dealGetInteger()

MQL5 provides the dealGetInteger() function to access integer properties of a deal, including DEAL_ENTRY. This function takes the deal ticket number (unique identifier) and the desired property as arguments and returns the property’s integer value.

Using dealGetInteger(ticket_number, DEAL_ENTRY) to Determine Entry Type

The dealGetInteger() function, combined with the DEAL_ENTRY property, is the primary way to retrieve the entry type of a deal. The ticket_number is the unique identifier assigned to each deal by the trading platform. You typically obtain this ticket number when iterating through deal history using functions like HistorySelect() and HistoryDealGetTicket(). The second argument DEAL_ENTRY tells the function to return the entry property of that particular deal.

Possible Values for DEAL_ENTRY: DEAL_ENTRY_IN, DEAL_ENTRY_OUT, DEAL_ENTRY_INOUT, DEAL_ENTRY_NONE

The DEAL_ENTRY property can have the following values, which are predefined constants in MQL5:

  • DEAL_ENTRY_IN: The deal represents an entry into the market (opening a new position).
  • DEAL_ENTRY_OUT: The deal represents an exit from the market (closing an existing position).
  • DEAL_ENTRY_INOUT: The deal represents a reversal (closing an existing position and opening a new position in the opposite direction simultaneously). This can occur with certain order types, such as stop-loss orders that trigger a market order in the opposite direction.
  • DEAL_ENTRY_NONE: The entry type is unknown or undefined. This is rare but can occur in specific scenarios, such as deals resulting from technical issues.

Example: Retrieving and Interpreting the DEAL_ENTRY Property

long ticket = HistoryDealGetTicket(i); // i is the index of the deal
long entryType = dealGetInteger(ticket, DEAL_ENTRY);

string entryTypeDescription;
switch (entryType) {
    case DEAL_ENTRY_IN:
        entryTypeDescription = "Entry In";
        break;
    case DEAL_ENTRY_OUT:
        entryTypeDescription = "Entry Out";
        break;
    case DEAL_ENTRY_INOUT:
        entryTypeDescription = "Entry InOut (Reversal)";
        break;
    case DEAL_ENTRY_NONE:
        entryTypeDescription = "Entry None";
        break;
    default:
        entryTypeDescription = "Unknown Entry Type";
        break;
}

Print("Deal Ticket: ", ticket, ", Entry Type: ", entryTypeDescription);

Practical Applications of DEAL_ENTRY and DEAL_ENTRY_OUT

Identifying Entry Points for Different Trading Strategies

By tracking DEAL_ENTRY, you can distinguish between different entry methods used by your trading strategy. For instance, you can differentiate between trades triggered by breakout signals versus trades initiated based on retracement patterns. This enables you to analyze the performance of each entry method separately.

Filtering Deals Based on Entry and Exit Types

You can filter deals based on their entry type to perform specific analyses. For example, you might want to analyze only the deals that opened new positions (DEAL_ENTRY_IN) to assess the effectiveness of your entry signals. Similarly, you can focus on exit deals (DEAL_ENTRY_OUT) to evaluate your exit strategy.

Calculating Performance Metrics Based on Entry/Exit

The DEAL_ENTRY property helps calculate performance metrics more accurately. For instance, you can calculate the average profit per trade for entry deals versus reversal deals to understand which type of trade is more profitable. You can also calculate the average holding time for trades based on their entry type.

Code Examples and Best Practices

Example 1: Filtering Entry Deals Only

This example iterates through the historical deals and prints information only for the entry deals (DEALENTRYIN).

void OnStart() {
    datetime from = TimeCurrent() - PeriodSeconds(PERIOD_D1) * 30; // History for the last 30 days
    datetime to = TimeCurrent();

    if (!HistorySelect(from, to)) {
        Print("HistorySelect failed, error code = ", GetLastError());
        return;
    }

    int deals = HistoryDealsTotal();
    Print("Total deals: ", deals);

    for (int i = 0; i < deals; i++) {
        long ticket = HistoryDealGetTicket(i);
        if (ticket == 0) {
            Print("HistoryDealGetTicket failed, error code = ", GetLastError());
            continue;
        }

        long entryType = dealGetInteger(ticket, DEAL_ENTRY);
        if (entryType == DEAL_ENTRY_IN) {
            double price = dealGetDouble(ticket, DEAL_PRICE);
            double volume = dealGetDouble(ticket, DEAL_VOLUME);
            Print("Entry Deal: Ticket=", ticket, ", Price=", price, ", Volume=", volume);
        }
    }
}

Example 2: Identifying Scalping Trades (Entry and Exit in Short Time)

This example identifies scalping trades by checking if the entry and exit deals for a specific order occurred within a short time frame (e.g., 5 minutes). It assumes that the entry and exit deals share the same order ticket number.

void OnStart() {
    datetime from = TimeCurrent() - PeriodSeconds(PERIOD_D1) * 30; // History for the last 30 days
    datetime to = TimeCurrent();

    if (!HistorySelect(from, to)) {
        Print("HistorySelect failed, error code = ", GetLastError());
        return;
    }

    int deals = HistoryDealsTotal();
    Print("Total deals: ", deals);

    for (int i = 0; i < deals; i++) {
        long entryTicket = HistoryDealGetTicket(i);
        if (entryTicket == 0) {
            Print("HistoryDealGetTicket failed, error code = ", GetLastError());
            continue;
        }

        long entryType = dealGetInteger(entryTicket, DEAL_ENTRY);
        if (entryType == DEAL_ENTRY_IN) {
            long orderTicket = dealGetInteger(entryTicket, DEAL_ORDER);
            datetime entryTime = dealGetInteger(entryTicket, DEAL_TIME);

            // Find the corresponding exit deal
            for (int j = 0; j < deals; j++) {
                long exitTicket = HistoryDealGetTicket(j);
                if (exitTicket == 0 || i == j) continue;

                long exitType = dealGetInteger(exitTicket, DEAL_ENTRY);
                if (exitType == DEAL_ENTRY_OUT) {
                    long exitOrderTicket = dealGetInteger(exitTicket, DEAL_ORDER);
                    datetime exitTime = dealGetInteger(exitTicket, DEAL_TIME);

                    // Check if it's the same order and within the time limit
                    if (orderTicket == exitOrderTicket && (exitTime - entryTime) <= 300) { // 5 minutes = 300 seconds
                        Print("Scalping Trade Found: Entry Ticket=", entryTicket, ", Exit Ticket=", exitTicket);
                        break;
                    }
                }
            }
        }
    }
}

Best Practices for Deal Entry/Exit Handling in MQL5

  • Always check for errors: After calling dealGetInteger() or HistoryDealGetTicket(), check the return value and GetLastError() to ensure the function executed successfully. Handle errors gracefully.
  • Use descriptive variable names: Use clear and descriptive names for variables to improve code readability (e.g., entryType, exitTime).
  • Optimize loops: When iterating through deal history, optimize your loops to minimize processing time. For example, use HistorySelect() to select only the necessary deals instead of iterating through the entire history.
  • Consider using classes: Encapsulate deal-related logic into classes to improve code organization and reusability. For example, create a Deal class that stores deal properties and provides methods for analyzing deal performance.
  • Understand the limitations: Be aware that the accuracy and availability of deal history may vary depending on your broker and the trading platform’s settings. If using multi-threaded applications, ensure proper synchronization to prevent race conditions when accessing historical data.

Leave a Reply