Tutte le domande dei nuovi arrivati su MQL4 e MQL5, aiuto e discussione su algoritmi e codici - pagina 531

 
Vitaly Muzichenko:

Confrontate la barra successiva e se la sequenza è interrotta, resettate la bandiera e registrate quanti erano corretti, e proseguite nel ciclo.

Basta scoprire che la barra è rialzista e la prossima è ribassista, la prossima, se è uguale alla precedente, si scrive il valore e si resetta la bandiera. E così via fino alla fine.

Ma il primo potrebbe non essere rialzista.

   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:

ma il primo potrebbe non essere un toro, ma non c'è modo.

Ecco una variante, anche se non del tutto corretta, sempre contando da una candela ribassista

File:
aCandle.mq4  8 kb
 
Vitaly Muzichenko:

Ecco una variante, anche se non del tutto corretta, sempre contando da una candela ribassista

Grazie. Se si eleva al quadrato questo numero e si aggiunge uno, il risultato è corretto.

Viene controllato if(i%2==0)?
 
PolarSeaman:

ma il primo potrebbe non essere un toro, assolutamente no.


Ecco un esempio di ritrovare le stesse candele e cambiare la direzione della catena:

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

Ora dove la catena continua, si può contare il numero di candele nella catena e salvare in una lista, e dove la catena cambia in una nuova, iniziare un nuovo conteggio.

Il numero di candele in ogni catena può essere memorizzato in una lista ordinata. Poi, ordinando la lista, si possono trovare le sequenze massime e minime.

 
PolarSeaman:

Grazie. Se il numero ottenuto è al quadrato e si aggiunge uno, il risultato è corretto.

È questo che stiamo controllando if(i%2==0)?

Se i è un multiplo di due.

È il resto di i diviso per 2

 
Juer:

Qui la dimensione delle variabili locali è troppo grande (più di 512kb) durante la compilazione.

Dove cercare e cosa fare? C'è un array di stringhe CArrayString nella funzione, sospetto che possa essere un errore.

Lo riempio usando il metodo Add(), poi faccio Clear() e Shutdown() di nuovo. E poi lo riempio di nuovo con nuovi dati usando il metodo Add(). In questo caso, l'array sarà di nuovo riempito con zero elementi?

Dobbiamo rimuovere tali membri dalle classi che già occupano memoria in fase di compilazione. Questi dati saranno allocati nella memoria dello stack, che è sempre molto piccola. La soluzione a questo problema è di allocare dinamicamente la memoria per i membri della classe che occupano molta memoria.

Per esempio, se c'è un membro della classe

class A
{
   double m_arrfArray[9999999];
};

dovrebbe essere sostituito con:

class A
{
   double m_arrfMyArray[];
};

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

Dobbiamo rimuovere dalle classi i membri che occupano già memoria in fase di compilazione. Questi dati saranno collocati nella memoria dello stack, che è sempre molto piccola. La soluzione a questo problema è di allocare dinamicamente la memoria per i membri della classe che occupano molta memoria.

Per esempio, se c'è un membro della classe

allora dovrebbe essere sostituito con:

Grazie. In qualche modo mi sono liberato di questo problema rimuovendo la classe dai parametri in ogni funzione. In generale, è stato possibile inizializzare questo oggetto una volta per tutti i metodi.

Ho un'altra domanda sulla classe CArray, più specificamente CArrayObj. Esiste un metodo Delete(), ma non sposta un elemento nell'array? Cioè, cancello Delete(18), rimuove un elemento in questa posizione e più tardi se voglio interrogare l'elemento per questo indice, ottengo un puntatore non valido. Esiste un metodo che elimini e sposti gli elementi in modo che in questo caso il 18° elemento sia il 19° dopo l'eliminazione?

 
Juer:

Grazie. In qualche modo mi sono liberato di questo problema rimuovendo la classe dai parametri in ciascuna delle funzioni. In generale, è stato possibile inizializzare questo oggetto una volta per tutti i metodi.

Ho un'altra domanda sulla classe CArray, più specificamente CArrayObj. C'è un metodo Delete(), ma non sposta un elemento nell'array? Cioè, cancello Delete(18), rimuove un elemento in questa posizione e più tardi se voglio interrogare l'elemento per questo indice, ottengo un puntatore non valido. Esiste un metodo che elimini e sposti gli elementi in modo che il 18° elemento sia il 19° dopo l'eliminazione?

Non ho lavorato con la libreria standard, ma secondo l'aiuto, il metodo Delete() dovrebbe rimuovere fisicamente l'elemento, cambiando la dimensione dell'array. Eccezione: se il meccanismo di gestione della memoria è disattivato. Per impostazione predefinita, questo meccanismo è abilitato. Il metodo FreeMode è usato per controllare lo stato del flag di gestione della memoria.

Da parte mia, consiglierei di usare i miei propri array in MQL (anche se in C++ uso vettori e liste) e la gestione della memoria da solo, perché non vedo nessuna particolare comodità o vantaggio nella classe CArray. Cancello gli elementi dei miei array piuttosto rapidamente usando questo metodo:

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

Il suo unico svantaggio è che non mantiene la sequenza degli elementi dell'array. Cioè, può essere applicato a tutti gli array, eccetto quelli ordinati (ordinati).

 

Salve, potreste dirmi dove posso trovare uno script che mi permetta di piazzare ordini pendenti di acquisto e vendita in MT4 in una sola volta per un certo numero di pip dal prezzo corrente, cioè senza contare manualmente e magari senza nemmeno entrare nella finestra degli ordini? Non voglio andare alla finestra dell'ordine, grazie.

PS: forse sto chiedendo qualcosa di sbagliato, non ho mai usato script prima.

 

Per favore spiegami il punto -"Gli ordini a mercato non possono essere chiusi se i loro valori di StopLoss o TakeProfit violano il parametro FreezeLevel".

Questo significa letteralmente che un ordine a mercato non può essere chiuso se il suo TakeProfit o StopLoss non incontra il FreezeLevel? Non capisco proprio come un ordine a mercato aperto possa avere degli stop che violano le regole StopLevel o FreezeLevel? Dopotutto, se vengono impostate le fermate sbagliate, il server darà semplicemente un errore e nessuna fermata verrà impostata.

Inoltre, per favore consigliate cos'altro dobbiamo sapere quando chiudiamo un ordine a mercato, quando un broker usa FreezeLevel?

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