Allow viewing profit
This commit is contained in:
parent
1e201e3f26
commit
77dcd4dd8f
|
@ -20,7 +20,7 @@ from django.contrib.auth.views import LogoutView
|
||||||
from django.urls import include, path
|
from django.urls import include, path
|
||||||
from two_factor.urls import urlpatterns as tf_urls
|
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
|
# from core.views.stripe_callbacks import Callback
|
||||||
|
|
||||||
|
@ -185,4 +185,9 @@ urlpatterns = [
|
||||||
ads.AdRedist.as_view(),
|
ads.AdRedist.as_view(),
|
||||||
name="ad_redist",
|
name="ad_redist",
|
||||||
),
|
),
|
||||||
|
path(
|
||||||
|
"profit/<str:type>/",
|
||||||
|
profit.Profit.as_view(),
|
||||||
|
name="profit",
|
||||||
|
),
|
||||||
] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
|
] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
|
||||||
|
|
|
@ -1,10 +1,13 @@
|
||||||
# Twisted imports
|
# Twisted imports
|
||||||
import logging
|
import logging
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
import asyncio
|
||||||
|
|
||||||
import urllib3
|
import urllib3
|
||||||
|
|
||||||
# Other library imports
|
# Other library imports
|
||||||
|
from core.models import Aggregator, Platform
|
||||||
|
|
||||||
from aiocoingecko import AsyncCoinGeckoAPISession
|
from aiocoingecko import AsyncCoinGeckoAPISession
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from elasticsearch import AsyncElasticsearch
|
from elasticsearch import AsyncElasticsearch
|
||||||
|
@ -38,28 +41,46 @@ class Money(object):
|
||||||
)
|
)
|
||||||
self.es = client
|
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.
|
Run all the balance checks that output into ES in another thread.
|
||||||
"""
|
"""
|
||||||
total = await self.get_total()
|
if not all([user, nordigen, agora]):
|
||||||
remaining = await self.get_remaining()
|
raise Exception
|
||||||
profit = await self.get_profit()
|
|
||||||
profit_with_trades = await self.get_profit(True)
|
# I hate circular dependencies
|
||||||
open_trades = await self.get_open_trades_usd()
|
self.nordigen = nordigen
|
||||||
total_remaining = await self.get_total_remaining()
|
self.agora = agora
|
||||||
total_with_trades = await self.get_total_with_trades()
|
|
||||||
# This will make them all run concurrently, hopefully not hitting rate limits
|
aggregators = Aggregator.objects.filter(user=user, enabled=True)
|
||||||
for x in (
|
platforms = Platform.objects.filter(user=user, enabled=True)
|
||||||
total,
|
|
||||||
remaining,
|
order = [
|
||||||
profit,
|
"total",
|
||||||
profit_with_trades,
|
# "remaining",
|
||||||
open_trades,
|
# "profit",
|
||||||
total_remaining,
|
# "profit_with_trades",
|
||||||
total_with_trades,
|
# "open_trades",
|
||||||
):
|
# "total_remaining",
|
||||||
yield x
|
# "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):
|
# def setup_loops(self):
|
||||||
# """
|
# """
|
||||||
|
@ -255,9 +276,43 @@ class Money(object):
|
||||||
await self.write_to_es("get_total_usd", cast_es)
|
await self.write_to_es("get_total_usd", cast_es)
|
||||||
return total_usd
|
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
|
# 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
|
# 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.
|
Get all the values corresponding to the amount of money we hold.
|
||||||
:return: ((total SEK, total USD, total GBP),
|
:return: ((total SEK, total USD, total GBP),
|
||||||
|
@ -267,30 +322,20 @@ class Money(object):
|
||||||
tuple(float, float),
|
tuple(float, float),
|
||||||
tuple(float, float))
|
tuple(float, float))
|
||||||
"""
|
"""
|
||||||
total_sinks_usd = await self.sinks.get_total_usd()
|
total_sinks_usd = await self.gather_total_map(aggregators)
|
||||||
agora_wallet_xmr = await self.agora.api.wallet_balance_xmr()
|
agora_wallet_xmr = await self.gather_wallet_balance_xmr(platforms)
|
||||||
agora_wallet_btc = await self.agora.api.wallet_balance()
|
agora_wallet_btc = await self.gather_wallet_balance(platforms)
|
||||||
# lbtc_wallet_btc = await self.lbtc.api.wallet_balance()
|
# lbtc_wallet_btc = await self.lbtc.api.wallet_balance()
|
||||||
if not agora_wallet_xmr["success"]:
|
|
||||||
return False
|
total_xmr_agora = agora_wallet_xmr
|
||||||
if not agora_wallet_btc["success"]:
|
total_btc_agora = agora_wallet_btc
|
||||||
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_btc_lbtc = lbtc_wallet_btc["response"]["data"]["total"]["balance"]
|
# total_btc_lbtc = lbtc_wallet_btc["response"]["data"]["total"]["balance"]
|
||||||
# Get the XMR -> USD exchange rate
|
# 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
|
# Get the BTC -> USD exchange rate
|
||||||
btc_usd = self.cg.get_price(ids="bitcoin", vs_currencies=["USD"])
|
btc_usd = await cg.get_price(ids="bitcoin", vs_currencies="USD")
|
||||||
|
|
||||||
# Convert the Agora XMR total to USD
|
# Convert the Agora XMR total to USD
|
||||||
total_usd_agora_xmr = float(total_xmr_agora) * xmr_usd["monero"]["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_usd = total_usd
|
||||||
price_gbp = rates["GBP"] * total_usd
|
price_gbp = rates["GBP"] * total_usd
|
||||||
|
|
||||||
cast = (
|
# cast = (
|
||||||
(
|
# (
|
||||||
price_sek,
|
# price_sek,
|
||||||
price_usd,
|
# price_usd,
|
||||||
price_gbp,
|
# price_gbp,
|
||||||
), # Total prices in our 3 favourite currencies
|
# ), # Total prices in our 3 favourite currencies
|
||||||
(
|
# (
|
||||||
total_xmr_usd,
|
# total_xmr_usd,
|
||||||
total_btc_usd,
|
# total_btc_usd,
|
||||||
), # Total USD balance in only Agora
|
# ), # Total USD balance in only Agora
|
||||||
(total_xmr, total_btc),
|
# (total_xmr, total_btc),
|
||||||
) # Total XMR and BTC balance in Agora
|
# ) # Total XMR and BTC balance in Agora
|
||||||
|
|
||||||
|
# TODO
|
||||||
cast_es = {
|
cast_es = {
|
||||||
"price_sek": price_sek,
|
"price_sek": price_sek,
|
||||||
"price_usd": price_usd,
|
"price_usd": price_usd,
|
||||||
|
@ -348,8 +394,8 @@ class Money(object):
|
||||||
"total_sinks_usd": total_sinks_usd,
|
"total_sinks_usd": total_sinks_usd,
|
||||||
"total_usd_agora": total_usd_agora,
|
"total_usd_agora": total_usd_agora,
|
||||||
}
|
}
|
||||||
await self.write_to_es("get_total", cast_es)
|
# await self.write_to_es("get_total", cast_es)
|
||||||
return cast
|
return cast_es
|
||||||
|
|
||||||
async def get_remaining(self):
|
async def get_remaining(self):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -219,7 +219,7 @@
|
||||||
Home
|
Home
|
||||||
</a>
|
</a>
|
||||||
{% if user.is_authenticated %}
|
{% if user.is_authenticated %}
|
||||||
<a class="navbar-item" href="#">
|
<a class="navbar-item" href="{% url 'profit' type='page' %}">
|
||||||
Profit
|
Profit
|
||||||
</a>
|
</a>
|
||||||
<div class="navbar-item has-dropdown is-hoverable">
|
<div class="navbar-item has-dropdown is-hoverable">
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
{% load cache %}
|
||||||
|
{% load cachalot cache %}
|
||||||
|
{% get_last_invalidation 'core.Platform' as last %}
|
||||||
|
{% include 'mixins/partials/notify.html' %}
|
||||||
|
{# cache 600 objects_platform_profit request.user.id object_list type last #}
|
||||||
|
{% for platform_name, profit_map in object_list.items %}
|
||||||
|
<h2 class="title is-4">{{ platform_name }}</h2>
|
||||||
|
<table
|
||||||
|
class="table is-fullwidth is-hoverable"
|
||||||
|
hx-target="#{{ context_object_name }}-table"
|
||||||
|
id="{{ context_object_name }}-table"
|
||||||
|
hx-swap="outerHTML"
|
||||||
|
hx-trigger="{{ context_object_name_singular }}Event from:body"
|
||||||
|
hx-get="{{ list_url }}">
|
||||||
|
<thead>
|
||||||
|
<th>id</th>
|
||||||
|
</thead>
|
||||||
|
{% for item in profit_map.values %}
|
||||||
|
<tr>
|
||||||
|
<td> {{ item }}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
</table>
|
||||||
|
{% endfor %}
|
||||||
|
{# endcache #}
|
|
@ -13,6 +13,7 @@ from mixins.views import (
|
||||||
from two_factor.views.mixins import OTPRequiredMixin
|
from two_factor.views.mixins import OTPRequiredMixin
|
||||||
|
|
||||||
from core.clients.aggregators.nordigen import NordigenClient
|
from core.clients.aggregators.nordigen import NordigenClient
|
||||||
|
|
||||||
from core.forms import AggregatorForm
|
from core.forms import AggregatorForm
|
||||||
from core.models import Aggregator
|
from core.models import Aggregator
|
||||||
from core.util import logs
|
from core.util import logs
|
||||||
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
from django.contrib.auth.mixins import LoginRequiredMixin
|
||||||
|
from django.http import HttpResponse
|
||||||
|
from django.shortcuts import render
|
||||||
|
from django.urls import reverse
|
||||||
|
from django.views import View
|
||||||
|
from mixins.views import (
|
||||||
|
ObjectCreate,
|
||||||
|
ObjectDelete,
|
||||||
|
ObjectList,
|
||||||
|
ObjectRead,
|
||||||
|
ObjectUpdate,
|
||||||
|
)
|
||||||
|
from two_factor.views.mixins import OTPRequiredMixin
|
||||||
|
|
||||||
|
from core.clients.aggregators.nordigen import NordigenClient
|
||||||
|
from core.clients.platforms.agora import AgoraClient
|
||||||
|
from core.util import logs
|
||||||
|
from core.models import Platform
|
||||||
|
from core.lib.money import money
|
||||||
|
from core.views.helpers import synchronize_async_helper
|
||||||
|
|
||||||
|
log = logs.get_logger(__name__)
|
||||||
|
|
||||||
|
class Profit(LoginRequiredMixin, OTPRequiredMixin, ObjectRead):
|
||||||
|
context_object_name_singular = "profit"
|
||||||
|
context_object_name = "profit"
|
||||||
|
# detail_template = "partials/profit-info.html"
|
||||||
|
|
||||||
|
def get_object(self, **kwargs):
|
||||||
|
res = synchronize_async_helper(money.check_all(user=self.request.user, nordigen=NordigenClient, agora=AgoraClient))
|
||||||
|
results = {
|
||||||
|
"Bank balance total (USD)": res["total"]["total_sinks_usd"],
|
||||||
|
"Platform balance total (USD)": res["total"]["total_usd_agora"],
|
||||||
|
"Sum of above": res["total"]["total_sinks_usd"] + res["total"]["total_usd_agora"],
|
||||||
|
}
|
||||||
|
return results
|
|
@ -239,18 +239,7 @@ class Money(util.Base):
|
||||||
agora_wallet_xmr = yield self.agora.api.wallet_balance_xmr()
|
agora_wallet_xmr = yield self.agora.api.wallet_balance_xmr()
|
||||||
agora_wallet_btc = yield self.agora.api.wallet_balance()
|
agora_wallet_btc = yield self.agora.api.wallet_balance()
|
||||||
lbtc_wallet_btc = yield self.lbtc.api.wallet_balance()
|
lbtc_wallet_btc = yield 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_xmr_agora = agora_wallet_xmr["response"]["data"]["total"]["balance"]
|
||||||
total_btc_agora = agora_wallet_btc["response"]["data"]["total"]["balance"]
|
total_btc_agora = agora_wallet_btc["response"]["data"]["total"]["balance"]
|
||||||
total_btc_lbtc = lbtc_wallet_btc["response"]["data"]["total"]["balance"]
|
total_btc_lbtc = lbtc_wallet_btc["response"]["data"]["total"]["balance"]
|
||||||
|
|
Loading…
Reference in New Issue