@@ -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))
|
||||||
|
|||||||
@@ -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),
|
||||||
|
),
|
||||||
|
]
|
||||||
@@ -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)
|
||||||
|
|||||||
@@ -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">
|
||||||
|
|||||||
@@ -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 %}
|
||||||
@@ -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>
|
||||||
|
|||||||
@@ -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
@@ -1,4 +1,4 @@
|
|||||||
django
|
django
|
||||||
django-registration
|
django-registration
|
||||||
matplotlib
|
matplotlib
|
||||||
|
btcde
|
||||||
|
|||||||
@@ -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),
|
||||||
|
|||||||
Reference in New Issue
Block a user