- 1 1. What “trade context busy” Means in MQL5
- 2 2. Main Causes: Understanding the Mechanism
- 3 3. Fastest Ways to Fix It: Implementation-Based Solutions
- 3.1 3.1 Basic Fix 1: Add Waiting Time Between Processes with Sleep
- 3.2 3.2 Basic Fix 2: Flag Management to Prevent Re-Entry
- 3.3 3.3 Basic Fix 3: Always Check the Order Result
- 3.4 3.4 Basic Fix 4: Check Whether Trading Is Allowed
- 3.5 3.5 Recommended Practical Combination: Template
- 3.6 Common Sticking Points and Notes
- 3.7 Common Mistakes
- 4 4. Implementation Examples: Copy-and-Paste Code
- 5 5. Common Mistakes: Important Cases
- 6 6. Practical Countermeasures to Prevent Recurrence
- 7 7. Performance and Design Perspective for Intermediate Developers
- 8 8. Differences from Similar Errors: Avoiding Misdiagnosis
- 9 9. FAQ
- 9.1 Q1. Is it okay to ignore trade context busy?
- 9.2 Q2. Does adding Sleep completely solve the issue?
- 9.3 Q3. Can OrderSendAsync avoid busy errors?
- 9.4 Q4. Why does it not happen in backtests but happens in live trading?
- 9.5 Q5. Will running multiple EAs always cause the error?
- 9.6 Q6. Will changing the VPS solve it?
- 9.7 Q7. What is the most effective countermeasure?
- 9.8 Q8. Can trade context busy be reduced to zero?
1. What “trade context busy” Means in MQL5
1.1 Meaning of the Error: trade context busy
trade context busy is an error that means a trade operation in MQL5, such as placing or closing an order, is already running and a new order cannot be accepted yet.
More precisely, MetaTrader has an internal processing area called the trade context. This area is designed so that only one trade operation can run at a time.
As a result, the error can occur in situations such as these:
- An order process has not finished yet
- The terminal is waiting for a server response
- Another order was sent immediately before the current one
For beginners, the simple explanation is this:
you sent the next order before the previous order had finished.
1.2 When It Occurs
This error mainly occurs when using the following functions or operations.
OrderSend()(send an order)OrderSendAsync()(send an asynchronous order)- Position closing or modification processes
It is especially likely to occur in these cases:
- Orders are sent repeatedly inside OnTick whenever conditions are met
- A loop sends multiple orders in a short period of time
- A high-speed EA, such as a scalping EA, is being used
- Multiple EAs are running on the same account at the same time
Example of a risky pattern:
void OnTick()
{
if(条件)
{
OrderSend(request, result);
OrderSend(request, result); // Consecutive execution -> likely to cause an error
}
}
In this way, the error is highly likely when trade operations are executed repeatedly without waiting for the previous process to finish.
1.3 Intuitive Explanation for Beginners
This error is less about a programming syntax problem and more about a mistake in managing the order of operations.
A simple analogy is:
- There is only one checkout counter
- Two customers try to cut in and pay at the same time instead of waiting their turn
Result: the process becomes busy and the request is rejected.
In other words, in MQL5 it is important to understand these assumptions:
- Trade processing is single-threaded for practical purposes: one operation at a time
- Orders need queue-like handling: each order must wait its turn
Common Sticking Points and Notes
- It is easy to assume the error is caused by a bad connection, but logic problems are often the real cause
- It is more likely when code runs at high speed without
Sleep - It can be hard to reproduce in backtests, and often appears for the first time in a live environment
- Some traders assume
OrderSendAsyncavoids the issue, but it can make the problem worse
Common Mistakes
- Ignoring the error and continuing to run the EA
- Not checking logs, so the cause is never identified
- Treating it as a random one-time issue even though recurrence is common
- Running multiple EAs and creating conflicts between them
2. Main Causes: Understanding the Mechanism
Key point in this section:trade context busy is not a random error. It occurs because of a clear structure: exclusive control of trade processing. Breaking down the causes makes the issue easier to understand and reproduce.

2.1 Simultaneous Orders: Consecutive OrderSend Calls
The most common cause is sending multiple orders consecutively within a short period of time.
In MQL5, the next order cannot be accepted until the current order process has finished.
However, consecutive sending can occur in code like this:
void OnTick()
{
if(買い条件)
OrderSend(request, result);
if(別の条件)
OrderSend(request, result);
}
In this case, the second order may run while the first order is still being processed.
The result is a busy error.
Notes
- A design where multiple conditions can become true at the same time is very risky
- This is especially common in scalping EAs
2.2 Misusing Asynchronous Processing: OrderSendAsync
OrderSendAsync() is an asynchronous function, meaning it moves on without waiting for completion.
At first glance, it may look like a way to speed up order execution, but in practice it creates these problems:
- It does not wait for processing to finish
- State management becomes necessary
- Consecutive sending becomes easier to trigger
OrderSendAsync(request, result);
OrderSendAsync(request, result); // Highly likely to conflict
Beginner misunderstanding
- Async does not mean fast and safe
- In practice, it can increase errors if it is not controlled properly
2.3 Conflicts Between Multiple EAs or Scripts
When multiple EAs run on the same account,
different EAs may send orders at the same time.
Example:
- EA 1: entry
- EA 2: close position
- EA 3: lot adjustment
When these run at the same time:
The EAs compete for the trade context.
Then the busy error occurs.
Important point
- MQL5 trade control is account-wide
- It is not isolated per EA
2.4 Broker and Server Latency
Orders do not complete locally. They require communication with the broker server.
Because of this, delays can happen due to factors such as:
- VPS quality
- Connection speed
- Server load
- Execution processing delay
During this time, the trade context is occupied.
Result
- The next order causes a busy error
Additional note
- The frequency varies by environment
- It can be especially noticeable with some overseas brokers
2.5 Locked Trade Processing
Inside MQL5, a lock, or exclusive control, is applied while trade processing is running.
This lock is released when:
- The order is completed
- An error is returned
- The server response is completed
However, the lock may remain active for a longer time in cases such as:
- Waiting for execution
- Retry processing
- Delayed server response
If a new order is sent in this state, it will almost certainly become busy.
Common Sticking Points and Notes
- It is easy to assume only your EA is running, while another EA is actually the cause
- The issue may not appear in testing but only in production
- The design may not account for communication delay
- Asynchronous processing may be used without proper understanding
Common Mistakes
- Calling
OrderSendimmediately whenever a condition is met inOnTick - No flag management
- High-speed loops without
Sleep - Running multiple EAs and causing interference
- No error handling implemented
3. Fastest Ways to Fix It: Implementation-Based Solutions
Key point in this section:trade context busy can be prevented by design. Start with fixes that reliably work, then use implementation patterns that are reproducible in real trading environments.
3.1 Basic Fix 1: Add Waiting Time Between Processes with Sleep
The simplest and fastest fix is to add a waiting time between orders.
void OnTick()
{
if(条件)
{
OrderSend(request, result);
Sleep(500); // Wait 500 milliseconds
}
}
Points
- Typical range: 300 to 1000 ms, adjusted by environment
- The best value depends on the VPS and broker
Advantages
- Easy to implement
- Can reduce errors immediately
Disadvantages
- Too much waiting can cause missed opportunities, especially in scalping
- It is not a root-cause fix
3.2 Basic Fix 2: Flag Management to Prevent Re-Entry
This is the most important fix.
Create a state where no new order is sent while an order is already being processed.
bool isTrading = false;
void OnTick()
{
if(isTrading) return;
if(条件)
{
isTrading = true;
if(OrderSend(request, result))
{
// Success
}
isTrading = false;
}
}
Points
- Use a flag for exclusive control and to prevent simultaneous execution
- This is essential for almost every EA
Notes
- Release the flag even when an error occurs
- If the flag is not released, the EA can stop placing orders
3.3 Basic Fix 3: Always Check the Order Result
If the result of OrderSend is ignored, state management becomes unreliable.
MqlTradeResult result;
if(OrderSend(request, result))
{
Print("Order successful");
}
else
{
Print("Error code: ", GetLastError());
}
Important
- Always branch on success and failure
- Log output is required for debugging
3.4 Basic Fix 4: Check Whether Trading Is Allowed
Before sending an order, check whether trading is currently allowed.
if(!TerminalInfoInteger(TERMINAL_TRADE_ALLOWED))
{
return;
}
Or:
if(!MQLInfoInteger(MQL_TRADE_ALLOWED))
{
return;
}
Effect
- Prevents unnecessary order requests
- Reduces error frequency
3.5 Recommended Practical Combination: Template
In real EA development, the following combination is stable.
bool isTrading = false;
void OnTick()
{
if(isTrading) return;
if(!TerminalInfoInteger(TERMINAL_TRADE_ALLOWED))
return;
if(条件)
{
isTrading = true;
if(OrderSend(request, result))
{
Print("Order successful");
}
else
{
Print("Error: ", GetLastError());
}
Sleep(300);
isTrading = false;
}
}
Common Sticking Points and Notes
- Relying only on
Sleep, which is not enough as a design - Forgetting to release the flag, causing the EA to stop trading
- No branch for error handling
- Not accounting for VPS latency
Common Mistakes
- Ending the fix with “just add Sleep”
- Combining async processing with
Sleep, which can become less stable - Sharing the same account across multiple EAs
- Running the EA without checking logs
4. Implementation Examples: Copy-and-Paste Code
4.1 Simple Avoidance Code: Add Sleep
Start with the minimum setup.
Add a waiting time between consecutive orders to avoid conflicts in trade processing.
void SendBuyOrder()
{
MqlTradeRequest request;
MqlTradeResult result;
ZeroMemory(request);
ZeroMemory(result);
request.action = TRADE_ACTION_DEAL;
request.symbol = _Symbol;
request.volume = 0.10;
request.type = ORDER_TYPE_BUY;
request.price = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
request.deviation= 10;
request.magic = 123456;
if(OrderSend(request, result))
{
Print("Order successful: ", result.order);
Sleep(500);
}
else
{
Print("Order failed: ", GetLastError());
}
}
When to use it
- When you want to reduce the error frequency first
- When you want to quickly stabilize a test EA
Notes
Sleep()is a temporary workaround- In high-frequency trading, too much waiting can be disadvantageous
4.2 OrderSend Implementation with Retry
In practice, it is often more stable to wait briefly and retry instead of stopping after one failure.
bool SendBuyOrderWithRetry(int max_retry = 3, int wait_ms = 500)
{
for(int i = 0; i < max_retry; i++)
{
MqlTradeRequest request;
MqlTradeResult result;
ZeroMemory(request);
ZeroMemory(result);
request.action = TRADE_ACTION_DEAL;
request.symbol = _Symbol;
request.volume = 0.10;
request.type = ORDER_TYPE_BUY;
request.price = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
request.deviation = 10;
request.magic = 123456;
if(OrderSend(request, result))
{
Print("Order successful: ", result.order);
return true;
}
int err = GetLastError();
Print("Order failed (", i + 1, "/", max_retry, ") err=", err);
Sleep(wait_ms);
}
return false;
}
Points
- Do not stop immediately after a failure
- This is more robust against communication delay and temporary conflicts
Common sticking point
- Unlimited retry is dangerous
- If you do not set a maximum count, the code can easily become an infinite loop
4.3 Control with Flag Management
The most important countermeasure for trade context busy is preventing re-entry with an in-order flag.
bool isTrading = false;
void OnTick()
{
if(isTrading) return;
if(買い条件)
{
isTrading = true;
bool ok = SendBuyOrderWithRetry();
if(!ok)
{
Print("Final order failure");
}
isTrading = false;
}
}
Important
- Be careful not to forget
isTrading = false; - An implementation that uses
return;midway and does not reset the flag is dangerous
4.4 Safe Implementation Pattern in OnTick
In OnTick, the basic rule is to avoid a structure that sends an order on every tick.
datetime last_trade_time = 0;
bool isTrading = false;
void OnTick()
{
if(isTrading) return;
if(TimeCurrent() - last_trade_time < 2)
return;
if(買い条件)
{
isTrading = true;
if(SendBuyOrderWithRetry())
{
last_trade_time = TimeCurrent();
}
isTrading = false;
}
}
Combining flag management with minimum interval control greatly reduces the recurrence rate of busy errors.
Common Mistakes
- Not using
ZeroMemory(), leaving values from the previous request - Allowing the order condition to pass every time in
OnTick() - Assuming
Sleep()alone solved the problem - Increasing the retry count too much, which can make the EA slower
5. Common Mistakes: Important Cases
5.1 Repeated Orders in an Infinite Loop
The most dangerous pattern with trade context busy is an infinite loop that immediately sends another order after a failure.
while(true)
{
if(OrderSend(request, result))
break;
}
At first glance, this may look like a safe method because it keeps trying until the order goes through. In reality, it is the opposite.
Because the code resends the order repeatedly while the previous order process has not finished, it makes the busy condition worse.
Problems
- It keeps filling the trade context
- CPU load increases
- The whole EA becomes unstable
Countermeasures
- Set a maximum number of attempts
- Add waiting time between attempts
for(int i = 0; i < 3; i++)
{
if(OrderSend(request, result))
break;
Sleep(500);
}
5.2 High-Speed EA Without Sleep
A common issue in scalping and short-term trading EAs is that OnTick runs at high speed but there is no waiting process.
void OnTick()
{
if(条件)
{
OrderSend(request, result);
}
}
This code is syntactically valid.
However, in live trading, ticks can arrive consecutively, so repeated orders can easily occur under the same condition.
Common sticking points
- It may look normal in backtests
- The busy error may appear only in a live account or VPS environment
Countermeasures
- Use
Sleep()as a supporting measure - Add order interval control
- Send orders based on state changes, not on every tick
5.3 Running Multiple EAs at the Same Time
When multiple EAs run on the same account and terminal, busy can occur even if your own EA is correct.
Example:
- EA A sends a buy order
- EA B sends a close order
- EA C updates a stop
If these run around the same time, a conflict occurs.
Common misunderstanding
- “This EA worked in a standalone test, so it must be fine”
- In reality, it may be interfering with other EAs in production
Countermeasures
- Organize EA roles at the account level
- Separate order timing when running multiple EAs
- Move toward an integrated EA when possible
5.4 Ignoring Errors and Not Checking Logs
If OrderSend() fails but no log is printed, the cause is invisible.
OrderSend(request, result);
With this style alone, you cannot know what happened.
As a result, you cannot separate causes such as:
- Busy error
- Volume error
- Market closed
Minimum required implementation
if(!OrderSend(request, result))
{
Print("OrderSend failed err=", GetLastError());
}
Notes
- Check not only the Experts tab but also the Journal tab
- The more occasional an error is, the more important logging becomes
5.5 Misusing OrderSendAsync
OrderSendAsync() looks convenient, but the failure rate can increase if it is used without understanding state management.
Asynchronous processing means the program moves on without waiting for completion.
Because of that, code like this is dangerous:
OrderSendAsync(request1, result1);
OrderSendAsync(request2, result2);
This can send the second request while the first one is still being processed.
Where beginners often get stuck
- They think “async means fast and better”
- In reality, it means “more responsibility for control moves to your EA”
Countermeasures
- Prefer
OrderSend()while learning - If using async processing, design state transitions explicitly
5.6 Forgetting to Release a Flag
Using a flag for exclusive control is effective, but forgetting to release it creates another serious bug.
isTrading = true;
if(!OrderSend(request, result))
{
return; // If the function exits here, the flag is not reset
}
isTrading = false;
In this code, isTrading can remain true after an order failure.
As a result, the EA may stop placing any future orders.
Countermeasures
- Always release the flag even after a failure
- Unify the process exit point
Common Sticking Points and Notes
- A fix for one error can easily create a separate stop-trading bug
- Busy errors often come from multiple overlapping factors, not one isolated cause
- Do not ignore the issue just because it happened only once
6. Practical Countermeasures to Prevent Recurrence
6.1 Build a Trade Control Flag into the Design
To reduce trade context busy in a stable way, it is important to build a mechanism into the EA design that prevents simultaneous orders, instead of relying only on temporary Sleep calls.
The most basic approach is an in-order flag.
bool isTrading = false;
bool SafeSendOrder(MqlTradeRequest &request, MqlTradeResult &result)
{
if(isTrading)
return false;
isTrading = true;
bool ok = OrderSend(request, result);
isTrading = false;
return ok;
}
By wrapping the order function itself this way,
you can reuse the same control across the whole EA.
Practical advantages
- The entry point for order processing is centralized
- The modification scope is smaller when specifications change
- It reduces accidental consecutive
OrderSendcalls
Notes
- Always reset the flag even on failures and exceptional branches
- If you create multiple functions without sharing this logic, control becomes scattered
6.2 Use the Concept of an Order Queue
In EAs where orders can come from multiple conditions, a design that sends an order immediately when a condition appears becomes a source of busy errors.
In that case, it is effective to store orders in a queue-like state first and process them one by one in order.
For beginners, the simplified flow is:
- Check signals
- Do not send an order immediately at that point
- Save only the state that an order is pending
- Send actual orders one by one from a dedicated process
Simple example:
bool buySignalPending = false;
void OnTick()
{
if(買い条件)
buySignalPending = true;
ProcessTradeQueue();
}
void ProcessTradeQueue()
{
if(isTrading) return;
if(!buySignalPending) return;
MqlTradeRequest request;
MqlTradeResult result;
ZeroMemory(request);
ZeroMemory(result);
request.action = TRADE_ACTION_DEAL;
request.symbol = _Symbol;
request.volume = 0.10;
request.type = ORDER_TYPE_BUY;
request.price = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
request.deviation = 10;
request.magic = 123456;
isTrading = true;
if(OrderSend(request, result))
{
buySignalPending = false;
Print("Buy order successful");
}
else
{
Print("Buy order failed err=", GetLastError());
}
isTrading = false;
}
Points
- Separate signal judgment from order sending
- Centralize the order sending process
- The EA is less likely to break when signals overlap
6.3 Separate the Roles of Each EA
When multiple EAs run on the same account, the cause of busy errors is often not only code quality but also poor role design.
Risky setup example:
- EA A: entry
- EA B: averaging down
- EA C: take profit and closing
- EA D: stop adjustment
With this setup, each EA can easily send orders or modifications at the same time during rapid market movement.
In practice, one of the following approaches is usually more stable.
- Option A: integrate into one EA
Manage everything from entry to exit in one EA - Option B: clearly separate responsibilities
For example, fix the rule so only one EA sends orders
Decision criteria
- If simplicity is the priority, use an integrated EA
- For a large-scale design, use responsibility separation plus central control
Common mistakes
- Adding more function-specific EAs just because it is convenient
- Running them without considering exclusive control across the whole account
6.4 Optimize the VPS and Communication Environment
trade context busy is mainly caused by logic,
but communication delay can increase how often it occurs.
Review these points especially:
- VPS location: whether it is close to the broker server
- VPS load: whether CPU or memory is insufficient
- Connection stability
- Number of MT5 terminals running at the same time
If communication delay is large, the processing time per order becomes longer.
As a result, the next order is more likely to collide with the current one.
Checkpoints
- Whether execution feels slow
- Whether communication-related errors appear in the Journal
- Whether unnecessary EAs or terminals are running on the VPS
Important
- Improving the VPS alone is not a root-cause fix
- However, even with proper design, a poor environment can increase busy errors
6.5 Reduce the Order Frequency Itself
One point often overlooked in busy-error prevention is whether the EA is sending too many orders in the first place.
Adding conditions like these can reduce unnecessary orders:
- Do not send a new order within a few seconds of the previous order
- Allow only one order per bar
- Do not add another order in the same direction while holding a position
- Do not send orders when spreads widen
Example:
datetime lastOrderTime = 0;
bool CanSendNewOrder()
{
if(TimeCurrent() - lastOrderTime < 3)
return false;
return true;
}
This alone can greatly reduce the busy error rate in live operation.
Common Sticking Points and Notes
- It is easy to add only
Sleepand assume the fix is complete - It is easy to optimize a single EA while missing account-wide conflicts
- When signal logic and order logic are mixed, later fixes become harder
Common Mistakes
- Order functions are scattered across multiple locations
OrderSendis called directly whenever a condition is met- Trying to fix the issue only by improving the VPS
- Keeping a multi-EA setup without defining responsibility boundaries
7. Performance and Design Perspective for Intermediate Developers
7.1 How to Think About the Trade Context
In practice, it is useful to treat trade context busy not as a temporary error, but as a sign that order processing has not been serialized correctly.
In MQL5, orders are sent with OrderSend() or OrderSendAsync(), and later results or state changes can be received through OnTrade() and OnTradeTransaction(). Also, one request can arrive as multiple trade events, and the arrival order is not fixed. For this reason, implementations that assume “the state will always become this right after sending the order” are fragile. (MQL5)
The key is not to treat order sending and execution completion as the same moment.
In particular, OnTradeTransaction() is an event handler for processing the results of trade requests, and it fits designs where the EA manages state transitions. (MQL5)
7.2 Best Practices for Simultaneous Order Control
From a design perspective, the following order of control is highly reproducible.
- Check the order signal
- Check whether sending is allowed
- Turn the sending flag ON
- Send the order
- Update state after receiving the result event
- Turn the sending flag OFF
In other words, do not try to complete everything inside OnTick(). Instead, separate sending from result reflection.
The MQL5 documentation also states that one request can generate multiple events and that OnTrade() should not be treated as “one request equals one event.” (MQL5)
A simplified image is below.
bool trade_pending = false;
void OnTick()
{
if(trade_pending) return;
if(エントリー条件)
{
MqlTradeRequest request;
MqlTradeResult result;
ZeroMemory(request);
ZeroMemory(result);
request.action = TRADE_ACTION_DEAL;
request.symbol = _Symbol;
request.volume = 0.10;
request.type = ORDER_TYPE_BUY;
request.price = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
request.deviation = 10;
request.magic = 123456;
trade_pending = true;
if(!OrderSend(request, result))
{
Print("OrderSend failed: ", GetLastError());
trade_pending = false;
}
}
}
void OnTradeTransaction(const MqlTradeTransaction& trans,
const MqlTradeRequest& request,
const MqlTradeResult& result)
{
trade_pending = false;
}
The advantage of this pattern is that rapid tick processing and execution processing can be separated.
7.3 Design Notes for High-Frequency EAs
OrderSendAsync() is a function that sends requests asynchronously without waiting for the server response, making it suitable for high-frequency trading.
However, it is not a function that automatically makes an EA faster in a simple and safe way. It is described as suitable for high-frequency trading, but because it is asynchronous, more responsibility for state management moves to the EA side. Results after sending must be tracked through events. If control is wrong, busy-related conflicts and duplicate orders can increase. (MQL5)
High-frequency EAs require special attention to these points:
- Do not send immediately on every
OnTick() - Store sent request IDs and states
- Do not allow another order in the same direction before execution is confirmed
- Use state transitions based on
OnTradeTransaction()
Common mistakes
- Assuming speed optimization is complete just because
OrderSendAsync()was added - Removing response waiting but increasing duplicate sends
- Trying to track all state with
OnTrade()alone and missing events
7.4 Move Away from Sleep-Dependent Design
Sleep() is useful as a short-term fix, but it should not be the center of the design.
In the official documentation, Sleep is a way to pause a program for a certain time, but it does not guarantee trade-state consistency. In testers and live environments, time and events can behave differently, so waiting 500 ms does not always mean it is safe. (MQL5)
For intermediate developers and above, the design mindset should shift as follows:
- From waiting by time to waiting by state
- From resending to event confirmation
- From temporary workarounds to order lifecycle management
In practice, Sleep() is a supporting tool. The main tools are state flags, event handling, and order interval control.
7.5 How to Think About Performance Optimization
To reduce busy-related errors, it is usually more effective to prioritize reducing the number of orders and centralizing the order path before CPU optimization.
A practical improvement order is:
- Prevent duplicate orders within the same bar
- Review conditions for adding orders while a position is already open
- Centralize the order function in one location
- Reflect sending results through events
- Use
OrderSendAsync()only when necessary
This order works because many trade context busy errors are caused by conflicts in order design, not lack of calculation performance.
Since MQL5 trade events can occur in stages, consistent state management is more important than lightweight code. (MQL5)
Common Sticking Points and Notes
- Design can easily break if you try to complete everything inside
OnTick() - State can become inconsistent if you do not understand the difference between
OnTrade()andOnTradeTransaction() - Async processing is speed optimization, not simplification
Sleep()cannot fully absorb environmental differences
Common Mistakes
- Managing execution only with variables immediately after sending, without using event handling
- Not keeping state per request
- Implementing duplicate-order prevention only with time waiting
- Using
OrderSendAsync()in a high-frequency EA while skipping result tracking
8. Differences from Similar Errors: Avoiding Misdiagnosis
Key point in this section:trade context busy is a processing conflict error. Its cause is fundamentally different from other order errors, so the wrong diagnosis leads to the wrong fix. Classify the main errors and make the separation criteria clear.
8.1 trade context busy vs requote
Core difference
| Error | Cause | Main target |
|---|---|---|
| trade context busy | Processing conflict, internal lock | EA-side design |
| requote | Price movement | Market or broker |
What is a requote?
- A situation where a new price is presented because the order price has shifted
- Mainly occurs during fast markets or spread changes
request.deviation = 10; // Allowed slippage
Important point
- A requote is a price problem
- Busy is a processing problem
The fixes are completely different.
8.2 trade context busy vs trade disabled
Core difference
| Error | Cause |
|---|---|
| trade context busy | Processing is already running |
| trade disabled | Trading is not allowed |
When trade disabled occurs
- Market is closed
- Algo trading is off
- Broker restriction applies
if(!TerminalInfoInteger(TERMINAL_TRADE_ALLOWED))
{
Print("Trading is disabled");
}
Important
- Busy may go through if you wait
- Disabled means trading is not possible in the current state
8.3 trade context busy vs invalid volume
Core difference
| Error | Cause |
|---|---|
| trade context busy | Timing problem |
| invalid volume | Invalid parameter |
Examples of invalid volume
- Below the minimum lot size
- Violation of the lot step
double minLot = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN);
Important
- Busy requires timing control
- Volume errors require numeric validation
8.4 trade context busy vs no connection
Core difference
| Error | Cause |
|---|---|
| trade context busy | Internal processing |
| no connection | Disconnected communication |
Characteristics of no connection
- Not connected to the server
- VPS is stopped
- Network failure
How to distinguish it
- Connection logs appear in the Journal
- Ping is abnormal
8.5 Practical Troubleshooting Steps
The important point in error handling is to identify the cause in one pass.
Recommended steps:
1. Check logs
Print("err=", GetLastError());
2. Classify the error type
- busy: review the design
- requote: adjust deviation
- disabled: check the environment
- volume: fix numeric values
3. Check reproducibility
- Happens every time: logic problem
- Happens occasionally: timing or environment issue
Common Sticking Points and Notes
- Misreading busy as a communication error
- Confusing busy with requote
- Trying to solve everything with
Sleep - Changing code by guessing without checking logs
Common Mistakes
- Not checking the error code
- Not separating fixes by cause
- Changing the lot size as a busy-error fix, which is meaningless
- Looking at only one error even though multiple errors are mixed together
9. FAQ
Key point in this section:
These answers organize the shortest path from cause to fix so beginners can solve the points where they commonly get stuck.
Q1. Is it okay to ignore trade context busy?
Answer direction:
Ignoring it is not recommended. A single occurrence may not be fatal, but frequent occurrences indicate a design problem in the EA.
Explanation:
If it occurs only temporarily, it may not become a major issue.
However, if it occurs repeatedly, these risks appear:
- Missed order opportunities
- Broken EA logic
- Unexpected position state
You should identify the cause and prevent recurrence.
Q2. Does adding Sleep completely solve the issue?
Answer direction:
It is partly effective, but it is not a root-cause fix.
Explanation:Sleep is a time-based workaround.
However, the core of the busy error is a state conflict.
- If communication delay is long,
Sleepmay be too short - In fast markets,
Sleepalone may not help
It should be combined with flag management and order control.
Q3. Can OrderSendAsync avoid busy errors?
Answer direction:
It can make the problem worse.
Explanation:
Asynchronous processing does not wait.
Without control, it can cause:
- Duplicate orders
- Inconsistent state
- More busy errors
Beginners should usually prioritize OrderSend().
Q4. Why does it not happen in backtests but happens in live trading?
Answer direction:
Because the tester and the live environment are structurally different.
Explanation:
Backtests:
- No network communication
- Immediate processing
- Synchronous behavior
Live environment:
- Server communication exists
- Execution delay exists
- Asynchronous events exist
Conflicts are more likely in live operation.
Q5. Will running multiple EAs always cause the error?
Answer direction:
Not always, but the probability increases.
Explanation:
- EAs are not fully independent because they share the account
- Simultaneous orders can cause conflicts
Countermeasures:
- Integrate order sending into one EA
- Separate timing
- Use central control
Q6. Will changing the VPS solve it?
Answer direction:
It may improve the situation, but it is not a root-cause fix.
Explanation:
What a better VPS can improve:
- Connection speed
- Response time
What it cannot fix:
- Logic conflicts
- Design mistakes
Both design and environment need to be reviewed.
Q7. What is the most effective countermeasure?
Answer direction:
Flag management plus order control.
Conclusion:
Priority order:
- Exclusive control with a flag
- Order interval control
- Log monitoring
Sleepas a supporting measure
This order is the most stable way to implement the fix.
Q8. Can trade context busy be reduced to zero?
Answer direction:
It is difficult in theory, but it can be reduced to nearly zero in practice.
Explanation:
- Communication delay never becomes zero
- Server conditions also change
However, by:
- Optimizing the design
- Controlling order frequency
- Managing state thoroughly
you can suppress it to a level where it practically does not occur.