Test checking maximum risk with market data
This commit is contained in:
parent
d3e2bc8648
commit
483333bf28
|
@ -23,10 +23,13 @@ def get_balance_hook(user_id, user_name, account_id, account_name, balance):
|
||||||
def tp_price_to_percent(tp_price, current_price, current_units, unrealised_pl):
|
def tp_price_to_percent(tp_price, current_price, current_units, unrealised_pl):
|
||||||
# Is this right?
|
# Is this right?
|
||||||
pl_per_unit = D(unrealised_pl) / D(current_units)
|
pl_per_unit = D(unrealised_pl) / D(current_units)
|
||||||
|
print("pl_per_unit: ", pl_per_unit)
|
||||||
initial_price = D(current_price) - pl_per_unit
|
initial_price = D(current_price) - pl_per_unit
|
||||||
|
print("initial_price: ", initial_price)
|
||||||
|
|
||||||
# Get the percent change of the TP price from the initial price.
|
# Get the percent change of the TP price from the initial price.
|
||||||
change_percent = ((D(tp_price) - initial_price) / initial_price) * 100
|
change_percent = ((D(tp_price) - initial_price) / initial_price) * 100
|
||||||
|
print("change_percent: ", change_percent)
|
||||||
|
|
||||||
# Doesn't check direction
|
# Doesn't check direction
|
||||||
return abs(round(change_percent, 5))
|
return abs(round(change_percent, 5))
|
||||||
|
@ -35,10 +38,13 @@ def tp_price_to_percent(tp_price, current_price, current_units, unrealised_pl):
|
||||||
def sl_price_to_percent(sl_price, current_price, current_units, unrealised_pl):
|
def sl_price_to_percent(sl_price, current_price, current_units, unrealised_pl):
|
||||||
# Is this right?
|
# Is this right?
|
||||||
pl_per_unit = D(unrealised_pl) / D(current_units)
|
pl_per_unit = D(unrealised_pl) / D(current_units)
|
||||||
|
print("pl_per_unit: ", pl_per_unit)
|
||||||
initial_price = D(current_price) - pl_per_unit
|
initial_price = D(current_price) - pl_per_unit
|
||||||
|
print("initial_price: ", initial_price)
|
||||||
|
|
||||||
# Get the percent change of the SL price from the initial price.
|
# Get the percent change of the SL price from the initial price.
|
||||||
change_percent = ((D(sl_price) - initial_price) / initial_price) * 100
|
change_percent = ((D(sl_price) - initial_price) / initial_price) * 100
|
||||||
|
print("change_percent: ", change_percent)
|
||||||
|
|
||||||
# Doesn't check direction
|
# Doesn't check direction
|
||||||
return abs(round(change_percent, 5))
|
return abs(round(change_percent, 5))
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
from django.test import TestCase
|
from django.test import TestCase
|
||||||
|
|
||||||
|
from core.exchanges.common import convert_open_trades
|
||||||
from core.models import RiskModel, User
|
from core.models import RiskModel, User
|
||||||
from core.trading import risk
|
from core.trading import risk
|
||||||
|
|
||||||
|
@ -23,9 +24,9 @@ class RiskModelTestCase(TestCase):
|
||||||
"symbol": "XXXYYY",
|
"symbol": "XXXYYY",
|
||||||
"side": "BUY",
|
"side": "BUY",
|
||||||
# We already calculated the TP percent loss relative to the account size
|
# We already calculated the TP percent loss relative to the account size
|
||||||
"tp_percent": 9,
|
"take_profit_percent": 9,
|
||||||
"sl_percent": 9,
|
"stop_loss_percent": 9,
|
||||||
"tsl_percent": 9,
|
"trailing_stop_loss_percent": 9,
|
||||||
}
|
}
|
||||||
|
|
||||||
def test_check_max_loss(self):
|
def test_check_max_loss(self):
|
||||||
|
@ -73,8 +74,8 @@ class RiskModelTestCase(TestCase):
|
||||||
multiple trades.
|
multiple trades.
|
||||||
"""
|
"""
|
||||||
trade = self.trade.copy()
|
trade = self.trade.copy()
|
||||||
trade["sl_percent"] = 1
|
trade["stop_loss_percent"] = 1
|
||||||
trade["tsl_percent"] = 1
|
trade["trailing_stop_loss_percent"] = 1
|
||||||
account_trades = [trade] * 9
|
account_trades = [trade] * 9
|
||||||
allowed = risk.check_max_risk(self.risk_model, account_trades)
|
allowed = risk.check_max_risk(self.risk_model, account_trades)
|
||||||
self.assertTrue(allowed)
|
self.assertTrue(allowed)
|
||||||
|
@ -85,7 +86,7 @@ class RiskModelTestCase(TestCase):
|
||||||
risked is exactly the max risk limit.
|
risked is exactly the max risk limit.
|
||||||
"""
|
"""
|
||||||
trade = self.trade.copy()
|
trade = self.trade.copy()
|
||||||
trade["sl_percent"] = 10
|
trade["stop_loss_percent"] = 10
|
||||||
account_trades = [trade]
|
account_trades = [trade]
|
||||||
allowed = risk.check_max_risk(self.risk_model, account_trades)
|
allowed = risk.check_max_risk(self.risk_model, account_trades)
|
||||||
self.assertFalse(allowed)
|
self.assertFalse(allowed)
|
||||||
|
@ -96,8 +97,8 @@ class RiskModelTestCase(TestCase):
|
||||||
risked is exactly the max risk limit with multiple trades.
|
risked is exactly the max risk limit with multiple trades.
|
||||||
"""
|
"""
|
||||||
trade = self.trade.copy()
|
trade = self.trade.copy()
|
||||||
trade["sl_percent"] = 1
|
trade["stop_loss_percent"] = 1
|
||||||
trade["tsl_percent"] = 1
|
trade["trailing_stop_loss_percent"] = 1
|
||||||
account_trades = [trade] * 10
|
account_trades = [trade] * 10
|
||||||
allowed = risk.check_max_risk(self.risk_model, account_trades)
|
allowed = risk.check_max_risk(self.risk_model, account_trades)
|
||||||
self.assertFalse(allowed)
|
self.assertFalse(allowed)
|
||||||
|
@ -189,3 +190,87 @@ class RiskModelTestCase(TestCase):
|
||||||
account_trades = [trade1, trade2, trade1, trade2, trade1, trade2]
|
account_trades = [trade1, trade2, trade1, trade2, trade1, trade2]
|
||||||
allowed = risk.check_max_open_trades_per_symbol(self.risk_model, account_trades)
|
allowed = risk.check_max_open_trades_per_symbol(self.risk_model, account_trades)
|
||||||
self.assertFalse(allowed)
|
self.assertFalse(allowed)
|
||||||
|
|
||||||
|
def check_max_risk_market_data(self):
|
||||||
|
"""
|
||||||
|
Check that we can open a trade within the max risk limit with market data.
|
||||||
|
"""
|
||||||
|
trade = {
|
||||||
|
"id": "abd123",
|
||||||
|
"symbol": "EUR_USD",
|
||||||
|
"currentUnits": 100,
|
||||||
|
"side": "long",
|
||||||
|
"state": "open",
|
||||||
|
"price": 1.0, # initial
|
||||||
|
"unrealizedPL": 0, # price == initial
|
||||||
|
"stopLossOrder": {
|
||||||
|
"price": 0.95, # down by 5%, 5% risk
|
||||||
|
},
|
||||||
|
}
|
||||||
|
converted = convert_open_trades([trade])
|
||||||
|
self.assertEqual(converted[0]["stop_loss_percent"], 5)
|
||||||
|
max_risk_check = risk.check_max_risk(self.risk_model, converted)
|
||||||
|
self.assertTrue(max_risk_check) # 5% risk is fine
|
||||||
|
|
||||||
|
def check_max_risk_market_data_multiple(self):
|
||||||
|
"""
|
||||||
|
Check that we can open a trade within the max risk limit with market data
|
||||||
|
and multiple trades.
|
||||||
|
"""
|
||||||
|
trade = {
|
||||||
|
"id": "abd123",
|
||||||
|
"symbol": "EUR_USD",
|
||||||
|
"currentUnits": 100,
|
||||||
|
"side": "long",
|
||||||
|
"state": "open",
|
||||||
|
"price": 1.0, # initial
|
||||||
|
"unrealizedPL": 0, # price == initial
|
||||||
|
"stopLossOrder": {
|
||||||
|
"price": 0.96, # down by 4%, 4% risk
|
||||||
|
},
|
||||||
|
}
|
||||||
|
converted = convert_open_trades([trade, trade])
|
||||||
|
max_risk_check = risk.check_max_risk(self.risk_model, converted)
|
||||||
|
self.assertTrue(max_risk_check) # 8% risk is fine
|
||||||
|
|
||||||
|
def check_max_risk_market_data_fail(self):
|
||||||
|
"""
|
||||||
|
Check that we can not open a trade outside the max risk limit with market data.
|
||||||
|
"""
|
||||||
|
trade = {
|
||||||
|
"id": "abd123",
|
||||||
|
"symbol": "EUR_USD",
|
||||||
|
"currentUnits": 100,
|
||||||
|
"side": "long",
|
||||||
|
"state": "open",
|
||||||
|
"price": 1.0, # initial
|
||||||
|
"unrealizedPL": 0, # price == initial
|
||||||
|
"stopLossOrder": {
|
||||||
|
"price": 0.9, # down by 10%, 10% risk
|
||||||
|
},
|
||||||
|
}
|
||||||
|
converted = convert_open_trades([trade])
|
||||||
|
self.assertEqual(converted[0]["stop_loss_percent"], 10)
|
||||||
|
max_risk_check = risk.check_max_risk(self.risk_model, converted)
|
||||||
|
self.assertFalse(max_risk_check) # 10% risk is too much
|
||||||
|
|
||||||
|
def check_max_risk_market_data_fail_multiple(self):
|
||||||
|
"""
|
||||||
|
Check that we can not open a trade outside the max risk limit with market data
|
||||||
|
and multiple trades.
|
||||||
|
"""
|
||||||
|
trade = {
|
||||||
|
"id": "abd123",
|
||||||
|
"symbol": "EUR_USD",
|
||||||
|
"currentUnits": 100,
|
||||||
|
"side": "long",
|
||||||
|
"state": "open",
|
||||||
|
"price": 1.0, # initial
|
||||||
|
"unrealizedPL": 0, # price == initial
|
||||||
|
"stopLossOrder": {
|
||||||
|
"price": 0.95, # down by 5%, 5% risk
|
||||||
|
},
|
||||||
|
}
|
||||||
|
converted = convert_open_trades([trade, trade])
|
||||||
|
max_risk_check = risk.check_max_risk(self.risk_model, converted)
|
||||||
|
self.assertFalse(max_risk_check) # 10% risk is too much
|
||||||
|
|
|
@ -15,11 +15,12 @@ def check_max_risk(risk_model, account_trades):
|
||||||
total_risk = 0
|
total_risk = 0
|
||||||
for trade in account_trades:
|
for trade in account_trades:
|
||||||
max_tmp = []
|
max_tmp = []
|
||||||
if "sl_percent" in trade:
|
if "stop_loss_percent" in trade:
|
||||||
max_tmp.append(trade["sl_percent"])
|
max_tmp.append(trade["stop_loss_percent"])
|
||||||
if "tsl_percent" in trade:
|
if "trailing_stop_loss_percent" in trade:
|
||||||
max_tmp.append(trade["tsl_percent"])
|
max_tmp.append(trade["trailing_stop_loss_percent"])
|
||||||
total_risk += max(max_tmp)
|
total_risk += max(max_tmp)
|
||||||
|
print("Total risk: ", total_risk)
|
||||||
return total_risk < max_risk_percent
|
return total_risk < max_risk_percent
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue