Backtrader Community

    • 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/

    Adding constituent lists on a monthly basis

    General Code/Help
    2
    1
    34
    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.
    • ?
      A Former User last edited by

      So, here you can find my code to apply a trading strategy that equally weighs the stocks in that month's constituent list. My starting and ending values are the same, while the code runs with yearly constituent lists.

      class EquallyWeightedM(bt.Strategy):
      params = (
      ('constituent_companies', {}), # a dictionary mapping year to list of consistent companies
      )

      def __init__(self):
          self.constituent_companies = constituent_companies
          self.weights = {}  # Dictionary to store the weights for each company
      
      def start(self):
          self.calculate_weights()
      
      def next(self):
          for i, d in enumerate(self.datas):
              if not self.getposition(d).size:
                  if d._name in self.weights:
                      size = self.broker.get_cash() * self.weights[d._name]  # calculate position size based on weight
                      self.buy(data=d, size=size)
      
      def calculate_weights(self):
          num_companies = len(self.constituent_companies)
          if num_companies > 0:
              weight = 1.0 / num_companies
              for company in self.constituent_companies:
                  self.weights[company] = weight
      

      if name == 'main':
      cerebro = bt.Cerebro()
      cerebro.addstrategy(EquallyWeightedM, constituent_companies=constituent_companies)

      base_path = '/Users/jonat/Documents/Documenten/data/Test/Constituents/'
      dates = [datetime(2000, 1, 1), datetime(2000, 2, 1), datetime(2000, 3, 1), datetime(2000, 4, 1), datetime(2000, 5, 1)]
      
      for date in dates:
          csv_path = base_path + f'constituent_companies_{date.strftime("%Y-%m-%d")}.csv'
          with open(csv_path, 'r', encoding='utf-8-sig') as csvfile:
              reader = csv.reader(csvfile)
              next(reader)  # Skip the header row
              companies = [row[0] for row in reader if row[0]]  # Read company names from column A
      
      datalist = ['AAPL.csv', 'DIS.csv', 'IBM.csv', 'BA.csv', 'F.csv', 'GE.csv', 'KO.csv', 'MMM.csv', 'PG.csv', 'XOM.csv']
      datapath= "/Users/jonat/Documents/Documenten/data/Test/"
      
      for i in range(len(datalist)):
          data = bt.feeds.YahooFinanceCSVData(
              dataname=datapath+datalist[i],
              fromdate=datetime(2000, 1, 1),
              todate=datetime(2004, 12, 31),
              reverse=False
          )
          cerebro.adddata(data, name=datalist[i])
      
      cerebro.broker.setcash(1000.0)
      cerebro.addsizer(bt.sizers.PercentSizer, percents=10)
      cerebro.broker.setcommission(commission=0.0)
      
      print('Starting Portfolio Value: %.2f' % cerebro.broker.getvalue())
      cerebro.run()
      print('Final Portfolio Value: %.2f' % cerebro.broker.getvalue())
      
      1 Reply Last reply Reply Quote 0
      • 1 / 1
      • First post
        Last post
      Copyright © 2016, 2017, 2018, 2019, 2020, 2021 NodeBB Forums | Contributors