|
|
|
|
|
|
|
|
… an apparent phenomenon that I've observed many times over the years, but for which I have no hard evidence: The majority of people trade worse than a purely random trader would. William Eckhardt (Jack D. Schwager The New Market Wizards)
We know the main trading functions (except OrderModify()), we have some thoughts about the simplest trading system оn EURUSD, based on the price increment in the normal process simulation, we only have to check it. For this purpose we will write an Expert Advisor ( Random Trade.mq4), that will open transactions at random in random direction with rigid parameters StopLoss and TakeProfit.
We will set the external parameter int StDev, that will mean a standard deviation in points. Our StopLoss will be equal to this parameter with a certain coefficient, which we will change, we will call it SL_K. Consequently TakeProfit will be also calculated as SL_K *StDev . That’s why such parameters as SL_K and TP_K will be also external (changeable at the discretion of the user).
For modeling a random value in MQL-4 there is such function as MathRand(). In order to get a random value within the interval from 0 to 1, we will have to divide its value by 32767. If the result is more than 0.5 – we buy at market price, if it is less than 0.5 – we sell. In principle the Advisor is ready.
We start the process of creating an Advisor with the help of «Expert Advisor Creation Wizard»
|
|
|
|
We write a simple function GetOrder(), and the Advisor is ready. Please note that the levels StopLoss(SL) and TakePofit(TP) for the order we open are previously normalized. As coefficients for calculating these levels won’t be necessarily integer, which means that the calculated levels themselves may contain more decimal places than Digits, it is better to round these prices to the needed value, otherwise the trading server may disallow the instruction to open an order. Normalization is always required when the levels of prices are calculated and it is desirable when we simply take prices from the chart. Also there is the nonzero parameter Slippage in the order, it won’t influence testing, but for trading online it is better to set it, in order not to receive refusals from the server for the reason of price deterioration in conditions of changing market when you open or close positions.
|
|
|
|
And of course we shouldn’t forget that we buy at Ask prices, and sell at Bid prices. As a comment we write a random number Random, on the base of which the decision about the trade direction was made. Partly it was done for an example, partly to check the correctness of the algorithm. We compile the Advisor, open in the terminal the tester panel (Ctrl+R), choose our Advisor, the needed symbol and time frame. We choose the way of testing «Open prices (quick method on completed bars)». It may happen that in the picklist of symbols there won’t be the one we need. Then it is necessary to grab the needed symbol by the mouse and drop it on the tester panel (method “Drag & Drop”).
|
|
|
|
But on closer view there is some artificiality, inaccuracy in it. If an order is opened, a new order won’t open until the previous one closes with profit or loss, but once the order closes, a new random order opens.
We press the button «Start», after the testing is over we open the tab «Results» and we can see the confirmation:
|
|
|
|
In real situations it isn’t so, neither when you trade manually, nor when your use an Expert Advisor. There is also some delay between closing of one order and opening of another. We will improve our model of random trading – we will add lagging between these two events. If this lagging is rigid we won’t realize the random trading model in full, that’s why I suggest making the pause between two orders random as well. Suppose, that there are in average 20 periods between closing of one order and opening of another while trading on hourly time frames.
Consequently we need to receive somehow information about the time of the last order closing. For this we will declare two new variables : lastTicket (the ticket number of the last order) and lastCloseTime (the time of the last closing). In order not to loose these values in the intervals between calls of the start() function, we will declare them on the global level. Also we will add an external parameter periodTrade, its value will guarantee the maximum time between two orders. Now our Advisor RandomTrade-2 looks like that:
|
|
|
|
A lot of commented outputs to log (Print()) are intentionally added in the Advisor, they may be uncommented when needed for better understanding.
Now in case of successful opening of an order its ticket is remembered. Later in the GetOrder() function the time interval between the last closing and the current time is compared with the set period in bars periodTrade. The expression (CurTime()-lastCloseTime)/( periodTrade*Period()*60.0) at first will be small, but it will increase with each new bar in the tester, and a random number within the interval from 0 to 1 at first will have the minimum possibility to be less than this expression, but after periodTrade bars the possibility of opening a new order will become equal to 100%.
We launch the new variant of the Advisor and we can see that the situation has improved. Now a pause between transactions has appeared.
|
|
|
|
But if we change the model «Open prices» for the model «All ticks» or «Control points», the picture will change. Here are «Results» for «Control points»
|
|
|
|
And here for «All ticks»
|
|
|
|
You may run a test on your computer, the number and order of transactions will be different from mine, but the general conclusion will be the same – the more detailed simulation is the more transactions we get. We received a visual proof that this simple Advisor is written incorrectly – when the mode of modeling is changed the test results change considerably. If your Advisor written according to some strategy (unlike mine written based on randomness) behaves in the same way – it means there is a serious defect in the algorithm of the Advisor. In order to achieve results relatively insensitive of the modeling mode, you need to :
- upload as detailed history as possible for the tested period started from minutes and
- in an explicit form divide the events EveryBar and EveryTick, as in the Advisor BlackBox.mq4.
Let these events (functions) will be called and defined differently from mine, but you must distinguish them clearly.
It is possible to contradict here - «Of course the number of transactions on different models will be different, as the transactions are random and they mustn’t be repeated». In fact our Advisor has the last weak point – it is not really random, though we used the MathRand() function. Each time when the Advisor is tested in the tester one and the same sequence of pseudo-random numbers is generated and that’s why we receive one and the same sequence of transactions regardless of the simulation mode. Check it by yourself.
In order to achieve a new sequence of random numbers it is necessary to initialize the random number generator with the help of the MathSrand() function. If we use MathSrand(1), we will get one sequence of random number, if we use MathSrand(2) it will be different. But in order to achieve a new series of transactions each time the Advisor is tested, the sequences of transactions must be different. The simplest way out is to use the construction MathSrand(GetTickCount()). We will insert it in the block init() and the problem is solved, as the function GetTickCount() will return a new value each time it is called. We will call the final variant RandomTrade-3.mq4.
Now we can optimize our Advisor, i.e. search the best parameters for getting profit, or in other words – is the hypothesis confirmed that in case of the ratio TP/SL=3 we will not only receive profit but the profit will be maximum. We press the button «Expert Advisor Properties» , choose the tab «Input parameters» and mark as shown in the picture.
|
|
|
|
Don’t forget to make sure that on the tab «Testing» the check-bock «Genetic algorithm» isn’t marked – we don’t need it now. We won’t change the initial deposit - $10000 , buying and selling are allowed (Ppositions: Long&Short).
|
|
|
|
We mark the check-box «Optimization», model «Open prices» on the tester panel and get something like that.
|
|
|
|
We run a test once again and get a new chart of results optimization.
|
|
|
|
We can see that on the same parameters each time we receive a new series of random transactions, i.e. after all we have achieved randomness. But a new question arises – how we can determine – if some parameters are better than other. In this case the optimization of the Advisor doesn’t give an unambiguous answer what to do. If we make 100 runs in the tester for each parameter we will be able to compare somehow the testing results, achieved for different parameters. We will be able to average profit achieved in the result of 100 runs, or the number of transactions, or profitability.
|
|
|
|
The optimization results are easy to sort out by in ascending or descending order by pressing on the column name. If we double click the line with the needed parameter of the Advisor we will get again to the tab «Settings», and these parameters will be used when the Advisor is tested.
|
|
|
|
We run the Advisor with these parameters and we get the following chart.
|
|
|
|
We can see that during testing the Balance curve went up and down, but profit of $3963.66 wasn’t detected. The number of transactions and other testing characteristics don’t coincide as well.
|
|
|
|
We wanted random to achieve random transactions – we achieved them. But our hypothesis of possibility to earn on random entries having a certain ratio between TP/SL hasn’t been checked yet. We have the last way to do it - we will add an empty variable (I called it Balk), from which nothing depends in the algorithm and we’ll do optimization. I put this new external variable on the first place in the external parameters section so that the run will start with sorting its values. We will call this variant of the Advisor RandomTrade-4, will compile it and set the optimization parameters.
|
|
|
|
The parameter SL_K I excluded in order to accelerate the process (as 3000 runs will be required). When I tested it on hourly time frames it took me 13 minutes.
|
|
|
|
We can see that when the value of StDev (consequently of StopLoss as well) is small, the Advisor heavy and stable unprofitability is observed, that practically doesn’t depend on the value TakeProfit. The chart of optimization may be seen in the form of two-dimensional plane, for this we press the right mouse button and set this mode.
|
|
|
|
We set values for X axis
|
|
|
|
и для Y
<#IMG21>
Thus it is very convenient to estimate visually the influence of the Advisor parameters on the results of testing. The files of Expert Advisors are here .
Go to article «Statistics ( the #include command)».
|
|