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/

    Need Help on Backtesting with Oanda Data

    General Code/Help
    2
    2
    1626
    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.
    • vensaiten
      vensaiten last edited by

      I need help on few problems I had while using Oanda data.

      Before anything, I tried oandatest.py and it worked fine.

      python oandatest.py --token XXXX --account 0000 --data0 EUR_USD --timeframe Minutes --historical
      

      gave me

      --------------------------------------------------
      Strategy Created
      --------------------------------------------------
      -- Contract Details:
      {'instrument': 'EUR_USD', 'displayName': 'EUR/USD', 'pip': '0.0001', 'maxTradeUnits': 10000000}
      Datetime, Open, High, Low, Close, Volume, OpenInterest, SMA
      ***** DATA NOTIF: DELAYED
      Data0, 0001, 736732.538194, 2018-02-07T12:55:00.000000, 1.234450, 1.234540, 1.234320, 1.234320,     46, 0, nan
      .
      .
      .
      Data0, 0500, 736633.366667, 2017-10-31T08:48:00.000000, 1.164445, 1.164460, 1.164300, 1.164325,     18, 0, 1.164377
      ***** DATA NOTIF: DISCONNECTED
      

      Then I tried to test the strategy from "Quickstart"

      import backtrader as bt
      from datetime import datetime  # For datetime objects
      
      #Oanda Account Info
      api_key = "XXXX"
      account_number = "0000"
      
      # Create a Stratey
      class TestStrategy(bt.Strategy):
      
          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 __init__(self):
              # Keep a reference to the "close" line in the data[0] dataseries
              self.dataclose = self.datas[0].close
      
          def next(self):
              # Simply log the closing price of the series from the reference
              self.log('Close, %.2f' % self.dataclose[0])
      
      if __name__ == '__main__':
      
          cerebro = bt.Cerebro()
      
          cerebro.addstrategy(TestStrategy)
      
          oandastore = bt.stores.OandaStore(token=api_key, account=account_number, practice=True)
      
          cerebro.broker = oandastore.getbroker()
      
          data = oandastore.getdata(
              dataname = "USD_JPY",
              timeframe = bt.TimeFrame.Minutes,
              compression = 30,
              fromdate = datetime(2017,11,1),
              todate=datetime(2017,11,30)
              )
      
          # Add data
          cerebro.adddata(data)
      
          print('Starting Portfolio Value: %.2f' % cerebro.broker.getvalue())
      
          cerebro.run()
      
          print('Final Portfolio Value: %.2f' % cerebro.broker.getvalue())
      
          # Finally plot the end results
          cerebro.plot(style="candle")
      

      It worked but with two problems:
      One problem is compression of 30 and below shows no log.

      Starting Portfolio Value: 0.00
      position for instrument: USD_JPY
      Final Portfolio Value: 96053.55
      

      But compression of 60 and above does show logs.

      Starting Portfolio Value: 0.00
      position for instrument: USD_JPY
      2017-11-01, Close, 113.88
      2017-11-01, Close, 113.90
      .
      .
      .
      2017-11-29, Close, 112.00
      2017-11-30, Close, 111.98
      Final Portfolio Value: 96053.55
      

      Is there a problem with my coding or is it the practice server thing?

      Second problem is that, as you can see from above logs, "Starting Portfolio Value:" is 0 and "Final Portfolio Value:" shows the amount of USD I have on Oanda account. Aren't those two supposed to be same?

      Lastly, when I change the strategy to the next one (compression=60 and keeping everything else same),

      class TestStrategy(bt.Strategy):
      
          def log(self, txt, dt=None):
              ''' Logging function fot this strategy'''
              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
              self.order = None
      
          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, %.2f' % order.executed.price)
                  elif order.issell():
                      self.log('SELL EXECUTED, %.2f' % order.executed.price)
      
                  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 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.dataclose[-1]:
                          # current close less than previous close
      
                          if self.dataclose[-1] < self.dataclose[-2]:
                              # previous close less than the previous close
      
                              # BUY, BUY, BUY!!! (with 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:
      
                  # Already in the market ... we might sell
                  if len(self) >= (self.bar_executed + 5):
                      # 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()
      

      I get an error of AttributeError: 'Lines_LineSeries_LineIterator_DataAccessor_Strateg' object has no attribute 'bar_executed' What do I need to do?

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

        @vensaiten said in Need Help on Backtesting with Oanda Data:

        One problem is compression of 30 and below shows no log.

        This may be due to a bug in the OandaData feed, which was using the same code to retrieve 5 minutes bars as to retrieve 10, 15 and 30 minutes bars. Recalling things, the codes were copied verbatim from Oanda's reference documentation, but they are different today. Regardless of the source it has been pushed.

        @vensaiten said in Need Help on Backtesting with Oanda Data:

        I get an error of AttributeError: 'Lines_LineSeries_LineIterator_DataAccessor_Strateg' object has no attribute 'bar_executed' What do I need to do?

        Initialize self.bar_executed somewhere in your code.

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