Archive | starfighter RSS feed for this section

Developing In Stockfighter With No Trading Experience

Starfighter is a company which makes fun programming challenges. One of our goals is inspiring engineers to take a whack at problems they might assume are “too difficult for me.” Both sets of levels for our first game, Stockfighter, give copious opportunities for this: one set has you do algorithmic trading and one set has you do low-level C and assembly coding, reverse engineering, and security research.

In my experience, the modal web developer probably does not believe they can do algorithmic trading or reverse engineering of assembly code. We strongly disagree: every great developer you know got there by solving problems they were unqualified to solve until they actually did it. That’s why we’re making an environment to let you sink your teeth into fun, hard problems at your own pace, in a supportive community, with us taking care of the scutwork so you can focus on the intellectually interesting bits.

I wrote the algorithmic trading levels (with, I rush to add, no background in finance myself), so I thought I’d write a little bit about how to get started with algorithmic trading for a generalist programmer.

(If this is the first time you’re hearing about Starfighter (the company) or Stockfighter (our first game), you may wish to read starfighters.io or why and how we’re intent on spending the next few years of our lives fixing dev hiring. If you’ve heard of us before and are wondering “Yeah yeah, when do you launch?”, the honest answer is “We bit off a very aggressive engineering schedule between building a stock exchange and an entire C toolchain. The last few months have been pretty rough, but we’re almost done. The game is feature-complete, in private beta now, and will be coming to an Internet near you ‘shortly.’”)

Mea Maxima Culpa, Finance Programmers

I apologize in advance to experienced finance programmers — some of this is simplified a little bit for general consumption. Other parts might accurately reflect how Stockfighter’s simulations work but might not be maximally true-to-life, as we occasionally have to break with reality for pedagogic or player-experience reasons. (Also, it’s entirely possible that I’m wrong with regards to details — feel free to ping me if you think I have material errors. They’re my fault rather than that of our trading advisors.)

The Problem Stock Exchanges Solve

Andy wants to buy a stock. Beth wants to sell the same stock. A stock exchange gives Andy and Beth a place to transact where they know there is a high likelihood that a willing counterparty (someone who takes “the other side” of the trade) exists.

The stock exchange is built around a data structure called an order book. An order book records orders: offers to buy a stock or sell a stock. By convention, these are called bids and asks respectively. (If you need a mnemonic, try “both ‘bids’ and ‘buy’ begin with ‘b’”, but you’ll have this in your muscle memory by your second day of writing trading systems.)

For a trade to happen, a bid and an ask must cross: that is, the maximum price the buyer is willing to pay must be greater than or equal to the lowest price the seller is willing to sell at. You might find it handy to remember those prices as ‘limits’, for reasons which will become obvious later.

An order book is a prioritized queue (or two of them: one for bids, one for asks), ordered by “priority”: “What is the first order that an incoming order would cross with?” There exist a variety of prioritization schemes at various exchanges, and they have huge impacts on how trading happens on those exchanges. Stockfighter assumes the simplest and most common algorithm: price/time priority. Basically, an order always interacts with the best priced order on the opposite side of the book first. Ties are broken by the timestamp that the exchange accepted the resting order at.

Since the order book is split into two parts, it’s often useful to know what the best bid and the best ask are. This is often called the quote. It is expressed as “$BID / $ASK” or, in spoken language, “$BID by $ASK.” For example, if I quote Google to you at $750.05 / $750.06, that means someone is willing to buy it for up to $750.05 and someone is willing to sell it for at least $750.06. (More sophisticated traders might want to know the size available at those levels. A level is simply a price. Why not call it a price? I have a sneaking suspicion Wall Street invented many of these words to give customers the impression “This is all really, really difficult — pay us money and the complexity goes away.”)

The Fundamental Order Book Algorithm

There exist multiple order types which an exchange can support. By far the most common is a limit order, which can be understood as “I want to buy X shares (or as many up to X as I can) for a price which is no more than Y” or “I want to sell X shares (or as many up to X as I can) for a price which is at least Y.”

For each limit order the exchange receives, it checks:

  1. Does the order cross with an order presently resting on the order book? If yes, they match, for as many shares as possible (up to the number specified in the order).
  2. Is the order fully satisfied yet? If no, goto 1 until the order no longer crosses with anything on the other side of the order book.
  3. Is the order fully satisfied? If no, the remainder of the order now rests on the book.
  4. For each order we matched with, write the fact of the match (the fill / execution) to the tape.

Steps 1 through 4 are, essentially, atomic with regards to all orders on the stock exchange. You’re guaranteed to not have two orders interleave execution — only one order is incoming at one time. It is either fully processed (potentially with part of it coming to rest on the book) or canceled before the next incoming order is processed.

The Tape(s)

Markets are by nature distributed systems. To simplify all participants having the same view on reality (or as close to that as possible), they typically have a relatively slow way to get a current snapshot of the order book and relatively fast ways to get a stream of deltas to the order book as they come in — new orders, order cancellations, executions, etc. That stream is called a tape, because way back in the day it was physically printed on a ticker tape.

The Stockfighter exchange implementation exposes a few tapes to users: one of all executions (with a new message for each execution) and one of all quotes (with a new quote — containing an at-a-glance view of the order book state and last trade — each time someone either sends in or cancels an order).

Stockfighter also does not, at this point in time, directly expose orders/cancels via a publicly visible tape. This is a considered game design decision for Chapter 1. I’m calling this out here as “A significant way we deviate from reality”, which we’ll do any time we need to to make the game more fun for players.

Order Types

We discussed the simplest and most common order type, limit orders, above. There are many order types supported by exchanges in the real world, all of them offering some benefit to at least some exchange participant. (Exchanges make money on every consummated trade, and they’re in vicious competition with each other for business, so they generally want to innovate on order types which offer particular customers things those customers want. They are constrained by the law and “not advantaging any participant overmuch against other participants, because that would chase the disadvantaged participants to a competitor.”)

Stockfighter supports three order types besides limit orders:

Immediate-or-cancel (IOC) orders: Exactly like a limit order, except if there is a part of the order which is not filled, that part is canceled rather than resting on the book.

Fill-or-kill (FOK) orders: Exactly like an immediate-or-cancel order, with one wrinkle: if the order can’t be fully filled for all shares it requests, it is canceled without causing any executions. (On real exchanges, this is sometimes described as “immediate-or-cancel all-or-nothing”, or “IOC AON.”)

Market orders: Market orders are what mom-and-pop retail investors use: they include a direction (buy or sell) and a quantity of shares to transact, but no price. They execute instantly and take whatever price the order book offers, again matching the most favorable prices first.

Let’s Talk Liquidity

One of the fundamental problems with buying/selling anything at all is that one is not guaranteed to have a counterparty ready at any given moment. This makes it difficult to buy/sell your thing and forces you to take a worse price if you want certainty of execution.

Consider houses. Lining up a buyer for your house takes, typically, weeks or months of work. If you needed to sell your house not at “some time in the vaguely defined future” but “within the next five minutes”, you would have to offer the house at a tremendous discount to its market value. Similarly, if you wanted to buy a house immediately, you would probably need to pay a tremendous premium.

The housing market is said to be illiquid, or lacking in liquidity: you cannot conveniently transform houses into money or money into houses quickly without losing a lot of value.

The stock market is incredibly liquid: for any stock listed on an exchange, you can buy almost any quantity and sell almost any quantity, at any time the market is in session. No negotiation, no red tape, no uncertainty. Click a button on your computer and bam trade done.

This property of stock markets is optional, tremendously useful for some participants, and very not free. Liquidity is a thing that can be sold, and much of the money on Wall Street is made by selling it. Let’s walk you through how it happens, but first, a bit of an explanation about why people actually want to buy it.

There exists a tradeoff between price and execution certainty. If you send in a limit order, there exists the possibility that it will not execute. This probability is higher if the order wouldn’t cross with the current state of the order book, but even if it looks like it will, the market might well change before your order arrives at the exchange. Even if it looks like someone is willing to sell Google at $750 a share, if you send in a limit order for 100 shares at $750, you have no guarantee that you actually get any Google shares.

If you send in a market order for Google shares, you’re guaranteed to get all of them that you want (subject to the availability of them at any price), but you give up certainty about the exact price you get.

That’s a reasonable tradeoff for many market participants! A family doing some casual trades in their retirement account wanting to buy 20 Google shares (~$15,000 worth) doesn’t really care about the exact price they get. If Google moves by a few cents in the interim, that costs them only a few dollars of value. Oh well — they just want to have the Google, for whatever investing or speculative reason they had for placing the trade originally.

A professional trader, who cared a lot about getting the best possible price and was therefore willing to pay attention to the market all day, might say “Well, Google routinely swings around a bit, so I’ll put in an order at $748 and see what happens.” If they’re buying 10,000 shares at a time, that saves a meaningful amount of money… if that order gets hit at all. If they were wrong, then they don’t get their Googles… or they have to adjust their orders mid-day. That’s fine — executing trades is their job.

Market Makers And The Spread

So the stock market exists to connect Andy and Beth. What happens if Andy and Beth want to trade a stock but are not both in the market at the same time? Enter the market maker. Once upon a time, market makers were designated individuals (called “specialists”), but these days it is often just “anyone running a market making strategy.”

A market maker’s job is TTTaaS: Teleportation and Time Travel as a Service. Suppose Andy wants to buy at 9:15 AM and Beth wants to sell at 9:30 AM. If neither Andy nor Beth are willing to wait, no trade would happen, and Andy, Beth, and the larger economy are all sad.

A market maker says “This is solvable. I sell Andy the stock he wants to buy at 9:15 AM. I then buy the stock back from Beth at 9:30 AM. I charge them slightly different prices and make a modest profit for holding onto the risk for 15 minutes. Then I do this a lot.”

(That’s the time-travel aspect. The teleportation aspect involves cross-venue arbitrage. Too complicated for today, but know that it exists.)

The difference between the price a market maker is willing to buy at and the price they are willing to sell at is called the spread. If you put in a market order, you’re guaranteed to “cross the spread”, effectively paying the market maker a small toll for guaranteed instant execution. (If you don’t want to cross the spread, just put in a limit order such that it rests on the book rather than immediately crosses, and hope that that limit order gets hit — again, no guarantees there.)

How Wide Is The Spread?

The width of the spread — the price of liquidity — is set by the market, not the exchange. It arises from the frothy interactions of thousands of participants firing orders at the exchange.

In the bad old days before computers, stocks were priced in eighths of a dollar (multiples of 12.5 cents). The spread could never be any less than 12.5 cents, which is a substantial chunk of the transaction value for many stocks.

Additionally, specialists colluded with each other extensively, such that they agreed to quote only “odd eighths”, essentially widening the spread to an entire quarter. They collected a one quarter tax on every share of stock which traded, every time it traded, for decades. Specialists loved this system. Investors, not so much — somebody pays that tax.

These days the markets are decimalized — stocks trade in increments of a penny. (They are not allowed to trade in increments smaller than a penny, by federal regulation. This is unfortunate, because “the minimum spread is 0.01 dollars” is not any more rational than “the minimum spread is 0.125 dollars” — if someone is willing to provide liquidity for cheaper, we should encourage that.) Additionally, since anyone can trade from any computer hooked to the exchange, human specialists have largely been outcompeted by algorithmic traders — computers which place orders all day long trying to be the one market maker of hundreds who successfully captures that penny.

You may have heard about High Frequency Trading (HFT). There is no hard-and-fast definition of it. You should understand that most HFT firms are just executing market making strategies really, really quickly while in vicious competition with traditional market makers (whom they utterly crush, because computers are better at doing math fast than people are) and other HFT firms. This is a huge benefit to most people attempting to transact in a stock, because a) no one is forced to do business with the market makers (again, just use a limit order and accept the risk of not executing if you don’t want to pay for their liquidity-providing services) and b) the presence of HFTs competes the spread down to a penny in most highly-traded stocks. Since they’re legally prohibited from competing with price below the penny increment, they then have to compete on speed, and that competition has intensified to the point that HFTs routinely run up against “the speed of light” as an annoying constraint on their engineering teams.

What Is The Risk In Being A Market Maker?

Your job is teleportation and time travel. Bad news: teleportation and time travel aren’t actually possible. This means you take on risk.

Consider the case where Andy wants to buy at 9:15 AM and Beth wants to sell at 9:30 AM. The market maker is not aware of Andy or Beth’s plans and cannot be certain they will not change. The market maker also cannot know what happens between 9:15 AM and 9:30 AM. The stock that they sold to Andy for $40 a share could soar in value to $50 a share when Beth wants to sell, costing them a loss of $10 a share.

This risk is the economic justification for liquidity having a price associated with it. If it were as simple as accepting “Hey, hold onto this stock for 15 minutes and then someone will ask for it — you have no price risk at all”, then it would cost as much as a coat check (“We’ll just throw that in for free”), and not “a small amount on every transaction” which turns into “billions of dollars over the course of the year.”

(You might sensibly be curious as to the impact on individual investors. Fair enough. I’m a small retail investor who trades very occasionally. I ran the math and, on my portfolio of ~$80,000, I’ve paid approximately $6 to market makers over the last ten years. This compares to e.g. $500 or so in commissions to my discount brokerage.)

How Do You Manage Risk As A Market Maker?

This is the entire ball game. At the most basic level, you want to limit the amount of inventory you take in any stock in either direction and charge an appropriate price for liquidity.

Sophisticated market makers use statistical techniques, simulations, etc to try to guess the near-term future behavior of the market, using this to determine how much inventory they’re willing to hold at any given time and what prices to charge.

In the real world, market makers use a variety of other instruments to hedge their inventory risk with respect to any given stock. In the early levels of Stockfighter, we intentionally restrict you to thinking about only a single stock at a time (for simplicity), so your main levers are canceling your existing orders, adding new orders to the book at different price levels, and (in extremis) unloading your position by transacting with orders on the book placed by someone else.

(Probably another market maker. Fun fact: most orders resting on the orderbook at any given time, both in Stockfighter and in real life, are there because a market maker put them there. This was one of my fun takeaways from the research phase for this project: liquidity really does exist primarily because market makers are actively adding it.)

The Simplest Market Maker That Can Possibly Work

1) Guess a current fair price for the stock. (The midpoint of the current quote might be a good first approximation, or perhaps the last price a trade happened at.)

2) Put that price on a number line.

3) Draw three equidistant ticks to the left of that price and three to the right. The distance between the ticks is up to you — you could use a set interval (say, 5 cents) or something sized relative to the price of the stock (say, 0.5% of the midpoint price).

4) Send orders into the exchange such that you currently have orders to buy or sell at each of those ticks. Sizing is up to you: the simplest thing that can possibly work is just “pick a number and use it everywhere.”

5) Wait.

6) Did someone transact with you? Great! Cancel all your outstanding orders. Now, do it all again.

7) Keep doing this until you make a squazillion dollars.

This is about as easy to implement as it looks. (My first market maker clocked in at about 144 lines of Ruby.)

Shockingly, if you’re the only market maker in the market, this will actually work most of the time. The monopoly supplier of liquidity makes money virtually by definition, particularly when the market does not quickly move in one direction and stay there.

In real life, you’re not the only market maker in the market, and you’re liable to get crushed if you try this, as you’re going to be systematically outcompeted for trades which are safe and you’ll systematically undercharge for trades which involve risk. Also, in real life, other people can look at how you choose to do business… and they have a lot of experience picking the pockets of naive market makers. Don’t say I didn’t warn you.

Doing This In Stockfighter

Now that you know in broad strokes how to write a market maker, you’re probably wondering “OK, but how does one actually do that?

In real life, you’d post about $30,000 of capital (bare minimum) with a broker, get access to their API, and then try not to bankrupt yourself while you learn the ropes. I can’t recommend most developers actually try this.

In Stockfighter, your fictional employer in the fictional game will give you lots of fictional money, backed by a reset button should you ever run out. We give you access to a REST API, which has everything you need to send in orders, get the status of orders, get quotes for stocks, and what have you. You can connect to the various tapes provided by the exchange over web sockets, but this isn’t necessary for our earlier levels — the vast majority of players will just write a for loop and poll every few seconds for updates.

This would be problematic if you were competing on speed with a HFT firm, but not only are our bots written in Ruby and not designed to be speed demons, we intentionally hobble them in the early levels to make it an inviting experience for programmers new to trading. (Our stock market maker bot is also literally the first trading program I ever wrote and close to the dumbest a market maker can possibly be, so clocking it shouldn’t be that difficult.)

In real life, most exchanges expose a quirky protocol called FIX. Stockfighter will support FIX in a later release, but for our Chapter 1 release, we have a simplified REST API with JSON. You’ll end up doing things like:

POST /venues/FOOEX/stocks/BAR/orders

with the order:

{
  “symbol”: “BAR”,
  “venue”: “FOOEX”,
  “direction”: “buy”,
  “qty”: 20,
  “price”:  5100,
  “type”: “limit”,
  “account” : “OGB12345”, // your trading account (game gives you this)
}

and get a response back like:

{
  “ok”: true,
  “symbol”: “BAR”,
  “venue”: “FOOEX”,
  “direction”: “buy”,
  “originalQty”: 100,
  “qty”: 20,   // this is the quantity *left outstanding*
  “price”:  5100, // the price on the order — may not match that of fills!
  “type”: “limit”,
  “id”: 12345, // guaranteed unique *on this venue*
  “account” : “OGB12345”,
  “ts”: “2015-07-05T22:16:18+00:00”, // ISO-8601 timestamp for when we received order
  “fills”:
    [
      {
        “price”: 5050,
        “qty”: 50
        “ts”: “2015-07-05T22:16:18+00:00”
      }, … // may have zero or multiple fills.  Note this order presumably has a total of 80 shares worth 
    ],
  “totalFilled”: 80,
  “open”: true
}

Take it from this web developer — you can be up and running on this API in a matter of minutes.

After you’re able to work with the API, you just have to use that to solve whatever challenge the level throws at you. One challenge might be “Here’s a venue (stock exchange) where a particular stock is traded by many bots, one of whom is running a poorly considered market making strategy. Implement a better one and make $X before time runs out.”

Our desired difficulty curve: our first level is a cakewalk if you’ve ever programmed with an API before. Our first few levels after that are solvable in an hour or so of donking around with the API. They range in conceptual difficulty from “A motivated CS102 student should be able to do this in a fairly straightforward fashion” to “You’ll feel pretty proud of yourself once the code works.”

We also have later, more challenging levels, calibrated to be a fun evening project for a developer skilled enough to make it to them. Many of the solutions would make a good conference talk: here are the dead ends I tried, here is the insight those gave me, here is the approach that ultimately worked, and here are the fun implementation details.

Affordances We Built To Make This Easy

Every public endpoint of our API is documented. This includes code samples, sample responses, commentary on how one would actually use that endpoint in an application, and an in-page API explorer so you can run ad-hoc queries without needing to write any code. This is courtesy of readme.io, which is one of my favorite new SaaS apps.

We’re not releasing the API documentation publicly until the game formally launches, to avoid giving anyone the ability to pre-write clients for the game. (Though that earlier sample probably gives you enough to predict most of the API… hmm… well, good on you if you can do it from that.)

We will not be releasing first-party libraries for the API at launch, to give the community the opportunity to build them for yourselves. (“Can I write a e.g. Python library for the API and throw it up on Github?” Heck yes. “Can I use a client library someone else wrote to let me focus on the fun work involved in solving my levels?” I’d personally be very disappointed in an engineer who, in 2015, defaulted to scratchbuilding their own clients for every API they consumed. Starfighter loves OSS and the OSS culture. Go nuts.)

You can, of course, use any language capable of driving a REST API to play these levels. Or curl, for that matter. (To quote Chris Rock: “You can drive a car with your feet if you want to, but that doesn’t make it a good idea.” Memo to self: add a Drives Car With Feet badge to the game.)

A Non-Trivial Sample Application

We built an in-browser trading application in React, which you’ll get instant access to once you open one of our trading levels. This interface is essentially what a day-trader would be working with… if their brokerage of choice made some pretty poor UX decisions because their dev team was one guy writing his first React app.

Wait, did I say that out loud? What I meant to say was: we produced an entire web-based trading interface, driven 100% through our API, which allows you to see the API actually getting worked with.

Blotter

It has virtually complete coverage of our API, by necessity, so if you need to know how to e.g. interact with a web socket you can just right-click and View Source. We don’t “cheat” and do anything to make the API easier to consume for our own applications like e.g. adding private endpoints which pre-digest information for the client.

(Most of our bots don’t cheat, either — they interact with the stock exchange the same way your applications do, and have no privileged access to e.g. market data. There exist exceptions to this general rule, in particular, in Chapter 1 level 6. I won’t spoil it for you.)

Further Reading

If you’re having trouble visualizing what an order book looks like, particularly as it gets mutated in response to incoming orders, I recommend taking a look at Chris Stucchio’s examples in these three essays. They’re in the context of an argument that HFT is not as abusive as the engineering community often believes.

I happen to think that Chris has the right of that argument, but even if you don’t, read his examples closely, because Chris has a view of trade execution which can be reconciled with reality and Michael Lewis (of Flash Boys) does not, as you will quickly discover if you try to actually write out what Lewis says is happening in pseudo-code.

What Happens If I Can Make A Market Maker?

In the process of learning to build a market maker, you’ll both demonstrate substantial practical engineering skills (e.g. working with a novel API, dealing with state, modeling a data structure that probably isn’t built into your language already, etc), learn some fun new things, and get a whirlwind tour of common Wall Street activities.

Each level of Stockfighter introduces you to a challenge which builds on the last, in the context of a narrative taking place in a simulated world. You can’t possibly screw up anything so badly that the reset button won’t fix it, and no money is actually on the line.

For example, after you have successfully built a toy market maker, we might give you a new level where that market maker is exposed to harsher conditions and tell you to adapt to them. (Fun intellectual exercise: read the section on risk and try to predict what features of a trading environment would make a market maker’s job harder.)

Market makers are among the first of many concepts Stockfighter will teach you. Our intention is that many generalist programmers, including folks who have never had the opportunity to do anything more interesting than a standard CRUD app, will discover (or develop) depths of engineering skill they didn’t know they had. That’s awesome regardless of what happens.

Our games are free to players. Most players will be playing Stockfighter simply because play is fun. We’ll always support that, but we want to support the engineering community in more direct ways as well. If you find that you’re a better engineer than your day job needs you to be, we might very well be able to find a job more suited to your abilities. Our business is introducing talented engineers to clients who want to hire them. They pay us if they hire you. We’ll have about 15 clients signed at launch, ranging from Wall Street institutions (“Want to learn how to do this when it isn’t a toy?”) to non-profits to startups with interesting engineering problems.

The market doesn’t believe there exist enough engineers who thrive when given a novel, hard problem. We think you’re out there, in multitudes, and we think there exist many other engineers who are on the cusp of greatness. We want to meet you and geek out together.

See you in the game in the near future. If you’d like to make sure you hear when we launch, and you’re not already on our email list, fix that here.

Designing And Building Stockfighter, Our Programming Game

Stockfighter, Starfighter’s first programming game, is presently in private beta. We’re moving to dark launch (to clients and handpicked vict^H^H^H friends) next week. We’ll launch publicly immediately after the servers give us signs that they won’t go down in a roaring fire. I’d anticipate within 3 weeks of today, but you know how engineering schedules go.

(Starfighter is a company which is trying to solve engineering hiring. We make games/puzzles which one plays by programming. Think Minecraft meets Legos meets World of Warcraft meets a CS class — we’re giving people a fun little world to play in by programming with some pre-planted goals and then seeing what emerges. More on our website or here if you’re curious.)

I wanted to talk a little about what we’ve built and why, both out of general interest and because I know some folks want some direction for how to prepare. I’m going to take the liberty of not spoiling actual levels, because discovery of them is a lot of fun, but will focus on the setting, infrastructure, and design goal.

Picking The Fiction / Setting

We picked “cops and robbers on Wall Street” for the setting of our first game — making money by legitimate means (like charging for liquidity) and illegitimate means (like stealing it). Although my co-founders Thomas and Erin have done substantial work with securing real stock exchanges over their career, I have no particular background in finance. We’re also primarily interested in general engineering skills rather than e.g. quantitative trading specifically. So why start in finance?

Basically, rotating the player around a series of Wall Street institutions allowed us carte blanche to hang virtually any engineering challenge off a more-or-less cohesive narrative. Trading systems touch low-level coding, networking (all seven layers of hello OSI Model), APIs, end-user UI, databases, embedded systems, enterprise web frameworks, cutting-edge programming language research, Big Data, state management, etc etc.

The fiction also gives us excuses to be naughty, which is something we think many programmers are attracted to. Many CTFs (games which practice security skills) cast the player as a hacker breaking into something, which works to a point. You can get the same adversarial frisson in legal fashions on Wall Street, often by building things rather than strictly by breaking them. (Though, ahem, not all of the things our levels have you build are, strictly speaking, legal. That’s also part of the fun. The fact that you’re being naughty vis-a-vis institutions which are not well-liked in the programming community is also useful to us from a player-motivation perspective. I hope people will, in the course of robbing them blind, actually learn what major Wall Street institutions do for a living and come to a more nuanced understanding of their position in society.)

There are natural in-universe tie-ins for both player-versus-player contests (which we won’t ship at launch, but soonish) and for dealing directly with computer-controlled opponents. Wall Street is, after all, one big computer-controlled opponent.

Some folks have been surprised that our game is not more, you know, game-y. Couldn’t we have made e.g. an RPG or strategy game or similar? Yes, certainly, but we had some concerns of a social nature.

Cards on the table: I used to run a World of Warcraft raid guild before I went into business. (Business has less dragons and better loot.) My co-founders, on the other hand, feel about gaming approximately the way I feel about ballet: it’s great that it exists in the world and I’m glad people find enjoyment in it, but it isn’t for me. This view is shared by many talented engineers and would-be engineers.

As of 2015, we don’t gate entrance to the tech industry based on demonstrable enthusiasm for ballet. It is important to our founders that the industry is not gated by demonstrable enthusiasm for gaming-qua-gaming or related geek cultural signifiers, like e.g. a fantasy or sci-fi setting.

Starfighter doesn’t ever intend to build gates (gates close; that’s what they are for). We dynamite gates.

Tech Trees

Stockfighter is divided into tech trees. A tech tree presents itself to the player as a series of challenges linked by narrative progression and pedagogy. Learn a new concept; beat a level; get introduced to new levels where you can build upon what you build and what you learned. (Fun game design challenge: how do we not bust you back to a blank editor between every level while simultaneously not making it feel like you’ve “already done this.”)

In architectural terms, a tech tree typically requires additional back-end engineering work on top of our general platform, and also some front-end engineering to make it playable in the browser. (About which, more later.)

We’re shipping two tech trees at launch: automated trading and emulators and compilers. My co-founder Erin discussed writing our emulator already, so I’ll be covering mostly the trading tree today.

Automated Trading

Automated trading is the classic problem people think of when they hear Wall Street. It’s topical: Flash Boys (a book about high-frequency trading) was on the New York Times bestseller list. It delivers on the “make a squazillion dollars using only your wits” fantasy for the game. (“Fantasy” is, in this sense, a term of art from game development: much like someone writing a novel or screenplay, a game designer wants to have intentional control over the player’s emotional state. If you’d like to read more about this, Raph Koster’s A Theory of Fun comes highly recommended.)

In Stockfighter’s automated trading tree, each level gives you a new scenario (randomly generated and assigned to a wee little copy of the world accessible only by you) and a plausible set of objectives. You achieve the objectives by driving our REST API, using any language/stack/tooling you’re comfortable with.

What we built to support trading:

  • a limit order book, written in Go
  • a stock exchange front-ended by a REST API, written in Go
  • a settlement system, written in Go
  • a world simulation for a universe of fictitious companies, written in Ruby
  • several automated traders, written in Ruby
  • a game master server, exposing a REST API, written in Go
  • an internal message bus, about which more later
  • a blotter interface (similar to a retail trader’s web application — think “what I see when I sign into eTrade”) written in React and consuming the exchange and game master APIs

I wrote most of this myself because Thomas and Erin were doing the technically ambitious parts of Stockfighter. No, really, compared to their stuff, scratch-building a stock exchange is actually fairly straightforward.

Writing A Stock Exchange

My primary stack since 2010 has been Ruby on Rails. I love Rails, and we use it for our user-facing web application, but Rails is not the right choice to build a stock exchange. The biggest reason was concerns about raw performance.

Stockfighter doesn’t do “high-frequency trading” like Wall Street understands that term, although it does support (and have you actually do) what many lay people understand HFT to mean.

The difference is one of degree. Many lay people basically think that any algorithm placing orders is HFT. There are many prop shops — i.e. hybrid tech/finance companies using the company’s money to trade algorithmically — which have a timescale on the order of days rather than on the order of nanoseconds. Their individual orders (and the logic behind them) might be faster than a human can reasonably follow, but that’s still not HFT. (Acid test: if you have never worried about the speed of light between your systems, you’re not doing HFT. The amateur trading from London on the Chicago Mercantile Exchange using MS-Freaking-Excel to place trades? Not HFT, guys.)

We abstract the notion of time quite a bit, but it was obvious that each exchange was going to have to be able to process thousands of orders a real-life second.

This would be… challenging in Rails. Low-complexity operations which do need to write to the DB typically hit about 300ms in my Rails experience. (Better, more experienced teams like the folks at Basecamp have gotten it to 50~100 ms in typical cases.) We would need to do thousands of them a second and, unlike a typical web application, we a) have a bursty, write-heavy, uncacheable load by nature and b) have some severe constraints with regards to requests affecting each other.

Why? Well, it is a stock exchange. The order book — the list of how many shares at what prices are currently available to be bought and sold — is (conceptually) a singleton sitting behind a global lock. (Per-exchange — Stockfighter will simulate thousands of exchanges simultaneously, but architecturally, it needed to consider the “Thousands of people hitting a single exchange at once” use case from the jump.) This is getting all the player and bot interaction. The matching engine has to be completely done with a particular order before starting processing of the next one.

We solved this in a roughly similar way to a real stock exchange: the order book is persisted entirely in memory, in Go.

Stockfighter is my first production system written in Go. The Google (et al) performance wizards have absolutely delivered. The language screams and, happily, it is possible for a mere mortal to actually ship a web server with it. (Note “server” but not application. More on that later.)

Incoming orders from the REST API or our internal message bus are passed to a single goroutine which manages ingress and egress to the order book. This goroutine writes the results of those orders to a series of tapes. A tape, physically, a buffered channel with a servicing go-routine. The tapes are then consumed by other parts of the systems to e.g. send execution notices to players/bots, update the quotes displayed by the API/UI, etc.

Our exchange is blazingly fast: we can process fairly complicated orders matching against a filled order book in on the order of 100 to 200 nanoseconds. Read operations are even faster. (I might eventually figure out some way to re-architect the exchange such that reads don’t touch the matching engine at all, but at present some of them do. Whoopsie.)

This is good — it allows players substantial latitude for experimentation with trading strategies (including ones which push the performance envelope), lets us run dozens or hundreds of bots per player, and keeps our infrastructure costs down to “less than a small fortune.” (We’re on EC2. At release, pending understanding how many users we have and what their typical behavior is, I anticipate that we’ll have a count-on-your-finger number of t2.micro instances for the stock exchanges.)

Getting this working was a bit of a beast. Our order book is represented internally as a red-black tree (Go implementation via GoLLRB). I had never actually used a red-black tree since finishing my CS degree. (Well, OK, they’re sitting down somewhere in MySQL or Postgres but I’ve never had to actually think about them before.) This is a preview of coming attractions for Stockfighter: even when we aren’t explicitly making tech decisions for pedagogic purposes, modeling the complexity of the stock market is a real engineering workout versus e.g. the typical CRUD application.

Bonus points: most players will, at some point, choose to represent the order book on their own machines. This is foundational to many trading strategies. If you want to golf cycles off to make your code faster, that will a) directly advantage you in later Stockfighter levels and b) be a fun opportunity to play with algorithms and data structures.

A quick case for a LLRB for the order book data structure: they tolerate arbitrary writes and deletes very well, are sorted, and let you do things like “Iterate over every price point on the tree from the low-price side and give me everything until you count up this many shares and do it fast.”

My main issue in this part of the development was managing concurrency. If I had cottoned onto the wisdom of the common Go pattern “Make a server object with one managing go-routine and have it tightly loop on a single channel of incoming requests” earlier, I probably would have a avoided a whole lot of deadlocks, crashes, and concurrency bugs caused by e.g. reading the order book for GET /venues/FOO/symbols/BAR at the same time a match was ongoing subsequent to someone POSTing a new order.

Stock Exchange Simulations

There exists substantial prior art on funny-money stock exchange simulations. Most of them are cunning artifice — you’re not actually trading with another actor. When you put in an order, you receive the results suggested by a stock market simulation. Amalgamated Cat Food (ACF) is up today — you paid $45.32 for your shares! But you didn’t buy them from anyone. Your account just got incremented, but there is no corresponding sell anywhere. Your counterparty is a fiction.

There are excellent engineering reasons to do this and I won’t knock their decision, but Stockfighter had different goals.

Why? Well, a lot of the fun engineering problems in trading are caused by it actually not being reliably the case that you send in an order and it gets unproblematically matched at “the price.” Markets are distributed systems. The exchange’s view of reality and your trading system’s view of reality are, by necessity, separated by the great firewall known as “physics.” For maximum possible results, you have to be able to do things like accurately predict what the future state of the exchange is, because the order you’re composing right now will arrive in the future not the present, while being cognizant that your present view of the exchange’s state is actually the exchange’s past.

Sound hard? It is hard. You don’t have to worry about it for the first couple of levels… well, actually, let me take that back. We do not intentionally expose you to the speed of light as a limiting factor early in Stockfighter… but we can’t remove latency as being an actual limitation distributed systems have to overcome.

Here’s an example of how this manifests: I was very frustrated during development at one point, debugging a level I had written. The blotter interface was showing a quote with an ask for 500 shares available for $100. (You’ll pick up the market jargon quickly — an ask is an offer to sell a given quantity at a given price. If they want to buy, it’s called a bid.)

I sent in a market order for testing. A market order is a special order type which doesn’t specify a price — it says “I’ll pay literally anything, I just want guaranteed execution of this order immediately.” (Aside: Stockfighter will quickly teach players in a visceral fashion why Wall Street considers people who place market orders to be idiots. Use a limit order most of the time. If you need instant execution, use fill-or-kill or immediate-or-cancel with a suitably-generous-but-not-actually-unbounded price attached.)

My order came back saying that I had bought 0 shares. And the quote from the exchange now read “500 shares available at $120.”

WHAT?!

After a lot of spelunking, I figured out what happened: there was only one bot on the ask side of the order book during that level. That bot had an order resting on the book displayed on my screen. In the time between I hit the button and my order reaching the exchange, the bot had hit the REST API to cancel its order. Then my order arrived to an empty book, soaking up 0 shares. It was then canceled (because market orders are instantaneous). The bot then replaced its order, causing the exchange to issue a new quote, which made it back to my PC before I had time to blink. From my imperfectly attentive human perspective, it looked like the exchange and the bot were intentionally colluding to abuse me.

They’re not.

But that sort of interaction — orders resting on the book, cancels, timing issues, different views on reality, profiling incoming order flow (as reflected by the quotes or execution tapes) and using it to send in or cancel orders faster than the incoming flow can itself adjust, using executions from one exchange to drive decisions to send orders to another exchange, etc, are all so fun to play with. And to do that, you need other agents participating on the exchange with you, rather than the exchange being a single-player experience.

Enter the bots.

Writing Bots

Since player-versus-player interaction causes a lot of social issues which we weren’t ready to design for for release, and since players are not reliably available to play a) at your skill level b) right-the-heck now, we knew we wanted AI to trade against for most levels. (Aside: We’ll support PVP in some levels of later chapters, for those players who enjoy it. If you just want to treat Stockfighter like an intellectual exercise and never have to worry about another human during your experience, that is a game mode we will always support.)

It fell upon me to write multiple trading algorithms. For context: I have an undergrad background in AI (enough to know that it’s largely not applicable to the problem at hand) and most of my investing experience was simply buying-and-holding rather than trading actively. (Aside: retail investors should not trade actively. If someone thinks Stockfighter has given them the confidence to try actively trading for real, I will bang my head into the wall several times and wonder how we can make the next chapter more clearly communicate how ROFLstomped one will be if one tries that.)

Luckily, the market has participants operating at all levels of skill. Markets are aggregation mechanisms for price signals, and they come to surprisingly sophisticated behavior even when composed out of relatively unsophisticated individual agents. As soon as we had multiple bots operating diverse strategies, we started to see fun emergent behavior.

An example, hopefully without spoiling too much: I did a technology preview of the game with a friend who has a Wall Street background. The only actual goal-oriented level in the game at the time was our tutorial, which just has you buy 100 shares to prove you’re mechanically capable of doing so.

(Aside: I could describe level 1 as “FizzBuzz for a REST API”, but we don’t. FizzBuzz is widely used to quickly weed out non-programmers from engineering hiring processes, but the experience of being asked to do it is a little off-putting for experienced developers. Giving people an actual fun goal — demonstrate mastery over a new system! — allows us to covertly test core engineering skills without writing This Is A Test Of Core Engineering Skills at the top of the screen.)

Anyhow, my Wall Streeter friend sailed through the tutorial and asked what was next. I told him “Well, content-wise, I’ve got nothing. But you’re hooked up to a stock exchange and all the other participants are idiots. What do you think would be fun to do?” “How dumb are they?” “Pretty dumb.” “So dumb they would follow the stock all the way down to zero if someone was to manipulate it?” “Umm… I don’t know.” “Let’s see.”

Five minutes later, we had verified that unplanned interactions between bots who a) don’t collude, b) don’t know of the existence of each other aside from seeing the order book, and c) have no mental model of the player can in fact successfully model sheer, unrestrained terror if a player manipulates the market correctly.

We’ve found a small number of not-too-complicated bots to be the gift that keeps on giving for level design — remix them and tweak parameters and the behavior of “the market” is different on every playthrough but roughly configurable in advance. This made level development much, much less expensive than I had modeled it out as.

We’re shipping with six trading levels, but we’ll have Chapter 2 out the door with more, probably within a month or two of release, and we intend to continue shipping new chapters every 6~8 weeks, indefinitely.

Another fun thing consequence of being a games company: in real life, when the state of the art advances in trading algorithms, you throw out everything that was done before because it would now be predated heavily. Being predated is a victory condition for us — it means levels are winnable! As we get better at building trading algorithms internally and/or hire experts to do it for us, earlier dumber bots don’t end up as bitrot, they end up as valuable game content. For example, the bugged momentum following bots which were proximately at fault for the market cascade were too disruptive to keep in that level… but, well, they’re now a resource that one can deploy to a variety of purposes.

Even after we have very sophisticated market makers (if that is a new word for you, I promise, you’ll understand it by the end of level 3), our idiot market makers are still valuable content for people who are still learning the field.

Simulating An Entire World Economy

Stockfighter’s trading levels are about trading rather than investment. It’s important that the markets dance to an internal logic, but it is less important that that logic be particularly complicated. We wanted the companies at issue to have plausible behavior — some do well, some do poorly, some are stable, some gyrate, and sometimes the entire market goes into bull or bear mode for uncertain reasons before unpredictably reversing. We’re not really concerned, though, with e.g. line-by-line analysis of the earnings report for Amalgamated Magitek Corporation.

So we faked it. I’m going to elide the details of the fakery here. Our order book and exchange server work like they have to work, so I’m happy to spill beans about implementation details. The world simulation, though, is “security sensitive” — if you understand the world simulation you can predict and influence the future. That’s an I-Win button for most of our trading levels.

“What if players reverse engineer your world simulation?” Then I pin a freaking medal on that player (and ask whether they’re happy in their current career).

I think you’ll be pleasantly surprised with some emergent features of the simulation.

At present, it’s totally opaque — the only thing you’ll learn about Amalgamated Magitek Corporation is what you surmise based on seeing a market for its shares develop organically out of the actions of various bots.

Some of the bots are performing market functions which are neutral with regards to the underlying, like a market maker. Some of the bots actually do care about AMC. Well, to the extent that a 200 line Ruby script can care about an earnings report.

It’s not perfectly realistic and isn’t designed to be.

For one, we abstract time heavily. It’s a lot more fun to play through one trading day every 5 seconds and thus get a year’s play done in a 30 minute session of watching your script run than it is for that to just represent the quiet post-bell lull in the morning on January 3rd.

For another, again for maximum fun, our simulated world is more volatile than the one we actually live in. The in-universe financial press would be an impossible job for someone who wasn’t actually manic depressive.

In the future, we’ll expose various elements of the simulation to players. For example, there is an in-universe Twitter. Seriously, that is an actual thing that exists. I pipe it to a text file and tail -f it as a debugging tool, because otherwise it is difficult to figure out whether e.g. the price is cratering because I inverted a comparison somewhere or the price is cratering because Amalgamated Magitek Corporation was hit with a terrorist attack.

The Magitek industry is, as they say, “politically exposed.” Plucky teenagers with outrageous hair hate them and blow up their buildings with disturbing regularity. They just have no consideration for the Imperial Pension Fund’s AMC holdings or the chaos that news will unleash on the markets.

(Aside: geek references are capped at about 5 to 10% of the stocks in the game — you’ll also see a lot of things like Red Tree Agriculture or Uganda Mining Inc. We also reference various things that only have value in a fictional universe, like unobtanium or Bitcoin.)

(Aside: I promise that’s the last Bitcoin joke I’ll make until we ship our cryptocurrency tech tree some months from now. Actually, no, I can’t promise that.)

Anyhow, we’ll expose the in-universe Twitter directly to players in a later chapter. You can try your hand at doing things like e.g. sentiment analysis or trading on news generated by the world simulation before other trades can react to it.

The best example yet of the flexibility this simulation gives us is in the 6th trading level. I won’t spoil the details here, but after I beat it the first time, I told Thomas and Erin “This level is why I signed on to this project.” It’s the capstone for the trading tree in Chapter 1.

A particular fact is inserted into the world simulation and bubbles up to the stock exchange. You’re asked to discover the fact. There are literally infinite ways to do it.

Players getting to level 6 are by construction pretty good at programming and will have learned enough about market microstructure to be effective at trading. Level 6 is, let me not mince words, hard. You have to synthesize what you’ve learned about market operations, about our particular implementation, and then stir in some special sauce of your own… and we give rather little direction on what that sauce needs to look like.

I expect that level to be very challenging, because it is totally out of left field, but it also rewards creativity. You can Big Data your way through it. You can Hadoop cluster your way through it. You can probably solve the hardest phase of it with an Excel spreadsheet. You can use Statistics 101 (if you figure out the right question to ask). You can even solve it by eyeball if you parse the right data and graph the right thing about it. I expect players to do all of these things, with substantial variation. I also expect the unexpected, in spades.

We can’t wait to see what you come up with.

Level Design

Again, no spoiler on individual levels, but I’ll talk about what makes a good level from the perspective of Starfighter.

Appropriate challenge progression: Our desired curve is:

  1. Early levels: Solvable by people learning to program with effort approaching an undergraduate lab session. Cakewalks for professional engineers.

  2. Middle Levels: Solvable by people who possess professional-grade engineering skills, even if they may not have professional-grade titles yet. Expect the level to require a bit of thought and execution quality but not to have much technical risk.

  3. Later levels: Solvable by very skilled engineers, but requiring an investment of effort, and having a corresponding emotional payoff for it (a sense of mastery, learning new skills that you could reasonably take with you, etc).

I was asked how we difficulty curved our levels. My design process was to throw out a lot of real-world trading problems (thanks a million to our advisors from industry; all mistakes in interpretation are our fault alone), winnow to the ones which seemed most amenable to working on our system, and then arranging them in rough order of difficulty assuming the player takes the most straightforward route through the level. I then wrote ourselves a few levers for difficulty — for example, parameterization of the level goals (e.g. if it is too hard to make $1 million in a simulated year, edit a YAML file and now players only need $250k) and providing instructions/hints.

While we’re doing our technical burn-in, we’re also collecting feedback on whether we guessed right on difficulty levels.  We can titrate how difficult a level is in production by choosing between e.g. giving no instructions on the path forward, saying something like “The path forward is obliquely suggested by the API docs.”, giving in-universe hints in e.g. the level briefing, giving out-of-universe hints, and directly telling players “Here’s one way to do it; you produce code to that.”

Players can, naturally, also do this, which suggests that our earlier levels are likely to get easier over time as e.g. better tooling is available on Github or people post walkthroughs. That’s a natural and not-unhappy result from a game design perspective.

Variety: Starfighter is a company, not a one-off event or a mobile game. We expect to (eventually) have a relationship with players which is denominated in years, not minutes. Accordingly, we want to produce regular content updates with them feeling sufficiently distinct from each other that there is a reason to play.

Variably difficulty: We wanted players to be able to Choose Their Own Adventure. If you want to pick the most straightforward solution for a level which works, blast through it, and move on, go for it. If you want to golf your solution, go for it.

Some of the most fun I’ve ever had with another team’s CTF was on Stripe’s 3rd CTF, where automatic detection of e.g. program speed supported a thriving optimization metagame. An example: some players looked at a fly like “An O(N^2) loop which compares text word-for-word against a world list.” and eschewed the flyswatter “An O(N) loop which compares against a hash table.” in favor of an orbital ion cannon like “Pre-compile the dictionary into the executable as a trie or bloom filter.”

We have per-level leaderboards which give people a meaningful number to golf on, and additionally, we have discretion to (automatically or after human review) award additional badges for going above-and-beyond on a level. We’ll also do that outside of levels, too — I can imagine issuing badges for people who, e.g., write OSS clients for our API, submit documentation patches, responsibly report security issues, etc.

Specified goals. Unspecified solutions. A common pattern in CTF development is “Make a program which conforms to this toy interface.” A lot of the work on the player’s side involves understanding that interface (and, often, the undocumented quirks of it). The interface often dictates exactly what your algorithms/structures/general approach need to look like.

We prefer modeling the actual practice of engineering, where you build stuff not to satisfy an arbitrarily defined interface but to achieve some motivating goal. Figuring out what to actually build to achieve the goal is a substantial portion of the challenge of real engineering work — and a whole lot of fun! (Also, companies hiring engineers right now are often looking for folks who can, given an underspecified goal, successfully reduce it to working computer code.)

This lets us support multiple solutions trivially, if we pick goals which are sufficiently robust. Luckily, the Wall Street fiction gives us numerous options. I mean, when in doubt it’s “Here’s the world; make money.”, but things can be arbitrarily rich.

This also has some unplanned for benefits from our internal engineering perspective. The modal level orchestration for our trading levels is roughly ~50 lines of Ruby code. Most victory conditions can be evaluated in a function with less than 10 lines. (Level six? The most fun I’ve ever had which was judged by a single string comparison.)

Level Orchestration

We have a GM server (“Game Master” is an RPG term): it a combination simulation of the world, judge, orchestrator of the non-player characters (bots), and opinionated producer of fun.

Our GM server is written in Go and exposes a REST API. (You could, in principle, play Stockfighter entirely through curl if someone told you what URLs to hit. That would be pretty spiffy. Tell me if you manage to do it.) This accepts commands like e.g. POST /levels/foobar, which creates a new instance of the foobar level.

GM’s level orchestration logic is actually kicked out to Ruby, mostly because I develop Ruby much faster than I develop Go and, since this code is less performance intensive than the stock exchange, we had some flexibility. Levels are plain-ol’ Ruby whose design was heavily influenced by Rails — convention over configuration, lots of reflection used to locate files given predictable naming schemes, etc. They also have a YAML configuration which allows us to adjust e.g. which bots are present in the level, what instructions are given to the player, etc.

The bots… well… every project which ships ships with one decision that you feel the need to say “Look, I know, I know, but it actually worked.” Our bots are all written in Ruby. The goroutine managing the level instance on the GM server periodically wakes up, opens a Ruby subprocess, unpickles the state of the world simulation and the bots, has the bots update themselves against the state of the exchange via the REST API, accepts the bots desired orders, makes them against the REST API, pickles the state of the simulation and the bots, and then sleeps until the entire process starts again in a few seconds.

Why? A combination of “That lets me write levels and bots in my best language”, “I wanted to ship in 2016” plus “If I did a slightly more obvious thing and kept all of our levels and bots constantly in memory rather than slicing them 500ms of the server’s attention every N seconds, then our memory requirements at launch would be measured in terabytes and go up from there.”

Why use Go for the server then, instead of e.g. Sinatra? Because Go’s concurrency story is much better than Ruby’s is.

Front-End Engineering

A core design goal for Stockfighter is that it is quick to pick-up-and-play, right in the browser, without requiring one to have a complicated toolchain installed.

Why? First, from a strict conversion optimization perspective, I’d anticipate a heavy, heavy dropoff between signup and completing level 1 if my first instruction was “OK, get a fully-functioning C toolchain installed on your box. Now clone this repo.” or even “Download this Vagrant image.”

Second, this is particularly difficult for less-experienced engineers. They’re not the core of our business, not by a long-shot, but I want to support them to the extent possible. I want a CS101 classroom to be able to play Stockfighter together. Many practicing engineers don’t remember this, but a CS101 classroom finds installing e.g. a full Rails toolchain to be a hard, frustrating, failure-filled experience. (I’m a professional engineer using Rails for the last 8 years. If you gave me a blank Macbook and a day I could do install Rails… after a lot of Googling to check whether we still use rbenv and Bundler or if that changed since last week.)

So a hard requirement for both of our tech trees was that they be playable in the browser to start. After players are invested, they can get additional edge by working in their stack of choice locally, writing tools which sit on top of our systems, or even e.g. deploying code to EC2 or Heroku or what have you, but batteries had to be included out of the box.

Thomas and Erin build an entire in-browser C development toolchain which compiles down to assembly and then executes on a farm of emulated Arduino processors. I had the comparatively easier task of figuring out “What does the simplest version of automated trading that works look like?”

Answer: it’s manual trading! So we made a blotter interface — basically, a stripped-down retail day trader’s interface for monitoring the market, placing orders, and seeing executions. You can use the UI to poke at any of our levels and get a sense for what the “normal” behavior of the market is given that level’s load out of bots and stocks. You can also use it as a stepping stone for bootstrapping your first programs — there is no need to write e.g. code to poll whether your orders hit anything because we’ve already taken care of that for you, so all you need to do is focus on generating the right orders to send in. If you want, you can even totally replace the UI with your own web application — go nuts.

Another nuts option: if you feel confident in your trading abilities, it is at least theoretically possible to beat many of our trading levels the old fashioned way — by running the math in your head and keying in your orders faster than the other guy. This is hard mode, since the other guy is Ruby code, but given that we force him to sleep for 80~90% of every trading day it’s at least possible.

The UI also includes controls for level operation, like e.g. restarting the level if you get stuck.

It was obvious that given goals like “Make a million dollars!,” in the inevitable learning period you could quickly get yourself in an unwinnable state by e.g. losing 95% of your starting capital. The designed operation of our trading levels is “Play them, lose horribly, write a program, reset the level, run the program, have it crash with a bug, fix and re-run, lose modestly, adjust your approach, re-start the level, run the program, win.” (Folks have asked whether we’ll hold this against you. No, no, of course not. We log everything under the sun, but losing/restarting levels is planned. That capability is an advantage of doing this in a rich simulation as opposed to real life — you can go Knight Capital as many times as you want and no one loses their job!)

We did the UI in React, because it has a lot more going on than most CRUD apps.

DHH describes the sweet spot of my favorite stack (Rails-with-some-Javascript) as “documents with some dynamic sprinkles.” I really love that model, but it does not describe a trading interface. You have an incoming stream of events, many per second, updating part of the DOM, potentially hundreds of orders open whose state can mutate at any time and whose accurate display is important, and a variety of actions available to you at any time.

Obligatory learning curve aside, as this is my first React app, I’m loving React and the Flux architecture. (We use Flummox, which was — sadly — EOLed between us picking it and launching. I swear, all the jokes about JS frameworks are true. That said, of the available options it seemed to require the least boilerplate, which can be further reduced with a sensible naming convention.)

Our blotter interacts directly with the exchange API (unlike most retail trading applications, which interact with a brokerage which interacts with another party which interacts with the exchange). This was enormously useful as I was doing parallel development on both systems. Forcing me to write a fairly complicated application against our API burned out a lot of the usage niggles prior to them being exposed to players. (Oh, don’t worry, you’ll find plenty more.)

Requirements generated by the blotter, like “Polling for order status is just crazy after you have hundreds of them — we need some sort of pub/sub system accessible over a websocket.”, made the exchange better for a variety of trading applications.

Here’s an image, although it’s modestly more amusing when quotes are streaming in and things are updating constantly.

Stockfighter Trading Front-End

The big challenges for React development, aside from the learning curve, were state management when switching between levels (eventually solved by rethinking our store design) and dealing with lots and lots of UI repainting.

At one point I was playing a level with a hundred bots. Each of those bots sent in about a thousand orders a minute. Each order changes the quote for the stock, causing a separate websocket message. Each websocket message would cause my entire table of orders to refresh.

100,000 refreshes of a table with a thousand elements in a minute will, pretty reliably, melt your poor little Macbook.

We eventually solved this by using built-in React features like shouldComponentUpdate (basically, we got very detail-oriented regarding the performance-sensitive components like orders and quotes, made sure they would always render the same given the same prop and states, and then canceled the render if their prop/states were deep-equals equal) and using keys on child objects.

Fun fact about child keys: even if every child is itself immutable, if you choose keys poorly (like, say, simply making a unique ID on creation of the child UI element), updating a single order out of an in-memory list of 1,000 will cause the entire table to refresh, and if your child key is different than the key for the same element in the last version of the table, React’s magic DOM-diffing technology does not save your bacon. Instead, your bacon sizzles amicably on your Macbook.

After I got my head around that and started picking better child keys (appending the ID and modified timestamp is all you really need — same as Rails Russian-doll caching), our UI became quite snappy. I log into our staging environment (Amazon’s Oregon data center) from Tokyo and I can’t tell it’s not on localhost… except when the speed of light decides to play tricks on me.

Supporting Technology

Our web application (signup/login/leaderboards/etc) is a bog-standard Rails 4 app. There is very little technically interesting about it, but it works and was quick to write — this is exactly Rails’ sweet spot.

You know whose sweet spot it is decidedly not? Go’s. I tried, I really did, but it would be very difficult to recommend Go for a web application at the moment.

The ORM we ended up using for e.g. our settlement service, Gorm, is not anywhere near the level of maturity of ActiveRecord, and to get its (valuable!) feature set you have to tolerate a) throwing out most of the benefits of using a type-safe language and b) programming bugs which can cause statements which certainly look like they should generate SQL queries to just silently not generate SQL queries. In general, working with the database has been so painful in Go that I have been instead either a) hitting a REST endpoint on an internal API to have Rails do the DB access then return formatted JSON (which Go can actually consume fairly decently) or b) throwing the data at NSQ.

I have fallen in love with NSQ, an enterprise message bus for people who don’t ever want to have an enterprise message bus. The elevator pitch for it: write a textual message, tag it with a topic, and send it to your local NSQ daemon. On some other machine that doesn’t even know you exist, another program says “Apropos of nothing I’m a member of the $FOO channel and want a copy of $BAR topic messages which have not been processed by the $FOO channel yet. $FOO doesn’t exist yet? It does now. Hit me.” NSQ handles all the magic to make that happen.

We use it for everything. Rails controllers need a way to log analytics-style events? Pipe it to NSQ — we’ll make a decision on an analytics-provider later and, in the meanwhile, we’ll have nsq_to_s3 just save them for us. Our settlement system needs executions from the stock exchange? Open a settlement channel on the executions topic; done. Executions also need to be logged somewhere? Sure, open a dumpToLog channel on that topic and use the provided nsq_to_file utility; done. We want a per-player list of historical UI actions taken by levels? Sure, no worries, have the GM server write to the levelActions topic, open a peristToDB channel on it, and use nsq_to_http to have those hit an internal API on our Rails app which takes care of that.

The best part? When you just assume the existence of NSQ everywhere, you don’t have to think about e.g. dropping more instances of a particular service on your infrastructure, routing requests, etc etc. You just fire-and-forget at the bus.

Actually, that isn’t actually the best part about NSQ. The best part is Stockfighter ships with about seven microservices and having them all understand every HTTP endpoint available would have been unwieldly. Instead, we standardized on a small set of common JSON object representations and then the topic names. This lets us do things like e.g. have our Arduino emulator slurp up quotes from the stock exchange simply by saying “Hey I’d like quotes, too” without the stock exchange even knowing that an Arduino is a thing.

For our services which communicate over HTTP, like e.g. the exchanges, we have to be a little smarter about routing because we can’t treat NSQ as the Magic Oracle Of Making Sure Messages Get Delivered. The short version of that story is consul.io, the longer version is a full infrastructure post because it gets complicated.

Documentation

We’ve been using readme.io for our player-facing documentation. I haven’t pushed our docs live yet (spoilers abound) but I love this service.

  • The docs come out looking very pretty without me having to do any more CSS munging.
  • The UX of the docs approaches that of e.g. a Stripe or Twilio rather than a Markdown file.
  • There is an in-browser API explorer, so you can (if you want) copy/paste in your API key and, from the page describing e.g. our POST /venue/FOO/symbol/BAR/order endpoint, actually post a live order against one of our running stock exchanges. It displays the HTTP headers and full response in-line.

Readme.io is ridiculously fun. We’ll push the docs live to it when the game launches publicly.

Further Reading About Trading

We’ve promised players a reading list to help with understanding Wall Street for generalist developers. Here’s a brief tour of my Amazon history over the last several months:

  • Flash Boys, Michael Lewis: I find this book impossible to avoid in a discussion of automated trading and yet difficult to recommend. Lewis is an exceptionally talented writer. I think many Starfighter players will come away from some of our levels saying “Michael Lewis, I have attempted to actually do the thing you said that the bad guys did, and that is, as a matter of engineering reality, actually impossible.” That said we’re totally ripping some levels off of his (highly entertaining) storytelling here. I mean, they named a computer program after a Greek god. How can we not make that into a level.
  • Flash Boys: Not So Fast: A much more lucid take on HFT, by someone whose paycheck depended on being able to turn it into actual engineering artifacts.
  • Dark Pools: The Rise of the Machine Traders and the Rigging of the U.S. Stock Market, Scott Patterson: If the title doesn’t give the game away, spoiler alert: Patterson probably doesn’t consider “more engineers able to do algorithmic trading” to be a victory for truth and justice. (Of course it is! At the very least, consider it self-defense training.) That said, unlike Flash Boys, the discussion of issues/attacks strikes me (and our advisors) as being more tightly grounded in consensus reality. This book also includes an excellent history of the development of computerized exchanges in the US from about the 90s through today. It was particularly wild when I realized that our cute little toy hosted on a t2.micro was a $X0 million or $Y00 million engineering project back in living memory.
  • I hesitate to recommend it based on the price, but if you want to pursue this topic professionally after Stockfighter, the Bible at Thomas’ last company was Trading and Exchanges: Market Microstructure for Practitioners.

That’s all I’ve got for today. Back into the code cave for us. We’ll see you in a few weeks!

Announcing Starfighter

Thomas Ptacek, Erin Ptacek, and I are pleased to announce Starfighter, a company that will publish CTFs (games) that are designed to develop, improve, and assess rare, extremely valuable programming skills.

Starfighter CTFs are not fantastic Hollywood-logic depictions of what programming is like. There is no “I built a GUI interface using Visual Basic to track the IP address.”

You will use real technology. You will build real systems. You will face the real problems faced by the world’s best programmers building the world’s most important pieces of software.

You will conquer those problems. You will prove yourself equal to the very best. Becoming a top Starfighter player is a direct path to receiving lucrative job offers from the best tech companies in the world, because you’ll have proven beyond a shadow of a doubt that you can do the work these companies need done.

We’re not here to fix the technical interview: we’re here to destroy it, and create something new and better in its place.

Sound interesting? Our first game will be ready shortly. Give us your email address and we’ll tell you when it is ready.

WHAT IS STARFIGHTER?

We’re going to publish a game in the genre often described as “Capture The Flag” (CTF). It will be a goal-oriented exploration of technology.

You will code to play. You will not pay to code.

Our CTF will be totally free for players. (Not “free-to-play.” There is no catch. We will not ask you to pay extra to buy funny hats or recharge energy or unlock the full version.)

To progress in the game, players will have to use every programming skill they know, and pick up new tricks along the way.

CTFs are a superior way to learn rare and valuable programming skills which you would not otherwise be exposed to. We’ll give you the excuse, and code/test harnesses/documentation/community support/etc, to try that language/framework/problem space/etc you’ve been meaning to learn “someday.” The games Starfighter produces will help programmers all over the world learn these skills absolutely free.

We’ve done this before: our founders ran MicroCorruption. It is one of the most successful CTFs ever created, by any metric, and unlike most CTFs it is still playable years later. Starfighter will run ongoing, supported, progressive CTFs at scale, which will operate indefinitely. Making and supporting CTFs will be our only business.

WHY IS STARFIGHTER GREAT FOR PLAYERS?

Starfighter games will be, first and foremost, fun to play. You’ll get to dig into new tech, on your own terms, in the comfort of your own living room. You will achieve mastery of it. You will be able to show off your skills to other devs, and they will say “That’s awesome how you did that.”

Progress in a Starfighter game will map naturally to skills that top tech employers need RIGHT NOW. Playing will teach you crazy programming skills you can’t learn anywhere else. (Bold talk, right? No, really — some of our levels are so fun that if you did them in real life you’d be thrown in jail. Others put you in charge of highly-lifelike-simulations-of programs that, if the real ones blew up, would rate the nightly news worldwide.)

You will learn what it is like to see the Matrix.

Sounds like BS, right. I know. I’m a generic web programmer (yay Ruby, meh JavaScript, boo low-level anything). The last time I played a CTF, written by my cofounders, they had me breaking into locks controlled by micro controllers which ran embedded assembly code. I haven’t touched assembly in 12 years, because I thought I hated it. But then I found myself in Hanoi finding myself with only a lock running vulnerable assembly code separating me from 25 points.

I pulled my hair out for hours. I tried everything I could to get that lock to open. I cracked open a book on assembly. I read tutorials on the Internet. The opcodes were an impenetrable blob, and then something I could sound out but make no sense of, and then a functioning computer program, and then… then they were a target.

I… I can’t even believe I’m saying this… I exploited a buffer overflow bug to corrupt the value on the stack storing the program counter so that when the function returned it wouldn’t go back to the call site but rather jump into memory that I controlled where I had pre-staged handwritten assembly code to gain control of the lock.

Take that, Neo. [Thomas comments: That’s one of the easier levels, actually.]

You will do bigger, more impressive things.

Starfighter will allow you to develop and show off skills possessed only by the most valuable programmers in the world. Does that make you one of the most valuable programmers in the world? Yes, yes it does.

Want to land a better gig? This is your opportunity to level up. Do well in the game, and we can short-circuit the resume spray-and-pray hiring nonsense and introduce you directly to CTOs who will be happy to hire you. (We’ll only do this if you ask us to.)

Sound good? Give us your email address; we’ll tell you when we have a game ready for you.

WHY IS STARFIGHTER GREAT FOR EMPLOYERS?

The science of hiring practices is settled: work-sample tests are the most effective way to assess skill in potential hires.

The problem? Work-sample tests take time and money to develop, deliver, maintain, and support. You’re not in the work-sample test business: you have a company to run.

Starfighter games are work-sample tests, built by a company which will do nothing else. We’ll treat our CTFs like a first-class tech product, because they will be our only product.

We will market them actively. We will track player behaviors and skill at incredible levels of granular detail, instrumenting them like they were built by the Orwellian MiniPeace. We will iterate on their game design, calibrating it to be accessible in the earlier levels but provide an appropriate challenge even to the best engineers in the world. We will create regular content updates. We will make the supporting documentation/libraries/etc a first-class concern rather than the afterthought of an overworked team building a side project. We will engage our players like our ability to feed our families depends on it.

We will erase all doubts you have about a candidate’s ability. You can guess whether they grok REST APIs based on their Github profile, if you are OK with ignoring 90%+ of the hiring pool with no public Github profiles. We can tell you exactly what happened when your candidates tried to implement a REST API. We can compare their performance against hundreds of other talented engineers (including your current employees) on the same task.

We can bring engineering rigor into your hiring process.

STARFIGHTER WILL REVOLUTIONIZE YOUR HIRING FUNNEL

You do not have enough qualified candidates, because your candidate filter greps resumes rather than ability. Starfighter will dispense with resumes and measure ability directly. We will source a higher volume and higher quality stream of engineering candidate leads than any channel you presently use. (We’re shooting for higher volume and higher quality than all channels you currently used, combined.)

We will love our players. They will love us. We will help the right ones fall in love with you, too.

Your present hiring process is secretive, scary, and stressful for candidates. We can offer an independent front-end to it without requiring ongoing management overhead from you.

Your team may occasionally falter in building hiring pipeline — the business gets busy, the milestones start slipping, so prospecting stops and coffee dates get neglected and interviews get rescheduled. It happens. We will constantly be identifying new, talented, pre-vetted engineers and introducing them deep into your hiring funnel.

Has anyone ever posted a video of themselves interviewing at your company? No. It is a painful experience. Nobody wants their friends to see them struggling in front of a whiteboard. Some companies would even threaten a candidate with legal action for doing this.

People will post Let’s Plays of Starfighter CTFs to Youtube. They will get together with their friends to to talk how awesome your company’s hiring funnel is. We won’t send them a cease-and-desist. We’ll send them a pizza.

“Aren’t you worried about players gaming your assessment?” The only way to game a Starfighter assessment will be to demonstrably possess the type of engineering skill which you want to hire for. Are we worried that players will teach themselves these skills just to play Starfighter? We’re counting on it. That would be an epic success.

You cannot buy hiring pipeline as effective as the one Starfighter will build for you.

STARFIGHTER BRINGS DOWN STRUCTURAL BARRIERS

The technology industry structurally excludes many qualified candidates from their hiring funnels and then is shocked when those hiring funnels disproportionately select for candidates who are not structurally excluded. Traditional tech interviews are terrible ways to identify, qualify, and evaluate top programming talent. Filtering by education level or university is unreliable. Keyword searches are applied by people who don’t understand the underlying technology. The tech industry excludes perfectly viable candidates for no reason at all.

(Case in point: Donald Knuth would be selected out of the hiring process for [senior C programmer with Unix experience] before any human had ever considered him at most tech companies. His CV doesn’t match the keywords C, programmer, or Unix.)

Starfighter is different. We attract the interest of a huge pool of potential talent. Tens of thousands of people will play Starfighter games for fun, and the act of playing improves their skills for free. Some will find them too difficult. Some players will sink their teeth into them, self-studying and rising to the occasion. A small percentage of serious players will breeze through all the levels faster than we can possibly create them.

You will want to hire our best-performing players, before someone else snaps them up.

You need people with skills, and we’d be happy to make the introduction. We run the CTF, then make the appropriate introductions under a standard contingency recruiting arrangement. You don’t need to make major changes to your hiring process to adopt Starfighter. (We’d be happy to suggest some, though.)

Everyone wins.

Starfighter has signed a few marquee clients. If you have hiring authority for 10+ engineers in 2015, send an email with details about your company to patrick@starfighters.io — we may be able to slot your company in for the first batch of candidates.

WHY SOLVE ENGINEERING HIRING?

The 21st century is going to belong to developers and the businesses which employ their talents successfully. Unfortunately, the technology industry is fundamentally unserious as to how it presently identifies and employs engineers.

This is one of the primary causes of the hiring crunch. It is a primary contributor to structural impediments to entering our industry. This negatively affects many candidates, including (but certainly not limited to) those from underrepresented backgrounds.

It is also a multi-billion dollar problem. Persistent market inefficiencies should be music to the ears of a capitalist, because they suggest free money. The technology industry has, through neglectfully embracing hiring policies which are so irrational as to shock the conscience, created a gigantic mountain of free money.

Starfighter claims that lonely mountain as its birthright. We are going to slay the dragons guarding it and then strip-mine it. This will continue until either dwarves sing about how wealthy we are or until every firm in the industry rationalizes its approach to hiring.

WHY IS STARFIGHTER THE RIGHT TEAM FOR THIS?

We have the technical chops to build CTFs, which are virtually impossible to keep in production without a strong technical team and ongoing focus.

We have built software companies and worked with the best teams in the industry. We understand how software firms work, inside and out. We know how frustrating hiring is because we did it for years, too, before we realized how CTFs are a cheat code for life.

The Starfighter founders can talk the geek talk. We have walked the geek walk. Of the three of us, I’m practically the non-technical co-founder, and I solo-shipped two SaaS products. Thomas and Erin spent most of the last decade looking at software systems made by the most talented engineers in the world and then breaking them in ways so horrible that describing some of them could bring down Western capitalism.

We’ve spent years helping engineers level up in their careers. I have a folder in Gmail saving messages from geeks who used my career advice or salary negotiation tips to their advantage. Those two essays are, by the numbers, apparently among my most useful career contributions to the software industry. Now I’ll have the excuse to do more like them every day.

It could be sensibly argued that desire to please clients will make us go against the interests of engineers. Don’t worry. We’re brokers in a seller-dominated market. Our economic incentive is to maintain our reputation as honest agents for the most valuable W-2 employees in the world. Also, again, we’re geeks. We come here not to serve technology recruiters, but instead to replace them with a small shell script.

HOW WILL STARFIGHTER MAKE MONEY?

It’s possible that some engineers might be confused about how we’re going to make money. No worries.

Companies pay “contingency recruiters” a commission, generally calculated as a percentage of an employee’s first year salary, to introduce them to candidates. This is paid “contingent” on the candidate accepting a job with the company.

Starfighter is a contingency recruiter with access to a better way to identify candidates than “Call up everyone on LinkedIn and beg them to take a job at Highly Regarded Tech Firm In Your Area.” We assess for skill first, passively as players play our games and then actively. Our founders — talented technologists — personally reconstruct candidates’ solutions and evaluate them.

We follow-up with players to ask if they have any interest in a no-obligation chat about career options. If they’re interested, we have an honest geek-to-geek conversation.

Then, if appropriate, we introduce the candidate as deep into the hiring funnel at our clients as our clients will allow. It’s not “Yay, as your special prize for winning we award you permission to send your resume into their /dev/null inbox”, it’s “The CTO’s got an hour free at 3 PM on Friday; would you like to meet him to talk about joining their DevOps team?”

After the introduction is made, the decision is up to the candidate and the employer, but we’ll be following up with both to make sure the process is running smoothly. Clients will give Starfighter-sourced candidates their full attention immediately and process them in an expeditious and dignified fashion, as befits skilled professionals.

Contingency fees are not paid by candidates and don’t come out of their salary, any more than the company’s rent or marketing budget comes out of employees’ salaries. They’re a cost of doing business. Companies are happy to pay them because companies understand how hiring engineers makes-or-breaks their businesses. (Potential clients interested in getting the best terms possible should get an engagement letter signed before I convince the other founders “Why are we only charging market?! We’re better than all our competitors! Charge more!”)

READY TO PLAY?

Thomas, Erin, and I are presently hard at work building Starfighter’s first game. It will assess a variety of programming skills, including general systems programming aptitude as well as a few more… esoteric fields. We’ll have challenges appropriate to your skill level, whether you’re new to these fields or a seasoned pro, and we’ll have study guides, skill trees, and friendly geeks who love helping other geeks level up.

We plan to launch the game publicly in the near future. If you’d like to hear when this happens, sign up here.

A quick note from Patrick (in my totally-not-the-CEO voice)

I’m super-pumped about Starfighter, which is my main gig as of now. I’ll talk later on what it means to be quitting the whole self-employment thing. This was a major decision for me.

What does this mean for my other projects?

Bingo Card Creator: Bingo Card Creator will be sold. I hope to close the sale before the end of March. Our broker is FEInternational. I’ve enjoyed working with them so far. If you’re interested in BCC, please talk to them.

Appointment Reminder: I have no announcement to make about my involvement with Appointment Reminder at this time. We will, naturally, continue keeping all commitments to our customers.

Kalzumeus Software: Kalzumeus Software is going to continuing operating and will continue to be home to my eclectic side projects.

I have one major upcoming commitment on this front, the A/B testing course that I’ve been working on for far too long now, and am hoping to get it out ASAP to get it off my plate and clear the way for Starfighter. My co-founders have graciously let me delay full-time involvement in Starfighter while I get this out. Expect news on this front soon-ish.

We haven’t done any consulting in a while. We will continue doing no consulting, to the best of our inability.

Blog/speaking/podcast/etc: Software seems to be my life’s work. Yay. I’m going to keep writing and speaking about it, in all the usual places and under the Starfighter banner as well. I look forward to applying old tactics in new ways (what happens when you give a hiring funnel to an engineer who sees conversion funnels in everything? We’re about to find out!) and figuring out some new tricks as well. As always, I’ll be happy to teach anything I learn.