For code/output blocks: Use ``` (aka backtick or grave accent) in a single line before and after the block. See: http://commonmark.org/help/

Trouble using holiday calendar



  • Hi, I'm having a bit of trouble using the holiday calendar. I'm still a beginner at Python, and am learning, so apologies if this is a simple issue!

    My aim is to have the algorithm not take any trades on on certain days (i.e. days with news events coming out). To try and work it out, I've taken a simple SMA crossover with some print statements, then tried to pass in a holiday dictionary. However whether I have the calendar enabled, or comment it out, trades still seem to happen on holidays. How do I fix this?

    Here is the sample code (the data being fed in is a data frame with daily price feed with OHLCV data):

    import backtrader as bt
    import backtrader.indicators as btind
    import datetime
    import pandas as pd
    
    
    class Holidays(bt.TradingCalendar):
        params = dict(
            holidays=holiday_dict,
        )
    
    class SMA_CrossOver(bt.Strategy):
    
        params = (('fast', 2), ('slow', 8))
    
        def __init__(self):
            self.buysig={}
            for d in self.getdatanames():
                sma_fast = btind.SMA(self.getdatabyname(d), period=self.p.fast)
                sma_slow = btind.SMA(self.getdatabyname(d), period=self.p.slow)
                self.buysig[d] = btind.CrossOver(sma_fast, sma_slow)
                
        def next(self):
            for d in self.getdatanames():
                if self.getpositionbyname(d).size:
                    if self.buysig[d] < 0:
                        self.sell(data=self.getdatabyname(d))
                        print(f'Sell {self.datetime.date()}')
                elif self.buysig[d] > 0:
                    self.buy(data=self.getdatabyname(d))
                    print(f'Buy {self.datetime.date()}')
    
    
    cerebro = bt.Cerebro()
    
    cerebro.addcalendar(Holidays())
    
    cerebro.broker.setcommission(commission = 0.002)
    data0 = cerebro.adddata(bt.feeds.PandasData(dataname=df))
    cerebro.adddata(data0)
    cerebro.addstrategy(SMA_CrossOver)
    cerebro.run()
    cerebro.broker.getvalue()
    

    My holiday_dict for testing is just a manual dictionary I made with dates from 2019,1,1 for every day for 3 months. Here is a sample (but extended in the actual one):

    holiday_dict=[datetime.date(2019, 1, 1), datetime.date(2019, 1, 2), datetime.date(2019, 1, 3), datetime.date(2019, 1, 4), datetime.date(2019, 1, 5), datetime.date(2019, 1, 6), datetime.date(2019, 1, 7)]
    

    Thanks for your help, and let me know if I can provide any other information to debug


  • administrators

    The calendars are not there to filter out some data points for you. Second sentence in the documentation for calendars:

    This is useful when resampling in for example the following scenarios

    From: Docs - Trading Calendar - https://www.backtrader.com/docu/tradingcalendar/tradingcalendar/

    If you provide data that has price points for day X and you want to consider this a non-trading day, you will have to manually do it.

    You may remove the "non-trading" days by implementing a specific filter


Log in to reply
 

});