Больше примеров для профилировщика событий в pyalgotrade

Я пытаюсь узнать, как внедрить пользовательские стратегии в профилировщик событий для pyalgotrade. Это пример по умолчанию, который они дают.

from pyalgotrade           import eventprofiler
from pyalgotrade.technical import stats
from pyalgotrade.technical import roc
from pyalgotrade.technical import ma
from pyalgotrade.tools     import yahoofinance

#     Event inspired on an example from Ernie Chan's book:
#    'Algorithmic Trading: Winning Strategies and Their Rationale'

class BuyOnGap(eventprofiler.Predicate):
    def __init__(self, feed):
        stdDevPeriod = 90
        smaPeriod = 20
        self.__returns = {}
        self.__stdDev = {}
        self.__ma = {}
        for instrument in feed.getRegisteredInstruments():
            priceDS = feed[instrument].getAdjCloseDataSeries()
            #      Returns over the adjusted close values.
            self.__returns[instrument] = roc.RateOfChange(priceDS, 1)
            #      StdDev over those returns.
            self.__stdDev[instrument] = stats.StdDev(self.__returns[instrument], stdDevPeriod)
            #      MA over the adjusted close values.
            self.__ma[instrument] = ma.SMA(priceDS, smaPeriod)

    def __gappedDown(self, instrument, bards):
        ret = False
        if self.__stdDev[instrument][-1] != None:
            prevBar = bards[-2]
            currBar = bards[-1]
            low2OpenRet = (currBar.getAdjOpen() - prevBar.getAdjLow()) / float(prevBar.getAdjLow())
            if low2OpenRet < (self.__returns[instrument][-1] - self.__stdDev[instrument][-1]):
                ret = True
        return ret

    def __aboveSMA(self, instrument, bards):
        ret = False
        if self.__ma[instrument][-1] != None and bards[-1].getAdjOpen() > self.__ma[instrument][-1]:
            ret = True
        return ret

    def eventOccurred(self, instrument, bards):
        ret = False
        if self.__gappedDown(instrument, bards) and self.__aboveSMA(instrument, bards):
            ret = True
        return ret

def main(plot):
    instruments = ["AA", "AES", "AIG"]
    feed = yahoofinance.build_feed(instruments, 2008, 2009, ".")

    predicate = BuyOnGap(feed)
    eventProfiler = eventprofiler.Profiler(predicate, 5, 5)
    eventProfiler.run(feed, True)

    results = eventProfiler.getResults()
    print "%d events found" % (results.getEventCount())
    if plot:
        eventprofiler.plot(results)

if __name__ == "__main__":
    main(True)

Есть ли у кого-нибудь еще источник примеров?

Я пытаюсь выяснить, как eventprofiler принимает и использует данные, хотя и вызывается несколько методов класса, и я считаю, что анализировать их немного сложно.

Я хочу начать с простого и просто использовать price а также volume, Это одна стратегия будет
if volume > 1000 and close < 50: event == True

Любая помощь будет оценена.

PS: бонус вопрос: есть ли аналогичный профилировщик событий для zipline?

РЕДАКТИРОВАТЬ: Благодаря user3666197 я смог внести изменения, которые я хотел, однако я получаю эту ошибку:

Traceback (most recent call last):
  File "C:\Users\David\Desktop\Python\Coursera\Computational Finance\Week2\PyAlgoTrade\Bitfinex\FCT\FCT_single_event_test.py", line 43, in <module>
    main(True)
  File "C:\Users\David\Desktop\Python\Coursera\Computational Finance\Week2\PyAlgoTrade\Bitfinex\FCT\FCT_single_event_test.py", line 35, in main
    eventProfiler.run(feed, True)
  File "C:\Python27\lib\site-packages\pyalgotrade\eventprofiler.py", line 215, in run
    disp.run()
  File "C:\Python27\lib\site-packages\pyalgotrade\dispatcher.py", line 102, in run
    eof, eventsDispatched = self.__dispatch()
  File "C:\Python27\lib\site-packages\pyalgotrade\dispatcher.py", line 90, in __dispatch
    if self.__dispatchSubject(subject, smallestDateTime):
  File "C:\Python27\lib\site-packages\pyalgotrade\dispatcher.py", line 68, in __dispatchSubject
    ret = subject.dispatch() is True
  File "C:\Python27\lib\site-packages\pyalgotrade\feed\__init__.py", line 105, in dispatch
    self.__event.emit(dateTime, values)
  File "C:\Python27\lib\site-packages\pyalgotrade\observer.py", line 59, in emit
    handler(*args, **kwargs)
  File "C:\Python27\lib\site-packages\pyalgotrade\eventprofiler.py", line 172, in __onBars
    eventOccurred = self.__predicate.eventOccurred(instrument, self.__feed[instrument])
  File "C:\Python27\lib\site-packages\pyalgotrade\eventprofiler.py", line 89, in eventOccurred
    raise NotImplementedError()
NotImplementedError
[Finished in 1.9s]

Я посмотрел на источник 'eventprofiler.py' и не могу понять, что это такое. Вот код

from pyalgotrade import eventprofiler
from pyalgotrade.technical import stats
from pyalgotrade.technical import roc
from pyalgotrade.technical import ma
from pyalgotrade.barfeed import csvfeed

# Event inspired on an example from Ernie Chan's book:
# 'Algorithmic Trading: Winning Strategies and Their Rationale'

class single_event_strat( eventprofiler.Predicate ):
    def __init__(self,feed):
        self.__returns = {} # CLASS ATTR
        for inst in feed.getRegisteredInstruments():

            priceDS = feed[inst].getAdjCloseDataSeries() # STORE: priceDS ( a temporary representation )

            self.__returns[inst] = roc.RateOfChange( priceDS, 1 )
            # CALC:  ATTR <- Returns over the adjusted close values, consumed priceDS 
            #( could be expressed as self.__returns[inst] = roc.RateOfChange( ( feed[inst].getAdjCloseDataSeries() ), 1 ), 
            #but would be less readable

    def eventOccoured( self, instrument, aBarDS):
        if (aBarDS[-1].getVolume() > 1000 and aBarDS[-1].getClose() > 50 ):
            return True
        else: 
            return False

def main(plot):
    feed = csvfeed.GenericBarFeed(0)

    feed.addBarsFromCSV('FCT', "FCT_daily_converted.csv")

    predicate = single_event_strat(feed)
    eventProfiler = eventprofiler.Profiler(predicate, 5, 5)
    eventProfiler.run(feed, True)

    results = eventProfiler.getResults()
    print "%d events found" % (results.getEventCount())
    if plot:
        eventprofiler.plot(results)

if __name__ == "__main__":
    main(True)

2 ответа

Решение

Квант Пролог:

Большое спасибо проф. Такер Балч, GA-TECH [GA], и его команда, для QSTK Инициативные и инновационные подходы к количественному моделированию финансов. введите описание изображения здесь

Как eventprofiler принимает данные?

Просто он получает доступ к полному feed оба в eventprofiler.run(feed, ... ) а также как eventprofiler.Predicate -wrapped feed где он получает доступ ко всем деталям подачи прямо в .Predicate Экземпляр по параметру Class, чтобы можно было рассчитать, реализованы ли все детали, требуемые для расчета стратегии. Умный, не так ли?

Все остальное делается путем повторного использования их методов класса.


Как построить свое?

Этого вполне достаточно, чтобы объявить eventprofiler.Predicate, который будет введен в evenprofiler конкретизации:

class DavidsSTRATEGY( eventprofiler.Predicate ):
      def __init__( self, feed ):                         # mandatory .__init__
          """                                               no need for this code
                                                            left here for didactic
                                                            purposes only
                                                            to show the principle

          self.__returns = {}                                         # CLASS ATTR

          for                inst in feed.getRegisteredInstruments():
              priceDS = feed[inst].getAdjCloseDataSeries()            # STORE: priceDS ( a temporary representation )
              self.__returns[inst] = roc.RateOfChange( priceDS, 1 )   # CALC:  ATTR <- Returns over the adjusted close values, consumed priceDS ( could be expressed as self.__returns[inst] = roc.RateOfChange( ( feed[inst].getAdjCloseDataSeries() ), 1 ), but would be less readable
          """

      def eventOccurred( self, instrument, aBarDS ):       # mandatory .eventOccured
          if (   aBarDS[-1].getVolume() > 1000             # "last" Bar's Volume >
             and aBarDS[-1].getClose()  <   50             # "last" Bar's Close  <
             ):
                 return True
          else:
                 return False

Остальное будет так же просто, как всегда:

eventProfiler = eventprofiler.Profiler( predicate = DavidsSTRATEGY( feed ), 5, 5 )
eventProfiler.run( feed, True )

Квантовый Эпилог:

Внимательный читатель отметил, что предложенный код не вызывает .getAdjClose() метод. Причина заключается в том, что глубокое тестирование на истории может искажаться из-за очень близких корректировок при принятии решений во времена, когда корректировки еще не известны. Любой профессиональный количественный аналитик обязан избегать любых способов заглянуть в будущее и тщательно решить, где необходимы корректировки, в отношении оценки портфеля, если время удержания инструмента превысило корректировку, в пределах его соответствующего жизненного цикла, или не.

Бонусный ответ

Хотя мотивация вопроса ясна, есть несколько причин, почему ответ не так прост, как может показаться.

Во-первых, как все работает:

eventprofiler в QSTK а также pyalgotrade построен на вершине DataSeries представление рынка, где внешние данные вводятся (не хранятся) через feed -механизм.

zipline Этот подход отличается и утверждает, что основная функциональность сосредоточена на его механизме моделирования на основе событий, который работает на уровне атомарной роли каждой цены. QUOTE -tick (асинхронное поступление внешних событий и локальная адаптивная обработка).

Последовательный характер обработки потока событий имеет некоторую привлекательность для эмулируемого тестирования in-vitro.

Сильные стороны QSTK -originated eventprofiler напротив, основаны на обработке полной длины DataSeries -представления сразу (или какой-то умный итератор, вербальный или эффективный numpystride -tricks& Магия).

Это огромное концептуальное различие затрудняет получение такого же интеллектуального + быстрого + эффективного + простого в использовании инструмента, так как QSTKeventprofiler вне всякого сомнения, в среде обработки событий.

Другие вопросы по тегам