vectorbt
vectorbt copied to clipboard
Bug: Stop loss results is very largely different between from_signals(sl_stop=0.1) and generate_ohlc_stop_exits(sl_stop=0.1)
I'm trying to compare the stop loss mechanisms implemented with different ways such as model 1: from_signals(sl_stop=0.1, sl_trail=False), model 2: generate_ohlc_stop_exits(sl_stop=0.1, sl_trail=False) and model 3: vbt.OHLCSTX.run(sl_stop=[0.1]).
I found that model 2 and model 3 gave the exact same results (i.e., total return=459.05%) , but for model 1, the results are very different (i.e., total return = 47.47%) as displayed below:
Model 1: from_signals(sl_stop=0.1, sl_trail=False)
Model 2: generate_ohlc_stop_exits(sl_stop=0.1, sl_trail=False)
Model 3: vbt.OHLCSTX.run(sl_stop=[0.1])
Is it a bug? Or is it my implementation error? And btw, here is where I got the reference from: https://github.com/polakowo/vectorbt/issues/181
Below are the codes for these 3 models:
Model 1: Using from_signals(sl_stop=0.1, sl_trail=False)
# Reference: stop exits with RANDENEX indicator: https://github.com/polakowo/vectorbt/issues/181
import vectorbt as vbt
ohlcv = vbt.YFData.download(
"BTC-USD",
start='2017-01-01 UTC',
end='2020-01-01 UTC'
).concat()
# Random enter signal generator based on the number of signals.
rand = vbt.RAND.run(ohlcv["Close"].shape, n=10, seed=42)
# Random exit signal generator based on the number of signals.
randx = vbt.RANDX.run(rand.entries, seed=42)
pf1 = vbt.Portfolio.from_signals(ohlcv["Close"],
rand.entries,
randx.exits,
open=ohlcv["Open"],
high=ohlcv["High"],
low=ohlcv["Low"],
sl_stop=0.1,
sl_trail=False,
)
pf1.stats()
Model 2: Using generate_ohlc_stop_exits(sl_stop=0.1, sl_trail=False)
import vectorbt as vbt
ohlcv = vbt.YFData.download(
"BTC-USD",
start='2017-01-01 UTC',
end='2020-01-01 UTC'
).concat()
# Random enter signal generator based on the number of signals.
rand = vbt.RAND.run(ohlcv["Close"].shape, n=10, seed=42)
# Random exit signal generator based on the number of signals.
randx = vbt.RANDX.run(rand.entries, seed=42)
stop_exits = rand.entries.vbt.signals.generate_ohlc_stop_exits(
open=ohlcv["Open"],
high=ohlcv['High'],
low=ohlcv['Low'],
close=ohlcv['Close'],
sl_stop=0.1,
sl_trail=False,
)
exits = randx.exits.vbt | stop_exits # optional: combine exit signals such that the first exit of two conditions wins
entries, exits = rand.entries.vbt.signals.clean(exits) # optional: automatically remove ignored exit signals
pf2 = vbt.Portfolio.from_signals(ohlcv['Close'], entries, exits,
open=ohlcv["Open"],high=ohlcv["High"],
low=ohlcv["Low"])
pf2.stats()
Model 3: Using vbt.OHLCSTX.run(sl_stop=[0.1])
import numpy
import vectorbt as vbt
ohlcv = vbt.YFData.download(
"BTC-USD",
start='2017-01-01 UTC',
end='2020-01-01 UTC'
).concat()
# Random enter signal generator based on the number of signals.
rand = vbt.RAND.run(ohlcv["Close"].shape, n=10, seed=42)
# Random exit signal generator based on the number of signals.
randx = vbt.RANDX.run(rand.entries, seed=42)
stops = [0.1,]
sl_exits = vbt.OHLCSTX.run(
rand.entries,
ohlcv['Open'],
ohlcv['High'],
ohlcv['Low'],
ohlcv['Close'],
sl_stop=list(stops),
stop_type=None,
stop_price=None
).exits
exits = randx.exits.vbt | sl_exits
pf3 = vbt.Portfolio.from_signals(ohlcv['Close'], rand.entries, exits) # with SL
pf3.stats()
The model 1 and 2 & 3 (they are the same thing) differ in only one thing: 1 executes orders using the hit price, and 2 & 3 execute orders using the close price. You can make model 1 execute stops using close as well by providing a proper stop_exit_price, or you can extract the hit price when working with models 2 & 3 and use it as order price to match the first model.
so, is it possible to change it to trade on next open price instead of current close price?
This issue is stale because it has been open for 90 days with no activity.
This issue was closed because it has been inactive for 14 days since being marked as stale.