Close Position by Ticket (CloseByTicket)ΒΆ
Sugar method: Closes order or position by ticket number with support for partial closure.
API Information:
- Extension method:
MT5Service.CloseByTicket(...)(fromMT5ServiceExtensions) - Package: Part of
mt5_term_apilibrary - Region: [06] TRADING β MARKET & PENDING
- Underlying calls:
OrderCloseAsync()
Method SignatureΒΆ
public static Task<OrderCloseData> CloseByTicket(
this MT5Service svc,
ulong ticket,
double? volume = null,
int timeoutSec = 15,
CancellationToken ct = default)
π½ InputΒΆ
| Parameter | Type | Description |
|---|---|---|
svc |
MT5Service |
MT5Service instance (extension method) |
ticket |
ulong |
Order or position ticket number to close |
volume |
double? |
Volume to close in lots. Pass null to close entire position (default: null) |
timeoutSec |
int |
RPC timeout in seconds (default: 15) |
ct |
CancellationToken |
Cancellation token |
β¬οΈ OutputΒΆ
| Type | Description |
|---|---|
Task<OrderCloseData> |
Order close result with execution details |
π¬ Just the essentialsΒΆ
- What it is: Closes position or pending order by ticket number - full or partial closure.
- Why you need it: Simplifies position closing - no manual OrderCloseRequest building.
- Sanity check: Pass
volume: nullfor full close. For partial, specify exact volume (must not exceed position size).
π― PurposeΒΆ
Use it for:
- Full position closure - exit entire position at market price
- Partial position closure - reduce position size (scale out)
- Pending order cancellation - cancel pending limit/stop orders
- Emergency exits - quickly close specific position
- Take partial profits - close portion while letting rest run
π§ Under the HoodΒΆ
// Build close request
var req = new OrderCloseRequest
{
Ticket = ticket,
Volume = volume ?? 0 // 0 means close entire position
};
// Send close request
return await svc.OrderCloseAsync(req, deadline, ct);
What it improves:
- Auto full close - null volume = close entire position
- Partial support - specify exact volume to close
- No request building - method handles it
- Simple API - just ticket + optional volume
π Usage ExamplesΒΆ
Example 1: Close Entire PositionΒΆ
ulong ticket = 12345;
// Close entire position (volume = null)
var result = await svc.CloseByTicket(ticket);
Console.WriteLine($"β
Position #{ticket} closed completely");
Example 2: Partial Close (50% of Position)ΒΆ
ulong ticket = 12345;
double totalVolume = 0.10; // Current position size
// Close half the position
var result = await svc.CloseByTicket(ticket, volume: 0.05);
Console.WriteLine($"β
Closed 0.05 lots, remaining: 0.05 lots");
Example 3: Scale Out in StagesΒΆ
ulong ticket = 12345;
double totalVolume = 0.10;
// Take profits in 3 stages: 25%, 50%, 25%
// Stage 1: Close 25% at first target
await svc.CloseByTicket(ticket, volume: 0.025);
Console.WriteLine("β
Stage 1: Closed 25% at TP1");
// Stage 2: Close 50% at second target
await svc.CloseByTicket(ticket, volume: 0.05);
Console.WriteLine("β
Stage 2: Closed 50% at TP2");
// Stage 3: Close remaining 25% at third target
await svc.CloseByTicket(ticket); // Close remainder
Console.WriteLine("β
Stage 3: Closed remaining 25% at TP3");
Example 4: Cancel Pending OrderΒΆ
ulong pendingOrderTicket = 67890;
// Cancel pending limit/stop order
var result = await svc.CloseByTicket(pendingOrderTicket);
Console.WriteLine($"β
Pending order #{pendingOrderTicket} cancelled");
Example 5: Close Multiple PositionsΒΆ
ulong[] tickets = { 12345, 12346, 12347 };
foreach (var ticket in tickets)
{
try
{
await svc.CloseByTicket(ticket);
Console.WriteLine($"β
Closed position #{ticket}");
}
catch (Exception ex)
{
Console.WriteLine($"β Failed to close #{ticket}: {ex.Message}");
}
}
Example 6: Close With Error HandlingΒΆ
ulong ticket = 12345;
try
{
var result = await svc.CloseByTicket(ticket);
if (result.ReturnedCode == 10009)
{
Console.WriteLine($"β
Position closed successfully");
Console.WriteLine($" Deal: #{result.Deal}");
Console.WriteLine($" Volume: {result.Volume}");
}
else
{
Console.WriteLine($"β Close failed: {result.Comment}");
}
}
catch (Exception ex)
{
Console.WriteLine($"β Exception: {ex.Message}");
}
Example 7: Partial Close Based on ProfitΒΆ
public async Task TakePartialProfits(MT5Service svc, ulong ticket, double profitPips)
{
var position = await GetPositionInfo(svc, ticket);
double currentVolume = position.Volume;
if (profitPips >= 100)
{
// Close 75% at 100 pips profit
double closeVol = currentVolume * 0.75;
await svc.CloseByTicket(ticket, volume: closeVol);
Console.WriteLine($"β
Took 75% profit at 100 pips");
}
else if (profitPips >= 50)
{
// Close 50% at 50 pips profit
double closeVol = currentVolume * 0.50;
await svc.CloseByTicket(ticket, volume: closeVol);
Console.WriteLine($"β
Took 50% profit at 50 pips");
}
}
Example 8: Emergency Close AllΒΆ
public async Task EmergencyCloseAll(MT5Service svc)
{
var opened = await svc.OpenedOrdersAsync(
BMT5_ENUM_OPENED_ORDER_SORT_TYPE.Bmt5OpenedOrderSortByOpenTimeAsc);
// Close all positions immediately
foreach (var position in opened.PositionInfos)
{
await svc.CloseByTicket(position.Ticket);
Console.WriteLine($"β
Emergency close: #{position.Ticket}");
}
// Cancel all pending orders
foreach (var order in opened.OpenedOrders)
{
await svc.CloseByTicket(order.Ticket);
Console.WriteLine($"β
Cancelled pending: #{order.Ticket}");
}
}
Example 9: Close Specific VolumeΒΆ
ulong ticket = 12345;
// Close exactly 0.03 lots from position
var result = await svc.CloseByTicket(ticket, volume: 0.03);
if (result.ReturnedCode == 10009)
{
Console.WriteLine($"β
Closed {result.Volume} lots");
Console.WriteLine($" Deal price: {result.Price:F5}");
}
Example 10: Smart Partial CloseΒΆ
public async Task SmartPartialClose(MT5Service svc, ulong ticket)
{
var position = await GetPositionInfo(svc, ticket);
double currentVolume = position.Volume;
double minVolume = 0.01; // Broker minimum
if (currentVolume > minVolume)
{
// Close 50% but ensure remaining is >= minimum
double halfVolume = currentVolume / 2.0;
if (currentVolume - halfVolume >= minVolume)
{
await svc.CloseByTicket(ticket, volume: halfVolume);
Console.WriteLine($"β
Closed {halfVolume} lots, remaining: {currentVolume - halfVolume}");
}
else
{
Console.WriteLine($"β οΈ Cannot partial close - remaining would be below minimum");
Console.WriteLine($" Closing entire position instead");
await svc.CloseByTicket(ticket);
}
}
}
π Related MethodsΒΆ
π¦ Low-level methods used internally:
OrderCloseAsync()- Sends close request to MT5 server
π¬ Alternative Sugar methods:
CloseAll()- Close all positions with optional filtersCloseAllPositions()- Close all market positionsCancelAll()- Cancel all pending ordersModifySlTpAsync()- Modify SL/TP instead of closing
β οΈ Common PitfallsΒΆ
-
Partial volume exceeds position size:
// β WRONG: Trying to close 1.0 lot from 0.5 lot position await svc.CloseByTicket(ticket, volume: 1.0); // Will fail // β CORRECT: Check position volume first var position = await GetPositionInfo(svc, ticket); double closeVolume = Math.Min(0.5, position.Volume); await svc.CloseByTicket(ticket, volume: closeVolume); -
Remaining volume below broker minimum:
// β WRONG: Closing 0.09 from 0.10 leaves 0.01 (may be below minimum) await svc.CloseByTicket(ticket, volume: 0.09); // β CORRECT: Check broker minimum volume double minVol = await svc.GetVolumeMinAsync(symbol); double remaining = currentVolume - closeVolume; if (remaining >= minVol) { await svc.CloseByTicket(ticket, volume: closeVolume); } -
Trying to close already closed position:
π‘ SummaryΒΆ
CloseByTicket provides clean position closing:
- β Full or partial closure support
- β Works with positions and pending orders
- β No manual request building
- β Simple API - just ticket + optional volume
// Full close:
await svc.CloseByTicket(ticket: 12345);
// Partial close:
await svc.CloseByTicket(ticket: 12345, volume: 0.05);
// Cancel pending:
await svc.CloseByTicket(pendingTicket: 67890);
Exit positions with precision! π