Description
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
'