✅ Closing Orders and Positions (OrderCloseAsync)¶
Request: Close an open position or cancel a pending order on MT5.
API Information:
- SDK wrapper:
MT5Account.OrderCloseAsync(...)(from NuGet packageMetaRPC.MT5) - gRPC service:
mt5_term_api.TradingHelper - Proto definition:
OrderClose(defined inmt5-term-api-trading-helper.proto)
RPC¶
- Service:
mt5_term_api.TradingHelper - Method:
OrderClose(OrderCloseRequest) → OrderCloseReply - Low‑level client (generated):
TradingHelper.TradingHelperClient.OrderClose(request, headers, deadline, cancellationToken) - SDK wrapper (your class):
namespace mt5_term_api
{
public class MT5Account
{
public async Task<OrderCloseData> OrderCloseAsync(
OrderCloseRequest request,
DateTime? deadline = null,
CancellationToken cancellationToken = default);
}
}
Request message:
OrderCloseRequest { ticket, volume, slippage }
Reply message:
OrderCloseReply { data: OrderCloseData }
🔽 Input¶
| Parameter | Type | Description |
|---|---|---|
request |
OrderCloseRequest |
Protobuf request with close parameters |
deadline |
DateTime? |
Absolute per‑call UTC deadline → converted to timeout |
cancellationToken |
CancellationToken |
Cooperative cancel for the call/retry loop |
OrderCloseRequest¶
| Field | Type | Description |
|---|---|---|
Ticket |
ulong |
Position or pending order ticket REQUIRED |
Volume |
double |
Volume to close (for partial close; use 0 for full close) |
Slippage |
int |
Max price slippage in points (for market positions) |
⬆️ Output — OrderCloseData¶
| Field | Type | Description |
|---|---|---|
ReturnedCode |
uint |
Operation return code (10009 = success) |
ReturnedStringCode |
string |
String representation of return code |
ReturnedCodeDescription |
string |
Human-readable description |
CloseMode |
MRPC_ORDER_CLOSE_MODE |
Close mode (market/partial/pending) |
🧱 Related enums (from proto)¶
MRPC_ORDER_CLOSE_MODE¶
MrpcMarketOrderClose— Full market position closeMrpcMarketOrderPartialClose— Partial market position closeMrpcPendingOrderRemove— Pending order cancellation
💬 Just the essentials¶
- What it is. Closes open market positions (full or partial) or cancels pending orders.
- Why you need it. Exit trades, take profits, cut losses, cancel unfilled pending orders.
- Sanity check. If
ReturnedCode == 10009→ close/cancel successful. CheckCloseModefor operation type.
🎯 Purpose¶
Use it to exit trades:
- Close entire position (full close).
- Close part of position (partial close).
- Cancel pending orders.
🧩 Notes & Tips¶
- Return codes: 10009 = success. Other codes indicate errors (invalid ticket, market closed, etc.).
- Full vs Partial: Set
Volume = 0for full close. Set specific volume (e.g.,0.01) for partial close. - Pending orders: For pending orders,
Volumeis ignored. Order is simply cancelled. - Slippage: For market positions, allows price deviation. Higher slippage = higher chance of execution.
- CloseMode: Check this field to confirm operation type (full/partial/pending).
🔗 Usage Examples¶
1) Close entire position¶
// acc — connected MT5Account
// positionTicket — ticket from OrderSendAsync or OpenedOrdersAsync
var result = await acc.OrderCloseAsync(new OrderCloseRequest
{
Ticket = positionTicket,
Volume = 0, // 0 = close entire position
Slippage = 10
});
if (result.ReturnedCode == 10009)
{
Console.WriteLine($"✓ Position closed: {result.CloseMode}");
}
else
{
Console.WriteLine($"✗ Close failed: {result.ReturnedCodeDescription}");
}
2) Partial position close¶
// Close half of 0.10 lot position (close 0.05 lots)
var result = await acc.OrderCloseAsync(new OrderCloseRequest
{
Ticket = positionTicket,
Volume = 0.05, // Partial close: 0.05 lots
Slippage = 10
});
if (result.CloseMode == MRPC_ORDER_CLOSE_MODE.MrpcMarketOrderPartialClose)
{
Console.WriteLine("✓ Partial close successful");
}
3) Cancel pending order¶
// pendingOrderTicket — ticket of pending order
var result = await acc.OrderCloseAsync(new OrderCloseRequest
{
Ticket = pendingOrderTicket,
Volume = 0 // Volume ignored for pending orders
});
if (result.CloseMode == MRPC_ORDER_CLOSE_MODE.MrpcPendingOrderRemove)
{
Console.WriteLine("✓ Pending order cancelled");
}
4) Close all positions for a symbol¶
var openOrders = await acc.OpenedOrdersAsync();
var eurusdPositions = openOrders.Positions.Where(p => p.Symbol == "EURUSD");
foreach (var position in eurusdPositions)
{
var result = await acc.OrderCloseAsync(new OrderCloseRequest
{
Ticket = (ulong)position.Ticket,
Volume = 0,
Slippage = 10
});
Console.WriteLine($"Position {position.Ticket}: {result.ReturnedCodeDescription}");
}
5) Close position with error handling¶
try
{
var result = await acc.OrderCloseAsync(
new OrderCloseRequest
{
Ticket = positionTicket,
Volume = 0,
Slippage = 20
},
deadline: DateTime.UtcNow.AddSeconds(10));
if (result.ReturnedCode == 10009)
{
Console.WriteLine($"✓ Closed: {result.CloseMode}");
}
else
{
Console.WriteLine($"⚠ Server returned: {result.ReturnedCodeDescription}");
}
}
catch (Grpc.Core.RpcException ex)
{
Console.WriteLine($"✗ gRPC error: {ex.Status}");
}
catch (ApiExceptionMT5 ex)
{
Console.WriteLine($"✗ API error: {ex.Message}");
}
6) Close position with volume validation¶
// Get position info first
var positions = await acc.OpenedOrdersAsync();
var position = positions.Positions.FirstOrDefault(p => p.Ticket == positionTicket);
if (position != null)
{
var volumeToClose = 0.01; // Want to close 0.01 lots
if (volumeToClose >= position.Volume)
{
// Close entire position if requested volume >= position volume
volumeToClose = 0;
}
var result = await acc.OrderCloseAsync(new OrderCloseRequest
{
Ticket = (ulong)position.Ticket,
Volume = volumeToClose,
Slippage = 10
});
Console.WriteLine($"Close result: {result.ReturnedCodeDescription}");
Console.WriteLine($"Mode: {result.CloseMode}");
}