Source code for backtrader.filters.bsplitter

#!/usr/bin/env python
"""Bar Splitter Filter Module - Daily bar splitting.

This module provides the DaySplitterClose filter for splitting daily
bars into two parts for intraday replay simulation.

Classes:
    DaySplitterClose: Splits daily bars into OHLX and CCCC ticks.

Example:
    >>> data = bt.feeds.GenericCSVData(dataname='daily.csv')
    >>> data.addfilter(bt.filters.DaySplitterClose())
    >>> cerebro.adddata(data)
"""

import datetime

from backtrader.parameters import ParameterizedBase

__all__ = ["DaySplitterClose", "DaySplitter_Close"]


[docs] class DaySplitterClose(ParameterizedBase): """ 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 indicates 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
[docs] def __init__(self, data, **kwargs): """Initialize the DaySplitterClose filter. Args: data: The data feed to apply the filter to. **kwargs: Additional keyword arguments passed to parent class. """ super().__init__(**kwargs) self.lastdt = None
[docs] def __call__(self, data): """Process the data feed to split daily bars. This method is called for each bar in the data feed. It splits the daily bar into two parts - an OHLX tick and a CCCC tick - to simulate intraday trading behavior. Args: data: The data feed containing the bar to process. Returns: bool: False if the initial tick can be further processed from stack. """ # 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
# Alias for backward compatibility DaySplitter_Close = DaySplitterClose