Implement storing asset restriction callbacks
This commit is contained in:
parent
c283c6c192
commit
010aba7f81
|
@ -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"]:
|
||||
|
|
|
@ -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'),
|
||||
),
|
||||
]
|
|
@ -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),
|
||||
),
|
||||
]
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue