fastquant icon indicating copy to clipboard operation
fastquant copied to clipboard

[BUG] Execution price does not fit between High and Close

Open jbdelmundo opened this issue 3 years ago • 3 comments

Problem description

When setting custom buy/sell signals, the order was executed the following day. However the execution price was still based on the current day. The execution price can be impossible because it was trying to execute today's price that may not be available the following day.

dt open high low close entry_signal exit_signal type price
0 2017-01-03 00:00:00 730 733 722.5 727 1 0 nan nan
1 2017-01-04 00:00:00 735 760 735 760 0 0 buy 727
2 2017-01-05 00:00:00 767 790 760.5 790 0 0 nan nan
3 2017-01-06 00:00:00 780 794.5 780 786.5 0 0 nan nan
4 2017-01-09 00:00:00 786.5 790 770.5 784.5 0 0 nan nan
5 2017-01-10 00:00:00 787.5 797 784 793 0 1 nan nan
6 2017-01-11 00:00:00 794 797 787 796 0 0 sell 796
7 2017-01-12 00:00:00 796.5 799.5 790.5 793.5 0 0 nan nan
8 2017-01-13 00:00:00 793.5 797.5 790 792 0 0 nan nan
9 2017-01-16 00:00:00 795.5 795.5 773 786.5 0 0 nan nan

When the entry signal is generated at 2017-01-03, the closing price is 727 Then the order is executed the following day. However the price (727) is not within the bounds of high and low at 2017-01-04

Example

  • Use fastquant.indicators.custom.CustomIndicator for creating entry and exit signals
  • Create a custom strategy that uses the your custom entry and exit signals (example here: https://github.com/enzoampil/fastquant/blob/master/examples/2020-10-26-user_defined_strategy.ipynb)
  • Run backtest and merge the order history with the original data

Expected behavior

It can be modified in strategies/base.py by specifying the exectype here: https://github.com/enzoampil/fastquant/blob/94d938397b7ee61aa82bf0f72875d6499458200c/python/fastquant/strategies/base.py#L358

# Explicitly setting exectype=bt.Order.Close will make the next day's closing the reference price
                    self.order = self.buy(size=final_size, exectype=bt.Order.Close)

Environment

  • platform: Linux
  • fastquant version : commit: 94d938397b7ee61aa82bf0f72875d6499458200c ("Update setup version")
  • installation method: source

jbdelmundo avatar Jul 23 '21 11:07 jbdelmundo

Also, the size (or amount of shares) is determined on the day the signal is generated

However, if the size * price > cash, where price is based on the execution date and not on the signal day (exectype=bt.Order.Close), the buy order will fail (order.status == order.Margin)

This usually happens when BUY_PROP = 1

jbdelmundo avatar Jul 23 '21 14:07 jbdelmundo

@jbdelmundo what's your proposed fix?

jpdeleon avatar Dec 16 '21 08:12 jpdeleon

@jpdeleon in a recent PR, enzo and i were looking at the execution type and making the execution type bt.Close caused issues in intraday. Removing it has then fixed the problem.

By default it reverts to bt.Market which gets the close of the day the signal was created.

In line 496 here https://github.com/enzoampil/fastquant/pull/396/commits/329fb5e01678dd5dc8a45fef358e035b571dc611 the exectype=bt.Order.Close was removed

mikeejazmines avatar Dec 16 '21 08:12 mikeejazmines