Apprendre et écrire ensemble en MQL5 - page 25

 
Khomtchenko:

Où j'ai fait une erreur. Pourquoi ai-je une position élargie.

Il existe un concept appelé "compensation". Selon la philosophie du NETTING, toutes les transactions unidirectionnelles augmentent la position, tandis que les transactions multidirectionnelles la ferment, la diminuent ou l'inversent.

Khomtchenko:
Vérification par indicateur - s'il devrait y avoir une position d'achat, mais qu'il y a une position de vente, alors il faut acheter.

Si nous tirons une conclusion de la ligne, nous comprenons qu'avec une vente existante, une nouvelle position d'achat fermera ou coupera la position existante.

PS

A propos, le TP et le SL dans MT5 sont fixés en fonction de la dernière transaction, ils doivent donc être surveillés également...

 
molotkovsm:

Comment puis-je supprimer correctement toutes les commandes avec un certain mode ?

J'ai deux fonctions pour cela, check_orders vérifie les commandes avec un certain mode, et remove_sl les supprime :

Le problème est que dans le journal de mon EA, j'obtiens des lignes comme celle-ci :

2011.05.11 21:40:19 Trades '726238' : échec de l'annulation de l'ordre #4375237 buy 0.00 at 0.00000 [Requête invalide].
C'est-à-dire que des demandes inutiles sont envoyées au serveur commercial avec une demande de suppression de l'ordre qui a déjà été demandé.

Je devrais passer en revue la liste des commandes de haut en bas, par ex :

      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     // имя инструмента
   );

Merci. Je vais essayer.

Au fait, j'utilise un seul symbole.

Selon la philosophie de ce même NETTING, toutes les transactions unidirectionnelles augmentent la position et les transactions multidirectionnelles ferment, diminuent ou s'inversent.

Exactement !

Nous concluons de la ligne que nous comprenons qu'avec une vente existante, un nouvel achat fermera ou réduira une position existante.

PS

A propos, le TP et le SL dans MT5 sont fixés en fonction de la dernière transaction, ils doivent donc être surveillés également...

D'après vos paroles, M.Intéressant , je comprends que j'ai tout compris correctement.

J'utilise les mêmes lots. J'utilise les mêmes arrêts. Tout est comme il se doit. Mais quelque chose ne va pas !

Ok. J'ai promis de faire deux EA et de montrer la différence. Je vais le faire. Je ne veux pas mettre le meilleur pour que tout le monde le voie.

 

Alors, qui parmi les experts respectés peut m'envoyer par courriel deux EA pour la même stratégie sur mql4 et sur mql5 ?

J'ai juste besoin de comprendre ce que je fais mal, c'est tout. Eh bien, des statistiques de prix différentes ne peuvent pas changer les résultats du test de 2-3 fois. C'est une question de programmation.

Lizar,Renat,sergeev, aidez-moi. Je peux vous donner tous les experts pour revoir le code. Le conseiller expert est simple mais efficace. Je peux encore l'améliorer, mais je l'ai simplifié au maximum, pour rendre plus clair l'essence du problème.

Je m'excuse également auprès de tous ceux qui ont été intempestifs dans leurs déclarations. Je suis embarrassé. Mais je veux TRES bien tout comprendre !

 
Vous pouvez le poster ici, et les personnes intéressées y jetteront un œil.
 
Rosh:

Il faut parcourir la liste des commandes de haut en bas, par exemple comme ceci :

Cela n'aide pas, apparemment la commande est supprimée avec succès et ensuite une autre demande est envoyée :

2011.05.12 16:42:57 Trades '726238' : annuler l'ordre #4388299 buy stop 0.02 EURUSD à 1.41700 effectué
2011.05.12 16:42:57 Trades '726238' : annuler l'ordre #4388299 buy stop 0.02 EURUSD à 1.41700
2011.05.12 16:42:58 Trades '726238' : échec de l'annulation de l'ordre #4388299 buy 0.00 at 0.00000 [Invalid request] - déjà un achat alors que l'arrêt d'achat était

 
//+------------------------------------------------------------------+
//|                                                     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);
}

similaire, mais sur 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);
}

Eh bien, regardez et comparez. J'ai fait une erreur quelque part... La différence est substantielle.

 
molotkovsm:

Cela n'aide pas, apparemment la commande est supprimée avec succès et ensuite une autre demande est envoyée :

2011.05.12 16:42:57 Trades '726238' : annuler l'ordre #4388299 buy stop 0.02 EURUSD à 1.41700 effectué
2011.05.12 16:42:57 Trades '726238' : annuler l'ordre #4388299 buy stop 0.02 EURUSD à 1.41700
2011.05.12 16:42:58 Trades '726238' : échec de l'annulation de l'ordre #4388299 buy 0.00 at 0.00000 [Invalid request] - déjà un achat alors que l'arrêt d'achat était

J'ai honte d'admettre que je n'ai toujours pas maîtrisé l'art de la télépathie.
 
J'ai presque oublié. Les EAs fonctionnent sur Eur/Usd H1. Testé du 1.01.2010 au 1.05.2011.
 
Rosh:
J'ai honte d'admettre que je n'ai toujours pas maîtrisé l'art de la télépathie.

Je vais répéter la question :

Comment supprimer correctement toutes les commandes avec un certain mag ?

J'ai deux fonctions pour cela, check_orders vérifie les commandes avec un certain mode et remove_sl les supprime :

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);
     }

Le problème est que ces lignes apparaissent dans le journal de l'EA :

2011.05.11 21:40:19 Trades '726238' : échec de l'annulation de l'ordre #4375237 acheter 0,00 à 0,00000 [Requête invalide].
C'est-à-dire que des demandes inutiles sont envoyées au serveur commercial pour supprimer l'ordre qui avait déjà été demandé.

Vous avez fait part de ce qui suit :

Vous devez parcourir la liste des commandes de haut en bas, par exemple comme ceci :

 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);
           }
        }

J'ai essayé de faire comme vous l'avez dit, mais le problème demeure - l'ordre en attente est d'abord supprimé, puis une autre demande est envoyée pour supprimer le même ordre. Voici un exemple des lignes du journal :

2011.05.12 16:42:57 Trades '726238' : annuler l'ordre #4388299 buy stop 0.02 EURUSD à 1.41700 effectué - suppression réussie de l'ordre
2011.05.12 16:42:57 Trades '726238' : annuler l'ordre #4388299 buy stop 0.02 EURUSD à 1.41700 - Une autre requête est en cours d'envoi
2011.05.12 16:42:58 Trades '726238' : échec de l'annulation de l'ordre #4388299 buy 0.00 at 0.00000 [Invalid request] - c'était un achat pour une raison quelconque.

Cela ne se produit pas à chaque fois, mais parfois, et cela n'affecte pas le fonctionnement du conseiller expert. Je veux juste faire tout correctement, ne pas charger le serveur commercial avec des requêtes vides, et résoudre le problème.

Je vous remercie de vos réponses et de votre volonté d'aider.


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