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/

    Backtest perpetually running, can't interrupt kernel/pandas data

    General Code/Help
    2
    3
    457
    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.
    • G
      guwop last edited by guwop

      I'm running into an issue where upon running a backtest, ipython will keep in a state of running with the asterisk [*] and no amount of spamming the interrupt kernel button will stop it. Restarting the kernel works, but I don't understand where the issue is originating. One idea of origin is that I am trying to feed pandas data, and it's fully possible that I'm not implementing it correctly. The strategy isn't anything special, it's simply the moving average cross taken from the quickstart page. My dataframe (ps) looks like this:
      0_1533256293649_dataframe.png

      And the rest of my code is:

      from __future__ import (absolute_import, division, print_function,
                          unicode_literals)
      
      import datetime  # For datetime objects
      import os.path  # To manage paths
      import sys  # To find out the script name (in argv[0])
      import MySQLdb
      import pandas as pd
      
      # Import the backtrader platform
      import backtrader as bt
      import backtrader.feeds as btfeeds
      
      
      # Create a Stratey
      class TestStrategy(bt.Strategy):
          params = (
          ('maperiod', 15),
          ('printlog', False),
          )
      
          def log(self, txt, dt=None, doprint=False):
          ''' Logging function fot this strategy'''
              if self.params.printlog or doprint:
                  dt = dt or self.datas[0].datetime.date(0)
                  print('%s, %s' % (dt.isoformat(), txt))
      
          def __init__(self):
              # Keep a reference to the "close" line in the data[0] dataseries
              self.dataclose = self.datas[0].close
      
              # To keep track of pending orders and buy price/commission
              self.order = None
              self.buyprice = None
              self.buycomm = None
      
              # Add a MovingAverageSimple indicator
              self.sma = bt.indicators.SimpleMovingAverage(
                  self.datas[0], period=self.params.maperiod)
      
          def notify_order(self, order):
              if order.status in [order.Submitted, order.Accepted]:
                  # Buy/Sell order submitted/accepted to/by broker - Nothing to do
                  return
      
              # Check if an order has been completed
              # Attention: broker could reject order if not enough cash
              if order.status in [order.Completed]:
                  if order.isbuy():
                      self.log(
                          'BUY EXECUTED, Price: %.2f, Cost: %.2f, Comm %.2f' %
                          (order.executed.price,
                           order.executed.value,
                           order.executed.comm))
      
                      self.buyprice = order.executed.price
                      self.buycomm = order.executed.comm
                  else:  # Sell
                      self.log('SELL EXECUTED, Price: %.2f, Cost: %.2f, Comm %.2f' %
                               (order.executed.price,
                                order.executed.value,
                                order.executed.comm))
      
                  self.bar_executed = len(self)
      
              elif order.status in [order.Canceled, order.Margin, order.Rejected]:
                  self.log('Order Canceled/Margin/Rejected')
      
              # Write down: no pending order
              self.order = None
      
          def notify_trade(self, trade):
              if not trade.isclosed:
                  return
      
              self.log('OPERATION PROFIT, GROSS %.2f, NET %.2f' %
                       (trade.pnl, trade.pnlcomm))
      
          def next(self):
              # Simply log the closing price of the series from the reference
              self.log('Close, %.2f' % self.dataclose[0])
      
              # Check if an order is pending ... if yes, we cannot send a 2nd one
              if self.order:
                  return
      
              # Check if we are in the market
              if not self.position:
      
                  # Not yet ... we MIGHT BUY if ...
                  if self.dataclose[0] > self.sma[0]:
      
                      # BUY, BUY, BUY!!! (with all possible default parameters)
                      self.log('BUY CREATE, %.2f' % self.dataclose[0])
      
                      # Keep track of the created order to avoid a 2nd order
                      self.order = self.buy()
      
              else:
      
                  if self.dataclose[0] < self.sma[0]:
                      # SELL, SELL, SELL!!! (with all possible default parameters)
                      self.log('SELL CREATE, %.2f' % self.dataclose[0])
      
                      # Keep track of the created order to avoid a 2nd order
                      self.order = self.sell()
      
          def stop(self):
              self.log('(MA Period %2d) Ending Value %.2f' %
                       (self.params.maperiod, self.broker.getvalue()), doprint=True)
      
      
      if __name__ == '__main__':
      # Create a cerebro entity
      cerebro = bt.Cerebro()
      
      # Add a strategy
      strats = cerebro.optstrategy(
          TestStrategy,
          maperiod=range(10, 31))
      
      # Datas are in a subfolder of the samples. Need to find where the script is
      # because it could have been called from anywhere
      #modpath = os.path.dirname(os.path.abspath(sys.argv[0]))
      #datapath = os.path.join(modpath, '../../datas/orcl-1995-2014.txt')
      
      
      # Create a Data Feed
      data = btfeeds.PandasData(dataname=ps)
      
      # Add the Data Feed to Cerebro
      cerebro.adddata(data)
      
      # Set our desired cash start
      cerebro.broker.setcash(1000000.0)
      
      # Add a FixedSize sizer according to the stake
      cerebro.addsizer(bt.sizers.FixedSize, stake=10)
      
      # Set the commission
      cerebro.broker.setcommission(commission=0.0)
      
      # Run over everything
      cerebro.run()
      

      If anybody has experienced this before or has any suggestions I'd love to hear about it, I'll be working all night. Thanks.

      EDIT: I have additionally tried setting the index to the datetime and running again, still no change

      1 Reply Last reply Reply Quote 0
      • B
        backtrader administrators last edited by

        In your description you have omitted the most important point: "You are optimizing the strategy". Even if you see it so, it is no longer the sample script with just a change in the data feed.

        The Kernel is known to hijack the start process of Python and have problems with multiprocessing

        This is a known problem and has nothing to do with backtrader: https://community.backtrader.com/topic/744/optstrategy-not-working-in-jupyter

        G 1 Reply Last reply Reply Quote 0
        • G
          guwop @backtrader last edited by

          @backtrader, Thank you for the explanation. I was just getting ready to post an update saying that it's working now. I started over from scratch, converted my data to csv, copy & pasted through the quickstart page, and everything has been going smoothly.

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