Browse Source

Basic trade sink functionality

master
Denis Tereshkin 9 years ago
parent
commit
48cb787f94
  1. 32
      migrations/0002_trade.py
  2. 14
      models.py
  3. 1
      templates/dashboard/base.html
  4. 33
      templates/dashboard/trades.html
  5. 55
      tradesink.py
  6. 1
      urls.py
  7. 9
      views.py

32
migrations/0002_trade.py

@ -0,0 +1,32 @@ @@ -0,0 +1,32 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.6 on 2017-03-06 14:17
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('dashboard', '0001_initial'),
]
operations = [
migrations.CreateModel(
name='Trade',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('account', models.CharField(max_length=256)),
('security', models.CharField(max_length=256)),
('price', models.DecimalField(decimal_places=10, max_digits=20)),
('quantity', models.IntegerField()),
('volume', models.DecimalField(decimal_places=10, max_digits=25)),
('volumeCurrency', models.CharField(max_length=10)),
('strategyId', models.CharField(max_length=64)),
('signalId', models.CharField(max_length=64)),
('comment', models.CharField(max_length=256)),
('timestamp', models.DateTimeField()),
('balanced', models.BooleanField(default=False)),
],
),
]

14
models.py

@ -2,3 +2,17 @@ from django.db import models @@ -2,3 +2,17 @@ from django.db import models
class RobotInstance(models.Model):
instanceId = models.CharField(max_length=255)
class Trade(models.Model):
account = models.CharField(max_length=256)
security = models.CharField(max_length=256)
price = models.DecimalField(max_digits=20, decimal_places=10)
quantity = models.IntegerField()
volume = models.DecimalField(max_digits=25, decimal_places=10)
volumeCurrency = models.CharField(max_length=10)
strategyId = models.CharField(max_length=64)
signalId = models.CharField(max_length=64)
comment = models.CharField(max_length=256)
timestamp = models.DateTimeField()
balanced = models.BooleanField(default=False)

1
templates/dashboard/base.html

@ -16,6 +16,7 @@ @@ -16,6 +16,7 @@
</div>
<ul class="nav navbar-nav">
<li><a href="{% url 'overview' %}">Overview</a></li>
<li><a href="{% url 'trades_index' %}">Trades</a></li>
</ul>
</nav>

33
templates/dashboard/trades.html

@ -0,0 +1,33 @@ @@ -0,0 +1,33 @@
{% extends "dashboard/base.html" %}
{% load mathfilters %}
{% block content %}
<table class="table table-condensed">
<tr>
<td>Time</td>
<td>Account</td>
<td>Security</td>
<td>Operation</td>
<td>Price</td>
<td>Quantity</td>
<td>Volume</td>
<td>Strategy ID</td>
<td>Signal ID</td>
<td></td>
</tr>
{% for trade in trades %}
<tr>
<td>{{ trade.timestamp }}</td>
<td>{{ trade.account }}</td>
<td>{{ trade.security }}</td>
<td>{% if trade.quantity > 0 %} Buy {% else %} Sell {% endif %}</td>
<td>{{ trade.price }}</td>
<td>{{ trade.quantity|abs }}</td>
<td>{{ trade.volume|stringformat:".3f"}} {{ trade.volumeCurrency }}</td>
<td>{{ trade.strategyId }}</td>
<td>{{ trade.signalId }}</td>
<td><button type="button" class="btn btn-danger" onclick="if(window.confirm('Confirm deletion')) { document.location.href = '/delete_trade?id={{ trade.pk }}'}; return false;">Delete</button></td>
</tr>
{% endfor %}
</table>
{% endblock %}

55
tradesink.py

@ -0,0 +1,55 @@ @@ -0,0 +1,55 @@
import os
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "atrade_dashboard.settings")
import django
django.setup()
import zmq
import argparse
import datetime
from dashboard.models import Trade
def parse_timestamp(ts):
return datetime.datetime.strptime(ts, '%Y-%m-%d %H:%M:%S.%f')
def store_trade(j):
quantity = int(j['quantity'])
if j['operation'] == 'sell':
quantity = -quantity
elif j['operation'] != 'buy':
raise Exception('Invalid operation: ' + j['operation'])
ts = parse_timestamp(j['execution-time'])
trade = Trade(account=j['account'], security=j['security'], price=float(j['price']), quantity=quantity, volume=float(j['volume']), volumeCurrency=j['volume-currency'], strategyId=j['strategy'],
signalId=j['signal-id'], comment=j['order-comment'], timestamp=ts)
trade.save()
def handle_cmd(cmd):
try:
if 'command' in cmd.keys():
return { 'response' : 'ok' }
elif 'trade' in cmd.keys():
store_trade(cmd['trade'])
return { 'response' : 'ok' }
except Exception as e:
print(e)
return { 'response' : 'error' }
def main():
parser = argparse.ArgumentParser(description='Trade sink process')
parser.add_argument('-e', '--endpoint', action='store', help='Trade sink endpoint')
args = parser.parse_args()
ctx = zmq.Context.instance()
s = ctx.socket(zmq.REP)
s.bind(args.endpoint)
while True:
events = s.poll(1000, zmq.POLLIN)
if events == zmq.POLLIN:
cmd = s.recv_json()
response = handle_cmd(cmd)
s.send_json(response)
if __name__ == "__main__":
main()

1
urls.py

@ -7,5 +7,6 @@ urlpatterns = [ @@ -7,5 +7,6 @@ urlpatterns = [
url(r'^$', views.overview, name='overview'),
url(r'^add_instance$', views.add_instance, name='add_instance'),
url(r'^delete_instance/(?P<instance_id>[^/]+)$', views.delete_instance, name='delete_instance'),
url(r'^trades/$', views.trades_index, name='trades_index'),
]

9
views.py

@ -5,7 +5,7 @@ from django.shortcuts import render, get_object_or_404 @@ -5,7 +5,7 @@ from django.shortcuts import render, get_object_or_404
from django.urls import reverse
from django.contrib import messages
from .models import RobotInstance
from .models import RobotInstance, Trade
import redis
import json
import datetime
@ -70,3 +70,10 @@ def delete_instance(request, instance_id): @@ -70,3 +70,10 @@ def delete_instance(request, instance_id):
instance.delete()
return HttpResponseRedirect(reverse('overview'))
def trades_index(request):
trades = Trade.objects.all()
template = loader.get_template('dashboard/trades.html')
context = {
'trades' : trades
}
return HttpResponse(template.render(context, request))

Loading…
Cancel
Save