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

От xbms, 13 апреля, 2013 в Уголок Программиста

#3651

Всем привет! У меня вопрос по уроку с советником по мартингейлу. Как ограничить количество открытий ордеров? Я пробовал сам, задав внешнюю переменную и создав цикл, но не вышло (2 недели учусь только). Прошу матерых программистов помочь с этой задачей. Во вложении файл с кодом советника с добавленными мною для удобства восприятия комментариями.

lesson3.mq47 скач.

Автор#3652


Всем привет! У меня вопрос по уроку с советником по мартингейлу. Как ограничить количество открытий ордеров? Я пробовал сам, задав внешнюю переменную и создав цикл, но не вышло (2 недели учусь только). Прошу матерых программистов помочь с этой задачей. Во вложении файл с кодом советника с добавленными мною для удобства восприятия комментариями.



День добрый!

1. Необходимо определить переменную(можно внешнюю) для указания кол-ва допустимых ордеров(MaxOrders, к примеру).
2. Далее добавить условие в строку if(CountTrades() == 0) дописав:

if( CountTrades() ....

Изменено 4 июля, 2016 пользователем xbms

#3653
Спойлер



Спойлер


Очередной вопрос к Сергею по урокам программированию MQL: "Программирование советника на мартингейле".

Как всегда, буква в букву два дня смотрел и переписывал урок по мартину.
Ошибок и некритических замечаний не получил.
По итогу: управления от iMa нет (включал/выключал - нет), работают только покупки под "машкой", мультипликатор (сам мартин) не работает - лотность одна и та же.


Добавлено: 15-06-2016 16:40:43



Добавлено: 15-06-2016 16:41:09



Добавлено: 15-06-2016 16:41:41

Да, в журнале ошибок чисто. Аттачу (см. выше)

Снизу прикрепил советник работает как в уроке. Спасибо Сергею за его уроки по MQL, теперь для себя пишу советники :d


Медленно, но верно уже просматриваю программные коды и даже начинаю что-то понимать.

Вопрос по уроку №4 "Программирование советника на мартингейле": какие изменения надо внести, чтобы вместо покупок советник открывал продажи и наоборот? Замена "+" на "-" в стр. 160 и 173 вопрос не решила.

mischkus что бы сделки открывались на оборот необходимо поменять условия на покупку и продажу местами
if(CountTrades() == 0)
{
if(Ask > maprice) /*если цена Ask выше линии MA то открывается продажа иначе если цена Ask ниже линии MA то покупка*/
{
tp = NormalizeDouble(Bid - TakeProfit * Point, Digits);
ticket = OrderSend(Symbol(), OP_SELL, Lots, Bid, 5, 0, tp, "", Magic, 0, Red);
}
else /*иначе*/
{
tp = NormalizeDouble(Ask + TakeProfit * Point, Digits);
ticket = OrderSend(Symbol(), OP_BUY, Lots, Ask, 5, 0, tp, "", Magic, 0, Blue);
}
}
#3654

xbms,

Добрый вечер и спасибо огромное за столь оперативный ответ!

Решение оказалось более изящным, чем я думал)

Сначала попробовал так, как Вы посоветовали - не получилось. Потом доперло, что условие нужно ведь для последующих ордеров (в коде функции void OnTick() идущих после else). Добавил так и все заработало:
else
{
int order_type = FindLastOrderType();
if (order_type == OP_BUY && CountTrades()
И аналогично для продаж. А "-1", потому что 1ый ордер выпадает, соответственно. Без Вас бы не сообразил!
Теперь доработаю OrdersModify(), чтобы выставлялся стоп лосс после максимально допустимого количества ордеров)

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

#3655

Добрый день! :) Регулярно на рынке происходят ситуации когда после пересечения средних, и открытия ордера, по ордеру срабатывает с/л, но затем цена идет в направлении пересечения. Подскажите пожалуйста, как написать условие открытия ордера так, чтобы после срабатывания с/л советник опять открыл ордер в том же направлении пересечения средних. :| Ставить слишком большой с/л не вариант. =;

#3656

Я благодарю Foxonnа за внимание!
Этот же вариант "инверсии" мартингейла мне предложил другой программист с более крутым опытом, чем у меня. Но ... ничего не получилось. Ответ меня ошеломил: тогда надо писать совсем другого советника, за что я не берусь даже за деньги.
А я-то думал: есть копировщики, которые инвертируют ордера, и нет тут большой проблемы... А оказывается, есть.

#3657
Спойлер


Я благодарю Foxonnа за внимание!
Этот же вариант "инверсии" мартингейла мне предложил другой программист с более крутым опытом, чем у меня. Но ... ничего не получилось. Ответ меня ошеломил: тогда надо писать совсем другого советника, за что я не берусь даже за деньги.
А я-то думал: есть копировщики, которые инвертируют ордера, и нет тут большой проблемы... А оказывается, есть.


mischkus по поводу копировальщика сделок, есть пост в блоге _http://tradelikeapro.ru/vozmozhno-luchshiy-kopirovshhik-sdelok/_, в советнике можно выставить параметр чтобы на терминал приходили реверсивные сигналы в разделе Account Export есть параметр ReverseTrades при включении которого советник будет посылать при копировании противоположные сигналы(вместо покупок продажи,вместо продаж — покупки).
P.s: Сам копировальщиком не пользовался.
#3658

Есть ERR_MARKET_CLOSED 132 Рынок закрыт

А как узнать CLOSED сейчас маркет или не CLOSED - без получения error?

Есть что-нибудь типа isMarketClosed ?

#3659


Есть ERR_MARKET_CLOSED 132 Рынок закрыт

А как узнать CLOSED сейчас маркет или не CLOSED - без получения error?

Есть что-нибудь типа isMarketClosed ?


второй вызов:
https://docs.mql4.com/ru/check/istradeallowed

проверка только потока на торговлю:
https://docs.mql4.com/ru/check/istradecontextbusy
#3660

Подскажите, что не так в функции. Функция должна выдавать ТРУ, если СЕГОДНЯ последние 2 ордера закрылись по стопу. Вроде все просто, но не пашет((

bool SLx2(string sy="", int mn=-1)
{
int a=0;
int i;
if (sy=="0") sy=Symbol();
for (i=0; i {
if (OrderSelect(i, SELECT_BY_POS, MODE_HISTORY))
{
if (OrderSymbol()==sy || sy=="")
{
if (mn {
if (OrderType()==OP_BUY)
{
if (OrderClosePrice() }
else if (OrderType()==OP_SELL)
{
if (OrderClosePrice() > OrderOpenPrice() && TimeDay (OrderCloseTime()) == Day()) a = a + 1;
}
}
}
}
}
if (a == 2) return(True);
else return(False);
}

#3661

Подскажите, что не так в функции. Функция должна выдавать ТРУ, если СЕГОДНЯ последние 2 ордера закрылись по стопу. Вроде все просто, но не пашет((

Не так всё просто... Сами функцию писали?
- В Вашей функции считаются лоси за текущий день, но не "последние 2 ордера".
- функция = тру если именно 2 лося за текущий день, а если 3 или 1 = фалс.
- узнать о лосе можно так: OrderProfit() - если надо именно "последние 2 ордера", то надо делать счётчик ( если доверяете МТ, запись идёт по времени закрытия ) или собирать ордера в массив, сортировать и анализировать крайние ( если хотите сортировать по другим параметрам ).
#3662


Подскажите, что не так в функции. Функция должна выдавать ТРУ, если СЕГОДНЯ последние 2 ордера закрылись по стопу. Вроде все просто, но не пашет((

Не так всё просто... Сами функцию писали?
- В Вашей функции считаются лоси за текущий день, но не "последние 2 ордера".

Все правильно, если СЕГОДНЯ 2 ПОСЛЕДНИЕ ОРДЕРА закрыты по стопу, то ТРУ
Цитата

- функция = тру если именно 2 лося за текущий день, а если 3 или 1 = фалс.


Усли 1 = фалс, а 3 не откроется, пока не наступит новый день
Цитата

- узнать о лосе можно так: OrderProfit()


А OrderClosePrice()
Цитата

- если надо именно "последние 2 ордера", то надо делать счётчик ( если доверяете МТ, запись идёт по времени закрытия ) или собирать ордера в массив, сортировать и анализировать крайние ( если хотите сортировать по другим параметрам ).


Так у меня и есть счетчик по истории for (i=0; i
#3663
rom_kaxxx, про "OrderClosePrice() и вместо
Спойлер

if (OrderType()==OP_BUY)
{
if (OrderClosePrice() }
else if (OrderType()==OP_SELL)
{
if (OrderClosePrice() > OrderOpenPrice() && TimeDay (OrderCloseTime()) == Day()) a = a + 1;
}



можно написать одной строкой

Спойлер

if (OrderProfit()



по истории - про " for (i=0; iа вот хрен, неправильно. это не последние два ордера а первые два. последние два будут вот так:

for (int i = OrdersHistoryTotal()-1; i>=OrdersHistoryTotal()-3; i--)

и опять же это с условием что терминал девственно чист и на нем не торгует ни одна другая сова, и с учетом что нет отложек и так далее, Oll правильно сказал - корректнее фильтровать еще и по времени закрытия.

Изменено 6 июля, 2016 пользователем dermitay

#3664
dermitay, спасибо!!!!
#3665



функция = тру если именно 2 лося за текущий день, а если 3 или 1 = фалс.


Усли 1 = фалс, а 3 не откроется, пока не наступит новый день
Счастливый человек! У Вас МТ никогда не вылетал в самый неподходящий момент? в тестере-то все будет гладко...

dermitay - всё видит, нашёл ошибку в описании цикла.
#3666

да ладно... я там один фиг в своем примере забыл добавить TimeDay(...).

мне вот интересно, никто не заморачивался с фильтрацией сигналов своей ТС по типу вот такого вот чуда-юда? :-b

https://www.mql5.com/ru/articles/1565
https://www.mql5.com/ru/articles/1574

обучить за 10 лет в тестере, и использовать данные по обучению уже на реале. грааль!!! :)) :d

Изменено 6 июля, 2016 пользователем dermitay

#3667

Здравствуйте ! Подскажите написал мартышку как в уроке а профит взял из урока №7 - Прибыль в валюте депозита. При достижении профита сова закрывает последний ордер, цена скаканёт на один тик и эта сволочь повторно открывает такой же ордер и продолжает торговать... Как вставить что бы сначала остановил торговлю а потом закрывал?

#3668
rom_kaxxx
ну на коленке вот как-то так
Спойлер


bool SLx2()
{
int ord = OrdersHistoryTotal();
if (ord ==0) return false;
int kol=0;

for (int i=ord-1; i>=0; i--)
{
if (!OrderSelect(i,SELECT_BY_POS,MODE_HISTORY)) continue;

/* игнорим несовпадающие магики(должна быть объявлена интовая перменная magic)/символы,
отмененные отложки, и те ордера, у которых
время закрытия меньше чем время открытия текущего дневного бара. */

if (OrderMagicNumber!=magic || OrderSymbol()!=Symbol()|| OrderType()>1 || OrderCloseTime()
/* задаем точность, так как
1. дабловые переменные сравнивать явно нельзя
2. стопы скользят
поэтому берется разница по модулю между ценой закрытия ордера и его стоплоссом, с точностью в 10 пипсопунктов,
если она больше - игнорится такой ордер*/

if (MathAbs(OrderClosePrice() - OrderStopLoss()) > 10*Point) continue;

// считаем количество ордеров
kol++;
/* принудительно выходим из цикла и всей функции с true если насчитали два ордера.*/
if (kol>=2) return true;
}

return false;
}


но это очень криво. по сути, если у тебя будет:

1. первый ордер закрылся по сл
2. второй закрылся по тп
3. третий закрылся по тп
4. четвертый закрылся по сл

то функция вернет тру.

для того чтобы было именно так как ты хочешь, нужно точно сортировать все ордера по времени закрытия, а для этого нужно загонять каждый ордер в двумерный массив, причем первый элемент будет его время закрытия а второе - его тикет.
дальше его сортириуем по первому измерению, и смотрим только на последние два/первые два значения(в зависимости от направления сортировки), обращаемся к ордерам по их тикетам, смотрим профит, считаем. ну вот как бы и всё.

щас нет времени писать код, пора ехать бухать отдыхать на природу, но позже могу накатать такой код. :d ;)

Изменено 8 июля, 2016 пользователем dermitay

#3669
dermitay
То что вы про TimeDay(...) не написали, это я заметил, в итоге написал так:
bool SLx2(string sy="", int mn=-1)
{
int a=0;
int i;
if (sy=="0") sy=Symbol();
for (i = OrdersHistoryTotal()-1; i>=OrdersHistoryTotal()-2; i--)
{
if (OrderSelect(i, SELECT_BY_POS, MODE_HISTORY))
{
if (OrderSymbol()==sy || sy=="")
{
if (mn {
if (OrderProfit() }
}
}
}
if (a == 2) return(True);
else return(False);
}


обучить за 10 лет в тестере, и использовать данные по обучению уже на реале. грааль!!! :)) :d


:)) Конечно, использовать для реала я это и не собирался, чисто протестировать стратегию. Суть простая, если сова сегодня подряд поймала 2 ЛОСЯ, то сегодня больше сделок не открываем. Вроде, в таком виде функция на истории работает

Добавлено: 09-07-2016 16:32:08


rom_kaxxx
ну на коленке вот как-то так

Спойлер


bool SLx2()
{
int ord = OrdersHistoryTotal();
if (ord ==0) return false;
int kol=0;

for (int i=ord-1; i>=0; i--)
{
if (!OrderSelect(i,SELECT_BY_POS,MODE_HISTORY)) continue;

/* игнорим несовпадающие магики(должна быть объявлена интовая перменная magic)/символы,
отмененные отложки, и те ордера, у которых
время закрытия меньше чем время открытия текущего дневного бара. */

if (OrderMagicNumber!=magic || OrderSymbol()!=Symbol()|| OrderType()>1 || OrderCloseTime()
/* задаем точность, так как
1. дабловые переменные сравнивать явно нельзя
2. стопы скользят
поэтому берется разница по модулю между ценой закрытия ордера и его стоплоссом, с точностью в 10 пипсопунктов,
если она больше - игнорится такой ордер*/

if (MathAbs(OrderClosePrice() - OrderStopLoss()) > 10*Point) continue;

// считаем количество ордеров
kol++;
/* принудительно выходим из цикла и всей функции с true если насчитали два ордера.*/
if (kol>=2) return true;
}

return false;
}





Опыта в написание сов, ..... маловато у меня, но, по-моему вы усложняете задачу.
Зачем сортировать по разнице ЦЕНЫЗАКРЫТИЯ и СТОПЛОССов
(spoiler)if (MathAbs(OrderClosePrice() - OrderStopLoss()) > 10*Point) continue; (/spoiler)
Если мы берем последний ордер, проверяем его магик && если закрылся сегодня && OrderProfit()В итоге если а++, то функция выдает ТРУ, и , например в моем случае, сова сегодня больше не торгует.


щас нет времени писать код, пора ехать бухать отдыхать на природу, но позже могу накатать такой код. :d ;)


если есть возможность, накатайте! Буду признателен! =d>

Изменено 9 июля, 2016 пользователем rom_kaxxx

#3670

Приветствую, товарищи программисты!

Как правильно указать параметр "expiration" функции "OrderSend"? Если ставлю "0" в данном параметре - отложенный ордер выставляется. Если же указываю 3600 (предполагается, что через час не активированный ордер должен быть удалён) то ордер не ставиться.

Правильно ли я делаю, что пишу "3600", ведь это "int", или же данное время надо указать каким-то иным образом?


Добавлено: 10-07-2016 11:00:08

Подскажите, пожалуйста, как сдвинуть не одну, а сразу несколько строк кода (выделенный фрагмент) на несколько пробелов в сторону?

Изменено 10 июля, 2016 пользователем Svarog_AZh

#3672


Итак, первый урок по MQL5:
http://tradelikeapro.ru/mql5-rabota-s-orderami/ >:d


Спасибо за урок!!!!!! Для понимания, MQL4 ГОРАЗДО легче!!!
Интересно, по сравнению с MQL4, у MQL5 какие преимущества? Т.Е. что можно сделать на MQL5 , что на MQL4 сделать нельзя?
#3673


Итак, первый урок по MQL5:
http://tradelikeapro.ru/mql5-rabota-s-orderami/ >:d




Спасибо большое, буду признателен если поделитесь какими то ссылками или примерами, с которыми лучше ознакомиться по вашему мнению!
#3674

Ура Сергею и Павлу! >0

#3675

Здравствуйте товарищи, хочу написать бота для торговли по БО, брокер Гранд Капитал, не могу понять почему строчит ошибки :

Спойлер


2016.07.12 14:49:58.862 BOGRC3SEC EURUSD_OP,M5: Ошибка открытия ордера на продажу
2016.07.12 14:49:58.597 BOGRC3SEC EURUSD_OP,M5: Ошибка открытия ордера на покупку


Вот код:
//+------------------------------------------------------------------+
//| GEAF.mq4 |
//| Foxonn |
//| hitman_94_1@mail.ru |
//+------------------------------------------------------------------+
#property copyright "Foxonn"
#property link "hitman_94_1@mail.ru"
#property version "1.00"

extern double Lots = 0.01;
extern int Magic = 101010;

double oOpen, oClose;
int ticket;
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{


return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//---

}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
oOpen = iOpen (0,0,1);
oClose = iClose (0,0,1);

Comment("Баланс: " + NormalizeDouble(AccountBalance(),3)
+ "\n" + "Цена открытия: " + NormalizeDouble(oOpen,5)
+ "\n" + "Цена закрытия: " + NormalizeDouble(oClose,5));


if (CountSell() == 0 && CountBuy() == 0 && oOpen {
ticket = OrderSend(Symbol(), OP_SELL, Lots, Bid, 0, 0, 0, 5, Magic, 0, Red);
}else Print("Ошибка открытия ордера на продажу");

if (CountSell() == 0 && CountBuy() == 0 && oOpen > oClose)
{
ticket = OrderSend(Symbol(), OP_BUY, Lots, Ask, 0, 0, 0, 5, Magic, 0, Blue);
}else Print("Ошибка открытия ордера на покупку");
}
//+------------------------------------------------------------------+
int CountBuy()
{
int count = 0;

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

Изменено 12 июля, 2016 пользователем Foxonn

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

Перейти к списку тем
Форум · 2.0.20260627.0025