Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create a composite strategy, using multiple instruments, in Pyalgotrade?

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()
like image 802
RageAgainstheMachine Avatar asked Dec 07 '16 00:12

RageAgainstheMachine


2 Answers

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

like image 192
Gabriel Avatar answered Oct 24 '22 07:10

Gabriel


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()
like image 23
gzc Avatar answered Oct 24 '22 06:10

gzc