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

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

#5276

У вас функции GetMaxPrice() и GetMinPrice() типа void, а надо double, чтобы они возвращали значение цены. И когда хотите открыть ордер, вызовите эту функцию.
например:



Сергей огромное спасибо. Очень помогло.
Есть еще вопрос.
Спойлер


В том же коде учитель пишет ограничение по выставлению ордеров командой int count - как я понял. Но как написать так чтобы советник выставлял только один отложенный ордер на каждую вершину которую он определил?

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

extern int BarCount = 10;
extern int HourStart = 11;
extern double Lots = 0.01;
extern int StopLoss = 300;
extern int TakeProfit = 200;
extern int Magic = 12345;

double SL, TP, MaxPrice, MinPrice;

int ticket;


//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//---

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

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

if(TimeHour(TimeCurrent()) == HourStart)
{
if (BuyLimitCount() == 0 && BuyCount() == 0)
{
double price_open = GetMinPrice();
SL = NormalizeDouble(price_open- StopLoss*Point, 5);
TP = NormalizeDouble(price_open + TakeProfit*Point, 5);
ticket = OrderSend(Symbol(), OP_BUYLIMIT, Lots, price_open, 3, SL, TP, "", Magic, 0, Blue);

if(ticket Print("Не удалось открыть ордер");
}

if (SellLimitCount() == 0 && SellCount() == 0)
{
double price_open = GetMaxPrice();
SL = NormalizeDouble(price_open + StopLoss*Point, 5);
TP = NormalizeDouble(price_open - TakeProfit*Point, 5);
ticket = OrderSend(Symbol(), OP_SELLLIMIT, Lots, price_open, 3, SL, TP, "", Magic, 0, Red);

if(ticket Print("Не удалось открыть ордер");
}
}

Comment("Maxprice:" +DoubleToStr(GetMaxPrice(), 5) + "\n"+
"Minprice:" +DoubleToStr(GetMinPrice(), 5));

}

//+------------------------------------------------------------------+
int BuyLimitCount()
{
int count = 0;
for(int i=OrdersTotal()-1; i>=0; i--)
{
if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES) == true &&
OrderMagicNumber() == Magic &&
OrderType() == OP_BUYLIMIT)
{
count++;
}
}
return(count);
}

//+------------------------------------------------------------------+
int SellLimitCount()
{
int count = 0;
for(int i=OrdersTotal()-1; i>=0; i--)
{
if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES) == true &&
OrderMagicNumber() == Magic &&
OrderType() == OP_SELLLIMIT)
{
count++;
}
}
return(count);
}

//+------------------------------------------------------------------+
int BuyCount()
{
int count = 0;
for(int i=OrdersTotal()-1; i>=0; i--)
{
if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES) == true &&
OrderMagicNumber() == Magic &&
OrderType() == OP_BUY)
{
count++;
}
}
return(count);
}

//+------------------------------------------------------------------+
int SellCount()
{
int count = 0;
for(int i=OrdersTotal()-1; i>=0; i--)
{
if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES) == true &&
OrderMagicNumber() == Magic &&
OrderType() == OP_SELL)
{
count++;
}
}
return(count);
}

//+------------------------------------------------------------------+
double GetMinPrice() // Функция для определения максимальной цены за n баров
{
double minprice = -99999;

for (int i=BarCount-1; i>=0; i--)
{
double mp = iLow(Symbol(), PERIOD_CURRENT, i);
if(mp > minprice)
minprice = mp;
MinPrice = minprice;
}
return(MinPrice); //что вернет функция
}

//+------------------------------------------------------------------+
double GetMaxPrice() // Функция для определения максимальной цены за n баров
{
double maxprice = -99999;

for (int i=BarCount-1; i>=0; i--)
{
double mp = iHigh(Symbol(), PERIOD_CURRENT, i);
if(mp > maxprice)
maxprice = mp;
MaxPrice = maxprice;
}
return(MaxPrice); //что вернет функция


Изменено 5 ноября, 2018 пользователем d4vv

#5277


У вас функции GetMaxPrice() и GetMinPrice() типа void, а надо double, чтобы они возвращали значение цены. И когда хотите открыть ордер, вызовите эту функцию.
например:



Сергей огромное спасибо. Очень помогло.
Есть еще вопрос.

В том же коде учитель пишет ограничение по выставлению ордеров командой int count - как я понял. Но как написать так чтобы советник выставлял только один отложенный ордер на каждую вершину которую он определил?

Спойлер

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

extern int BarCount = 10;
extern int HourStart = 11;
extern double Lots = 0.01;
extern int StopLoss = 300;
extern int TakeProfit = 200;
extern int Magic = 12345;

double SL, TP, MaxPrice, MinPrice;

int ticket;


//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//---

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

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

if(TimeHour(TimeCurrent()) == HourStart)
{
if (BuyLimitCount() == 0 && BuyCount() == 0)
{
double price_open = GetMinPrice();
SL = NormalizeDouble(price_open- StopLoss*Point, 5);
TP = NormalizeDouble(price_open + TakeProfit*Point, 5);
ticket = OrderSend(Symbol(), OP_BUYLIMIT, Lots, price_open, 3, SL, TP, "", Magic, 0, Blue);

if(ticket Print("Не удалось открыть ордер");
}

if (SellLimitCount() == 0 && SellCount() == 0)
{
double price_open = GetMaxPrice();
SL = NormalizeDouble(price_open + StopLoss*Point, 5);
TP = NormalizeDouble(price_open - TakeProfit*Point, 5);
ticket = OrderSend(Symbol(), OP_SELLLIMIT, Lots, price_open, 3, SL, TP, "", Magic, 0, Red);

if(ticket Print("Не удалось открыть ордер");
}
}

Comment("Maxprice:" +DoubleToStr(GetMaxPrice(), 5) + "\n"+
"Minprice:" +DoubleToStr(GetMinPrice(), 5));

}

//+------------------------------------------------------------------+
int BuyLimitCount()
{
int count = 0;
for(int i=OrdersTotal()-1; i>=0; i--)
{
if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES) == true &&
OrderMagicNumber() == Magic &&
OrderType() == OP_BUYLIMIT)
{
count++;
}
}
return(count);
}

//+------------------------------------------------------------------+
int SellLimitCount()
{
int count = 0;
for(int i=OrdersTotal()-1; i>=0; i--)
{
if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES) == true &&
OrderMagicNumber() == Magic &&
OrderType() == OP_SELLLIMIT)
{
count++;
}
}
return(count);
}

//+------------------------------------------------------------------+
int BuyCount()
{
int count = 0;
for(int i=OrdersTotal()-1; i>=0; i--)
{
if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES) == true &&
OrderMagicNumber() == Magic &&
OrderType() == OP_BUY)
{
count++;
}
}
return(count);
}

//+------------------------------------------------------------------+
int SellCount()
{
int count = 0;
for(int i=OrdersTotal()-1; i>=0; i--)
{
if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES) == true &&
OrderMagicNumber() == Magic &&
OrderType() == OP_SELL)
{
count++;
}
}
return(count);
}

//+------------------------------------------------------------------+
double GetMinPrice() // Функция для определения максимальной цены за n баров
{
double minprice = -99999;

for (int i=BarCount-1; i>=0; i--)
{
double mp = iLow(Symbol(), PERIOD_CURRENT, i);
if(mp > minprice)
minprice = mp;
MinPrice = minprice;
}
return(MinPrice); //что вернет функция
}

//+------------------------------------------------------------------+
double GetMaxPrice() // Функция для определения максимальной цены за n баров
{
double maxprice = -99999;

for (int i=BarCount-1; i>=0; i--)
{
double mp = iHigh(Symbol(), PERIOD_CURRENT, i);
if(mp > maxprice)
maxprice = mp;
MaxPrice = maxprice;
}
return(MaxPrice); //что вернет функция


d4vv, прячьте ваш код под спойлер, а то модераторы будут ругаться :)
Как использовать спойлер (скрытый текст)
Так по логике советника, он и будет выставлять один лимитный ордер на минимуме и максимуме, определенном за BarCount баров.
У вас ошибка в функции GetMinPrice()
должно быть так:

double GetMinPrice() // Функция для определения минимальной цены за n баров
{
double minprice = 99999;

for (int i=BarCount-1; i>=0; i--)
{
double mp = iLow(Symbol(), PERIOD_CURRENT, i);
if(mp minprice = mp;
MinPrice = minprice;
}
return(MinPrice);
}

#5278

Так по логике советника, он и будет выставлять один лимитный ордер на минимуме и максимуме, определенном за BarCount баров.
У вас ошибка в функции GetMinPrice()



Да ошибку я исправил спасибо. Да советник выставляет один ордер все верно. Но я хотел написать так чтобы он выставлял по одному ордеру на каждый определивший хай или лоу. Т.е. если сейчас он определяет хай лоу - выставляет ордер и до его исполнения и закрытия более не выставляет ордера. Получается если он выставил ордер и если цена улетела то вернуться к нему сможет через несколько лет или позже.

Я проверил по другому убрав ограничения - и советник выставляет бесконечное количество на определившийся хай или лоу. Это я и хочу изменить т.е. я убираю совсем ограничение по исполненному ордеру а вот как ограничить по одному ордеру на каждый хай или лоу не могу сообразить.

И еще момент мне не понятен. На тестере если я ставлю BarCount = более 1000 то у меня работает только GetMaxPrice а GetMinPrice пишет 0.00000 ну и соответственно не ставит ордера.
#5279

Получается если он выставил ордер и если цена улетела то вернуться к нему сможет через несколько лет или позже.


У отложек нужно выставлять Срок истечения отложенного ордера..
В Вашей функции открытия задан 0 , т.е. до удаления (руками или кодом), либо активации.
#5280

У отложек нужно выставлять Срок истечения отложенного ордера..
В Вашей функции открытия задан 0 , т.е. до удаления (руками или кодом), либо активации.



Да с этим я не поспорю. Но это не много не то что я хотел написать в коде.
#5281

Но это не много не то что я хотел написать в коде.


Если я понял логику, то нужно проверять не просто наличие отложки, но и ее цену. Если цены отложенных ордеров не совпадают с ценой ХАЙ/ЛОУ, то выставляем ордер
#5282

Если определяю переменную через extern и после ее значения через коммент записываю ее описание, то когда в советнике в окне настроек заместь названия переменной пишется ее описание, как сделать чтоб писалось название переменной?

#5283

как сделать чтоб писалось название переменной?

переместите описание на другую строчку
#5284

Добрый день! Подскажите пожалуйста начинающему трейдеру:

если данная функция определяет максимум за n баров /свечей то как написать так чтобы определились все параметры данного максимума т.е. бара/свечи (опен клос хай лоу)?

Спойлер


double GetMaxPrice() // Функция для определения максимальной цены за n баров

{
double maxprice = -99999;

for (int i=BarCount-1; i>=0; i--)
{
double mp = iHigh(Symbol(), PERIOD_CURRENT, i);
if(mp > maxprice)
maxprice = mp;
MaxPrice = maxprice;
}
return(MaxPrice); //что вернет функция
}





Спасибо

Изменено 8 ноября, 2018 пользователем d4vv

#5285

если данная функция определяет максимум за n баров /свечей то как написать так чтобы определились все параметры данного максимума

в mql4 есть функции попроще, например iHighest(), которая возвращает номер бара, а зная номер можно узнать о баре всё, например Low[n] и т.д. О вызове функции iHighest() читайте в справке.
#5286

в mql4 есть функции попроще, например iHighest(), которая возвращает номер бара, а зная номер можно узнать о баре всё, например Low[n] и т.д. О вызове функции iHighest() читайте в справке.



Это здорово спасибо, но в программирование я пока тоже не силен, только учусь. Возможно ли с этой функции узнать либо номер бара либо его параметры? Если это не сверх сложно конечно...
#5287

Возможно ли с этой функции узнать либо номер бара либо его параметры?

Ладно, ещё разок..., Да, Вы узнаете номер бара, а с номером Вы будете знать о баре всё что только можно узнать! Откройте справку в метаедиторе, найдите функцию и почитайте.
#5288

Ладно, ещё разок..., Да, Вы узнаете номер бара, а с номером Вы будете знать о баре всё что только можно узнать! Откройте справку в метаедиторе, найдите функцию и почитайте.



Спасибо еще разок ;)

Тема форума: Обучение языку MQL4 под MetaTrader 4?
Или я пишу в какую то другую тему.

Зачем снимать видео создавать тему в форуме что писать потом - читайте справку. Круто. Спасибо еще разок..

Я прочитал но не понял. Если тема обучения можно объяснить или просто не отвечать.

Добавлено: 09-11-2018 10:14:37

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



Вопрос по тестеру стратегий. Как пользоваться вот этими столбцами см скриншот? Не могу разобраться. Дайте пожалуйста ссылку или просто на словах объясните.


Screenshot_125.jpg

Изменено 9 ноября, 2018 пользователем d4vv

#5289

Вопрос по тестеру стратегий. Как пользоваться вот этими столбцами см скриншот?

Эти столбцы относятся к оптимизации параметров тестируемого советника, нужно задать диапазон и шаг параметра и поставить галочку "Оптимизация".
ПС: научить пользоваться справкой - это часть нашей работы.
#5290

Всем добрый день!
Прошу совета по следующему вопросу.
Есть желание запрограммировать стратегию, использующую пересечение индикаторов Stochastic и Envelopes.
Индикатор Envelopes размещается в том же окне, что и стохастик (под графиком цены).
Визуально отследить пересечение просто, но это вручную надо открывать ордера.
"Непонятка" в том, что параметр "applied_price" индикатора Envelopes должен принимать значение "First Indicator's Data" или "Previous Indicator's Data". Как корректно написать код обращения к индикатору Envelopes с таким значением параметра? Величина 7 или 8 не проходит. График Envelopes по окончанию работы советника отображается в окне цены и пересечения со стохастиком не происходит.
Отдельный респект, если подскажете, как это можно реализовать средствами EA Forex Generator 6.

Изменено 10 ноября, 2018 пользователем VL712

#5291

Здраствуйте! Если номер тикета меняется при закрытий части лота, то есть ли такой нейзменный параметр по которому можно определить, что когда ордер полностью закрылся, понять что это тот ордер, который нам нужен?

#5292

есть ли такой нейзменный параметр по которому можно определить, что когда ордер полностью закрылся, понять что это тот ордер, который нам нужен?

Привет, нет такого параметра, ну разве что магик (если при открытии генерировать уникальный магик для каждого ордера). Некоторые читают коммент и находят оставшийся кусок. Я сортирую по времени - например появился сигнал на вход - с этого момента и до закрытия всех ордеров они обрабатываются как группа.
#5293

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

#5294

Большое спасибо за курс! Изучила все базовые уроки. Возник такой вопрос: когда пишем советник, торгующий по индикатору, есть ли возможность из советника считывать параметры индикатора, установленого на графике или же эти параметры можно только заводить вручную при запуске советника, как описано в одном из уроков?
Например, мы сначала рисуем МА с определенными параметрами (количество баров, тип усреднения...), а потом повторно заводим эти же параметры при запуске советника, который торгует по MA. А может ли в советнике быть реализована возможность автоматически считывать параметры с установленного на грaфике индикатора MA?

И вытекающий отсюда вопрос ,можно ли объединить советника и индикатор, чтобы одна программа и рисовала линии и торговала по ним?

#5295
Larcher Привет, хорошие вопросы! В рамках mql считывать параметры сторонних индикаторов нельзя, менять параметры вызванного советником индикатора - можно попробовать. Объединить код индикатора и советника можно - это распространено, но автоматически не получится и тем более в советниках трудно реализуемо рисование линий по буферам.
Самый распространённый случай - расчёт последнего значения индикатора в советнике и его использование как часть торгового сигнала, без сохранения истории в буфере и с минимальной визуализацией.
#5296

Здравствуйте! Подскажите пожалуйста ,в чём ошибка и как исправить! Спасибо!

IMG_20181116_152557.jpg

#5297

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


Спасибо за ответ. Я правильно поняла, что проще использовать индикатор и советник параллельно, чем объединять их в одном коде? И на практике как чаще делают?
#5298


Здравствуйте! Подскажите пожалуйста ,в чём ошибка и как исправить! Спасибо!

Это не ошибка, скорее предупреждение. Он-лайн переводчик: empty controlled statement found / найден пустой управляемый оператор! строка 63. Я тоже учусь, и учусь помогать, Если работает с предупреждением то хорошо если как у меня нет, то лучше целиком выкладывать код. Возможно ";" лишнее строка 63. да простят меня гуру.
#5299



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


Спасибо за ответ. Я правильно поняла, что проще использовать индикатор и советник параллельно, чем объединять их в одном коде? И на практике как чаще делают?

Можно подтягивать любой нестандартный индикатор через iCustom(), но это работает достаточно медленно, поэтому если есть возможность лучше перенести код индикатора в сову.
#5300

но это работает достаточно медленно, поэтому если есть возможность лучше перенести код индикатора в сову.


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

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

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