Geometric mean with negative numbers
July 12, 2008Thanks for visiting! If you like what you're reading, you may want to subscribe to my RSS feed.
This won’t quite be a conventional Personal Finance post, but the fact that I cannot calculate my portfolio’s performance without converting negative returns into “false positive” ones annoyed me too much to just ignore. Since I couldn’t find a straightforward way around it, I decided to simply code the Excel function I was looking for myself.
While the code is by no means perfect (yet) it does the job nicely and I’m nevertheless pleased with the result. As long as it gets called properly, it converts your negative percentages into a value equivalent to (100 - x) / 100 where x is your percentage. For positive values, it does the conversion according to (100 + x) / 100. These conversions means that a decrease of 10% will be expressed as 0.9 and an increase of 10% as 1.1 which subsequently allows you to compute the geometric mean (which is exactly what it does).
Below is the VBA code you will need to utilise this functionality. Feel free to use it as you please but don’t worry if you have no clue how exactly to do that. I have included a step-by-step description of how to install and call it from your Excel worksheet underneath the code.
Function geometric(data As Variant)
Dim vaData As Variant
Dim rnData As Range
Dim i As Long
Dim j As Long
Dim iblank As Long
Dim jblank As Long
Dim bblank As Boolean
Set rnData = data
vaData = rnData.Value
temp = 1
n = 0
For j = 1 To UBound(vaData, 2)
For i = 1 To UBound(vaData, 1)
If vaData(i, j) <> Empty Then
vaData(i, j) = 1 + vaData(i, j)
’ compute product for non-empty data cells
temp = temp * vaData(i, j)
’ count number of items in list
n = n + 1
End If
Next i
Next j
geometric = (temp ^ (1 / n)) - 1
End Function
Follow the steps below to make the above function available in your Excel worksheet:
- In Excel, open the file you want to use the function in. Note: at the moment the function will only be available on a per-file basis. That means, if you’re planning to use it in more than one file, you will need to repeat this procedure for every single file. I’m working on coding a proper add-on that you simply install into Excel and hence make available to any new or existing file. I told you it was work in progress…
- In the menu bar, next to the entry “File”, right-click on the Excel icon and select “View Code”
- The Microsoft Visual Basic Editor opens and you stare at a blank document
- In the menu bar, click on “Insert” followed by “Module”
- Copy and paste the above code into that “new” blank space and hit “Save”
- After you have saved the changes, click on “File” and select the entry “Close and return to Microsoft Excel”. This brings you back to where you started, and your function is ready to use.
Here is how you use the function:
- Open the file in which you have installed the above function
- Pick a cell that you want the result to contain and type “=geometric(”
- Note the opening bracket !
- With your mouse click and hold until you have highlighted the cell range that contains the numbers you want the geometric mean of. Alternatively, type the cell range yourself as A1:D4 where A1 should be replaced by the coordinates of your first cell and D4 should be replaced by the last cell’s identifier. At the moment, the geometric function only works with a cell range, not individual cells or numbers. I’m working on it…
- Close the bracket by typing “)”
- Hit ENTER to see the geometric mean of your highlighted cells
If you format the cell in question in such a way to convert your result back into a percentage (just right-click, choose Format - Number Format - Percentage), the result should make sense in the context of portfolio returns.
Note that the code above has been tested and verified in Excel 2002 and should work with any other Excel version(s) since. The only concern I have regards the compatibility with - you might guess it - Excel 2007. If anyone manages to run it under the new Office version, please let me know!
As usual, if you have questions or concerns, find a bug or just need a hand to get it to work, just give me a shout or leave a comment! I hope you will find it as useful as I did. ![]()
















