From 5786ef3482b032ef2525aeecf94219601e6bb556 Mon Sep 17 00:00:00 2001 From: Mark Veidemanis Date: Sun, 9 Jan 2022 17:52:26 +0000 Subject: [PATCH] Improve market cheating algorithm --- handler/agora.py | 54 +++++++++++++++++++++++++++++++-------------- handler/commands.py | 7 +++--- 2 files changed, 41 insertions(+), 20 deletions(-) diff --git a/handler/agora.py b/handler/agora.py index 8cffcd7..1a8f56f 100644 --- a/handler/agora.py +++ b/handler/agora.py @@ -215,8 +215,8 @@ class Agora(object): ads_total.append([ad[0], ad[1], ad[2]]) return ads_total - def enum_public_ads(self, country, currency, page=0): - ads = self.agora._api_call(api_method=f"buy-monero-online/{currency}/{country}/REVOLUT", query_values={"page": page}) + def enum_public_ads(self, currency, page=0): + ads = self.agora._api_call(api_method=f"buy-monero-online/{currency}/REVOLUT", query_values={"page": page}) if not ads["success"]: return False for ad in ads["response"]["data"]["ad_list"]: @@ -225,14 +225,14 @@ class Agora(object): if "pagination" in ads["response"]: if "next" in ads["response"]["pagination"]: page += 1 - for ad in self.enum_public_ads(country, currency, page): + for ad in self.enum_public_ads(currency, page): yield [ad[0], ad[1], ad[2]] - def wrap_public_ads(self, country, currency, rates=None): + def wrap_public_ads(self, currency, rates=None): """ Wrapper to sort public ads. """ - ads = list(self.enum_public_ads(country, currency)) + ads = list(self.enum_public_ads(currency.upper())) if not rates: base_monero_price = self.cg.get_price(ids="monero", vs_currencies=currency)["monero"][currency.lower()] else: @@ -246,31 +246,41 @@ class Agora(object): def sort_ads_annotate_place(self, ads): ads.sort(key=lambda x: float(x[2])) + place = None for index, ad in enumerate(ads): if ad[1] == settings.Agora.Username: place = index break + if place is None: + print("Place is none for ads:", ads) return (ads, place) def update_prices(self): our_ads = self.enum_ads() currencies = [x[2].lower() for x in our_ads] + public_ad_dict = {} rates_xmr = self.cg.get_price(ids="monero", vs_currencies=currencies) - for ad_id, country, currency in our_ads: - # Get the ads for this country/currency pair + for currency in currencies: try: - public_ads = self.wrap_public_ads(country, currency, rates=rates_xmr["monero"][currency.lower()]) + rates = rates_xmr["monero"][currency] + public_ad_dict[currency] = self.wrap_public_ads(currency, rates=rates) except KeyError: self.log.error("Error getting public ads for currency {currency}", currency=currency) continue - new_margin = self.autoprice(public_ads, country, currency) + for ad_id, country, currency in our_ads: + # Get the ads for this country/currency pair + try: + public_ads = public_ad_dict[currency.lower()] + except KeyError: + continue + new_margin = self.autoprice(public_ads, currency) new_formula = f"coingeckoxmrusd*usd{currency.lower()}*{new_margin}" rtrn = self.agora.ad_equation(ad_id, new_formula) if not rtrn["success"]: self.log.error("Error updating ad {ad_id}: {response}", ad_id=ad_id, response=rtrn["response"]) - self.log.info("Rate for {country}/{currency}: {margin}", country=country, currency=currency, margin=new_margin) + self.log.info("Rate for {currency}: {margin}", currency=currency, margin=new_margin) - def autoprice(self, ads, country, currency): + def autoprice(self, ads, currency): """ Helper function to automatically adjust the price up/down in certain markets in order to gain the most profits and sales. @@ -278,14 +288,25 @@ class Agora(object): ads, place = self.sort_ads_annotate_place(ads) if place == 0: if len(ads) > 1: - next_max = float(ads[1][3]) + competitor_index = None + for index, ad in enumerate(ads): + if ad[1] != settings.Agora.Username: + competitor_index = index + print("Found a competitor at index", competitor_index, ad) + break + else: + print("Skipping ad", ad) + if not competitor_index: + print("Couldn't find a competitor from ads:", ads) + return float(ads[0][3]) + + next_max = float(ads[competitor_index][3]) our_max_adjusted = next_max - 0.01 if our_max_adjusted > float(settings.Agora.MaxMargin): our_max_adjusted = float(settings.Agora.MaxMargin) # Lowball next competitor self.log.info( - "Lowballing next competitor for {country}/{currency}: {margin}", - country=country, + "Lowballing next competitor for {currency}: {margin}", currency=currency, margin=our_max_adjusted, ) @@ -297,14 +318,15 @@ class Agora(object): iter_count = 0 while place > 1 and not iter_count > 100: iter_count += 1 - recommended_margin = float(ads[place][2]) + 0.01 + recommended_margin = float(ads[place][3]) - 0.01 if recommended_margin <= float(settings.Agora.MinMargin): break ads[place][3] = recommended_margin + print("Set recommended margin for", currency, recommended_margin) ads, place = self.sort_ads_annotate_place(ads) # Return our adjusted (or left) margin - return ads[place][3] + return float(ads[place][3]) def nuke_ads(self): """ diff --git a/handler/commands.py b/handler/commands.py index 2f93bcb..9895fee 100644 --- a/handler/commands.py +++ b/handler/commands.py @@ -301,10 +301,9 @@ class IRCCommands(object): @staticmethod def run(cmd, spl, length, authed, msg, agora, revolut, tx): - if length == 3: - country = spl[1] - currency = spl[2] - rtrn = agora.wrap_public_ads(country, currency) + if length == 2: + currency = spl[1] + rtrn = agora.wrap_public_ads(currency) for ad in rtrn: msg(f"({ad[0]}) {ad[1]} {ad[2]} {ad[3]}")