Расчет величины лота в зависимости от размера СЛ

Программирование прибыли: от азов к секретам мастерства. Читайте, спрашивайте, делитесь опытом.
Бонус за сообщение 0.5$
Ответственный Модератор - Haos

Расчет величины лота в зависимости от размера СЛ

Сообщение Haos » 04 июл 2015, 08:52

По этому вопросу "велосипед изобретать" не приходится, так как вопрос весьма распространенный для разработчиков ПО для Метатрейдера и есть уже решения. Сам я решал этот вопрос несколько иначе, но возможно здесь приведено более эффективное решение. Надо ознакомиться. :-):
Столкнулся с проблемой и вот уже третий день бьюсь и решить не могу. В готовом советнике решил вместо лота ввести % риска, поэтому нужен расчёт лота к стопу, например при депо 10 000 риск 1% при стопе 100 пп это будет примерно лот 0.1 а вот при стопе 200 лот уже лот должен быть 0.05, для того чтобы риск 1% остался на том же уровне. Надеюсь всё понятно изложил.

Для расчета лота в зависимости от стоплосса мы должны знать стоимость 1 пункта.

Расчет стоимости пункта


Все валютые пары можно условно разделить на три категории — пары с обратной котировкой (EURUSD, GBPUSD), пары с прямой котировкой (USDJPY, USDCHF) и кросс-курсы (GBPCHF, EURJPY и т.п.).

1. Для валютных пар с обратной котировкой стоимость пункта, выраженная в долларах, рассчитывается по формуле
PIP = LOT_SIZE * TICK_SIZE,
где LOT_SIZE — размер лота, TICK_SIZE — размер тика.

Для валютных пар с обратной котировкой стоимость пункта постоянна и не зависит от текущей котировки.

Пример:
Для EURUSD размер лота 100,000 евро, размер тика — 0.0001
PIP = 100,000 * 0.0001 = $10.00

2. Для валютных пар с прямой котировкой стоимость пункта, выраженная в долларах, рассчитывается по формуле
PIP = LOT_SIZE * TICK_SIZE / CURRENT_QUOTE,
где LOT_SIZE — размер лота, TICK_SIZE — размер тика, CURRENT_QUOTE — текущая котировка пары.

Для валютных пар с прямой котировкой стоимость пункта меняется в зависимости от текущей котировки.

Пример:
Для USDJPY размер лота 100,000 долларов, размер тика — 0.01. При котировке USDJPY 114.66
PIP = 100,000 * 0.01 / 114.66 = $8.72

3. Для кросс-курсов стоимость пункта, выраженная в долларах, рассчитывается по формуле
PIP = LOT_SIZE * TICK_SIZE * BASE_QUOTE / CURRENT_QUOTE,
где LOT_SIZE — размер лота, TICK_SIZE — размер тика, BASE_QUOTE — текущая котировка базовой (первой) валюты к доллару США, CURRENT_QUOTE — текущая котировка пары.

Для кросс-курсов стоимость пункта меняется в зависимости от текущих котировок как самой пары, так и базовой валюты.

Пример:
Для GBPJPY размер лота 100,000 фунтов, размер тика — 0.01, базовая валюта — GBPUSD. При котировке GBPJPY 230.82 и котировке GBPUSD 2.0107
PIP = 100,000 * 0.01 * 2.0107 / 230.82 = $8.71

Разработчики MetaTrader позаботились об этом и предоставили нам функцию: MarketInfo(Symbol(),MODE_TICKVALUE) — стоимость 1 пункта в валюте депозита для 1 лота. Напишем скрипт для расчета лота:


Код: выделить все
//±-----------------------------------------------------------------+
//| Расчет лота в зависимости от размера стоплосса |
//| Copyright © 2010. |
//| http://mql4you.ru |
//±-----------------------------------------------------------------+
#property copyright "Copyright © 2010."
#property link "http://mql4you.ru"
#property show_inputs
extern int MaxRisk = 2;
extern int StopLoss = 100;
//±-----------------------------------------------------------------+
int start()
{
double Free = AccountFreeMargin();
double LotVal = MarketInfo(Symbol(), MODE_TICKVALUE); //стоимость 1 пункта для 1 лота
double Min_Lot = MarketInfo(Symbol(), MODE_MINLOT);
double Max_Lot = MarketInfo(Symbol(), MODE_MAXLOT);
double Step = MarketInfo(Symbol(), MODE_LOTSTEP);
double Lot = MathFloor((Free * MaxRisk / 100) / (StopLoss * LotVal) / Step) * Step;
if(Lot < Min_Lot) Lot = Min_Lot;
if(Lot > Max_Lot) Lot = Max_Lot;
Alert(Lot);
return(0);
}
Аватар пользователя
Haos
Специалист MQL
 
Сообщений: 24699
Зарегистрирован: 29 мар 2014, 16:07
Средств на руках: 193.70 Доллар
Группа: Главные модераторы
Благодарил (а): 3379 раз.
Поблагодарили: 8200 раз.

Расчет величины лота в зависимости от размера СЛ

Сообщение Haos » 04 июл 2015, 12:57

Не понятно зачем в коде сначала делить на Step, а потом умножать на Step - если это ничего не меняет? Опять же нет учета спреда... в общем "упушение". Если найденный лот меньше меньшего, то нельзя торговать меньшим, так как это нарушение риска! Подразачаровал... :ni_zia: :hi_hi_hi:
Аватар пользователя
Haos
Специалист MQL
 
Сообщений: 24699
Зарегистрирован: 29 мар 2014, 16:07
Средств на руках: 193.70 Доллар
Группа: Главные модераторы
Благодарил (а): 3379 раз.
Поблагодарили: 8200 раз.

Расчет величины лота в зависимости от размера СЛ

Сообщение Kalkin » 06 июл 2015, 07:46

Haos писал(а):Не понятно зачем в коде сначала делить на Step, а потом умножать на Step - если это ничего не меняет?
Человек всё правильно сделал - это изящный способ нормализации лота, так как деление выполняется внутри функции MathFloor(), а последующее умножение - вне её.
Аватар пользователя
Kalkin
 
Сообщений: 1589
Зарегистрирован: 05 мар 2015, 06:51
Средств на руках: 108.80 Доллар
Награды: 2
Ветеран I (1) Медаль за научный вклад (1)
Группа: Базовая
Благодарил (а): 633 раз.
Поблагодарили: 1190 раз.
Ace Register Votive

Расчет величины лота в зависимости от размера СЛ

Сообщение mfcoder » 06 июл 2015, 08:36

Kalkin писал(а):
Haos писал(а):Не понятно зачем в коде сначала делить на Step, а потом умножать на Step - если это ничего не меняет?
Человек всё правильно сделал - это изящный способ нормализации лота, так как деление выполняется внутри функции MathFloor(), а последующее умножение - вне её.


это частный случай.. я всегда явно нормализую лот к числу знаков после зяпятой, которое получаю так
Код: выделить все
int getLotDigits()
  {
   int digits=0;
   double l=MarketInfo(Symbol(),MODE_LOTSTEP);
   if(l!=0)
     {
      while(l<1)
        {
         l*=10.0; digits++;
        }
     }
   return(digits);
  }
Аватар пользователя
mfcoder
 
Сообщений: 1531
Зарегистрирован: 29 июл 2013, 11:55
Средств на руках: 26.85 Доллар
Группа: Базовая
Благодарил (а): 78 раз.
Поблагодарили: 423 раз.

Расчет величины лота в зависимости от размера СЛ

Сообщение Haos » 06 июл 2015, 10:22

Kalkin писал(а):
Haos писал(а):Не понятно зачем в коде сначала делить на Step, а потом умножать на Step - если это ничего не меняет?
Человек всё правильно сделал - это изящный способ нормализации лота, так как деление выполняется внутри функции MathFloor(), а последующее умножение - вне её.

И что? Подставь цифры и посмотри какая нелепость получается. :hi_hi_hi:
Аватар пользователя
Haos
Специалист MQL
 
Сообщений: 24699
Зарегистрирован: 29 мар 2014, 16:07
Средств на руках: 193.70 Доллар
Группа: Главные модераторы
Благодарил (а): 3379 раз.
Поблагодарили: 8200 раз.

Расчет величины лота в зависимости от размера СЛ

Сообщение Kalkin » 06 июл 2015, 11:16

Haos писал(а):
Kalkin писал(а):
Haos писал(а):Не понятно зачем в коде сначала делить на Step, а потом умножать на Step - если это ничего не меняет?
Человек всё правильно сделал - это изящный способ нормализации лота, так как деление выполняется внутри функции MathFloor(), а последующее умножение - вне её.

И что? Подставь цифры и посмотри какая нелепость получается. :hi_hi_hi:

Делать мне больше нечего... кому надо - тот пусть и подставляет :-):

Могу высказать свою точку зрения по вопросу в целом.
Всё просто - есть система мани-менеджмента (ММ) и есть система риск-менеджмента (РМ). Маленький пример.
Система ММ предназначена для выделения средств на торговлю
Код: выделить все
double minLots               = 0.1;            // допустимый минимальный лот
double maxLots               = 20;             // допустимый максимальный лот
double VolumeMarginPer       = 20;             // допустимый процент занятой маржи на все позиции
int    LotDigits             = 1;
double BALANCE_STEP          = 500;   


Система РМ ограничивает выделенные средства в зависимости от риска
Код: выделить все
double RiskOnStopLossPer     = 3;           // допустимый процент риска при срабатывании стоп-лосса 0-без снижения риска


Дальше советник определяет точку входа и уровень стоп-лосса. А функция расчета лота при этом может принять хотя бы такой вид:
Код: выделить все
double LotsOptimized(double OpenPrice, double StopLoss)
  {
   string _symbol = Symbol();
   double _minLots, _maxLots;
   _minLots = MathMax(minLots, MarketInfo(_symbol,MODE_MINLOT));
   _maxLots = MathMin(maxLots, MarketInfo(_symbol,MODE_MAXLOT));
   _maxLots = MathMin(_maxLots, NormalizeDouble(AccountBalance()/BALANCE_STEP*_minLots, LotDigits));
   
   double lot=_minLots;
   lot = NormalizeDouble((AccountFreeMargin()*AccountLeverage()*VolumeMarginPer/100/MarketInfo(_symbol,MODE_LOTSIZE)), LotDigits);

   if (RiskOnStopLossPer>0) //------------------ Учёт риска по стопу
   {
      double Koeff = 1;
      double Loss = 0.0;
      if (StopLoss>0.0 && StopLoss<OpenPrice)
      {
         // buy Order
         Loss = (OpenPrice-StopLoss)*MarketInfo(_symbol,MODE_TICKVALUE)/MarketInfo(_symbol,MODE_POINT)*lot;
      }
      else if (StopLoss>OpenPrice)
      {
         // sell Order
         Loss = (StopLoss-OpenPrice)*MarketInfo(_symbol,MODE_TICKVALUE)/MarketInfo(_symbol,MODE_POINT)*lot;
      }
      if ((Loss/AccountEquity())>(RiskOnStopLossPer/100))
      {
         // корректируем величину лота
         Koeff = (RiskOnStopLossPer/100)/(Loss/AccountEquity());
      }
      if (StopLoss==0.0) Koeff = 1;
      lot *= Koeff;
      lot = NormalizeDouble(lot,LotDigits);
   }

//---- return lot size
   if(lot<_minLots) lot=0.0;
   if(lot>_maxLots) lot=_maxLots;
 
   return(lot);
  }


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

Для мультивалютных советников система манименеджмента немного сложнее, но учет рисков для каждой позиции не меняется.
Аватар пользователя
Kalkin
 
Сообщений: 1589
Зарегистрирован: 05 мар 2015, 06:51
Средств на руках: 108.80 Доллар
Награды: 2
Ветеран I (1) Медаль за научный вклад (1)
Группа: Базовая
Благодарил (а): 633 раз.
Поблагодарили: 1190 раз.
Ace Register Votive

Расчет величины лота в зависимости от размера СЛ

Сообщение mfcoder » 06 июл 2015, 19:35

вот поясните, почему у меня при 49923.29 $ при плече 1000 на пятизнаке со стопом 1000 пунктов, при тех настройках что выше (20% риска) и при этом больше ничего не открыто лот всего 1.5 на EURUSD ?

а теперь посчитайте по вашей формуле для 100$ лот и получите дырку от бублика, а денег-то достаточно для торговли ?!

параметры счета
2015-07-06_224304.jpg
Аватар пользователя
mfcoder
 
Сообщений: 1531
Зарегистрирован: 29 июл 2013, 11:55
Средств на руках: 26.85 Доллар
Группа: Базовая
Благодарил (а): 78 раз.
Поблагодарили: 423 раз.

Расчет величины лота в зависимости от размера СЛ

Сообщение Kalkin » 06 июл 2015, 20:32

По всей видимости потому, что в настройках выше 3% риска, а не 20%. Система ММ готова отдать 20% маржи, но система РМ, посчитав риск 3% со стопом в 1000 5-тизначных пунктов, позволила открыть только 1.5 лота при балансе в полтинник косарей. А при 100 баксах даже минимальный лот не даст 3% риска при таком стопе. Потому - "дырка от бублика". Либо увеличивай риски, либо уменьшай стоп.
Аватар пользователя
Kalkin
 
Сообщений: 1589
Зарегистрирован: 05 мар 2015, 06:51
Средств на руках: 108.80 Доллар
Награды: 2
Ветеран I (1) Медаль за научный вклад (1)
Группа: Базовая
Благодарил (а): 633 раз.
Поблагодарили: 1190 раз.
Ace Register Votive

Расчет величины лота в зависимости от размера СЛ

Сообщение mfcoder » 06 июл 2015, 21:24

Kalkin писал(а):По всей видимости потому, что в настройках выше 3% риска, а не 20%. Система ММ готова отдать 20% маржи, но система РМ, посчитав риск 3% со стопом в 1000 5-тизначных пунктов, позволила открыть только 1.5 лота при балансе в полтинник косарей. А при 100 баксах даже минимальный лот не даст 3% риска при таком стопе. Потому - "дырка от бублика". Либо увеличивай риски, либо уменьшай стоп.


прикольно, сам придумал или кто подсказал..


простая рихметика говорит, что стоимость одного пункта EURUSD составляет 1$ при лоте 1, отсюда 1000 пунктов стопа это 1000 $ при лоте 1 и 10$ при минлоте 0.01,
далее при 20% риска имеем от 100$ всего 20$ и получается по твоей правильной логике, что 20$ недостаточно, чтобы открыть ордер лотом 0.01 со стопом 1000, который может дать минуc в 10$, получается логичка расчета некорректна, потому что она упирается в какие-то 3% риска вместо 20%, зачем эти 3% несовсем понятно, зачем вводить какой-то второй процен, который только путает и вносит непонимание..
Аватар пользователя
mfcoder
 
Сообщений: 1531
Зарегистрирован: 29 июл 2013, 11:55
Средств на руках: 26.85 Доллар
Группа: Базовая
Благодарил (а): 78 раз.
Поблагодарили: 423 раз.

Расчет величины лота в зависимости от размера СЛ

Сообщение Kalkin » 07 июл 2015, 04:01

Придумал сам, но вдохновили труды Райана Джонса и Курта Вирта :-):

Тут ведь какая интересная штука получается: когда стоп "далекий" - работает система РМ, ограничивая риски при срабатывании стопа. А когда стоп очень близкий - уже система ММ не дает установить заоблачный лот.
Аватар пользователя
Kalkin
 
Сообщений: 1589
Зарегистрирован: 05 мар 2015, 06:51
Средств на руках: 108.80 Доллар
Награды: 2
Ветеран I (1) Медаль за научный вклад (1)
Группа: Базовая
Благодарил (а): 633 раз.
Поблагодарили: 1190 раз.
Ace Register Votive


Вернуться в MQL – теория и практика

Кто сейчас на форуме?

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 86

Права доступа к форуму

Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

cron