Skip to content

Instantly share code, notes, and snippets.

@alexchinco
Created December 29, 2016 14:34
Show Gist options
  • Save alexchinco/b515f8895860f3e5ee8971dc4086eb99 to your computer and use it in GitHub Desktop.
Save alexchinco/b515f8895860f3e5ee8971dc4086eb99 to your computer and use it in GitHub Desktop.
Estimate Beta via MAP and OLS
<!DOCTYPE html>
<meta charset="utf-8">
<style>
.olsLine {
stroke: red;
stroke-width: 5.0px;
stroke-dasharray: 5;
opacity: 0.75;
}
.mapLine {
stroke: blue;
stroke-width: 5.0px;
opacity: 0.75;
}
.track,
.track-inset,
.track-overlay {
stroke-linecap: round;
}
.track {
stroke: #000;
stroke-opacity: 0.3;
stroke-width: 5px;
}
.track-inset {
stroke: #ddd;
stroke-width: 5px;
}
.track-overlay {
pointer-events: stroke;
stroke-width: 10px;
cursor: pointer;
}
.handle {
fill: #fff;
stroke: #000;
stroke-opacity: 0.50;
fill-opacity: 0.95;
stroke-width: 1.5px;
}
</style>
<body>
<svg width="700" height="200"></svg>
<script type="text/javascript" src="http://latex.codecogs.com/latexit.js"></script>
<script type="text/javascript" src="https://d3js.org/d3.v4.min.js"></script>
<script>
// url for LaTeX compiler
var LATEX_URL = "http://latex.codecogs.com/svg.latex?";
// canvas setup
var svg = d3.select("svg");
var margin = {TOP: 10, RIGHT: 75, BOTTOM: 10, LEFT: 10};
var WIDTH = +svg.attr("width") - margin.LEFT - margin.RIGHT;
var HEIGHT = +svg.attr("height") - margin.TOP - margin.BOTTOM;
var canvas = svg.append("g")
.attr("id", "canvas")
.attr("transform", "translate(" + margin.LEFT + "," + margin.TOP + ")");
// sample realized returns
var SAMPLE_SIZE = 50;
var r = [-0.7487571658047313, -0.21286253060748025, 1.3497270944624424, 0.2690462526182047, -0.8958940322952502, 0.10136076799010091, 0.8715001265523143, 1.854441648120538, 1.026463890050679, -2.104305497970443, 0.2429970241165549, -0.46483943855054566, 1.1728949363723988, -0.7132645709749166, -0.6481891915606102, 0.11024777390782564, -1.552440887261149, -0.763572003122677, 1.2746230222343597, -1.8060546352047575, -0.4042706625258313, 2.9740562731385514, 1.6709559669460385, -1.4971054234635606, 2.055842873617507, -0.7834646083822411, -0.3774397354261526, 1.1719131508979972, 0.6771536915214518, -0.41572094091223816, 2.023988950462008, -0.686730226780964, -0.05026927007795473, 0.5702927306257386, 2.536226935317326, 0.7873177963632263, 0.46156819521999626, -0.4759979633310151, -0.8206598302495086, 0.5653248246382503, 0.1627880235944923, 0.37388032955017003, -0.04694146624225137, -0.8519704731565727, -1.7481402858995623, -0.1786204021291313, -1.296739288026139, -1.6733659859855168, 0.6632121599587789, 0.7688608815277582];
var x = [0.10796990245946711, 0.9792670292383457, 0.635803576043767, 0.1939996401141402, 0.8580519435675714, 0.2664547000295578, -1.1555252127510942, 1.0539655490936317, 0.06074391404559159, -0.2296503665963928, -0.6264904190417383, 0.27421741439208025, 0.5050224119535681, -1.7187163924430533, -0.7332560789388278, 2.2944244667594047, -0.8646138502965482, 1.1657337918507182, 1.0032812387452346, 0.49189849437843974, -0.0762395157071335, 0.48921759540847304, -0.09859194065519336, -1.7442023252071448, 1.91952402323896, 0.467602803858127, 0.17356973986359256, 1.5628194495604815, 0.884931624883003, -0.17621570213499244, 0.7049832273829615, -0.058017674668809166, -1.9327917712866014, -0.21765110981931796, 0.5761663959433387, 0.35110427357530716, 1.1963120370880898, 0.9678259327042897, 0.15305014517422943, 1.2232266819761208, 0.9024031894105585, -0.07252370910263634, 1.9725900776674, -0.6186492869709288, -0.8302823545908066, -0.3603020339466248, -0.16282714386897904, -0.5131627773266852, -1.3040796574310547, -0.8718932297761575];
var realizedReturns = [];
for (n=0; n < SAMPLE_SIZE; n++) {
realizedReturns.push({y:r[n], x:x[n]});
}
// define coordinate scales
var xCoord = d3.scaleLinear().domain([-2, 2]).range([0, WIDTH]);
var sCoord = d3.scaleLinear().domain([0, 2]).range([270, 475]).clamp(true);
var yCoord = d3.scaleLinear().domain([-1, 1]).range([HEIGHT, 0]);
// plot realized returns
canvas.append("g")
.selectAll(".dot").data(realizedReturns).enter()
.append("circle")
.attr("class", "dot")
.attr("stroke", "#000")
.attr("r", 4)
.attr("opacity", 0.25)
.attr("cx", function(d) { return xCoord(d.x); })
.attr("cy", function(d) { return yCoord(d.y); });
canvas.append("foreignObject")
.attr("id", "pointLab")
.attr("requiredFeatures", "http://www.w3.org/TR/SVG11/feature#Extensibility")
.append("xhtml")
.append("img")
.attr("width", 100)
.attr("src", LATEX_URL + encodeURI("(x_n, \\, r_n)"));
canvas.selectAll("#pointLab")
.attr("x", xCoord(-1.85))
.attr("y", yCoord(1.10));
// compute coefficient estimates
function estimateBeta(r, x, SIGMA){
var SUM_XR = 0;
var SUM_XX = 0;
for (var n = 0; n < r.length; n++) {
SUM_XR += (x[n]*r[n]);
SUM_XX += (x[n]*x[n]);
}
var OLS_BETA = SUM_XR/SUM_XX;
var MAP_BETA = ((SIGMA**2) * SUM_XR)/(1 + (SIGMA**2) * SUM_XX);
return [OLS_BETA, MAP_BETA];
}
var beta = estimateBeta(r, x, 0);
var olsLine = d3.range(100)
.map(function(d) {
return beta[0] * 4 * (d - 49)/100;
});
var mapLine = d3.range(100)
.map(function(d) {
return beta[1] * 4 * (d - 49)/100;
});
var line = d3.line()
.x(function(d,i) { return xCoord(4 * (i - 49)/100); })
.y(function(d,i) { return yCoord(d); });
canvas.append("path")
.attr("id", "olsLine")
.datum(olsLine)
.attr("class", "olsLine")
.attr("d", line);
canvas.append("foreignObject")
.attr("id", "olsLab")
.attr("requiredFeatures", "http://www.w3.org/TR/SVG11/feature#Extensibility")
.append("xhtml")
.append("img")
.attr("style", "vertical-align:middle")
.attr("width", 60)
.attr("src", LATEX_URL + encodeURI("\\color{red}" + "\\hat{\\beta}_{\\text{OLS}}"));
canvas.selectAll("#olsLab")
.attr("x", xCoord(2))
.attr("y", yCoord(olsLine[99]));
canvas.append("path")
.attr("id", "mapLine")
.datum(mapLine)
.attr("class", "mapLine")
.attr("d", line);
canvas.append("foreignObject")
.attr("id", "mapLab")
.attr("requiredFeatures", "http://www.w3.org/TR/SVG11/feature#Extensibility")
.append("xhtml")
.append("img")
.attr("width", 69)
.attr("src", LATEX_URL + encodeURI("\\color{blue}\\hat{\\beta}_{\\text{MAP}}"));
canvas.selectAll("#mapLab")
.attr("x", xCoord(2))
.attr("y", yCoord(mapLine[99]));
// create slider
var slider = svg.append("g")
.attr("class", "slider")
.attr("transform", "translate(" + 175 + "," + 175 + ")");
slider.append("line")
.attr("class", "track")
.attr("x1", sCoord(0))
.attr("x2", sCoord(2))
.select(function() {
return this.parentNode.appendChild(this.cloneNode(true));
})
.attr("class", "track-inset")
.select(function() {
return this.parentNode.appendChild(this.cloneNode(true));
})
.attr("class", "track-overlay")
.call(d3.drag()
.on("start.interrupt", function() {
slider.interrupt();
})
.on("start drag", function() {
update(sCoord.invert(d3.event.x));
})
);
slider.insert("g", ".track-overlay")
.attr("class", "ticks")
.attr("transform", "translate(0," + 20 + ")")
.selectAll("text")
.data(sCoord.ticks(6))
.enter()
.append("text")
.attr("x", sCoord)
.attr("text-anchor", "middle")
.attr("font-size", 20)
.attr("font-family", "serif")
.text(function(d) {
return d;
});
var handle = slider.insert("circle", ".track-overlay")
.attr("class", "handle")
.attr("r", 9)
.attr("cx", sCoord(0));
canvas.append("foreignObject")
.attr("id", "sliderLab")
.attr("requiredFeatures", "http://www.w3.org/TR/SVG11/feature#Extensibility")
.append("xhtml")
.append("img")
.attr("width", 60)
.attr("src", LATEX_URL + encodeURI("\\sigma = "));
canvas.selectAll("#sliderLab")
.attr("style", "horizontal-align:middle")
.attr("x", xCoord(0.30))
.attr("y", yCoord(-0.80));
// define update function
function update(SIGMA) {
beta = estimateBeta(r, x, SIGMA);
mapLine = d3.range(100)
.map(function(d) {
return beta[1] * 4 * (d - 49)/100;
});
canvas.selectAll("#mapLine")
.datum(mapLine)
.attr("d", line);
canvas.selectAll("#mapLab")
.datum([2, mapLine[99]])
.attr("x", function(d) { return xCoord(d[0]); })
.attr("y", function(d) { return yCoord(d[1]); });
handle.attr("cx", sCoord(SIGMA));
}
</script>
</body>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment