Implement configuration of trading times

This commit is contained in:
Mark Veidemanis 2022-11-25 18:01:34 +00:00
parent bcb3272064
commit baa8e4fead
Signed by: m
GPG Key ID: 5ACFCEED46C0904F
9 changed files with 275 additions and 2 deletions

View File

@ -21,7 +21,16 @@ from django.urls import include, path
from django.views.generic import TemplateView
from django_otp.forms import OTPAuthenticationForm
from core.views import accounts, base, callbacks, hooks, positions, strategies, trades
from core.views import (
accounts,
base,
callbacks,
hooks,
limits,
positions,
strategies,
trades,
)
from core.views.stripe_callbacks import Callback
urlpatterns = [
@ -136,4 +145,24 @@ urlpatterns = [
strategies.StrategyDelete.as_view(),
name="strategy_delete",
),
path(
"trading_times/<str:type>/",
limits.TradingTimeList.as_view(),
name="tradingtimes",
),
path(
"trading_times/<str:type>/create/",
limits.TradingTimeCreate.as_view(),
name="tradingtime_create",
),
path(
"trading_times/<str:type>/update/<str:pk>/",
limits.TradingTimeUpdate.as_view(),
name="tradingtime_update",
),
path(
"trading_times/<str:type>/delete/<str:pk>/",
limits.TradingTimeDelete.as_view(),
name="tradingtime_delete",
),
] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)

View File

@ -2,7 +2,7 @@ from django import forms
from django.contrib.auth.forms import UserCreationForm
from django.forms import ModelForm
from .models import Account, Hook, Strategy, Trade, User
from .models import Account, Hook, Strategy, Trade, TradingTime, User
# Create your forms here.
@ -96,3 +96,16 @@ class TradeForm(ModelForm):
"take_profit",
"direction",
)
class TradingTimeForm(ModelForm):
class Meta:
model = TradingTime
fields = (
"name",
"description",
"start_day",
"start_time",
"end_day",
"end_time",
)

View File

@ -0,0 +1,26 @@
# Generated by Django 4.1.3 on 2022-11-25 17:39
import django.db.models.deletion
from django.conf import settings
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('core', '0027_strategy_trailing_stop_loss_percent_and_more'),
]
operations = [
migrations.CreateModel(
name='TradingTime',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(blank=True, max_length=255, null=True)),
('description', models.TextField(blank=True, null=True)),
('start_ts', models.DateTimeField()),
('end_ts', models.DateTimeField()),
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
],
),
]

View File

@ -0,0 +1,19 @@
# Generated by Django 4.1.3 on 2022-11-25 17:40
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('core', '0028_tradingtime'),
]
operations = [
migrations.AlterField(
model_name='tradingtime',
name='name',
field=models.CharField(default='DEFAULT', max_length=255),
preserve_default=False,
),
]

View File

@ -0,0 +1,45 @@
# Generated by Django 4.1.3 on 2022-11-25 17:43
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('core', '0029_alter_tradingtime_name'),
]
operations = [
migrations.RemoveField(
model_name='tradingtime',
name='end_ts',
),
migrations.RemoveField(
model_name='tradingtime',
name='start_ts',
),
migrations.AddField(
model_name='tradingtime',
name='end_day',
field=models.CharField(choices=[('monday', 'Monday'), ('tuesday', 'Tuesday'), ('wednesday', 'Wednesday'), ('thursday', 'Thursday'), ('friday', 'Friday'), ('saturday', 'Saturday'), ('sunday', 'Sunday')], default='monday', max_length=255),
preserve_default=False,
),
migrations.AddField(
model_name='tradingtime',
name='end_time',
field=models.TimeField(default='12:00'),
preserve_default=False,
),
migrations.AddField(
model_name='tradingtime',
name='start_day',
field=models.CharField(choices=[('monday', 'Monday'), ('tuesday', 'Tuesday'), ('wednesday', 'Wednesday'), ('thursday', 'Thursday'), ('friday', 'Friday'), ('saturday', 'Saturday'), ('sunday', 'Sunday')], default='monday', max_length=255),
preserve_default=False,
),
migrations.AddField(
model_name='tradingtime',
name='start_time',
field=models.TimeField(default='12:00'),
preserve_default=False,
),
]

View File

@ -24,6 +24,15 @@ TIF_CHOICES = (
("fok", "FOK (Fill Or Kill)"),
("ioc", "IOC (Immediate Or Cancel)"),
)
DAY_CHOICES = (
("monday", "Monday"),
("tuesday", "Tuesday"),
("wednesday", "Wednesday"),
("thursday", "Thursday"),
("friday", "Friday"),
("saturday", "Saturday"),
("sunday", "Sunday"),
)
class Plan(models.Model):
@ -237,6 +246,16 @@ class Strategy(models.Model):
return self.name
class TradingTime(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
name = models.CharField(max_length=255)
description = models.TextField(null=True, blank=True)
start_day = models.CharField(choices=DAY_CHOICES, max_length=255)
end_day = models.CharField(choices=DAY_CHOICES, max_length=255)
start_time = models.TimeField()
end_time = models.TimeField()
# class Perms(models.Model):
# class Meta:
# permissions = (

View File

@ -234,6 +234,20 @@
</a>
</div>
</div>
<div class="navbar-item has-dropdown is-hoverable">
<a class="navbar-link">
Limits
</a>
<div class="navbar-dropdown">
<!-- <a class="navbar-item" href="#">
Directions
</a> -->
<a class="navbar-item" href="{% url 'tradingtimes' type='page' %}">
Trading Times
</a>
</div>
</div>
{% endif %}
{% if settings.STRIPE_ENABLED %}
{% if user.is_authenticated %}

View File

@ -0,0 +1,61 @@
{% include 'partials/notify.html' %}
<table
class="table is-fullwidth is-hoverable"
hx-target="#{{ context_object_name }}-table"
id="{{ context_object_name }}-table"
hx-swap="outerHTML"
hx-trigger="{{ context_object_name_singular }}Event from:body"
hx-get="{{ list_url }}">
<thead>
<th>id</th>
<th>user</th>
<th>name</th>
<th>description</th>
<th>start</th>
<th>end</th>
<th>actions</th>
</thead>
{% for item in object_list %}
<tr>
<td>{{ item.id }}</td>
<td>{{ item.user }}</td>
<td>{{ item.name }}</td>
<td>{{ item.description }}</td>
<td>{{ item.start_day }} at {{ item.start_time }}</td>
<td>{{ item.end_day }} at {{ item.end_time }}</td>
<td>
<div class="buttons">
<button
hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'
hx-get="{% url 'tradingtime_update' type=type pk=item.id %}"
hx-trigger="click"
hx-target="#{{ type }}s-here"
hx-swap="innerHTML"
class="button is-info">
<span class="icon-text">
<span class="icon">
<i class="fa-solid fa-pencil"></i>
</span>
</span>
</button>
<button
hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'
hx-delete="{% url 'tradingtime_delete' type=type pk=item.id %}"
hx-trigger="click"
hx-target="#modals-here"
hx-swap="innerHTML"
hx-confirm="Are you sure you wish to delete {{ item.name }}?"
class="button is-danger">
<span class="icon-text">
<span class="icon">
<i class="fa-solid fa-trash"></i>
</span>
</span>
</button>
</div>
</td>
</tr>
{% endfor %}
</table>

47
core/views/limits.py Normal file
View File

@ -0,0 +1,47 @@
from django.contrib.auth.mixins import LoginRequiredMixin
from core.forms import TradingTimeForm
from core.models import TradingTime
from core.util import logs
from core.views import ObjectCreate, ObjectDelete, ObjectList, ObjectUpdate
log = logs.get_logger(__name__)
class TradingTimeList(LoginRequiredMixin, ObjectList):
list_template = "partials/trading-time-list.html"
model = TradingTime
page_title = "List of allowed trading times. Used as options for a strategy."
page_subtitle = "Add times here in order to permit trading."
list_url_name = "tradingtimes"
list_url_args = ["type"]
submit_url_name = "tradingtime_create"
class TradingTimeCreate(LoginRequiredMixin, ObjectCreate):
model = TradingTime
form_class = TradingTimeForm
list_url_name = "tradingtimes"
list_url_args = ["type"]
submit_url_name = "tradingtime_create"
class TradingTimeUpdate(LoginRequiredMixin, ObjectUpdate):
model = TradingTime
form_class = TradingTimeForm
list_url_name = "tradingtimes"
list_url_args = ["type"]
submit_url_name = "tradingtime_update"
class TradingTimeDelete(LoginRequiredMixin, ObjectDelete):
model = TradingTime
list_url_name = "tradingtimes"
list_url_args = ["type"]