Tools and market management for manifold.markets
Project description
Market Manager for Manifold
Currently Implemented
- Resolve a market based on a GitHub PR
- Both "does it merge" and "how long did it take to merge"
- Resolve a market based on its close date and current answer
- Resolve a market based on any logical combination of implemented rules
- Resolve market randomly, like in a lottery
- Several methods implemented, including:
- Random value
- Random index
- Weighted or unweighted
- Excluding early indices if wanted
- Only including the first N indices if wanted
- Can also specify the method, arguments yourself
- Automatically formats rules for the market type
- Before resolving a market, reach out on Telegram to confirm that's okay
Application Behavior
Every time you run example.py, it goes through the following steps:
- (TODO) If flagged, scan a JSON file
- For each entry:
- If it's a market creation request, add it to
pending - If it's an existing market, add it to
markets
- If it's a market creation request, add it to
- Clear the file
- For each entry:
- (TODO) Unless flagged otherwise, for each market in
pending:- Check your balance
- If it's less than M$100, break
- If it's less than the
costof this market, continue - Create the market
- Add it to
markets - Remove it from
pending
- If flagged, manually remove many markets from
markets - If flagged, manually add a market to
markets - Unless flagged otherwise, for each market in
markets:- If the time is before
last_checked + check_rateand refresh is not flagged, continue - If the market does not meet the resolution criteria, continue
- Ask the operator what action to take (either via Telegram or the console):
- Cancel it, or
- Resolve to the suggested value, or
- Do nothing
- Update check time
- If the time is before
Database Spec
marketsid: INTEGERmarket: A serialized python object with the relevant rulescheck_rate: REAL, the minimum number of hours between checkslast_checked: TIMESTAMP, the time it was last checked (or NULL)
pendingid: INTEGERpriority: REAL, lower means you get created soonercost: INTEGER, cost in mana to create, lower means you get created soonerrequest: A serialized python object with the relevant rules and info
Immediate Goals
- Testing for the API bindings by spinning up a dev node of Manifold
- Resolve based on passage of a US law
- Automatic creation of a market when a Pull Request is made
- A way to queue creation of markets for when account has enough mana
Future Goals
The goal of this project is to make a Manifold agent that can manage various forms of markets. Currently targeted are:
- Mirror markets on another service
- Include ability to do this for future markets via regex or tag matching
- Example: Election markets
- Future Discount Markets
- Automatically make markets that resolve at a variety of different dates
- Offer a link that charts the future discount based off of these markets
- Ethereum/Python Improvement Proposals
- Automatically make markets for whether a PEP or EIP is accepted
- Resolve when the associated issue has been closed for some amount of time
- Might be able to just resolve to round(MKT), honestly
- Maybe use this instead as a flag for error, if ex: pull request accepted but round(MKT)=0, flag for attention
- Actually, this might look like a generic Pull Request -> Manifold Market bridge
- If so, make some for every Manifold PR
- Box Office Futures Markets
- Note that this could include Rotten Tomatoes scores as well
- Feels easily queryable
- Feels like movies from major studios could be fetched fairly easily
- Rotten Tomatoes Markets
- Make it for 1, 4, 10 weeks after release
- Use https://pypi.org/project/rotten-tomatoes-scraper/
- Markets for OSM campaigns and bounties
- Conditional Markets
- Does a US Congress bill pass?
- Use https://sunlightlabs.github.io/congress/bills.html
- Resolve to YES iff history.enacted
- Resolve to NO iff not history.enacted and not history.active
How to Run/Contribute
- First, make sure you are running Python >= 3.7
- Load the submodules
- Run
make dependencies - Make a file called
env_<name>.sh. It should contain a max of 7 exportsManifoldAPIKey: The API key for managing your Manifold markets. See here for instructions on how to retrieve it.DBName: The name of your database fileLogFile: The name of a logfile to useTelegramAPIKey: The API key for your Telegram bot. For more info, see hereTelegramChatID: The chat ID between your Telegram bot and you. For more info, see hereGithubAccessToken: The Personal Access Token for reading GitHub issues and pull requests. Strictly speaking not needed, and it will try to fall back to unauthorized requests, but that isn't always feasible.GithubUsername: See above
- Add your first markets using the arguments provided in
src/__main__.py. Each market needs at least one DoResolveRule and at least one ResolveToRule. The simplest ResolveToRule is--roundor--current. The simplest DoResolve rule is--rel-date. More complicated markets may need to have rules constructed manually. - When you've added all your markets, modify the polling frequency in
daemon.sh, then runmake daemon
Dependencies
Recent Coverage Report
---------- coverage: platform linux, python 3.10.5-final-0 -----------
Name Stmts Miss Branch BrPart Cover
-------------------------------------------------------------------------
src/PyManifold/pymanifold/__init__.py 4 0 0 0 100%
src/PyManifold/pymanifold/lib.py 159 118 74 0 18%
src/PyManifold/pymanifold/types.py 92 2 24 0 95%
src/__init__.py 78 39 24 1 43%
src/__main__.py 85 85 34 0 0%
src/application.py 132 132 40 0 0%
src/market.py 155 95 86 4 28%
src/rule/__init__.py 59 39 42 2 26%
src/rule/generic/__init__.py 2 0 0 0 100%
src/rule/generic/time.py 86 43 20 1 49%
src/rule/generic/value.py 83 48 30 1 39%
src/rule/github/__init__.py 11 2 0 0 82%
src/rule/github/time.py 27 12 4 1 58%
src/rule/github/value.py 58 35 14 1 39%
src/rule/manifold/__init__.py 2 0 0 0 100%
src/rule/manifold/value.py 73 37 28 1 49%
src/test/__init__.py 6 0 2 0 100%
src/test/rule/__init__.py 0 0 0 0 100%
src/test/rule/generic/__init__.py 0 0 0 0 100%
src/test/rule/generic/test_time.py 43 1 12 1 96%
src/test/test_market.py 35 0 10 0 100%
src/test/test_rule.py 13 0 4 0 100%
src/test/test_util.py 39 2 16 2 93%
src/util.py 92 40 40 1 49%
-------------------------------------------------------------------------
TOTAL 1334 730 504 16 40%
JSON Examples
50/50 Lottery
{
"manifold": {
"outcomeType": "FREE_RESPONSE",
"question": "Manifold 50/50 #3",
"description": { // Uses TipTap formatting :(
"type": "doc",
"content": [
{
"type": "paragraph",
"content": [
{
"type": "text",
"text": "This question resolves to a 50% share between the subsidy and one other entry chosen randomly (weighted by probability)."
}
]
},
{
"type": "paragraph",
"content": [
{
"type": "text",
"text": "I will periodically add to the subsidy such that it has value at least 25% of the non-subsidy options."
}
]
}
],
"processed": false // This tells the program to append explain_abstract()
},
"closeTime": "2022-09-12T11:59:59" // Doesn't necessarily need the time
},
// all rules are serialized as a two item array
// the first entry is the name of the rule relative to the `rule.py` file
// the second entry is a dictionary of keyword arguments for the rule
"time_rules": [ // rules for when to resolve a market
[
"generic.time.ResolveAtTime",
{"resolve_at": "2022-09-12T11:59:59"}
]
],
"value_rules": [ // rules for what to resolve to
[
"generic.value.ResolveMultipleValues",
{
"shares": [ // format: [<serialized rule>, <relative weight>]
[
[
"generic.value.ResolveToValue",
{"resolve_value": 0}
],
1
],
[
[
"generic.value.ResolveRandomIndex",
{
"start": 1,
"seed": "feijwaopfewa"
}
],
1
]
]
}
]
],
"notes": "",
"initial_values": { // Used in free response / multiple choice to set initial answers
"Subsidy": 50,
"Example Ticket": 1
}
}
Pseudonumeric Example
{
"manifold": {
"outcomeType": "PSEUDO_NUMERIC",
"question": "When will the next mission to Kuiper Belt be launched?",
"description": {
"type": "doc",
"content": [
{
"type": "paragraph",
"content": [
{
"type": "text",
"text": "Resolves to the fractional year at which a mission to the Kuiper Belt is launched. This includes any body in the Kuiper Belt that is not considered a major planet or in orbit of a major planet."
}
]
}
],
"processed": true // tells the application to NOT add explanatory text
},
"closeTime": "2100-12-31T11:59:59",
"minValue": 2023,
"maxValue": 2100,
"isLogScale": true,
"initialValue": 2035
},
"time_rules": [
[
"generic.time.ResolveAtTime",
{"resolve_at": "2100-12-31T11:59:59"}
]
],
"value_rules": [
["manifold.value.CurrentValueRule", {}]
],
"notes": ""
}
Mutliple Choice Example
{
"manifold": {
"outcomeType": "MULTIPLE_CHOICE",
"question": "Which character is best?",
"description": {
"type": "doc",
"content": [
{
"type": "paragraph",
"content": [
{
"type": "text",
"text": "This market is purely intended as a poll to try and settle an argument. It will resolve to MKT."
}
]
}
],
"processed": false
},
"answers": [
"Harry Potter",
"Cthulu",
"Ririsu/Ririto Ibusuki",
],
"closeTime": "2022-09-13T11:59:59"
},
"time_rules": [
[
"generic.time.ResolveAtTime",
{"resolve_at": "2022-09-13T11:59:59"}
]
],
"value_rules": [
[
"manifold.value.CurrentValueRule",
{}
]
],
"notes": ""
}
GitHub PR Merge Date
{
"manifold": {
"outcomeType": "PSEUDO_NUMERIC",
"question": "How many days after Septermber 1st will Manifold PR#830 be merged?",
"description": {
"type": "doc",
"content": [
{
"type": "paragraph",
"content": [
{
"type": "text",
"text": "Resolves to MAX if rejected at time of check"
}
]
}
],
"processed": false
},
"closeTime": "2025-05-28T11:59:59",
"minValue": 0,
"maxValue": 1000,
"isLogScale": true,
"initialValue": 30.639
},
"time_rules": [
[
"generic.time.ResolveAtTime",
{"resolve_at": "2025-05-28T11:59:59"}
],
[
"github.time.ResolveWithPR",
{
"owner": "manifoldmarkets",
"repo": "manifold",
"number": 830
}
]
],
"value_rules": [
[
"github.value.ResolveToPRDelta",
{
"owner": "manifoldmarkets",
"repo": "manifold",
"number": 830,
"start": "2022-09-01"
}]
],
"notes": ""
}
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file ManifoldMarketManager-0.6.0.7.tar.gz.
File metadata
- Download URL: ManifoldMarketManager-0.6.0.7.tar.gz
- Upload date:
- Size: 26.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/4.0.1 CPython/3.10.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
430fb65cb19edfa89692d8249e91f463b0f133ed59c7d5d3692cfe102b5e4d90
|
|
| MD5 |
5830fe085f0f0cff44f2df3c2fbf0f68
|
|
| BLAKE2b-256 |
29b0a49a66ca574d3324a3fac493cc797146ca257bd4befd72f15ec2ce4a31c6
|
File details
Details for the file ManifoldMarketManager-0.6.0.7-py3-none-any.whl.
File metadata
- Download URL: ManifoldMarketManager-0.6.0.7-py3-none-any.whl
- Upload date:
- Size: 30.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/4.0.1 CPython/3.10.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
680014157ca7794a4f6cb45848003181656b31851073ae08e49d609799d38a96
|
|
| MD5 |
b8cee597d240e4bfb480de30b2b026d7
|
|
| BLAKE2b-256 |
79024ed2d18ea5d15f8e6c71f648360a7f509736fe05c308b11b463f65d7ce75
|