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

order is removed due to no enough cash/margin, however, it's a sell order

Open zillionare opened this issue 3 years ago • 4 comments

Currently position is long and there's buy trade in queue:

<Trade size=476 time=7- price=21.0- pl=652>

Now a sell signal is triggerred, and a sell order is placed, however, the order is removed/cancelled in _process_orders due to no cash/margin:

图片

logger is added by me.

Since this is a sell order, why we need cash/margin?

Expected Behavior

if the order is for sell, we need to check if we hold long position; otherwise, check if cash is enough.

Actual Behavior

the sell order is discarded due to no cash/margin. Thus no more buy/sell even buy/sell signals are fired.

Steps to Reproduce

  1. trigger a long trade with size 0.9999
  2. trigger a sell order, see if it's placed

Additional info

  • Backtesting version: 0.3.1

zillionare avatar Apr 30 '21 10:04 zillionare

(I am not familiar with the codebase, I am a new user)

Since this is a sell order, why we need cash/margin?

Actually I think we need "some" cash as we need to pay a commission.

gaborvecsei avatar May 08 '21 15:05 gaborvecsei

The commission is already accounted for with spread at trade entry. If we're just selling (buying) some units we already have (owe), we should not be checking available cash.

kernc avatar May 09 '21 01:05 kernc

@kernc, just for the sake of my understanding:

  • When we are closing a position (selling), there is no commissions we need to pay?

I understand that there is a commission when we enter a trade (e.g. buy a stock), but we should also pay a commission when we are selling. At elast for Interactive Brokers, we pay commission when closing a position. (And as I know this is the same for most of the cases).

In theory I could not sell my shares on IB if I would not have enough money to pay the commission at "sell time".

gaborvecsei avatar May 09 '21 14:05 gaborvecsei

I understand that there is a commission when we enter a trade (e.g. buy a stock), but we should also pay a commission when we are selling. At elast for Interactive Brokers, we pay commission when closing a position. (And as I know this is the same for most of the cases).

Ah, this already came up in https://github.com/kernc/backtesting.py/issues/149. The idea then was to just pass Backtest(commission=2*real_commission), which is approximately valid for all but the instruments with very wide price fluctuation.

In theory I could not sell my shares on IB if I would not have enough money to pay the commission at "sell time".

I don't think that's correct. You pay the commission when and upon exchanging the asset for whatever it's priced.

kernc avatar May 09 '21 19:05 kernc

  • trigger a long trade with size 0.9999

  • trigger a sell order, see if it's placed

The recommended way of closing existing trades is via Strategy.trades[i].close() or Strategy.position.close().

Alternatively, if after the initial long trade you call self.sell(size=int(long_order_size)) (rather than the equity-relative size), the behavior is as expected.

kernc avatar Dec 13 '22 15:12 kernc