I'm trying to create a strategy that keeps a separate stop loss for each entry. To achieve this, I append consecutive numbers to each entry name.
Here's an example strategy:
//@version=5
strategy(title="Example Strategy", overlay=true, pyramiding=5)
// Entries storage.
var longId = 1
var longs = array.new<string>()
// These are just for the sake of creating a reasonable number of entries for the testing.
// They shouldn't matter for the problem itself.
backtestStartDate = timestamp("1 Jan 2020")
backtestEndDate = timestamp("1 Jan 2021")
inTradeWindow = time >= backtestStartDate and time < backtestEndDate
var currentOrder = 1
var ordersLimit = 5
var barsBetweenEntries = 5
var barsSinceLastEntry = barsBetweenEntries
// -----------------------------------------------------
if inTradeWindow
if currentOrder <= ordersLimit and barsSinceLastEntry == barsBetweenEntries
stopLossPrice = low*0.8
entryName = "LE#" + str.tostring(longId)
strategy.entry(entryName, strategy.long)
strategy.exit(entryName + "#SL", from_entry=entryName, stop=stopLossPrice)
log.info("Entry " + entryName + " @ " + str.tostring(close) + ", SL " + str.tostring(stopLossPrice))
longs.push(entryName)
longId += 1
currentOrder += 1
barsSinceLastEntry := 0
else
barsSinceLastEntry += 1
else if inTradeWindow[1]
strategy.cancel_all()
strategy.close_all(comment="Date Range Exit")
Here's the log for BTCUSDT 1D:
[2020-01-01T01:00:00.000+01:00]: Entry LE#1 @ 7200.85, SL 5740.12
[2020-01-07T01:00:00.000+01:00]: Entry LE#2 @ 8145.28, SL 6178.968
[2020-01-13T01:00:00.000+01:00]: Entry LE#3 @ 8110.34, SL 6444.712
[2020-01-19T01:00:00.000+01:00]: Entry LE#4 @ 8701.7, SL 6772.8
[2020-01-25T01:00:00.000+01:00]: Entry LE#5 @ 8340.58, SL 6603.92
And here's the chart for BTCUSDT 1D:
In "List of Trades" panel, I get the following trades:
As you can see, stop losses are all over the place: reaching LE#4#SL closes LE#1, reaching LE#5#SL closes LE#2 etc.
I assume it has something to do with pyramiding since such issues could not occur with only one trade at a time.
I have no idea what might be causing this. I thought these two lines should keep the connection between an entry and its stop loss:
strategy.entry(entryName, strategy.long)
strategy.exit(entryName + "#SL", from_entry=entryName, stop=stopLossPrice)
Clearly, this is not the case so I must be missing something.
Also, in my actual strategy I had the same problem when stop losses were called on different bars (in the test above, they are all called on the same bar).
You are on the right track. If you want to close trades individually, you need to specify individual trade ids.
However, by default, the trades will be closed on FIFO based. You need to set close_entries_rule
parameter of strategy()
to "ANY"
.
Then all you need to do is make sure you areusing the correct trade ids for from_entry
of strategy.exit()
.
close_entries_rule (const string) Determines the order in which trades are closed. Possible values are: "FIFO" (First-In, First-Out) if the earliest exit order must close the earliest entry order, or "ANY" if the orders are closed based on the from_entry parameter of the strategy.exit function. "FIFO" can only be used with stocks, futures and US forex (NFA Compliance Rule 2-43b), while "ANY" is allowed in non-US forex. Optional. The default is "FIFO".