Generate code in 3 minutes
Enter your idea and AI generates runnable code.
To open a buy or sell trade programmatically in MQL4, you use the OrderSend() function. This is the primary function for executing trade operations.
Below is a complete, robust code snippet demonstrating how to create wrapper functions for opening Buy and Sell orders. This code includes price normalization and error handling, which are essential for live trading.
//+------------------------------------------------------------------+
//| TradeExecutor.mq4 |
//| User Request |
//| https://www.metaquotes.net|
//+------------------------------------------------------------------+
#property copyright "Copyright 2023, MetaQuotes Ltd."
#property link "https://www.mql5.com"
#property version "1.00"
#property strict
//--- Input Parameters
input double LotSize = 0.1; // Volume in lots
input int StopLoss = 500; // Stop Loss in points (50 pips on 5-digit broker)
input int TakeProfit = 1000; // Take Profit in points (100 pips on 5-digit broker)
input int Slippage = 3; // Max slippage allowed in points
input int MagicNumber = 12345; // Unique identifier for this EA
//+------------------------------------------------------------------+
//| Function to Open a Buy Order |
//+------------------------------------------------------------------+
void OpenBuy()
{
double openPrice = Ask;
double sl = 0;
double tp = 0;
// Calculate Stop Loss and Take Profit if defined
if(StopLoss > 0)
sl = NormalizeDouble(openPrice - StopLoss * Point, Digits);
if(TakeProfit > 0)
tp = NormalizeDouble(openPrice + TakeProfit * Point, Digits);
// Send the order
int ticket = OrderSend(
Symbol(), // Symbol
OP_BUY, // Operation: Buy
LotSize, // Volume
openPrice, // Price (Ask for Buy)
Slippage, // Slippage tolerance
sl, // Stop Loss
tp, // Take Profit
"Buy Order", // Comment
MagicNumber, // Magic Number
0, // Expiration (0 for market orders)
clrGreen // Arrow Color
);
// Error Handling
if(ticket < 0)
{
Print("OrderSend failed with error #", GetLastError());
}
else
{
Print("Buy order placed successfully. Ticket: ", ticket);
}
}
//+------------------------------------------------------------------+
//| Function to Open a Sell Order |
//+------------------------------------------------------------------+
void OpenSell()
{
double openPrice = Bid;
double sl = 0;
double tp = 0;
// Calculate Stop Loss and Take Profit if defined
if(StopLoss > 0)
sl = NormalizeDouble(openPrice + StopLoss * Point, Digits);
if(TakeProfit > 0)
tp = NormalizeDouble(openPrice - TakeProfit * Point, Digits);
// Send the order
int ticket = OrderSend(
Symbol(), // Symbol
OP_SELL, // Operation: Sell
LotSize, // Volume
openPrice, // Price (Bid for Sell)
Slippage, // Slippage tolerance
sl, // Stop Loss
tp, // Take Profit
"Sell Order", // Comment
MagicNumber, // Magic Number
0, // Expiration
clrRed // Arrow Color
);
// Error Handling
if(ticket < 0)
{
Print("OrderSend failed with error #", GetLastError());
}
else
{
Print("Sell order placed successfully. Ticket: ", ticket);
}
}
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
// Example usage: Open a buy trade immediately upon loading
// Note: In a real strategy, you would call these in OnTick() based on logic
// OpenBuy();
return(INIT_SUCCEEDED);
}
OrderSend(): This is the core function. It returns the ticket number of the order if successful, or -1 if it fails.OP_BUY / OP_SELL: These constants define the direction of the trade.Ask / Bid:
NormalizeDouble(..., Digits): This is crucial. Calculated prices (like Stop Loss) often result in floating-point errors (e.g., 1.1234500001). The server will reject these. NormalizeDouble rounds the price to the correct number of decimal places supported by the symbol.Point: This holds the size of the smallest price change (e.g., 0.00001 for 5-digit brokers).ticket < 0. If true, we print GetLastError() to the "Experts" tab in the terminal to diagnose issues (e.g., "Not enough money", "Invalid stops").Q: Why do I get Error 130 (ERR_INVALID_STOPS)?
A: This usually happens if your Stop Loss or Take Profit is too close to the current price. Every broker has a MODE_STOPLEVEL (minimum distance). Ensure your SL/TP distance in points is greater than MarketInfo(Symbol(), MODE_STOPLEVEL).
Q: Why do I get Error 131 (ERR_INVALID_TRADE_VOLUME)?
A: The LotSize is incorrect. It might be too small (below MODE_MINLOT), too large (above MODE_MAXLOT), or not a multiple of MODE_LOTSTEP.
Q: How do I handle ECN brokers?
A: Some ECN brokers do not allow setting SL and TP during the initial OrderSend call. You must pass 0 for SL and TP in OrderSend, capture the ticket number, and then immediately use OrderModify() to set the Stop Loss and Take Profit.