Всем привет! У меня вопрос по уроку с советником по мартингейлу. Как ограничить количество открытий ордеров? Я пробовал сам, задав внешнюю переменную и создав цикл, но не вышло (2 недели учусь только). Прошу матерых программистов помочь с этой задачей. Во вложении файл с кодом советника с добавленными мною для удобства восприятия комментариями.
Обучение языку MQL4 под MetaTrader 4📌
От xbms, 13 апреля, 2013 в Уголок Программиста
Всем привет! У меня вопрос по уроку с советником по мартингейлу. Как ограничить количество открытий ордеров? Я пробовал сам, задав внешнюю переменную и создав цикл, но не вышло (2 недели учусь только). Прошу матерых программистов помочь с этой задачей. Во вложении файл с кодом советника с добавленными мною для удобства восприятия комментариями.
День добрый!
1. Необходимо определить переменную(можно внешнюю) для указания кол-ва допустимых ордеров(MaxOrders, к примеру).
2. Далее добавить условие в строку if(CountTrades() == 0) дописав:
if( CountTrades() ....
Изменено 4 июля, 2016 пользователем xbms
Спойлер
Очередной вопрос к Сергею по урокам программированию 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);
}
}xbms,
Добрый вечер и спасибо огромное за столь оперативный ответ!
Решение оказалось более изящным, чем я думал)
Сначала попробовал так, как Вы посоветовали - не получилось. Потом доперло, что условие нужно ведь для последующих ордеров (в коде функции void OnTick() идущих после else). Добавил так и все заработало:
else
{
int order_type = FindLastOrderType();
if (order_type == OP_BUY && CountTrades()
И аналогично для продаж. А "-1", потому что 1ый ордер выпадает, соответственно. Без Вас бы не сообразил!
Теперь доработаю OrdersModify(), чтобы выставлялся стоп лосс после максимально допустимого количества ордеров)
P.S. Еще выражаю благодарность за Ваши видео уроки! Пожалуй, единственные уроки на русском языке, изложенные настолько понятно и последовательно.
Добрый день! :) Регулярно на рынке происходят ситуации когда после пересечения средних, и открытия ордера, по ордеру срабатывает с/л, но затем цена идет в направлении пересечения. Подскажите пожалуйста, как написать условие открытия ордера так, чтобы после срабатывания с/л советник опять открыл ордер в том же направлении пересечения средних. :| Ставить слишком большой с/л не вариант. =;
Я благодарю Foxonnа за внимание!
Этот же вариант "инверсии" мартингейла мне предложил другой программист с более крутым опытом, чем у меня. Но ... ничего не получилось. Ответ меня ошеломил: тогда надо писать совсем другого советника, за что я не берусь даже за деньги.
А я-то думал: есть копировщики, которые инвертируют ордера, и нет тут большой проблемы... А оказывается, есть.
Я благодарю Foxonnа за внимание!
Этот же вариант "инверсии" мартингейла мне предложил другой программист с более крутым опытом, чем у меня. Но ... ничего не получилось. Ответ меня ошеломил: тогда надо писать совсем другого советника, за что я не берусь даже за деньги.
А я-то думал: есть копировщики, которые инвертируют ордера, и нет тут большой проблемы... А оказывается, есть.
mischkus по поводу копировальщика сделок, есть пост в блоге _http://tradelikeapro.ru/vozmozhno-luchshiy-kopirovshhik-sdelok/_, в советнике можно выставить параметр чтобы на терминал приходили реверсивные сигналы в разделе Account Export есть параметр ReverseTrades при включении которого советник будет посылать при копировании противоположные сигналы(вместо покупок продажи,вместо продаж — покупки).
P.s: Сам копировальщиком не пользовался.
Есть ERR_MARKET_CLOSED 132 Рынок закрыт
А как узнать CLOSED сейчас маркет или не CLOSED - без получения error?
Есть что-нибудь типа isMarketClosed ?
Есть ERR_MARKET_CLOSED 132 Рынок закрыт
А как узнать CLOSED сейчас маркет или не CLOSED - без получения error?
Есть что-нибудь типа isMarketClosed ?
второй вызов:
https://docs.mql4.com/ru/check/istradeallowed
проверка только потока на торговлю:
https://docs.mql4.com/ru/check/istradecontextbusy
Подскажите, что не так в функции. Функция должна выдавать ТРУ, если СЕГОДНЯ последние 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);
}
Не так всё просто... Сами функцию писали?Подскажите, что не так в функции. Функция должна выдавать ТРУ, если СЕГОДНЯ последние 2 ордера закрылись по стопу. Вроде все просто, но не пашет((
- В Вашей функции считаются лоси за текущий день, но не "последние 2 ордера".
- функция = тру если именно 2 лося за текущий день, а если 3 или 1 = фалс.
- узнать о лосе можно так: OrderProfit() - если надо именно "последние 2 ордера", то надо делать счётчик ( если доверяете МТ, запись идёт по времени закрытия ) или собирать ордера в массив, сортировать и анализировать крайние ( если хотите сортировать по другим параметрам ).
Не так всё просто... Сами функцию писали?Подскажите, что не так в функции. Функция должна выдавать ТРУ, если СЕГОДНЯ последние 2 ордера закрылись по стопу. Вроде все просто, но не пашет((
- В Вашей функции считаются лоси за текущий день, но не "последние 2 ордера".
Все правильно, если СЕГОДНЯ 2 ПОСЛЕДНИЕ ОРДЕРА закрыты по стопу, то ТРУ
Цитата- функция = тру если именно 2 лося за текущий день, а если 3 или 1 = фалс.
Усли 1 = фалс, а 3 не откроется, пока не наступит новый день
Цитата- узнать о лосе можно так: OrderProfit()
А OrderClosePrice()
Цитата- если надо именно "последние 2 ордера", то надо делать счётчик ( если доверяете МТ, запись идёт по времени закрытия ) или собирать ордера в массив, сортировать и анализировать крайние ( если хотите сортировать по другим параметрам ).
Так у меня и есть счетчик по истории for (i=0; i
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
Счастливый человек! У Вас МТ никогда не вылетал в самый неподходящий момент? в тестере-то все будет гладко...
функция = тру если именно 2 лося за текущий день, а если 3 или 1 = фалс.
Усли 1 = фалс, а 3 не откроется, пока не наступит новый день
dermitay - всё видит, нашёл ошибку в описании цикла.
да ладно... я там один фиг в своем примере забыл добавить TimeDay(...).
мне вот интересно, никто не заморачивался с фильтрацией сигналов своей ТС по типу вот такого вот чуда-юда? :-b
https://www.mql5.com/ru/articles/1565
https://www.mql5.com/ru/articles/1574
обучить за 10 лет в тестере, и использовать данные по обучению уже на реале. грааль!!! :)) :d
Изменено 6 июля, 2016 пользователем dermitay
Здравствуйте ! Подскажите написал мартышку как в уроке а профит взял из урока №7 - Прибыль в валюте депозита. При достижении профита сова закрывает последний ордер, цена скаканёт на один тик и эта сволочь повторно открывает такой же ордер и продолжает торговать... Как вставить что бы сначала остановил торговлю а потом закрывал?
ну на коленке вот как-то так
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. четвертый закрылся по сл
то функция вернет тру.
для того чтобы было именно так как ты хочешь, нужно точно сортировать все ордера по времени закрытия, а для этого нужно загонять каждый ордер в двумерный массив, причем первый элемент будет его время закрытия а второе - его тикет.
дальше его сортириуем по первому измерению, и смотрим только на последние два/первые два значения(в зависимости от направления сортировки), обращаемся к ордерам по их тикетам, смотрим профит, считаем. ну вот как бы и всё.
щас нет времени писать код, пора ехать
Изменено 8 июля, 2016 пользователем 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
Приветствую, товарищи программисты!
Как правильно указать параметр "expiration" функции "OrderSend"? Если ставлю "0" в данном параметре - отложенный ордер выставляется. Если же указываю 3600 (предполагается, что через час не активированный ордер должен быть удалён) то ордер не ставиться.
Правильно ли я делаю, что пишу "3600", ведь это "int", или же данное время надо указать каким-то иным образом?
Добавлено: 10-07-2016 11:00:08
Подскажите, пожалуйста, как сдвинуть не одну, а сразу несколько строк кода (выделенный фрагмент) на несколько пробелов в сторону?
Изменено 10 июля, 2016 пользователем Svarog_AZh
Итак, первый урок по MQL5:
http://tradelikeapro.ru/mql5-rabota-s-orderami/ >:d
Итак, первый урок по MQL5:
http://tradelikeapro.ru/mql5-rabota-s-orderami/ >:d
Спасибо за урок!!!!!! Для понимания, MQL4 ГОРАЗДО легче!!!
Интересно, по сравнению с MQL4, у MQL5 какие преимущества? Т.Е. что можно сделать на MQL5 , что на MQL4 сделать нельзя?
Итак, первый урок по MQL5:
http://tradelikeapro.ru/mql5-rabota-s-orderami/ >:d
Спасибо большое, буду признателен если поделитесь какими то ссылками или примерами, с которыми лучше ознакомиться по вашему мнению!
Ура Сергею и Павлу! >0
Здравствуйте товарищи, хочу написать бота для торговли по БО, брокер Гранд Капитал, не могу понять почему строчит ошибки :
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
Для публикации сообщений создайте учётную запись или авторизуйтесь
Перейти к списку тем