Click here to Skip to main content
15,887,676 members
Articles / Web Development / HTML5

Charting Profit/Loss of Financial Options Using HTML 5 Canvas and JavaScript

Rate me:
Please Sign up or sign in to vote.
3.63/5 (6 votes)
18 May 2016CPOL5 min read 16.3K   6   3
Charting Profit/Loss of Financial Options Using HTML 5 Canvas and JavaScript

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:

Image 1

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:

  1. Define HTML 5 drawing surface.
  2. Define a JavaScript object with necessary parameters to describe the chart.
  3. Define a method for the above object to draw the X (Stock Price) axis.
  4. Define a method for the above object to draw the Y (Profit/Loss) axis.
  5. Define a method for the above object to draw an equation representing the Buy a Call Option strategy.
  6. Define a method to transform the chart to fit the drawing surface.
  7. 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:

C++
<!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:
C++
//object definition
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.
C++
// using prototype and create function
    ProfitLossChart.prototype.drawPriceAxis= function () {
        var context = this.context;
        context.save();
        context.beginPath();

        //start x 10 pix to the left edge, y is at the center
        context.moveTo(10, this.centerProfitLoss);
        //draw horizontal line, Price axis
        context.lineTo(this.canvas.width, this.centerProfitLoss);

        context.strokeStyle = this.axisColor;
        context.lineWidth = 2;
        context.stroke();

        // draw right tick marks
        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) {
            //draw tick marks as line crossing the Price axis
            context.moveTo(pricePos , this.centerProfitLoss - this.tickSize / 2);
            context.lineTo(pricePos , this.centerProfitLoss + this.tickSize / 2);
            context.stroke();
            //draw numerical label for tic marks
            //note we add minPrice
            context.fillText(unit + this.minPrice, pricePos, this.centerProfitLoss + this.tickSize / 2 - 30);
            unit += this.unitsPrice;
            pricePos = Math.round(pricePos + pricePosIncrement);
        }

        //draw X axix label as Price at center of X axis
        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:
C++
ProfitLossChart.prototype.drawProfitLossAxis = function () {
      var context = this.context;
      context.save();
      context.beginPath();
      //draw vertical line
      context.moveTo( 20, 0)
      context.lineTo( 20, this.canvas.height);
      context.strokeStyle = this.axisColor;
      context.lineWidth = 2;
      context.stroke();

      // draw tick marks
      var profitLossPosIncrement = this.unitsProfitLoss * this.unitProfitLoss;
      var profitLossPos, unit;
      context.font = this.font;
      context.textAlign = 'right';
      context.textBaseline = 'middle';

      // draw top tick marks
      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);
      }

      // draw bottom tick marks
      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);
      }

        //draw Y axix label as Profit/Loss (P/L) to the right

          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:
C++
//do the transform
    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:
C++
//define parameters, instantiate and draw the chart!
    var minPrice = 0;
    var maxPrice = 2200;
    var minPL = -10000;
    var maxPL = 10000;
    var unitsPrice = 50;
    var unitsProfitLoss = 500;

    //create object
    var chart = new ProfitLossChart(minPrice, minPL, maxPrice, maxPL, unitsPrice, unitsProfitLoss);
  chart.drawPriceAxis();
  chart.drawProfitLossAxis();

  //draw buy call equation, spx June 17, today is 5/16/2016
   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. 

 

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer
United States United States
.NET Developer, MCSD.

Comments and Discussions

 
PraiseNICE! Pin
johnta119-May-16 8:17
professionaljohnta119-May-16 8:17 
QuestionJust dont stop Pin
Alexey KK19-May-16 8:14
professionalAlexey KK19-May-16 8:14 
GeneralMy vote of 4 Pin
Ian Klek19-May-16 3:00
Ian Klek19-May-16 3:00 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.