- 1 1. What Is PositionGetInteger?
- 2 2. Basic Syntax and Usage: The Shortest Way to Understand It
- 3 3. Main Property List and Practical Use Cases
- 4 4. Handling Multiple Positions: Loops and Practical Patterns
- 5 5. Differences Between PositionGetInteger, PositionGetDouble, and PositionGetString
- 5.1 5.1 Roles of the Three Functions
- 5.2 5.2 What PositionGetInteger Is For
- 5.3 5.3 What PositionGetDouble Is For
- 5.4 5.4 What PositionGetString Is For
- 5.5 5.5 Correct Function Selection: Important
- 5.6 5.6 Practical Combination Example: Important Template
- 5.7 Common Pitfalls, Notes, and Mistakes
- 5.8 Best Practical Design Guideline
- 6 6. Practical Samples: EA Usage Patterns
- 6.1 6.1 Entry Control: Preventing Duplicate Positions
- 6.2 6.2 Branching Logic by Buy or Sell Direction
- 6.3 6.3 Closing by Holding Time: Time Control
- 6.4 6.4 Complete Filtering by Magic Number
- 6.5 6.5 Integrated Template: Ready for Practical Use
- 6.6 Common Pitfalls, Notes, and Mistakes
- 6.7 Practical Summary
- 7 7. Errors, Bugs, and Why It Does Not Work: Troubleshooting
- 7.1 7.1 Cannot Get a Value: Always 0 or an Abnormal Value
- 7.2 7.2 Conditional Branching Does Not Work
- 7.3 7.3 Unexpected Behavior with Multiple Positions
- 7.4 7.4 Accidentally Operating on Another EA’s or Manual Position
- 7.5 7.5 Symbol Does Not Match
- 7.6 7.6 Time Calculation Does Not Work Correctly
- 7.7 7.7 Bugs During a Loop, Especially When Closing
- 7.8 7.8 Debugging Is Difficult
- 7.9 Summary of Common Pitfalls
- 7.10 Practical Conclusion
- 8 8. Summary
- 9 FAQ
- 9.1 1. What does PositionGetInteger retrieve?
- 9.2 2. Why should PositionGetInteger not be used by itself?
- 9.3 3. Why is the value always 0?
- 9.4 4. How should POSITION_TYPE be checked?
- 9.5 5. What is the difference between PositionGetDouble and PositionGetString?
- 9.6 6. Why is the magic number important?
- 9.7 7. How should multiple positions be processed?
- 9.8 8. How should POSITION_TIME be handled?
- 9.9 9. Can I use it the same way as MQL4 OrderSelect?
- 9.10 10. What practical pattern should beginners learn first?
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 asPOSITION_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 buyPOSITION_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 / SELLPOSITION_MAGIC
→ Magic number, used to identify the EAPOSITION_TICKET
→ Position ticket numberPOSITION_TIME
→ Position open time, usually handled as adatetimevaluePOSITION_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→ orderPositionGetInteger→ 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

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:
PositionGetIntegeris 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.
| Property | Description | Use Case |
|---|---|---|
| POSITION_TYPE | Buy or sell direction | BUY / SELL check |
| POSITION_MAGIC | Magic number | EA identification |
| POSITION_TICKET | Ticket number | Position management |
| POSITION_TIME | Open time | Holding-time calculation |
| POSITION_TIME_UPDATE | Update time | Trailing 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 timePOSITION_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
forloop - 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
PositionsTotalis 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:
PositionsTotalchanges- 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:
MAGICSYMBOL
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 integersPositionGetDouble, for decimal valuesPositionGetString, 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
| Function | Type Retrieved | Main Use |
|---|---|---|
| PositionGetInteger | long, integer | Type, time, and identification data |
| PositionGetDouble | double, decimal | Price, profit/loss, and lot size |
| PositionGetString | string | Symbol 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→ IntegerPOSITION_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 functionsPositionGetDoublePositionGetString
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/SELLare 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
| Problem | Cause | Fix |
|---|---|---|
| Value is 0 | No PositionSelect | Select the position first |
| Wrong condition result | Constants not used | Use ENUM constants |
| Wrong position operated on | Magic not checked | Filter by magic number |
| Unstable behavior | Loop issue | Use a reverse loop |
| Time bug | Type mistake | Convert to datetime |
Practical Conclusion
Most PositionGetInteger problems come down to the following three causes.
- The position was not selected, meaning
PositionSelectis 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
PositionGetIntegerby itself; always combine it withPositionSelectorPositionSelectByIndex - It retrieves integer-based information; use
PositionGetDoublefor price and profit/loss, andPositionGetStringfor symbol names - In practice,
POSITION_TYPE,POSITION_MAGIC,POSITION_TICKET, andPOSITION_TIMEare especially important - For multiple positions,
PositionsTotaland 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:PositionSelect → PositionGetInteger → 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
PositionSelectwas 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: integersPositionGetDouble: decimal values such as price, profit/loss, and lotsPositionGetString: 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.