Home Trading Sistematico Post

Scarica la Storia Completa dei Tick di un Simbolo con MetaTrader 5

Allegato
56324.zip (3.28 KB, Scarica 0 volte)

Ciao a tutti, oggi voglio parlarvi di un Expert Advisor che può aiutarvi a scaricare tutti i tick disponibili per un simbolo specifico sul vostro conto di trading. Questo è particolarmente utile per chi desidera effettuare backtest dettagliati o creare grafici personalizzati a partire dai tick.

Il codice di questo EA esplorerà la vostra lista di strumenti e scaricherà tutti i tick disponibili, fino a una data specifica. Ricordatevi che i terminali salveranno i tick nella cartella dei dati, quindi assicuratevi di avere spazio sufficiente sul disco rigido.

Per facilitare il download dei simboli, abbiamo bisogno di un download manager. La struttura CDownloadManager conterrà tutte le informazioni necessarie per gestire il processo.

struct CDownloadManager
  {
   bool m_started, m_finished;
   string m_symbols[], m_current;
   int m_index;
}
  • Lo stato del download (iniziato/finalizzato)
  • La lista dei simboli da esaminare
  • Il simbolo corrente
  • L'indice del simbolo in esame

In aggiunta, avremo bisogno di funzioni per leggere e scrivere sul disco rigido. Dato che lavoriamo con i simboli, creiamo due funzioni per gestire la scrittura e la lettura delle stringhe dai file binari.

Funzione per salvare la stringa su file:

void writeStringToFile(int f,string thestring)
  {
   // salva la stringa del simbolo
   char sysave[];
   int charstotal=StringToCharArray(thestring,sysave,0,StringLen(thestring),CP_ACP);
   FileWriteInteger(f,charstotal,INT_VALUE);
   for(int i=0;i<charstotal;i++)
     {
      FileWriteInteger(f,sysave[i],CHAR_VALUE);
     }
}

Questa funzione riceve:

  • Il manico del file f, di un file aperto per la scrittura con flag binario FILE_WRITE|FILE_BIN
  • La stringa da scrivere nel file

Scrive un intero che rappresenta la lunghezza della stringa e poi memorizza ciascun carattere della stringa.

Funzione per caricare la stringa dal file:

string readStringFromFile(int f)
  {
   string result="";
   // carica la stringa del simbolo
   char syload[];
   int charstotal=(int)FileReadInteger(f,INT_VALUE);
   if(charstotal>0)
     {
      ArrayResize(syload,charstotal,0);
      for(int i=0;i<charstotal;i++)
        {
         syload[i]=(char)FileReadInteger(f,CHAR_VALUE);
        }
      result=CharArrayToString(syload,0,charstotal,CP_ACP);
     }
   return(result);
}

Questa funzione riceve:

  • Il manico del file f di un file aperto per la lettura con flag binario, FILE_READ|FILE_BIN

Legge un intero che rappresenta quanti caratteri ci si aspetta in quel punto del file. Procede quindi a leggere ciascun carattere in un array di char e poi crea una stringa da quell'array che viene restituita come risultato della lettura.

Torniamo alla struttura CDownloadManager. Abbiamo bisogno di un modo per inizializzare il manager e riempirlo con i simboli dalla lista di strumenti:

//+------------------------------------------------------------------+
//| Estrai i simboli dalla lista di strumenti |
//+------------------------------------------------------------------+
void grab_symbols()
   {
    //! solo dalla lista di strumenti !
    int s=SymbolsTotal(true);
    ArrayResize(m_symbols,s,0);
    for(int i=0;i<ArraySize(m_symbols);i++)
      {
         m_symbols[i]=SymbolName(i,true);
      }
  }

Abbastanza semplice:

  • Chiediamo quanti simboli ci sono nella lista di strumenti (attivi)
  • Ridimensioniamo il nostro array m_symbols per riceverli
  • Iteriamo attraverso i simboli totali e richiediamo il nome di ciascun simbolo

Ora siamo responsabili anche della gestione del download dei dati dei simboli, quindi avremo bisogno di una funzione che essenzialmente gestisca il processo:

//+------------------------------------------------------------------+
//| Gestisci il processo di download dei simboli |
//+------------------------------------------------------------------+
void manage(string folder,string filename)
   {
    // essenzialmente inizia o naviga al simbolo successivo
    // se impostato
    if(ArraySize(m_symbols)>0)
    {
      // se non iniziato
      if(!m_started)
         {
        m_started=true;
        // vai al primo simbolo
        m_current=m_symbols[0];
        m_index=1;
        save(folder,filename);
        if(_Symbol!=m_current)
          {
            ChartSetSymbolPeriod(ChartID(),m_current,_Period);
          }
        else
          {
            ENUM_TIMEFRAMES new_period=PERIOD_M1;
            for(int p=0;p<ArraySize(TFS);p++)
             {
                if(_Period!=TFS[p])
                {
                     new_period=TFS[p];
                    break;
                }
                }
            ChartSetSymbolPeriod(ChartID(),m_current,new_period);
            }
        return;
     }
      // se iniziato
     else
     {
        m_index++;
        if(m_index<=ArraySize(m_symbols))
          {
            m_current=m_symbols[m_index-1];
            save(folder,filename);
            if(_Symbol!=m_current)
             {
                ChartSetSymbolPeriod(ChartID(),m_current,_Period);
             }
            return;
      }
      else
      {
         m_finished=true;
         FileDelete(folder+"\"+filename);
         Print("Finito");
         ExpertRemove();
         return;
      }
    }
    else
    {
        Print("Per favore, estrai prima i simboli");
    }
    }

Come funziona il sistema:

  • Il grafico si apre, abbiamo bisogno di un grafico, e viene impostato un timer.
  • Quel timer viene eseguito, annulliamo il timer
  • Controlliamo se si tratta di un nuovo download o di un download continuato
  • Se è un nuovo download, lo impostiamo estraendo tutti i simboli
  • Se è un download continuato, scarichiamo i dati per il simbolo corrente

Questa è la parte del codice che gestisce il download temporizzato:

//+------------------------------------------------------------------+
//| Timer |
//+------------------------------------------------------------------+
void OnTimer()
  {
   //--- se sincronizzato
   if(SymbolIsSynchronized(_Symbol)&&TerminalInfoInteger(TERMINAL_CONNECTED)==1)
     {
      EventKillTimer();
      //--- carica il sistema qui
      if(MANAGER.load(MANAGER_FOLDER,MANAGER_STATUS_FILE))
        {
        //--- sistema caricato, stiamo processando un simbolo
        Comment("Sistema caricato e stiamo processando "+MANAGER.m_current);
        //--- caricamento dei tick
        //--- trova il tick più vecchio disponibile presso il broker
        int attempts=0;
        int ping=-1;
        datetime cursor=flatten(TimeTradeServer());
        long cursorMSC=((long)cursor)*1000;
        long jump=2592000000;//60*60*24*30*1000;
        MqlTick receiver[];
        long oldest=LONG_MAX;
        Comment("Attendere prego");
        while(attempts<5)
         {
            ping=CopyTicks(_Symbol,receiver,COPY_TICKS_ALL,cursorMSC,1);
            if(ping==1)
              {
                 if(receiver[0].time_msc==oldest)
                 {
                   attempts++;
                 }
               else
                 {
                   attempts=0;
                 }
               if(receiver[0].time_msc<oldest)
                 {
                  oldest=receiver[0].time_msc;
                 }
               cursorMSC-=jump;
               if(limitDate&&receiver[0].time<=oldestLimit)
                 {
                  break;
                 }
              }
            else
              {
               attempts++;
              }
            Sleep(44);
            Comment("Tick più vecchio: "+TimeToString((datetime)(oldest/1000),TIME_DATE|TIME_MINUTES|TIME_SECONDS)+"\nCursore("+TimeToString((datetime)(cursorMSC/1000),TIME_DATE|TIME_MINUTES|TIME_SECONDS)+")\nTentativi("+IntegerToString(attempts)+")\nAttendere la risposta...");
         }
        //--- a questo punto abbiamo il tick più vecchio
        //--- inizia a richiedere i tick dal più vecchio al più nuovo
        if(oldest!=LONG_MAX)
         {
            ArrayFree(receiver);
            datetime newest_tick=0;
            //--- ricevi il tempo dell'ultimo tick per questo simbolo memorizzato in symbol_time
            datetime most_recent_candle=(datetime)SymbolInfoInteger(_Symbol,SYMBOL_TIME);
            while(newest_tick<most_recent_candle)
              {
              //--- richiedi un nuovo lotto partendo dal tempo più vecchio con il limite di tick specificato
               int pulled=CopyTicks(_Symbol,receiver,COPY_TICKS_ALL,oldest,tick_packets);
               if(pulled>0)
                 {
                  //--- se estraiamo un nuovo lotto aggiorniamo i tempi scaricati
                  newest_tick=receiver[pulled-1].time;
                  oldest=receiver[pulled-1].time_msc;
                  ArrayFree(receiver);
                 }
               //--- timeout delle richieste al server, alteralo se vuoi
               Sleep(44);
               Comment("Estratti fino a "+TimeToString(newest_tick,TIME_DATE|TIME_MINUTES|TIME_SECONDS)+" fino ad ora");
          }
      }
      else
       {
        Alert("Chiudi il terminale 
 vai alla cartella dei tick 
 e cancella le cartelle vuote");
        ExpertRemove();
      }
      //--- aggiorna il manager e passa oltre
     MANAGER.manage(MANAGER_FOLDER,MANAGER_STATUS_FILE);
    }
    else
    {
      //--- estrai i simboli dalla lista di strumenti per iniziare il download
      Comment("Estraendo MW e avviando");
       MANAGER.grab_symbols();
       MANAGER.manage(MANAGER_FOLDER,MANAGER_STATUS_FILE);
    }
  }

Post correlati

Commento (0)