commit 5d3c657a7185bd88bb164a061d3d8560ec078c32 Author: Denis Tereshkin Date: Sun Mar 5 14:14:51 2017 +0700 Initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..355241b --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +.* +*.sqlite3 +*__pycache__* diff --git a/__init__.py b/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/admin.py b/admin.py new file mode 100644 index 0000000..8c38f3f --- /dev/null +++ b/admin.py @@ -0,0 +1,3 @@ +from django.contrib import admin + +# Register your models here. diff --git a/apps.py b/apps.py new file mode 100644 index 0000000..50878e7 --- /dev/null +++ b/apps.py @@ -0,0 +1,5 @@ +from django.apps import AppConfig + + +class DashboardConfig(AppConfig): + name = 'dashboard' diff --git a/migrations/0001_initial.py b/migrations/0001_initial.py new file mode 100644 index 0000000..07d6589 --- /dev/null +++ b/migrations/0001_initial.py @@ -0,0 +1,23 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.10.6 on 2017-03-04 23:52 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ] + + operations = [ + migrations.CreateModel( + name='RobotInstance', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('instanceId', models.CharField(max_length=255)), + ], + ), + ] diff --git a/migrations/__init__.py b/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/models.py b/models.py new file mode 100644 index 0000000..cbece3c --- /dev/null +++ b/models.py @@ -0,0 +1,4 @@ +from django.db import models + +class RobotInstance(models.Model): + instanceId = models.CharField(max_length=255) diff --git a/templates/dashboard/base.html b/templates/dashboard/base.html new file mode 100644 index 0000000..bd84c32 --- /dev/null +++ b/templates/dashboard/base.html @@ -0,0 +1,29 @@ +{% load bootstrap3 %} + + + + + {% bootstrap_css %} + + {% bootstrap_javascript %} + ATrade dashboard + + + + + + {% bootstrap_messages %} + +
+ {% block content %}{% endblock %} +
+ + + diff --git a/templates/dashboard/overview.html b/templates/dashboard/overview.html new file mode 100644 index 0000000..9a79294 --- /dev/null +++ b/templates/dashboard/overview.html @@ -0,0 +1,56 @@ +{% extends "dashboard/base.html" %} + +{% block content %} +
+{% for index, instanceId, state, positions in robot_states %} +
+ +
+
+
{{ state }}
+ + {% for position in positions %} +
+
+

State: {{ position.posState.tag }}

+

Ticker: {{ position.posTicker }}

+

Balance: {{ position.posBalance }}

+ {% if position.posEntryTime %} +

Entry: {{ position.posEntryTime }}

+ {% endif %} + {% if position.posExitTime %} +

Exit: {{ position.posExitTime }}

+ {% endif %} + {% if position.posStopPrice %} +

Stop at: {{ position.posStopPrice }}

+ {% endif %} + {% if position.posTakeProfitPrice %} +

Take profit at: {{ position.posTakeProfitPrice }}

+ {% endif %} +

Account: {{ position.posAccount }}

+
+
+ {% endfor %} + +
+ +
+
+{% endfor %} +
+ +
+ {% csrf_token %} +
+ + +
+ +
+{% endblock %} diff --git a/tests.py b/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/urls.py b/urls.py new file mode 100644 index 0000000..71fb116 --- /dev/null +++ b/urls.py @@ -0,0 +1,11 @@ + +from django.conf.urls import url + +from . import views + +urlpatterns = [ + url(r'^$', views.overview, name='overview'), + url(r'^add_instance$', views.add_instance, name='add_instance'), + url(r'^delete_instance/(?P[^/]+)$', views.delete_instance, name='delete_instance'), + +] diff --git a/views.py b/views.py new file mode 100644 index 0000000..636f0f4 --- /dev/null +++ b/views.py @@ -0,0 +1,51 @@ + +from django.http import HttpResponse, HttpResponseRedirect +from django.template import loader +from django.shortcuts import render, get_object_or_404 +from django.urls import reverse +from django.contrib import messages + +from .models import RobotInstance +import redis +import json + +def overview(request): + r = redis.StrictRedis(unix_socket_path='/var/run/redis/redis') + robot_instances = RobotInstance.objects.order_by('instanceId') + robot_states = [] + index = 0 + for robot in robot_instances: + raw_state = r.get(robot.instanceId) + if raw_state is not None: + state = json.loads(str(raw_state, 'utf-8')) + try: + positions = state['positions'] + except KeyError: + positions = dict() + del state['positions'] + else: + state = dict() + index += 1 + robot_states.append((index, robot.instanceId, json.dumps(state, sort_keys=True, indent=2, separators=(',', ': ')), positions)) + + template = loader.get_template('dashboard/overview.html') + context = { + 'robot_instances' : robot_instances, + 'robot_states' : robot_states + } + return HttpResponse(template.render(context, request)) + +def add_instance(request): + instance_id = request.POST['instance_id'] + if instance_id == "" or RobotInstance.objects.filter(instanceId=instance_id).count() > 0: + messages.error(request, 'Invalid instance ID specified') + else: + new_instance = RobotInstance(instanceId=instance_id) + new_instance.save() + return HttpResponseRedirect(reverse('overview')) + +def delete_instance(request, instance_id): + instance = get_object_or_404(RobotInstance, instanceId=instance_id) + instance.delete() + return HttpResponseRedirect(reverse('overview')) +