Прошу совета по MQL4 - страница 2

 
xgnom:

В Profit.mq4 я поместил код функции isCloseLastPosByTake, а в своем советнике перед функцией start() сделал #include < Profit.mq4 >

Сейчас убрал #include < Profit.mq4 > из советника, и вписал полностью код функции isCloseLastPosByTake - естественно ничего не поменялось, и такое же предупреждение "'isCloseLastPosByTake' - expression on global scope not allowed "

Может быть у меня структура кода неправильная?

код функции isCloseLastPosByTake

старт

если(условие выполняется)

открываем ордер1 на покупку

открываем ордер2 на покупку

ставим отложенный ордер3 на покупку

ставим отложенный ордер4 на покупку

ретурн

если(условие выполняется)

открываем ордер1 на продажу

открываем ордер2 на продажу

ставим отложенный ордер3 на продажу

ставим отложенный ордер4 на продажу

ретурн

если( isCloseLastPosByTake )

закрываем все ордера

ретурн

Выложите последний вариант кода советника полностью.
 
bool isCloseLastPosByTake(string sy="", int op=-1, int mn=-1) {
  datetime t;
  double   ocp, otp;
  int      dg, i, j=-1, k=OrdersHistoryTotal();

  if (sy=="0") sy=Symbol();
  for (i=0; i<k; i++) {
    if (OrderSelect(i, SELECT_BY_POS, MODE_HISTORY)) {
      if (OrderSymbol()==sy || sy=="") {
        if (OrderType()==OP_BUY || OrderType()==OP_SELL) {
          if (op<0 || OrderType()==op) {
            if (mn<0 || OrderMagicNumber()==mn) {
              if (t<OrderCloseTime()) {
                t=OrderCloseTime();
                j=i;
              }
            }
          }
        }
      }
    }
  }
  if (OrderSelect(j, SELECT_BY_POS, MODE_HISTORY)) {
    dg=MarketInfo(sy, MODE_DIGITS);
    if (dg==0) if (StringFind(OrderSymbol(), "JPY")<0) dg=4; else dg=2;
    ocp=NormalizeDouble(OrderClosePrice(), dg);
    otp=NormalizeDouble(OrderTakeProfit(), dg);
    if (ocp==otp) return(True);
  }
  return(False);
}

int init()
  {

   return(0);
  }

int deinit()
  {

   return(0);
  }

int start()
{
double TakeProfit = 100;
double NextBuy = 100;
double Lots = 0.01;
int buy, buy2, buy3, buy4, sell, sell2, sell3, sell4, 
if (OrderSelect(0,SELECT_BY_POS,MODE_TRADES)==False)
{
if(Bid>iMA(Symbol(),PERIOD_M15,21,0,1,4,0)) 
{
buy=OrderSend(Symbol(),OP_BUY,Lots,Ask,3,0, Ask+TakeProfit*Point, "buy");
buy2=OrderSend(Symbol(),OP_BUY,Lots*2,Ask-NextBuy*Point,3,0, Ask, "buy2");
buy3=OrderSend(Symbol(),OP_BUYLIMIT,Lots*4,Ask-NextBuy*2*Point,3,0, Ask-TakeProfit*Point, "buy3");
buy4=OrderSend(Symbol(),OP_BUYLIMIT,Lots*8,Ask-NextBuy*3*Point,3,0, Ask-TakeProfit*2*Point, "buy4");
return(0);
}
if (OrderSelect(0,SELECT_BY_POS,MODE_TRADES)==False)
{
if(Bid<iMA(Symbol(),PERIOD_M15,21,0,1,4,0)) 
{
sell=OrderSend(Symbol(),OP_SELL,Lots,Bid,3,0, Bid-TakeProfit*Point, "sell");
sell2=OrderSend(Symbol(),OP_SELL,Lots*2,Bid+NextBuy*Point,3,0, Bid, "sell2");
sell3=OrderSend(Symbol(),OP_SELLLIMIT,Lots*4,Bid+NextBuy*2*Point,3,0, Bid+TakeProfit*Point, "sell3");
sell4=OrderSend(Symbol(),OP_SELLLIMIT,Lots*8,Bid+NextBuy*3*Point,3,0, Bid+TakeProfit*2*Point, "sell4");
}
}
}
return(0);
}

if(isCloseLastPosByTake(0, -1, -1))
{
  int total = OrdersTotal();
  for(int i=total-1;i>=0;i--)
  {
    OrderSelect(i, SELECT_BY_POS);
    int type   = OrderType();

    bool result = false;
    
    switch(type)
    {
      //Close opened long positions
      case OP_BUY       : result = OrderClose( OrderTicket(), OrderLots(), MarketInfo(OrderSymbol(), MODE_BID), 5, Red );
                          break;
      
      //Close opened short positions
      case OP_SELL      : result = OrderClose( OrderTicket(), OrderLots(), MarketInfo(OrderSymbol(), MODE_ASK), 5, Red );
                          break;

      //Close pending orders
      case OP_BUYLIMIT  :
      case OP_BUYSTOP   :
      case OP_SELLLIMIT :
      case OP_SELLSTOP  : result = OrderDelete( OrderTicket() );
    }
    
    if(result == false)
    {
      Alert("Order " , OrderTicket() , " failed to close. Error:" , GetLastError() );
      Sleep(3000);
    }  
  }
  
  return(0);
}
 

Ошибки компиляции устранил, отсутствие других, если такие имеются, не гарантирую.

bool isCloseLastPosByTake(string sy="", int op=-1, int mn=-1) {
  datetime t;
  double   ocp, otp;
  int      dg, i, j=-1, k=OrdersHistoryTotal();

  if (sy=="0") sy=Symbol();
  for (i=0; i<k; i++) {
    if (OrderSelect(i, SELECT_BY_POS, MODE_HISTORY)) {
      if (OrderSymbol()==sy || sy=="") {
        if (OrderType()==OP_BUY || OrderType()==OP_SELL) {
          if (op<0 || OrderType()==op) {
            if (mn<0 || OrderMagicNumber()==mn) {
              if (t<OrderCloseTime()) {
                t=OrderCloseTime();
                j=i;
              }
            }
          }
        }
      }
    }
  }
  if (OrderSelect(j, SELECT_BY_POS, MODE_HISTORY)) {
    dg=MarketInfo(sy, MODE_DIGITS);
    if (dg==0) if (StringFind(OrderSymbol(), "JPY")<0) dg=4; else dg=2;
    ocp=NormalizeDouble(OrderClosePrice(), dg);
    otp=NormalizeDouble(OrderTakeProfit(), dg);
    if (ocp==otp) return(True);
  }
  return(False);
}

int init()
  {

   return(0);
  }

int deinit()
  {

   return(0);
  }

int start()
{
double TakeProfit = 100;
double NextBuy = 100;
double Lots = 0.01;
int buy, buy2, buy3, buy4, sell, sell2, sell3, sell4; 
//if (OrderSelect(0,SELECT_BY_POS,MODE_TRADES)==False)
//   {
    if(Bid>iMA(Symbol(),PERIOD_M15,21,0,1,4,0)) 
      {
       buy=OrderSend(Symbol(),OP_BUY,Lots,Ask,3,0, Ask+TakeProfit*Point, "buy");
       buy2=OrderSend(Symbol(),OP_BUY,Lots*2,Ask-NextBuy*Point,3,0, Ask, "buy2");
       buy3=OrderSend(Symbol(),OP_BUYLIMIT,Lots*4,Ask-NextBuy*2*Point,3,0, Ask-TakeProfit*Point, "buy3");
       buy4=OrderSend(Symbol(),OP_BUYLIMIT,Lots*8,Ask-NextBuy*3*Point,3,0, Ask-TakeProfit*2*Point, "buy4");
      }
//if (OrderSelect(0,SELECT_BY_POS,MODE_TRADES)==False)
//{
    if(Bid<iMA(Symbol(),PERIOD_M15,21,0,1,4,0)) 
      {
       sell=OrderSend(Symbol(),OP_SELL,Lots,Bid,3,0, Bid-TakeProfit*Point, "sell");
       sell2=OrderSend(Symbol(),OP_SELL,Lots*2,Bid+NextBuy*Point,3,0, Bid, "sell2");
       sell3=OrderSend(Symbol(),OP_SELLLIMIT,Lots*4,Bid+NextBuy*2*Point,3,0, Bid+TakeProfit*Point, "sell3");
       sell4=OrderSend(Symbol(),OP_SELLLIMIT,Lots*8,Bid+NextBuy*3*Point,3,0, Bid+TakeProfit*2*Point, "sell4");
      }
//}
//}
//return(0);
//}

if(isCloseLastPosByTake("0", -1, -1))
  {
   int total = OrdersTotal();
   for(int i=total-1;i>=0;i--)
   {
    OrderSelect(i, SELECT_BY_POS);
    int type   = OrderType();

    bool result = false;
    
    switch(type)
    {
      //Close opened long positions
      case OP_BUY       : result = OrderClose( OrderTicket(), OrderLots(), MarketInfo(OrderSymbol(), MODE_BID), 5, Red );
                          break;
      
      //Close opened short positions
      case OP_SELL      : result = OrderClose( OrderTicket(), OrderLots(), MarketInfo(OrderSymbol(), MODE_ASK), 5, Red );
                          break;

      //Close pending orders
      case OP_BUYLIMIT  :
      case OP_BUYSTOP   :
      case OP_SELLLIMIT :
      case OP_SELLSTOP  : result = OrderDelete( OrderTicket() );
    }
    
    if(result == false)
    {
      Alert("Order " , OrderTicket() , " failed to close. Error:" , GetLastError() );
      Sleep(3000);
    }  
  }
}     
  return(0);
}
 
khorosh:

Ошибки компиляции устранил, отсутствие других, если такие имеются, не гарантирую.



Спасибо огромное! Наконец-то все заработало как надо.
 
khorosh:

Ошибки компиляции устранил, отсутствие других, если такие имеются, не гарантирую.



khorosh, не могли бы Вы ответить еще на один вопрос?

Дело в том, что при прогоне советника в тестере МТ4, при срабатывании тейк-профит, соответсвенно и закрытия всех ордеров... происходит цикл открытия и моментального закрытия ордеров много раз, в связи с чем свопами съедается ощутимая сумма. Складывается впечатление, что скрипт isCloseLastPosByTake еще не доработал, а новый вход в рынок уже происходит. Как можно это устранить? Пробовал функцию sleep(10000), но она не помогла. Или такое происходит потому, что тестер, а на реале и демо счете будет работать нормально?

 
xgnom:



khorosh, не могли бы Вы ответить еще на один вопрос?

Дело в том, что при прогоне советника в тестере МТ4, при срабатывании тейк-профит, соответсвенно и закрытия всех ордеров... происходит цикл открытия и моментального закрытия ордеров много раз, в связи с чем свопами съедается ощутимая сумма. Складывается впечатление, что скрипт isCloseLastPosByTake еще не доработал, а новый вход в рынок уже происходит. Как можно это устранить? Пробовал функцию sleep(10000), но она не помогла. Или такое происходит потому, что тестер, а на реале и демо счете будет работать нормально?

ну так конечно будет открываться. вы по тренду достигаете ТП и конечно же будет выполняться вот это условие для БАЙ

if(Bid>iMA(Symbol(),PERIOD_M15,21,0,1,4,0)) { //... }

идет новая серия открытия.

Функция Кима видит закрытые ордера по ТП и соответственно тут же их закрывает.

Вместо if(isCloseLastPosByTake("0", -1, -1)) считайте историю ордеров. Сравните их цену закрытия с ТП. Если разница небольшая, то вызывайте функцию isCloseLastPosByTake("0", -1, -1);

Даже если Все ордера не отработаются функцией (что за положняк на реале в кухнях, выдадут реквот например), то на следующем тике не отработанные ордера опять будут обрабатываться.

Обратите внимание на:

sell2=OrderSend(Symbol(),OP_SELL,Lots*2,Bid+NextBuy*Point,3,0, Bid, "sell2");

для бай2 - то же самое

Вы открываете ордер "прям щас " Но смещаете цену от той которая есть сейчас. такой ордер не откроется в 99% случаев. Ставьте вместо него отложенный.

 
xgnom:



khorosh, не могли бы Вы ответить еще на один вопрос?

Дело в том, что при прогоне советника в тестере МТ4, при срабатывании тейк-профит, соответсвенно и закрытия всех ордеров... происходит цикл открытия и моментального закрытия ордеров много раз, в связи с чем свопами съедается ощутимая сумма. Складывается впечатление, что скрипт isCloseLastPosByTake еще не доработал, а новый вход в рынок уже происходит. Как можно это устранить? Пробовал функцию sleep(10000), но она не помогла. Или такое происходит потому, что тестер, а на реале и демо счете будет работать нормально?

Во первых isCloseLastPosByTake не скрипт, а функция. Вы почитайте учебник, чтобы иметь элементарные понятия: что такое скрипт, советник, функция, индикатор. А то не имея элементарных знаний сразу пытаетесь что-то программировать. У вас беспрерывное открытие ордеров так как количество открываемых ордеров ничем не ограничено. Вы что хотите, чтобы я открыл курс ликбеза в этой ветке? А смысл? Что я должен сюда копировать главы из учебника? Читайте учебник напрямую.
 

Прошу помощи.

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

Нужно: После закрытия ордера по ТП в этот день по этому условию советник ордер больше не открывал, а при закрытии по СЛ могбы опять открыть сделку по этому условию.

Или хотя бы чтобы в день советник не мог совершать больше одной сделки.

Прошу прощения если коряво изъяснился.

 
dimeon:

ну так конечно будет открываться. вы по тренду достигаете ТП и конечно же будет выполняться вот это условие для БАЙ

if(Bid>iMA(Symbol(),PERIOD_M15,21,0,1,4,0)) { //... }

идет новая серия открытия.

Функция Кима видит закрытые ордера по ТП и соответственно тут же их закрывает.

Вместо if(isCloseLastPosByTake("0", -1, -1)) считайте историю ордеров. Сравните их цену закрытия с ТП. Если разница небольшая, то вызывайте функцию isCloseLastPosByTake("0", -1, -1);

Даже если Все ордера не отработаются функцией (что за положняк на реале в кухнях, выдадут реквот например), то на следующем тике не отработанные ордера опять будут обрабатываться.

Обратите внимание на:

sell2=OrderSend(Symbol(),OP_SELL,Lots*2,Bid+NextBuy*Point,3,0, Bid, "sell2");

для бай2 - то же самое

Вы открываете ордер "прям щас " Но смещаете цену от той которая есть сейчас. такой ордер не откроется в 99% случаев. Ставьте вместо него отложенный.

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

"...идет новая серия открытия. Функция Кима видит закрытые ордера по ТП и соответственно тут же их закрывает." Не правильно. После закрытия по тейку первого ордера остальные ордера будут закрыты по команде, а не по тейку, поэтому функция Кима примет состояние false и не разрешит сразу удаление ордеров новой серии, до того пока один из них не закроется по тейку.

"Вместо if(isCloseLastPosByTake("0", -1, -1)) считайте историю ордеров. Сравните их цену закрытия с ТП. Если разница небольшая, то вызывайте функцию isCloseLastPosByTake("0", -1, -1);" - а это для чего? Непонятно.

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


 
MOHCTP36:

Прошу помощи.

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

Нужно: После закрытия ордера по ТП в этот день по этому условию советник ордер больше не открывал, а при закрытии по СЛ могбы опять открыть сделку по этому условию.

Или хотя бы чтобы в день советник не мог совершать больше одной сделки.

Прошу прощения если коряво изъяснился.

- запомнить тикет открытой позиции

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

Причина обращения: