backtesting.py icon indicating copy to clipboard operation
backtesting.py copied to clipboard

Logging Orders

Open bscully27 opened this issue 4 years ago • 7 comments

Desired Behavior

To dig into each backtest order, specifically to evaluate target prices which I don't believe are working correctly or I'm not calling properly. Didn't see an example in the docs.

I tried adding self.orders to _broker.log but without success - the idea was use copy.copy(self.orders) in backtesting.py for a PIT (point in time) snapshot.

So 2 points I'd like addressed:

  1. How to properly set target prices.
  2. How to enhance the logs with more Order granularity.

Additional Log Attempt

In class _Broker.next(), I called this function when opening or closing a position.

for example in class _Broker.next():
        if entry or orders._close:
            self._update_order_log(self.orders, i)
where:
    def _update_order_log(self, order, i):
            self.log.order_info[i] = copy.copy(order)

then in class _Broker:

    class _Log:
        def __init__(self, length):
        ...
        self.order_info = {k: '' for k in range(length)}

Steps to Reproduce

class SmaCrossTarget(Strategy):
    def init(self):
        self.sma1 = self.I(SMA, self.data.Close, 2)
        self.sma2 = self.I(SMA, self.data.Close, 6)
        self.Close = self.data.Close
        
    def next(self):
        if (self.sma1[-2] < self.sma2[-2]  and  self.sma1[-1] > self.sma2[-1]):
            self.buy(tp=self.Close[-1]*1.05)
        elif (self.sma1[-2] > self.sma2[-2]  and  self.sma1[-1] < self.sma2[-1]):
            self.sell()

GOOG = GOOG.head(40)
bt = Backtest(GOOG, SmaCrossTarget, cash=1000, commission=.001)
result = bt.run()
result._trade_data.dropna(subset=['Entry Price']).head(3)
               Equity  Exit Entry  Exit Position  Entry Price  Entry Direction  Exit Price Exit Comment      P/L  Returns
2004-08-30 1,030.0300         nan            nan     105.2800          -1.0000         nan                   nan      nan
2004-09-09 1,021.8743      7.0000        -9.4890     102.5300           1.0000    102.5300          NaN  25.0957   0.0244
2004-09-28 1,154.8585     14.0000         9.9880     121.3000          -1.0000    121.3000          NaN 186.4511   0.1825

The 3rd line should have been closing the position when target_price was hit.

Additional info

  • Backtesting version: 0.1.6

bscully27 avatar Mar 22 '20 14:03 bscully27

Is the Entry Direction column not longer available ?

lkmh avatar Apr 18 '20 08:04 lkmh

This was overhauled in #47 (released in 0.2.0), rendering this issue obsolete.

The new way to access individual trades data is:

stats = bt.run()

stats._equity_curve  # equity/drawdown data
stats._trades        # trade data

kernc avatar Jul 15 '20 12:07 kernc

I'm curious about orders though, not trades.

bscully27 avatar Jul 17 '20 00:07 bscully27

@bscully27 You could always continue to log orders yourself: :grin:

class MyStrategy(Strategy):
    def init(self):
        self.orders_log = []
        ...

    def buy(self, *args, **kwargs):
        super().buy(*args, **kwargs)
        self.orders_log.append(self.orders[-1])

    def next(self):
        ...
        self.buy(...)

stats = Backtest(...).run()
orders_placed = stats._strategy.orders_log

kernc avatar Jul 17 '20 11:07 kernc

Is the Entry Direction column not longer available ?

@lkmh In fact, you can infer the Entry Direction with size column, if size > 0 Entry Direction is long otherwise is short.

albertwh1te avatar Sep 28 '20 02:09 albertwh1te

Dear author, the information about accessing individual trades and orders is very useful and even essential. Would you please make it easier to find? I mean, add this information into the manuals and examples.

When I tried the following code def buy(*args, **kwargs): super().buy(*args, **kwargs) self.orders_log.append(self.orders[-1])

I got an error

RuntimeError: super(): no arguments

I have found the solution here.

This works better: def buy(self, *args, **kwargs): super().buy(*args, **kwargs) self.orders_log.append(self.orders[-1])

s-kust avatar Nov 17 '20 13:11 s-kust

There's some new related discussion in https://github.com/kernc/backtesting.py/issues/197.

kernc avatar Dec 16 '20 06:12 kernc