Нормализация лота

Автор: | 03.07.2018

В некоторых экспертах выполняется расчет лота. В результате расчета может получаться значение неподходящее для использования в функция открытия и закрытия позиции. Прежде чем использоваться полученное значение его необходимо нормализовать. 

Имеем параметры лота определяемые брокером:

  • Минимальный лот.
  • Максимальный лот.
  • Шаг изменения лота.

Расчетный лот не может быть меньше минимального значения, больше максимального, а промежуточные значения должны соответствовать шагу изменения лота.

Для определения этих параметров лота в МТ4 используется функция MarketInfo() с соответствующими идентификаторами:

double LotsMin=MarketInfo(Symbol(),MODE_MINLOT); // максимальный лот
double LotsMax=MarketInfo(Symbol(),MODE_MAXLOT); // минимальный лот
double LotsStp=MarketInfo(Symbol(),MODE_LOTSTEP);// шаг изменения лота 

В МТ5 для этого используется функция SymbolInfoDouble():

double LotsMin=SymbolInfoDouble(Symbol(),SYMBOL_VOLUME_MIN);
double LotsMax=SymbolInfoDouble(Symbol(),SYMBOL_VOLUME_MAX);
double LotsStp=SymbolInfoDouble(Symbol(),SYMBOL_VOLUME_STEP);

Допустим, расчетное значение лота находится в переменной lot:

1. Вычитаем минимальное значение лота:

lots-=LotsMin;

2. Определяем количество минимальный лотов входящих в остаток:

double n=lots/LotsStp;

В результате деления получаем дробное значение, а нам нужно целое. В зависимости от стоящей задачи полученное дробное число может быть округлено, может быть отброшен дробный остаток или оно может быть увеличено до ближайшего целого. Для округления используется функция MathRound(), для отбрасывания дробного остатка – MathFloor(), для увеличения до ближайшего целого – MathCeil().

3. В данном примере используем функцию округления:

n=MathRound(n).

4. Вычисляем окончательный размер лота умножая полученное целое n на шаг изменения лота и прибавляя к нему минимальный лот:

lot=LotsMin+n*LotsStp;

5. Переменные double, после каких-либо арифметических действий с ними, могут иметь, так сказать, иррациональный “хвост”, по этому, перед использованием, их нужно нормализовывать, для этого есть соответствующая функция NormalizeDouble(). Выполняем нормализацию до двух знаков:

lot=NormalizeDouble(lot,2);

6. Остается подкорректировать полученное значение в соответствие с максимальным и минимальным лотами:

lot=MathMax(lot,LotsMin);
lot=MathMin(lot,LotsMax);

В итоге получаем функции:

Для МТ4:

double LotsNormalize(string symbol,double lot){
   double LotsMin=MarketInfo(symbol,MODE_MINLOT);
   double LotsMax=MarketInfo(symbol,MODE_MAXLOT);
   double LotsStp=MarketInfo(symbol,MODE_LOTSTEP);
   lot-=LotsMin;
   lot=NormalizeDouble(MathRound(lot/LotsStp)*LotsStp+LotsMin,2);
   lot=MathMax(lot,LotsMin);
   lot=MathMin(lot,LotsMax);   
   return(lot);
} 

Для МТ5:

double LotsNormalize(string symbol,double lot){
   double LotsMin=SymbolInfoDouble(symbol,SYMBOL_VOLUME_MIN);
   double LotsMax=SymbolInfoDouble(symbol,SYMBOL_VOLUME_MAX);
   double LotsStp=SymbolInfoDouble(symbol,SYMBOL_VOLUME_STEP); 
   lot-=LotsMin;   
   lot=NormalizeDouble(MathRound(lot/LotsStp)*LotsStp+LotsMin,2);
   lot=MathMax(lot,LotsMin);
   lot=MathMin(lot,LotsMax);   
   return(lot);
} 

При вызове функции в нее передается символ и расчетный лот, возвращает функция нормализованный лот.

В случае необходимости, можно получит разновидности функций с округлением до ближайшего меньшего целого и большего целого, достаточно заменить функцию MathRound() на MathFloor() или MathCeil(). Конечно можно было бы сделать универсальную функцию еще с одним параметром для выбор типа округления, но эти разновидности используются очень редко, поэтому в этом нет смысла.