edtechre / pybroker

Algorithmic Trading in Python with Machine Learning

Home Page:https://www.pybroker.com

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Suspicious short trade in a pure long trades

none2003 opened this issue · comments

Hi @edtechre,

I'm reviewing examples in "10. Rotational Trading.ipynb", I modified nothing but adding a line of trailing stop setting code to function "rotate" like this:

def rotate(ctx: ExecContext):
    if ctx.long_pos():
        if ctx.symbol not in pyb.param('top_symbols'):
            ctx.sell_all_shares()
    else:
        target_size = pyb.param('target_size')
        ctx.buy_shares = ctx.calc_target_shares(target_size)
        ctx.score = ctx.indicator('roc_20')[-1]
        ctx.stop_trailing_pct = 5 # <------- adding trailing stop setting here

The backtesting result is interesting. There are some weird short trades in this purely long scenario. Is this normal?
image

This is likely due to using both a trailing stop and selling all shares in the same strategy. You should only use either sell_all_shares or a stop if your intention is to exit a position, not both at the same time.

However, I will look into this more to see if it makes sense to add logic for the long stop to trigger only if there is a long position.

I was intended to try if it's possible to sell all share either not in "top symbols" list or a daily drop greater than trailing stop threshold.

Yes, please investigate further. Much appreciate.

Added a check for an existing long/short position before triggering a long/short stop. Fix is in dev and will be merged into v1.1.30.

Hi @edtechre,

I saw 1.1.30 added "Checks for existing long/short positions before triggering long/short stops". So I upgraded pybroker to 1.1.30 and re-run "10. Rotational Trading.ipynb" with ctx.stop_trailing_pct = 5, the result seems no difference with using 1.1.29.
image

If the trailing stop sold all long position at trade id#4, and in function "rotate" using "if ctx.long_pos()" prevents over sell, how these short trades happened?

You need to cancel all stops after calling sell_all_shares:

def rotate(ctx: ExecContext):
    if ctx.long_pos():
        if ctx.symbol not in pyb.param('top_symbols'):
            ctx.sell_all_shares()
            ctx.cancel_stops(ctx.symbol)
    else:
        target_size = pyb.param('target_size')
        ctx.buy_shares = ctx.calc_target_shares(target_size)
        ctx.score = ctx.indicator('roc_20')[-1]
        ctx.stop_trailing_pct = 5

You need to cancel all stops after calling sell_all_shares:

def rotate(ctx: ExecContext):
    if ctx.long_pos():
        if ctx.symbol not in pyb.param('top_symbols'):
            ctx.sell_all_shares()
            ctx.cancel_stops(ctx.symbol)
    else:
        target_size = pyb.param('target_size')
        ctx.buy_shares = ctx.calc_target_shares(target_size)
        ctx.score = ctx.indicator('roc_20')[-1]
        ctx.stop_trailing_pct = 5

Thank, this helps a lot! 👍

Hi @edtechre,

I noticed the change log of release 1.1.34:

Removes all stops when ctx.sell_all_shares is called.

Does this mean there is no need to manually call "ctx.cancel_stops(ctx.symbol)" after "ctx.sell_all_shares()"?

Hi @none2003,

It is equivalent. The only difference is that ctx.cancel_stops(symbol) also cancels stops for any short positions for symbol.

Hi @none2003,

It is equivalent. The only difference is that ctx.cancel_stops(symbol) also cancels stops for any short positions for symbol.

Can I understand that while sell_all_shares closes all long positions, it also cancels stops for any long positions? So does it also mean cover_all_shares close all short positions and also cancel stops for any short positions?

Thanks for catching, I have also made the change to cover_all_shares.