Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 15 additions & 15 deletions tests/vali_tests/test_positions.py
Original file line number Diff line number Diff line change
Expand Up @@ -483,7 +483,7 @@ def test_simple_long_position_with_explicit_FLAT(self):
self.add_order_to_position_and_save(position, o2)
self.validate_intermediate_position_state(position, {
'orders': [o1, o2],
'position_type': OrderType.FLAT,
'position_type': OrderType.LONG,
'is_closed_position': True,
'net_leverage': 0.0,
'net_value': 0.0,
Expand Down Expand Up @@ -598,7 +598,7 @@ def test_simple_long_position_with_implicit_FLAT(self):
self.add_order_to_position_and_save(position, o2)
self.validate_intermediate_position_state(position, {
'orders': [o1, o2],
'position_type': OrderType.FLAT,
'position_type': OrderType.LONG,
'is_closed_position': True,
'net_leverage': 0.0,
'net_value': 0.0,
Expand Down Expand Up @@ -670,7 +670,7 @@ def test_simple_short_position_with_explicit_FLAT(self):
self.add_order_to_position_and_save(position, o2)
self.validate_intermediate_position_state(position, {
'orders': [o1, o2],
'position_type': OrderType.FLAT,
'position_type': OrderType.SHORT,
'is_closed_position': True,
'net_leverage': 0.0,
'net_value': 0.0,
Expand Down Expand Up @@ -736,7 +736,7 @@ def test_liquidated_long_position_with_explicit_FLAT(self):
self.add_order_to_position_and_save(position, o2)
self.validate_intermediate_position_state(position, {
'orders': [o1, o2],
'position_type': OrderType.FLAT,
'position_type': OrderType.LONG,
'is_closed_position': True,
'net_leverage': 2.0,
'initial_entry_price': 100,
Expand Down Expand Up @@ -802,7 +802,7 @@ def test_liquidated_short_position_with_explicit_FLAT(self):
self.add_order_to_position_and_save(position, o2)
self.validate_intermediate_position_state(position, {
'orders': [o1, o2],
'position_type': OrderType.FLAT,
'position_type': OrderType.SHORT,
'is_closed_position': True,
'net_leverage': -1.0,
'initial_entry_price': 100,
Expand Down Expand Up @@ -880,7 +880,7 @@ def test_liquidated_short_position_with_no_FLAT(self):

self.validate_intermediate_position_state(position, {
'orders': [o1, o2, position.orders[2]],
'position_type': OrderType.FLAT,
'position_type': OrderType.SHORT,
'is_closed_position': True,
'net_leverage': -1.0,
'initial_entry_price': 100,
Expand All @@ -906,7 +906,7 @@ def test_liquidated_short_position_with_no_FLAT(self):
self.add_order_to_position_and_save(position, o3)
self.validate_intermediate_position_state(position, {
'orders': [o1, o2, position.orders[2]],
'position_type': OrderType.FLAT,
'position_type': OrderType.SHORT,
'is_closed_position': True,
'net_leverage': -1.0,
'initial_entry_price': 100,
Expand Down Expand Up @@ -983,7 +983,7 @@ def test_liquidated_long_position_with_no_FLAT(self):

self.validate_intermediate_position_state(position, {
'orders': [o1, o2, position.orders[2]],
'position_type': OrderType.FLAT,
'position_type': OrderType.LONG,
'is_closed_position': True,
'net_leverage': 2.0,
'initial_entry_price': 100,
Expand All @@ -1010,7 +1010,7 @@ def test_liquidated_long_position_with_no_FLAT(self):

self.validate_intermediate_position_state(position, {
'orders': [o1, o2, position.orders[2]],
'position_type': OrderType.FLAT,
'position_type': OrderType.LONG,
'is_closed_position': True,
'net_leverage': 2.0,
'initial_entry_price': 100,
Expand Down Expand Up @@ -1076,7 +1076,7 @@ def test_simple_short_position_with_implicit_FLAT(self):
self.add_order_to_position_and_save(position, o2)
self.validate_intermediate_position_state(position, {
'orders': [o1, o2],
'position_type': OrderType.FLAT,
'position_type': OrderType.SHORT,
'is_closed_position': True,
'net_leverage': 0.0,
'initial_entry_price': 1000,
Expand Down Expand Up @@ -1204,7 +1204,7 @@ def test_three_orders_with_longs_no_drawdown(self):
self.add_order_to_position_and_save(position, o3)
self.validate_intermediate_position_state(position, {
'orders': [o1, o2, o3],
'position_type': OrderType.FLAT,
'position_type': OrderType.LONG,
'is_closed_position': True,
'net_leverage': 0.0,
'initial_entry_price': 1000,
Expand Down Expand Up @@ -1269,7 +1269,7 @@ def test_two_orders_with_a_loss(self):
self.add_order_to_position_and_save(position, o2)
self.validate_intermediate_position_state(position, {
'orders': [o1, o2],
'position_type': OrderType.FLAT,
'position_type': OrderType.LONG,
'is_closed_position': True,
'net_leverage': 0.0,
'initial_entry_price': 1000,
Expand Down Expand Up @@ -1431,7 +1431,7 @@ def test_returns_on_large_price_increase(self):

self.validate_intermediate_position_state(position, {
'orders': [o1, o2, o3, o4, o5],
'position_type': OrderType.FLAT,
'position_type': OrderType.LONG,
'is_closed_position': True,
'net_leverage': 0.0,
'initial_entry_price': 1000,
Expand Down Expand Up @@ -1495,7 +1495,7 @@ def test_returns_on_many_shorts(self):

self.validate_intermediate_position_state(position, {
'orders': [o1, o2, o3, o4, o5],
'position_type': OrderType.FLAT,
'position_type': OrderType.SHORT,
'is_closed_position': True,
'net_leverage': 0.0,
'initial_entry_price': 1000,
Expand Down Expand Up @@ -1559,7 +1559,7 @@ def test_returns_on_alternating_long_short(self):

self.validate_intermediate_position_state(position, {
'orders': [o1, o2, o3, o4, o5],
'position_type': OrderType.FLAT,
'position_type': OrderType.SHORT,
'is_closed_position': True,
'net_leverage': 0.0,
'initial_entry_price': 1000,
Expand Down
11 changes: 5 additions & 6 deletions vali_objects/vali_dataclasses/position.py
Original file line number Diff line number Diff line change
Expand Up @@ -596,7 +596,7 @@ def calculate_pnl(self, current_price, live_price_fetcher, t_ms=None, order=None
# pnl with slippage
if order:
# update realized pnl for orders that reduce the size of a position
if order.order_type != self.position_type or self.position_type == OrderType.FLAT:
if order.order_type != self.position_type or self.is_closed_position:
exit_price = current_price * (1 + order.slippage) if order.leverage > 0 else current_price * (1 - order.slippage)
order_realized_pnl_quote = -1 * (exit_price - self.average_entry_price) * (order.quantity * order.trade_pair.lot_size)
order.realized_pnl = order_realized_pnl_quote * order.quote_usd_rate
Expand Down Expand Up @@ -825,7 +825,7 @@ def update_position_state_for_new_order(self, order, delta_quantity, delta_lever
self._position_log(f"closed position total w/o fees [{self.current_return}]. Trade pair: {self.trade_pair.trade_pair_id}")
self._position_log(f"closed return with fees [{self.return_at_close}]. Trade pair: {self.trade_pair.trade_pair_id}")

if self.position_type == OrderType.FLAT:
if self.is_closed_position:
self.net_leverage = 0.0
self.net_quantity = 0.0
self.net_value = 0.0
Expand Down Expand Up @@ -867,7 +867,6 @@ def initialize_position_from_first_order(self, order):
self.close_out_position(order.processed_ms)

def close_out_position(self, close_ms):
self.position_type = OrderType.FLAT
self.is_closed_position = True
self.close_ms = close_ms

Expand Down Expand Up @@ -1070,10 +1069,10 @@ def _update_position(self, price_fetcher_client=None):

# Reflect the current order in the current position's return.
adjusted_quantity = (
0.0 if self.position_type == OrderType.FLAT else order.quantity
0.0 if self.is_closed_position else order.quantity
)
adjusted_leverage = (
0.0 if self.position_type == OrderType.FLAT else order.leverage
0.0 if self.is_closed_position else order.leverage
)
#bt.logging.info(
# f"Updating position state for new order {order} with adjusted leverage {adjusted_quantity}"
Expand All @@ -1082,5 +1081,5 @@ def _update_position(self, price_fetcher_client=None):


# If the position is already closed, we don't need to process any more orders. break in case there are more orders.
if self.position_type == OrderType.FLAT:
if self.is_closed_position:
break
2 changes: 1 addition & 1 deletion vanta_api/websocket_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -320,7 +320,7 @@ def _create_test_position(self, timestamp: int) -> Dict[str, Any]:
'order_uuid': 'd6e1e768-9024-4cc5-84d7-d66691d82061', 'price_sources': [], 'src': 0}],
'current_return': 0.9980034808990859, 'close_ms': 1742362860000, 'net_leverage': 0.0,
'return_at_close': 0.9980034808990859, 'average_entry_price': 82871.92127250001,
'position_type': OrderType.FLAT,
'position_type': OrderType.SHORT,
'is_closed_position': True})
return p.to_websocket_dict()

Expand Down
Loading