Dalam artikel kali ini, kita akan membincangkan tentang cara untuk memuat turun semua tick sejarah bagi simbol tertentu menggunakan sistem trading di MetaTrader 5. Kode penasihat pakar ini akan meneliti senarai pasaran broker anda dan mengekstrak simbol-simbol untuk dimuat turun.
Proses ini dapat membantu anda mendapatkan sejarah simbol yang lengkap untuk ujian kembali (backtest) atau untuk mencipta carta khusus berdasarkan tick tersebut.
Pastikan anda mempunyai ruang cakera keras yang mencukupi kerana terminal akan menyimpan tick dalam folder data.
Untuk memudahkan proses muat turun simbol, kita perlu menggunakan pengurus muat turun terlebih dahulu. Struktur CDownloadManager mengandungi semua maklumat yang diperlukan untuk menyimpan keadaan muat turun.
struct CDownloadManager { bool m_started, m_finished; string m_symbols[], m_current; int m_index; }
- Keadaan muat turun (dimulakan/selesai)
- Senarai simbol yang akan dikaji
- Simbol semasa
- Indeks simbol yang sedang dikaji
Kita juga perlu membaca dan menulis ke cakera keras, jadi kita akan membuat 2 fungsi untuk menulis dan membaca rentetan dari fail binari.
Fungsi untuk menyimpan rentetan ke dalam fail:
void writeStringToFile(int f, string thestring) { // Simpan rentetan simbol char sysave[]; int charstotal=StringToCharArray(thestring, sysave, 0, StringLen(thestring), CP_ACP); FileWriteInteger(f, charstotal, INT_VALUE); for(int i=0; iFileWriteInteger(f, sysave[i], CHAR_VALUE); } }
Fungsi ini menerima:
- pemegang fail f yang dibuka untuk menulis dan bendera binari FILE_WRITE|FILE_BIN
- rentetan yang ingin ditulis ke dalam fail
Fungsi untuk memuatkan rentetan dari fail:
string readStringFromFile(int f) { string result=""; // Memuatkan rentetan simbol char syload[]; int charstotal=(int)FileReadInteger(f, INT_VALUE); if(charstotal>&0) { ArrayResize(syload, charstotal, 0); for(int i=0; ichar)FileReadInteger(f, CHAR_VALUE); } result=CharArrayToString(syload, 0, charstotal, CP_ACP); } return(result); }
Fungsi ini menerima:
- pemegang fail f yang dibuka untuk dibaca sebagai binari, bendera FILE_READ|FILE_BIN
Fungsi ini membaca panjang integer berapa banyak watak yang diharapkan pada titik tertentu dalam fail. Ia kemudian membaca setiap watak ke dalam array char dan mencipta rentetan dari array char tersebut yang akan dikembalikan sebagai hasil.
Kembali kepada struktur CDownloadManager. Kita perlu cara untuk menginisialisasi pengurus ini dan mengisinya berdasarkan senarai pasaran:
//+------------------------------------------------------------------+ //| Ambil simbol dari senarai pasaran | //+------------------------------------------------------------------+ 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); } }
Ia cukup mudah:
- Meminta berapa banyak simbol dalam senarai pasaran (aktif)
- Mengubah saiz array m_symbols untuk memuatkannya
- Berputar dalam jumlah simbol dan meminta nama simbol tersebut
Kita juga bertanggungjawab untuk menguruskan muat turun data simbol, jadi kita memerlukan fungsi yang pada dasarnya adalah pengurus:
//+------------------------------------------------------------------+ //| Mengurus proses muat turun simbol | //+------------------------------------------------------------------+ void manage(string folder, string filename) { // Pada dasarnya ini memulakan atau menavigasi ke simbol seterusnya // Jika ditetapkan if(ArraySize(m_symbols)>&0) { // jika belum dimulakan 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 dimulakan 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("Sila ambil simbol terlebih dahulu"); } // jika set berakhir di sini }
Bagaimana sistem ini berfungsi:
- Carta dibuka, kita memerlukan 1 carta, dan pemasa ditetapkan.
- Pemasa tersebut dieksekusi, kita membatalkan pemasa tersebut.
- Kita memeriksa sama ada ini muat turun baru atau muat turun yang berterusan.
- Jika ia muat turun baru, kita mengaturnya dengan mengambil semua simbol.
- Jika ia muat turun yang berterusan, kita memuat turun data untuk simbol semasa.
Ini adalah bahagian kode yang menjalankan muat turun pada pemasa:
//+------------------------------------------------------------------+ //| Pemasa | //+------------------------------------------------------------------+ void OnTimer() { //--- jika diselaraskan if(SymbolIsSynchronized(_Symbol)&&TerminalInfoInteger(TERMINAL_CONNECTED)==1) { EventKillTimer(); //--- muatkan sistem di sini if(MANAGER.load(MANAGER_FOLDER, MANAGER_STATUS_FILE)) { //--- sistem dimuatkan jadi kita sedang memproses simbol Comment("Sistem dimuatkan dan kami sedang memproses "+MANAGER.m_current); //--- muat tick //--- cari tick paling lama yang tersedia di broker 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("Sila 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_msc0].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)+" Cursor("+TimeToString((datetime)(cursorMSC/1000),TIME_DATE|TIME_MINUTES|TIME_SECONDS)+") Attempts("+IntegerToString(attempts)+") Sila tunggu untuk respons..."); } //--- Pada ketika ini, kita telah mendapatkan tick tertua //--- mula 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 disimpan di symbol_time datetime most_recent_candle=(datetime)SymbolInfoInteger(_Symbol,SYMBOL_TIME); while(newest_tick //--- minta satu batch baru bermula dari waktu tertua dengan had tick yang ditentukan int pulled=CopyTicks(_Symbol, receiver,COPY_TICKS_ALL, oldest, tick_packets); if(pulled>&0) { //--- jika kita mengambil batch baru, kemas kini waktu yang dimuat turun newest_tick=receiver[pulled-1].time; oldest=receiver[pulled-1].time_msc; ArrayFree(receiver); } //--- timeout untuk permintaan server, ubah jika anda mahu Sleep(44); Comment("Ditarik sehingga "+TimeToString(newest_tick,TIME_DATE|TIME_MINUTES|TIME_SECONDS)+" sehingga kini"); } } else { Alert("Sila tutup terminal pergi ke folder tick dan hapus folder kosong"); ExpertRemove(); } //--- kemas kini pengurus dan teruskan MANAGER.manage(MANAGER_FOLDER, MANAGER_STATUS_FILE); } else { //--- ambil simbol senarai pasaran untuk memulakan muat turun Comment("Mengambil MW dan memulakan"); MANAGER.grab_symbols(); MANAGER.manage(MANAGER_FOLDER, MANAGER_STATUS_FILE); } }
Siaran berkaitan
- MQL5 Wizard: Cipta Sistem Trading Berdasarkan Pola Morning/Evening Star dan RSI
- Panduan Lengkap MQL5 Wizard untuk Isyarat Dagangan Berdasarkan Morning/Evening Stars dan Stochastic
- Moving Average: EA Terbaik untuk MetaTrader 5
- MQL5 Wizard: Cipta Isyarat Dagangan Menggunakan Corak Morning/Evening Star dan MFI
- MQL5 Wizard: Cipta EA Berdasarkan Pola Bullish dan Bearish Engulfing dengan Stochastic