Toute question des nouveaux arrivants sur MQL4 et MQL5, aide et discussion sur les algorithmes et les codes. - page 531

 
Vitaly Muzichenko:

Comparez la mesure suivante, et si la séquence est rompue, remettez le drapeau à zéro et enregistrez le nombre de mesures correctes, puis continuez la boucle.

Il suffit de constater que la barre est haussière et que la suivante est baissière, la suivante, si elle est identique à la précédente, vous notez la valeur et réinitialisez le drapeau. Et ainsi de suite jusqu'à la fin.

Mais la première n'est pas forcément haussière.

   for(int i=limit-1; i>0; i--)

     {


      if(open[i]<close[i]&&open[i+1]>close[i+1]&&open[i+3]<close[i+3])

        {

         up++;

        }

      else up=0;

    
    
if(max_c<up)max_c=up;

Comment(max_c);
}

//--- return value of prev_calculated for next call

   return(rates_total);

  }

 
PolarSeaman:

mais le premier n'est peut-être pas un taureau, mais c'est impossible.

Voici une variante, mais pas tout à fait correcte, qui consiste à toujours compter à partir d'une bougie baissière.

Dossiers :
aCandle.mq4  8 kb
 
Vitaly Muzichenko:

Voici une variante, mais pas tout à fait correcte, qui consiste à toujours compter à partir d'une bougie baissière.

Merci. Si vous mettez ce nombre au carré et ajoutez un, le résultat est correct.

Est-il vérifié si(i%2==0) ?
 
PolarSeaman:

mais le premier n'est peut-être pas un taureau, c'est impossible.


Voici un exemple où l'on retrouve les mêmes bougies et où l'on change la direction de la chaîne :

//+------------------------------------------------------------------+
//|                                              CandlesSequence.mq5 |
//|                        Copyright 2018, MetaQuotes Software Corp. |
//|                             https://mql5.com/ru/users/artmedia70 |
//+------------------------------------------------------------------+
#property copyright "Copyright 2018, MetaQuotes Software Corp."
#property link      "https://mql5.com/ru/users/artmedia70"
#property version   "1.00"
#property indicator_separate_window
#property indicator_buffers 2
#property indicator_plots   1
//--- plot Sequence
#property indicator_label1  "Sequence"
#property indicator_type1   DRAW_COLOR_HISTOGRAM
#property indicator_color1  clrGreen,clrRed,clrGray
#property indicator_style1  STYLE_SOLID
#property indicator_width1  2
//--- enums
enum ENUM_CANDLE_TYPE
  {
   CANDLE_TYPE_BULL  =  0,       // Bullish candle
   CANDLE_TYPE_BEAR  =  1,       // Bearish candle
   CANDLE_TYPE_DOJI  = -1        // Doji candle
  };
//--- indicator buffers
double         BufferSeq[];
double         BufferSeqColors[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   SetIndexBuffer(0,BufferSeq,INDICATOR_DATA);
   SetIndexBuffer(1,BufferSeqColors,INDICATOR_COLOR_INDEX);
//--- setting indicator parameters
   IndicatorSetString(INDICATOR_SHORTNAME,"Candles sequence");
   IndicatorSetInteger(INDICATOR_DIGITS,Digits());
//--- setting buffer arrays as timeseries
   ArraySetAsSeries(BufferSeq,true);
   ArraySetAsSeries(BufferSeqColors,true);
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {
//--- Проверка на минимальное колиество баров для расчёта
   if(rates_total<2) return 0;
//--- Установка массивов буферов как таймсерий
   ArraySetAsSeries(open,true);
   ArraySetAsSeries(high,true);
   ArraySetAsSeries(low,true);
   ArraySetAsSeries(close,true);
   ENUM_CANDLE_TYPE type_refs=CANDLE_TYPE_DOJI;
   ENUM_CANDLE_TYPE type_curr=CANDLE_TYPE_DOJI;
//--- Проверка и расчёт количества просчитываемых баров   
   int limit=rates_total-prev_calculated;
   if(limit>1)
     {
      limit=rates_total-2;
      ArrayInitialize(BufferSeq,EMPTY_VALUE);
      BufferSeq[rates_total-1]=open[rates_total-1];
     }
//--- Расчёт индикатора
   for(int i=limit; i>=0 && !IsStopped(); i--)
     {
      type_refs=GetTypeCandle(i+1,open,close);
      type_curr=GetTypeCandle(i,open,close);
   //--- смена направления цепочки свечей
      if(!CheckCandle(type_refs,type_curr))
        {
         BufferSeq[i]=(type_curr==CANDLE_TYPE_BULL ? low[i]: type_curr==CANDLE_TYPE_BEAR ? high[i]: open[i]);
        }
   //--- свечи одного типа
      else
        {
         BufferSeq[i]=BufferSeq[i+1];
        }
      BufferSeqColors[i]=(type_curr==CANDLE_TYPE_BULL ? 0 : type_curr==CANDLE_TYPE_BEAR ? 1 : 2);
     }

//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+
//| Возвращает тип свечи                                             |
//+------------------------------------------------------------------+
ENUM_CANDLE_TYPE GetTypeCandle(const int shift,const double &open[],const double &close[])
  {
   return(close[shift]>open[shift] ? CANDLE_TYPE_BULL : close[shift]<open[shift] ? CANDLE_TYPE_BEAR : CANDLE_TYPE_DOJI);
  }
//+------------------------------------------------------------------+
//| Сравнивает два типа свечей                                       |
//+------------------------------------------------------------------+
bool CheckCandle(const ENUM_CANDLE_TYPE reference_candle_type,const ENUM_CANDLE_TYPE checked_candle_type)
  {
   return(reference_candle_type==checked_candle_type ? true : false);
  }
//+------------------------------------------------------------------+

Maintenant, lorsque la chaîne se poursuit, vous pouvez compter le nombre de bougies dans la chaîne et l'enregistrer dans une liste, et lorsque la chaîne change pour une nouvelle, commencer un nouveau compte.

Le nombre de bougies de chaque chaîne peut être enregistré dans une liste triée. Ensuite, en triant la liste, on peut trouver les séquences maximales et minimales.

 
PolarSeaman:

Merci. Si le nombre obtenu est élevé au carré et que l'on ajoute un, le résultat est correct.

C'est ce que nous vérifions si(i%2==0) ?

Si i est un multiple de deux.

C'est le reste de i divisé par 2.

 
Juer:

Ici la taille des variables locales est trop grande (plus de 512kb) lors de la compilation.

Où chercher et que faire ? Il y a un tableau de chaînes CArrayString dans la fonction, je pense qu'il s'agit d'une erreur.

Je le remplis en utilisant la méthode Add(), puis je fais Clear() et Shutdown() à nouveau. Puis je le remplis à nouveau avec de nouvelles données en utilisant la méthode Add(). Dans ce cas, le tableau sera-t-il à nouveau rempli de zéro élément ?

Nous devons supprimer ces membres des classes qui occupent déjà de la mémoire lors de la compilation. Ces données seront allouées dans la mémoire de la pile, qui est toujours très petite. La solution à ce problème est d'allouer dynamiquement la mémoire pour les membres de la classe qui occupent beaucoup de mémoire.

Par exemple, s'il existe un membre de la classe :

class A
{
   double m_arrfArray[9999999];
};

il doit être remplacé par :

class A
{
   double m_arrfMyArray[];
};

bool A::Init()
{
   if (ArrayResize(m_arrfMyArray, 9999999) != 9999999)
      return false;
   ....
}
 
Ihor Herasko:

Nous devons retirer des classes les membres qui occupent déjà de la mémoire au moment de la compilation. Ces données seront placées dans la mémoire de la pile, qui est toujours très petite. La solution à ce problème est d'allouer dynamiquement la mémoire pour les membres de la classe qui occupent beaucoup de mémoire.

Par exemple, s'il existe un membre de la classe :

alors il doit être remplacé par :

Merci. Je me suis débarrassé de ce problème en supprimant la classe des paramètres de chaque fonction. En général, il était possible d'initialiser cet objet une fois pour toutes les méthodes.

J'ai une autre question concernant la classe CArray, et plus précisément CArrayObj. Il existe une méthode Delete(), mais elle ne déplace pas un élément dans le tableau ? C'est-à-dire que si je supprime Delete(18), cela supprime un élément à cette position et plus tard si je veux interroger l'élément par cet index, j'obtiens un pointeur invalide. Existe-t-il une méthode permettant de supprimer et de déplacer des éléments de sorte que, dans ce cas, le 18e élément soit le 19e après la suppression ?

 
Juer:

Merci. Je me suis débarrassé de ce problème en supprimant la classe des paramètres de chacune des fonctions. En général, il était possible d'initialiser cet objet une fois pour toutes les méthodes.

J'ai une autre question concernant la classe CArray, et plus précisément CArrayObj. Il existe une méthode Delete(), mais elle ne déplace pas un élément dans le tableau ? C'est-à-dire que si je supprime Delete(18), cela supprime un élément à cette position et plus tard si je veux interroger l'élément par cet index, j'obtiens un pointeur invalide. Existe-t-il une méthode permettant de supprimer et de déplacer des éléments de sorte que le 18e élément soit le 19e après la suppression ?

Je n'ai pas travaillé avec la bibliothèque standard, mais d'après l'aide, la méthode Delete() doit supprimer physiquement l'élément, ce qui modifie la taille du tableau. Exception : si le mécanisme de gestion de la mémoire est désactivé. Par défaut, ce mécanisme est activé. La méthode FreeMode est utilisée pour vérifier l'état de l'indicateur de gestion de la mémoire.

Pour ma part, je recommanderais d'utiliser mes propres tableaux dans MQL (bien qu'en C++ j'utilise des vecteurs et des listes) et de gérer moi-même la mémoire, car je ne vois pas de commodité ou d'avantage particulier dans la classe CArray. Je supprime les éléments des tableaux de mes propres tableaux assez rapidement en utilisant cette méthode :

template<typename Array>
bool DeleteArrayElement(Array &array[], int nIndex)
{
   int nArraySize = ArraySize(array);
   if (nIndex < 0 || nIndex >= nArraySize)
      return true;
   
   array[nIndex] = array[nArraySize - 1];
   return (ArrayResize(array, nArraySize - 1, ARRAY_RESERVE_SIZE) == nArraySize - 1);
}

Son seul inconvénient est qu'il ne conserve pas la séquence des éléments du tableau. C'est-à-dire qu'elle peut être appliquée à tous les tableaux, à l'exception des tableaux ordonnés (triés).

 

Bonjour, pourriez-vous me dire où je peux trouver un script qui me permet de placer des ordres d'achat et de vente en attente dans MT4 en une seule fois pour un certain nombre de pips à partir du prix actuel, c'est-à-dire sans compter manuellement et peut-être même sans entrer dans la fenêtre d'ordre ? Je ne veux pas aller à la fenêtre de commande. Merci.

PS : peut-être que je demande quelque chose de mal, je n'ai jamais utilisé de scripts auparavant.

 

Veuillez m'expliquer le point -"Les ordres de marché ne peuvent pas être fermés si leurs valeurs StopLoss ou TakeProfit violent le paramètre FreezeLevel".

Cela signifie-t-il littéralement qu'un ordre au marché ne peut être clôturé si son TakeProfit ou son StopLoss n'atteint pas le FreezeLevel ? Je ne comprends pas bien comment un ordre de marché ouvert peut avoir des arrêts qui violent les règles StopLevel ou FreezeLevel ? Après tout, si des arrêts incorrects sont définis, le serveur émettra simplement une erreur et aucun arrêt ne sera défini.

En outre, veuillez nous indiquer ce qu'il faut savoir de plus lors de la clôture d'un ordre au marché, lorsqu'un courtier utilise FreezeLevel ?

Требования и ограничения при проведении торговых операций - Приложения - Учебник по MQL4
Требования и ограничения при проведении торговых операций - Приложения - Учебник по MQL4
  • book.mql4.com
В таблицах указаны расчётные значения, ограничивающие проведение торговых операций при открытии, закрытии, установке, удалении и модификации ордеров. Для получения значения минимальной дистанции StopLevel и дистанции заморозки FreezeLevel необходимо вызвать функцию MarketInfo(). Требования. Правильные цены, используемые при осуществлении...
Raison: