Navigation

    Backtrader Community

    • Register
    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    1. Home
    2. SoakedOats
    For code/output blocks: Use ``` (aka backtick or grave accent) in a single line before and after the block. See: http://commonmark.org/help/
    S
    • Profile
    • Following 0
    • Followers 0
    • Topics 0
    • Posts 2
    • Best 0
    • Groups 0

    SoakedOats

    @SoakedOats

    0
    Reputation
    1
    Profile views
    2
    Posts
    0
    Followers
    0
    Following
    Joined Last Online

    SoakedOats Unfollow Follow

    Latest posts made by SoakedOats

    • RE: [Errno 2] No such file or directory

      @run-out Yes you are correct, if I uncomment the YahooFinanceCSVData function my program works correctly and the CSVs are stored in a subdirectory. However, I would like to use the other function YahooFinanceData (or any other data feed that automatically gets the closing prices), so I don't have to manually download the CSV files. I tried using Quandl and uncommented that function as well and got this error:

      <ipython-input-11-981141189bb6> in <module>
            3 cerebro.addanalyzer(bt.analyzers.DrawDown, _name='mydrawdown')
            4 # Run over everything
      ----> 5 thestrats = cerebro.run(runonce = True)
            6 
            7 thestrat = thestrats[0]
      
      ~/opt/anaconda3/envs/IKF/lib/python3.9/site-packages/backtrader/cerebro.py in run(self, **kwargs)
         1125             # let's skip process "spawning"
         1126             for iterstrat in iterstrats:
      -> 1127                 runstrat = self.runstrategies(iterstrat)
         1128                 self.runstrats.append(runstrat)
         1129                 if self._dooptimize:
      
      ~/opt/anaconda3/envs/IKF/lib/python3.9/site-packages/backtrader/cerebro.py in runstrategies(self, iterstrat, predata)
         1210                 data._start()
         1211                 if self._dopreload:
      -> 1212                     data.preload()
         1213 
         1214         for stratcls, sargs, skwargs in iterstrat:
      
      ~/opt/anaconda3/envs/IKF/lib/python3.9/site-packages/backtrader/feed.py in preload(self)
          693 
          694         # preloaded - no need to keep the object around - breaks multip in 3.x
      --> 695         self.f.close()
          696         self.f = None
          697 
      
      AttributeError: 'NoneType' object has no attribute 'close'
      

      I believe my API key works and have looked at other posts about 'no attribute 'close'' https://community.backtrader.com/topic/860/tried-quickstart-strategy-with-quandl-and-getting-attribute-error

      If anyone knows another API that is currently working with backtrader please reply below.

      posted in General Code/Help
      S
      SoakedOats
    • RE: [Errno 2] No such file or directory

      Like @dongbuluo I am also getting the same issue with YahooFinanceData. My strategy is below:

      class Test_MA_Multi(bt.Strategy):
          params = (
              ('hold', 7),
              ('MA1', 5),
              ('MA2', 20),
              ('oneplot', False),
          )
      
              
          def __init__(self):
              
              
              self.inds = dict()
              for i, d in enumerate(self.datas):
                  self.inds[d] = dict()
                  self.inds[d]['MA1'] = bt.indicators.SMA(
                      d.close, period=self.params.MA1)
                  self.inds[d]['MA2'] = bt.indicators.SMA(
                      d.close, period=self.params.MA2)
                  self.inds[d]['cross'] = bt.indicators.CrossOver(self.inds[d] 
                                           ['MA1'],self.inds[d]['MA2'], plot = False)
      
                  if i > 0: #Check we are not on the first loop of data feed:
                      if self.p.oneplot == True:
                          d.plotinfo.plotmaster = self.datas[0]
              
            
              
              
              
             
              
              
          def notify_order(self, order):
              
              dt, dn = self.datetime.date(), order.data._name
              if order.status in [order.Completed]:
                  if order.isbuy():
                          print('{} BUY EXECUTED {} at {}, cost {}, com {}'.format(
                                                        dt, dn,
                                                        order.executed.price,
                                                        order.executed.value,
                                                        order.executed.comm))
                      
                  else:
                          print('{} SELL EXECUTED {} at {}, cost {}, com 
                                                         {}'.format(
                                                         dt, dn,
                                                         order.executed.price,
                                                         order.executed.value,
                                                         order.executed.comm))
                          
                          
                      
                  self.bar_executed = len(self)
              elif order.status in [order.Canceled, order.Margin, 
                                                    order.Rejected]:
                  print('{} Order Canceled/Margin/Rejected {} {}'.format(dt, 
                                dn, order.status))
                  if order.status in [order.Margin]:
                      print('MARGIN')
              self.order = None
      
          def prenext(self):
              self.next()
      
          def notify_trade(self, trade):
              if trade.justopened:
                  self.trade_length = 0
              
              if not trade.isclosed:
                  return
      
              print('{} OPERATION PROFIT {}: {} days, GROSS {:.2f}, NET {:.2f}'.format(self.datetime.date(),trade.data._name,self.trade_length,trade.pnl,  trade.pnlcomm))
              self.trade_length = None
        
      
          def next(self):
            
              
              for i, d in enumerate(self.datas):
                      dt, dn = self.datetime.date(), d._name
                      pos = self.getposition(d).size
                      if pos > 0:
                          self.trade_length += 1
                          print('{} {} Position: SHARES: {}, PRICE: {:.2f}, VALUE: {:.2f}, {} days'.format(dt, dn, pos, d.close[0], self.broker.get_value(),self.trade_length))
      
                          if self.inds[d]['cross'] < 0:
                              self.close()
                          
      
                          elif self.trade_length >= self.p.hold:
                              o = self.close(data = d)
                              print('{} {} Manual Close'.format(dt, dn))
      
      
                      else: 
                          if pos != 0:
                              print('THIS IS WRONG')
                          print('CASH: {}'.format(self.broker.get_cash()))
                          self.order_target_percent(data = d, target = .99)
      
      
      
      cerebro = bt.Cerebro(cheat_on_open = False)
      
      
      
      for i in data['Assets']:
      #     sData = bt.feeds.Quandl(dataname= i, apikey='xxx', fromdate = start_date, todate = end_date)
          sData = bt.feeds.YahooFinanceData(dataname = i, fromdate = start_date, todate = end_date)
      #     sData = bt.feeds.YahooFinanceCSVData(dataname = 
      #                                          '/YahooCSVS/' + i + '.csv', 
      #                                          fromdate = start_date, todate = end_date)
          cerebro.adddata(sData, name = i)
          
      cerebro.addstrategy(Test_MA_Multi)
      
      pv = 1000
      cerebro.broker.setcash(pv)
      cerebro.broker.setcommission(commission = 0.01)
      
      cerebro.addanalyzer(bt.analyzers.SharpeRatio, _name='mysharpe')
      cerebro.addanalyzer(bt.analyzers.AnnualReturn, _name='myannual')
      cerebro.addanalyzer(bt.analyzers.DrawDown, _name='mydrawdown')
      # Run over everything
      thestrats = cerebro.run(runonce = True)
      
      thestrat = thestrats[0]
      print('Sharpe Ratio:', thestrat.analyzers.mysharpe.get_analysis())
      print('Annual Return:', thestrat.analyzers.myannual.get_analysis())
      print('Drawdown Info:', thestrat.analyzers.mydrawdown.get_analysis()) 
      
      print('Starting Portfolio Value: %.2f' % pv)
      
      print('Final Portfolio Value: %.2f' % cerebro.broker.getvalue())
      print('Return: {:.2f}%' .format((int(cerebro.broker.getvalue()) / int(pv) - 1) * 100))
      
      b = Bokeh(style='bar', plot_mode='single', plot_width=800, plot_height=3000)
      cerebro.plot(b)
      plt.savefig('samplefig.png')
      

      Basically buys and holds a position for a maximum for 14 days and trys to sell early if the two moving averages cross. I have other code that switches the active stock by using a dictionary of strings to ints for the ticker names to 0/1 if the stock is the active one, and use in if statement in the next to use the right ticker. However, this shouldn't affect the data feeds.

      Also when adding the data feeds the:
      for i in data['Assets']:
      makes i a string with the ticker.

      Here is the output of my code:

      ---------------------------------------------------------------------------
      FileNotFoundError                         Traceback (most recent call last)
      <ipython-input-11-981141189bb6> in <module>
            3 cerebro.addanalyzer(bt.analyzers.DrawDown, _name='mydrawdown')
            4 # Run over everything
      ----> 5 thestrats = cerebro.run(runonce = True)
            6 
            7 thestrat = thestrats[0]
      
      ~/opt/anaconda3/envs/IKF/lib/python3.9/site-packages/backtrader/cerebro.py in run(self, **kwargs)
         1125             # let's skip process "spawning"
         1126             for iterstrat in iterstrats:
      -> 1127                 runstrat = self.runstrategies(iterstrat)
         1128                 self.runstrats.append(runstrat)
         1129                 if self._dooptimize:
      
      ~/opt/anaconda3/envs/IKF/lib/python3.9/site-packages/backtrader/cerebro.py in runstrategies(self, iterstrat, predata)
         1208                 if self._exactbars < 1:  # datas can be full length
         1209                     data.extend(size=self.params.lookahead)
      -> 1210                 data._start()
         1211                 if self._dopreload:
         1212                     data.preload()
      
      ~/opt/anaconda3/envs/IKF/lib/python3.9/site-packages/backtrader/feed.py in _start(self)
          201 
          202     def _start(self):
      --> 203         self.start()
          204 
          205         if not self._started:
      
      ~/opt/anaconda3/envs/IKF/lib/python3.9/site-packages/backtrader/feeds/yahoo.py in start(self)
          353 
          354         # Prepared a "path" file -  CSV Parser can take over
      --> 355         super(YahooFinanceData, self).start()
          356 
          357 
      
      ~/opt/anaconda3/envs/IKF/lib/python3.9/site-packages/backtrader/feeds/yahoo.py in start(self)
           92 
           93     def start(self):
      ---> 94         super(YahooFinanceCSVData, self).start()
           95 
           96         if not self.params.reverse:
      
      ~/opt/anaconda3/envs/IKF/lib/python3.9/site-packages/backtrader/feed.py in start(self)
          672             else:
          673                 # Let an exception propagate to let the caller know
      --> 674                 self.f = io.open(self.p.dataname, 'r')
          675 
          676         if self.p.headers:
      
      FileNotFoundError: [Errno 2] No such file or directory: 'MRO'
      

      If you need more info from me, ask. It most likely is an issue with YahooFinance becuase I haven't changed my yahoo.py (can send that too) and it was working two days ago. Thanks.

      posted in General Code/Help
      S
      SoakedOats