Beranda Perdagangan Sistem Postingan

Download Semua Riwayat Tick Simbol dengan EA untuk MetaTrader 5

Lampiran
56324.zip (3.28 KB, Unduh 0 kali)

Halo, trader! Kali ini kita akan membahas tentang cara mendownload semua riwayat tick dari simbol yang ada di MetaTrader 5 dengan menggunakan Expert Advisor (EA). Dengan EA ini, kamu bisa mengambil semua tick yang tersedia dari broker yang kamu gunakan, atau hingga tanggal tertentu yang kamu inginkan.

Ini sangat berguna untuk melakukan backtest atau membuat grafik kustom dari tick yang sudah diambil. Pastikan juga kamu memiliki ruang penyimpanan yang cukup di hard drive, karena terminal akan menyimpan tick di folder data.

Sebelum mulai mendownload simbol, kita perlu menyiapkan download manager terlebih dahulu. Struktur CDownloadManager akan berisi semua informasi yang kita butuhkan.

struct CDownloadManager
  {
    bool    m_started,m_finished;
    string    m_symbols[],m_current;
    int    m_index;
  }
  • Status download (mulai/selesai)
  • Daftar simbol yang akan dipindai
  • Simbol saat ini
  • Indeks simbol yang sedang dipindai

Kita juga perlu membaca dan menulis ke hard drive. Karena kita bekerja dengan simbol, kita akan membuat dua fungsi cepat untuk menulis dan membaca string dari file biner.

Fungsi untuk menyimpan string ke file:

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

Fungsi ini menerima:

  • Handle file f, dari file yang dibuka untuk menulis dengan bendera biner FILE_WRITE|FILE_BIN
  • String yang akan ditulis ke file

Fungsi ini menulis integer yang menunjukkan berapa banyak karakter yang ada dalam string dan kemudian menyimpan setiap karakter dalam string tersebut.

Fungsi untuk memuat string dari file:

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

Fungsi ini menerima:

  • Handle file f dari file yang dibuka untuk membaca sebagai biner, dengan bendera FILE_READ|FILE_BIN

Fungsi ini membaca integer yang menunjukkan berapa banyak karakter yang diharapkan pada titik tersebut dalam file. Kemudian, ia melanjutkan untuk membaca setiap karakter ke dalam array char dan kemudian membuat string dari array char tersebut yang dikembalikan sebagai hasil pemuatan.

Kembali ke struktur CDownloadManager. Kita perlu cara untuk menginisialisasi manager dan mengisinya dari market watch:

   //+------------------------------------------------------------------+
   //| Mengambil simbol dari market watch |
   //+------------------------------------------------------------------+
   void    grab_symbols()
     {
      //! hanya dari 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);
        }
     }

Cukup sederhana:

  • Meminta berapa banyak simbol yang ada di market watch (aktif)
  • Mengubah ukuran array m_symbols untuk menerima simbol-simbol tersebut
  • Melakukan loop untuk semua simbol dan meminta nama simbolnya

Kita juga bertanggung jawab untuk mengelola proses download data simbol, jadi kita memerlukan fungsi yang pada dasarnya adalah manajernya:

   //+------------------------------------------------------------------+
   //| Mengelola proses download simbol |
   //+------------------------------------------------------------------+
   void    manage(string folder,string filename)
     {
      // pada dasarnya ini memulai atau navigasi ke simbol berikutnya
      // jika sudah diatur
      if(ArraySize(m_symbols)>0)
        {
        // jika belum dimulai
           if(!m_started)
           {
            m_started=true;
            // pergi ke simbol pertama
            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;
         }
         // jika sudah dimulai
        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("Selesai");
                ExpertRemove();
                return;
              }
         }
      else
        {
         Print("Silakan ambil simbol terlebih dahulu");
        }
      // jika sudah diatur berakhir di sini
     }

Bagaimana sistem ini bekerja:

  • Chart terbuka, kita memerlukan 1 chart, dan timer diatur.
  • Timer tersebut dieksekusi, kita batalkan timer
  • Kita memeriksa apakah ini adalah download baru atau download yang berlanjut
  • Jika ini adalah download baru, kita siapkan dengan mengambil semua simbol
  • Jika ini adalah download yang berlanjut, kita download data untuk simbol saat ini

Ini adalah bagian dari kode yang melakukan download berdasarkan timer:

//+------------------------------------------------------------------+
//|Timer |
//+------------------------------------------------------------------+
void OnTimer()
  {
    //--- jika disinkronkan
    if(SymbolIsSynchronized(_Symbol)&&TerminalInfoInteger(TERMINAL_CONNECTED)==1)
       {
        EventKillTimer();
        //--- memuat sistem di sini
        if(MANAGER.load(MANAGER_FOLDER,MANAGER_STATUS_FILE))
          {
            //--- sistem dimuat jadi kita memindai simbol di sini
            Comment("Sistem dimuat dan kita sedang memproses "+MANAGER.m_current);
            //--- pemuatan tick
            //--- temukan tick tertua yang tersedia di broker terlebih dahulu
            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("Silakan tunggu");
            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 Tertua : "+TimeToString((datetime)(oldest/1000),TIME_DATE|TIME_MINUTES|TIME_SECONDS)+"\nCursor("+TimeToString((datetime)(cursorMSC/1000),TIME_DATE|TIME_MINUTES|TIME_SECONDS)+")\nAttempts("+IntegerToString(attempts)+")\nSilakan tunggu untuk respon...");
         }
        //--- pada titik ini kita memiliki tick tertua
        //--- mulai meminta tick dari yang tertua ke yang terbaru
        if(oldest!=LONG_MAX)
           {
            ArrayFree(receiver);
            datetime newest_tick=0;
            //--- terima waktu tick terakhir untuk simbol ini yang disimpan dalam symbol_time
            datetime most_recent_candle=(datetime)SymbolInfoInteger(_Symbol,SYMBOL_TIME);
            while(newest_tick<most_recent_candle)
              {
               //--- meminta batch baru mulai dari waktu tertua dengan batas tick yang ditentukan
               int pulled=CopyTicks(_Symbol,receiver,COPY_TICKS_ALL,oldest,tick_packets);
               if(pulled>0)
                 {
                  //--- jika kita menarik batch baru, perbarui waktu yang diunduh
                newest_tick=receiver[pulled-1].time;
                oldest=receiver[pulled-1].time_msc;
                ArrayFree(receiver);
                 }
                 //--- batas waktu untuk permintaan server, ubah jika perlu
               Sleep(44);
               Comment("Ditarik hingga "+TimeToString(newest_tick,TIME_DATE|TIME_MINUTES|TIME_SECONDS)+" sejauh ini");
              }
      }
        else
           {
            Alert("Silakan tutup terminal pergi ke folder ticks dan hapus folder kosong");
            ExpertRemove();
           }
        //--- perbarui manager dan lanjutkan
         MANAGER.manage(MANAGER_FOLDER,MANAGER_STATUS_FILE);
      }
    else
      {
        //--- ambil simbol dari market watch untuk mulai download
         Comment("Mengambil MW dan memulai");
         MANAGER.grab_symbols();
         MANAGER.manage(MANAGER_FOLDER,MANAGER_STATUS_FILE);
      }
  }

Postingan terkait

Komentar (0)