Long post ahead. This algorithm is actually really simple in theory, but to get it to work effectively in practice, there are lots of other considerations that wasn't implemented yet. This algorithm has an enormous negative return. I used IB's RelativeOrder for this algorithm. On the API doc it says:
"When backtesting this order type, or forward-testing a
Quantopian-backed paper trading algorithm, the order is modeled as a
simple market order. It is only executed as a true RelativeOrder when
run with an IB-backed paper or real-money algorithm. "
What this did was reverse every single one of my orders causing the -4204.9% return. A consistent loser on every trade is just as difficult as a consistent winner barring transaction costs. Essentially, to be a consistent loser, you would have to "guess" in the wrong direction every single trade. In this algorithm, this is indeed the case because most of the losses are much much larger than the commission, meaning if every single one of the trade is reversed, this would actually have a positive return. Not only that, but with enough volume, the rebates would subsidize most of the commission.
Some possible improvements that could be implemented to make this algorithm competitive:
Model the optimal cash/inventory allocation to reduce the chances of unfavorable positions. For example, increase inventory when the price series is non-trending, and holding more in cash when it is trending. Also, how much cash vs inventory at the beginning of the day.
Model overnight risks; Hawke processes or Poisson jump processes could be used for frequency, not sure what distribution for severity of the jump. An alternative would be to reduce all inventory by the end of trading day, which might suffer some losses if there are people waiting purposely for this. VWAP could be useful, but it cuts into the time this algorithm is running.
Rewrite this algorithm in parallel, since it's difficult to set money aside for different stocks in serial; if you put 20% of your money already in AAPL, GOOG, MSFT, DAL, and suddenly WMT is the only stock that is nontrending, your algorithm is still allocating money for your 4 prior stocks and the money is essentially stuck with them.
Add in regime-switching provisions with regard to liquidity. This strategy is dependent on (il)liquidity to keep the spread high. Adjust inventory appropriately by using liquidity proxies.
Resolve the issue of bid-ask bounce. The current price is likely to be affected by this algorithm, and the bounce can lead to wrong calculations. The bounce, if happens too frequently due to this very algorithm, can make the price seem mean-reverting, causing even more trading, when in fact, the spread is actually thinning. Once liquidity thins too much, commissions will eat away the profits, causing drastic losses.
Slippage/opportunity cost. Here I used exclusively limit orders (which the API remodelled into market orders). It's entirely possible many of the orders don't get executed. Although opportunity cost is irrelevant because this only trades when the stock is comparatively nontrending, it is still a good idea to determine a distribution of limit order prices given the liquidity proxies. For example, for a "very liquid" stock, perhaps 95% of limit orders would be on the best bid/ask, and 4% would be 1 cent away, and 1% would be 2 cents away.
Instead of just using a simple moving average (which is in terms of days instead of minutes), use a better averaging method (for example, there's stochastic volatility, long-term volatility, take into account of autocorrelation, less relevance as you get closer to the present, volatility clustering etc.). Second/tick data would be useful too.
Watch out for hidden/iceberg orders. The orderbook might not show all the orders, causing some liquidity proxies to give a false indication. Save the already executed orders, and compare it daily to see if there's any disparity. Maybe ping the book with some orders and try to "echo" out the depth. Or treat the hidden orders as censored data, in which case, maximum likehood estimation can be used.