Skip to content

Commit

Permalink
Improve TraderoBotGroup
Browse files Browse the repository at this point in the history
- Add Bot creation on Group create
- Add Bot editing on Group edit
  • Loading branch information
math-a3k committed Aug 20, 2023
1 parent 96f0485 commit 2fdf3b7
Show file tree
Hide file tree
Showing 3 changed files with 198 additions and 12 deletions.
84 changes: 77 additions & 7 deletions base/forms.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
from decimal import Decimal

from django import forms
from django.db.models import Model

from .models import Symbol, TraderoBot, TraderoBotGroup, User
from .strategies import get_strategies
Expand All @@ -10,7 +13,8 @@ class TraderoBotForm(forms.ModelForm):
queryset=Symbol.objects.available(), empty_label="(Selecionar)"
)
strategy = forms.ChoiceField(
choices=[(k, v.__name__) for k, v in get_strategies().items()]
choices=[(None, "(Selecionar)")]
+ [(k, v.__name__) for k, v in get_strategies().items()]
)

class Meta:
Expand All @@ -32,18 +36,84 @@ class Meta:
"should_stop",
]

def __init__(self, *args, **kwargs):
user = kwargs.pop("user")
def __init__(self, *args, for_group=False, **kwargs):
user = kwargs.pop("user", None)
super().__init__(*args, **kwargs)
self.fields["group"].queryset = TraderoBotGroup.objects.filter(
user=user
)
if for_group:
self.fields.pop("group")
else:
self.fields["group"].queryset = TraderoBotGroup.objects.filter(
user=user
)


class TraderoBotGroupForm(forms.ModelForm):
prefix_bot_data = "bot_"

add_edit_bots = forms.BooleanField(
label="Add / Edit Botzinhos", required=False
)
bots_quantity = forms.IntegerField(
label="# of Botzinhos", initial=10, required=False
)

class Meta:
model = TraderoBotGroup
fields = ["name"]
fields = [
"name",
"add_edit_bots",
"bots_quantity",
]

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields["add_edit_bots"].label = "Add Botzinhos"
bot_form_fields = TraderoBotForm(for_group=True).fields
for field in bot_form_fields:
new_field = f"{self.prefix_bot_data}{field}"
self.fields[new_field] = bot_form_fields[field]
self.fields[new_field].required = False
self.fields[new_field].initial = None

def clean(self):
cleaned_data = super().clean()
if cleaned_data["add_edit_bots"]:
bot_data = self.get_bot_data(cleaned_data)
for k, v in bot_data.items():
if isinstance(v, Model):
bot_data[k] = v.pk
elif isinstance(v, Decimal):
bot_data[k] = str(v)
bot_form = TraderoBotForm(bot_data, for_group=True)
if not bot_form.is_valid():
for field, message in bot_form.errors.items():
self.add_error(f"{self.prefix_bot_data}{field}", message)
return cleaned_data

def get_bot_data(self, data_dict):
return {
k[len(self.prefix_bot_data) :]: v
for k, v in data_dict.items()
if k.startswith(self.prefix_bot_data)
}


class TraderoBotGroupEditForm(TraderoBotGroupForm):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields["add_edit_bots"].label = "Edit Botzinhos"
self.fields["bots_quantity"].initial = self.instance.bots.all().count()
self.fields["bots_quantity"].widget.attrs["readonly"] = True
for field in [
f for f in self.fields if f.startswith(self.prefix_bot_data)
]:
if isinstance(self.fields[field], forms.fields.BooleanField):
self.fields[field] = forms.fields.NullBooleanField(
label=self.fields[field].label
)

def clean(self):
pass


class UserForm(forms.ModelForm):
Expand Down
81 changes: 81 additions & 0 deletions base/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -423,6 +423,58 @@ def test_botzinhos_group_create(self):
).count(),
1,
)
response = self.client.post(
url,
{
"name": "testing group bot create",
"add_edit_bots": True,
"bots_quantity": 2,
"bot_name": "tt",
},
follow=True,
)
self.assertEqual(response.status_code, 200)
self.assertIn(
b"This field is required",
response.content,
)
response = self.client.post(
url,
{
"name": "testing group bot create",
"add_edit_bots": True,
"bots_quantity": 2,
"bot_name": "tt",
"bot_strategy": "acmadness",
"bot_symbol": self.s1.pk,
"bot_fund_quote_asset_initial": 20,
},
follow=True,
)
self.assertEqual(response.status_code, 200)
self.assertEqual(
TraderoBot.objects.filter(name__startswith="tt").count(),
2,
)
response = self.client.post(
url,
{
"name": "testing group bot create 2",
"add_edit_bots": True,
"bots_quantity": 2,
"bot_strategy": "acmadness",
"bot_symbol": self.s1.pk,
"bot_fund_quote_asset_initial": 55,
},
follow=True,
)
self.assertEqual(response.status_code, 200)
self.assertEqual(
TraderoBot.objects.filter(
name__startswith="BT", fund_quote_asset_initial=55
).count(),
2,
)

def test_botzinhos_group_update(self):
self.client.force_login(self.user1)
Expand All @@ -443,6 +495,35 @@ def test_botzinhos_group_update(self):
).count(),
1,
)
response = self.client.post(
url,
{
"add_edit_bots": True,
"bot_name": "Group 1",
},
follow=True,
)
self.assertEqual(response.status_code, 200)
self.assertEqual(
TraderoBot.objects.filter(name__startswith="Group 1").count(),
3,
)
# import ipdb; ipdb.set_trace()
response = self.client.post(
url,
{
"add_edit_bots": True,
"bot_fund_quote_asset_initial": 25,
},
follow=True,
)
self.assertEqual(response.status_code, 200)
self.assertEqual(
TraderoBot.objects.filter(
name__startswith="Group 1", fund_quote_asset_initial=25
).count(),
3,
)

def test_botzinhos_actions(self):
self.client.force_login(self.user1)
Expand Down
45 changes: 40 additions & 5 deletions base/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,12 @@
UpdateView,
)

from .forms import TraderoBotForm, TraderoBotGroupForm, UserForm
from .forms import (
TraderoBotForm,
TraderoBotGroupEditForm,
TraderoBotGroupForm,
UserForm,
)
from .models import Symbol, TradeHistory, TraderoBot, TraderoBotGroup, User


Expand Down Expand Up @@ -235,20 +240,50 @@ def get_context_data(self, **kwargs):

class BotzinhosGroupCreateView(LoginRequiredMixin, CreateView):
model = TraderoBotGroup
form = TraderoBotGroupForm
form_class = TraderoBotGroupForm
template_name = "base/botzinhos_group_form.html"
fields = ["name"]

def form_valid(self, form):
form.instance.user = self.request.user
self.object = form.save()
if form.cleaned_data["add_edit_bots"]:
bot_kwargs = form.get_bot_data(form.cleaned_data)
bot_kwargs.update(
{"user": self.request.user, "group": self.object}
)
bot_name = bot_kwargs["name"]
for i in range(form.cleaned_data["bots_quantity"]):
if bot_name:
bot_kwargs.update({"name": f"{bot_name}-{i+1:03d}"})
bot = TraderoBot(**bot_kwargs)
bot.save()
return super().form_valid(form)


class BotzinhosGroupUpdateView(OwnerMixin, LoginRequiredMixin, UpdateView):
model = TraderoBotGroup
form = TraderoBotGroupForm
form_class = TraderoBotGroupEditForm
template_name = "base/botzinhos_group_form.html"
fields = ["name"]

def form_valid(self, form):
form.instance.user = self.request.user
self.object = form.save()
if form.cleaned_data["add_edit_bots"]:
bot_data = form.get_bot_data(form.cleaned_data)
bot_name = bot_data.pop("name", None)
for index, bot in enumerate(self.object.bots.all()):
if bot_name:
bot.name = f"{bot_name}-{index + 1:03d}"
for field in bot_data:
if (
bot_data[field]
not in form.fields[
f"{form.prefix_bot_data}{field}"
].empty_values
):
setattr(bot, field, bot_data[field])
bot.save()
return super().form_valid(form)


class BotzinhosGroupActionView(ActionView):
Expand Down

0 comments on commit 2fdf3b7

Please sign in to comment.