2020 Fall Competition Case Packet: Traders@mit - Edu Traders - Mit.edu

Download as pdf or txt
Download as pdf or txt
You are on page 1of 20
At a glance
Powered by AI
The document discusses high frequency trading, fixed income trading, information valuation trading, and provides details on the Kirin API and order book functionality.

High frequency trading, fixed income trading through auctions and market trading, and information valuation trading are discussed.

Information such as bond details, limits, and case details are provided about bonds.

2020 Fall Competition

Case Packet

[email protected]
traders.mit.edu

October 28, 2020


Contents

1 Introduction 4

1.1 Schedule of Events . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5

1.2 Piazza . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5

2 High-Frequency Trading (HFT) 6

2.1 Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6

2.2 How Trading Works . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6

2.3 Limits . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7

2.3.1 Position limits . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7

2.3.2 Rate limits . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7

2.3.3 Open order limits . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7

2.3.4 Memory Limits . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7

2.4 How Your Code Will Be Run . . . . . . . . . . . . . . . . . . . . . . . . . . 7

2.5 AWS and Building Kirin . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8

2.5.1 AWS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8

2.5.2 AWS Recommendations . . . . . . . . . . . . . . . . . . . . . . . . 8

2.5.3 Running Kirin with Your Bot . . . . . . . . . . . . . . . . . . . . . 8

2.6 Writing Your Bot . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8

2.6.1 Callback Model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9

2.6.2 Placing and Cancelling Orders . . . . . . . . . . . . . . . . . . . . 9

2.7 Evaluating Performance . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9

1
2.8 Scoring . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9

2.9 Advice . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9

3 Fixed Income 10

3.1 Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10

3.2 How Trading Works . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10

3.2.1 Auctions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10

3.2.2 Market Trading . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11

3.2.3 Customer Orders . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11

3.3 Information about Bonds . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12

3.4 Limits . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13

3.5 Case Details . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13

4 Five Rings Information Valuation 14

4.1 Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14

4.2 Technical Details . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14

5 Kirin API 15

5.1 Kirin Callbacks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15

5.1.1 Initialization . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15

5.1.2 Order Updates . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15

5.1.3 Order Reject . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16

5.1.4 Trade Updates . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16

5.1.5 Cancel Updates . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17

5.1.6 Cancel Reject . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17

5.1.7 Packet start / end . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17

5.2 Submitting Orders . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17

5.2.1 Submitting Order . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18

5.2.2 Canceling Order . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18

2
5.3 Order Book . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18

3
1 Introduction

Traders@MIT welcomes you to our 13th Annual Intercollegiate Trading Competition!


We are excited to be holding the competition virtually this year and are confident that
it will provide a rich and challenging learning experience. The competition will be held
on Saturday and Sunday, November 7th and 8th.

Our competition consists of electronic trading. Teams will be ranked overall based
on their total weighted rankings from each of the three cases. Between rounds, you will
also have several opportunities to speak with our attending sponsors.

There will be programming from 12:00 PM to 7:00 PM ET on both Saturday and


Sunday. Competitors are required to attend all networking events over the two days,
and up to 100 dollars in dining expenses will be reimbursed.

Our sponsors for this year’s competition are:

Diamond: Citadel, DRW, Five Rings Capital, Jane Street Capital

Gold: IMC Trading

Silver: Barclays, Cubist, D. E. Shaw, Flow Traders, Schonfeld Strategic Advisors, SIG,
Tower Research

Bronze: G-Research, Headlands Technologies, Vatic Labs

The three cases are: High-Frequency Trading, Fixed Income, and the Five Rings Cap-
ital Information Valuation case. The High-Frequency Trading case will be algorithmi-
cally traded using our low-latency C++ exchange, Kirin. Competitors must algorithmi-
cally trade and cannot click trade. You will be expected to submit your code before the
day of the competition.

The two cases held on competition day are Fixed Income and Information Valuation.
Relatively little advance preparation is expected, but we’d recommend familiarizing
yourself with statistical analysis packages in Python and installing relevant packages
on the laptop you’ll be using. More information on the cases can be found in the fol-
lowing sections.

4
1.1 Schedule of Events

Note that all events in this schedule are mandatory for competitors to attend if they
wish to receive dining reimbursements and be eligible for prize money; attendance
will be taken. If this is not possible for you, then please email [email protected]
with a detailed reason as to why you have a conflict with any of the events.

Saturday, November 7 (all times in ET)

12:00PM – 12:30PM Opening Remarks


12:30PM – 1:00PM Case 1: High-Frequency Trading
1:00PM – 3:00PM Case 2: Fixed Income
3:00PM – 4:00PM Poker with Sponsors
4:00PM – 5:30PM Citadel Event
5:30PM – 7:00PM Jane Street Event

Sunday, November 8 (all times in ET)

12:00PM – 3:00PM Case 3: Five Rings Capital Information Valuation


3:00PM – 4:00PM Diamond and Gold Sponsor Panel
4:00PM – 5:00PM DRW Event
5:00PM – 6:00PM Networking
6:00PM – 7:00PM Awards Ceremony

1.2 Piazza

We have created a Piazza forum to answer questions about cases and any other ques-
tions you may have. Most of our updates and announcements will be placed here,
so it is in your best interest to be on this forum. We will be answering all questions
through this forum, and not by email:

https://piazza.com/mit/fall2020/tamit2020

Traders@MIT executive board members will do our best to reply to all questions within
24 hours.

5
2 High-Frequency Trading (HFT)

2.1 Overview

In this case, you will implement a low-latency trading strategy in C++ to trade a single
stock in a standard limit order book. At a high level, you could profit in this case by:

1. Market making (i.e. putting in limit orders around the fair price, in the hopes of
earning the bid-ask spread)

2. Exploiting signals in market microstructure (i.e. exploiting information leaked by


other market participants by their trading patterns)

2.2 How Trading Works

Trading occurs through a limit order book. You place limit orders, which indicate will-
ingness to buy/sell a certain quantity at or below/above a certain price. If your order
matches with limit orders already on the book (i.e. someone had previously indicated
willingness to take a trade in the opposite direction at the price you indicated), then a
trade occurs at the price of the limit order already on the book. The limit orders on the
book are matched to yours in order of best price, with ties broken by earliest time. If the
quantity of your order is not filled completely by such trades, the remaining quantity is
inserted as a limit order into the book, unless it is marked immediate-or-cancel (IOC),
in which case the remaining quantity is discarded.

You can also cancel limit orders you have placed.

All prices are multiples of $0.01, referred to as one tick.

All participants in the market get updates for all order insertions, cancels, and trades.

6
2.3 Limits

2.3.1 Position limits

We are imposing position limits on the security: you may not hold more than 2000
shares, or have open orders out that could be filled in a way that would cause you to
hold more than 2000 shares.

To be clear, we will not allow you to submit an order if it and your other open orders
can be filled in a way that allows you to exceed your position limit. For example, you
would not be able to put in a bid for 1500 shares if you already hold 800 shares.

2.3.2 Rate limits

You may not perform more than 10000 actions in any 10-second period, where an action
is an order placement or a cancel. An action will be rejected if 10000 actions have been
performed in the last 10 seconds.

2.3.3 Open order limits

You will not be allowed to have more than 500 open orders. We will reject any order if
you already have 500 open orders out.

2.3.4 Memory Limits

You must not use more than 1GB of memory, including the heap and the data segment
of your program. Your process may be killed if you do so. You shouldn’t need to use
anywhere near this much memory for this case.

2.4 How Your Code Will Be Run

For you to test your bots before the competition, we will provide you with an object
file containing Kirin that you can use to compile and run your bot.

However, during the actual competition, you will just submit your competitor.cpp
file containing your bot, which will then run in a separate process from Kirin, and will
communicate through shared memory.

The code submission deadline for this case is 11:59pm ET on Thursday, October 5, 2020.
We will run and score each team’s submission before the competition, and announce
the result on competition day.

7
2.5 AWS and Building Kirin

2.5.1 AWS

Before accessing your AWS instance, you’ll need to start it using our web interface
(instructions on Piazza). Afterward, use the IP address and password provided to you
via email. In a terminal, type:

ssh ec2-user@{ip}

But replace {ip} the the IP address which you received from us (e.g. 68.53.237.147).

2.5.2 AWS Recommendations

Depending on your machine, you may have to install software that will let you use
ssh. Additionally, if you would like to develop in a local text editor without having
to transfer files to and from your AWS instance, we recommend checking out sshfs or
Unison.

2.5.3 Running Kirin with Your Bot

In the competitor-files directory, simply type make to compile, followed by:

./kirin 1 start Kirin, expecting 1 competitor bot.

./mybot run your bot.

These commands should be run in separate terminal sessions (unless you want to
run Kirin in the background). The main method we have written in competitor.cpp
will register your bot and run the case for infinitely long.

In a third terminal session (or another background process), you can run python3
print_book.py, which periodically prints the book logged by our sample code in book.log.

2.6 Writing Your Bot

You will want to edit the various callbacks we have provided you for market updates
etc. in the MyBot class in competitor.cpp. Search for EDIT THIS METHOD in the file to
see where to go. We have provided a lot of code for maintaining the state of the order
book, your open orders, etc. in the MyState class. Feel free to edit this class (there may
be benefits to improving its performance) or get rid of it entirely.

There is some sample code in the MyBot class that shows you how to place and cancel
orders.

8
2.6.1 Callback Model

Your bot will get callbacks whenever an order is inserted/cancelled/rejected, a trade


occurs, or a cancel is rejected. For the API, see Section 5.

2.6.2 Placing and Cancelling Orders

See the sample code already in competitor.cpp for examples, and see the API in Sec-
tion 5. There is only one stock being traded in this case, and it is denoted with .ticker
= 0 in orders/cancels. Note that the sample code hardly qualifies as a strategy and is
just for demonstrational purposes.

Orders must have strictly positive prices and quantities. Cancels must have a valid
order ID that you are the owner of.

2.7 Evaluating Performance

The code we have provided runs indefinitely. The most relevant statistic is PNL per
second, which we print out in the sample code every time your bot makes a trade. You
should be aiming to get hundreds of dollars per second.

2.8 Scoring

Every round will be a 1v1 with another team and will last exactly 60 seconds. At the
end of the round, the team with the higher PnL wins. We will run a simple round robin,
and rank the teams by number of wins. We will then run a final round with the top 10
teams running simultaneously to determine the overall results.

2.9 Advice

For determining signals, you should be looking at the order book (quantities, prices)
and how it changes in time, and trades (directions, quantities, prices) and how they
occur over time.

The market dynamics of this case will differ markedly when you are competing against
other teams compared to when you test by yourself. Note that you are essentially
competing to exploit the same inefficiencies created by our internal bots.

Thus, you want your code to be robust to different market conditions (e.g. a tighter
spread). Additionally, engineering your code to be low-latency will help you beat other
teams. One way to test the effect of latency is to run a slow version of your bot against
a fast version of your bot.

9
3 Fixed Income

3.1 Overview

In this case, you will manually trade bonds. Your goal will be to maximize the amount
of money you make in a given round relative to other teams in your exchange.

3.2 How Trading Works

There will be three ways to participate in trades: bidding in auctions, trading with
other competitors, and providing to customers.

3.2.1 Auctions

The primary way to acquire bonds is by bidding in auctions. Each year, you can place
bids for any bond expiring at most N years from the current year (N is to be deter-
mined). Each bid will only specify a size (or amount of notional). At the end of the
year, all auctions will be conducted, and bonds will be allocated to teams based on
their bids.

Each bond auction is at a fixed price (or yield), and has a certain size (amount of no-
tional) available. For a given bond auction, if the sum of all teams’ bids is less than the
size available, then all teams will receive the amount they bid for that bond. Otherwise,
each team will receive an amount proportional to their bid.

For example, suppose a bond X expiring in 2020 is up for auction with $100000 no-
tional available. If the bids are as follows:

• Team 1: $20000

• Team 2: $30000

• Team 3: $40000

then each team will receive their bid amount in notional of X expiring 2020.

10
However, if the bids are as follows:

• Team 1: $60000

• Team 2: $70000

• Team 3: $70000

then since the total sum of bids is $200000, the payout will be as follows:

• Team 1: receives $30000 notional of X expiring 2020

• Team 2: receives $35000 notional of X expiring 2020

• Team 3: receives $35000 notional of X expiring 2020

Bond expirations are essentially 1-indexed, so in year Y, bonds expiring in year Y


will be sold at auction, be treated as expiring in one year, and expire immediately.

3.2.2 Market Trading

You will also be able to trade with other teams on an open market.

Trading occurs through a limit order book. You place limit orders, which indicate will-
ingness to buy (sell) a certain amount of notional at or above (below) a certain yield.
Note that yield is inversely related to price. If your order matches with limit orders
already on the book (i.e. someone had previously indicated willingness to take a trade
in the opposite direction at the yield you indicated), then a trade occurs at the yield of
the limit order already on the book (the limit orders on the book are matched to yours
in order of best yield, with ties broken by earliest time). If the quantity of your order is
not filled completely by such trades, the remaining quantity is inserted as a limit order
into the book.

You can also cancel limit orders you have placed.

All prices are multiples of 0.1% (subject to change), referred to as one tick.

A live order book will be displayed for each tradeable bond.

3.2.3 Customer Orders

Periodically, customers will ask to buy certain bonds from you. These customers will
appear to different teams at different times, and will be announced to your team the
year before the order is available.

11
3.3 Information about Bonds

A bond is a financial instrument that pays out a fixed coupon every year until maturity
(as a percentage of its notional value), and pays out its notional value at expiration. For
example, if you own $100 notional of a bond with a 2% coupon expiring 5 years from
now, you will receive $2 every year for the next five years and $100 in five years (along
with the coupon payment for that year). So, you will receive $110 total over five years.

The payout structure, more explicitly, is as follows:

• $2 after 1 year

• $2 after 2 years

• $2 after 3 years

• $2 after 4 years

• $102 after 5 years

The notional value of a bond is just a face value used to calculate its payout structure,
and is not related to how much you might pay for the bond, as bonds are tradeable on
the market. If you pay some amount for a bond, then the average rate your money
grows at based on the payout structure is the yield for that bond. So, yield is inversely
related to price, and is just another way to state the price. However, you will trade
bonds by specifying a yield (in percent), rather than by specifying a price in dollars.

For a bond expiring in T years, a notional amount N, and a coupon payment C per
year, the price P is related to the yield Y (in percent) by the following formula:

C C C C+N
P= + +···+ −
+ .
1 + Y/100 (1 + Y/100) 2 (1 + Y/100) T 1 (1 + Y/100)T

The coupon fraction is C/N. So if the bond had a 2% coupon, then C/N would be
0.02. Note that P is approximately N for low values of C and Y. For the above bond
($100 notional with 2% coupon expiring in 5 years), if you buy it at a 2% yield, you pay

2 2 2 2 102
P= + + + + = 100.
1.02 1.022 1.023 1.024 1.025

This equality makes sense; if the yield is equal to the coupon, you pay the notional
amount. For a yield > 2%, you would pay < $100.

Because yield is inversely related to price, buying a bond at a low yield is akin to
buying it for a high price. Note that yield can be negative. The market for a bond then
has buy orders at higher yields than sell orders.

12
3.4 Limits

The sum of the notionals in all your open buy orders and bids cannot exceed the
amount of capital you have. Also, the amount of notional in open sell orders for a
bond cannot exceed the amount of that bond you possess. You will be prevented from
making orders or bids that violate these bounds.

3.5 Case Details

We will send specific case details the day before the competition. The case will be held
on Discord. Please make a Discord account if you do not already have one and submit
your username using this form:

https://tinyurl.com/traders2020discord

13
4 Five Rings Information Valuation

4.1 Overview

For the Information Valuation case, you will have the opportunity to buy and sell as-
sets, as well as the opportunity to buy certain data sources that may or may not predict
price movement. Your goal will be to build a bot that uses the purchasable data to
make good trades. To do so, you will need to determine which data sources are useful
and what predictive models work best.

You will not receive any training or testing data to begin. All data must be purchased
via your bot. There is no bid-ask spread, and you will not be trading against other
competitors. Instead, we will run your strategy on a test data set, and your goal is to
maximize your profit over all time steps.

Successful competitors will be able to determine the informational advantage of vari-


ous signals, build good predictive models, and allocate funds to best take advantage of
price changes.

4.2 Technical Details

In this case, you will periodically submit a Python bot that executes your strategy for
you. We will provide some starter code for convenience, though you will be expected
to write Python code (both to improve your bot, and to analyze results). Code perfor-
mance is not a priority, though particularly slow submissions may be disqualified.

Once you submit your bot for a round, your bot will be evaluated on many timesteps.
As feedback, you will receive your profits for that round, price data, and the specific
data you chose to buy. You will then be able to use this information to improve your
bot for the next round. The event will last 2-2.5 hours, with each round lasting 5-30
minutes.

A more detailed case packet will be made available at the beginning of the case. You are
not expected to work on this case before the competition, though familiarity with data
science packages (e.g. matplotlib, sklearn, and numpy) as well as Jupyter notebooks,
is recommended.

14
5 Kirin API

5.1 Kirin Callbacks

Kirin uses a callback mechanism to deliver updates to your bot about the market. You
can find these callbacks in MyBot in competitor.cpp, and you are responsible for im-
plementing them. The callbacks mechanism are implemented in AbstractBot, which
internally polls our system for market updates and delivers to you with the appropriate
call back.

It’s important to recognize that every update on the market from other people are for-
warded to your callbacks, not just your activities.

It’s important that calls backs return since everything in your bot is single threaded,
and you won’t get another update until a call back that is invoked returns.

Each callback takes Bot::Communicator& object which is what you use to submit and
cancel orders. You are allowed to submit orders any time.

We describe the types of call back below. For more details, refer to competitor.cpp
where sample usage is outlined. You can find the definition of structs used in the
callbacks in kirin.hpp.

5.1.1 Initialization

void init(Bot::Communicator& com)

You should use this callback to initialize your bot with state. Its only called once at the
beginning of the case.

5.1.2 Order Updates

void on_order_update(Common::OrderUpdate & update, Bot::Communicator& com)

Orders submitted to Kirin are associated with a unique order ID.

15
This is called every time an order happens on Kirin. The update object is a struct that
contains the ticker, price, and quantity.

Layout of OrderUpdate:

struct OrderUpdate {
ticker_t ticker; // ticker symbol (0 for HFT 2019)
price_t price; // price of order
quantity_t quantity; // quantity of order
order_id_t order_id; // order id, unique across all orders
bool buy; // direction of buy
}

5.1.3 Order Reject

void on_reject_order_update(Common::RejectOrderUpdate& update, Bot::Communicator&


com)

This is called when an order gets rejected by Kirin.

struct RejectOrderUpdate {
ticker_t ticker;
order_id_t order_id; // order id that was rejected
RejectReason reason; //reason for rejection
}

5.1.4 Trade Updates

void on_trade_update(Common::TradeUpdate& update, Bot::Communicator& com)

This is called every time a trade happens on the the market and the update contains
which orders traded, at what price and quantity.

struct TradeUpdate {
ticker_t ticker;
price_t price;
quantity_t quantity; //quantity traded
order_id_t resting_order_id; // order id that was already on the book
order_id_t aggressing_order_id; // order id that arrived and traded
bool buy; // direction of aggressing order
}

16
5.1.5 Cancel Updates

void on_cancel_update(const Common::CancelUpdate& update)

Called when a cancel is accepted on Kirin. This is the struct layout for Cancel Update:

struct CancelUpdate {
ticker_t ticker;
order_id_t order_id; // order id that was canceled
}

5.1.6 Cancel Reject

void on_cancel_reject(const Common::CancelUpdate& update)

Called when a cancel is rejected on Kirin. Possible reasons for rejection could be that
the order is not active on Kirin, order limits have been exceeded, etc.

struct RejectCancelUpdate{
ticker_t ticker; // ticker
order_id_t order_id; // order id of rejected cancel
RejectReason reason; // reason for rejection
}

5.1.7 Packet start / end

Messages are delivered as packets to our internal system. A packet can contain multi-
ple order/trade updates.

void on_packet_start(Communicator& com)


Called at the beginning of every packet .

void on_packet_end(Communicator& com)


Called at the end of every packet.

5.2 Submitting Orders

The callbacks noted above take in a Communicator object, which you can use to submit
/ cancel orders.

17
5.2.1 Submitting Order

order_id_t place_order(Bot::Communicator& com, const Common::Order& order)

Places an order to Kirin. The order struct has an extra member "trader_id" compared
to the struct OrderUpdate. You should set this to your trader id, otherwise you will get
OrderReject callbacks.

5.2.2 Canceling Order

void place_cancel(Bot::Communicator& com, const Common::cancel& cancel)

Places a cancel to Kirin. The cancel struct has an extra member "trader_id" compared
to struct OrderUpdate. You should set this to your trader id, otherwise you will get
CancelReject callbacks.

5.3 Order Book

The provided MyBot implementation also maintains an order book per ticker. You have
full freedom to implement your own order book. If you want to use the one we pro-
vided, make sure to maintain the calls to it in the callbacks. The order book provides
functionality to get:

Best price:

price_t get_bbo(bool buy) // current best price to buy stock if "buy" is true, or to
sell if buy is false.

Mid price:

price_t get_mid_price(price_t default_to) //returns mid price of stock if its non


zero, or default_to otherwise

Printing the book:

void print_book(std::string fp, const std::unordered_map<order_id_t, Common::Order>&


mine={}) // prints current state of book into fp, and marks orders are in the "mine" set.
Prints "EOF" at the end of the input.

18
Quote Size:

quantity_t quote_size(bool buy) //returns quote size on the side of buy provided

Spread:

price_t spread() //returns the spread of the ticker

19

You might also like