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 @@
# -*- 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
class RobotInstance(models.Model): class RobotInstance(models.Model):
instanceId = models.CharField(max_length=255) 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 @@
</div> </div>
<ul class="nav navbar-nav"> <ul class="nav navbar-nav">
<li><a href="{% url 'overview' %}">Overview</a></li> <li><a href="{% url 'overview' %}">Overview</a></li>
<li><a href="{% url 'trades_index' %}">Trades</a></li>
</ul> </ul>
</nav> </nav>

33
templates/dashboard/trades.html

@ -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 @@
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 = [
url(r'^$', views.overview, name='overview'), url(r'^$', views.overview, name='overview'),
url(r'^add_instance$', views.add_instance, name='add_instance'), 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'^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
from django.urls import reverse from django.urls import reverse
from django.contrib import messages from django.contrib import messages
from .models import RobotInstance from .models import RobotInstance, Trade
import redis import redis
import json import json
import datetime import datetime
@ -70,3 +70,10 @@ def delete_instance(request, instance_id):
instance.delete() instance.delete()
return HttpResponseRedirect(reverse('overview')) 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