umop
umop

Reputation: 2192

Issue with Matching Order IDs in TradingView's Pine Script

Update:

I managed to simplify this so I can paste a whole snippet to reproduce this problem. This script, when run on ETHUSDT.P for Binance in Trading View Strategy Tester using the 15 minute chart (important because the timestamps will fail otherwise):

//@version=5
strategy("Multiple Positions Strategy", overlay=true, pyramiding=2)

if timestamp("2023-06-10T11:00:00-07:00") <= time_close and time_close < timestamp("2023-06-10T11:15:00-07:00")
    strategy.entry('id1', strategy.long, 1)
if timestamp("2023-06-10T11:00:00-07:00") <= time_close and time_close < timestamp("2023-06-10T11:15:00-07:00")
    strategy.exit('id1', 'id1', limit = 1763)
if timestamp("2023-06-11T09:00:00-07:00") <= time_close and time_close < timestamp("2023-06-11T09:15:00-07:00")
    strategy.entry('id2', strategy.long, 1)
if timestamp("2023-06-11T09:00:00-07:00") <= time_close and time_close < timestamp("2023-06-11T09:15:00-07:00")
    strategy.exit('id2', 'id2', limit = 1751)

Will cause the following to show in the List of Trades tab:

Trade # Type Signal
2 Exit Long id1
Entry Long id2
1 Exit Long id2
Entry Long id1

Even though both trades are wins, the strategy tester will show that the first trade is a loss (-0.48%) and the second is a larger win (1.31%) than I believe it was. This can especially affect drawdown unfairly, so it's a problem even if the overall PnL might be accurate.

Previous question:

I am experiencing an issue with pinescript in trading view's strategy tester where my trades are getting mixed up due to order ids not matching as expected. Here's the "list of trades"

Trade #1
Type: Entry Long
Signal: Long Trade 770
Type: Exit Long
Signal: Exit Long 772

Trade #2:
Type: Entry Long
Signal: Long Trade 772
Type: Exit Long
Signal: Exit Long 787

Trade #3:
Type: Entry Long
Signal: Long Trade 787
Type: Exit Long
Signal: Open

note that the trades should actually occur in the order (and this is reflected in the strategy tester overview):

Enter long #770
Enter long #772
Exit long #772
Enter long #778
Exit long #778
(#770 never exits because limit is never reached)

My understanding is that the entry and exit ids should match for each trade. However, as seen above, the exit for trade #1 has the same id as the entry for trade #2, which seems to be causing some confusion.

Here is the relevant part of my code:


//@version=5
strategy(title = 'My Signal', shorttitle='MY_MAIN', overlay=true, max_bars_back=300,max_boxes_count=500, max_lines_count=500, max_labels_count=500, pyramiding=5000)

...

if (bar_index == 787 or bar_index == 770 or bar_index == 772)
    if (myCondition) // Defined above this snippet
        candleHigh := open
        exitLongLine := line.new(x1=bar_index, y1=candleHigh, x2=bar_index+1, y2=candleHigh, color=color.red, width = 1)
        strategy.entry("Long Trade " + str.tostring(bar_index), strategy.long)
        strategy.exit("Exit Long " + str.tostring(bar_index), "Long Trade " + str.tostring(bar_index), limit=candleHigh)

Based on the Pine Script v5 documentation for strategy.exit() and strategy.entry(), I am under the impression that the from_entry parameter in strategy.exit() should match the id of the corresponding strategy.entry() call. However, this does not seem to be the case in my script.

While the visual appears to be correct, the net profits are incorrect (consistent with the incorrect list of trades.

Can anyone help me understand what might be causing this discrepancy, and how to ensure the correct matching of trade entry and exit ids?

Addition:

I tried a more understandable example using the first few candles which match. The reason I'm filtering out only certain ids is because I want to simplify it for purposes of troubleshooting, but the same issue shows up when I don't filter:

Here, I filter only 19, 20, 21, and 36:

Trade # Type Signal
4 Exit Short ShortTrade21
Entry Short ShortTrade32
3 Exit Short ShortTrade32
Entry Short ShortTrade21
2 Exit Long ShortTrade21
Entry Long LongTrade20
1 Exit Long LongTrade20
Entry Long LongTrade19

However, when I precede each entry with a

        strategy.close_all()

Then I get something more expected:

Trade # Type Signal
4 Exit Short ShortTrade32
Entry Short ShortTrade32
3 Exit Short Close Position Order
Entry Short ShortTrade21
2 Exit Long LongTrade20
Entry Long LongTrade20
1 Exit Long Close Position Order
Entry Long LongTrade19

The full code looks like this:

bool longCondition = ...
bool shortCondition = ...

if (bar_index == 19 or bar_index == 20 or bar_index == 21 or bar_index == 32)
    if (longCondition)
        redCandleHigh := open
        trade_id := "LongTrade" + str.tostring(bar_index)
        strategy.close_all() // <-- Maybe
        strategy.entry(trade_id, strategy.long)
        strategy.exit(trade_id, trade_id, limit=candleHigh)
    else if (shortCondition)
        greenCandleLow := open
        trade_id := "ShortTrade" + str.tostring(bar_index)
        strategy.close_all() // <-- Maybe
        strategy.entry(trade_id, strategy.short)
        strategy.exit(trade_id, trade_id, limit=candleLow)

if (barstate.islast)
    strategy.close_all()

Thanks!

Upvotes: 1

Views: 698

Answers (2)

t0m3
t0m3

Reputation: 36

add close_entries_rule="ANY" to your strategy

@version=5
strategy("Multiple Positions Strategy", pyramiding=2, close_entries_rule="ANY")

to close relative entry from

Upvotes: 0

G.Lebret
G.Lebret

Reputation: 3108

Here is what happen with your code :

if (bar_index == 19 or bar_index == 20 or bar_index == 21 or bar_index == 32)
    if (longCondition)
        redCandleHigh := open
        trade_id := "LongTrade" + str.tostring(bar_index)
        strategy.close_all() // <-- Maybe
        strategy.entry(trade_id, strategy.long)
        strategy.exit(trade_id, trade_id, limit=candleHigh)

You are at bar_index == 19 and your longCondition == true :
So you will have a strategy.entry named LongTrade19
And a strategy.exit named LongTrade19
Only the strategy.entry is executed : you see Entry Long LongTrade19

Then you are at bar_index == 20 and your longCondition == true :
So you will have a strategy.entry named LongTrade20
And a strategy.exit named LongTrade20
The strategy.entry and strategy.exit are executec : you see, on the same candle your exit and entry for LongTrade20

In fact in your first array in your 'Addition' part, you misinterpret when your orders are executed, you should consider this :

Trade # Type Signal
4 Exit Short ShortTrade32
Entry Short ShortTrade32
3 Exit Short ShortTrade21
Entry Short ShortTrade21
2 Exit Long LongTrade20
Entry Long LongTrade20
1 - -
Entry Long LongTrade19

EDIT :
this part of your code :

if (barstate.islast)
    strategy.close_all()

will close all your trade at each end of the bar !

Upvotes: 0

Related Questions