我正在尝试学习如何在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
如何接受和使用数据,但是有很多类方法可以调用,而且我是&#39我觉得解剖它有点棘手。
我想从简单开始,只使用price
和volume
。它是,一种策略是if volume > 1000 and close < 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]
我已经查看过来源&event;事件发展日期&#39;并且无法弄清楚它是什么。这是代码
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)
答案 0 :(得分:1)
Many thanks to prof. Tucker BALCH, GA-TECH [GA], and his team, for
QSTK
-initiative以及量化金融建模的创新方法。
eventprofiler
如何获取数据?
简单地说,它可以在feed
eventprofiler.run(
feed
中同时访问完整的 , ... )
eventprofiler.Predicate
- 包裹 feed
,其中包含所有Feed详情&#39;通过Class-parameter访问 .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()
方法。理由是,深度回测可能会因为非常接近的调整,在做出决策时有所偏差,而调整尚不清楚。每个专业定量分析师的公平义务是避免任何窥视未来的方法,并在需要调整的情况下仔细决定投资组合估值,如果持有时间的工具已进行调整,则在其中进行调整。相应的生命周期,或不是。
答案 1 :(得分:1)
虽然问题的动机是明确的,但有几个原因,为什么答案不是那么简单,因为它可能看起来。
首先,事情是如何运作的:
eventprofiler
和 QSTK
中的 pyalgotrade
是建立在市场的 DataSeries
表示之上,外部数据通过 feed
机制输入(未存储)。
zipline
方法与众不同,其核心功能主要集中在基于事件的模拟引擎上,该引擎在每个价格的原子角色级别上运行 - {{ 1}} - tick(异步外部事件到达和本地响应处理)。
事件流处理的顺序性质对模拟的体外回溯测试具有一定的吸引力。
QUOTE
- 来源QSTK
的优势正相反,基于一次处理完整 - 长度eventprofiler
- 表示(或某些智能迭代器重新验证或高效 DataSeries
numpy
- 技巧和魔法)。
这种巨大的概念差异使得很难获得类似智能+快速+高效+易于重复使用的工具,因为stride
QSTK
问题是,在事件处理环境中。