We were backtesting a Channel-Breakout strategy for a customer for some time on Tradingview and later in NinjaTrader 8. The backtesting results on both platforms were very promising, specifically for lower Minute timeframes, e.g. 1min. The Channel-Breakout strategy is using Market orders for entering long and short positions; the strategy is always in a trade all the time.
The Strategy was actually losing money!
While live-trading on BitMEX via NinjaTrader 8 the chart entry and exit points still looked good, however the daily trading results in BitMEX showed a different picture; basically the strategy was losing every day a bit of the account money on BitMEX. The key factor which we were not considering were the trading fees at BitMEX. It differentiates between Taker-Fees for Market Orders and Maker-Fees for Limit Orders (fee structure explained here). The Taker-Fee is 0.075% of the traded value, so if using a higher margin value this fee increases accordingly. Using Market Orders for entering a long position and exiting the same position adds up to 0.15% of the whole trading value. In clear text, the strategy has to gain at least 0.15% to breakeven before even make a single cent. This is the critical part if using a scalping strategy for lower Minute timeframes. The strategy typically made 60-70% positive trades, which were mostly in the 0.1..0.2% effective gain area, so finally including the BitMEX fees the strategy effectively was losing money.
How to run a scalping strategy in BitMEX and not losing money?
Use Limit orders wherever possible! BitMEX pays a Maker-Fee of 0.025% for using Limit Orders, which are contributing to make the market for BitMEX. By using Limit Orders, a strategy using this order type only could add 0.05% of the order value to its balance sheet for every trade (enter and exit).
This is unfortunately not always that simple. The Channel-Breakout strategy does not work well using a Stop-Limit Order instead of a Stop-Market Order for entering the market. The limit order gets simply executed too late – typically then, if the market has turned again and instead of being in a delayed long position the strategy should be in a short position. The solution was to use Market Orders for entering a position and pay the 0.075% fee and use Limit-Orders for existing a position if a certain profit target has been reached. So finally the strategy paid additional 0.075% for entering a position and got 0.025% back when exiting. This finally reduced the trading fees by two-third from 0.15% to 0.05% (0.075%-0.025%), which finally made the trades profitable including the gain and fees.
Implementation
The strategy is using the BitMEX NinjaTrader 8 adapter for accessing the data feed. Unfortunately this adapter does not support any trading functions.
For submitting orders, we have added our own C# BitMEX Trading API, which is accessing the BitMEX REST API. This API supports the basic functions for submitting market/limit and stop orders, and has a function to request the current order status. The order status is available inside the NinjaTrader 8 strategy, similar to a “unmanaged” Ninjatrader 8 strategy. The order status has to be retrieved from BitMEX asynchronously from within the strategy, as the REST API is poll-based. This is realized as a timer callback inside the NinjaTrader 8 strategy, which pulls the status of all orders every 2seconds. The frequency for pulling the order status can be configured; clearly someone needs to pay attention to the BitMEX API rate-limit, which allows roughly 1 request in average per second.
This solution works quite nice, but it’s a good approach to implement the strategy in a way to submit orders as limit or stop-market orders ahead. Because BitMEX API is notorious for being not accessible in case of strong up or down trends, where their server seems to reach their limits.
Questions & Contact
Please contact us know if you are interested in using this API, or if you are interested in the implementation of a similar strategy.