Problem with crossovers
-
I have an EMA set to 8 periods and another at 21 periods. I have setup a log that records the date at which the crossovers happened.
The issue is sometimes it gives the correct date of crossover and sometimes it give a wrong date (off by one day). Can this be rectified?? Or is there a way to get the correct date of crossover??
Help will be appreciated.
-
Can you please provide your logging code? Thanks.
-
Please provide script and outputs confirming behavior described.
-
@run-out same time :)
-
def log(self, txt, dt=None): date = date or self.data.datetime[0] if isinstance(date, float): date = bt.num2date(date) print("%s, %s" % (date.date(), txt))
-
That's just the log to print. Where to you capture the crossover and send it to the log?
-
This is the entire next function that I have in place.
I save the date of the crossovers in the crossovers list.
Then I compare the dates stored in the crossovers list with the plot and some dates stored are on point but some dates gets registered as a crossover at the date of next candlestick.def next(self): self.index.append(bt.num2date(self.data.datetime[0]).date()) self.equity.append(cerebro.broker.getvalue()) self.print_signal() if self.altering_params['entry_condition'] == 'Open': # price_array = self.data.Open price_array = self.datas[0].open elif self.altering_params['entry_condition'] == 'High': # price_array = self.data.High price_array = self.datas[0].high elif self.altering_params['entry_condition'] == 'Low': # price_array = self.data.Low price_array = self.datas[0].low elif self.altering_params['entry_condition'] == 'Close': # price_array = self.data.Close price_array = self.datas[0].close try: self.recentLow = min(self.data.low.get(size=self.LookBack+1)[:self.LookBack]) self.lows.append(self.recentLow) self.recentHigh = max(self.data.high.get(size=self.LookBack+1)[:self.LookBack]) self.highs.append(self.recentHigh) except Exception as e: print(e) if cerebro.broker.getvalue() < self.maintanance_margin: pass # pending opening orders do nothing # if len(self.o_li) > 0: # return if self.crossover == 1: if self.buy_sell_request_made and exit_at_crossover: self.close() price = price_array[0] for low in self.lows[::-1]: if price > low: stop_loss = low break print("------------------------------") print(" FAST MA CROSSES OVER SLOW MA ") print("------------------------------") self.crossovers.append(self.datetime.date()) take_profit = price + self.altering_params['pips_profit_loss']/10000 # for order in self.pending_orders: # self.cancel(order) # self.pending_orders = [] if not exit_at_crossover: self.long_buy_order = self.buy_bracket( exectype=bt.Order.Stop, price=price, stopprice=stop_loss, stopexec=bt.Order.Stop, limitprice=take_profit, limitexec=bt.Order.Limit) else: self.long_buy_order = self.buy( exectype=bt.Order.Stop, price=price) self.buy_sell_request_made = True if isinstance(self.long_buy_order,list): self.pending_orders = self.pending_orders + self.long_buy_order self.log( "LONG BUY at market {}: Oref {} / Buy at {} / Stop loss at {} / Take Profit at {}".format( self.datetime.date(), self.long_buy_order[0].ref, price, stop_loss, take_profit )) else: self.pending_orders.append(self.long_buy_order) self.log( "LONG BUY at market {}: Oref {} / Buy at {} / Stop loss at {} / Take Profit at {}".format( self.datetime.date(), self.long_buy_order.ref, price, stop_loss, take_profit )) # Store orders in a list else: pass if self.crossover == -1: if self.buy_sell_request_made and exit_at_crossover: self.close() price = price_array[0] # price = self.data.Close[-1] for high in self.highs[::-1]: if price < high: stop_loss = high break print("------------------------------") print(" SLOW MA CROSSES OVER FAST MA ") print("------------------------------") self.crossovers.append(self.datetime.date()) take_profit = price - self.altering_params['pips_profit_loss']/10000 # for order in self.pending_orders: # self.cancel(order) # self.pending_orders = [] if not exit_at_crossover: self.short_sell_order = self.sell_bracket( exectype=bt.Order.Stop, price=price, stopprice=stop_loss, stopexec=bt.Order.Stop, limitprice=take_profit, limitexec=bt.Order.Limit ) else: self.short_sell_order = self.sell( exectype=bt.Order.Stop, price=price ) if isinstance(self.short_sell_order,list): self.pending_orders = self.pending_orders + self.short_sell_order self.log( "SHORT SELL at market {}: Oref {} / Sell at {} / Stop Loss at {} / Take Profit at {}".format( self.datetime.date(), self.short_sell_order[0].ref, price, stop_loss, take_profit ) ) else: self.pending_orders.append(self.short_sell_order) self.log( "SHORT SELL at market {}: Oref {} / Sell at {} / Stop Loss at {} / Take Profit at {}".format( self.datetime.date(), self.short_sell_order.ref, price, stop_loss, take_profit ) ) self.trades_occured = True # Store orders in a list else: pass
I might sound foolish but I have a theory to what might be happening.
I think the crossover in backtrader works like this - if the crossover has occurred at or before the horizontal center of the candlestick then the date is right on point , but if the crossover has occurred after the horizontal center and before the end of a particular candlestick then it considers the next date as the Crossover date.
-
Thank you for posting the extra code. Could you also post the self.crossover creation you made? Thanks.
-
[datetime.date(1991, 10, 30), datetime.date(1992, 1, 15), datetime.date(1992, 2, 5), datetime.date(1992, 2, 11), datetime.date(1992, 3, 30), datetime.date(1992, 4, 15), datetime.date(1992, 5, 4), datetime.date(1992, 9, 13), datetime.date(1992, 9, 29), datetime.date(1992, 10, 8), datetime.date(1992, 12, 13), datetime.date(1993, 1, 3), datetime.date(1993, 1, 24), datetime.date(1993, 1, 31), datetime.date(1993, 2, 23), datetime.date(1993, 2, 24), datetime.date(1993, 3, 22), datetime.date(1993, 5, 11), datetime.date(1993, 5, 30), datetime.date(1993, 6, 3), datetime.date(1993, 8, 8), datetime.date(1993, 8, 9), datetime.date(1993, 8, 15), datetime.date(1993, 10, 18), datetime.date(1994, 2, 15), datetime.date(1994, 4, 5), datetime.date(1994, 4, 20), datetime.date(1994, 6, 6), datetime.date(1994, 6, 12), datetime.date(1994, 7, 27), datetime.date(1994, 8, 10), datetime.date(1994, 8, 29), datetime.date(1994, 9, 4), datetime.date(1994, 11, 9), datetime.date(1995, 1, 8), datetime.date(1995, 5, 10), datetime.date(1995, 5, 28), datetime.date(1995, 6, 5), datetime.date(1995, 6, 8), datetime.date(1995, 7, 11), datetime.date(1995, 7, 12), datetime.date(1995, 7, 16), datetime.date(1995, 7, 18), datetime.date(1995, 8, 3), datetime.date(1995, 9, 20), datetime.date(1995, 11, 12), datetime.date(1995, 11, 13), datetime.date(1995, 11, 26), datetime.date(1996, 2, 15), datetime.date(1996, 3, 3), datetime.date(1996, 6, 12), datetime.date(1996, 9, 5), datetime.date(1996, 10, 27), datetime.date(1996, 11, 26), datetime.date(1997, 3, 26), datetime.date(1997, 4, 6), datetime.date(1997, 5, 8), datetime.date(1997, 6, 1), datetime.date(1997, 8, 24), datetime.date(1997, 10, 21), datetime.date(1997, 10, 26), datetime.date(1997, 11, 24), datetime.date(1998, 1, 26), datetime.date(1998, 1, 28), datetime.date(1998, 2, 4), datetime.date(1998, 2, 5), datetime.date(1998, 2, 23), datetime.date(1998, 2, 24), datetime.date(1998, 3, 3), datetime.date(1998, 3, 30), datetime.date(1998, 4, 8), datetime.date(1998, 6, 9), datetime.date(1998, 7, 15), datetime.date(1998, 8, 13), datetime.date(1998, 8, 27), datetime.date(1998, 10, 29), datetime.date(1998, 12, 7), datetime.date(1999, 1, 8), datetime.date(1999, 5, 7), datetime.date(1999, 5, 14), datetime.date(1999, 7, 21), datetime.date(1999, 8, 18), datetime.date(1999, 8, 19), datetime.date(1999, 8, 23), datetime.date(1999, 9, 2), datetime.date(1999, 9, 10), datetime.date(1999, 9, 29), datetime.date(1999, 10, 27), datetime.date(2000, 1, 3), datetime.date(2000, 1, 17), datetime.date(2000, 2, 22), datetime.date(2000, 2, 25), datetime.date(2000, 3, 26), datetime.date(2000, 3, 28), datetime.date(2000, 5, 26), datetime.date(2000, 6, 25), datetime.date(2000, 6, 29), datetime.date(2000, 7, 13), datetime.date(2000, 9, 27), datetime.date(2000, 10, 6), datetime.date(2000, 11, 3), datetime.date(2000, 11, 17), datetime.date(2000, 11, 30), datetime.date(2001, 1, 24), datetime.date(2001, 2, 4), datetime.date(2001, 2, 7), datetime.date(2001, 3, 2), datetime.date(2001, 3, 14), datetime.date(2001, 4, 22), datetime.date(2001, 4, 30), datetime.date(2001, 6, 26), datetime.date(2001, 6, 28), datetime.date(2001, 7, 15), datetime.date(2001, 9, 5), datetime.date(2001, 9, 11), datetime.date(2001, 10, 11), datetime.date(2001, 12, 2), datetime.date(2001, 12, 24), datetime.date(2002, 1, 2), datetime.date(2002, 1, 15), datetime.date(2002, 2, 19), datetime.date(2002, 2, 20), datetime.date(2002, 2, 24), datetime.date(2002, 2, 25), datetime.date(2002, 3, 7), datetime.date(2002, 3, 28), datetime.date(2002, 4, 3), datetime.date(2002, 7, 30), datetime.date(2002, 8, 30), datetime.date(2002, 9, 10), datetime.date(2002, 9, 24), datetime.date(2002, 9, 25), datetime.date(2002, 9, 29), datetime.date(2002, 10, 17), datetime.date(2002, 10, 30), datetime.date(2002, 11, 25), datetime.date(2002, 12, 6), datetime.date(2003, 3, 17), datetime.date(2003, 3, 31), datetime.date(2003, 4, 6), datetime.date(2003, 4, 14), datetime.date(2003, 6, 22), datetime.date(2003, 7, 25), datetime.date(2003, 7, 31), datetime.date(2003, 9, 9), datetime.date(2003, 10, 31), datetime.date(2003, 11, 14), datetime.date(2004, 1, 19), datetime.date(2004, 1, 21), datetime.date(2004, 1, 26), datetime.date(2004, 1, 27), datetime.date(2004, 1, 28), datetime.date(2004, 2, 6), datetime.date(2004, 2, 23), datetime.date(2004, 5, 5), datetime.date(2004, 5, 9), datetime.date(2004, 5, 21), datetime.date(2004, 6, 13), datetime.date(2004, 6, 24), datetime.date(2004, 7, 23), datetime.date(2004, 8, 9), datetime.date(2004, 8, 24), datetime.date(2004, 9, 10), datetime.date(2005, 1, 6), datetime.date(2005, 2, 18), datetime.date(2005, 3, 22), datetime.date(2005, 4, 20), datetime.date(2005, 4, 28), datetime.date(2005, 7, 20), datetime.date(2005, 7, 26), datetime.date(2005, 7, 28), datetime.date(2005, 8, 21), datetime.date(2005, 8, 26), datetime.date(2005, 8, 30), datetime.date(2005, 8, 31), datetime.date(2005, 9, 14), datetime.date(2005, 10, 27), datetime.date(2005, 10, 31), datetime.date(2005, 12, 12), datetime.date(2005, 12, 28), datetime.date(2006, 1, 3), datetime.date(2006, 2, 3), datetime.date(2006, 3, 3), datetime.date(2006, 3, 9), datetime.date(2006, 3, 14), datetime.date(2006, 6, 9), datetime.date(2006, 7, 2), datetime.date(2006, 7, 16), datetime.date(2006, 7, 28), datetime.date(2006, 9, 8), datetime.date(2006, 9, 24), datetime.date(2006, 9, 26), datetime.date(2006, 10, 27), datetime.date(2006, 12, 26), datetime.date(2006, 12, 29), datetime.date(2007, 1, 5), datetime.date(2007, 2, 8), datetime.date(2007, 5, 10), datetime.date(2007, 5, 15), datetime.date(2007, 5, 16), datetime.date(2007, 6, 24), datetime.date(2007, 8, 1), datetime.date(2007, 8, 3), datetime.date(2007, 8, 12), datetime.date(2007, 8, 29), datetime.date(2007, 12, 7), datetime.date(2007, 12, 12), datetime.date(2007, 12, 13), datetime.date(2007, 12, 30), datetime.date(2008, 1, 21), datetime.date(2008, 1, 25), datetime.date(2008, 2, 7), datetime.date(2008, 2, 19), datetime.date(2008, 4, 27), datetime.date(2008, 5, 21), datetime.date(2008, 6, 1), datetime.date(2008, 6, 8), datetime.date(2008, 6, 10), datetime.date(2008, 6, 25), datetime.date(2008, 7, 25), datetime.date(2008, 9, 22), datetime.date(2008, 9, 30), datetime.date(2008, 11, 26), datetime.date(2008, 11, 30), datetime.date(2008, 12, 8), datetime.date(2009, 1, 9), datetime.date(2009, 3, 12), datetime.date(2009, 4, 12), datetime.date(2009, 4, 13), datetime.date(2009, 4, 15), datetime.date(2009, 5, 1), datetime.date(2009, 6, 18), datetime.date(2009, 6, 19), datetime.date(2009, 6, 22), datetime.date(2009, 6, 23), datetime.date(2009, 7, 7), datetime.date(2009, 7, 15), datetime.date(2009, 8, 17), datetime.date(2009, 8, 20), datetime.date(2009, 11, 1), datetime.date(2009, 11, 6), datetime.date(2009, 12, 7), datetime.date(2010, 1, 14), datetime.date(2010, 1, 15), datetime.date(2010, 3, 12), datetime.date(2010, 3, 19), datetime.date(2010, 4, 12), datetime.date(2010, 4, 20), datetime.date(2010, 6, 18), datetime.date(2010, 6, 30), datetime.date(2010, 7, 1), datetime.date(2010, 8, 13), datetime.date(2010, 9, 5), datetime.date(2010, 9, 7), datetime.date(2010, 9, 14), datetime.date(2010, 11, 10), datetime.date(2010, 12, 31), datetime.date(2011, 1, 6), datetime.date(2011, 1, 14), datetime.date(2011, 2, 15), datetime.date(2011, 2, 17), datetime.date(2011, 5, 9), datetime.date(2011, 6, 1), datetime.date(2011, 6, 15), datetime.date(2011, 6, 30), datetime.date(2011, 7, 8), datetime.date(2011, 7, 24), datetime.date(2011, 8, 2), datetime.date(2011, 8, 3), datetime.date(2011, 8, 4), datetime.date(2011, 8, 15), datetime.date(2011, 9, 2), datetime.date(2011, 10, 13), datetime.date(2011, 11, 7), datetime.date(2011, 11, 8), datetime.date(2011, 11, 9), datetime.date(2012, 1, 23), datetime.date(2012, 3, 6), datetime.date(2012, 3, 22), datetime.date(2012, 4, 5), datetime.date(2012, 4, 24), datetime.date(2012, 5, 4), datetime.date(2012, 6, 17), datetime.date(2012, 6, 24), datetime.date(2012, 7, 3), datetime.date(2012, 7, 4), datetime.date(2012, 8, 5), datetime.date(2012, 10, 28), datetime.date(2012, 11, 23), datetime.date(2013, 1, 6), datetime.date(2013, 1, 10), datetime.date(2013, 2, 14), datetime.date(2013, 4, 8), datetime.date(2013, 5, 12), datetime.date(2013, 6, 2), datetime.date(2013, 6, 25), datetime.date(2013, 7, 16), datetime.date(2013, 8, 30), datetime.date(2013, 9, 13), datetime.date(2013, 11, 3), datetime.date(2013, 11, 26), datetime.date(2014, 1, 5), datetime.date(2014, 1, 26), datetime.date(2014, 1, 30), datetime.date(2014, 2, 11), datetime.date(2014, 3, 27), datetime.date(2014, 4, 10), datetime.date(2014, 5, 11), datetime.date(2014, 6, 27), datetime.date(2014, 7, 7), datetime.date(2014, 7, 9), datetime.date(2014, 7, 10), datetime.date(2014, 10, 19), datetime.date(2014, 10, 22), datetime.date(2014, 12, 16), datetime.date(2014, 12, 17), datetime.date(2015, 4, 5), datetime.date(2015, 4, 8), datetime.date(2015, 4, 24), datetime.date(2015, 5, 24), datetime.date(2015, 6, 4), datetime.date(2015, 6, 28), datetime.date(2015, 8, 11), datetime.date(2015, 9, 7), datetime.date(2015, 9, 9), datetime.date(2015, 9, 22), datetime.date(2015, 10, 8), datetime.date(2015, 10, 22), datetime.date(2015, 12, 4), datetime.date(2016, 1, 4), datetime.date(2016, 1, 10), datetime.date(2016, 1, 12), datetime.date(2016, 1, 15), datetime.date(2016, 1, 22), datetime.date(2016, 1, 28), datetime.date(2016, 1, 29), datetime.date(2016, 2, 2), datetime.date(2016, 2, 24), datetime.date(2016, 3, 10), datetime.date(2016, 4, 22), datetime.date(2016, 4, 28), datetime.date(2016, 5, 15), datetime.date(2016, 6, 5), datetime.date(2016, 6, 16), datetime.date(2016, 6, 19), datetime.date(2016, 6, 24), datetime.date(2016, 7, 31), datetime.date(2016, 8, 31), datetime.date(2016, 9, 7), datetime.date(2016, 9, 18), datetime.date(2016, 9, 25), datetime.date(2016, 10, 6), datetime.date(2016, 11, 3), datetime.date(2016, 11, 9), datetime.date(2017, 1, 8), datetime.date(2017, 2, 12), datetime.date(2017, 3, 12), datetime.date(2017, 4, 3), datetime.date(2017, 4, 20), datetime.date(2017, 6, 20), datetime.date(2017, 6, 25), datetime.date(2017, 9, 25), datetime.date(2017, 11, 15), datetime.date(2017, 12, 10), datetime.date(2017, 12, 20), datetime.date(2018, 2, 25), datetime.date(2018, 3, 6), datetime.date(2018, 3, 16), datetime.date(2018, 3, 25), datetime.date(2018, 4, 1), datetime.date(2018, 4, 11), datetime.date(2018, 4, 22), datetime.date(2018, 7, 6), datetime.date(2018, 7, 18), datetime.date(2018, 7, 20), datetime.date(2018, 7, 26), datetime.date(2018, 8, 24), datetime.date(2018, 10, 1), datetime.date(2018, 12, 7), datetime.date(2018, 12, 11), datetime.date(2018, 12, 20), datetime.date(2019, 1, 18), datetime.date(2019, 1, 29), datetime.date(2019, 2, 7), datetime.date(2019, 2, 26), datetime.date(2019, 3, 5), datetime.date(2019, 3, 19), datetime.date(2019, 3, 26), datetime.date(2019, 4, 14), datetime.date(2019, 4, 19), datetime.date(2019, 5, 12), datetime.date(2019, 5, 15), datetime.date(2019, 6, 4), datetime.date(2019, 6, 19), datetime.date(2019, 6, 20), datetime.date(2019, 7, 5), datetime.date(2019, 8, 11), datetime.date(2019, 8, 14), datetime.date(2019, 10, 11), datetime.date(2019, 11, 8), datetime.date(2019, 12, 4), datetime.date(2020, 1, 14), datetime.date(2020, 1, 15), datetime.date(2020, 1, 17), datetime.date(2020, 2, 28), datetime.date(2020, 3, 18), datetime.date(2020, 3, 30), datetime.date(2020, 4, 1), datetime.date(2020, 5, 1), datetime.date(2020, 5, 6), datetime.date(2020, 5, 19)]
-
@run-out I am using EURUSD data from 01-10-1991 to current. I would like to send you the csv file that I am using but cant find a way how to send it here.
-
I have also added a log to record the date at which the
next()
is called and found that next is called first at 30-10-1991 and hence missing the first 29 candles. Is there something that I am doing wrong.Also the plot shows that the first crossover occurs at 29-10-1991 and the first recorded candlestick is at 30-10-1991.
-
@Sajil-Thamban said in Problem with crossovers:
I have also added a log to record the date at which the
next()
is called and found that next is called first at 30-10-1991 and hence missing the first 29 candles. Is there something that I am doing wrong.Also the plot shows that the first crossover occurs at 29-10-1991 and the first recorded candlestick is at 30-10-1991.
Sorry its not missing 29 candlesticks but the candlesticks between 01-10-1991 - 29-10-1991
-
[0_1595496036203_EURUSDMTONE.csv](Uploading 100%)
-
Link to the CSV file
https://drive.google.com/file/d/1dcEfkRPC5lo4CoOubbEtFZe8i9B7lygE/view?usp=sharing -
Correct Crossovers
-
Sorry to be a pain, but the one line I was looking for starts with :
bt.ind.CrossOver()
-
self.ema_fast = bt.indicators.ExponentialMovingAverage(self.data, period=self.p.pfast) self.ema_slow = bt.indicators.ExponentialMovingAverage(self.data, period=self.p.pslow)
-
And this is the crossover
self.crossover = bt.ind.CrossOver(self.ema_fast, self.ema_slow)
-
-
@Sajil-Thamban post full script which generates issues, not pieces here and there, outputs that prove issues. After that I can take a look and try to help you.