过滤器 – backtrader中文教程
Filters
This功能相对较晚除了backtrader而且必须是安装在现有的内部。这使得它是不灵活和100%功能全的希望,但它仍然可以达到目的在许多cases.
Although落实试图允许即插即用过滤器链接,此预先存在的内部,因此难以确保可能永远是实现。因此,一些过滤器可被链接和其他一些可以通过not.
Purpose
- Transform提供的值的data feed以递送不同data
feed
的实施开始,以简化这两个实施这可以通过cerebroAPI直接使用明显的过滤器。它们是:
- Resampling(
cerebro.resampledata
)的这里的滤波器变换
timeframe
和compression
的进入data feed。例如:(Seconds, 1) -> (Days, 1)
这意味着,原始数据馈送是输送杆,分辨率的1 Second。在Resampling滤波器截取数据并对其进行缓冲直到它可以提供一个1 Day酒吧。这将发生在一个1 Second栏从第二天是seen.
- Replaying(
cerebro.replaydata
)对于与上述相同的时间框架,所述过滤器将使用1 Second分辨率酒吧重建1 Daybar.
That指1 Day栏提供多次1 Second酒吧都见过,更新,以包含最新的information.
This模拟,例如,实际交易日如何有数据developed.
Note
The长度,
len(data)
,因此长度策略只要保持不变的day不在work
Given change.
Filters一个现有的数据进料/源您使用的数据的addfilter
方法饲料:
data = MyDataFeed(dataname=myname) data.addfilter(filter, *args, **kwargs) cerebro.addata(data)
而且,即使它正好是在重采样兼容/ replay过滤以下也可以做到:
data = MyDataFeed(dataname=myname) data.addfilter(filter, *args, **kwargs) cerebro.replaydata(data)
过滤Interface
Afilter
必须符合给定的接口,是这样的:
- 可调用它接受这个签名:
callable(data, *args, **kwargs)
or
- A类可以是instantiated和called
- 在实例化
__init__
方法必须支持签名:
def __init__(self, data, *args, **kwargs)
- `的
__call__
方法证明了这签名:
def __call__(self, data, *args, **kwargs)
实例将被称为从data
feed每个新进入的值。该\*args
和\*kwargs
在相同的传递给__init__
RETURN VALUES:
* `True`: the inner data fetching loop of the data feed must retry fetching data from the feed, becaue the length of the stream was manipulated * `False` even if data may have been edited (example: changed `close` price), the length of the stream has remain untouched
在基于类滤波器的情况下2种附加的方法可以用下面的签名来implemented
last
:
def last(self, data, *args, **kwargs)
这将被调用的时候data feed结束后,允许过滤器提供它可能已例如缓冲的数据。一个典型的例子是resampling的,因为条被缓冲,直到数据从下一次期间看到。当数据料已经结束,没有推新数据缓冲的数据out.
last
提供推缓冲数据out. - 在实例化
Note
It的机会是显而易见的,如果filter在所有支持没有参数,无任何将被添加,所述签名可以被简化为在:
def __init__(self, data, *args, **kwargs) -> def __init__(self, data)
A样品Filter
A非常快速的过滤器实现:
class SessionFilter(object): def __init__(self, data): pass def __call__(self, data): if data.p.sessionstart <= data.datetime.time() <= data.p.sessionend: # bar is in the session return False # tell outer data loop the bar can be processed # bar outside of the regular session times data.backwards() # remove bar from data stack return True # tell outer data loop to fetch a new bar
这个过滤器:
- `使用
data.p.sessionstart
和data.p.sessionend
(标准数据馈送参数),以决定是否酒吧是在session. - Ifin-the-session返回值是
False
,表示什么也没有完成,并且当前条的处理可以continue - Ifnot-in-the-session,所述杆从所述流中除去和
True
是返回指示新栏必须fetched.Note
The
data.backwards()
使得用途LineBuffer
接口。这种深层挖掘到的backtrader.
使用这种过滤器的内部结构:
- 有些数据馈送包含out of regular trading hours数据,这可能不有兴趣的商人。有了这个过滤器只in-session条将被considered.
Data伪API用于Filters
In它上面的例子已经示出了如何在过滤器所调用data.backwards()
,以除去从流电流条。有用的电话从中意味着作为数据馈送对象pseudo-API for Filters是:
data.backwards(size=1, force=False)
:删除size从数据条流通过向后移动的逻辑指针(默认为1
)。如果force=True
,则物理存储也是removed.卸下物理存储是一个微妙的操作,并仅作为一个黑客内部operations.
data.forward(value=float("NaN"), size=1)
:移动size棒存储向前,增加物理存储,如果需要,可以并用填充value
data._addtostack(bar, stash=False)
:增加了bar
到烟囱供以后处理。bar
是含有尽可能多的值作为lines
可迭代具有数据feed.If
stash=False
的栏添加到堆栈将被立即消耗通过该系统在下次iteration.如果
stash=True
栏将经历整个循环处理,包括潜在地重新解析由filtersdata._save2stack(erase=False, force=False)
:保存当前数据栏到堆叠用于以后的处理。如果erase=True
然后data.backwards
将被调用和将接收参数force
data._updatebar(bar, forward=False, ago=0)
:使用在所述值可迭代bar
覆盖数据流中的值ago
位置。使用默认的ago=0
当前栏将更新。同-1
,以前one.
Another例如:Pinkfish Filter
这是可以被链接的过滤器的一个例子,并且是指这样,到另一个过滤器,即replay filter。该Pinkfish名字是从图书馆它描述了在其主页的想法:利用每天的数据来执行操作,这些操作将只可能与盘中data.
To达到的效果:
- 每日栏将在2个COMPONENTES被打破:
OHL
然后C
. - 那些2片链与replay有以下情况发生在流:
With Len X -> OHL With Len X -> OHLC With Len X + 1 -> OHL With Len X + 1 -> OHLC With Len X + 2 -> OHL With Len X + 2 -> OHLC ...
逻辑:
- 当
OHLC
接收杆它被拷贝到一个interable和破到成为:- `的
OHL
栏。因为这个概念实际上并不存在的closing价格被替换为opening价格真正形成一个OHLO
bar. - An
C
栏whic也并不存在。现实情况是,这将是递送像蜱CCCC
- 如果分布在2 parts
- The电流棒之间从stream
- The
OHLO
除去一部分被放置到该卷堆栈立即processing - The
CCCC
部分在下一round - Because投入藏匿处理堆栈有适合立即处理过滤器可以返回
False
指示it.
- `的
This过滤器的工作原理连同:
- `的replay过滤器,拼
OHLO
和CCCC
部分最终实现了OHLC
bar.
The使用情况:
- 看到的东西一样,如果今天最大的是在最高最大过去的20届签发了
Close
而它与执行的顺序2nd tick.
The代码:
class DaySplitter_Close(bt.with_metaclass(bt.MetaParams, object)): """ Splits a daily bar in two parts simulating 2 ticks which will be used to replay the data: - First tick: ``OHLX`` The ``Close`` will be replaced by the *average* of ``Open``, ``High`` and ``Low`` The session opening time is used for this tick and - Second tick: ``CCCC`` The ``Close`` price will be used for the four components of the price The session closing time is used for this tick The volume will be split amongst the 2 ticks using the parameters: - ``closevol`` (default: ``0.5``) The value indicate which percentage, in absolute terms from 0.0 to 1.0, has to be assigned to the *closing* tick. The rest will be assigned to the ``OHLX`` tick. **This filter is meant to be used together with** ``cerebro.replaydata`` """ params = ( ("closevol", 0.5), # 0 -> 1 amount of volume to keep for close ) # replaying = True def __init__(self, data): self.lastdt = None def __call__(self, data): # Make a copy of the new bar and remove it from stream datadt = data.datetime.date() # keep the date if self.lastdt == datadt: return False # skip bars that come again in the filter self.lastdt = datadt # keep ref to last seen bar # Make a copy of current data for ohlbar ohlbar = [data.lines[i][0] for i in range(data.size())] closebar = ohlbar[:] # Make a copy for the close # replace close price with o-h-l average ohlprice = ohlbar[data.Open] + ohlbar[data.High] + ohlbar[data.Low] ohlbar[data.Close] = ohlprice / 3.0 vol = ohlbar[data.Volume] # adjust volume ohlbar[data.Volume] = vohl = int(vol * (1.0 - self.p.closevol)) oi = ohlbar[data.OpenInterest] # adjust open interst ohlbar[data.OpenInterest] = 0 # Adjust times dt = datetime.datetime.combine(datadt, data.p.sessionstart) ohlbar[data.DateTime] = data.date2num(dt) # Ajust closebar to generate a single tick -> close price closebar[data.Open] = cprice = closebar[data.Close] closebar[data.High] = cprice closebar[data.Low] = cprice closebar[data.Volume] = vol - vohl ohlbar[data.OpenInterest] = oi # Adjust times dt = datetime.datetime.combine(datadt, data.p.sessionend) closebar[data.DateTime] = data.date2num(dt) # Update stream data.backwards(force=True) # remove the copied bar from stream data._add2stack(ohlbar) # add ohlbar to stack # Add 2nd part to stash to delay processing to next round data._add2stack(closebar, stash=True) return False # initial tick can be further processed from stack
评论被关闭。