> stdout Tradier Developer Blog

Knowing what endpoints your Dropwizard application supports

Posted on 02 Sep 2016 by | Development

A vast majority of our API technology is built on Dropwizard - we love the framework and how easily it allows us to build new APIs. As the number of services we run has increased, it can often be difficult to remember what endpoints an application responds to. When you start a Dropwizard application, the framework logs the endpoints in a really elegant format:

INFO  [2016-09-01 20:41:23,904] io.dropwizard.jersey.DropwizardResourceConfig: The following paths were found for the configured resources:

POST    /eat/lunch (com.tradier.rest.LunchResource)
GET     /fruit/banana (com.tradier.rest.BananaResource)
GET     /vegetable/avocado (com.tradier.rest.AvocadoResource)

But it’s both impractical and slow to startup a server periodically to see it’s endpoints. Of course documentation would be a solution here as well, but ain’t nobody got time for that!. Fortunately, Dropwizard 0.8 added public methods to DropwizardResourceConfig to access the endpoint data in a way that can be leveraged within an application. Not wanting this to be part of a public API, Dropwizard tasks are a great place to add this to our application:

public class EndpointsTask extends Task {

  public EndpointsTask() {
    super("endpoints");
  }

  @Override
  public void execute(ImmutableMultimap<String, String> parameters, PrintWriter output)
      throws Exception {
    DropwizardResourceConfig config = new DropwizardResourceConfig();
    config.packages("com.tradier.rest");
    output.println(config.getEndpointsInfo());
  }
}

Now, when we want to see the endpoints for a given application, we can just access the task!

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));
    });
  },
Tradier Inc.
  • 11016 Rushmore Drive, Suite 350
  • Charlotte, NC 28277
  • Phone: 980.272.3670
  • Email: hello@tradier.com