Implement storing asset restriction callbacks

This commit is contained in:
Mark Veidemanis 2023-02-10 23:26:30 +00:00
parent c283c6c192
commit 010aba7f81
Signed by: m
GPG Key ID: 5ACFCEED46C0904F
5 changed files with 78 additions and 8 deletions

View File

@ -89,10 +89,10 @@ class AccountForm(RestrictedFormMixin, ModelForm):
"exchange",
"api_key",
"api_secret",
"sandbox",
"enabled",
"risk_model",
"initial_balance",
"sandbox",
"enabled",
)
help_texts = {
"name": "Name of the account. Informational only.",
@ -119,6 +119,7 @@ class StrategyForm(RestrictedFormMixin, ModelForm):
"name",
"description",
"account",
"asset_group",
"trading_times",
"order_type",
"time_in_force",
@ -138,6 +139,7 @@ class StrategyForm(RestrictedFormMixin, ModelForm):
"name": "Name of the strategy. Informational only.",
"description": "Description of the strategy. Informational only.",
"account": "The account to use for this strategy.",
"asset_group": "Asset groups determine which pairs can be traded.",
"trading_times": "When the strategy will place new trades.",
"order_type": "Market: Buy/Sell at the current market price. Limit: Buy/Sell at a specified price. Limits protect you more against market slippage.",
"time_in_force": "The time in force controls how the order is executed.",
@ -323,6 +325,7 @@ class AssetRestrictionForm(RestrictedFormMixin, ModelForm):
"name",
"description",
"pairs",
"pairs_parsed",
)
help_texts = {
"name": "Name of the asset restriction group. Informational only.",
@ -330,6 +333,8 @@ class AssetRestrictionForm(RestrictedFormMixin, ModelForm):
"pairs": "Comma-separated list of pairs to restrict when a webhook is received. This does nothing on its own.",
}
pairs_parsed = forms.BooleanField(widget=forms.HiddenInput)
def clean(self):
cleaned_data = super(AssetRestrictionForm, self).clean()
if "pairs" in cleaned_data and cleaned_data["pairs"]:

View File

@ -0,0 +1,19 @@
# Generated by Django 4.1.6 on 2023-02-10 22:57
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('core', '0054_assetrestriction_webhook_id_alter_assetgroup_allowed'),
]
operations = [
migrations.AddField(
model_name='strategy',
name='asset_group',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to='core.assetgroup'),
),
]

View File

@ -0,0 +1,18 @@
# Generated by Django 4.1.6 on 2023-02-10 23:09
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('core', '0055_strategy_asset_group'),
]
operations = [
migrations.AlterField(
model_name='assetrestriction',
name='pairs_parsed',
field=models.JSONField(blank=True, default=dict, null=True),
),
]

View File

@ -369,6 +369,10 @@ class Strategy(models.Model):
trade_size_percent = models.FloatField(default=0.5)
trends = models.JSONField(null=True, blank=True)
asset_group = models.ForeignKey(
"core.AssetGroup", on_delete=models.PROTECT, null=True, blank=True
)
class Meta:
verbose_name_plural = "strategies"
@ -414,7 +418,7 @@ class AssetGroup(models.Model):
allowed = models.JSONField(null=True, blank=True, default=dict)
def __str__(self):
return self.name
return f"{self.name} ({self.restrictions})"
@property
def matches(self):
@ -438,7 +442,7 @@ class AssetRestriction(models.Model):
name = models.CharField(max_length=255)
description = models.TextField(null=True, blank=True)
pairs = models.CharField(max_length=4096, null=True, blank=True)
pairs_parsed = models.JSONField(null=True, blank=True)
pairs_parsed = models.JSONField(null=True, blank=True, default=dict)
webhook_id = models.UUIDField(default=uuid.uuid4, editable=False, unique=True)

View File

@ -8,6 +8,7 @@ from rest_framework.views import APIView
from core.forms import AssetGroupForm, AssetRestrictionForm
from core.models import AssetGroup, AssetRestriction
from core.util import logs
import json
log = logs.get_logger(__name__)
@ -109,12 +110,35 @@ class AssetRestrictionAPI(APIView):
parser_classes = [JSONParser]
def post(self, request, webhook_id):
log.debug(f"AssetAPI POST {webhook_id}: {request.data}")
# log.debug(f"AssetAPI POST {webhook_id}: {request.data}")
print(json.dumps(request.data, indent=2))
try:
webhook = AssetRestriction.objects.get(webhook_id=webhook_id)
restriction = AssetRestriction.objects.get(webhook_id=webhook_id)
except AssetRestriction.DoesNotExist:
log.error(f"AssetRestriction {webhook_id} does not exist")
log.error(f"Asset restriction {webhook_id} does not exist")
return HttpResponse(status=status.HTTP_404_NOT_FOUND)
return HttpResponse(status=status.HTTP_200_OK)
if restriction.group is not None:
group = restriction.group
else:
log.error(f"Asset restriction {restriction} has no group")
return HttpResponse(status=status.HTTP_404_NOT_FOUND)
# if group.strategy_set.exists() is not None:
# strategies = group.strategy_set.all()
# else:
# log.error(f"Asset group {group} has no strategy")
# return HttpResponse(status=status.HTTP_404_NOT_FOUND)
# log.debug(f"Asset API {webhook_id} matched to strategies {strategies}")
if "meta" in request.data:
if "is_match" in request.data["meta"]:
is_match = request.data["meta"]["is_match"]
if isinstance(restriction.pairs_parsed, list):
for pair in restriction.pairs_parsed:
group.allowed[pair] = is_match
group.save()
return HttpResponse(status=status.HTTP_200_OK)
return HttpResponse(status=status.HTTP_400_BAD_REQUEST)