import trades from bitcoin.de via API

fixes #15
This commit is contained in:
2021-02-14 00:09:21 +01:00
parent fb468b20bc
commit 5e27eae9ca
10 changed files with 178 additions and 1 deletions
+10
View File
@@ -24,3 +24,13 @@ class TransactionForm(forms.ModelForm):
'fiat_currency': forms.Select(choices = fiat_currencies), 'fiat_currency': forms.Select(choices = fiat_currencies),
'crypto_currency': forms.Select(choices = crypto_currencies), 'crypto_currency': forms.Select(choices = crypto_currencies),
} }
class ImportForm(forms.Form):
api_key = forms.CharField(label='API Key', widget=forms.PasswordInput, max_length=100)
api_secret = forms.CharField(label='API Secret', widget=forms.PasswordInput, max_length=100)
YEAR_CHOICES = []
now = datetime.datetime.now()
for y in range(2000,now.year+1):
YEAR_CHOICES.append(y)
start_date = forms.DateField(label='Start Date', widget=forms.SelectDateWidget(years=YEAR_CHOICES), initial=datetime.datetime(year=now.year, month=1, day=1))
+55
View File
@@ -0,0 +1,55 @@
from django.db import connection
from apps.transactions.models import Transaction
from decimal import Decimal
import datetime
import btcde
class ImportBtcDe:
def Import(self, apiKey, apiSecret, StartDate, Owner):
conn = btcde.Connection(apiKey, apiSecret)
page=1
while True:
response = conn.showMyTrades(date_start=StartDate.isoformat()+"T00:00:00+00:00", state=1,page=page)
trades = response.get('trades')
if not trades:
raise Exception(('%s' % (response,)))
raise Exception(('%s %s %s ' % (apiKey,apiSecret, StartDate.isoformat())))
break
for trade in trades:
# TODO: check if this trade_id does not exist in the database for this user
with connection.cursor() as cursor:
sql = """SELECT trade_id FROM `transaction` WHERE trade_id=%s and owner_id=%s"""
cursor.execute(sql, [trade['trade_id'], Owner.id])
if cursor.rowcount > 0:
continue
# import the trade
t = Transaction()
t.trade_id = trade['trade_id']
supported_cryptos = ['BTC', 'BCH', 'ETH']
for c in supported_cryptos:
if trade['trading_pair'].upper().startswith(c):
t.crypto_currency = c
supported_fiat = ['USD', 'EUR']
for f in supported_fiat:
if trade['trading_pair'].upper().endswith(f):
t.fiat_currency = f
t.owner = Owner
t.amount_before_fee = Decimal(trade['amount'])
t.amount_after_fee = Decimal(trade['amount']) - Decimal(trade['fee_currency'])
t.amount = Decimal(trade['volume'])
if trade['type'] == 'sell':
t.amount -= Decimal(trade['fee_eur'])
t.amount_before_fee *= -1
t.amount_after_fee *= -1
t.amount *= -1
t.exchange_rate = trade['price']
t.date_valid = trade['created_at']
t.save()
if page >= response.get('page')['last']:
break
page += 1
@@ -0,0 +1,18 @@
# Generated by Django 3.1.5 on 2021-02-13 21:59
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('transactions', '0001_initial'),
]
operations = [
migrations.AddField(
model_name='transaction',
name='trade_id',
field=models.CharField(default='MANUAL', max_length=20),
),
]
+1
View File
@@ -3,6 +3,7 @@ from django.contrib.auth.models import User
# Create your models here. # Create your models here.
class Transaction(models.Model): class Transaction(models.Model):
trade_id = models.CharField(max_length=20, default='MANUAL')
crypto_currency = models.CharField(max_length=10) crypto_currency = models.CharField(max_length=10)
owner = models.ForeignKey(User, on_delete=models.CASCADE) owner = models.ForeignKey(User, on_delete=models.CASCADE)
amount_before_fee = models.DecimalField(max_digits=24, decimal_places=10) amount_before_fee = models.DecimalField(max_digits=24, decimal_places=10)
+7
View File
@@ -28,6 +28,13 @@
</div> </div>
</div> </div>
<div class="form-group row">
<label class="col-sm-2 col-form-label">Trade ID:</label>
<div class="col-sm-4">
{{ form.trade_id }}
</div>
</div>
<div class="form-group row"> <div class="form-group row">
<label class="col-sm-2 col-form-label">Crypto Currency:</label> <label class="col-sm-2 col-form-label">Crypto Currency:</label>
<div class="col-sm-4"> <div class="col-sm-4">
+63
View File
@@ -0,0 +1,63 @@
{% extends 'base.html' %}
{% block content %}
<div class="form-box">
<form method="POST" class="post-form" action="/transactions/import">
{% csrf_token %}
<div class="container">
<br>
{% if form.errors %}
{% for field in form %}
{% for error in field.errors %}
<div class="alert alert-danger">
<strong>{{field.name}}: {{ error|escape }}</strong>
</div>
{% endfor %}
{% endfor %}
{% for error in form.non_field_errors %}
<div class="alert alert-danger">
<strong>{{ error|escape }}</strong>
</div>
{% endfor %}
{% endif %}
<div class="form-group row">
<label class="col-sm-1 col-form-label"></label>
<div class="col-sm-4">
<h3>Import Transactions from Bitcoin.de API</h3>
<p>You need an API Key with Show permissions, and with access from only this IP: {{my_ip}}</p>
</div>
</div>
<div class="form-group row">
<label class="col-sm-2 col-form-label">API Key:</label>
<div class="col-sm-4">
{{ form.api_key }}
</div>
</div>
<div class="form-group row">
<label class="col-sm-2 col-form-label">API Secret:</label>
<div class="col-sm-4">
{{ form.api_secret }}
</div>
</div>
<div class="form-group row">
<label class="col-sm-2 col-form-label">Starting Date:</label>
<div class="col-sm-4">
{{ form.start_date }}
</div>
</div>
<div class="form-group row">
<label class="col-sm-1 col-form-label"></label>
<div class="col-sm-4">
<button type="submit" class="btn btn-primary">Submit</button>
</div>
</div>
</div>
</form>
</div>
{% endblock %}
+2
View File
@@ -5,6 +5,8 @@
<div class="form-box"> <div class="form-box">
<center><a href="/transactions/add" class="button button-primary">Add New Record</a></center> <center><a href="/transactions/add" class="button button-primary">Add New Record</a></center>
<br/> <br/>
<center><a href="/transactions/import" class="button button-primary">Import from Bitcoin.de</a></center>
<br/>
<table class="table table-striped table-bordered table-sm"> <table class="table table-striped table-bordered table-sm">
<thead class="thead-dark"> <thead class="thead-dark">
<tr> <tr>
+20
View File
@@ -1,7 +1,10 @@
from django.shortcuts import render, redirect from django.shortcuts import render, redirect
from django.contrib.auth.decorators import login_required from django.contrib.auth.decorators import login_required
from apps.transactions.forms import TransactionForm from apps.transactions.forms import TransactionForm
from apps.transactions.forms import ImportForm
from apps.transactions.models import Transaction from apps.transactions.models import Transaction
from apps.transactions.importbtcde import ImportBtcDe
import socket
@login_required @login_required
def add(request): def add(request):
@@ -20,6 +23,23 @@ def add(request):
form = TransactionForm() form = TransactionForm()
return render(request,'add.html',{'form':form}) return render(request,'add.html',{'form':form})
@login_required
def importbtcde(request):
form = ImportForm()
if request.method == "POST":
form = ImportForm(request.POST)
if form.is_valid():
# try:
importBtcDe = ImportBtcDe()
# importBtcDe.Import(request.POST['api_key'], request.POST['api_secret'], request.POST['start_date'], request.user.id)
importBtcDe.Import(form.cleaned_data.get('api_key'), form.cleaned_data.get('api_secret'), form.cleaned_data.get('start_date'), request.user)
return redirect('/transactions/show')
# except:
# pass
hostname = socket.gethostname()
my_ip = socket.gethostbyname(hostname)
return render(request,'import.html',{'form':form, 'my_ip': my_ip})
@login_required @login_required
def show(request): def show(request):
if 'crypto' in request.GET: if 'crypto' in request.GET:
+1 -1
View File
@@ -1,4 +1,4 @@
django django
django-registration django-registration
matplotlib matplotlib
btcde
+1
View File
@@ -29,6 +29,7 @@ urlpatterns = [
path('monitor/', monitor_views.monitor), path('monitor/', monitor_views.monitor),
path('graph/', monitor_views.graph), path('graph/', monitor_views.graph),
path('transactions/add', tr_views.add), path('transactions/add', tr_views.add),
path('transactions/import', tr_views.importbtcde),
path('transactions/show', tr_views.show), path('transactions/show', tr_views.show),
path('transactions/edit/<int:id>', tr_views.edit), path('transactions/edit/<int:id>', tr_views.edit),
path('transactions/update/<int:id>', tr_views.update), path('transactions/update/<int:id>', tr_views.update),