Правильное определение размера лота. Минимальный размер лота и шаг изменения лота. - страница 2

 
komposter писал (а):
ExpertTrader писал (а):
if(AccountFreeMargin()<(1000*Lots)) - т.е. на один лот 1000, а к примеру для евро надо уже больше, сейчас почти 1300... Это первая проблема, вторая, шаг лота.
Дык Bid*1000 =)

А это не всегда так. Есть ДЦ, у кот. маржинальные требования 1000 енотов на 1 лот любой валюты.

Разработчикам: подумать бы над созданием функции, отвечающей по маржинальным требовниям. В особенности это важно для кросс-курсов.

 
komposter писал (а):
Во-вторых, сразу после этого надо добавить:

   double raznica = MathMod( Lots, MarketInfo(Symbol(),MODE_LOTSTEP) );
   if ( raznica > 0.0 ) Lots -= raznica;


Должно работать ;)


ps: настоятельно рекомендую все выражения и переменные нормализовывать перед сравнением. Речь идёт о размере лота - ошибка может быть достаточно обидной...


Мне кажеться это не то что нужно, ведь шаг лота может быть и не 1, а 10 или больше.
 
Нужно как-то округлять до шага лота.
 

Есть такая функция:

double MathRound(double value)
Функция возвращает значение, округленное до ближайшего целого числа указанного числового значения.

Можно ли её использовать для округления не до ближайщего целого числа, а с точностью до шага лота?

 
ExpertTrader:
Мне кажеться это не то что нужно, ведь шаг лота может быть и не 1, а 10 или больше.
А проверить? Возьми сделай скрипт:
   Lots = 24.0;
   double raznica = MathMod( Lots, 10.0 );
   if ( raznica > 0.0 ) Lots -= raznica;
   Print( Lots );
Нельзя быть таким ленивым ;)
 

Ё! Работает! Спасибо!

 

Вот конечный результат:

//+------------------------------------------------------------------+
//| Расчет оптимального размера лота                                 |
//+------------------------------------------------------------------+
double LotsOptimized()
  {
//----
   double Lots=NormalizeDouble(AccountBalance()*RiskMax/(100000.0*Ask),1);
   if(AccountFreeMargin()<(1000*Ask*Lots))
     {
      Lots=NormalizeDouble(AccountFreeMargin()*RiskMax/(100000.0*Ask),1);
     }
   if(Lots>LotsMax)
     {
      Lots=LotsMax;
      Print("Превышен максимальный размер лота. Размер лота изменен на ",LotsMax);
     }
   
   int orders=HistoryTotal();
   int losses=0;
   
   if(DecreaseFactor>0)
     {
      for(int i=orders-1;i>=0;i--)
        {
         if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY)==false)
           {
            Print("Ошибка в истории!");
            break;
           }
         if(OrderSymbol()!=Symbol() || OrderMagicNumber()!=MAGIC || OrderType()>OP_SELL)continue;
         if(OrderProfit()>0) break;
         if(OrderProfit()<0) losses++;
        }
         if(losses>1)
           {
            Lots=NormalizeDouble(Lots/(DecreaseFactor*(losses+1)),1);
           }
       }
     if(Lots<MarketInfo(Symbol(),MODE_MINLOT))
       {
        Lots=MarketInfo(Symbol(),MODE_MINLOT);
       }
     double raznica = MathMod(Lots,MarketInfo(Symbol(),MODE_LOTSTEP));
     if(raznica>0.0)
       {
        Lots -= raznica;
       }
//----
   return(Lots);
  }
 
komposter, а может стоит истользовать не Ask, а MarketInfo(Symbol(),MODE_ASK)?
 

И как быть например с йеной? Ask будет больше 100, значит размер лота будет в сто раз меньше :-(

 
ExpertTrader:
komposter, а может стоит истользовать не Ask, а MarketInfo(Symbol(),MODE_ASK)?
А разница? Если используется текущий инструмент, то Ask == MarketInfo(Symbol(), MODE_ASK) ;)

И как быть например с йеной? Ask будет больше 100, значит размер лота будет в сто раз меньше :-(
Надо умножать не на 1000, а на 10 в степени (Digits-1)
Если я ничего не перепутал =)

Для евры - 10 в степени (4-1) = 10*10*10 = 1000
Для йены - 10 в степени (2-1) = 10 = 10

Правильно?
Причина обращения: