10

I'm using pyalgotrade for a trading strategy where I want to use multiple tickers in a list.

The way it is set up now, it runs the strategy for each individual ticker in the list, but what I want it to do is to run them all as one, composite strategy.

How do I go about doing this?

Here is the code:

    from pyalgotrade.tools     import yahoofinance
    from pyalgotrade           import strategy
    from pyalgotrade.barfeed   import yahoofeed
    from pyalgotrade.technical import stoch
    from pyalgotrade           import dataseries
    from pyalgotrade.technical import ma
    from pyalgotrade           import technical
    from pyalgotrade.technical import highlow
    from pyalgotrade           import talibext
    from pyalgotrade.talibext  import indicator
    import numpy as np
    import talib


    testlist = ['aapl', 'msft', 'z']

    class MyStrategy( strategy.BacktestingStrategy ):

        def __init__( self, feed, instrument ):
            strategy.BacktestingStrategy.__init__( self, feed )
            self.__position = []
            self.__instrument = instrument
            self.setUseAdjustedValues( True )
            self.__prices = feed[instrument].getPriceDataSeries()

            self.__stoch = stoch.StochasticOscillator( feed[instrument], 20, dSMAPeriod = 3, maxLen = 3 )

        def onBars( self, bars ):

            self.__PPO = talibext.indicator.PPO( self.__prices, len( self.__prices ), 12, 26, matype = 1 )

            try: slope = talib.LINEARREG_SLOPE( self.__PPO, 3 )[-1]
            except Exception: slope = np.nan


            bar = bars[self.__instrument]
            self.info( "%s,%s,%s" % ( bar.getClose(), self.__PPO[-1], slope ) )

            if self.__PPO[-1] is None:
                return

            for inst in self.__instrument:
                print inst
               #INSERT STRATEGY HERE

def run_strategy():
    # Load the yahoo feed from the CSV file
    instruments = ['aapl', 'msft', 'z']
    feed = yahoofinance.build_feed(instruments,2015,2016, ".")

    # Evaluate the strategy with the feed.
    myStrategy = MyStrategy(feed, instruments)
    myStrategy.run()
    print "Final portfolio value: $%.2f" % myStrategy.getBroker().getEquity()




run_strategy()
RageAgainstheMachine
  • 901
  • 2
  • 11
  • 28
  • I would suggest leading with `from pyalgotrade import *`, because it seems a little exhaustive to do the individuals, unless there is variable contradiction in the class. – GreenHawk1220 Dec 10 '16 at 00:08
  • @GreenHawk1220 Thanks, will do! Any idea how to get this running with multiple instruments? – RageAgainstheMachine Dec 10 '16 at 00:52
  • You'll need to find a way to combine them all together. I'm not familiar with the `pyalgotrade` library, but I think you problem is that you are running each element in an array individually. I may be wrong, though. I would suggest finding some way to combine the array to where you can still work with it, but I could very well be wrong, 'cause I'm really unfamiliar with `pyalgotrade`. – GreenHawk1220 Dec 10 '16 at 17:12
  • `from pyalgotrade import *` imports the whole library... Which is a bit much for this... It will slow things down – Jamie Lindsey Mar 04 '20 at 12:01

2 Answers2

2

You can use this example as a guide for trading multiple instruments: http://gbeced.github.io/pyalgotrade/docs/v0.18/html/sample_statarb_erniechan.html

Gabriel
  • 492
  • 3
  • 4
2

feed is instance of pyalgotrade.feed.BaseFeed. it contains one or many instruments' BarDataSeries which defines a sequence of prices. When call feed[instrument], you get this instrument's BarDataSeries. You need a for loop to process each individual instrument. And It will make your code clean to add a dedicated class to handle each instrument. See the class InstrumentManager. And I fix many program errors.

class InstrumentManager():
    def __init__(self, feed, instrument):
        self.instrument = instrument

        self.__prices = feed[instrument].getPriceDataSeries()

        self.__stoch = stoch.StochasticOscillator( feed[instrument], 20, dSMAPeriod = 3, maxLen = 3 )

        self.__signal = None

    def onBars(self, bars):
        bar = bars.getBar(self.instrument)
        if bar:
            self.__PPO = talibext.indicator.PPO( self.__prices, len( self.__prices ), 12, 26, matype = 1 )

            try: slope = talib.LINEARREG_SLOPE( self.__PPO, 3 )[-1]
            except Exception: slope = np.nan

            print( "%s,%s,%s" % ( bar.getClose(), self.__PPO[-1], slope ) )

            if self.__PPO[-1] is None:
                return

            # set signal in some conditions. eg self.__signal = 'buy'

    def signal():
        return self.__signal

class MyStrategy( strategy.BacktestingStrategy ):

    def __init__( self, feed, instruments ):
        strategy.BacktestingStrategy.__init__( self, feed )
        self.__position = []
        self.__feed = feed
        self.__instruments = instruments
        self.setUseAdjustedValues( True )
        self.instManagers = {}
        self.loadInstManagers()

    def loadInstManagers(self):
        for i in self.__instruments:
            im = InstrumentManager(self.__feed, i)

            self.instManagers[i] = im

    def updateInstManagers(self, bars):
        for im in self.instManagers.values():
            im.onBars(bars)

    def onBars( self, bars ):
        self.updateInstManagers(bars)

        for inst in self.__instruments:
            instManager = self.instManagers[inst]
            print inst

            # Do something by instManager.signal()
gzc
  • 8,180
  • 8
  • 42
  • 62