Convert cached currency to relation children of order

This commit is contained in:
Reckless_Satoshi 2022-01-16 08:06:53 -08:00
parent 185cc71e91
commit 2cbc82a535
No known key found for this signature in database
GPG Key ID: 9C4585B561315571
5 changed files with 46 additions and 30 deletions

View File

@ -2,7 +2,7 @@ from django.contrib import admin
from django_admin_relation_links import AdminChangeLinksMixin
from django.contrib.auth.models import Group, User
from django.contrib.auth.admin import UserAdmin
from .models import Order, LNPayment, Profile, MarketTick, CachedExchangeRate
from .models import Order, LNPayment, Profile, MarketTick, Currency
admin.site.unregister(Group)
admin.site.unregister(User)
@ -24,9 +24,9 @@ class EUserAdmin(UserAdmin):
@admin.register(Order)
class OrderAdmin(AdminChangeLinksMixin, admin.ModelAdmin):
list_display = ('id','type','maker_link','taker_link','status','amount','currency','t0_satoshis','is_disputed','is_fiat_sent','created_at','expires_at', 'buyer_invoice_link','maker_bond_link','taker_bond_link','trade_escrow_link')
list_display = ('id','type','maker_link','taker_link','status','amount','currency_link','t0_satoshis','is_disputed','is_fiat_sent','created_at','expires_at', 'buyer_invoice_link','maker_bond_link','taker_bond_link','trade_escrow_link')
list_display_links = ('id','type')
change_links = ('maker','taker','buyer_invoice','maker_bond','taker_bond','trade_escrow')
change_links = ('maker','taker','currency','buyer_invoice','maker_bond','taker_bond','trade_escrow')
list_filter = ('is_disputed','is_fiat_sent','type','currency','status')
@admin.register(LNPayment)
@ -43,8 +43,8 @@ class UserProfileAdmin(AdminChangeLinksMixin, admin.ModelAdmin):
change_links =['user']
readonly_fields = ['avatar_tag']
@admin.register(CachedExchangeRate)
class CachedExchangeRateAdmin(admin.ModelAdmin):
@admin.register(Currency)
class CurrencieAdmin(admin.ModelAdmin):
list_display = ('currency','exchange_rate','timestamp')
readonly_fields = ('currency','exchange_rate','timestamp')

View File

@ -2,7 +2,7 @@ from datetime import time, timedelta
from django.utils import timezone
from .lightning.node import LNNode
from .models import Order, LNPayment, MarketTick, User, CachedExchangeRate
from .models import Order, LNPayment, MarketTick, User, Currency
from decouple import config
import math
@ -72,7 +72,7 @@ class Logics():
if order.is_explicit:
satoshis_now = order.satoshis
else:
exchange_rate = float(CachedExchangeRate.objects.get(currency=order.currency).exchange_rate)
exchange_rate = float(order.currency.exchange_rate)
premium_rate = exchange_rate * (1+float(order.premium)/100)
satoshis_now = (float(order.amount) / premium_rate) * 100*1000*1000
@ -80,7 +80,7 @@ class Logics():
def price_and_premium_now(order):
''' computes order premium live '''
exchange_rate = float(CachedExchangeRate.objects.get(currency=order.currency).exchange_rate)
exchange_rate = float(order.currency.exchange_rate)
if not order.is_explicit:
premium = order.premium
price = exchange_rate * (1+float(premium)/100)
@ -373,7 +373,7 @@ class Logics():
order.last_satoshis = cls.satoshis_now(order)
bond_satoshis = int(order.last_satoshis * BOND_SIZE)
pos_text = 'Buying' if cls.is_buyer(order, user) else 'Selling'
description = (f"RoboSats - Taking 'Order {order.id}' {pos_text} BTC for {str(float(order.amount)) + Order.currency_dict[str(order.currency)]}"
description = (f"RoboSats - Taking 'Order {order.id}' {pos_text} BTC for {str(float(order.amount)) + str(order.currency)}"# Order.currency_dict[str(order.currency)]}"
+ " - This is a taker bond, it will freeze in your wallet temporarily and automatically return. It will be charged if you cheat or cancel.")
# Gen hold Invoice

View File

@ -15,6 +15,24 @@ MAX_TRADE = int(config('MAX_TRADE'))
FEE = float(config('FEE'))
BOND_SIZE = float(config('BOND_SIZE'))
class Currency(models.Model):
currency_dict = json.load(open('./frontend/static/assets/currencies.json'))
currency_choices = [(int(val), label) for val, label in list(currency_dict.items())]
currency = models.PositiveSmallIntegerField(choices=currency_choices, null=False, unique=True)
exchange_rate = models.DecimalField(max_digits=10, decimal_places=2, default=None, null=True, validators=[MinValueValidator(0)])
timestamp = models.DateTimeField(auto_now_add=True)
def __str__(self):
# returns currency label ( 3 letters code)
return self.currency_dict[str(self.currency)]
class Meta:
verbose_name = 'Cached market currency'
verbose_name_plural = 'Currencies'
class LNPayment(models.Model):
class Types(models.IntegerChoices):
@ -62,6 +80,10 @@ class LNPayment(models.Model):
def __str__(self):
return (f'LN-{str(self.id)[:8]}: {self.Concepts(self.concept).label} - {self.Status(self.status).label}')
class Meta:
verbose_name = 'Lightning payment'
verbose_name_plural = 'Lightning payments'
class Order(models.Model):
class Types(models.IntegerChoices):
@ -87,9 +109,6 @@ class Order(models.Model):
FAI = 15, 'Failed lightning network routing'
MLD = 16, 'Maker lost dispute'
TLD = 17, 'Taker lost dispute'
currency_dict = json.load(open('./frontend/static/assets/currencies.json'))
currency_choices = [(int(val), label) for val, label in list(currency_dict.items())]
# order info
status = models.PositiveSmallIntegerField(choices=Status.choices, null=False, default=Status.WFB)
@ -98,7 +117,7 @@ class Order(models.Model):
# order details
type = models.PositiveSmallIntegerField(choices=Types.choices, null=False)
currency = models.PositiveSmallIntegerField(choices=currency_choices, null=False)
currency = models.ForeignKey(Currency, null=True, on_delete=models.SET_NULL)
amount = models.DecimalField(max_digits=9, decimal_places=4, validators=[MinValueValidator(0.00001)])
payment_method = models.CharField(max_length=35, null=False, default="not specified", blank=True)
@ -155,7 +174,7 @@ class Order(models.Model):
def __str__(self):
# Make relational back to ORDER
return (f'Order {self.id}: {self.Types(self.type).label} BTC for {float(self.amount)} {self.currency_dict[str(self.currency)]}')
return (f'Order {self.id}: {self.Types(self.type).label} BTC for {float(self.amount)} {self.currency}')
@receiver(pre_delete, sender=Order)
def delete_lnpayment_at_order_deletion(sender, instance, **kwargs):
@ -219,13 +238,6 @@ class Profile(models.Model):
def avatar_tag(self):
return mark_safe('<img src="%s" width="50" height="50" />' % self.get_avatar())
class CachedExchangeRate(models.Model):
currency = models.PositiveSmallIntegerField(choices=Order.currency_choices, null=False, unique=True)
exchange_rate = models.DecimalField(max_digits=10, decimal_places=2, default=None, null=True, validators=[MinValueValidator(0)])
timestamp = models.DateTimeField(auto_now_add=True)
class MarketTick(models.Model):
'''
Records tick by tick Non-KYC Bitcoin price.
@ -242,7 +254,7 @@ class MarketTick(models.Model):
price = models.DecimalField(max_digits=10, decimal_places=2, default=None, null=True, validators=[MinValueValidator(0)])
volume = models.DecimalField(max_digits=8, decimal_places=8, default=None, null=True, validators=[MinValueValidator(0)])
premium = models.DecimalField(max_digits=5, decimal_places=2, default=None, null=True, validators=[MinValueValidator(-100), MaxValueValidator(999)], blank=True)
currency = models.PositiveSmallIntegerField(choices=Order.currency_choices, null=True)
currency = models.PositiveSmallIntegerField(choices=Currency.currency_choices, null=True)
timestamp = models.DateTimeField(auto_now_add=True)
# Relevant to keep record of the historical fee, so the insight on the premium can be better analyzed
@ -259,7 +271,7 @@ class MarketTick(models.Model):
elif order.taker_bond.status == LNPayment.Status.LOCKED:
volume = order.last_satoshis / 100000000
price = float(order.amount) / volume # Amount Fiat / Amount BTC
market_exchange_rate = float(CachedExchangeRate.objects.get(currency=order.currency).exchange_rate)
market_exchange_rate = float(order.currency.exchange_rate)
premium = 100 * (price / market_exchange_rate - 1)
tick = MarketTick.objects.create(
@ -273,4 +285,7 @@ class MarketTick(models.Model):
def __str__(self):
return f'Tick: {str(self.id)[:8]}'
class Meta:
verbose_name = 'Market tick'
verbose_name_plural = 'Market ticks'

View File

@ -2,7 +2,7 @@ from celery import shared_task
from .lightning.node import LNNode
from django.contrib.auth.models import User
from .models import LNPayment, Order, CachedExchangeRate
from .models import LNPayment, Order, Currency
from .logics import Logics
from .utils import get_exchange_rates
@ -55,14 +55,15 @@ def query_all_lnd_invoices():
@shared_task(name="cache_market", ignore_result=True)
def cache_market():
exchange_rates = get_exchange_rates(list(Order.currency_dict.values()))
exchange_rates = get_exchange_rates(list(Currency.currency_dict.values()))
results = {}
for val in Order.currency_dict:
for val in Currency.currency_dict:
rate = exchange_rates[int(val)-1] # currecies are indexed starting at 1 (USD)
results[val] = {Order.currency_dict[val], rate}
results[val] = {Currency.currency_dict[val], rate}
# Create / Update database cached prices
CachedExchangeRate.objects.update_or_create(
Currency.objects.update_or_create(
id = int(val),
currency = int(val),
# if there is a Cached Exchange rate matching that value, it updates it with defaults below
defaults = {

View File

@ -9,7 +9,7 @@ from django.contrib.auth import authenticate, login, logout
from django.contrib.auth.models import User
from .serializers import ListOrderSerializer, MakeOrderSerializer, UpdateOrderSerializer
from .models import LNPayment, MarketTick, Order
from .models import LNPayment, MarketTick, Order, Currency
from .logics import Logics
from .utils import get_lnd_version, get_commit_robosats
@ -54,7 +54,7 @@ class MakerView(CreateAPIView):
# Creates a new order
order = Order(
type=type,
currency=currency,
currency=Currency.objects.get(id=currency),
amount=amount,
payment_method=payment_method,
premium=premium,