-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
position.close() and stop loss features #1018
-
Hello all, I am fairly new to trading, backtesting and backtesting.py in general, I would like know more about two things:
- When you call
position.close()
after certain conditions are met, what exactly willposition.close()
do? - I am coding a ema crossover strategy for backtesting that implements both a stop loss and trailing stop loss and would like to know if this is a logical way to do it. I want to set my stop loss at 1RR and a trailing stop loss at a set percentage of the price. Here is what I have done:
`class EmaCross(Strategy):
#EMA candles
w1 = 5
w2 = 21
#Set stop loss and take profit percentage for long and short orders
stop_loss = 5
take_profit = 10
stop_loss_short = 4
take_profit_short = 8
#Modify indicators for strategies here
def init(self):
#Calculate two EMAs
self.ema1 = self.I(ta.EMA, self.data.Close, self.w1)
self.ema2 = self.I(ta.EMA, self.data.Close, self.w2)
#Calculate RSI
self.RSI = self.I(ta.RSI, self.data.Close)
#Define your strategy here
def next(self):
price = self.data.Close[-1]
riskpertrade = 0.03 * 1000000 #risk allowed * balance
takeprofit = price + price*self.take_profit/100
takeprofit_s = price - price*self.take_profit_short/100
stoploss = price - price*self.stop_loss/100
stoploss_s = price + price*self.stop_loss_short/100
#Order size can be negative (short), sell() won't take in negative values
order_size = abs(int(riskpertrade/(price - stoploss)))
order_size_s = abs(int(riskpertrade/(price - stoploss_s)))
if (crossover(self.ema1, self.ema2) and
self.RSI > 50):
self.position.close()
self.buy(tp = takeprofit,
sl = stoploss,
size = order_size)
elif (crossover(self.ema2, self.ema1) and
self.RSI < 50):
self.position.close()
self.sell(tp = takeprofit_s,
sl = stoploss_s,
size = order_size_s)`
Thank you in advance!
Beta Was this translation helpful? Give feedback.
All reactions
Hi,
Thank you for your explanation. I understood.
Your trailing stop is not working.
Once the order (buy or sell) is done, the stop loss of backtesting.py "sl" is not changed until the position is closed.
If you want to change the stop loss level to always be 5% of price.
You need to change the "sl" parametor of "trades".
https://kernc.github.io/backtesting.py/doc/backtesting/backtesting.html#backtesting.backtesting.Strategy.trades
Example
# set a pl/tp (trailing stop)
if len(self.trades) > 0 and self.trades[0].is_long:
self.trades[0].sl = price - price*self.stop_loss/100
self.trades[0].tp = price + price*self.stop_loss/100
elif len(self.trades) > 0 and self.trades[0].is_short:
...
Replies: 1 comment 7 replies
-
The answer to your question No1 is written below.
https://kernc.github.io/backtesting.py/doc/backtesting/backtesting.html#backtesting.backtesting.Position
https://kernc.github.io/backtesting.py/doc/backtesting/backtesting.html#backtesting.backtesting.Trade.close
"Place new order to close portion of the trade at next market price."
Beta Was this translation helpful? Give feedback.
All reactions
-
Thank you for your help! Have you got a chance to look at the code I have written? Logical wise, do you think that is the way to code what I want?
Thank you so much!
Beta Was this translation helpful? Give feedback.
All reactions
-
Hi,
It looks like there is no particular problem.
But I could't find "a trailing stop loss at a set percentage of the price" in your code.
Beta Was this translation helpful? Give feedback.
All reactions
-
Hi there,
Sorry for the confusion, I have set the stop loss and take profit percentage here:
stop_loss = 5 take_profit = 10 stop_loss_short = 4 take_profit_short = 8
And for the trailing:
stoploss = price - price*self.stop_loss/100 stoploss_s = price + price*self.stop_loss_short/100
I wrote this to set the stop loss to always be 5% of price. Do you think this is logically correct?
Beta Was this translation helpful? Give feedback.
All reactions
-
Hi,
Thank you for your explanation. I understood.
Your trailing stop is not working.
Once the order (buy or sell) is done, the stop loss of backtesting.py "sl" is not changed until the position is closed.
If you want to change the stop loss level to always be 5% of price.
You need to change the "sl" parametor of "trades".
https://kernc.github.io/backtesting.py/doc/backtesting/backtesting.html#backtesting.backtesting.Strategy.trades
Example
# set a pl/tp (trailing stop)
if len(self.trades) > 0 and self.trades[0].is_long:
self.trades[0].sl = price - price*self.stop_loss/100
self.trades[0].tp = price + price*self.stop_loss/100
elif len(self.trades) > 0 and self.trades[0].is_short:
self.trades[0].sl = price + price*self.stop_loss_short/100
self.trades[0].tp = price - price*self.stop_loss_short/100
*trades[0] can be trades[0] or trades[-] if the number of valid trades is 1.
def next(self):
price = self.data.Close[-1]
riskpertrade = 0.03 * 1000000 #risk allowed * balance
takeprofit = price + price*self.take_profit/100
takeprofit_s = price - price*self.take_profit_short/100
stoploss = price - price*self.stop_loss/100
stoploss_s = price + price*self.stop_loss_short/100
#Order size can be negative (short), sell() won't take in negative values
order_size = abs(int(riskpertrade/(price - stoploss)))
order_size_s = abs(int(riskpertrade/(price - stoploss_s)))
if len(self.trades) > 0 and self.trades[0].is_long:
self.trades[0].sl = price - price*self.stop_loss/100
self.trades[0].tp = price + price*self.stop_loss/100
elif len(self.trades) > 0 and self.trades[0].is_short:
self.trades[0].sl = price + price*self.stop_loss_short/100
self.trades[0].tp = price - price*self.stop_loss_short/100
if (crossover(self.ema1, self.ema2) and
self.RSI > 50):
self.position.close()
self.buy(tp = takeprofit,
sl = stoploss,
size = order_size)
elif (crossover(self.ema2, self.ema1) and
self.RSI < 50):
self.position.close()
self.sell(tp = takeprofit_s,
sl = stoploss_s,
size = order_size_s)`
But above example is not good.
Because, sl or tp are not compared to the current price.
*The trailing stop price should change in one direction (not increase or decrease)
A good example is listed below.
#238
price = self.data.Close[-1]
if buy_condition:
self.buy(sl=price*.99)
for trade in trades:
if price / trade.entry_price > 1.01: # Once profit is over >1%
trade.sl = max(trade.sl, price*.98) # "turn on" -2% trailing SL
This is simple, but very good example.
Sorry for the poor explanation.
Beta Was this translation helpful? Give feedback.
All reactions
-
Thank you for your explanation! I will make sure to implement this! Have a nice one!
Beta Was this translation helpful? Give feedback.
All reactions
-
And just a quick confirmation, when you said my example is not good since the sl and tp are not compared to the current price, I thought that by calculating SL and TP based on current price I have already compared them to the current price?
price = self.data.Close[-1]
stoploss = price - price*self.stop_loss/100
Is this not the correct way to write it?
Thank you for your quick responses!!
Beta Was this translation helpful? Give feedback.
All reactions
-
I'm sorry for confusing.
Your calculation of sl is not problem.
I should have comment "compared to the current tp/sl price" .
It's just my own opinion.
So, please ignore.
Thanks
Beta Was this translation helpful? Give feedback.