Module 2 · Financial Arithmetic, Time Value, and Returns Lesson 19 of 120
Arithmetic versus Geometric Average Return
Choosing an average that answers the actual return question.
Transcript
21 sentences · select one to jump thereCheck your understanding
Which average reproduces this compounded endpoint when repeated?
Code lab
Run it yourself
The lesson source in 7 languages. Edit it, run TypeScript and Python right here, and compare with the expected output.
/**
* Fintech Math Bootcamp · Lesson 019 of 120
* Arithmetic versus Geometric Average Return
* Module 02: Financial Arithmetic, Time Value, and Returns
*
* Scenario: Choosing an average that answers the actual return question
* Rule: AM = mean(R); GM = Π(1+R)^(1/n) − 1
*
* Try it: Which average reproduces this compounded endpoint when repeated?
*
* Lesson article: https://thefintechbuilder.com/financial-mathematics-statistics-and-data-foundations/financial-arithmetic-time-value-and-returns/arithmetic-geometric-return/
* Free course: https://courses.thefintechbuilder.com
* Synthetic teaching example, not financial advice or a production library.
*/
export function lesson019() {
const rs = [0.20, -0.20];
const arithmetic = rs.reduce((a, r) => a + r, 0) / rs.length;
const factor = rs.reduce((a, r) => a * (1 + r), 1);
const geometric = factor ** (1 / rs.length) - 1;
const result = {arithmetic, geometric};
return result;
}
export const checkedResult = {"arithmetic":0,"geometric":-0.020204102886728803};
// Run this file directly: npx tsx lessons/02-financial-arithmetic-time-value-and-returns/019-arithmetic-versus-geometric-average-return.ts
if (process.argv[1] && import.meta.url.endsWith(process.argv[1].replace(/\\/g, "/").split("/").pop()!)) {
console.log(JSON.stringify(lesson019(), null, 2));
}
Your output
Press Run to execute the code in your browser.
Expected output
{
"arithmetic": 0,
"geometric": -0.020204102886728803
}"""
Fintech Math Bootcamp · Lesson 019 of 120
Arithmetic versus Geometric Average Return
Module 02: Financial Arithmetic, Time Value, and Returns
Scenario: Choosing an average that answers the actual return question
Rule: AM = mean(R); GM = Π(1+R)^(1/n) − 1
Try it: Which average reproduces this compounded endpoint when repeated?
Lesson article: https://thefintechbuilder.com/financial-mathematics-statistics-and-data-foundations/financial-arithmetic-time-value-and-returns/arithmetic-geometric-return/
Free course: https://courses.thefintechbuilder.com
Synthetic teaching example, not financial advice or a production library.
Run it: python main.py
"""
import json
import math
def lesson019() -> dict:
rs = [0.20, -0.20]
arithmetic = sum(rs) / len(rs)
factor = math.prod(1 + r for r in rs)
geometric = factor ** (1 / len(rs)) - 1
result = {"arithmetic": arithmetic, "geometric": geometric}
return result
if __name__ == "__main__":
print(json.dumps(lesson019(), indent=2))
Your output
Press Run to execute the code in your browser.
Expected output
{
"arithmetic": 0,
"geometric": -0.020204102886728803
}/**
* Fintech Math Bootcamp · Lesson 019 of 120
* Arithmetic versus Geometric Average Return
* Module 02: Financial Arithmetic, Time Value, and Returns
*
* Scenario: Choosing an average that answers the actual return question
* Rule: AM = mean(R); GM = Π(1+R)^(1/n) − 1
*
* Try it: Which average reproduces this compounded endpoint when repeated?
*
* Lesson article: https://thefintechbuilder.com/financial-mathematics-statistics-and-data-foundations/financial-arithmetic-time-value-and-returns/arithmetic-geometric-return/
* Free course: https://courses.thefintechbuilder.com
* Synthetic teaching example, not financial advice or a production library.
*
* Run it: javac Main.java && java Main
*/
import java.util.Arrays;
public class Main {
static final class AverageReturns {
final double arithmetic;
final double geometric;
AverageReturns(double arithmetic, double geometric) {
this.arithmetic = arithmetic;
this.geometric = geometric;
}
}
static AverageReturns lesson019() {
double[] rs = {0.20, -0.20};
double arithmetic = Arrays.stream(rs).reduce(0, (a, r) -> a + r) / rs.length;
double factor = Arrays.stream(rs).reduce(1, (a, r) -> a * (1 + r));
double geometric = Math.pow(factor, 1.0 / rs.length) - 1;
AverageReturns result = new AverageReturns(arithmetic, geometric);
return result;
}
public static void main(String[] args) {
AverageReturns result = lesson019();
System.out.println(object(
"arithmetic", num(result.arithmetic),
"geometric", num(result.geometric)));
}
// Formats a double the way JSON.stringify does: whole numbers without ".0", null for NaN or infinity.
static String num(double x) {
if (Double.isNaN(x) || Double.isInfinite(x)) return "null";
if (x == Math.rint(x) && Math.abs(x) < 1e15) return String.valueOf((long) x);
return String.valueOf(x);
}
static String quote(String text) {
return "\"" + text.replace("\\", "\\\\").replace("\"", "\\\"") + "\"";
}
// Indents an already formatted JSON value by one level.
static String nested(String json) {
return json.replace("\n", "\n ");
}
static String object(String... keysAndValues) {
if (keysAndValues.length == 0) return "{}";
StringBuilder out = new StringBuilder("{");
for (int i = 0; i < keysAndValues.length; i += 2) {
out.append(i == 0 ? "\n " : ",\n ")
.append(quote(keysAndValues[i])).append(": ").append(nested(keysAndValues[i + 1]));
}
return out.append("\n}").toString();
}
}
No browser runner for Java yet
Read the code here, then run it in your own toolchain or a ready-made cloud workspace.
Expected output
{
"arithmetic": 0,
"geometric": -0.020204102886728803
}// Fintech Math Bootcamp · Lesson 019 of 120
// Arithmetic versus Geometric Average Return
// Module 02: Financial Arithmetic, Time Value, and Returns
//
// Scenario: Choosing an average that answers the actual return question
// Rule: AM = mean(R); GM = Π(1+R)^(1/n) − 1
//
// Try it: Which average reproduces this compounded endpoint when repeated?
//
// Lesson article: https://thefintechbuilder.com/financial-mathematics-statistics-and-data-foundations/financial-arithmetic-time-value-and-returns/arithmetic-geometric-return/
// Free course: https://courses.thefintechbuilder.com
// Synthetic teaching example, not financial advice or a production library.
//
// Run it: go run main.go
package main
import (
"encoding/json"
"fmt"
"math"
)
type AverageReturns struct {
Arithmetic float64 `json:"arithmetic"`
Geometric float64 `json:"geometric"`
}
func lesson019() AverageReturns {
rs := []float64{0.20, -0.20}
sum, factor := 0.0, 1.0
for _, r := range rs {
sum += r
factor *= 1 + r
}
n := float64(len(rs))
arithmetic := sum / n
geometric := math.Pow(factor, 1/n) - 1
result := AverageReturns{Arithmetic: arithmetic, Geometric: geometric}
return result
}
func main() {
printJSON(lesson019())
}
// printJSON prints a value as JSON indented with two spaces, like JSON.stringify(value, null, 2).
func printJSON(value any) {
out, err := json.MarshalIndent(value, "", " ")
if err != nil {
panic(err)
}
fmt.Println(string(out))
}
No browser runner for Go yet
Read the code here, then run it in your own toolchain or a ready-made cloud workspace.
Expected output
{
"arithmetic": 0,
"geometric": -0.020204102886728803
}/**
* Fintech Math Bootcamp · Lesson 019 of 120
* Arithmetic versus Geometric Average Return
* Module 02: Financial Arithmetic, Time Value, and Returns
*
* Scenario: Choosing an average that answers the actual return question
* Rule: AM = mean(R); GM = Π(1+R)^(1/n) − 1
*
* Try it: Which average reproduces this compounded endpoint when repeated?
*
* Lesson article: https://thefintechbuilder.com/financial-mathematics-statistics-and-data-foundations/financial-arithmetic-time-value-and-returns/arithmetic-geometric-return/
* Free course: https://courses.thefintechbuilder.com
* Synthetic teaching example, not financial advice or a production library.
*
* Run it: g++ -std=c++17 -o main main.cpp && ./main
*/
#include <charconv>
#include <cmath>
#include <iostream>
#include <numeric>
#include <string>
#include <utility>
#include <vector>
// Formats a double the way JSON.stringify does: shortest round-trip form, null for NaN or infinity.
std::string num(double x) {
if (!std::isfinite(x)) return "null";
char buffer[32];
auto [end, error] = std::to_chars(buffer, buffer + sizeof buffer, x);
(void)error;
return std::string(buffer, end);
}
std::string quote(const std::string& text) {
std::string out = "\"";
for (char c : text) {
if (c == '"' || c == '\\') out += '\\';
out += c;
}
return out + "\"";
}
// Indents an already formatted JSON value by one level.
std::string nested(const std::string& json) {
std::string out;
for (char c : json) {
out += c;
if (c == '\n') out += " ";
}
return out;
}
std::string object(const std::vector<std::pair<std::string, std::string>>& fields) {
if (fields.empty()) return "{}";
std::string out = "{";
for (std::size_t i = 0; i < fields.size(); ++i) {
out += i == 0 ? "\n " : ",\n ";
out += quote(fields[i].first) + ": " + nested(fields[i].second);
}
return out + "\n}";
}
struct AverageReturns {
double arithmetic;
double geometric;
};
AverageReturns lesson019() {
const std::vector<double> rs{0.20, -0.20};
const double n = static_cast<double>(rs.size());
const double arithmetic = std::accumulate(rs.begin(), rs.end(), 0.0) / n;
const double factor = std::accumulate(rs.begin(), rs.end(), 1.0,
[](double a, double r) { return a * (1 + r); });
const double geometric = std::pow(factor, 1 / n) - 1;
const AverageReturns result{arithmetic, geometric};
return result;
}
int main() {
const AverageReturns result = lesson019();
std::cout << object({
{"arithmetic", num(result.arithmetic)},
{"geometric", num(result.geometric)}
}) << "\n";
}
No browser runner for C++ yet
Read the code here, then run it in your own toolchain or a ready-made cloud workspace.
Expected output
{
"arithmetic": 0,
"geometric": -0.020204102886728803
}//! Fintech Math Bootcamp · Lesson 019 of 120
//! Arithmetic versus Geometric Average Return
//! Module 02: Financial Arithmetic, Time Value, and Returns
//!
//! Scenario: Choosing an average that answers the actual return question
//! Rule: AM = mean(R); GM = Π(1+R)^(1/n) − 1
//!
//! Try it: Which average reproduces this compounded endpoint when repeated?
//!
//! Lesson article: https://thefintechbuilder.com/financial-mathematics-statistics-and-data-foundations/financial-arithmetic-time-value-and-returns/arithmetic-geometric-return/
//! Free course: https://courses.thefintechbuilder.com
//! Synthetic teaching example, not financial advice or a production library.
//!
//! Run it: rustc main.rs && ./main
struct AverageReturns {
arithmetic: f64,
geometric: f64,
}
fn lesson019() -> AverageReturns {
let rs = [0.20_f64, -0.20];
let n = rs.len() as f64;
let arithmetic = rs.iter().fold(0.0, |a, &r| a + r) / n;
let factor = rs.iter().fold(1.0, |a, &r| a * (1.0 + r));
let geometric = f64::powf(factor, 1.0 / n) - 1.0;
let result = AverageReturns { arithmetic, geometric };
result
}
fn main() {
let result = lesson019();
println!(
"{}",
object(&[
("arithmetic", num(result.arithmetic)),
("geometric", num(result.geometric)),
])
);
}
/// Formats a number the way JSON.stringify does: shortest round-trip form, null for NaN or infinity.
fn num(x: f64) -> String {
if x.is_finite() {
format!("{}", x)
} else {
"null".to_string()
}
}
fn quote(text: &str) -> String {
format!("\"{}\"", text.replace('\\', "\\\\").replace('"', "\\\""))
}
/// Indents an already formatted JSON value by one level.
fn nested(json: &str) -> String {
json.replace('\n', "\n ")
}
fn object(fields: &[(&str, String)]) -> String {
if fields.is_empty() {
return "{}".to_string();
}
let lines: Vec<String> = fields
.iter()
.map(|(key, value)| format!(" {}: {}", quote(key), nested(value)))
.collect();
format!("{{\n{}\n}}", lines.join(",\n"))
}
No browser runner for Rust yet
Read the code here, then run it in your own toolchain or a ready-made cloud workspace.
Expected output
{
"arithmetic": 0,
"geometric": -0.020204102886728803
}/**
* Fintech Math Bootcamp · Lesson 019 of 120
* Arithmetic versus Geometric Average Return
* Module 02: Financial Arithmetic, Time Value, and Returns
*
* Scenario: Choosing an average that answers the actual return question
* Rule: AM = mean(R); GM = Π(1+R)^(1/n) − 1
*
* Try it: Which average reproduces this compounded endpoint when repeated?
*
* Lesson article: https://thefintechbuilder.com/financial-mathematics-statistics-and-data-foundations/financial-arithmetic-time-value-and-returns/arithmetic-geometric-return/
* Free course: https://courses.thefintechbuilder.com
* Synthetic teaching example, not financial advice or a production library.
*
* Run it: dotnet run (inside a console project that holds this Program.cs)
*/
using System.Text.Json;
var jsonOptions = new JsonSerializerOptions { WriteIndented = true, PropertyNamingPolicy = JsonNamingPolicy.CamelCase };
Console.WriteLine(JsonSerializer.Serialize(Lesson019(), jsonOptions));
static AverageReturns Lesson019()
{
double[] rs = { 0.20, -0.20 };
var arithmetic = rs.Aggregate(0.0, (a, r) => a + r) / rs.Length;
var factor = rs.Aggregate(1.0, (a, r) => a * (1 + r));
var geometric = Math.Pow(factor, 1.0 / rs.Length) - 1;
var result = new AverageReturns(arithmetic, geometric);
return result;
}
record AverageReturns(double Arithmetic, double Geometric);
No browser runner for C# yet
Read the code here, then run it in your own toolchain or a ready-made cloud workspace.
Expected output
{
"arithmetic": 0,
"geometric": -0.020204102886728803
}Prefer your own machine? Every file is in the course repository · open it in Codespaces.
Lesson notes
The rule
AM = mean(R); GM = Π(1+R)^(1/n) − 1