MQL5 PositionGetInteger Guide: How to Get Position Type, Magic Number, and Time

目次

1. What Is PositionGetInteger?

PositionGetInteger is an MQL5 function used to get information about the position currently held. In an EA, or Expert Advisor, it plays a central role in deciding what kind of position the program currently has.

In MQL5, trade-related data is broadly divided into two types.

  • Order: an order that has not been filled yet, or an order in history
  • Position: an actual open holding

PositionGetInteger gets integer data related to a Position, meaning an open position.


1.1 Overview of PositionGetInteger

The basic role of PositionGetInteger is to get values such as the following.

  • Position type, such as buy or sell
  • Magic number, which is an ID used to identify the EA
  • Ticket number, which identifies the position
  • Holding time, meaning the time when the position was created

These are integer values, returned as the long type.

The basic syntax is as follows.

long PositionGetInteger(ENUM_POSITION_PROPERTY_INTEGER property_id);
  • property_id: the type of information you want to get, such as POSITION_TYPE
  • Return value: long, an integer type

For example, to get the buy or sell direction of a position:

long type = PositionGetInteger(POSITION_TYPE);

This value is interpreted as follows.

  • POSITION_TYPE_BUY, meaning buy
  • POSITION_TYPE_SELL, meaning sell

1.2 Types of Information You Can Get: ENUM_POSITION_PROPERTY_INTEGER

The information retrieved by PositionGetInteger is specified with the ENUM_POSITION_PROPERTY_INTEGER enumeration, which is a set of predefined constants.

Common examples include the following.

  • POSITION_TYPE
    → Buy or sell direction, BUY / SELL
  • POSITION_MAGIC
    → Magic number, used to identify the EA
  • POSITION_TICKET
    → Position ticket number
  • POSITION_TIME
    → Position open time, usually handled as a datetime value
  • POSITION_TIME_UPDATE
    → Last update time

By combining these values, an EA can make decisions such as the following.

  • Was this position opened by my EA?
  • Do I currently have a buy position?
  • When did the entry occur?

1.3 Where It Is Used in Real EA Logic

PositionGetInteger is mainly used in the following kinds of logic.

1. Checking Whether a Position Exists

if(PositionSelect(Symbol()))
{
    // Position exists
}

2. Branching by Buy or Sell Direction

long type = PositionGetInteger(POSITION_TYPE);

if(type == POSITION_TYPE_BUY)
{
    // Buy position logic
}
else if(type == POSITION_TYPE_SELL)
{
    // Sell position logic
}

3. Checking Only the EA’s Own Positions, Which Is Important

long magic = PositionGetInteger(POSITION_MAGIC);

if(magic == 123456)
{
    // Position opened by this EA
}

In this way, PositionGetInteger is used for state checks, so it is
a central function for branching EA logic.


Common Pitfalls, Notes, and Mistakes

1. Forgetting PositionSelect

This is the most common mistake.

PositionGetInteger(POSITION_TYPE); // Not OK by itself

Always select the target position first.

PositionSelect(Symbol());

2. Calling It When No Position Exists

If there is no position, the value cannot be retrieved correctly.

Solution:

if(PositionSelect(Symbol()))
{
    long type = PositionGetInteger(POSITION_TYPE);
}

3. Confusing It with Order Functions

This mistake is common among developers with MQL4 experience.

  • OrderSelect → order
  • PositionGetInteger → position

They have different roles, so one cannot simply replace the other.


4. Not Using a Magic Number

If multiple EAs and manual trades coexist, the EA may make the wrong decision.

→ Always filter with POSITION_MAGIC.

2. Basic Syntax and Usage: The Shortest Way to Understand It

MQL5 PositionGetInteger usage with PositionSelect showing execution flow for validating open positions, retrieving trade properties like POSITION_TYPE and POSITION_MAGIC, and managing BUY/SELL positions in MetaTrader with code and chart visualization

PositionGetInteger does not work correctly by itself. It is essential to use it together with PositionSelect. This section shows working code and the correct procedure in the shortest practical form.


2.1 Basic Syntax

The basic form of PositionGetInteger is as follows.

long PositionGetInteger(ENUM_POSITION_PROPERTY_INTEGER property_id);

In real development, however, the flow is always as follows.

Basic procedure, important

  • 1. Select the target position
  • 2. Get information with PositionGetInteger
  • 3. Branch the logic based on the value

In code, this looks like this:

if(PositionSelect(Symbol()))
{
    long value = PositionGetInteger(POSITION_TYPE);
}

This PositionSelect → get value order is the key point.


2.2 Minimal Sample Code: Complete Working Example

First, here is the smallest useful code for getting the buy or sell direction of a position.

void OnTick()
{
    if(PositionSelect(Symbol()))
    {
        long type = PositionGetInteger(POSITION_TYPE);

        if(type == POSITION_TYPE_BUY)
        {
            Print("Holding a buy position");
        }
        else if(type == POSITION_TYPE_SELL)
        {
            Print("Holding a sell position");
        }
    }
    else
    {
        Print("No position");
    }
}

With this code, you can check the following.

  • Whether a position exists
  • Whether it is buy or sell
  • The basic structure of conditional branching

2.3 Relationship with PositionSelect: Required Knowledge

PositionGetInteger works only on the currently selected position.

Therefore, without PositionSelect:

long type = PositionGetInteger(POSITION_TYPE); // Undefined or 0

→ You cannot get the correct value.


Role of PositionSelect

bool PositionSelect(string symbol);
  • Selects the position for the specified symbol
  • Success: true
  • Failure: false

Correct Usage Template

if(PositionSelect(Symbol()))
{
    long type = PositionGetInteger(POSITION_TYPE);
}

Why It Works This Way: Understanding the Structure

Internally, MQL5 is designed around two steps:

  • the currently selected position
  • getting information from that selected position

In other words:

PositionGetInteger is a function that cannot specify its target by itself.

That is the important design point.


Common Pitfalls, Notes, and Mistakes

1. Using It Without PositionSelect

long type = PositionGetInteger(POSITION_TYPE); // NG

PositionSelect is always required.


2. Hard-Coding Symbol()

PositionSelect(Symbol());

This targets only the current chart.

For a multi-currency EA, you need to specify the symbol explicitly, as in:

PositionSelect("EURUSD");

3. Mishandling the long Type

The return value of PositionGetInteger is a long type, a 64-bit integer.

int type = PositionGetInteger(POSITION_TYPE); // Not recommended

→ This can cause bugs due to type mismatch.


4. Not Handling the Case Where No Position Exists

long type = PositionGetInteger(POSITION_TYPE); // Risky

→ Always wrap it with if(PositionSelect()).


5. Ignoring Success or Failure

if(PositionSelect(Symbol()))
{
    // Process only when selection succeeds
}

If you skip this check, the EA may make incorrect decisions.

3. Main Property List and Practical Use Cases

PositionGetInteger can retrieve many kinds of information, but only some are especially important in real development. This section focuses on the properties frequently used in EA development.


3.1 Frequently Used Properties: Important

The following properties are almost essential in practical EA development.

PropertyDescriptionUse Case
POSITION_TYPEBuy or sell directionBUY / SELL check
POSITION_MAGICMagic numberEA identification
POSITION_TICKETTicket numberPosition management
POSITION_TIMEOpen timeHolding-time calculation
POSITION_TIME_UPDATEUpdate timeTrailing stop logic and similar checks

3.2 POSITION_TYPE: Buy or Sell Direction

This property checks whether the position is a buy or a sell.

long type = PositionGetInteger(POSITION_TYPE);

How to check it:

if(type == POSITION_TYPE_BUY)
{
    // Buy
}
else if(type == POSITION_TYPE_SELL)
{
    // Sell
}

Practical Uses

  • Checking the direction for averaging-down logic
  • Controlling entries in the opposite direction
  • Branching take-profit and stop-loss conditions

3.3 POSITION_MAGIC: EA Identification

This is the ID used to identify whether a position was opened by a specific EA.

long magic = PositionGetInteger(POSITION_MAGIC);

Practical Use: Important

if(magic == 123456)
{
    // Process only this EA's positions
}

Why It Matters

  • Manual trades may coexist with EA trades
  • Multiple EAs may run at the same time

In this situation, if you do not filter by magic number:

  • the EA may operate on another EA’s position
  • the EA may close a manual position

→ This can lead to serious trading mistakes.


3.4 POSITION_TICKET: Position Identification

This is the unique ID for each position.

long ticket = PositionGetInteger(POSITION_TICKET);

Practical Uses

  • Log output
  • Debugging
  • Individual position management

Important Note

In MQL5, there is usually one position per symbol, known as a net position.

→ In many cases, symbol-based management is more basic than ticket-based management.


3.5 POSITION_TIME: Entry Time

This property gets the start time of the position.

long time = PositionGetInteger(POSITION_TIME);

Convert it to datetime:

datetime open_time = (datetime)PositionGetInteger(POSITION_TIME);

Practical Use

  • Limiting holding time
datetime open_time = (datetime)PositionGetInteger(POSITION_TIME);

if(TimeCurrent() - open_time > 3600)
{
    // Held for more than 1 hour -> close
}

3.6 POSITION_TIME_UPDATE: Update Time

This is the last update time of the position.

long update_time = PositionGetInteger(POSITION_TIME_UPDATE);

Practical Uses

  • Trailing stop management
  • Monitoring update frequency
  • Checking EA operation

Common Pitfalls, Notes, and Mistakes

1. Not Checking the Magic Number

if(PositionSelect(Symbol()))
{
    // This may target all positions
}

→ Always use:

if(PositionGetInteger(POSITION_MAGIC) == YOUR_ID)

2. Forgetting datetime Conversion

long time = PositionGetInteger(POSITION_TIME);

→ It is hard to use as-is.

datetime t = (datetime)time;

3. Misunderstanding Net Positions

Difference from MQL4:

  • MQL4: multiple positions
  • MQL5: basically one position per currency pair

→ The logic design changes.


4. Confusing Update Time and Open Time

  • POSITION_TIME → entry time
  • POSITION_TIME_UPDATE → last update

They have different purposes, so confusing them can cause bugs.


5. Misunderstanding the Property Type

PositionGetInteger retrieves:

  • long, an integer type

It cannot retrieve prices:

  • → Use PositionGetDouble.

4. Handling Multiple Positions: Loops and Practical Patterns

In MQL5, the default model is basically one position per symbol, known as a net position. However, multi-symbol operation, multiple EAs, and hedging accounts require handling multiple positions. This section explains practical loop patterns used together with PositionGetInteger.


4.1 Getting the Number of Positions: PositionsTotal

First, get the number of currently held positions.

int total = PositionsTotal();
  • Return value: current number of positions
  • If the value is 0: no positions exist

4.2 Looping with PositionSelectByIndex

This is the basic structure for processing multiple positions.

for(int i = 0; i < PositionsTotal(); i++)
{
    if(PositionSelectByIndex(i))
    {
        long type = PositionGetInteger(POSITION_TYPE);
        Print("Type: ", type);
    }
}

Processing Flow

  • Get the count with PositionsTotal
  • Access each position in order with a for loop
  • Select the target with PositionSelectByIndex
  • Get information with PositionGetInteger

4.3 Practical EA Template

This is an almost complete template for real EA development.

for(int i = 0; i < PositionsTotal(); i++)
{
    if(PositionSelectByIndex(i))
    {
        string symbol = PositionGetString(POSITION_SYMBOL);
        long magic   = PositionGetInteger(POSITION_MAGIC);
        long type    = PositionGetInteger(POSITION_TYPE);

        // Target only this EA
        if(magic != 123456) continue;

        // Symbol filter
        if(symbol != Symbol()) continue;

        if(type == POSITION_TYPE_BUY)
        {
            Print("BUY position detected");
        }
        else if(type == POSITION_TYPE_SELL)
        {
            Print("SELL position detected");
        }
    }
}

What This Template Can Do

  • Scan all positions
  • Filter by EA
  • Filter by currency pair
  • Check buy or sell direction

→ This is the foundation of almost all EA logic.


4.4 Difference Between Hedging Accounts and Netting Accounts

Netting Account, Normal Case

  • One symbol = one position
  • PositionsTotal is usually small

Hedging Account

  • Multiple positions can exist on the same symbol
  • BUY and SELL positions can be held at the same time

Impact

On a hedging account:

for(int i = 0; i < PositionsTotal(); i++)

becomes required.


4.5 Common Practical Patterns

1. Count Positions Opened by Your EA

int count = 0;

for(int i = 0; i < PositionsTotal(); i++)
{
    if(PositionSelectByIndex(i))
    {
        if(PositionGetInteger(POSITION_MAGIC) == 123456)
        {
            count++;
        }
    }
}

2. Count Only BUY Positions

int buy_count = 0;

for(int i = 0; i < PositionsTotal(); i++)
{
    if(PositionSelectByIndex(i))
    {
        if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY)
        {
            buy_count++;
        }
    }
}

3. Extract Close Candidates by Condition

datetime now = TimeCurrent();

for(int i = 0; i < PositionsTotal(); i++)
{
    if(PositionSelectByIndex(i))
    {
        datetime open_time = (datetime)PositionGetInteger(POSITION_TIME);

        if(now - open_time > 3600)
        {
            Print("More than 1 hour elapsed -> close candidate");
        }
    }
}

Common Pitfalls, Notes, and Mistakes

1. Forgetting PositionSelectByIndex

PositionGetInteger(POSITION_TYPE); // NG

→ Selection is always required.


2. Positions Changing During the Loop

If the EA closes or opens positions:

  • PositionsTotal changes
  • Index shifting can occur

→ Solution:

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

Use a reverse loop.


3. Processing Without Filters

// Targeting all positions -> risky

→ Always narrow the target by:

  • MAGIC
  • SYMBOL

before processing.


4. Not Accounting for Hedging Accounts

If the EA is built only for netting accounts:

  • the logic can break
  • unexpected behavior can occur

5. Forgetting to Use PositionGetString

string symbol = PositionGetString(POSITION_SYMBOL);

→ This is required for symbol checks.

5. Differences Between PositionGetInteger, PositionGetDouble, and PositionGetString

In MQL5, the functions for getting position information are divided into three types.

  • PositionGetInteger, for integers
  • PositionGetDouble, for decimal values
  • PositionGetString, for strings

If you do not understand this difference, retrieval mistakes, type errors, and logic bugs can occur. This section organizes the difference so you can use the right function in practice.


5.1 Roles of the Three Functions

FunctionType RetrievedMain Use
PositionGetIntegerlong, integerType, time, and identification data
PositionGetDoubledouble, decimalPrice, profit/loss, and lot size
PositionGetStringstringSymbol name and similar text data

5.2 What PositionGetInteger Is For

It handles integer-based information.

long type = PositionGetInteger(POSITION_TYPE);

Main targets include:

  • buy or sell direction, POSITION_TYPE
  • magic number, POSITION_MAGIC
  • time, POSITION_TIME
  • ticket number, POSITION_TICKET

5.3 What PositionGetDouble Is For

It handles decimal data such as prices and quantities.

double price = PositionGetDouble(POSITION_PRICE_OPEN);

Main targets include:

  • entry price
  • current price
  • profit/loss, PROFIT
  • lot size

Practical Example: Getting Profit/Loss

double profit = PositionGetDouble(POSITION_PROFIT);

5.4 What PositionGetString Is For

It handles string data.

string symbol = PositionGetString(POSITION_SYMBOL);

Main targets include:

  • currency pair name, such as EURUSD
  • comments

5.5 Correct Function Selection: Important

Bad Example: Common Mistake

long price = PositionGetInteger(POSITION_PRICE_OPEN); // NG

→ Price is a double.


Correct Example

double price = PositionGetDouble(POSITION_PRICE_OPEN);

5.6 Practical Combination Example: Important Template

The basic approach is to combine all three functions.

if(PositionSelect(Symbol()))
{
    string symbol = PositionGetString(POSITION_SYMBOL);
    long   type   = PositionGetInteger(POSITION_TYPE);
    double profit = PositionGetDouble(POSITION_PROFIT);

    Print("Symbol:", symbol);
    Print("Type:", type);
    Print("Profit/Loss:", profit);
}

Meaning of This Structure

  • Integer → state checks
  • Double → numeric evaluation, such as profit/loss
  • String → target identification

→ Use these as one set.


Common Pitfalls, Notes, and Mistakes

1. Mixing Up Types

long profit = PositionGetInteger(POSITION_PROFIT); // NG

PROFIT is a double.


2. Confusing ENUM Groups

  • POSITION_TYPE → Integer
  • POSITION_PRICE_OPEN → Double

→ The names are similar, so they are easy to confuse.


3. Forgetting to Cast Time

datetime t = PositionGetInteger(POSITION_TIME); // Not recommended

→ Write it explicitly:

datetime t = (datetime)PositionGetInteger(POSITION_TIME);

4. Forgetting String Retrieval

In multi-symbol operation:

// Judging only with Symbol() -> insufficient

→ Always use:

PositionGetString(POSITION_SYMBOL);

5. Trying to Get Everything with Integer

This is a common mistake among developers with MQL4 experience.

→ In MQL5, functions are separated by data type.


Best Practical Design Guideline

  • Checks → PositionGetInteger
  • Numeric values → PositionGetDouble
  • Identification → PositionGetString

Designing with this rule greatly reduces bugs.

6. Practical Samples: EA Usage Patterns

This section explains practical code that can be used almost directly in a real EA, centered on PositionGetInteger. Instead of only retrieving values, the examples apply it to real trading logic such as entry control, close conditions, and position holding control.


6.1 Entry Control: Preventing Duplicate Positions

This is the most basic and important pattern.
If a position already exists, the EA does not open a new entry.

bool HasPosition(string symbol, long magic)
{
    for(int i = 0; i < PositionsTotal(); i++)
    {
        if(PositionSelectByIndex(i))
        {
            if(PositionGetString(POSITION_SYMBOL) == symbol &&
               PositionGetInteger(POSITION_MAGIC) == magic)
            {
                return true;
            }
        }
    }
    return false;
}

Usage example:

if(!HasPosition(Symbol(), 123456))
{
    // Entry logic
}

Practical Points

  • Prevents averaging down when it is not intended
  • Prevents duplicate entries
  • Prevents the EA from running out of control

6.2 Branching Logic by Buy or Sell Direction

The EA changes its processing based on the direction of the position.

if(PositionSelect(Symbol()))
{
    long type = PositionGetInteger(POSITION_TYPE);

    if(type == POSITION_TYPE_BUY)
    {
        // BUY-only logic
    }
    else if(type == POSITION_TYPE_SELL)
    {
        // SELL-only logic
    }
}

Practical Uses

  • Adjusting trailing stop direction
  • Changing take-profit and stop-loss conditions
  • Controlling contrarian or trend-following logic

6.3 Closing by Holding Time: Time Control

This logic closes a position after a certain amount of time has passed.

void CheckTimeClose()
{
    for(int i = 0; i < PositionsTotal(); i++)
    {
        if(PositionSelectByIndex(i))
        {
            datetime open_time = (datetime)PositionGetInteger(POSITION_TIME);

            if(TimeCurrent() - open_time > 3600)
            {
                Print("1 hour elapsed -> close target");
                // Close logic, implemented separately
            }
        }
    }
}

Practical Uses

  • Time limits for scalping
  • Avoiding rollover
  • Reducing long holding risk

6.4 Complete Filtering by Magic Number

This separates positions by EA.

for(int i = 0; i < PositionsTotal(); i++)
{
    if(PositionSelectByIndex(i))
    {
        if(PositionGetInteger(POSITION_MAGIC) != 123456)
            continue;

        // Process only this EA's positions
    }
}

Practical Importance

  • Multiple EAs running at the same time
  • Coexistence with manual trades

→ This is effectively required.


6.5 Integrated Template: Ready for Practical Use

The following is integrated code often used in real development.

void ManagePositions()
{
    for(int i = PositionsTotal() - 1; i >= 0; i--)
    {
        if(PositionSelectByIndex(i))
        {
            string symbol = PositionGetString(POSITION_SYMBOL);
            long magic   = PositionGetInteger(POSITION_MAGIC);
            long type    = PositionGetInteger(POSITION_TYPE);
            datetime open_time = (datetime)PositionGetInteger(POSITION_TIME);

            // Filters
            if(symbol != Symbol()) continue;
            if(magic != 123456) continue;

            // Time control
            if(TimeCurrent() - open_time > 3600)
            {
                Print("Time elapsed close target");
            }

            // Direction-specific logic
            if(type == POSITION_TYPE_BUY)
            {
                Print("Managing BUY");
            }
            else if(type == POSITION_TYPE_SELL)
            {
                Print("Managing SELL");
            }
        }
    }
}

Features of This Template

  • Supports all positions
  • Includes filters
  • Includes time control
  • Includes direction branching

→ This is the basic structure of an intermediate-level EA.


Common Pitfalls, Notes, and Mistakes

1. Close Logic Is Not Implemented

// Ends with Print only

→ In real trading, close processing with OrderSend is required.


2. Not Using a Reverse Loop

for(int i = 0; i < PositionsTotal(); i++)

→ This can cause bugs when closing positions.

→ Solution:

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

3. Forgetting the Symbol Filter

→ The EA may interfere with other currency pairs.


4. Not Using Magic

→ The EA may affect other EAs.


5. Misunderstanding the Time Condition

TimeCurrent() - open_time

→ This is in seconds, so 3600 equals 1 hour.


Practical Summary

The essence of PositionGetInteger is not to use it alone, but to combine it with:

  • PositionSelect-related functions
  • PositionGetDouble
  • PositionGetString

and use it as a state-check engine.

7. Errors, Bugs, and Why It Does Not Work: Troubleshooting

PositionGetInteger is a simple function, but it will not work correctly unless its prerequisites are met. This section organizes common real-world causes of failure and gives reproducible fixes.


7.1 Cannot Get a Value: Always 0 or an Abnormal Value

Cause 1: PositionSelect Was Not Called

long type = PositionGetInteger(POSITION_TYPE); // NG

→ Fix:

if(PositionSelect(Symbol()))
{
    long type = PositionGetInteger(POSITION_TYPE);
}

Cause 2: No Position Exists

PositionSelect(Symbol()) == false

→ In this case, the retrieved value has no practical meaning.


Fix Template

if(!PositionSelect(Symbol()))
{
    Print("No position");
    return;
}

7.2 Conditional Branching Does Not Work

Cause: Misunderstanding the Type or Value

if(PositionGetInteger(POSITION_TYPE) == 0)

→ This is hard to read and can cause mistakes.


Correct Way to Write It

if(type == POSITION_TYPE_BUY)

Important Notes

  • POSITION_TYPE_BUY / SELL are constants
  • Do not compare by raw numbers because readability and maintainability are lower

7.3 Unexpected Behavior with Multiple Positions

Cause: Logic Assumes Only One Position

PositionSelect(Symbol());

→ This checks only one position.


Fix: Loop Processing

for(int i = 0; i < PositionsTotal(); i++)
{
    PositionSelectByIndex(i);
}

7.4 Accidentally Operating on Another EA’s or Manual Position

Cause: Magic Number Is Not Checked

// No filter

Fix

if(PositionGetInteger(POSITION_MAGIC) != 123456)
    continue;

7.5 Symbol Does Not Match

Cause

PositionSelect(Symbol());

→ This targets only the current chart.


Fix

string symbol = PositionGetString(POSITION_SYMBOL);
if(symbol != Symbol()) continue;

7.6 Time Calculation Does Not Work Correctly

Cause: Type Conversion Mistake

long time = PositionGetInteger(POSITION_TIME);

→ It is hard to handle as-is.


Correct Method

datetime open_time = (datetime)PositionGetInteger(POSITION_TIME);

Common Misunderstanding

  • The difference from TimeCurrent() is in seconds
  • 3600 = 1 hour

7.7 Bugs During a Loop, Especially When Closing

Cause: Forward Loop

for(int i = 0; i < PositionsTotal(); i++)

→ Closing positions can break the index order.


Fix: Important

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

7.8 Debugging Is Difficult

Cause: Not Enough Logs


Fix: Required

Print("type:", type);
Print("magic:", magic);
Print("symbol:", symbol);

Practical Debugging Tips

  • Always output important variables
  • Add logs before and after conditional branches
  • Verify behavior in the tester

Summary of Common Pitfalls

ProblemCauseFix
Value is 0No PositionSelectSelect the position first
Wrong condition resultConstants not usedUse ENUM constants
Wrong position operated onMagic not checkedFilter by magic number
Unstable behaviorLoop issueUse a reverse loop
Time bugType mistakeConvert to datetime

Practical Conclusion

Most PositionGetInteger problems come down to the following three causes.

  • The position was not selected, meaning PositionSelect is missing
  • The position was not filtered, meaning Magic / Symbol checks are missing
  • The data type is not understood correctly

→ If you follow these three rules, almost all related bugs can be avoided.

8. Summary

PositionGetInteger is a basic MQL5 function for getting integer-based information about positions. It may look like a simple value-reading function, but in real EA development it is used at the core of trading logic, including state checks, holding control, duplicate-entry prevention, and close-condition checks.

The key practical points from this article are as follows.

  • Do not use PositionGetInteger by itself; always combine it with PositionSelect or PositionSelectByIndex
  • It retrieves integer-based information; use PositionGetDouble for price and profit/loss, and PositionGetString for symbol names
  • In practice, POSITION_TYPE, POSITION_MAGIC, POSITION_TICKET, and POSITION_TIME are especially important
  • For multiple positions, PositionsTotal and loop processing are required
  • Most bugs are explained by three issues: not selecting, not filtering, and misunderstanding the type

The first basic template beginners should learn is this:

if(PositionSelect(Symbol()))
{
    long type = PositionGetInteger(POSITION_TYPE);

    if(type == POSITION_TYPE_BUY)
    {
        Print("Holding a BUY position");
    }
    else if(type == POSITION_TYPE_SELL)
    {
        Print("Holding a SELL position");
    }
}
else
{
    Print("No position");
}

Starting from this form, it is safer to add the following checks as needed.

  • Magic number check
  • Symbol check
  • Holding-time check
  • Loop processing for multiple positions

In short, it is better to understand PositionGetInteger not just as a function that gets something, but as a foundational function that lets an EA correctly recognize its current holding state. If this part is vague, duplicate entries, accidental operation on another EA’s positions, and position-detection mistakes become more likely.

To build stable trading logic in MQL5, first make sure you can reliably reproduce the flow:
PositionSelectPositionGetInteger → conditional branching.

The next section organizes FAQs that answer the questions search users are most likely to have.

FAQ

1. What does PositionGetInteger retrieve?

It retrieves integer-type information about a position. Typical examples include buy or sell direction, magic number, ticket number, and position open time.

2. Why should PositionGetInteger not be used by itself?

PositionGetInteger works on the currently selected position. If you do not select the target first with PositionSelect or PositionSelectByIndex, you cannot reliably get the correct value.

3. Why is the value always 0?

The main causes are as follows.

  • No position exists
  • PositionSelect was not executed
  • The target symbol is different

First, check with if(PositionSelect(Symbol())).

4. How should POSITION_TYPE be checked?

Compare it with constants as follows.

long type = PositionGetInteger(POSITION_TYPE);

if(type == POSITION_TYPE_BUY)
{
    // Buy
}
else if(type == POSITION_TYPE_SELL)
{
    // Sell
}

Comparing by constant names is safer than directly comparing raw numeric values.

5. What is the difference between PositionGetDouble and PositionGetString?

The difference is the type of data each function retrieves.

  • PositionGetInteger: integers
  • PositionGetDouble: decimal values such as price, profit/loss, and lots
  • PositionGetString: strings such as symbol names and comments

You need to choose the correct function for each purpose.

6. Why is the magic number important?

The magic number identifies only the positions opened by your EA in an environment where multiple EAs or manual trades may coexist. Without it, the EA may accidentally operate on unrelated positions.

7. How should multiple positions be processed?

Use PositionsTotal() to get the count, then loop through positions with PositionSelectByIndex(). This may be required for hedging accounts or multi-currency EAs.

8. How should POSITION_TIME be handled?

The retrieved value is an integer, but it is normally cast to datetime.

datetime open_time = (datetime)PositionGetInteger(POSITION_TIME);

After that, compare it with TimeCurrent() to check holding time.

9. Can I use it the same way as MQL4 OrderSelect?

No. In MQL5, orders and positions are clearly separated. If you implement MQL5 logic with the same assumptions as MQL4, it can cause incorrect behavior.

10. What practical pattern should beginners learn first?

Start with the following flow.

  • Select the target with PositionSelect
  • Get the type with PositionGetInteger
  • Branch by BUY / SELL
  • Filter by MAGIC or TIME as needed

Once you can write this basic form correctly, it becomes much easier to build stable EA position-management logic.