Closing and Deleting Orders

เริ่มโดย admin, มีนาคม 03, 2018, 08:22:47 AM

« หน้าที่แล้ว - ต่อไป »

admin

Closing and Deleting Orders

Closing Market Orders

Trade requests for closing of market orders are formed using the function OrderClose().

Function OrderClose()
bool OrderClose (int ticket, double lots, double price, int slippage, color Color=CLR_NONE)
It is a function used to close a market order. The function returns TRUE, if the trade is performed successfully. It returns FALSE, if the trade fails.

Parameters:

ticket - the unique number of the order.

lots - the amount of lots to be closed. It is allowed to specify a value that is less than the available amount of lots in the order. In this case, if the trade request is successfully executed, the order will be closed partly.

price - close price. This parameter is set according to the requirements and limitations accepted for performing of trades (see Order Characteristics and Rules for Making Trades and Appendix 3). If there is no requested price available for closing of the market order in the price flow or if it is outdated, this trade request will be rejected; if the price is outdated, but found in the price flow and, at the same time, its deviation from the current price ranges within the value of slippage, the trade request will be accepted by the client terminal and sent to the trade server.

slippage - the maximum allowed deviation of the requested price for closing of the order from the market price (in points).

Color - the color of the closing arrow in a chart. If this parameter is unavailable or its value is equal to that of CLR_NONE, the arrow will not be displayed in the chart.


If the program contains information about the type of the order to be closed, about its unique number, as well as about the amount of lots to be closed, then it is very easy to close the order. For this, you should use in the program code the OrderClose() function call with preset parameters. For example, if the unique number of the order Buy is 12345 and if you want to close 0.5 lot, the call to the function closing the order may look like this:

OrderClose( 12345, 0.5, Bid, 2 );
In order to decide about what orders and in what sequence should be closed, you have to have data of all orders opened in the current situation. In MQL4, there is a number of functions that can be used to get various data that characterize any order. For example, the function OrderOpenPrice() returns the value of the order open price (or of the requested price for pending orders), the function OrderLots() returns the amount of lots, the function OrderType() returns the type of the order, etc. All functions that return the values of an order characteristic call at their execution to the order that has been selected by the function OrderSelect().

Function OrderSelect()

In order to get the parameters of any of your orders (no matter market or pending, closed or deleted ones), you should first select it using the function OrderSelect().

bool OrderSelect(int index, int select, int pool=MODE_TRADES)
OrderSelect is a function that selects an order for further operations with it. It returns TRUE, if the function is executed successfully. Otherwise, it returns FALSE.

Parameters:

index - the order position or number, it depends on the second parameter.

select - the flag of selection method. Parameter 'select' can take one of two possible values:

SELECT_BY_POS - in the parameter 'index', the order number in the list is returned (the numbering starts with 0),

SELECT_BY_TICKET - in the parameter 'index', the ticket number (the unique order number) is returned.

pool - the data source for selection. The parameter 'pool' is used, when the parameter 'select' is equal to the value of SELECT_BY_POS. The parameter 'pool' is ignored, if the order is selected by the ticket number (SELECT_BY_TICKET). The parameter 'pool' can take on of two possible values:

MODE_TRADES (by default) - the order is selected in open and pending orders, i.e., among the orders displayed in the "Trade" tab of the "Terminal" window;

MODE_HISTORY - the order is selected in closed and deleted orders, i.e., among the orders displayed in the "Account History" tab of the "Terminal" window. In this case, the depth of history specified by the user for displaying of closed and deleted orders is important.


In order to demonstrate the method of using trade functions for closing of market orders, let's solve a problem:

   Problem 28. Write a script that closes one of the market orders available on the account. The script execution must result in closing of the order closest to the location of the script attached to the symbol window with the mouse.
Suppose there are three market orders opened in the terminal for the symbol Eur/Usd and a pending order opened for Usd/Chf:


Fig. 90. Displaying several orders opened for different symbols in the terminal window.

We should write such a script that can be dragged by the mouse from the "Navigator" window into the symbol window, which should result in closing of one of the market orders, namely, the order closest to the cursor (as of the moment when the user released the mouse button). In Fig. 91, you can see the alternative, at which the cursor is closest to order Sell 4372889. It is this order that must be closed as a result of the script execution.


Fig. 91. Script closeorder.mq4 used for closing of the selected order.

To solve the problem, we should select (using the function OrderSymbol()) among all orders only those opened for the symbol, in the window of which the script is dropped. Then we should find the open prices of all selected market orders (i.e., execute the function OrderOpenPrice() successively for each order). Knowing the order open prices, we can easily select one of them that corresponds with the statement of the problem. To specify the proper values of parameters in the function OrderClose(), we will also need to know some other data about the selected order: the amount of lots (determined by the function OrderLots()) and the unique order number (determined by the function OrderTicket()). Besides, to find one or another price of a two-way quote, we have to know the type of the order (determined by the function OrderType()).

Let's consider what parameters must be specified in the function OrderSelect() in order to obtain the above order characteristics.

First of all, it is necessary to choose the order selection method. In our problem, the selection method is determined by the problem statement itself: The data about order numbers is supposed to be unavailable in the program as of the moment of launching the script for execution, i.e., the program is considered to contain a block that would determine those order numbers. This means that we should check all orders one by one displayed in "Terminal" (Fig. 64.1), so we have to use the parameter SELECT_BY_POS.

The source for selection of orders is obvious, as well. To solve the problem, there is no need to analyze closed and deleted orders. In this case, we are interested in market orders only, so we will search in them using the parameter MODE_TRADES in the function OrderSelect(). For the parameter 'pool', the default value of MODE_TRADES is specified in the function header, so it can be skipped.

Below is shown how a block for analyzing of market and pending orders can be built:

   for (int i=1; i<=OrdersTotal(); i++)       //Cycle for all orders..
     {                                        //displayed in the terminal
      if(OrderSelect(i-1,SELECT_BY_POS)==true)//If there is the next one
        {                                     
         // Order characteristics..
         // ..must be analyzed here
        }
     }                                        //End of the cycle body
In the heading of the cycle operator, the initial value is specified as i=1, whereas the condition to exit the cycle is the expression i<=OrdersTotal(). Function OrdersTotal() returns the total amount of market and pending orders, i.e., those orders that are shown in the "Trade" tab of the "Terminal" window. This is why there will be as many iterations in the cycle as many orders participate in trading.

At each iteration, when the condition is calculated in the operator 'if', the function OrderSelect(i-1,SELECT_BY_POS) will be executed. The following important matter must be noted here:

   The numbering of orders in the list of market and pending orders starts with zero.
This means that the first order in the list (Fig. 90) is placed in zero position, the position of the second order is numbered as 1, that of the third order is numbered as 2, etc. This is why, in the function call OrderSelect(), the value of index is given as i-1. Thus, for all selected orders, this index will always be 1 less than the value of the variable i (that coincides with the number of the next iteration).

The function OrderSelect() returns true, if the order is successfully selected. It means that it is possible that an order selection can fail. This can happen, if the amount of orders changed during their processing. When programming in MQL4, you should well remember that an application program will work in the real-time mode and that, while it is processing some parameters, the values of these parameters may change. For example, the amount of market orders can change as a result of both opening/closing of orders and modifying of pending orders into market ones. This is why you should keep to the following rule when programming order processing: Orders must be processed as soon as possible, whereas the program block responsible for this processing should not, if possible, contain redundant program lines.

According to the code represented in Fig. 64.3, in the header of the operator 'if', the program analyzes whether the next order is available in the order list at the moment when it is selected. If the next order is available, the control will be passed into the body of the operator 'if' to process the order parameters. It must be noted that such construction does not help much, in case of possible conflicts, because the order can be lost (closed) during processing of its parameters. However, this solution turns out to be most efficient if, as of the moment of its selection, the order is not available anymore. In the body of the operator 'if', the parameters of the selected order are analyzed. When executing the functions OrderOpenPrice(), OrderTicket(), OrderType() and others of the kind, each of them will return the value of a certain characteristic of the order selected as a result of execution of the function OrderSelect().

All the above reasoning was used in the program that would solve Problem 28.

   An example of a simple script intended for closing of a market order, the open price of which is closer to the location of the script attachment than the open prices of other orders (closeorder.mq4).

//--------------------------------------------------------------------------------------
// closeorder.mq4
// The code should be used for educational purpose only.
//--------------------------------------------------------------------------------- 1 --
int start()                                     // Special function 'start'
  {
   string Symb=Symbol();                        // Symbol
   double Dist=1000000.0;                       // Presetting
   int Real_Order=-1;                           // No market orders yet
   double Win_Price=WindowPriceOnDropped();     // The script is dropped here
//-------------------------------------------------------------------------------- 2 --
   for(int i=1; i<=OrdersTotal(); i++)          // Order searching cycle
     {
      if (OrderSelect(i-1,SELECT_BY_POS)==true) // If the next is available
        {                                       // Order analysis:
         //----------------------------------------------------------------------- 3 --
         if (OrderSymbol()!= Symb) continue;    // Symbol is not ours
         int Tip=OrderType();                   // Order type
         if (Tip>1) continue;                   // Pending order 
         //----------------------------------------------------------------------- 4 --
         double Price=OrderOpenPrice();         // Order price
         if (NormalizeDouble(MathAbs(Price-Win_Price),Digits)< //Selection
            NormalizeDouble(Dist,Digits))       // of the closest order       
           {
            Dist=MathAbs(Price-Win_Price);      // New value
            Real_Order=Tip;                     // Market order available
            int Ticket=OrderTicket();           // Order ticket
            double Lot=OrderLots();             // Amount of lots
           }
         //----------------------------------------------------------------------- 5 --
        }                                       //End of order analysis
     }                                          //End of order searching
//-------------------------------------------------------------------------------- 6 --
   while(true)                                  // Order closing cycle
     {
      if (Real_Order==-1)                       // If no market orders available
        {
         Alert("For ",Symb," no market orders available");
         break;                                 // Exit closing cycle       
        }
      //-------------------------------------------------------------------------- 7 --
      switch(Real_Order)                        // By order type
        {
         case 0: double Price_Cls=Bid;          // Order Buy
            string Text="Buy ";                 // Text for Buy
            break;                              // Из switch
         case 1: Price_Cls=Ask;                 // Order Sell
            Text="Sell ";                       // Text for Sell
        }
      Alert("Attempt to close ",Text," ",Ticket,". Awaiting response..");
      bool Ans=OrderClose(Ticket,Lot,Price_Cls,2);// Order closing
      //-------------------------------------------------------------------------- 8 --
      if (Ans==true)                            // Got it! :)
        {
         Alert ("Closed order ",Text," ",Ticket);
         break;                                 // Exit closing cycle
        }
      //-------------------------------------------------------------------------- 9 --
      int Error=GetLastError();                 // Failed :(
      switch(Error)                             // Overcomable errors
        {
         case 135:Alert("The price has changed. Retrying..");
            RefreshRates();                     // Update data
            continue;                           // At the next iteration
         case 136:Alert("No prices. Waiting for a new tick..");
            while(RefreshRates()==false)        // To the new tick
               Sleep(1);                        // Cycle sleep
            continue;                           // At the next iteration
         case 146:Alert("Trading subsystem is busy. Retrying..");
            Sleep(500);                         // Simple solution
            RefreshRates();                     // Update data
            continue;                           // At the next iteration
        }
      switch(Error)                             // Critical errors
        {
         case 2 : Alert("Common error.");
            break;                              // Exit 'switch'
         case 5 : Alert("Old version of the client terminal.");
            break;                              // Exit 'switch'
         case 64: Alert("Account is blocked.");
            break;                              // Exit 'switch'
         case 133:Alert("Trading is prohibited");
            break;                              // Exit 'switch'
         default: Alert("Occurred error ",Error);//Other alternatives   
        }
      break;                                    // Exit closing cycle
     }
//------------------------------------------------------------------------------- 10 --
   Alert ("The script has finished operations -----------------------------");
   return;                                      // Exit start()
  }
//------------------------------------------------------------------------------- 11 --
The whole code of the program closeorder.mq4 is concentrated in the special function start(). In block 1-2, some variables are initialized. The variable Dist is the distance from the location where the script has been dropped to the closest order. The variable Real_Order is a flag that displays the availability of at least one market order in the client terminal (nonnegative value). The variable Win_Price is the price, at which the user has attached the script to the symbol window. In block 2-6, the order is analyzed: One of the orders available is assigned to be closed. Block 6-10 is the block of closing the order and of processing the errors that can occur during performing of the trade.

Starting from the moment when the user attached the script to the symbol window, the values of the variables are calculated in block 1-2, the variable Win_Price taking the value of the price, at the level of which the user attached the script. It is now necessary to find the order (with its characteristics) that is closest to this location.

In the cycle 'for' (block 2-6), the orders are searched in. In block 2-3, the program checks whether there is an order in the next line of the "Terminal". If an order is found, the control is passed to the body of the operator 'if' to get and analyze the characteristics of that order. In block 3-4, the orders opened for wrong symbols (not the symbol, for which the program is being executed) are filtered out. In our case, it is order 4372930 opened for Usd/Chf. Function OrderSymbol() returns the symbol name of the selected order. If this symbol name is other than that, for which the program is being executed, the current iteration is broken, preventing the order opened for another symbol from being processed. If the order under analysis turns out to be opened for "our" symbol, one more check will be performed. The order type is determined using the function OrderType() (see Types of Trades). If the order type turns out to be more than 1, it means that the order is a pending one. In this case, the current iteration is interrupted, too, because we are not interested in pending orders. In our example, we have such an order, but it is opened for another symbol, so it has already been filtered out. All orders that pass block 3-4 successfully are market ones.

Block 4-5 is intended for selecting only one order of all market orders that have successfully passed the preceding block. This order must be the closest to the predefined price (the value of the variable Win_Price). The user is not required to "pinpoint" the order line with his or her mouse cursor. The order that is closer than any other orders to the cursor as of the moment of launching the script for execution will be selected. The open price of the order processed is found using the function OrderOpenPrice(). If the absolute value of the distance between the price of the current order and the "cursor price" is less than the same distance for the preceding order, the current order will be selected (the absolute value of the distance is necessary for excluding of the influence of the cursor position - under or above the order line). In this case, this order will be memorized at the current iteration of the cycle 'for' as a front-runner for being closed. For this order, the ticket number (the individual number of the order) and the amount of lots are calculated at the end of block 4-5. In this example (Fig. 90), the total amount of orders is four (three market ones and one pending order), so there will be four iterations executed in the cycle 'for', which will result in finding all necessary data for closing of one selected order.

Then the control in the executing program will be passed to the cycle operator 'while' (block 6-10). In block 6-7, the market orders found are checked for availability. If no market orders are found in block 2-4 (it is quite possible, in general), the value of the flag Real_Order remains equal to -1, which means the unavailability of market orders. If the checking in block 6-7 detects no market orders, the execution of the cycle 'while' is broken, the program then finishes its operations. If the value of the variable Real_Order turns out to be equal to 0 or 1, this means that a market is predefined for closing and must be closed.

In block 7-8, according to the order type, the close price of the order is calculated. It is the value of Bid for Buy orders, and the value of Ask for Sell orders (see Requirements and Limitations in Making Trades).

In block 7-8, the values of the auxiliary variable Text are calculated. The trade request for closing of the order is formed in the function OrderClose() in the line below:

      bool Ans=OrderClose(Ticket,Lot,Price_Cls,2);// Order closing
Trade function OrderClose() returns true, if the trade is made successfully, and false, if not. If the trade request is successfully executed on the server, the value 'true' will be assigned to the variable Ans (answer). In this case, when executing block 8-9, the program will inform the user about successful order closing. After that, the execution of the cycle operator 'while' will be stopped, and the program will end its operations. Otherwise, the control will be passed to block 9-10 in order to analyze the error returned by the client terminal to the program.

At the beginning of block 9-10, the error code is calculated. After that, according to the error code, either program exit or repeated operation are executed. In the first operator 'switch', the program processes the errors that are implicitly overcomable, i.e., the errors can be considered as temporary difficulties in performing of the trade. All necessary actions are taken for each of such errors, then the current iteration is stopped and the execution of the cycle 'while' restarts. (Please note that, in this example, we use for error processing the operator 'switch' that is exited as a result of using of the operator 'continue' that, as such, is not intended for passing of the control outside the operator 'switch'. This construction works just because the operator 'switch' is a part of contents of the external cycle operator 'while' and the operator 'continue' interrupts the current iteration by passing of the control to the header of the operator 'while').

If the error code is not processed in the first operator 'switch', this error is considered to be critical. In this case, the control is passed to the second operator 'switch', which is executed in order to inform the user that one or another critical error has occurred. Further, the program uses the operator 'break' that interrupts the execution of the cycle 'while'. Exiting the cycle 'while', for any reason, will result in passing of the control to block 9-10 that produces a message about the end of the program operations. The operator 'return' stops the execution of the special function start(), and the program finishes its operations.

Practical result obtained after launching of the script under the stated conditions (see Fig. 90 and 91) is shown below. The trade was successfully made on the server.


Fig. 92. Messages received as a result of successful execution of the script closeorder.mq4.

As a result of closing of one of the orders, there are two orders left in the window of Eur/Usd.


Fig. 93. Execution of the script closeorder.mq4 results in closing of one of the orders.

Order closing has also been displayed in the "Terminal" window:


Fig. 94. After Execution of the Script closeorder.mq4, Two Market Orders Are Displayed in the "Terminal" Window.

Later, the other two orders are closed using this script, too.
บจก.สยามเอวีเอส
63 Moo 2 แพรกษาใหม่ เมือง สมุทรปราการ
นำเข้า-จำหน่าย เครื่องจักร cnc มือสองญี่ปุ่น
ติดต่อ คุณ ธนเดช  084-387-2401
EMAIL kiattub@gmail.com
คลิกลิ้งแอดไลน์ได้เลย Line id : boysiamavs
http://line.me/ti/p/~boysiamavs