Improve market cheating algorithm

This commit is contained in:
Mark Veidemanis 2022-01-09 17:52:26 +00:00
parent ec73d1b2e1
commit 4db63998a1
Signed by: m
GPG Key ID: 5ACFCEED46C0904F
2 changed files with 41 additions and 20 deletions

View File

@ -215,8 +215,8 @@ class Agora(object):
ads_total.append([ad[0], ad[1], ad[2]]) ads_total.append([ad[0], ad[1], ad[2]])
return ads_total return ads_total
def enum_public_ads(self, country, currency, page=0): def enum_public_ads(self, currency, page=0):
ads = self.agora._api_call(api_method=f"buy-monero-online/{currency}/{country}/REVOLUT", query_values={"page": page}) ads = self.agora._api_call(api_method=f"buy-monero-online/{currency}/REVOLUT", query_values={"page": page})
if not ads["success"]: if not ads["success"]:
return False return False
for ad in ads["response"]["data"]["ad_list"]: for ad in ads["response"]["data"]["ad_list"]:
@ -225,14 +225,14 @@ class Agora(object):
if "pagination" in ads["response"]: if "pagination" in ads["response"]:
if "next" in ads["response"]["pagination"]: if "next" in ads["response"]["pagination"]:
page += 1 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]] 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. Wrapper to sort public ads.
""" """
ads = list(self.enum_public_ads(country, currency)) ads = list(self.enum_public_ads(currency.upper()))
if not rates: if not rates:
base_monero_price = self.cg.get_price(ids="monero", vs_currencies=currency)["monero"][currency.lower()] base_monero_price = self.cg.get_price(ids="monero", vs_currencies=currency)["monero"][currency.lower()]
else: else:
@ -246,31 +246,41 @@ class Agora(object):
def sort_ads_annotate_place(self, ads): def sort_ads_annotate_place(self, ads):
ads.sort(key=lambda x: float(x[2])) ads.sort(key=lambda x: float(x[2]))
place = None
for index, ad in enumerate(ads): for index, ad in enumerate(ads):
if ad[1] == settings.Agora.Username: if ad[1] == settings.Agora.Username:
place = index place = index
break break
if place is None:
print("Place is none for ads:", ads)
return (ads, place) return (ads, place)
def update_prices(self): def update_prices(self):
our_ads = self.enum_ads() our_ads = self.enum_ads()
currencies = [x[2].lower() for x in our_ads] currencies = [x[2].lower() for x in our_ads]
public_ad_dict = {}
rates_xmr = self.cg.get_price(ids="monero", vs_currencies=currencies) rates_xmr = self.cg.get_price(ids="monero", vs_currencies=currencies)
for ad_id, country, currency in our_ads: for currency in currencies:
# Get the ads for this country/currency pair
try: 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: except KeyError:
self.log.error("Error getting public ads for currency {currency}", currency=currency) self.log.error("Error getting public ads for currency {currency}", currency=currency)
continue 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}" new_formula = f"coingeckoxmrusd*usd{currency.lower()}*{new_margin}"
rtrn = self.agora.ad_equation(ad_id, new_formula) rtrn = self.agora.ad_equation(ad_id, new_formula)
if not rtrn["success"]: if not rtrn["success"]:
self.log.error("Error updating ad {ad_id}: {response}", ad_id=ad_id, response=rtrn["response"]) 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 Helper function to automatically adjust the price up/down in certain markets
in order to gain the most profits and sales. in order to gain the most profits and sales.
@ -278,14 +288,25 @@ class Agora(object):
ads, place = self.sort_ads_annotate_place(ads) ads, place = self.sort_ads_annotate_place(ads)
if place == 0: if place == 0:
if len(ads) > 1: 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 our_max_adjusted = next_max - 0.01
if our_max_adjusted > float(settings.Agora.MaxMargin): if our_max_adjusted > float(settings.Agora.MaxMargin):
our_max_adjusted = float(settings.Agora.MaxMargin) our_max_adjusted = float(settings.Agora.MaxMargin)
# Lowball next competitor # Lowball next competitor
self.log.info( self.log.info(
"Lowballing next competitor for {country}/{currency}: {margin}", "Lowballing next competitor for {currency}: {margin}",
country=country,
currency=currency, currency=currency,
margin=our_max_adjusted, margin=our_max_adjusted,
) )
@ -297,14 +318,15 @@ class Agora(object):
iter_count = 0 iter_count = 0
while place > 1 and not iter_count > 100: while place > 1 and not iter_count > 100:
iter_count += 1 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): if recommended_margin <= float(settings.Agora.MinMargin):
break break
ads[place][3] = recommended_margin ads[place][3] = recommended_margin
print("Set recommended margin for", currency, recommended_margin)
ads, place = self.sort_ads_annotate_place(ads) ads, place = self.sort_ads_annotate_place(ads)
# Return our adjusted (or left) margin # Return our adjusted (or left) margin
return ads[place][3] return float(ads[place][3])
def nuke_ads(self): def nuke_ads(self):
""" """

View File

@ -301,10 +301,9 @@ class IRCCommands(object):
@staticmethod @staticmethod
def run(cmd, spl, length, authed, msg, agora, revolut, tx): def run(cmd, spl, length, authed, msg, agora, revolut, tx):
if length == 3: if length == 2:
country = spl[1] currency = spl[1]
currency = spl[2] rtrn = agora.wrap_public_ads(currency)
rtrn = agora.wrap_public_ads(country, currency)
for ad in rtrn: for ad in rtrn:
msg(f"({ad[0]}) {ad[1]} {ad[2]} {ad[3]}") msg(f"({ad[0]}) {ad[1]} {ad[2]} {ad[3]}")