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

aufx

Интересующийся
MessageBox

Коллеги, просветите плисс...
Окном, которое выводит MessageBox, можно управлять? (имеется ввиду размер и расположение в окне инструмента)
 

Abi

Элитный участник
Привет всем, подскажите почему в скрипте код закрытия ордеров(например селл, как в коде ниже) хорошо работает на счетах типа инстант и не работает на маркет ордерах(просто закрывает все ордера подряд, независимо от условий в функции закрывать только селл-ордера).
например в этом куске от известного прогера expforex...
Код:
void start() 
{
   int li_0 = OrdersTotal() - 1;
   if (AllSymbols == TRUE) 
   {
      if (gi_84) 
      {
         for (int l_pos_4 = li_0; l_pos_4 >= 0; l_pos_4--)
            if (OrderSelect(l_pos_4, SELECT_BY_POS, MODE_TRADES) && OrderType() == OP_SELL && GetMarketInfo() && (!OrderClose(OrderTicket(), OrderLots(), gda_76[0], g_slippage_80))) Print(OrderError());
      }
   }
   if (AllSymbols == FALSE) 
   {
      if (gi_84) {
         for (l_pos_4 = li_0; l_pos_4 >= 0; l_pos_4--) 
         {
            if (OrderSelect(l_pos_4, SELECT_BY_POS, MODE_TRADES)) 
            {
               if (OrderSymbol() == Symbol())
                  if (OrderSymbol() == Symbol() && OrderType() == OP_SELL && GetMarketInfo() && (!OrderClose(OrderTicket(), OrderLots(), gda_76[0], g_slippage_80))) Print(OrderError());
            }
         }
      }
   }
}
 

Abi

Элитный участник
Здесь проверка на тип ордера есть. Так что єто скорее всего не єтот блок бай закрывает.
Да вроде все пересмотрел - это основная функция закрывающая ордера по условию.

помогите если что = вот весь код...

Код:
#property copyright "expforex"
#property link      "Expforex Прибыльные советники - - Главная страница -"
#property show_inputs
#include <stdlib.mqh>
double gda_76[2];
int g_slippage_80;
bool gi_84 = TRUE;
extern bool AllSymbols = FALSE;
void init() 
{
   //Stamp();
   start();
}
void start() 
{
   int li_0 = OrdersTotal() - 1;
   if (AllSymbols == TRUE) 
   {
      if (gi_84) 
      {
         for (int l_pos_4 = li_0; l_pos_4 >= 0; l_pos_4--)
            if (OrderSelect(l_pos_4, SELECT_BY_POS, MODE_TRADES) && OrderType() == OP_SELL && GetMarketInfo() && (!OrderClose(OrderTicket(), OrderLots(), gda_76[0], g_slippage_80))) Print(OrderError());
      }
   }
   if (AllSymbols == FALSE) 
   {
      if (gi_84) 
      {
         for (l_pos_4 = li_0; l_pos_4 >= 0; l_pos_4--) 
         {
            if (OrderSelect(l_pos_4, SELECT_BY_POS, MODE_TRADES)) 
            {
               if (OrderSymbol() == Symbol())
                  if (OrderSymbol() == Symbol() && OrderType() == OP_SELL && GetMarketInfo() && (!OrderClose(OrderTicket(), OrderLots(), gda_76[0], g_slippage_80))) Print(OrderError());
            }
         }
      }
   }
}
string OrderError() 
{
   int l_error_0 = GetLastError();
   return (StringConcatenate("Order:", OrderTicket(), " GetLastError()=", l_error_0, " ", ErrorDescription(l_error_0)));
}
int GetMarketInfo() 
{
   RefreshRates();
   gda_76[0] = MarketInfo(OrderSymbol(), MODE_ASK);
   gda_76[1] = MarketInfo(OrderSymbol(), MODE_BID);
   double l_point_0 = MarketInfo(OrderSymbol(), MODE_POINT);
   if (l_point_0 == 0.0) return (0);
   g_slippage_80 = (gda_76[0] - gda_76[1]) / l_point_0;
   return (gda_76[0] > 0.0 && gda_76[1] > 0.0);
}
void Stamp() 
{
   ObjectCreate("Original", OBJ_LABEL, 0, 0, 0);
   ObjectSetText("Original", " ---http://Expforex.at.ua---", 10, "Arial Bold", Red);
   ObjectSet("Original", OBJPROP_CORNER, 2);
   ObjectSet("Original", OBJPROP_XDISTANCE, 200);
   ObjectSet("Original", OBJPROP_YDISTANCE, 10);
}

проверял на ECN-счетах от Альпари и KGFX - результат одинаковый, закрывает все подряд....
 
Последнее редактирование модератором:

eevviill

Заблокирован
Да вроде все пересмотрел - это основная функция закрывающая ордера по условию.

помогите если что = вот весь код...
...
проверял на ECN-счетах от Альпари и KGFX - результат одинаковый, закрывает все подряд....
Если чесно мне не очень нравится как написано. Могу помочь функцией закрытия ордера.
PHP:
////////////////////////////////////////////////////////////////////////////////
void Close_f()
{
for(int i=OrdersTotal()-1; i>=0; i--)
 {
 OrderSelect(i,SELECT_BY_POS);
 {
 if(OrderMagicNumber()==magic)
 {
 if(OrderSymbol()==Symbol())
 {
 bool ticket_ex=false;
 for (int j_ex = 0;j_ex < MaxAttempts; j_ex++)
 {
 while(IsTradeContextBusy()) Sleep(1000);
 
 //if(OrderType()==OP_BUY ) ticket_ex=OrderClose(OrderTicket(),OrderLots(),Bid,slippage,Yellow); 
 if(OrderType()==OP_SELL) ticket_ex=OrderClose(OrderTicket(),OrderLots(),Ask,slippage,Yellow);
 //if(OrderType()==OP_SELLSTOP || OrderType()==OP_BUYSTOP || OrderType()==OP_SELLLIMIT || OrderType()==OP_BUYLIMIT) ticket_ex=OrderDelete(OrderTicket(),CLR_NONE);
 if(ticket_ex==true)break;
 }
 }
 }
 }
 }
 
}
 
Последнее редактирование модератором:

sochinik

Местный житель
Коллеги, просветите плисс...
Окном, которое выводит MessageBox, можно управлять? (имеется ввиду размер и расположение в окне инструмента)

Как я слышал с MessageBox нужно работать осторожно, оно осмтанавливает работу советника пока не закроете его.....Но это по учебной информации... на себе не проверял
 

hoz

Активный участник
По той простой причине, что объявляя переменную без присваивания ей значения она автоматом равна нулю. Так вот -1 в этом случае просто означает, что функция не выполнена, а 0 означает что ордера ещё не открывались (не-было попыток это сделать) и соответственно если больше нуля значит ордер открыт.


Подчёркнутое - это не разные вещи! Это следствие... Рассмотрим канкретнее данный момент:
1. Если функция, в данном случает OrderSend() не выполнена, значит ордер есс-но не открылся.
2. Если функция выполнена, ордер может открыться, а может и не открыться.

И самое интересное, тут:

а 0 означает что ордера ещё не открывались (не было попыток это сделать) и соответственно если больше нуля значит ордер открыт.


3. если ордера не открывались это означает, что функция вернёт -1 т.е. она не вернула нам ордер тикета, а значит вернёт -1(согласно справке)

Я не буду перечитывать весь ваш диалог, но знаю, что Ugar, (Андрей) очень грамотный программист. И если он что-то не понял значит об этом было не так сказано. Я почти уверен, что он говорил о том-же коде который процитировал я, а ты уже о другом, с поправками.

Таким образом, Nata_FX права...
0 - это тикет ордеров открытых в ручную, на сколько мне известно.

На сколько грамотный программист Ugar я понятия не имею, но мне важно не это, а отношение к других программиста.
Ведь я просил совета, и всего то...
 

alexshell

Элитный участник
Да вроде все пересмотрел - это основная функция закрывающая ордера по условию.

помогите если что = вот весь код...


проверял на ECN-счетах от Альпари и KGFX - результат одинаковый, закрывает все подряд....
Он и будет всё закрывать.
if (OrderSymbol() == Symbol() && OrderType() == OP_SELL && GetMarketInfo() && (!OrderClose(OrderTicket(), OrderLots(), gda_76[0], g_slippage_80))) Print(OrderError());
Грубо говоря Ордер селл-нет&& закрыть Он и закроет.
Замените на это
PHP:
#property copyright "expforex"
#property link      "Expforex Прибыльные советники - - Главная страница -"
#property show_inputs
#include <stdlib.mqh>
double gda_76[2];
int g_slippage_80;
bool gi_84 = TRUE;
extern bool AllSymbols = FALSE;
void init() 
{
   //Stamp();
   start();
}
void start() 
{
   int li_0 = OrdersTotal() - 1;
   if (AllSymbols == TRUE) 
   {
      if (gi_84) 
      {
         for (int l_pos_4 = li_0; l_pos_4 >= 0; l_pos_4--)
            if (OrderSelect(l_pos_4, SELECT_BY_POS, MODE_TRADES) && OrderType() == OP_SELL && GetMarketInfo() )
            {
          int t= OrderClose(OrderTicket(), OrderLots(), gda_76[0], g_slippage_80);if (t<0) Print(OrderError());}
      }
   }
   if (AllSymbols == FALSE) 
   {
      if (gi_84) 
      {
         for (l_pos_4 = li_0; l_pos_4 >= 0; l_pos_4--) 
         {
            if (OrderSelect(l_pos_4, SELECT_BY_POS, MODE_TRADES)) 
            {
               if (OrderSymbol() == Symbol()) {
                 if (OrderSelect(l_pos_4, SELECT_BY_POS, MODE_TRADES) && OrderType() == OP_SELL && GetMarketInfo() )
            {
         t= OrderClose(OrderTicket(), OrderLots(), gda_76[0], g_slippage_80);if (t<0) Print(OrderError());}
            } }
         }
      }
   }
}
string OrderError() 
{
   int l_error_0 = GetLastError();
   return (StringConcatenate("Order:", OrderTicket(), " GetLastError()=", l_error_0, " ", ErrorDescription(l_error_0)));
}
int GetMarketInfo() 
{
   RefreshRates();
   gda_76[0] = MarketInfo(OrderSymbol(), MODE_ASK);
   gda_76[1] = MarketInfo(OrderSymbol(), MODE_BID);
   double l_point_0 = MarketInfo(OrderSymbol(), MODE_POINT);
   if (l_point_0 == 0.0) return (0);
   g_slippage_80 = (gda_76[0] - gda_76[1]) / l_point_0;
   return (gda_76[0] > 0.0 && gda_76[1] > 0.0);
}
void Stamp() 
{
   ObjectCreate("Original", OBJ_LABEL, 0, 0, 0);
   ObjectSetText("Original", " ---http://Expforex.at.ua---", 10, "Arial Bold", Red);
   ObjectSet("Original", OBJPROP_CORNER, 2);
   ObjectSet("Original", OBJPROP_XDISTANCE, 200);
   ObjectSet("Original", OBJPROP_YDISTANCE, 10);
}
 
Последнее редактирование модератором:

Abi

Элитный участник
Спасибо eevviill , попробую вставить в скрипт...
И тебе alexshell спасибо...
хотя не совсем понял - вроде там нет ошибки, на инстанте ведь работает как часы...
и вроде там не "Ордер селл-нет&& "
а так: если все наши условия соблюдены, типа символ=наш, ордер=селл и GetMarketInfo вернул значение слипажа, а ордер при этом не закрылся = то выдать ошибку...
 
Последнее редактирование:

Abi

Элитный участник
0 - это тикет ордеров открытых в ручную, на сколько мне известно.

...

Насколько помню я, 0 - это магик ордера открытого вручную, тикет не может быть равен нулю вроде.
Иначе(если следовать вашей логике) мы вручную наплодим к примеру 10 ордеров с 0 тикетом, как их потом отделять друг от друга?
 

alexshell

Элитный участник
Спасибо eevviill , попробую вставить в скрипт...
И тебе alexshell спасибо...
хотя не совсем понял - вроде там нет ошибки, на инстанте ведь работает как часы...
вроде там не "Ордер селл-нет&& " а если ордер не закрыт то выдать ошибку...
Не знаю как он на инстанте может работать. Ф-я закрытия находится в условиях. Т.е всё что мы выбрали до этого это символ.
 
  • Like
Реакции: Abi

Abi

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

alexshell

Элитный участник
Abi, скопируй ещё раз скрипт. Я его отредактировал. В спешке пару скобок забыл. А то он у меня тоже бы начал ордера все закрывать которые не по совпадают с символом.
 
  • Like
Реакции: Abi

AlexeyVik

Программист mql4 mql5
Подчёркнутое - это не разные вещи! Это следствие... Рассмотрим канкретнее данный момент:
1. Если функция, в данном случает OrderSend() не выполнена, значит ордер есс-но не открылся.
2. Если функция выполнена, ордер может открыться, а может и не открыться.

И самое интересное, тут:




3. если ордера не открывались это означает, что функция вернёт -1 т.е. она не вернула нам ордер тикета, а значит вернёт -1(согласно справке)
У меня, извини, нет желания повторно разжёвывать всё это. Только уточню лично для тебя. Если ордера не открывались означает, что не-было сигнала и соответственно ф-ция OrderSend() не вызывалась.

Таким образом, Nata_FX права...
0 - это тикет ордеров открытых в ручную, на сколько мне известно.

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

Не в обиду тебе. Я видел твой вопрос ещё до ответа Андрея, но отвечать на него не стал. Какой вопрос такой и ответ. Ты путаешь тикет с магиком и что-то оспариваешь вместо того чтобы вникнуть и понять. И мне кажется, что в диалоге с Андреем ты тоже пытался что-то доказывать.
 

hoz

Активный участник
Не в обиду тебе. Я видел твой вопрос ещё до ответа Андрея, но отвечать на него не стал. Какой вопрос такой и ответ. Ты путаешь тикет с магиком и что-то оспариваешь вместо того чтобы вникнуть и понять. И мне кажется, что в диалоге с Андреем ты тоже пытался что-то доказывать.


Никакой обиды нет, я же не профи, чтоб всегда выражаться верно. Видать, где-то ошибся. Но зачем же так категорично то всё воспринимать?
По сути, я на самом деле, с меджиком перепутал. Как обычно, на форум вылез уже после того как немало заработался, и написать не то что хотел. Понимаю, что не то, но в тот момент, голова уже не особо понимала, что писал..:oops:
Признаю свою описку(ошибку) в предыдущем посте. Хотя вот один нюанс я так всё-таки не особо понял, но он не столь важный, чтобы мусолить его видимо.

Не допонял я это:

Так вот поясняю почему все эти функции, не только OrderSend(...), возвращают значение или -1.
По той простой причине, что объявляя переменную без присваивания ей значения она автоматом равна нулю. Так вот -1 в этом случае просто означает, что функция не выполнена, а 0 означает что ордера ещё не открывались (не-было попыток это сделать) и соответственно если больше нуля значит ордер открыт.


Никто ни когда не сравнивает тикет с 0, а сразу пишут -1. Вот тут я честно сказать, не допонял.
 

AlexeyVik

Программист mql4 mql5
но он не столь важный, чтобы мусолить его видимо.

Не допонял я это:

Никто ни когда не сравнивает тикет с 0, а сразу пишут -1. Вот тут я честно сказать, не допонял.

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

По существу:
Если я так сравниваю, то "Никто ни когда" уже не выполнено
Всё зависит из какого места кода идёт сравнение и цель сравнивания. Я часто пользуюсь переменной Ticket объявленной на глобальном уровне. Это избавляет от лишних циклов перебора ордеров для определения каких-либо свойств ордера. Поэтому обязательно должно быть условие Ticket > 0 а когда ордер закрывается переменную Ticket обнуляю.
Но в момент открытия ордера нужна именно такая проверка о которой ты говоришь, но для такого сравнения у меня другая переменная в отдельной пользовательской функции открытия ордеров. Вот тогда и сравниваю if(ticket == -1) Если условие выполнено значит ошибка. И надо предпринять что-то для повторной попытки открыть ордер или выйти из функции. А для пущей уверенности, что корявость МТ4 не перепутает переменные я пишу их разными Ticket и ticket
Очень надеюсь, что теперь ты всё понял.
 

hoz

Активный участник
По существу:
Если я так сравниваю, то "Никто ни когда" уже не выполнено
Всё зависит из какого места кода идёт сравнение и цель сравнивания. Я часто пользуюсь переменной Ticket объявленной на глобальном уровне. Это избавляет от лишних циклов перебора ордеров для определения каких-либо свойств ордера. Поэтому обязательно должно быть условие Ticket > 0 а когда ордер закрывается переменную Ticket обнуляю.
Но в момент открытия ордера нужна именно такая проверка о которой ты говоришь, но для такого сравнения у меня другая переменная в отдельной пользовательской функции открытия ордеров. Вот тогда и сравниваю if(ticket == -1) Если условие выполнено значит ошибка. И надо предпринять что-то для повторной попытки открыть ордер или выйти из функции. А для пущей уверенности, что корявость МТ4 не перепутает переменные я пишу их разными Ticket и ticket
Очень надеюсь, что теперь ты всё понял.


Понял с большего, хотя, конечно, визуально понимается лучше.
 

hoz

Активный участник
Я переписал эксперт, и теперь у него не всегда при модификации ставятся стопы(для есн. типа счетов).

Вот что у меня в торговой ф-ции и ф-циях открытия и модификации):

PHP:
//+-------------------------------------------------------------------------------------+
//| Модификация ордеров для ECN - счетов                                                |
//+-------------------------------------------------------------------------------------+
bool OrdersModifying()
{
  int total = OrdersTotal() - 1;
  double sl = 0, tp = 0;
  
  for(int i=total; i>=0; i--)
  {
    if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES) == true)                            // Если ордер есть и он выбран..
    {
      if(g_type == OP_BUY)
      {
        if(i_sl != 0)                                                                 // Если входной параметр стоп-лосса не равен 0, то..
           sl = NormalizeDouble(OrderOpenPrice() - i_sl*pt,Digits);                    // Получаем значение стоп-лосса для выбранного ордера
        if(i_tp != 0)                                                                 // Если входной параметр тейкпрофита не равен 0, то..
           tp = NormalizeDouble(OrderOpenPrice() + i_tp*pt,Digits);                    // Получаем значение тейкпрофита для выбранного ордера
      }
      if(g_type == OP_SELL)
      {
        if(i_sl != 0)                                                                 // Если входной параметр стоп-лосса не равен 0, то..
           sl = NormalizeDouble(OrderOpenPrice() + i_sl*pt,Digits);                // Получаем значение стоп-лосса для выбранного ордера
        if(i_tp != 0)                                                                 // Если входной параметр тейкпрофита не равен 0, то..
           tp = NormalizeDouble(OrderOpenPrice() - i_tp*pt,Digits);                // Получаем значение тейкпрофита для выбранного ордера
      }
      if(OrderStopLoss() != sl || OrderTakeProfit() != tp)                                                            // Если полученные значения sl и tp не равныы 0, то..
      {
        OrderModify(g_ticket,OrderOpenPrice(),sl,tp,OrderOpenTime() + 86400,Lime);      // Модифицируем ордер
      }
    }
  }
  return(true);
}
//+-------------------------------------------------------------------------------------+
//| Открытие длинной позиции                                                            |
//+-------------------------------------------------------------------------------------+
bool OpenBuy()
{
  g_ticket = -1;
  string myNote = "сов баянул";
  
  if(GetPriceToInput() < Ask)
  {       
    g_ticket = OrderSend(Symbol(),OP_BUYLIMIT,0.1,GetPriceToInput(),3,0,0,myNote,myMagic,0,Blue);
  }
    if(g_ticket > 0 && OrderSelect(g_ticket,SELECT_BY_TICKET,MODE_TRADES) == true)
    {
      if(!OrdersModifying())
        return(false);
    }

  return(true);
}
//+-------------------------------------------------------------------------------------+
//| Открытие короткой позиции                                                           |
//+-------------------------------------------------------------------------------------+
bool OpenSell()
{
  g_ticket = -1;
  string myNote = "сов шортанул";

  if(GetPriceToInput() > Bid)
  {
    g_ticket = OrderSend(Symbol(),OP_SELLLIMIT,0.1,GetPriceToInput(),3,0,0,myNote,myMagic,0,Red);
  }
    if(g_ticket > 0 && OrderSelect(g_ticket,SELECT_BY_TICKET,MODE_TRADES) == true)
    {
      if(!OrdersModifying())
        return(false);
    }
  
  return(true);
}
//+-------------------------------------------------------------------------------------+
//| Открытие позиций                                                                    |
//+-------------------------------------------------------------------------------------+
bool Trade (int signal)
{
  FindOrders();

  if(signal == SIGNAL_BUY)                                                          // Если сигнал на покупку и открытых ордеров нет..
    if(!OpenBuy())                                                                  // открываем лимитный ордер на покупку
      return(false);                                                                
      
  if(signal == SIGNAL_SELL)                                                       // Если сигнал на продажу и открытых ордеров нет..
     if(!OpenSell())
       return(false);                                                              // открываем лимитный ордер на продажу

 //   if(OrderSelect(g_ticket,SELECT_BY_TICKET,MODE_TRADES))
  //  {
   //     if(OrderStopLoss() == 0 || OrderTakeProfit() == 0)
    //    OrdersModifying();                                                             // Модифицируем ордер, добавим SL и TP
  //  }    
 // if(UseBU == true)
   //  MovingStopLossToBU();                                                         // Перевод в б.у. по достижению некоторого значения TP

  return(true);
}


Может кто подсказать где ошибка? По логике всё верно как я вижу.
 
Последнее редактирование модератором:
Верх