How to test a strategy on MT5 using a fix spread "à la" MT4

31 January 2020, 16:26
Icham Aidibe
0
49
  • Create a custom symbol with the spec of the target instrument
  • Export bars from the source symbol, timeframe by timeframe until you get that : 

  • The boring part since it's about editing line by line to change the spread to the desired one ... 
  • Import that folder on any unix shell 
xxx@xxx:~/EURUSD$ ls
EURUSD_Daily_201201020000_202001310000.csv  EURUSD_M10_201705231550_202001310810.csv  EURUSD_M4_201901031820_202001310816.csv
EURUSD_H1_201201020000_202001310800.csv     EURUSD_M1_201910230509_202001310818.csv   EURUSD_M5_201809251440_202001310815.csv
EURUSD_H12_201201020000_202001310000.csv    EURUSD_M12_201611090948_202001310812.csv  EURUSD_M6_201806200448_202001310818.csv
EURUSD_H2_201201020000_202001310800.csv     EURUSD_M15_201601212100_202001310815.csv  EURUSD_Monthly_201201010000_202001010000.csv
EURUSD_H3_201201020000_202001310600.csv     EURUSD_M20_201409151920_202001310800.csv  EURUSD_Weekly_201201010000_202001260000.csv
EURUSD_H4_201201020000_202001310800.csv     EURUSD_M2_201907171810_202001310818.csv   fixspread.sh
EURUSD_H6_201201020000_202001310600.csv     EURUSD_M30_201201022230_202001310800.csv
EURUSD_H8_201201020000_202001310800.csv     EURUSD_M3_201904110809_202001310818.csv
xxx@xxx:~/EURUSD$

  • Put the below bash script in the same folder - *quickly done - feel free to improve*

#!/bin/bash
: ${3?"Usage: $0 <fix_spread> <input_folder> <output_folder>"}
#
echo " _     _              __"
echo "| |__ | | ___  _   _ / _|"
echo "| '_ \| |/ _ \| | | | |_"
echo "| |_) | | (_) | |_| |  _|"
echo "|_.__/|_|\___/ \__,_|_|"
echo ""
echo "*** Using spread : " $1
echo "*** Input folder : " $2
echo "*** Output folder : " $3
##
overwrite=0
if ([ -d $3 ] && [ "$(ls -A $3)" ]) && ([ $overwrite="0" ])
then
        echo "*** Copy already exists."
        read -p "Overwrite (y/n)?" choice
                case "$choice" in
                        y|Y ) overwrite=1 && echo "*** Overwriting : " $overwrite;;
                        n|N ) echo "*** Exiting ..." && exit -1;;
                        * ) echo "*** Invalid answer. Exiting ..." && exit -1;;
                esac
fi
if ([ -d $3 ] && [ ! "$(ls -A $3)" ]) || ([ ! -d $2 ]) || ([ $overwrite="1" ])
then
        echo "*** Proceeding on *.csv files ..."
        mkdir -p $3
        for file in $2/*.csv; do [[ -f "${file}" ]] && awk -v fs=$1 -F "\t" '{print $1 "\t" $2 "\t" $3 "\t" $4 "\t" $5 "\t" $6 "\t" $7 "\t" $8 "\t" fs}' $file > $3/$file ; done ;
fi
#####

  • Execute : 

xxx@xxx:~/EURUSD$ chmod +x fixspread.sh && ./fixspread.sh 10 ./ output/
 _     _              __
| |__ | | ___  _   _ / _|
| '_ \| |/ _ \| | | | |_
| |_) | | (_) | |_| |  _|
|_.__/|_|\___/ \__,_|_|

*** Using spread :  10
*** Input folder :  ./
*** Output folder :  output/
*** Proceeding on *.csv files ...
xxx@xxx:~/EURUSD$ ls output/
EURUSD_Daily_201201020000_202001310000.csv  EURUSD_H8_201201020000_202001310800.csv   EURUSD_M30_201201022230_202001310800.csv
EURUSD_H1_201201020000_202001310800.csv     EURUSD_M10_201705231550_202001310810.csv  EURUSD_M3_201904110809_202001310818.csv
EURUSD_H12_201201020000_202001310000.csv    EURUSD_M1_201910230509_202001310818.csv   EURUSD_M4_201901031820_202001310816.csv
EURUSD_H2_201201020000_202001310800.csv     EURUSD_M12_201611090948_202001310812.csv  EURUSD_M5_201809251440_202001310815.csv
EURUSD_H3_201201020000_202001310600.csv     EURUSD_M15_201601212100_202001310815.csv  EURUSD_M6_201806200448_202001310818.csv
EURUSD_H4_201201020000_202001310800.csv     EURUSD_M20_201409151920_202001310800.csv  EURUSD_Monthly_201201010000_202001010000.csv
EURUSD_H6_201201020000_202001310600.csv     EURUSD_M2_201907171810_202001310818.csv   EURUSD_Weekly_201201010000_202001260000.csv
xxx@xxx:~/EURUSD$

  • Bring it back to your platform's system & import it file by file, timeframe by timeframe, as bars for the custom symbol previously created
  • Enjoy !

UPDATE 

It's probably not the way those who integrated python to MQL5 intented to use it, but it did appear to be particularly relevant.

Some requirements : 

  • python3
  • metatrader module
  • panda module
  • python integration enabled in the terminal

pip install Metatrader5 pandas

... you'll find plenty of doc in the forum to set this up ... 

python script : import.py

from datetime import datetime
from numpy import savetxt
import MetaTrader5 as mt5
import pytz
import os
import shutil
import pandas


### settings
symbols = ["EURUSD","GBPUSD", "USDJPY"] # case sensitive
date_start = [2021, 1, 1] # Year - Month - Day
date_end = [2021, 5, 18] # Year - Month - Day
spread_mod = 10
delimiter='\t'
output_ext=".csv"


# display data on the MetaTrader 5 package
print("MetaTrader5 package author: ",mt5.__author__)
print("MetaTrader5 package version: ",mt5.__version__)

# establish connection to MetaTrader 5 terminal
if not mt5.initialize():
    print("initialize() failed, error code =",mt5.last_error())
    quit()

# timeframes as a dict
timeframe = { 
"M1" : mt5.TIMEFRAME_M1,
"M2" : mt5.TIMEFRAME_M2,
"M3" : mt5.TIMEFRAME_M3,
"M4" : mt5.TIMEFRAME_M4,
"M5" : mt5.TIMEFRAME_M5,
"M6" : mt5.TIMEFRAME_M6,
"M10" : mt5.TIMEFRAME_M10,
"M12" : mt5.TIMEFRAME_M12,
"M15" : mt5.TIMEFRAME_M15,
"M20" : mt5.TIMEFRAME_M20,
"M30" : mt5.TIMEFRAME_M30,
"H1" : mt5.TIMEFRAME_H1,
"H2" : mt5.TIMEFRAME_H2,
"H3" : mt5.TIMEFRAME_H3,
"H4" : mt5.TIMEFRAME_H4,
"H6" : mt5.TIMEFRAME_H6,
"H8" : mt5.TIMEFRAME_H8,
"H12" : mt5.TIMEFRAME_H12,
"Daily" : mt5.TIMEFRAME_D1,
"Weekly" : mt5.TIMEFRAME_W1,
"Monthly" : mt5.TIMEFRAME_MN1
}


# set time zone to UTC
timezone = pytz.timezone("Etc/UTC")
utc_from = datetime(date_start[0], date_start[1], date_start[2], tzinfo=timezone)
utc_to = datetime(date_end[0], date_end[1], date_end[2], tzinfo=timezone)



for pair in symbols:
    print("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++")
    print("+ SYMBOL : ",pair)
    print("+ FROM : ",str(date_start[0]) + "-" + str(date_start[1]) + "-" + str(date_start[2]))
    print("+ TO : ",str(date_end[0]) + "-" + str(date_end[1]) + "-" + str(date_end[2]))
    print("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++")
    
    # delete subfolder if already exists
    shutil.rmtree(pair + "/", True, None)

    # main loop
    for i in range(len(timeframe)):
        try:
            rates = mt5.copy_rates_range(pair, list(timeframe.values())[i], utc_from, utc_to)
            if len(rates) > 0:
                print("+ SYMBOL : ",pair,"--- TIMEFRAME : ",list(timeframe)[i],"--- Bars imported : ",len(rates))
                               
                # switch to panda frame
                rates_frame = pandas.DataFrame(rates)
                
                # add column date 
                rates_frame['date']=""
                
                # rename columns
                mapping = {rates_frame.columns[0]:'<TIME>', rates_frame.columns[1]: '<OPEN>', rates_frame.columns[2]:'<HIGH>', rates_frame.columns[3]: '<LOW>',rates_frame.columns[4]:'<CLOSE>', rates_frame.columns[5]: '<TICKVOL>',rates_frame.columns[6]:'<SPREAD>',rates_frame.columns[7]:'<VOL>',rates_frame.columns[8]:'<DATE>'}
                rates_frame = rates_frame.rename(columns=mapping)
                
                # re-arrange columns
                # .date & time
                tmp_column = rates_frame.pop('<DATE>')
                rates_frame.insert(0, '<DATE>', tmp_column)
                tmp_column = ""
                date = pandas.to_datetime(rates_frame['<TIME>'], unit='s')
                rates_frame['<DATE>']=date.dt.strftime('%Y-%m-%d')
                rates_frame['<TIME>']=date.dt.strftime('%H:%M:%S')
                
                
                # .spread
                rates_frame['<SPREAD>']=spread_mod 
                tmp_column = rates_frame.pop('<SPREAD>')
                rates_frame.insert(8, '<SPREAD>', tmp_column)                
                
                # display frame
                #print(rates_frame)                 
                
                # re-create folder if do not exist yet to store data files based on symbol name
                os.makedirs(pair + "/", exist_ok=True);
                
                # write csv
                rates_frame.to_csv(pair + "/" + pair + '_' + str(list(timeframe)[i]) + output_ext,  index=False, header=True, sep=delimiter, encoding='utf-8')

        except TypeError:print("+ SYMBOL : ",pair,"--- TIMEFRAME : ",list(timeframe)[i],"--- No data found. Skipping ...");continue




  • Copy/paste & edit the script (symbols, date start - end, spread value)
  • Run the script


  • In the script folder, you'll find subfolders containing the datas as csv files for each timeframes

  • When importing the datas in MT make sur to check the Tick Volume checkbox

... and voila - much more convenient & crossplatform as you can see uh ? ;)