Fix profit/loss calculation

This commit is contained in:
Mark Veidemanis 2023-01-06 08:52:15 +00:00
parent 1bab2a729b
commit ae42d9b223
Signed by: m
GPG Key ID: 5ACFCEED46C0904F
4 changed files with 39 additions and 19 deletions

View File

@ -1,6 +1,7 @@
from decimal import Decimal as D from decimal import Decimal as D
from core.lib.elastic import store_msg from core.lib.elastic import store_msg
from core.trading.market import to_currency
def get_balance_hook(user_id, user_name, account_id, account_name, balance): def get_balance_hook(user_id, user_name, account_id, account_name, balance):
@ -34,9 +35,22 @@ def tp_price_to_percent(tp_price, side, current_price, current_units, unrealised
# 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 = ((initial_price - D(tp_price)) / initial_price) * 100 change_percent = ((initial_price - D(tp_price)) / initial_price) * 100
# If the trade is long, the TP price will be lower than the initial price.
if side == "long": if side == "long":
change_percent *= -1 if D(tp_price) < initial_price:
loss = True
else:
loss = False
else:
if D(tp_price) > initial_price:
loss = True
else:
loss = False
# if we are in loss on the short side, we want to show a negative
if loss:
change_percent = 0 - abs(change_percent)
else:
change_percent = abs(change_percent)
return round(change_percent, 5) return round(change_percent, 5)
@ -65,23 +79,22 @@ def sl_price_to_percent(sl_price, side, current_price, current_units, unrealised
# change_percent *= -1 # change_percent *= -1
if side == "long": if side == "long":
if D(current_price) > initial_price: if D(sl_price) > initial_price:
profit = True profit = True
else: else:
profit = False profit = False
else: else:
if D(current_price) < initial_price: if D(sl_price) < initial_price:
profit = True profit = True
else: else:
profit = False profit = False
# if we are in profit on the short side, we want to show a negative loss print("CHANGE PERCENT: ", change_percent)
if profit and side == "short": print("PROFIT", profit)
# change_percent *= -1
if profit:
change_percent = 0 - abs(change_percent) change_percent = 0 - abs(change_percent)
# if we are in loss on the long side, we want to show a positive loss else:
if not profit and side == "long":
# change_percent *= -1
change_percent = abs(change_percent) change_percent = abs(change_percent)
return round(change_percent, 5) return round(change_percent, 5)
@ -143,3 +156,9 @@ def convert_open_trades(open_trades):
trades.append(cast) trades.append(cast)
return trades return trades
def convert_trades_to_usd(account, trades):
"""
Convert a list of trades to USD.
"""

View File

@ -163,7 +163,7 @@ class CommonTestCase(TestCase):
""" """
Test that the SL price to percent conversion works for long trades. Test that the SL price to percent conversion works for long trades.
""" """
sl_price = 1.1 # 10% sl_price = 0.9 # 10%
current_price = 1.0 current_price = 1.0
current_units = 1 current_units = 1
unrealised_pl = 0 unrealised_pl = 0
@ -176,7 +176,7 @@ class CommonTestCase(TestCase):
""" """
Test that the SL price to percent conversion works for short trades. Test that the SL price to percent conversion works for short trades.
""" """
sl_price = 0.9 # 10% sl_price = 1.1 # 10%
current_price = 1.0 current_price = 1.0
current_units = 1 current_units = 1
unrealised_pl = 0 unrealised_pl = 0
@ -219,7 +219,7 @@ class CommonTestCase(TestCase):
Test that the SL price to percent conversion works for long trades Test that the SL price to percent conversion works for long trades
with multiple units. with multiple units.
""" """
sl_price = 1.1 # -10% sl_price = 0.9 # -10%
current_price = 1.0 current_price = 1.0
current_units = 10 current_units = 10
unrealised_pl = 0 unrealised_pl = 0
@ -233,14 +233,14 @@ class CommonTestCase(TestCase):
Test that the SL price to percent conversion works for short trades Test that the SL price to percent conversion works for short trades
with multiple units. with multiple units.
""" """
sl_price = 0.9 # -10% sl_price = 1.2 # -20%
current_price = 1.0 current_price = 1.0
current_units = 10 current_units = 10
unrealised_pl = 0 unrealised_pl = 0
percent = sl_price_to_percent( percent = sl_price_to_percent(
sl_price, "short", current_price, current_units, unrealised_pl sl_price, "short", current_price, current_units, unrealised_pl
) )
self.assertEqual(percent, 10) self.assertEqual(percent, 20)
def test_sl_price_to_percent_change_long_multi_profit(self): def test_sl_price_to_percent_change_long_multi_profit(self):
""" """

View File

@ -134,14 +134,10 @@ class LiveTradingTestCase(ElasticMock, LiveBase, TestCase):
expected_sl_percent = D(2 - self.commission) expected_sl_percent = D(2 - self.commission)
actual_tp_percent = trades_converted[0]["take_profit_percent"] actual_tp_percent = trades_converted[0]["take_profit_percent"]
actual_sl_percent = trades_converted[0]["stop_loss_percent"] actual_sl_percent = trades_converted[0]["stop_loss_percent"]
print("actual_tp_percent", actual_tp_percent)
print("actual_sl_percent", actual_sl_percent)
tp_percent_difference = abs(expected_tp_percent - actual_tp_percent) tp_percent_difference = abs(expected_tp_percent - actual_tp_percent)
sl_percent_difference = abs(expected_sl_percent - actual_sl_percent) sl_percent_difference = abs(expected_sl_percent - actual_sl_percent)
max_difference = D(0.08) # depends on market conditions max_difference = D(0.08) # depends on market conditions
print("TP percent difference: {}".format(tp_percent_difference))
print("SL percent difference: {}".format(sl_percent_difference))
self.assertLess(tp_percent_difference, max_difference) self.assertLess(tp_percent_difference, max_difference)
self.assertLess(sl_percent_difference, max_difference) self.assertLess(sl_percent_difference, max_difference)

View File

@ -1,3 +1,6 @@
from core.trading.market import to_currency
def check_max_loss(risk_model, initial_balance, account_balance): def check_max_loss(risk_model, initial_balance, account_balance):
""" """
Check that the account balance is within the max loss limit. Check that the account balance is within the max loss limit.
@ -15,6 +18,8 @@ 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 = []
# Need to calculate the max risk in base account currency
# Percentages relate to the price movement, without accounting the size of the trade
if "stop_loss_percent" in trade: if "stop_loss_percent" in trade:
max_tmp.append(trade["stop_loss_percent"]) max_tmp.append(trade["stop_loss_percent"])
if "trailing_stop_loss_percent" in trade: if "trailing_stop_loss_percent" in trade: