Вопросы от начинающих MQL5 MT5 MetaTrader 5 - страница 574

 
Anton Balakirew:
Идея открытия ордеров по сигналам бачего или медвежего захвата, как сделать, чтобы была только одна сделка на бай/селл и одна сделка отложенного ордера, у меня открывается на каждом тике сделки. Помогите решить проблему.
Проверяйте количество установленных ордеров и количество открытых позиций прежде, чем открывать новую позицию или ставить новый отложенный ордер.
 
Artyom Trishkin:

Ну вот можно ещё так: тут для каждой свечи диапазона записываются совпадения. В прошлой версии совпадения писались только для одной свечи - т.е., для той, которая совпадает с этой, уже совпадение не писалось.

Артем, спасибо. Буду разбираться. 

pako:

Значения high можно округлить , например значение 1.23456 округляем до 1.2346


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

 
Andrey Koldorkin:

Артем, спасибо. Буду разбираться. 

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

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

for(int i=0; i<copy_bars-1; i++) {                             // цикл по скопированным данным от начала до "на один меньше размера массива"

нужно изменить количество баров поиска на

for(int i=0; i<copy_bars; i++) {                             // цикл по скопированным данным от начала до конца диапазона
 
Artyom Trishkin:
Проверяйте количество установленных ордеров и количество открытых позиций прежде, чем открывать новую позицию или ставить новый отложенный ордер.

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

if (o4>c4&&o3>c3&&l2>l1&&c2<c1&&o2>c2&&o1<c1&&c1>o2&&h1>h2||o2>c1&&h2>h1&&h1<o2&&o1<c1&&l2>l1&&o3>c3&&o4>c4){  //первое условие

  if (OrdersTotal()==0) //второе условие

      OrderSend(Symbol(), OP_BUY,Lot,o,10,l1,0); }  ...................................и так для каждой сделки?

 И какая функция считает количество открытых позиций? 

 

вроде решил проблему:

if (Hour()>=0&&Hour()<23){  

  if (o4>c4&&o3>c3&&l2>l1&&c2<c1&&o2>c2&&o1<c1&&c1>o2&&h1>h2||o2>c1&&h2>h1&&h1<o2&&o1<c1&&l2>l1&&o3>c3&&o4>c4){

  if (PositionsTotal()<=1)

      OrderSend(Symbol(), OP_BUY,Lot,o,10,l1,0); }                       //открывает Buy

          

  if (o4>c4&&o3>c3&&l2>l1&&c2<c1&&o2>c2&&o1<c1&&c1>o2&&h1>h2||o2>c1&&h2>h1&&h1<o2&&o1<c1&&l2>l1&&o3>c3&&o4>c4){ 

  if (PositionsTotal()==1&&OrderType()==0)         

      OrderSend(Symbol(), OP_SELLSTOP,Lot,l2,10,h2,0);}               //отложенный ордер SellStop

           

  if (o4<c4&&o3<c3&&h2<h1&&c2>c1&&o2<c2&&o1>c1&&c1<o2&&l1<l2||o2<c1&&l2<l1&&l1>o2&&o1>c1&&h2<h1&&o3<c3&&o4<c4){

  if (PositionsTotal()<=1)

      OrderSend(Symbol(),OP_SELL,Lot,o,10,h1,0); }                       //открывает Sell

      

  if (o4<c4&&o3<c3&&h2<h1&&c2>c1&&o2<c2&&o1>c1&&c1<o2&&l1<l2||o2<c1&&l2<l1&&l1>o2&&o1>c1&&h2<h1&&o3<c3&&o4<c4){ 

  if (PositionsTotal()==1&&OrderType()==1)                 

      OrderSend(Symbol(), OP_BUYSTOP,Lot,h2,10,l2,0);}                 //отложенный ордер BuyStop

                     

         } 

 //+------------------------------------------------------------------+

//    Функция, возвращающая сумманое количество открытых позиций     |

//                                                                   |

//+------------------------------------------------------------------+

int PositionsTotal() {

   int pos = 0;

   for (int i=0; i<OrdersTotal(); i++) {

      OrderSelect(i, SELECT_BY_POS, MODE_TRADES);

      if (OrderType() == OP_BUY || OrderType() == OP_SELL)

         pos++;

   }

   return(pos);

}

//+------------------------------------------------------------------+

 
Artyom Trishkin:

Ну вот можно ещё так: тут для каждой свечи диапазона записываются совпадения. В прошлой версии совпадения писались только для одной свечи - т.е., для той, которая совпадает с этой, уже совпадение не писалось.

Гуд. Однако как я понимаю, если хай свечи 2 совпадает с хаем свечи 7, то будет найдено два совпадения: 2 <=> 7, 7 <=>2. А как насчет учета обратных пар, но только без дополнительного цикла?

А слабо решить задачу за один проход, не испльзуя вложенных циклов for:)))?

 
Vasiliy Sokolov:

Гуд. Однако как я понимаю, если хай свечи 2 совпадает с хаем свечи 7, то будет найдено два совпадения: 2 <=> 7, 7 <=>2. А как насчет учета обратных пар, но только без дополнительного цикла?

А слабо решить задачу за один проход, не испльзуя вложенных циклов for:)))?

:) Не нужно меня на слабо ;) Конечно, думаю, можно решить и одним циклом, но мне лень было дольше думать - сделал как сразу придумалось.

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

И далее решать задачи по оптимизации расчётов можно, но мне не нужно.

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

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

ЗЫ, быть может стоит и методы Кохонена подключить зная нужный входной параметр.

 
Artyom Trishkin:

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

Жаль, очень жаль.
 
Vasiliy Sokolov:
Жаль, очень жаль.
Ну да, задачка-то интересная, но, увы, временем не располагаю.
 
Artyom Trishkin:

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

нужно изменить количество баров поиска на

Подскажите пож-та смысл этих строк:

input int Search_Period=10;   // Количество копируемых свечей

int searchPeriod=(Search_Period<1)?1:Search_Period;   // что означают символы "?", ":"  ?

input int Delta=2;            // Количество пунктов допуска

int delta=(Delta<0)?0:Delta;   // что означают символы "?", ":"  ?

 
Andrey Koldorkin:

Подскажите пож-та смысл этих строк:

input int Search_Period=10;   // Количество копируемых свечей

int searchPeriod=(Search_Period<1)?1:Search_Period;   // что означают символы "?", ":"  ?

input int Delta=2;            // Количество пунктов допуска

int delta=(Delta<0)?0:Delta;   // что означают символы "?", ":"  ?

// строку int searchPeriod=(Search_Period<1)?1:Search_Period;
// можно расписать так:

input int Search_Period=10; // Количество копируемых свечей ... эту строку вы видите в настройках
int searchPeriod;           // Сюда будем записывать входной параметр
if(Search_Period<1) searchPeriod=1; // Если во входном параметре ввели ноль или меньше нуля, то параметр будет равен единице
else searchPeriod=Search_Period;    // иначе примем входной параметр

// соответственно и строку int delta=(Delta<0)?0:Delta;
// можно расписать точно так же

Из справки:

Условный оператор ?:

Общая форма тернарного оператора выглядит так:

выражение? выражение: выражение3

В качестве первого операнда – "выражение1" – может быть использовано любое выражение, результатом которого является значение типа bool. Если результат равен true, то выполняется оператор, заданный вторым операндом, то есть, "выражение2".

Если же первый операнд paвен false, то выполняется третий операнд – "выражениеЗ". Второй и третий операнды, то есть "выражение2" и "выражениеЗ", должны возвращать значения одного типа и не должны иметь тип void. Результатом выполнения условного оператора является результат "выражения2" либо результат "выражение3", в зависимости от результата "выражение1".

//--- пронормируем разность между ценами открытия и закрытия на дневной размах

double true_range = (High==Low)?0:(Close-Open)/(High-Low);

Эта запись эквивалентна следующей

double true_range;

if(High==Low)true_range=0;               // если High и Low равны

else true_range=(Close-Open)/(High-Low); // если размах ненулевой