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

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

#4776


Здравствуйте, уважаемые!
Проблема вот в чем: при инициализации советника необходимо иметь историю в несколько недель по текущему инструменту и на текущем ТФ.
Как организовать проверку средствами MQL и, при необходимости, подкачку истории?
Спасибо.



Можно создать массив и заполнить его функцией ArrayCopySeries. Если с историей все ок, вернет кол-во скопированных элементов. Если же нет, вернет -1 в случае неудачи, или начнет качать историю и вернет ошибку 4066 (запрошенные исторические данные в состоянии обновления)
#4777

вернет кол-во скопированных элементов. Если же нет, вернет -1 в случае неудачи, или начнет качать историю и вернет ошибку 4066 (запрошенные исторические данные в состоянии обновления)


А чем он(а) отличается в данном случает от Bar?
Или все таки производится попытка подкачать историю?
В сети видел решения на dll, но как-то хочется внутренними резервами обойтись...
Попробовал, не подкачивает историю ArrayCopySeries, возвращает количество имеющихся баров.
Ручная прокрутка "решает" проблему.. :(

Изменено 22 августа, 2017 пользователем usver73

#4778

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

#4779

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


Попробовал.
iTime на определенной глубине ошибку не дает, возвращает 0, т.е. 01.01.1970.
Open(i) выдает ошибку "array out of range".

Изменено 23 августа, 2017 пользователем usver73

#4780

Попробуй все таки ArrayCopySeries через цикл. Должно сработать. Раньше точно работало.

#4781

Попробуй все таки ArrayCopySeries через цикл. Должно сработать. Раньше точно работало.



Так?
   datetime arr[];
for (int k=0; k {
int CountBarsArr= ArrayCopySeries(arr,MODE_TIME,Symbol(),_Period);
Print(__FUNCTION__ , " Скопировано ", CountBarsArr, " баров из истории в массив");
Sleep(500);
}

Результат:
Цитата

AUDUSDf,H4: OnInit Скопировано 1707 баров из истории в массив
AUDUSDf,H4: OnInit Скопировано 1707 баров из истории в массив
AUDUSDf,H4: OnInit Скопировано 1707 баров из истории в массив
AUDUSDf,H4: OnInit Скопировано 1707 баров из истории в массив
AUDUSDf,H4: OnInit Скопировано 1707 баров из истории в массив

#4782

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

void CloseOrders(int dir)
{
double PriceClose = 0;
color Color = Black;

for (int i = OrdersTotal()-1; i>=0; i--)
{
if (!OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) continue;
if (OrderSymbol()!=Symbol() || OrderMagicNumber()!=MagicNumber) continue;

if (OrderType() == dir)
{
if((SignalExit(dir) && ExitProfit (dir, ExitPips)) || (ExitTimeProfit(dir, OrderExitHour) && ExitProfit (dir, ExitPips)))
{
if (OrderType() == OP_BUY) {PriceClose = Bid; Color = Blue;}
if (OrderType() == OP_SELL) {PriceClose = Ask; Color = Red;}

{
if(!OrderClose(OrderTicket(), OrderLots(), PriceClose, Slippage, Color))
{
Print ("Не удалось закрыть ордер");
}
}
}
}
}
}

PS; извините не разобрался как отправить функцию под спойлер

#4783

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

В журнале ошибок нет. Получается покупки просто пересиживаются в случае попадания в просадку.

mart001.mq49 скач.
mart001.ex45 скач.

Изменено 27 августа, 2017 пользователем lordsamven

#4784

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

Автор#4785


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

В журнале ошибок нет. Получается покупки просто пересиживаются в случае попадания в просадку.



День добрый!

Всё в порядке, проблем не вижу.
Работает как часы...

2017-1.png
2017-2.png

#4786



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

В журнале ошибок нет. Получается покупки просто пересиживаются в случае попадания в просадку.



День добрый!

Всё в порядке, проблем не вижу.
Работает как часы...

Не совсем так, обратите внимание что в журнале модифицируются только ордера sell, а ордера типа buy ниодного модифицированного нет. На имитации видно что ордера buy просто пересиживают просадку до сробатывания takeprofit.

Добавлено: 30-08-2017 18:58:34




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

В журнале ошибок нет. Получается покупки просто пересиживаются в случае попадания в просадку.



День добрый!

Всё в порядке, проблем не вижу.
Работает как часы...

Не совсем так, обратите внимание что в журнале модифицируются только ордера sell, а ордера типа buy ниодного модифицированного нет. На имитации видно что ордера buy просто пересиживают просадку до сробатывания takeprofit.


Ниже прикрепил скрин примера. Выделил сделку 19 buy с явным пересиживанием без наращивания дополнительных позиций.

пример.jpg

Изменено 30 августа, 2017 пользователем lordsamven

Автор#4787


В журнале ошибок нет. Получается покупки просто пересиживаются в случае попадания в просадку.



Да, увидел.
Проблема в функции FindLastOrderType() .
Она недописана.
Замените её на эту:


//+------------------------------------------------------------------+
//| Expert function |
//+------------------------------------------------------------------+
int FindLastOrderType()
{
int order_type = -1;
int oldticketnumber = 0;
int ticketnumber = 0;

for(int cnt = OrdersTotal() - 1; cnt >= 0; cnt--)
{
if (OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES))
{
if (OrderSymbol() == Symbol() && OrderMagicNumber() == Magic)
{
oldticketnumber = OrderTicket();
if (oldticketnumber > ticketnumber)
{
order_type = OrderType();
ticketnumber = oldticketnumber;
}
}
}
}
return (order_type);
}
#4788

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

Вам надо переписать функцию ExitTimeProfit(dir, OrderExitHour) сейчас она закрывает ордера не по времени жизни ордера, а по некому времени OrderExitHour.
Или вообще её выкинуть и заменить выражением (TimeCurrent() - OrderOenTime())/*в секундах*/ > ВремяЖизни
#4789

Подскажите пожалуйста что исправить в данной функции, чтобы она закрывала только тот ордер на котором сработал сигнал (в частности закрытие по времени), а не все открытые при срабатывании сигнала на одном из ордеров?
Вам надо переписать функцию ExitTimeProfit(dir, OrderExitHour) сейчас она закрывает ордера не по времени жизни ордера, а по некому времени OrderExitHour.
Или вообще её выкинуть и заменить выражением (TimeCurrent() - OrderOenTime())/*в секундах*/ > ВремяЖизни



Это выражение и написано как раз в этой функции ,а OrderExitHour это и есть ВремяЖизни, вынесенное в глобальные переменные. Просто когда открыто несколько ордеров (допустим BUY) соответственно с разным временем открытия, при достижении ВремениЖизни одним из ордеров, почему-то закрываются и все остальные, открытые гораздо позже.

Изменено 31 августа, 2017 пользователем Leery

#4790
Leery может код функции дадите глянуть и проверьте время жизни в секундах
#4791

Leery может код функции дадите глянуть и проверьте время жизни в секундах



Нет проблем ( ВремяЖизни не меняется! Первый ордер закрывается правильно и остальные одновременно с ним)

Спойлер

extern int OrderExitHour = 16;

//+------------------------------------------------------------------+
bool ExitTimeProfit (int dir, int ExitHour)
{
if(!UseExitTimeProfit) return(true);
for (int i = OrdersTotal()-1; i>=0; i--)
{
if (!OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) continue;
if (OrderSymbol()!=Symbol() || OrderMagicNumber()!=MagicNumber) continue;
if ((OrderType()==OP_BUY && dir==OP_BUY) || (OrderType()==OP_SELL && dir==OP_SELL))
{
if (TimeCurrent()-OrderOpenTime() >= 60*60*ExitHour) return(true);
}
}
return(false);
}
//+------------------------------------------------------------------+
bool ExitProfit (int dir, double ExitProfitPips)
{
if(!UseExitProfit) return(true);
for (int i = OrdersTotal()-1; i>=0; i--)
{
if (!OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) continue;
if (OrderSymbol()!=Symbol() || OrderMagicNumber()!=MagicNumber) continue;
if (OrderType()==OP_BUY && dir==OP_BUY)
{
if (Bid-OrderOpenPrice() > ExitProfitPips*_Point) return(true);
}
if (OrderType()==OP_SELL && dir==OP_SELL)
{
if (OrderOpenPrice()-Ask > ExitProfitPips*_Point) return(true);
}
}
return(false);
}
//+------------------------------------------------------------------+
//| Функция закрытия ордеров |
//+------------------------------------------------------------------+
void CloseOrders(int dir)
{
double PriceClose = 0;
color Color = Black;

for (int i = OrdersTotal()-1; i>=0; i--)
{
if (!OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) continue;
if (OrderSymbol()!=Symbol() || OrderMagicNumber()!=MagicNumber) continue;

if (OrderType() == dir)
{
if((SignalExit(dir) && ExitProfit (dir, ExitPips)) || (ExitTimeProfit(dir, OrderExitHour) && ExitProfit (dir, ExitPips)))
{
if (OrderType() == OP_BUY) {PriceClose = Bid; Color = Blue;}
if (OrderType() == OP_SELL) {PriceClose = Ask; Color = Red;}

{
if(!OrderClose(OrderTicket(), OrderLots(), PriceClose, Slippage, Color))
{
Print ("Не удалось закрыть ордер");
}
}
}
}
}
}



В void OnTick() идет проверка только есть ли открытые ордера.
#4792
Leery В закрывающей функции цикл по ордерам, в функции проверки времени жизни свой цикл по ордерам - который доходит до нужного ордера и выдаёт = тру; в это время в закрывающей функции другой ордер.
Мой совет: избавьтесь от лишних циклов, все проверки в один цикл. если не хотите менять структуру программы, то имейте в виду: в основном цикле ордер выбирается селектом - и становится активным, с ним можно работать в других функциях без дополнительных манипуляций.
#4793
Oll Спасибо огромное. буду исправлять
#4794

Здравствуйте.
Если при открытии ордера есть желание контролировать спред, то нужно проверить при открытии как БАЙ так и СЕЛЛ ордеров или можно проверять только при открытии БАЙ?
Спасибо.

#4795

Дык какая разница? или без СЛ торгуете?

#4796

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

#4797

без стопов :)
Я спросил с точки зрения входа по лучшей цене.
Когда спред расширяется (больше интересует во время открытия рынка), то раздвигаются обе цены или только Аск подпрыгивает?

Изменено 5 сентября, 2017 пользователем usver73

#4798

Вот тиковый график в ролловер.

EURAUD.JPG
GBPUSD.JPG

Изменено 6 сентября, 2017 пользователем master_255

#4799

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

Al.ex40 скач.
Al.mq44 скач.

#4800


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

Посмотрел. Это то же самое, что советовал machine. Результат отрицательный.
Добавил Принт в подкачку часовых свеч. Выдает
0	20:04:25.620	QuoteLoader AUDCADf,H1: Load H1 1970.01.01 00:00
0 20:04:25.620 QuoteLoader AUDCADf,H1: Load H1 1970.01.01 00:00
0 20:04:25.620 QuoteLoader AUDCADf,H1: Load H1 1970.01.01 00:00
0 20:04:25.620 QuoteLoader AUDCADf,H1: Load H1 2017.05.10 11:00
0 20:04:25.620 QuoteLoader AUDCADf,H1: Load H1 2017.05.10 12:00
0 20:04:25.620 QuoteLoader AUDCADf,H1: Load H1 2017.05.10 13:00
0 20:04:25.620 QuoteLoader AUDCADf,H1: Load H1 2017.05.10 14:00
, т.е. в результат попадает только существующая история :(

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

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