Skip to content

Move stop loss (to break even) #179

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
darkknight9394 opened this issue Mar 28, 2025 · 1 comment
Open

Move stop loss (to break even) #179

darkknight9394 opened this issue Mar 28, 2025 · 1 comment
Assignees

Comments

@darkknight9394
Copy link

Hi gents,

I am wondering if there's anyway to do the following. After we are in a trade for 3 days, if we are profitable, we move the stop loss to break-even point (at the fill price). I have include 2 segments below. The first one sells 1/3 of the shares, whereas in the 2nd statement we want to move the stop loss to fill price. I am encountering an error which leads me to think there's no way of modifying the stop loss once it's been set.

ERROR ==> ValueError: Either buy_shares or sell_shares must be set when a stop is set.

` if ctx.long_pos().bars == N_BAR_SHORT_TERM and ctx.long_pos().pnl > 0:
ctx.sell_shares = ctx.long_pos().shares/3
if is_verbose:
print(f"{current_date} - SELL HALF for {symbol}: held for {N_BAR_SHORT_TERM} bars. shares {ctx.sell_shares}")
return

    # this simulates move stop loss to breakeven
    if ctx.long_pos().bars == N_BAR_SHORT_TERM+1 and ctx.long_pos().pnl > 0:
       print("Shares remaining", ctx.long_pos().shares)
       ctx.cancel_stops(ctx.symbol)
       # ideally I will have a new stop loss order set here for breakeven, or order amend 
       return

`

Temporary solution that I come up with is to first cancel the order, afterwards make use of the ctx.session dictionary to continuously monitor where the close price falls below a breakeven, if so sell the remaining shares at the breakeven point. I am fully aware this is not a clean approach and the code can be very spaghetti once more profit taking rules are added. Is there anyway we can do that in a more clean fashion?

' #################################################################################################################
# The logic is as follows:
# 1) after N_BAR_SHORT_TERM if we are profitable, sell 1/3 of the shares
# 2) on the same day we move the stop loss to breakeven by
# i) cancel the existing stop loss
# ii) setup session dict for the symbol to monitor the breakeven price and decision
# iii) continuous monitoring if the price is below the breakeven price if so sell it

    if ctx.long_pos().bars == N_BAR_SHORT_TERM and ctx.long_pos().pnl > 0:
        ctx.sell_shares = ctx.long_pos().shares/3
        if is_verbose:
            print(f"{current_date} - SELL HALF for {symbol}: held for {N_BAR_SHORT_TERM} bars. shares {ctx.sell_shares}")
        return

    # i) cancel the existing stop loss
    if ctx.long_pos().bars == N_BAR_SHORT_TERM+1 and ctx.long_pos().pnl > 0:
        remaining_shares = ctx.long_pos().shares
        #if ctx.long_pos().bars == N_BAR_SHORT_TERM and ctx.long_pos().pnl > 0:
        print("Shares remaining", remaining_shares)
        ctx.cancel_stops(ctx.symbol)

        #ii) setup session dict for the symbol to monitor the breakeven price and decision
        if ctx.session.get(symbol, True):
            # # Clear the signal once trade is entered.
            ctx.session[symbol] = {
                'fill_price': ctx.long_pos().entries[0].price,
                'bar': np.nan,
                'date': None,
                'monitor_breakeven': True,
            }
        return

    #iii) continuous monitoring if the price is below the breakeven price if so sell it 
    # we are selling all remaining shares if the price is below the breakeven
    if ctx.session.get(symbol, False) and ctx.session[symbol]['monitor_breakeven']:
        if ctx.close[-1] <= ctx.session[symbol]['fill_price']:
            ctx.sell_fill_price = ctx.session[symbol]['fill_price']
            ctx.sell_shares = ctx.long_pos().shares
            if is_verbose:
                print(f"{current_date} - BREAK_EVEN POINT for {symbol}: close {current_close:.2f} below breakeven {ctx.session[symbol]['fill_price']:.2f}")

            ctx.session[symbol] =None
        return

'

@edtechre edtechre self-assigned this Apr 13, 2025
@edtechre
Copy link
Owner

Thanks for the info @darkknight9394. I will think about how to support modifying stops that have not yet triggered. Let me know if you have any suggestions on what the API should look like.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants