-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
15d2754
commit cf12244
Showing
7 changed files
with
318 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
# gpt-manifold | ||
|
||
 | ||
|
||
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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
from .gpt_manifold import init | ||
|
||
if __name__ == "__main__": | ||
init() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
[bdist_wheel] | ||
universal=1 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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", | ||
], | ||
) |