✅ Modify Orders and Positions¶
Request: modify parameters of existing pending orders or StopLoss/TakeProfit levels of open positions.
API Information:
- Low-level API:
MT5Account.OrderModify(...)(from Go packagegithub.com/MetaRPC/GoMT5/package/Helpers) - gRPC service:
mt5_term_api.TradingHelper - Proto definition:
OrderModify(defined inmt5-term-api-trading-helper.proto)
RPC¶
- Service:
mt5_term_api.TradingHelper - Method:
OrderModify(OrderModifyRequest) → OrderModifyReply - Low‑level client (generated):
TradingHelperClient.OrderModify(ctx, request, opts...)
💬 Just the essentials¶
- What it is. Modifies parameters of existing orders and positions.
- Why you need it. Adjust SL/TP levels, change pending order prices, manage risk.
- Flexible. Works with both pending orders and open positions.
🎯 Purpose¶
Use it to:
- Adjust stop-loss and take-profit levels
- Move pending order entry prices
- Implement trailing stops
- Update risk management parameters
- Change order expiration times
📚 Tutorial¶
For a detailed line-by-line explanation with examples, see: → OrderModify - How it works
package mt5
type MT5Account struct {
// ...
}
// OrderModify modifies an existing pending order or position.
// Can change entry price (pending orders), StopLoss, TakeProfit, and expiration.
func (a *MT5Account) OrderModify(
ctx context.Context,
req *pb.OrderModifyRequest,
) (*pb.OrderModifyData, error)
Request message:
OrderModifyRequest {
uint64 ticket = 1; // Pending order or position ticket (REQUIRED)
optional double stop_loss = 2; // New SL for position or pending order
optional double take_profit = 3; // New TP for position or pending order
optional double price = 4; // New price ONLY for pending order modification
optional TMT5_ENUM_ORDER_TYPE_TIME expiration_time_type = 5; // Expiration type ONLY for pending order
optional google.protobuf.Timestamp expiration_time = 6; // Order expiration time (for ORDER_TIME_SPECIFIED)
optional double stop_limit = 8; // New stop limit ONLY for pending order modification
}
🔽 Input¶
| Parameter | Type | Description |
|---|---|---|
ctx |
context.Context |
Context for deadline/timeout and cancellation |
req |
*pb.OrderModifyRequest |
Request with ticket and new parameters |
Request fields:
| Field | Type | Required | Description |
|---|---|---|---|
Ticket |
uint64 |
✅ | Order ticket number to modify |
StopLoss |
double |
optional | New stop loss level (0 = remove) |
TakeProfit |
double |
optional | New take profit level (0 = remove) |
Price |
double |
optional | New entry price (for pending orders only) |
ExpirationTimeType |
TMT5_ENUM_ORDER_TYPE_TIME |
optional | Expiration type (GTC, DAY, SPECIFIED, etc) |
ExpirationTime |
google.protobuf.Timestamp |
optional | Expiration time (for SPECIFIED type) |
StopLimit |
double |
optional | New stop limit level (for stop-limit orders) |
⬆️ Output — OrderModifyData¶
| Field | Type | Description |
|---|---|---|
ReturnedCode |
uint32 |
Operation return code (10009 = success) |
Deal |
uint64 |
Deal ticket, if it is performed |
Order |
uint64 |
Order ticket, if it is placed |
Volume |
double |
Deal volume, confirmed by broker |
Price |
double |
Deal price, confirmed by broker |
Bid |
double |
Current Bid price |
Ask |
double |
Current Ask price |
Comment |
string |
Broker comment to operation |
RequestId |
uint32 |
Request ID set by terminal during dispatch |
RetCodeExternal |
int32 |
Return code of external trading system |
ReturnedStringCode |
string |
String representation of return code |
ReturnedCodeDescription |
string |
Description of return code |
💡 Enum Usage Note: The tables show simplified constant names for readability. In Go code, use full names with the enum type prefix.
Format:
pb.<ENUM_TYPE>_<CONSTANT_NAME>Example:
pb.TMT5_ENUM_ORDER_TYPE_TIME_TMT5_ORDER_TIME_GTC
📘 Enum: TMT5_ENUM_ORDER_TYPE_TIME¶
| Value | Constant | Description |
|---|---|---|
| 0 | TMT5_ORDER_TIME_GTC |
Good Till Cancelled (order valid until explicitly cancelled) |
| 1 | TMT5_ORDER_TIME_DAY |
Good Till Day (order valid until end of trading day) |
| 2 | TMT5_ORDER_TIME_SPECIFIED |
Good Till Specified Time (order valid until ExpirationTime) |
| 3 | TMT5_ORDER_TIME_SPECIFIED_DAY |
Good Till Specified Day (order valid until end of specified day) |
🧩 Notes & Tips¶
- Automatic reconnection: All
MT5Accountmethods have built-in protection against transient gRPC errors with automatic reconnection viaExecuteWithReconnect. - Default timeout: If context has no deadline, a default
30stimeout is applied automatically. - Nil context: If you pass
nilcontext,context.Background()is used automatically. - Remove SL/TP: Set StopLoss or TakeProfit to 0 to remove them.
- Price for positions: Cannot modify entry price of open positions (only pending orders).
🔗 Usage Examples¶
1) Modify stop-loss and take-profit¶
package main
import (
"context"
"fmt"
"time"
pb "github.com/MetaRPC/GoMT5/package"
"github.com/MetaRPC/GoMT5/package/Helpers"
)
func main() {
account, _ := mt5.NewMT5Account(12345, "password", "mt5.mrpc.pro:443", uuid.New())
defer account.Close()
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
ticket := uint64(12345678)
newSL := 1.10000
newTP := 1.12000
data, err := account.OrderModify(ctx, &pb.OrderModifyRequest{
Ticket: ticket,
StopLoss: &newSL,
TakeProfit: &newTP,
})
if err != nil {
panic(err)
}
// Check modification result using helper from errors.go
if mt5.IsRetCodeSuccess(data.ReturnedCode) {
fmt.Printf("Order %d modified: SL=%.5f, TP=%.5f\n", ticket, newSL, newTP)
} else {
fmt.Printf("Modification failed: %s (code: %d)\n",
mt5.GetRetCodeMessage(data.ReturnedCode),
data.ReturnedCode)
}
}
2) Move stop-loss to breakeven¶
func MoveToBreakeven(account *mt5.MT5Account, ticket uint64, openPrice float64) error {
ctx := context.Background()
data, err := account.OrderModify(ctx, &pb.OrderModifyRequest{
Ticket: ticket,
StopLoss: &openPrice,
// Don't pass TakeProfit to keep existing TP
})
if err != nil {
return fmt.Errorf("failed to move to breakeven: %w", err)
}
// Validate modification result using helper from errors.go
if !mt5.IsRetCodeSuccess(data.ReturnedCode) {
return fmt.Errorf("modification unsuccessful: %s (code: %d)",
mt5.GetRetCodeMessage(data.ReturnedCode),
data.ReturnedCode)
}
fmt.Printf("Moved order %d to breakeven\n", ticket)
return nil
}
3) Implement trailing stop¶
func TrailingStop(account *mt5.MT5Account, ticket uint64, trailDistance float64) error {
ctx := context.Background()
// Get current position
positions, err := account.OpenedOrders(ctx, &pb.OpenedOrdersRequest{})
if err != nil {
return err
}
var order *pb.Order
for _, o := range positions.Orders {
if o.Ticket == ticket {
order = o
break
}
}
if order == nil {
return fmt.Errorf("position not found")
}
// Calculate new SL
var newSL float64
if order.Type == 0 { // Buy position
newSL = order.CurrentPrice - trailDistance
// Only move SL up, never down
if newSL <= order.StopLoss {
return nil // No change needed
}
} else { // Sell position
newSL = order.CurrentPrice + trailDistance
// Only move SL down, never up
if order.StopLoss > 0 && newSL >= order.StopLoss {
return nil // No change needed
}
}
data, err := account.OrderModify(ctx, &pb.OrderModifyRequest{
Ticket: ticket,
StopLoss: &newSL,
})
if err != nil {
return err
}
// Check modification result using helper from errors.go
if mt5.IsRetCodeSuccess(data.ReturnedCode) {
fmt.Printf("Trailing stop updated for %d: new SL=%.5f\n", ticket, newSL)
}
return nil
}
4) Modify pending order price¶
func ModifyPendingOrderPrice(account *mt5.MT5Account, ticket uint64, newPrice float64) error {
ctx := context.Background()
data, err := account.OrderModify(ctx, &pb.OrderModifyRequest{
Ticket: ticket,
Price: &newPrice,
})
if err != nil {
return err
}
if data.ReturnedCode != 10009 {
return fmt.Errorf("failed to modify pending order price: %s", data.ReturnedCodeDescription)
}
fmt.Printf("Pending order %d price changed to %.5f\n", ticket, newPrice)
return nil
}
5) Remove stop-loss¶
func RemoveStopLoss(account *mt5.MT5Account, ticket uint64) error {
ctx := context.Background()
zeroSL := 0.0
data, err := account.OrderModify(ctx, &pb.OrderModifyRequest{
Ticket: ticket,
StopLoss: &zeroSL, // 0 means remove SL
})
if err != nil {
return err
}
if data.ReturnedCode == 10009 {
fmt.Printf("Stop-loss removed from order %d\n", ticket)
}
return nil
}
🔧 Common Patterns¶
Safe SL/TP modification¶
func SafeModifySLTP(account *mt5.MT5Account, ticket uint64, newSL, newTP float64) error {
ctx := context.Background()
// Validate stop levels first
stopsLevel, _ := account.SymbolInfoInteger(ctx, &pb.SymbolInfoIntegerRequest{
Symbol: "EURUSD", // Should get symbol from position
PropertyId: 19, // SYMBOL_STOPS_LEVEL
})
// Add validation logic here...
data, err := account.OrderModify(ctx, &pb.OrderModifyRequest{
Ticket: ticket,
StopLoss: &newSL,
TakeProfit: &newTP,
})
if err != nil {
return fmt.Errorf("modification failed: %w", err)
}
if data.ReturnedCode != 10009 {
return fmt.Errorf("modification unsuccessful: %s", data.ReturnedCodeDescription)
}
return nil
}
📚 See Also¶
- OrderSend - Place new orders
- OrderClose - Close positions
- OpenedOrders - Get current positions
- SymbolInfoInteger - Get stops level