Jump to content
Rosh

Статьи по программированию на MQL-4.

Recommended Posts

Player 2

Да, возможно это неплохой вариант для индикатора. Я индикаторы не писал так что точно не могу сказать заработает или нет. У меня проблема с советником. Вот его лог:

 

2006.04.05 09:37:24;start check history download: Error=0 Description: no error

2006.04.05 09:37:24;start ihigh check: ihigh=1.1622: Error=0 Description: no error

2006.04.05 09:37:24;start ibars check: ibars=31311: Error=0 Description: no error

2006.04.05 09:37:24;Start called. Bid=1.1622 Ask=1.1626 High[0]=1.1622 Low[0]=1.1622 Bars=31311

2006.04.05 09:37:24;Calling GetSignal()

2006.04.05 09:37:25;BuyLevel=1.1649 SellLevel=1.1639 CallsCount=1

2006.04.05 09:37:25;p1pc0openbuy: trying to open order

2006.04.05 09:37:25;p1pc0openbuy: Error=4051 Description: invalid function parameter value

2006.04.05 09:37:25;p1pc0opensl1: trying to open order

2006.04.05 09:37:25;p1pc0opensl1: Error=4051 Description: invalid function parameter value

2006.04.05 09:37:40;start check history download: Error=0 Description: no error

2006.04.05 09:37:40;start ihigh check: ihigh=1.1625: Error=0 Description: no error

2006.04.05 09:37:40;start ibars check: ibars=31413: Error=0 Description: no error

2006.04.05 09:37:40;Start called. Bid=1.1623 Ask=1.1627 High[0]=1.1625 Low[0]=1.1621 Bars=31413

2006.04.05 09:37:40;Calling GetSignal()

2006.04.05 09:37:41;BuyLevel=1.1627 SellLevel=1.1634 CallsCount=2

2006.04.05 09:37:41;p1pc0openbuy: trying to open order

2006.04.05 09:37:41;p1pc0openbuy: Error=4109 Description: trade is not allowed

2006.04.05 09:37:41;p1pc0opensl1: trying to open order

2006.04.05 09:37:41;p1pc0opensl1: Error=4109 Description: trade is not allowed

2006.04.05 09:37:57;start check history download: Error=0 Description: no error

2006.04.05 09:37:57;start ihigh check: ihigh=1.1625: Error=0 Description: no error

 

Это я сегодня утром запустил МТ4 после перерыва в несколько часов. В функции start() вызываются функции High, iHigh, iBars и проверяется какие при этом были ошибки (по идее именно эти функции выдают ошибку err_history_will_updated). Но при первом тике, когда история еще не загружена (это видно по количеству баров=31311) такой ошибки не возникает. Дальше сама система, которая дает сигнал на основе истории, дает его неправильно. В результате при попытке установить ордер возникает ошибка invalid function parameter value. При следующем вызове start() история уже подгружена (Bars=31413), и все начинает работать в нормальном режиме, сигнал система дает уже другой, т.к. использует только что подгруженную историю.

У меня был случай, когда при недогруженных данных система решила что открытый ордер надо закрыть и закрыла его. На следующем тике, когда данные подгрузились, система решила что она его зря закрыла и открыла по новой. Вот такие фокусы. Интересно, разве никто с этим не сталкивался?

 

Думаю тут можно только извращаться. То есть, например, делать так:

 

В функции start() проверять:

если это первый ее запуск, то сделать задержку для загрузки данных и выйти.

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

В остальных случаях, то есть когда тик не первый и предыдущий тик был недавно, нормально работать.

 

Код будет вроде такой:

 

глобальные переменные:

int CallsCount;

datetime LastTickTime;

 

в init():

CallsCount=0;

LastTickTime=0;

 

в start():

CallsCount++;

if (CallsCount==1 || CurTime()-LastTickTime>MaxAllowedTime)

{LastTickTime=CurTime();Sleep(5000);return(0);}

 

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

Share this post


Link to post
Share on other sites
GameOver

сделал вроде

вот код

int q1=-1;
bool show=false;

int start(){

  if (q1!=Bars){ q1=Bars; Sleep(1000);show=false; return(0);}

  if (show==true && isFirst==Time[0]) return(0); else isFirst=Time[0]; // запускаеца тока на 1м тике

  // заполнили и отобразили точки демарка
  if (qBars==0) qBars=Bars-LevDP;
  ArrayInitialize(Buf1,0.0);
  ArrayInitialize(Buf2,0.0);
  for (int cnt=qBars;cnt>LevDP;cnt--) {
     Buf1[cnt]=DemHigh(cnt,LevDP);
     Buf2[cnt]=DemLow(cnt,LevDP);
  }
  show=true;

 

------------------

новую версию демарка то выкладывать? или не надо никому? :-]


Никаких крыльев нету. Просто умираешь и все. (гусеница)

Share this post


Link to post
Share on other sites
GameOver

или еще проще

int qBars=-1; double qTime=0; // переменные для ликвидации глюков при загрузке

int deinit() {
  Comment("");
  ArrayInitialize(Buf1,0.0);
  ArrayInitialize(Buf2,0.0);
  // kill objects

}

int start(){
  if (qBars!=Bars){ deinit(); Sleep(1000); qBars=Bars; qTime=0; return(0);}
  if (qTime==Time[0]) return(0);
  qTime=Time[0]; // запускаеца тока на 1м тике

 

прорисовка идет с приходом 1го тика.


Никаких крыльев нету. Просто умираешь и все. (гусеница)

Share this post


Link to post
Share on other sites
Player 2

Для того чтобы не было того глюка что я писал с недогрузкой истории я у себя в советнике сделал так:

глобальные переменные:

datetime LastTickTime;

init():

int init()
 {
//----
     LastTickTime = 0;
//----
  return(0);
 }

start():

int start()
 {
//----
     if (CurTime() - LastTickTime > 60) {
     for (int kk=10;kk>=0;kk--) {
     Comment("Interval between ticks is exceeded. Sleep "+kk+" sec.");
     Sleep(1000);}
     RefreshRates();}
//========================================
//основной код функции start()
//========================================
     RefreshRates();
     LastTickTime = CurTime();
//----
  return(0);
 }

Сегодня ночью это работало. Работает так. Если врубил МТ4 только что то при приходе первого тика оно ждет 11 секунд перед его обработкой чтобы загрузились данные графика. Если был обрыв связи (то есть если тика не было больше 1 минуты) то делается то же самое. Несколько раз было так что связь не обрывалась но тика не было более минуты, тогда все равно делается задержка которая не нужна, но тик при этом не пропускается и думаю тут больших проблем быть не должно, тем более что такое бывает при низкой частоте тиков, то есть при низкой волатильности, где быстрая реакция советника не обязательна.

 

ЗЫ Никто не знает как зарегиться на metaquotes.com? Уже второй раз регюсь и никто не отвечает. Задницу бы им надрать.

 

Да, еще, команды RefreshRates(); LastTickTime = CurTime(); стоят именно в конце функции start() не просто так, а со смыслом.

Share this post


Link to post
Share on other sites
-FOX-

если ты выставляешь лимитник или стоп-ордер, будет возвращать

OP_BUYLIMIT или OP_BUYSTOP

когда поз откроеца, вернет OP_BUY

 

Спасибо, что ответил, оч. рад :) Но чем мне это поможет? Ведь какую бы константу я OrderType`у не указывал, всеравно он удаляет раньше чем мне нужно. Вот пример:

int start()
 {
int total=OrdersTotal();
  if(total<1)
{
int buy= OrderSend(Symbol(),OP_BUYSTOP,0.1,Ask+4*Point,3,Ask-16*Point,Ask+24*Point,"level 1",255,0,CLR_NONE);
int sell= OrderSend(Symbol(),OP_SELLSTOP,0.1,Ask-7*Point,3,Ask+13*Point,Ask-27*Point,"level 1",255,0,CLR_NONE);
if(OrderType()==OP_BUY) OrderDelete(sell); 
if(OrderType()==OP_SELL) OrderDelete(buy); 

}   
 }

Вроде бы, если я все правильно понимаю, я написал, что если ордер открывается в позицию на покупку, то удалить ордер "sell". Если ордер открывается в позицию на продажу, то удалить ордер "buy". МТС же удаляет ордер сразу после выставления ордеров. :( Вот результаты теста:(

2006.04.07 09:55:24 2006.02.16 22:25 Tester: order #3, buy 0.10 EURUSD is opened at 1.1903

2006.04.07 09:55:24 2006.02.16 21:57 1 EURUSD,M1: delete #4 sell stop 0.10 EURUSD at 1.1892 sl: 1.1912 tp: 1.1872 ok

2006.04.07 09:55:24 2006.02.16 21:57 1 EURUSD,M1: open #4 sell stop 0.10 EURUSD at 1.1892 sl: 1.1912 tp: 1.1872 ok

2006.04.07 09:55:24 2006.02.16 21:57 1 EURUSD,M1: open #3 buy stop 0.10 EURUSD at 1.1903 sl: 1.1883 tp: 1.1923 ok

2006.04.07 09:55:24 2006.02.16 21:57 Tester: take profit #1 at 1.1899 (1.1896 / 1.1899)

2006.04.07 09:55:24 2006.02.16 18:52 Tester: order #1, buy 0.10 EURUSD is opened at 1.1879

2006.04.07 09:55:24 2006.02.16 18:37 1 EURUSD,M1: delete #2 sell stop 0.10 EURUSD at 1.1868 sl: 1.1888 tp: 1.1848 ok

2006.04.07 09:55:24 2006.02.16 18:37 1 EURUSD,M1: open #2 sell stop 0.10 EURUSD at 1.1868 sl: 1.1888 tp: 1.1848 ok

2006.04.07 09:55:24 2006.02.16 18:37 1 EURUSD,M1: open #1 buy stop 0.10 EURUSD at 1.1879 sl: 1.1859 tp: 1.1899 ok

2006.04.07 09:55:24 1 inputs: tp=20; sl=20; tp1=23; sl1=23; tp2=40; sl2=43;

2006.04.07 09:55:24 1 EURUSD,M1: loaded successfully

 

Как заставить его удалять оставшийся ордер после открытия одного из ордеров?? :?:

Share this post


Link to post
Share on other sites
-FOX-
если ты выставляешь лимитник или стоп-ордер, будет возвращать

OP_BUYLIMIT или OP_BUYSTOP

когда поз откроеца, вернет OP_BUY??

 

 

Спасибо, что ответил, оч. рад Но чем мне это поможет? Ведь какую бы константу я OrderType`у не указывал, всеравно он удаляет раньше чем мне нужно. Вот пример:

int start() 
 { 
int total=OrdersTotal(); 
  if(total<1) 
{ 
int buy= OrderSend(Symbol(),OP_BUYSTOP,0.1,Ask+4*Point,3,Ask-16*Point,Ask+24*Point,"level 1",255,0,CLR_NONE); 
int sell= OrderSend(Symbol(),OP_SELLSTOP,0.1,Ask-7*Point,3,Ask+13*Point,Ask-27*Point,"level 1",255,0,CLR_NONE); 
if(OrderType()==OP_BUY) OrderDelete(sell); 
if(OrderType()==OP_SELL) OrderDelete(buy); 

}    
 }

 

Вроде бы, если я все правильно понимаю, я написал, что если ордер открывается в позицию на покупку, то удалить ордер "sell". Если ордер открывается в позицию на продажу, то удалить ордер "buy". МТС же удаляет ордер сразу после выставления ордеров. :( Вот результаты теста:

2006.04.07 09:55:24 2006.02.16 22:25 Tester: order #3, buy 0.10 EURUSD is opened at 1.1903

2006.04.07 09:55:24 2006.02.16 21:57 1 EURUSD,M1: delete #4 sell stop 0.10 EURUSD at 1.1892 sl: 1.1912 tp: 1.1872 ok

2006.04.07 09:55:24 2006.02.16 21:57 1 EURUSD,M1: open #4 sell stop 0.10 EURUSD at 1.1892 sl: 1.1912 tp: 1.1872 ok

2006.04.07 09:55:24 2006.02.16 21:57 1 EURUSD,M1: open #3 buy stop 0.10 EURUSD at 1.1903 sl: 1.1883 tp: 1.1923 ok

2006.04.07 09:55:24 2006.02.16 21:57 Tester: take profit #1 at 1.1899 (1.1896 / 1.1899)

2006.04.07 09:55:24 2006.02.16 18:52 Tester: order #1, buy 0.10 EURUSD is opened at 1.1879

2006.04.07 09:55:24 2006.02.16 18:37 1 EURUSD,M1: delete #2 sell stop 0.10 EURUSD at 1.1868 sl: 1.1888 tp: 1.1848 ok

2006.04.07 09:55:24 2006.02.16 18:37 1 EURUSD,M1: open #2 sell stop 0.10 EURUSD at 1.1868 sl: 1.1888 tp: 1.1848 ok

2006.04.07 09:55:24 2006.02.16 18:37 1 EURUSD,M1: open #1 buy stop 0.10 EURUSD at 1.1879 sl: 1.1859 tp: 1.1899 ok

2006.04.07 09:55:24 1 inputs: tp=20; sl=20; tp1=23; sl1=23; tp2=40; sl2=43;

2006.04.07 09:55:24 1 EURUSD,M1: loaded successfully

 

Как заставить его удалять оставшийся ордер после открытия одного из ордеров?? :?:

 

P.s. Это сообщение случайно продублировано где то на форуме :oops:

Share this post


Link to post
Share on other sites
Player 2
Как заставить его удалять оставшийся ордер после открытия одного из ордеров??

Ничего себе, ну и код. Как он работает я вообще не понимаю, может я чего-то не знаю, но перед тем как использовать ordertype() надо выбрать ордер функцией orderselect(). Ты скажи конкретно, что тебе надо. А то по твоему коду не совсем понятно что ты хочешь сделать. Если ты открываешь 2 отложенных и ждешь пока один из них сработает а потом после срабатывания убираешь не сработавший, то тут есть один момент: сработать могут оба ордера, тем более поставленные от цены на 4 пункта. Что делать в таком случае?

Может так должно быть?:

int start() {
int total=OrdersTotal();
if (totall==0) {
OrderSend(Symbol(),OP_BUYSTOP,0.1,Ask+4*Point,3,Ask-16*Point,Ask+24*Point,"level 1",255,0,CLR_NONE); 
OrderSend(Symbol(),OP_SELLSTOP,0.1,Ask-7*Point,3,Ask+13*Point,Ask-27*Point,"level 1",255,0,CLR_NONE);
} else {

int Tickets[100];
for (int i=0;i<total;i++) {
OrderSelect(i,SELECT_BY_POS, MODE_TRADES);
Tickets[i]=OrderTicket();}

OrderSelect(0,SELECT_BY_POS, MODE_TRADES);
if (OrderType()==OP_BUY || OrderType() == OP_SELL) 
for (i=1;i<total;i++) {
OrderSelect(Tickets[i],SELECT_BY_TICKET);
if (OrderType()!=OP_BUY && OrderType()!=OP_SELL)
OrderDelete(Tickets[i]);}
}
}

PS. Код не проверял.

Share this post


Link to post
Share on other sites
-FOX-

Спасибо большущее, Player 2 :D Ты все правильно понял, просто мне за не имением программного образования и опыта сложно ориентироваться в языке программы. Все пишу буквально методом проб и ошибок!

 

P.S. К стати код работает идеально. :shock: Мне б так научится.

Share this post


Link to post
Share on other sites
Player 2
Спасибо большущее, Player 2

Не за что. А в коде есть ошибки. Во-первых переменная total один раз названа как totall, во-вторых, нет проверки символа ордера, я всегда забываю ее ставить. При бэктесте этого не видно, а в реале увидишь что система будет убирать все отложенные ордера всех валютных пар если есть хоть один открытый ордер по какой-нибудь паре. Допустим система будет торговать по eurusd, а ты решишь поставить отложенный по usdchf вручную, и система увидев его уберет его как ненужный. Или, система поставит 2 отложенных ордера, ты вручную откроешь buy с рынка по usdchf, и система тут же уберет свои отложенные, думая что один из них уже открыт. Короче, код не идеален. Но думаю на первое время тебе и такой сойдет, ты ж только тестер гоняешь как я понял. Удачи.

Share this post


Link to post
Share on other sites
Player 2

Черт, забыл спросить. Код сливает?

Share this post


Link to post
Share on other sites
GameOver

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

к тому же счет ордеров надо вести не от нуля, а к нулю - если ты выполняешь операцию "OrderDelete" - будут косяки

 

  for(i=OrdersTotal()-1;i>=0;i--){
     if (!OrderSelect(i,SELECT_BY_POS,MODE_TRADES)) continue;
     if (OrderSymbol()==Symbol() && OrderMagicNumber()==MagiсNum){
        if (OrderType()==OP_BUY) {// тут обработка открытых баев}
        if (OrderType()==OP_SELL) {// или селов}
     }
  }

 

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

--


Никаких крыльев нету. Просто умираешь и все. (гусеница)

Share this post


Link to post
Share on other sites
Player 2
подозреваю, что копировать тикеты в массив, дабы потом его обрабатывать в повторном цикле - не есть гуд - данные могут уже изменица.

Да, действительно. Но они могут измениться в любом случае, даже во время твоего цикла без копирования тикетов.

к тому же счет ордеров надо вести не от нуля, а к нулю - если ты выполняешь операцию "OrderDelete" - будут косяки

Да, точно. Я собственно и копировал в отдельный массив тикеты чтобы таких косяков не было, в этом случае не важно в каком направлении обрабатывать ордера. А вести счет в обратную сторону чтобы не копировать тикеты не додумался. А так код будет короче и удобнее.

Раз ты такой умный хочу тебе вопрос задать. OrderMagicNumber это что такое? Я правильно понимаю что этот номер имеет ордер и он хранится на сервере? То есть вырубание МТ4 к потерям не приведет? То есть эти магические номера можно использовать для отделения ордеров системы от других ордеров. Я правильно мыслю? В справке это не описано или я не нашел.

Share this post


Link to post
Share on other sites
GameOver
Раз ты такой умный хочу тебе вопрос задать.

 

это наезд или повод для драки? ;-)

 

OrderMagicNumber это что такое? Я правильно понимаю что этот номер имеет ордер и он хранится на сервере? То есть вырубание МТ4 к потерям не приведет? То есть эти магические номера можно использовать для отделения ордеров системы от других ордеров. Я правильно мыслю? В справке это не описано или я не нашел.

 

все верно. при выставлении ордеров советником ему можно задасть MagicNumber (тип int). тогда при обработке советником можно проверять этот самый MagicNumber, и игнорировать ордера выставленные с рынка


Никаких крыльев нету. Просто умираешь и все. (гусеница)

Share this post


Link to post
Share on other sites
Player 2
это наезд или повод для драки?

Где ж ты там увидел наезд или повод для драки :?::D По-моему я сказал что твой код лучше моего, и такие слова не должны были показаться наездом или приколом.

Share this post


Link to post
Share on other sites
GameOver

:)

 

кстати, обычно если обрабатываеца много вариантов одеров, то

 

     if (!OrderSelect(i,SELECT_BY_POS,MODE_TRADES)) continue; 
     oType=OrderType();oTicket=OrderTicket();
     if (OrderSymbol()==Symbol() && OrderMagicNumber()==MagiсNum){ 
        if (oType==OP_BUY) {// тут обработка открытых баев} 
        if (oType==OP_SELL) {// или селов} 
     } 

мелочь, а код проще читать


Никаких крыльев нету. Просто умираешь и все. (гусеница)

Share this post


Link to post
Share on other sites
Player 2

Да и работать быстрее будет. Где-то читал что лучше сразу скопировать в локальные переменные результаты таких функций как orderstotal и т.п.

Share this post


Link to post
Share on other sites
-FOX-
Во-первых переменная total один раз названа как totall, во-вторых, нет проверки символа ордера, я всегда забываю ее ставить. При бэктесте этого не видно, а в реале увидишь что система будет убирать все отложенные ордера всех валютных пар если есть хоть один открытый ордер по какой-нибудь паре. Допустим система будет торговать по eurusd, а ты решишь поставить отложенный по usdchf вручную, и система увидев его уберет его как ненужный.

 

С "totall" проблем не было, я его конечно переправил и все работало так как надо. А все остальные побочные эффекты в принципе не волнуют. :wink:

Share this post


Link to post
Share on other sites
SoMax

Недавно скачал код эксперта, но он не компилируется. Может кто поможет найти ошибку? Выкладываю код с ошибкой.

111_202.mq4


Правило трейдера: проиграл квартиру матери - остановись!

Share this post


Link to post
Share on other sites
Rombur
Недавно скачал код эксперта, но он не компилируется. Может кто поможет найти ошибку? Выкладываю код с ошибкой.

А это не оно.

starter_v6_853.mq4


Дисциплина, вера, терпение - путь к успеху.

Share this post


Link to post
Share on other sites
SoMax

Да оно, спасибо. А кто объяснит для чего нужен stdlib.mqh и другие файлы mqh в папке include?


Правило трейдера: проиграл квартиру матери - остановись!

Share this post


Link to post
Share on other sites
NewTartan
Люди, помогите кто знает. Пытаюсь написать эксперта.Алгоритм действий следующий:

1.выставить два ордера buystop/sellstop

2.как только один ордер откроется, необходимо удалить оставшийся.

 

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

Выставляю два ордера X и Y, далее

if(OrderType==0) OrderDelete(Y);

if(OrderType==1) OrderDelete(X);

В итоге МТС выставляет мне два ордера и тут же один из них удаляет, не дождавшись открытия позиции. Как сделать так, чтобы МТС удаляла ордер после открытия позиции???

Привет.

Сделай проще.

Напиши простенькую процедуру проверки наличия активных ордеров, а не лимитников и не стопов, а именно активных ордеров.

И пусть она постоянно считает их. При выставлении отложек активные =0, а после инициализации одного из них появится 1 активный ордер.

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

Если нужен код пиши на мыло, но лучще сделай сам - это полезно.

Попутного тренда и больших профитов.


Бороться, искать, найти и не сдаваться

Share this post


Link to post
Share on other sites
-FOX-

NewTartan, спасибо за участие в проблемме. Обязательно пришлю письмо.

Share this post


Link to post
Share on other sites
RGT

Rosh ! Индикаторов в инете большой выбор, только проблема, какие выбрать для создания прибыльного советника?

Я думаю все с нетерпением ждут, когда Вы перейдете к анализу особенностей создания советников.

Огромное спасибо за ваш цикл статей!


Don't worry, be happy !!

Share this post


Link to post
Share on other sites
Guest
This topic is now closed to further replies.

  • Recently Browsing   0 members

    No registered users viewing this page.

×