Как рассчитать размер участка?

 

Допустим, мой мини-счет имеет маржу в $10 000, и я хочу рискнуть 2% на следующей сделке (то есть просто использовать $200 для покупки <некоторого количества> контрактов).

(Я понимаю, что это ограниченный взгляд на "риск". Меня не интересуют стоп-лосс пипсы, цели прибыли и т.д.].

Используя MetaTrader, я получаю от своего брокера следующую информацию о мини-счете:

accountLeverage = AccountLeverage(); // значение = 200
modeLotSize = MarketInfo("EURUSDm", MODE_LOTSIZE); // значение = 10000
modeLotStep = MarketInfo("EURUSDm", MODE_LOTSTEP); // значение = .01
modeMinLot = MarketInfo("EURUSDm", MODE_MINLOT) ); // значение = .01

ВОПРОС: Как мне рассчитать размер лота для $200? (Было бы полезно знать стоимость лота минимального размера. В данном случае минимальный размер лота составляет .01).

ВОПРОС: Одинакова ли формула расчета размера лота для всех валютных пар?

Заранее большое спасибо.

 

Проблема не до конца определена. Если вы говорите, что хотите рисковать 2%, то вам нужно исправить одну из переменных: уровень стоп-лосса или объем сделки. Поскольку вы спрашиваете о расчете размера лота, это означает, что вы не хотите фиксировать его, но это требует, чтобы вы заинтересовались пунктами стоп-лосса, хотя вы говорите, что это не так. Если у вас нет стоп-лосса, то рисковать 2% означает взять фиксированный размер лота, например, 1.0, и ждать, пока ваши текущие потери не достигнут 2% от начальной маржи. Здесь, как вы видите, не нужно рассчитывать размер лота.


Как только в поле зрения попадает уровень стоп-лосса, расчет становится простым:


double tradeVolume = AccountFreeMargin() * Risk/100 / ( StopLossPoints * MarketInfo( Symbol(), MODE_TICKVALUE ) );


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


Вы также захотите нормализовать полученное значение по MODE_LOTSTEP и ограничить его по MODE_MINLOT и MODE_MAXLOT.

 
bstone wrote >>

Проблема не до конца определена. Если вы говорите, что хотите рисковать 2%, то вам нужно зафиксировать одну из переменных: уровень стоп-лосса или объем сделки. Поскольку вы спрашиваете о расчете размера лота, это означает, что вы не хотите его фиксировать, но это требует, чтобы вы заинтересовались пунктами стоп-лосса, хотя вы говорите, что это не так. Если у вас нет стоп-лосса, то рисковать 2% означает взять фиксированный размер лота, например, 1.0, и ждать, пока ваши текущие потери не достигнут 2% от начальной маржи. Здесь, как вы видите, не нужно рассчитывать размер лота.


Как только уровень стоп-лосса попадает в поле зрения, расчет становится простым:

double tradeVolume = AccountFreeMargin() * Risk/100 / ( StopLossPoints * MarketInfo( Symbol(), MODE_TICKVALUE ) );


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

Вы также захотите нормализовать полученное значение по MODE_LOTSTEP и ограничить его по MODE_MINLOT и MODE_MAXLOT.

Это дает ответ 6,66 на мини-счете. Кажется ли это правильным?

двойной риск3 = 2.0;
stopLossPips = 30;
double orderLotSize3 = AccountFreeMargin() * risk3/100 / ( stopLossPips * MarketInfo( Symbol(), MODE_TICKVALUE ) );
orderLotSize3 = orderLotSize3 - MathMod( orderLotSize3, 2*MarketInfo( Symbol(), MODE_LOTSTEP ) );
orderLotSize3 = NormalizeDouble(orderLotSize3, 2);

 

Только если MODE_TICKVALUE равен 1.0, что выглядит странно (но зависит от свойств мини-счета). Что такое MODE_TICKVALUE для данного инструмента и вашего мини-счета? Для EURUSD, стандартного счета и кредитного плеча 1:100 это $10, что дает торговый объем 0,66 лота при риске 2% и стопе 30 пп.

 
Hello.

int    init ()
{

double ad.Volume                                                                                                ;

string as.Symbol            = "EURUSD"                                                                          ;

double ad.LotStep           = MarketInfo ( as.Symbol , MODE_LOTSTEP        )                                    ;
double ad.MinimalVolume     = MarketInfo ( as.Symbol , MODE_MINLOT         )                                    ;
double ad.NominalLot        = MarketInfo ( as.Symbol , MODE_LOTSIZE        )                                    ;
double ad.NominalMargin     = MarketInfo ( as.Symbol , MODE_MARGINREQUIRED )                                    ;
double ad.QuoteAsk          = MarketInfo ( as.Symbol , MODE_ASK            )                                    ;
double ad.QuoteBid          = MarketInfo ( as.Symbol , MODE_BID            )                                    ;

double ad.EquityQuant       = 0.01                                                                              ;
double ad.MarginLimit       = AccountEquity () * ad.EquityQuant                                                 ;
double ad.VolumeLimit       = ad.MarginLimit   / ad.NominalMargin                                               ;

if   ( ad.VolumeLimit       < ad.MinimalVolume )
       ad.Volume            = 0                                                                                 ;
else { int ai.Steps         = MathFloor ( ( ad.VolumeLimit - ad.MinimalVolume ) / ad.LotStep )                  ;
       ad.Volume            = ad.MinimalVolume + ad.LotStep * ai.Steps                                          ; }

double ad.Leverage          = AccountLeverage ()                                                                ;
double ad.RealLeverage      = ad.Leverage                                                                       ;

double ad.MarginBuy.1       = ad.QuoteAsk * ad.Volume * ad.NominalLot / ad.RealLeverage                         ;
double ad.MarginSell.1      = ad.QuoteBid * ad.Volume * ad.NominalLot / ad.RealLeverage                         ;

double ad.MarginBuy.2       = AccountFreeMargin () - AccountFreeMarginCheck ( as.Symbol , OP_BUY  , ad.Volume ) ;
double ad.MarginSell.2      = AccountFreeMargin () - AccountFreeMarginCheck ( as.Symbol , OP_SELL , ad.Volume ) ;

Alert ( "ad.MarginSell.2    = " , ad.MarginSell.2    , " " , AccountCurrency ()                               ) ;
Alert ( "ad.MarginBuy.2     = " , ad.MarginBuy.2     , " " , AccountCurrency ()                               ) ;
Alert ( "ad.MarginSell.1    = " , ad.MarginSell.1    , " " , AccountCurrency ()                               ) ;
Alert ( "ad.MarginBuy.1     = " , ad.MarginBuy.1     , " " , AccountCurrency ()                               ) ;
Alert ( "ad.Volume          = " , ad.Volume          , " " , "lots"                                           ) ;
Alert ( "Output :"                                                                                            ) ;
Alert ( " "                                                                                                   ) ;
Alert ( "ai.Steps           = " , ai.Steps                                                                    ) ;
Alert ( "ad.LotStep         = " , ad.LotStep         , " " , "lots"                                           ) ;
Alert ( "ad.MinimalVolume   = " , ad.MinimalVolume   , " " , "lots"                                           ) ;
Alert ( "ad.VolumeLimit     = " , ad.VolumeLimit     , " " , "lots"                                           ) ;
Alert ( "ad.MarginLimit     = " , ad.MarginLimit     , " " , AccountCurrency ()                               ) ;
Alert ( "ad.NominalMargin   = " , ad.NominalMargin   , " " , AccountCurrency ()                               ) ;
Alert ( "ad.RealLeverage    = " , ad.RealLeverage                                                             ) ;
Alert ( "ad.NominalLot      = " , ad.NominalLot      , " " , StringSubstr ( as.Symbol , 0 , 3 )               ) ;
Alert ( "Processing :"                                                                                        ) ;
Alert ( " "                                                                                                   ) ;
Alert ( "ad.EquityQuant     = " , ad.EquityQuant                                                              ) ;
Alert ( "AccountEquity   () = " , AccountEquity   () , " " , AccountCurrency ()                               ) ;
Alert ( "as.Symbol          = " , as.Symbol                                                                   ) ;
Alert ( "Input :"                                                                                             ) ;
Alert ( " "                                                                                                   ) ;
Alert ( "AccountCurrency () = " , AccountCurrency ()                                                          ) ;
}
Best regards,
Ais.
 
Important.
1. Calculation of the "ad.Margin****.1" is correct for "***USD" symbols if USD is account currency.
2. Calculation of the "ad.Margin****.2" is more universal but some symbols may have miscounts.
3. Real leverage and "AccountLeverage ()" may differ.
4. Real leverage calculation formula depends on forex symbol parsing.
Example.
...

//<method 24>
int    air.Ticker.Compute.4

 (//<0>

){//<24>

if      ( avi.Ticker.Conversion      ==   ac.Direct      )
        { avi.Ticker.ConversionDigits =         avi.Ticker.QuoteDigits                                                 ;
          avd.Ticker.ConversionAsk    =         avd.Ticker.QuoteAsk                                                    ;
          avd.Ticker.ConversionBid    =         avd.Ticker.QuoteBid                                                    ;
          avd.Ticker.RealLeverage     =         avd.Ticker.QuoteAsk * avd.Ticker.NominalLot / avd.Ticker.NominalMargin ; }

else if ( avi.Ticker.Conversion      ==   ac.DirectCross )
        { avi.Ticker.ConversionDigits =         MarketInfo ( avs.Ticker.ConversionSymbol    , MODE_DIGITS )            ;
          avd.Ticker.ConversionAsk    =         MarketInfo ( avs.Ticker.ConversionSymbol    , MODE_ASK    )            ;
          avd.Ticker.ConversionBid    =         MarketInfo ( avs.Ticker.ConversionSymbol    , MODE_BID    )            ;
          avd.Ticker.RealLeverage     = ( avd.Ticker.ConversionAsk + avd.Ticker.ConversionBid ) / 2
                                        * avd.Ticker.NominalLot    / avd.Ticker.NominalMargin                          ; }

else if ( avi.Ticker.Conversion      ==   ac.Inverse     )
        { avi.Ticker.ConversionDigits =   8   - avi.Ticker.QuoteDigits                                                 ;
          avd.Ticker.ConversionAsk    =   1.0 / avd.Ticker.QuoteBid                                                    ;
          avd.Ticker.ConversionBid    =   1.0 / avd.Ticker.QuoteAsk                                                    ;
          avd.Ticker.RealLeverage     =                              avd.Ticker.NominalLot  / avd.Ticker.NominalMargin ; }

else    { avi.Ticker.ConversionDigits =   8   - MarketInfo ( avs.Ticker.ConversionSymbol    , MODE_DIGITS )            ;
          avd.Ticker.ConversionAsk    =   1.0 / MarketInfo ( avs.Ticker.ConversionSymbol    , MODE_BID    )            ;
          avd.Ticker.ConversionBid    =   1.0 / MarketInfo ( avs.Ticker.ConversionSymbol    , MODE_ASK    )            ;
          avd.Ticker.RealLeverage     = ( avd.Ticker.ConversionAsk + avd.Ticker.ConversionBid ) / 2
                                        * avd.Ticker.NominalLot    / avd.Ticker.NominalMargin                          ; }

}//</method 24>

... 
Best regards,
Ais.
 
Hello.
Another method of operation volume computing is in https://www.mql5.com/ru/forum/111267.
Best regards,
Ais.
 

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


MarketInfo(Symbol(),MODE_MARGINREQUIRED);


Я обычно использую следующую формулу для расчета лотов:

double OneLotMargin = MarketInfo(Symbol(),MODE_MARGINREQUIRED);
double FreeMargin = AccountFreeMargin();
double lotMM = FreeMargin/OneLotMargin*Risk/100;
double LotStep = MarketInfo(Symbol(),MODE_LOTSTEP);
lotMM = NormalizeDouble(lotMM/LotStep,0)*LotStep;

Однако вы спрашивали о том, как рассчитать количество лотов, которые используют фиксированную сумму маржи, например 200$, в этом случае формула foolowing должна быть изменена на:

double OneLotMargin = MarketInfo(Symbol(),MODE_MARGINREQUIRED);
double MarginAmount = 200; //this means we want to use 200$ for trade
double lotMM = MarginAmount/OneLotMargin;
double LotStep = MarketInfo(Symbol(),MODE_LOTSTEP);
lotMM = NormalizeDouble(lotMM/LotStep,0)*LotStep;

 
Hello.
Note, that "minimal lot" and "lot step" may differ.
For example, "minimal lot" may be 0.10, "lot step" may be 0.01.
In this case, simple calculation methods may produce incorrect operation volume, for example, 0.05.
Best regards,
Ais.
 
Ais wrote >>
Hello.
Another method of operation volume computing is in 'Ищу функцию вычисления размера лота.'.
Best regards,
Ais.

Ais
wrote
>>
Hello.
Note, that "minimal lot" and "lot step" may differ.
For example, "minimal lot" may be 0.10, "lot step" may be 0.01.
In this case, simple calculation methods may produce incorrect operation volume, for example, 0.05.
Best regards,
Ais.

Я использую код, который вы упомянули в 'Ищу функцию вычисления размера лота'. Спасибо.

У МЕНЯ ЕСТЬ ОДИН ВОПРОС ПО ПОВОДУ ЭТОГО КОДА: Всегда ли он выдает четный размер партии (например, 6.66, а не 6.67).

Это хорошо, если так. Я просто не понимаю, почему так происходит.

Прилагаемый код находится в формате файла Script, поэтому вы можете вставить код в новый скрипт и сразу же запустить его.

Файлы:
 
Hello.
Correct code must be able to produce any valid result.
Examples.




Best regards,
Ais.
Причина обращения: