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

Use function that takes pandas series as argument i __init__ part



  • Hello,

    First, I want to say I read a plenty of docs (no all, there lot of stuff:)) and successfully implemented some simple strategies like buy if price is above VIX, vice versa.

    Now I wanted to backtest my ML strategy with backtrader.

    In nutshell, I have saved sklearn model in pkl format. I want to make predictions using this model every "event" and buy if the prediction is 1, and sell if -1. If position is already 1, than keep holding, vice versa.

    Now I don't want to make predictions every minute. On contrary, I want to make prediction only when event happens. The event is calculated using CUSUM filter. In pandas data.frame world, I would calculate trading events using function from mlfinlab package:

    # Compute volatility
    daily_vol = mlfinlab.util.get_daily_vol(
                close,
                lookback=self.volatility_lookback)
    

    But to calculate daily volatility using this function we have to set pandas serires (close prices) as frist argument.

    My first naive approach to implement this in backtrader was to define daily_vol as I would do that in pandas world:

    class RandomForestStrategy(bt.Strategy):
        
        params = (
            ('volatility_scaler', 1),
            ('volatility_lookback', 50)
        )
        
        def start(self):
            # get started value
            self.val_start = self.broker.get_cash()  # keep the starting cash
            self.log(f"Type:  {type(self.datas[0].close)}")
    
        def log(self, txt, dt=None):
            ''' Logging function for this strategy'''
            dt = dt or self.datas[0].datetime.datetime(0)
            print(f'{dt.isoformat()}, {txt}')
    
        def __init__(self):
            # Keep a reference to the "close" line in the data[0] dataseries
            self.dataclose = self.datas[0].close
            
            # load ml model
            clf = joblib.load("C:/Users/Mislav/Documents/GitHub/trademl/trademl/modeling/rf_model.pkl")
            
            # Compute volatility get CUSUM events
            self.daily_vol = ml.util.get_daily_vol(
                self.datas[0].close,
                lookback=self.params.volatility_lookback)
            # self.cusum_events = ml.filters.cusum_filter(
            #     self.dataclose,
            #     threshold=self.daily_vol.mean()*self.params.volatility_scaler)
            
            # To keep track of pending orders and buy price/commission
            self.order = None
            self.buyprice = None
            self.buycomm = None
    

    There is also next part but not important for now. Backtrader can calculate daily volatility because self.datas[0].close is line buffer object, not pandas series (expected).

    My question is, is it possible to somehow provide pandas series as argument to ml.util.get_daily_vol or I have to rewrite the original function from mlfinlab?



  • It seems to me that all backtesting framework I tried don't have some easy way to include ML models inside them. It's not rare that we need hundreds of variables in ML, based on OHLC data. I don't understand how to construct this data inside backtrader. I know I can write function for generating every indicator by hand, but that's probably the last option. I have function that generate fatures on padans df using talib package and some my own calculations. Nut I cant just call this function in backtrader.


Log in to reply
 

});