(note: math shows up weird, see PDF in GitHub repo)

Inspiration

Optiver has created a virtual exchange titled Optibook, where market participants are allowed to create automated trading bots. For Hack the Burgh 2021, Optiver provided three securities: AMAZON, GOOGLE, and TECH_BASKET. TECH_BASKET functions as a market basket, where the price of the security should be equivalent to the sum of AMAZON and GOOGLE’s individual prices. To our knowledge, Optiver had trading bots providing sufficient liquidity to AMAZON and GOOGLE, as well as trading TECH_BASKET towards the sum of AMAZON and GOOGLE when the prices diverged; however, market participants were asked to create more liquidity for TECH_BASKET.

What it does

In order to add liquidity to the market, participants were expected to trade both sides of TECH_BASKET. Based on the documentation and studying market participant behavior, we were able to design a trading bot that exploited the illiquidity. When a participant wants to take a position in TECH_BASKET, they generally follow these steps:

  1. Decide which side to take the position (submit a bid or ask)
  2. Calculate the most attractive price using available market data
  3. Submit an ask/bid offer to accept the most attractive price

We found that illiquidity was particularly an issue when determining most attractive prices. If Participant A attempts to take a position where only Participant B is providing opposing liquidity, then Participant A acts as a price taker. We found the above pricing strategy to be true of both other competitors and Optiver’s liquidity-providing bots.

Based on the above, it’s clear that if we can create a market where we provide the only liquidity, we become price setters and can profit as much or as little as we desire. We considered two strategies to become the only liquidity providers:

A. Trade when no one else was trading B. Pick up order flow before others could, leaving our offers as the only ones on the market

We considered strategy A first: there is inherent risk with strategy B as we become price takers to others’ order flow. From 2am GMT to 6am GMT we attempted to become the only liquidity providers but found this was unreasonable; Optiver’s liquidity providers ran around the clock and provided sufficient liquidity. Thus, we continued with strategy B.

In order to implement strategy B, our bot would need to take all order flow between our bid and ask, leaving our bid and ask as the only available options. In order to do so, we made a few assumptions:

  1. Participants were providing equivalent liquidity to both sides of TECH_BASKET (that is, the bid volume and ask volume were essentially the same)
  2. Trades are centered around a value, μ, where μ ≈〖Price〗_AMAZON+〖Price〗_GOOGLE
  3. Participant trade distance (“error”) from μ can be approximated with a normal distribution
  4. Liquidity is sufficiently small

We tested each of the assumptions and found them all to hold with the exception of Assumption 4. There were certain market “regimes” where liquidity was sufficiently high to where our efforts were insufficient; particularly, when individuals were testing immediately after the challenge started and when the final bots were submitted.

After estimating typical deviations from μ, we were able to estimate the price we’d need to set in order to profit:

Profit= -∑_orders▒〖|〖Price〗_order- μ|+bid volume* 〖(p〗_U- μ) +ask volume*〖(μ- p〗_L)〗

Where p_U and p_L are our bot-controlled upper and lower prices, respectively. Stated another way, after taking a loss on all the order flow we purchase, we gain 〖(p〗_U- μ) or 〖(μ- p〗_L) on every transaction. With little time, we used estimates for p_U and p_L rather than derived values.

How we built it

We used Python, multithreading, and statistics to build the bot - one thread to manage orders and one thread to clear incoming order flow.

Challenges we ran into

We were originally challenged with some of our parameter tuning; before putting together the math, we found it to be fairly unpredictable. Fortunately, after exploring the mathematical and statistical theory behind our assumptions and trading bot, we were able to come up with something that worked (some might even say a bit too well)!

Accomplishments that we're proud of

In the training period, we were able to achieve $100mm PnL over a time span of ~8 hours. In the testing period, we achieved ~$45mm over a time span of ~1 hour. Rather than leaving the bot running, we decided to let it trade for long enough to prove our thesis; we left the bot off for the remainder of the competition.

Through the competition, we learned firsthand why illiquid markets are poor environments for market participants to trade in and why firms like Optiver, among other market makers, are essential to the health of the markets. It was incredible to learn this through an experiential learning exercise rather than through a textbook, and we thank Optiver for access to their platform.

What we learned

We learned a LOT about how market exchanges work - as students interested in quant finance, we wanted to really get into the nitty gritty. We've always heard illiquidity is bad for an exchange, so we really wanted to figure out why. And I would certainly say we did!

Built With

Share this project:

Updates