Imc Prosperity 2
My IMC Prosperity 2 code (9th place)
Install / Use
npx skills add jmerle/imc-prosperity-2Installs into whichever agent you are using.
README
IMC Prosperity 2
This repository contains the IMC Prosperity 2 code of my solo team named "camel_case".
Final position: 9th overall, 3rd in Europe, 1st in the Netherlands.
This is a list of all my open-source Prosperity 2 tools:
- jmerle/imc-prosperity-2-visualizer is a visualizer for results of submissions and local backtests (available online at jmerle.github.io/imc-prosperity-2-visualizer/).
- jmerle/imc-prosperity-2-backtester is a backtester that allows locally running algorithms on the provided data files.
- jmerle/imc-prosperity-2-submitter is a CLI that allows submitting algorithms from the command-line.
- jmerle/imc-prosperity-2-leaderboard is an alternative leaderboard viewer (available online at jmerle.github.io/imc-prosperity-2-leaderboard/).
Round results
<table> <thead> <tr> <th></th> <th colspan="4" style="text-align: center">Profit / loss</th> <th colspan="4" style="text-align: center">Leaderboard position</th> <th colspan="2" style="text-align: center">Visualizer links</th> </tr> <tr> <th></th> <th>Overall</th> <th>Manual</th> <th>Algo</th> <th>Round</th> <th>Overall</th> <th>Manual</th> <th>Algo</th> <th>Country</th> <th>Submission</th> <th>Final</th> </tr> </thead> <tbody> <tr> <td><a href="https://github.com/jmerle/imc-prosperity-2/blob/master/src/submissions/round1.py">1</a></td> <td>133,761</td> <td>102,028</td> <td>31,733</td> <td>133,761</td> <td>210</td> <td>349</td> <td>265</td> <td>10</td> <td><a href="https://jmerle.github.io/imc-prosperity-2-visualizer/?open=https://raw.githubusercontent.com/jmerle/imc-prosperity-2/master/logs/round1-submission.log">Link</a></td> <td><a href="https://jmerle.github.io/imc-prosperity-2-visualizer/?open=https://raw.githubusercontent.com/jmerle/imc-prosperity-2/master/logs/round1-final.log">Link</a></td> </tr> <tr> <td><a href="https://github.com/jmerle/imc-prosperity-2/blob/master/src/submissions/round2.py">2</a></td> <td>842,398</td> <td>113,938</td> <td>594,698</td> <td>708,636</td> <td>6</td> <td>319</td> <td>6</td> <td>1</td> <td><a href="https://jmerle.github.io/imc-prosperity-2-visualizer/?open=https://raw.githubusercontent.com/jmerle/imc-prosperity-2/master/logs/round2-submission.log">Link</a></td> <td><a href="https://jmerle.github.io/imc-prosperity-2-visualizer/?open=https://raw.githubusercontent.com/jmerle/imc-prosperity-2/master/logs/round2-final.log">Link</a></td> </tr> <tr> <td><a href="https://github.com/jmerle/imc-prosperity-2/blob/master/src/submissions/round3.py">3</a></td> <td>985,116</td> <td>78,577</td> <td>64,141</td> <td>142,718</td> <td>9</td> <td>452</td> <td>11</td> <td>1</td> <td><a href="https://jmerle.github.io/imc-prosperity-2-visualizer/?open=https://raw.githubusercontent.com/jmerle/imc-prosperity-2/master/logs/round3-submission.log">Link</a></td> <td><a href="https://jmerle.github.io/imc-prosperity-2-visualizer/?open=https://raw.githubusercontent.com/jmerle/imc-prosperity-2/master/logs/round3-final.log">Link</a></td> </tr> <tr> <td><a href="https://github.com/jmerle/imc-prosperity-2/blob/master/src/submissions/round4.py">4</a></td> <td>1,331,214</td> <td>102,592</td> <td>234,505</td> <td>346,097</td> <td>9</td> <td>349</td> <td>9</td> <td>1</td> <td><a href="https://jmerle.github.io/imc-prosperity-2-visualizer/?open=https://raw.githubusercontent.com/jmerle/imc-prosperity-2/master/logs/round4-submission.log">Link</a></td> <td><a href="https://jmerle.github.io/imc-prosperity-2-visualizer/?open=https://raw.githubusercontent.com/jmerle/imc-prosperity-2/master/logs/round4-final.log">Link</a></td> </tr> <tr> <td><a href="https://github.com/jmerle/imc-prosperity-2/blob/master/src/submissions/round5.py">5</a></td> <td>1,700,672</td> <td>115,500</td> <td>253,956</td> <td>369,457</td> <td>9</td> <td>160</td> <td>8</td> <td>1</td> <td><a href="https://jmerle.github.io/imc-prosperity-2-visualizer/?open=https://raw.githubusercontent.com/jmerle/imc-prosperity-2/master/logs/round5-submission.log">Link</a></td> <td><a href="https://jmerle.github.io/imc-prosperity-2-visualizer/?open=https://raw.githubusercontent.com/jmerle/imc-prosperity-2/master/logs/round5-final.log">Link</a></td> </tr> </tbody> </table>Round summaries
Tutorial round
I spent most of the tutorial round building developer tooling for later rounds. I made all of them open-source (visualizer, backtester, and submitter), and although I didn't embed analytics in them, based on Discord messages I believe a significant number of participants used at least one of them :).
After building developer tools I spent about a day on building a market-making algorithm for amethysts and starfruit. I took some inspiration from the code of the team that finished 2nd in IMC Prosperity 1, especially their use of the popular buy/sell price, i.e. the buy/sell price with maximum volume. For amethysts I assumed a true value of 10k, and for starfruit I assumed a true value in the middle between the popular buy and sell prices. I also found some improvement in adding soft/hard liquidation procedures, which would force a buy or a sell at less-than-usual prices to get out of prolonged positions at the boundary of the limit (position = limit or position = -limit), because in those positions we can no longer market-make in both directions.
Based on Discord messages from other participants I also tried to do some sort of linear regression on starfruit, but couldn't get that to work profitably.
Round 1
The algo side of round 1 appeared to be a continuation of the tutorial round on new data. I tried to improve my market making strategy, but couldn't improve on my tutorial code, so ended up submitting that without any changes.
For the manual side I took 10M random reserve prices according to the given distribution and ran a grid search over all possible low/high bid combinations. This resulted in a maximum profit of 204M with a price-per-fish at 33.6 (considering only the fishes that we took up on their offer) or 20.4 (considering all 10M fishes in the simulation) using a low bid of 952 and a high bid of 978. After the round ended Edgar Maddocks published a write-up of a closed-form solution that resulted in the same bids, which served as a pleasant confirmation that my simulation was accurate.
Round 2
The algo side of round 2 had me struggling. Even though many people on Discord were claiming 60k+ and eventually even 100k+ profits, I couldn't get past a few thousands in profit. I posted about my struggles on Discord about 6 hours before the round ended, and got two surprisingly useful and specific hints seconds later. I guess making my developer tooling for the competition open-source got people in a helpful mood :). The trick was to continuously short sell to the limit at a price at which you could immediately convert profitably back to 0 in the next iteration, hoping for other bots in the simulated market to fill your orders. This got me to 60k profit at first, and to 109k minutes later after I realized you can convert your position to 0 and then immediately go short again in the same iteration.
For the manual side of round 2 I calculated the profit of each possible answer, and ended up submitting seashells -> pizza slices -> wasabi roots -> seashells -> pizza slices -> seashells, which gave the maximum profit of 113,938.8.
Also, according to round 2 Discord lore I should thank Marlon for their help. Thank you Marlon.
Round 3
After the round opened, it was clear that the algo side of round 3 was basically a copy-paste of last year's round 4. As such, I started off with building a strategy based on the difference between the value of gift baskets and the combined value of the contents of a gift basket. When this difference crosses certain thresholds, the strategy would go 100% long or 100% short on gift baskets. I later extended it to mirror the position on the individual products of the gift basket, which did reasonably well (although overfit).
After hearing other participants reaching 600k in backtests and failing to figure that out myself, I decided to start trading the gift baskets and its components at different thresholds, and performed several grid searches to find good thresholds for the 30k iterations of example data. This resulted in a profit on everything but roses, on which I lost over 36k. Following these
Related Skills
node-connect
385.5kDiagnose OpenClaw Android, iOS, or macOS node pairing, QR/setup code, route, auth, and connection failures.
blender-python-addon
40.5kBlender Python add-on rules for operators, panels, properties, registration, testing, and API-safe scripting
flutter-development-guidelines-cursorrules-prompt-file
40.5kCursor rules for Flutter development with MVVM architecture, Riverpod state management, Material widgets, and Dart style guidelines.
commit-push-pr
140.7kCommit, push, and open a PR
