Navigation

    Backtrader Community

    • Register
    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    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

    General Code/Help
    2
    3
    534
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • Marina Zaitseva
      Marina Zaitseva last edited by Marina Zaitseva

      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)

      1 Reply Last reply Reply Quote 0
      • snevins
        snevins last edited by snevins

        @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

        Marina Zaitseva 1 Reply Last reply Reply Quote 0
        • Marina Zaitseva
          Marina Zaitseva @snevins last edited by

          @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

          1 Reply Last reply Reply Quote 0
          • 1 / 1
          • First post
            Last post
          Copyright © 2016, 2017, 2018, 2019, 2020, 2021 NodeBB Forums | Contributors