Ваши вопросы по языку MQL4

AlexeyVik

Программист mql4 mql5
Пожалуйста, подскажите, как грамотно рассчитать необходимую маржу для открытия позиции ДО её открытия?

К примеру, я хочу открыть длинную позицию объёмом 1 лот. Я полагал, что рассчитать маржу можно двумя способами:
MQL4:
Expand Collapse Copy
MarketInfo(_Symbol, MODE_MARGINREQUIRED)
AccountFreeMarginCheck(_Symbol, OP_BUY, 1)

Однако на самом деле оказалось, что оба эти способа возвращают неверные значения.

Вот, к примеру, есть такой брокер Альпари. Плечо моего счёта у данного брокера составляет 1:500, валюта счёта - доллары США. Казалось бы, размер залога (маржи) для покупки одного лота можно вычислить, разделив размер контракта (100 тыс. единиц базовой валюты) на плечо. Дело вроде бы нехитрое. Однако на практике этот подход почему-то не работает. Точнее, результат такого вычисления не совпадает с тем, что возвращают вышеупомянутые функции MQL.

У брокера из моего примера есть таблица (_alpari.forex/ru/trading/trading_terms/#margin_requirements), в которой указаны значения максимального кредитного плеча для различных инструментов. Вот небольшая выдержка из неё:

SymbolMax. Leverage
USDCHF1:1000
USDRUB1:100
USDZAR1:25
USDTRY1:3

Я специально выбрал инструменты с базовой валютой USD для лучшего понимания.

Поскольку плечо моего счёта составляет 1:500, логично предположить, что величина залога при покупке одного лота для данных инструментов должна составлять:

SymbolRequired Margin
USDCHF200
USDRUB1000
USDZAR4000
USDTRY33333.33

Для проверки этого предположения я написал простенький скрипт:
MQL4:
Expand Collapse Copy
void OnStart() {
   Print("MarginRequired[USDTRY] = ",MarketInfo("USDTRY",MODE_MARGINREQUIRED));
   Print("MarginRequired[USDZAR] = ",MarketInfo("USDZAR",MODE_MARGINREQUIRED));
   Print("MarginRequired[USDRUB] = ",MarketInfo("USDRUB",MODE_MARGINREQUIRED));
   Print("MarginRequired[USDCHF] = ",MarketInfo("USDCHF",MODE_MARGINREQUIRED));
   Print("----------------------------");
   Print("MarginCheck[USDTRY] = ",AccountFreeMarginCheck("USDTRY",OP_BUY,1));
   Print("MarginCheck[USDZAR] = ",AccountFreeMarginCheck("USDZAR",OP_BUY,1));
   Print("MarginCheck[USDRUB] = ",AccountFreeMarginCheck("USDRUB",OP_BUY,1));
   Print("MarginCheck[USDCHF] = ",AccountFreeMarginCheck("USDCHF",OP_BUY,1));
}

К моему величайшему удивлению, этот скрипт вернул одинаковые значения для всех валютных пар! В частности, маржа для открытия одного лота USDCHF и USDZAR одинакова и равна 200. Хотя на самом деле она должна отличаться в 167 раз!

Внимание, вопрос! Где в моих рассуждениях ошибка и как на самом деле средствами MQL4 можно получить размер залога ДО открытия позиции?
Для начала посмотри спецификации этих инструментов. У меня нет счёта в альпарях и никогда не будет, потому я не могу посмотреть, а вот в робо такие значения процента маржи

00.png

01.png

Но эти значения в окружении не хранятся.
 

Moriarti

Активный участник
Для начала посмотри спецификации этих инструментов. У меня нет счёта в альпарях и никогда не будет, потому я не могу посмотреть, а вот в робо такие значения процента маржи

В моём случае эти значения одинаковые для всех инструментов и равны 100%

USDCHF.png

USDRUB.png
 

AlexeNP

Гуру форума
Пожалуйста, подскажите, как грамотно рассчитать необходимую маржу для открытия позиции ДО её открытия?

К примеру, я хочу открыть длинную позицию объёмом 1 лот. Я полагал, что рассчитать маржу можно двумя способами:
MQL4:
Expand Collapse Copy
MarketInfo(_Symbol, MODE_MARGINREQUIRED)
AccountFreeMarginCheck(_Symbol, OP_BUY, 1)

Однако на самом деле оказалось, что оба эти способа возвращают неверные значения.

Вот, к примеру, есть такой брокер Альпари. Плечо моего счёта у данного брокера составляет 1:500, валюта счёта - доллары США. Казалось бы, размер залога (маржи) для покупки одного лота можно вычислить, разделив размер контракта (100 тыс. единиц базовой валюты) на плечо. Дело вроде бы нехитрое. Однако на практике этот подход почему-то не работает. Точнее, результат такого вычисления не совпадает с тем, что возвращают вышеупомянутые функции MQL.

У брокера из моего примера есть таблица (_alpari.forex/ru/trading/trading_terms/#margin_requirements), в которой указаны значения максимального кредитного плеча для различных инструментов. Вот небольшая выдержка из неё:

SymbolMax. Leverage
USDCHF1:1000
USDRUB1:100
USDZAR1:25
USDTRY1:3

Я специально выбрал инструменты с базовой валютой USD для лучшего понимания.

Поскольку плечо моего счёта составляет 1:500, логично предположить, что величина залога при покупке одного лота для данных инструментов должна составлять:

SymbolRequired Margin
USDCHF200
USDRUB1000
USDZAR4000
USDTRY33333.33

Для проверки этого предположения я написал простенький скрипт:
MQL4:
Expand Collapse Copy
void OnStart() {
   Print("MarginRequired[USDTRY] = ",MarketInfo("USDTRY",MODE_MARGINREQUIRED));
   Print("MarginRequired[USDZAR] = ",MarketInfo("USDZAR",MODE_MARGINREQUIRED));
   Print("MarginRequired[USDRUB] = ",MarketInfo("USDRUB",MODE_MARGINREQUIRED));
   Print("MarginRequired[USDCHF] = ",MarketInfo("USDCHF",MODE_MARGINREQUIRED));
   Print("----------------------------");
   Print("MarginCheck[USDTRY] = ",AccountFreeMarginCheck("USDTRY",OP_BUY,1));
   Print("MarginCheck[USDZAR] = ",AccountFreeMarginCheck("USDZAR",OP_BUY,1));
   Print("MarginCheck[USDRUB] = ",AccountFreeMarginCheck("USDRUB",OP_BUY,1));
   Print("MarginCheck[USDCHF] = ",AccountFreeMarginCheck("USDCHF",OP_BUY,1));
}

К моему величайшему удивлению, этот скрипт вернул одинаковые значения для всех валютных пар! В частности, маржа для открытия одного лота USDCHF и USDZAR одинакова и равна 200. Хотя на самом деле она должна отличаться в 167 раз!

Внимание, вопрос! Где в моих рассуждениях ошибка и как на самом деле средствами MQL4 можно получить размер залога ДО открытия позиции?
эк, барин обмишурился... но, ничего Пёскин сейчас всё объяснит)))
 

Вложения

Moriarti

Активный участник
эк, барин обмишурился... но, ничего Пёскин сейчас всё объяснит)))

@AlexeNP, благодарю за отличный скрипт! Он прекрасно иллюстрирует мой вопрос:

Step01.png

Step02.png

Step03.png

Step04.png

В первом случае маржа, которую рассчитал скрипт, совпала с той, которая была фактически удержана. А во втором случае она оказалась в пять раз меньше.

Почему была удержана именно такая маржа, мне понятно. Чуть выше я приводил ссылку на торговые условия, где указано максимальное плечо для первого инструмента 1:1000, а для второго - 1:100. Плечо моего счёта составляет 1:500, поэтому в первом случае за лот 0.10 был удержан залог 20 USD (что соответствует плечу 1:500), а во втором - 100 USD (плечо 1:100).

Мой вопрос состоит в том, как правильно средствами MQL4 определить необходимую маржу ДО открытия позиции.
 
Последнее редактирование:

AlexeNP

Гуру форума
@AlexeNP, благодарю за отличный скрипт! Он прекрасно иллюстрирует мой вопрос:

Посмотреть вложение 402153

Посмотреть вложение 402154

Посмотреть вложение 402155

Посмотреть вложение 402156

В первом случае маржа, которую рассчитал скрипт, совпала с той, которая была фактически удержана. А во втором случае она оказалась в пять раз меньше.

Почему была удержана именно такая маржа, мне понятно. Чуть выше я приводил ссылку на торговые условия, где указано максимальное плечо для первого инструмента 1:1000, а для второго - 1:100. Плечо моего счёта составляет 1:500, поэтому в первом случае за лот 0.10 был удержан залог 20 USD (что соответствует плечу 1:500), а во втором - 100 USD (плечо 1:100).

Мой вопрос состоит в том, как правильно средствами MQL4 определить необходимую маржу ДО открытия позиции.
ну, так посмотри
 

Вложения

Moriarti

Активный участник
ну, так посмотри

Благодарю за ещё один полезный скрипт! Я посмотрел, но, к сожалению, ясности не прибавилось. Более того, я запутался ещё больше. Вот как я действовал.

1. Открываем график USDCHF, бросаем на него скрипт:

Step05.png

Скрипт вычисляет необходимую маржу для покупки 0.1 лота USDCHF, которая равна 20 USD. Открываем позицию:

Step06.png

Видим, что маржа действительно равна 20 USD. Отлично, скрипт работает! Ровно так, как и ожидалось. Закрываем позицию.

2. Открываем график USDRUB (с той же базовой валютой), бросаем на него скрипт:

Step07.png

Видим, что необходимая маржа снова равна 20 USD (несмотря на то, что плечо по данному инструменту в пять раз ниже). Тщательно рассчитав принимаемый риск, открываем соответствующую позицию:

Step08.png

И что мы видим? Вместо рассчитанной скриптом маржи 20 USD с нас удержано в пять раз больше - 100 USD. Теперь мы в пять раз ближе к стоп-ауту, чем можно было предположить, исходя из рассчитанной заранее величины!

В скрипте есть ещё вот такие формулы:

MQL4:
Expand Collapse Copy
percent_buy=100*leverage*marga_buy/(size*ask),
percent_sell=100*leverage*marga_sell/(size*bid),
margin_buy=lot*size*ask/leverage,
margin_sell=lot*size*bid/leverage;

Я не очень понимаю смысл первых двух, а вот вторую и третью я тоже использовал! Если я ничего не путаю, они применяются в том случае, если базовая валюта (в которой вычисляется залоговые средства) не совпадает с валютой депозита. Но в приведённых мной примерах (в том числе в самом первом) эти валюты совпадают. Таким образом, для этого частного случая (которому сосуществуют все приводимые мной примеры) множители ask и bid нужно исключить (IMHO). Если я ошибаюсь, пожалуйста, поправьте меня.

В любом случае, ни одна из рассчитанных скриптом величин в случае с парой USDRUB (а также USDZAR и USDTRY) не соответствует сумме маржи, которая фактически удерживается при открытии позиции.

Собственно, что я хочу понять...

Как же при помощи MQL4 рассчитать маржу ДО открытия позиции таким образом, чтобы рассчитанная нами маржа соответствовала той, которая будет удержана в действительности?
 

AlexeNP

Гуру форума
Благодарю за ещё один полезный скрипт! Я посмотрел, но, к сожалению, ясности не прибавилось. Более того, я запутался ещё больше. Вот как я действовал.

1. Открываем график USDCHF, бросаем на него скрипт:

Посмотреть вложение 402189

Скрипт вычисляет необходимую маржу для покупки 0.1 лота USDCHF, которая равна 20 USD. Открываем позицию:

Посмотреть вложение 402190

Видим, что маржа действительно равна 20 USD. Отлично, скрипт работает! Ровно так, как и ожидалось. Закрываем позицию.

2. Открываем график USDRUB (с той же базовой валютой), бросаем на него скрипт:

Посмотреть вложение 402191

Видим, что необходимая маржа снова равна 20 USD (несмотря на то, что плечо по данному инструменту в пять раз ниже). Тщательно рассчитав принимаемый риск, открываем соответствующую позицию:

Посмотреть вложение 402192

И что мы видим? Вместо рассчитанной скриптом маржи 20 USD с нас удержано в пять раз больше - 100 USD. Теперь мы в пять раз ближе к стоп-ауту, чем можно было предположить, исходя из рассчитанной заранее величины!

В скрипте есть ещё вот такие формулы:

MQL4:
Expand Collapse Copy
percent_buy=100*leverage*marga_buy/(size*ask),
percent_sell=100*leverage*marga_sell/(size*bid),
margin_buy=lot*size*ask/leverage,
margin_sell=lot*size*bid/leverage;

Я не очень понимаю смысл первых двух, а вот вторую и третью я тоже использовал! Если я ничего не путаю, они применяются в том случае, если базовая валюта (в которой вычисляется залоговые средства) не совпадает с валютой депозита. Но в приведённых мной примерах (в том числе в самом первом) эти валюты совпадают. Таким образом, для этого частного случая (которому сосуществуют все приводимые мной примеры) множители ask и bid нужно исключить (IMHO). Если я ошибаюсь, пожалуйста, поправьте меня.

В любом случае, ни одна из рассчитанных скриптом величин в случае с парой USDRUB (а также USDZAR и USDTRY) не соответствует сумме маржи, которая фактически удерживается при открытии позиции.

Собственно, что я хочу понять...

Как же при помощи MQL4 рассчитать маржу ДО открытия позиции таким образом, чтобы рассчитанная нами маржа соответствовала той, которая будет удержана в действительности?
"Сдаётся мне, джентльмены, это была комедия..."
вот что я тут подумал - а точно, что по разным символам используется один и тот же способ расчета маржи?
проверь по символам вот такое SymbolInfoInteger(NULL,SYMBOL_TRADE_CALC_MODE)
если не равно 0, то вот такая будет маржа
 

Вложения

  • Calc_moce.jpg
    Calc_moce.jpg
    236,3 КБ · Просмотры: 16

Moriarti

Активный участник
проверь по символам вот такое SymbolInfoInteger(NULL,SYMBOL_TRADE_CALC_MODE)

Проверил. Для всех символов возвращается 0. Как я понимаю, это соответствует константе SYMBOL_CALC_MODE_FOREX. Это косвенно подтверждается скриншотами из вот этого поста.
 

AlexeNP

Гуру форума
Проверил. Для всех символов возвращается 0. Как я понимаю, это соответствует константе SYMBOL_CALC_MODE_FOREX. Это косвенно подтверждается скриншотами из вот этого поста.
все верно... так, надо подумать чего мы еще не учли
 

Akvisto

Активный участник
Guten Tag,

Wie kann ich eine Lizenz auf Ihre Anzeige auf MQ4 Zeit es zu benutzen? Kann jemand mir bitte helfen? Vielen Dank! Ein herzliches Hallo aus Deutschland
 

Lamulata

Прохожий
Добрый день! Помогите пожалуйста с кодом закрытия. Сейчас советник работает на H1, но я хочу добавить условия для открытия сделок по M15. С условиями открытия мне все понятно, но вот если советник открыл сделку по М15 то и закрыть он ее будет должен при создании условий выхода на этом таймфрейме а не на H1. Никак не могу понять как написать код выхода, вернее как сказать что если вход был по M15 то условия выхода такие а если по H1 то такие. Буду благодарен за помощь
 

AlexeNP

Гуру форума
Добрый день! Помогите пожалуйста с кодом закрытия. Сейчас советник работает на H1, но я хочу добавить условия для открытия сделок по M15. С условиями открытия мне все понятно, но вот если советник открыл сделку по М15 то и закрыть он ее будет должен при создании условий выхода на этом таймфрейме а не на H1. Никак не могу понять как написать код выхода, вернее как сказать что если вход был по M15 то условия выхода такие а если по H1 то такие. Буду благодарен за помощь
сделай раздельные побаровые режимы для M15 и H1
 

Genry_05

Отдыхает
Guten Tag,

Wie kann ich eine Lizenz auf Ihre Anzeige auf MQ4 Zeit es zu benutzen? Kann jemand mir bitte helfen? Vielen Dank! Ein herzliches Hallo aus Deutschland
Ваш вопрос сложно понять: вам нужна подписка на эту тему чтобы вовремя читать эти сообщения?
или вы желаете получить mq4 код программы ex4 ?
Ihre Frage ist schwer zu verstehen: Benötigen Sie ein Abonnement für dieses Thema, um diese Nachrichten rechtzeitig lesen zu können?
oder möchten Sie den mq4-Code des ex4-Programms erhalten?
 

mobidik

-----
Добрый день! Помогите пожалуйста с кодом закрытия. Сейчас советник работает на H1, но я хочу добавить условия для открытия сделок по M15. С условиями открытия мне все понятно, но вот если советник открыл сделку по М15 то и закрыть он ее будет должен при создании условий выхода на этом таймфрейме а не на H1. Никак не могу понять как написать код выхода, вернее как сказать что если вход был по M15 то условия выхода такие а если по H1 то такие. Буду благодарен за помощь
Вам нужно пометить позиции, советник должен различать: где позиция по М15, а где позиция по Н1. Есть два варианта: по комментарию к ордеру и по меджику. Проще и надежнее по меджику, комент брокер может изменить. Задаете начальный меджик, например, 10000, затем прибавляете к нему значение ТФ на котором будет установлена позиция, т.е., позиция по М15 будет иметь меджик - 10015, а по Н1 - 10060 и т.д. Теперь следует узнать с какими меджиками есть позиции в рынке, сколько их, при этом раздельно посчитать на бай/селл. Зная какие есть позиции в рынке + выполнение условия по закрытию на выбранном ТФ - производим закрытие нужных.
 

Lamulata

Прохожий
Вам нужно пометить позиции, советник должен различать: где позиция по М15, а где позиция по Н1. Есть два варианта: по комментарию к ордеру и по меджику. Проще и надежнее по меджику, комент брокер может изменить. Задаете начальный меджик, например, 10000, затем прибавляете к нему значение ТФ на котором будет установлена позиция, т.е., позиция по М15 будет иметь меджик - 10015, а по Н1 - 10060 и т.д. Теперь следует узнать с какими меджиками есть позиции в рынке, сколько их, при этом раздельно посчитать на бай/селл. Зная какие есть позиции в рынке + выполнение условия по закрытию на выбранном ТФ - производим закрытие нужных.
Спасибо огромное
 

Lamulata

Прохожий
Добрый день! Очень нужен совет по нижеуказанной функции на покупку. Я в ней дважды прописал ограничение на открытие сделок

if((TradesCountOnAllCharts() > Trading_EA_Restriction) || (spread > MaxSpread) || (IsThereOpenTrade(Symbol(), MagicNumber)) || (OrdersTotal()>=Trading_EA_Restriction))

Но он все равно открывает на одну больше или когда одна из сделок закрывается либо по тэйк профиту или иначе, может открыть еще несколько. А я также и в условие вставил что если OrdersTotal()>=Trading_EA_Restriction то новую сделку не открывать. Что можно сделать?

void buy()
{
if((OneBar && Time[0] != LastTradeBarTime) || !OneBar)
{
//Check restriction before open trade
if((TradesCountOnAllCharts() > Trading_EA_Restriction) || (spread > MaxSpread) || (IsThereOpenTrade(Symbol(), MagicNumber)) || (OrdersTotal()>=Trading_EA_Restriction))
{
if(LastRestictionTime != Time[0])
{
Print("Buy Restricted! " + ChartSymbol() + " " + (string)ChartPeriod() + " Trades: " + (string)TradesCountOnAllCharts() + " Spread: " + (string)spread);
LastRestictionTime = Time[0];
}
}
else// if allowed - open
{
if(WorkMode == Alerts)
{
DrawArrow("Buy_" + IntegerToString(Time[0]), 108, Low[0], Time[0], clrGreen, ANCHOR_TOP, 2);
LastTradeBarTime = Time[0];
VirtualBuys++;
VirtualBuyPrice = Ask;
inBuy = true;
}
else
if(TradesCountOnAllCharts() < Trading_EA_Restriction && !IsThereOpenTrade(Symbol(), MagicNumber) && OrdersTotal()< Trading_EA_Restriction)
{
double lot = GetVolume(StopLoss);
double TheStopLoss = 0;
double TheTakeProfit = 0;
if(TakeProfit > 0)
TheTakeProfit = Ask + TakeProfit * MyPoint;
if(StopLoss > 0)
TheStopLoss = Ask - StopLoss * MyPoint;
LastNotRecoveryTicket = OrderSend(_Symbol, OP_BUY, lot, Ask, Slippage, TheStopLoss, TheTakeProfit, "", MagicNumber, 0, clrGreen);
if(LastNotRecoveryTicket == -1)
Print("BUY OrderSend failed with error ", ErrorDescription(GetLastError()));
else
{
inBuy = true;
LastTradeBarTime = Time[0];
}
}
}
}
}
 

Akvisto

Активный участник
Ihre Frage ist schwer zu verstehen: Sie benötigen ein Abonnement zu diesem Thema in der Zeit zu Lesen diese Nachrichten?
oder Sie möchten bekommen mq4 Code des Programms ex4 ?
Ihre Frage ist schwer zu verstehen: Benötigen Sie ein Abonnement für dieses Thema, um diese Nachrichten rechtzeitig lesen zu können?
oder möchten Sie den mq4-Code des ex4-Programms erhalten?
Danke, es ist getan
 
Верх