This repository contains code and instructions for setting up an LLM agent based trading bot for https://manifold.markets/. This agent is compatible with most LLM backends and comes with customizable prompts and scripts for backtesting on historical Manifold data.
You can read my blog post about it here.
- Clone this repo and set up a virtual environment, then install requirements with
pip install -r requirements.txt. I've tested on Mac and Linux with python 3.11, you're on your own if it breaks for Windows. - Specify an LLM config. LLM configuration is compatible with any provider that uses an OpenAI-compatible endpoint, which includes OpenAI, Anthropic, Together AI, llama.cpp's default server and more. Consult
config/llm/gpt-4o-mini-example.jsonfor reference. Knowledge cutoff date is only required for backtesting on historical data, you can trade without it. - Set up a Google Custom Search engine and obtain a your Programmable Search Engine identifier as well as a Google API key.
- Obtain a Manifold Markets API key.
- Use your Programmable Search Engine identifier, Google API key and Manifold Markets API key to create a secrets config (see
config/secrets/secrets-example.jsonfor reference) - Edit your bot config to point at your LLM config and your secrets config.
config/bot/kbot.jsoncontains the config that I use for my manifold bot, whileconfig/bot/test.jsoncontains a config that uses OpenAI's agent framework instead of DSPy's.
Once you have a bot config set up, run python -m src.scripts.trade my/config/path to start trading. If you just want to test the bot and aren't ready for it to interact with Manifold for real just yet, set the config value dry_run to true.
configs/bot/kbot.json is configured to sell if the market probability hits >.9 if kbot has bet YES or <.1 if kbot has bet NO. It uses a local database to keep track of its positions. This database is updated as the bot trades and should remain in sync with the website, but in case they fall out of sync running src.scripts.prefill_trade_database will create a fresh database based on the website's current data.
- Download bets, markets and comments dumps. If you'd like you can inspect the contents of each file with
src.scripts.inspect_data_dump path/to/json. - Run
python -m src.scripts.make_dataset --markets_filepath some/path --trades_filepath some/other/path --comments_filepath you/get/the/ideato combine the data into a parquet file. - Run
python -m src.scripts.make_data_splitin order to create test, val and train parquet files. - You can try to run
python -m src.scripts.evaluate --config_path config/bot/my_config.json --max_examples $SOME_REASONABLE_NUMBER --num_workers $SOME_OTHER_NUMBERto use DSPy's built-in evaluation utility, but if$SOME_REASONABLE_NUMBER > 10and$SOME_OTHER_NUMBER > 1it may hang indefinitely. I recommend instead usingpython -m src.scripts.dirty_evaluate --config_path config/bot/my_config.json --max_examples $SOME_REASONABLE_NUMBER --num_threads $SOME_OTHER_NUMBER. The latter script also lets you specify a--timeoutvalue in seconds, which gracefully fails examples which take longer than that value to complete.
python -m src.scripts.optimize will let you run optimization using DSPY's implementation of MIRPOv2 or COPRO depending on flags. But it is again likely to hang, so IMO you're better off editing the programs by hand and then linking them in the bot config: see dspy_programs/halawi_zero_shot.json for an example.
The prompts in dspy_programs/halawi_zero_shot.json and config/templates/halawi_scratchpad.txt were adapted from https://arxiv.org/html/2402.18563v1.