General refactoring of code
This commit is contained in:
parent
e7b17cdead
commit
376e67934d
Binary file not shown.
Binary file not shown.
|
@ -6,7 +6,7 @@ do
|
|||
do
|
||||
echo "Running for environment $file"
|
||||
source $file
|
||||
python example.py
|
||||
python -m src
|
||||
done
|
||||
echo "Press once <CTRL+C> to check now, and twice to exit before next loop."
|
||||
hour=0
|
||||
|
|
200
example.json
200
example.json
|
@ -1,153 +1,49 @@
|
|||
[
|
||||
{
|
||||
"manifold": {
|
||||
"outcomeType": "BINARY",
|
||||
"question": "Is supersymmetry correct?",
|
||||
"description": {
|
||||
"type": "doc",
|
||||
"content": [{
|
||||
"type": "paragraph",
|
||||
"content": [{
|
||||
"type": "text",
|
||||
"text": "https://en.wikipedia.org/wiki/Supersymmetry",
|
||||
"marks": [{
|
||||
"type": "link",
|
||||
"attrs": {
|
||||
"href": "https://en.wikipedia.org/wiki/Supersymmetry",
|
||||
"target": "_blank",
|
||||
"class": null
|
||||
}
|
||||
}]
|
||||
}]
|
||||
}]
|
||||
},
|
||||
"closeTime": "2100-12-31T11:59:59",
|
||||
|
||||
"initialProb": 50,
|
||||
|
||||
"minValue": null,
|
||||
"maxValue": null,
|
||||
"isLogScale": null,
|
||||
"initialValue": null,
|
||||
"groups": ["Physics Forecasting", "Olivia"]
|
||||
},
|
||||
"time_rules": [
|
||||
["ResolveAtTime", {
|
||||
"resolve_at": "2100-12-31T11:59:59"
|
||||
}]
|
||||
],
|
||||
"value_rules": [
|
||||
["RoundValueRule", {}]
|
||||
],
|
||||
"notes": "",
|
||||
"initial_values": {}
|
||||
},
|
||||
{
|
||||
"manifold": {
|
||||
"outcomeType": "PSEUDO_NUMERIC",
|
||||
"question": "When will the next mission to Jupiter be launched?",
|
||||
"description": {
|
||||
"type": "doc",
|
||||
"content": [{
|
||||
"type": "paragraph",
|
||||
"content": [{
|
||||
"type": "text",
|
||||
"text": "Resolves to the fractional year at which a mission to the Jovian system is launched. This includes flyby missions, orbiters, landers, or any of these types of mission to a moon in orbit of Jupiter. This does not include any bodies which are in resonance with Jupiter but not in orbit."
|
||||
}]
|
||||
}],
|
||||
"processed": true
|
||||
},
|
||||
"closeTime": "2100-12-31T11:59:59",
|
||||
|
||||
"initialProb": null,
|
||||
|
||||
"minValue": 2023,
|
||||
"maxValue": 2100,
|
||||
"isLogScale": true,
|
||||
"initialValue": 2035,
|
||||
"groups": ["Space", "Olivia"]
|
||||
},
|
||||
"time_rules": [
|
||||
["ResolveAtTime", {
|
||||
"resolve_at": "2100-12-31T11:59:59"
|
||||
}]
|
||||
],
|
||||
"value_rules": [
|
||||
["CurrentValueRule", {}]
|
||||
],
|
||||
"notes": "",
|
||||
"initial_values": {}
|
||||
},
|
||||
{
|
||||
"manifold": {
|
||||
"outcomeType": "PSEUDO_NUMERIC",
|
||||
"question": "When will the next mission to a minor body between Mars and the 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 Neptunian system is launched. This includes flyby missions, orbiters, landers, or miners. This does not include any bodies which are in orbit of a major planet."
|
||||
}]
|
||||
}],
|
||||
"processed": true
|
||||
},
|
||||
"closeTime": "2100-12-31T11:59:59",
|
||||
|
||||
"initialProb": null,
|
||||
|
||||
"minValue": 2023,
|
||||
"maxValue": 2100,
|
||||
"isLogScale": true,
|
||||
"initialValue": 2035,
|
||||
"groups": ["Space", "Olivia"]
|
||||
},
|
||||
"time_rules": [
|
||||
["ResolveAtTime", {
|
||||
"resolve_at": "2100-12-31T11:59:59"
|
||||
}]
|
||||
],
|
||||
"value_rules": [
|
||||
["CurrentValueRule", {}]
|
||||
],
|
||||
"notes": "",
|
||||
"initial_values": {}
|
||||
},
|
||||
{
|
||||
"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
|
||||
},
|
||||
"closeTime": "2100-12-31T11:59:59",
|
||||
|
||||
"initialProb": null,
|
||||
|
||||
"minValue": 2023,
|
||||
"maxValue": 2100,
|
||||
"isLogScale": true,
|
||||
"initialValue": 2035,
|
||||
"groups": ["Space", "Olivia"]
|
||||
},
|
||||
"time_rules": [
|
||||
["ResolveAtTime", {
|
||||
"resolve_at": "2100-12-31T11:59:59"
|
||||
}]
|
||||
],
|
||||
"value_rules": [
|
||||
["CurrentValueRule", {}]
|
||||
],
|
||||
"notes": "",
|
||||
"initial_values": {}
|
||||
}
|
||||
]
|
||||
{
|
||||
"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
|
||||
},
|
||||
"closeTime": "2100-12-31T11:59:59",
|
||||
"initialProb": null,
|
||||
"minValue": 2023,
|
||||
"maxValue": 2100,
|
||||
"isLogScale": true,
|
||||
"initialValue": 2035,
|
||||
"groups": [
|
||||
"Space",
|
||||
"Olivia"
|
||||
]
|
||||
},
|
||||
"time_rules": [
|
||||
[
|
||||
"ResolveAtTime",
|
||||
{
|
||||
"resolve_at": "2100-12-31T11:59:59"
|
||||
}
|
||||
]
|
||||
],
|
||||
"value_rules": [
|
||||
[
|
||||
"CurrentValueRule",
|
||||
{}
|
||||
]
|
||||
],
|
||||
"notes": "",
|
||||
"initial_values": {}
|
||||
}
|
||||
]
|
|
@ -5,9 +5,9 @@ from json import dump, load
|
|||
from re import match
|
||||
from typing import Any, Dict, List, Literal, Optional, Union
|
||||
|
||||
from src import rule
|
||||
from src.rule import explain_abstract, DoResolveRule, ResolutionValueRule
|
||||
from src.market import Market, get_client
|
||||
from src import rule, explain_abstract
|
||||
from src.rule import DoResolveRule, ResolutionValueRule
|
||||
from src.market import get_client, Market
|
||||
from example import register_db
|
||||
|
||||
from pymanifold.types import DictDeserializable
|
||||
|
@ -21,16 +21,19 @@ def main():
|
|||
for mkt in obj.copy():
|
||||
my_mkt = CreationRequest.from_dict(mkt).create()
|
||||
db.execute("INSERT INTO markets VALUES ( (SELECT MAX(id)+1 from markets), ?, 3, NULL);", (my_mkt, ))
|
||||
((new_id, ), ) = db.execute("SELECT MAX(id) from markets;")
|
||||
print(f"Added as ID {new_id}")
|
||||
print(my_mkt.market.url)
|
||||
obj.remove(mkt)
|
||||
finally:
|
||||
db.commit()
|
||||
db.close()
|
||||
with open('example.json', 'w') as f:
|
||||
dump(obj, default=date_serialization_hook)
|
||||
dump(obj, f, default=date_serialization_hook, indent="\t")
|
||||
|
||||
|
||||
def date_serialization_hook(obj):
|
||||
"""JSON serializer for objects not serializable by default json code"""
|
||||
"""JSON serializer for objects not serializable by default json code."""
|
||||
if isinstance(obj, (datetime, date)):
|
||||
return obj.isoformat()
|
||||
raise TypeError(f"Type ${type(obj)} not serializable")
|
||||
|
@ -56,13 +59,13 @@ class ManifoldRequest(DictDeserializable):
|
|||
description: Union[str, Any]
|
||||
closeTime: int
|
||||
|
||||
initialProb: Optional[float] # Note: probability is multiplied by 100, may only allow integers in binary market
|
||||
initialProb: Optional[float] = None # Note: probability is multiplied by 100, may only allow integers
|
||||
|
||||
minValue: Optional[float]
|
||||
maxValue: Optional[float]
|
||||
isLogScale: Optional[bool]
|
||||
initialValue: Optional[float]
|
||||
groups: List[str] = field(default_factory=list)
|
||||
minValue: Optional[float] = None
|
||||
maxValue: Optional[float] = None
|
||||
isLogScale: Optional[bool] = None
|
||||
initialValue: Optional[float] = None
|
||||
tags: List[str] = field(default_factory=list)
|
||||
|
||||
def __post_init__(self):
|
||||
if self.outcomeType == "BINARY":
|
||||
|
@ -91,20 +94,27 @@ class CreationRequest:
|
|||
notes: str = ""
|
||||
initial_values: Dict[str, int] = field(default_factory=dict)
|
||||
|
||||
def __postinit__(self):
|
||||
def __post_init__(self):
|
||||
if not self.manifold.description.get("processed"):
|
||||
for paragraph in explain_abstract(
|
||||
explanation = "\n" + explain_abstract(
|
||||
time_rules=self.time_rules, value_rules=self.value_rules
|
||||
).splitlines():
|
||||
# if not paragraph:
|
||||
# continue
|
||||
self.manifold.description["content"].append({
|
||||
"type": "paragraph",
|
||||
"content": [{
|
||||
"type": "text",
|
||||
"text": paragraph
|
||||
}]
|
||||
})
|
||||
)
|
||||
for paragraph in explanation.splitlines():
|
||||
if paragraph:
|
||||
if paragraph.startswith(" "):
|
||||
for idx, character in enumerate(paragraph):
|
||||
if character != " ":
|
||||
break
|
||||
paragraph = paragraph.replace(" ", " ", idx)
|
||||
self.manifold.description["content"].append({
|
||||
"type": "paragraph",
|
||||
"content": [{
|
||||
"type": "text",
|
||||
"text": paragraph
|
||||
}]
|
||||
})
|
||||
else:
|
||||
self.manifold.description["content"].append({"type": "paragraph"})
|
||||
self.manifold.description["processed"] = True
|
||||
|
||||
@classmethod
|
||||
|
@ -139,7 +149,12 @@ class CreationRequest:
|
|||
else:
|
||||
raise ValueError()
|
||||
|
||||
return Market(market, do_resolve_rules=self.time_rules, resolve_to_rules=self.value_rules, notes=self.notes)
|
||||
return Market(
|
||||
client.get_market_by_id(market.id),
|
||||
do_resolve_rules=self.time_rules,
|
||||
resolve_to_rules=self.value_rules,
|
||||
notes=self.notes
|
||||
)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
|
|
@ -47,6 +47,27 @@ def require_env(*env: str):
|
|||
return bar
|
||||
|
||||
|
||||
def explain_abstract(**kwargs) -> str:
|
||||
"""Explain how the market will resolve and decide to resolve."""
|
||||
ret = "This market will resolve if any of the following are true:\n"
|
||||
for rule_ in kwargs["time_rules"]:
|
||||
ret += rule_.explain_abstract(**kwargs)
|
||||
ret += ("\nIt will resolve based on the following decision tree:\n"
|
||||
"- If the human operator agrees:\n")
|
||||
for rule_ in kwargs["value_rules"]:
|
||||
ret += rule_.explain_abstract(indent=1, **kwargs)
|
||||
ret += (
|
||||
"- Otherwise, a manually provided value\n\n"
|
||||
"Note that the bot operator reserves the right to resolve contrary to the purely automated rules to "
|
||||
"preserve the spirit of the market. All resolutions are first verified by the human operator."
|
||||
"\n\n"
|
||||
"The operator also reserves the right to trade on this market unless otherwise specified. Even if "
|
||||
"otherwise specified, the operator reserves the right to buy shares for subsidy or to trade for the "
|
||||
"purposes of cashing out liquidity.\n"
|
||||
)
|
||||
return ret
|
||||
|
||||
|
||||
class Rule(DictDeserializable):
|
||||
"""The basic unit of market automation, rules defmine how a market should react to given events."""
|
||||
|
||||
|
|
|
@ -0,0 +1,128 @@
|
|||
from argparse import ArgumentParser
|
||||
from datetime import datetime
|
||||
from logging import basicConfig, getLogger, DEBUG, INFO
|
||||
from os import getenv
|
||||
from typing import cast, Optional, Tuple
|
||||
|
||||
from .application import register_db, main
|
||||
from . import market, rule
|
||||
|
||||
# Enable logging
|
||||
basicConfig(
|
||||
format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
|
||||
level=(INFO if not getenv("DEBUG") else DEBUG),
|
||||
filename=getenv("LogFile"),
|
||||
)
|
||||
logger = getLogger(__name__)
|
||||
|
||||
parser = ArgumentParser()
|
||||
parser.add_argument('-s', '--add-slug', action='store', dest='slug')
|
||||
parser.add_argument('-i', '--add-id', action='store', dest='id_')
|
||||
parser.add_argument('-u', '--add-url', action='store', dest='url')
|
||||
parser.add_argument('-c', '--check-rate', action='store', dest='rate', help='Check rate in hours')
|
||||
|
||||
parser.add_argument('-mi', '--min', action='store',
|
||||
help="Only used for numeric markets, until they add this to the API")
|
||||
parser.add_argument('-ma', '--max', action='store',
|
||||
help="Only used for numeric markets, until they add this to the API")
|
||||
parser.add_argument('-ls', '--log_scale', action='store_true', dest='isLogScale',
|
||||
help="Only used for numeric markets, until they add this to the API")
|
||||
|
||||
parser.add_argument('-r', '--refresh', action='store_true', dest='refresh',
|
||||
help="Ignore time last checked and look at all markets immediately")
|
||||
|
||||
parser.add_argument('-rm', '--remove-id', action='append', dest='rm_id', default=[],
|
||||
help="Remove a specific market from management. May be repeated.")
|
||||
|
||||
parser.add_argument('-rnd', '--round', action='store_true')
|
||||
parser.add_argument('-cur', '--current', action='store_true')
|
||||
parser.add_argument('-rd', '--rel-date', action='store', dest='rel_date',
|
||||
help='Please give as "year/month/day" or "year-month-day". Used in: poll, git PR')
|
||||
|
||||
parser.add_argument('-pr', '--pull-request', action='store', dest='pr_slug', help='Please give as "owner/repo/num"')
|
||||
parser.add_argument('-pb', '--pull-binary', action='store_true', dest='pr_bin')
|
||||
|
||||
parser.add_argument('-sk', '--skip', action='store_true')
|
||||
parser.add_argument('-co', '--console-only', action='store_true')
|
||||
|
||||
parser.add_argument('-rs', '--random-seed', action='store')
|
||||
parser.add_argument('-rr', '--random-rounds', action='store', type=int, default=1)
|
||||
parser.add_argument('-ri', '--random-index', action='store_true')
|
||||
parser.add_argument('-is', '--index-size', action='store', type=int)
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
for id_ in args.rm_id:
|
||||
conn = register_db()
|
||||
((mkt, ), ) = conn.execute(
|
||||
"SELECT market FROM markets WHERE id = ?;",
|
||||
(id_, )
|
||||
)
|
||||
if input(f'Are you sure you want to remove {id_}: "{mkt.market.question}" (y/N)?').lower().startswith('y'):
|
||||
conn.execute(
|
||||
"DELETE FROM markets WHERE id = ?;",
|
||||
(id_, )
|
||||
)
|
||||
conn.commit()
|
||||
logger.info(f"{id_} removed from db")
|
||||
conn.close()
|
||||
|
||||
if any((args.slug, args.id_, args.url)):
|
||||
if args.url:
|
||||
args.slug = args.url.split('/')[-1]
|
||||
|
||||
if args.slug:
|
||||
mkt = market.Market.from_slug(args.slug)
|
||||
else:
|
||||
mkt = market.Market.from_id(args.id)
|
||||
|
||||
if args.rel_date:
|
||||
sections = args.rel_date.split('/')
|
||||
if len(sections) == 1:
|
||||
sections = args.rel_date.split('-')
|
||||
try:
|
||||
date: Optional[Tuple[int, int, int]] = tuple(int(x) for x in sections) # type: ignore[assignment]
|
||||
except ValueError:
|
||||
raise
|
||||
else:
|
||||
date = None
|
||||
|
||||
if args.random_index:
|
||||
mkt.resolve_to_rules.append(
|
||||
rule.ResolveRandomIndex(args.random_seed, size=args.index_size, rounds=args.random_rounds)
|
||||
)
|
||||
|
||||
if args.round:
|
||||
mkt.resolve_to_rules.append(rule.RoundValueRule())
|
||||
if args.current:
|
||||
mkt.resolve_to_rules.append(rule.CurrentValueRule())
|
||||
|
||||
if args.pr_slug:
|
||||
pr_ = list(args.pr_slug.split('/'))
|
||||
pr_[-1] = int(pr_[-1])
|
||||
pr = cast(Tuple[str, str, int], tuple(pr_))
|
||||
mkt.do_resolve_rules.append(rule.ResolveWithPR(*pr))
|
||||
if date:
|
||||
mkt.resolve_to_rules.append(rule.ResolveToPRDelta(*pr, datetime(*date)))
|
||||
elif args.pr_bin:
|
||||
mkt.resolve_to_rules.append(rule.ResolveToPR(*pr))
|
||||
else:
|
||||
raise ValueError("No resolve rule provided")
|
||||
|
||||
if not mkt.do_resolve_rules:
|
||||
if not date:
|
||||
raise ValueError("No resolve date provided")
|
||||
mkt.do_resolve_rules.append(rule.ResolveAtTime(datetime(*date)))
|
||||
|
||||
conn = register_db()
|
||||
|
||||
idx = max(((0, ), *conn.execute("SELECT id FROM markets;")))[0] + 1
|
||||
conn.execute("INSERT INTO markets values (?, ?, ?, ?);", (idx, mkt, 1, None))
|
||||
conn.commit()
|
||||
|
||||
print(msg := f"Successfully added as ID {idx}!")
|
||||
logger.info(msg)
|
||||
conn.close()
|
||||
|
||||
if not args.skip:
|
||||
main(args.refresh, args.console_only)
|
|
@ -1,13 +1,12 @@
|
|||
from argparse import ArgumentParser
|
||||
from asyncio import get_event_loop, new_event_loop, set_event_loop
|
||||
from dataclasses import dataclass
|
||||
from datetime import datetime, timedelta
|
||||
from enum import IntEnum
|
||||
from logging import basicConfig, getLogger, DEBUG, INFO
|
||||
from logging import getLogger
|
||||
from pathlib import Path
|
||||
from os import getenv
|
||||
from sqlite3 import connect, PARSE_COLNAMES, PARSE_DECLTYPES
|
||||
from typing import cast, Optional, Tuple
|
||||
from typing import cast
|
||||
|
||||
from telegram import __version__ as TG_VER
|
||||
|
||||
|
@ -26,14 +25,8 @@ if __version_info__ < (20, 0, 0, "alpha", 1):
|
|||
from telegram import InlineKeyboardButton, InlineKeyboardMarkup, Update
|
||||
from telegram.ext import Application, CallbackQueryHandler, ContextTypes
|
||||
|
||||
from src import (market, require_env, rule)
|
||||
from src import market, require_env
|
||||
|
||||
# Enable logging
|
||||
basicConfig(
|
||||
format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
|
||||
level=(INFO if not getenv("DEBUG") else DEBUG),
|
||||
filename=getenv("LogFile"),
|
||||
)
|
||||
logger = getLogger(__name__)
|
||||
|
||||
|
||||
|
@ -195,117 +188,3 @@ def main(refresh: bool = False, console_only: bool = False):
|
|||
)
|
||||
conn.commit()
|
||||
conn.close()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
parser = ArgumentParser()
|
||||
parser.add_argument('-s', '--add-slug', action='store', dest='slug')
|
||||
parser.add_argument('-i', '--add-id', action='store', dest='id_')
|
||||
parser.add_argument('-u', '--add-url', action='store', dest='url')
|
||||
parser.add_argument('-c', '--check-rate', action='store', dest='rate', help='Check rate in hours')
|
||||
|
||||
parser.add_argument('-mi', '--min', action='store',
|
||||
help="Only used for numeric markets, until they add this to the API")
|
||||
parser.add_argument('-ma', '--max', action='store',
|
||||
help="Only used for numeric markets, until they add this to the API")
|
||||
parser.add_argument('-ls', '--log_scale', action='store_true', dest='isLogScale',
|
||||
help="Only used for numeric markets, until they add this to the API")
|
||||
|
||||
parser.add_argument('-r', '--refresh', action='store_true', dest='refresh',
|
||||
help="Ignore time last checked and look at all markets immediately")
|
||||
|
||||
parser.add_argument('-rm', '--remove-id', action='append', dest='rm_id', default=[],
|
||||
help="Remove a specific market from management. May be repeated.")
|
||||
|
||||
parser.add_argument('-rnd', '--round', action='store_true')
|
||||
parser.add_argument('-cur', '--current', action='store_true')
|
||||
parser.add_argument('-rd', '--rel-date', action='store', dest='rel_date',
|
||||
help='Please give as "year/month/day" or "year-month-day". Used in: poll, git PR')
|
||||
|
||||
parser.add_argument('-pr', '--pull-request', action='store', dest='pr_slug', help='Please give as "owner/repo/num"')
|
||||
parser.add_argument('-pb', '--pull-binary', action='store_true', dest='pr_bin')
|
||||
|
||||
parser.add_argument('-sk', '--skip', action='store_true')
|
||||
parser.add_argument('-co', '--console-only', action='store_true')
|
||||
|
||||
parser.add_argument('-rs', '--random-seed', action='store')
|
||||
parser.add_argument('-rr', '--random-rounds', action='store', type=int, default=1)
|
||||
parser.add_argument('-ri', '--random-index', action='store_true')
|
||||
parser.add_argument('-is', '--index-size', action='store', type=int)
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
for id_ in args.rm_id:
|
||||
conn = register_db()
|
||||
((mkt, ), ) = conn.execute(
|
||||
"SELECT market FROM markets WHERE id = ?;",
|
||||
(id_, )
|
||||
)
|
||||
if input(f'Are you sure you want to remove {id_}: "{mkt.market.question}" (y/N)?').lower().startswith('y'):
|
||||
conn.execute(
|
||||
"DELETE FROM markets WHERE id = ?;",
|
||||
(id_, )
|
||||
)
|
||||
conn.commit()
|
||||
logger.info(f"{id_} removed from db")
|
||||
conn.close()
|
||||
|
||||
if any((args.slug, args.id_, args.url)):
|
||||
if args.url:
|
||||
args.slug = args.url.split('/')[-1]
|
||||
|
||||
if args.slug:
|
||||
mkt = market.Market.from_slug(args.slug)
|
||||
else:
|
||||
mkt = market.Market.from_id(args.id)
|
||||
|
||||
if args.rel_date:
|
||||
sections = args.rel_date.split('/')
|
||||
if len(sections) == 1:
|
||||
sections = args.rel_date.split('-')
|
||||
try:
|
||||
date: Optional[Tuple[int, int, int]] = tuple(int(x) for x in sections) # type: ignore[assignment]
|
||||
except ValueError:
|
||||
raise
|
||||
else:
|
||||
date = None
|
||||
|
||||
if args.random_index:
|
||||
mkt.resolve_to_rules.append(
|
||||
rule.ResolveRandomIndex(args.random_seed, size=args.index_size, rounds=args.random_rounds)
|
||||
)
|
||||
|
||||
if args.round:
|
||||
mkt.resolve_to_rules.append(rule.RoundValueRule())
|
||||
if args.current:
|
||||
mkt.resolve_to_rules.append(rule.CurrentValueRule())
|
||||
|
||||
if args.pr_slug:
|
||||
pr_ = list(args.pr_slug.split('/'))
|
||||
pr_[-1] = int(pr_[-1])
|
||||
pr = cast(Tuple[str, str, int], tuple(pr_))
|
||||
mkt.do_resolve_rules.append(rule.ResolveWithPR(*pr))
|
||||
if date:
|
||||
mkt.resolve_to_rules.append(rule.ResolveToPRDelta(*pr, datetime(*date)))
|
||||
elif args.pr_bin:
|
||||
mkt.resolve_to_rules.append(rule.ResolveToPR(*pr))
|
||||
else:
|
||||
raise ValueError("No resolve rule provided")
|
||||
|
||||
if not mkt.do_resolve_rules:
|
||||
if not date:
|
||||
raise ValueError("No resolve date provided")
|
||||
mkt.do_resolve_rules.append(rule.ResolveAtTime(datetime(*date)))
|
||||
|
||||
conn = register_db()
|
||||
|
||||
idx = max(((0, ), *conn.execute("SELECT id FROM markets;")))[0] + 1
|
||||
conn.execute("INSERT INTO markets values (?, ?, ?, ?);", (idx, mkt, 1, None))
|
||||
conn.commit()
|
||||
|
||||
print(msg := f"Successfully added as ID {idx}!")
|
||||
logger.info(msg)
|
||||
conn.close()
|
||||
|
||||
if not args.skip:
|
||||
main(args.refresh, args.console_only)
|
|
@ -10,8 +10,8 @@ from typing import Any, Dict, List, Union
|
|||
from pymanifold import ManifoldClient
|
||||
from pymanifold.types import Market as APIMarket
|
||||
|
||||
from . import require_env
|
||||
from .rule import explain_abstract, DoResolveRule, ResolutionValueRule
|
||||
from . import explain_abstract, require_env
|
||||
from .rule import DoResolveRule, ResolutionValueRule
|
||||
|
||||
|
||||
@lru_cache
|
||||
|
|
19
src/rule.py
19
src/rule.py
|
@ -11,25 +11,6 @@ import requests
|
|||
from . import require_env, Rule
|
||||
|
||||
|
||||
def explain_abstract(**kwargs) -> str:
|
||||
"""Explain how the market will resolve and decide to resolve."""
|
||||
ret = "This market will resolve if any of the following are true:\n"
|
||||
for rule in kwargs["time_rules"]:
|
||||
ret += rule.explain_abstract(**kwargs)
|
||||
ret += "\nIt will resolve based on the following decision tree:\n"
|
||||
for rule in kwargs["value_rules"]:
|
||||
ret += rule.explain_abstract(**kwargs)
|
||||
ret += (
|
||||
"\nNote that the bot operator reserves the right to resolve contrary to the purely automated rules to "
|
||||
"preserve the spirit of the market. All resolutions are first verified by the human operator."
|
||||
"\n\n"
|
||||
"The operator also reserves the right to trade on this market unless otherwise specified. Even if "
|
||||
"otherwise specified, the operator reserves the right to buy shares for subsidy or to trade for the "
|
||||
"purposes of cashing out liquidity.\n"
|
||||
)
|
||||
return ret
|
||||
|
||||
|
||||
class DoResolveRule(Rule):
|
||||
"""The subtype of rule which determines if a market should resolve, returning a bool."""
|
||||
|
||||
|
|
Loading…
Reference in New Issue