Back to Community
Ordering behaves funny in a gap-up + stop trailing algo

Dear Quantopians,

I wrote an algo which trades long (so far, for testing) when the following things happen:

  • gap up on market opening in an asset (AAPL for testing). Gap has to be 0.5%
  • momentum up (in a direction of the gap) is present even after the first 5 min bar . I detect the latter using the rule "body of the first 5 min bar is relatively small comparing to upper & lower wicks".

The overall logic here is that if gap was up and momentum is rolling on after 5 min we could jump in opening a long position
and then we are rolling on with an asset for some time until the momentum is exhausted. To achieve the latter, we need to implement a trailing stop loss. Once position is open, I am doing trailing stop loss (credit goes to John F and his post here.

The position is closed either when current price hits a trailing stop price (set to -5% of the highest price today) or, if position is held open until the last 5 min of a day, all positions will be closed 4 min before the market closes

Algo is generally working, however, something odd happens when I tested it with AAPL. Positions are often (not always) held over-night and/or not properly close (selling more than opened before resulting in exposure to short position over-night)

I think that my ordering management is poor or maybe some other errors too. Also, the commentators to the John F. post mentioned that one has to always check if there are unfilled orders every time when ordering again.

I would appreciate suggestions and/or code snippets to fix those things.

The algo and backtest are attached.

Clone Algorithm
1
Loading...
Backtest from to with initial capital
Total Returns
--
Alpha
--
Beta
--
Sharpe
--
Sortino
--
Max Drawdown
--
Benchmark Returns
--
Volatility
--
Returns 1 Month 3 Month 6 Month 12 Month
Alpha 1 Month 3 Month 6 Month 12 Month
Beta 1 Month 3 Month 6 Month 12 Month
Sharpe 1 Month 3 Month 6 Month 12 Month
Sortino 1 Month 3 Month 6 Month 12 Month
Volatility 1 Month 3 Month 6 Month 12 Month
Max Drawdown 1 Month 3 Month 6 Month 12 Month
# Backtest ID: 59563802cc255551de0753c6
There was a runtime error.
9 responses

Sometime orders fail or will be partially filled. You can see some logic to handle that in this post. I have updated it recently to cancel all open orders as well. You can run into the case of partial fills and you want to get out of the position but still have some open intra-day orders pending.

Thanks John. That's indeed helpful.

Updated with better order tracking including order cancellation.

Clone Algorithm
40
Loading...
Backtest from to with initial capital
Total Returns
--
Alpha
--
Beta
--
Sharpe
--
Sortino
--
Max Drawdown
--
Benchmark Returns
--
Volatility
--
Returns 1 Month 3 Month 6 Month 12 Month
Alpha 1 Month 3 Month 6 Month 12 Month
Beta 1 Month 3 Month 6 Month 12 Month
Sharpe 1 Month 3 Month 6 Month 12 Month
Sortino 1 Month 3 Month 6 Month 12 Month
Volatility 1 Month 3 Month 6 Month 12 Month
Max Drawdown 1 Month 3 Month 6 Month 12 Month
# Backtest ID: 5961494421f0506b5d0230c2
There was a runtime error.

John thanks a lot. I'll look into it. Am working on my momentum+trailing stop algo as well.

Hi Josh,

I backtested your algo since 2003-01-01.
Backtest ID: 597250440f65804e24174ec5

Looks interesting but largely behind the benchmark. It is in draw-down most of the time and psychologically it would mean untradability, it least for me. Pattern of clustering for good returns is as follows: very few events. In 2017 it was one biomedical stock HTMG which received EU licensing back in March
https://www.benzinga.com/trading-ideas/technicals/17/03/9213047/htg-molecular-diagnostics-up-nearly-400-in-2-days

Interesting that good return cluster around the beginning of long-term up-trends (yearly 2003 after the dot com bust and yearly in 2009 after the Great Recession downtrend). However, in the recent environment of uptrend we see better returns since 2015 which does not match this patter.

Overall, the algo has good snippets and approaches which are very helpful for me. Thanks.

See the original post link above. You definitely do NOT want to trade this. It is just to show the technique.

Yes, I read. I see. Thanks a lot for sharing this.

Dear John

Thanks for your MIT code. It was/is very helpful.

I ran into an issue with partial fill of orders when doing backtesting (I guess in the real trading one can order "fill or kill" order type but not in backtesting). I will try to place not default market orders, but rather limit orders with some 'breathing space' for order price to allow full fill. I have also read that some solutions are: (1) adjust trade size to available volume and (2) call cancel_order() function.

Any other ideas how to secure full order fill?

I tend limit shares ordered to 1% of the last 10 bar volume for these simple experiments. You likely will need an entirely different strategy to avoid partial fills/moving market on very large portfolios. Chunking up your orders over hours/days and tracking total shares acquired is a possibility.