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/

    backtrader addwriter output buy and sell point error?

    General Code/Help
    2
    2
    103
    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.
    • D
      damag00 last edited by

      I used

      cerebro.addwriter(bt.WriterFile, csv=True, out='outputfiles\{}.csv'.format(ticker))
      

      to write out the output.

      the output CSV file has 2 "datetime" columns 3 "len" columns

      question 1, how to output only desired columns (say: tickername, date, cash, value)

      question 2, the output CSV file wrote down buy and sell price, but those prices are none of the open/high/low/close. How can I find out how/where does the backtrader gets those values?
      following is the screenshot of the output file.

      2f560280-bccf-4ca4-a385-b7184aab5cca-image.png

      I attached the code here:

      import pandas as pd
      
      import datetime
      import backtrader as bt
      import pickle
      
      from zclasses.GoldenCross1 import GoldCross
      from zclasses.sma_crossover import MA_CrossOver
      
      # def run_test_macd():
      #     with open("sp500tickers.pickle", "rb") as f:
      #         tickers = pickle.load(f)
      #     for ticker in tickers:
      #         print(ticker)
      #         macd_stock_test2(ticker)
      
      
      def run_test_single():
          ticker="OXY"
          print("ticker")
          print(ticker)
          macd_stock_test2(ticker)
      
      
      def macd_stock_test2(ticker):
          cerebro = bt.Cerebro()
          cerebro.addstrategy(GoldCross)
          # cerebro.addstrategy(MA_CrossOver)
          cerebro.broker.set_cash(1000000)
          ticker_prices = pd.read_csv('stock_dfs/{}.csv'.format(ticker), index_col='Date', parse_dates=True)
      
          # print(ticker_prices)
          feed = bt.feeds.PandasData(
              dataname=ticker_prices,
              timeframe=bt.TimeFrame.Days,
              fromdate=datetime.datetime(1996, 1, 1), # this is used for all
              # fromdate=datetime.datetime(2020, 5, 1), #this is used for debug
              todate=datetime.datetime(2020, 12, 31), #this is used for all
              # todate=datetime.datetime(2012, 12, 31),  #this is used for debug
              # reverse=False,
          )
      
          # feed = bt.feeds.YahooFinanceData(
          #
          #     dataname=ticker,
          #
          #     timeframe=bt.TimeFrame.Days,
          #     fromdate=datetime.datetime(1996, 1, 1),
          #     todate=datetime.datetime(2020, 12, 31),
          #     reverse=False,
          # )
          cerebro.adddata(feed)
          # cerebro.addsizer(bt.sizers.FixedSize, stake=1000)
          # cerebro.addanalyzer(bt.analyzers.DrawDown)
          # cerebro.addanalyzer(btanalyzers.DrawDown, _name='returns')
          # cerebro.addanalyzer(SQN)
          #
      
      
          print("starting portfolio value: %.2f" % cerebro.broker.getvalue())
          cerebro.addwriter(bt.WriterFile, csv=False, out='outputfiles\{}.csv'.format(ticker))
          cerebro.run()
      
          print("final portfolio value: %.2f" % cerebro.broker.getvalue())
          # cerebro.plot(style='candle')
      
      
      run_test_single()
      
      
      
      class GoldCross(bt.Strategy):  #unknow gold cross
      
          # set parameters to define fast and slow
          fastd = 12
          slowd = 26
          params = (
              ("fast", fastd),
              ("slow", slowd),
              ("order_percentage", 1),
              ("ticker", "stock"),
          )
      
          # define constractors
          def __init__(self):
              print("position size:", self.position.size)
      
              self.fast_moving_average = bt.indicators.EMA(
                  self.data.close, period=self.params.fast, plotname="12 day moving average"
              )
      
              self.slow_moving_average = bt.indicators.EMA(
                  self.data.close, period=self.params.slow, plotname="26 day moving average"
              )
      
              self.crossover = bt.indicators.CrossOver(
                  self.fast_moving_average, self.slow_moving_average
              )
      
          def log(self, txt, dt=None):
              """ Logging function fot this strategy"""
              dt = dt or self.data.datetime[0]
              if isinstance(dt, float):
                  dt = bt.num2date(dt)
              print("%s, %s" % (dt.date(), txt))
      
          def notify_order(self, order):
              """ Triggered upon changes to orders. """
      
              # Suppress notification if it is just a submitted order.
              if order.status == order.Submitted:
                  return
      
              # Print out the date, security name, order number and status.
              dt, dn = self.datetime.date(), order.data._name
              type = "Buy" if order.isbuy() else "Sell"
              # self.log(
              #     # print(dn)
              #     f"{order.data._name:<6} Order: {order.ref:3d}\tType: {type:<5}\tStatus"
              #     f" {order.getstatusname():<8} \t"
              #     f"Size: {order.created.size:9.2f} Price: {order.created.price:9.2f} "
              #     f"Position: {self.getposition(order.data).size}"
              # )
              if order.status == order.Margin:
                  return
      
              # Check if an order has been completed
              if order.status in [order.Completed]:
                  self.log(
                      f"{order.data._name:<6} {('BUY' if order.isbuy() else 'SELL'):<5} "
                      f"EXECUTED for: {dn} "
                      f"Price: {order.executed.price:6.2f} "
                      f"Cost: {order.executed.value:6.2f} "
                      # f"Comm: {order.executed.comm:4.2f} "
                      f"Size: {order.created.size:9.0f} "
                  )
      
          def notify_trade(self, trade):
              """Provides notification of closed trades."""
              if trade.isclosed:
                  self.log(
                      "{} Closed: PnL Gross {}, Net {},".format(
                          trade.data._name,
                          round(trade.pnl, 2),
                          round(trade.pnlcomm, 2),
                      )
                  )
      
          def next(self):
              if self.position.size == 0:
                  if self.crossover > 0:
                      amount_to_invest = self.params.order_percentage * self.broker.cash
                      self.size = math.floor(amount_to_invest / self.data.open[1])
                      # self.size = math.floor(amount_to_invest / self.data.close)
      
                      # self.log(
                      #     "Buy {} shares of {} at {}".format(
                      #         self.size,
                      #         self.params.ticker,
                      #         # self.data.close[0],
                      #         self.data.open[1],
                      #     )
                      # )
                      # self.buy(size=self.size,price=self.data.close[0])
                      self.buy(size=self.size, price=self.data.open[1])
      
              if self.position.size > 0:
                  if self.crossover < 0:
                      # self.log(
                      #     "Sell {} shares of {} at {}".format(
                      #         # self.size, self.params.ticker, self.data.close[0],
                      #         self.size, self.params.ticker, self.data.open[1],
                      #     )
                      # )
                      self.sell(size=self.size,price=self.data.open[1])
      
          def end(self):
              # self.sell(size=self.size, price=self.data.close[0])
              self.sell(size=self.size, price=self.data.open[1])
              return
      
      if __name__ == "__main__":
          print("File one executed when ran directly")
      
      else:
          print("File one executed when imported")
      
      class GoldCross(bt.Strategy):  #unknow gold cross
      
          # set parameters to define fast and slow
          fastd = 12
          slowd = 26
          params = (
              ("fast", fastd),
              ("slow", slowd),
              ("order_percentage", 1),
              ("ticker", "stock"),
          )
      
          # define constractors
          def __init__(self):
              print("position size:", self.position.size)
      
              self.fast_moving_average = bt.indicators.EMA(
                  self.data.close, period=self.params.fast, plotname="12 day moving average"
              )
      
              self.slow_moving_average = bt.indicators.EMA(
                  self.data.close, period=self.params.slow, plotname="26 day moving average"
              )
      
              self.crossover = bt.indicators.CrossOver(
                  self.fast_moving_average, self.slow_moving_average
              )
      
          def log(self, txt, dt=None):
              """ Logging function fot this strategy"""
              dt = dt or self.data.datetime[0]
              if isinstance(dt, float):
                  dt = bt.num2date(dt)
              print("%s, %s" % (dt.date(), txt))
      
          def notify_order(self, order):
              """ Triggered upon changes to orders. """
      
              # Suppress notification if it is just a submitted order.
              if order.status == order.Submitted:
                  return
      
              # Print out the date, security name, order number and status.
              dt, dn = self.datetime.date(), order.data._name
              type = "Buy" if order.isbuy() else "Sell"
              # self.log(
              #     # print(dn)
              #     f"{order.data._name:<6} Order: {order.ref:3d}\tType: {type:<5}\tStatus"
              #     f" {order.getstatusname():<8} \t"
              #     f"Size: {order.created.size:9.2f} Price: {order.created.price:9.2f} "
              #     f"Position: {self.getposition(order.data).size}"
              # )
              if order.status == order.Margin:
                  return
      
              # Check if an order has been completed
              if order.status in [order.Completed]:
                  self.log(
                      f"{order.data._name:<6} {('BUY' if order.isbuy() else 'SELL'):<5} "
                      f"EXECUTED for: {dn} "
                      f"Price: {order.executed.price:6.2f} "
                      f"Cost: {order.executed.value:6.2f} "
                      # f"Comm: {order.executed.comm:4.2f} "
                      f"Size: {order.created.size:9.0f} "
                  )
      
          def notify_trade(self, trade):
              """Provides notification of closed trades."""
              if trade.isclosed:
                  self.log(
                      "{} Closed: PnL Gross {}, Net {},".format(
                          trade.data._name,
                          round(trade.pnl, 2),
                          round(trade.pnlcomm, 2),
                      )
                  )
      
          def next(self):
              if self.position.size == 0:
                  if self.crossover > 0:
                      amount_to_invest = self.params.order_percentage * self.broker.cash
                      self.size = math.floor(amount_to_invest / self.data.open[1])
                      # self.size = math.floor(amount_to_invest / self.data.close)
      
                      # self.log(
                      #     "Buy {} shares of {} at {}".format(
                      #         self.size,
                      #         self.params.ticker,
                      #         # self.data.close[0],
                      #         self.data.open[1],
                      #     )
                      # )
                      # self.buy(size=self.size,price=self.data.close[0])
                      self.buy(size=self.size, price=self.data.open[1])
      
              if self.position.size > 0:
                  if self.crossover < 0:
                      # self.log(
                      #     "Sell {} shares of {} at {}".format(
                      #         # self.size, self.params.ticker, self.data.close[0],
                      #         self.size, self.params.ticker, self.data.open[1],
                      #     )
                      # )
                      self.sell(size=self.size,price=self.data.open[1])
      
          def end(self):
              # self.sell(size=self.size, price=self.data.close[0])
              self.sell(size=self.size, price=self.data.open[1])
              return
      
      if __name__ == "__main__":
          print("File one executed when ran directly")
      
      else:
          print("File one executed when imported")
      Kisko Apeles 1 Reply Last reply Reply Quote 1
      • Kisko Apeles
        Kisko Apeles @damag00 last edited by

        @damag00 Saw your post here

        Did you figure it out?

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