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
cost
of 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_rate
and 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
markets
id
: 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)
pending
id
: 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--round
or--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 86 38 26 1 49%
src/__main__.py 85 85 34 0 0%
src/application.py 137 137 40 0 0%
src/market.py 140 79 66 3 33%
src/rule/__init__.py 55 39 42 2 23%
src/rule/generic/__init__.py 2 0 0 0 100%
src/rule/generic/time.py 85 49 18 0 43%
src/rule/generic/value.py 81 47 30 0 38%
src/rule/github/__init__.py 9 2 0 0 78%
src/rule/github/time.py 26 11 2 0 61%
src/rule/github/value.py 57 34 12 0 39%
src/rule/manifold/__init__.py 0 0 0 0 100%
src/rule/manifold/value.py 80 50 48 0 31%
src/test/__init__.py 6 0 2 0 100%
src/test/test_market.py 35 0 10 0 100%
src/test/test_rule.py 9 0 0 0 100%
src/test/test_util.py 39 2 16 2 93%
src/util.py 33 1 8 0 98%
-------------------------------------------------------------------------
TOTAL 1220 694 452 8 38%
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
Close
Hashes for ManifoldMarketManager-0.5.0.19.tar.gz
Algorithm | Hash digest | |
---|---|---|
SHA256 | c5595a9f9dd6fc7cd305725b234e93820519a779d7c61dc34a11ef2860a68a88 |
|
MD5 | 9fb37a1296809918b43ed2f3bc1ada1d |
|
BLAKE2b-256 | 659a1a6aed4089c3988a6f14e514644d83a996136e49ec46445048040db6b41d |
Close
Hashes for ManifoldMarketManager-0.5.0.19-py3-none-any.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 6cd2ad091e663925b643279040af3a3ae920461f3a45faca38bfdfcdde114431 |
|
MD5 | ed6344a4e7c8566e98f5829432718b5d |
|
BLAKE2b-256 | 445a004a52c1bf2861b4a65af9fee7a9a70fba7a5ce2f18fc0a6cc68552b1d1a |