diff --git a/README.md b/README.md index 5193a0d..1dc9587 100644 --- a/README.md +++ b/README.md @@ -66,10 +66,16 @@ This repo is inteded for use with Python 3.9 6. Load your wallet with USDC. -7. Trade! +7. Try the command line interface... ``` - python application/trade.py + python scripts/python/cli.py + ``` + + Or just go trade! + + ``` + python agents/application/trade.py ``` 8. Note: If running the command outside of docker, please set the following env var: @@ -89,18 +95,18 @@ This repo is inteded for use with Python 3.9 The Polymarket Agents architecture features modular components that can be maintained and extended by individual community members. -### Connectors +### APIs Polymarket Agents connectors standardize data sources and order types. -- `Polymarket.py`: defines a Polymarket class that interacts with the Polymarket API to retrieve and manage market and event data, and to execute orders on the Polymarket DEX. It includes methods for API key initialization, market and event data retrieval, and trade execution. The file also provides utility functions for building and signing orders, as well as examples for testing API interactions. - -- `Objects.py`: data models using Pydantic; representations for trades, markets, events, and related entities. - - `Chroma.py`: chroma DB for vectorizing news sources and other API data. Developers are able to add their own vector database implementations. - `Gamma.py`: defines `GammaMarketClient` class, which interfaces with the Polymarket Gamma API to fetch and parse market and event metadata. Methods to retrieve current and tradable markets, as well as defined information on specific markets and events. +- `Polymarket.py`: defines a Polymarket class that interacts with the Polymarket API to retrieve and manage market and event data, and to execute orders on the Polymarket DEX. It includes methods for API key initialization, market and event data retrieval, and trade execution. The file also provides utility functions for building and signing orders, as well as examples for testing API interactions. + +- `Objects.py`: data models using Pydantic; representations for trades, markets, events, and related entities. + ### Scripts Files for managing your local environment, server set-up to run the application remotely, and cli for end-user commands. @@ -164,4 +170,4 @@ Enjoy using the CLI application! If you encounter any issues, feel free to open # Terms of Service -[Terms of Service](https://polymarket.com/tos) prohibit US persons and persons from certain other jurisdictions from trading on Polymarket (via UI & API and including agents developed by persons in restricted jurisdictions), although data and information is viewable globally. \ No newline at end of file +[Terms of Service](https://polymarket.com/tos) prohibit US persons and persons from certain other jurisdictions from trading on Polymarket (via UI & API and including agents developed by persons in restricted jurisdictions), although data and information is viewable globally. diff --git a/application/creator.py b/agents/application/creator.py similarity index 89% rename from application/creator.py rename to agents/application/creator.py index 47839e6..ebef695 100644 --- a/application/creator.py +++ b/agents/application/creator.py @@ -1,8 +1,6 @@ -from application.executor import Executor as Agent -from connectors.gamma import GammaMarketClient as Gamma -from connectors.polymarket import Polymarket - -import time +from agents.application.executor import Executor as Agent +from agents.polymarket.gamma import GammaMarketClient as Gamma +from agents.polymarket.polymarket import Polymarket class Creator: diff --git a/application/cron.py b/agents/application/cron.py similarity index 91% rename from application/cron.py rename to agents/application/cron.py index e64b192..6620e95 100644 --- a/application/cron.py +++ b/agents/application/cron.py @@ -1,5 +1,6 @@ +from agents.application.trade import Trader + import time -from application.trade import Trader from scheduler import Scheduler from scheduler.trigger import Monday diff --git a/application/executor.py b/agents/application/executor.py similarity index 92% rename from application/executor.py rename to agents/application/executor.py index a821727..e6d1f75 100644 --- a/application/executor.py +++ b/agents/application/executor.py @@ -1,19 +1,17 @@ import os import json -import pdb import ast -import time import re from dotenv import load_dotenv from langchain_core.messages import HumanMessage, SystemMessage from langchain_openai import ChatOpenAI -from connectors.gamma import GammaMarketClient as Gamma -from connectors.chroma import PolymarketRAG as Chroma -from connectors.objects import SimpleEvent, SimpleMarket -from application.prompts import Prompter -from connectors.polymarket import Polymarket +from agents.polymarket.gamma import GammaMarketClient as Gamma +from agents.connectors.chroma import PolymarketRAG as Chroma +from agents.utils.objects import SimpleEvent, SimpleMarket +from agents.application.prompts import Prompter +from agents.polymarket.polymarket import Polymarket class Executor: @@ -40,7 +38,7 @@ def get_superforecast( self, event_title: str, market_question: str, outcome: str ) -> str: messages = self.prompter.superforecaster( - event_title=event_title, market_question=market_question, outcome=outcome + description=event_title, question=market_question, outcome=outcome ) result = self.llm.invoke(messages) return result.content diff --git a/application/prompts.py b/agents/application/prompts.py similarity index 96% rename from application/prompts.py rename to agents/application/prompts.py index a993ee1..6a98c4a 100644 --- a/application/prompts.py +++ b/agents/application/prompts.py @@ -22,7 +22,7 @@ def market_analyst(self) -> str: Assign a probability estimate to the event occurring described by the user """ - def sentiment_analyzer(question: str, outcome: str) -> float: + def sentiment_analyzer(self, question: str, outcome: str) -> float: return f""" You are a political scientist trained in media analysis. You are given a question: {question}. @@ -34,7 +34,7 @@ def sentiment_analyzer(question: str, outcome: str) -> float: """ def prompts_polymarket( - data1: str, data2: str, market_question: str, outcome: str + self, data1: str, data2: str, market_question: str, outcome: str ) -> str: current_market_data = str(data1) current_event_data = str(data2) @@ -52,7 +52,7 @@ def prompts_polymarket( I believe {market_question} has a likelihood {float} for outcome of {outcome}. """ - def prompts_polymarket(data1: str, data2: str, user_input: str) -> str: + def prompts_polymarket(self, data1: str, data2: str) -> str: current_market_data = str(data1) current_event_data = str(data2) return f""" @@ -63,13 +63,12 @@ def prompts_polymarket(data1: str, data2: str, user_input: str) -> str: current Polymarket events {current_event_data}. Help users identify markets to trade based on their interests or queries. Provide specific information for markets including probabilities of outcomes. - """ - def routing(system_message: str) -> str: - return f"""You are an expert at routing a user question to the appropriate data source. """ + def routing(self, system_message: str) -> str: + return f"""You are an expert at routing a user question to the appropriate data source. System message: ${system_message}""" - def multiquery(question: str) -> str: + def multiquery(self, question: str) -> str: return f""" You're an AI assistant. Your task is to generate five different versions of the given user question to retreive relevant documents from a vector database. By generating diff --git a/application/trade.py b/agents/application/trade.py similarity index 92% rename from application/trade.py rename to agents/application/trade.py index 0d1876d..b779d91 100644 --- a/application/trade.py +++ b/agents/application/trade.py @@ -1,6 +1,6 @@ -from application.executor import Executor as Agent -from connectors.gamma import GammaMarketClient as Gamma -from connectors.polymarket import Polymarket +from agents.application.executor import Executor as Agent +from agents.polymarket.gamma import GammaMarketClient as Gamma +from agents.polymarket.polymarket import Polymarket import shutil diff --git a/connectors/chroma.py b/agents/connectors/chroma.py similarity index 97% rename from connectors/chroma.py rename to agents/connectors/chroma.py index 905be1b..e34bff3 100644 --- a/connectors/chroma.py +++ b/agents/connectors/chroma.py @@ -1,15 +1,13 @@ import json import os import time -import pdb from langchain_openai import OpenAIEmbeddings from langchain_community.document_loaders import JSONLoader from langchain_community.vectorstores.chroma import Chroma -from connectors.gamma import GammaMarketClient -from connectors.objects import SimpleEvent -from connectors.objects import SimpleMarket +from agents.polymarket.gamma import GammaMarketClient +from agents.utils.objects import SimpleEvent, SimpleMarket class PolymarketRAG: diff --git a/connectors/news.py b/agents/connectors/news.py similarity index 98% rename from connectors/news.py rename to agents/connectors/news.py index e520549..9e8f076 100644 --- a/connectors/news.py +++ b/agents/connectors/news.py @@ -3,7 +3,7 @@ from newsapi import NewsApiClient -from connectors.objects import Article +from agents.utils.objects import Article class News: diff --git a/connectors/search.py b/agents/connectors/search.py similarity index 100% rename from connectors/search.py rename to agents/connectors/search.py diff --git a/connectors/gamma.py b/agents/polymarket/gamma.py similarity index 97% rename from connectors/gamma.py rename to agents/polymarket/gamma.py index d05785a..5958c60 100644 --- a/connectors/gamma.py +++ b/agents/polymarket/gamma.py @@ -1,11 +1,8 @@ import httpx import json -from connectors.objects import Market, PolymarketEvent -from connectors.objects import ClobReward -from connectors.objects import Tag - -from connectors.polymarket import Polymarket +from agents.polymarket.polymarket import Polymarket +from agents.utils.objects import Market, PolymarketEvent, ClobReward, Tag class GammaMarketClient: diff --git a/connectors/polymarket.py b/agents/polymarket/polymarket.py similarity index 98% rename from connectors/polymarket.py rename to agents/polymarket/polymarket.py index 34c1f47..3fe1237 100644 --- a/connectors/polymarket.py +++ b/agents/polymarket/polymarket.py @@ -28,7 +28,7 @@ ) from py_clob_client.order_builder.constants import BUY -from connectors.objects import SimpleMarket, SimpleEvent +from agents.utils.objects import SimpleMarket, SimpleEvent load_dotenv() @@ -194,14 +194,15 @@ def get_all_markets(self) -> "list[SimpleMarket]": try: market_data = self.map_api_to_market(market) markets.append(SimpleMarket(**market_data)) - except: + except Exception as e: + print(e) pass return markets def filter_markets_for_trading(self, markets: "list[SimpleMarket]"): tradeable_markets = [] for market in markets: - if market.active and market.deployed: + if market.active: tradeable_markets.append(market) return tradeable_markets @@ -238,21 +239,25 @@ def get_all_events(self) -> "list[SimpleEvent]": events = [] res = httpx.get(self.gamma_events_endpoint) if res.status_code == 200: + print(len(res.json())) for event in res.json(): try: + print(1) event_data = self.map_api_to_event(event) events.append(SimpleEvent(**event_data)) - except: + except Exception as e: + print(e) pass return events def map_api_to_event(self, event) -> SimpleEvent: + description = event["description"] if "description" in event.keys() else "" return { "id": int(event["id"]), "ticker": event["ticker"], "slug": event["slug"], "title": event["title"], - "description": event["description"], + "description": description, "active": event["active"], "closed": event["closed"], "archived": event["archived"], diff --git a/connectors/objects.py b/agents/utils/objects.py similarity index 99% rename from connectors/objects.py rename to agents/utils/objects.py index e5c71fe..863f56c 100644 --- a/connectors/objects.py +++ b/agents/utils/objects.py @@ -31,13 +31,13 @@ class SimpleMarket(BaseModel): end: str description: str active: bool - deployed: bool + # deployed: Optional[bool] funded: bool # orderMinSize: float # orderPriceMinTickSize: float rewardsMinSize: float rewardsMaxSpread: float - volume: float + # volume: Optional[float] spread: float outcomes: str outcome_prices: str diff --git a/application/utils.py b/agents/utils/utils.py similarity index 100% rename from application/utils.py rename to agents/utils/utils.py diff --git a/connectors/recorder.py b/connectors/recorder.py deleted file mode 100644 index 199cef7..0000000 --- a/connectors/recorder.py +++ /dev/null @@ -1 +0,0 @@ -# record the trades placed here diff --git a/EXAMPLE.md b/docs/EXAMPLE.md similarity index 100% rename from EXAMPLE.md rename to docs/EXAMPLE.md diff --git a/docs/images/cli.png b/docs/images/cli.png new file mode 100644 index 0000000..c5f3065 Binary files /dev/null and b/docs/images/cli.png differ diff --git a/scripts/python/cli.py b/scripts/python/cli.py index 1cae4f9..2430d98 100644 --- a/scripts/python/cli.py +++ b/scripts/python/cli.py @@ -1,12 +1,12 @@ import typer from devtools import pprint -from connectors.polymarket import Polymarket -from application import executor, prompts -from connectors.chroma import PolymarketRAG -from connectors.news import News -from application.trade import Trader -from application.creator import Creator +from agents.polymarket.polymarket import Polymarket +from agents.connectors.chroma import PolymarketRAG +from agents.connectors.news import News +from agents.application.trade import Trader +from agents.application.executor import Executor +from agents.application.creator import Creator app = typer.Typer() polymarket = Polymarket() @@ -15,15 +15,15 @@ @app.command() -def get_all_markets(limit: int = 5, sort_by: str = "volume") -> None: +def get_all_markets(limit: int = 5, sort_by: str = "spread") -> None: """ Query Polymarket's markets """ print(f"limit: int = {limit}, sort_by: str = {sort_by}") markets = polymarket.get_all_markets() markets = polymarket.filter_markets_for_trading(markets) - if sort_by == "volume": - markets = sorted(markets, key=lambda x: x.volume, reverse=True) + if sort_by == "spread": + markets = sorted(markets, key=lambda x: x.spread, reverse=True) markets = markets[:limit] pprint(markets) @@ -78,6 +78,7 @@ def ask_superforecaster(event_title: str, market_question: str, outcome: str) -> print( f"event: str = {event_title}, question: str = {market_question}, outcome (usually yes or no): str = {outcome}" ) + executor = Executor() response = executor.get_superforecast( event_title=event_title, market_question=market_question, outcome=outcome ) @@ -99,6 +100,7 @@ def ask_llm(user_input: str) -> None: """ Ask a question to the LLM and get a response. """ + executor = Executor() response = executor.get_llm_response(user_input) print(f"LLM Response: {response}") @@ -108,6 +110,7 @@ def ask_polymarket_llm(user_input: str) -> None: """ What types of markets do you want trade? """ + executor = Executor() response = executor.get_polymarket_llm(user_input=user_input) print(f"LLM + current markets&events response: {response}") diff --git a/test/test.py b/tests/test.py similarity index 100% rename from test/test.py rename to tests/test.py