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

Custom indicator creation help.



  • Hey I'm working on my mean reversion strategy but in order for me to fully start I need to finish my indicator. So what I want is a Linear regression slope from TALib which ive created then I want standard 8 standard deviations with different distances from the slope (4 above and 4 below). This is what I've got so far;

    class LregressionSlope(bt.indicators):
        params = (
            ('period', 17),
        )
    
        def __init__(self):
            self.slope = bt.talib.LINEARREG_SLOPE(timeperiod=self.params.period)
    
    
    class Cstdev(bt.indicators.StandardDeviation, LregressionSlope):
        lines = (
            ('upper_dev1', 1),
            ('upper_dev2', 2),
            ('upper_dev3', 3),
            ('upper_dev4', 4),
            ('lower_dev1', -1),
            ('lower_dev2', -2),
            ('lower_dev3', -3),
            ('lower_dev4', -4)
        )
        params = (
            ('period', 14),
            ('movav', 'LregressionSlope')
        )
    
        def __init__(self):
            self.upper_dev1 = bt.indicators.StandardDeviation(self.lines.data, self)
            self.upper_dev2 = bt.indicators.StandardDeviation()
            self.upper_dev3 = bt.indicators.StandardDeviation()
            self.upper_dev4 = bt.indicators.StandardDeviation()
            self.lower_dev1 = bt.indicators.StandardDeviation()
            self.lower_dev2 = bt.indicators.StandardDeviation()
            self.lower_dev3 = bt.indicators.StandardDeviation()
            self.lower_dev4 = bt.indicators.StandardDeviation()
    

    I want the stdev to inherit the 'LregressionSlope' as its movav and then build the deviations around that. Any way I can plot it individually as I have a trading background and im still a novice (if that) coder. Thanks for any help!

    Regards,

    cept0r



  • Reading trough all the docs again and going trough the 'parttimelarry' videos again will post updated code later.



  • Okay I'm working on just getting the LINEARREG_SLOPE to plot to begin with.
    I'm getting this output error:

    self.lines[i].array = array.array(str('d'), o)
    TypeError: 'numpy.float64' object is not iterable
    
    

    When running this code:

    #  Imports
    import backtrader as bt
    from backtrader.talib import LINEARREG_SLOPE
    
    
    class LregressionSlope(bt.talib.LINEARREG_SLOPE):
        lines = ('slope',)
        params = (
            ('timeperiod', 17),
        )
    
        def __init__(self):
            self.slope = bt.talib.LINEARREG_SLOPE(self.data, timeperiod=self.params.timeperiod)
    
        def __next__(self):
            pass```


  • Here is my backtester setup:

    #  Imports
    from __future__ import (absolute_import, division, print_function,
                            unicode_literals)
    
    import backtrader as bt
    import pandas as pd
    import datetime
    from strat.examplestrat_04 import LregressionSlope
    
    class CommInfoFractional(bt.CommissionInfo):
        def getsize(self, price, cash):
            """Returns fractional size for cash operation @price"""
            return self.p.leverage * (cash / price)
    
    
    startcash = 1000000
    cerebro = bt.Cerebro()
    cerebro.addindicator(LregressionSlope)
    
    #  Datafeed
    btc = pd.read_csv('/home/dev/PycharmProjects/Backtesting/csvdata/BTCUSDT-1m-data.csv',
                      index_col='timestamp',
                      parse_dates=True
                      )
    
    feed = bt.feeds.PandasData(
        dataname=btc,
    
        fromdate=datetime.datetime(2020, 1, 1),
        todate=datetime.datetime(2020, 1, 2),
    
        timeframe=bt.TimeFrame.Minutes,
    
    )
    
    cerebro.adddata(feed)
    cerebro.broker.setcash(startcash)
    
    cerebro.addsizer(bt.sizers.PercentSizer, percents=0.05)
    cerebro.broker.addcommissioninfo(CommInfoFractional())
    cerebro.broker.setcommission(commission=0.0025, leverage=50)
    
    cerebro.run()
    
    portvalue = cerebro.broker.getvalue()
    pnl = portvalue - startcash
    
    print('Final Portfolio Value: ${}'.format(round(portvalue, 2)))
    print('P/L: ${}'.format(round(pnl, 2)))
    
    cerebro.plot(style='candlestick')
    
    
    


  • Using btalib instead and going trough the docs there..



  • Let us know how you get on and if you still need help after you work through the docs. Good luck.



  • @run-out
    All right I managed to solve it using 4 of these indicators:

    #  Imports
    import backtrader as bt
    
    
    class MeanReversionLong(bt.Strategy):
        lines = ('kama', 'mean'
                 'top1', 'emamean'
                 'bot1', 'emamean'
                 'top2', 'emadev1'
                 'bot2', 'emadev1'
                 'top3', 'emadev2'
                 'bot3', 'emadev2'
                 'top4', 'emadev3'
                 'bot4', 'emadev3')
    
        params = dict(period=30,
                      fast=2,
                      slow=30,
                      perc=2.5)
    
        def __init__(self):
            emamean = bt.indicators.AdaptiveMovingAverageEnvelope(period=9, fast=1, slow=7, perc=0.2, plotname='mean')
            emadev1 = bt.indicators.AdaptiveMovingAverageEnvelope(period=9, fast=1, slow=7, perc=0.4, plotname='dev1')
            emadev2 = bt.indicators.AdaptiveMovingAverageEnvelope(period=9, fast=1, slow=7, perc=0.8, plotname='dev2')
            emadev3 = bt.indicators.AdaptiveMovingAverageEnvelope(period=9, fast=1, slow=7, perc=1.2, plotname='dev3')
    
    

    But now I need to identify each "band" like I do it in my lines section, because when I plot it it only identifies the moving average which is the same for all indicators.



  • @run-out
    AdaptiveMovingAverageEnvelope

    Alias:

    KAMAEnvelope, MovingAverageAdaptiveEnvelope
    

    AdaptiveMovingAverage and envelope bands separated “perc” from it

    Formula:

    kama (from AdaptiveMovingAverage)
    
    top = kama * (1 + perc)
    
    bot = kama * (1 - perc)
    

    See also:

    http://stockcharts.com/school/doku.php?id=chart_school:technical_indicators:moving_average_envelopes
    

    Lines:

    kama
    
    top
    
    bot
    

    Params:

    period (30)
    
    fast (2)
    
    slow (30)
    
    perc (2.5)
    
        def __init__(self):
    
            emamean = bt.indicators.AdaptiveMovingAverageEnvelope(period=30, fast=1, slow=8, perc=0.2, plotname='mean')
            emadev1 = bt.indicators.AdaptiveMovingAverageEnvelope(period=30, fast=1.2, slow=8.2, perc=0.4, plotname='dev1')
            emadev2 = bt.indicators.AdaptiveMovingAverageEnvelope(period=30, fast=1.4, slow=8.5, perc=0.8, plotname='dev2')
            emadev3 = bt.indicators.AdaptiveMovingAverageEnvelope(period=30, fast=1.8, slow=8.9, perc=1.2, plotname='dev3')
    
            top1 = emamean()
    

    How do I create a unique identifier on each respective band ? or what is the calculation I need to provide inside "top1" for example.

    And also;
    Should I create an indicator or just develop within the strategy what is the best or rather easiest approach?



  • Maybe I should calculate inside the lines or parameters.. hmm



  • @run-out
    All right I'm kind of stuck on this calculation.. I changed my code but I can't seem to get the "top" code done right. No output errors but it won't plot.
    here is the code;

    from backtrader.indicators import AdaptiveMovingAverageEnvelope
    
    amae = AdaptiveMovingAverageEnvelope
    
    
    class Adaptive_ma1(amae):
    
        lines = ('kama',
                 'top',
                 'bot')
    
        params = dict(period=27,
                      fast=1.0,
                      slow=8,
                      perc=0.2)
    
        def __init__(self):
            self.l.kama = amae(period=self.p.period)
            self.l.top = self.l.kama * (1 + amae(perc=self.p.perc))
            #  self.l.bot = self.l.kama * (1 - ama(self.data, self.p.perc))
    
        def __next__(self):
            pass
    

    here is the plot:
    link text

    This is what I need to calculate:
    top = kama * (1 + perc)

    Thanks in advance!


Log in to reply
 

});