el5
el5

Reputation: 13

Am I misunderstanding how strategy.close() works?

I am having some trouble understanding the expected behavior of strategy.close().

After some testing/debugging of a very basic strategy, it seems that entries with strategy.entry() are ok and are executed at the next bar open, but with strategy.close(), the exits are happening on the bar where the exit condition is met, but they're happening as a market order at the open of that same bar instead of at the open of the next bar (which is actually what I was expecting with "process_orders_on_close = false") or even at the close of the current bar where the exit condition is met.

Can someone please explain if what I describe above is what is expected of strategy.close() or am I missing a setting or variable somewhere?

I am including my test strategy code below and a screenshot. It's not meant to be profitable or anything, just a demonstration of the issue.

Strategy summary:

I have added some debugging with plotshape() to understand where trades are being opened and closed.

I plot up triangles at the bottom when the long condition is met, and a trade is indeed entered on the next bar following the first triangle occurrence in each up triangle sequence below the candles.

I plot down triangles at the top when the exit condition is met, but here we observe that, although the exit condition is met at the candle where it is satisfied, we also see that the trade is closed at the open of that same candle used to evaluate the condition, before the information could technically be available. But the strategy tester is using it.

I also tried both "process_orders_on_close = true" and "process_orders_on_close = false", but this just shifts entries and exits by one bar and doesn't fix the issue.

//@version=5
strategy("test strategy", overlay=true, initial_capital = 10000)

// limit strategy time window
start = 0
finish = 0
start  := input.time(timestamp('01 Jan 2000'), title='      ‣   From')
finish := input.time(timestamp('01 Apr 2024'), title='      ‣   To')
window() =>
    time >= start and time <= finish ? true : false


o = open
h = high
l = low
c = close


activeTrade = false
longEntry = false
// Enter long when current close < previous low and no trade is active
if window() and (activeTrade == false ) and ( c < l[1] )
    longEntry := true
    activeTrade := true
// Exit long when currect close is above previous high and trade is active
if window() and (activeTrade == true ) and ( c > h[1] )
    longEntry := false
    activeTrade := false


if longEntry == true
    strategy.entry("Long", direction=strategy.long)
if longEntry == false
    strategy.close("Long")  //immediate market close


plotshape(longEntry, style=shape.triangleup, location=location.bottom, color=color.green)
plotshape(c > h[1], style=shape.triangledown, location=location.top, color=color.red)

Dates where we can observe this using SPX on a daily timeframe:

enter image description here

Upvotes: 1

Views: 250

Answers (1)

vitruvius
vitruvius

Reputation: 21294

Your understanding and the way you are trying to debug it are correct but you just need to be a little bit more careful.

Your whole market orders depend on one variable only. And that is longEntry. If it is true, you place your entry order. If it is false you place your exit order. That's it. So, you just need to see what it is doing.

Whenever you don't see a triangle, it places the exit order.

enter image description here

There is no need to complicate things and you can use the built-in variables such as strategy.position_size to do the same thing.

strategy.position_size

Direction and size of the current market position. If the value is > 0, the market position is long. If the value is < 0, the market position is short. The absolute value is the number of contracts/shares/lots/units in trade (position size).

You can write the same strategy as below:

time_cond = (time >= start and time <= finish)
entry_cond = time_cond and (strategy.position_size == 0) and (close < low[1])
exit_cond = time_cond and (strategy.position_size > 0) and (close > high[1])

if (entry_cond)
    strategy.entry("Long", direction=strategy.long)
if (exit_cond)
    strategy.close("Long")  //immediate market close

Upvotes: 1

Related Questions