MQL для чайников, программирование на MQL4, MQL5
25 Мар
Столкнулся с проблемой и вот уже третий день бьюсь и решить не могу. В готовом советнике решил вместо лота ввести % риска, поэтому нужен расчёт лота к стопу, например при депо 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);}
//±-----------------------------------------------------------------+
Скачать скрипт: lotstop.mq4
Если Вы хотите изучать язык MQL или вам понравилась данная публикация - Вы можете подписаться на получение новых материалов сайта mql4you.ru по |
17 комментариев на «Вопрос №8 «Как рассчитать размер лота в зависимости от размера стоплосса?»»
Огроменное СПАСИБО.
Здравствуйте Александр!
Оффтоп, но не нашел отдельной формы для того, что бы задать вопрос.
Столкнулся с проблемой, которую никак не могу решить и понять.
Задача:
Есть открытый ордер, допустим на покупку, с выставленным профитом. не достигая его, хочу закрыть половину лота и профит отодвинуть.
if((OrderType() == OP_BUY)&&(OrderTakeProfit() -MarketInfo(OrderSymbol(),MODE_ASK)<=MathPow(10, — (Digits)))
{
CloseOrder(NormalizeDouble(OrderLots()/2,5));
}
Проблема в следующем
При закрытии по профиту мы получаем прибыль — 10 пунктов.
При закрытии по условию, мы получаем прибыль не около 5 пунктов,как я ожидал, а около 2. То есть четверть.
Можете подсказать, что неправильно?
Спасибо большое!!!
Самый нужный скрипт для любого трейдера!
Спасибо за очень толковый сайт! Сами разработчики до такого не додумались!
Хотелось бы внести предложение от новичка в MQL, но не новичка в программировании. Мне всегда проще было начинать обучение с разборки готовых программ, а потом дополнить её например ещё чем-то. Например, разобрать советник работающий по пересечению средних, а потом добавить туда ещё индикатор.
А как учитывается плечё в данном расчете?
Здравствуйте,
Будет ли скрипт работать корректно в случае 5-ти цифр после запятой?
Спасибо!
leobog
Во первых закрывается половина открытого лота. Но это хорошо работает когда лот четный (например 0.4), а вот когда он не четный (например 0.5) будет закрыто меньше половины. Во вторых закрытие происходит на несколько пунктов менеше чем при срабатывании тейкпрофита.
Олег
Конечно будет. Только надо не забывать что параметр StopLoss будет в 10 раз больше чем при 4 значных котировках (например 100 при 4 знаках = 1000 при 5 знаках).
Василий
Здесь плече не имеет значения. При любом плече Вы потеряете (в случае если сработает стоплосс) ровно столько (или чуть меньше) сколько укажите в параметре MaxRisk.
MODE_TICKVALUE — это плавающее значение?
Как можно посмотреть историю его изменения?
У Вас перед скриптом ошибка. Идентификатор MODE_TICKVALUE покажет на какое минимальное число может измениться цена торгового инструмента за 1 тик. (Ведь не все торговые инструменты ходят по одному пункту за 1 тик.) Но это не есть стоимость одного пункта для одного лота в валюте депозита.
А TickValue почему не использовал?
/////////////////////////////////////////////////////////
double perc_lot_by_stop_f(double Stop_points)
{
double lose_on_stop_lose=Stop_points*(MarketInfo(Symbol(),MODE_TICKVALUE)/100);
double propotion=(AccountBalance()/100*Lot_perc_by_stop)/lose_on_stop_lose;
double Loto_=MarketInfo(Symbol(),MODE_MINLOT)*propotion;
if(Loto_>MarketInfo(Symbol(),MODE_MAXLOT)) Loto_=MarketInfo(Symbol(),MODE_MAXLOT);
return(Loto_);
}
Мне кажется, что для 5-зн. котировок надо умножать
MarketInfo(Symbol(),MODE_TICKVALUE) на 10
А лучше: 10*StopLoss
Скопировал рассчет лота, в отоге лот выдает = 10 000
Тут ни деление на Плечо ни еще на 10 если 5-знак не помогает. Ошибка в самой формуле.
Не используйте не глядя люди!
Ну что, присоединюсь к некропостерам, не удержался:
Автор предпочитает shitcoder-style:
if(LotMax_Lot) Lot=Max_Lot;
А можно проще, kiss-style:
Lot=MathMin(MathMax(Lot, Min_Lot), Max_Lot);
Каково? Так-то...