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/

    How to execute(buy or sell) create and complete operations at one time?

    General Code/Help
    3
    6
    136
    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.
    • S
      Sasha last edited by Sasha

      For instance,
      2018-02-20, BUY CREATE AAPL, price = 171.85
      2018-02-21, BUY COMPLETE, 178.13
      171.85 and 178.13 are the close price of each day.
      It is daily trading. Complete operation is performed the next day, in 2018-02-21.
      I want to create and complete the operation in 2018-02-20.
      I mean that the action was created and completed at a price of 171.85.
      Is it possible to perform such an operation?
      In short, I want to buy and sell shares in the market the same day when a signal comes to me, and not the next day as in the document

      import datetime  # For datetime objects
      import os  # To manage paths
      import sys  # To find out the script name (in argv[0])
      
      # Import the backtrader platform
      import backtrader as bt
      import scipy.stats
      
          
      # Create a Stratey
      class TestStrategy(bt.Strategy):
      
          lines = ('correlation',)
          params = dict(
              period20=20,
              period10=10,
              stake=10,
              qty1=0,
              qty2=0,
              status=0,
              portfolio_value=10000,
          )
      
          
          def log(self, txt, dt=None):
              ''' Logging function for this strategy'''
              dt = dt or self.datas[0].datetime.date(0)
              print('%s, %s' % (dt.isoformat(), txt))
      
          
          def notify_order(self, order):
              if order.status in [bt.Order.Submitted, bt.Order.Accepted]:
                  return  # Await further notifications
      
              if order.status == order.Completed:
                  if order.isbuy():
                      buytxt = 'BUY COMPLETE, %.2f' % order.executed.price
                      self.log(buytxt)
                  else:
                      selltxt = 'SELL COMPLETE, %.2f' % order.executed.price
                      self.log(selltxt)
                  
              elif order.status in [order.Expired, order.Canceled, order.Margin]:
                  self.log('%s ,' % order.Status[order.status])
                  pass  # Simply log
      
              # Allow new orders
              self.orderid = None
          
          def __init__(self):
              # Keep a reference to the "close" line in the data[0] dataseries
              
              self.orderid = None
              self.qty1 = self.p.qty1
              self.qty2 = self.p.qty2
              self.status = self.p.status
              self.portfolio_value = self.p.portfolio_value
              self.profit_fix = 30
              self.profit = 0 
              self.cash_aapl = 0
              self.cash_msft = 0
              self.init_close1 = 0
              self.init_close2 = 0
              
              
          def next(self):
              if self.orderid:
                  return
              print('*'*20)
              print('Status is ', self.status)
      
              c10, p = scipy.stats.pearsonr(self.data0.get(size=self.p.period10),
                                           self.data1.get(size=self.p.period10))
      
              c20, p = scipy.stats.pearsonr(self.data0.get(size=self.p.period20),
                                           self.data1.get(size=self.p.period20))
              c10, c20 = round(c10, 2), round(c20, 2)
              self.log('Close, {}'.format(self.datas[0].close[0]))
              self.log('Close, {}'.format(self.datas[1].close[0]))    
              print('corr10: {}, corr20: {}'.format(c10, c20))
              # Step 2: Check conditions for LONG & place the order
              # Checking the condition for LONG
      
              
              if self.status == 1:
                  self.cash_aapl = round((self.data0.close[0] - self.init_close1)*self.qty1,2)
                  self.cash_msft = round((self.init_close2 - self.data1.close[0])*self.qty2,2)
                  self.profit = round((self.cash_aapl + self.cash_msft),2)
                  
                  print('Profit stock1: {}'.format(self.cash_aapl))
                  print('Profit stock2: {}'.format(self.cash_msft))
                  print('Total profit: {}'.format(self.profit))
                     
              
              if (c10 > 0.7 and c20 > 0.7) and (self.status != 1):
      
                  # Calculating the number of shares for each stock
                  value = 0.45 * self.portfolio_value  # Divide the cash equally
                  x = int(value / (self.data0.close))  # Find the number of shares for Stock1
                  y = int(value / (self.data1.close))  # Find the number of shares for Stock2
      
                  
                  print('portfolio_value: {}'.format(self.portfolio_value))
                  
                  # Place the order
                  self.log('BUY CREATE %s, price = %.2f, qty = %d' % ("AAPL", self.data0.close[0], x))
                  self.buy(data=self.data0, size=(x))  
      
                  self.log('SELL CREATE %s, price = %.2f, qty = %d' % ("MSFT", self.data1.close[0], y))
                  self.sell(data=self.data1, size=(y))  
      
                  
                  self.qty1 = x  # The new open position quantity for Stock1 is x shares
                  self.qty2 = y  # The new open position quantity for Stock2 is y shares
                  self.init_close1 = self.data0.close[0]
                  self.init_close2 = self.data1.close[0]
                  self.status = 1  # The current status is "long the spread"
                  
              elif (self.profit > self.profit_fix) and self.status == 1:
                  print('profit: {}, profit_fix: {}'.format(self.profit, self.profit_fix))
                  # Placing the order
                  self.log('SELL CREATE %s, price = %.2f, qty = %d' % ("AAPL", self.data0.close[0], self.qty1))
                  self.sell(data=self.data0, size=(self.qty1))  
                  
                  self.log('BUY CREATE %s, price = %.2f, qty = %d' % ("MSFT", self.data1.close[0], self.qty2))
                  self.buy(data=self.data1, size=(self.qty2))  
      
                  # Updating the counters with new value
                  self.portfolio_value+=self.profit
                  self.qty1, self.qty2 = 0, 0
                  
                  self.cash_aapl, self.cash_msft, self.profit = 0, 0, 0
                  
                  self.status = 0 
      
          def stop(self):
              print('==================================================')
              print('Starting Value - %.2f' % self.broker.startingcash)
              print('Ending   Value - %.2f' % self.broker.getvalue())
              print('==================================================')
              
              
      if __name__ == '__main__':
          # Create a cerebro entity
          cerebro = bt.Cerebro()
      
          # Add a strategy
          cerebro.addstrategy(TestStrategy)
          
          
          def read_data(file_name):    
              datapath = os.path.abspath(os.getcwd() + '/' + file_name)
              return bt.feeds.YahooFinanceCSVData(
                      dataname=datapath,
                      # Do not pass values before this date
                      #fromdate=datetime.datetime(2018, 1, 1),
                      # Do not pass values before this date
                      #todate=datetime.datetime(2019, 1, 1),
                      # Do not pass values after this date
                      reverse=False)
          
          # Create a Data Feed
          data1 = read_data('aapl_1819.csv')
          cerebro.adddata(data1, name='AAPL')
          
          data2 = read_data('msft_1819.csv')
          cerebro.adddata(data2, 'MSFT')
          
          # Set our desired cash start
          cerebro.broker.setcash(100000.0)
      
          # Print out the starting conditions
          print('Starting Portfolio Value: %.2f' % cerebro.broker.getvalue())
      
          # Run over everything
          cerebro.run()
      
          # Print out the final result
          print('Final Portfolio Value: %.2f' % cerebro.broker.getvalue())
      

      Output:

      Status is  0
      2018-02-20, Close, 171.85
      2018-02-20, Close, 92.72
      corr10: 0.9, corr20: 0.73
      portfolio_value: 10000
      2018-02-20, BUY CREATE AAPL, price = 171.85, qty = 26
      2018-02-20, SELL CREATE MSFT, price = 92.72, qty = 48
      2018-02-21, BUY COMPLETE, 178.13
      2018-02-21, SELL COMPLETE, 95.61
      ********************
      Status is  1
      2018-02-21, Close, 171.07
      2018-02-21, Close, 91.49
      corr10: 0.93, corr20: 0.76
      Profit stock1: -20.28
      Profit stock2: 59.04
      Total profit: 38.76
      profit: 38.76, profit_fix: 30
      2018-02-21, SELL CREATE AAPL, price = 171.07, qty = 26
      2018-02-21, BUY CREATE MSFT, price = 91.49, qty = 48
      2018-02-22, SELL COMPLETE, 177.95
      2018-02-22, BUY COMPLETE, 94.96
      1 Reply Last reply Reply Quote 0
      • A
        ab_trader last edited by

        Take a look on cheat-on-close and cheat-on-open modes. This is probably what you are looking for.

        S 1 Reply Last reply Reply Quote 1
        • S
          Sasha @ab_trader last edited by Sasha

          @ab_trader thanks, but I do not benefit from this because the prices are different and I want to buy a stock that day at the same price

          2018-02-20, BUY CREATE AAPL, price = 171.85, qty = 26
          2018-02-20, BUY COMPLETE, 178.27
          I want to buy and complete stock with a price 171.85, not 178.27

          A 1 Reply Last reply Reply Quote 0
          • A
            ab_trader @Sasha last edited by

            @Sasha said in How to execute(buy or sell) create and complete operations at one time?:

            but I do not benefit from this because the prices are different and I want to buy a stock that day at the same price

            With two cheat modes shown above you will be able to issue and execute the order on the same bar. Briefly, cheat-on-close helps to execute your order on the close of the current bar, cheat-on-open helps to issue and execute an order on the open of the bar. I recommend you to read the docs.

            1 Reply Last reply Reply Quote 0
            • S
              Sasha last edited by

              Thanks a lot
              I need to be careful )

              1 Reply Last reply Reply Quote 0
              • Brandon Johnson
                Brandon Johnson last edited by

                @Sasha consider using the replay datafeeds functionality of Backtrader. This allows you to make trading decisions on a lower timeframe while your higher level algorithm still operates on the higher timeframe. For instance, my system looks at indicators to make choices on the 1D candle, but my entries and exits are made on the 1H level. This way I can place a trade 1H before the close of the 1D candle and my trading results will be much more accurate.

                1 Reply Last reply Reply Quote 1
                • 1 / 1
                • First post
                  Last post
                Copyright © 2016, 2017, 2018 NodeBB Forums | Contributors
                $(document).ready(function () { app.coldLoad(); }); }