Aprender e escrever juntos em MQL5 - página 25

 
Khomtchenko:

Onde cometi um erro. Porque é que tenho uma posição alargada.

Existe um conceito chamado netting. De acordo com a filosofia da NETTING, todas as transacções unidireccionais aumentam a posição, enquanto as transacções multidireccionais fecham, diminuem ou invertem-na.

Khomtchenko:
Verificação por indicador - se deve haver uma posição de Compra, mas há uma Venda, então compre.

Se tirarmos uma conclusão da linha, compreendemos que com uma Venda existente uma nova posição de Compra irá fechar ou cortar a posição existente.

PS

A propósito, TP e SL em MT5 são definidos de acordo com a última transacção, pelo que também devem ser monitorizados...

 
molotkovsm:

Qual é a forma correcta de eliminar todas as encomendas com um determinado modo?

Tenho duas funções para isto, check_orders checks_orders para encomendas com um determinado modo, e remove_sl elimina as encomendas:

O problema é que no meu diário da EA, recebo linhas como esta:

2011.05.11 21:40:19 Comércios '726238' : não conseguiu cancelar a encomenda #4375237 comprar 0,00 a 0,00000 [Pedido inválido]
Isto é, os pedidos desnecessários são enviados para o servidor comercial com um pedido de eliminação da ordem que já foi solicitada.

Devo consultar a lista de encomendas de cima para baixo, por exemplo

      while(check_orders()==true)
        {
         int orders=OrdersTotal();
         for(counter01=orders-1; counter01>=0; counter01--)
           {
            counter02=OrderGetTicket(counter01);
            if(OrderGetInteger(ORDER_MAGIC)!=magick)
               continue;
            remove_request.action=TRADE_ACTION_REMOVE; remove_request.order=counter02;
            if(OrderCheck(start_request,check_result)==true)
               OrderSend(start_request,trade_result);
           }
        }
 

ЗЫ Если вы знаете инструмент то для поиска позиции совсем не нужно перебирать все позиции, достаточно воспользоваться вот этой функцией:

bool  PositionSelect(
   string  symbol     // имя инструмента
   );

Obrigado. Vou tentar.

A propósito, utilizo um símbolo.

De acordo com a filosofia desta mesma REDE, todas as transacções unidireccionais aumentam a posição e as transacções multidireccionais fecham, diminuem ou invertem.

Exactamente!

Concluímos da linha que entendemos que com uma Venda existente uma nova Compra irá fechar ou aparar uma posição existente.

PS

A propósito, TP e SL em MT5 são definidos de acordo com a última transacção, pelo que também devem ser monitorizados...

Das suas palavras, Sr.Interessante , compreendo que compreendo tudo correctamente.

Estou a utilizar os mesmos lotes. Estou a utilizar as mesmas paragens. Tudo é como deveria ser. Mas algo está errado!

Está bem. Prometeu fazer dois EAs e mostrar a diferença. Eu faço-o. Não quero pôr o melhor lá fora para que todos possam ver.

 

Então, quem entre os peritos respeitados pode enviar dois EAs para a mesma estratégia em mql4 e em mql5?

Só preciso de descobrir o que estou a fazer mal, é só isso. Bem, estatísticas de preços diferentes não podem alterar os resultados dos testes em 2-3 vezes. Trata-se de programação.

Lizar,Renat,sergeev, HELP me. Posso dar-vos todos os peritos para reverem o código. O Expert Advisor é simples mas eficaz. Ainda posso melhorá-lo, mas simplifiquei-o ao máximo, para tornar a essência do problema mais clara.

Peço também desculpa a todos por ser intemperados nas suas declarações. Estou envergonhada. Mas eu quero MUITO compreender tudo!

 
Pode colocá-lo aqui, para que aqueles que estão interessados possam dar uma vista de olhos.
 
Rosh:

Necessidade de percorrer a lista de encomendas de cima para baixo, por exemplo, desta forma:

Não ajuda, aparentemente a encomenda é eliminada com sucesso e depois é enviado outro pedido:

2011.05.12 16:42:57 Comércios '726238' : cancelar encomenda #4388299 comprar paragem 0.02 EURUSD a 1.41700 feito
2011.05.12 16:42:57 Comércios '726238' : cancelar encomenda #4388299 comprar paragem 0.02 EURUSD a 1.41700
2011.05.12 16:42:58 Comércios '726238' : não conseguiu cancelar a encomenda #4388299 comprar 0,00 a 0,00000 [Pedido inválido] - já uma compra enquanto a paragem de compra era

 
//+------------------------------------------------------------------+
//|                                                     M2H1mql5.mq5 |
//|                              Copyright 2011, Yuriy V.Khomtchenko |
//|                                         mr.Khomtchenko@gmail.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2011, Yuriy V.Khomtchenko"
#property link      "mr.Khomtchenko@gmail.com"
#property version   "1.00"

MqlRates price[2];

double m_buff_EMAs[];
double m_buff_EMAb[];
double Ask; 
double Bid; 
int N=2;
double m_handle_ema1, m_handle_ema3;
extern double Lots = 0.1;
extern int Period_MA1=4;   
extern int Period_MA3=21;
bool mm =0;
bool New_Bar=false;
int const magic=102406;
double Mas0, Mab0, Mas1, Mab1;

double  
         StopLoss=200,                  
         TakeProfit=3200;                  
   
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
  m_handle_ema1=iMA(_Symbol,_Period,Period_MA1,0,MODE_EMA,PRICE_CLOSE);
  m_handle_ema3=iMA(_Symbol,_Period,Period_MA3,0,MODE_EMA,PRICE_CLOSE);
 
//---
   return(0);
  }

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
   GetIns();
   if (!PositionSelect(_Symbol))
    { 
     if(Mas0>Mab0 && Mas1<Mab1)  OpenBuy(Lots,10,"EUR/USD (Buy)",102406);
     if(Mas0<Mab0 && Mas1>Mab1)  OpenSell(Lots,10,"EUR/USD (Sell)",102406);
    }
  if (PositionSelect(_Symbol)) TryToClose();
  }
//+------------------------------------------------------------------+
void GetIns()
{
 CopyRates(_Symbol, _Period,0,2,price); 
 CopyBuffer(m_handle_ema1,0,0,N,m_buff_EMAs);
 ArraySetAsSeries(m_buff_EMAs,true);
 CopyBuffer(m_handle_ema3,0,0,N,m_buff_EMAb);
 ArraySetAsSeries(m_buff_EMAb,true);
 Mas0=m_buff_EMAs[0];
 Mas1=m_buff_EMAs[1];
 Mab0=m_buff_EMAb[0];
 Mab1=m_buff_EMAb[1];
 MqlTick last_tick;//Здесь будут храниться цены последнего пришедшего тика
 SymbolInfoTick(_Symbol,last_tick);//заполняем структуру last_tick последними ценами текущего символа.
 Ask=last_tick.ask;//Обновляем переменные Ask и Bid для дальнейшего использования
 Bid=last_tick.bid;
 return;
}

//Функция открытия длинной (Long) позиции. Указываем также значения переменных по умолчанию
int OpenBuy(double volume,int slippage=10,string comment="EUR/USD (Buy)",int magic0=102406)
  {
   MqlTradeRequest my_trade;//объявляем структуру типа MqlTradeRequest для формирования запроса
   MqlTradeResult my_trade_result;//в этой структуре будет ответ сервера на запрос.

   //далее заполняеем все НЕОБХОДИМЫЕ поля структуры запроса.
   my_trade.action=TRADE_ACTION_DEAL;//Установить торговый ордер на немедленное совершение сделки с указанными 
                                     //параметрами (поставить рыночный ордер)
   my_trade.symbol=Symbol();//указываем в качестве валютной пары - текущую валютную пару 
                            //(ту, на которой запущен советник)
   my_trade.volume=NormalizeDouble(volume,1);//размер лота
   my_trade.price=NormalizeDouble(Ask,_Digits);//Цена, при достижении которой ордер должен быть исполнен. 
   //В нашем случае для TRADE_ACTION_DEAL это текущая цена и ее, согласно инструкции указывать не обязательно.
   my_trade.sl=NormalizeDouble(Ask-StopLoss*_Point,_Digits);//стоплосс ордера (цена при которой следует закрыть 
                                                            //убыточную сделку)
   my_trade.tp=NormalizeDouble(Ask+TakeProfit*_Point,_Digits);//тейкпрофит (цена при которой следует закрыть
                                                              // прибыльную сделку)
   my_trade.deviation=slippage;//проскальзывание в пунктах (при тестировании особой роли не играет, т.к. 
                               //проскальзывания не бывает на тестах)
   my_trade.type=ORDER_TYPE_BUY;//тип рыночного ордера (покупаем)
   my_trade.type_filling=ORDER_FILLING_AON;//Указываем как исполнять ордер. (All Or Nothing - все или ничего) 
   //Сделка может быть совершена исключительно в указанном объеме и по цене равной или лучше указанной в ордере.
   my_trade.comment=comment;//комментарий ордера
   my_trade.magic=magic;//магическое число ордера

   ResetLastError();//обнуляем код последней ошибки 
   if(OrderSend(my_trade,my_trade_result))//отправляем запрос на открытие позиции. При этом проверяем 
                                          //успешно ли прошла отправка запроса
     {
      // Если сервер принял ордер то смортрим на результат 
  
      Print("Код результата операции - ",my_trade_result.retcode);
     }
   else
     {
      //Сервер не принял ордер в нем есть ошибки, выводим их в журнал
      Print("Код результата операции - ",my_trade_result.retcode);
      Print("Ошибка открытия ордера = ",GetLastError());
     }
return(0);// Выходим из функции открытия ордера     
}

//функция открытия короткой (Short) позиции. Аналогична функции открытия длинной позиции.
int OpenSell(double volume,int slippage=10,string comment="Open Short EUR/USD (Sell)",int magic0=102406)
  {
   MqlTradeRequest my_trade;
   MqlTradeResult my_trade_result;
   my_trade.action=TRADE_ACTION_DEAL;
   my_trade.symbol=Symbol();
   my_trade.volume=NormalizeDouble(volume,1);
   my_trade.price=NormalizeDouble(Bid,_Digits);
   my_trade.sl=NormalizeDouble(Bid+StopLoss*_Point,_Digits);
   my_trade.tp=NormalizeDouble(Bid-TakeProfit*_Point,_Digits);
   my_trade.deviation=slippage;
   my_trade.type=ORDER_TYPE_SELL;
   my_trade.type_filling=ORDER_FILLING_AON;
   my_trade.comment=comment;
   my_trade.magic=magic;

   ResetLastError();
   if(OrderSend(my_trade,my_trade_result))
     {

      Print("Код результата операции - ",my_trade_result.retcode);
     }
   else
     {
      Print("Код результата операции - ",my_trade_result.retcode);
      Print("Ошибка открытия ордера = ",GetLastError());
      }
return(0);
}

int TryToClose()
{
       if (PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY)
       if(Mas0<Mab0 && Mas1>Mab1) OpenSell(Lots,10,"EUR/USD (Sell)",102406);
      if (PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_SELL)
       if(Mas0>Mab0 && Mas1<Mab1) OpenBuy(Lots,10,"EUR/USD (Buy)",102406);
  return(0);
}

semelhante, mas em mql4:

//+------------------------------------------------------------------+
//|                                                       H1EU2M.mq4 |
//|                             Copyright © 2011 Khomtchenko V. Yury |
//|                                         mr.Khomtchenko@gmail.com |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2011 Khomtchenko V. Yury"
#property link      "mr.Khomtchenko@gmail.com"

 extern double Lots = 0.1;

 extern int Period_MA1=4;    
 extern int Period_MA3=21;
  bool mm =0;
 bool New_Bar=false;
  int magic=10605;
 double Mas0, Mal0, Mab0, Mas1, Mal1, Mab1;
 int mt,ticket, total, mtotal, i, count, time_oc, md, refresh;
 double  
         SL=0.002,                 
         kmin=1,                   
         border=500,
         TP=0.032;                  
            
int      delay=3200,//3200
         maxr=10;
int      handle;

int init()
  {
//----
 time_oc=0; 
 md=0; 
 refresh=0;
//----
   return(0);
  }

int start()
  {
//----
  GetIns();
 

  OpenBuy();
  OpenSell(); 
  
 
  CloseSellEnd();
  CloseBuyEnd();
//----
   return(0);
  }
//+------------------------------------------------------------------+

int GetIns()
{
 Mas0=iMA(NULL,0,Period_MA1,0,MODE_EMA,PRICE_CLOSE,0);//40
 Mab0=iMA(NULL,0,Period_MA3,0,MODE_EMA,PRICE_CLOSE,0);//40
 Mas1=iMA(NULL,0,Period_MA1,0,MODE_EMA,PRICE_CLOSE,1);//40
 Mab1=iMA(NULL,0,Period_MA3,0,MODE_EMA,PRICE_CLOSE,1);//40
}

int OpenBuy()
{
total=Total();
  
   if(Total()<1) 
     {//2
      if(Mas0>Mab0 && Mas1<Mab1 )
        {//21
        refresh=0;
        while(true){ RefreshRates();
        Print("Try to open BUY H1:",Ask,"(",refresh,")", ", TotalOrders:",OrdersTotal(),", My orders:", Total());
        refresh++;
        ticket=OrderSend(Symbol(),OP_BUY,Lots,Ask,50,Ask-SL,Ask+TP,"BUY 60",magic,0,Green);
        if (refresh>=maxr) return(0); 
         if(ticket>0)
           {//22
            Print("BUY order opened H1: ",Ask, ", TotalOrders:",OrdersTotal(),", My orders:", Total());
            time_oc=TimeLocal( );
            md=0;
            return(0);
           }//22
           continue;  }
        }//21
      }//2
}

int OpenSell()
{
 total=Total();
       if(Total()<1) 
       {
        if(Mas0<Mab0 && Mas1>Mab1)
          {
          refresh=0;
          while(true){ RefreshRates();
           Print("Try to open Sell H1: ",Bid,"(",refresh,")", ", TotalOrders:",OrdersTotal(),", My orders:", Total());
           refresh++;
           ticket=OrderSend(Symbol(),OP_SELL,Lots,Bid,50,Bid+SL,Bid-TP,"SELL 60",magic,0,Red);
           if (refresh>=maxr) return(0); 
           if(ticket>0)
             {
              Print("SELL order opened H1: ",Bid, ", TotalOrders:",OrdersTotal(),", My orders:", Total());
              time_oc=TimeLocal( );
              md=0;
              return(0);
             } 
           continue;  }
          }
        }
}

int CloseBuyEnd()
{
if (Total()>0)
     {//3
     mtotal=OrdersTotal();
     for (i=0; i<mtotal; i++)
      {//for
      if(OrderSelect(i,SELECT_BY_POS)==true)
       {//31
       if (OrderType()==OP_BUY && OrderMagicNumber()==magic)// check for long position (BUY) close possibility
        {//32
         if(Mas0<Mab0 && Mas1>Mab1)//70
          {//33
          refresh=0;
          while(true){ RefreshRates();
          refresh++;
          ticket=OrderClose(OrderTicket(),OrderLots(),Bid,50,Red);
          if (refresh>=maxr) return(0);
          if (ticket>0)
           {//331
            Print("BUY order CLOSED (TP): ",OrderClosePrice());
            time_oc=0;
            md=0;
            return(0);
           }//331
           continue;  }
           }//33
         }//32 
        }//31
        }//for
     }//3
}

int CloseSellEnd()
{
mtotal=OrdersTotal();
if (Total()>0)
     {//3
     for (i=0; i<mtotal; i++)
      {//for
      if(OrderSelect(i,SELECT_BY_POS)==true)
       {//31
       if (OrderType()==OP_SELL && OrderMagicNumber()==magic)// check for long position (SELL) close possibility
         {//32
          if(Mas0>Mab0 && Mas1<Mab1)//70
          {//33
          refresh=0;
          while(true){ RefreshRates();
          refresh++;
           ticket=OrderClose(OrderTicket(),OrderLots(),Ask,50,Green);
           if (refresh>=maxr) return(0);
            if (ticket>0)
             {//351
              Print("SELL order closed (TP): ",OrderClosePrice()); 
              time_oc=0;
              md=0;
              return(0);
             }//351
             continue;  }
          }//33
         }//32 
        }//31
        }//for
     }//3  
}

int Total()
{
 count=0;
 for (i=0;i<OrdersTotal();i++)
  {
   OrderSelect(i,SELECT_BY_POS);
   if (OrderMagicNumber( )==magic) {count++;}
  }
 return(count);
}

Bem, veja e compare. Fiz asneira algures... A diferença é substancial.

 
molotkovsm:

Não ajuda, aparentemente a encomenda é eliminada com sucesso e depois é enviado outro pedido:

2011.05.12 16:42:57 Comércios '726238' : cancelar encomenda #4388299 comprar paragem 0.02 EURUSD a 1.41700 feito
2011.05.12 16:42:57 Comércios '726238' : cancelar encomenda #4388299 comprar paragem 0.02 EURUSD a 1.41700
2011.05.12 16:42:58 Comércios '726238' : não conseguiu cancelar a encomenda #4388299 comprar 0,00 a 0,00000 [Pedido inválido] - já uma compra enquanto a paragem de compra era

Tenho vergonha de admitir que ainda não dominei a arte da telepatia.
 
Quase me esquecia. Os EAs trabalham em Eur/Usd H1. Testado de 1.01.2010 a 1.05.2011.
 
Rosh:
Tenho vergonha de admitir que ainda não dominei a arte da telepatia.

Vou repetir a pergunta:

Como posso eliminar correctamente todas as encomendas com um certo mag?

Tenho duas funções para isto, check_orders verifica as encomendas com um determinado modo e remove_sl remove-as:

void remove_sl()
     {
      int counter01;
      ulong counter02;
      while(check_orders()==true)
        {
         for(counter01=0; counter01<OrdersTotal(); counter01++)
           {
            counter02=OrderGetTicket(counter01);
            if(OrderGetInteger(ORDER_MAGIC)!=magick)
               continue;
            remove_request.action=TRADE_ACTION_REMOVE; remove_request.order=counter02;
            if(OrderCheck(start_request,check_result)==true)
               OrderSend(start_request,trade_result);
           }
        }
     }



bool check_orders()
     {
      int counter01;
      bool order_exist=false;
      for(counter01=0; counter01<OrdersTotal(); counter01++)
        {
         OrderGetTicket(counter01);
         if(OrderGetInteger(ORDER_MAGIC)==magick)
           {
            order_exist=true;
            break;
           }
        }
      return(order_exist);
     }

O problema é que na revista da EA estas linhas aparecem:

2011.05.11 21:40:19 Comércios '726238' : não conseguiu cancelar a encomenda #4375237 comprar 0,00 a 0,00000 [Pedido inválido]
Isto é, pedidos desnecessários são enviados para o servidor comercial para remover a encomenda que já tinha sido solicitada.

Aconselha-se o seguinte:

É necessário percorrer a lista de encomendas de cima para baixo, por exemplo, desta forma:

 while(check_orders()==true)
        {
         int orders=OrdersTotal();
         for(counter01=orders-1; counter01>=0; counter01--)
           {
            counter02=OrderGetTicket(counter01);
            if(OrderGetInteger(ORDER_MAGIC)!=magick)
               continue;
            remove_request.action=TRADE_ACTION_REMOVE; remove_request.order=counter02;
            if(OrderCheck(start_request,check_result)==true)
               OrderSend(start_request,trade_result);
           }
        }

Tentei fazer como disse, mas o problema mantém-se - a ordem pendente é apagada primeiro, depois é enviado outro pedido para apagar a mesma ordem. Aqui está um exemplo das linhas de registo:

2011.05.12 16:42:57 Comércios '726238' : cancelar a encomenda #4388299 comprar paragem 0.02 EURUSD a 1.41700 feito - eliminar a encomenda com sucesso
2011.05.12 16:42:57 Comércios '726238' : cancelar encomenda #4388299 comprar paragem 0.02 EURUSD a 1.41700 - Outro pedido está a ser enviado
2011.05.12 16:42:58 Comércios '726238' : não conseguiu cancelar a encomenda #4388299 comprar 0,00 a 0,00000 [Pedido inválido] - foi comprada por alguma razão.

Isto não acontece sempre, mas por vezes, e não afecta o funcionamento do Conselheiro Especialista. Só quero fazer tudo correctamente, não para carregar o servidor comercial com pedidos vazios, e para resolver o problema.

Obrigado pelas vossas respostas e pela vossa disponibilidade para ajudar.


Документация по MQL5: Стандартные константы, перечисления и структуры / Торговые константы / Свойства ордеров
Документация по MQL5: Стандартные константы, перечисления и структуры / Торговые константы / Свойства ордеров
  • www.mql5.com
Стандартные константы, перечисления и структуры / Торговые константы / Свойства ордеров - Документация по MQL5