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

eevviill

Заблокирован
У меня следующая ситуация. Совок ставит в определённое время, а точнее, по закрытия свечи на D1 отложенный ордер - лимитник по канкретной цене. Если лимитник не сработал к закрытию следующей свечи на, то его нужно просто удалить.

Если вариантов несколько как я понимаю:

1. Можно дать параметру expiration функции OrderSend() значение, т.е. просчитать его и задать ровно 24 часа в секундах, итого получиться (60 * 60) *24 часа = 86400 секунд.
Т.е. ордер будет иметь такой вид(если байлимит):

PHP:
OrderSend(string symbol, OP_BUYLIMIT, double volume, double price, int slippage, double stoploss, double takeprofit, string comment=NULL, int magic=0, datetime 86400, color arrow_color=CLR_NONE)


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

PHP:
if( (time[0] == ВРЕМЯ, ГДЕ ОРДЕР НУЖНО ЗАКРЫТЬ ) && ( Ordertype >= 1 ))
  {
     Orderclose();
  }


Т.е. если время, в которое истекает срок его закрытия пришло и тип ордера - отложенник.. ЗАКРЫВАЕМ ЕГО.

Прошу подсказать как более грамотно реализовать данный момент.
А может есть ещё какие варианты?
Слушай. У меня третий вариант. Очень простой.
PHP:
Sleep(24*60*60*1000);
 

hoz

Активный участник
Ну так всё правильно. Советник будет на открытии свечи проверять условия. Или тебе надо открыто в 15, проверка на следующий день в 15?
eevviill, у тебя указано, что:
PHP:
iTime(Symbol(),0,0)


Советник находится на ТФ H1. Если и пользоваться таймсерией, то нужно указывать ТФ = 1440 в нужном месте, иначе он будет возвращать значение времени открытия часа. А это нам не нужно. Нам важен день, в данном случае.

Всё. Понял. Но Time[0], я думаю нельзя использовать. Ровно через 24 часа именно такого времени может не быть. особенно если флэт.


Какая разница флет или тренд? Бар то всё-равно закроется, а Time[0], это всего лишь значение времени открытия текущего бара и только лишь.. В данном случает дневки.

Слушай. У меня третий вариант. Очень простой.
PHP:
Sleep(24*60*60*1000);


Ага. Тока это тоже самое, что и:

PHP:
OrderSend(Symbol(),g_type,lot,GetPriceToInput(),NULL,SL * Point,TP * Point," ",magic,86400,Green)


у меня

Тут смысл в том, что нет смысла впихивать в код лишние строчки, если в этом нет необходимости.
 
Последнее редактирование:

Алекc1234

Местный житель
eevviill, никак не могу сделать так, чтобы при открытии нескольких рыночных ордеров, в коде написать цену первого открытого ордера? То есть OderOpenPrice() первого по времени открытого ордера. Сделал, как Вы написали
OrderSelect(OrdersTotal()-1,SELECT_BY_POS);
double fir_or_pr=OrderOpenPrice();
но сов видит цену последнего по времени открытого ордера. Можно ли что-нибудь сделать? Может, по другому нужно?
 

Алекc1234

Местный житель
Делаю так(подобно приведённому выше коду)
if(OrderSelect(OrdersTotal()-1,SELECT_BY_POS,MODE_TRADES))
{
double fir_or_pr = OrderOpenPrice();
if(ot==OP_BUY)
{
prof = NormalizeDouble((Bid-fir_or_pr),Digits)/Point; }
if (ot == OP_SELL)
{
prof = NormalizeDouble((fir_or_pr-Ask),Digits)/Point; }
}
Но всё равно сов не видит цену первого открытого ордера, а смотрит на последнюю цену.
 

Ugar

Гуру форума
eevviill, никак не могу сделать так, чтобы при открытии нескольких рыночных ордеров, в коде написать цену первого открытого ордера? То есть OderOpenPrice() первого по времени открытого ордера. Сделал, как Вы написали
OrderSelect(OrdersTotal()-1,SELECT_BY_POS);
double fir_or_pr=OrderOpenPrice();
но сов видит цену последнего по времени открытого ордера. Можно ли что-нибудь сделать? Может, по другому нужно?
Конечно это последний. Для первого надо указывать на 0 ордер в списке, а не на OrdersTotal()-1.
OrderSelect(0,SELECT_BY_POS);
double fir_or_pr=OrderOpenPrice();
Это будет первый открытый. Конечно всё это художественная самодеятельность. Если по серьёзному то в 2 строчки не уложиться.
 

Алекc1234

Местный житель
Конечно это последний. Для первого надо указывать на 0 ордер в списке, а не на OrdersTotal()-1.
OrderSelect(0,SELECT_BY_POS);
double fir_or_pr=OrderOpenPrice();
Это будет первый открытый. Конечно всё это художественная самодеятельность. Если по серьёзному то в 2 строчки не уложиться.

Спасибо, но всё равно не работает. Я выложил весь кусок куда, может, если что-нибудь исправить, заработает?
 

alexshell

Элитный участник
Спасибо, но всё равно не работает. Я выложил весь кусок куда, может, если что-нибудь исправить, заработает?

Сделайте так:
datetime Times=TimeCurrent( ) ;// ставите перед циклом
OrderSelect(OrdersTotal()-1,SELECT_BY_POS);

if(OrderOpenTime<Times)
{
double fir_or_pr=OrderOpenPrice();
Times=OrderOpenTime( ) ;
}
на выходе цикла будет цена первого по времени ордера.
 

Алекc1234

Местный житель
Спасибо всем, вот как сейчас выглядит код, но всё равно не работает:
double prof;
datetime Times=TimeCurrent();
double fir_or_pr;

OrderSelect(OrdersTotal()-1,SELECT_BY_POS,MODE_TRADES);
if (OrderOpenTime()<Times)
{
fir_or_pr=OrderOpenPrice();
Times=OrderOpenTime();
}
if(OrderType() == OP_BUY)
{
prof = NormalizeDouble((Bid-fir_or_pr),Digits)/Point; }
if (OrderType() == OP_SELL)
{
prof = NormalizeDouble((fir_or_pr-Ask),Digits)/Point; }
 

Алекc1234

Местный житель
Ещё добавлю, что при открытии второго рыночного ордера в рынке находится один отложенный стоп ордер...
 

alexshell

Элитный участник
Ещё добавлю, что при открытии второго рыночного ордера в рынке находится один отложенный стоп ордер...

Так всё таки что вы в итоге ищете профит первого по времени ордера? или цену. И у вас одновременно могут быть ордера и бай и селл? А у вас вообще сам цикл то есть? типа for(......).
 
Последнее редактирование:

Ugar

Гуру форума
Ещё добавлю, что при открытии второго рыночного ордера в рынке находится один отложенный стоп ордер...
Может, для начала стоит ознакомиться с учебником? Метод научного тыка не очень подходит для изучения языка программирования.
 

Алекc1234

Местный житель
Так всё таки что вы в итоге ищете профит первого по времени ордера? или цену. И у вас одновременно могут быть ордера и бай и селл? А у вас вообще сам цикл то есть? типа for(......).

Ищу профит первого по времени ордера. Одновременно могут быть и бай и селл, но такое бывает редко. Цикл сделал такой
for (int j = OrdersTotal()-1; j >= 0; j--)
{
if (OrderSelect(j, SELECT_BY_POS,MODE_TRADES))
{
 
Последнее редактирование:

Алекc1234

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

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

Ugar

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

alexshell

Элитный участник
Ищу профит первого по времени ордера.

PHP:
 double prof;
 datetime Times=TimeCurrent();
 for( int i=0; i<OrdersTotal(); i++) 
 {
  if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)) 
  if (OrderOpenTime()<Times)
   {
    prof = OrderProfit( ) ;
  
    Times=OrderOpenTime();
   }
  }
Если вам не важно бай это или селл и какой символ.Проверку по символу сами добавите.
 
Последнее редактирование:

Алекc1234

Местный житель
PHP:
 double prof;
 datetime Times=TimeCurrent();
 for( int i=0; i<OrdersTotal(); i++) 
 {
  if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)) 
  if (OrderOpenTime()<Times)
   {
    prof = OrderProfit( ) ;
  
    Times=OrderOpenTime();
   }
  }
Если вам не важно бай это или селл.

Спасибо большое, только я ищу профит в пунктах, а не в валюте. Сделал так, но опять не получилось
double prof;
datetime Times=TimeCurrent();
for( int i=0; i<OrdersTotal(); i++)
{
if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
if (OrderOpenTime()<Times)
{
double fir_or_pr=OrderOpenPrice();

if(ot == OP_BUY)
{
prof = NormalizeDouble((Bid-fir_or_pr),Digits)/Point; }
if (ot == OP_SELL)
{
prof = NormalizeDouble((fir_or_pr-Ask),Digits)/Point; }

Times=OrderOpenTime();
}
}
 

Алекc1234

Местный житель
Тогда стоит найти другого программиста для переделки. Есть же ветка по доработке советников. Надо там выложить советник с подробным описанием что надо изменить. Может кто нибудь и переделает.

Дело-то в том, что нужно только это переделать, всё остальное нормально.
 

alexshell

Элитный участник
Спасибо большое, только я ищу профит в пунктах, а не в валюте. Сделал так, но опять не получилось
double prof;
datetime Times=TimeCurrent();
for( int i=0; i<OrdersTotal(); i++)
{
if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
if (OrderOpenTime()<Times)
{
double fir_or_pr=OrderOpenPrice();

if(ot == OP_BUY)
{
prof = NormalizeDouble((Bid-fir_or_pr),Digits)/Point; }
if (ot == OP_SELL)
{
prof = NormalizeDouble((fir_or_pr-Ask),Digits)/Point; }

Times=OrderOpenTime();
}
}

PHP:
double fir_or_pr;
 double prof;
 datetime Times=TimeCurrent();
 
for( int i=0; i<OrdersTotal(); i++) 
 { if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)&&OrderSymbol() ==  Symbol()) 
  { if (OrderOpenTime()<Times)
    { fir_or_pr=OrderOpenPrice();
      if(OrderType() == OP_BUY) { 
      prof = NormalizeDouble((Bid-fir_or_pr),Digits)/Point; }
      if(OrderType() == OP_SELL) {
      prof = NormalizeDouble((fir_or_pr-Ask),Digits)/Point; } 
      Times=OrderOpenTime();
    }
  }
 }
И не говорите что не работает. Специально в советник вставлял для проверки.Если проверка по символу не нужна уберите её.
 
Верх