Published
Edited
Aug 12, 2018
1 fork
8 stars
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
loss_samples = drawSamples(sample_size)
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
function path_line_intersections(pathEl, pathLength, line) {
var n_segments = 100;
var pts = []
for (var i=0; i<n_segments; i++) {
var pos1 = pathEl.getPointAtLength(pathLength * i / n_segments);
var pos2 = pathEl.getPointAtLength(pathLength * (i+1) / n_segments);
var line1 = {x1: pos1.x, x2: pos2.x, y1: pos1.y, y2: pos2.y};
var line2 = {x1: line.attr('x1'), x2: line.attr('x2'),
y1: line.attr('y1'), y2: line.attr('y2')};
var pt = line_line_intersect(line1, line2);
if (typeof(pt) != "string") {
pts.push(pt);
}
}
return pts;

}
Insert cell
moveRuler = function() {
// const mouse_x = x.invert(d3.mouse(this)[0]);
const mouse_x = x.invert(+d3.event.x);
let mouse_y = 0.5;
if(typeof(this)!='undefined'){
mouse_y = y.invert(d3.mouse(this)[1]);
};
const Y = serieY;
const X = serieX;
const path = d3.select('path.line');
const pathEl = path.node();
const pathLength = pathEl.getTotalLength();
const ruler = d3.select('.ruler');
const ruler_ox = +ruler.attr('x1');
const vruler = d3.select('.vruler');
const hruler = d3.select('.hruler');
const marker = d3.select('.marker');
const xlabel = d3.select('.xlabel');
const xlabelbg = d3.select('.xlabel-bg');
const ylabel = d3.select('.ylabel');
const ylabelbg = d3.select('.ylabel-bg');
const check_x = (mouse_x >= serieXExtent[0]) && (mouse_x <= serieXExtent[1]);
const check_y = (mouse_y >= serieYExtent[0]) && (mouse_y <= serieYExtent[1]);
if (check_x && check_y){
// ruler.attr('x1', +d3.event.x).attr('x2', +d3.event.x);
try {
ruler.attr('x1', d3.mouse(this)[0]).attr('x2', d3.mouse(this)[0]);
} catch (err) {
console.log(err);
ruler.attr('x1', +d3.event.x).attr('x2', +d3.event.x);
}


const pts = path_line_intersections(pathEl, pathLength, ruler);
// console.log(pts);
if (pts.length>0){
marker.attr('cx', pts[0].x).attr('cy', pts[0].y);
hruler.attr('y1', pts[0].y).attr('y2', pts[0].y);
vruler.attr('x1', pts[0].x).attr('x2', pts[0].x);
ruler.attr('x1', pts[0].x).attr('x2', pts[0].x);
} else {
ruler.attr('x1', ruler_ox).attr('x2', ruler_ox);
}
const x_text = d3.format(',.1%')(x.invert(marker.attr('cx')));
const y_text = d3.format(',.1%')(y.invert(marker.attr('cy')));
xlabel.attr('x', +marker.attr('cx')).text(x_text);
xlabelbg.attr('x', +marker.attr('cx')-labelsize[0]/2);
ylabel.attr('y', +marker.attr('cy')+labelsize[1]/5).text(y_text);
ylabelbg.attr('y', +marker.attr('cy')-labelsize[1]/2);
marker.style('opacity',1);
hruler.style('opacity',1);
vruler.style('opacity',1);
ruler.style('opacity',1);
xlabel.style('opacity',1);
xlabelbg.style('opacity',1);
ylabel.style('opacity',1);
ylabelbg.style('opacity',1);
} else {
marker.style('opacity',0);
hruler.style('opacity',0);
vruler.style('opacity',0);
ruler.style('opacity',0);
xlabel.style('opacity',0);
xlabelbg.style('opacity',0);
ylabel.style('opacity',0);
ylabelbg.style('opacity',0);
}
}
Insert cell
Insert cell
Insert cell
function moveHandle(d) {
moveRuler();
const drag_item = d3.select(this);
const drag_id = +drag_item.attr('data-handle');
const drag_x = +(d3.event.x);
const handle = d3.selectAll(`.handle-${drag_id}`)
const drag_line = d3.selectAll(`.drag-line-${drag_id}`)
const drag_overlay = d3.selectAll(`.drag-overlay-${drag_id}`)
const layer = d3.selectAll(`#layer-below-${drag_id} rect`);
const next_layer = d3.selectAll(`#layer-below-${(parseInt(drag_id)+1)} rect`);
// const previous_layer = d3.selectAll(`#layer-below-${(parseInt(drag_id)-1)} rect`);
const label = d3.selectAll(`.label-${drag_id}`);
const next_label = d3.selectAll(`.label-${(parseInt(drag_id)+1)}`);
const handle_starting_position = +handle.attr('cx');
const layer_starting_width = +layer.attr('width');
const layer_starting_position = +layer.attr('x');
const nextlayer_starting_width = +next_layer.attr('width');
const nextlayer_starting_position = +next_layer.attr('x');
const layer_new_width = drag_x - layer_starting_position;
const next_layer_new_width = handle_starting_position - drag_x + nextlayer_starting_width;
const animation_duration = 400
// console.log('tranches', tranches, drag_id);
tranches[drag_id] = [x.invert(drag_x-layer_new_width),x.invert(drag_x)];
tranches[drag_id+1] = [x.invert(drag_x), x.invert(drag_x+next_layer_new_width)];
// .transition().duration(animation_duration).ease(d3.easeCircleOut)
if ((layer_new_width>10) && (next_layer_new_width>10)) {
layer.attr('width', drag_x - layer_starting_position);
next_layer.attr('width', next_layer_new_width);
next_layer.attr('x', drag_x);
drag_overlay.attr('x', drag_x-drag_overlay_width/2);
label.attr('x', drag_x - layer_starting_width/2);
next_label.attr('x', drag_x + nextlayer_starting_width/2);
handle.attr('cx', drag_x);
drag_line.attr('x', drag_x-drag_line_width/2);
const tranching = calculateReturns(tranches);
displayTranching(tranching);
};
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
drawSamples(1000)
Insert cell
Insert cell
serieY
Insert cell
((serieY[10]<0.7575412433665638)&&(0.7575412433665638<=serieY[10+1]))==true
Insert cell
(0.7575412433665638<=serieY[10+1])
Insert cell
function drawSamples(size) {
const sim = Array.from({length: size}, () => Math.random(10));
let loss_samples = [];
// serieY, serieX
const Y = serieY;
const X = serieX;
// console.log(Y);
// console.log(X);
loop1: for (const i in sim) {
if (sim[i]<=Y[0]) {
loss_samples.push(X[0])
} else if(sim[i]>=Y[Y.length-1]){
loss_samples.push(X[X.length-1])
} else {
loop2: for (const j in Y) {
if (j<Y.length) {
if (((Y[j]<sim[i]) && (sim[i]<=Y[parseInt(j)+1]))) {
const a = (Y[parseInt(j)+1]-Y[j])/(X[parseInt(j)+1]-X[j]);
const b = Y[j]-a*X[j];
const Y_interpolated = (sim[i]-b)/a;
loss_samples.push(Y_interpolated);
break loop2;
};
};
};
};
};
// console.log(sim);
// console.log(loss_samples);
return loss_samples
}
Insert cell
function calculateReturns(tranches) {
// calculate for each tranche
let exp_loss = [];
let exp_loss_mean = [];
let returns = [];
let adjusted_returns = [];
let expected_losses = [];
let standard_deviation = [];
let sharpe_ratios = [];
const A = pricing[0];
const B = pricing[1];
const C = pricing[2];
for (const i in tranches) {
exp_loss.push([]);
const attach = tranches[i][0];
const exhaust = tranches[i][1];
const diff = exhaust-attach;
for (const j in loss_samples){
let loss_draw = Math.max(0, loss_samples[j]-attach);
loss_draw = Math.min(loss_draw, diff);
exp_loss[i].push(loss_draw);
};
const EL = average(exp_loss[i])/diff;
const R = EL*(A + B*Math.pow(EL*100, C));
exp_loss_mean.push(average(exp_loss[i]));
returns.push(R);
expected_losses.push(EL);
adjusted_returns.push(R-EL);
standard_deviation.push(standardDeviation(exp_loss[i])/diff);
sharpe_ratios.push(standard_deviation[i]/adjusted_returns[i])
};
const tranching = {
'returns': returns.map(d=>+(d*100).toFixed(2)),
'expected_loss': expected_losses,
'exp_loss_mean': exp_loss_mean,
'adjusted_returns': adjusted_returns.map(d=>+(d*100).toFixed(2)),
'standard_deviation': standard_deviation.map(d=>+(d*100).toFixed(2)),
'sharpe_ratios': sharpe_ratios.map(d=>+(d*100).toFixed(2)),
'collateral_ratio': tranches.map(d=>+((d[1]-d[0])*100).toFixed(2)),
'collateral_dollar': tranches.map(d=>+((d[1]-d[0])*premium).toFixed(0)),
}
console.log(tranching);
// console.log(tranching);
return tranching
}
Insert cell
calculateReturns(tranches)
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more