Virtual Markets, Part One: An Introduction to the Grand Exchange

I have always been drawn to online games which feature player-run economies. Virtual marketplaces with their various nuances and constraints provide us with a microcosm of human behavior to study and apply economic models against.

An old favorite of mine is an MMORPG published by Jagex called Old School Runescape, also known as OSRS. With 480 thousand active players each day, OSRS provides us with an excellent case study of market forces manifesting in a virtual environment.

Before we can get started modeling behavior for any market, we need to validate that some important prerequisites are met:

  • Do market conditions facilitate and encourage trade between players?
  • Which modes of trade are available and actively-utilized by players?
  • Can transaction data be collected?

Disclaimer: This article is strictly academic in-nature and does not constitute financial advice. I have deleted my OSRS accounts and have no stake in any position within the game.

OSRS Macro Economics 101

In-order for a market to exist, players need incentive and means to trade. With an elementary understanding of the broader game mechanics of OSRS, we can make some inferences and summarize all economic activity that occurs within the game:

  • Players obtain commodities and goods by performing in-game actions and activities. These commodity-generating actions are referred to as faucets.
  • Commodities and goods are annihilated through in-game consumption mechanics, referred to as sinks.
  • “gold pieces”, or gp, is the commodity that serves as the primary in-game currency. It is the most common medium of exchange and is subject to a unique set of sinks and faucets.
  • Sinks and faucets are governed, adjusted, introduced, and removed at the discretion of the game publishers (Jagex) in a partially-democratic manner. Furthermore, sinks and faucets can only be activated through player activity, with very few exceptions.
  • Players are permitted to engage in mostly unlimited free trade, with very marginal restrictions/exceptions.

These mechanisms, combined with the large player count and the implementation of 4,000+ unique commodities and goods results in a very dynamic and free market where players are rewarded for engaging in profit-maximizing behavior. As a result of these conditions, our first prerequisite is met: Players absolutely have the means and encouragement to trade with one other.

How do players trade?

Before we can collect data about a market, we need to understand what modes players are using to engage in trade. In the case of OSRS, there are currently three available modes:

The Grand Exchange (GE)

The Grand Exchange is the centralized marketplace of OSRS which functions as a primitive securities exchange operating with the following mechanics:

  • Players possessing a commodity that they wish to sell in-exchange for gp can place a “Sell” order, while players conversely wishing to purchase commodities with gp can place a “Buy” order. These are roughly analogous to Ask and Bid offers on real exchanges.
  • Players placing a Buy or Sell order must specify a unit quantity and price; once an order is placed, the corresponding commodities or gp are removed from the player’s inventory and are held in an escrow.
  • Orders are instantly executed the moment they are placed if the order’s price overlaps with preexisting converse orders for the same commodity. This is referred-to as “insta-buying” when a buy order is placed and instantly fulfilled by an existing sell order, or “insta-selling” when a sell order is placed and instantly fulfilled by an existing buy order.
  • Conversely, if an order is not instantly fulfilled, it will remain open indefinitely until other players initiate converse insta-buy or insta-sell orders.
  • Orders may be partially-fulfilled if converse orders match or overlap in price, but not in quantity. Orders which are partially-fulfilled will remain open until their remaining quantity is fulfilled by additional converse orders.
  • Any unfulfilled or partially-fulfilled order may be cancelled by players at any time; any remaining gp or commodities will be freed from escrow and returned to the player’s inventory.
  • Players may take the fulfilled portion of an otherwise incomplete order out of escrow and into their inventory without cancelling the order.
  • In circumstances where two converse orders overlap but do not match in price, the price of the older order is used to complete the transaction. This is analogous to the Strike price on real exchanges.
  • If two or more competing orders are identical, older orders are given priority for fulfillment.

The Grand Exchange also has a handful of limitations:

  • Up-to 8 concurrent Buy or Sell orders may be active at any time per player.
  • Sell orders are subject to a 0-1% tax. More specifically, for items sold below 100gp per-unit, there is no tax. For every 100gp in per-unit price, a 1gp tax is charged. There is an upper tax limit of 5,000,000gp per-unit which applies to items sold for 500,000,000gp or more.
  • Purchasing parties are subject to buying limits per-commodity, which expire in 4-hour intervals. These buying limits can range from as few as 4 units, to as many as tens or hundreds of thousands of units.
  • There is no in-game order or price transparency. While a “guide price” is provided for all commodities, this seldom reflects the actual prices set by other players’ orders. As a result, it is impossible to know with certainty, once an order is placed, whether or not it will be fulfilled.

Despite these limitations, the Grand Exchange is vastly the most frequently-used mode of trade in OSRS, due largely in-part to its superior convenience and relative safety compared to other modes of trade.

Player-to-player

OSRS also features a player-to-player trading interface which functions as an ad-hoc escrow, permitting the mutual exchange of goods. Direct player-to-player trading used to be the primary mode for exchanging goods between players, however it has been vastly supplanted following the introduction of the GE. Player-to-player trading still sees some edge use-cases, including but not limited to evading GE taxes, trading extremely high-value items, bypassing the GE’s timed buy limits, moving commodities between multiple accounts belonging to a single player, trading novelty items not listed on the GE, or to facilitate rule-breaking activity such as scamming and real-world trading.

Players may also exchange goods with other players in a uni-directional manner by “dropping” items on the floor, which can then be picked-up by anybody in the player’s vicinity. In-practice, this is generally employed as a mode of redistributing wealth, either voluntarily in the form of “drop parties”, or involuntarily via rule-breaking scam coercion tactics.

Non-player characters (NPCs)

Throughout the game world, there are many NPCs who players can trade with. With the exception of some extremely specific edge use-cases, NPC traders are typically not utilized by players. This is largely because they buy and sell goods at fixed and extremely high margins; as a result, it is almost always more advantageous for players to trade goods with each other rather than with NPCs.

Give me the data!

Since we’ve established that the Grand Exchange is the most frequently-utilized mode of trade within OSRS, obtaining data from the GE should be our primary goal. While it would be nice to have data about ad-hoc NPC and player-to-player trade, having this data isn’t 100% necessary since they only service edge use-cases. On the other hand, since the Grand Exchange facilitates the vast majority of trade within the game, not having access to this transaction data would be a non-starter for any modeling.

So, how do we go about obtaining transaction data from the GE?

The most obvious source would be the game publishers themselves; Jagex provides some cursory information about the Grand Exchange through the OSRS website, however there is no API available to use, and this data is time-delayed and subject to sanitization. It is only somewhat useful for casual tracking of long-term trends, but not much else. The same is true of the “guide” price provided in-game; it is a metric that is fairly useless for any real-time tracking or detailed modeling purposes.

It is possible for players to directly access real-time prices by directly leveraging the Grand Exchange mechanics described earlier; by placing orders on the GE which trigger an “insta-buy” or “insta-sell” transaction, players can identify the current “High” and “Low” real market prices. Unfortunately, extracting information in this manner is extremely cumbersome, time-consuming, and expensive.

Fortunately, there is an active, community-driven effort via the OSRS Wiki to obtain real-time pricing from the Grand Exchange. This data collection leverages the large base of players who use a third-party client called RuneLite to play OSRS. Players who use RuneLite typically use “plugins” to enhance gameplay, including enhancing the in-game accuracy of real-time pricing of the Grand Exchange. A bi-product of this is an anonymized, crowd-sourced pool of Grand Exchange transaction data for the general public to use. While this data does not include transactions that involve any two players not using the plugin, the sheer quantity of players using the plugin provides a sufficiently large sample size to reflect the real state of the market.

As a result of these efforts, the prices website can provide casual players with real-time price information and history that is far more useful than any information published directly by Jagex. However, the real power comes from the direct use of the prices API. Current and historical data can be accessed using a variety of endpoints, allowing players to obtain granular market data in-order to make inferences about the market.

Let the modeling begin!

With all three of our prerequisites met, we can now get to work modeling market behavior in OSRS via the Grand Exchange and the API that we have at our disposal. Let’s start with a quick overview of the API endpoints so that we have a baseline understanding of the data that we have access to:

The /5m, /1h, and /24h endpoints all provide historical data about the market. Calling these endpoints provides High (ask, or insta-buy) and Low (bid, or insta-sell) price averages along with their respective trade volumes for the given time interval. Older data can be obtained by specifying a timestamp, with data from as far back as 2021 being available to download. Since the /5m endpoint features a narrow span of time, the resulting data is more granular, but may be missing data for items that don’t trade as frequently. Likewise, the /24h endpoint is less granular, but will include averages for more items, including those which are less frequently traded.

The /latest endpoint on the other hand provides the most recent market information, and is refreshed approximately once every minute. This endpoint does not include volume; rather, it includes current high and low pricing for all items, each with a corresponding timestamp indicating when that price was last recorded.

The /mapping endpoint provides some general useful information about each item in OSRS that can be traded on the Grand Exchange. As new items are introduced into the game, or as item qualities are changed by Jagex, the /mapping endpoint is likewise updated.

There are numerous ways that these API endpoints can be utilized. The simplest way to use them is to simply click on the links and view the raw JSON. This isn’t particularly useful, however; APIs are best utilized through scripts or applications that fetch and process the data for a specific purpose.

For my purposes, I’ve created a Python script that routinely fetches, concatenates, and processes historical and mapping data from the API, generating a table containing useful statistics about the endpoints in-aggregate. This includes mean, median, max, and min values for all items, against any desired endpoints and any desired span of time. The script caches collected data in-order to avoid making redundant calls, and the script runs on a 5 minute schedule to keep local data fresh.

I’ve also created a companion script that rapidly combines this fresh historical data with the “real-time” /latest endpoint data, allowing near-instantaneous generation of useful reports.

Source code and report examples are all published on the Projects page. The published reports all capitalize on distinct market inefficiencies discovered in OSRS which will be covered in extensive detail in the subsequent articles in this series. I have personally used this information to generate between 20 and 50 million gp of in-game profit per day using a single account.

Thank you for reading, and stay tuned for detailed market analysis and Python/SQLite snippets in my upcoming articles.

*Update* Virtual Markets, Part Two: Market Fundamentals and the High-Low Spread is now live!