Home Systeemhandel Bericht

Download Alle Tickdata van Symbolen in MetaTrader 5

Bijlage
56324.zip (3.28 KB, Downloaden 2 keer)

Met deze Expert Advisor code kun je de markten van je broker scannen en alle beschikbare ticks van symbolen downloaden, of ticks tot een bepaalde datum.

Dit kan handig zijn om de gehele historie van een symbool te downloaden voor je backtest of om een aangepast grafiek te maken op basis van die ticks.

Vergeet niet dat de terminals de ticks opslaan in de gegevensmap, dus zorg ervoor dat je voldoende schijfruimte hebt.

Om de symbolen te downloaden, hebben we eerst een downloadmanager nodig.

struct CDownloadManager
  {
   bool              m_started,m_finished;
   string            m_symbols[],m_current;
   int               m_index;
}

In deze structuur houden we het volgende bij:

  • De status van de download (gestart/voltooid)
  • De lijst van symbolen die gescand moeten worden
  • Het huidige symbool
  • De index van het gescande symbool

Daarnaast zullen we ook naar de harde schijf moeten lezen en schrijven. Aangezien we met symbolen werken, creëren we twee eenvoudige functies om strings naar binaire bestanden te schrijven en te lezen.

De functie om een string naar een bestand te schrijven:

void writeStringToFile(int f,string thestring)
  {
// sla symbol string op
   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);
     }
  }

Deze functie ontvangt:

  • Bestandshandle f, van een bestand dat geopend is voor schrijven met binaire vlaggen FILE_WRITE|FILE_BIN
  • De string die naar het bestand geschreven moet worden

Het schrijft een geheel getal dat aangeeft hoeveel karakters er in de string staan en slaat daarna elk karakter in de string op.

De functie om een string uit een bestand te lezen:

string readStringFromFile(int f)
  {
   string result="";
// laad symbol string
   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);
  }

Deze functie ontvangt:

  • Bestandshandle f van een bestand dat geopend is voor lezen met binaire vlaggen, FILE_READ|FILE_BIN

Het leest een geheel getal dat aangeeft hoeveel karakters er op dat moment in het bestand verwacht worden. Vervolgens leest het elk karakter in een char-array en maakt daar een string van, die als resultaat wordt teruggegeven.

Terug naar de CDownloadManager structuur. We moeten een manier hebben om de manager te initialiseren en deze te vullen vanuit de marktmonitor:

   //+------------------------------------------------------------------+
   //| pak symbolen van de marktmonitor                           |
   //+------------------------------------------------------------------+
   void              grab_symbols()
     {
      //! alleen van de mw !
      int s=SymbolsTotal(true);
      ArrayResize(m_symbols,s,0);
      for(int i=0;i<ArraySize(m_symbols);i++)
        {
         m_symbols[i]=SymbolName(i,true);
        }
     }

Dit is vrij rechttoe rechtaan:

  • Vraag hoeveel symbolen er in de marktmonitor (actief) zijn
  • Pas onze m_symbols array aan om ze te ontvangen
  • Loop door de totale symbolen en vraag de naam van het symbool aan

We zijn ook verantwoordelijk voor het beheren van het downloaden van de symboldgegevens, dus we hebben een functie nodig die in wezen de manager is:

   //+------------------------------------------------------------------+
   //| Beheer het downloadproces van symbolen                           |
   //+------------------------------------------------------------------+
   void              manage(string folder,string filename)
     {
      // dit start of navigeert naar het volgende symbool
      // als ingesteld
      if(ArraySize(m_symbols)>0)
        {
         // als niet gestart
         if(!m_started)
           {
            m_started=true;
            // ga naar het eerste symbool
            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;
         }
         // als gestart
         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("Voltooid");
               ExpertRemove();
               return;
              }
           }
        }
      else
        {
         Print("Pak eerst de symbolen");
        }
      // als ingesteld eindigt hier
     }

Hoe het systeem werkt:

  • De grafiek opent, we hebben 1 grafiek nodig en een timer wordt ingesteld.
  • Die timer voert de actie uit, we annuleren de timer
  • We controleren of dit een nieuwe download is of een voortzetting van een download
  • Als het een nieuwe download is, stellen we het in door alle symbolen te pakken
  • Als het een voortzetting van een download is, downloaden we gegevens voor het huidige symbool

Dit is het deel van de code dat de download op de timer uitvoert:

//+------------------------------------------------------------------+
//| Timer                                                             |
//+------------------------------------------------------------------+
void OnTimer()
  {
//--- als gesynchroniseerd
   if(SymbolIsSynchronized(_Symbol)&&TerminalInfoInteger(TERMINAL_CONNECTED)==1)
     {
      EventKillTimer();
      //--- laad het systeem hier
      if(MANAGER.load(MANAGER_FOLDER,MANAGER_STATUS_FILE))
        {
        //--- systeem geladen, dus we zijn een symbool aan het scannen
        Comment("Systeem geladen en we verwerken "+MANAGER.m_current);
        //--- tick laden

        //--- vind de oudste tick die beschikbaar is bij de 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("PleaseWait");
         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("Oudste Tick : "+TimeToString((datetime)(oldest/1000),TIME_DATE|TIME_MINUTES|TIME_SECONDS)+"
Cursor("+TimeToString((datetime)(cursorMSC/1000),TIME_DATE|TIME_MINUTES|TIME_SECONDS)+")
Pogingen("+IntegerToString(attempts)+")
Wacht alstublieft op antwoord...");
         }
         //--- op dit punt hebben we de oudste tick
         //--- begin met het aanvragen van ticks van de oudste naar de nieuwste
         if(oldest!=LONG_MAX)
           {
            ArrayFree(receiver);
            datetime newest_tick=0;
            //--- ontvang de tijd van de laatste tick voor dit symbool opgeslagen in symbol_time
            datetime most_recent_candle=(datetime)SymbolInfoInteger(_Symbol,SYMBOL_TIME);
            while(newest_tick<most_recent_candle)
              {
               //--- vraag een nieuwe batch aan, beginnend vanaf de oudste tijd met de gespecificeerde ticks-limiet
               int pulled=CopyTicks(_Symbol,receiver,COPY_TICKS_ALL,oldest,tick_packets);
               if(pulled>0)
                 {
                  //--- als we een nieuwe batch binnenhalen, werken we onze gedownloade tijden bij
                  newest_tick=receiver[pulled-1].time;
                  oldest=receiver[pulled-1].time_msc;
                  ArrayFree(receiver);
                 }
              //--- time-out server aanvragen, wijzig het als je dat wilt
               Sleep(44);
               Comment("Tot nu toe tot "+TimeToString(newest_tick,TIME_DATE|TIME_MINUTES|TIME_SECONDS)+" gehaald");
           }
         }
         else
         {
            Alert("Sluit de terminal alstublieft 
 ga naar de ticks-map 
 en verwijder de lege mappen");
            ExpertRemove();
         }
         //--- werk de manager bij en ga verder
         MANAGER.manage(MANAGER_FOLDER,MANAGER_STATUS_FILE);
        }
      else
        {
         //--- pak de symbolen van de marktmonitor om de download te starten
         Comment("Symbolen pakken en starten");
         MANAGER.grab_symbols();
         MANAGER.manage(MANAGER_FOLDER,MANAGER_STATUS_FILE);
        }
     }
  }

Gerelateerde berichten

Reactie (0)