pluto/handler/money.py

145 lines
4.5 KiB
Python
Raw Normal View History

# Other library imports
from pycoingecko import CoinGeckoAPI
from forex_python.converter import CurrencyRates
# Project imports
from settings import settings
import util
class Money(util.Base):
"""
Generic class for handling money-related matters that aren't Revolut or Agora.
"""
def __init__(self):
"""
Initialise the Money object.
Set the logger.
Initialise the CoinGecko API.
"""
super().__init__()
self.cr = CurrencyRates()
self.cg = CoinGeckoAPI()
2022-04-15 14:06:28 +00:00
def lookup_rates(self, platform, ads, rates=None):
"""
Lookup the rates for a list of public ads.
"""
if not rates:
2022-04-12 21:06:28 +00:00
rates = self.cg.get_price(
ids=["monero", "bitcoin"],
2022-04-15 14:06:28 +00:00
vs_currencies=self.markets.get_all_currencies(platform),
2022-04-12 21:06:28 +00:00
)
# Set the price based on the asset
for ad in ads:
if ad[4] == "XMR":
coin = "monero"
elif ad[4] == "BTC":
coin = "bitcoin" # No s here
currency = ad[5]
base_currency_price = rates[coin][currency.lower()]
price = float(ad[2])
rate = round(price / base_currency_price, 2)
ad.append(rate)
# TODO: sort?
return sorted(ads, key=lambda x: x[2])
def get_rates_all(self):
"""
Get all rates that pair with USD.
:return: dictionary of USD/XXX rates
:rtype: dict
"""
rates = self.cr.get_rates("USD")
return rates
2022-04-15 14:12:31 +00:00
def get_acceptable_margins(self, platform, currency, amount):
"""
Get the minimum and maximum amounts we would accept a trade for.
:param currency: currency code
:param amount: amount
:return: (min, max)
:rtype: tuple
"""
2022-04-15 14:12:31 +00:00
sets = util.get_settings(platform)
rates = self.get_rates_all()
if currency == "USD":
2022-04-15 14:12:31 +00:00
min_amount = amount - float(sets.AcceptableUSDMargin)
max_amount = amount + float(sets.AcceptableUSDMargin)
return (min_amount, max_amount)
amount_usd = amount / rates[currency]
2022-04-15 14:12:31 +00:00
min_usd = amount_usd - float(sets.AcceptableUSDMargin)
max_usd = amount_usd + float(sets.AcceptableUSDMargin)
min_local = min_usd * rates[currency]
max_local = max_usd * rates[currency]
return (min_local, max_local)
2022-02-22 20:12:26 +00:00
2022-04-15 14:12:31 +00:00
def get_minmax(self, platform, asset, currency):
sets = util.get_settings(platform)
rates = self.get_rates_all()
if currency not in rates and not currency == "USD":
self.log.error(f"Can't create ad without rates: {currency}")
return
if asset == "XMR":
2022-04-15 14:12:31 +00:00
min_usd = float(sets.MinUSDXMR)
max_usd = float(sets.MaxUSDXMR)
elif asset == "BTC":
2022-04-15 14:12:31 +00:00
min_usd = float(sets.MinUSDBTC)
max_usd = float(sets.MaxUSDBTC)
if currency == "USD":
min_amount = min_usd
max_amount = max_usd
else:
min_amount = rates[currency] * min_usd
max_amount = rates[currency] * max_usd
return (min_amount, max_amount)
2022-02-22 20:12:26 +00:00
def to_usd(self, amount, currency):
if currency == "USD":
return float(amount)
else:
rates = self.get_rates_all()
return float(amount) / rates[currency]
2022-02-24 22:28:00 +00:00
2022-04-09 18:59:22 +00:00
def multiple_to_usd(self, currency_map):
"""
Convert multiple curencies to USD while saving API calls.
"""
rates = self.get_rates_all()
cumul = 0
for currency, amount in currency_map.items():
if currency == "USD":
cumul += float(amount)
else:
cumul += float(amount) / rates[currency]
return cumul
2022-02-24 22:28:00 +00:00
# TODO: move to money
def get_profit(self, trades=False):
"""
Check how much total profit we have made.
:return: profit in USD
:rtype: float
"""
total_usd = self.tx.get_total_usd()
if not total_usd:
return False
if trades:
trades_usd = self.tx.get_open_trades_usd()
total_usd += trades_usd
profit = total_usd - float(settings.Money.BaseUSD)
if trades:
cast_es = {
"profit_trades_usd": profit,
}
else:
cast_es = {
"profit_usd": profit,
}
self.tx.write_to_es("get_profit", cast_es)
return profit