robosats/api/utils.py

124 lines
3.7 KiB
Python
Raw Normal View History

import requests, ring, os
from decouple import config
import numpy as np
import requests
2022-01-18 18:24:45 +00:00
from api.models import Order
2022-01-10 01:12:58 +00:00
def get_tor_session():
session = requests.session()
# Tor uses the 9050 port as the default socks port
session.proxies = {'http': 'socks5://127.0.0.1:9050',
'https': 'socks5://127.0.0.1:9050'}
return session
2022-02-17 19:50:10 +00:00
market_cache = {}
2022-02-17 19:50:10 +00:00
@ring.dict(market_cache, expire=3) # keeps in cache for 3 seconds
def get_exchange_rates(currencies):
2022-02-17 19:50:10 +00:00
"""
Params: list of currency codes.
Checks for exchange rates in several public APIs.
Returns the median price list.
2022-02-17 19:50:10 +00:00
"""
2022-01-15 00:28:19 +00:00
session = get_tor_session()
2022-02-17 19:50:10 +00:00
APIS = config("MARKET_PRICE_APIS",
cast=lambda v: [s.strip() for s in v.split(",")])
api_rates = []
for api_url in APIS:
2022-02-17 19:50:10 +00:00
try: # If one API is unavailable pass
if "blockchain.info" in api_url:
blockchain_prices = session.get(api_url).json()
blockchain_rates = []
for currency in currencies:
2022-02-17 19:50:10 +00:00
try: # If a currency is missing place a None
blockchain_rates.append(
float(blockchain_prices[currency]["last"]))
except:
blockchain_rates.append(np.nan)
api_rates.append(blockchain_rates)
2022-02-17 19:50:10 +00:00
elif "yadio.io" in api_url:
yadio_prices = session.get(api_url).json()
yadio_rates = []
for currency in currencies:
try:
2022-02-17 19:50:10 +00:00
yadio_rates.append(float(
yadio_prices["BTC"][currency]))
except:
yadio_rates.append(np.nan)
api_rates.append(yadio_rates)
except:
pass
if len(api_rates) == 0:
2022-02-17 19:50:10 +00:00
return None # Wops there is not API available!
exchange_rates = np.array(api_rates)
median_rates = np.nanmedian(exchange_rates, axis=0)
return median_rates.tolist()
2022-02-17 19:50:10 +00:00
def get_lnd_version():
# If dockerized, return LND_VERSION envvar used for docker image.
# Otherwise it would require LND's version.grpc libraries...
try:
2022-02-17 19:50:10 +00:00
lnd_version = config("LND_VERSION")
return lnd_version
except:
pass
# If not dockerized and LND is local, read from CLI
try:
2022-02-17 19:50:10 +00:00
stream = os.popen("lnd --version")
lnd_version = stream.read()[:-1]
return lnd_version
except:
2022-02-17 19:50:10 +00:00
return ""
robosats_commit_cache = {}
@ring.dict(robosats_commit_cache, expire=3600)
def get_commit_robosats():
commit = os.popen('git log -n 1 --pretty=format:"%H"')
commit_hash = commit.read()
return commit_hash
2022-01-18 18:24:45 +00:00
premium_percentile = {}
@ring.dict(premium_percentile, expire=300)
def compute_premium_percentile(order):
2022-02-17 19:50:10 +00:00
queryset = Order.objects.filter(
currency=order.currency, status=Order.Status.PUB).exclude(id=order.id)
2022-01-18 18:24:45 +00:00
print(len(queryset))
if len(queryset) <= 1:
return 0.5
order_rate = float(order.last_satoshis) / float(order.amount)
rates = []
for similar_order in queryset:
2022-02-17 19:50:10 +00:00
rates.append(
float(similar_order.last_satoshis) / float(similar_order.amount))
2022-01-18 18:24:45 +00:00
rates = np.array(rates)
return round(np.sum(rates < order_rate) / len(rates), 2)
def compute_avg_premium(queryset):
weighted_premiums = []
volumes = []
for tick in queryset:
weighted_premiums.append(tick.premium * tick.volume)
volumes.append(tick.volume)
total_volume = sum(volumes)
# Avg_premium is the weighted average of the premiums by volume
avg_premium = sum(weighted_premiums) / total_volume
return avg_premium, total_volume