Chapter 5. Commissioning an Auction Sniper

To Begin at the Beginning

We're a development team for Markup and Gouge, a company that buys antiques on the professional market to sell to clients “with the best possible taste”. Markup and Gouge has been following the industry and now does a lot of its buying on-line, largely from Southabee's, a venerable auction house that is keen to grow online. The trouble is that our buyers are spending a lot of their time manually checking the state of an auction to decide whether or not to bid, and even missed a couple of attractive items because they could not respond quickly enough.

After intense discussion, the management decides to commission an Auction Sniper, an application that watches on-line auctions and automatically bids slightly higher whenever the price changes, until it reaches a stop-price or the auction closes. The buyers are very keen to have this new application and some of them agree to help us clarify what to build.

We start by talking through their ideas with the buyers' group and find, to avoid confusion, that we need to agree some basic terms:

  • Item Something that can be identified and bought;

  • Bidder Person or organisation that is interested in buying an Item;
  • Bid A statement that a Bidder will pay a given price for an Item;

  • Current Price The current highest bid for the item;

  • Stop Price The most a Bidder is prepared to pay for an Item;

  • Auction A process for managing Bids for an Item; and,

  • Auction House An institution that hosts Auctions.

The discussions generate a long list of requirements, such as being able to bid for related groups of Items. There's no way anyone could deliver everything within a useful time, so we talk through the options and, regretfully, the buyers agree that they'd rather get a basic application working first. Once that's in place, we can make it more powerful.

It turns out that in the online system there's an Auction for every Item, so we decide to use an Item's identifier to refer to its Auction. In practice, it also turns out that the Sniper application doesn't have to concern itself with managing any Items we've bought since other systems will handle payment and delivery.

We decide, for a host of secondary reasons to build the Auction Sniper as a Java™ Swing application. It will run on a desktop and allow the user to bid for multiple Items at a time. It will show the identifier, stop price, and the current Auction price and status for each Item it's sniping. Users will be able to add new items for sniping through the user interface, and the display values will change in response to events arriving from the Auction House. The buyers are still working with our usability people, but we've agreed a rough version that looks like Figure 5.1, “A First User Interface”.

A First User Interface

Figure 5.1. A First User Interface


This is obviously incomplete and not pretty, but it's close enough to get us started.

While these discussions are taking place, we also talk to the technicians at Southabee’s who support their online services. They send us a document that describes their protocol for bidding in auctions, which uses XMPP (Jabber) for its underlying communication layer. Figure 5.2, “Southabee's On-Line Auction System” shows how it handles multiple bidders sending bids over XMPP to the Auction House, our Sniper being one of them. As the Auction progresses, Southabee's will send events to all the connected Bidders to tell them when anyone's bid has raised the Current Price and when the Auction closes.

Southabee's On-Line Auction System

Figure 5.2. Southabee's On-Line Auction System


Communicating with an Auction

The Auction Protocol

The protocol for messages between a Bidder and an Auction House is simple, Bidders send Commands and Auctions send Events. The messages are:

Join (Command)
A Bidder joins an Auction. The sender of the XMPP message identifies the Bidder, and the name of the chat session identifiers the Item.
Price (Event)
An Auction reports the currently accepted price. This event also includes the minimum increment that the next bid must be raised by, and the name of Bidder who bid this price. The Auction will send this event to a Bidder when it joins and to all Bidders whenever a new bid has been accepted.
Bid (Command)
A Bidder sends a bidding price to the Auction.
Close (Event)
An Auction announces that it has closed. The winner of the last Price event has won the Auction.

We spend some time working through the documentation and talking to Southabee's On-Line support people, and figure out a state machine that shows the transitions a Sniper can make. Essentially, a Sniper joins an Auction, then there are some rounds of bidding, until the Auction closes, at which point the Sniper will have won or lost; see Figure 5.3, “A Bidder's behaviour represented as a state machine”.

A Bidder's behaviour represented as a state machine

Figure 5.3. A Bidder's behaviour represented as a state machine


Added a couple more arcs to the state machine. Needs redrawing to have a consistent style.

The XMPP messages

Southabee's On-Line has also sent us details of the formats they use within the XMPP messages. They're pretty simple, since they only involve a few names and values, and are serialised in a single line with key/value pairs. Each line starts with a version number for the protocol itself. The messages look like this:

SOLVersion: 1.1; Command: JOIN; 
SOLVersion: 1.1; Event: PRICE; CurrentPrice: 192; Increment: 7; Bidder: Someone else;
SOLVersion: 1.1; Command: BID; Price: 199;
SOLVersion: 1.1; Event: CLOSE;

Southabee's On-Line uses login names to identify items for sale, so to bid for an item with identifier “12793” a client would start a chat with auction-12793 at the Southabee's server. The server can tell who is bidding from the identity of the caller, assuming that the accounts have been set up beforehand.

Getting there safely

We don't think we can write the whole application in one go, so we need to figure out, roughly, the steps we might take to get there. A critical technique with incremental development is learning how to slice up the functionality so that it can be built a little at a time. Each slice should be significant (and concrete) enough that the team can tell when it's done, and small enough to be focused on one concept and achievable quickly. Part of the idea is that, with progress divided into manageable steps, we can manage the risk at each step—it's not a crisis if we have to roll back the work for a cycle occasionally—and, crucially, to get frequent, immediate feedback on our progress. As you'll see, small steps also let us adjust our route as we (the whole team) make discoveries through the project.

Our immediate task is to propose a series of slices for this Sniper application. At each step we want to add a new feature, building on the work that has gone before. After some discussion, we come up with this plan:

Single item: join, lose without bidding. Our starting case where we put together the core infrastructure, this is the subject of the next chapter.
Single item: join, bid, and lose. Add bidding to the basic connectivity.
Single item: join, bid, and win. Distinguish who sent the winning bid.
Show price details. Start to fill out the user interface.
Multiple items. Support bidding for multiple items in the same application.
Add items through the user interface. Add input via the user interface.
Stop bidding at the Stop Price. More intelligence in the Sniper algorithm.

Within the list, the buyers have prioritized the user interface over the stop price, partly because they want to make sure they'll feel comfortable with the application and partly because there won't be an easy way to add multiple items, each with its own stop price, without a user interface.

Once this is stable we can work on more complicated scenarios, such as retrying if a bid fails or different strategies for bidding, but implementing just these features should keep us busy for a while.

We don't know if this is exactly the order we'll implement features, but we believe we need all of this and we can adjust as we go along. To keep ourselves focused, we've written the plan on a card as in Figure 5.4, “The Initial Plan”.

The Initial Plan

Figure 5.4. The Initial Plan


Some More Tools

introduce windowlicker, Smack, etc. here.