From 77dcd4dd8f01b2e7a21b01d6947c9037e3bf21a7 Mon Sep 17 00:00:00 2001 From: Mark Veidemanis Date: Sat, 11 Mar 2023 00:21:58 +0000 Subject: [PATCH] Allow viewing profit --- app/urls.py | 7 +- core/lib/money.py | 154 +++++++++++++++-------- core/templates/base.html | 2 +- core/templates/partials/profit-info.html | 27 ++++ core/views/aggregators.py | 1 + core/views/profit.py | 36 ++++++ handler/lib/money.py | 13 +- 7 files changed, 172 insertions(+), 68 deletions(-) create mode 100644 core/templates/partials/profit-info.html create mode 100644 core/views/profit.py diff --git a/app/urls.py b/app/urls.py index 93dca0b..be090f3 100644 --- a/app/urls.py +++ b/app/urls.py @@ -20,7 +20,7 @@ from django.contrib.auth.views import LogoutView from django.urls import include, path from two_factor.urls import urlpatterns as tf_urls -from core.views import ads, aggregators, banks, base, notifications, platforms +from core.views import ads, aggregators, banks, base, notifications, platforms, profit # from core.views.stripe_callbacks import Callback @@ -185,4 +185,9 @@ urlpatterns = [ ads.AdRedist.as_view(), name="ad_redist", ), + path( + "profit//", + profit.Profit.as_view(), + name="profit", + ), ] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT) diff --git a/core/lib/money.py b/core/lib/money.py index 0fcc17d..128e2d8 100644 --- a/core/lib/money.py +++ b/core/lib/money.py @@ -1,10 +1,13 @@ # Twisted imports import logging from datetime import datetime +import asyncio import urllib3 # Other library imports +from core.models import Aggregator, Platform + from aiocoingecko import AsyncCoinGeckoAPISession from django.conf import settings from elasticsearch import AsyncElasticsearch @@ -38,28 +41,46 @@ class Money(object): ) self.es = client - async def run_checks_in_thread(self): + async def check_all(self, user=None, nordigen=None, agora=None): """ Run all the balance checks that output into ES in another thread. """ - total = await self.get_total() - remaining = await self.get_remaining() - profit = await self.get_profit() - profit_with_trades = await self.get_profit(True) - open_trades = await self.get_open_trades_usd() - total_remaining = await self.get_total_remaining() - total_with_trades = await self.get_total_with_trades() - # This will make them all run concurrently, hopefully not hitting rate limits - for x in ( - total, - remaining, - profit, - profit_with_trades, - open_trades, - total_remaining, - total_with_trades, - ): - yield x + if not all([user, nordigen, agora]): + raise Exception + + # I hate circular dependencies + self.nordigen = nordigen + self.agora = agora + + aggregators = Aggregator.objects.filter(user=user, enabled=True) + platforms = Platform.objects.filter(user=user, enabled=True) + + order = [ + "total", + # "remaining", + # "profit", + # "profit_with_trades", + # "open_trades", + # "total_remaining", + # "total_with_trades", + ] + tasks = [ + self.get_total(aggregators, platforms), + # self.get_remaining(), + # self.get_profit(), + # self.get_profit(True), + # self.get_open_trades_usd(), + # self.get_total_remaining(), + # self.get_total_with_trades(), + ] + task_output = await asyncio.gather(*tasks) + print("TASK OUTPUT", task_output) + results = dict(zip(order, task_output)) + print("RESULTS", results) + + return results + + # def setup_loops(self): # """ @@ -255,9 +276,43 @@ class Money(object): await self.write_to_es("get_total_usd", cast_es) return total_usd + async def gather_total_map(self, aggregators): + total = 0 + for aggregator in aggregators: + run = await self.nordigen(aggregator) + total_map = await run.get_total_map() + total_usd = await self.multiple_to_usd(total_map) + print("gather_total_map total_usd", total_usd) + total += total_usd + + return total + + async def gather_wallet_balance_xmr(self, platforms): + # TODO: check success + total = 0 + for platform in platforms: + run = await self.agora(platform) + xmr = await run.api.wallet_balance_xmr() + xmr = float(xmr["response"]["data"]["total"]["balance"]) + print("gather waller xmr", xmr) + total += xmr + return total + + async def gather_wallet_balance(self, platforms): + # TODO: check success + total = 0 + for platform in platforms: + run = await self.agora(platform) + btc = await run.api.wallet_balance() + btc = float(btc["response"]["data"]["total"]["balance"]) + total += btc + return total + + + # TODO: possibly refactor this into smaller functions which don't return as much # check if this is all really needed in the corresponding withdraw function - async def get_total(self): + async def get_total(self, aggregators, platforms): """ Get all the values corresponding to the amount of money we hold. :return: ((total SEK, total USD, total GBP), @@ -267,30 +322,20 @@ class Money(object): tuple(float, float), tuple(float, float)) """ - total_sinks_usd = await self.sinks.get_total_usd() - agora_wallet_xmr = await self.agora.api.wallet_balance_xmr() - agora_wallet_btc = await self.agora.api.wallet_balance() + total_sinks_usd = await self.gather_total_map(aggregators) + agora_wallet_xmr = await self.gather_wallet_balance_xmr(platforms) + agora_wallet_btc = await self.gather_wallet_balance(platforms) # lbtc_wallet_btc = await self.lbtc.api.wallet_balance() - if not agora_wallet_xmr["success"]: - return False - if not agora_wallet_btc["success"]: - return False - # if not lbtc_wallet_btc["success"]: - # return False - if not agora_wallet_xmr["response"]: - return False - if not agora_wallet_btc["response"]: - return False - # if not lbtc_wallet_btc["response"]: - # return False - total_xmr_agora = agora_wallet_xmr["response"]["data"]["total"]["balance"] - total_btc_agora = agora_wallet_btc["response"]["data"]["total"]["balance"] + + total_xmr_agora = agora_wallet_xmr + total_btc_agora = agora_wallet_btc # total_btc_lbtc = lbtc_wallet_btc["response"]["data"]["total"]["balance"] # Get the XMR -> USD exchange rate - xmr_usd = self.cg.get_price(ids="monero", vs_currencies=["USD"]) + async with AsyncCoinGeckoAPISession() as cg: + xmr_usd = await cg.get_price(ids="monero", vs_currencies="USD") - # Get the BTC -> USD exchange rate - btc_usd = self.cg.get_price(ids="bitcoin", vs_currencies=["USD"]) + # Get the BTC -> USD exchange rate + btc_usd = await cg.get_price(ids="bitcoin", vs_currencies="USD") # Convert the Agora XMR total to USD total_usd_agora_xmr = float(total_xmr_agora) * xmr_usd["monero"]["usd"] @@ -320,19 +365,20 @@ class Money(object): price_usd = total_usd price_gbp = rates["GBP"] * total_usd - cast = ( - ( - price_sek, - price_usd, - price_gbp, - ), # Total prices in our 3 favourite currencies - ( - total_xmr_usd, - total_btc_usd, - ), # Total USD balance in only Agora - (total_xmr, total_btc), - ) # Total XMR and BTC balance in Agora + # cast = ( + # ( + # price_sek, + # price_usd, + # price_gbp, + # ), # Total prices in our 3 favourite currencies + # ( + # total_xmr_usd, + # total_btc_usd, + # ), # Total USD balance in only Agora + # (total_xmr, total_btc), + # ) # Total XMR and BTC balance in Agora + # TODO cast_es = { "price_sek": price_sek, "price_usd": price_usd, @@ -348,8 +394,8 @@ class Money(object): "total_sinks_usd": total_sinks_usd, "total_usd_agora": total_usd_agora, } - await self.write_to_es("get_total", cast_es) - return cast + # await self.write_to_es("get_total", cast_es) + return cast_es async def get_remaining(self): """ diff --git a/core/templates/base.html b/core/templates/base.html index 2189c2b..b7a4c7a 100644 --- a/core/templates/base.html +++ b/core/templates/base.html @@ -219,7 +219,7 @@ Home {% if user.is_authenticated %} - + Profit