Navigation

    Backtrader Community

    • Register
    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    1. Home
    2. ruiarruda
    For code/output blocks: Use ``` (aka backtick or grave accent) in a single line before and after the block. See: http://commonmark.org/help/
    R
    • Profile
    • Following 0
    • Followers 0
    • Topics 1
    • Posts 4
    • Best 0
    • Groups 0

    ruiarruda

    @ruiarruda

    0
    Reputation
    1
    Profile views
    4
    Posts
    0
    Followers
    0
    Following
    Joined Last Online

    ruiarruda Unfollow Follow

    Latest posts made by ruiarruda

    • RE: Transactions happen for times that don't exist in source data

      @davidavr thanks a lot, the problem wasn't so complicated afterall

      @run-out thank you for the pointer, I'll consult it

      posted in General Code/Help
      R
      ruiarruda
    • RE: Transactions happen for times that don't exist in source data

      @run-out Thanks a lot for your code. Was great to learn that I was setting the buy price incorrectly.

      However, the most confusing issue still stands: the RSI indicator, which I initialize but do NOT use (intentionally, at least), is somehow necessary for the code to run (if you comment it out on your code, the code breaks). Also, the script waits for the RSI period (14) to be over before starting to search for the buy signal. I don't understand it...

      Regarding the take profit limit price of .8%... I don't get why it would be a problem. In fact it leads to a higher p&l than 5% on this very code. Also, I ran a live bot for some time with that take profit and it was profitable, and I selected it after running my own simple backtest on different options for the price. Can I not trust Backtrader backtesting results if I use .8% as the limit price?

      posted in General Code/Help
      R
      ruiarruda
    • RE: Transactions happen for times that don't exist in source data

      @run-out thank you. I couldn't reproduce the problem again (that's how lost I am), but in my attempts I realized some things:

      • An indicator (RSI) I still had from the template code I had copy-pasted is influencing the strategy even though I don't use it anywhere after declaring it, and in fact I can't even run the code if I comment it out. I get the message "ValueError: min() arg is an empty sequence"

      • I'm trying to trade when the price hits a 3-hour low, placing a bracket order with that price as the buy price, and a take profit 0.8% higher and a stop loss 5% lower. That buy signal of mine apparently only starts being searched for after the period of the RSI is over... Couldn't be more lost

      • The order notification (and the transaction analyzer, sometimes) shows <backtrader.linebuffer.LineBuffer object at ...> instead of the price for the buy order only, showing a decimal number, as expected, for the other ones

      • Also, that price of the buy order, that I can't see as I explained above, is apparently set as the low price of the NEXT candle after the buy signal is found (I expected it to be set to the current candle's low and only buy if the price is met on the next candle)

      I'm rather stunned at how little sense I can make of anything that is happening. Here is the full code:

      import backtrader as bt
      from datetime import datetime
      import backtrader.analyzers as btanalyzers
      import yfinance
      
      class firstStrategy(bt.Strategy):
      
          def __init__(self):
              self.min_profit_sell = 0.008
              self.stop_loss = .05
              self.rsi = bt.indicators.RSI_SMA(self.data.close, period=14)
              self.orefs = []
      
          def notify_order(self, order):
              print('{}: Order ref: {} / Type {} / Status {} / Size {} / Price {}'.format(
                  self.data.datetime.datetime(0),
                  order.ref, 'Buy' * order.isbuy() or 'Sell',
                  order.getstatusname(),
                  round(order.size, 2),
                  'NA' if not order.price else order.price))
      
              if order.status == order.Completed:
                  self.holdstart = len(self)
      
              if not order.alive() and order.ref in self.orefs:
                  self.orefs.remove(order.ref)
      
                  
          def next(self):
              self.interval_low = min(self.data.low.get(size=3))
              print (self.data.low.get(size=1))
              if not self.position:
                  if self.data.low == self.interval_low:
                      limitprice = self.data.low * (1 + self.min_profit_sell)
                      print (f'Limit buy price: {self.data.low.get(size=1)[0]}')
                      print (f'Take profit price: {limitprice}')
                      stopprice = self.data.low * (1 - self.stop_loss)
                      print (f'Stop loss price: {stopprice}')
                      os = self.buy_bracket(size=100, limitprice=limitprice, price=self.data.low, stopprice=stopprice)
                      self.orefs = [o.ref for o in os]
      
      #Variable for our starting cash
      startcash = 10000
      
      #Create an instance of cerebro
      cerebro = bt.Cerebro()
      
      #Add our strategy
      cerebro.addstrategy(firstStrategy)
      
      a = yfinance.download(tickers="VGAC",period="max",interval="60m", groupby='ticker', prepost=True)
      data = bt.feeds.PandasData(dataname=a, name='VGAC')
      
      #Add the data to Cerebro
      cerebro.adddata(data)
      
      # Set our desired cash start
      cerebro.broker.setcash(startcash)
      
      # save a CSV with results
      cerebro.addwriter(bt.WriterFile, csv=True, out='backtest.csv')
      
      cerebro.addanalyzer(btanalyzers.Transactions, _name = "trans")
      cerebro.addanalyzer(btanalyzers.TradeAnalyzer, _name = "trades")
      
      # Run over everything
      back = cerebro.run()
      
      #Get final portfolio Value
      portvalue = cerebro.broker.getvalue()
      pnl = portvalue - startcash
      

      Thanks a lot to you or anyone who can point me in the right direction to not give up on this library before even really starting

      posted in General Code/Help
      R
      ruiarruda
    • Transactions happen for times that don't exist in source data

      I'm trying to use the Pandas Data Feed to load data and run a strategy. I load it like this:

      import yfinance
      a = yfinance.download(tickers="VGAC",period="max",interval="60m", groupby='ticker', prepost=True)
      data = bt.feeds.PandasData(dataname=a, name='VGAC')
      

      I add a transactions analyzer and run the strategy like this:

      cerebro.addanalyzer(btanalyzers.Transactions, _name = "trans")
      back = cerebro.run()
      

      And I then look at the transactions like this:

      back[0].analyzers.trans.get_analysis()
      

      To my surprise there are many transactions happening with a datetime that isn't in the source data. For instance, a transaction at (datetime.datetime(2020, 11, 25, 19, 30), when that value isn't in the source data (the "a" dataframe) datetime column.

      Does backtrader automatically fill gaps in candles? Or what is happening here? Couldn't find references to this in the documentation. After simplifying my tests by orders of magnitude in an attempt to obtain a result I actually understand and expect, I still can't. Surely it is because I lack in intellectual capacity, as apparently after several years of coding without major hassles, I discover a library that somehow is super easy to use for everyone else but makes me the most lost I've ever been when trying to tackle any problem, ever.

      posted in General Code/Help
      R
      ruiarruda