0

I'm working with Pyalgotrade to test a trading strategy in python. Pyalgotrade allows for the use of a library called TA-LIB,which is a technical analysis library. For some reason, when I use the PPO indicator it returns "None". The indicator takes in a few arguments:(http://gbeced.github.io/pyalgotrade/docs/v0.12/html/talib.html)

I provided a snippet of the output which for now is only the closing stock price of the day and what was supposed to be the output from this indicator. 'DDD' is the ticker I've been testing with.

I've been trying to get this to work for longer than I would like to admit. How can I fix this?

OUTPUT:

2016-11-08 00:00:00 strategy [INFO] 13.56,None
2016-11-09 00:00:00 strategy [INFO] 13.77,None
2016-11-10 00:00:00 strategy [INFO] 14.06,None
2016-11-11 00:00:00 strategy [INFO] 14.71,None
2016-11-14 00:00:00 strategy [INFO] 14.3,None
2016-11-15 00:00:00 strategy [INFO] 13.91,None

Here's my code:

from pyalgotrade import strategy
from pyalgotrade.tools import yahoofinance
from pyalgotrade import talibext
from pyalgotrade.talibext import indicator
import talib
import numpy

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

        self.__PPO = talibext.indicator.PPO(feed,0,12,26,9)

    def onEnterOk(self, position):
        execInfo = position.getEntryOrder().getExecutionInfo()
        self.info("BUY at $%.2f" % (execInfo.getPrice()))

    def onEnterCanceled(self, position):
        self.__position = None

    def onExitOk(self, position):
        execInfo = position.getExitOrder().getExecutionInfo()
        self.info("SELL at $%.2f" % (execInfo.getPrice()))
        self.__position = None

    def onExitCanceled(self, position):
        # If the exit was canceled, re-submit it.
        self.__position.exitMarket()

    def onBars(self, bars):

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

    def run_strategy(inst):
    # Load the yahoo feed from the CSV file

    feed = yahoofinance.build_feed([inst],2015,2016, ".")

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


def main():
    instruments = ['ddd']
    for inst in instruments:
            run_strategy(inst)


if __name__ == '__main__':
        main()
RageAgainstheMachine
  • 901
  • 2
  • 11
  • 28

1 Answers1

2

The parameters you passed are wrong. This is PPO function signature:

def PPO(ds, count, fastperiod=-2**31, slowperiod=-2**31, matype=0):

ds type is BarDataSeries, count specify how long data from tail do you want to calculate. It will return a numpy array if calculation succeed.

And talibext indicators calculate only once, it won't calculate new result when new bar is fed.

So you need to calculate PPO in every onBars call.

def __init__(self, feed, instrument):
    ...

    self.__feed = feed

def onBars(self, bars):
    feed = self.__feed
    self.__PPO = talibext.indicator.PPO(feed[self.__instrument], len(feed[self.__instrument]),12,26, matype=0)
    bar = bars[self.__instrument]
    self.info("%s,%s" % (bar.getClose(),self.__PPO[-1]))
gzc
  • 8,180
  • 8
  • 42
  • 62
  • I replaced feed[self.__instrument] with self.__prices, now its spitting out data. However, I have no idea what the data is. I'm trying to get the 3 day slope of the PPO Histogram. http://stockcharts.com/articles/chartwatchers/2011/04/using-the-ppo-indicator.html – RageAgainstheMachine Nov 17 '16 at 14:08
  • See update. You want to save `feed` in `__init__` and use it in `onBars`. – gzc Nov 17 '16 at 15:34
  • thanks. any ideas about the 3 day slope of the PPO Histogram?? – RageAgainstheMachine Nov 17 '16 at 15:36
  • PPO is based on EMA. Since PPO in talib is a bit different from what you want, I think you can implement one by yourself. – gzc Nov 17 '16 at 15:55
  • Also, why is it that for each date I get a whole list of data? How can I just get the corresponding data per date? I also realized the data coming out is the black line of the PPO when I use ma=1. I'm trying to use this in the onbars but still no luck(I need either the angle or the slope): self.__Slope = talibext.indicator.LINEARREG_ANGLE(self.__PPO,3) – RageAgainstheMachine Nov 17 '16 at 16:58
  • Because talib indicators don't have interface to feed bars one by one, It accept whole array and output whole array. You just get `self.__PPO[-1]` per date. For slope, try `talibext.indicator.LINEARREG_ANGLE(self.__PPO, len(self.__PPO), 3)`. And you need to clarify how to pass parameters to talib indicators before using them, refer [talib wrapper](https://github.com/gbeced/pyalgotrade/blob/master/pyalgotrade/talibext/indicator.py) – gzc Nov 17 '16 at 17:43
  • the self.__PPO[-1] works like a charm. Small problem, the talibext.indicator.LINEARREG_ANGLE(self.__PPO, len(self.__PPO), 3) returns the error: "Exceptions: all inputs are nan" (appreciate all the help btw) – RageAgainstheMachine Nov 17 '16 at 17:57
  • I found this in the link you provided: def LINEARREG_ANGLE(ds, count, timeperiod=-2**31): """Linear Regression Angle""" return call_talib_with_ds(ds, count, talib.LINEARREG_ANGLE, timeperiod) What you suggested I input seems like it matches the criteria for the inputs...data,#periods, time period). – RageAgainstheMachine Nov 17 '16 at 18:10
  • do i need to put the ppo output into a dataseries before i put it into the linear angle ?? If so, how would I do that? – RageAgainstheMachine Nov 17 '16 at 21:05
  • Yes. You can use `talib.LINEARREG_ANGLE(self.__PPO, 3)` directly, which you can avoid extra convertion. – gzc Nov 18 '16 at 14:33
  • Strange because I know there is something in self.__PPO – RageAgainstheMachine Nov 18 '16 at 14:42
  • In first several days, self.__PPO output are all nan. Just wrap this in try-catch statement. – gzc Nov 18 '16 at 14:48
  • "Just wrap this in try-catch statement". can you explain this? – RageAgainstheMachine Nov 18 '16 at 15:10
  • `try: slope = talib.LINEARREG_ANGLE(self.__PPO, 3)[-1] except Exception: slope = numpy.nan` – gzc Nov 18 '16 at 15:12
  • dude it works!!!! Thank you! Thank you! The only thing is that when I use self.info("%s,%s" % (bar.getClose(),self.__PPO[-1], slope)) to see the printout i get the error "TypeError: not all arguments converted during string formatting". It works when I remove self.__PPO[-1], I suspect its because since their are nan's in "slope" it bugs. Any idea? THANK YOU! – RageAgainstheMachine Nov 18 '16 at 15:40
  • Congratulations! And please accept my answer by clicking **√**. – gzc Nov 18 '16 at 15:43
  • You lose a `%s` – gzc Nov 18 '16 at 15:45
  • Can't believe i missed that. Thanks! Any chance you would be interested in swapping emails? – RageAgainstheMachine Nov 18 '16 at 16:12
  • Of course. You can contact me via zhecong123@126.com – gzc Nov 18 '16 at 16:17