> stdout Tradier Developer Blog

Calculating a Net Quote

Posted on 01 Sep 2016 by Jason Barry | Code

We’ve been asked a few times about the logic we use to calculate the net quote on our site for complex option orders. While not any sort of proprietary calculation, it’s incredibly hard to find resources on how to do the math, so we thought we’d share ours. Of course, this was already pseudo-public since the Tradier Brokerage trading site is an Ember application…

Hope this helps someone looking for resources on how to do this in their own trading applications!

  _calculateNetQuote: function() {
    var order = this;
    var bid = 0;
    var ask = 0;

    // return if equity or option or not enough legs
    if(this.get('isEquity') || this.get('isOption') || this.get('legs.length') < 2 ) return;

    // also return if there aren't quantities for all legs
    if(!this.get('legs').every(function(leg) { return leg.get('quantity') > 0; })   ) return;

    // get the GCD for all leg quantities
    // where there is no factor gcd will be 1
    var gcd = this._gcl();

    this.get('legs').forEach(function(leg) {
      var security = (leg.get('isOption')) ? leg.get('security') : order.get('security');
      var quantity = leg.get('quantity');

      // divide by 100 for equity quantities (1 contract is 100 shares)
      if(order.get('isCombo') && leg.get('isEquity')) {
        quantity = quantity / 100;
      }

      // calculate!
      if(!Ember.isNone(security)) {
        if(leg.get('isBuy')) {
          ask += (quantity * security.get('ask')) / gcd;
          bid += (quantity * security.get('bid')) / gcd;
        }
        if(leg.get('isSell')) {
          ask -= (quantity * security.get('bid')) / gcd;
          bid -= (quantity * security.get('ask')) / gcd;
        }
      }
    });

    // Ensure the bid is always the smallest numerical value
    if(Math.abs(bid) > Math.abs(ask)) {
      this.set('netBid', ask);
      this.set('netAsk', bid);
    } else {
      this.set('netBid', bid);
      this.set('netAsk', ask);
    }

  }.observes('legs.length', 'legs.@each.quantity', 'legs.@each.side', 'legs.@each.security.@each.bid', 'legs.@each.security.@each.ask', 'security.bid', 'security.ask'),

  netMid: function() {
    return (this.get('netBid') + this.get('netAsk')) / 2;
  }.property('netBid', 'netAsk'),

  _gcl: function() {
    return this.get('legs').reduce(function(a, b) {
      var a = (typeof a === 'number') ? a : a.get('quantity');
      var b = (typeof b === 'number') ? b : b.get('quantity');
      return Math.gcd(parseInt(a), parseInt(b));
    });
  },
comments powered by Disqus
Tradier Inc.
  • 11016 Rushmore Drive, Suite 350
  • Charlotte, NC 28277
  • Phone: 980.272.3670
  • Email: hello@tradier.com