Example: Web-Based Bond Pricing Tool Using JavaScript
This example shows how to create a web application that calculates the price of a bond from a simple formula. It uses the MATLAB®
Production Server™ RESTful API and JSON Representation of MATLAB Data Types to depict an end-to-end workflow of using MATLAB
Production Server. You run this example by entering the following known values into a web interface:
The application calculates price (P
) based on the following equation:
P = C * ( (1 - (1 + i)^-N) / i ) + M * (1 + i)^-N
You can use the sliders in the web application to price different bonds.Step 1: Write MATLAB Code
Write the following code in MATLAB to price bonds. Save the code using the filename pricecalc.m
.
Step 2: Create a Deployable Archive with the Production Server Compiler App
To create the deployable archive for this example:
On the Apps tab, select the Production Server Compiler App.
In the Application Type list, select Deployable Archive.
In the Exported Functions field, add pricecalc.m
.
Under Archive information, change pricecalc
to BondTools
.
Click Package.
The generated deployable archive, BondTools.ctf
is located in the for_redistribution
folder of the project.
Step 3: Place the Deployable Archive on a Server
Step 4: Enable Cross-Origin Resource Sharing (CORS) on the Server
Enable Cross-Origin Resource Sharing (CORS) by editing the server configuration file, main_config
and specifying the list of domains origins from which requests can be made to the server. For example, setting the cors-allowed-origins
option to --cors-allowed-origins *
allows requests from any domain to access the server. See cors-allowed-origins
and Edit the Configuration File for details.
Step 5: Write JavaScript Code using the RESTful API and JSON
Using the RESTful API and JSON Representation of MATLAB Data Types as a guide, write the following JavaScript® code. Save this code as a JavaScript file named calculatePrice.js
.
Code:
calculatePrice.js
//calculatePrice.js : JavaScript code to calculate the price of a bond.
function calculatePrice()
{
var cp = parseFloat(document.getElementById('coupon_payment_value').value);
var np = parseFloat(document.getElementById('num_payments_value').value);
var ir = parseFloat(document.getElementById('interest_rate_value').value);
var vm = parseFloat(document.getElementById('facevalue_value').value);
// A new XMLHttpRequest object
var request = new XMLHttpRequest();
//Use MPS RESTful API to specify URL
var url = "http://localhost:9910/BondTools/pricecalc";
//Use MPS RESTful API to specify params using JSON
var params = { "nargout":1,
"rhs": [vm, cp, ir, np] };
document.getElementById("request").innerHTML = "URL: " + url + "<br>"
+ "Method: POST <br>" + "Data:" + JSON.stringify(params);
request.open("POST", url);
//Use MPS RESTful API to set Content-Type
request.setRequestHeader("Content-Type", "application/json");
request.onload = function()
{ //Use MPS RESTful API to check HTTP Status
if (request.status == 200)
{
// Deserialization: Converting text back into JSON object
// Response from server is deserialized
var result = JSON.parse(request.responseText);
//Use MPS RESTful API to retrieve response in "lhs"
if('lhs' in result)
{ document.getElementById("error").innerHTML = "" ;
document.getElementById("price_of_bond_value").innerHTML = "Bond Price: " + result.lhs[0].mwdata; }
else { document.getElementById("error").innerHTML = "Error: " + result.error.message; }
}
else { document.getElementById("error").innerHTML = "Error:" + request.statusText; }
document.getElementById("response").innerHTML = "Status: " + request.status + "<br>"
+ "Status message: " + request.statusText + "<br>" +
"Response text: " + request.responseText;
}
//Serialization: Converting JSON object to text prior to sending request
request.send(JSON.stringify(params));
}
//Get value from slider element of "document" using its ID and update the value field
//The "document" interface represent any web page loaded in the browser and
//serves as an entry point into the web page's content.
function printValue(sliderID, valueID) {
var x = document.getElementById(valueID);
var y = document.getElementById(sliderID);
x.value = y.value;
}
//Execute JavaScript and calculate price of bond when slider is moved
function updatePrice(sliderID, valueID) {
printValue(sliderID, valueID);
calculatePrice();
}
Step 6: Embed JavaScript within HTML Code
Embed the JavaScript from the previous step within the following HTML code by using the following syntax:
<script src="calculatePrice.js" type="text/javascript"></script>
Save this code as an HTML file named bptool.html
.
Code:
bptool.html
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head lang="en">
<meta charset="UTF-8">
<title>Bond Pricing Tool</title>
</head>
<body>
<!-- Embed the JavaScript code here by referencing calculatePrice.js -->
<!-- <script src="calculatePrice.js" type="text/javascript"></script> -->
<script>
//Helper Code: Execute JavaScript immediately after the page has been loaded
window.onload = function() {
printValue('coupon_payment_slider', 'coupon_payment_value');
printValue('num_payments_slider', 'num_payments_value');
printValue('interest_rate_slider', 'interest_rate_value');
printValue('facevalue_slider', 'facevalue_value');
calculatePrice();
}
</script>
<h1><a>Bond Pricing Tool</a></h1>
<h2></h2>
This example shows an application that calculates a bond price from a simple formula.<p>
You run this example by entering the following known values into a simple graphical interface:<p>
<ul>
<li>Face Value (or value of bond at maturity) - M</li>
<li>Coupon payment - C</li>
<li>Number of payments - N</li>
<li>Interest rate - i</li>
</ul>
The application calculates price (P) based on the following equation:<p>
P = C * ( (1 - (1 + i)^-N) / i ) + M * (1 + i)^-N<p>
<hr>
<h3>M: Face Value </h3>
<input id="facevalue_value" type="number" maxlength="4" oninput="updatePrice('facevalue_value', 'facevalue_slider')"/>
<input type="range" id="facevalue_slider" value="0" min="0" max="10000" onchange="updatePrice('facevalue_slider', 'facevalue_value')"/>
<h3>C: Coupon Payment </h3>
<input id="coupon_payment_value" type="number" maxlength="4" oninput="updatePrice('coupon_payment_value', 'coupon_payment_slider')" />
<input type="range" id="coupon_payment_slider" value="0" min="0" max="1000" onchange="updatePrice('coupon_payment_slider', 'coupon_payment_value')"/>
<h3>N: Number of payments </h3>
<input id="num_payments_value" type="number" maxlength="4" oninput="updatePrice('num_payments_value', 'num_payments_slider')"/>
<input type="range" id="num_payments_slider" value="0" min="0" max="1000" onchange="updatePrice('num_payments_slider', 'num_payments_value')"/>
<h3>i: Interest rate </h3>
<input id="interest_rate_value" type="number" maxlength="4" step="0.01" oninput="updatePrice('interest_rate_value', 'interest_rate_slider')"/>
<input type="range" id="interest_rate_slider" value="0" min="0" max="1" step="0.01" onchange="updatePrice('interest_rate_slider', 'interest_rate_value')"/>
<h2>BOND PRICE</h2>
<p id="price_of_bond_value" style="font-weight: bold">
<p id="error" style="color:red">
<hr>
<h3>Request to MPS Server</h3>
<p id="request">
<h3>Response from MPS Server</h3>
<p id="response">
<hr>
</body>
</html>
Step 7: Run Example
Assuming, the server with the deployed MATLAB function is up and running, open the HTML file bptool.html
in a web browser. The default bond price is NaN
because no values have been entered as yet. Try the following values to price a bond:
The resulting bond price is $1079.85
You can use the sliders in the tool price different bonds. Varying the interest rate results in the most dramatic change in the price of the bond.