Metadata-Version: 2.4
Name: prosperity4btest
Version: 0.3.0
Summary: Backtester for IMC Prosperity 4 algorithms
Author-email: Nabayan Saha <nabayansaha214@gmail.com>
License: MIT License
        
        Copyright (c) 2024 Jasper van Merle
        
        Permission is hereby granted, free of charge, to any person obtaining a copy
        of this software and associated documentation files (the "Software"), to deal
        in the Software without restriction, including without limitation the rights
        to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
        copies of the Software, and to permit persons to whom the Software is
        furnished to do so, subject to the following conditions:
        
        The above copyright notice and this permission notice shall be included in all
        copies or substantial portions of the Software.
        
        THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
        IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
        FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
        AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
        LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
        OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
        SOFTWARE.
        
Project-URL: Repository, https://github.com/nabayansaha/imc-prosperity-4-backtester
Project-URL: Issues, https://github.com/nabayansaha/imc-prosperity-4-backtester/issues
Project-URL: Changelog, https://github.com/nabayansaha/imc-prosperity-4-backtester/releases
Keywords: imc,prosperity,backtest,backtester
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Financial and Insurance Industry
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: ipython>=8.18.1
Requires-Dist: jsonpickle>=4.0.2
Requires-Dist: orjson>=3.10.15
Requires-Dist: tqdm>=4.67.1
Requires-Dist: typer>=0.15.2
Dynamic: license-file

# IMC Prosperity 4 Backtester

[![Build Status](https://github.com/nabayansaha/imc-prosperity-4-backtester/workflows/Build/badge.svg)](https://github.com/nabayansaha/imc-prosperity-4-backtester/actions/workflows/build.yml)

This repository contains a backtester for [IMC Prosperity 4](https://prosperity.imc.com/) algorithms, based on [jmerle's backtester for Prosperity 3](https://github.com/jmerle/imc-prosperity-3-backtester).

## Usage

Basic usage:
```sh
# Install the latest version of the backtester
$ pip install -U prosperity4btest

# Run the backtester on an algorithm using all data from round 0
$ prosperity4btest <path to algorithm file> 0
```

Run `pip install -U prosperity4btest` again when you want to update the backtester to the latest version.

The PyPI distribution and CLI are named `prosperity4btest`. The Python package directory is still `prosperity4bt` (e.g. bundled data lives under `prosperity4bt/resources`).

Some more usage examples:
```sh
# Backtest on all days from round 1
$ prosperity4btest example/starter.py 1

# Backtest on round 1 day 0
$ prosperity4btest example/starter.py 1-0

# Backtest on round 1 day -1 and round 1 day 0
$ prosperity4btest example/starter.py 1--1 1-0

# Backtest on all days from rounds 1 and 2
$ prosperity4btest example/starter.py 1 2

# You get the idea

# Merge profit and loss across days
$ prosperity4btest example/starter.py 1 --merge-pnl

# Automatically open the result in the visualizer when done
# Assumes your algorithm logs in the visualizer's expected format
$ prosperity4btest example/starter.py 1 --vis

# Write algorithm output to custom file
$ prosperity4btest example/starter.py 1 --out example.log

# Skip saving the output log to a file
$ prosperity4btest example/starter.py 1 --no-out

# Backtest on custom data
# Requires the value passed to `--data` to be a path to a directory that is similar in structure to https://github.com/nabayansaha/imc-prosperity-4-backtester/tree/master/prosperity4bt/resources
$ prosperity4btest example/starter.py 1 --data prosperity4bt/resources

# Print trader's output to stdout while running
# This may be helpful when debugging a broken trader
$ prosperity4btest example/starter.py 1 --print
```

## Order Matching

Orders placed by `Trader.run` at a given timestamp are matched against the order depths and market trades of that timestamp's state. Order depths take priority, if an order can be filled completely using volume in the relevant order depth, market trades are not considered. If not, the backtester matches your order against the timestamp's market trades. In this case the backtester assumes that for each trade, the buyer and the seller of the trade are willing to trade with you instead at the trade's price and volume. Market trades are matched at the price of your orders, e.g. if you place a sell order for €9 and there is a market trade for €10, the sell order is matched at €9 (even though there is a buyer willing to pay €10, this appears to be consistent with what the official Prosperity environment does).

Matching orders against market trades can be configured through the `--match-trades` option:
- `--match-trades all` (default): match market trades with prices equal to or worse than your quotes.
- `--match-trades worse`: match market trades with prices worse than your quotes, inspired by [team Linear Utility's Prosperity 2 write-up](https://github.com/ericcccsliu/imc-prosperity-2).
- `--match-trades none`: do not match market trades against orders.

Limits are enforced before orders are matched to order depths. If for a product your position would exceed the limit, assuming all your orders would get filled, all your orders for that product get canceled. During matching, each fill is also clamped so your position never goes beyond the configured limit (even if multiple price levels would otherwise fill more).

### Position limits

Known Prosperity 4 products are defined in `prosperity4bt/data.py` (`LIMITS`). The tutorial round uses **80** for `EMERALDS` and `TOMATOES`. Any product not listed there uses a default of **50** until you add it to `LIMITS`.

Override limits from the CLI without editing code:

```sh
prosperity4btest sample.py 0 --limit EMERALDS:80 --limit TOMATOES:80
```

## Data Files

Data files for Prosperity 4 rounds will be added as they become available.

Conversions are not supported.

## Environment Variables

During backtests two environment variables are set for the trader to know the round and day it's being backtested on. The environment variable named `PROSPERITY4BT_ROUND` contains the round number and `PROSPERITY4BT_DAY` contains the day number. Note that these environment variables do not exist in the official submission environment, so make sure the code you submit doesn't require them to be defined.

## Development

Follow these steps if you want to make changes to the backtester:
1. Install [uv](https://docs.astral.sh/uv/).
2. Clone (or fork and clone) this repository.
3. Open a terminal in your clone of the repository.
4. Create a venv with `uv venv` and activate it.
5. Run `uv sync`.
6. Any changes you make are now automatically taken into account the next time you run `prosperity4btest` inside the venv.

## Publishing to PyPI

Releases are built and published with [GitHub Actions](.github/workflows/build.yml) using [trusted publishing](https://docs.pypi.org/trusted-publishers/) (no long-lived PyPI token in the repo).

1. On [PyPI](https://pypi.org), open **Account settings** → **Publishing** → **Add a new pending publisher**.
2. Set **PyPI project name** to `prosperity4btest`, **Owner** to `nabayansaha`, **Repository name** to `imc-prosperity-4-backtester`, **Workflow name** to `build.yml`, and **Environment name** to `pypi`.
3. On GitHub: repository **Settings** → **Environments** → create an environment named `pypi` (no protection rules required unless you want them).
4. Tag and push a version; the workflow replaces `version = "0.0.0"` in `pyproject.toml` with the tag name and uploads the wheel and sdist:

```sh
git tag 0.1.0
git push origin 0.1.0
```

The `publish` job only runs on tag pushes. The project name must match your pending publisher (`prosperity4btest`).
