Last active
August 29, 2015 14:19
-
-
Save kent37/c67f0fd4d104034acb13 to your computer and use it in GitHub Desktop.
Expense ratio vs yield
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Symbol | Name | ExpenseRatio | Y1 | Y3 | Y5 | Y10 | |
|---|---|---|---|---|---|---|---|
| VASGX | Vanguard LifeStrategy Growth Fund | 0.17 | 7.8 | 11.36 | 10.34 | 6.63 | |
| VSMGX | Vanguard LifeStrategy Moderate Growth Fund | 0.16 | 7.47 | 9.38 | 9.01 | 6.31 | |
| VMMXX | Vanguard Prime Money Market Fund | 0.16 | 0.01 | 0.02 | 0.03 | 1.58 | |
| VPMCX | Vanguard PRIMECAP Fund Investor Shares | 0.44 | 15.58 | 21 | 15.91 | 10.78 | |
| VGSLX | Vanguard REIT Index Fund Admiral Shares | 0.1 | 24.09 | 14.11 | 15.84 | 9.87 | |
| VTTVX | Vanguard Target Retirement 2025 Fund | 0.17 | 7.65 | 10.35 | 9.78 | 6.58 | |
| VBTLX | Vanguard Total Bond Market Index Fund Admiral Shares | 0.08 | 5.62 | 3.04 | 4.35 | 4.9 | |
| VTIAX | Vanguard Total International Stock Index Fund Admiral Shares | 0.14 | -1.05 | 6.62 | NA | NA | |
| VTSAX | Vanguard Total Stock Market Index Fund Admiral Shares | 0.05 | 12.3 | 16.39 | 14.76 | 8.55 | |
| VWENX | Vanguard Wellington Fund Admiral Shares | 0.18 | 8.27 | 11.61 | 10.72 | 8.22 | |
| BAICX | BlackRock Multi-Asset Income Portfolio Investor A Shares | 0.99 | -1.15 | 5.85 | 7.22 | NA | |
| CMNIX | Calamos Market Neutral Income Fund Institutional Class | 0.97 | 2.28 | 3.65 | 4.26 | 3.85 | |
| EIFAX | Eaton Vance Floating-Rate Advantage Fund Class I | 1.02 | 2.6 | 5.11 | 5.93 | NA | |
| SGIIX | First Eagle Global Fund Class I | 0.83 | 2.61 | 8.25 | 9.28 | 9 | |
| FRIAX | Franklin Income Series Class Advisor | 0.46 | 0.9 | 9.16 | 9.05 | 6.91 | |
| FMISX | Franklin Massachusetts Tax-Free Income Fund Class A | 0.66 | 3.46 | 2.23 | 3.57 | 3.67 | |
| NEZYX | Loomis Sayles Strategic Income Fund Class Y | 0.69 | 2.05 | 7.66 | 8.39 | 7.92 | |
| FLAAX | Nuveen All-American Municipal Bond Fund Class A | 0.72 | 4.81 | 4.03 | 5.91 | 4.96 | |
| TGBAX | Templeton Global Bond Fund Advisor Class | 0.66 | 1.29 | 4.24 | 4.74 | 7.88 | |
| LTMIX | Thornburg Limited Term Municipal Fund Class I | 0.4 | 2.74 | 2.2 | 3.34 | 3.78 | |
| EMGYX | Wells Fargo Advantage Emerging Markets Equity Fund Administrator Class | 1.49 | -3.67 | -1.62 | 1.43 | 10.09 | |
| VWO | VANGUARD FTSE EMERGING MARKETS ETF | 0.15 | 3.35 | 0.6 | 1.79 | 8.17 | |
| VHT | VANGUARD HEALTH CARE ETF | 0.12 | 27.88 | 27.67 | 20.75 | 12.15 | |
| VYM | VANGUARD HIGH DIVIDEND YIELD ETF | 0.1 | 11.04 | 15.48 | 14.89 | NA | |
| VOO | VANGUARD S&P 500 INDEX ETF NEW | 0.05 | 12.71 | 16.08 | NA | NA | |
| VOX | VANGUARD TELECOM SERVICES ETF | 0.12 | 4.4 | 13.69 | 12.56 | 8.42 | |
| VTI | VANGUARD TOTAL STOCK MARKET ETF | 0.05 | 12.34 | 16.4 | 14.76 | 8.57 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <!DOCTYPE html> | |
| <html lang="en"> | |
| <head> | |
| <meta charset="utf-8"> | |
| <title>Expense Ratio vs Yield</title> | |
| <script type="text/javascript" src="http://d3js.org/d3.v3.js"></script> | |
| <style type="text/css"> | |
| body { | |
| background-color: white; | |
| font-family: Helvetica, Arial, sans-serif; | |
| } | |
| h1 { | |
| font-size: 24px; | |
| margin: 0; | |
| } | |
| p { | |
| font-size: 14px; | |
| margin: 10px 0 0 0; | |
| } | |
| button { | |
| background-color: orange; | |
| } | |
| svg { | |
| background-color: white; | |
| } | |
| circle:hover { | |
| fill: orange; | |
| } | |
| .axis path, | |
| .axis line { | |
| fill: none; | |
| stroke: black; | |
| shape-rendering: crispEdges; | |
| } | |
| .axis text { | |
| font-family: sans-serif; | |
| font-size: 11px; | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <h1>Expense Ratio vs Yield</h1> | |
| <p>Expense Ratio vs Yield for a selection of mutual funds and ETFs.</p> | |
| <p id='legend'>Showing one-year yield.</p> | |
| <script type="text/javascript"> | |
| var w = 700; | |
| var h = 600; | |
| var padding = [ 20, 10, 50, 50 ]; //Top, right, bottom, left | |
| var xScale = d3.scale.linear() | |
| .range([ padding[3], w - padding[1] - padding[3] ]); | |
| var yScale = d3.scale.linear() | |
| .range([ padding[0], h - padding[2] ]); | |
| var colorScale = d3.scale.category10(); | |
| var xAxis = d3.svg.axis() | |
| .scale(xScale) | |
| .orient("bottom"); | |
| var yAxis = d3.svg.axis() | |
| .scale(yScale) | |
| .orient("left"); | |
| var svg = d3.select("body") | |
| .append("svg") | |
| .attr("width", w) | |
| .attr("height", h); | |
| d3.csv("ExpenseVsYield.csv", function(data) { | |
| xScale.domain([ | |
| d3.min(data, function(d) { | |
| return +d.ExpenseRatio; | |
| }), | |
| d3.max(data, function(d) { | |
| return +d.ExpenseRatio; | |
| }) | |
| ]); | |
| // The domain of yScale has to be the max of all the yields | |
| yScale.domain([ | |
| d3.max(data, function(d) { | |
| return d3.max([+d.Y1, +d.Y3, +d.Y5, +d.Y10]); | |
| }), | |
| d3.min(data, function(d) { | |
| return d3.min([+d.Y1, +d.Y3, +d.Y5, +d.Y10]); | |
| }) | |
| ]); | |
| colorScale.domain([0, data.length-1]); | |
| // Make a group for each stock | |
| var groups = svg.selectAll("g") | |
| .data(data) | |
| .enter() | |
| .append("g"); | |
| // A function to create a translation string for a stock | |
| var translation = function(d, year) { | |
| return "translate(" + xScale(d.ExpenseRatio) + "," + yScale(d[year]) + ")"; | |
| } | |
| // A function to format title text | |
| var titleText = function(d, year, text) | |
| { | |
| return d.Name + "'s expense ratio is " + d.ExpenseRatio + ", and " + text + " yield is " + d[year] + ""; | |
| } | |
| // Locate the group | |
| groups.attr("transform", function(d) { return translation(d, 'Y1');}) | |
| .append("title") | |
| .text(function(d) { return titleText(d, 'Y1', 'one-year'); }); | |
| // Add a circle and a text legend for each group | |
| groups.append('circle') | |
| .attr("cx", 0) | |
| .attr("cy", 0) | |
| .attr("r", 5) | |
| .attr("fill", function(d, i) { return colorScale(i%10); }); | |
| groups.append('text') | |
| .attr({ | |
| x: 8, | |
| y: 4, | |
| class: 'label', | |
| 'font-size': '10px', | |
| fill: function(d, i) { return colorScale(i%10); } | |
| }) | |
| .text(function (d) { | |
| return d.Symbol; | |
| }); | |
| // Add the axes | |
| svg.append("g") | |
| .attr("class", "x axis") | |
| .attr("transform", "translate(0," + (h - padding[2] + 10) + ")") | |
| .call(xAxis); | |
| svg.append("g") | |
| .attr("class", "y axis") | |
| .attr("transform", "translate(" + (padding[3] - 10) + ",0)") | |
| .call(yAxis); | |
| // Add event handlers for the controls | |
| // This is the function that will be called | |
| yield = function(year, text) | |
| { | |
| // Reset text label positions | |
| svg.selectAll('.label').attr({x: 8, y: 4}); | |
| groups.select('title') | |
| .text(function(d) { return titleText(d, year, text); }); | |
| groups.transition(1500) | |
| .attr("transform", function(d) { return translation(d, year);}) | |
| .attr('visibility', function(d) { return d[year]=='NA' ? 'hidden' : 'visible';}) | |
| .each('end', arrangeLabels(year)); | |
| d3.select('p#legend') | |
| .transition(750).style('color', 'white') | |
| .transition(750).style('color', 'black') | |
| .text('Showing ' + text + ' yield.'); | |
| } | |
| d3.select('button#y1').on('click', function () { yield('Y1', 'one-year'); }); | |
| d3.select('button#y3').on('click', function () { yield('Y3', 'three-year'); }); | |
| d3.select('button#y5').on('click', function () { yield('Y5', 'five-year'); }); | |
| d3.select('button#y10').on('click', function () { yield('Y10', 'ten-year'); }); | |
| // Set the initial positions | |
| arrangeLabels('Y1'); | |
| }); | |
| // Test for intersection of two rectangles | |
| var intersectRect = function(r1, r2) { | |
| return !(r2.left > r1.right || | |
| r2.right < r1.left || | |
| r2.top > r1.bottom || | |
| r2.bottom < r1.top); | |
| }; | |
| // Arrange the labels so they don't overlap | |
| // From http://bl.ocks.org/larskotthoff/11406992 | |
| // and https://blog.safaribooksonline.com/2014/03/11/solving-d3-label-placement-constraint-relaxing/ | |
| function arrangeLabels(year) { | |
| var alpha = 0.5; | |
| // First reset them all | |
| var textLabels = svg.selectAll('.label'); | |
| //textLabels.attr({x: 8, y: 4}); | |
| var again = false; | |
| textLabels.each(function() { | |
| if (this.__data__[year] == 'NaN') return; | |
| var that = this, thatRect = this.getBoundingClientRect(); | |
| textLabels.each(function() { | |
| if (this == that || this.__data__[year]=='NaN') return; | |
| var thisRect = this.getBoundingClientRect(); | |
| if (!intersectRect(thisRect, thatRect)) return; | |
| var deltaY = thatRect.top - thisRect.top; | |
| // If the labels collide, we'll push each | |
| // of the two labels up and down a little bit. | |
| again = true; | |
| var sign = deltaY > 0 ? 1 : -1; | |
| var adjust = sign * alpha; | |
| var dthat = d3.select(that); | |
| dthat.attr("y", +dthat.attr('y') + adjust); | |
| var dthis = d3.select(this); | |
| dthis.attr("y", +dthis.attr('y') - adjust); | |
| }); | |
| }); | |
| if(again) { | |
| setTimeout(function() { arrangeLabels(year); },20); | |
| } | |
| } | |
| </script> | |
| <p>Click the buttons to change the displayed yield.</p> | |
| <button class='click' id='y1'>1-Year</button> <button class='click' id='y3'>3-Year</button> | |
| <button class='click' id='y5'>5-Year</button> <button class='click' id='y10'>10-Year</button> | |
| </body> | |
| </html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment