Navigation

    Backtrader Community

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

    Mark Weaver

    @Mark Weaver

    0
    Reputation
    10
    Profile views
    5
    Posts
    0
    Followers
    0
    Following
    Joined Last Online

    Mark Weaver Unfollow Follow

    Latest posts made by Mark Weaver

    • RE: How to deal with multiple stocks data with multiple timeframes?

      @Suraj-Thorat I've had similar challenge.. I've settled on doing something like this in init and next. I check the _compression of the data to determine which datafeeds i want to setup indicators for, run calculations against, etc

               def next(self):
                      if data._compression==self.p.largerCompression:
                          # do the larger timeframe stuff here
                      if data._compression==self.p.smallerCompression:
                          # do the smaller timeframe stuff here
      

      I've been able to add pairs of data feeds, one for each timeframe, for a couple dozen stocks and run them against months of data.. (takes a while obviously)

      posted in General Discussion
      Mark Weaver
      Mark Weaver
    • RE: strategy.getposition returning different values for same ticker on different timeframes

      @backtrader OK thanks for response :) It has nothing to do with me expecting an AI to have belief in other AI entities or any of whatever you're trying to imply.

      It has to do with the simple expectation--of a framework--that a BUY order executed for a given symbol will have a position size reflected in any query on that same symbol, regardless of whatever timeframe the orders or queries are being executed on. It is counter-intuitive to operate in any other way.

      I will work around that, and I will see what Alpaca has to say and post back here if its relevant. Cheers!

      posted in General Code/Help
      Mark Weaver
      Mark Weaver
    • RE: strategy.getposition returning different values for same ticker on different timeframes

      @Mark-Weaver Also, please don't assume that I'm expecting magical behavior out of this. I already have code which is attempting to manage my position sizes without having to rely on that particular broker call. Above is just an example to demonstrate the particular issue and question I have about it, because this behavior didn't immediately make sense to me

      posted in General Code/Help
      Mark Weaver
      Mark Weaver
    • RE: strategy.getposition returning different values for same ticker on different timeframes

      @backtrader hehe fair enough & clever. But that begs the question, if I have a DataFeed for FCEL on a 5m aggregation, and I send a buy order through the broker API, what is it actually buying, that's different than, say, the underlying instrument behind the FCEL datafeed on a 1M aggregration?

      I expected that there was a member variable within the DataFeed representing the symbol itself, independent of timeframe, but i was not able to see it in docs, or in dir(data), or elsewhere. I don't see it as a parameter in the buy function. I just see data relating back to the symbol. So why would the broker interface return different position values for FCEL 5M vs FCEL 1M? Is that how it would work in live trading?

      posted in General Code/Help
      Mark Weaver
      Mark Weaver
    • strategy.getposition returning different values for same ticker on different timeframes

      The gist here is to generate a signal on a larger timeframe (e.g. 5M) and trigger a buy off a smaller timeframe (e.g. 1M).. I am using Alpaca as the broker here, and have not ruled out that it could be an issue there.

      I am seeing BUYS on the smaller timeframe, but cannot retrieve accurate position information on the larger timeframe. It is as if the broker is treating these both as 2 separate tickers

      You can see that the position only increases on the smaller timeframe:

      enumerating in next!  name: FCEL compression: 1 posSize = 300 2020-02-03 14:24:00 cash: 9534.0 close: 1.56
      enumerating in next!  name: FCEL compression: 5 posSize = 0 2020-02-03 14:20:00 cash: 9534.0 close: 1.55
       setting signalHigh: 1.55.. will buy if we close over it on the smaller timeframe
      next!
      enumerating in next!  name: FCEL compression: 1 posSize = 400 2020-02-03 14:25:00 cash: 9379.0 close: 1.55
      enumerating in next!  name: FCEL compression: 5 posSize = 0 2020-02-03 14:25:00 cash: 9379.0 close: 1.55
       setting signalHigh: 1.56.. will buy if we close over it on the smaller timeframe:
      

      the posSize value is retrieved via

      for i, d in enumerate(self.datas):
                  posSize = self.getposition(d).size
      

      I have tried mucking with the datanames in the DataFeeds.. I have tired using 2 separately created DataFeeds, and 1 DataFeed along with a resampled feed

      Code example:

      import alpaca_backtrader_api
      import backtrader as bt
      import conf
      from datetime import datetime
      
      # 14:30:00 GMT is market open!
      
      ALPACA_API_KEY = conf.paper_api_key
      ALPACA_SECRET_KEY = conf.paper_api_secret
      ALPACA_PAPER = True
      
      triggerPeriod = 1
      signalPeriod = 5
      
      class TestyStrat(bt.Strategy): # for demo'ing issue
          params = (('signalCompression',30),('triggerCompression',5),)
          def __init__(self):
              print(f"init TestyStrat # datas: {len(self.datas)}")
      
              self.ema8_map = {}
              self.signalHigh = None
      
              for i, d in enumerate(self.datas):
                  print(f" TestyStrat enumerating {d._name} compression={d._compression} {dir(d)}")
                  # dir(d)
      
                  if d._compression==self.p.signalCompression:
                      self.ema8_map[d._name] = bt.ind.EMA(d.close, period=8)
      
              print("Done with init TestyStrat")
      
          def next(self):
              print("\nnext!")
              for i, d in enumerate(self.datas):
                  posSize = self.getposition(d).size
                  print(f"enumerating in next!  name: {d._name} compression: {d._compression} posSize = {posSize} {d.num2date()} cash: {self.broker.get_cash()} close: {d.close[0]}")
                  if d._compression==self.p.signalCompression:
                      # we just trigger SELLS on this larger timeframe
                      if self.ema8_map[d._name][0] > self.ema8_map[d._name][-1]:
                          print(f" setting signalHigh: {d.high[0]}.. will buy if we close over it on the smaller timeframe")
                          self.signalHigh = d.high[0]
                  elif d._compression==self.p.triggerCompression:
                      # we just trigger BUYS on this smaller timeframe
                      if self.signalHigh is not None and d.close[0] > self.signalHigh:
                          self.buy(d, 100)
      
      
          # end class TestyStrat -------------
      
      cerebro = bt.Cerebro(writer=True)
      # cerebro.addstrategy(AscPairMAsByATRStrategy)
      cerebro.addstrategy(TestyStrat,signalCompression=signalPeriod, triggerCompression=triggerPeriod) #{'signalCompression':5, 'triggerCompression':2}))
      #cerebro.addstrategy(SmaCross)
      cerebro.addsizer(bt.sizers.PercentSizerInt, percents=25)
      print("Added sizer")
      store = alpaca_backtrader_api.AlpacaStore(
          key_id=ALPACA_API_KEY,
          secret_key=ALPACA_SECRET_KEY,
          paper=ALPACA_PAPER
      )
      
      if not ALPACA_PAPER:
        broker = store.getbroker()  # or just alpaca_backtrader_api.AlpacaBroker()
        cerebro.setbroker(broker)
      
      DataFactory = store.getdata  # or use alpaca_backtrader_api.AlpacaData
      
      def addData(symbol):
          trigger  = DataFactory(dataname=symbol, historical=True, fromdate=datetime(2020,2,3),
                          todate=datetime(2020,2,6),
                          timeframe=bt.TimeFrame.Minutes, compression=triggerPeriod)
      
          # smallest timeframes FIRST!!
          cerebro.adddata(trigger, name=symbol) # name=f"{symbol}{triggerPeriod}m"
          cerebro.resampledata(trigger, timeframe=bt.TimeFrame.Minutes, compression=signalPeriod, name=symbol)
      
      addData("FCEL")
      
      print('Starting Portfolio Value: %.2f' % cerebro.broker.getvalue())
      cerebro.run()
      print('Final Portfolio Value: %.2f' % cerebro.broker.getvalue())
      cerebro.plot(style='candlestick',barup='green', bardown='red')
      print("fini...")
      
      posted in General Code/Help
      Mark Weaver
      Mark Weaver