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.

100 lines
3.2 KiB
Python

from core.models import AssetRule
def get_allowed(group, base, quote, side):
"""
Determine whether the trade is allowed according to the group.
See tests for examples. The logic requires trading knowledge.
:param group: The group to check
:param base: The base currency
:param quote: The quote currency
:param side: The direction of the trade
"""
# If our base has allowed == False, we can only short it, or long the quote
base_rule = AssetRule.objects.filter(group=group, asset=base).first()
if base_rule:
mapped_status = update_status_from_mappings(base_rule.status, group)
if mapped_status == 6:
# Always allow
return True
elif mapped_status == 7:
# Always deny
return False
elif mapped_status == 3:
if side == "long":
return False
elif mapped_status == 2:
if side == "short":
return False
# If our quote has allowed == False, we can only long it, or short the base
quote_rule = AssetRule.objects.filter(group=group, asset=quote).first()
if quote_rule:
mapped_status = update_status_from_mappings(quote_rule.status, group)
if mapped_status == 6:
# Always allow
return True
elif mapped_status == 7:
# Always deny
return False
elif mapped_status == 3:
if side == "short":
return False
elif mapped_status == 2:
if side == "long":
return False
if not base_rule and not quote_rule:
if group.when_no_data == 7:
# Always deny
return False
elif group.when_no_data == 6:
# Always allow
return True
return True
def check_asset_aggregation(value, trigger_above, trigger_below):
"""
Check if the value is within the bounds of the aggregation.
:param value: The value to check
:param trigger_above: Only trigger if the value is above this
:param trigger_below: Only trigger if the value is below this
"""
if trigger_below is not None:
if value < trigger_below:
# Prohibited
return 3
if trigger_above is not None:
if value > trigger_above:
# Permitted
return 2
# Neither is defined, so we match
if not any(x is not None for x in [trigger_above, trigger_below]):
# No aggregation
return 4
# Not in bounds
return 5
def update_status_from_mappings(status, asset_group):
if status == 0:
if asset_group.when_no_data > -1:
return asset_group.when_no_data
elif status == 1:
if asset_group.when_no_match > -1:
return asset_group.when_no_match
elif status == 2:
if asset_group.when_bullish > -1:
return asset_group.when_bullish
elif status == 3:
if asset_group.when_bearish > -1:
return asset_group.when_bearish
elif status == 4:
if asset_group.when_no_aggregation > -1:
return asset_group.when_no_aggregation
elif status == 5:
if asset_group.when_not_in_bounds > -1:
return asset_group.when_not_in_bounds
return status