Introduction
In this article I am going to write about how HTML 5 Canvas and JavaScript could be used to draw a chart of the profit and loss profile of an option trading strategy as a function of the equity price.
Background
As a developer who also has an interest in the theory of and practice in trading security assets using financial leverages such as options I have a need to calculate the profit and loss profile of a trade before placing it. For those who are not familiar with options, one of the many references could be found at http://www.investopedia.com/university/options/option.asp to begin with, otherwise I assume you are already an expert of this domain and already making and losing money doing this. Some of you may be so good at this that you might be able to have all the numbers of potential gain and loss in your head when you enter a trade but for me I find that having a chart of profit/loss versus price of a stock/equity is to look at is important. A picture is worth a thousand words is true as always. There are so many different option trading strategies from simple with one leg to complex with multiple legs. For the purpose of this article I am going simplify by drawing the chart of profit and loss versus price of an equity by doing a trade with buying a call. The charting for complex strategies would use the same techniques. Using HTML 5 canvas and its drawing capabilities along with JavaScript I will build an equation and draw the profit/loss chart with X and Y axes as we all remember from high school.
So let’s say we want to buy 1 contract (100 shares) of the CALL option of the American SP 500 ETF index codenamed SPX. As of the time of this writing, 5/17/2016 at end of trading day, the price of SPX is 2047, the call option price for the June 17, 2016 at strike price 2110 is priced approximately at $5.5 per contract. So what does the chart of profit/loss of this trade look like when the contract expires on June 17? For a preview, it would look like the chart below:
From the chart above the maximum loss is capped at $550, the breakeven price is at 2115, the profit is unlimited to the upside once the price passes the breakeven price. You would be very rich if somehow you think the SP 500 will explode to the upside a few hundred points within the next month using this strategy!
Using The Code
OK now comes the technical discussion on how a chart like above can be drawn using HTML 5 canvas and JavaScript. The steps are as below:
- Define HTML 5 drawing surface.
- Define a JavaScript object with necessary parameters to describe the chart.
- Define a method for the above object to draw the X (Stock Price) axis.
- Define a method for the above object to draw the Y (Profit/Loss) axis.
- Define a method for the above object to draw an equation representing the Buy a Call Option strategy.
- Define a method to transform the chart to fit the drawing surface.
- Use the object with targeted parameters and call its methods to draw the chart.
Step 1:
HTML 5 canvas is used to define the drawing surface in this code snippet:
<!DOCTYPE HTML>
<html>
<head>
<style>
body {
margin: 0px;
padding: 0px;
}
</style>
</head>
<body>
<canvas id="canvasProfitLoss" width="1200" height="600" style="border:1px solid #000000;"></canvas>
<script>
</script>
</body>
</html>
Step 2:
A graph for an equation needs to have certain parameters to define the range of the X and Y axis, the units for X and Y axis, etc.
Below is the code snippet for the JavaScript chart object to be insert between the <script></script> tag in step 1:
function ProfitLossChart(minPrice, minProfitLoss, maxPrice, maxProfitLoss, unitsPrice, unitsProfitLoss) {
this.canvas = document.getElementById("canvasProfitLoss");
this.minPrice = minPrice;
this.minProfitLoss = minProfitLoss;
this.maxPrice = maxPrice;
this.maxProfitLoss = maxProfitLoss;
this.unitsPrice = unitsPrice;
this.unitsProfitLoss = unitsProfitLoss;
this.tickSize = 20;
this.context = this.canvas.getContext('2d');
this.rangePrice = this.maxPrice - this.minPrice;
this.rangeProfitLoss = this.maxProfitLoss - this.minProfitLoss;
this.unitPrice = this.canvas.width / this.rangePrice;
this.unitProfitLoss = this.canvas.height / (this.rangeProfitLoss);
this.centerProfitLoss = Math.round(Math.abs(this.minProfitLoss / this.rangeProfitLoss) * this.canvas.height) ;
this.centerPrice = + Math.round(Math.abs(this.minPrice / this.rangePrice) * this.canvas.width);
this.iteration = (this.maxPrice - this.minPrice) / 1000;
this.scalePrice = this.canvas.width / this.rangePrice;
this.scaleProfitLoss = this.canvas.height / this.rangeProfitLoss;
};
Step 3:
To draw the X (Price) axis use JavaScript prototype to give the object the functionality. We draw the tick marks, the unit label, the axis label also.
ProfitLossChart.prototype.drawPriceAxis= function () {
var context = this.context;
context.save();
context.beginPath();
context.moveTo(10, this.centerProfitLoss);
context.lineTo(this.canvas.width, this.centerProfitLoss);
context.strokeStyle = this.axisColor;
context.lineWidth = 2;
context.stroke();
var pricePosIncrement = this.unitsPrice * this.unitPrice;
var pricePos, unit;
context.font = this.font;
context.textAlign = 'center';
context.textBaseline = 'top';
pricePos = pricePosIncrement;
unit = this.unitsPrice ;
while (pricePos < this.canvas.width) {
context.moveTo(pricePos , this.centerProfitLoss - this.tickSize / 2);
context.lineTo(pricePos , this.centerProfitLoss + this.tickSize / 2);
context.stroke();
context.fillText(unit + this.minPrice, pricePos, this.centerProfitLoss + this.tickSize / 2 - 30);
unit += this.unitsPrice;
pricePos = Math.round(pricePos + pricePosIncrement);
}
context.font = "12px";
context.fillStyle = "green";
context.fillText("Price($)", this.canvas.width / 2, this.centerProfitLoss + this.tickSize / 2 -50);
context.restore();
};
Step 4:
Same concept and technique as step 3, create an object’s method to draw the Y (Profit/Loss) axis with tickmarks and labels:
ProfitLossChart.prototype.drawProfitLossAxis = function () {
var context = this.context;
context.save();
context.beginPath();
context.moveTo( 20, 0)
context.lineTo( 20, this.canvas.height);
context.strokeStyle = this.axisColor;
context.lineWidth = 2;
context.stroke();
var profitLossPosIncrement = this.unitsProfitLoss * this.unitProfitLoss;
var profitLossPos, unit;
context.font = this.font;
context.textAlign = 'right';
context.textBaseline = 'middle';
profitLossPos = this.centerProfitLoss - profitLossPosIncrement;
unit = this.unitsProfitLoss;
while (profitLossPos > 0) {
context.moveTo(20 - this.tickSize / 2, profitLossPos);
context.lineTo(20 + this.tickSize / 2, profitLossPos);
context.stroke();
context.fillText(unit, 70 - this.tickSize / 2 - 3 , profitLossPos);
unit += this.unitsProfitLoss;
profitLossPos = Math.round(profitLossPos - profitLossPosIncrement);
}
profitLossPos = this.centerProfitLoss + profitLossPosIncrement;
unit = -1 * this.unitsProfitLoss;
while (profitLossPos < this.canvas.height) {
context.moveTo(20- this.tickSize / 2, profitLossPos);
context.lineTo(20 + this.tickSize / 2, profitLossPos);
context.stroke();
context.fillText(unit, 70 - this.tickSize / 2 - 3, profitLossPos);
unit -= this.unitsProfitLoss;
profitLossPos = Math.round(profitLossPos + profitLossPosIncrement);
}
context.font = "12px";
context.fillStyle = "green";
context.fillText("Profit/Loss($)", this.centerPrice + 140, this.canvas.height / 4);
context.restore();
};
Step 5:
Drawing the profit/loss equation involves drawing a series of small lines over a defined iteration and “connect” them together to form a complete chart. The exact equation for the desired strategy is passed as an anonymous function from the user of the object. In our case, it is the “Buy Call Option” equation, for another strategy the corresponding equation is passed in. The code snippet is as below:
ProfitLossChart.prototype.drawEquation = function (drawFunction) {
var context = this.context;
context.save();
this.transformContext();
context.beginPath();
context.moveTo(this.minPrice, drawFunction(this.minPrice));
for (var x = this.minPrice + this.iteration; x <= this.maxPrice; x += this.iteration) {
context.lineTo(x, drawFunction(x));
}
context.restore();
context.lineJoin = 'round';
context.lineWidth = 3;
context.strokeStyle = 'red';
context.stroke();
context.restore();
};
Step 6:
ProfitLossChart.prototype.transformContext = function () {
var context = this.context;
this.context.translate(this.centerPrice, this.centerProfitLoss);
context.scale(this.scalePrice , -this.scaleProfitLoss);
};
That’s it. We have defined all properties and methods of the object necessary to draw the chart. Let’s take our case of buying the call option on the SPX index mentioned earlier and draw it:
Step 7:
var minPrice = 0;
var maxPrice = 2200;
var minPL = -10000;
var maxPL = 10000;
var unitsPrice = 50;
var unitsProfitLoss = 500;
var chart = new ProfitLossChart(minPrice, minPL, maxPrice, maxPL, unitsPrice, unitsProfitLoss);
chart.drawPriceAxis();
chart.drawProfitLossAxis();
var pStrike = 2110;
var pCall = 5.5;
chart.drawEquation(function (x) {
if (x > pStrike)
{
return 100 * (x - pStrike - pCall);
}
else
{
return -(100 * pCall);
}
});
Points of Interest
This article just simply illustrates some of the basics of HTML5 canvas features to draw charts and graphs as applied to the financial options world. Certainly other more advanced features could be developed and added such as resizing, interactive charting, moving the mouse cursor above the chart should give the X, Y coordinate at that point, etc.
There are 1 or 2 websites out there that provide free options charting for many other complex strategies with more practical features such as getting real time option data. I have managed to also to develop my own site www.optionschart101.com for this purpose. At the current stage, the site provides drawing for strategies such as iron condor, butterfly, straddle, and others. The site is a work in progress, I will hope to make money from it one day providing other premium services but it is free for now and for a while, and therefore it is likely not free of errors yet.