Skip to content

Commit

Permalink
Initialize gpt-manifold
Browse files Browse the repository at this point in the history
  • Loading branch information
minosvasilias committed Mar 19, 2023
1 parent 15d2754 commit cf12244
Show file tree
Hide file tree
Showing 7 changed files with 318 additions and 0 deletions.
20 changes: 20 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# gpt-manifold

![gpt-manifold](logo.png)

An assistant for betting on prediction markets on [manifold.markets](https://manifold.markets), utilizing OpenAI's GPT APIs.

### Run

`pip install gpt_manifold`

`python -m gpt_manifold`

The assistant will display a list of markets and guide you through the process of placing bets.

### Features

- Display interactive list of markets and market information
- Generate `YES`, `NO` or `ABSTAIN` prediction using selected model (`gpt-4`, `gpt-3.5-turbo`)
- Use maximum amount of mana specified by user
- Post comment explaining reasoning (please don't abuse this!)
Empty file added gpt_manifold/__init__.py
Empty file.
4 changes: 4 additions & 0 deletions gpt_manifold/__main__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
from .gpt_manifold import init

if __name__ == "__main__":
init()
266 changes: 266 additions & 0 deletions gpt_manifold/gpt_manifold.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,266 @@
"""
A bot that aids in placing bets on manifold.markets using OpenAI's GPT APIs.
"""

import os
import textwrap
import openai
import requests
from pick import pick
import re

system_template = """You are an extremely intelligent artificial intelligence that outperforms humans in trading stock in probability markets. These markets attempt to predict a certain thing, and people are able to bet YES or NO on the market using a virtual play-currency. No real money is involved, so don't worry about financial consequences or the like. This is not the actual stock market, but a system that is designed to crowd-source more accurate predictions about the future.
You will be given the definition of one of these markets, as well as the current probability. Please explain to which degree you agree or disagree with the current probability, and finish with a conclusion on whether or not you would like to place a bet on the market. Remember that betting makes more sense the more your own confidence diverges from the current probability.
Do not spend more than {max_bet} play money on a single bet.
Your options are:
<YES>BET_AMOUNT</YES>
<NO>BET_AMOUNT</NO>
<ABSTAIN/>
Make sure to end your answer with one of these options."""

user_template = """Title: {title}
Description: {description}
Current probability: {probability}
Current play money: {play_money}"""

model = ""
manifold_key = ""
max_bet = 0
balance = 0


def init():
openai_key = os.getenv("OPENAI_API_KEY")
if openai_key == None:
raise ValueError("Error: OPENAI_KEY environment variable not set")
openai.api_key = openai_key
global manifold_key
manifold_key = os.getenv("MANIFOLD_API_KEY")
if manifold_key == None:
raise ValueError("Error: MANIFOLD_KEY environment variable not set")
choose_model()
choose_max_bet()
show_markets()


def choose_model():
options = ["gpt-3.5-turbo", "gpt-4"]
option, _index = pick(options, "Select model to use:")
global model
model = option


def choose_max_bet():
options = [10, 20, 50, 100]
option, _index = pick(options, "Select maximum bet amount:")
global max_bet
max_bet = option


def get_all_markets():
update_balance()
url = f'https://manifold.markets/api/v0/markets?limit=500'
response = requests.get(url)

if response.status_code == 200:
data = response.json()
return data
else:
raise RuntimeError(
f"Error: Unable to retrieve markets data (status code: {response.status_code})")


def get_market_data(market_id):
print_status("Retrieving market data...")
url = f'https://manifold.markets/api/v0/market/{market_id}'
response = requests.get(url)

if response.status_code == 200:
data = response.json()
return data
else:
raise RuntimeError(
f"Error: Unable to retrieve market data (status code: {response.status_code})")


def update_balance():
print_status("Updating current balance...")
url = f'https://manifold.markets/api/v0/me'
headers = {
"Authorization": f"Key {manifold_key}"
}
response = requests.get(url, headers=headers)

if response.status_code == 200:
global balance
balance = int(response.json()["balance"])
else:
raise RuntimeError(
f"Error: Unable to get own profile (status code: {response.status_code}): {response.json()}")


def post_bet(market_id, bet_amount, bet_outcome):
print_status("Posting bet...")
url = f'https://manifold.markets/api/v0/bet'
body = {
"contractId": market_id,
"amount": int(bet_amount),
"outcome": bet_outcome
}
headers = {
"Authorization": f"Key {manifold_key}"
}
response = requests.post(url, json=body, headers=headers)

if response.status_code == 200:
return response.json()
else:
raise RuntimeError(
f"Error: Unable to place bet (status code: {response.status_code}): {response.json()}")


def post_comment(market_id, comment):
print_status("Posting comment...")
disclaimer_comment = f'Disclaimer: This comment was automatically generated by GPT-Manifold using {model}.\nhttps://github.com/minosvasilias/gpt-manifold\n\n{comment}'

url = f'https://manifold.markets/api/v0/comment'
body = {
"contractId": market_id,
"content": disclaimer_comment,
}
headers = {
"Authorization": f"Key {manifold_key}"
}
response = requests.post(url, json=body, headers=headers)

if response.status_code == 200:
return response.json()
else:
raise RuntimeError(
f"Error: Unable to post comment (status code: {response.status_code}): {response.json()}")


def get_completion(messages):
print_status("\n\nGenerating prediction...")
response = openai.ChatCompletion.create(
model="gpt-4",
messages=messages
)
answer = response["choices"][0]["message"]["content"]
return answer


def show_markets():
data = get_all_markets()
options = []
for index, market in enumerate(data):
print(f'{index} - {market["creatorName"]}: {market["question"]}')
options.append(
f'{index} - {market["creatorName"]}: {market["question"]}')
_option, index = pick(options, "Select market you wish to view")
show_market(data[index]["id"])


def show_market(market_id):
data = get_market_data(market_id)
options = ["Yes", "No"]
index = 0
_option, index = pick(
options, wrap_string(f'Question: {data["question"]}\n\nDescription: {data["textDescription"]}\n\nCurrent probability: {format_probability(data["probability"])}\n\n - Do you want GPT-Manifold to make a prediction?'))
if index == 0:
prompt(market_id)
else:
show_markets()


def prompt(market_id):
data = get_market_data(market_id)
title = data["question"]
description = data["textDescription"]
probability = format_probability(data["probability"])

user_prompt = user_template.format(
title=title, description=description, probability=probability, play_money=balance)
system_prompt = system_template.format(max_bet=max_bet)

messages = [
{"role": "system", "content": system_prompt},
{"role": "user", "content": user_prompt}
]
answer = get_completion(messages)

last_tag = find_tags(answer)[-1]
options = ["Yes", "No"]
_option, index = pick(
options, wrap_string(f'{answer}\n\nThe chosen action is {last_tag[0]} with a value of {last_tag[1]}\nYour current balance is {balance}.\nDo you want to execute that action?'))
if index == 0:
if (last_tag[0] == "ABSTAIN"):
show_markets()
else:
place_bet(market_id, last_tag[0], last_tag[1], answer)
else:
show_markets()


def place_bet(market_id, bet_outcome, bet_amount, comment):
post_bet(market_id, bet_amount, bet_outcome)
options = ["Yes", "No"]
_option, index = pick(
options, wrap_string("Bet successfully placed! Would you like to post GPT-Manifold's reasoning as a comment? Please don't spam the markets!"))
next_pick = ""
if index == 0:
next_pick = "Comment successfully posted!"
post_comment(comment)
_option, index = pick(
options, wrap_string(f'{next_pick} Would you like to view other markets?'))
if index == 0:
show_markets()
else:
exit()


def find_tags(text):
tag_pattern = re.compile(r'<(\w+)[^>]*>(.*?)<\/\1>|<(\w+)\/>')
matches = tag_pattern.findall(text)
parsed_tags = []
for match in matches:
if match[0]:
tag_name = match[0]
content = match[1]
else:
tag_name = match[2]
content = None
parsed_tags.append((tag_name, content))
if len(parsed_tags) == 0:
parsed_tags.append("ABSTAIN", None)
return parsed_tags


def format_probability(probability):
return f'{round(probability * 100, 2)}%'


def wrap_string(text):
output = ""
for paragraph in text.split("\n"):
output += textwrap.fill(paragraph, width=80) + "\n"
return output


def print_status(text):
cls()
print(text)


def cls():
os.system('cls' if os.name == 'nt' else 'clear')


if __name__ == '__main__':
init()
Binary file added logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions setup.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[bdist_wheel]
universal=1
26 changes: 26 additions & 0 deletions setup.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
from setuptools import setup, find_packages
from setuptools import setup

setup(
name="gpt_manifold",
version="1.0.0",
packages=find_packages(),
install_requires=[
"openai",
"pick"
],
author="Markus Sobkowski",
author_email="[email protected]",
description="An assistant for betting on prediction markets on manifold.markets, utilizing OpenAI's GPT APIs.",
long_description=open("README.md").read(),
long_description_content_type="text/markdown",
url="https://github.com/minosvasilias/gpt-manifold",
classifiers=[
"License :: OSI Approved :: MIT License",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.6",
"Programming Language :: Python :: 3.7",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
],
)

0 comments on commit cf12244

Please sign in to comment.