【问题标题】:More examples for the event profiler in pyalgotradepyalgotrade 中事件分析器的更多示例
【发布时间】:2016-05-19 07:11:42
【问题描述】:

我正在尝试学习如何在 pyalgotrade 的事件分析器中实施自定义策略。 This is the default example they give

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 如何接收和使用数据,虽然调用了很多类方法,但我发现剖析它有点棘手.

我想从简单的开始,只使用pricevolume。是的,一种策略是
if volume &gt; 1000 and close &lt; 50: event == True

任何帮助将不胜感激。

P.s.:额外问题: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)

【问题讨论】:

  • 更好地使用 复制/粘贴 以避免拼写错误 >>> stackoverflow.com/a/37442549/3666197 指出了在 def eventOccoured(...) 而不是 @987654334 中找到的一个@
  • 我下次再做。再次感谢您的详细回答,非常感谢。

标签: python quantitative-finance algorithmic-trading zipline pyalgotrade


【解决方案1】:

量化序言:

Many thanks to prof. Tucker BALCH, GA-TECH [GA], and his team, for QSTK-initiative 和量化金融建模的创新方法。

eventprofiler 是如何获取数据的?

简单地说,它可以在eventprofiler.run( feed , ... )eventprofiler.Predicate-wrapped 中访问完整的feed >feed,它通过一个Class-parameter获取所有feed-details对.Predicate实例的访问权限,以便能够计算那里实现的所有细节战略演算要求。 很聪明,不是吗?

其余的都是通过重用他们的类方法来完成的。


如何自建?

声明一个适当装备的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() 方法。原因是,深度回测可能会被非常接近的调整所扭曲,在调整未知的时候做出决定。每个专业的量化分析师都有公平的责任避免任何窥探未来的方式,并仔细决定在投资组合估值方面需要调整的地方,如果工具持有时间在其各自的生命周期内经历了调整,或者不是。

【讨论】:

  • 嘿,非常感谢您的精彩回复,它非常有帮助。您建议的代码虽然给出了错误。您介意快速浏览一下吗?
  • 很抱歉打扰您,但我正在尝试配置 EP 以分析 i > -1 的 bards[i]。但是我收到了 IndexError。如果你能看看会很有帮助stackoverflow.com/questions/37536998/…
【解决方案2】:

奖励答案

虽然问题的动机很明确,但有几个原因,为什么答案不像看起来那么简单。

首先,事情是如何运作的:

QSTKpyalgotrade中的eventprofiler建立在DataSeries 表示市场,外部数据通过 feed-机制输入(未存储)。

zipline 方法有所不同,其核心功能集中在其基于事件的模拟引擎上,该引擎在每个价格的原子角色级别上运行-QUOTE- tick(异步外部事件到达和本地响应处理)。

事件流处理的顺序性对于模拟体外回测具有一定的吸引力。

相反,QSTK-originated eventprofiler 的优势在于同时处理完整-长度的DataSeries-representations(或一些智能迭代器重述或高效numpy stride-tricks&magics)。

这种巨大的概念差异使得很难获得类似的智能 + 快速 + 高效 + 易于重用的工具,因为 QSTK eventprofiler 毫无疑问是,在一个事件处理环境。

【讨论】:

    猜你喜欢
    • 2017-04-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多