def test_build_graph(self): # Hand-crafted offers to produce a profitable path offers_with_vendor = [ Offer(league="Heist", have="Orb of Regret", want="Chaos Orb", stock=8, conversion_rate=8, contact_ign="some_guy"), Offer(league="Heist", have="Orb of Alchemy", want="Orb of Regret", stock=8, conversion_rate=1, contact_ign=VENDOR_OFFER_IGN), Offer(league="Heist", have="Chaos Orb", want="Orb of Alchemy", stock=100, conversion_rate=.25, contact_ign="some_guy"), ] graph = build_graph(offers_with_vendor) paths = find_paths(graph, "Chaos Orb", "Chaos Orb", user_config) self.assertTrue(len(paths) > 0)
async def fetch_offer_async(self, client_session: aiohttp.ClientSession, task: Task) -> List[Offer]: url = "https://currency.poe.trade/search" params = { "league": task.league, "want": self.item_list.map_item(task.want, self.name()), "have": self.item_list.map_item(task.have, self.name()), "online": "x", } response = await client_session.request("GET", url=url, params=params) html = await response.text() if response.status is not 200: logging.debug("Error during poe.trade fetch: Status {}".format( response.status)) logging.debug(html) raise TaskException() offers = PoeTrade.parse_conversion_offers(html) offers = filter_large_outliers(offers)[:task.limit] offers = [ Offer(task.league, task.have, task.want, x["contact_ign"], x["conversion_rate"], x["stock"]) for x in offers ] return offers
async def fetch_offer_async(self, client_session: aiohttp.ClientSession, task: Task) -> List[Offer]: offer_ids: List[str] = [] query_id = None offers: List[Dict] = [] # Fetching offer ids is rate-limited by 12:6:60,20:12:300 offer_id_url = "http://www.pathofexile.com/api/trade/exchange/{}".format( urllib.parse.quote(task.league)) payload = { "exchange": { "status": { "option": "online" }, "have": [self.item_list.map_item(task.have, self.name())], "want": [self.item_list.map_item(task.want, self.name())], } } try: query_id, offer_ids = await fetch_ids(client_session, offer_id_url, payload) offers = [] except Exception as e: logging.debug("Rate limited during ids: {} -> {}".format( task.have, task.want)) logging.debug("Exception: {}".format(e)) raise TaskException() try: if len(offer_ids) != 0: # Fetching offer data is rate-limited by 12:4:10,16:12:300 id_string = ",".join(offer_ids[:self.max_offers_per_request]) url = "http://www.pathofexile.com/api/trade/fetch/{}?query={}&exchange".format( id_string, query_id) response = await client_session.get(url) if response.status != 200: raise TaskException() json = await response.json() raw_offers = json["result"] offers = [ PoeOfficial.map_offers_details(x) for x in raw_offers ] offers = filter_large_outliers(offers)[:task.limit] offers = [ Offer(task.league, task.have, task.want, x["contact_ign"], x["conversion_rate"], x["stock"]) for x in offers ] return offers except Exception as e: logging.debug("Rate limited during data: {} -> {}".format( task.have, task.want)) logging.debug("Exception: {}".format(e)) raise TaskException()
def build_vendor_offers(league: str) -> List[Offer]: ret: List[Offer] = [] for raw in raw_vendor_offers: (sell, buy, conversion_rate) = raw offer = Offer(league=league, contact_ign=VENDOR_OFFER_IGN, conversion_rate=conversion_rate, have=sell, want=buy, stock=1_000_000) ret.append(offer) return ret
def expected_paths_small_same_currency() -> List[List[Offer]]: return [ [ Offer(contact_ign="wreddnuy", conversion_rate=12.0, stock=100, have="Chaos", want="Alteration", league=LEAGUE), Offer(contact_ign="Shioua_ouah", conversion_rate=0.6897, stock=1576, have="Alteration", want="Chromatic", league=LEAGUE), Offer(contact_ign="MVP_Kefir", conversion_rate=0.087, stock=20, have="Chromatic", want="Chaos", league=LEAGUE), ], [ Offer(contact_ign="wreddnuy", conversion_rate=12.0, stock=100, have="Chaos", want="Alteration", league=LEAGUE), Offer(contact_ign="Shioua_ouah", conversion_rate=0.6897, stock=1576, have="Alteration", want="Chromatic", league=LEAGUE), Offer(contact_ign="_ZEUS___", conversion_rate=0.0909, stock=100, have="Chromatic", want="Chaos", league=LEAGUE) ], [ Offer(contact_ign="wreddnuy", conversion_rate=12.0, stock=100, have="Chaos", want="Alteration", league=LEAGUE), Offer(contact_ign="Ashkeri", conversion_rate=0.7143, stock=449, have="Alteration", want="Chromatic", league=LEAGUE), Offer(contact_ign="MVP_Kefir", conversion_rate=0.087, stock=200, have="Chromatic", want="Chaos", league=LEAGUE), ], [ Offer(contact_ign="wreddnuy", conversion_rate=12.0, stock=100, have="Chaos", want="Alteration", league=LEAGUE), Offer(contact_ign="Ashkeri", conversion_rate=0.7143, stock=449, have="Alteration", want="Chromatic", league=LEAGUE), Offer(contact_ign="_ZEUS___", conversion_rate=0.0909, stock=100, have="Chromatic", want="Chaos", league=LEAGUE) ], ]
import unittest from src.config.user_config import UserConfig from src.core.graph import build_graph, find_paths, build_conversion, is_profitable from src.core.offer import Offer from src.core.edge import Edge from typing import List, Dict LEAGUE = "Abyss" test_offers: List[Offer] = [ Offer( contact_ign="KnifeySpooneyClaw", conversion_rate=0.0893, stock=153, want="Chaos", have="Alteration", league="Abyss", ), Offer( contact_ign="_ZEUS___", conversion_rate=0.0909, stock=10, want="Chaos", have="Chromatic", league="Abyss", ), Offer( contact_ign="MVP_Kefir", conversion_rate=0.087, stock=20,
async def fetch_offer_async(self, client_session: aiohttp.ClientSession, task: Task) -> List[Offer]: await self.throttler_ensemble.wait() client_session.headers.update({ "User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.71 Safari/537.36", "Cookie": "POESESSID=be398733532f6a251513aabc3200790b" }) offer_ids: List[str] = [] query_id = None offers: List[Offer] = [] # Fetching offer ids is rate-limited by 3:5:60,7:15:60,15:90:120,45:300:1800 offer_id_url = "http://www.pathofexile.com/api/trade/exchange/{}".format( urllib.parse.quote(task.league)) payload = { "exchange": { "status": { "option": "online" }, "have": [self.item_list.map_item(task.have, self.name())], "want": [self.item_list.map_item(task.want, self.name())], } } response = await client_session.request("POST", url=offer_id_url, json=payload) if response.status == 429: logging.debug("Body: {}".format(response.text)) logging.debug("Rate limited during ids: {} -> {}".format( task.have, task.want)) await AsyncLimiter(60, 1).acquire() if response.status != 200: raise TaskException(response.status) json = await response.json() offer_ids = json["result"] query_id = json["id"] offers = [] if len(offer_ids) != 0: id_string = ",".join(offer_ids[:self.max_offers_per_request]) url = "http://www.pathofexile.com/api/trade/fetch/{}?query={}&exchange".format( id_string, query_id) response = await client_session.get(url) if response.status == 429: logging.debug("Body: {}".format(response.text)) logging.debug("Rate limited during ids: {} -> {}".format( task.have, task.want)) await AsyncLimiter(60, 1).acquire() if response.status != 200: raise TaskException(response.status) json = await response.json() raw_offers: List[Dict[str, Any]] = json["result"] offers_details = [ PoeOfficial.map_offers_details(x) for x in raw_offers ] offers_details = filter_large_outliers(offers_details)[:task.limit] offers = [ Offer(league=task.league, have=task.have, want=task.want, contact_ign=details["contact_ign"], conversion_rate=details["conversion_rate"], stock=details["stock"]) for details in offers_details ] return offers