commit
5d3c657a71
12 changed files with 188 additions and 0 deletions
@ -0,0 +1,3 @@
@@ -0,0 +1,3 @@
|
||||
from django.contrib import admin |
||||
|
||||
# Register your models here. |
||||
@ -0,0 +1,5 @@
@@ -0,0 +1,5 @@
|
||||
from django.apps import AppConfig |
||||
|
||||
|
||||
class DashboardConfig(AppConfig): |
||||
name = 'dashboard' |
||||
@ -0,0 +1,23 @@
@@ -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)), |
||||
], |
||||
), |
||||
] |
||||
@ -0,0 +1,4 @@
@@ -0,0 +1,4 @@
|
||||
from django.db import models |
||||
|
||||
class RobotInstance(models.Model): |
||||
instanceId = models.CharField(max_length=255) |
||||
@ -0,0 +1,29 @@
@@ -0,0 +1,29 @@
|
||||
{% load bootstrap3 %} |
||||
<!DOCTYPE html> |
||||
<html lang="en"> |
||||
<head> |
||||
<meta name="viewport" content="width=device-width, initial-scale=1"> |
||||
{% bootstrap_css %} |
||||
<script src="{% bootstrap_jquery_url %}"></script> |
||||
{% bootstrap_javascript %} |
||||
<title>ATrade dashboard</title> |
||||
</head> |
||||
|
||||
<body> |
||||
<nav class="navbar navbar-default"> |
||||
<div class="navbar-header"> |
||||
<a class="navbar-brand">Dashboard</a> |
||||
</div> |
||||
<ul class="nav navbar-nav"> |
||||
<li><a href="{% url 'overview' %}">Overview</a></li> |
||||
</ul> |
||||
</nav> |
||||
|
||||
{% bootstrap_messages %} |
||||
|
||||
<div id="container"> |
||||
{% block content %}{% endblock %} |
||||
</div> |
||||
</body> |
||||
</html> |
||||
|
||||
@ -0,0 +1,56 @@
@@ -0,0 +1,56 @@
|
||||
{% extends "dashboard/base.html" %} |
||||
|
||||
{% block content %} |
||||
<div class="panel-group"> |
||||
{% for index, instanceId, state, positions in robot_states %} |
||||
<div class="panel panel-default"> |
||||
<div class="panel-heading" id="heading-{{instanceId}}"> |
||||
<a role="button" data-toggle="collapse" href="#collapse-{{index}}"> |
||||
{{ instanceId }} |
||||
</a> |
||||
</div> |
||||
<div id="collapse-{{index}}" class="panel-collapse collapse"> |
||||
<div class="panel-body"> |
||||
<pre>{{ state }}</pre> |
||||
|
||||
{% for position in positions %} |
||||
<div class="panel panel-default"> |
||||
<div class="panel-body"> |
||||
<p>State: {{ position.posState.tag }} </p> |
||||
<p>Ticker: {{ position.posTicker }} </p> |
||||
<p>Balance: {{ position.posBalance }} </p> |
||||
{% if position.posEntryTime %} |
||||
<p>Entry: {{ position.posEntryTime }} </p> |
||||
{% endif %} |
||||
{% if position.posExitTime %} |
||||
<p>Exit: {{ position.posExitTime }} </p> |
||||
{% endif %} |
||||
{% if position.posStopPrice %} |
||||
<p>Stop at: {{ position.posStopPrice }} </p> |
||||
{% endif %} |
||||
{% if position.posTakeProfitPrice %} |
||||
<p>Take profit at: {{ position.posTakeProfitPrice }} </p> |
||||
{% endif %} |
||||
<p>Account: {{ position.posAccount }} </p> |
||||
</div> |
||||
</div> |
||||
{% endfor %} |
||||
|
||||
</div> |
||||
<div class="panel-footer"> |
||||
<a class="btn btn-danger" href="{% url 'delete_instance' instanceId %}">Delete</a> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
{% endfor %} |
||||
</div> |
||||
|
||||
<form class="form-inline" action="{% url 'add_instance' %}" method="POST"> |
||||
{% csrf_token %} |
||||
<div class="form-group"> |
||||
<label for="instance_id">New instance ID:</label> |
||||
<input type="text" class="form-control" id="instance_id" name="instance_id" placeholder="instance ID" /> |
||||
</div> |
||||
<button type="submit" class="btn btn-success">Add</button> |
||||
</form> |
||||
{% endblock %} |
||||
@ -0,0 +1,3 @@
@@ -0,0 +1,3 @@
|
||||
from django.test import TestCase |
||||
|
||||
# Create your tests here. |
||||
@ -0,0 +1,11 @@
@@ -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<instance_id>[^/]+)$', views.delete_instance, name='delete_instance'), |
||||
|
||||
] |
||||
@ -0,0 +1,51 @@
@@ -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')) |
||||
|
||||
Loading…
Reference in new issue