Skip to content

Algothon Guidelines + Brief

Preliminary round submissions are due 9:00AM AEST 14 July. 5 teams will proceed to the final round, held at 6:00PM AEST 21 July and judged by SIG traders in office.

We recommend that each team have at least one member with programming experience in Python, as well as financial knowledge. Impressive submissions will be expected to involve reasonably advanced data analysis and implementation of reasonably sophisticated trading strategies.


Objective

Develop a trading strategy algorithm to perform optimally given certain metrics.

How to Get Started

  1. Assess provided price data from our simulated trading universe.
  2. Build a predictive model.
  3. Back-test the predictive model across given price data.
  4. Evaluate your algorithmic strategy.
  5. Hope for the best (just kidding!).
  6. Consider factors such as optimisation and risk analysis. Topics that may be explored include:
    • Optimising for trade frequency.
    • Projections for worst-case scenarios and methods to mitigate this.
    • Considering risk factors, and techniques to minimise risk.

For more information, make sure to take a look at our learning resources and technical advice page!


Case Brief

Task

Implement a function getMyPosition() which

  • Takes as input a NumPy array of the shape nInst x nt.
    • nInst = 100 is the number of instruments.
    • nt is the number of days for which the prices have been provided.
  • Returns a vector of desired positions.
    • i.e. This function returns a NumPy vector of integers. This integer denotes your daily position per instrument in the universe. With 100 instruments, we can expect this function to return 100 integers each time it is called.

Data

All required data has been generated by us, and is available here Work in progress. We'd highly recommend cloning this repo to use a base for your algorithm development, and to make it easier for submission.

  • Our simulated trading universe consists of several years of daily price data, spanning 100 instruments.
  • The instruments are numbered from 0 to 99, and days go chronologically from 0 onwards such that p[inst, t] indicates the price of the instrument inst on day t.
  • The price data file contains a NumPy array of the shape nInst x nt.
    • nInst = number of instruments, nt = number of days.

In the preliminary round, teams will be provided the first 250 days of price data to be used as training data. This can be found in prices250.txt.

  • Preliminary round algorithms will be assessed on data from days 251 - 500.
  • Successful teams will then receive price data and results from preliminary evaluation.
  • Final round algorithms will be assessed on remaining future price data.

The Algorithm

Format

Algorithms must be contained in a file titled [teamName].py.

  • This file must contain a function getMyPosition().
  • getMyPosition() must take in the daily price data, and output a vector of integer positions - the numbers of shares desired for each stock as the total final position after the last day.
  • getMyPosition() must be in the global scope of the file called [teamName].py and have the appropriate signature.
    • The function will be called once a day, with the entire price history up to and including that day. For example, on day 240, your function should take as input an array of 100 inst x 240 days.
    • When getMyPosition() is called, we will trade position differences from the previous position at the most recent price, buying or selling.
    • Consider the case where your last position was +30, and the new stock price is $20. If your new position is +100, eval will register this as buying 70 extra shares at $20 a share. If your new position is -200, eval will sell 230 shares also at $20 a share.

Accepted Packages

To ensure that code runs smoothly on the servers used for marking, we advise the following:

  • Use only standard packages and their respective versions from the Anaconda library. The best way to do this is to simply download Anaconda...
  • Where necessary, packages that are not included as part of Anaconda, or version numbers that are greater than those provided in Anaconda need to be declared in the submission form in the relevant section.

We will attempt to import and run through all non-standard packages if declared. However, in the case that your code still does not run, your team will be disqualified. Similarly, if your submission does not declare a non-standard package or provide a brief description of its use, it will also be disqualified.

Considerations

  • A commission rate of 25 bps (0.0025) can be assumed, meaning you will be charged commission equating 0.0025 * totalDollarVolumeTraded. This will be deducted from your PL.
  • Positions can be long or short (i.e. the integer positions can be either positive or negative).
  • Teams are limited to a $10k position limit per stock, positive or negative. The $10k limit cannot be breached at the time of the trade.
    • This position limit may technically be exceeded in the case that exactly $10k worth of a stock is bought, and stock goes up the next day - this is fine.
    • However, given this occurs, the position must be slightly reduced to be no greater than $10k by the new day's price.
    • Note: eval.py contains a function to clip positions to a maximum of $10k. This means that if the price is $10 and the algorithm returns a position of 1500 shares, eval.py will assume a request of 1000 shares.

Assessment Benchmarks

The program we will use to evaluate your algorithm is provided in eval.py

Metrics used to quantitatively assess your submission will include:

  • PL (daily and mean),
  • Return (net PL / dollarVolumeTraded),
  • Sharpe Ratio, and
  • Trading volume.

Your algorithms will be assessed against unseen, future price data of the same 100 instruments within the provided simulated trading universe.

We expect algorithms to have a maximum runtime of ~10min.

Submission

Submission details can be found on our Submission page.

Ensure that all code submitted is tested against eval.py This will be the test used to evaluate the performance of your algorithm.

Judging criteria can be found here.