pyalgotrade 中事件分析器的更多示例
More examples for the event profiler in pyalgotrade
我正在尝试学习如何将自定义策略实施到 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
是如何接收和使用数据的,虽然有很多 class 方法被调用并且我发现剖析它有点棘手。
我想从简单的开始,只使用 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]
我查看了源代码 '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)
量化序言:
Many thanks to prof. Tucker BALCH, GA-TECH [GA], and his team, for QSTK
-initiative and the innovative approaches to Quantitative Finance Modelling.
How the eventprofiler
takes in data?
简单地说,它在 eventprofiler.run(
feed
中都可以访问完整的 feed
, ... )
也作为 eventprofiler.Predicate
-wrapped feed
,它将所有 feed-details 的访问权限直接放入 .Predicate
实例通过 Class 参数,以便能够计算那里实现了策略演算所需的所有细节。 聪明,不是吗?
其余的是通过重新使用他们的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 )
量化结语:
细心的 reader 注意到,建议的代码不调用 .getAdjClose()
方法。原因是,深度回溯测试可能会被非常接近的调整所扭曲,在调整未知的时候及时做出决定。每个专业量化分析师都有义务避免以任何方式窥视未来,并谨慎决定在投资组合估值方面需要调整的地方,如果工具的持有时间在其各自的生命周期内经历了调整,或者没有。
奖金回答
虽然问题的动机很明确,但有几个原因导致答案不像看起来那么简单。
首先,事情是如何运作的:
eventprofiler
QSTK
和pyalgotrade
建立在市场的 DataSeries
表示之上,其中外部数据通过feed
-机制.
zipline
方法不同并指出,核心功能集中在其基于事件的模拟引擎上,该引擎在原子角色级别上运行每个价格-QUOTE
-tick(异步外部事件到达和本地响应处理)。
事件流处理的顺序性质对模拟体外回测具有一定的吸引力。
QSTK
-起源eventprofiler
的优势恰恰相反,基于处理全-长度DataSeries
-一次表示(或一些智能迭代器重新描述或高效numpy
stride
-tricks&magics)。
这种巨大的概念差异使得很难获得类似智能 + 快速 + 高效 + 易于重用的工具,因为 QSTK
eventprofiler
毫无疑问,在事件处理环境中。
我正在尝试学习如何将自定义策略实施到 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
是如何接收和使用数据的,虽然有很多 class 方法被调用并且我发现剖析它有点棘手。
我想从简单的开始,只使用 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]
我查看了源代码 '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)
量化序言:
Many thanks to prof. Tucker BALCH, GA-TECH [GA], and his team, for
QSTK
-initiative and the innovative approaches to Quantitative Finance Modelling.How the
eventprofiler
takes in data?
简单地说,它在 eventprofiler.run(
feed
中都可以访问完整的 feed
, ... )
也作为 eventprofiler.Predicate
-wrapped feed
,它将所有 feed-details 的访问权限直接放入 .Predicate
实例通过 Class 参数,以便能够计算那里实现了策略演算所需的所有细节。 聪明,不是吗?
其余的是通过重新使用他们的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 )
量化结语:
细心的 reader 注意到,建议的代码不调用 .getAdjClose()
方法。原因是,深度回溯测试可能会被非常接近的调整所扭曲,在调整未知的时候及时做出决定。每个专业量化分析师都有义务避免以任何方式窥视未来,并谨慎决定在投资组合估值方面需要调整的地方,如果工具的持有时间在其各自的生命周期内经历了调整,或者没有。
奖金回答
虽然问题的动机很明确,但有几个原因导致答案不像看起来那么简单。
首先,事情是如何运作的:
eventprofiler
QSTK
和pyalgotrade
建立在市场的 DataSeries
表示之上,其中外部数据通过feed
-机制.
zipline
方法不同并指出,核心功能集中在其基于事件的模拟引擎上,该引擎在原子角色级别上运行每个价格-QUOTE
-tick(异步外部事件到达和本地响应处理)。
事件流处理的顺序性质对模拟体外回测具有一定的吸引力。
QSTK
-起源eventprofiler
的优势恰恰相反,基于处理全-长度DataSeries
-一次表示(或一些智能迭代器重新描述或高效numpy
stride
-tricks&magics)。
这种巨大的概念差异使得很难获得类似智能 + 快速 + 高效 + 易于重用的工具,因为 QSTK
eventprofiler
毫无疑问,在事件处理环境中。