How is the Sharpe ratio calculated in the Strategy Tester report?

 

Hello everyone,

I have been trying for several hours to reproduce the Sharpe Ratio statistics that appear in the Strategy Tester, but I cannot figure out the formula used by MetaTrader 5 to arrive at the displayed result.

To do this, I followed the article ‘Mathematics in trading: Sharpe and Sortino ratios’ by MetaQuotes, and more specifically the section ‘Example of Sharpe ratio calculation in the MetaTrader 5 Strategy Tester’.

The latter indicates that the formula is as follows:

sharpe = mean(log_returns) / std(log_returns) ; with log_returns being the array composed of log_return = ln(E_t / E_(t-1)). E being the equity at bar t.

So, of course, I tested this formula (using the robot from the article, as well as the Sharpe.mqh file without any modifications), and I found completely different results. See below images.

 <- found on the tester report.

 <- found by the article's script.

So I thought that perhaps the calculation formula used in the report was non-logarithmic, so I modified few lines of the Sharpe calculator code from:

(Line 83 of Sharpe.mqh): log_return = MathLog(m_equities[i] / prev_equity);

To:

tmp_return = (m_equities[i] - prev_equity) / prev_equity; // Of course, also changing the other variables to tmp_return and so on.

And yet it sill does not work (very different result between Strategy Tester report and OnTester() result). I therefore thought, as one user rightfully commented in the article, that this was due to the fact that the article was only taking into consideration bars that had a change in equity, while dividing later on by the total amount of bars. Consequently, I removed the different equity check and made a few changes accordingly, and yet, still a totally different results.

for (int i = 1; i < m_bars_counter; i++) 
{
   // No different equity check, implementing counter at each bar.
   log_return = MathLog(m_equities[i] / prev_equity); // increment logarithm
   // tmp_return = (m_equities[i] - prev_equity) / prev_equity;
   aver += log_return;            // average logarithm of increments
   AddReturn(log_return);         // fill the array of increment logarithms
   counter++;                     // counter of returns
   prev_equity = m_equities[i];
}

Does anyone know exactly how the Sharpe ratio is calculated in the Strategy Tester report? Preferably, does anyone have a piece of code that can emulate it? I can't find any answers anywhere.


PS: by any chance, is it possible to add LaTeX to the forum? :x

Mathematics in trading: Sharpe and Sortino ratios
Mathematics in trading: Sharpe and Sortino ratios
  • 2022.03.31
  • www.mql5.com
Return on investments is the most obvious indicator which investors and novice traders use for the analysis of trading efficiency. Professional traders use more reliable tools to analyze strategies, such as Sharpe and Sortino ratios, among others.
 

By the way, here is the rest of the code (with standard deviation and such), which you can also find in the article ("Sharpe.mqh").

//--- if values are not enough for Sharpe calculation, return 0
if (counter <= 1)
   return(0);
//--- average value of the increment logarithm
aver /= counter;
//--- calculate standard deviation
for (int i = 0; i < counter; i++)
   std += (m_returns[i] - aver) * (m_returns[i] - aver);

std /= counter;
std = MathSqrt(std);
//--- Sharpe ratio on the current timeframe
double sharpe = aver / std; // Also tried with "(aver - 1) / std" instead, to account with Risk Free Rate (1-RFR=1-0), does not work as well.
 
Zaky Hamdoun:

The discrepancy may be due to the inclusion of bars with no variation in equity, which would introduce zero returns that could dilute both the mean and the standard deviation, thus affecting the Sharpe ratio calculation.

 
Miguel Angel Vico Alba #:

The discrepancy may be due to the inclusion of bars with no variation in equity, which would introduce zero returns that could dilute both the mean and the standard deviation, thus affecting the Sharpe ratio calculation.

Unfortunately no, as explained in the post, I have made tests while removing the check for bars with no variation in equity. (Check out the for loop code in the post). Therefore including all bars. Yet, it still produces a very different result from the strategy tester, so this can't be the issue...

I have tried both removing/including those zero bars, yet, still different results in both cases.
 

I have also tried following the function posted by Rashid Umarov on the following post, which is basically the same as I have except that the standard deviation is computed with:

//--- calculate standard deviation
for (int i = 0; i < counter; i++)
   std += (aver - m_returns[i]) * (aver - m_returns[i]);

Instead of (the code of the article):

//--- calculate standard deviation
for (int i = 0; i < counter; i++)
   std += (m_returns[i] - aver) * (m_returns[i] - aver);

Yet, I still face totally different results between the strategy tester and the calculated result.

Sharp Ratio or/and Sortino Ratio
Sharp Ratio or/and Sortino Ratio
  • 2007.07.17
  • www.mql5.com
Can anybody from MT4 developers or experienced guys publish formulas/methods for Sharp Ratio calculations used in new reports on Championship websi...
 

Would be better if you post a simple test with array with input data.

From what you say it looks like you process the bars/trades in reverse order.

 

As an example, you can just use the "MACD_Sample_Sharpe.mq5" file from the MQL5 article linked above. Just by running it as a backtest on any symbol/timeframe, you'll see a different result between the Strategy Tester's report Sharpe Ratio and the one returned by OnTester(), even though the program is supposed to use the official formula.

EDIT: Turns out: the formula used in the article sometimes provides the same result, but it only works when on long backtesting periods (so for example, strategy testing for a year). Otherwise, it does not yield the same result as the strategy tester itself. Anyone knows what's used for smaller backtesting periods?
 
Admin Rashid Umarov specified that the formula used was the one in the article I mentioned before, as per his comment: https://www.mql5.com/en/forum/434469/page2

What I do not understand is the fact that on large backtesting durations (1 year and above), the result is the same as the strategy tester, but on lower durations (testing for a month for example), the result is totally different than the one on the report provided by the strategy tester...
Sharpe ratio signal - How the Sharpe Ratio is used for signals and tester?
Sharpe ratio signal - How the Sharpe Ratio is used for signals and tester?
  • 2022.10.13
  • www.mql5.com
If i say i'm looking for a sign with a ratio greater than 2 is because it is recommended to use systems with a ratio greater than 2. Yesterday evening i took the script amended it so that it reads the trading history of a signal and calculates the sharp ratio - but based on single trades and not a set timespan like month, year,. Com/en/forum/392431#comment_42650592
 
Zaky Hamdoun #:
Admin Rashid Umarov specified that the formula used was the one in the article I mentioned before, as per his comment: https://www.mql5.com/en/forum/434469/page2

What I do not understand is the fact that on large backtesting durations (1 year and above), the result is the same as the strategy tester, but on lower durations (testing for a month for example), the result is totally different than the one on the report provided by the strategy tester...

The results are not identical formulas. On long backtests the difference between the time based calculation and the trade based calculation becomes very small, so they appear the same.

On short backtests that small difference becomes proportionally much larger, so the values no longer match.

Think of two ways to measure a car's fuel efficiency. One method measures it every minute of driving, the other measures it every time you stop to refuel.

If you drive for a very long trip (many hours), both methods will give almost the same average because small differences smooth out over time.

If you drive for a short trip (just a few minutes), the difference between the two methods will be bigger because there are fewer measurements and any small variation has a bigger impact.

The same happens with the Sharpe ratio. The Strategy Tester uses time based increments, while the old calculation in Signals is based on trade increments. Over long backtests both converge, but in short backtests the difference becomes more visible.
 
Miguel Angel Vico Alba #:

The results are not identical formulas. On long backtests the difference between the time based calculation and the trade based calculation becomes very small, so they appear the same.

On short backtests that small difference becomes proportionally much larger, so the values no longer match.

Think of two ways to measure a car's fuel efficiency. One method measures it every minute of driving, the other measures it every time you stop to refuel.

If you drive for a very long trip (many hours), both methods will give almost the same average because small differences smooth out over time.

If you drive for a short trip (just a few minutes), the difference between the two methods will be bigger because there are fewer measurements and any small variation has a bigger impact.

The same happens with the Sharpe ratio. The Strategy Tester uses time based increments, while the old calculation in Signals is based on trade increments. Over long backtests both converge, but in short backtests the difference becomes more visible.

Do you know where can I find the exact formula that is used by the Strategy Tester, in all cases? I have a client requesting to have a program pause depending on that value each 5 trades, but I can't find the formula for those short periods of time... I basically just need a way of getting the same value the Strategy Tester would in all cases.

 
Zaky Hamdoun #Do you know where can I find the exact formula that is used by the Strategy Tester, in all cases? I have a client requesting to have a program pause depending on that value each 5 trades, but I can't find the formula for those short periods of time... I basically just need a way of getting the same value the Strategy Tester would in all cases.

The Strategy Tester calculates the Sharpe ratio using logarithmic returns of equity per bar (last tick), ignoring bars with no change, and with Rf=0.

Over long periods this method converges with trade-based calculations, but in short periods the difference becomes larger due to sampling and time-scale effects.

To replicate it exactly, use the code from the "Mathematics in trading: Sharpe and Sortino ratios" article and apply annualization according to your data frequency.