Перейти к содержанию

Обучение языку MQL4 под MetaTrader 4


Рекомендуемые сообщения

  • Ответов 6,8k
  • Создано
  • Последний ответ

Популярные авторы

Популярные авторы

Популярные посты

Смотрим видео-уроки, изучаем MQL:       Скачать видеокурс «MQL программирование. Как самому написать форекс советник/ индикатор/ скрипт»   P.S. Тема про Обучение MQ

Перейти

Циклы цикл for Иногда необходимо повторять одно и то же действие несколько раз подряд. Для этого используют циклы. К примеру, мы хотим проанализировать последние 10 баров и выяснить наименьшую цен

Перейти

Речь идет о том, что не будет значимых нововведений. А только баги периодически будут править. А вот все новое мол - в МТ5. Когда они вживую сказали то же самое на конференции в Москве, я уточнил: "То

Перейти
Обучение языку MQL4 под MetaTrader 4 Опубликовано
oleguitar, не совсем понятно что вы имеете ввиду, если нужно подсчитать ордера Sell и SellStop, то в последнем условии нужно вместо и - (&&), поставить или - (||).
Ссылка на сообщение
Поделиться на другие сайты

Обучение языку MQL4 под MetaTrader 4 Опубликовано


oleguitar, не совсем понятно что вы имеете ввиду, если нужно подсчитать ордера Sell и SellStop, то в последнем условии нужно вместо и - (&&), поставить или - (||).



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

Обучение языку MQL4 под MetaTrader 4 Опубликовано
Спойлер



oleguitar, не совсем понятно что вы имеете ввиду, если нужно подсчитать ордера Sell и SellStop, то в последнем условии нужно вместо и - (&&), поставить или - (||).



Я тоже не совсем понял, отложники в сове вроде бы не предусмотрены.
Подскажите пожалуйста почему ордера не открываются?


С помощью советника, можно устанавливать любой тип ордеров, ведь суть-то такая, что мы просто перекладываем рутину на бота, соответственно он должен уметь всё, что можно сделать вручную, единственная проблема только - как ему всё объяснить. По вашему сообщению что-то не понимаю, ссылаетесь на чужое сообщение и ещё пишите вопрос по работе чужого бота, не думаю что вы работаете совместно?
  • Лайк 1
Ссылка на сообщение
Поделиться на другие сайты

Обучение языку MQL4 под MetaTrader 4 Опубликовано

Ребят, прохожу 3й урок Сергея из курса и на данный момент столкнулся с проблемой:
Советник должен модифицировать открытые ордера после их заключения, но он модифицирует только первый ордер. В чем проблема - понять не смог. Найдите ошибку, кто может, пожалуйста=)

Вот код:

extern double Vol = 0.1;
extern int SL = 50;
extern int TP = 300;
extern int Slip = 5;
extern int Magic = 12345;
extern bool KanalClose = true;

extern string Par = "Параметры TMA";
extern string TimeFrame = "current time frame";
extern int HalfLength = 56;
extern int Price = PRICE_CLOSE;
extern double ATRMultiplier = 2.0;
extern int ATRPeriod = 100;
extern bool Interpolate = true;

double PriceHigh, PriceLow, Sl, Tp;
int ticket;

//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
if (Digits == 3 || Digits == 5)
{
SL *= 10;
TP *= 10;
Slip *= 10;
}
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{


}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{

PriceHigh = iCustom (Symbol(), 0, "TMA with Distances", TimeFrame, HalfLength, Price, ATRMultiplier, ATRPeriod, Interpolate, 1, 0);
PriceLow = iCustom (Symbol(), 0, "TMA with Distances", TimeFrame, HalfLength, Price, ATRMultiplier, ATRPeriod, Interpolate, 2, 0);


if (Bid >= PriceHigh && CountOrder() == 0)
{
Sl = NormalizeDouble(Bid + SL*Point, Digits);
Tp = NormalizeDouble(Bid - TP*Point, Digits);
bool Send1 = OrderSend (Symbol(), OP_SELL, Vol, Bid, Slip, 0, 0, "", Magic, 0, clrDarkBlue);
ticket = Send1;
if (ticket > 0)
{
ModOrder();
}
}

if (Bid {
Sl = NormalizeDouble(Ask - SL*Point, Digits);
Tp = NormalizeDouble(Ask + TP*Point, Digits);
bool Send2 = OrderSend (Symbol(), OP_BUY, Vol, Ask, Slip, 0, 0, "", Magic, 0, clrRed);
ticket = Send2;
if (ticket > 0)
{
ModOrder();
}
}
if (KanalClose == true)
{
if (Bid 0)
{
CloseOrderSell();
}
if (Bid >= PriceHigh && CountBuy()>0)
{
CloseOrderBuy();
}
}
}
//+------------------------------------------------------------------+
int CountBuy()
{
int count = 0;
for (int trade = OrdersTotal()-1; trade>=0; trade --)
{
bool Select3 = OrderSelect (trade, SELECT_BY_POS, MODE_TRADES);
if (OrderSymbol() == Symbol() && OrderMagicNumber() == Magic)
{
if (OrderType() == OP_BUY)
count++;
}
}
return(count);

}


//+------------------------------------------------------------------+
int CountSell()
{
int count = 0;
for(int trade = OrdersTotal() - 1; trade >=0; trade--)
{
bool Select4 = OrderSelect (trade, SELECT_BY_POS, MODE_TRADES);
if (OrderSymbol() == Symbol() && OrderMagicNumber() == Magic)
{
if (OrderType() == OP_SELL)
count++;
}

}

return(count);
}
//+------------------------------------------------------------------+
void CloseOrderSell()
{
for (int trade = OrdersTotal() - 1; trade >=0; trade--)
{
bool Select5 = OrderSelect(trade, SELECT_BY_POS, MODE_TRADES);
if (Select5 == true)
{
if (OrderSymbol() == Symbol() && OrderMagicNumber() == Magic && OrderType() == OP_SELL)
{
bool Close1 = OrderClose (OrderTicket(), OrderLots(), Ask, Slip, clrDarkMagenta);
}
}
}
}
//+------------------------------------------------------------------+
void CloseOrderBuy()
{
for (int trade = OrdersTotal() - 1; trade >=0; trade--)
{
bool Select6 = OrderSelect(trade, SELECT_BY_POS, MODE_TRADES);
if (Select6 == true)
{
if (OrderSymbol() == Symbol() && OrderMagicNumber() == Magic && OrderType() == OP_BUY)
{
bool Close2 = OrderClose (OrderTicket(), OrderLots(), Bid, Slip, clrDarkMagenta);
}
}
}
}
//+------------------------------------------------------------------+
int CountOrder()
{
int count = 0;
for(int trade = OrdersTotal() - 1; trade >=0; trade--)
{
bool Select7 = OrderSelect (trade, SELECT_BY_POS, MODE_TRADES);
if (OrderSymbol() == Symbol() && OrderMagicNumber() == Magic)
{
count++;
}

}

return(count);
}
//+------------------------------------------------------------------+
void ModOrder()
{
bool Select8 = OrderSelect(ticket, SELECT_BY_TICKET, MODE_TRADES);
if(Select8 == true)
{
bool Modify = OrderModify (ticket, OrderOpenPrice(), Sl, Tp, 0, clrAqua);
}
}
//+------------------------------------------------------------------+

Ссылка на сообщение
Поделиться на другие сайты

Обучение языку MQL4 под MetaTrader 4 Опубликовано
stainsgate, если уж вы решили сделать отдельную функцию по модификации, то нужно в ней же сделать цикл перебора ордеров и выбора по условиям. Там же разместить расчёт TP и SL по условиям. Вообще, что значит модифицирует только один, вроде же по условиям не предусмотрено усреднение?
  • Лайк 1
Ссылка на сообщение
Поделиться на другие сайты

Обучение языку MQL4 под MetaTrader 4 Опубликовано


В чем проблема - понять не смог. Найдите ошибку, кто может, пожалуйста=)


Попробуй так, вместо:
bool Send1 = OrderSend (Symbol(), OP_SELL, Vol, Bid, Slip, 0, 0, "", Magic, 0, clrDarkBlue);
ticket = Send1;
сделай:
ticket = OrderSend (Symbol(), OP_SELL, Vol, Bid, Slip, 0, 0, "", Magic, 0, clrDarkBlue);

Подробнее здесь написано. Удачи!
  • Лайк 1
Ссылка на сообщение
Поделиться на другие сайты

Обучение языку MQL4 под MetaTrader 4 Опубликовано

Oll, спасибо, помогло. Если можешь, объясни, что ему не понравилось в прошлом варианте. Важно понять это.

chistaia-rodina, открывает ордер, модифицирует(Sl, Tp), закрывает, открывает новый - больше не модифицирует, остальные также. Надеюсь, понятно=)
Если не ошибаюсь, то функция указана правильно, и пересчет ордеров там не нужен потому, что мы ссылаемся к ордеру по тикету. Вызвав функцию в цикле она ссылается на Sl и Tp, характерные для этого цикла. Проблемы быть не должно. К тому же изначально модификация одера вызывалась не отдельной функцией, проблема была та же=)
Если не прав, поправьте. Только начал обучение, многого не понимаю.

Подумал еще, понял, что пересчет ордеров не помешал бы, если функция будет использоваться еще, в других обстоятельствах, а в данном случае и без него можно=)

Изменено пользователем stainsgate
Ссылка на сообщение
Поделиться на другие сайты

Обучение языку MQL4 под MetaTrader 4 Опубликовано


Oll, спасибо, помогло. Если можешь, объясни, что ему не понравилось в прошлом варианте. Важно понять это.

Функция OrderSend() возвращает число (int) - номер тикета (я ссылку давал).
А Вы присваивали в (bool) который может быть 0 или 1 - вот у Вас только 1-ый тикет и отрабатывал.
Т.к. (bool) это тоже целое и его длина совпадает с (int) - ошибки не возникло...
  • Лайк 1
Ссылка на сообщение
Поделиться на другие сайты

Обучение языку MQL4 под MetaTrader 4 Опубликовано
stainsgate, ну да правильно 0ll говорит, а то я что-то сразу и не присмотрелся к этому. По отдельной функции модификации, я бы наверное сделал так, прописал бы в старте ссылку к ней при наличии покупки или продажи и уже в ней перебор, потом проверка на тип и проверка наличия SL и TP, ну и потом если не установлены, то модификация. Функция будет проверяться на каждом тике при наличии ордеров и если по каким-то причинам не произойдёт установки сразу, то на следующем тике выставит. Также из основного кода будут убраны расчёты SL и TP.
  • Лайк 1
Ссылка на сообщение
Поделиться на другие сайты

Обучение языку MQL4 под MetaTrader 4 Опубликовано

chistaia-rodina, если я вас правильно понял, для этого в функции нужно указать не void тип данных, а, например, int. Далее произвести поиск ордеров через цикл for и сделать выборку по параметрам. Если не прав, поправьте.
На счет Sl и Tp, в циклах для Buy и для Sell сделок они рассчитываются немного по разному, и, как по мне, разницы большой в количестве текста не будет, будем ли мы ее ставить в расчете функции (тогда понадобится 2 функции для каждого типа сделок) или в цикле старт.

Ссылка на сообщение
Поделиться на другие сайты

Обучение языку MQL4 под MetaTrader 4 Опубликовано
stainsgate, нет почему, как раз void и будет, нам же не надо из неё что-то получать, мы просто отсылаем к ней ордер на обработку. Ну да перебор через for, а далее можно сделать разветвление, если Buy одно, а если Sell то другое. Так же для расчёта TP и SL, будем отталкиваться от OrderOpenPrice, что в данном случае будет более правильно. Если что-то не получится, то в крайнем случае, можно в функции сделать цикл для каждого типа.

Суть не в том, что размер кода в функции и старте будет равносилен, главное по возможности не нагружать старт, так легче будет ориентироваться, особенно в больших кодах. К тому же, выписанная функция универсальна и её можно будет использовать в других кодах, просто скопировав.
  • Лайк 1
Ссылка на сообщение
Поделиться на другие сайты

Обучение языку MQL4 под MetaTrader 4 Опубликовано

Перечитал еще раз ваше сообщение. Если мы сохраняем тип void, то нам эту функцию необходимо будет прописать не внутри цикла по открытию сделки, а вне оного. Я вас правильно понял?

Ссылка на сообщение
Поделиться на другие сайты

Обучение языку MQL4 под MetaTrader 4 Опубликовано

Ну вот так:
_________________________________________________
void OrderModify()
{
for и так далее, вся обработка внутри скобок

}
_________________________________________________

Прописываем всё отдельно в виде пользовательской функции.
В основном коде, напишем просто:

if (CountBuy() > 0 || CountSell() > 0)
OrderModify();

Изменено пользователем chistaia-rodina
Ссылка на сообщение
Поделиться на другие сайты

Обучение языку MQL4 под MetaTrader 4 Опубликовано

Да, это я понял. Я имел ввиду, вызов функции мы делаем уже не из цикла с открытием ордера(как это было раньше), а просто из старта?! Ну, в общем, я понял. Спасибо!=)

Ссылка на сообщение
Поделиться на другие сайты

Обучение языку MQL4 под MetaTrader 4 Опубликовано

огромное человеческое спасибо! с понедельника начну.


Добавлено: 08-09-2014 05:50:35


Попробуй этот вариант, пошаманил маненько, авось поможет


не помогло,все тоже-самое.пока бай не откроется селл не открывается Изменено пользователем beketv1
Ссылка на сообщение
Поделиться на другие сайты

Обучение языку MQL4 под MetaTrader 4 Опубликовано


Советник открывает ордера при каждом тике, как запретить?



Проводить предварительную проверку на наличие открытого ордера.
Ссылка на сообщение
Поделиться на другие сайты

Обучение языку MQL4 под MetaTrader 4 Опубликовано

Всем привет!

Есть такой вопрос:
Я хочу, чтобы при выполнении условия на покупку или продажу открывался не один ордер, а два. Мне продублировать условия с разными мэджиками или как-то по-другому сделать можно?

Ссылка на сообщение
Поделиться на другие сайты

Обучение языку MQL4 под MetaTrader 4 Опубликовано


Всем привет!

Есть такой вопрос:
Я хочу, чтобы при выполнении условия на покупку или продажу открывался не один ордер, а два. Мне продублировать условия с разными мэджиками или как-то по-другому сделать можно?



Сам конечно так ещё не делал, но думаю можно просто после успешного выполнения операции установки первого ордера, прописать ещё одну. На счёт разных мейджиков, это смотря что вы будете дальше с ними делать и какие проверки идут до установки ордеров.
Ссылка на сообщение
Поделиться на другие сайты

Обучение языку MQL4 под MetaTrader 4 Опубликовано

Сделал с разными мэджиками, работает как нужно

Спойлер



if (мое условие)

{
SL = NormalizeDouble(low1 - StopLoss*Point, Digits);

openprice = NormalizeDouble(high1 + Indent*Point, Digits);
TP = NormalizeDouble(openprice + TakeProfit*Point, Digits);
TP1 = NormalizeDouble(openprice + TakeProfit1*Point, Digits);

ticket = OrderSend(Symbol(),OP_BUYSTOP, Lot, openprice, Slippage, 0, 0, "", Magic, 0, Red);

if (ticket > 0)
{
if (OrderSelect(ticket, SELECT_BY_TICKET, MODE_TRADES) == true)
bool om1 = OrderModify(ticket, OrderOpenPrice(), SL, TP, 0);
}



ticket = OrderSend(Symbol(),OP_BUYSTOP, Lot, openprice, Slippage, 0, 0, "", Magic1, 0, Red);

if (ticket > 0)
{
if (OrderSelect(ticket, SELECT_BY_TICKET, MODE_TRADES) == true)
bool om1 = OrderModify(ticket, OrderOpenPrice(), SL, TP1, 0);
}

}
//+------------------------------------------------------------------+


int CountBuy()
{
int count = 0;

for (int trade = OrdersTotal()-1; trade>=0; trade--)
{
bool select2 = OrderSelect(trade, SELECT_BY_POS, MODE_TRADES);
if (OrderSymbol() == Symbol() && OrderMagicNumber() == Magic)
{
if (OrderType() == OP_BUY || OrderType() == OP_BUYSTOP)
count++;
}
}
return(count);
}



Но теперь наткнулся на другую проблему:
Мне нужно удалять отложки, если цена прошла уровень предполагаемого стоп-лосса, для этого написал вот такую функцию:

Спойлер


void CloseBuyStop()
{
if (CountBuy() != 0)
{
bool os = OrderSelect(ticket,SELECT_BY_TICKET);
bool od = OrderDelete(ticket, Red);
}
}



И перед основным условием торговли я написал вот такое:

Спойлер


if (Ask {
CloseBuyStop();
}



Первый ордер удаляется, а второй - нет
Решение пока что в голову не приходит Изменено пользователем oleguitar
Ссылка на сообщение
Поделиться на другие сайты

Обучение языку MQL4 под MetaTrader 4 Опубликовано
oleguitar:

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

По условию для удаления отложек, по идее надо сравнивать с ценой Bid, потому что стоп по рыночному ордеру сработал бы так и лучше поставить (
По самому удалению, я бы запустил цикл for и нашёл все BuyStop ордера, а затем удалил.
Ссылка на сообщение
Поделиться на другие сайты

Обучение языку MQL4 под MetaTrader 4 Опубликовано
oleguitar:
Спойлер


void CloseBuyStop() {
for (int i = OrdersTotal()-1; i >= 0; i--) {
if (!OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) continue;
if (!(OrderSymbol() == Symbol() && (OrderMagicNumber() == MAGIC1 || OrderMagicNumber() == MAGIC2))) continue;
if (OrderType() == OP_BUYSTOP) OrderDelete(OrderTicket());
}
}

Ссылка на сообщение
Поделиться на другие сайты

Для публикации сообщений создайте учётную запись или авторизуйтесь

Вы должны быть пользователем, чтобы оставить комментарий

Создать учетную запись

Зарегистрируйте новую учётную запись в нашем сообществе. Это очень просто!

Регистрация нового пользователя

Войти

Уже есть аккаунт? Войти в систему.

Войти

  • Специальное предложение


  • Рекомендуемые брокеры

  • ×
    ×
    • Создать...