Download all quotes of the symbol history - MetaTrader 5 Expert | MT5 EA Download - MetaTrader 5 Resource
This Expert Advisor code will scan the user's broker's market watch and extract the symbol and download all available quotes or quotes as of date for it.
It helps you download all symbol history for backtesting or create custom charts from these price movements.
Terminal caches ticks in the data folder, so make sure you have enough hard drive space.
To facilitate downloading symbols, we first need a download manager.
The CDownloadManager structure contains all the information we need to retain.
Structure CD Download Manager { boolean m_start, m_finish; String m_symbols[],m_current; int m_index;
We also need to read and write to the hard drive, and since we are working with symbols, we created 2 quick functions to write and read strings from binary files.
Save string to file function:
whitespace writes string to file( integer f, string string) { //Save symbol string character system save[]; The total number of integer characters = string to character array (string, saved by the system, 0 , string length (string), CP_ACP ); FileWriteInteger (f, total number of characters, INT_VALUE ); for ( integer i = 0 ;i<total number of characters;i++) { File write integer (f, system save[i], CHAR_VALUE ); } }
It receives:
It writes the integer length of how many characters are in the string and then stores each character in the string.
Load string function from file:
String reads string( integer f) from file { String result = "" ; //Load symbol string character syload[]; Integer total number of characters = ( integer ) file read integer (f, INT_VALUE ); if (total number of characters > 0 ) { arrayresize (syload,chartotal, 0 ); for ( integer i = 0 ;i<total number of characters;i++) { syload[i]=( character ) file reading integer (f, CHAR_VALUE ); } Result = character array to string (system load, 0 , total number of characters, CP_ACP ); } return (result); }
It reads the integer length of the number of characters expected at that point in the file. It proceeds to read each character into a char array and then creates a string from the char array, which is returned as the result of the string load.
Return to the CDownloadManager structure. We need a way to initialize the manager and populate it from market observations:
//+------------------------------------------------------------------+ //|Get symbols from Market Watch | //+------------------------------------------------------------------+ Blank grab-symbol() { //! Only from MW! integer s = total number of symbols ( true ); arrayResize (m_symbol, s, 0 ); for ( integer i = 0 ; i < array_size (m_symbol); i++) { m_symbol[i] = symbol_name (i, true ); } }
Very simple:
We are also responsible for managing the download of symbolic data, so we need a function that is essentially a manager:
//+------------------------------------------------------------------+ //|Manage symbol download process | //+------------------------------------------------------------------+ Blank management ( string folder, string file name) { //Essentially this will start or navigate to the next symbol //if set if ( array_size (m_symbol) > 0 ) { //if not started if (!m_start) { m_start= true ; //Go to the first symbol m_current=m_symbol[ 0 ]; m_index = 1 ; save(folder, filename); if ( _symbol !=m_current) { ChartSetSymbolPeriod ( chartID (),m_current, _period ); } other { ENUM_TIMEFRAMES new periods = PERIOD_M1 ; for ( integer p= 0 ;p< array size (TFS);p++) { if ( _period !=TFS[p]) { new_period=TFS[p]; rest ; } } ChartSetSymbolPeriod ( ChartID (),m_current,new_period); } return ; } //If other { m_index++; if (m_index<= array size (m_symbol)) { m_current=m_symbol[m_index- 1 ]; save(folder, filename); if ( _symbol !=m_current) { ChartSetSymbolPeriod ( chartID (),m_current, _period ); } return ; } other { m_done= true ; File delete (folder + "\\" + file name); print ( "completed" ); ExpertDelete (); return ; } } } other { print ( "Please grab the symbol first" ); } //If the setting ends here }
How the system works:
This is the part of the code that does the download on a timer:
//+------------------------------------------------------------------+ //|Timer | //+------------------------------------------------------------------+ blank timer () { //--- if synchronized if ( symbol synchronized ( _symbol )&& terminal information integer ( TERMINAL_CONNECTED terminal connected ) == 1 ) { EventExpirationTimer (); //--- Load the system here if (MANAGER.load(MANAGER_FOLDER,MANAGER_STATUS_FILE)) { //--- The system is loaded, so we are scanning here for symbols comments ( "The system is loaded, we are working on it" +MANAGER.m_current); //--- tick load //--- first find the oldest available quote in the broker integer try = 0 ; Integer square= -1 ; datetimecursor = flatten( timeTradingServer ()); Long cursor MSC = (( long ) cursor) * 1000 ; Long jump = 2592000000 ; //60*60*24*30*1000; MQTickReceiver []; Long oldest = long_largest ; comment ( "Please wait" ); Although (try < 5 ) { flat = copy_token ( _token , receiver, COPY_TICKS_ALL , cursor MSC, 1 ); if (flat == 1 ) { if (receiver[ 0 ].time_msc==oldest) { try++; } other { try = 0 ; } if (receivers[ 0 ].time_msc<oldest) { oldest = receiver[ 0 ].time_msc; } Cursor MSC-=jump; if (limitdate&&receiver[ 0 ].time<=oldestLimit) { rest ; } } other { try++; } sleep ( 44 ); comment ( "Oldest tick:" + String time (( datetime )(oldest/ 1000 ), TIME_DATE | TIME_MINUTES | TIME_SECONDS )+ "\ncursor(" + String time (( datetime )(cursorMSC/ 1000 ), TIME_DATE | TIME_MINUTES | TIME_SECONDS )+ ")\ntry(" + integer to string (try)+ ")\nPlease wait for the reply..." ); } //--- at this point we have the oldest tick //--- start requesting price changes from oldest to newest if (oldest != long_max ) { array free (receiver); DateTimeLatest_Scale = 0 ; //--- Receive the last quote time of the trading symbol stored in symbol_time date time nearest candle = ( date time ) symbol information integer ( _symbol , SYMBOL_TIME ); althoughn>(newest_tick//--- Request a new batch of integers starting with the oldest time and specifying the tick limit pull = copy_tick ( _token , receiver, COPY_TICKS_ALL , oldest, tick_packets); if (pull > 0 ) { //--- If we pull a new batch update our download time latest_tick=receiver[pull - 1 ]. time; oldest = receiver[pull - 1 ].time_msc; array free (receiver); } //--- Timeout server request, you can change it if needed sleep ( 44 ); comment ( "pull to" + string time (newest tick, TIME_DATE | TIME_MINUTES | TIME_SECONDS )+ "so far" ); } } else { alert ( "Please close terminal\n Go to ticks folder\n and delete empty folders" ); expert delete (); } //--- Update manager and continue MANAGER.manage(MANAGER_FOLDER,MANAGER_STATUS_FILE); } else { //--- Get market watch symbols to start downloading comments ( "grab MW and start" ); MANAGER.grab_symbols(); MANAGER.Manage(MANAGER_FOLDER,MANAGER_STATUS_FILE); } } }