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/

    Execute orders with bid/ask prices

    General Discussion
    1
    1
    766
    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.
    • R
      roch_02 last edited by

      @Nigel said in Execute on bid/ask:

      BidAskCSV

      Hello,

      I am also using Bid/ask data. Wanted to do a test where I buy and sell like @Nigel did.
      But it seems like the orders are not being executed because when I access the order.Exuecuted.price is always 0.

      from __future__ import (absolute_import, division, print_function,
                              unicode_literals)
      
      import argparse
      
      import backtrader as bt
      import backtrader.feeds as btfeeds
      #import backtrader.indicators as btind
      import random
      
      
      class BidAskCSV(btfeeds.GenericCSVData):
          linesoverride = True  # discard usual OHLC structure
          # datetime must be present and last
          lines = ('bid', 'ask', 'close', 'open','low', 'high', 'datetime')
          # datetime (always 1st) and then the desired order for
          params = (
              # (datetime, 0), # inherited from parent class
              ('bid', 1),  # default field pos 1
              ('ask', 2),  # default field pos 2
              ('close', 2), ('open', 1), ('low', 1), ('high',2)
          )
          
          def __init__(self):
              super(BidAskCSV, self).__init__()
      

      The strategy:

      class St(bt.Strategy):
      
          def log(self, txt, dt= None):
              """Logging function """
              dt= dt or self.datas[0].datetime[0]
              if isinstance(dt, float):
                  dt = bt.num2date(dt)
              print('%s, %s' % (dt.isoformat(), txt))
      
      
          def __init__(self):
              self.order = None
              self.dataclose= self.datas[0].close
              #self.dataclose = self.datas[0].close[0]
                  
                  
          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 enougth cash
             if order.status in [order.Completed]:
                 if order.isbuy():
                     self.log(
                         'BUY EXECUTED, Price: %.2f, Cost: %.2f' %
                         (order.executed.price,
                          order.executed.value))
      
                     self.buyprice = order.executed.price
                     
                 else:  # Sell
                     self.log('SELL EXECUTED, Price: %.2f, Cost: %.2f' %
                              (order.executed.price,
                               order.executed.value))
      
                 self.bar_executed = len(self)
             elif order.status in [order.Canceled, order.Margin, order.Rejected]:
                 self.log('Order Canceled/Margin/Rejected')
      
             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):
              dtstr = self.datas[0].datetime.datetime().isoformat()
              txt = '%4d: %s - Bid %.4f - %.4f Ask, CLOSE %.4f ' % (
                  (len(self), dtstr, self.datas[0].bid[0], self.datas[0].ask[0],
                   self.datas[0].close[0]))
      
              print(txt)
              
              position = self.getposition(data=self.datas[0])
              rand = random.random()
              print('-------------')
              print ('Random:', rand)
              print('-------------')
              if rand < 0.2:
                  if position:
                      # SELL (with all possible default parameters)
                      self.log('SELL CREATE '.format(self.data.bid[0]))
      
                      # Keep track of the created order to avoid a 2nd order
                      self.order = self.sell(data=self.datas[0])
                      print ('Bid', self.data.bid[0])
              elif rand > 0.8:
                  if not position:
                      # BUY (with all possible default parameters)
                      self.log('BUY CREATE {}'.format(self.data.ask[0]))
      
                      # Keep track of the created order to avoid a 2nd order
                      self.order = self.buy(data=self.datas[0])
                      self.log('Executed Price:{}'.format(self.order.executed.price))
                      print ('Executed Price:', self.order.executed.price)
                      print ('ASK', self.data.ask[0])
                      
      

      and finale code:

      def parse_args():
          parser = argparse.ArgumentParser(
              description='Bid/Ask Line Hierarchy',
              formatter_class=argparse.ArgumentDefaultsHelpFormatter,
          )
      
          parser.add_argument('--data', '-d', action='store',
                              required=False, default='bidask.csv',
                              help='data to add to the system')
      
          parser.add_argument('--dtformat', '-dt',
                              required=False, default='%m/%d/%Y %H:%M:%S',
                              help='Format of datetime in input')
      
          return parser.parse_args()
      
      
      def runstrategy():
          args = parse_args()
      
          cerebro = bt.Cerebro()  # Create a cerebro
             
          data = BidAskCSV(dataname=args.data, dtformat=args.dtformat)
          cerebro.adddata(data)  # Add the 1st data to cerebro
          # Set our desired cash start
          cerebro.broker.setcash(100000.0)
          
          # Add the strategy to cerebro
          cerebro.addstrategy(St)    
          
              # Add a FixedSize sizer according to the stake
          cerebro.addsizer(bt.sizers.FixedSize, stake=10)
          
          # 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())
        
      
      if __name__ == '__main__':
          runstrategy()
      

      This is what I get as output:

      Starting Portfolio Value: 100000.00
         1: 2010-02-03T23:59:59.999989 - Bid 0.5346 - 0.5347 Ask, CLOSE 0.5347 
      -------------
      Random: 0.329840335116921
      -------------
         2: 2010-02-03T23:59:59.999989 - Bid 0.5343 - 0.5347 Ask, CLOSE 0.5347 
      -------------
      Random: 0.680459956622627
      -------------
         3: 2010-02-03T23:59:59.999989 - Bid 0.5543 - 0.5545 Ask, CLOSE 0.5545 
      -------------
      Random: 0.04838233726017549
      -------------
         4: 2010-02-03T23:59:59.999989 - Bid 0.5342 - 0.5344 Ask, CLOSE 0.5344 
      -------------
      Random: 0.7977225266469058
      -------------
         5: 2010-02-03T23:59:59.999989 - Bid 0.5245 - 0.5464 Ask, CLOSE 0.5464 
      -------------
      Random: 0.8661165246756014
      -------------
      2010-02-03T23:59:59.999989, BUY CREATE 0.5464
      2010-02-03T23:59:59.999989, Executed Price:0.0
      Executed Price: 0.0
      ASK 0.5464
         6: 2010-02-03T23:59:59.999989 - Bid 0.5460 - 0.5470 Ask, CLOSE 0.5470 
      -------------
      Random: 0.7797905933237207
      -------------
         7: 2010-02-03T23:59:59.999989 - Bid 0.5824 - 0.5826 Ask, CLOSE 0.5826 
      -------------
      Random: 0.585687043100518
      -------------
         8: 2010-02-03T23:59:59.999989 - Bid 0.5371 - 0.5374 Ask, CLOSE 0.5374 
      -------------
      Random: 0.2171674683269379
      -------------
         9: 2010-02-03T23:59:59.999989 - Bid 0.5793 - 0.5794 Ask, CLOSE 0.5794 
      -------------
      Random: 0.6576887524911412
      -------------
        10: 2010-02-03T23:59:59.999989 - Bid 0.5684 - 0.5688 Ask, CLOSE 0.5688 
      -------------
      Random: 0.406599019686264
      -------------
      Final Portfolio Value: 100000.00
      

      I don't understand what I am doing wrong, and why the orders are not being executed. Can I get some help here? Thanks!

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