OrderSend function


for example, forex

The format of the function:

   int OrderSend(string symbol, int cmd, double volume, double price, int slippage, 
                          double stoploss, double takeprofit, string comment=NULL, 
                          int magic=0, datetime expiration=0, color arrow_color=CLR_NONE)

The OrderSend() function is used to place a pending order or to open a position. The function returns the number of ticket of an open position or a placed pending order. In case of a failure the OrderSend() function returns number -1.

At that:

  • symbol — instrument in which a position will be open or a pending order will be placed;
  • cmd — the type of the order (refer to table 1);
  • volume — volume in lots;
  • price — the price of opening the position or the level of the pending order;
  • slippage — the maximum allowable deviation between price and the price of the server at which a position will be open (for placing pending orders the value of parameter slippage doesn’t matter);
  • stoploss — level of Stop Loss;
  • takeprofit — level of Take Profit;
  • comment — comments to the order or position (later this field can be modified by the server — refer to the article «OrderComment() — comments of the selected order»);
  • magic — the magic number of the order (can be received later by the OrderMagicNumber() function);
  • expiration — the expiration date and time of the pending order (if the pending order doesn’t work out by this date and time it will be deleted — refer to the article «OrderExpiration() — the expiration date of a pending order»);
  • arrow_color — the color of the opening arrow on the chart. If the parameter lacks or its value is equal to CLR_NONE, the opening arrow isn’t displayed on the chart.

In parameter cmd we convey the type of an order:

Table 1. Possible values of parameter cmd of the OrderSend() function

ConstantValueDescription
OP_BUY0Open a long position
OP_SELL1Open a short position
OP_BUYLIMIT2Place a pending order BUY LIMIT
OP_SELLLIMIT3Place a pending order SELL LIMIT
OP_BUYSTOP4Place a pending order BUY STOP
OP_SELLSTOP5Place a pending order SELL STOP

Thus to open a short position one should indicate OP_SELL as parameter cmd. To open a long position OP_BUY is used. To place a pending order the values OP_BUYLIMIT, OP_SELLLIMIT, OP_BUYSTOP or OP_SELLSTOP should be used depending on the type of the placed order.

When a position is open the current Bid (if cmd equals OP_SELL) or the current Ask (if cmd equals OP_BUY) should be used as parameter price:

  • the Bid function returns the current Bid in the instrument to which the expert advisor is «attached»;
  • the Ask function returns the current Ask in the instrument to which the expert advisor is «attached»;
  • the MarketInfo(string symbol, int type) function with parameter type, equal to MODE_BID or MODE_ASK, returns the current Bid or Ask in the instrument which was passed to it as parameter symbol.

Note:
By no means the price, calculated by some formula or the price which you haven’t reduced (normalized) to such number of decimal places that this instrument must have, should be used.

In order to «normalize» the price the NormalizeDouble() function is used:

   double NormalizeDouble ( double value, int digits )

This function rounds off a real number value with an accuracy to digits decimal places. The number of digits after the decimal point must be in the range of 0 .. 8.

In case an «incorrect» price is used in parameter price the following codes of errors will be shown:

  • ERR_INVALID_PRICE (129) — if the price wasn’t «normalized» or there wasn’t such a price in the flow;
  • ERR_REQUOTE (138) — if the price is out-of-date considerably (regardless of the value of parameter slippage);

If the price is out-of-date but it is still in the flow, a transaction will be performed at the current price, if the current price is within the range of price +/- slippage.

When you open a position (place a pending order), then Stop Loss and Take Profit orders must be in relation to the current price (the price of the pending order) not closer than at the distance of certain number of points. For example if You have a trading account in Alpari, You can’t place Stop Loss and Take Profit orders in FOREX closer than one spread to the current price for an open position or to the price of a pending order.

If You try to place Stop Loss or Take Profit closer than it is permitted the OrderSend() function will return error 130 (ERR_INVALID_STOPS).

If You don’t know the minimum permissible value You can always get it with the help of the MarketInfo() function. The MarketInfo(string symbol, int type) function with parameter type, equal to MODE_STOPLEVEL, returns this value for the instrument which was passed to it as parameter symbol.

The instrument of the chart to which the expert is attached can be received with the help of the Symbol() function:

   string Symbol()

If the OrderSend() function returns error 147 (ERR_TRADE_EXPIRATION_DENIED), it means that pending orders with a set expiration date are prohibited on the trading server. In this case the OrderSend() function with parameter expiration, equal to zero should be used in future. «Alpari» allows its clients to set any date and time when an unexecuted pending order will be deleted automatically.

If the OrderSend() function returns error 148 (ERR_TRADE_TOO_MANY_ORDERS), it means that a limit for maximum permissible number of open positions and placed pending orders on a trading account is set on the trading server. Trying to open one more position or place one more pending order You exceed the permissible limit and that’s why You won’t be able to do this.

An example of usage of the OrderSend() function can be found in our first expert advisor:

   MyOrderTicket = OrderSend(Symbol(), OP_SELL, LotsNumber, Bid, 3, 0, 0, 
                                                 NULL, 0, 0, CLR_NONE);
   if (MyOrderTicket<0)
     {
       err = GetLastError();
       Print("Error at opening a position: ", err);
       MyOrderTicket = 0;
     }

Example of an expert advisor

Task.

The expert advisor must at a specified time (parameters MyHour and MyMinute) at a previously set distance from the current price (parameter MyPendingLevel) place two orders — Sell Stop and Buy Stop. At the same time order Stop Loss at the distance of MySL pips from the order’s price and order Take Profit at the distance of MyTP pips must be placed as well.

Solution.

   //+------------------------------------------------------------------+
   //|                                           2nd Expert.mq4 |
   //|                                          Andrey Vedikhin |
   //|                                http://www.vedikhin.ru |
   //+------------------------------------------------------------------+ 
   #property copyright "Andrey Vedikhin"
   #property link      "http://www.vedikhin.ru"
//---- input parameters extern int MyPendingLevel=15; extern int MySL=30; extern int MyTP=15; extern int MyHour=19; extern int MyMinute=40; extern int MyLots=1.0;
datetime LastTradeTime; // the time of the last trading operation
//+------------------------------------------------------------------+ //| expert initialization function | //+------------------------------------------------------------------+ int init() { //---- // we’ll set yesterday as the time of the last trading operation LastTradeTime = CurTime()-24*60*60; //---- return(0); } //+------------------------------------------------------------------+ //| expert deinitialization function | //+------------------------------------------------------------------+ int deinit() { //----
//---- return(0); } //+------------------------------------------------------------------+ //| expert start function | //+------------------------------------------------------------------+ int start() { //---- // we’ll check whether we have already placed an order today // if we have placed - we exit if (TimeDayOfYear(CurTime())==TimeDayOfYear(LastTradeTime)) return(0);
// we’ll check whether it is time to place an order if ((TimeHour(CurTime())==MyHour)&&(TimeMinute(CurTime())==MyMinute)) { // we’ll place a Buy Stop if (OrderSend(Symbol(), OP_BUYSTOP, MyLots, Ask+Point*MyPendingLevel, 0, Ask+Point*MyPendingLevel-Point*MySL, Ask+Point*MyPendingLevel+Point*MyTP)!=-1) LastTradeTime = CurTime(); // order isn’t placed else return(0);
// compulsory 10-second pause Sleep(10000);
// we’ll refresh the current Bid and Ask RefreshRates();
// we’ll place a Sell Stop if (OrderSend(Symbol(), OP_SELLSTOP, MyLots, Bid-Point*MyPendingLevel, 0, Bid-Point*MyPendingLevel+Point*MySL, Bid-Point*MyPendingLevel-Point*MyTP)!=-1) LastTradeTime = CurTime(); // order isn’t placed else return(0); } //---- return(0); } //+------------------------------------------------------------------+

First of all this expert advisor has several parameters:

   extern int       MyPendingLevel=15;
   extern int       MySL=30;
   extern int       MyTP=15;
   extern int       MyHour=19;
   extern int       MyMinute=40;
   extern int       MyLots=1.0;

These parameters have the following meaning:

  • MyPendingLevel — distance in pips from the current price at which a pending order is placed;
  • MySL and MyTP — Stop Loss and Tale Profit in pips from the price of the pending order;
  • MyHour and MyMinute — the hour and minute when the pending order is placed;
  • MyLots — the size of the lot of the pending order.

Let me remind you that how to describe the expert’s parameters in the code I explained in the article «External variables».

In fact a situation may emerge when there can be several ticks on the bar MyHour:MyMinute, that’s why to avoid placing pending orders on each tick we have introduced a global variable LastTradeTime:

  datetime LastTradeTime; // the time of the last trading operation

We assign yesterday’s date as initial value to this variable at initializing the expert advisor— in the init() function:

  //+------------------------------------------------------------------+
  //| expert initialization function                          |
  //+------------------------------------------------------------------+
  int init()
    {
  //----
     // we’ll set yesterday as the time of the last trading operation  
     LastTradeTime = CurTime()-24*60*60;   
 //----
     return(0);
  }

On each tick the start() function is called in which we at first check whether we have already placed pending orders today:

   // we’ll check whether we have already placed an order today
   // if we have placed – we exit
   if (TimeDayOfYear(CurTime())==TimeDayOfYear(LastTradeTime)) 
         return(0);

Here an unknown for us function is used TimeDayOfYear():

   int TimeDayOfYear( datetime date )

This function returns the order number of the day (from the beginning of the year): 1 — 1 January, … , 365 or 366 — 31 December.

If the order number of the day of the last trading operation — TimeDayOfYear(LastTradeTime) — equals to the order day of the current time — TimeDayOfYear(CurTime()), — it means that we have already placed orders today and that’s why we exit the expert advisor : return(0).

Now we’ll check whether it is time to place a pending order:

   // we’ll check if it is time to place an order
   if ((TimeHour(CurTime())==MyHour)&&(TimeMinute(CurTime())==MyMinute))
     {
       ...
     }

I will tell you about two unknown functions in this portion of the code:

  • int TimeHour(datetime time) — returns the hour for the time time: 0..23;
  • int TimeMinute(datetime time) — returns the minute for the time time: 0..59.

If it is time to place a pending order at first with the help of the OrderSend() function we place a Buy Stop order.

Then we wait a ten-second pause with the help of the Sleep() function:

   void Sleep(int milliseconds)

This function make a pause in the work of the expert advisor for milliseconds milliseconds (1 second = 1000 milliseconds).

During these 10 seconds the current bid and ask might have changed and that’s why we refresh them with the help of the RefreshRates() function.

Then we place a pending order Sell Stop.

So this is the end of our expert advisor. I’d like to note that this expert advisor may miss the moment when a pending order should be placed if there weren’t quotes in this bar and the start() function wasn’t called. I think that my reader has enough knowledge to correct this lack of the expert advisor by himself.


Next article: "OrderModify function"

+7 (495) 710-76-76
© 1998—2008 «Alpari»

close

Your Personal Area

For alpari.classic enter your account number (a letter and 4 figures) and the code word for the Personal Area.

For alpari.micro account: enter your login (6 figures) and the password for MT.

Open an account!Forgotten your password?