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

Help with starting using BT



  • I'm a beginner in BT. First, I tried to create the easiest indicator, using BT. The Code in TradeStation:
    TS9_DirNum.png

    I want to get same result for f_LDirNum using BT.

    1. I copied sma.py to fxd_sma_mod.py
      fxd_sma_mod.png
    2. Added fxd_sma_mod.py to init.py
      init_fxd_sma_mod.png
    3. Filled fxd_sma_mod.py with several classes
    #!/usr/bin/env python
    # -*- coding: utf-8; py-indent-offset:4 -*-
    ###############################################################################
    #
    # Copyright (C) 2015, 2016, 2017 Daniel Rodriguez
    #
    # This program is free software: you can redistribute it and/or modify
    # it under the terms of the GNU General Public License as published by
    # the Free Software Foundation, either version 3 of the License, or
    # (at your option) any later version.
    #
    # This program is distributed in the hope that it will be useful,
    # but WITHOUT ANY WARRANTY; without even the implied warranty of
    # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    # GNU General Public License for more details.
    #
    # You should have received a copy of the GNU General Public License
    # along with this program.  If not, see <http://www.gnu.org/licenses/>.
    #
    ###############################################################################
    from __future__ import (absolute_import, division, print_function,
                            unicode_literals)
    
    from . import MovingAverageBase, Average
    from . import (Indicator, Highest, Lowest, If, Accum)
    
    import backtrader as bt
    import math
    
    class f_MovingAverageSimple(MovingAverageBase):
        '''
        Non-weighted average of the last n periods
    
        Formula:
          - movav = Sum(data, period) / period
    
        See also:
          - http://en.wikipedia.org/wiki/Moving_average#Simple_moving_average
        '''
        alias = ('f_SMA', 'f_SimpleMovingAverage',)
        lines = ('f_sma',)
    
        def __init__(self):
            # Before super to ensure mixins (right-hand side in subclassing)
            # can see the assignment operation and operate on the line
            self.lines[0] = Average(self.data, period=self.p.period)
    
            super(f_MovingAverageSimple, self).__init__()
    		
    class f_LDir(Indicator):
    
        alias = ('f_LDir',)
        lines = ('f_lDir',)
    
        def __init__(self):
            l = self.data.low
            l1 = self.data.low(-1)		
            self.lines.f_lDir =  bt.If(l < l1, l-l+1, l-l-1)
            super(f_LDir, self).__init__()
    
    
    class f_LDirNum(Indicator):
    
        alias = ('f_LDirNum',)
        lines = ('f_lDirNum',)
    
        def __init__(self):
            #Sign = lambda x: math.copysign(1, x) # two will work
            l = self.data.low
            l1 = self.data.low(-1)	
    				
            lDir =  bt.If(l < l1, l-l+1, l-l-1)
    
            lDir1 = lDir(-1)
            deltalDir = abs(lDir - lDir1)		
    	
            self.lines.f_lDirNum =  bt.If(deltalDir==2, lDir, 
                                        f_lDirNum1+lDir)									
    									
            f_lDirNum1 = self.lines.f_lDirNum		
    	
            super(f_LDirNum, self).__init__()	
    
    1. In Jupyter Notebook created a file with a next code
    #from datetime import datetime
    
    import backtrader as bt
    import datetime
    import backtrader.feeds as btfeeds
    
    import pandas
    import pandas_datareader
    import datetime
    import pandas_datareader.data as web
    
    # Create a subclass of Strategy to define the indicators and logic
    class BasicIndicator(bt.Strategy):
        # list of parameters which are configurable for the strategy
        params = dict(
            pfast=10,  # period for the fast moving average
            pslow=30   # period for the slow moving average
        )
    
        def __init__(self):
            
            #sma = bt.indicators.SimpleMovingAverage(self.data)
            f_sma = bt.indicators.f_SMA(self.data, period=15)
    
            f_lDir = bt.indicators.f_LDir(self.data)
            #f_lDirNum = bt.indicators.f_LDirNum(self.data)        
    
    # Create a data feed      
    
    dataframe = pandas.read_csv(
        'GBP_D_MW.txt',
        parse_dates=True,
        index_col=0,
        )
    
    
    # Pass it to the backtrader datafeed and add it to the cerebro
    data = bt.feeds.PandasData(
                                fromdate = datetime.datetime(2018, 12, 1),
                                todate =  datetime.datetime(2019, 12, 31),    
                                dataname=dataframe,
                                nocase=True,
                               )
    
    cerebro = bt.Cerebro()  # create a "Cerebro" engine instance
    cerebro.adddata(data)  # Add the data feed
    cerebro.addstrategy(BasicIndicator)  # Add the trading strategy
    cerebro.run(stdstats=False)  # run it all
    
    cerebro.plot(iplot=False, style='candlestick',   
                 #numfigs = 1,              
                 volume=False, 
                 plotstyle = 2, 
                 zup = False, zdown=False )  # and plot it with a single command
    

    Using this code, i get result, which i expect
    Plot_lDir.png

    I've got same result "lDir", as at blue histogram in TradeStation Chart.
    But i need to get a red Histogram "f_LDirNum"of TS.
    And this is - my Big Problem, where i need a Help.

    I can't write right way a code for a class:

    class f_LDirNum(Indicator):
    

    If i change a code in Jupyter NB, adding f_lDirNum

        def __init__(self):
            
            #sma = bt.indicators.SimpleMovingAverage(self.data)
            f_sma = bt.indicators.f_SMA(self.data, period=15)
    
            f_lDir = bt.indicators.f_LDir(self.data)
            f_lDirNum = bt.indicators.f_LDirNum(self.data) 
    

    i get an error
    errot.png

    I can understand why, looking at my code
    Скриншот 26-08-2019 165502.png

    But i'm a beginner in Python too, so i don't know where i can initialize f_lDirNum1 to Zero for Example. In TradeStation i can use:

    if BarNumber = 1 then f_lDirNum1 = 0

    But in BackTrader Guide I could find how to check a barnumber in TimeSeries.
    I tried many variants of algorithm "class f_LDirNum(Indicator):", but couldn't get a Red Histogram from TradeStation Chart.
    After 1 week experiments, i decided to ask your help.

    Please, help me to code a class f_LDirNum(Indicator)



  • @Marina-Zaitseva said in Help with starting using BT:

    from TradeStation Chart

    Do you mean to have the 1 at the end of f_lDirNum1? You don't have anything defined by that name prior to it executing but you have f_lDirNum. When you run that if statement you are inherently defining f_lDirNum1 so that's why it works when that if statement executes



  • @snevins
    I'd like to know how to define f_lDirNum1 somehow (0 or 1 or any number) before f_lDirNum will be counted. (if its possible). Or maybe other algorithm to count f_lDirNum.

    Briefly describe the task:

    I have Condition = Low < Low[1] (I can choose any other condition)

    Each time when Condition = True - lDir=1
    If Condiiton = True 2 times in а row - lDir=1, f_lDirNum=2
    If Condiiton = True 3 times in а row - lDir=1, f_lDirNum=3
    If Condiiton = True X times in а row - lDir=1, f_lDirNum=X
    .......
    Each time when Condition = False lDir=-1
    If Condiiton = False 2 times in а row - lDir=-1, f_lDirNum=-2
    If Condiiton = False 3 times in а row - lDir=-1, f_lDirNum=-3
    If Condiiton = False X times in а row - lDir=-1, f_lDirNum=-X


Log in to reply
 

});