commit 9c0026fe9230feda26ef434a24823fe8b7c2eabe
Author: Jacob R. Edwards <jacob@jacobedwards.org>
Date: Wed, 13 Mar 2024 20:01:19 -0700
Add expense ratio script
Diffstat:
A | er | | | 81 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
1 file changed, 81 insertions(+), 0 deletions(-)
diff --git a/er b/er
@@ -0,0 +1,81 @@
+#!/usr/bin/awk -f
+# Written 2024-03-13
+#
+# Has two functions:
+# 1. Calculate the expense of each asset in a list using it's
+# expense ratio
+# 2. Calculate the weighted expense ratio for each asset given
+#
+# Expense ratios are listed in a file with
+# symbol er
+# on each line specifying the expense ratio for symbol.
+#
+# Assets are listed in a format like so
+# symbol value
+# where value is a number defining the value of the asset (which
+# may be USD)
+
+function die(msg)
+{
+ status = 1
+ print "error: " msg > "/dev/stderr"
+ exit status
+}
+
+function load_ers(file, _s)
+{
+ while (_s = getline < file)
+ ers[$1] = $2;
+ return _s != 0
+}
+
+function er(symbol)
+{
+ if (!(symbol in ers))
+ die(symbol ": Expense ratio not defined");
+ return ers[symbol];
+}
+
+BEGIN {
+ FS = " "
+ OFS = FS
+ OFMT = "%.2f"
+
+ if (!ARGV[1])
+ die("No expense-ratios");
+ if (load_ers(ARGV[1]))
+ die("Unable to load ERs: I/O error");
+ delete ARGV[1];
+
+ if (ARGV[2] ~ /^-/) {
+ action = substr(ARGV[2], 2)
+ delete ARGV[2]
+ }
+}
+
+{
+ if (!action || action == "costs") {
+ print $1, $2 * (er($1) / 100)
+ } else if (action == "weighted") {
+ amounts[$1] += $2;
+ total += $2;
+ } else
+ die("Invalid action");
+}
+
+END {
+ if (status)
+ exit status
+
+ if (action != "weighted")
+ exit
+
+ OFMT = "%.3f"
+ for (symbol in amounts) {
+ percent = amounts[symbol] / (total / 100)
+ weighted = (percent * er(symbol)) / 100
+ comment = sprintf("%.2f%% ER, %5.2f%% of funds valued at %.2f",
+ er(symbol), percent, amounts[symbol]);
+ print symbol, weighted, comment
+ }
+}