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

mobidik

-----
Привет, коллеги, привет всем кого знаю и не знаю! *hi*

Прошу помочь с таким кодом. Цель: сделать обновление советника каждое энное время, независимо от поступления тиков:
PHP:
[SIZE="2"]
//+------------------------------------------------------------------+
//| Timer function                                                   |
//+------------------------------------------------------------------+
void OnTimer()
  {
   Comment(TimeCurrent());
  }
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
void OnInit()
  {
//--- create timer
   EventSetTimer(1);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//--- destroy timer
   EventKillTimer();
   Comment(""); } [/SIZE]

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

В комментарий выводится кол-во секунд неравномерно. Идут задержки зависимые от поступления тиков. Нужно, чтобы отсчет велся равномерно, без пропусков.

Жду помощи от тех, кто смог решить однажды такую задачку! :please:

Все верно у тебя работает. TimeCurrent() - это последнее известное время брокера, которое терминал получает с приходом новых данных. Если в "Обзоре рынка" находится только один инструмент - данные TimeCurrent будут обновляться по тиково данного инструмента. Если в "Обзоре рынка" находится, скажем 3 инструмента, то обновление времени будет синхронизироваться уже по 3 инструментам, максимум точности можно получить, если "Обзоре рынка" показать все инструменты - выше этой точности уже не получить. Т.е., если случится так, что по всем инструментам наступит пауза, не будут идти тики, то и время TimeCurrent не обновится. TimeCurrent - это последнее известное время брокера. Это относится только при работе с ф-цией OnTimer() . Как вариант, для теста, замени TimeCurrent() на TimeLocal(), и посмотри как будет происходить обновление данных времени, но это уже будет время компа.

PS.
Для более частого обновления данных, можешь воспользоваться ф-цией EventSetMillisecondTimer(), тогда обновления будет чаще 1 сек, но не исключает наличия пауз.
 
Последнее редактирование:

e-partner

Местный знаток
Все верно у тебя работает. TimeCurrent() - это последнее известное время брокера, которое терминал получает с приходом новых данных. Если в "Обзоре рынка" находится только один инструмент - данные TimeCurrent будут обновляться по тиково данного инструмента. Если в "Обзоре рынка" находится, скажем 3 инструмента, то обновление времени будет синхронизироваться уже по 3 инструментам, максимум точности можно получить, если "Обзоре рынка" показать все инструменты - выше этой точности уже не получить. Т.е., если случится так, что по всем инструментам наступит пауза, не будут идти тики, то и время TimeCurrent не обновится. TimeCurrent - это последнее известное время брокера. Это относится только при работе с ф-цией OnTimer() . Как вариант, для теста, замени TimeCurrent() на TimeLocal(), и посмотри как будет происходить обновление данных времени, но это уже будет время компа.

PS.
Для более частого обновления данных, можешь воспользоваться ф-цией EventSetMillisecondTimer(), тогда обновления будет чаще 1 сек, но не исключает наличия пауз.

Спасибо большое, получилось! :D:embrace: :) Еще на всякий случай обновил МТ4 и стал теперь компилировать только в новом MetaEditor'e.
Даже Каспера выключил! :)


Появился вопрос: а можно ли как-то получить в Советнике время сервера с точностью до миллисекунд? Например, получаем: 23.09.2016 14час. : 53мин. : 54000 миллисекунд? То есть ровно в 54 секунды.
 
Последнее редактирование:

mobidik

-----
Спасибо большое, получилось! :D:embrace: :) Еще на всякий случай обновил МТ4 и стал теперь компилировать только в новом MetaEditor'e.
Даже Каспера выключил! :)


Появился вопрос: а можно ли как-то получить в Советнике время сервера с точностью до миллисекунд? Например, получаем: 23.09.2016 14час. : 53мин. : 54000 миллисекунд? То есть ровно в 54 секунды.

На счет Каспера - это как выстрел в небо, разве что, если комп слабенький...
На счет "с точностью до миллисекунд" - нет, т.к. дискретизация времени 1 сек. А "ровно в 54 секунды" - да, можно, только если в это время будет приход новых данных. Задавать условие на "==" - не стоит, можно проскочить.
 

Kayros

Интересующийся
Прошу подсказать в чем ошибка.
Ставлю в сову блок на подсчет открытых ордеров на покупку. Вот в таком виде:

int CountBuy()
{
int count = 0;
for (int trade=OrdersTotal(); trade<=0; trade--)
{
if (OrderSelect(trade, SELECT_BY_POS, MODE_TRADES))
{
if(OrderSymbol() == Symbol() && OrderMagicNumber() == Magic && OrderType() == OP_BUY)
count++;
}
}
return(count);
}

Ну потом (на самом деле до описания функции, а сама функция отдельным блоком после всего идет) по условию if (CountBuy()<=0) запускаю покупку.
Компилируется нормально.
Только в тестере сова виснет намертво.
 

grom2016

Новичок форума
Kayros,по моему если ты уменьшаешь счетчик, то должен писать
for (int trade=OrdersTotal()-1; trade<=0; trade--)
потому что нумерация идет от нуля (0,1,2,3,4,5) всего шесть ордеров, но ордера номер 6 у тебя нет
 

mobidik

-----
Прошу подсказать в чем ошибка.
Ставлю в сову блок на подсчет открытых ордеров на покупку. Вот в таком виде:

int CountBuy()
{
int count = 0;
for (int trade=OrdersTotal(); trade<=0; trade--)
{
if (OrderSelect(trade, SELECT_BY_POS, MODE_TRADES))
{
if(OrderSymbol() == Symbol() && OrderMagicNumber() == Magic && OrderType() == OP_BUY)
count++;
}
}
return(count);
}

Ну потом (на самом деле до описания функции, а сама функция отдельным блоком после всего идет) по условию if (CountBuy()<=0) запускаю покупку.
Компилируется нормально.
Только в тестере сова виснет намертво.

Kayros,по моему если ты уменьшаешь счетчик, то должен писать
for (int trade=OrdersTotal()-1; trade<=0; trade--)
потому что нумерация идет от нуля (0,1,2,3,4,5) всего шесть ордеров, но ордера номер 6 у тебя нет

Kayros, на счет того, что "-1", согласен, но ошибка в другом.
trade<=0 и как тут выполнится следующая часть условия? Может следует что-то развернуть?
 

Ugar

Гуру форума
Kayros,по моему если ты уменьшаешь счетчик, то должен писать
for (int trade=OrdersTotal()-1; trade<=0; trade--)
потому что нумерация идет от нуля (0,1,2,3,4,5) всего шесть ордеров, но ордера номер 6 у тебя нет
Про нумерацию всё правильно. Только эта ошибка вряд ли приводит к зависанию советника в тестере. Так как сначала выполняется проверка выбран ли ордер, только потом проверки на символ маджик и подсчёт ордеров.
if (OrderSelect(trade, SELECT_BY_POS, MODE_TRADES))
Ордер по несуществующему индексу не выбирается, значит и условие не выполняется.
 

Kayros

Интересующийся
Kayros,по моему если ты уменьшаешь счетчик, то должен писать
for (int trade=OrdersTotal()-1; trade<=0; trade--)
потому что нумерация идет от нуля (0,1,2,3,4,5) всего шесть ордеров, но ордера номер 6 у тебя нет
Благодарю. Это и в самом деле недочет, который следует устранить. Хоть и правы другие участники - виснет не из-за него (исправление результата не принесло). Но убрать его надо )
 

grom2016

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

PS вобщем ошибка тут в этой строке
у меня в советнике написано так: for (int i=OrdersTotal()-1; i>=0; i--)
и ключ здесь - это знак i>=0
если ставишь i<=0 то тестер "зависает" т.е. просто не открывает сделки
правильная запись в данном случае:
for (int trade=OrdersTotal()-1; trade>=0; trade--)

в первоначальном варианте, получается на старте у нас ОрдерсТотал равно 0, условие trade<=0 выполняется, и потом уменьшается счетчиком, и опять выполняется, получается бесконечный цикл
 
Последнее редактирование:

Kayros

Интересующийся
в первоначальном варианте, получается на старте у нас ОрдерсТотал равно 0, условие trade<=0 выполняется, и потом уменьшается счетчиком, и опять выполняется, получается бесконечный цикл

Да, так и оказалось. После исправления программа пошла. Благодарю еще раз. :)
 

Violetta

Новичок форума
Уважаемые программисты, подскажите как разделить правильно фракталы upper и lower в разные массивы, чтобы поиск и построение линий по 3 ближайшим фракталам отрисовывал две линии по upper и lower за n баров. Или киньте ссылку как это делается. Help!
 

Ugar

Гуру форума
Уважаемые программисты, подскажите как разделить правильно фракталы upper и lower в разные массивы, чтобы поиск и построение линий по 3 ближайшим фракталам отрисовывал две линии по upper и lower за n баров. Или киньте ссылку как это делается. Help!
Не обязательно для этого использовать массив. Хотя, использовать 4 переменных или массив с 4 ячейками, дело вкуса.
В цикле перебирай бары с вызовом iFractals(...); для верхних и нижних фракталов. Как находится, пиши в массив или переменную. Как нашёл все нужные, прерывай цикл.
 

Nart60

Активный участник
Знатоки, подскажите, как в коде советника отразить следующую ситуацию:
после закрытия ордера по стопу (сл или тп или по трейлинг стоп) по данной паре, на котором поставлена сова. следующий ордер чтобы открывался только после прохождения (пересечения) цены на графике определенной линии А, SSA называется линия.
Спасибо!

Советник в следующем посту, все это нужно для его доделки-переделки.
 
Последнее редактирование:

Nart60

Активный участник
Советник вроде бы работает (мое детище, программиста без году неделя), простой. особенно хорошо показывает в периоды волатильности.
Стала проблема, сова открывает ордер по той валютной паре, по которой уже сигнал отработался и ордер закрыт с прибылью. То есть надо дописать в коде, чтобы после закрытия ордера с прибылью в том направлении (покупка или продажа) чтобы больше советник не торговал, не открывал ордер, пока цена повторно не пересечет линию (А или В) облако Кумо по Ишимоку. Если кто умеет, прошу сделать. Сам, конечно, тоже попробую, хотя не представляю как это вообще сделать. Наверное какой то возврат цикла, или функции надо сделать или как там его. Или может дописать надо if.
 

Вложения

  • Bella TT.mq4
    3,6 КБ · Просмотры: 34

AlexeyVik

Программист mql4 mql5
Советник вроде бы работает (мое детище, программиста без году неделя), простой. особенно хорошо показывает в периоды волатильности.
Стала проблема, сова открывает ордер по той валютной паре, по которой уже сигнал отработался и ордер закрыт с прибылью. То есть надо дописать в коде, чтобы после закрытия ордера с прибылью в том направлении (покупка или продажа) чтобы больше советник не торговал, не открывал ордер, пока цена повторно не пересечет линию (А или В) облако Кумо по Ишимоку. Если кто умеет, прошу сделать. Сам, конечно, тоже попробую, хотя не представляю как это вообще сделать. Наверное какой то возврат цикла, или функции надо сделать или как там его. Или может дописать надо if.
Вот основные слова сказанные тобой. Они и помогут решить проблему.
Пересечение вверх, это было ниже стало выше... но не просто сейчас выше, значит пересечение было. Надеюсь что этой подсказки достаточно.
 

Nart60

Активный участник
Вот основные слова сказанные тобой. Они и помогут решить проблему.
Пересечение вверх, это было ниже стало выше... но не просто сейчас выше, значит пересечение было. Надеюсь что этой подсказки достаточно.

Задача такая. Ишимоку. 1-ый вариант открытия сделки на покупку: Линия тенкан пересекает снизу вверх линию киджун (золотой крес) - это первое условие и второе условие для открытия этой же сделки- при этом цена открытия должна находиться ниже линии сенкоспан А или В, в зависимости которая из них в данный момент выше (не важно сенкоспан А или В, важно чтобы из них если А выше, то естесственно речь идет об А линии и наоборот, если В выше- то чтобы цена при открытии сделки была ниже этой линии В, то есть о верхней линии, о верхней границе облако Кумо идет речь).;
2-ой вариант - открытие сделки на продажу: Линия тенкан пересекает киджун сверху вниз (мертвый крест) открываем сделку на продажу. но при этом как и в первом случае второе условие для открытия сделки: чтобы линия В или А находилась выше цены открытия, в момент открытия сделки, то есть чтобы цена находилась выше нижней границы облако Кумо ( линия А или В в зависимости от того какая из этих линий в данный момент открытия позиции нижняя часть, нижняя граница облако Кумо по Ишимоку).

Далее. Дело в том, что после написания этого кода советник продолжает открывать сделки когда цена уже давно отошла от облака вверх или вниз и одна открытая первая сделка с прибылью закрыта и это уже факт свершившийся. но программа имеет задание открывать позиции если цена вше Линии А или В и тенканом пересечен киджун. Но тут дело в том что не задано в коде второе условие, чтобы выполнялось второе условие- чтобы до открытия ордера на покупку- цена должна дойти, пробраться, находиться ниже верхней линии облако кумо (А ил В. как известно они меняют позиции то одна верхняя часть облако- то вторая образует верхнюю часть и наоборот, поэтому не важно о которой речь идет- об этом сказано уже выше). И при продаже в коде должно быть прописано выполнение второго условия - цена должна находиться выше нижней линии облако кумо (А или В) и при этом не забываем, что выполнено первое условие открытия сделки- тенкан пересек киджун сверху вниз. То есть, надо прописать в коде оба условия для открытия сделки.
Чуть позже хотел попросить пришить трейлинг стоп. Спасибо! Мастера. на вас надежда.
 
Последнее редактирование:

Nart60

Активный участник
Вот основные слова сказанные тобой. Они и помогут решить проблему.
Пересечение вверх, это было ниже стало выше... но не просто сейчас выше, значит пересечение было. Надеюсь что этой подсказки достаточно.

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

vladradon

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

Задай буловскую флаговую переменную типа
bool Open=true;
Когда доходит до открытия
if (Open) {OrderSend(....); Open=false;}
и сбрасываешь Open в true, когда цена по индикатору вернется в какое-то исходное положение или пересечет противоположное направление.
Что-то типа того. Можно 2 такие переменные добавить на бай и селл отдельно и еще дополнительно проверять наличие в рынке уже открытого ордера в каком-то направлении, чтобы если ордер не отработал и цена ушла в минус и снова вернулась, а сов это посчитал, как новый сигнал, не сбрасывал флаг в true.
 

Kayros

Интересующийся
Блин, ну я не знаю уже! Очень зол.
Мой эксперт не хочет открывать лоты на покупку. На продажу - сколько угодно. А на покупку -балалайка! Прошу показать, может у меня глаз кривой. Вот часть кода про продажу и про покупку:

void OnTick()
{
PriceHigh = NormalizeDouble(iCustom(Symbol(), PERIOD_CURRENT,"X_C_O_D_E", SignalPeriod, Deviat, 1, 2),Digits);
PriceLow = NormalizeDouble(iCustom(Symbol(), PERIOD_CURRENT,"X_C_O_D_E", SignalPeriod, Deviat, 0, 2),Digits);
Comment("верх"+DoubleToString(PriceHigh, Digits())+"\n"+ "низ"+DoubleToString(PriceLow, Digits()));
//+--- Выставляем ордер на покупку
if (OrdersTotal()<=0)
{
if(Open[2]<PriceHigh && Close[1]>PriceHigh) //Если ордеров на покупку нет, открытие бара ниже, а закрытие выше или равно, и прошло тиков не более 4, то...
ticket=OrderSend(Symbol(), OP_BUY, Lots, Ask, Slippage, PriceLow, NormalizeDouble(Ask+TakeProfit*Point, Digits), "TMA", Magic, 0, Green); // Открываем сделку на покупку
Alert (GetLastError());
}
//+---Задаем цикл для расчета количества активных ордеров на продажу -------------------+

if (CountSell()<=0)
{
if(Open[1]>=PriceLow && Close[1]<PriceLow && Volume[0]<2) //Если открытие бара выше, а закрытие ниже ил равно, и прошло тиков не более 4, то...
ticket=OrderSend(Symbol(), OP_SELL, Lots, Bid, Slippage, PriceHigh, NormalizeDouble(Bid-TakeProfit*Point, Digits), "TMA", Magic, 0, Red); // Открываем сделку на продажу
}

Ну и далее по тексту. Вначале идет оператор своего индюка и он берет данные корректно - это подтверждено комментами и в продажном лоте потом СтопЛосс на это ориентируется. А вот покупной скрипт не фигачит. Вообще не ставит лоты. И алерта ошибки нету. Хрень какая-то...
 
Последнее редактирование модератором:
Верх