From 317969286a8b2703d2453dac9d63e883452996d0 Mon Sep 17 00:00:00 2001 From: Timotheus Pokorra Date: Mon, 20 Sep 2021 06:32:00 +0200 Subject: [PATCH] show graph for the whole wallet --- apps/monitor/calc.py | 13 +++ apps/monitor/graph.py | 118 ++++++++++++++++++++++++++++ apps/monitor/templates/monitor.html | 41 +++++++++- apps/monitor/views.py | 15 +++- 4 files changed, 182 insertions(+), 5 deletions(-) diff --git a/apps/monitor/calc.py b/apps/monitor/calc.py index 4bb04f7..ec8979a 100644 --- a/apps/monitor/calc.py +++ b/apps/monitor/calc.py @@ -150,3 +150,16 @@ class Calc: total_tax_free += out["value_tax_free"] return (total_investment, current_value, total_tax_free, rateEUR.rate, rateUSD.rate, last_updated, out) + + def GetWalletGraphs(self, userid): + out = {} + out["graphs"] = [] + out["graphs"].append({"id": "w1", "label": "1 week", "period": "number_of_days=7"}) + out["graphs"].append({"id": "m1", "active": "active", "label": "1 month", "period": "number_of_days=30"}) + out["graphs"].append({"id": "m6", "label": "6 months", "period": "number_of_days=180"}) + out["graphs"].append({"id": "y1", "label": "1 year", "period": "number_of_days=365"}) + out["graphs"].append({"id": "y3", "label": "3 years", "period": "number_of_days=" + str(365*3)}) + out["graphs"].append({"id": "y5", "label": "5 years", "period": "number_of_days=" + str(365*5)}) + out["graphs"].append({"id": "y10", "label": "10 years", "period": "number_of_days=" + str(365*10)}) + + return (out["graphs"]) diff --git a/apps/monitor/graph.py b/apps/monitor/graph.py index ba8373a..c2d5b1a 100644 --- a/apps/monitor/graph.py +++ b/apps/monitor/graph.py @@ -7,6 +7,7 @@ from matplotlib.figure import Figure import matplotlib.ticker as plticker import matplotlib.dates as mdates from django.http import HttpResponse +from decimal import Decimal class Graph: @@ -113,3 +114,120 @@ class Graph: canvas = FigureCanvasAgg(fig) canvas.print_png(response) return response + + def wallet_graph_days(self, Userid, Fiat, DayDiff): + + x = [] + y = [] + y2 = [] + + with connection.cursor() as cursor: + # first get the relevant crypto currencies + sql = "SELECT distinct crypto_currency FROM transaction where owner_id = %s" + cursor.execute(sql, [Userid,]) + currency_rows = cursor.fetchall() + cryptos = [] + for currency_row in currency_rows: + cryptos.append(currency_row[0]) + + # loop through the days + start_date = datetime.datetime.today().replace(hour=0, minute=0, second=0, microsecond=0) - datetime.timedelta(days=int(DayDiff)) + end_date = datetime.datetime.today().replace(hour=0, minute=0, second=0, microsecond=0) + delta = datetime.timedelta(days=1) + + while start_date <= end_date: + date = start_date + start_date += delta + + total_fiat_amount = Decimal(0) + total_fiat_value = Decimal(0) + + # get the average exchange rates for this day + sql = """SELECT AVG(rate), crypto_currency + FROM exchangerate + WHERE fiat_currency = %s + AND crypto_currency IN %s + AND datetime_valid BETWEEN %s AND %s + GROUP BY crypto_currency""" + cursor.execute(sql, [Fiat, cryptos, date, date + delta]) + rate_rows = cursor.fetchall() + + # get the current amount on that day + sql = """SELECT crypto_currency, transaction_type, SUM(crypto_amount), SUM(fiat_amount), SUM(crypto_fee), SUM(fiat_fee) + FROM transaction + WHERE owner_id = %s + AND date_valid <= %s + GROUP BY crypto_currency, transaction_type""" + cursor.execute(sql, [Userid, date]) + amount_rows = cursor.fetchall() + + for rate_row in rate_rows: + rate = rate_row[0] + crypto = rate_row[1] + total_crypto_amount = Decimal(0) + + for amount_row in amount_rows: + tr_crypto = amount_row[0] + if tr_crypto == crypto: + tr_type = amount_row[1] + tr_amount = amount_row[2] + tr_fiat_amount = amount_row[3] + tr_crypto_fee = amount_row[4] + tr_fiat_fee = amount_row[5] + if tr_amount: + if tr_type == "S": + total_crypto_amount -= tr_amount + total_fiat_amount += tr_fiat_amount + elif tr_type == "B": + total_crypto_amount += tr_amount + total_fiat_amount -= tr_fiat_amount + if tr_crypto_fee: + total_crypto_amount -= tr_crypto_fee + if tr_fiat_fee: + total_fiat_value -= tr_fiat_fee + total_fiat_amount -= tr_fiat_fee + total_fiat_value += total_crypto_amount * rate + + x.append(date) + y.append(total_fiat_value) + y2.append(total_fiat_amount) + + + if len(x) == 0: + raise Exception("no data for this time range in the database") + + fig_size = plt.rcParams["figure.figsize"] + fig_size[0] = 5 + fig_size[1] = 4 + plt.rcParams["figure.figsize"] = fig_size + + fig = Figure() + ax = fig.add_subplot(1, 1, 1) + + ax.plot(x, y, color='green', linestyle='dashed', linewidth = 2, + marker='o', markerfacecolor='blue', markersize=2) + ax.plot(x, y2, color='blue', linestyle='dashed', linewidth = 2, + marker='o', markerfacecolor='red', markersize=2) + + if int(DayDiff) <= 30: + hours = mdates.DayLocator(interval = 6) + elif int(DayDiff) <= 180: + hours = mdates.DayLocator(interval = 30) + elif int(DayDiff) <= 360: + hours = mdates.DayLocator(interval = int((int(DayDiff)/6))) + else: + hours = mdates.DayLocator(interval = 360) + + h_fmt = mdates.DateFormatter('%b %d\n%Y') + ax.xaxis.set_major_locator(hours) + ax.xaxis.set_major_formatter(h_fmt) + + #ax.set_xlabel("time") + ax.set_ylabel(Fiat) + Crypto = "Wallet" + ax.set_title(('%s in %s' % (Crypto, Fiat))) + + response = HttpResponse(content_type = 'image/png') + canvas = FigureCanvasAgg(fig) + canvas.print_png(response) + return response diff --git a/apps/monitor/templates/monitor.html b/apps/monitor/templates/monitor.html index fd2bdbf..8feeaaa 100644 --- a/apps/monitor/templates/monitor.html +++ b/apps/monitor/templates/monitor.html @@ -118,8 +118,47 @@ {% endfor %} -


+ + +
+ +
+ {% for g in wallet.graphs %} +
+

{{ g.label }}

+
+
+ {% endfor %} +
+
+ +


{% endblock %} diff --git a/apps/monitor/views.py b/apps/monitor/views.py index d32c39c..603d1c3 100644 --- a/apps/monitor/views.py +++ b/apps/monitor/views.py @@ -25,8 +25,11 @@ def monitor(request): django_timezone = pytz.timezone(settings.TIME_ZONE) + wallet = {"rateEUR": current_value, "graphs": calc.GetWalletGraphs(request.user.id)} + return render(request,"monitor.html", {'cryptos':cryptos, + 'wallet': wallet, 'total_tax_free': total_tax_free, 'total_investment': total_investment, 'current_value': current_value, @@ -42,7 +45,11 @@ def graph(request): Crypto = request.GET['crypto'] Fiat = request.GET['fiat'] - if 'number_of_days' in request.GET: - return Graph().graph_days(Crypto, Fiat, request.GET['number_of_days']) - if 'number_of_hours' in request.GET: - return Graph().graph_hours(Crypto, Fiat, request.GET['number_of_hours']) + if Crypto == "WALLET": + if 'number_of_days' in request.GET: + return Graph().wallet_graph_days(request.user.id, Fiat, request.GET['number_of_days']) + else: + if 'number_of_days' in request.GET: + return Graph().graph_days(Crypto, Fiat, request.GET['number_of_days']) + if 'number_of_hours' in request.GET: + return Graph().graph_hours(Crypto, Fiat, request.GET['number_of_hours'])