You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

264 lines
9.2 KiB
Python

import json
from django.contrib.auth.mixins import LoginRequiredMixin
from django.http import HttpResponse
from django.shortcuts import render
from django.views import View
from mixins.views import (
ObjectCreate,
ObjectDelete,
ObjectList,
ObjectNameMixin,
ObjectUpdate,
)
from rest_framework import status
from rest_framework.parsers import JSONParser
from rest_framework.views import APIView
from core.forms import AssetGroupForm # , AssetRestrictionForm
from core.models import AssetGroup # , AssetRestriction
from core.trading import assetfilter
from core.util import logs
log = logs.get_logger(__name__)
# Asset Groups
class AssetGroupList(LoginRequiredMixin, ObjectList):
list_template = "partials/assetgroup-list.html"
model = AssetGroup
page_title = "List of asset groups for restrictions. Linked to strategies."
page_subtitle = "Asset groups are collections of asset restrictions."
list_url_name = "assetgroups"
list_url_args = ["type"]
submit_url_name = "assetgroup_create"
class AssetGroupCreate(LoginRequiredMixin, ObjectCreate):
model = AssetGroup
form_class = AssetGroupForm
submit_url_name = "assetgroup_create"
class AssetGroupUpdate(LoginRequiredMixin, ObjectUpdate):
model = AssetGroup
form_class = AssetGroupForm
submit_url_name = "assetgroup_update"
class AssetGroupDelete(LoginRequiredMixin, ObjectDelete):
model = AssetGroup
# Asset Restrictions
# class AssetRestrictionsPermissionMixin:
# # Check the user has permission to view the asset group
# # We have a user check on the AssetRestriction, but we need to check the
# # AssetGroup as well
# def set_extra_args(self, user):
# self.extra_permission_args = {
# "group__user": user,
# "group__pk": self.kwargs["group"],
# }
# class AssetRestrictionList(
# LoginRequiredMixin, AssetRestrictionsPermissionMixin, ObjectList
# ):
# list_template = "partials/assetrestriction-list.html"
# model = AssetRestriction
# page_title = "List of asset restrictions. Linked to asset groups."
# page_subtitle = (
# "Allows API calls to permit or prohibit trading on defined currency pairs."
# )
# list_url_name = "assetrestrictions"
# list_url_args = ["type", "group"]
# submit_url_name = "assetrestriction_create"
# submit_url_args = ["type", "group"]
# class AssetRestrictionCreate(
# LoginRequiredMixin, AssetRestrictionsPermissionMixin, ObjectCreate
# ):
# model = AssetRestriction
# form_class = AssetRestrictionForm
# submit_url_name = "assetrestriction_create"
# submit_url_args = ["type", "group"]
# def form_invalid(self, form):
# """If the form is invalid, render the invalid form."""
# return self.get(self.request, **self.kwargs, form=form)
# def pre_save_mutate(self, user, obj):
# try:
# assetgroup = AssetGroup.objects.get(pk=self.kwargs["group"], user=user)
# obj.group = assetgroup
# except AssetGroup.DoesNotExist:
# log.error(f"Asset Group {self.kwargs['group']} does not exist")
# raise AbortSave("asset group does not exist or you don't have access")
# class AssetRestrictionUpdate(
# LoginRequiredMixin, AssetRestrictionsPermissionMixin, ObjectUpdate
# ):
# model = AssetRestriction
# form_class = AssetRestrictionForm
# submit_url_name = "assetrestriction_update"
# submit_url_args = ["type", "pk", "group"]
# class AssetRestrictionDelete(
# LoginRequiredMixin, AssetRestrictionsPermissionMixin, ObjectDelete
# ):
# model = AssetRestriction
class AssetGroupAPI(APIView):
parser_classes = [JSONParser]
def post(self, request, webhook_id):
# log.debug(f"AssetAPI POST {webhook_id}: {request.data}")
print(json.dumps(request.data, indent=2))
try:
group = AssetGroup.objects.get(webhook_id=webhook_id)
except AssetGroup.DoesNotExist:
log.error(f"Asset group {webhook_id} does not exist")
return HttpResponse(status=status.HTTP_404_NOT_FOUND)
# 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" not in request.data:
log.error(f"Asset API {webhook_id} has no meta")
return HttpResponse(status=status.HTTP_400_BAD_REQUEST)
if "is_match" not in request.data["meta"]:
log.error(f"Asset API {webhook_id} has no is_match")
return HttpResponse(status=status.HTTP_400_BAD_REQUEST)
is_match = request.data["meta"]["is_match"]
if "topic" not in request.data:
log.error(f"Asset API {webhook_id} has no topic")
return HttpResponse(status=status.HTTP_400_BAD_REQUEST)
topic = request.data["topic"]
print("YES TOPIC", topic)
new_pairs = []
pair_split = topic.split(",")
if not pair_split:
log.error(f"Asset API {webhook_id} topic {topic} is not a pair")
return HttpResponse(status=status.HTTP_400_BAD_REQUEST)
for pair in pair_split:
if pair:
new_pairs.append(pair.strip())
else:
log.error(f"Asset API {webhook_id} pair {pair} is not a pair")
return HttpResponse(status=status.HTTP_400_BAD_REQUEST)
print("YES PAIRS", new_pairs)
# Check if we have lower/upper bounds
if group.aggregation != "none":
if "aggs" in request.data["meta"]:
aggs = request.data["meta"]["aggs"]
if group.aggregation in aggs:
if "value" in aggs[group.aggregation]:
value = aggs[group.aggregation]["value"]
print("YES AVG", value)
is_match = assetfilter.check_asset_aggregation(
value, group.trigger_above, group.trigger_below
)
print("YES AVG IS MATCH", is_match)
for pair in new_pairs:
group.allowed[pair] = is_match is True or None
group.save()
return HttpResponse(status=status.HTTP_200_OK)
# Asset group allowed field
class AssetFilterList(LoginRequiredMixin, ObjectList):
list_template = "partials/asset-filter-list.html"
page_title = "List of asset filters."
page_subtitle = None
context_object_name_singular = "asset filter"
context_object_name = "asset filters"
list_url_name = "assetfilters"
list_url_args = ["type", "group_id"]
def get_queryset(self, **kwargs):
group_id = kwargs.get("group_id", None)
self.extra_context = {"group_id": group_id}
try:
group = AssetGroup.objects.get(id=group_id, user=self.request.user)
except AssetGroup.DoesNotExist:
context = {"message": "Asset group does not exist", "class": "danger"}
return self.render_to_response(context)
return group.allowed
class AssetFilterFlip(LoginRequiredMixin, ObjectNameMixin, View):
template_name = "mixins/partials/notify.html"
model = AssetGroup
def get(self, request, group_id, symbol):
try:
group = AssetGroup.objects.get(id=group_id, user=request.user)
except AssetGroup.DoesNotExist:
context = {"message": "Asset group does not exist", "class": "danger"}
return render(request, self.template_name, context)
if symbol not in group.allowed:
context = {"message": "Asset filter does not exist", "class": "danger"}
return render(request, self.template_name, context)
group.allowed[symbol] = not group.allowed[symbol]
group.save()
context = {"message": "Asset filter updated", "class": "success"}
response = render(request, self.template_name, context)
response["HX-Trigger"] = "assetgroupEvent"
return response
class AssetFilterDelete(LoginRequiredMixin, ObjectNameMixin, View):
template_name = "mixins/partials/notify.html"
model = AssetGroup
def delete(self, request, group_id, symbol):
try:
group = AssetGroup.objects.get(id=group_id, user=request.user)
except AssetGroup.DoesNotExist:
context = {"message": "Asset group does not exist", "class": "danger"}
return render(request, self.template_name, context)
if symbol not in group.allowed:
context = {"message": "Asset filter does not exist", "class": "danger"}
return render(request, self.template_name, context)
del group.allowed[symbol]
group.save()
context = {"message": "Asset filter deleted", "class": "success"}
response = render(request, self.template_name, context)
response["HX-Trigger"] = "assetgroupEvent"
return response