Domande dai principianti MQL5 MT5 MetaTrader 5 - pagina 1332

 
Mikhail Tkachev:

Scavando attraverso la documentazione e il forum ...
Come rendere globali le variabili di tipo puntatore [nell'esempio var], se sono create in OnInit() da stringa:

e il numero di oggetti e i parametri del costruttore sono sconosciuti in anticipo e sono calcolati in OnInit() ?

Questo è facile.

CObj* var1 = NULL;
CObj* var2 = NULL;
CObj* var3 = NULL;

int OnInit()
{
   var1 = new CObj( p1, p2, p3 );
   var2 = new CObj( p1, p2, p3 );
   var3 = new CObj( p1, p2, p3 );
}
 

Ciao

mt5 ha un pulsante per il mirino

Quando lo premi sul grafico, mostra quante barre, quanti pip e la percentuale

Aiutatemi a calcolare correttamente questo valore in modo da poterlo legare al mio robot

Grazie

 
Artyom Trishkin:

La nuova classe di bar è già in funzione?

E come sono esattamente i parametri di input?

La classe è presa in prestito da:https://www.mql5.com/ru/code/768, con piccole modifiche

//+------------------------------------------------------------------+
//|                                                     IsNewBar.mqh |
//|                               Copyright © 2011, Nikolay Kositsin |
//|                              Khabarovsk,   farria@mail.redcom.ru | 
//+------------------------------------------------------------------+ 
#property copyright "2011,   Nikolay Kositsin"
#property link      "farria@mail.redcom.ru"
#property version   "1.00"
//+------------------------------------------------------------------+
//|  Алгоритм определения момента появления нового бара              |
//| Для каждого таймфрейма каждого символа нужно создавать объект    |
//+------------------------------------------------------------------+  
#include <Object.mqh>

class CIsNewBar : public CObject // Сделан наследником класса для возможности работы с классом CArrayObj (из библиотеки)
// class CIsNewBar   // Первоначальная редакция
  {
   //----
public:

      //---- функция определения момента появления нового бара
   bool IsNewBar()
     {
      //---- получим время появления текущего бара
      datetime TNew=datetime(SeriesInfoInteger(m_Symbol,m_TimeFrame,SERIES_LASTBAR_DATE));

      if(TNew!=m_TOld && TNew) // проверка на появление нового бара
        {
         m_TOld=TNew;
         return(true); // появился новый бар!
        }
      //----
      return(false); // новых баров пока нет!
     };

   //---- конструктор класса    
                     CIsNewBar(const string &pSymbol, const ENUM_TIMEFRAMES pTimeFrame){
                        m_Symbol=pSymbol; m_TimeFrame=pTimeFrame;
                        m_TOld=-1;};

protected:
   datetime          m_TOld;        // Время хранится 
   ENUM_TIMEFRAMES   m_TimeFrame;   //    для каждого таймфрейма
   string            m_Symbol;      //    каждого символа

   //---- 
  };
//+------------------------------------------------------------------+

È destinato ad essere applicato come segue:

int OnInit()
{
    // Переменная NB_M1 - объект для контроля нового бара по символу currSymbol для таймфрейма M1

    CIsNewBar* NB_M1=new CIsNewBar(currSymbol,PERIOD_M1);
}

void OnTick()
{
    if (NB_M1.IsNewBar())  // (1) Если появился новый бар M1
        {....}
    ......
}
 
Koldun Zloy:

Facile.

Grazie per la risposta)
L'ho fatto all'inizio.
Così l'oggetto viene creato due volte, prima vuoto, poi come dovrebbe essere da un costruttore con parametri.
Ma... In questo caso il compilatore stampa un avvertimento sulla linea in OnInit():

dichiarazione di 'var1' nasconde la variabile globale -> sulla linea in OnInit()
vedere la dichiarazione precedente di 'var1'.

Quindi una variabile locale nasconde una variabile globale ... Quindi cosa succede?
Quale variabile vede l'altra funzione, OnTick(), per esempio? La variabile globale è =NULL, quella locale è inizializzata correttamente ma non può essere vista da un'altra funzione ...

 
Mikhail Tkachev:

La classe è presa in prestito da:https://www.mql5.com/ru/code/768, con piccole modifiche

Dovrebbe essere applicato come segue:

Estrae tutte le sottostringhe dai parametri di input e le usa per creare i nomi dei simboli e dei tempi corrispondenti.

Poi create nuovi oggetti barra da queste liste e mettete il puntatore ad ogni oggetto da creare - "New Bar" - in CArrayObj che è dichiarato globalmente.

Poi, riceve un puntatore al prossimo oggetto della lista nel ciclo OnTimer() e controlla la presenza di una nuova barra. Se non c'è un nuovo oggetto, devi andare al prossimo, se c'è, devi fare quello che devi fare quando si apre una nuova barra.

Il timer dovrebbe essere impostato secondo le vostre esigenze - millisecondo, secondo, minuto - in generale, con qualsiasi frequenza che considerate sufficiente per rispondere a una nuova barra su un simbolo non corrente.

 
Mikhail Tkachev:

Grazie per la risposta)
All'inizio ho fatto così.
Così l'oggetto viene creato due volte, prima vuoto, poi come dovrebbe essere da un costruttore con parametri.
Ma... In questo caso il compilatore stampa un avvertimento sulla linea in OnInit():

dichiarazione di 'var1' nasconde la variabile globale -> sulla linea in OnInit()
vedere la dichiarazione precedente di 'var1'.

Quindi una variabile locale nasconde una variabile globale ... Quindi cosa succede?
Quale variabile sarà poi vista da un'altra funzione, OnTick(), per esempio? La variabile globale è =NULL e quella locale è inizializzata correttamente, ma non può essere vista da un'altra funzione.

Guardate attentamente. Non è quello che hai fatto.

 
Artyom Trishkin:

Dai parametri di input devono essere estratte tutte le sottostringhe, dalle quali devono essere compilati i nomi dei simboli e i loro tempi corrispondenti.

Poi create nuovi oggetti barra da queste liste e mettete un puntatore ad ogni nuovo oggetto in CArrayObj che è dichiarato a livello globale.

Poi, riceve un puntatore al prossimo oggetto della lista nel ciclo OnTimer() e controlla la presenza di una nuova barra. Se non c'è un nuovo oggetto, devi andare al prossimo, se c'è, devi fare quello che devi fare quando si apre una nuova barra.

Fate un timer secondo le vostre esigenze - millisecondo, secondo, minuto - in generale, con qualsiasi frequenza che pensate sia sufficiente per rispondere a una nuova barra su un simbolo non corrente.

Questo è quello che stavo facendo, ma ArrObj.At(0) non chiama le funzioni membro dellaclasse...

 
Koldun Zloy:

Date un'occhiata più da vicino. Non è quello che stavi facendo.

Già notato)
Quindi la soluzione è dichiarare oggetti globalmente vuoti....
E se non si sa in anticipo quanti ce ne saranno? Basta dichiarare "con riserva"? :)
P.S. Non ho trovato questo modo di dichiarare oggetti nell'aiuto integrato

CObj* var1 = NULL;
 
Mikhail Tkachev:

Già notato)
Quindi la soluzione è dichiarare oggetti globalmente vuoti....
E se non si sa in anticipo quanti ce ne saranno? Basta dichiararli "con riserva"? :)

Mettere inCArrayObj.

La funzioneArrObj.At(0) restituisce un puntatore a una classe base che non sa nulla dei membri della classe derivata.

Per fare riferimento a loro, basta fare una conversione di tipo.

CIsNewBar* newBar = (CIsNewBar*)ArrayObj.At(0);
newBar.method( parameter );
 
Koldun Zloy:

Mettere inCArrayObj.

La funzioneArrObj.At(0) restituisce il puntatore alla classe base, che non sa nulla dei membri delle classi derivate.

Basta fare una conversione di tipo per riferirsi a loro.

Grazie per la risposta, non sei affatto cattivo)
Ora tutto è chiaro)
UPD
Anche questa è la costruzione che funziona

CIsNewBar* newBar = ArrayObj.At(0);
newBar.method( parameter )
Motivazione: