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

placement of custom indicator file



  • How can I create a custom indicator in my own "indicators" folder? Or do I have to put it in the official backtrader indicators folder? I want to do my own folders like strategies, indicators, config files, etc. so that when I back my project up, if I lose everything I can just paste them right into the main folder without going into all the places to paste everything. I tried making my own indicator and it said it wasn't found.





  • @Wayne-Filkins I use a directory called extensions and then a file called indicators. I create my class indicators there. Then just add them to the main file like this.

    from extension.indicator import IndicatorClass1, IndictorClass2
    

    Then in the init you can instantiate like:

    self.ic1 = IndicatorClass1(arg1='blah',  arg2='moreblah')
    # Using kwargs
    kwargs=dict(x=1, y=2)
    self.ic2 = IndicatorClass(**kwargs)
    

    This method is useful for analyzers, custom data feeds, observers.

    You can also set up a strategy file in the extensions and house all the standard stuff in there, then create strategy class inheriting from the extensions' class.

    For example, in an extension/strategy module, you might have the following reasonably standard code.

    class StandardStrategy(bt.Strategy):
    
        """
        This is a standard strategy.
        """
    
        def __init__(self):
            """Set up indicators line level"""
    
            self.o_li = list() 
            # self.orefs = list()
            logging.basicConfig(stream=sys.stdout, level=logging.INFO)
    
        def log(self, txt, dt=None):
            """ Logging function for this strategy"""
            dt = self.datas[0].datetime.datetime(0)
            logging.debug("%s, %s" % (dt, txt))
            print("%s, %s" % (dt, txt))
    
        def status(self):
            """Print debug status of market values, cash, positions, etc."""
    
            if self.p.printon:
                logging.debug(
                    "\n{}  THIS IS THE DAILY OPEN...".format(self.datas[0].datetime.date(0))
                )
    
                logging.debug(
                    "Cash: {:.2f}, \t Market Value: {:.2f}".format(
                        self.broker.get_cash(), self.broker.getvalue()
                    )
                )
    
            else:
                pass
    
        def notify_order(self, order):
            """Triggered upon changes to orders. Notifications on order changes are here."""
    
            # Suppress notification if it is just a submitted order.
            if order.status == order.Submitted:
                return
    
            # Print out the date, security name, order number and status.
            dt, dn = self.datetime.date(), order.data._name
            if self.p.printon_main:
                type = "Buy" if order.isbuy() else "Sell"
                self.log(
                    "{} Order {:3d},\tType {},\tStatus {}".format(dn, order.ref, type,  order.getstatusname())
                )
    
            # Check if an order has been completed
            # Attention: broker could reject order if not enough cash
            if order.status in [order.Completed, order.Margin]:
                if self.p.printon_main:
                    if order.isbuy():
                        self.log(
                            "BUY  EXECUTED for {}, Price: {:.2f}, Cost: {:.2f}, Comm {:.2f}".format(
                                dn,
                                order.executed.price,
                                order.executed.value,
                                order.executed.comm,
                            )
                        )
                    else:  # Sell
                        self.log(
                            "SELL EXECUTED for {}, Price: {:.2f}, Cost: {:.2f}, Comm {:.2f}".format(
                                dn,
                                order.executed.price,
                                order.executed.value,
                                order.executed.comm,
                            )
                        )
    
            # Cleans up the order list.
            if not order.alive() and order in self.o_li:
                self.o_li.remove(order)
    
    
        def notify_trade(self, trade):
            """Provides notification of closed trades."""
    
            dt = self.data.datetime.datetime()
            if trade.isclosed:
                if self.p.printon_main:
                    self.log(
                        "{} Closed: PnL Gross {}, Net {},".format(
                            trade.data._name, round(trade.pnl, 2), round(trade.pnlcomm, 1),
                        )
                    )
                else:
                    pass
    
        def print_signal(self):
            """ Print out OHLCV. """
            self.log(
                "o {:5.2f}\th {:5.2f}\tl {:5.2f}\tc {:5.2f}\tv {:5.0f}"
                .format(
                    self.datas[0].open[0],
                    self.datas[0].high[0],
                    self.datas[0].low[0],
                    self.datas[0].close[0],
                    self.datas[0].volume[0],
                )
            )
    

    This takes a lot of clutter out of your main strategy. You would create your strategy object in your main file:

    from extension.strategy import StandardStrategy
    class Strategy(StandardStrategy):
        etc....
    ...
    
    
    


  • @run-out said in placement of custom indicator file:

    self.ic2 = IndicatorClass(**kwargs)

    Should be IndicaatorClass2

    self.ic2 = IndicatorClass2(**kwargs)
    


  • Great, yeah that's pretty much what I was trying to do. Do you happen to have a way of saving settings too? For example the default chart plots a 'line' for the ohlc data and I went into scheme.py to change it to 'candle' and the way I usually update the whole albacka_backtrader_api is I just go on github and download the zip and replace the old one, so I lose settings like that. Is there a way to save all that or not update those files?


Log in to reply
 

});