MQL4 Book  Creation of a Normal Program  Volume Defining Function


Volume Defining Function


For his or her practical work, a trader needs to be able to regulate the amount of lots for new orders to be opened. It is quite difficult to create a universal function for this purpose, since every trading strategy implies its special volume management. For example, some strategies imply the possibility to work with only one market order, whereas others allow to open new market orders regardless of the existing ones. Strategies based on management of different pending orders are known, too, the simultaneous availability of several market and pending orders being allowed in some cases.

One of the most common methods of volume calculation for newly opened orders (for the strategies that allow only one market order to be opened at a time) is the method of progressive investments. According to this method, the collateral cost of each new order is proportional to the free margin available at the moment of trade. If a market order is closed with profit, the allowed amount of lots for the new order increases. If it is closed with a loss, that amount will be decreased.

In the example below, the user-defined function Lot() is considered that allows you to set the volume for newly opening orders using one of the two alternatives:

Alternative 1. User sets the amount of lots for new orders manually.

Alternative 2. The amount of lots is calculated according to the amount of the money allocated by user. The amount of allocated money is set as percentage of free margin.

User-Defined Function Lot()

bool Lot()

The function calculates the amount of lots for new orders. As a result of the function execution, the value of the global variable Lots_New changes: the amount of lots. The function returns TRUE, if the free margin is sufficient for opening an order with the minimum amount of lots (for the symbol, in the window of which the EA is attached). Otherwise, it returns FALSE.

The function uses the values of the following global variables:

  • Lots - volume in lots defined by the user;
  • Percent - the percentage of free margin defined by the user.

To display message, the function uses the data function Inform(). If the function Inform() is not included in the EA, no messages will be displayed.

The function Lot() that determines the amount of lots is formed as include file Lot.mqh:

//----------------------------------------------------------------------------------
// Lot.mqh
// The code should be used for educational purpose only.
//----------------------------------------------------------------------------- 1 --
// Function calculating the amount of lots.
// Global variables:
// double Lots_New - the amount of lots for new orders (calculated)
// double Lots - the desired amount of lots defined by the user.
// int Percent - free margin percentage defined by the user
// Returned values:
// true - if there is enough money for the minimum volume
// false - if there is no enough money for the minimum volume
//----------------------------------------------------------------------------- 2 --
bool Lot() // User-defined function
{
string Symb =Symbol(); // Symbol
double One_Lot=MarketInfo(Symb,MODE_MARGINREQUIRED);//!-lot cost
double Min_Lot=MarketInfo(Symb,MODE_MINLOT);// Min. amount of lots
double Step =MarketInfo(Symb,MODE_LOTSTEP);//Step in volume changing
double Free =AccountFreeMargin(); // Free margin
//----------------------------------------------------------------------------- 3 --
if (Lots>0) // Volume is explicitly set..
{ // ..check it
double Money=Lots*One_Lot; // Order cost
if(Money<=AccountFreeMargin()) // Free margin covers it..
Lots_New=Lots; // ..accept the set one
else // If free margin is not enough..
Lots_New=MathFloor(Free/One_Lot/Step)*Step;// Calculate lots
}
//----------------------------------------------------------------------------- 4 --
else // If volume is not preset
{ // ..take percentage
if (Percent > 100) // Preset, but incorrectly ..
Percent=100; // .. then no more than 100
if (Percent==0) // If 0 is preset ..
Lots_New=Min_Lot; // ..then the min. lot
else // Desired amount of lots:
Lots_New=MathFloor(Free*Percent/100/One_Lot/Step)*Step;//Calc
}
//----------------------------------------------------------------------------- 5 --
if (Lots_New < Min_Lot) // If it is less than allowed..
Lots_New=Min_Lot; // .. then minimum
if (Lots_New*One_Lot > AccountFreeMargin()) // It isn't enough even..
{ // ..for the min. lot:(
Inform(11,0,Min_Lot); // Message..
return(false); // ..and exit
}
return(true); // Exit user-defined function
}
//----------------------------------------------------------------------------- 6 --

The function has a simple code. In block 1-2, global variables and returned values are described. In block 2-3, the values of some variables are calculated. For calculations, the following priority in setting of values is accepted: If a user has set a non-zero amount of lots, the value of the percentage of free margin is not taken into consideration. External variables Lots and Percent are declared in the include file Variables.mqh.

In block 3-4, the calculations are made for the situation where the user has defined a non-zero value of the volume in lots in the external variable Lots. In this case, the program makes a check. If the free margin is sufficient to open a market order with the defined amount of lots, then the value set by the user will be assigned to the global variable Lots_New and used in further calculations. If the free margin doesn't cover this amount, then the maximum possible amount of lots is calculated that is used further (see Mathematical Functions).

The control is passed to block 4-5, if the user has defined zero amount of lots. At the same time, we take into consideration the percentage of free margin specified by the user in the external variable Percent. The program makes a check: If the value exceeds one hundred (percent), the value of 100 is used in calculations. If the user has defined zero value of the variable Percent, the amount of lots is equated with the minimum possible value set by the dealing center. For all intermediate Для всех промежуточных величин высчитывается количество лотов, соответствующее количеству выделенных пользователем средств.

In block 5-6, the necessary checks are made. If the calculated amount of lots turns out to be less than the minimum allowed one (for example, zero value can be obtained in block 4-5, if the user has defined a small value of the variable Percent), then the minimum value will be assigned to the variable Lots_New. Then the program checks whether there are enough free assets to open an order with the volume of the previously calculated amount of lots (there can be insufficient money on the account). If the money available is not enough, the program displays a message for the user and exits the function, the function returning 'false'. However, the successful check results in returning of 'true'.