Dealing with unfilled stopped out positions in order to remain hedged

I submitted some testing long/short algos to the latest contest, just to see how the contest/paper trading works, and I was unpleasantly surprised that the algos don't have the 'Hedged' badge.

After closer inspection, it seems the reason they're not considered hedged, is that on some days they have 2 or 3 positions (out of 150 per side) left open because the stop order to liquidate all positions wasn't entirely filled before the end of the day. The stop order was placed a couple of hours after the open (I do this to reduce losses on days the algo is clearly wrong).

Is it really a big problem that a couple of one-sided positions remain open? And if so, any suggestions what to do about it? Is stop usage considered a bad idea for long/short algos?

4 responses

I'd take that as a signal that you're trading in stocks that are illiquid. If you have orders that are taking hours to fill, then you're trading in something that just doesn't trade that much.

In a technical sense, the hedged badge might be overly aggressive , but as a practical matter, it's doing the right thing - it's encouraging you to reconsider the risk of the positions your algorithm is taking on.

Have you tried limiting your algorithm to the Q1500? Anything in the Q1500 is going to close out positions relatively quickly.

Disclaimer

The material on this website is provided for informational purposes only and does not constitute an offer to sell, a solicitation to buy, or a recommendation or endorsement for any security or strategy, nor does it constitute an offer to provide investment advisory services by Quantopian. In addition, the material offers no opinion with respect to the suitability of any security or specific investment. No information contained herein should be regarded as a suggestion to engage in or refrain from any investment-related course of action as none of Quantopian nor any of its affiliates is undertaking to provide investment advice, act as an adviser to any plan or entity subject to the Employee Retirement Income Security Act of 1974, as amended, individual retirement account or individual retirement annuity, or give advice in a fiduciary capacity with respect to the materials presented herein. If you are an individual retirement or other investor, contact your financial advisor or other fiduciary unrelated to Quantopian about whether any given investment idea, strategy, product or service described herein may be appropriate for your circumstances. All investments involve risk, including loss of principal. Quantopian makes no guarantees as to the accuracy or completeness of the views expressed in the website. The views are subject to change, and may have become unreliable for various reasons, including changes in market conditions or economic circumstances.

I'm actually using the Q1500US, here's the filter:

    price_filter = USEquityPricing.close.latest >= 5
universe = (Q1500US() & price_filter)


The stop order fires 2 hours after market open, the positions are 1/300 * 10M = 33k each. The following warnings are in the log:

2017-09-28 22:00 WARN Your order for 1877 shares of PTCT failed to fill by the end of day and was canceled.
2017-09-27 22:00 WARN Your order for 147 shares of NDRM has been partially filled. 22 shares were successfully purchased. 125 shares were not filled by the end of day and were canceled.
2017-09-22 22:00 WARN Your order for -228 shares of NDRM has been partially filled. 166 shares were successfully sold. 62 shares were not filled by the end of day and were canceled.
2017-09-21 22:00 WARN Your order for 130 shares of NDRM failed to fill by the end of day and was canceled.
2017-09-21 22:00 WARN Your order for -855 shares of NDRM has been partially filled. 519 shares were successfully sold. 336 shares were not filled by the end of day and were canceled.
2017-09-20 22:00 WARN Your order for 2587 shares of CHRS has been partially filled. 2573 shares were successfully purchased. 14 shares were not filled by the end of day and were canceled.

Something strange is going on, since I'm seeing 15 open positions after close on a certain day, and the very first day starts with a 151/150 distribution of short/long positions (I requested 300 using the Optimize API).

Perhaps the code to liquidate all positions doesn't work correctly or something:

    def liquidate_all(context):
for psid, pos in context.portfolio.positions.iteritems():
order_target(psid, 0)


I'll have to do some further digging.

I apparently jumped to the wrong conclusion!

• PTCT had a very weird day on 9/28, and it looks like it didn't trade at all, so I can see why that one wouldn't fill that day.
• NRDM sure looks like it should have filled on those days, given enough minutes, so I can't explain that one with what I've seen so far.

Thanks for looking into it.

Here's what I found: apparently liquidity isn't as high as I expected, it takes on average 2 hours to purchase 10M worth of shares divided over 300 stocks, and sometimes a couple of stocks just don't make it and I'm left holding the bag.

The couple of stocks I was left with each day after a stop was triggered, were the result of some orders still being live and me trying to liquidate all positions without first cancelling all open orders.

Anyway, even after properly taking care of open orders I'm still left with the occasional single long or short position after close when I try to liquidate all assets 2 hours after the open. I guess there's not much to be done, except maybe buying more stocks.

BTW here's another order that didn't fill even though the stock does seem to have traded that day (this is with volume_limit=1):

2017-09-11 22:00 WARN Your order for -819 shares of KNX failed to fill by the end of day and was canceled.

So daily re-balancing seems to be a tricky thing; even if you don't use stops and just place a portfolio order at the open, you can still miss a substantial part of the price movement. (which wouldn't be obvious when looking at 1 day alpha using e.g. AlphaLens)