Skip to content

Commit

Permalink
Raises error if sell/cover_all_shares is called without open position.
Browse files Browse the repository at this point in the history
  • Loading branch information
edtechre committed Jan 8, 2025
1 parent 96f0609 commit fc54771
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 7 deletions.
9 changes: 7 additions & 2 deletions src/pybroker/context.py
Original file line number Diff line number Diff line change
Expand Up @@ -829,7 +829,9 @@ def sell_all_shares(self):
"""Sells all long shares of :attr:`.ExecContext.symbol`."""
pos = self.long_pos()
if pos is None:
return
raise ValueError(
f"sell_all_shares failed: No long position for {self.symbol}"
)
self.sell_shares = pos.shares
self._portfolio.remove_stops(pos)
self._exiting_pos = True
Expand All @@ -838,7 +840,9 @@ def cover_all_shares(self):
"""Covers all short shares of :attr:`.ExecContext.symbol`."""
pos = self.short_pos()
if pos is None:
return
raise ValueError(
f"cover_all_shares failed: No short position for {self.symbol}"
)
self.cover_shares = pos.shares
self._portfolio.remove_stops(pos)
self._exiting_pos = True
Expand Down Expand Up @@ -1304,6 +1308,7 @@ def to_result(self) -> Optional[ExecResult]:
"sell_shares or hold_bars must be set when "
"sell_fill_price is set."
)

if self.buy_shares is None and self.sell_shares is None:
if (
self.stop_loss is not None
Expand Down
14 changes: 10 additions & 4 deletions tests/test_context.py
Original file line number Diff line number Diff line change
Expand Up @@ -263,8 +263,11 @@ def test_sell_all_shares(ctx_with_pos):


def test_sell_all_shares_when_no_position(ctx):
ctx.sell_all_shares()
assert ctx.sell_shares is None
with pytest.raises(
ValueError,
match=re.escape("sell_all_shares failed: No long position for SPY"),
):
ctx.sell_all_shares()


def test_cover_all_shares(ctx_with_pos):
Expand All @@ -274,8 +277,11 @@ def test_cover_all_shares(ctx_with_pos):


def test_cover_all_shares_when_no_position(ctx):
ctx.cover_all_shares()
assert ctx.buy_shares is None
with pytest.raises(
ValueError,
match=re.escape("cover_all_shares failed: No short position for SPY"),
):
ctx.cover_all_shares()


def test_model(ctx, trained_models, symbol):
Expand Down
2 changes: 1 addition & 1 deletion tests/test_strategy.py
Original file line number Diff line number Diff line change
Expand Up @@ -2378,7 +2378,7 @@ def test_backtest_when_no_stops(self, data_source_df):
def exec_fn(ctx):
if ctx.bars == 1:
ctx.buy_shares = 100
elif ctx.bars > 30:
elif ctx.long_pos() and ctx.bars > 30:
ctx.sell_all_shares()

strategy = Strategy(data_source_df, START_DATE, END_DATE)
Expand Down

0 comments on commit fc54771

Please sign in to comment.