Как правильно расчитать свободные средства на фьючерсах?

 

"... наверное многие ещё помнят механические печатные машинки

и как нажатием на шифт приподнималась каретка меняя регистр..."

Нечто подобное происходит и при расчёте необходимых средств для маржи фьючерсов.

Фючерсы в отличии например от форексных инструментов имеют более расширеный формат

представления этого инструмента в системе:

- маржа инициализации

т.е. необходимое количество средств для открытия позиции

- маржа поддержки

т.е. необходимое количество средств для "сопровождения" окрытой позиции

именно она отображена в текущем пуле маржи в терминале...

-

В мкл4 эти данные доступны из функции MarketInfo

  double МАРЖАИНИ=MarketInfo(Symbol(),MODE_MARGININIT);
  double МАРЖАПОДД=MarketInfo(Symbol(),MODE_MARGINMAINTENANCE);

Как правило маржа инициализации больше чем поддержки,

хотя и встречаются случаи их полного равенства...

-

Но самое интесное то, как производится расчёт необходимых и свободных средств в терминале.

Допустим, имеем фьючерс CL

м.ини=1200, м.подд=550, открыто три позиции БАЙ по 1 лоту каждая,

маржа общая ини=1650 (550*3) свободно 2000

-

Теоритически имея свободных средств 2000 вполне хватает для открытия ещё 1 лота...

Но тут-то мы и обламаемся, почему? да потому что машинка печатна механическа ;)))

Если серьёзно, то вот почему...

В момент открытия четвёртой позиции, терминал "поднимет каретку" расчитав суммарную

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

оказывается не 2000 на счету а на 1950 меньше, т.е. всего 50, что сами понимаете маловато.

-

Происходит это для случаев одного инструмента в одном направлении...

Вот и призадумался как бы это учесть в блоках расчёта для советников.

Или достаточно будет везде использовать данные возвращеные MarketInfo(Symbol(),MODE_MARGININIT);

как вы считаете?

-

Так-же интересует момент учёта свободных средств если к тем трём позициям

открывать другой инструмент, например 1 лот EURUSD

 

Для вычисления рекомендуемого лота для торговли на FOREX я использую следующую функцию:

double МаксимальныйЛот(int Процент=100, int StopLoss=1000)
  {//Все 100% (или меньше) свободные средства размазываются по всем StopLoss пунктам, умножанным на их цену
   double MinLot = MarketInfo(Symbol(),MODE_MINLOT);     //Минимальный размер лота
   double MaxLot = MarketInfo(Symbol(),MODE_MAXLOT);     //Максимальный размер лота
   double StepLot = MarketInfo(Symbol(),MODE_LOTSTEP);   //Шаг изменения размера лота
   double TickVal = MarketInfo(Symbol(),MODE_TICKVALUE); //Размер минимального изменения цены инструмента в валюте депозита
   double MarjMain = MarketInfo(Symbol(),MODE_MARGINREQUIRED); //Размер свободных средств, необходимых для открытия 1 лота на покупку
   //Рассчитаем максимальный лот, который нам даст открыть программа
   if(MaxLot>AccountFreeMargin()*0.9/MarjMain)//где 0.9 - коэффициент запаса
      MaxLot=NormalizeDouble(AccountFreeMargin()*0.9/MarjMain,-Log10(StepLot));
   //Print("MarjMain="+MarjMain+", MaxLot="+MaxLot);
   //Рассчитаем фактический лот
   if(StopLoss==0) StopLoss=1000;
   double FreeLot=NormalizeDouble((AccountFreeMargin()*Процент/100)/StopLoss/TickVal,-Log10(StepLot));
   if(FreeLot>MaxLot)
      FreeLot=MaxLot;
   else if(FreeLot<MinLot)
      FreeLot=MinLot;
   return(FreeLot);   
  }

В этом коде непонятной для вас будет функция Log10(). Её название говорит само за себя:

int Log10(double Value)
  {   // возвращает количество знаков дробной части до первой значимой цифры, например: Log10(0.001) вернёт -3
   if(Value==0) return(0);
   for(int i = -8; i<=8; i++)
      if(NormalizeDouble(Value/MathPow(0.1,i),8)>=1.00000000) break;
   return(-i);
  }